📄 mstp.c
字号:
break;
/* In the PREAMBLE state, the node waits for the second octet of the preamble. */
case MSTP_RECEIVE_STATE_PREAMBLE:
/* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) {
/* a correct preamble has not been received */
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
}
/* Error */
else if (mstp_port->ReceiveError == true) {
mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
} else if (mstp_port->DataAvailable == true) {
#if PRINT_ENABLED_RECEIVE_DATA
fprintf(stderr, "%02X ", mstp_port->DataRegister);
#endif
/* Preamble2 */
if (mstp_port->DataRegister == 0xFF) {
mstp_port->DataAvailable = false;
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->Index = 0;
mstp_port->HeaderCRC = 0xFF;
/* receive the remainder of the frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
}
/* ignore RepeatedPreamble1 */
else if (mstp_port->DataRegister == 0x55) {
mstp_port->DataAvailable = false;
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
/* wait for the second preamble octet. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE;
}
/* NotPreamble */
else {
mstp_port->DataAvailable = false;
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
}
}
break;
/* In the HEADER state, the node waits for the fixed message header. */
case MSTP_RECEIVE_STATE_HEADER:
/* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) {
/* indicate that an error has occurred during the reception of a frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
}
/* Error */
else if (mstp_port->ReceiveError == true) {
mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
/* indicate that an error has occurred during the reception of a frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
} else if (mstp_port->DataAvailable == true) {
#if PRINT_ENABLED_RECEIVE_DATA
fprintf(stderr, "%02X ", mstp_port->DataRegister);
#endif
/* FrameType */
if (mstp_port->Index == 0) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->FrameType = mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 1;
mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
}
/* Destination */
else if (mstp_port->Index == 1) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->DestinationAddress = mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 2;
mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
}
/* Source */
else if (mstp_port->Index == 2) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->SourceAddress = mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 3;
mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
}
/* Length1 */
else if (mstp_port->Index == 3) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->DataLength = mstp_port->DataRegister * 256;
mstp_port->DataAvailable = false;
mstp_port->Index = 4;
mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
}
/* Length2 */
else if (mstp_port->Index == 4) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->DataLength += mstp_port->DataRegister;
mstp_port->DataAvailable = false;
mstp_port->Index = 5;
mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER;
}
/* HeaderCRC */
else if (mstp_port->Index == 5) {
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC =
CRC_Calc_Header(mstp_port->DataRegister,
mstp_port->HeaderCRC);
mstp_port->DataAvailable = false;
/* don't wait for next state - do it here */
/* MSTP_RECEIVE_STATE_HEADER_CRC */
if (mstp_port->HeaderCRC != 0x55) {
/* BadCRC */
/* 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;
} else {
if ((mstp_port->DestinationAddress ==
mstp_port->This_Station)
|| (mstp_port->DestinationAddress ==
MSTP_BROADCAST_ADDRESS)) {
/* FrameTooLong */
if (mstp_port->DataLength > MAX_MPDU) {
/* indicate that a frame with an illegal or */
/* unacceptable data length has been received */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */
mstp_port->receive_state =
MSTP_RECEIVE_STATE_IDLE;
}
/* NoData */
else if (mstp_port->DataLength == 0) {
/* CHEAT: it is very difficult to respond to
poll for master in the Master Node state machine
before Tusage_timeout, so we will do it here. */
if ((mstp_port->FrameType ==
FRAME_TYPE_POLL_FOR_MASTER)
&& (mstp_port->DestinationAddress ==
mstp_port->This_Station)
&& (mstp_port->master_state ==
MSTP_MASTER_STATE_IDLE)) {
MSTP_Create_And_Send_Frame(mstp_port,
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
mstp_port->SourceAddress,
mstp_port->This_Station, NULL, 0);
/* don't indicate that a frame has been received */
mstp_port->ReceivedInvalidFrame = false;
mstp_port->ReceivedValidFrame = false;
} else {
/* indicate that a frame with no data has been received */
mstp_port->ReceivedValidFrame = true;
}
/* wait for the start of the next frame. */
mstp_port->receive_state =
MSTP_RECEIVE_STATE_IDLE;
}
/* Data */
else {
mstp_port->Index = 0;
mstp_port->DataCRC = 0xFFFF;
/* receive the data portion of the frame. */
mstp_port->receive_state =
MSTP_RECEIVE_STATE_DATA;
}
}
/* NotForUs */
else {
/* wait for the start of the next frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
}
}
}
/* not per MS/TP standard, but it is a case not covered */
else {
mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
/* indicate that an error has occurred during */
/* the reception of a frame */
mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
}
}
break;
/* In the HEADER_CRC state, the node validates the CRC on the fixed */
/* message header. */
case MSTP_RECEIVE_STATE_HEADER_CRC:
break;
/* In the DATA state, the node waits for the data portion of a frame. */
case MSTP_RECEIVE_STATE_DATA:
/* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) {
/* 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;
}
/* Error */
else if (mstp_port->ReceiveError == true) {
mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0;
/* 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;
} else if (mstp_port->DataAvailable == true) {
#if PRINT_ENABLED_RECEIVE_DATA
fprintf(stderr, "%02X ", mstp_port->DataRegister);
#endif
/* DataOctet */
if (mstp_port->Index < mstp_port->DataLength) {
mstp_port->DataCRC =
CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
mstp_port->InputBuffer[mstp_port->Index] =
mstp_port->DataRegister;
mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
}
/* CRC1 */
else if (mstp_port->Index == mstp_port->DataLength) {
mstp_port->DataCRC =
CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
}
/* CRC2 */
else if (mstp_port->Index == (mstp_port->DataLength + 1)) {
mstp_port->DataCRC =
CRC_Calc_Data(mstp_port->DataRegister,
mstp_port->DataCRC);
/* 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;
}
mstp_port->DataAvailable = false;
mstp_port->SilenceTimer = 0;
}
break;
default:
/* shouldn't get here - but if we do... */
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, "\n");
fflush(stderr);
}
receive_state = mstp_port->receive_state;
#endif
return;
}
#if PRINT_ENABLED
char *mstp_master_state_text(
int state)
{
char *text = "unknown";
switch (state) {
case MSTP_MASTER_STATE_INITIALIZE:
text = "INITIALIZE";
break;
case MSTP_MASTER_STATE_IDLE:
text = "IDLE";
break;
case MSTP_MASTER_STATE_USE_TOKEN:
text = "USE_TOKEN";
break;
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
text = "WAIT_FOR_REPLY";
break;
case MSTP_MASTER_STATE_DONE_WITH_TOKEN:
text = "IDLE";
break;
case MSTP_MASTER_STATE_PASS_TOKEN:
text = "DONE_WITH_TOKEN";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -