📄 mstp.c
字号:
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) {
/* 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;
}
/* returns true if we need to transition immediately */
bool MSTP_Master_Node_FSM(
volatile struct mstp_port_struct_t * mstp_port)
{
int mtu_len = 0;
int frame_type = 0;
uint8_t next_poll_station = 0;
uint8_t next_this_station = 0;
uint8_t next_next_station = 0;
uint16_t my_timeout = 10, ns_timeout = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -