Reverted the 135-2008v MS/TP changes, since they were not done correctly.

This commit is contained in:
skarg
2010-06-28 00:45:27 +00:00
parent 6f9ba36967
commit 99ec130371
5 changed files with 177 additions and 251 deletions
+31 -42
View File
@@ -1,6 +1,6 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2007-2010 Steve Karg
Copyright (C) 2007 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -159,13 +159,13 @@ static uint8_t This_Station;
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
static uint8_t Nmax_info_frames = 1;
static uint8_t Nmax_info_frames;
/* This parameter represents the value of the Max_Master property of the */
/* node's Device object. The value of Max_Master specifies the highest */
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
static uint8_t Nmax_master = 127;
static uint8_t Nmax_master;
/* An array of octets, used to store octets for transmitting */
/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */
/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */
@@ -191,7 +191,7 @@ static uint8_t TransmitPacketDest;
/* node must wait for a remote node to begin using a token or replying to */
/* a Poll For Master frame: 20 milliseconds. (Implementations may use */
/* larger values for this timeout, not to exceed 100 milliseconds.) */
#define Tusage_timeout 60
#define Tusage_timeout 25
/* The number of tokens received or used before a Poll For Master cycle */
/* is executed: 50. */
@@ -241,7 +241,7 @@ static uint8_t TransmitPacketDest;
bool dlmstp_init(
char *ifname)
{
ifname = ifname;
(void) ifname;
/* initialize hardware */
RS485_Initialize();
@@ -403,8 +403,8 @@ static void MSTP_Send_Frame(
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * pdu, /* any data to be sent - may be null */
uint16_t pdu_len)
uint8_t * data, /* any data to be sent - may be null */
uint16_t data_len)
{ /* number of bytes of data (up to 501) */
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
@@ -420,24 +420,24 @@ static void MSTP_Send_Frame(
crc8 = CRC_Calc_Header(buffer[3], crc8);
buffer[4] = source;
crc8 = CRC_Calc_Header(buffer[4], crc8);
buffer[5] = HI_BYTE(pdu_len);
buffer[5] = HI_BYTE(data_len);
crc8 = CRC_Calc_Header(buffer[5], crc8);
buffer[6] = LO_BYTE(pdu_len);
buffer[6] = LO_BYTE(data_len);
crc8 = CRC_Calc_Header(buffer[6], crc8);
buffer[7] = ~crc8;
RS485_Turnaround_Delay();
RS485_Transmitter_Enable(true);
RS485_Send_Data(buffer, 8);
/* send any data */
if (pdu_len) {
if (data_len) {
/* calculate CRC for any data */
for (i = 0; i < pdu_len; i++) {
crc16 = CRC_Calc_Data(pdu[i], crc16);
for (i = 0; i < data_len; i++) {
crc16 = CRC_Calc_Data(data[i], crc16);
}
crc16 = ~crc16;
buffer[0] = (crc16 & 0x00FF);
buffer[1] = ((crc16 & 0xFF00) >> 8);
RS485_Send_Data(pdu, pdu_len);
RS485_Send_Data(data, data_len);
RS485_Send_Data(buffer, 2);
}
RS485_Transmitter_Enable(false);
@@ -704,11 +704,8 @@ static bool MSTP_Master_Node_FSM(
bool transition_now = false;
/* some calculations that several states need */
/* (PS+1) modulo (Nmax_master+1) */
next_poll_station = (Poll_Station + 1) % (Nmax_master + 1);
/* (TS+1) modulo (Nmax_master+1) */
next_this_station = (This_Station + 1) % (Nmax_master + 1);
/* (NS +1) modulo (Nmax_master+1) */
next_next_station = (Next_Station + 1) % (Nmax_master + 1);
switch (Master_State) {
case MSTP_MASTER_STATE_INITIALIZE:
@@ -905,7 +902,8 @@ static bool MSTP_Master_Node_FSM(
}
/* Npoll changed in Errata SSPC-135-2004 */
else if (TokenCount < (Npoll - 1)) {
if (MSTP_Flag.SoleMaster == true) {
if ((MSTP_Flag.SoleMaster == true) &&
(Next_Station != next_this_station)) {
/* SoleMaster */
/* there are no other known master nodes to */
/* which the token may be sent
@@ -915,30 +913,21 @@ static bool MSTP_Master_Node_FSM(
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true;
} else {
if (Next_Station == This_Station) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
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 (Next_Station == next_this_station) {
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1
eliminates the Poll For Master
if there are no addresses between
TS and NS, since there is no
address at which a new master node
may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1
eliminates the Poll For Master
if there are no addresses between
TS and NS, since there is no
address at which a new master node
may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
} else if (next_poll_station == Next_Station) {
if (MSTP_Flag.SoleMaster == true) {
@@ -1012,7 +1001,7 @@ static bool MSTP_Master_Node_FSM(
}
}
break;
/* The NO_TOKEN state is entered if Silence Timer
/* The NO_TOKEN state is entered if Timer_Silence()
becomes greater than Tno_token, indicating that
there has been no network activity for that period
of time. The timeout is continued to determine
+35 -60
View File
@@ -162,13 +162,13 @@ static uint8_t This_Station;
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
static uint8_t Nmax_info_frames = 1;
static uint8_t Nmax_info_frames;
/* This parameter represents the value of the Max_Master property of the */
/* node's Device object. The value of Max_Master specifies the highest */
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
static uint8_t Nmax_master = 127;
static uint8_t Nmax_master;
/* An array of octets, used to store octets for transmitting */
/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */
/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */
@@ -188,13 +188,13 @@ static uint8_t TransmitPacketDest;
/* that a node must wait for a station to begin replying to a */
/* confirmed request: 255 milliseconds. (Implementations may use */
/* larger values for this timeout, not to exceed 300 milliseconds.) */
#define Treply_timeout 260
#define Treply_timeout 295
/* The minimum time without a DataAvailable or ReceiveError event that a */
/* node must wait for a remote node to begin using a token or replying to */
/* a Poll For Master frame: 20 milliseconds. (Implementations may use */
/* larger values for this timeout, not to exceed 100 milliseconds.) */
#define Tusage_timeout 60
#define Tusage_timeout 95
/* The number of tokens received or used before a Poll For Master cycle */
/* is executed: 50. */
@@ -219,11 +219,6 @@ static uint8_t TransmitPacketDest;
/* of a frame the node is transmitting: 20 bit times. */
#define Tframe_gap 20
/* The maximum time after the end of the stop bit of the final */
/* octet of a transmitted frame before a node must disable its */
/* EIA-485 driver: 15 bit times. */
#define Tpostdrive 15
/* The maximum time a node may wait after reception of a frame that expects */
/* a reply before sending the first octet of a reply or Reply Postponed */
/* frame: 250 milliseconds. */
@@ -593,9 +588,9 @@ static bool MSTP_Master_Node_FSM(
/* When this counter reaches the value Nmax_info_frames, the node must */
/* pass the token. */
static uint8_t FrameCount;
/* "Next Station," the MAC address of the node to which This Station
passes the token. If the Next_Station is unknown, Next_Station shall
be equal to This_Station. */
/* "Next Station," the MAC address of the node to which This Station passes */
/* the token. If the Next_Station is unknown, Next_Station shall be equal to */
/* This_Station. */
static uint8_t Next_Station;
/* "Poll Station," the MAC address of the node to which This Station last */
/* sent a Poll For Master. This is used during token maintenance. */
@@ -603,10 +598,10 @@ static bool MSTP_Master_Node_FSM(
/* A counter of transmission retries used for Token and Poll For Master */
/* transmission. */
static unsigned RetryCount;
/* The number of tokens received by this node. When this counter reaches */
/* the value Npoll, the node polls the address range between TS and NS */
/* for additional master nodes. TokenCount is set to zero at the end of */
/* the polling process. */
/* The number of tokens received by this node. When this counter reaches the */
/* value Npoll, the node polls the address range between TS and NS for */
/* additional master nodes. TokenCount is set to zero at the end of the */
/* polling process. */
static unsigned TokenCount;
/* next-x-station calculations */
uint8_t next_poll_station = 0;
@@ -618,11 +613,8 @@ static bool MSTP_Master_Node_FSM(
bool transition_now = false;
/* some calculations that several states need */
/* (PS+1) modulo (Nmax_master+1) */
next_poll_station = (Poll_Station + 1) % (Nmax_master + 1);
/* (TS+1) modulo (Nmax_master+1) */
next_this_station = (This_Station + 1) % (Nmax_master + 1);
/* (NS +1) modulo (Nmax_master+1) */
next_next_station = (Next_Station + 1) % (Nmax_master + 1);
switch (Master_State) {
case MSTP_MASTER_STATE_INITIALIZE:
@@ -677,7 +669,7 @@ static bool MSTP_Master_Node_FSM(
MSTP_Flag.ReceivePacketPending = true;
break;
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
/* indicate successful reception to higher layers */
/* indicate successful reception to the higher layers */
MSTP_Flag.ReceivePacketPending = true;
/* broadcast DER just remains IDLE */
if (DestinationAddress != MSTP_BROADCAST_ADDRESS) {
@@ -730,10 +722,8 @@ static bool MSTP_Master_Node_FSM(
FrameCount = Nmax_info_frames;
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
/* Any retry of the data frame shall await the next entry */
/* to the USE_TOKEN state. */
/* (Because of the length of the timeout, */
/* this transition will cause the token to be */
/* passed regardless */
/* 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.) */
transition_now = true;
} else {
@@ -757,10 +747,8 @@ static bool MSTP_Master_Node_FSM(
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 */
/* or a proprietary type that indicates a reply */
/* indicate successful reception to the higher layers */
MSTP_Flag.ReceivePacketPending = true;
Master_State =
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
@@ -798,40 +786,28 @@ static bool MSTP_Master_Node_FSM(
}
/* Npoll changed in Errata SSPC-135-2004 */
else if (TokenCount < (Npoll - 1)) {
if (MSTP_Flag.SoleMaster == true) {
if ((MSTP_Flag.SoleMaster == true) &&
(Next_Station != next_this_station)) {
/* SoleMaster */
/* there are no other known master nodes to */
/* which the token may be sent
(true master-slave operation). */
/* which the token may be sent (true master-slave operation). */
FrameCount = 0;
TokenCount++;
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true;
} else {
if (Next_Station == This_Station) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
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 (Next_Station == next_this_station) {
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1
eliminates the Poll For Master
if there are no addresses between
TS and NS, since there is no
address at which a new master node
may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */
/* if there are no addresses between TS and NS, since there is no */
/* address at which a new master node may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
} else if (next_poll_station == Next_Station) {
if (MSTP_Flag.SoleMaster == true) {
@@ -904,11 +880,10 @@ static bool MSTP_Master_Node_FSM(
}
}
break;
/* The NO_TOKEN state is entered if Silence Timer
becomes greater than Tno_token, indicating that
there has been no network activity for that period
of time. The timeout is continued to determine
whether or not this node may create a token. */
/* The NO_TOKEN state is entered if Timer_Silence() becomes greater */
/* than Tno_token, indicating that there has been no network activity */
/* for that period of time. The timeout is continued to determine */
/* whether or not this node may create a token. */
case MSTP_MASTER_STATE_NO_TOKEN:
my_timeout = Tno_token + (Tslot * This_Station);
if (Timer_Silence() < my_timeout) {
+26 -37
View File
@@ -1,6 +1,6 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2009-2010 Steve Karg
Copyright (C) 2009 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -407,8 +407,8 @@ static void MSTP_Send_Frame(
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * pdu, /* any data to be sent - may be null */
uint16_t pdu_len)
uint8_t * data, /* any data to be sent - may be null */
uint16_t data_len)
{ /* number of bytes of data (up to 501) */
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
@@ -424,24 +424,24 @@ static void MSTP_Send_Frame(
crc8 = CRC_Calc_Header(buffer[3], crc8);
buffer[4] = source;
crc8 = CRC_Calc_Header(buffer[4], crc8);
buffer[5] = HI_BYTE(pdu_len);
buffer[5] = HI_BYTE(data_len);
crc8 = CRC_Calc_Header(buffer[5], crc8);
buffer[6] = LO_BYTE(pdu_len);
buffer[6] = LO_BYTE(data_len);
crc8 = CRC_Calc_Header(buffer[6], crc8);
buffer[7] = ~crc8;
rs485_turnaround_delay();
rs485_rts_enable(true);
rs485_bytes_send(buffer, 8);
/* send any data */
if (pdu_len) {
if (data_len) {
/* calculate CRC for any data */
for (i = 0; i < pdu_len; i++) {
crc16 = CRC_Calc_Data(pdu[i], crc16);
for (i = 0; i < data_len; i++) {
crc16 = CRC_Calc_Data(data[i], crc16);
}
crc16 = ~crc16;
buffer[0] = (crc16 & 0x00FF);
buffer[1] = ((crc16 & 0xFF00) >> 8);
rs485_bytes_send(pdu, pdu_len);
rs485_bytes_send(data, data_len);
rs485_bytes_send(buffer, 2);
}
rs485_rts_enable(false);
@@ -724,11 +724,8 @@ static bool MSTP_Master_Node_FSM(
bool transition_now = false;
/* some calculations that several states need */
/* (PS+1) modulo (Nmax_master+1) */
next_poll_station = (Poll_Station + 1) % (Nmax_master + 1);
/* (TS+1) modulo (Nmax_master+1) */
next_this_station = (This_Station + 1) % (Nmax_master + 1);
/* (NS +1) modulo (Nmax_master+1) */
next_next_station = (Next_Station + 1) % (Nmax_master + 1);
log_master_state(Master_State);
switch (Master_State) {
@@ -926,7 +923,8 @@ static bool MSTP_Master_Node_FSM(
}
/* Npoll changed in Errata SSPC-135-2004 */
else if (TokenCount < (Npoll - 1)) {
if (MSTP_Flag.SoleMaster == true) {
if ((MSTP_Flag.SoleMaster == true) &&
(Next_Station != next_this_station)) {
/* SoleMaster */
/* there are no other known master nodes to */
/* which the token may be sent
@@ -936,30 +934,21 @@ static bool MSTP_Master_Node_FSM(
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true;
} else {
if (Next_Station == This_Station) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
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 (Next_Station == next_this_station) {
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1
eliminates the Poll For Master
if there are no addresses between
TS and NS, since there is no
address at which a new master node
may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1
eliminates the Poll For Master
if there are no addresses between
TS and NS, since there is no
address at which a new master node
may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
} else if (next_poll_station == Next_Station) {
if (MSTP_Flag.SoleMaster == true) {
+56 -70
View File
@@ -143,7 +143,7 @@ static uint8_t FrameType;
and microcontroller architectures have limits as to places to
hold contiguous memory. */
static uint8_t *InputBuffer;
static uint16_t InputBufferSize;
static uint8_t InputBufferSize;
/* Used to store the Source Address of a received frame. */
static uint8_t SourceAddress;
/* "This Station," the MAC address of this node. TS is generally read from a */
@@ -158,13 +158,13 @@ static uint8_t This_Station;
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
static uint8_t Nmax_info_frames = 1;
static uint8_t Nmax_info_frames;
/* This parameter represents the value of the Max_Master property of the */
/* node's Device object. The value of Max_Master specifies the highest */
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
static uint8_t Nmax_master = 127;
static uint8_t Nmax_master;
/* An array of octets, used to store octets for transmitting */
/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */
/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */
@@ -190,7 +190,7 @@ static uint8_t TransmitPacketDest;
/* node must wait for a remote node to begin using a token or replying to */
/* a Poll For Master frame: 20 milliseconds. (Implementations may use */
/* larger values for this timeout, not to exceed 100 milliseconds.) */
#define Tusage_timeout 60
#define Tusage_timeout 25
/* The number of tokens received or used before a Poll For Master cycle */
/* is executed: 50. */
@@ -402,8 +402,8 @@ static void MSTP_Send_Frame(
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * pdu, /* any data to be sent - may be null */
uint16_t pdu_len)
uint8_t * data, /* any data to be sent - may be null */
uint16_t data_len)
{ /* number of bytes of data (up to 501) */
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
@@ -419,24 +419,24 @@ static void MSTP_Send_Frame(
crc8 = CRC_Calc_Header(buffer[3], crc8);
buffer[4] = source;
crc8 = CRC_Calc_Header(buffer[4], crc8);
buffer[5] = HI_BYTE(pdu_len);
buffer[5] = HI_BYTE(data_len);
crc8 = CRC_Calc_Header(buffer[5], crc8);
buffer[6] = LO_BYTE(pdu_len);
buffer[6] = LO_BYTE(data_len);
crc8 = CRC_Calc_Header(buffer[6], crc8);
buffer[7] = ~crc8;
RS485_Turnaround_Delay();
RS485_Transmitter_Enable(true);
RS485_Send_Data(buffer, 8);
/* send any data */
if (pdu_len) {
if (data_len) {
/* calculate CRC for any data */
for (i = 0; i < pdu_len; i++) {
crc16 = CRC_Calc_Data(pdu[i], crc16);
for (i = 0; i < data_len; i++) {
crc16 = CRC_Calc_Data(data[i], crc16);
}
crc16 = ~crc16;
buffer[0] = (crc16 & 0x00FF);
buffer[1] = ((crc16 & 0xFF00) >> 8);
RS485_Send_Data(pdu, pdu_len);
RS485_Send_Data(data, data_len);
RS485_Send_Data(buffer, 2);
}
RS485_Transmitter_Enable(false);
@@ -453,7 +453,7 @@ static void MSTP_Receive_Frame_FSM(
static uint8_t HeaderCRC = 0;
/* Used as an index by the Receive State Machine,
up to a maximum value of the MPDU */
static uint16_t Index = 0;
static uint8_t Index = 0;
switch (Receive_State) {
case MSTP_RECEIVE_STATE_IDLE:
@@ -609,8 +609,7 @@ static void MSTP_Receive_Frame_FSM(
/* In the DATA state, the node waits for the data portion of a frame. */
if (Timer_Silence() > Tframe_abort) {
/* Timeout */
/* indicate that an error has occurred
during the reception of a frame */
/* indicate that an error has occurred during the reception of a frame */
MSTP_Flag.ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */
Receive_State = MSTP_RECEIVE_STATE_IDLE;
@@ -672,9 +671,9 @@ static bool MSTP_Master_Node_FSM(
/* When this counter reaches the value Nmax_info_frames, the node must */
/* pass the token. */
static uint8_t FrameCount;
/* "Next Station," the MAC address of the node to which This Station
passes the token. If the Next_Station is unknown, Next_Station shall
be equal to This_Station. */
/* "Next Station," the MAC address of the node to which This Station passes */
/* the token. If the Next_Station is unknown, Next_Station shall be equal to */
/* This_Station. */
static uint8_t Next_Station;
/* "Poll Station," the MAC address of the node to which This Station last */
/* sent a Poll For Master. This is used during token maintenance. */
@@ -682,10 +681,10 @@ static bool MSTP_Master_Node_FSM(
/* A counter of transmission retries used for Token and Poll For Master */
/* transmission. */
static unsigned RetryCount;
/* The number of tokens received by this node. When this counter reaches */
/* the value Npoll, the node polls the address range between TS and NS */
/* for additional master nodes. TokenCount is set to zero at the end of */
/* the polling process. */
/* The number of tokens received by this node. When this counter reaches the */
/* value Npoll, the node polls the address range between TS and NS for */
/* additional master nodes. TokenCount is set to zero at the end of the */
/* polling process. */
static unsigned TokenCount;
/* next-x-station calculations */
uint8_t next_poll_station = 0;
@@ -693,16 +692,13 @@ static bool MSTP_Master_Node_FSM(
uint8_t next_next_station = 0;
/* timeout values */
uint16_t my_timeout = 10, ns_timeout = 0;
bool matched = false;
bool matched;
/* transition immediately to the next state */
bool transition_now = false;
/* some calculations that several states need */
/* (PS+1) modulo (Nmax_master+1) */
next_poll_station = (Poll_Station + 1) % (Nmax_master + 1);
/* (TS+1) modulo (Nmax_master+1) */
next_this_station = (This_Station + 1) % (Nmax_master + 1);
/* (NS +1) modulo (Nmax_master+1) */
next_next_station = (Next_Station + 1) % (Nmax_master + 1);
switch (Master_State) {
case MSTP_MASTER_STATE_INITIALIZE:
@@ -753,7 +749,7 @@ static bool MSTP_Master_Node_FSM(
MSTP_Flag.ReceivePacketPending = true;
break;
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
/* indicate successful reception to higher layers */
/* indicate successful reception to the higher layers */
MSTP_Flag.ReceivePacketPending = true;
/* broadcast DER just remains IDLE */
if (DestinationAddress != MSTP_BROADCAST_ADDRESS) {
@@ -827,10 +823,8 @@ static bool MSTP_Master_Node_FSM(
FrameCount = Nmax_info_frames;
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
/* Any retry of the data frame shall await the next entry */
/* to the USE_TOKEN state. */
/* (Because of the length of the timeout, */
/* this transition will cause the token to be */
/* passed regardless */
/* 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.) */
transition_now = true;
} else {
@@ -854,10 +848,8 @@ static bool MSTP_Master_Node_FSM(
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 */
/* or a proprietary type that indicates a reply */
/* indicate successful reception to the higher layers */
MSTP_Flag.ReceivePacketPending = true;
Master_State =
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
@@ -895,40 +887,28 @@ static bool MSTP_Master_Node_FSM(
}
/* Npoll changed in Errata SSPC-135-2004 */
else if (TokenCount < (Npoll - 1)) {
if (MSTP_Flag.SoleMaster == true) {
if ((MSTP_Flag.SoleMaster == true) &&
(Next_Station != next_this_station)) {
/* SoleMaster */
/* there are no other known master nodes to */
/* which the token may be sent
(true master-slave operation). */
/* which the token may be sent (true master-slave operation). */
FrameCount = 0;
TokenCount++;
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true;
} else {
if (Next_Station == This_Station) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
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 (Next_Station == next_this_station) {
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1
eliminates the Poll For Master
if there are no addresses between
TS and NS, since there is no
address at which a new master node
may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */
/* if there are no addresses between TS and NS, since there is no */
/* address at which a new master node may be found in that case. */
TokenCount++;
/* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station,
This_Station, NULL, 0);
RetryCount = 0;
EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
}
} else if (next_poll_station == Next_Station) {
if (MSTP_Flag.SoleMaster == true) {
@@ -1001,11 +981,10 @@ static bool MSTP_Master_Node_FSM(
}
}
break;
/* The NO_TOKEN state is entered if Silence Timer
becomes greater than Tno_token, indicating that
there has been no network activity for that period
of time. The timeout is continued to determine
whether or not this node may create a token. */
/* The NO_TOKEN state is entered if Timer_Silence() becomes greater */
/* than Tno_token, indicating that there has been no network activity */
/* for that period of time. The timeout is continued to determine */
/* whether or not this node may create a token. */
case MSTP_MASTER_STATE_NO_TOKEN:
my_timeout = Tno_token + (Tslot * This_Station);
if (Timer_Silence() < my_timeout) {
@@ -1096,8 +1075,7 @@ static bool MSTP_Master_Node_FSM(
/* Re-enter the current state. */
} else {
/* DeclareSoleMaster */
/* to indicate that this station
is the only master */
/* to indicate that this station is the only master */
MSTP_Flag.SoleMaster = true;
FrameCount = 0;
Master_State = MSTP_MASTER_STATE_USE_TOKEN;
@@ -1200,7 +1178,15 @@ uint16_t dlmstp_receive(
/* only do receive state machine while we don't have a frame */
if ((MSTP_Flag.ReceivedValidFrame == false) &&
(MSTP_Flag.ReceivedInvalidFrame == false)) {
MSTP_Receive_Frame_FSM();
for (;;) {
MSTP_Receive_Frame_FSM();
if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame)
break;
/* if we are not idle, then we are
receiving a frame or timing out */
if (Receive_State == MSTP_RECEIVE_STATE_IDLE)
break;
}
}
/* only do master state machine while rx is idle */
if (Receive_State == MSTP_RECEIVE_STATE_IDLE) {
+16 -29
View File
@@ -1,6 +1,6 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2003-2010 Steve Karg
Copyright (C) 2003-2007 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -585,13 +585,10 @@ bool MSTP_Master_Node_FSM(
static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE;
/* some calculations that several states need */
/* (PS+1) modulo (Nmax_master+1) */
next_poll_station =
(mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1);
/* (TS+1) modulo (Nmax_master+1) */
next_this_station =
(mstp_port->This_Station + 1) % (mstp_port->Nmax_master + 1);
/* (NS +1) modulo (Nmax_master+1) */
next_next_station =
(mstp_port->Next_Station + 1) % (mstp_port->Nmax_master + 1);
if (mstp_port->master_state != master_state) {
@@ -819,7 +816,8 @@ bool MSTP_Master_Node_FSM(
transition_now = true;
} else if (mstp_port->TokenCount < (Npoll - 1)) {
/* Npoll changed in Errata SSPC-135-2004 */
if (mstp_port->SoleMaster == true) {
if ((mstp_port->SoleMaster == true) &&
(mstp_port->Next_Station != next_this_station)) {
/* SoleMaster */
/* there are no other known master nodes to */
/* which the token may be sent (true master-slave operation). */
@@ -828,30 +826,19 @@ bool MSTP_Master_Node_FSM(
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
transition_now = true;
} else {
if (mstp_port->Next_Station == mstp_port->This_Station) {
/* NextStationUnknown - added in Addendum 135-2008v-1 */
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->Next_Station == next_this_station) {
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */
/* if there are no addresses between TS and NS, since there is no */
/* address at which a new master node may be found in that case. */
mstp_port->TokenCount++;
/* 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->EventCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
}
/* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */
/* if there are no addresses between TS and NS, since there is no */
/* address at which a new master node may be found in that case. */
mstp_port->TokenCount++;
/* 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->EventCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
}
} else if (next_poll_station == mstp_port->Next_Station) {
if (mstp_port->SoleMaster == true) {