This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -185,13 +185,13 @@ static uint8_t TransmitPacketDest;
|
|||||||
/* that a node must wait for a station to begin replying to a */
|
/* that a node must wait for a station to begin replying to a */
|
||||||
/* confirmed request: 255 milliseconds. (Implementations may use */
|
/* confirmed request: 255 milliseconds. (Implementations may use */
|
||||||
/* larger values for this timeout, not to exceed 300 milliseconds.) */
|
/* larger values for this timeout, not to exceed 300 milliseconds.) */
|
||||||
#define Treply_timeout 260
|
#define Treply_timeout 295
|
||||||
|
|
||||||
/* The minimum time without a DataAvailable or ReceiveError event that a */
|
/* The minimum time without a DataAvailable or ReceiveError event that a */
|
||||||
/* node must wait for a remote node to begin using a token or replying to */
|
/* node must wait for a remote node to begin using a token or replying to */
|
||||||
/* a Poll For Master frame: 20 milliseconds. (Implementations may use */
|
/* a Poll For Master frame: 20 milliseconds. (Implementations may use */
|
||||||
/* larger values for this timeout, not to exceed 100 milliseconds.) */
|
/* larger values for this timeout, not to exceed 100 milliseconds.) */
|
||||||
#define Tusage_timeout 25
|
#define Tusage_timeout 95
|
||||||
|
|
||||||
/* The number of tokens received or used before a Poll For Master cycle */
|
/* The number of tokens received or used before a Poll For Master cycle */
|
||||||
/* is executed: 50. */
|
/* is executed: 50. */
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ void init(void)
|
|||||||
|
|
||||||
/* Configure USART */
|
/* Configure USART */
|
||||||
RS485_Initialize();
|
RS485_Initialize();
|
||||||
RS485_Set_Baud_Rate(38400);
|
|
||||||
|
|
||||||
/* Configure Timer0 for millisecond timer */
|
/* Configure Timer0 for millisecond timer */
|
||||||
Timer_Initialize();
|
Timer_Initialize();
|
||||||
@@ -163,7 +162,7 @@ int main(void)
|
|||||||
|
|
||||||
init();
|
init();
|
||||||
#if defined(BACDL_MSTP)
|
#if defined(BACDL_MSTP)
|
||||||
RS485_Set_Baud_Rate(38400);
|
//RS485_Set_Baud_Rate(38400);
|
||||||
dlmstp_set_max_master(127);
|
dlmstp_set_max_master(127);
|
||||||
dlmstp_set_max_info_frames(1);
|
dlmstp_set_max_info_frames(1);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "mstp.h"
|
//#include "mstp.h"
|
||||||
|
|
||||||
/* This file has been customized for use with ATMEGA168 */
|
/* This file has been customized for use with ATMEGA168 */
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
@@ -42,7 +42,19 @@ static uint8_t LED1_Off_Timer;
|
|||||||
static uint8_t LED3_Off_Timer;
|
static uint8_t LED3_Off_Timer;
|
||||||
|
|
||||||
/* baud rate */
|
/* baud rate */
|
||||||
static uint32_t RS485_Baud = 38400;
|
static uint32_t RS485_Baud = 9600;
|
||||||
|
/* autobaud - switch baud on errors if autobaud is true */
|
||||||
|
static bool RS485_Autobaud = true;
|
||||||
|
/* we saw some data, so we are on an active wire */
|
||||||
|
static uint8_t RS485_Data_Count;
|
||||||
|
/* count of errors before autobaud switching */
|
||||||
|
static uint8_t RS485_Error_Count;
|
||||||
|
/* time limit */
|
||||||
|
#define RS485_ERROR_TIMEOUT 1000
|
||||||
|
/* millisecond timer to limit error window */
|
||||||
|
static uint16_t RS485_Error_Timer = RS485_ERROR_TIMEOUT;
|
||||||
|
/* number of errors in 1000ms before autobaud switching */
|
||||||
|
#define RS485_ERROR_LIMIT 30
|
||||||
|
|
||||||
/* The minimum time after the end of the stop bit of the final octet of a */
|
/* The minimum time after the end of the stop bit of the final octet of a */
|
||||||
/* received frame before a node may enable its EIA-485 driver: 40 bit times. */
|
/* received frame before a node may enable its EIA-485 driver: 40 bit times. */
|
||||||
@@ -141,6 +153,34 @@ bool RS485_Set_Baud_Rate(uint32_t baud)
|
|||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RS485_Next_Baud_Rate(void)
|
||||||
|
{
|
||||||
|
uint32_t baud;
|
||||||
|
|
||||||
|
switch (RS485_Baud) {
|
||||||
|
case 9600:
|
||||||
|
baud = 19200;
|
||||||
|
break;
|
||||||
|
case 19200:
|
||||||
|
baud = 38400;
|
||||||
|
break;
|
||||||
|
case 38400:
|
||||||
|
baud = 57600;
|
||||||
|
break;
|
||||||
|
case 57600:
|
||||||
|
baud = 76800;
|
||||||
|
break;
|
||||||
|
case 76800:
|
||||||
|
baud = 115200;
|
||||||
|
break;
|
||||||
|
case 115200:
|
||||||
|
default:
|
||||||
|
baud = 9600;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
RS485_Set_Baud_Rate(baud);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* DESCRIPTION: Waits on the SilenceTimer for 40 bits.
|
* DESCRIPTION: Waits on the SilenceTimer for 40 bits.
|
||||||
* RETURN: none
|
* RETURN: none
|
||||||
@@ -201,6 +241,9 @@ void RS485_LED_Timers(void)
|
|||||||
BIT_SET(PORTD,PD7);
|
BIT_SET(PORTD,PD7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (RS485_Error_Timer) {
|
||||||
|
RS485_Error_Timer--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -263,7 +306,7 @@ void RS485_Send_Data(
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* DESCRIPTION: Return true if a framing or overrun error is present
|
* DESCRIPTION: Return true if a framing or overrun error is present
|
||||||
* RETURN: true if error
|
* RETURN: true if error
|
||||||
* ALGORITHM: none
|
* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate
|
||||||
* NOTES: Clears any error flags.
|
* NOTES: Clears any error flags.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
bool RS485_ReceiveError(void)
|
bool RS485_ReceiveError(void)
|
||||||
@@ -285,6 +328,34 @@ bool RS485_ReceiveError(void)
|
|||||||
do {
|
do {
|
||||||
dummy_data = UDR0;
|
dummy_data = UDR0;
|
||||||
} while (BIT_CHECK(UCSR0A,RXC0));
|
} while (BIT_CHECK(UCSR0A,RXC0));
|
||||||
|
/* count errors during autobaud */
|
||||||
|
if (RS485_Error_Count < RS485_ERROR_LIMIT) {
|
||||||
|
RS485_Error_Count++;
|
||||||
|
} else {
|
||||||
|
if (RS485_Autobaud && RS485_Error_Timer) {
|
||||||
|
/* We are in autobaud mode, and there were excessive
|
||||||
|
errors while the timer was counting down */
|
||||||
|
RS485_Next_Baud_Rate();
|
||||||
|
RS485_Error_Timer = RS485_ERROR_TIMEOUT;
|
||||||
|
RS485_Error_Count = 0;
|
||||||
|
} else if (RS485_Autobaud) {
|
||||||
|
/* autobaud, but timer expired */
|
||||||
|
RS485_Autobaud = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (RS485_Autobaud) {
|
||||||
|
if ((RS485_Error_Timer == 0) && (RS485_Error_Count == 0)) {
|
||||||
|
if (RS485_Data_Count > 8) {
|
||||||
|
/* no errors, timer expired, and we saw data */
|
||||||
|
RS485_Autobaud = false;
|
||||||
|
} else {
|
||||||
|
/* no errors, timer expired, and no data*/
|
||||||
|
RS485_Error_Timer = RS485_ERROR_TIMEOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReceiveError;
|
return ReceiveError;
|
||||||
@@ -305,6 +376,8 @@ bool RS485_DataAvailable(uint8_t *data)
|
|||||||
*data = UDR0;
|
*data = UDR0;
|
||||||
DataAvailable = true;
|
DataAvailable = true;
|
||||||
RS485_LED1_On();
|
RS485_LED1_On();
|
||||||
|
if (RS485_Data_Count < 0xFF)
|
||||||
|
RS485_Data_Count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DataAvailable;
|
return DataAvailable;
|
||||||
|
|||||||
Reference in New Issue
Block a user