Added extra sub-state for MS/TP from Addendum 135-2008v. Tested with ports/bdk-atxx4-mstp/ code on the BACnet Development Kit. Clean compile on src/mstp.c, ports/at91sam7s and ports/atmega168, but untested. All other changes were not compiled or tested.
This commit is contained in:
@@ -866,9 +866,19 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* before passing the token. */
|
||||
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
transition_now = true;
|
||||
}
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
else if (TokenCount < (Npoll - 1)) {
|
||||
} else if ((MSTP_Flag.SoleMaster == false) &&
|
||||
(Next_Station == This_Station)) {
|
||||
/* NextStationUnknown - added in Addendum 135-2008v-1 */
|
||||
/* then the next station to which the token
|
||||
should be sent is unknown - so PollForMaster */
|
||||
Poll_Station = next_this_station;
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
|
||||
This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
} else if (TokenCount < (Npoll - 1)) {
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
if ((MSTP_Flag.SoleMaster == true) &&
|
||||
(Next_Station != next_this_station)) {
|
||||
/* SoleMaster */
|
||||
|
||||
@@ -783,6 +783,17 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* before passing the token. */
|
||||
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
transition_now = true;
|
||||
} else if ((MSTP_Flag.SoleMaster == false) &&
|
||||
(Next_Station == This_Station)) {
|
||||
/* NextStationUnknown - added in Addendum 135-2008v-1 */
|
||||
/* then the next station to which the token
|
||||
should be sent is unknown - so PollForMaster */
|
||||
Poll_Station = next_this_station;
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
|
||||
This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
}
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
else if (TokenCount < (Npoll - 1)) {
|
||||
|
||||
@@ -888,6 +888,17 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* before passing the token. */
|
||||
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
transition_now = true;
|
||||
} else if ((MSTP_Flag.SoleMaster == false) &&
|
||||
(Next_Station == This_Station)) {
|
||||
/* NextStationUnknown - added in Addendum 135-2008v-1 */
|
||||
/* then the next station to which the token
|
||||
should be sent is unknown - so PollForMaster */
|
||||
Poll_Station = next_this_station;
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
|
||||
This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
}
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
else if (TokenCount < (Npoll - 1)) {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "bacaddr.h"
|
||||
|
||||
/* This file has been customized for use with small microprocessors */
|
||||
/* Assumptions:
|
||||
/* Assumptions:
|
||||
Only one MS/TP datalink layer
|
||||
*/
|
||||
#include "timer.h"
|
||||
@@ -121,7 +121,7 @@ static struct mstp_flag_t {
|
||||
/* A Boolean flag set TRUE by the datalink transmit if a
|
||||
pending packet is DataExpectingReply */
|
||||
unsigned TransmitPacketDER:1;
|
||||
/* A Boolean flag set TRUE by the datalink if a
|
||||
/* A Boolean flag set TRUE by the datalink if a
|
||||
packet has been received, but not processed. */
|
||||
unsigned ReceivePacketPending:1;
|
||||
} MSTP_Flag;
|
||||
@@ -287,8 +287,8 @@ static bool dlmstp_compare_data_expecting_reply(
|
||||
uint8_t dest_address)
|
||||
{
|
||||
uint16_t offset;
|
||||
/* One way to check the message is to compare NPDU
|
||||
src, dest, along with the APDU type, invoke id.
|
||||
/* One way to check the message is to compare NPDU
|
||||
src, dest, along with the APDU type, invoke id.
|
||||
Seems a bit overkill */
|
||||
struct DER_compare_t {
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
@@ -327,7 +327,7 @@ static bool dlmstp_compare_data_expecting_reply(
|
||||
if (reply.npdu_data.network_layer_message) {
|
||||
return false;
|
||||
}
|
||||
/* reply could be a lot of things:
|
||||
/* reply could be a lot of things:
|
||||
confirmed, simple ack, abort, reject, error */
|
||||
reply.pdu_type = reply_pdu[offset] & 0xF0;
|
||||
switch (reply.pdu_type) {
|
||||
@@ -451,7 +451,7 @@ static void MSTP_Receive_Frame_FSM(
|
||||
static uint16_t DataCRC = 0;
|
||||
/* Used to accumulate the CRC on the header of a frame. */
|
||||
static uint8_t HeaderCRC = 0;
|
||||
/* Used as an index by the Receive State Machine,
|
||||
/* Used as an index by the Receive State Machine,
|
||||
up to a maximum value of the MPDU */
|
||||
static uint8_t Index = 0;
|
||||
|
||||
@@ -473,7 +473,7 @@ static void MSTP_Receive_Frame_FSM(
|
||||
}
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_PREAMBLE:
|
||||
/* In the PREAMBLE state, the node waits for the
|
||||
/* In the PREAMBLE state, the node waits for the
|
||||
second octet of the preamble. */
|
||||
if (Timer_Silence() > Tframe_abort) {
|
||||
/* Timeout */
|
||||
@@ -553,7 +553,7 @@ static void MSTP_Receive_Frame_FSM(
|
||||
} else if (Index == 5) {
|
||||
/* HeaderCRC */
|
||||
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
|
||||
/* In the HEADER_CRC state, the node validates the CRC
|
||||
/* In the HEADER_CRC state, the node validates the CRC
|
||||
on the fixed message header. */
|
||||
if (HeaderCRC != 0x55) {
|
||||
/* BadCRC */
|
||||
@@ -565,7 +565,7 @@ static void MSTP_Receive_Frame_FSM(
|
||||
} else {
|
||||
/* Note: proposed change to BACnet MSTP state machine!
|
||||
If we don't decode data that is not for us, we could
|
||||
get confused about the start if the Preamble 55 FF
|
||||
get confused about the start if the Preamble 55 FF
|
||||
is part of the data. */
|
||||
if ((DataLength) && (DataLength <= InputBufferSize)) {
|
||||
/* Data */
|
||||
@@ -580,7 +580,7 @@ static void MSTP_Receive_Frame_FSM(
|
||||
(DestinationAddress ==
|
||||
MSTP_BROADCAST_ADDRESS)) {
|
||||
/* ForUs */
|
||||
/* indicate that a frame with
|
||||
/* indicate that a frame with
|
||||
no data has been received */
|
||||
MSTP_Flag.ReceivedValidFrame = true;
|
||||
} else {
|
||||
@@ -617,7 +617,7 @@ static void MSTP_Receive_Frame_FSM(
|
||||
/* Error */
|
||||
Timer_Silence_Reset();
|
||||
INCREMENT_AND_LIMIT_UINT8(EventCount);
|
||||
/* indicate that an error has occurred during
|
||||
/* indicate that an error has occurred during
|
||||
the reception of a frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of the next frame. */
|
||||
@@ -643,7 +643,7 @@ static void MSTP_Receive_Frame_FSM(
|
||||
if ((DestinationAddress == This_Station) ||
|
||||
(DestinationAddress == MSTP_BROADCAST_ADDRESS)) {
|
||||
/* ForUs */
|
||||
/* indicate that a frame with no data
|
||||
/* indicate that a frame with no data
|
||||
has been received */
|
||||
MSTP_Flag.ReceivedValidFrame = true;
|
||||
}
|
||||
@@ -766,7 +766,7 @@ static bool MSTP_Master_Node_FSM(
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* For DATA_EXPECTING_REPLY, we will keep the Rx Frame for
|
||||
/* For DATA_EXPECTING_REPLY, we will keep the Rx Frame for
|
||||
reference, and the flag will be cleared in the next state */
|
||||
if (Master_State != MSTP_MASTER_STATE_ANSWER_DATA_REQUEST) {
|
||||
MSTP_Flag.ReceivedValidFrame = false;
|
||||
@@ -884,6 +884,17 @@ static bool MSTP_Master_Node_FSM(
|
||||
/* before passing the token. */
|
||||
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
transition_now = true;
|
||||
} else if ((MSTP_Flag.SoleMaster == false) &&
|
||||
(Next_Station == This_Station)) {
|
||||
/* NextStationUnknown - added in Addendum 135-2008v-1 */
|
||||
/* then the next station to which the token
|
||||
should be sent is unknown - so PollForMaster */
|
||||
Poll_Station = next_this_station;
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
|
||||
This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
}
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
else if (TokenCount < (Npoll - 1)) {
|
||||
@@ -1182,7 +1193,7 @@ uint16_t dlmstp_receive(
|
||||
MSTP_Receive_Frame_FSM();
|
||||
if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame)
|
||||
break;
|
||||
/* if we are not idle, then we are
|
||||
/* if we are not idle, then we are
|
||||
receiving a frame or timing out */
|
||||
if (Receive_State == MSTP_RECEIVE_STATE_IDLE)
|
||||
break;
|
||||
@@ -1214,7 +1225,7 @@ void dlmstp_set_mac_address(
|
||||
This_Station = mac_address;
|
||||
/* FIXME: implement your data storage */
|
||||
/* I2C_Write_Byte(
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
mac_address,
|
||||
EEPROM_MSTP_MAC_ADDR); */
|
||||
if (mac_address > Nmax_master)
|
||||
@@ -1243,8 +1254,8 @@ void dlmstp_set_max_info_frames(
|
||||
if (max_info_frames >= 1) {
|
||||
Nmax_info_frames = max_info_frames;
|
||||
/* FIXME: implement your data storage */
|
||||
/* I2C_Write_Byte(
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
/* I2C_Write_Byte(
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
(uint8_t)max_info_frames,
|
||||
EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */
|
||||
}
|
||||
@@ -1271,7 +1282,7 @@ void dlmstp_set_max_master(
|
||||
Nmax_master = max_master;
|
||||
/* FIXME: implement your data storage */
|
||||
/* I2C_Write_Byte(
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
max_master,
|
||||
EEPROM_MSTP_MAX_MASTER_ADDR); */
|
||||
}
|
||||
|
||||
@@ -799,6 +799,17 @@ bool MSTP_Master_Node_FSM(
|
||||
/* before passing the token. */
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
transition_now = true;
|
||||
} else if ((MSTP_Flag.SoleMaster == false) &&
|
||||
(Next_Station == This_Station)) {
|
||||
/* NextStationUnknown - added in Addendum 135-2008v-1 */
|
||||
/* then the next station to which the token
|
||||
should be sent is unknown - so PollForMaster */
|
||||
Poll_Station = next_this_station;
|
||||
MSTP_Send_Frame(
|
||||
FRAME_TYPE_POLL_FOR_MASTER, Poll_Station,
|
||||
This_Station, NULL, 0);
|
||||
RetryCount = 0;
|
||||
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
}
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
else if (mstp_port->TokenCount < (Npoll - 1)) {
|
||||
|
||||
@@ -474,7 +474,7 @@ void MSTP_Receive_Frame_FSM(
|
||||
}
|
||||
/* NoData */
|
||||
else if (mstp_port->DataLength == 0) {
|
||||
/* CHEAT: it is very difficult to respond to
|
||||
/* 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 ==
|
||||
@@ -784,7 +784,7 @@ bool MSTP_Master_Node_FSM(
|
||||
case FRAME_TYPE_POLL_FOR_MASTER:
|
||||
/* CHEAT: we cheat a little and this is really handled in the
|
||||
receive state machine since it is difficult to respond
|
||||
quick enough (i.e. faster than Tusage_timeout of the
|
||||
quick enough (i.e. faster than Tusage_timeout of the
|
||||
other node which could be 20ms). */
|
||||
MSTP_Create_And_Send_Frame(mstp_port,
|
||||
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
|
||||
@@ -938,6 +938,17 @@ bool MSTP_Master_Node_FSM(
|
||||
/* then this node may send another information frame */
|
||||
/* before passing the token. */
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
} else if ((mstp_port->SoleMaster == false) &&
|
||||
(mstp_port->Next_Station == mstp_port->This_Station)) {
|
||||
/* NextStationUnknown - added in Addendum 135-2008v-1 */
|
||||
/* then the next station to which the token
|
||||
should be sent is unknown - so PollForMaster */
|
||||
mstp_port->Poll_Station = next_this_station;
|
||||
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->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
}
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
else if (mstp_port->TokenCount < (Npoll - 1)) {
|
||||
|
||||
@@ -795,6 +795,17 @@ bool MSTP_Master_Node_FSM(
|
||||
/* before passing the token. */
|
||||
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
||||
transition_now = true;
|
||||
} else if ((mstp_port->SoleMaster == false) &&
|
||||
(mstp_port->Next_Station == mstp_port->This_Station)) {
|
||||
/* NextStationUnknown - added in Addendum 135-2008v-1 */
|
||||
/* then the next station to which the token
|
||||
should be sent is unknown - so PollForMaster */
|
||||
mstp_port->Poll_Station = next_this_station;
|
||||
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->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||
} else if (mstp_port->TokenCount < (Npoll - 1)) {
|
||||
/* Npoll changed in Errata SSPC-135-2004 */
|
||||
if ((mstp_port->SoleMaster == true) &&
|
||||
|
||||
Reference in New Issue
Block a user