From aba682950a8b93c17380d829b7558e1841b3b6ab Mon Sep 17 00:00:00 2001 From: skarg Date: Thu, 10 Aug 2006 21:12:01 +0000 Subject: [PATCH] Getting the PIC port to function with MS/TP. --- bacnet-stack/dlmstp.c | 92 ---------- bacnet-stack/dlmstp.h | 18 +- bacnet-stack/ports/pic18/BACnet-Server.mcp | 131 ++++++++++++++ bacnet-stack/ports/pic18/BACnet-Server.mcw | Bin 0 -> 32768 bytes bacnet-stack/ports/pic18/bacnet.mcp | 85 ++++----- bacnet-stack/ports/pic18/bacnet.mcw | Bin 28160 -> 29184 bytes bacnet-stack/ports/pic18/dlmstp.c | 194 +++++++++++++++++++++ bacnet-stack/ports/pic18/main.c | 140 +++++++++++++-- bacnet-stack/tsm.c | 2 +- 9 files changed, 514 insertions(+), 148 deletions(-) delete mode 100644 bacnet-stack/dlmstp.c create mode 100644 bacnet-stack/ports/pic18/BACnet-Server.mcp create mode 100644 bacnet-stack/ports/pic18/BACnet-Server.mcw create mode 100644 bacnet-stack/ports/pic18/dlmstp.c diff --git a/bacnet-stack/dlmstp.c b/bacnet-stack/dlmstp.c deleted file mode 100644 index 55429d57..00000000 --- a/bacnet-stack/dlmstp.c +++ /dev/null @@ -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 -#include -#include -#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; -} diff --git a/bacnet-stack/dlmstp.h b/bacnet-stack/dlmstp.h index 850c5d28..a3eddd4e 100644 --- a/bacnet-stack/dlmstp.h +++ b/bacnet-stack/dlmstp.h @@ -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 */ diff --git a/bacnet-stack/ports/pic18/BACnet-Server.mcp b/bacnet-stack/ports/pic18/BACnet-Server.mcp new file mode 100644 index 00000000..cf4a4372 --- /dev/null +++ b/bacnet-stack/ports/pic18/BACnet-Server.mcp @@ -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}= diff --git a/bacnet-stack/ports/pic18/BACnet-Server.mcw b/bacnet-stack/ports/pic18/BACnet-Server.mcw new file mode 100644 index 0000000000000000000000000000000000000000..c7ac1e2f1018f0d4aad5f2d4b27fc0281a56273f GIT binary patch literal 32768 zcmeHQYiv|S6rOFNykC`;iipe0R)n=cfr3PV0zm@-SuY zeZlvE`+@HV_Xj@!_JRk12Z9HI2ZM)z9|UKEbHERQIXCh!9t+L~j{}bfKMI}zW;>xK1fEuY{0m_%rm9M$RjL*!#ZQ^g7-uxMt%xRwejNhPuNFIr5ptJBCTa1uDSXSEvAfD=`NmFjEyGEmWm( z&1ql~@+o=^HyeoZE7g2e4tX;nu>$2p)}U_^^0`mBhe_O^J)i3`nz<rz~ouZ#wDCfNBwKxXrwjRy2yr@~-evR^`^|1!y z8Ox+q$j>^~R8Re#a5`O$N&Q6Ezn}V^Zp*$N)s8CPNGs6SSYpemLq2zEhMItMA9$|i zwb*bY@;fm;^BmKQlw*-T#q$Q#UqH$_mK`~Br)TK#=3*}AYwfWV@||932)oDOoY?Q1 z%^x4;n4CMyWk^q;tvYjMDf1&&HH34JM)(ZGF^*?EuFqcD6^D2>$D)4d8v<_uuWNT8 z+!5muUyfH6T@%V}IX7durMQk>40;iH%G{rNS&OX0Si~&vj6G({b)Sy*>_<#utvk^LoU`3I3_)xNmb9Vcm7z>nPM#x%DuVSkwLK5PUkJjcv%CN` zwDVOc2X($2PpP#^HP;Q!W7CBL;VirlX?A3Q6@>2XUeOTd^R2(9tFMt#ry7u_*E6!i zT8lO{rxQJ(43*#QklGThJM%}n$~s+V<)aN>jcqrlt+jgU@#}S8+Ssy=_4ut<#}_Y2 zJ+AvIHSBEcz9-PXSPira(1W!2Z@b;%OLbbtBBTSVkAy=m8MN_P9c&qaQ8lSEP`3u- z*Ih$~_tak=`h3L1p^3;`JeRI9;xn!f>t}#D9#hhKRPZ_1zwBU!)|*^l(Q=;>*W#58 z8qc|?-&62?o#OqO!Lu>I>+_~_`ru5dT(mMiTq^u=&{_hQbqPg zjz%UX((&fCZC!uunnLJt0A8?(DY*9zXGFXYpSSgvWzs=B{F93xgJxhy6zY9btfs&V z31Z}hcv6d8Jk(#MXn&4tMBR?34|hn^{ekxv(0#ccKInD`e^jk;>DleXY>I{ zlVJ}_u-*%>4t}fwJ>W#vAS(&{=>yr)`R$emZ(*GNW^T6kzxqHQ(x31dlre@?=$%&5>uirj~5g% zt4)99{PI#?89m-v)uBLjh<6h)n--T;_>G`;r=y9_Y-QZeKh;^W&h8!lBig_F1?TL= zOIMceL3szx)^#wn^fNX_^9r_pFV4SM{$4KH>=>QxsJc3dcE`b_eeKs;N8xAKr#J1u zB=}MM2Byz62Wge6(Z4=?lbWy&LV|!GAP5Kof`A|(2nYg#fFK|U2m*qDARq_`0)l`b zAP5Kof`A|(2nYg#fFK|U2m*qDARq_`0)l`bAP5Kof`A|(2nYg#fFK|U2m*qDARq_` z0)l`bAP5Kof`A|(2nYg#fFK|U2m*qDARq_`0yhJJ=J7|GM*xaPUVlU!V%!lD<3zoP(bc$v7nlS$)9+H;=oD&*R#EywOZXILWIZ;A=stn`*-*IC^ zZ~hy-;Wi*=LucMdSZ^2)kr8DLa8YBFD+4ip80o84&C`+JYND~^AV%HnctfH$H(qZT zdymu+k)9m8vjS!EE>sR_gWd#Pk)RAjhI7Y-GBG}xBzjY?V`Sa#=hR!!m6_xQ!n!Pb!9gwA+y zev#t$i(|)gHsIB`?U0Ev$s{?a?u>J4HFRb@)^iW^=5cVcw15Hb3j+b4RuD$RM?_Db z&u4_nD{JQ!m(b);`p+5w literal 0 HcmV?d00001 diff --git a/bacnet-stack/ports/pic18/bacnet.mcp b/bacnet-stack/ports/pic18/bacnet.mcp index 5f98f1d8..df2429fe 100644 --- a/bacnet-stack/ports/pic18/bacnet.mcp +++ b/bacnet-stack/ports/pic18/bacnet.mcp @@ -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 diff --git a/bacnet-stack/ports/pic18/bacnet.mcw b/bacnet-stack/ports/pic18/bacnet.mcw index f64e23bab764b898ae67277f962c96168854e12c..fd4051421ed7660f312ceb7fb996cf0b0d1a2a32 100644 GIT binary patch delta 2388 zcmd^A?Qc_67=LbC+ODv-xtqWG;4)3x=^0y^}@2eFTWMEu-c2+G2LK_*lvRnGH(gvtofo*^b*beLfb^^PADOPPrG#r8y0(t-$2m=w|Fc1Y4 zU}}1LI*z#)NB~EGqrfrXMIgy8X&$rcA-Us9B(9hs`9!}gDYhPef~Cw$^8->(*cCZU>6V$@Xw_cR#aO#>sXe8?N_K$=KXvTWT_lYrBiks4QeEG~h;%}SM2gvEgqV+rq+nOuaJc?H=9}Qs zoqzhcybghbn5SVIz)WPJb%wztEoM6wZqb}u&Q2|C)DATbv!51LRA8o)*oOPJ#mQcN zaWM=)&7WrV^tjFstALg2mN4g{r&br#mrxhHFDw{Lx(pWT!OU5;y1^vhoO-lFi^?-+ ze16e+LCgAcD+~R&yfW>lZaP3V3KFHye-w3n3))SijIqAvPMuAPW?Me@|O=|Mnw>jzp zz4e~$4rhxLUB^CcD>EML3`o5;|60~>Ud^s~^@S@C&#~F-4+kW#PelEgwxeOA75nDZ zy11c%MzH_Sfy*CRl7WfRB)4DRV^I$`_hU4IdX!vy#cU zcI0lRjzQzFT1Q^La@ea7uRySK>g?e5%z8U{V71;R)P0ye=PMJ2S*NcwpKkHiCVIoh z@Bc76?Xwizw+Y0p_mR095m<8HvQ@*JMW;(Qs0X%bCLwPl{-9iEcYIY<{Ds5uHo7h! zTe@)1Ob*&i^`6FfPi>XSDJo)<*b@m!P5x*&6kBDK|~8MW2f403}k`tUqTIMOOA z{va$aF{HTVdXHO{K+bB-i7+%rND`x*oKVTtribsxdPi7R_|Bwghshn0WQ23Xo1@tR z%q7dLuQD~YW)oB){G3)jo2=C>?~cn*osLY^GB0IzqJ8HR^`2Or9FPJ?!^`LpBT76f zL4%`7Ivkf|zZ77j?ORvP5g+2srxkeXif6;k4>m7Uqqn9gn{i$`Q+kcG*KnqDO=W;2 ze0##=1$=Z6njhaBFVKyvag;iVGkVd`etg}QcT_%lZL+=#jl=N@T13#zwTTxs38Oyz rOIsOJME@bYQsn*J2W&w$sHx+RSF+uV-yGsw>1o_V}epMOz@EbYBrF^C@osGWsH`U%+IwX z5|?Gkz}pyO4VlhFjd4y(48F1%B_R&n{(z{F`DDowkc^3DgN=I5?Z>u66aVlZPkQe? z_uTWi=XcKi8lGX{X?Ai_Vk__0Z(=WMy=gFIhxq?Z!tL+JN^#nHXKC^7{I6K|m zj&8rrRg5P)xI-^%@*1AyP5Nxdw@@TG7y$kR{i%5rBq_mf0wY{=ov}{h-YH}jn434l zVb4_Xc6J=dmJjRg8d;OgXZ2e(8x6U9Lvo2$96X#XhwuQB(OEc8stcosJCLVn<0xOH zJY=TX5d0dM3{HJ886^G~%FH-swEJ-e7*cO^?vh!^UhYrW)2-ztS?JL8>GP98Qq85! zkQ{=8hyK~28y!`u!K#se4SA2`#)K2bg_kKjz!6pN*0Va)RRakBLJ=o|y&3f>W@Nz( z5iNfrB~A0ylU3ZG(zh%5g};YbZm$YXyz}uix#&d`+P{J8Eb79g>mlOH(48CCILVL( zkO#0pnQl;VB=HAR@0GrOi62hgsqxlE`S++L{ z+~9={=mtO7VyBGTnH13SrL=CH+Rib*=_LSQV1bG+0C(jqh0$LQd7?p_Y;+ zviWdgy>bz4h{g~kIdTSu7ZbpF^icsE0hWhyJ^GWGgH&%2$rJVts6(kd4+wOWf8r}( zQU0UPYATbAiW5>DD8Py zXKB_eD4=l`-$ezcH1>xXcEH^{vQ1Lc%pj;60`js4E zKX;3r=aEbpQSHX`>a#^%s)=XfGx0wX%e1#siwQp?nRdku`AQA$5)Fneh`wPv^7>`1!&>V|J15C+OgGX RJcY1K@y`uavC@on>@VXD7FPfO diff --git a/bacnet-stack/ports/pic18/dlmstp.c b/bacnet-stack/ports/pic18/dlmstp.c new file mode 100644 index 00000000..26bdf0d1 --- /dev/null +++ b/bacnet-stack/ports/pic18/dlmstp.c @@ -0,0 +1,194 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* 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 +#include +#include +#include +#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; +} diff --git a/bacnet-stack/ports/pic18/main.c b/bacnet-stack/ports/pic18/main.c index cf2ef1ae..14ed3362 100644 --- a/bacnet-stack/ports/pic18/main.c +++ b/bacnet-stack/ports/pic18/main.c @@ -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); } diff --git a/bacnet-stack/tsm.c b/bacnet-stack/tsm.c index 6f765688..bd523851 100644 --- a/bacnet-stack/tsm.c +++ b/bacnet-stack/tsm.c @@ -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)