Added reset of SilenceTimer in the SendFrame part of MS/TP that had been missing. Refactored more master state machine states.

This commit is contained in:
skarg
2006-08-28 21:13:37 +00:00
parent 011536b9c5
commit 23a8636b90
5 changed files with 230 additions and 245 deletions
+89 -114
View File
@@ -56,7 +56,8 @@
/* debug print statements */ /* debug print statements */
#define PRINT_ENABLED_RECEIVE 0 #define PRINT_ENABLED_RECEIVE 0
#define PRINT_ENABLED_MASTER 0 #define PRINT_ENABLED_RECEIVE_DATA 0
#define PRINT_ENABLED_MASTER 1
/* MS/TP Frame Format */ /* MS/TP Frame Format */
/* All frames are of the following format: */ /* All frames are of the following format: */
@@ -249,9 +250,6 @@ char *mstp_receive_state_text(int state)
case MSTP_RECEIVE_STATE_DATA: case MSTP_RECEIVE_STATE_DATA:
text = "DATA"; text = "DATA";
break; break;
case MSTP_RECEIVE_STATE_DATA_CRC:
text = "CRC";
break;
default: default:
break; break;
} }
@@ -262,6 +260,10 @@ char *mstp_receive_state_text(int state)
void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port) void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
{ {
#if PRINT_ENABLED_MASTER
static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE;
#endif
#if PRINT_ENABLED_RECEIVE #if PRINT_ENABLED_RECEIVE
fprintf(stderr,"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\r\n", fprintf(stderr,"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\r\n",
mstp_receive_state_text(mstp_port->receive_state), mstp_receive_state_text(mstp_port->receive_state),
@@ -272,6 +274,16 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->DataLength, mstp_port->DataLength,
mstp_port->SilenceTimer); mstp_port->SilenceTimer);
#endif #endif
#if PRINT_ENABLED_RECEIVE_DATA
if (mstp_port->DataAvailable == true)
{
if ((mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE) &&
(receive_state != MSTP_RECEIVE_STATE_IDLE))
fprintf(stderr,"MSTP Rx: ");
fprintf(stderr,"%02X ", mstp_port->DataRegister);
}
receive_state = mstp_port->receive_state;
#endif
switch (mstp_port->receive_state) { switch (mstp_port->receive_state) {
/* In the IDLE state, the node waits for the beginning of a frame. */ /* In the IDLE state, the node waits for the beginning of a frame. */
@@ -515,51 +527,34 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
} else if (mstp_port->DataAvailable == true) { } else if (mstp_port->DataAvailable == true) {
/* DataOctet */ /* DataOctet */
if (mstp_port->Index < mstp_port->DataLength) { if (mstp_port->Index < mstp_port->DataLength) {
mstp_port->SilenceTimer = 0;
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC); mstp_port->DataCRC);
mstp_port->InputBuffer[mstp_port->Index] = mstp_port->InputBuffer[mstp_port->Index] =
mstp_port->DataRegister; mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index++; mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
} }
/* CRC1 */ /* CRC1 */
else if (mstp_port->Index == mstp_port->DataLength) { else if (mstp_port->Index == mstp_port->DataLength) {
mstp_port->SilenceTimer = 0;
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC); mstp_port->DataCRC);
mstp_port->DataAvailable = false;
mstp_port->Index++; mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
} }
/* CRC2 */ /* CRC2 */
else if (mstp_port->Index == (mstp_port->DataLength + 1)) { else if (mstp_port->Index == (mstp_port->DataLength + 1)) {
mstp_port->SilenceTimer = 0;
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister, mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC); mstp_port->DataCRC);
mstp_port->DataAvailable = false; /* STATE DATA CRC - no need for new state */
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA_CRC;
}
}
break;
/* In the DATA_CRC state, the node validates the CRC of the message data. */
case MSTP_RECEIVE_STATE_DATA_CRC:
/* GoodCRC */
if (mstp_port->DataCRC == 0xF0B8) {
/* indicate the complete reception of a valid frame */ /* indicate the complete reception of a valid frame */
if (mstp_port->DataCRC == 0xF0B8)
mstp_port->ReceivedValidFrame = true; mstp_port->ReceivedValidFrame = true;
/* the master node state machine will receive else
and validate the message */ mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
} }
/* BadCRC */ mstp_port->DataAvailable = false;
else { mstp_port->SilenceTimer = 0;
/* to indicate that an error has occurred during the reception of a frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
} }
break; break;
default: default:
@@ -567,6 +562,13 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
break; break;
} }
#if PRINT_ENABLED_RECEIVE_DATA
if ((receive_state != MSTP_RECEIVE_STATE_IDLE) &&
(mstp_port->receive_state == MSTP_RECEIVE_STATE_IDLE))
{
fprintf(stderr,"\r\n");
}
#endif
return; return;
} }
@@ -663,7 +665,9 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
uint8_t next_this_station = 0; uint8_t next_this_station = 0;
uint8_t next_next_station = 0; uint8_t next_next_station = 0;
uint16_t my_timeout = 10, ns_timeout = 0; uint16_t my_timeout = 10, ns_timeout = 0;
#if PRINT_ENABLED_MASTER
static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE; static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE;
#endif
/* some calculations that several states need */ /* some calculations that several states need */
@@ -723,11 +727,12 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
else if (mstp_port->ReceivedValidFrame == true) { else if (mstp_port->ReceivedValidFrame == true) {
#if PRINT_ENABLED_MASTER #if PRINT_ENABLED_MASTER
fprintf(stderr, fprintf(stderr,
"MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u Type=%s\r\n", "MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u ST=%u Type=%s\r\n",
mstp_port->SourceAddress, mstp_port->SourceAddress,
mstp_port->DestinationAddress, mstp_port->DestinationAddress,
mstp_port->DataLength, mstp_port->DataLength,
mstp_port->FrameCount, mstp_port->FrameCount,
mstp_port->SilenceTimer,
mstp_frame_type_text(mstp_port->FrameType)); mstp_frame_type_text(mstp_port->FrameType));
#endif #endif
/* destined for me! */ /* destined for me! */
@@ -832,8 +837,8 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* In the WAIT_FOR_REPLY state, the node waits for */ /* In the WAIT_FOR_REPLY state, the node waits for */
/* a reply from another node. */ /* a reply from another node. */
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
/* ReplyTimeout */
if (mstp_port->SilenceTimer >= Treply_timeout) { if (mstp_port->SilenceTimer >= Treply_timeout) {
/* ReplyTimeout */
/* assume that the request has failed */ /* assume that the request has failed */
mstp_port->FrameCount = mstp_port->Nmax_info_frames; mstp_port->FrameCount = mstp_port->Nmax_info_frames;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
@@ -841,67 +846,49 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* to the USE_TOKEN state. (Because of the length of the timeout, */ /* to the USE_TOKEN state. (Because of the length of the timeout, */
/* this transition will cause the token to be passed regardless */ /* this transition will cause the token to be passed regardless */
/* of the initial value of FrameCount.) */ /* of the initial value of FrameCount.) */
} } else {
if (mstp_port->ReceivedInvalidFrame == true) {
/* InvalidFrame */ /* InvalidFrame */
else if ((mstp_port->SilenceTimer < Treply_timeout) &&
(mstp_port->ReceivedInvalidFrame == true)) {
/* error in frame reception */ /* error in frame reception */
mstp_port->ReceivedInvalidFrame = false; mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
} } else if (mstp_port->ReceivedValidFrame == true) {
if (mstp_port->DestinationAddress == mstp_port->This_Station) {
switch (mstp_port->TxFrameType)
{
case FRAME_TYPE_REPLY_POSTPONED:
/* ReceivedReplyPostponed */
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
break;
case FRAME_TYPE_TEST_RESPONSE:
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* ReceivedReply */ /* ReceivedReply */
/* or a proprietary type that indicates a reply */ /* or a proprietary type that indicates a reply */
else if ((mstp_port->SilenceTimer < Treply_timeout) &&
(mstp_port->ReceivedValidFrame == true) &&
(mstp_port->DestinationAddress == mstp_port->This_Station) &&
((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) ||
/*(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || */
(mstp_port->FrameType ==
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) {
/* indicate successful reception to the higher layers */ /* indicate successful reception to the higher layers */
dlmstp_put_receive( dlmstp_put_receive(
mstp_port->SourceAddress, /* source MS/TP address */ mstp_port->SourceAddress, /* source MS/TP address */
(uint8_t *) & mstp_port->InputBuffer[0], (uint8_t *) & mstp_port->InputBuffer[0],
mstp_port->DataLength); mstp_port->DataLength);
mstp_port->ReceivedValidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
}
/* ReceivedPostpone */
else if ((mstp_port->SilenceTimer < Treply_timeout) &&
(mstp_port->ReceivedValidFrame == true) &&
(mstp_port->DestinationAddress == mstp_port->This_Station) &&
(mstp_port->FrameType == FRAME_TYPE_REPLY_POSTPONED)) {
/* FIXME: then the reply to the message has been postponed until a later time. */
/* So, what does this really mean? */
mstp_port->ReceivedValidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
break;
default:
/* if proprietary frame was expected, you might
need to transition to DONE WITH TOKEN */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
break;
} }
} else {
/* ReceivedUnexpectedFrame */ /* ReceivedUnexpectedFrame */
else if ((mstp_port->SilenceTimer < Treply_timeout) &&
(mstp_port->ReceivedValidFrame == true) &&
(mstp_port->DestinationAddress != mstp_port->This_Station))
/*the expected reply should not be broadcast) */
{
/* an unexpected frame was received */ /* an unexpected frame was received */
/* This may indicate the presence of multiple tokens. */ /* This may indicate the presence of multiple tokens. */
mstp_port->ReceivedValidFrame = false;
/* Synchronize with the network. */ /* Synchronize with the network. */
/* This action drops the token. */ /* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} }
/* ReceivedUnexpectedFrame */
else if ((mstp_port->SilenceTimer < Treply_timeout) &&
(mstp_port->ReceivedValidFrame == true) &&
((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) ||
/*(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || */
(mstp_port->FrameType ==
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) {
/* An unexpected frame was received. */
/* This may indicate the presence of multiple tokens. */
mstp_port->ReceivedValidFrame = false; mstp_port->ReceivedValidFrame = false;
/* Synchronize with the network. */ }
/* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} }
break; break;
/* The DONE_WITH_TOKEN state either sends another data frame, */ /* The DONE_WITH_TOKEN state either sends another data frame, */
@@ -985,16 +972,16 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* The PASS_TOKEN state listens for a successor to begin using */ /* The PASS_TOKEN state listens for a successor to begin using */
/* the token that this node has just attempted to pass. */ /* the token that this node has just attempted to pass. */
case MSTP_MASTER_STATE_PASS_TOKEN: case MSTP_MASTER_STATE_PASS_TOKEN:
if (mstp_port->SilenceTimer < Tusage_timeout) {
if (mstp_port->EventCount > Nmin_octets) {
/* SawTokenUser */ /* SawTokenUser */
if ((mstp_port->SilenceTimer < Tusage_timeout) &&
(mstp_port->EventCount > Nmin_octets)) {
/* Assume that a frame has been sent by the new token user. */ /* Assume that a frame has been sent by the new token user. */
/* Enter the IDLE state to process the frame. */ /* Enter the IDLE state to process the frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} }
} else {
if (mstp_port->RetryCount < Nretry_token) {
/* RetrySendToken */ /* RetrySendToken */
else if ((mstp_port->SilenceTimer >= Tusage_timeout) &&
(mstp_port->RetryCount < Nretry_token)) {
mstp_port->RetryCount++; mstp_port->RetryCount++;
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
@@ -1003,10 +990,8 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->EventCount = 0; mstp_port->EventCount = 0;
/* re-enter the current state to listen for NS */ /* re-enter the current state to listen for NS */
/* to begin using the token. */ /* to begin using the token. */
} } else {
/* FindNewSuccessor */ /* FindNewSuccessor */
else if ((mstp_port->SilenceTimer >= Tusage_timeout) &&
(mstp_port->RetryCount >= Nretry_token)) {
/* Assume that NS has failed. */ /* Assume that NS has failed. */
mstp_port->Poll_Station = next_next_station; mstp_port->Poll_Station = next_next_station;
/* Transmit a Poll For Master frame to PS. */ /* Transmit a Poll For Master frame to PS. */
@@ -1021,6 +1006,7 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* find a new successor to TS */ /* find a new successor to TS */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
}
break; break;
/* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater */ /* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater */
/* than Tno_token, indicating that there has been no network activity */ /* than Tno_token, indicating that there has been no network activity */
@@ -1028,17 +1014,18 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* whether or not this node may create a token. */ /* whether or not this node may create a token. */
case MSTP_MASTER_STATE_NO_TOKEN: case MSTP_MASTER_STATE_NO_TOKEN:
my_timeout = Tno_token + (Tslot * mstp_port->This_Station); my_timeout = Tno_token + (Tslot * mstp_port->This_Station);
ns_timeout = Tno_token + (Tslot * (mstp_port->This_Station + 1)); if (mstp_port->SilenceTimer < my_timeout) {
if (mstp_port->EventCount > Nmin_octets) {
/* SawFrame */ /* SawFrame */
if ((mstp_port->SilenceTimer < my_timeout) &&
(mstp_port->EventCount > Nmin_octets)) {
/* Some other node exists at a lower address. */ /* Some other node exists at a lower address. */
/* Enter the IDLE state to receive and process the incoming frame. */ /* Enter the IDLE state to receive and process the incoming frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} }
}
else {
ns_timeout = Tno_token + (Tslot * (mstp_port->This_Station + 1));
if (mstp_port->SilenceTimer < ns_timeout) {
/* GenerateToken */ /* GenerateToken */
else if ((mstp_port->SilenceTimer >= my_timeout) &&
(mstp_port->SilenceTimer < ns_timeout)) {
/* Assume that this node is the lowest numerical address */ /* Assume that this node is the lowest numerical address */
/* on the network and is empowered to create a token. */ /* on the network and is empowered to create a token. */
mstp_port->Poll_Station = next_this_station; mstp_port->Poll_Station = next_this_station;
@@ -1054,16 +1041,17 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */ /* enter the POLL_FOR_MASTER state to find a new successor to TS. */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
}
break; break;
/* In the POLL_FOR_MASTER state, the node listens for a reply to */ /* In the POLL_FOR_MASTER state, the node listens for a reply to */
/* a previously sent Poll For Master frame in order to find */ /* a previously sent Poll For Master frame in order to find */
/* a successor node. */ /* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
/* ReceivedReplyToPFM */ if (mstp_port->ReceivedValidFrame == true)
if ((mstp_port->ReceivedValidFrame == true) &&
(mstp_port->DestinationAddress == mstp_port->This_Station) &&
(mstp_port->FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER))
{ {
if ((mstp_port->DestinationAddress == mstp_port->This_Station) &&
(mstp_port->FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
/* ReceivedReplyToPFM */
mstp_port->SoleMaster = false; mstp_port->SoleMaster = false;
mstp_port->Next_Station = mstp_port->SourceAddress; mstp_port->Next_Station = mstp_port->SourceAddress;
mstp_port->EventCount = 0; mstp_port->EventCount = 0;
@@ -1074,37 +1062,30 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->Poll_Station = mstp_port->This_Station; mstp_port->Poll_Station = mstp_port->This_Station;
mstp_port->TokenCount = 0; mstp_port->TokenCount = 0;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->ReceivedValidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} }
else {
/* ReceivedUnexpectedFrame */ /* ReceivedUnexpectedFrame */
else if ((mstp_port->ReceivedValidFrame == true) &&
((mstp_port->DestinationAddress != mstp_port->This_Station) ||
(mstp_port->FrameType !=
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER))) {
/* An unexpected frame was received. */ /* An unexpected frame was received. */
/* This may indicate the presence of multiple tokens. */ /* This may indicate the presence of multiple tokens. */
mstp_port->ReceivedValidFrame = false;
/* enter the IDLE state to synchronize with the network. */ /* enter the IDLE state to synchronize with the network. */
/* This action drops the token. */ /* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} }
mstp_port->ReceivedValidFrame = false;
}
else if ((mstp_port->SilenceTimer >= Tusage_timeout) ||
(mstp_port->ReceivedInvalidFrame == true)) {
if (mstp_port->SoleMaster == true) {
/* SoleMaster */ /* SoleMaster */
else if ((mstp_port->SoleMaster == true) &&
((mstp_port->SilenceTimer >= Tusage_timeout) ||
(mstp_port->ReceivedInvalidFrame == true))) {
/* There was no valid reply to the periodic poll */ /* There was no valid reply to the periodic poll */
/* by the sole known master for other masters. */ /* by the sole known master for other masters. */
mstp_port->FrameCount = 0; mstp_port->FrameCount = 0;
/* mstp_port->TokenCount++; removed in 2004 */ /* mstp_port->TokenCount++; removed in 2004 */
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
} } else {
if (mstp_port->Next_Station != mstp_port->This_Station) {
/* DoneWithPFM */ /* DoneWithPFM */
else if ((mstp_port->SoleMaster == false) &&
(mstp_port->Next_Station != mstp_port->This_Station) &&
((mstp_port->SilenceTimer >= Tusage_timeout) ||
(mstp_port->ReceivedInvalidFrame == true))) {
/* There was no valid reply to the maintenance */ /* There was no valid reply to the maintenance */
/* poll for a master at address PS. */ /* poll for a master at address PS. */
mstp_port->EventCount = 0; mstp_port->EventCount = 0;
@@ -1113,35 +1094,29 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
FRAME_TYPE_TOKEN, FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0); mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} } else {
if (next_poll_station != mstp_port->This_Station)
{
/* SendNextPFM */ /* SendNextPFM */
else if ((mstp_port->SoleMaster == false) &&
(mstp_port->Next_Station == mstp_port->This_Station) && /* no known successor node */
(next_poll_station != mstp_port->This_Station) &&
((mstp_port->SilenceTimer >= Tusage_timeout)
|| (mstp_port->ReceivedInvalidFrame == true))) {
mstp_port->Poll_Station = next_poll_station; mstp_port->Poll_Station = next_poll_station;
/* Transmit a Poll For Master frame to PS. */ /* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port, MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER, FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0); mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->ReceivedInvalidFrame = false;
/* Re-enter the current state. */ /* Re-enter the current state. */
} } else {
/* DeclareSoleMaster */ /* DeclareSoleMaster */
else if ((mstp_port->SoleMaster == false) && (mstp_port->Next_Station == mstp_port->This_Station) && /* no known successor node */
(next_poll_station == mstp_port->This_Station)
&& ((mstp_port->SilenceTimer >= Tusage_timeout)
|| (mstp_port->ReceivedInvalidFrame == true))) {
/* to indicate that this station is the only master */ /* to indicate that this station is the only master */
mstp_port->SoleMaster = true; mstp_port->SoleMaster = true;
mstp_port->FrameCount = 0; mstp_port->FrameCount = 0;
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
} }
}
}
mstp_port->ReceivedInvalidFrame = false;
}
break; break;
/* The ANSWER_DATA_REQUEST state is entered when a */ /* The ANSWER_DATA_REQUEST state is entered when a */
/* BACnet Data Expecting Reply, a Test_Request, or */ /* BACnet Data Expecting Reply, a Test_Request, or */
-1
View File
@@ -75,7 +75,6 @@ typedef enum {
MSTP_RECEIVE_STATE_HEADER, MSTP_RECEIVE_STATE_HEADER,
MSTP_RECEIVE_STATE_HEADER_CRC, MSTP_RECEIVE_STATE_HEADER_CRC,
MSTP_RECEIVE_STATE_DATA, MSTP_RECEIVE_STATE_DATA,
MSTP_RECEIVE_STATE_DATA_CRC
} MSTP_RECEIVE_STATE; } MSTP_RECEIVE_STATE;
/* master node FSM states */ /* master node FSM states */
+6
View File
@@ -111,7 +111,13 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
void dlmstp_task(void) void dlmstp_task(void)
{ {
RS485_Check_UART_Data(&MSTP_Port); RS485_Check_UART_Data(&MSTP_Port);
/* only do receive state machine while we don't have a frame */
if ((MSTP_Port.ReceivedValidFrame == false) &&
(MSTP_Port.ReceivedInvalidFrame == false))
{
MSTP_Receive_Frame_FSM(&MSTP_Port); MSTP_Receive_Frame_FSM(&MSTP_Port);
}
/* only do master state machine while rx is idle */
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE)
MSTP_Master_Node_FSM(&MSTP_Port); MSTP_Master_Node_FSM(&MSTP_Port);
} }
+2 -4
View File
@@ -74,16 +74,14 @@ static void Init_Service_Handlers(void)
void millisecond_task(void) void millisecond_task(void)
{ {
Time ticks = 0; /* task cycle */ Time ticks = 0; /* task cycle */
const int UPDATE_CYCLE = 5; /* task cycle in mS */
int i = 0; /* loop counter */ int i = 0; /* loop counter */
ticks = RTKGetTime() + MilliSecsToTicks(UPDATE_CYCLE); ticks = RTKGetTime() + MilliSecsToTicks(1);
while (TRUE) while (TRUE)
{ {
RTKDelayUntil(ticks); RTKDelayUntil(ticks);
for (i = 0; i < UPDATE_CYCLE; i++)
dlmstp_millisecond_timer(); dlmstp_millisecond_timer();
ticks += MilliSecsToTicks(UPDATE_CYCLE); ticks += MilliSecsToTicks(1);
} }
} }
+14 -7
View File
@@ -22,7 +22,7 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#define PRINT_ENABLED_RS485 0 #define PRINT_ENABLED_RS485 1
#include <stdint.h> #include <stdint.h>
#include <rtkernel.h> #include <rtkernel.h>
@@ -132,7 +132,6 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
{ /* number of bytes of data (up to 501) */ { /* number of bytes of data (up to 501) */
bool status = true; /* return value */ bool status = true; /* return value */
(void) mstp_port;
RS485_TRANSMIT_ENABLE(RS485_Port); RS485_TRANSMIT_ENABLE(RS485_Port);
SendBlock(RS485_Port, (char *) buffer, nbytes); SendBlock(RS485_Port, (char *) buffer, nbytes);
/* need to wait at least 9600 baud * 512 bytes = 54mS */ /* need to wait at least 9600 baud * 512 bytes = 54mS */
@@ -140,6 +139,7 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY)) while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY))
RTKScheduler(); RTKScheduler();
RS485_RECEIVE_ENABLE(RS485_Port); RS485_RECEIVE_ENABLE(RS485_Port);
mstp_port->SilenceTimer = 0;
#if PRINT_ENABLED_RS485 #if PRINT_ENABLED_RS485
{ {
int i = 0; int i = 0;
@@ -162,18 +162,22 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port) void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
{ /* port specific data */ { /* port specific data */
COMData com_data = 0; /* byte from COM driver */ COMData com_data = 0; /* byte from COM driver */
unsigned timeout = 10; /* milliseconds to wait for a character */ unsigned timeout = 1; /* milliseconds to wait for a character */
Duration ticks; /* duration to wait for data */ static Duration ticks = 0; /* duration to wait for data */
if (!ticks)
{
ticks = MilliSecsToTicks(timeout);
if (!ticks)
ticks = 1;
}
if (mstp_port->ReceiveError) { if (mstp_port->ReceiveError) {
/* wait for state machine to clear this */ /* wait for state machine to clear this */
RTKDelay(ticks);
} }
/* wait for state machine to read from the DataRegister */ /* wait for state machine to read from the DataRegister */
else if (!mstp_port->DataAvailable) { else if (!mstp_port->DataAvailable) {
/* check for data */ /* check for data */
ticks = MilliSecsToTicks(timeout);
if (!ticks)
ticks = 1;
if (RTKGetTimed(ReceiveBuffer[RS485_Port], &com_data, ticks)) { if (RTKGetTimed(ReceiveBuffer[RS485_Port], &com_data, ticks)) {
/* if error, */ /* if error, */
if (com_data & (COM_OVERRUN << 8)) if (com_data & (COM_OVERRUN << 8))
@@ -186,4 +190,7 @@ void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
} }
} }
} }
else
RTKDelay(ticks);
} }