Working on MS/TP port to PIC18F series microcontroller.
This commit is contained in:
@@ -73,12 +73,6 @@ extern "C" {
|
|||||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||||
unsigned timeout); /* milliseconds to wait for a packet */
|
unsigned timeout); /* milliseconds to wait for a packet */
|
||||||
|
|
||||||
/* function for MS/TP state machine to use to get a packet
|
|
||||||
to transmit. It returns the number of bytes in the
|
|
||||||
packet, or 0 if none. */
|
|
||||||
int dlmstp_get_transmit_pdu(BACNET_ADDRESS * dest, /* destination address */
|
|
||||||
uint8_t * pdu); /* any data to be sent - may be null */
|
|
||||||
|
|
||||||
/* This parameter represents the value of the Max_Info_Frames property of */
|
/* This parameter represents the value of the Max_Info_Frames property of */
|
||||||
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
||||||
/* maximum number of information frames the node may send before it must */
|
/* maximum number of information frames the node may send before it must */
|
||||||
@@ -94,7 +88,7 @@ extern "C" {
|
|||||||
/* 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. */
|
||||||
void dlmstp_set_max_info_frames(uint8_t max_master);
|
void dlmstp_set_max_master(uint8_t max_master);
|
||||||
uint8_t dlmstp_max_master(void);
|
uint8_t dlmstp_max_master(void);
|
||||||
|
|
||||||
void dlmstp_set_my_address(uint8_t my_address);
|
void dlmstp_set_my_address(uint8_t my_address);
|
||||||
|
|||||||
+60
-74
@@ -50,7 +50,6 @@
|
|||||||
#include "bytes.h"
|
#include "bytes.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "rs485.h"
|
#include "rs485.h"
|
||||||
#include "ringbuf.h"
|
|
||||||
|
|
||||||
/* MS/TP Frame Format */
|
/* MS/TP Frame Format */
|
||||||
/* All frames are of the following format: */
|
/* All frames are of the following format: */
|
||||||
@@ -128,14 +127,17 @@ const unsigned Tusage_delay = 15;
|
|||||||
/* larger values for this timeout, not to exceed 100 milliseconds.) */
|
/* larger values for this timeout, not to exceed 100 milliseconds.) */
|
||||||
const unsigned Tusage_timeout = 20;
|
const unsigned Tusage_timeout = 20;
|
||||||
|
|
||||||
/* creates the 8 octet frame header */
|
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
||||||
unsigned MSTP_Create_Frame_Header(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 */
|
||||||
uint8_t destination, /* destination address */
|
uint8_t destination, /* destination address */
|
||||||
uint8_t source) /* source 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) */
|
{ /* 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 */
|
||||||
|
unsigned index = 0; /* used to load the data portion of the frame */
|
||||||
|
|
||||||
/* not enough to do a header */
|
/* not enough to do a header */
|
||||||
if (buffer_len < 8)
|
if (buffer_len < 8)
|
||||||
@@ -155,53 +157,24 @@ unsigned MSTP_Create_Frame_Header(uint8_t * buffer, /* where frame is loaded
|
|||||||
crc8 = CRC_Calc_Header(buffer[6], crc8);
|
crc8 = CRC_Calc_Header(buffer[6], crc8);
|
||||||
buffer[7] = ~crc8;
|
buffer[7] = ~crc8;
|
||||||
|
|
||||||
return 8; /* returns the frame length */
|
index = 8;
|
||||||
}
|
while (data_len && data && (index < buffer_len)) {
|
||||||
|
buffer[index] = *data;
|
||||||
/* copies the PDU to a buffer while calculating its CRC checksum
|
crc16 = CRC_Calc_Data(buffer[index], crc16);
|
||||||
The CRC checksum is appended to the last two octets. */
|
data++;
|
||||||
unsigned MSTP_Copy_PDU_CRC(uint8_t * buffer, /* where frame is loaded */
|
index++;
|
||||||
unsigned buffer_len, /* amount of space available */
|
data_len--;
|
||||||
uint16_t crc16, /* used to calculate the crc value */
|
|
||||||
uint8_t * data, /* any data to be sent - may be null */
|
|
||||||
unsigned data_len)
|
|
||||||
{
|
|
||||||
unsigned index = 0; /* offset into the buffer */
|
|
||||||
|
|
||||||
if (buffer && data && data_len && ((data_len + 2) < buffer_len))
|
|
||||||
{
|
|
||||||
for (index = 0; index < data_len; index++)
|
|
||||||
{
|
|
||||||
buffer[index] = data[index];
|
|
||||||
crc16 = CRC_Calc_Data(buffer[index], crc16);
|
|
||||||
}
|
|
||||||
|
|
||||||
crc16 = ~crc16;
|
|
||||||
buffer[data_len] = LO_BYTE(crc16);
|
|
||||||
buffer[data_len + 1] = HI_BYTE(crc16);
|
|
||||||
index = data_len + 2;
|
|
||||||
}
|
}
|
||||||
|
/* append the data CRC if necessary */
|
||||||
return index;
|
if (index > 8) {
|
||||||
}
|
if ((index + 2) <= buffer_len) {
|
||||||
|
crc16 = ~crc16;
|
||||||
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
buffer[index] = LO_BYTE(crc16);
|
||||||
unsigned buffer_len, /* amount of space available */
|
index++;
|
||||||
uint8_t frame_type, /* type of frame to send - see defines */
|
buffer[index] = HI_BYTE(crc16);
|
||||||
uint8_t destination, /* destination address */
|
index++;
|
||||||
uint8_t source, /* source address */
|
} else
|
||||||
uint8_t * data, /* any data to be sent - may be null */
|
return 0;
|
||||||
unsigned data_len)
|
|
||||||
{ /* number of bytes of data (up to 501) */
|
|
||||||
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
|
|
||||||
unsigned index = 0; /* used to load the data portion of the frame */
|
|
||||||
|
|
||||||
index = MSTP_Create_Frame_Header(buffer, buffer_len, frame_type,
|
|
||||||
destination, source);
|
|
||||||
if (data && data_len)
|
|
||||||
{
|
|
||||||
index += MSTP_Copy_PDU_CRC(&buffer[index], buffer_len - index,
|
|
||||||
crc16, data, data_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return index; /* returns the frame length */
|
return index; /* returns the frame length */
|
||||||
@@ -214,10 +187,10 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port,
|
|||||||
uint8_t * data, /* any data to be sent - may be null */
|
uint8_t * data, /* any data to be sent - may be null */
|
||||||
unsigned data_len)
|
unsigned data_len)
|
||||||
{ /* number of bytes of data (up to 501) */
|
{ /* number of bytes of data (up to 501) */
|
||||||
uint8_t buffer[MAX_MPDU] = { 0 };
|
uint8_t buffer[MAX_MPDU] = {0}; /* buffer for sending */
|
||||||
uint16_t len = 0; /* number of bytes to send */
|
uint16_t len = 0; /* number of bytes to send */
|
||||||
|
|
||||||
len = (uint16_t) MSTP_Create_Frame(buffer, /* where frame is loaded */
|
len = (uint16_t) MSTP_Create_Frame(&buffer[0], /* where frame is loaded */
|
||||||
sizeof(buffer), /* amount of space available */
|
sizeof(buffer), /* amount of space available */
|
||||||
frame_type, /* type of frame to send - see defines */
|
frame_type, /* type of frame to send - see defines */
|
||||||
destination, /* destination address */
|
destination, /* destination address */
|
||||||
@@ -225,7 +198,9 @@ void MSTP_Create_And_Send_Frame(volatile struct mstp_port_struct_t *mstp_port,
|
|||||||
data, /* any data to be sent - may be null */
|
data, /* any data to be sent - may be null */
|
||||||
data_len); /* number of bytes of data (up to 501) */
|
data_len); /* number of bytes of data (up to 501) */
|
||||||
|
|
||||||
RS485_Send_Frame(mstp_port, buffer, len);
|
RS485_Send_Frame(mstp_port, &buffer[0], len);
|
||||||
|
RS485_Process_Tx_Message();
|
||||||
|
while (RS485_Tx_Complete()) {/* FIXME: watchdog? */};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Millisecond Timer - called every millisecond */
|
/* Millisecond Timer - called every millisecond */
|
||||||
@@ -543,6 +518,8 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
|
|
||||||
void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
||||||
{
|
{
|
||||||
|
int mtu_len = 0;
|
||||||
|
int frame_type = 0;
|
||||||
|
|
||||||
switch (mstp_port->master_state) {
|
switch (mstp_port->master_state) {
|
||||||
case MSTP_MASTER_STATE_INITIALIZE:
|
case MSTP_MASTER_STATE_INITIALIZE:
|
||||||
@@ -669,31 +646,40 @@ void MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* proprietary frames. */
|
/* proprietary frames. */
|
||||||
case MSTP_MASTER_STATE_USE_TOKEN:
|
case MSTP_MASTER_STATE_USE_TOKEN:
|
||||||
/* NothingToSend */
|
/* NothingToSend */
|
||||||
/* FIXME: If there is no data frame awaiting transmission, */
|
if (!mstp_port->TxReady)
|
||||||
{
|
{
|
||||||
mstp_port->FrameCount = mstp_port->Nmax_info_frames;
|
mstp_port->FrameCount = mstp_port->Nmax_info_frames;
|
||||||
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||||
}
|
}
|
||||||
/* SendNoWait */
|
else
|
||||||
/* FIXME: If there is a frame awaiting transmission that */
|
{
|
||||||
/* is of type Test_Response, BACnet Data Not Expecting Reply, */
|
RS485_Send_Frame(
|
||||||
/* or a proprietary type that does not expect a reply, */
|
mstp_port,
|
||||||
/* { */
|
&mstp_port->TxBuffer[0],
|
||||||
/* // transmit the data frame */
|
mstp_port->TxLength);
|
||||||
/* MSTP_Create_And_Send_Frame(?????????????); */
|
RS485_Process_Tx_Message();
|
||||||
/* FrameCount++; */
|
while (RS485_Tx_Complete()) {/* FIXME: watchdog? */};
|
||||||
/* mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; */
|
mstp_port->TxReady = false;
|
||||||
/* } */
|
mstp_port->FrameCount++;
|
||||||
/* SendAndWait */
|
/* SendNoWait */
|
||||||
/* FIXME: If there is a frame awaiting transmission that is of */
|
/* There is a frame awaiting transmission that */
|
||||||
/* type Test_Request, BACnet Data Expecting Reply, or */
|
/* is of type Test_Response, BACnet Data Not Expecting Reply, */
|
||||||
/* a proprietary type that expects a reply, */
|
/* or a proprietary type that does not expect a reply, */
|
||||||
/* { */
|
if ((mstp_port->TxFrameType == FRAME_TYPE_TEST_RESPONSE) ||
|
||||||
/* // transmit the data frame */
|
(mstp_port->TxFrameType == FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))
|
||||||
/* MSTP_Create_And_Send_Frame(); */
|
{
|
||||||
/* FrameCount++; */
|
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
|
||||||
/* mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY; */
|
}
|
||||||
/* } */
|
/* SendAndWait */
|
||||||
|
/* If there is a frame awaiting transmission that is of */
|
||||||
|
/* type Test_Request, BACnet Data Expecting Reply, or */
|
||||||
|
/* a proprietary type that expects a reply, */
|
||||||
|
else if ((mstp_port->TxFrameType == FRAME_TYPE_TEST_REQUEST) ||
|
||||||
|
(mstp_port->TxFrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY))
|
||||||
|
{
|
||||||
|
mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* In the WAIT_FOR_REPLY state, the node waits for */
|
/* In the WAIT_FOR_REPLY state, the node waits for */
|
||||||
/* a reply from another node. */
|
/* a reply from another node. */
|
||||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||||
|
|||||||
+13
-9
@@ -64,6 +64,9 @@
|
|||||||
/* of a Proprietary frame shall be in the range of 2 to 501 octets. */
|
/* of a Proprietary frame shall be in the range of 2 to 501 octets. */
|
||||||
#define FRAME_TYPE_PROPRIETARY_MIN 128
|
#define FRAME_TYPE_PROPRIETARY_MIN 128
|
||||||
#define FRAME_TYPE_PROPRIETARY_MAX 255
|
#define FRAME_TYPE_PROPRIETARY_MAX 255
|
||||||
|
/* The initial CRC16 checksum value */
|
||||||
|
#define CRC16_INITIAL_VALUE (0xFFFF)
|
||||||
|
|
||||||
|
|
||||||
/* receive FSM states */
|
/* receive FSM states */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -191,6 +194,13 @@ struct mstp_port_struct_t {
|
|||||||
/* 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. */
|
||||||
unsigned Nmax_master;
|
unsigned Nmax_master;
|
||||||
|
|
||||||
|
/* An array of octets, used to store PDU octets prior to being transmitted. */
|
||||||
|
/* This array is not used for passing token frames */
|
||||||
|
uint8_t TxBuffer[MAX_MPDU];
|
||||||
|
int TxLength;
|
||||||
|
bool TxReady; /* true if ready to be sent or received */
|
||||||
|
uint8_t TxFrameType; /* type of message - needed by MS/TP */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_MAX_INFO_FRAMES 1
|
#define DEFAULT_MAX_INFO_FRAMES 1
|
||||||
@@ -214,19 +224,13 @@ 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);
|
||||||
|
|
||||||
/* creates the 8 octet frame header */
|
unsigned MSTP_Create_Frame(uint8_t * buffer, /* where frame is loaded */
|
||||||
unsigned MSTP_Create_Frame_Header(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 */
|
||||||
uint8_t destination, /* destination address */
|
uint8_t destination, /* destination address */
|
||||||
uint8_t source); /* source address */
|
uint8_t source, /* source address */
|
||||||
/* copies the PDU to a buffer while calculating its CRC checksum
|
|
||||||
The CRC checksum is appended to the last two octets. */
|
|
||||||
unsigned MSTP_Copy_PDU_CRC(uint8_t * buffer, /* where frame is loaded */
|
|
||||||
unsigned buffer_len, /* amount of space available */
|
|
||||||
uint16_t crc16, /* used to calculate the crc value */
|
|
||||||
uint8_t * data, /* any data to be sent - may be null */
|
uint8_t * data, /* any data to be sent - may be null */
|
||||||
unsigned data_len);
|
unsigned data_len); /* number of bytes of data (up to 501) */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ file_047=no
|
|||||||
file_048=no
|
file_048=no
|
||||||
file_049=no
|
file_049=no
|
||||||
file_050=no
|
file_050=no
|
||||||
file_051=no
|
|
||||||
[FILE_INFO]
|
[FILE_INFO]
|
||||||
file_000=C:\code\bacnet-stack\abort.c
|
file_000=C:\code\bacnet-stack\abort.c
|
||||||
file_001=C:\code\bacnet-stack\apdu.c
|
file_001=C:\code\bacnet-stack\apdu.c
|
||||||
@@ -83,14 +82,14 @@ file_010=C:\code\bacnet-stack\mstp.c
|
|||||||
file_011=C:\code\bacnet-stack\npdu.c
|
file_011=C:\code\bacnet-stack\npdu.c
|
||||||
file_012=C:\code\bacnet-stack\rd.c
|
file_012=C:\code\bacnet-stack\rd.c
|
||||||
file_013=C:\code\bacnet-stack\reject.c
|
file_013=C:\code\bacnet-stack\reject.c
|
||||||
file_014=C:\code\bacnet-stack\ringbuf.c
|
file_014=C:\code\bacnet-stack\rp.c
|
||||||
file_015=C:\code\bacnet-stack\rp.c
|
file_015=C:\code\bacnet-stack\whois.c
|
||||||
file_016=C:\code\bacnet-stack\whois.c
|
file_016=C:\code\bacnet-stack\demo\handler\h_dcc.c
|
||||||
file_017=C:\code\bacnet-stack\demo\handler\h_dcc.c
|
file_017=C:\code\bacnet-stack\demo\handler\h_rd.c
|
||||||
file_018=C:\code\bacnet-stack\demo\handler\h_rd.c
|
file_018=main.c
|
||||||
file_019=main.c
|
file_019=C:\code\bacnet-stack\demo\object\tiny_dev.c
|
||||||
file_020=C:\code\bacnet-stack\demo\object\tiny_dev.c
|
file_020=dlmstp.c
|
||||||
file_021=dlmstp.c
|
file_021=rs485.c
|
||||||
file_022=C:\code\bacnet-stack\wp.h
|
file_022=C:\code\bacnet-stack\wp.h
|
||||||
file_023=C:\code\bacnet-stack\abort.h
|
file_023=C:\code\bacnet-stack\abort.h
|
||||||
file_024=C:\code\bacnet-stack\apdu.h
|
file_024=C:\code\bacnet-stack\apdu.h
|
||||||
@@ -110,17 +109,16 @@ file_037=C:\code\bacnet-stack\mstp.h
|
|||||||
file_038=C:\code\bacnet-stack\npdu.h
|
file_038=C:\code\bacnet-stack\npdu.h
|
||||||
file_039=C:\code\bacnet-stack\rd.h
|
file_039=C:\code\bacnet-stack\rd.h
|
||||||
file_040=C:\code\bacnet-stack\reject.h
|
file_040=C:\code\bacnet-stack\reject.h
|
||||||
file_041=C:\code\bacnet-stack\ringbuf.h
|
file_041=C:\code\bacnet-stack\rp.h
|
||||||
file_042=C:\code\bacnet-stack\rp.h
|
file_042=C:\code\bacnet-stack\rs485.h
|
||||||
file_043=C:\code\bacnet-stack\rs485.h
|
file_043=C:\code\bacnet-stack\whois.h
|
||||||
file_044=C:\code\bacnet-stack\whois.h
|
file_044=C:\code\bacnet-stack\demo\handler\client.h
|
||||||
file_045=C:\code\bacnet-stack\demo\handler\client.h
|
file_045=C:\code\bacnet-stack\demo\handler\handlers.h
|
||||||
file_046=C:\code\bacnet-stack\demo\handler\handlers.h
|
file_046=C:\code\bacnet-stack\demo\object\ai.h
|
||||||
file_047=C:\code\bacnet-stack\demo\object\ai.h
|
file_047=C:\code\bacnet-stack\demo\object\ao.h
|
||||||
file_048=C:\code\bacnet-stack\demo\object\ao.h
|
file_048=C:\code\bacnet-stack\demo\object\device.h
|
||||||
file_049=C:\code\bacnet-stack\demo\object\device.h
|
file_049=stdbool.h
|
||||||
file_050=stdbool.h
|
file_050=stdint.h
|
||||||
file_051=stdint.h
|
|
||||||
[SUITE_INFO]
|
[SUITE_INFO]
|
||||||
suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416}
|
suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416}
|
||||||
suite_state=
|
suite_state=
|
||||||
|
|||||||
Binary file not shown.
@@ -32,22 +32,18 @@
|
|||||||
#include "rs485.h"
|
#include "rs485.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
|
|
||||||
|
/* receive buffer */
|
||||||
static DLMSTP_PACKET Receive_Buffer;
|
static DLMSTP_PACKET Receive_Buffer;
|
||||||
static DLMSTP_PACKET Transmit_Buffer;
|
/* temp buffer for NPDU insertion */
|
||||||
static uint8_t PDU_Buffer[MAX_MPDU];
|
static uint8_t PDU_Buffer[MAX_MPDU];
|
||||||
/* local MS/TP port data */
|
/* local MS/TP port data */
|
||||||
volatile struct mstp_port_struct_t MSTP_Port; /* port data */
|
static volatile struct mstp_port_struct_t MSTP_Port;
|
||||||
|
|
||||||
void dlmstp_init(void)
|
void dlmstp_init(void)
|
||||||
{
|
{
|
||||||
/* initialize buffer */
|
/* initialize buffer */
|
||||||
Receive_Buffer.ready = false;
|
Receive_Buffer.ready = false;
|
||||||
Receive_Buffer.data_expecting_reply = false;
|
|
||||||
Receive_Buffer.pdu_len = 0;
|
Receive_Buffer.pdu_len = 0;
|
||||||
/* initialize buffer */
|
|
||||||
Transmit_Buffer.ready = false;
|
|
||||||
Transmit_Buffer.data_expecting_reply = false;
|
|
||||||
Transmit_Buffer.pdu_len = 0;
|
|
||||||
/* initialize hardware */
|
/* initialize hardware */
|
||||||
RS485_Initialize();
|
RS485_Initialize();
|
||||||
MSTP_Init(&MSTP_Port, MSTP_Port.This_Station);
|
MSTP_Init(&MSTP_Port, MSTP_Port.This_Station);
|
||||||
@@ -71,11 +67,11 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
|||||||
uint8_t destination = 0; /* destination address */
|
uint8_t destination = 0; /* destination address */
|
||||||
BACNET_ADDRESS src;
|
BACNET_ADDRESS src;
|
||||||
|
|
||||||
if (Transmit_Buffer.ready == false) {
|
if (MSTP_Port.TxReady == false) {
|
||||||
if (npdu_data->confirmed_message)
|
if (npdu_data->confirmed_message)
|
||||||
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
|
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
|
||||||
else
|
else
|
||||||
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
|
MSTP_Port.TxFrameType = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
|
||||||
|
|
||||||
/* load destination MAC address */
|
/* load destination MAC address */
|
||||||
if (dest && dest->mac_len == 1) {
|
if (dest && dest->mac_len == 1) {
|
||||||
@@ -88,58 +84,28 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
|||||||
}
|
}
|
||||||
dlmstp_get_my_address(&src);
|
dlmstp_get_my_address(&src);
|
||||||
npdu_len = npdu_encode_pdu(&PDU_Buffer[0], dest, &src, npdu_data);
|
npdu_len = npdu_encode_pdu(&PDU_Buffer[0], dest, &src, npdu_data);
|
||||||
if ((8 + npdu_len + pdu_len) > MAX_MPDU) {
|
if ((8 /* header len */ + npdu_len + pdu_len) > MAX_MPDU) {
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "mstp: PDU is too big to send!\n");
|
fprintf(stderr, "mstp: PDU is too big to send!\n");
|
||||||
#endif
|
#endif
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
memcpy(&PDU_Buffer[npdu_len], pdu, pdu_len);
|
memmove(&PDU_Buffer[npdu_len], pdu, pdu_len);
|
||||||
/* copies the PDU to a buffer while calculating its CRC checksum
|
|
||||||
The CRC checksum is appended to the last two octets. */
|
|
||||||
unsigned MSTP_Copy_PDU_CRC(uint8_t * buffer, /* where frame is loaded */
|
|
||||||
unsigned buffer_len, /* amount of space available */
|
|
||||||
uint16_t crc16, /* used to calculate the crc value */
|
|
||||||
uint8_t * data, /* any data to be sent - may be null */
|
|
||||||
unsigned data_len);
|
|
||||||
|
|
||||||
bytes_sent = MSTP_Create_Frame(
|
bytes_sent = MSTP_Create_Frame(
|
||||||
&Transmit_Buffer.pdu[0],
|
&MSTP_Port.TxBuffer[0],
|
||||||
sizeof(Transmit_Buffer.pdu),
|
sizeof(MSTP_Port.TxBuffer),
|
||||||
frame_type,
|
MSTP_Port.TxFrameType,
|
||||||
destination,
|
destination,
|
||||||
MSTP_Port.This_Station,
|
MSTP_Port.This_Station,
|
||||||
&PDU_Buffer[0],
|
&PDU_Buffer[0],
|
||||||
npdu_len + pdu_len);
|
npdu_len + pdu_len);
|
||||||
Transmit_Buffer.ready = true;
|
MSTP_Port.TxLength = bytes_sent;
|
||||||
|
MSTP_Port.TxReady = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes_sent;
|
return bytes_sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function for MS/TP to use to get a packet to transmit
|
|
||||||
returns the number of bytes in the packet, or zero if none. */
|
|
||||||
int dlmstp_get_transmit_pdu(BACNET_ADDRESS * dest, /* destination address */
|
|
||||||
uint8_t * pdu)
|
|
||||||
{ /* any data to be sent - may be null */
|
|
||||||
bool status;
|
|
||||||
DLMSTP_PACKET *packet;
|
|
||||||
unsigned pdu_len = 0;
|
|
||||||
|
|
||||||
if (Transmit_Buffer.ready) {
|
|
||||||
memmove(dest, &packet->address, sizeof(packet->address));
|
|
||||||
pdu_len = packet->pdu_len;
|
|
||||||
memmove(pdu, packet->pdu, sizeof(packet.pdu));
|
|
||||||
}
|
|
||||||
|
|
||||||
return pdu_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dlmstp_set_transmit_pdu_ready(bool ready)
|
|
||||||
{
|
|
||||||
Transmit_Buffer.ready = ready;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dlmstp_task(void)
|
void dlmstp_task(void)
|
||||||
{
|
{
|
||||||
RS485_Check_UART_Data(&MSTP_Port);
|
RS485_Check_UART_Data(&MSTP_Port);
|
||||||
@@ -162,15 +128,16 @@ uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */
|
|||||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||||
unsigned timeout)
|
unsigned timeout)
|
||||||
{
|
{
|
||||||
DLMSTP_PACKET *packet;
|
uint16_t pdu_len = 0;
|
||||||
|
|
||||||
(void) timeout;
|
(void) timeout;
|
||||||
/* see if there is a packet available */
|
/* see if there is a packet available */
|
||||||
if (!Ringbuf_Empty(&Receive_Buffer)) {
|
if (Receive_Buffer.ready)
|
||||||
packet = (char *) Ringbuf_Pop_Front(&Receive_Buffer);
|
{
|
||||||
memmove(src, &packet->address, sizeof(packet->address));
|
memmove(src, &Receive_Buffer.address, sizeof(Receive_Buffer.address));
|
||||||
pdu_len = packet->pdu_len;
|
pdu_len = Receive_Buffer.pdu_len;
|
||||||
memmove(pdu, packet->pdu, max_pdu);
|
memmove(&pdu[0], &Receive_Buffer.pdu[0], max_pdu);
|
||||||
|
Receive_Buffer.ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pdu_len;
|
return pdu_len;
|
||||||
@@ -181,17 +148,11 @@ uint16_t dlmstp_put_receive(BACNET_ADDRESS * src, /* source address */
|
|||||||
uint8_t * pdu, /* PDU data */
|
uint8_t * pdu, /* PDU data */
|
||||||
uint16_t pdu_len)
|
uint16_t pdu_len)
|
||||||
{
|
{
|
||||||
bool status;
|
memmove(&Receive_Buffer.address, src, sizeof(Receive_Buffer.address));
|
||||||
int bytes_put = 0;
|
Receive_Buffer.pdu_len = pdu_len;
|
||||||
|
memmove(Receive_Buffer.pdu, pdu, sizeof(Receive_Buffer.pdu));
|
||||||
|
|
||||||
memmove(&Temp_Packet.address, src, sizeof(Temp_Packet.address));
|
return pdu_len;
|
||||||
Temp_Packet.pdu_len = pdu_len;
|
|
||||||
memmove(Temp_Packet.pdu, pdu, sizeof(Temp_Packet.pdu));
|
|
||||||
status = Ringbuf_Put(&Receive_Buffer, &Temp_Packet);
|
|
||||||
if (status)
|
|
||||||
bytes_put = pdu_len;
|
|
||||||
|
|
||||||
return bytes_put;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlmstp_set_my_address(uint8_t mac_address)
|
void dlmstp_set_my_address(uint8_t mac_address)
|
||||||
@@ -226,7 +187,7 @@ unsigned dlmstp_max_info_frames(void)
|
|||||||
/* 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. */
|
||||||
void dlmstp_set_max_info_frames(uint8_t max_master)
|
void dlmstp_set_max_master(uint8_t max_master)
|
||||||
{
|
{
|
||||||
MSTP_Port.Nmax_master = max_master;
|
MSTP_Port.Nmax_master = max_master;
|
||||||
|
|
||||||
@@ -240,6 +201,8 @@ uint8_t dlmstp_max_master(void)
|
|||||||
|
|
||||||
void dlmstp_get_my_address(BACNET_ADDRESS * my_address)
|
void dlmstp_get_my_address(BACNET_ADDRESS * my_address)
|
||||||
{
|
{
|
||||||
|
int i = 0; /* counter */
|
||||||
|
|
||||||
my_address->mac_len = 1;
|
my_address->mac_len = 1;
|
||||||
my_address->mac[0] = MSTP_Port.This_Station;
|
my_address->mac[0] = MSTP_Port.This_Station;
|
||||||
my_address->net = 0; /* local only, no routing */
|
my_address->net = 0; /* local only, no routing */
|
||||||
|
|||||||
@@ -207,6 +207,17 @@ void RS485_Process_Tx_Message(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* DESCRIPTION: Returns the value of Transmit Complete flag.
|
||||||
|
* RETURN: none
|
||||||
|
* ALGORITHM: none
|
||||||
|
* NOTES: none
|
||||||
|
*****************************************************************************/
|
||||||
|
bool RS485_Tx_Complete(void)
|
||||||
|
{
|
||||||
|
return RS485_Flags.TransmitComplete;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* DESCRIPTION: Checks for data on the receive UART, and handles errors
|
* DESCRIPTION: Checks for data on the receive UART, and handles errors
|
||||||
* RETURN: none
|
* RETURN: none
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ extern "C" {
|
|||||||
|
|
||||||
void RS485_Process_Tx_Message(void);
|
void RS485_Process_Tx_Message(void);
|
||||||
|
|
||||||
|
bool RS485_Tx_Complete(void);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
Reference in New Issue
Block a user