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