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:
skarg
2010-10-07 15:52:45 +00:00
parent 23eecbc100
commit b54218939e
7 changed files with 99 additions and 23 deletions
+13 -3
View File
@@ -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 */
+11
View File
@@ -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)) {
+29 -18
View File
@@ -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); */
}
+11
View File
@@ -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)) {
+13 -2
View File
@@ -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)) {
+11
View File
@@ -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) &&