Changed MS/TP receive to read more bytes from UART queue if they are available during each cycle. This fixes high baud rate issues on slower processors if the main loop cycle time is not fast enough.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user