Finally got MS/TP communicating on ports/rtos32. I still need to verify that it is doing things correctly since it seems a little slow to respond to service requests. Still more work to do refactoring the state machine.
This commit is contained in:
+216
-249
@@ -72,7 +72,7 @@
|
|||||||
/* least significant octet first */
|
/* least significant octet first */
|
||||||
/* (pad): (optional) at most one octet of padding: X'FF' */
|
/* (pad): (optional) at most one octet of padding: X'FF' */
|
||||||
|
|
||||||
/* 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. */
|
||||||
const unsigned Npoll = 50;
|
const unsigned Npoll = 50;
|
||||||
|
|
||||||
@@ -88,7 +88,8 @@ const uint8_t Nmin_octets = 4;
|
|||||||
/* (Implementations may use larger values for this timeout, */
|
/* (Implementations may use larger values for this timeout, */
|
||||||
/* not to exceed 100 milliseconds.) */
|
/* not to exceed 100 milliseconds.) */
|
||||||
/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */
|
/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */
|
||||||
const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600);
|
/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */
|
||||||
|
const uint16_t Tframe_abort = 100;
|
||||||
|
|
||||||
/* The maximum idle time a sending node may allow to elapse between octets */
|
/* The maximum idle time a sending node may allow to elapse between octets */
|
||||||
/* of a frame the node is transmitting: 20 bit times. */
|
/* of a frame the node is transmitting: 20 bit times. */
|
||||||
@@ -132,12 +133,18 @@ const uint16_t Tusage_delay = 15;
|
|||||||
/* 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.) */
|
||||||
const uint16_t Tusage_timeout = 20;
|
const uint16_t Tusage_timeout = 50;
|
||||||
|
|
||||||
/* we need to be able to increment without rolling over */
|
/* we need to be able to increment without rolling over */
|
||||||
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;}
|
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;}
|
||||||
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
|
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
|
||||||
|
|
||||||
|
|
||||||
|
bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port)
|
||||||
|
{
|
||||||
|
return (mstp_port->EventCount > Nmin_octets);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
||||||
unsigned buffer_len, /* amount of space available */
|
unsigned buffer_len, /* amount of space available */
|
||||||
uint8_t frame_type, /* type of frame to send - see defines */
|
uint8_t frame_type, /* type of frame to send - see defines */
|
||||||
@@ -523,7 +530,7 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
|
mstp_port->DataCRC = CRC_Calc_Data(mstp_port->DataRegister,
|
||||||
mstp_port->DataCRC);
|
mstp_port->DataCRC);
|
||||||
mstp_port->DataAvailable = false;
|
mstp_port->DataAvailable = false;
|
||||||
mstp_port->Index++; /* Index now becomes the number of data octets */
|
mstp_port->Index++;
|
||||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
|
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
|
||||||
}
|
}
|
||||||
/* CRC2 */
|
/* CRC2 */
|
||||||
@@ -542,10 +549,8 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
if (mstp_port->DataCRC == 0xF0B8) {
|
if (mstp_port->DataCRC == 0xF0B8) {
|
||||||
/* indicate the complete reception of a valid frame */
|
/* indicate the complete reception of a valid frame */
|
||||||
mstp_port->ReceivedValidFrame = true;
|
mstp_port->ReceivedValidFrame = true;
|
||||||
|
/* the master node state machine will receive
|
||||||
/* now might be a good time to process the message or */
|
and validate the message */
|
||||||
/* copy the data to a buffer so that we can process the message */
|
|
||||||
|
|
||||||
/* wait for the start of the next frame. */
|
/* wait for the start of the next frame. */
|
||||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||||
}
|
}
|
||||||
@@ -566,19 +571,7 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mstp_put_receive(volatile struct mstp_port_struct_t
|
#if PRINT_ENABLED
|
||||||
*mstp_port)
|
|
||||||
{
|
|
||||||
if (mstp_port)
|
|
||||||
{
|
|
||||||
dlmstp_put_receive(
|
|
||||||
mstp_port->SourceAddress, /* source MS/TP address */
|
|
||||||
(uint8_t *) & mstp_port->InputBuffer[0],
|
|
||||||
mstp_port->Index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PRINT_ENABLED_MASTER
|
|
||||||
char *mstp_master_state_text(int state)
|
char *mstp_master_state_text(int state)
|
||||||
{
|
{
|
||||||
char *text = "unknown";
|
char *text = "unknown";
|
||||||
@@ -667,29 +660,36 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
int mtu_len = 0;
|
int mtu_len = 0;
|
||||||
int frame_type = 0;
|
int frame_type = 0;
|
||||||
uint8_t next_poll_station = 0;
|
uint8_t next_poll_station = 0;
|
||||||
uint8_t next_poll_neighbor = 0;
|
uint8_t next_this_station = 0;
|
||||||
uint8_t next_station = 0;
|
uint8_t next_next_station = 0;
|
||||||
|
uint16_t my_timeout = 10, ns_timeout = 0;
|
||||||
|
static MSTP_MASTER_STATE master_state = MSTP_MASTER_STATE_INITIALIZE;
|
||||||
|
|
||||||
|
|
||||||
/* some calculations that several states need */
|
/* some calculations that several states need */
|
||||||
next_poll_station = (mstp_port->Poll_Station + 1) %
|
next_poll_station = (mstp_port->Poll_Station + 1) %
|
||||||
(mstp_port->Nmax_master + 1);
|
(mstp_port->Nmax_master + 1);
|
||||||
next_poll_neighbor = (mstp_port->This_Station + 1) %
|
next_this_station = (mstp_port->This_Station + 1) %
|
||||||
(mstp_port->Nmax_master + 1);
|
(mstp_port->Nmax_master + 1);
|
||||||
next_station = (mstp_port->Next_Station + 1) %
|
next_next_station = (mstp_port->Next_Station + 1) %
|
||||||
(mstp_port->Nmax_master + 1);
|
(mstp_port->Nmax_master + 1);
|
||||||
#if PRINT_ENABLED_MASTER
|
#if PRINT_ENABLED_MASTER
|
||||||
fprintf(stderr,"MSTP: State=%s TS=%u NS=%u PS=%u EC=%u TC=%u Silence=%u\r\n",
|
if (mstp_port->master_state != master_state)
|
||||||
mstp_master_state_text(mstp_port->master_state),
|
{
|
||||||
mstp_port->This_Station,
|
master_state = mstp_port->master_state;
|
||||||
mstp_port->Next_Station,
|
fprintf(stderr,
|
||||||
mstp_port->Poll_Station,
|
"MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u %s\r\n",
|
||||||
mstp_port->EventCount,
|
mstp_port->This_Station,
|
||||||
mstp_port->TokenCount,
|
next_this_station,
|
||||||
mstp_port->SilenceTimer);
|
mstp_port->Next_Station,
|
||||||
fprintf(stderr,"MSTP: NextPollStation=%u NextPollNeighbor=%u NextStation=%u\r\n",
|
next_next_station,
|
||||||
next_poll_station,
|
mstp_port->Poll_Station,
|
||||||
next_poll_neighbor,
|
next_poll_station,
|
||||||
next_station);
|
mstp_port->EventCount,
|
||||||
|
mstp_port->TokenCount,
|
||||||
|
mstp_port->SilenceTimer,
|
||||||
|
mstp_master_state_text(mstp_port->master_state));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (mstp_port->master_state) {
|
switch (mstp_port->master_state) {
|
||||||
@@ -718,119 +718,75 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
else if (mstp_port->ReceivedInvalidFrame == true) {
|
else if (mstp_port->ReceivedInvalidFrame == true) {
|
||||||
/* invalid frame was received */
|
/* invalid frame was received */
|
||||||
mstp_port->ReceivedInvalidFrame = false;
|
mstp_port->ReceivedInvalidFrame = false;
|
||||||
/* wait for the next frame */
|
/* wait for the next frame - remain in IDLE */
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
|
||||||
}
|
}
|
||||||
else if (mstp_port->ReceivedValidFrame == true) {
|
else if (mstp_port->ReceivedValidFrame == true) {
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED_MASTER
|
||||||
fprintf(stderr,"MSTP: ReceivedValidFrame Type=%s Dest=%02X\r\n",
|
fprintf(stderr,
|
||||||
mstp_frame_type_text(mstp_port->FrameType),
|
"MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u Type=%s\r\n",
|
||||||
mstp_port->DestinationAddress);
|
mstp_port->SourceAddress,
|
||||||
|
mstp_port->DestinationAddress,
|
||||||
|
mstp_port->DataLength,
|
||||||
|
mstp_port->FrameCount,
|
||||||
|
mstp_frame_type_text(mstp_port->FrameType));
|
||||||
#endif
|
#endif
|
||||||
/* ReceivedUnwantedFrame - not for me */
|
/* destined for me! */
|
||||||
if (!((mstp_port->DestinationAddress == mstp_port->This_Station)
|
if ((mstp_port->DestinationAddress ==
|
||||||
|| (mstp_port->DestinationAddress ==
|
mstp_port->This_Station) ||
|
||||||
MSTP_BROADCAST_ADDRESS))) {
|
(mstp_port->DestinationAddress ==
|
||||||
/* an unexpected or unwanted frame was received. */
|
MSTP_BROADCAST_ADDRESS)) {
|
||||||
mstp_port->ReceivedValidFrame = false;
|
switch (mstp_port->FrameType)
|
||||||
/* wait for the next frame */
|
{
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
/* ReceivedToken */
|
||||||
}
|
case FRAME_TYPE_TOKEN:
|
||||||
/* ReceivedUnwantedFrame - broadcast TOKEN or TEST_REQUEST */
|
/* tokens can't be broadcast */
|
||||||
/* DestinationAddress is equal to 255 (broadcast) and */
|
if (mstp_port->DestinationAddress ==
|
||||||
/* FrameType has a value of Token, BACnet Data Expecting Reply, Test_Request, */
|
MSTP_BROADCAST_ADDRESS)
|
||||||
/* or a proprietary type known to this node that expects a reply */
|
break;
|
||||||
/* (such frames may not be broadcast), or */
|
mstp_port->ReceivedValidFrame = false;
|
||||||
else if ((mstp_port->DestinationAddress ==
|
mstp_port->FrameCount = 0;
|
||||||
MSTP_BROADCAST_ADDRESS)
|
mstp_port->SoleMaster = false;
|
||||||
&& ((mstp_port->FrameType == FRAME_TYPE_TOKEN)
|
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
||||||
/* removed in Add-2004-135b-PR1 - see BroadcastDataNeedingReply
|
break;
|
||||||
|| (mstp_port->FrameType ==
|
/* ReceivedPFM */
|
||||||
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) */
|
case FRAME_TYPE_POLL_FOR_MASTER:
|
||||||
|| (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST))) {
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
/* an unexpected or unwanted frame was received. */
|
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
|
||||||
mstp_port->ReceivedValidFrame = false;
|
mstp_port->SourceAddress, mstp_port->This_Station,
|
||||||
/* wait for the next frame */
|
NULL, 0);
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
break;
|
||||||
}
|
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
|
||||||
/* ReceivedUnwantedFrame - PROPRIETARY unknown to me */
|
/* indicate successful reception to the higher layers */
|
||||||
/* FrameType has a value that indicates a standard or proprietary type */
|
dlmstp_put_receive(
|
||||||
/* that is not known to this node. */
|
mstp_port->SourceAddress,
|
||||||
/* FIXME: change this if you add a proprietary type */
|
(uint8_t *) & mstp_port->InputBuffer[0],
|
||||||
else if /*( */ (mstp_port->FrameType >=
|
mstp_port->DataLength);
|
||||||
FRAME_TYPE_PROPRIETARY_MIN) { /*&& */
|
break;
|
||||||
/*(FrameType <= FRAME_TYPE_PROPRIETARY_MAX)) */
|
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||||
/* unnecessary if FrameType is uint8_t with max of 255 */
|
mstp_port->ReplyPostponedTimer = 0;
|
||||||
/* an unexpected or unwanted frame was received. */
|
/* indicate successful reception to the higher layers */
|
||||||
mstp_port->ReceivedValidFrame = false;
|
dlmstp_put_receive(
|
||||||
/* wait for the next frame */
|
mstp_port->SourceAddress, /* source MS/TP address */
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
(uint8_t *) & mstp_port->InputBuffer[0],
|
||||||
}
|
mstp_port->DataLength);
|
||||||
/* ReceivedToken */
|
/* broadcast DER just remains IDLE */
|
||||||
else if ((mstp_port->DestinationAddress ==
|
if (mstp_port->DestinationAddress !=
|
||||||
mstp_port->This_Station)
|
MSTP_BROADCAST_ADDRESS)
|
||||||
&& (mstp_port->FrameType == FRAME_TYPE_TOKEN)) {
|
mstp_port->master_state =
|
||||||
mstp_port->ReceivedValidFrame = false;
|
MSTP_MASTER_STATE_ANSWER_DATA_REQUEST;
|
||||||
mstp_port->FrameCount = 0;
|
break;
|
||||||
mstp_port->SoleMaster = false;
|
case FRAME_TYPE_TEST_REQUEST:
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
}
|
FRAME_TYPE_TEST_RESPONSE,
|
||||||
/* ReceivedPFM */
|
mstp_port->SourceAddress, mstp_port->This_Station,
|
||||||
else if ((mstp_port->DestinationAddress ==
|
NULL, 0);
|
||||||
mstp_port->This_Station)
|
break;
|
||||||
&& (mstp_port->FrameType == FRAME_TYPE_POLL_FOR_MASTER)) {
|
case FRAME_TYPE_TEST_RESPONSE:
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
default:
|
||||||
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
|
break;
|
||||||
mstp_port->SourceAddress, mstp_port->This_Station,
|
}
|
||||||
NULL, 0);
|
|
||||||
mstp_port->ReceivedValidFrame = false;
|
|
||||||
/* wait for the next frame */
|
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
|
||||||
}
|
|
||||||
/* ReceivedDataNoReply */
|
|
||||||
/* or a proprietary type known to this node that does not expect a reply */
|
|
||||||
else if (((mstp_port->DestinationAddress ==
|
|
||||||
mstp_port->This_Station)
|
|
||||||
|| (mstp_port->DestinationAddress ==
|
|
||||||
MSTP_BROADCAST_ADDRESS))
|
|
||||||
&& ((mstp_port->FrameType ==
|
|
||||||
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY) ||
|
|
||||||
/* (mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || */
|
|
||||||
(mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE))) {
|
|
||||||
/* indicate successful reception to the higher layers */
|
|
||||||
mstp_put_receive(mstp_port);
|
|
||||||
mstp_port->ReceivedValidFrame = false;
|
|
||||||
/* wait for the next frame */
|
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
|
||||||
}
|
|
||||||
/* ReceivedDataNeedingReply */
|
|
||||||
/* or a proprietary type known to this node that expects a reply */
|
|
||||||
else if ((mstp_port->DestinationAddress ==
|
|
||||||
mstp_port->This_Station)
|
|
||||||
&& ((mstp_port->FrameType ==
|
|
||||||
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) ||
|
|
||||||
/* (mstp_port->FrameType == FRAME_TYPE_PROPRIETARY) || */
|
|
||||||
(mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST))) {
|
|
||||||
mstp_port->ReplyPostponedTimer = 0;
|
|
||||||
/* indicate successful reception to the higher layers */
|
|
||||||
/* (management entity in the case of Test_Request); */
|
|
||||||
mstp_put_receive(mstp_port);
|
|
||||||
mstp_port->ReceivedValidFrame = false;
|
|
||||||
mstp_port->master_state =
|
|
||||||
MSTP_MASTER_STATE_ANSWER_DATA_REQUEST;
|
|
||||||
}
|
|
||||||
/* BroadcastDataNeedingReply */
|
|
||||||
else if ((mstp_port->DestinationAddress ==
|
|
||||||
MSTP_BROADCAST_ADDRESS)
|
|
||||||
&& (mstp_port->FrameType ==
|
|
||||||
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY))
|
|
||||||
{
|
|
||||||
/* indicate successful reception to the higher layers */
|
|
||||||
mstp_put_receive(mstp_port);
|
|
||||||
mstp_port->ReceivedValidFrame = false;
|
|
||||||
/* wait for the next frame */
|
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
|
||||||
}
|
}
|
||||||
|
mstp_port->ReceivedValidFrame = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* In the USE_TOKEN state, the node is allowed to send one or */
|
/* In the USE_TOKEN state, the node is allowed to send one or */
|
||||||
@@ -850,31 +806,31 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
mstp_port,
|
mstp_port,
|
||||||
(uint8_t *) &mstp_port->TxBuffer[0],
|
(uint8_t *) &mstp_port->TxBuffer[0],
|
||||||
mstp_port->TxLength);
|
mstp_port->TxLength);
|
||||||
mstp_port->TxReady = false;
|
|
||||||
mstp_port->FrameCount++;
|
mstp_port->FrameCount++;
|
||||||
/* SendNoWait */
|
switch (mstp_port->TxFrameType)
|
||||||
/* There is a frame awaiting transmission that */
|
|
||||||
/* is of type Test_Response, BACnet Data Not Expecting Reply, */
|
|
||||||
/* or a proprietary type that does not expect a reply, */
|
|
||||||
if ((mstp_port->TxFrameType == FRAME_TYPE_TEST_RESPONSE) ||
|
|
||||||
(mstp_port->TxFrameType == FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY) ||
|
|
||||||
((mstp_port->TxFrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) &&
|
|
||||||
(destination == MSTP_BROADCAST_ADDRESS)))
|
|
||||||
{
|
{
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
/* SendAndWait */
|
||||||
}
|
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||||
/* SendAndWait */
|
if (destination == MSTP_BROADCAST_ADDRESS)
|
||||||
/* If there is a frame awaiting transmission that is of */
|
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||||
/* type Test_Request, BACnet Data Expecting Reply, or */
|
else
|
||||||
/* a proprietary type that expects a reply, */
|
mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY;
|
||||||
else if ((mstp_port->TxFrameType == FRAME_TYPE_TEST_REQUEST) ||
|
break;
|
||||||
(mstp_port->TxFrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY))
|
case FRAME_TYPE_TEST_REQUEST:
|
||||||
{
|
mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY;
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY;
|
break;
|
||||||
|
/* SendNoWait */
|
||||||
|
case FRAME_TYPE_TEST_RESPONSE:
|
||||||
|
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
|
||||||
|
default:
|
||||||
|
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
mstp_port->TxReady = false;
|
||||||
}
|
}
|
||||||
/* In the WAIT_FOR_REPLY state, the node waits for */
|
break;
|
||||||
/* a reply from another node. */
|
/* In the WAIT_FOR_REPLY state, the node waits for */
|
||||||
|
/* a reply from another node. */
|
||||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||||
/* ReplyTimeout */
|
/* ReplyTimeout */
|
||||||
if (mstp_port->SilenceTimer >= Treply_timeout) {
|
if (mstp_port->SilenceTimer >= Treply_timeout) {
|
||||||
@@ -903,7 +859,10 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
(mstp_port->FrameType ==
|
(mstp_port->FrameType ==
|
||||||
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) {
|
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) {
|
||||||
/* indicate successful reception to the higher layers */
|
/* indicate successful reception to the higher layers */
|
||||||
mstp_put_receive(mstp_port);
|
dlmstp_put_receive(
|
||||||
|
mstp_port->SourceAddress, /* source MS/TP address */
|
||||||
|
(uint8_t *) & mstp_port->InputBuffer[0],
|
||||||
|
mstp_port->DataLength);
|
||||||
mstp_port->ReceivedValidFrame = false;
|
mstp_port->ReceivedValidFrame = false;
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||||
}
|
}
|
||||||
@@ -954,81 +913,75 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* before passing the token. */
|
/* before passing the token. */
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
||||||
}
|
}
|
||||||
/* SoleMaster */
|
/* Npoll changed in Errata SSPC-135-2004 */
|
||||||
else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) &&
|
else if (mstp_port->TokenCount < (Npoll-1))
|
||||||
/* Npoll changed in Errata SSPC-135-2004 */
|
{
|
||||||
(mstp_port->TokenCount < (Npoll-1)) &&
|
if ((mstp_port->SoleMaster == true) &&
|
||||||
(mstp_port->SoleMaster == true)) {
|
(mstp_port->Next_Station != next_this_station)) {
|
||||||
/* there are no other known master nodes to */
|
/* SoleMaster */
|
||||||
/* which the token may be sent (true master-slave operation). */
|
/* there are no other known master nodes to */
|
||||||
mstp_port->FrameCount = 0;
|
/* which the token may be sent (true master-slave operation). */
|
||||||
mstp_port->TokenCount++;
|
mstp_port->FrameCount = 0;
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
mstp_port->TokenCount++;
|
||||||
|
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* 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 */
|
else if (next_poll_station == mstp_port->Next_Station) {
|
||||||
else if (((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) &&
|
if (mstp_port->SoleMaster == true) {
|
||||||
/* Npoll changed in Errata SSPC-135-2004 */
|
/* SoleMasterRestartMaintenancePFM */
|
||||||
(mstp_port->TokenCount < (Npoll-1)) &&
|
mstp_port->Poll_Station = next_poll_station;
|
||||||
(mstp_port->SoleMaster == false)) ||
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
/* The comparison of NS and TS+1 eliminates the Poll For Master */
|
FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station,
|
||||||
/* if there are no addresses between TS and NS, since there is no */
|
mstp_port->This_Station, NULL, 0);
|
||||||
/* address at which a new master node may be found in that case. */
|
/* no known successor node */
|
||||||
(mstp_port->Next_Station == next_poll_neighbor)) {
|
mstp_port->Next_Station = mstp_port->This_Station;
|
||||||
mstp_port->TokenCount++;
|
mstp_port->RetryCount = 0;
|
||||||
/* transmit a Token frame to NS */
|
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
|
||||||
FRAME_TYPE_TOKEN,
|
/* find a new successor to TS */
|
||||||
mstp_port->Next_Station, mstp_port->This_Station, NULL, 0);
|
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||||
mstp_port->RetryCount = 0;
|
}
|
||||||
mstp_port->EventCount = 0;
|
else {
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
|
/* ResetMaintenancePFM */
|
||||||
|
mstp_port->Poll_Station = mstp_port->This_Station;
|
||||||
|
/* 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->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
||||||
|
mstp_port->EventCount = 0;
|
||||||
|
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* SendMaintenancePFM */
|
else {
|
||||||
else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) &&
|
/* SendMaintenancePFM */
|
||||||
/* Npoll changed in Errata SSPC-135-2004 */
|
|
||||||
(mstp_port->TokenCount >= (Npoll-1)) &&
|
|
||||||
(next_poll_station != mstp_port->Next_Station)) {
|
|
||||||
mstp_port->Poll_Station = next_poll_station;
|
mstp_port->Poll_Station = next_poll_station;
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station,
|
FRAME_TYPE_POLL_FOR_MASTER,
|
||||||
|
mstp_port->Poll_Station,
|
||||||
mstp_port->This_Station, NULL, 0);
|
mstp_port->This_Station, NULL, 0);
|
||||||
mstp_port->RetryCount = 0;
|
mstp_port->RetryCount = 0;
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
||||||
}
|
}
|
||||||
/* ResetMaintenancePFM */
|
break;
|
||||||
else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) &&
|
|
||||||
/* Npoll changed in Errata SSPC-135-2004 */
|
|
||||||
(mstp_port->TokenCount >= (Npoll-1)) &&
|
|
||||||
(next_poll_station == mstp_port->Next_Station)
|
|
||||||
&& (mstp_port->SoleMaster == false)) {
|
|
||||||
mstp_port->Poll_Station = mstp_port->This_Station;
|
|
||||||
/* 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->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
|
||||||
mstp_port->EventCount = 0;
|
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
|
|
||||||
}
|
|
||||||
/* SoleMasterRestartMaintenancePFM */
|
|
||||||
else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) &&
|
|
||||||
/* Npoll changed in Errata SSPC-135-2004 */
|
|
||||||
(mstp_port->TokenCount >= (Npoll-1)) &&
|
|
||||||
(next_poll_station == mstp_port->Next_Station)
|
|
||||||
&& (mstp_port->SoleMaster == true)) {
|
|
||||||
mstp_port->Poll_Station = next_poll_station;
|
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
|
||||||
FRAME_TYPE_POLL_FOR_MASTER, mstp_port->Poll_Station,
|
|
||||||
mstp_port->This_Station, NULL, 0);
|
|
||||||
/* no known successor node */
|
|
||||||
mstp_port->Next_Station = mstp_port->This_Station;
|
|
||||||
mstp_port->RetryCount = 0;
|
|
||||||
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */
|
|
||||||
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */
|
|
||||||
/* find a new successor to TS */
|
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
|
|
||||||
}
|
|
||||||
/* The PASS_TOKEN state listens for a successor to begin using */
|
/* The PASS_TOKEN state listens for a successor to begin using */
|
||||||
/* the token that this node has just attempted to pass. */
|
/* the token that this node has just attempted to pass. */
|
||||||
case MSTP_MASTER_STATE_PASS_TOKEN:
|
case MSTP_MASTER_STATE_PASS_TOKEN:
|
||||||
@@ -1055,7 +1008,7 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
else if ((mstp_port->SilenceTimer >= Tusage_timeout) &&
|
else if ((mstp_port->SilenceTimer >= Tusage_timeout) &&
|
||||||
(mstp_port->RetryCount >= Nretry_token)) {
|
(mstp_port->RetryCount >= Nretry_token)) {
|
||||||
/* Assume that NS has failed. */
|
/* Assume that NS has failed. */
|
||||||
mstp_port->Poll_Station = next_station;
|
mstp_port->Poll_Station = next_next_station;
|
||||||
/* Transmit a Poll For Master frame to PS. */
|
/* Transmit a Poll For Master frame to PS. */
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
FRAME_TYPE_POLL_FOR_MASTER,
|
FRAME_TYPE_POLL_FOR_MASTER,
|
||||||
@@ -1074,22 +1027,21 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* for that period of time. The timeout is continued to determine */
|
/* for that period 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 * mstp_port->This_Station);
|
||||||
|
ns_timeout = Tno_token + (Tslot * (mstp_port->This_Station + 1));
|
||||||
/* SawFrame */
|
/* SawFrame */
|
||||||
if ((mstp_port->SilenceTimer <
|
if ((mstp_port->SilenceTimer < my_timeout) &&
|
||||||
(Tno_token + (Tslot * mstp_port->This_Station)))
|
(mstp_port->EventCount > Nmin_octets)) {
|
||||||
&& (mstp_port->EventCount > Nmin_octets)) {
|
|
||||||
/* Some other node exists at a lower address. */
|
/* Some other node exists at a lower address. */
|
||||||
/* Enter the IDLE state to receive and process the incoming frame. */
|
/* Enter the IDLE state to receive and process the incoming frame. */
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
||||||
}
|
}
|
||||||
/* GenerateToken */
|
/* GenerateToken */
|
||||||
else if ((mstp_port->SilenceTimer >=
|
else if ((mstp_port->SilenceTimer >= my_timeout) &&
|
||||||
(Tno_token + (Tslot * mstp_port->This_Station)))
|
(mstp_port->SilenceTimer < ns_timeout)) {
|
||||||
&& (mstp_port->SilenceTimer <
|
|
||||||
(Tno_token + (Tslot * (mstp_port->This_Station + 1))))) {
|
|
||||||
/* Assume that this node is the lowest numerical address */
|
/* Assume that this node is the lowest numerical address */
|
||||||
/* on the network and is empowered to create a token. */
|
/* on the network and is empowered to create a token. */
|
||||||
mstp_port->Poll_Station = next_poll_neighbor;
|
mstp_port->Poll_Station = next_this_station;
|
||||||
/* Transmit a Poll For Master frame to PS. */
|
/* Transmit a Poll For Master frame to PS. */
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
FRAME_TYPE_POLL_FOR_MASTER,
|
FRAME_TYPE_POLL_FOR_MASTER,
|
||||||
@@ -1203,7 +1155,14 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* (the mechanism used to determine this is a local matter), */
|
/* (the mechanism used to determine this is a local matter), */
|
||||||
/* then call MSTP_Create_And_Send_Frame to transmit the reply frame */
|
/* then call MSTP_Create_And_Send_Frame to transmit the reply frame */
|
||||||
/* and enter the IDLE state to wait for the next frame. */
|
/* and enter the IDLE state to wait for the next frame. */
|
||||||
|
if ((mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) &&
|
||||||
|
(mstp_port->TxReady)) {
|
||||||
|
RS485_Send_Frame(
|
||||||
|
mstp_port,
|
||||||
|
(uint8_t *) &mstp_port->TxBuffer[0],
|
||||||
|
mstp_port->TxLength);
|
||||||
|
mstp_port->TxReady = false;
|
||||||
|
}
|
||||||
/* Test Request */
|
/* Test Request */
|
||||||
/* If a receiving node can successfully receive and return */
|
/* If a receiving node can successfully receive and return */
|
||||||
/* the information field, it shall do so. If it cannot receive */
|
/* the information field, it shall do so. If it cannot receive */
|
||||||
@@ -1215,17 +1174,16 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* no information field. If the receiving node cannot detect */
|
/* no information field. If the receiving node cannot detect */
|
||||||
/* the valid reception of frames with overlength information fields, */
|
/* the valid reception of frames with overlength information fields, */
|
||||||
/* then no response shall be returned. */
|
/* then no response shall be returned. */
|
||||||
if (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST) {
|
else if (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST) {
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
FRAME_TYPE_TEST_RESPONSE,
|
FRAME_TYPE_TEST_RESPONSE,
|
||||||
mstp_port->SourceAddress,
|
mstp_port->SourceAddress,
|
||||||
mstp_port->This_Station,
|
mstp_port->This_Station,
|
||||||
(uint8_t *) & mstp_port->InputBuffer[0],
|
(uint8_t *) & mstp_port->InputBuffer[0],
|
||||||
mstp_port->Index);
|
mstp_port->DataLength);
|
||||||
}
|
}
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
|
||||||
}
|
}
|
||||||
/* */
|
|
||||||
/* DeferredReply */
|
/* DeferredReply */
|
||||||
/* If no reply will be available from the higher layers */
|
/* If no reply will be available from the higher layers */
|
||||||
/* within Treply_delay after the reception of the */
|
/* within Treply_delay after the reception of the */
|
||||||
@@ -1235,7 +1193,6 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* Any reply shall wait until this node receives the token. */
|
/* Any reply shall wait until this node receives the token. */
|
||||||
/* Call MSTP_Create_And_Send_Frame to transmit a Reply Postponed frame, */
|
/* Call MSTP_Create_And_Send_Frame to transmit a Reply Postponed frame, */
|
||||||
/* and enter the IDLE state. */
|
/* and enter the IDLE state. */
|
||||||
|
|
||||||
else {
|
else {
|
||||||
MSTP_Create_And_Send_Frame(mstp_port,
|
MSTP_Create_And_Send_Frame(mstp_port,
|
||||||
FRAME_TYPE_REPLY_POSTPONED,
|
FRAME_TYPE_REPLY_POSTPONED,
|
||||||
@@ -1289,6 +1246,16 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port,
|
|||||||
mstp_port->This_Station = this_station_mac;
|
mstp_port->This_Station = this_station_mac;
|
||||||
mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES;
|
mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES;
|
||||||
mstp_port->Nmax_master = DEFAULT_MAX_MASTER;
|
mstp_port->Nmax_master = DEFAULT_MAX_MASTER;
|
||||||
|
|
||||||
|
/* An array of octets, used to store PDU octets prior to being transmitted. */
|
||||||
|
/* This array is only used for APDU messages */
|
||||||
|
for (i = 0; i < sizeof(mstp_port->TxBuffer); i++) {
|
||||||
|
mstp_port->TxBuffer[i] = 0;
|
||||||
|
}
|
||||||
|
mstp_port->TxLength = 0;
|
||||||
|
mstp_port->TxReady = false;
|
||||||
|
mstp_port->TxFrameType = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-7
@@ -225,13 +225,16 @@ extern "C" {
|
|||||||
void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t
|
void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t
|
||||||
*mstp_port);
|
*mstp_port);
|
||||||
|
|
||||||
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
/* returns true if line is active */
|
||||||
unsigned buffer_len, /* amount of space available */
|
bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port);
|
||||||
uint8_t frame_type, /* type of frame to send - see defines */
|
|
||||||
uint8_t destination, /* destination address */
|
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
||||||
uint8_t source, /* source address */
|
unsigned buffer_len, /* amount of space available */
|
||||||
uint8_t * data, /* any data to be sent - may be null */
|
uint8_t frame_type, /* type of frame to send - see defines */
|
||||||
unsigned data_len); /* number of bytes of data (up to 501) */
|
uint8_t destination, /* destination address */
|
||||||
|
uint8_t source, /* source address */
|
||||||
|
uint8_t * data, /* any data to be sent - may be null */
|
||||||
|
unsigned data_len); /* number of bytes of data (up to 501) */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -112,7 +112,8 @@ void dlmstp_task(void)
|
|||||||
{
|
{
|
||||||
RS485_Check_UART_Data(&MSTP_Port);
|
RS485_Check_UART_Data(&MSTP_Port);
|
||||||
MSTP_Receive_Frame_FSM(&MSTP_Port);
|
MSTP_Receive_Frame_FSM(&MSTP_Port);
|
||||||
MSTP_Master_Node_FSM(&MSTP_Port);
|
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE)
|
||||||
|
MSTP_Master_Node_FSM(&MSTP_Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called about once a millisecond */
|
/* called about once a millisecond */
|
||||||
@@ -175,17 +176,17 @@ uint16_t dlmstp_put_receive(
|
|||||||
uint8_t * pdu, /* PDU data */
|
uint8_t * pdu, /* PDU data */
|
||||||
uint16_t pdu_len)
|
uint16_t pdu_len)
|
||||||
{
|
{
|
||||||
if (Receive_Buffer.ready)
|
if (Receive_Buffer.ready) {
|
||||||
{
|
|
||||||
/* FIXME: what to do when we miss a message? */
|
/* FIXME: what to do when we miss a message? */
|
||||||
pdu_len = 0;
|
pdu_len = 0;
|
||||||
}
|
} else if (pdu_len < sizeof(Receive_Buffer.pdu)) {
|
||||||
else
|
|
||||||
{
|
|
||||||
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
|
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
|
||||||
Receive_Buffer.pdu_len = pdu_len;
|
Receive_Buffer.pdu_len = pdu_len;
|
||||||
memmove(Receive_Buffer.pdu, pdu, sizeof(Receive_Buffer.pdu));
|
memmove(Receive_Buffer.pdu, pdu, pdu_len);
|
||||||
Receive_Buffer.ready = true;
|
Receive_Buffer.ready = true;
|
||||||
|
} else {
|
||||||
|
/* FIXME: message too large? */
|
||||||
|
pdu_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pdu_len;
|
return pdu_len;
|
||||||
|
|||||||
@@ -161,10 +161,8 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef BACDL_MSTP
|
#ifdef BACDL_MSTP
|
||||||
dlmstp_task();
|
dlmstp_task();
|
||||||
#endif
|
#endif
|
||||||
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
|
|
||||||
/* returns 0 bytes on timeout */
|
/* returns 0 bytes on timeout */
|
||||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||||
#endif
|
|
||||||
/* process */
|
/* process */
|
||||||
if (pdu_len) {
|
if (pdu_len) {
|
||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ COMPort COM1 115200 // use COM1 with 115200 baud
|
|||||||
VideoRAM = None // program output sent to debugger - clrscr() crashes it.
|
VideoRAM = None // program output sent to debugger - clrscr() crashes it.
|
||||||
#elifdef DEBUGCOM3
|
#elifdef DEBUGCOM3
|
||||||
COMPort COM3 115200 9 // use COM3 IRQ9 115200 baud - Everex EV170 serial card
|
COMPort COM3 115200 9 // use COM3 IRQ9 115200 baud - Everex EV170 serial card
|
||||||
VideoRAM = ColorText // program output sent to debugger - clrscr() crashes it.
|
//VideoRAM = ColorText // program output sent to Graphic Card
|
||||||
|
VideoRAM = None // program output sent to debugger - clrscr() crashes it.
|
||||||
#else
|
#else
|
||||||
COMPort COM3 115200 9 // use COM3 IRQ9 115200 baud - Everex EV170 serial card
|
COMPort COM3 115200 9 // use COM3 IRQ9 115200 baud - Everex EV170 serial card
|
||||||
VideoRAM = ColorText // program output sent to Graphic Card
|
VideoRAM = ColorText // program output sent to Graphic Card
|
||||||
|
|||||||
@@ -22,12 +22,13 @@
|
|||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
#define PRINT_ENABLED_RS485 0
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <rtkernel.h>
|
#include <rtkernel.h>
|
||||||
#include <rtcom.h>
|
#include <rtcom.h>
|
||||||
#include <itimer.h>
|
#include <itimer.h>
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED_RS485
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
#include "mstp.h"
|
#include "mstp.h"
|
||||||
@@ -41,7 +42,7 @@
|
|||||||
/* COM port number - COM1 = 0 */
|
/* COM port number - COM1 = 0 */
|
||||||
static int RS485_Port = COM2;
|
static int RS485_Port = COM2;
|
||||||
/* baud rate */
|
/* baud rate */
|
||||||
static long RS485_Baud = 38400;
|
static long RS485_Baud = 9600;
|
||||||
/* io base address */
|
/* io base address */
|
||||||
static long RS485_Base = 0;
|
static long RS485_Base = 0;
|
||||||
/* hardware IRQ number */
|
/* hardware IRQ number */
|
||||||
@@ -111,7 +112,7 @@ static RS485_Open_Port(int port, /* COM port number - COM1 = 0 */
|
|||||||
/* enable the 485 via the DTR pin */
|
/* enable the 485 via the DTR pin */
|
||||||
RS485_IO_ENABLE(port);
|
RS485_IO_ENABLE(port);
|
||||||
RS485_RECEIVE_ENABLE(port);
|
RS485_RECEIVE_ENABLE(port);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED_RS485
|
||||||
fprintf(stderr,"RS485: COM%d Enabled\r\n",port+1);
|
fprintf(stderr,"RS485: COM%d Enabled\r\n",port+1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -139,7 +140,7 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
|
|||||||
while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY))
|
while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY))
|
||||||
RTKScheduler();
|
RTKScheduler();
|
||||||
RS485_RECEIVE_ENABLE(RS485_Port);
|
RS485_RECEIVE_ENABLE(RS485_Port);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED_RS485
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
fprintf(stderr,"RS485 Tx:");
|
fprintf(stderr,"RS485 Tx:");
|
||||||
|
|||||||
@@ -30,7 +30,8 @@
|
|||||||
Locate DiskBuffer DiskIO LowMem 16k 16k // needed by disk boot code
|
Locate DiskBuffer DiskIO LowMem 16k 16k // needed by disk boot code
|
||||||
NoFPU=0 // Check FPU
|
NoFPU=0 // Check FPU
|
||||||
CPL = 3 // normal priveleges
|
CPL = 3 // normal priveleges
|
||||||
VideoRAM ColorText // program output sent to Graphic Card
|
// VideoRAM ColorText // program output sent to Graphic Card
|
||||||
|
VideoRAM None // program output sent to file and host
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FillRAM HeapMem // remap unused RAM
|
FillRAM HeapMem // remap unused RAM
|
||||||
|
|||||||
Reference in New Issue
Block a user