Getting the PIC port to function with MS/TP.
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2005 Steve Karg
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
The Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307
|
||||
USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or
|
||||
use macros or inline functions from this file, or you compile
|
||||
this file and link it with other works to produce a work based
|
||||
on this file, this file does not by itself cause the resulting
|
||||
work to be covered by the GNU General Public License. However
|
||||
the source code for this file must still be made available in
|
||||
accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work
|
||||
based on this file might be covered by the GNU General Public
|
||||
License.
|
||||
-------------------------------------------
|
||||
####COPYRIGHTEND####*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "bacdef.h"
|
||||
#include "mstp.h"
|
||||
#include "dlmstp.h"
|
||||
|
||||
void dlmstp_init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void dlmstp_cleanup(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
{ /* number of bytes of data */
|
||||
|
||||
(void) dest;
|
||||
(void) pdu;
|
||||
(void) pdu_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
(void) src;
|
||||
(void) pdu;
|
||||
(void) max_pdu;
|
||||
(void) timeout;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dlmstp_set_my_address(BACNET_ADDRESS * my_address)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_get_my_address(BACNET_ADDRESS * my_address)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest)
|
||||
{ /* destination address */
|
||||
return;
|
||||
}
|
||||
+17
-1
@@ -44,12 +44,21 @@
|
||||
#define MAX_HEADER (2+1+1+1+2+1+2+1)
|
||||
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
|
||||
|
||||
typedef struct dlmstp_packet
|
||||
{
|
||||
BACNET_ADDRESS address;
|
||||
unsigned pdu_len;
|
||||
uint8_t pdu[MAX_MPDU];
|
||||
} DLMSTP_PACKET;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void dlmstp_init(void);
|
||||
void dlmstp_cleanup(void);
|
||||
void dlmstp_task(void);
|
||||
void dlmstp_millisecond_timer(void);
|
||||
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
@@ -61,8 +70,15 @@ extern "C" {
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
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 */
|
||||
|
||||
|
||||
void dlmstp_set_my_address(BACNET_ADDRESS * my_address);
|
||||
void dlmstp_set_my_address(uint8_t my_address);
|
||||
void dlmstp_get_my_address(BACNET_ADDRESS * my_address);
|
||||
void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
[HEADER]
|
||||
magic_cookie={66E99B07-E706-4689-9E80-9B2582898A13}
|
||||
file_version=1.0
|
||||
[PATH_INFO]
|
||||
dir_src=
|
||||
dir_bin=
|
||||
dir_tmp=
|
||||
dir_sin=
|
||||
dir_inc=C:\code\bacnet-stack;C:\code\bacnet-stack\demo\handler;C:\code\bacnet-stack\demo\object;C:\code\bacnet-stack\ports\pic18
|
||||
dir_lib=C:\mcc18\lib
|
||||
dir_lkr=
|
||||
[CAT_FILTERS]
|
||||
filter_src=*.asm;*.c
|
||||
filter_inc=*.h;*.inc
|
||||
filter_obj=*.o
|
||||
filter_lib=*.lib
|
||||
filter_lkr=*.lkr
|
||||
[OTHER_FILES]
|
||||
file_000=no
|
||||
file_001=no
|
||||
file_002=no
|
||||
file_003=no
|
||||
file_004=no
|
||||
file_005=no
|
||||
file_006=no
|
||||
file_007=no
|
||||
file_008=no
|
||||
file_009=no
|
||||
file_010=no
|
||||
file_011=no
|
||||
file_012=no
|
||||
file_013=no
|
||||
file_014=no
|
||||
file_015=no
|
||||
file_016=no
|
||||
file_017=no
|
||||
file_018=no
|
||||
file_019=no
|
||||
file_020=no
|
||||
file_021=no
|
||||
file_022=no
|
||||
file_023=no
|
||||
file_024=no
|
||||
file_025=no
|
||||
file_026=no
|
||||
file_027=no
|
||||
file_028=no
|
||||
file_029=no
|
||||
file_030=no
|
||||
file_031=no
|
||||
file_032=no
|
||||
file_033=no
|
||||
file_034=no
|
||||
file_035=no
|
||||
file_036=no
|
||||
file_037=no
|
||||
file_038=no
|
||||
file_039=no
|
||||
file_040=no
|
||||
file_041=no
|
||||
file_042=no
|
||||
file_043=no
|
||||
file_044=no
|
||||
file_045=no
|
||||
file_046=no
|
||||
file_047=no
|
||||
file_048=no
|
||||
file_049=no
|
||||
file_050=no
|
||||
file_051=no
|
||||
[FILE_INFO]
|
||||
file_000=C:\code\bacnet-stack\abort.c
|
||||
file_001=C:\code\bacnet-stack\apdu.c
|
||||
file_002=C:\code\bacnet-stack\bacapp.c
|
||||
file_003=C:\code\bacnet-stack\bacdcode.c
|
||||
file_004=C:\code\bacnet-stack\bacerror.c
|
||||
file_005=C:\code\bacnet-stack\bacstr.c
|
||||
file_006=C:\code\bacnet-stack\crc.c
|
||||
file_007=C:\code\bacnet-stack\datalink.c
|
||||
file_008=C:\code\bacnet-stack\dcc.c
|
||||
file_009=C:\code\bacnet-stack\iam.c
|
||||
file_010=C:\code\bacnet-stack\mstp.c
|
||||
file_011=C:\code\bacnet-stack\npdu.c
|
||||
file_012=C:\code\bacnet-stack\rd.c
|
||||
file_013=C:\code\bacnet-stack\reject.c
|
||||
file_014=C:\code\bacnet-stack\ringbuf.c
|
||||
file_015=C:\code\bacnet-stack\rp.c
|
||||
file_016=C:\code\bacnet-stack\whois.c
|
||||
file_017=C:\code\bacnet-stack\demo\handler\h_dcc.c
|
||||
file_018=C:\code\bacnet-stack\demo\handler\h_rd.c
|
||||
file_019=main.c
|
||||
file_020=C:\code\bacnet-stack\demo\object\tiny_dev.c
|
||||
file_021=dlmstp.c
|
||||
file_022=C:\code\bacnet-stack\wp.h
|
||||
file_023=C:\code\bacnet-stack\abort.h
|
||||
file_024=C:\code\bacnet-stack\apdu.h
|
||||
file_025=C:\code\bacnet-stack\bacapp.h
|
||||
file_026=C:\code\bacnet-stack\bacdcode.h
|
||||
file_027=C:\code\bacnet-stack\bacdef.h
|
||||
file_028=C:\code\bacnet-stack\bacenum.h
|
||||
file_029=C:\code\bacnet-stack\bacerror.h
|
||||
file_030=C:\code\bacnet-stack\bacstr.h
|
||||
file_031=C:\code\bacnet-stack\config.h
|
||||
file_032=C:\code\bacnet-stack\crc.h
|
||||
file_033=C:\code\bacnet-stack\datalink.h
|
||||
file_034=C:\code\bacnet-stack\dcc.h
|
||||
file_035=C:\code\bacnet-stack\dlmstp.h
|
||||
file_036=C:\code\bacnet-stack\iam.h
|
||||
file_037=C:\code\bacnet-stack\mstp.h
|
||||
file_038=C:\code\bacnet-stack\npdu.h
|
||||
file_039=C:\code\bacnet-stack\rd.h
|
||||
file_040=C:\code\bacnet-stack\reject.h
|
||||
file_041=C:\code\bacnet-stack\ringbuf.h
|
||||
file_042=C:\code\bacnet-stack\rp.h
|
||||
file_043=C:\code\bacnet-stack\rs485.h
|
||||
file_044=C:\code\bacnet-stack\whois.h
|
||||
file_045=C:\code\bacnet-stack\demo\handler\client.h
|
||||
file_046=C:\code\bacnet-stack\demo\handler\handlers.h
|
||||
file_047=C:\code\bacnet-stack\demo\object\ai.h
|
||||
file_048=C:\code\bacnet-stack\demo\object\ao.h
|
||||
file_049=C:\code\bacnet-stack\demo\object\device.h
|
||||
file_050=stdbool.h
|
||||
file_051=stdint.h
|
||||
[SUITE_INFO]
|
||||
suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416}
|
||||
suite_state=
|
||||
[TOOL_SETTINGS]
|
||||
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}=
|
||||
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/o"$(TARGETBASE).cof" /M"$(BINDIR_)$(TARGETBASE).map"
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DPRINT_ENABLED=0 -DBACDL_MSTP -DBIG_ENDIAN=1 -mL -Ls -Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
|
||||
TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}=
|
||||
Binary file not shown.
@@ -6,7 +6,7 @@ dir_src=
|
||||
dir_bin=
|
||||
dir_tmp=
|
||||
dir_sin=
|
||||
dir_inc=c:\mcc18\h;c:\code\bacnet-stack;c:\code\bacnet-stack\ports\pic18
|
||||
dir_inc=c:\mcc18\h;c:\code\bacnet-stack;c:\code\bacnet-stack\ports\pic18;c:\code\bacnet-stack\demo\object;c:\code\bacnet-stack\demo\handler
|
||||
dir_lib=c:\mcc18\lib
|
||||
dir_lkr=
|
||||
[CAT_FILTERS]
|
||||
@@ -70,6 +70,9 @@ file_050=no
|
||||
file_051=no
|
||||
file_052=no
|
||||
file_053=no
|
||||
file_054=no
|
||||
file_055=no
|
||||
file_056=no
|
||||
[FILE_INFO]
|
||||
file_000=rs485.c
|
||||
file_001=main.c
|
||||
@@ -85,53 +88,56 @@ file_010=C:\code\bacnet-stack\bacerror.c
|
||||
file_011=C:\code\bacnet-stack\bigend.c
|
||||
file_012=C:\code\bacnet-stack\crc.c
|
||||
file_013=C:\code\bacnet-stack\datalink.c
|
||||
file_014=C:\code\bacnet-stack\device.c
|
||||
file_015=C:\code\bacnet-stack\dlmstp.c
|
||||
file_016=C:\code\bacnet-stack\iam.c
|
||||
file_017=C:\code\bacnet-stack\mstp.c
|
||||
file_018=C:\code\bacnet-stack\npdu.c
|
||||
file_019=C:\code\bacnet-stack\reject.c
|
||||
file_020=C:\code\bacnet-stack\ringbuf.c
|
||||
file_021=C:\code\bacnet-stack\address.c
|
||||
file_022=C:\code\bacnet-stack\tsm.c
|
||||
file_023=C:\code\bacnet-stack\ao.c
|
||||
file_024=C:\code\bacnet-stack\ai.c
|
||||
file_025=C:\code\bacnet-stack\handlers.c
|
||||
file_026=C:\code\bacnet-stack\wp.c
|
||||
file_014=C:\code\bacnet-stack\dlmstp.c
|
||||
file_015=C:\code\bacnet-stack\iam.c
|
||||
file_016=C:\code\bacnet-stack\mstp.c
|
||||
file_017=C:\code\bacnet-stack\npdu.c
|
||||
file_018=C:\code\bacnet-stack\reject.c
|
||||
file_019=C:\code\bacnet-stack\ringbuf.c
|
||||
file_020=C:\code\bacnet-stack\wp.c
|
||||
file_021=C:\code\bacnet-stack\demo\object\ai.c
|
||||
file_022=C:\code\bacnet-stack\demo\object\ao.c
|
||||
file_023=C:\code\bacnet-stack\dcc.c
|
||||
file_024=C:\code\bacnet-stack\bacstr.c
|
||||
file_025=C:\code\bacnet-stack\bacapp.c
|
||||
file_026=C:\code\bacnet-stack\demo\object\tiny_dev.c
|
||||
file_027=stdbool.h
|
||||
file_028=stdint.h
|
||||
file_029=init.h
|
||||
file_030=timer.h
|
||||
file_031=C:\code\bacnet-stack\tsm.h
|
||||
file_032=C:\code\bacnet-stack\whois.h
|
||||
file_033=C:\code\bacnet-stack\abort.h
|
||||
file_034=C:\code\bacnet-stack\address.h
|
||||
file_035=C:\code\bacnet-stack\apdu.h
|
||||
file_036=C:\code\bacnet-stack\bacdcode.h
|
||||
file_037=C:\code\bacnet-stack\bacdef.h
|
||||
file_038=C:\code\bacnet-stack\bacenum.h
|
||||
file_039=C:\code\bacnet-stack\bacerror.h
|
||||
file_040=C:\code\bacnet-stack\bigend.h
|
||||
file_041=C:\code\bacnet-stack\bits.h
|
||||
file_042=C:\code\bacnet-stack\bytes.h
|
||||
file_043=C:\code\bacnet-stack\config.h
|
||||
file_044=C:\code\bacnet-stack\crc.h
|
||||
file_045=C:\code\bacnet-stack\datalink.h
|
||||
file_046=C:\code\bacnet-stack\device.h
|
||||
file_047=C:\code\bacnet-stack\dlmstp.h
|
||||
file_048=C:\code\bacnet-stack\mstp.h
|
||||
file_049=C:\code\bacnet-stack\npdu.h
|
||||
file_050=C:\code\bacnet-stack\reject.h
|
||||
file_051=C:\code\bacnet-stack\ringbuf.h
|
||||
file_052=C:\code\bacnet-stack\rs485.h
|
||||
file_053=18f252.lkr
|
||||
file_031=C:\code\bacnet-stack\whois.h
|
||||
file_032=C:\code\bacnet-stack\abort.h
|
||||
file_033=C:\code\bacnet-stack\apdu.h
|
||||
file_034=C:\code\bacnet-stack\bacdcode.h
|
||||
file_035=C:\code\bacnet-stack\bacdef.h
|
||||
file_036=C:\code\bacnet-stack\bacenum.h
|
||||
file_037=C:\code\bacnet-stack\bacerror.h
|
||||
file_038=C:\code\bacnet-stack\bigend.h
|
||||
file_039=C:\code\bacnet-stack\bits.h
|
||||
file_040=C:\code\bacnet-stack\bytes.h
|
||||
file_041=C:\code\bacnet-stack\config.h
|
||||
file_042=C:\code\bacnet-stack\crc.h
|
||||
file_043=C:\code\bacnet-stack\datalink.h
|
||||
file_044=C:\code\bacnet-stack\dlmstp.h
|
||||
file_045=C:\code\bacnet-stack\mstp.h
|
||||
file_046=C:\code\bacnet-stack\npdu.h
|
||||
file_047=C:\code\bacnet-stack\reject.h
|
||||
file_048=C:\code\bacnet-stack\ringbuf.h
|
||||
file_049=C:\code\bacnet-stack\rs485.h
|
||||
file_050=C:\code\bacnet-stack\demo\object\ai.h
|
||||
file_051=C:\code\bacnet-stack\demo\object\ao.h
|
||||
file_052=C:\code\bacnet-stack\demo\object\device.h
|
||||
file_053=C:\code\bacnet-stack\dcc.h
|
||||
file_054=C:\code\bacnet-stack\bacstr.h
|
||||
file_055=C:\code\bacnet-stack\bacapp.h
|
||||
file_056=18f252.lkr
|
||||
[SUITE_INFO]
|
||||
suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416}
|
||||
suite_state=
|
||||
[TOOL_SETTINGS]
|
||||
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}=
|
||||
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}=/m"$(BINDIR_)$(TARGETBASE).map" /o"$(TARGETBASE).cof"
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DBACDL_MSTP
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}=-DBACDL_MSTP -DTSM_ENABLED=0 -DPRINT_ENABLED=0 -mL
|
||||
TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}=
|
||||
TS{DD2213A8-6310-47B1-8376-9430CDFC013F}001=
|
||||
TS{BFD27FBA-4A02-4C0E-A5E5-B812F3E7707C}001=/o"$(TARGETBASE).cof"
|
||||
@@ -139,6 +145,3 @@ TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}001=-Ou- -Ot- -Ob- -Op- -Or- -Od- -Opa-
|
||||
TS{ADE93A55-C7C7-4D4D-A4BA-59305F7D0391}001=
|
||||
[ACTIVE_FILE_SETTINGS]
|
||||
TS{C2AF05E7-1416-4625-923D-E114DB6E2B96}001_active=yes
|
||||
[TOOL_LOC_STAMPS]
|
||||
tool_loc{96C98149-AA1B-4CF9-B967-FAE79CAB663C}=C:\mcc18\bin\mplink.exe
|
||||
tool_loc{E56A1C86-9D32-4DF6-8C34-FE0388B1B644}=C:\mcc18\bin\mcc18.exe
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,194 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*********************************************************************/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "bacdef.h"
|
||||
#include "mstp.h"
|
||||
#include "dlmstp.h"
|
||||
#include "ringbuf.h"
|
||||
#include "rs485.h"
|
||||
|
||||
#define RB_PACKET_COUNT 2
|
||||
#define RB_PACKET_SIZE sizeof(DLMSTP_PACKET)
|
||||
static RING_BUFFER Receive_Buffer;
|
||||
static char Receive_Data_Store[RB_PACKET_COUNT * RB_PACKET_SIZE];
|
||||
static RING_BUFFER Transmit_Buffer;
|
||||
static char Transmit_Data_Store[RB_PACKET_COUNT * RB_PACKET_SIZE];
|
||||
|
||||
volatile struct mstp_port_struct_t MSTP_Port; /* port data */
|
||||
static uint8_t MSTP_MAC_Address = 0x05; /* local MAC address */
|
||||
DLMSTP_PACKET Temp_Packet;
|
||||
|
||||
void dlmstp_init(void)
|
||||
{
|
||||
Ringbuf_Init(&Receive_Buffer,
|
||||
&Receive_Data_Store[0],
|
||||
RB_PACKET_SIZE,
|
||||
RB_PACKET_COUNT);
|
||||
Ringbuf_Init(&Transmit_Buffer,
|
||||
&Transmit_Data_Store[0],
|
||||
RB_PACKET_SIZE,
|
||||
RB_PACKET_COUNT);
|
||||
RS485_Initialize();
|
||||
MSTP_Init(&MSTP_Port, MSTP_MAC_Address);
|
||||
}
|
||||
|
||||
void dlmstp_cleanup(void)
|
||||
{
|
||||
/* nothing to do for static buffers */
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
{ /* number of bytes of data */
|
||||
bool status;
|
||||
int bytes_sent = 0;
|
||||
|
||||
memmove(&Temp_Packet.address,dest,sizeof(Temp_Packet.address));
|
||||
Temp_Packet.pdu_len = pdu_len;
|
||||
memmove(Temp_Packet.pdu,pdu,sizeof(Temp_Packet.pdu));
|
||||
status = Ringbuf_Put(&Transmit_Buffer, &Temp_Packet);
|
||||
if (status)
|
||||
bytes_sent = pdu_len;
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
/* function for MS/TP to use to get a packet to transmit
|
||||
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 */
|
||||
{
|
||||
bool status;
|
||||
DLMSTP_PACKET *packet;
|
||||
unsigned pdu_len = 0;
|
||||
|
||||
if (!Ringbuf_Empty(&Transmit_Buffer))
|
||||
{
|
||||
packet = Ringbuf_Pop_Front(&Transmit_Buffer);
|
||||
memmove(dest,&packet->address,sizeof(packet->address));
|
||||
pdu_len = packet->pdu_len;
|
||||
memmove(pdu,packet->pdu,sizeof(packet.pdu));
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
void dlmstp_task(void)
|
||||
{
|
||||
RS485_Check_UART_Data(&MSTP_Port);
|
||||
MSTP_Receive_Frame_FSM(&MSTP_Port);
|
||||
|
||||
RS485_Process_Tx_Message();
|
||||
MSTP_Master_Node_FSM(&MSTP_Port);
|
||||
}
|
||||
|
||||
/* called about once a millisecond */
|
||||
void dlmstp_millisecond_timer(void)
|
||||
{
|
||||
MSTP_Millisecond_Timer(&MSTP_Port);
|
||||
}
|
||||
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
/* This function is expecting to be polled. */
|
||||
uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
{
|
||||
DLMSTP_PACKET *packet;
|
||||
|
||||
(void) timeout;
|
||||
/* see if there is a packet available */
|
||||
if (!Ringbuf_Empty(&Receive_Buffer))
|
||||
{
|
||||
packet = (char *)Ringbuf_Pop_Front(&Receive_Buffer);
|
||||
memmove(src,&packet->address,sizeof(packet->address));
|
||||
pdu_len = packet->pdu_len;
|
||||
memmove(pdu,packet->pdu,max_pdu);
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
/* for the MS/TP state machine to use for putting received data */
|
||||
uint16_t dlmstp_put_receive(BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t pdu_len)
|
||||
{
|
||||
bool status;
|
||||
int bytes_put = 0;
|
||||
|
||||
memmove(&Temp_Packet.address,src,sizeof(Temp_Packet.address));
|
||||
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)
|
||||
{
|
||||
/* FIXME: Master Nodes can only have address 1-127 */
|
||||
MSTP_MAC_Address = mac_address;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_get_my_address(BACNET_ADDRESS * my_address)
|
||||
{
|
||||
my_address->mac_len = 1;
|
||||
my_address->mac[0] = MSTP_MAC_Address;
|
||||
my_address->net = 0; /* local only, no routing */
|
||||
my_address->len = 0;
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
my_address->adr[i] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest)
|
||||
{ /* destination address */
|
||||
int i = 0; /* counter */
|
||||
|
||||
if (dest) {
|
||||
dest->mac_len = 1;
|
||||
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
|
||||
dest->net = BACNET_BROADCAST_NETWORK;
|
||||
dest->len = 0; /* len=0 denotes broadcast address */
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
dest->adr[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
+127
-13
@@ -32,10 +32,102 @@
|
||||
#include "ringbuf.h"
|
||||
#include "init.h"
|
||||
#include "timer.h"
|
||||
#include "datalink.h"
|
||||
#include "handlers.h"
|
||||
#include "device.h"
|
||||
#include "hardware.h"
|
||||
#include "iam.h"
|
||||
/* for readproperty handler */
|
||||
#include "config.h"
|
||||
#include "txbuf.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacerror.h"
|
||||
#include "apdu.h"
|
||||
#include "npdu.h"
|
||||
#include "abort.h"
|
||||
#include "rp.h"
|
||||
|
||||
/* buffer used for encoding RP apdu */
|
||||
static uint8_t Temp_Buf[MAX_APDU];
|
||||
/* buffer used for receiving */
|
||||
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||
/* address where message came from */
|
||||
static BACNET_ADDRESS src;
|
||||
/* address used to send */
|
||||
static BACNET_ADDRESS my_address;
|
||||
|
||||
/* see demo/handler/h_rp.c for a more complete example */
|
||||
void My_Read_Property_Handler(uint8_t * service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
||||
{
|
||||
BACNET_READ_PROPERTY_DATA data;
|
||||
int len = 0;
|
||||
int pdu_len = 0;
|
||||
bool send = false;
|
||||
bool error = false;
|
||||
int bytes_sent = 0;
|
||||
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
|
||||
len = rp_decode_service_request(service_request, service_len, &data);
|
||||
/* prepare a reply */
|
||||
datalink_get_my_address(&my_address);
|
||||
/* encode the NPDU portion of the packet */
|
||||
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */
|
||||
MESSAGE_PRIORITY_NORMAL);
|
||||
/* bad decoding - send an abort */
|
||||
if (len == -1) {
|
||||
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER);
|
||||
send = true;
|
||||
} else if (service_data->segmented_message) {
|
||||
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
||||
send = true;
|
||||
} else {
|
||||
switch (data.object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
/* FIXME: probably need a length limitation sent with encode */
|
||||
if (data.object_instance == Device_Object_Instance_Number()) {
|
||||
len = Device_Encode_Property_APDU(&Temp_Buf[0],
|
||||
data.object_property,
|
||||
data.array_index, &error_class, &error_code);
|
||||
if (len >= 0) {
|
||||
/* encode the APDU portion of the packet */
|
||||
data.application_data = &Temp_Buf[0];
|
||||
data.application_data_len = len;
|
||||
/* FIXME: probably need a length limitation sent with encode */
|
||||
pdu_len +=
|
||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer
|
||||
[pdu_len], service_data->invoke_id, &data);
|
||||
send = true;
|
||||
} else
|
||||
error = true;
|
||||
} else
|
||||
error = true;
|
||||
break;
|
||||
default:
|
||||
error = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
|
||||
send = true;
|
||||
}
|
||||
if (send) {
|
||||
bytes_sent = datalink_send_pdu(src, /* destination address */
|
||||
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
volatile struct mstp_port_struct_t MSTP_Port; /* port data */
|
||||
static uint8_t MSTP_MAC_Address = 0x05; /* local MAC address */
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Handles our calling our module level milisecond counters
|
||||
@@ -48,34 +140,56 @@ static void Check_Timer_Milliseconds(void)
|
||||
{
|
||||
/* We might have missed some so keep doing it until we have got them all */
|
||||
while (Milliseconds) {
|
||||
MSTP_Millisecond_Timer(&MSTP_Port);
|
||||
dlmstp_millisecond_timer();
|
||||
Milliseconds--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main(void)
|
||||
{
|
||||
init_hardware();
|
||||
RS485_Initialize();
|
||||
MSTP_Init(&MSTP_Port, MSTP_MAC_Address);
|
||||
unsigned timeout = 100; /* milliseconds */
|
||||
uint16_t pdu_len = 0;
|
||||
|
||||
|
||||
/* we need to handle who-is
|
||||
to support dynamic device binding to us */
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
|
||||
handler_who_is);
|
||||
/* set the handler for all the services we don't implement
|
||||
It is required to send the proper reject message... */
|
||||
apdu_set_unrecognized_service_handler_handler
|
||||
(handler_unrecognized_service);
|
||||
/* we must implement read property - it's required! */
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
handler_read_property);
|
||||
/* handle communication so we can shutup when asked */
|
||||
apdu_set_confirmed_handler
|
||||
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||
handler_device_communication_control);
|
||||
|
||||
Device_Set_Object_Instance_Number(5);
|
||||
dlmstp_set_my_address(0x05);
|
||||
dlmstp_init();
|
||||
|
||||
init_hardware();
|
||||
|
||||
/* broadcast an I-Am on startup */
|
||||
iam_send(&Handler_Transmit_Buffer[0]);
|
||||
/* loop forever */
|
||||
for (;;) {
|
||||
WATCHDOG_TIMER();
|
||||
|
||||
/* input */
|
||||
Check_Timer_Milliseconds();
|
||||
/* note: also called by RS-485 Receive ISR */
|
||||
RS485_Check_UART_Data(&MSTP_Port);
|
||||
MSTP_Receive_Frame_FSM(&MSTP_Port);
|
||||
dlmstp_task();
|
||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||
|
||||
/* process */
|
||||
|
||||
if (pdu_len) {
|
||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||
}
|
||||
|
||||
/* output */
|
||||
RS485_Process_Tx_Message();
|
||||
MSTP_Master_Node_FSM(&MSTP_Port);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@
|
||||
|
||||
/* declare space for the TSM transactions, and set it up in the init. */
|
||||
/* table rules: an Invoke ID = 0 is an unused spot in the table */
|
||||
static BACNET_TSM_DATA TSM_List[MAX_TSM_TRANSACTIONS] = { {0} };
|
||||
static BACNET_TSM_DATA TSM_List[MAX_TSM_TRANSACTIONS];
|
||||
|
||||
/* returns MAX_TSM_TRANSACTIONS if not found */
|
||||
static uint8_t tsm_find_invokeID_index(uint8_t invokeID)
|
||||
|
||||
Reference in New Issue
Block a user