AllJoyn/Samples/BACnetAdapter/bacnet-stack-0.8.2/ports/bdk-atxx4-mstp/dlmstp.c
static void MSTP_Send_Frame(
    uint8_t frame_type, /* type of frame to send - see defines */
    uint8_t destination,        /* destination address */
    uint8_t source,     /* source address */
    uint8_t * data,     /* any data to be sent - may be null */
    uint16_t data_len)
{       /* number of bytes of data (up to 501) */
    uint8_t crc8 = 0xFF;        /* used to calculate the crc value */
    uint16_t crc16 = 0xFFFF;    /* used to calculate the crc value */
    uint8_t buffer[8];  /* stores the header and header crc */
    uint8_t buffer_crc[2];      /* stores the data crc */
    uint16_t i = 0;     /* used to calculate CRC for data */

    /* create the MS/TP header */
    buffer[0] = 0x55;
    buffer[1] = 0xFF;
    buffer[2] = frame_type;
    crc8 = CRC_Calc_Header(buffer[2], crc8);
    buffer[3] = destination;
    crc8 = CRC_Calc_Header(buffer[3], crc8);
    buffer[4] = source;
    crc8 = CRC_Calc_Header(buffer[4], crc8);
    buffer[5] = HI_BYTE(data_len);
    crc8 = CRC_Calc_Header(buffer[5], crc8);
    buffer[6] = LO_BYTE(data_len);
    crc8 = CRC_Calc_Header(buffer[6], crc8);
    buffer[7] = ~crc8;
    if (data_len) {
        /* calculate CRC for any data */
        for (i = 0; i < data_len; i++) {
            crc16 = CRC_Calc_Data(data[i], crc16);
        }
        crc16 = ~crc16;
        buffer_crc[0] = (crc16 & 0x00FF);
        buffer_crc[1] = ((crc16 & 0xFF00) >> 8);
    }
    /* on a slower processor, we don't want to calculate
       the CRC after we send the header because there
       will be a gap */
    rs485_turnaround_delay();
    rs485_rts_enable(true);
    rs485_bytes_send(buffer, 8);
    if (data_len) {
        rs485_bytes_send(data, data_len);
        rs485_bytes_send(buffer_crc, 2);
    }
    rs485_rts_enable(false);
}
/* MS/TP Frame Format */
/* All frames are of the following format: */
/* */
/* Preamble: two octet preamble: X`55', X`FF' */
/* Frame Type: one octet */
/* Destination Address: one octet address */
/* Source Address: one octet address */
/* Length: two octets, most significant octet first, of the Data field */
/* Header CRC: one octet */
/* Data: (present only if Length is non-zero) */
/* Data CRC: (present only if Length is non-zero) two octets, */
/*           least significant octet first */
/* (pad): (optional) at most one octet of padding: X'FF' */
MS/TP Frame Format
All frames are of the following format.


MS / TP Frame Format All frames are of the following format .
static void MSTP_Send_Frame(
    uint8_t frame_type, 
    uint8_t destination,        
    uint8_t source,     
    uint8_t * data,     
    uint16_t data_len)
{       
    uint8_t crc8 = 0xFF;        
    uint16_t crc16 = 0xFFFF;    
    uint8_t buffer[8];  
    uint8_t buffer_crc[2];      
    uint16_t i = 0;     
    buffer[0] = 0x55;
    buffer[1] = 0xFF;
    buffer[2] = frame_type;
    crc8 = CRC_Calc_Header(buffer[2], crc8);
    buffer[3] = destination;
    crc8 = CRC_Calc_Header(buffer[3], crc8);
    buffer[4] = source;
    crc8 = CRC_Calc_Header(buffer[4], crc8);
    buffer[5] = HI_BYTE(data_len);
    crc8 = CRC_Calc_Header(buffer[5], crc8);
    buffer[6] = LO_BYTE(data_len);
    crc8 = CRC_Calc_Header(buffer[6], crc8);
    buffer[7] = ~crc8;
    if (data_len) {
        for (i = 0; i < data_len; i++) {
            crc16 = CRC_Calc_Data(data[i], crc16);
        }
        crc16 = ~crc16;
        buffer_crc[0] = (crc16 & 0x00FF);
        buffer_crc[1] = ((crc16 & 0xFF00) >> 8);
    }
    rs485_turnaround_delay();
    rs485_rts_enable(true);
    rs485_bytes_send(buffer, 8);
    if (data_len) {
        rs485_bytes_send(data, data_len);
        rs485_bytes_send(buffer_crc, 2);
    }
    rs485_rts_enable(false);
}
static void MSTP_Send_Frame ( uint8_t frame_type , uint8_t destination , uint8_t source , uint8_t * data , uint16_t data_len ) { uint8_t crc8 = 0xFF ; uint16_t crc16 = 0xFFFF ; uint8_t buffer [ 8 ] ; uint8_t buffer_crc [ 2 ] ; uint16_t i = 0 ; buffer [ 0 ] = 0x55 ; buffer [ 1 ] = 0xFF ; buffer [ 2 ] = frame_type ; crc8 = CRC_Calc_Header ( buffer [ 2 ] , crc8 ) ; buffer [ 3 ] = destination ; crc8 = CRC_Calc_Header ( buffer [ 3 ] , crc8 ) ; buffer [ 4 ] = source ; crc8 = CRC_Calc_Header ( buffer [ 4 ] , crc8 ) ; buffer [ 5 ] = HI_BYTE ( data_len ) ; crc8 = CRC_Calc_Header ( buffer [ 5 ] , crc8 ) ; buffer [ 6 ] = LO_BYTE ( data_len ) ; crc8 = CRC_Calc_Header ( buffer [ 6 ] , crc8 ) ; buffer [ 7 ] = ~ crc8 ; if ( data_len ) { for ( i = 0 ; i < data_len ; i ++ ) { crc16 = CRC_Calc_Data ( data [ i ] , crc16 ) ; } crc16 = ~ crc16 ; buffer_crc [ 0 ] = ( crc16 & 0x00FF ) ; buffer_crc [ 1 ] = ( ( crc16 & 0xFF00 ) >> 8 ) ; } rs485_turnaround_delay ( ) ; rs485_rts_enable ( true ) ; rs485_bytes_send ( buffer , 8 ) ; if ( data_len ) { rs485_bytes_send ( data , data_len ) ; rs485_bytes_send ( buffer_crc , 2 ) ; } rs485_rts_enable ( false ) ; }
MS/TP Frame Format
All frames are of the following format:
MS / TP Frame Format All frames are of the following format :
/* type of frame to send - see defines */ /* destination address */ /* source address */ /* any data to be sent - may be null */ /* number of bytes of data (up to 501) */ /* used to calculate the crc value */ /* used to calculate the crc value */ /* stores the header and header crc */ /* stores the data crc */ /* used to calculate CRC for data */ /* create the MS/TP header */ /* calculate CRC for any data */ /* on a slower processor, we don't want to calculate
       the CRC after we send the header because there
       will be a gap */