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
+205 -230
View File
@@ -56,7 +56,8 @@
/* debug print statements */
#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 */
/* All frames are of the following format: */
@@ -249,9 +250,6 @@ char *mstp_receive_state_text(int state)
case MSTP_RECEIVE_STATE_DATA:
text = "DATA";
break;
case MSTP_RECEIVE_STATE_DATA_CRC:
text = "CRC";
break;
default:
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)
{
#if PRINT_ENABLED_MASTER
static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE;
#endif
#if PRINT_ENABLED_RECEIVE
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),
@@ -272,6 +274,16 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->DataLength,
mstp_port->SilenceTimer);
#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) {
/* 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) {
/* DataOctet */
if (mstp_port->Index < mstp_port->DataLength) {
mstp_port->SilenceTimer = 0;
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
mstp_port->InputBuffer[mstp_port->Index] =
mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
}
/* CRC1 */
else if (mstp_port->Index == mstp_port->DataLength) {
mstp_port->SilenceTimer = 0;
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
mstp_port->DataAvailable = false;
mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
}
/* CRC2 */
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);
mstp_port->DataAvailable = false;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA_CRC;
/* STATE DATA CRC - no need for new state */
/* indicate the complete reception of a valid frame */
if (mstp_port->DataCRC == 0xF0B8)
mstp_port->ReceivedValidFrame = true;
else
mstp_port->ReceivedInvalidFrame = true;
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
}
}
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 */
mstp_port->ReceivedValidFrame = true;
/* the master node state machine will receive
and validate the message */
/* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
}
/* BadCRC */
else {
/* 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;
mstp_port->DataAvailable = false;
mstp_port->SilenceTimer = 0;
}
break;
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;
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;
}
@@ -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_next_station = 0;
uint16_t my_timeout = 10, ns_timeout = 0;
#if PRINT_ENABLED_MASTER
static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE;
#endif
/* 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) {
#if PRINT_ENABLED_MASTER
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->DestinationAddress,
mstp_port->DataLength,
mstp_port->FrameCount,
mstp_port->SilenceTimer,
mstp_frame_type_text(mstp_port->FrameType));
#endif
/* 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 */
/* a reply from another node. */
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
/* ReplyTimeout */
if (mstp_port->SilenceTimer >= Treply_timeout) {
/* ReplyTimeout */
/* assume that the request has failed */
mstp_port->FrameCount = mstp_port->Nmax_info_frames;
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, */
/* this transition will cause the token to be passed regardless */
/* of the initial value of FrameCount.) */
}
/* InvalidFrame */
else if ((mstp_port->SilenceTimer < Treply_timeout) &&
(mstp_port->ReceivedInvalidFrame == true)) {
/* error in frame reception */
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
}
/* ReceivedReply */
/* 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 */
dlmstp_put_receive(
mstp_port->SourceAddress, /* source MS/TP address */
(uint8_t *) & mstp_port->InputBuffer[0],
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;
}
/* 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 */
/* This may indicate the presence of multiple tokens. */
mstp_port->ReceivedValidFrame = false;
/* Synchronize with the network. */
/* This action drops the token. */
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;
/* Synchronize with the network. */
/* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} else {
if (mstp_port->ReceivedInvalidFrame == true) {
/* InvalidFrame */
/* error in frame reception */
mstp_port->ReceivedInvalidFrame = false;
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 */
/* or a proprietary type that indicates a reply */
/* indicate successful reception to the higher layers */
dlmstp_put_receive(
mstp_port->SourceAddress, /* source MS/TP address */
(uint8_t *) & mstp_port->InputBuffer[0],
mstp_port->DataLength);
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 */
/* an unexpected frame was received */
/* This may indicate the presence of multiple tokens. */
/* Synchronize with the network. */
/* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
}
mstp_port->ReceivedValidFrame = false;
}
}
break;
/* The DONE_WITH_TOKEN state either sends another data frame, */
@@ -985,41 +972,40 @@ 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 token that this node has just attempted to pass. */
case MSTP_MASTER_STATE_PASS_TOKEN:
/* SawTokenUser */
if ((mstp_port->SilenceTimer < Tusage_timeout) &&
(mstp_port->EventCount > Nmin_octets)) {
/* Assume that a frame has been sent by the new token user. */
/* Enter the IDLE state to process the frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
}
/* RetrySendToken */
else if ((mstp_port->SilenceTimer >= Tusage_timeout) &&
(mstp_port->RetryCount < Nretry_token)) {
mstp_port->RetryCount++;
/* Transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
mstp_port->EventCount = 0;
/* re-enter the current state to listen for NS */
/* to begin using the token. */
}
/* FindNewSuccessor */
else if ((mstp_port->SilenceTimer >= Tusage_timeout) &&
(mstp_port->RetryCount >= Nretry_token)) {
/* Assume that NS has failed. */
mstp_port->Poll_Station = next_next_station;
/* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
/* no known successor node */
mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
/* find a new successor to TS */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
if (mstp_port->SilenceTimer < Tusage_timeout) {
if (mstp_port->EventCount > Nmin_octets) {
/* SawTokenUser */
/* Assume that a frame has been sent by the new token user. */
/* Enter the IDLE state to process the frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
}
} else {
if (mstp_port->RetryCount < Nretry_token) {
/* RetrySendToken */
mstp_port->RetryCount++;
/* Transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
mstp_port->EventCount = 0;
/* re-enter the current state to listen for NS */
/* to begin using the token. */
} else {
/* FindNewSuccessor */
/* Assume that NS has failed. */
mstp_port->Poll_Station = next_next_station;
/* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
/* no known successor node */
mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
/* find a new successor to TS */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
}
}
break;
/* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater */
@@ -1028,119 +1014,108 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
/* whether or not this node may create a token. */
case MSTP_MASTER_STATE_NO_TOKEN:
my_timeout = Tno_token + (Tslot * mstp_port->This_Station);
ns_timeout = Tno_token + (Tslot * (mstp_port->This_Station + 1));
/* SawFrame */
if ((mstp_port->SilenceTimer < my_timeout) &&
(mstp_port->EventCount > Nmin_octets)) {
/* Some other node exists at a lower address. */
/* Enter the IDLE state to receive and process the incoming frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
if (mstp_port->SilenceTimer < my_timeout) {
if (mstp_port->EventCount > Nmin_octets) {
/* SawFrame */
/* Some other node exists at a lower address. */
/* Enter the IDLE state to receive and process the incoming frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
}
}
/* GenerateToken */
else if ((mstp_port->SilenceTimer >= my_timeout) &&
(mstp_port->SilenceTimer < ns_timeout)) {
/* Assume that this node is the lowest numerical address */
/* on the network and is empowered to create a token. */
mstp_port->Poll_Station = next_this_station;
/* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
/* indicate that the next station is unknown */
mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed Addendum 135-2004d-8 */
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
else {
ns_timeout = Tno_token + (Tslot * (mstp_port->This_Station + 1));
if (mstp_port->SilenceTimer < ns_timeout) {
/* GenerateToken */
/* Assume that this node is the lowest numerical address */
/* on the network and is empowered to create a token. */
mstp_port->Poll_Station = next_this_station;
/* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
/* indicate that the next station is unknown */
mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed Addendum 135-2004d-8 */
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
}
}
break;
/* 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 successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
/* ReceivedReplyToPFM */
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->ReceivedValidFrame == true)
{
mstp_port->SoleMaster = false;
mstp_port->Next_Station = mstp_port->SourceAddress;
mstp_port->EventCount = 0;
/* Transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
mstp_port->Poll_Station = mstp_port->This_Station;
mstp_port->TokenCount = 0;
mstp_port->RetryCount = 0;
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->Next_Station = mstp_port->SourceAddress;
mstp_port->EventCount = 0;
/* Transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
mstp_port->Poll_Station = mstp_port->This_Station;
mstp_port->TokenCount = 0;
mstp_port->RetryCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
}
else {
/* ReceivedUnexpectedFrame */
/* An unexpected frame was received. */
/* This may indicate the presence of multiple tokens. */
/* enter the IDLE state to synchronize with the network. */
/* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
}
mstp_port->ReceivedValidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
}
/* 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. */
/* This may indicate the presence of multiple tokens. */
mstp_port->ReceivedValidFrame = false;
/* enter the IDLE state to synchronize with the network. */
/* This action drops the token. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
}
/* 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 */
/* by the sole known master for other masters. */
mstp_port->FrameCount = 0;
/* mstp_port->TokenCount++; removed in 2004 */
else if ((mstp_port->SilenceTimer >= Tusage_timeout) ||
(mstp_port->ReceivedInvalidFrame == true)) {
if (mstp_port->SoleMaster == true) {
/* SoleMaster */
/* There was no valid reply to the periodic poll */
/* by the sole known master for other masters. */
mstp_port->FrameCount = 0;
/* mstp_port->TokenCount++; removed in 2004 */
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
} else {
if (mstp_port->Next_Station != mstp_port->This_Station) {
/* DoneWithPFM */
/* There was no valid reply to the maintenance */
/* poll for a master at address PS. */
mstp_port->EventCount = 0;
/* transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} else {
if (next_poll_station != mstp_port->This_Station)
{
/* SendNextPFM */
mstp_port->Poll_Station = next_poll_station;
/* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0;
/* Re-enter the current state. */
} else {
/* DeclareSoleMaster */
/* to indicate that this station is the only master */
mstp_port->SoleMaster = true;
mstp_port->FrameCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
}
}
}
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
}
/* 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 */
/* poll for a master at address PS. */
mstp_port->EventCount = 0;
/* transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_TOKEN,
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0;
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
}
/* 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;
/* Transmit a Poll For Master frame to PS. */
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_POLL_FOR_MASTER,
mstp_port->Poll_Station, mstp_port->This_Station, NULL, 0);
mstp_port->RetryCount = 0;
mstp_port->ReceivedInvalidFrame = false;
/* Re-enter the current state. */
}
/* 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 */
mstp_port->SoleMaster = true;
mstp_port->FrameCount = 0;
mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
}
break;
/* The ANSWER_DATA_REQUEST state is entered when a */
-1
View File
@@ -75,7 +75,6 @@ typedef enum {
MSTP_RECEIVE_STATE_HEADER,
MSTP_RECEIVE_STATE_HEADER_CRC,
MSTP_RECEIVE_STATE_DATA,
MSTP_RECEIVE_STATE_DATA_CRC
} MSTP_RECEIVE_STATE;
/* master node FSM states */
+8 -2
View File
@@ -109,9 +109,15 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
}
void dlmstp_task(void)
{
{
RS485_Check_UART_Data(&MSTP_Port);
MSTP_Receive_Frame_FSM(&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);
}
/* only do master state machine while rx is idle */
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE)
MSTP_Master_Node_FSM(&MSTP_Port);
}
+3 -5
View File
@@ -74,16 +74,14 @@ static void Init_Service_Handlers(void)
void millisecond_task(void)
{
Time ticks = 0; /* task cycle */
const int UPDATE_CYCLE = 5; /* task cycle in mS */
int i = 0; /* loop counter */
ticks = RTKGetTime() + MilliSecsToTicks(UPDATE_CYCLE);
ticks = RTKGetTime() + MilliSecsToTicks(1);
while (TRUE)
{
RTKDelayUntil(ticks);
for (i = 0; i < UPDATE_CYCLE; i++)
dlmstp_millisecond_timer();
ticks += MilliSecsToTicks(UPDATE_CYCLE);
dlmstp_millisecond_timer();
ticks += MilliSecsToTicks(1);
}
}
+14 -7
View File
@@ -22,7 +22,7 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#define PRINT_ENABLED_RS485 0
#define PRINT_ENABLED_RS485 1
#include <stdint.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) */
bool status = true; /* return value */
(void) mstp_port;
RS485_TRANSMIT_ENABLE(RS485_Port);
SendBlock(RS485_Port, (char *) buffer, nbytes);
/* 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))
RTKScheduler();
RS485_RECEIVE_ENABLE(RS485_Port);
mstp_port->SilenceTimer = 0;
#if PRINT_ENABLED_RS485
{
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)
{ /* port specific data */
COMData com_data = 0; /* byte from COM driver */
unsigned timeout = 10; /* milliseconds to wait for a character */
Duration ticks; /* duration to wait for data */
unsigned timeout = 1; /* milliseconds to wait for a character */
static Duration ticks = 0; /* duration to wait for data */
if (!ticks)
{
ticks = MilliSecsToTicks(timeout);
if (!ticks)
ticks = 1;
}
if (mstp_port->ReceiveError) {
/* wait for state machine to clear this */
RTKDelay(ticks);
}
/* wait for state machine to read from the DataRegister */
else if (!mstp_port->DataAvailable) {
/* check for data */
ticks = MilliSecsToTicks(timeout);
if (!ticks)
ticks = 1;
if (RTKGetTimed(ReceiveBuffer[RS485_Port], &com_data, ticks)) {
/* if error, */
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);
}