diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c index b9aac6c9..722eb563 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c @@ -370,7 +370,8 @@ static void MSTP_Send_Frame( { /* 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 data crc */ + 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 */ @@ -387,20 +388,24 @@ static void MSTP_Send_Frame( buffer[6] = LO_BYTE(data_len); crc8 = CRC_Calc_Header(buffer[6], crc8); buffer[7] = ~crc8; - rs485_turnaround_delay(); - rs485_rts_enable(true); - rs485_bytes_send(buffer, 8); - /* send any data */ 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[0] = (crc16 & 0x00FF); - buffer[1] = ((crc16 & 0xFF00) >> 8); + 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, 2); + rs485_bytes_send(buffer_crc, 2); } rs485_rts_enable(false); } @@ -1211,11 +1216,15 @@ uint16_t dlmstp_receive( InputBuffer = pdu; InputBufferSize = max_pdu; } - /* only do receive state machine while we don't have a frame */ - if ((MSTP_Flag.ReceivedValidFrame == false) && + while ((MSTP_Flag.ReceivedValidFrame == false) && (MSTP_Flag.ReceivedValidFrameNotForUs == false) && (MSTP_Flag.ReceivedInvalidFrame == false)) { + /* only do receive state machine while we don't have a frame */ MSTP_Receive_Frame_FSM(); + /* process another byte, if available */ + if (!rs485_byte_available(NULL)) { + break; + } } if (MSTP_Flag.ReceivedValidFrameNotForUs) { MSTP_Flag.ReceivedValidFrameNotForUs = false; @@ -1246,11 +1255,6 @@ void dlmstp_set_mac_address( /* Master Nodes can only have address 0-127 */ if (mac_address <= 127) { This_Station = mac_address; - /* FIXME: implement your data storage */ - /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, - mac_address, - EEPROM_MSTP_MAC_ADDR); */ if (mac_address > Nmax_master) dlmstp_set_max_master(127); } diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c index d1c68b97..34a67d2c 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c @@ -53,18 +53,33 @@ static FIFO_BUFFER Receive_Buffer; static struct etimer Silence_Timer; +/**************************************************************************** +* DESCRIPTION: Determines the amount of silence time elapsed +* RETURN: true if the amount of silence time has elapsed +* NOTES: none +*****************************************************************************/ bool rs485_silence_time_elapsed( uint16_t milliseconds) { return timer_elapsed_milliseconds_short(&Silence_Timer, milliseconds); } +/**************************************************************************** +* DESCRIPTION: Resets the silence timer +* RETURN: nothing +* NOTES: none +*****************************************************************************/ void rs485_silence_time_reset( void) { timer_elapsed_start(&Silence_Timer); } +/**************************************************************************** +* DESCRIPTION: Configures the RTS output +* RETURN: nothing +* NOTES: none +*****************************************************************************/ static void rs485_rts_init( void) { @@ -72,7 +87,11 @@ static void rs485_rts_init( BIT_SET(DDRD, DDD4); } -/* enable the transmit-enable line on the RS-485 transceiver */ +/**************************************************************************** +* DESCRIPTION: enable the transmit-enable line on the RS-485 transceiver +* RETURN: nothing +* NOTES: none +*****************************************************************************/ void rs485_rts_enable( bool enable) { @@ -83,12 +102,22 @@ void rs485_rts_enable( } } +/**************************************************************************** +* DESCRIPTION: enable the UART receiver and interrupt +* RETURN: nothing +* NOTES: none +*****************************************************************************/ static void rs485_receiver_enable( void) { UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); } +/**************************************************************************** +* DESCRIPTION: delay for 40 bit times +* RETURN: nothing +* NOTES: none +*****************************************************************************/ void rs485_turnaround_delay( void) { @@ -114,6 +143,11 @@ void rs485_turnaround_delay( BIT_SET(UCSR0A, TXC0); } +/**************************************************************************** +* DESCRIPTION: Interrupt service routine for UART Receiver +* RETURN: nothing +* NOTES: none +*****************************************************************************/ ISR(USART0_RX_vect) { uint8_t data_byte; @@ -128,6 +162,11 @@ ISR(USART0_RX_vect) } } +/**************************************************************************** +* DESCRIPTION: Checks for data on the receive UART, and handles errors +* RETURN: none +* NOTES: none +*****************************************************************************/ bool rs485_byte_available( uint8_t * data_register) { @@ -135,19 +174,31 @@ bool rs485_byte_available( if (!FIFO_Empty(&Receive_Buffer)) { led_on_interval(LED_4, 1); - *data_register = FIFO_Get(&Receive_Buffer); + if (data_register) { + *data_register = FIFO_Get(&Receive_Buffer); + } data_available = true; } return data_available; } +/**************************************************************************** +* DESCRIPTION: returns an error indication if errors are enabled +* RETURN: nothing +* NOTES: none +*****************************************************************************/ bool rs485_receive_error( void) { return false; } +/**************************************************************************** +* DESCRIPTION: Transmits a frame using the UART +* RETURN: none +* NOTES: none +*****************************************************************************/ void rs485_bytes_send( uint8_t * buffer, /* data to send */ uint16_t nbytes) @@ -181,12 +232,22 @@ void rs485_bytes_send( return; } +/**************************************************************************** +* DESCRIPTION: Returns the baud rate that we are currently running at +* RETURN: baud rate in bps +* NOTES: none +*****************************************************************************/ uint32_t rs485_baud_rate( void) { return Baud_Rate; } +/**************************************************************************** +* DESCRIPTION: configure the UART baud rate +* RETURN: nothing +* NOTES: none +*****************************************************************************/ static void rs485_baud_rate_configure( void) { @@ -196,6 +257,11 @@ static void rs485_baud_rate_configure( UBRR0 = (F_CPU / (8UL * Baud_Rate)) - 1; } +/**************************************************************************** +* DESCRIPTION: set the UART baud rate to a standard value +* RETURN: true if the baud rate is valid +* NOTES: none +*****************************************************************************/ bool rs485_baud_rate_set( uint32_t baud) { @@ -223,6 +289,11 @@ bool rs485_baud_rate_set( return valid; } +/**************************************************************************** +* DESCRIPTION: initialize the hardware UART +* RETURN: nothing +* NOTES: none +*****************************************************************************/ static void rs485_usart_init( void) { @@ -243,6 +314,11 @@ static void rs485_usart_init( BIT_CLEAR(PRR, PRUSART0); } +/**************************************************************************** +* DESCRIPTION: read any non-volatile data +* RETURN: nothing +* NOTES: none +*****************************************************************************/ static void rs485_init_nvdata( void) { @@ -278,6 +354,11 @@ static void rs485_init_nvdata( rs485_baud_rate_configure(); } +/**************************************************************************** +* DESCRIPTION: initialize the module +* RETURN: nothing +* NOTES: none +*****************************************************************************/ void rs485_init( void) {