diff --git a/bacnet-stack/.svn/README.txt b/bacnet-stack/.svn/README.txt deleted file mode 100644 index 271a8ce9..00000000 --- a/bacnet-stack/.svn/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -This is a Subversion working copy administrative directory. -Visit http://subversion.tigris.org/ for more information. diff --git a/bacnet-stack/.svn/empty-file b/bacnet-stack/.svn/empty-file deleted file mode 100644 index e69de29b..00000000 diff --git a/bacnet-stack/.svn/entries b/bacnet-stack/.svn/entries deleted file mode 100644 index 7a4728e7..00000000 --- a/bacnet-stack/.svn/entries +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bacnet-stack/.svn/format b/bacnet-stack/.svn/format deleted file mode 100644 index b8626c4c..00000000 --- a/bacnet-stack/.svn/format +++ /dev/null @@ -1 +0,0 @@ -4 diff --git a/bacnet-stack/.svn/prop-base/Makefile.svn-base b/bacnet-stack/.svn/prop-base/Makefile.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/Makefile.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/bytes.h.svn-base b/bacnet-stack/.svn/prop-base/bytes.h.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/bytes.h.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/crc.c.svn-base b/bacnet-stack/.svn/prop-base/crc.c.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/crc.c.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/crc.h.svn-base b/bacnet-stack/.svn/prop-base/crc.h.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/crc.h.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/crc.ide.svn-base b/bacnet-stack/.svn/prop-base/crc.ide.svn-base deleted file mode 100644 index 5e9587e6..00000000 --- a/bacnet-stack/.svn/prop-base/crc.ide.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 24 -application/octet-stream -END diff --git a/bacnet-stack/.svn/prop-base/main.c.svn-base b/bacnet-stack/.svn/prop-base/main.c.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/main.c.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/mstp.c.svn-base b/bacnet-stack/.svn/prop-base/mstp.c.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/mstp.c.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/mstp.h.svn-base b/bacnet-stack/.svn/prop-base/mstp.h.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/mstp.h.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/mstp.ide.svn-base b/bacnet-stack/.svn/prop-base/mstp.ide.svn-base deleted file mode 100644 index 5e9587e6..00000000 --- a/bacnet-stack/.svn/prop-base/mstp.ide.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 24 -application/octet-stream -END diff --git a/bacnet-stack/.svn/prop-base/ringbuf.c.svn-base b/bacnet-stack/.svn/prop-base/ringbuf.c.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/ringbuf.c.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/ringbuf.h.svn-base b/bacnet-stack/.svn/prop-base/ringbuf.h.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/ringbuf.h.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/rs485.h.svn-base b/bacnet-stack/.svn/prop-base/rs485.h.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/rs485.h.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/stdbool.h.svn-base b/bacnet-stack/.svn/prop-base/stdbool.h.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/stdbool.h.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/stdint.h.svn-base b/bacnet-stack/.svn/prop-base/stdint.h.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/prop-base/stdint.h.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/prop-base/test.sh.svn-base b/bacnet-stack/.svn/prop-base/test.sh.svn-base deleted file mode 100644 index 869ac71c..00000000 --- a/bacnet-stack/.svn/prop-base/test.sh.svn-base +++ /dev/null @@ -1,5 +0,0 @@ -K 14 -svn:executable -V 1 -* -END diff --git a/bacnet-stack/.svn/props/Makefile.svn-work b/bacnet-stack/.svn/props/Makefile.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/Makefile.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/bytes.h.svn-work b/bacnet-stack/.svn/props/bytes.h.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/bytes.h.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/crc.c.svn-work b/bacnet-stack/.svn/props/crc.c.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/crc.c.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/crc.h.svn-work b/bacnet-stack/.svn/props/crc.h.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/crc.h.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/crc.ide.svn-work b/bacnet-stack/.svn/props/crc.ide.svn-work deleted file mode 100644 index 5e9587e6..00000000 --- a/bacnet-stack/.svn/props/crc.ide.svn-work +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 24 -application/octet-stream -END diff --git a/bacnet-stack/.svn/props/main.c.svn-work b/bacnet-stack/.svn/props/main.c.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/main.c.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/mstp.c.svn-work b/bacnet-stack/.svn/props/mstp.c.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/mstp.c.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/mstp.h.svn-work b/bacnet-stack/.svn/props/mstp.h.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/mstp.h.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/mstp.ide.svn-work b/bacnet-stack/.svn/props/mstp.ide.svn-work deleted file mode 100644 index 5e9587e6..00000000 --- a/bacnet-stack/.svn/props/mstp.ide.svn-work +++ /dev/null @@ -1,5 +0,0 @@ -K 13 -svn:mime-type -V 24 -application/octet-stream -END diff --git a/bacnet-stack/.svn/props/ringbuf.c.svn-work b/bacnet-stack/.svn/props/ringbuf.c.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/ringbuf.c.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/ringbuf.h.svn-work b/bacnet-stack/.svn/props/ringbuf.h.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/ringbuf.h.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/rs485.h.svn-work b/bacnet-stack/.svn/props/rs485.h.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/rs485.h.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/stdbool.h.svn-work b/bacnet-stack/.svn/props/stdbool.h.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/stdbool.h.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/stdint.h.svn-work b/bacnet-stack/.svn/props/stdint.h.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/.svn/props/stdint.h.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/.svn/props/test.sh.svn-work b/bacnet-stack/.svn/props/test.sh.svn-work deleted file mode 100644 index 869ac71c..00000000 --- a/bacnet-stack/.svn/props/test.sh.svn-work +++ /dev/null @@ -1,5 +0,0 @@ -K 14 -svn:executable -V 1 -* -END diff --git a/bacnet-stack/.svn/text-base/Makefile.svn-base b/bacnet-stack/.svn/text-base/Makefile.svn-base deleted file mode 100644 index a555ed31..00000000 --- a/bacnet-stack/.svn/text-base/Makefile.svn-base +++ /dev/null @@ -1,29 +0,0 @@ -#Makefile to build BACnet Application -CC = gcc -BASEDIR = . -#CFLAGS = -Wall -I. -# -g for debugging with gdb -#CFLAGS = -Wall -I. -g -CFLAGS = -Wall -I. -Itest -g - -OBJS = main.o mstp.o crc.o ringbuf.o ports/linux/rs485.o - -TARGET = bacnet - -all: ${TARGET} - -${TARGET}: ${OBJS} - ${CC} -o $@ ${OBJS} - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini - -include: .depend - diff --git a/bacnet-stack/.svn/text-base/bytes.h.svn-base b/bacnet-stack/.svn/text-base/bytes.h.svn-base deleted file mode 100644 index 97dce0bd..00000000 --- a/bacnet-stack/.svn/text-base/bytes.h.svn-base +++ /dev/null @@ -1,42 +0,0 @@ -// Defines the bit/byte/word/long conversions that are used in code - -#ifndef BYTES_H -#define BYTES_H - -#include - -#ifndef LO_NIB - #define LO_NIB(b) ((b) & 0xF) -#endif - -#ifndef HI_NIB - #define HI_NIB(b) ((b) >> 4) -#endif - -#ifndef LO_BYTE - #define LO_BYTE(w) ((uint8_t)(w)) -#endif - -#ifndef HI_BYTE - #define HI_BYTE(w) ((uint8_t)((uint16_t)(w) >> 8)) -#endif - -#ifndef LO_WORD - #define LO_WORD(x) ((uint16_t)(x)) -#endif - -#ifndef HI_WORD - #define HI_WORD(x) ((uint16_t)((uint32_t)(x) >> 16)) -#endif - -#ifndef MAKE_WORD - #define MAKE_WORD(lo,hi) \ - ((uint16_t)(((uint8_t)(lo))|(((uint16_t)((uint8_t)(hi)))<<8))) -#endif - -#ifndef MAKE_LONG - #define MAKE_LONG(lo,hi) \ - ((uint32_t)(((uint16_t)(lo))|(((uint32_t)((uint16_t)(hi)))<<16))) -#endif - -#endif // end of header file diff --git a/bacnet-stack/.svn/text-base/crc.c.svn-base b/bacnet-stack/.svn/text-base/crc.c.svn-base deleted file mode 100644 index 6c429155..00000000 --- a/bacnet-stack/.svn/text-base/crc.c.svn-base +++ /dev/null @@ -1,153 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 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 - -// Accumulate "dataValue" into the CRC in crcValue. -// Return value is updated CRC -// -// The ^ operator means exclusive OR. -// Note: This function is copied directly from the BACnet standard. -uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue) -{ - uint16_t crc; - - crc = crcValue ^ dataValue; /* XOR C7..C0 with D7..D0 */ - - /* Exclusive OR the terms in the table (top down) */ - crc = crc ^ (crc << 1) ^ (crc << 2) ^ (crc << 3) - ^ (crc << 4) ^ (crc << 5) ^ (crc << 6) - ^ (crc << 7); - - /* Combine bits shifted out left hand end */ - return (crc & 0xfe) ^ ((crc >> 8) & 1); -} - -// Accumulate "dataValue" into the CRC in crcValue. -// Return value is updated CRC -// -// The ^ operator means exclusive OR. -// Note: This function is copied directly from the BACnet standard. -uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue) -{ - uint16_t crcLow; - - crcLow = (crcValue & 0xff) ^ dataValue; /* XOR C7..C0 with D7..D0 */ - - /* Exclusive OR the terms in the table (top down) */ - return (crcValue >>8) ^ (crcLow << 8) ^ (crcLow <<3) - ^ (crcLow <<12) ^ (crcLow >> 4) - ^ (crcLow & 0x0f) ^ ((crcLow & 0x0f) << 7); -} - -#ifdef TEST -#include -#include -#include "ctest.h" -#include "bytes.h" - -// test from Annex G 1.0 of BACnet Standard -void testCRC8(Test* pTest) -{ - uint8_t crc = 0xff; // accumulates the crc value - uint8_t frame_crc; // appended to the end of the frame - - crc = CRC_Calc_Header(0x00,crc); - ct_test(pTest,crc == 0x55); - crc = CRC_Calc_Header(0x10,crc); - ct_test(pTest,crc == 0xC2); - crc = CRC_Calc_Header(0x05,crc); - ct_test(pTest,crc == 0xBC); - crc = CRC_Calc_Header(0x00,crc); - ct_test(pTest,crc == 0x95); - crc = CRC_Calc_Header(0x00,crc); - ct_test(pTest,crc == 0x73); - // send the ones complement of the CRC in place of - // the CRC, and the resulting CRC will always equal 0x55. - frame_crc = ~crc; - ct_test(pTest,frame_crc == 0x8C); - // use the ones complement value and the next to last CRC value - crc = CRC_Calc_Header(frame_crc,crc); - ct_test(pTest,crc == 0x55); -} - -// test from Annex G 2.0 of BACnet Standard -void testCRC16(Test* pTest) -{ - uint16_t crc = 0xffff; - uint16_t data_crc; - - crc = CRC_Calc_Data(0x01,crc); - ct_test(pTest,crc == 0x1E0E); - crc = CRC_Calc_Data(0x22,crc); - ct_test(pTest,crc == 0xEB70); - crc = CRC_Calc_Data(0x30,crc); - ct_test(pTest,crc == 0x42EF); - // send the ones complement of the CRC in place of - // the CRC, and the resulting CRC will always equal 0xF0B8. - data_crc = ~crc; - ct_test(pTest,data_crc == 0xBD10); - crc = CRC_Calc_Data(LO_BYTE(data_crc),crc); - ct_test(pTest,crc == 0x0F3A); - crc = CRC_Calc_Data(HI_BYTE(data_crc),crc); - ct_test(pTest,crc == 0xF0B8); -} - -#endif - -#ifdef TEST_CRC -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("crc", NULL); - - /* individual tests */ - rc = ct_addTestFunction(pTest, testCRC8); - assert(rc); - rc = ct_addTestFunction(pTest, testCRC16); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); - - ct_destroy(pTest); - - return 0; -} -#endif diff --git a/bacnet-stack/.svn/text-base/crc.h.svn-base b/bacnet-stack/.svn/text-base/crc.h.svn-base deleted file mode 100644 index afc0d6d4..00000000 --- a/bacnet-stack/.svn/text-base/crc.h.svn-base +++ /dev/null @@ -1,44 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 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####*/ -#ifndef CRC_H -#define CRC_H - -#include -#include - -uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue); -uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue); - -#endif diff --git a/bacnet-stack/.svn/text-base/crc.ide.svn-base b/bacnet-stack/.svn/text-base/crc.ide.svn-base deleted file mode 100644 index d7b2030c..00000000 Binary files a/bacnet-stack/.svn/text-base/crc.ide.svn-base and /dev/null differ diff --git a/bacnet-stack/.svn/text-base/crc.mak.svn-base b/bacnet-stack/.svn/text-base/crc.mak.svn-base deleted file mode 100644 index e5bb862f..00000000 --- a/bacnet-stack/.svn/text-base/crc.mak.svn-base +++ /dev/null @@ -1,29 +0,0 @@ -#Makefile to build CRC tests -CC = gcc -BASEDIR = . -#CFLAGS = -Wall -I. -# -g for debugging with gdb -#CFLAGS = -Wall -I. -g -CFLAGS = -Wall -I. -Itest -DTEST -DTEST_CRC -g - -OBJS = crc.o test/ctest.o - -TARGET = crc - -all: ${TARGET} - -${TARGET}: ${OBJS} - ${CC} -o $@ ${OBJS} - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini - -include: .depend - diff --git a/bacnet-stack/.svn/text-base/main.c.svn-base b/bacnet-stack/.svn/text-base/main.c.svn-base deleted file mode 100644 index c54fdc5b..00000000 --- a/bacnet-stack/.svn/text-base/main.c.svn-base +++ /dev/null @@ -1,63 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 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 "mstp.h" -#include "bytes.h" -#include "crc.h" -#include "rs485.h" -#include "ringbuf.h" - -void main(void) -{ - struct mstp_port_struct_t mstp_port; // port data - uint8_t my_mac = 0x05; // local MAC address - - MSTP_Init(&mstp_port,my_mac); - - // loop forever - for (;;) - { - // input - RS485_Check_UART_Data(&mstp_port); - MSTP_Receive_Frame_FSM(&mstp_port); - // process - - // output - MSTP_Master_Node_FSM(&mstp_port); - - } -} diff --git a/bacnet-stack/.svn/text-base/mstp.c.svn-base b/bacnet-stack/.svn/text-base/mstp.c.svn-base deleted file mode 100644 index a1214073..00000000 --- a/bacnet-stack/.svn/text-base/mstp.c.svn-base +++ /dev/null @@ -1,1671 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2003 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####*/ - -// This clause describes a Master-Slave/Token-Passing (MS/TP) data link -// protocol, which provides the same services to the network layer as -// ISO 8802-2 Logical Link Control. It uses services provided by the -// EIA-485 physical layer. Relevant clauses of EIA-485 are deemed to be -// included in this standard by reference. The following hardware is assumed: -// (a) A UART (Universal Asynchronous Receiver/Transmitter) capable of -// transmitting and receiving eight data bits with one stop bit -// and no parity. -// (b) An EIA-485 transceiver whose driver may be disabled. -// (c) A timer with a resolution of five milliseconds or less - -#include -#include -#include "mstp.h" -#include "bytes.h" -#include "crc.h" -#include "rs485.h" -#include "ringbuf.h" - -// MS/TP Frame Format -// All frames are of the following format: -// -// Preamble: two octet preamble: X`55', X`FF' -// Frame Type: one octet -// Destination Address: one octet address -// Source Address: one octet address -// Length: two octets, most significant octet first, of the Data field -// Header CRC: one octet -// Data: (present only if Length is non-zero) -// Data CRC: (present only if Length is non-zero) two octets, -// least significant octet first -// (pad): (optional) at most one octet of padding: X'FF' - - // The number of tokens received or used before a Poll For Master cycle -// is executed: 50. -const unsigned Npoll = 50; - -// The number of retries on sending Token: 1. -const unsigned Nretry_token = 1; - -// The minimum number of DataAvailable or ReceiveError events that must be -// seen by a receiving node in order to declare the line "active": 4. -const unsigned Nmin_octets = 4; - -// The minimum time without a DataAvailable or ReceiveError event within -// a frame before a receiving node may discard the frame: 60 bit times. -// (Implementations may use larger values for this timeout, -// not to exceed 100 milliseconds.) -// At 9600 baud, 60 bit times would be about 6.25 milliseconds -const unsigned Tframe_abort = 1 + ((1000 * 60) / 9600); - -// The maximum idle time a sending node may allow to elapse between octets -// of a frame the node is transmitting: 20 bit times. -const unsigned Tframe_gap = 20; - -// The time without a DataAvailable or ReceiveError event before declaration -// of loss of token: 500 milliseconds. -const unsigned Tno_token = 500; - -// The maximum time after the end of the stop bit of the final -// octet of a transmitted frame before a node must disable its -// EIA-485 driver: 15 bit times. -const unsigned Tpostdrive = 15; - -// The maximum time a node may wait after reception of a frame that expects -// a reply before sending the first octet of a reply or Reply Postponed -// frame: 250 milliseconds. -const unsigned Treply_delay = 225; - -// The minimum time without a DataAvailable or ReceiveError event -// that a node must wait for a station to begin replying to a -// confirmed request: 255 milliseconds. (Implementations may use -// larger values for this timeout, not to exceed 300 milliseconds.) -const unsigned Treply_timeout = 255; - -// Repeater turnoff delay. The duration of a continuous logical one state -// at the active input port of an MS/TP repeater after which the repeater -// will enter the IDLE state: 29 bit times < Troff < 40 bit times. -const unsigned Troff = 30; - -// The width of the time slot within which a node may generate a token: -// 10 milliseconds. -const unsigned Tslot = 10; - -// The maximum time a node may wait after reception of the token or -// a Poll For Master frame before sending the first octet of a frame: -// 15 milliseconds. -const unsigned Tusage_delay = 15; - -// The minimum time without a DataAvailable or ReceiveError event that a -// node must wait for a remote node to begin using a token or replying to -// a Poll For Master frame: 20 milliseconds. (Implementations may use -// larger values for this timeout, not to exceed 100 milliseconds.) -const unsigned Tusage_timeout = 20; - -// Millisecond Timer - called every millisecond -void MSTP_Millisecond_Timer(struct mstp_port_struct_t *mstp_port) -{ - if (mstp_port->SilenceTimer < 255) - mstp_port->SilenceTimer++; - if (mstp_port->ReplyPostponedTimer < 255) - mstp_port->ReplyPostponedTimer++; - - return; -} - -void MSTP_Receive_Frame_FSM(struct mstp_port_struct_t *mstp_port) -{ - switch (mstp_port->receive_state) - { - // In the IDLE state, the node waits for the beginning of a frame. - case MSTP_RECEIVE_STATE_IDLE: - // EatAnError - if (mstp_port->ReceiveError == TRUE) - { - mstp_port->ReceiveError = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else - { - if (mstp_port->DataAvailable == TRUE) - { - // Preamble1 - if (mstp_port->DataRegister == 0x55) - { - mstp_port->DataAvailable = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // receive the remainder of the frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; - } - // EatAnOctet - else - { - mstp_port->DataAvailable = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - } - break; - // In the PREAMBLE state, the node waits for the second octet of the preamble. - case MSTP_RECEIVE_STATE_PREAMBLE: - // Timeout - if (mstp_port->SilenceTimer > Tframe_abort) - { - // a correct preamble has not been received - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - - // Error - else if (mstp_port->ReceiveError == TRUE) - { - mstp_port->ReceiveError = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else - { - if (mstp_port->DataAvailable == TRUE) - { - // Preamble2 - if (mstp_port->DataRegister == 0xFF) - { - mstp_port->DataAvailable = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->Index = 0; - mstp_port->HeaderCRC = 0xFF; - // receive the remainder of the frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // ignore RepeatedPreamble1 - else if (mstp_port->DataRegister == 0x55) - { - mstp_port->DataAvailable = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the second preamble octet. - mstp_port->receive_state = MSTP_RECEIVE_STATE_PREAMBLE; - } - // NotPreamble - else - { - mstp_port->DataAvailable = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - } - break; - // In the HEADER state, the node waits for the fixed message header. - case MSTP_RECEIVE_STATE_HEADER: - // Timeout - if (mstp_port->SilenceTimer > Tframe_abort) - { - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - - // Error - else if (mstp_port->ReceiveError == TRUE) - { - mstp_port->ReceiveError = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else if (mstp_port->DataAvailable == TRUE) - { - // FrameType - if (mstp_port->Index == 0) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->FrameType = mstp_port->DataRegister; - mstp_port->DataAvailable = FALSE; - mstp_port->Index = 1; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // Destination - else if (mstp_port->Index == 1) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DestinationAddress = mstp_port->DataRegister; - mstp_port->DataAvailable = FALSE; - mstp_port->Index = 2; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // Source - else if (mstp_port->Index == 2) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->SourceAddress = mstp_port->DataRegister; - mstp_port->DataAvailable = FALSE; - mstp_port->Index = 3; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // Length1 - else if (mstp_port->Index == 3) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataLength = mstp_port->DataRegister * 256; - mstp_port->DataAvailable = FALSE; - mstp_port->Index = 4; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // Length2 - else if (mstp_port->Index == 4) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataLength += mstp_port->DataRegister; - mstp_port->DataAvailable = FALSE; - mstp_port->Index = 5; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER; - } - // HeaderCRC - else if (mstp_port->Index == 5) - { - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - mstp_port->HeaderCRC = CRC_Calc_Header( - mstp_port->DataRegister, - mstp_port->HeaderCRC); - mstp_port->DataAvailable = FALSE; - mstp_port->receive_state = MSTP_RECEIVE_STATE_HEADER_CRC; - } - // not per MS/TP standard, but it is a case not covered - else - { - mstp_port->ReceiveError = FALSE; - mstp_port->SilenceTimer = 0; - mstp_port->EventCount++; - // indicate that an error has occurred during - // the reception of a frame - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of a frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - // In the HEADER_CRC state, the node validates the CRC on the fixed - // message header. - case MSTP_RECEIVE_STATE_HEADER_CRC: - // BadCRC - if (mstp_port->HeaderCRC != 0x55) - { - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else - { - if ((mstp_port->DestinationAddress == mstp_port->This_Station) || - (mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS)) - { - // FrameTooLong - if (mstp_port->DataLength > INPUT_BUFFER_SIZE) - { - // indicate that a frame with an illegal or - // unacceptable data length has been received - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // NoData - else if (mstp_port->DataLength == 0) - { - // indicate that a frame with no data has been received - mstp_port->ReceivedValidFrame = TRUE; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // Data - else - { - mstp_port->Index = 0; - mstp_port->DataCRC = 0xFFFF; - // receive the data portion of the frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } - } - // NotForUs - else - { - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - // In the DATA state, the node waits for the data portion of a frame. - case MSTP_RECEIVE_STATE_DATA: - // Timeout - if (mstp_port->SilenceTimer > Tframe_abort) - { - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // Error - else if (mstp_port->ReceiveError == TRUE) - { - mstp_port->ReceiveError = FALSE; - mstp_port->SilenceTimer = 0; - // indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - else if (mstp_port->DataAvailable == TRUE) - { - // DataOctet - if (mstp_port->Index < mstp_port->DataLength) - { - mstp_port->SilenceTimer = 0; - mstp_port->DataCRC = CRC_Calc_Data( - mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->InputBuffer[mstp_port->Index] = mstp_port->DataRegister; - mstp_port->DataAvailable = FALSE; - mstp_port->Index++; - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } - // CRC1 - else if (mstp_port->Index == mstp_port->DataLength) - { - mstp_port->SilenceTimer = 0; - mstp_port->DataCRC = CRC_Calc_Data( - mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->DataAvailable = FALSE; - mstp_port->Index++; // Index now becomes the number of data octets - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; - } - // CRC2 - else if (mstp_port->Index == (mstp_port->DataLength + 1)) - { - mstp_port->SilenceTimer = 0; - mstp_port->DataCRC = CRC_Calc_Data( - mstp_port->DataRegister, - mstp_port->DataCRC); - mstp_port->DataAvailable = FALSE; - mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA_CRC; - } - } - break; - // In the DATA_CRC state, the node validates the CRC of the message data. - case MSTP_RECEIVE_STATE_DATA_CRC: - // GoodCRC - if (mstp_port->DataCRC == 0xF0B8) - { - // indicate the complete reception of a valid frame - mstp_port->ReceivedValidFrame = TRUE; - - // now might be a good time to process the message or - // copy the data to a buffer so that we can process the message - - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - // BadCRC - else - { - // to indicate that an error has occurred during the reception of a frame - mstp_port->ReceivedInvalidFrame = TRUE; - // wait for the start of the next frame. - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - } - break; - default: - // shouldn't get here - but if we do... - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - break; - } - - return; -} - -void MSTP_Master_Node_FSM(struct mstp_port_struct_t *mstp_port) -{ - - switch (mstp_port->master_state) - { - case MSTP_MASTER_STATE_INITIALIZE: - // DoneInitializing - mstp_port->This_Station = 0; // FIXME: the node's station address - // indicate that the next station is unknown - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->Poll_Station = mstp_port->This_Station; - // cause a Poll For Master to be sent when this node first - // receives the token - mstp_port->TokenCount = Npoll; - mstp_port->SoleMaster = FALSE; - mstp_port->ReceivedValidFrame = FALSE; - mstp_port->ReceivedInvalidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - break; - // In the IDLE state, the node waits for a frame. - case MSTP_MASTER_STATE_IDLE: - // LostToken - if (mstp_port->SilenceTimer >= Tno_token) - { - // assume that the token has been lost - mstp_port->master_state = MSTP_MASTER_STATE_NO_TOKEN; - } - // mstp_port->ReceivedInvalidFrame - else if (mstp_port->ReceivedInvalidFrame == TRUE) - { - // invalid frame was received - mstp_port->ReceivedInvalidFrame = FALSE; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // ReceivedUnwantedFrame - else if (mstp_port->ReceivedValidFrame == TRUE) - { - if ((mstp_port->DestinationAddress != mstp_port->This_Station) || - (mstp_port->DestinationAddress != MSTP_BROADCAST_ADDRESS)) - { - // an unexpected or unwanted frame was received. - mstp_port->ReceivedValidFrame = FALSE; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // DestinationAddress is equal to 255 (broadcast) and - // FrameType has a value of Token, BACnet Data Expecting Reply, Test_Request, - // or a proprietary type known to this node that expects a reply - // (such frames may not be broadcast), or - else if ((mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS) && - ((mstp_port->FrameType == FRAME_TYPE_TOKEN) || - (mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) || - (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST))) - { - // an unexpected or unwanted frame was received. - mstp_port->ReceivedValidFrame = FALSE; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // FrameType has a value that indicates a standard or proprietary type - // that is not known to this node. - // FIXME: change this if you add a proprietary type - else if /*(*/(mstp_port->FrameType >= FRAME_TYPE_PROPRIETARY_MIN) /*&&*/ - /*(FrameType <= FRAME_TYPE_PROPRIETARY_MAX))*/ - /* unnecessary if FrameType is uint8_t with max of 255 */ - { - // an unexpected or unwanted frame was received. - mstp_port->ReceivedValidFrame = FALSE; - // wait for the next frame - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // ReceivedToken - else if ((mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_TOKEN)) - { - mstp_port->ReceivedValidFrame = FALSE; - mstp_port->FrameCount = 0; - mstp_port->SoleMaster = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // ReceivedPFM - else if ((mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_POLL_FOR_MASTER)) - { - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER, - 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))) - { - // FIXME: indicate successful reception to the higher layers - // i.e. Process this frame! - 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_port->ReceivedValidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_ANSWER_DATA_REQUEST; - } - } - break; - // In the USE_TOKEN state, the node is allowed to send one or - // more data frames. These may be BACnet Data frames or - // proprietary frames. - case MSTP_MASTER_STATE_USE_TOKEN: - // NothingToSend - // FIXME: If there is no data frame awaiting transmission, - { - mstp_port->FrameCount = mstp_port->Nmax_info_frames; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // SendNoWait - // FIXME: If 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, -// { -// // transmit the data frame -// RS485_Send_Frame(?????????????); -// FrameCount++; -// mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; -// } - // SendAndWait - // FIXME: 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, -// { -// // transmit the data frame -// RS485_Send_Frame(); -// FrameCount++; -// mstp_port->master_state = MSTP_MASTER_STATE_WAIT_FOR_REPLY; -// } - // In the WAIT_FOR_REPLY state, the node waits for - // a reply from another node. - case MSTP_MASTER_STATE_WAIT_FOR_REPLY: - // ReplyTimeout - if (mstp_port->SilenceTimer >= Treply_timeout) - { - // assume that the request has failed - mstp_port->FrameCount = mstp_port->Nmax_info_frames; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - // Any retry of the data frame shall await the next entry - // to the USE_TOKEN state. (Because of the length of the timeout, - // this transition will cause the token to be passed regardless - // of the initial value of FrameCount.) - } - // InvalidFrame - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedInvalidFrame == TRUE)) - { - // error in frame reception - mstp_port->ReceivedInvalidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // ReceivedReply - // or a proprietary type that indicates a reply - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == TRUE) && - (mstp_port->DestinationAddress == mstp_port->This_Station) && - ((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) || - //(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || - (mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) - { - // FIXME: indicate successful reception to the higher layers - mstp_port->ReceivedValidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // ReceivedPostpone - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == TRUE) && - (mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_REPLY_POSTPONED)) - { - // FIXME: then the reply to the message has been postponed until a later time. - // So, what does this really mean? - mstp_port->ReceivedValidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; - } - // ReceivedUnexpectedFrame - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == TRUE) && - (mstp_port->DestinationAddress != mstp_port->This_Station)) - //the expected reply should not be broadcast) - { - // an unexpected frame was received - // This may indicate the presence of multiple tokens. - mstp_port->ReceivedValidFrame = FALSE; - // Synchronize with the network. - // This action drops the token. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // ReceivedUnexpectedFrame - else if ((mstp_port->SilenceTimer < Treply_timeout) && - (mstp_port->ReceivedValidFrame == TRUE) && - ((mstp_port->FrameType == FRAME_TYPE_TEST_RESPONSE) || - //(mstp_port->FrameType == FRAME_TYPE_PROPRIETARY_0) || - (mstp_port->FrameType == FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY))) - { - // An unexpected frame was received. - // This may indicate the presence of multiple tokens. - mstp_port->ReceivedValidFrame = FALSE; - // Synchronize with the network. - // This action drops the token. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - break; - // The DONE_WITH_TOKEN state either sends another data frame, - // passes the token, or initiates a Poll For Master cycle. - case MSTP_MASTER_STATE_DONE_WITH_TOKEN: - // SendAnotherFrame - if (mstp_port->FrameCount < mstp_port->Nmax_info_frames) - { - // then this node may send another information frame - // before passing the token. - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // mstp_port->SoleMaster - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount < Npoll) && - (mstp_port->SoleMaster == TRUE)) - { - // there are no other known master nodes to - // which the token may be sent (true master-slave operation). - mstp_port->FrameCount = 0; - mstp_port->TokenCount++; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // SendToken - else if (((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount < Npoll) && - (mstp_port->SoleMaster == FALSE)) || - // 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->Next_Station == - (uint8_t)((mstp_port->This_Station +1) % (mstp_port->Nmax_master + 1)))) - { - mstp_port->TokenCount++; - // transmit a Token frame to NS - RS485_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; - } - // SendMaintenancePFM - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount >= Npoll) && - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) != mstp_port->Next_Station)) - { - mstp_port->Poll_Station = (mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1); - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - // ResetMaintenancePFM - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount >= Npoll) && - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) == mstp_port->Next_Station) && - (mstp_port->SoleMaster == FALSE)) - { - mstp_port->Poll_Station = mstp_port->This_Station; - // transmit a Token frame to NS - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - mstp_port->EventCount = 0; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - // SoleMasterRestartMaintenancePFM - else if ((mstp_port->FrameCount >= mstp_port->Nmax_info_frames) && - (mstp_port->TokenCount >= Npoll) && - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) == mstp_port->Next_Station) && - (mstp_port->SoleMaster == TRUE)) - { - mstp_port->Poll_Station = (mstp_port->Next_Station +1) % (mstp_port->Nmax_master + 1); - RS485_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 = 0; - mstp_port->EventCount = 0; - // 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 token that this node has just attempted to pass. - case MSTP_MASTER_STATE_PASS_TOKEN: - // SawTokenUser - if ((mstp_port->SilenceTimer < Tusage_timeout) && - (mstp_port->EventCount > Nmin_octets)) - { - // Assume that a frame has been sent by the new token user. - // Enter the IDLE state to process the frame. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // RetrySendToken - else if ((mstp_port->SilenceTimer >= Tusage_timeout) && - (mstp_port->RetryCount < Nretry_token)) - { - mstp_port->RetryCount++; - // Transmit a Token frame to NS - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->EventCount = 0; - // re-enter the current state to listen for NS - // to begin using the token. - } - // FindNewSuccessor - else if ((mstp_port->SilenceTimer >= Tusage_timeout) && - (mstp_port->RetryCount >= Nretry_token)) - { - // Assume that NS has failed. - mstp_port->Poll_Station = (mstp_port->Next_Station + 1) % (mstp_port->Nmax_master + 1); - // Transmit a Poll For Master frame to PS. - RS485_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 = 0; - mstp_port->EventCount = 0; - // find a new successor to TS - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - break; - // The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater - // than Tno_token, indicating that there has been no network activity - // for that period of time. The timeout is continued to determine - // whether or not this node may create a token. - case MSTP_MASTER_STATE_NO_TOKEN: - // SawFrame - if ((mstp_port->SilenceTimer < (Tno_token + (Tslot * mstp_port->This_Station))) && - (mstp_port->EventCount > Nmin_octets)) - { - // Some other node exists at a lower address. - // Enter the IDLE state to receive and process the incoming frame. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // GenerateToken - else if ((mstp_port->SilenceTimer >= (Tno_token + (Tslot * mstp_port->This_Station))) && - (mstp_port->SilenceTimer < (Tno_token + (Tslot * (mstp_port->This_Station + 1))))) - { - // Assume that this node is the lowest numerical address - // on the network and is empowered to create a token. - mstp_port->Poll_Station = (mstp_port->This_Station + 1) % (mstp_port->Nmax_master + 1); - // Transmit a Poll For Master frame to PS. - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - // indicate that the next station is unknown - mstp_port->Next_Station = mstp_port->This_Station; - mstp_port->RetryCount = 0; - mstp_port->TokenCount = 0; - mstp_port->EventCount = 0; - // enter the POLL_FOR_MASTER state to find a new successor to TS. - mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER; - } - break; - // In the POLL_FOR_MASTER state, the node listens for a reply to - // a previously sent Poll For Master frame in order to find - // a successor node. - case MSTP_MASTER_STATE_POLL_FOR_MASTER: - // ReceivedReplyToPFM - if ((mstp_port->ReceivedValidFrame == TRUE) && - (mstp_port->DestinationAddress == mstp_port->This_Station) && - (mstp_port->FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) - { - mstp_port->SoleMaster = FALSE; - mstp_port->Next_Station = mstp_port->SourceAddress; - mstp_port->EventCount = 0; - // Transmit a Token frame to NS - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->Poll_Station = mstp_port->This_Station; - mstp_port->TokenCount = 0; - mstp_port->RetryCount = 0; - mstp_port->ReceivedValidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - // ReceivedUnexpectedFrame - else if ((mstp_port->ReceivedValidFrame == TRUE) && - ((mstp_port->DestinationAddress != mstp_port->This_Station) || - (mstp_port->FrameType != FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER))) - { - // An unexpected frame was received. - // This may indicate the presence of multiple tokens. - mstp_port->ReceivedValidFrame = FALSE; - // enter the IDLE state to synchronize with the network. - // This action drops the token. - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - // mstp_port->SoleMaster - else if ((mstp_port->SoleMaster == TRUE) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == TRUE))) - { - // There was no valid reply to the periodic poll - // by the sole known master for other masters. - mstp_port->FrameCount = 0; - mstp_port->ReceivedInvalidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - // DoneWithPFM - else if ((mstp_port->SoleMaster == FALSE) && - (mstp_port->Next_Station != mstp_port->This_Station) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == TRUE))) - { - // There was no valid reply to the maintenance - // poll for a master at address PS. - mstp_port->EventCount = 0; - // transmit a Token frame to NS - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_TOKEN, - mstp_port->Next_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->ReceivedInvalidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; - } - // SendNextPFM - else if ((mstp_port->SoleMaster == FALSE) && - (mstp_port->Next_Station == mstp_port->This_Station) && // no known successor node - ((uint8_t)((mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1)) != mstp_port->This_Station) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == TRUE))) - { - mstp_port->Poll_Station = - (mstp_port->Poll_Station + 1) % (mstp_port->Nmax_master + 1); - // Transmit a Poll For Master frame to PS. - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_POLL_FOR_MASTER, - mstp_port->Poll_Station, - mstp_port->This_Station, - NULL,0); - mstp_port->RetryCount = 0; - mstp_port->ReceivedInvalidFrame = FALSE; - // Re-enter the current state. - } - // DeclareSoleMaster - else if ((mstp_port->SoleMaster == FALSE) && - (mstp_port->Next_Station == mstp_port->This_Station) && // no known successor node - ((uint8_t)((mstp_port->Poll_Station + 1) % - (mstp_port->Nmax_master + 1)) == mstp_port->This_Station) && - ((mstp_port->SilenceTimer >= Tusage_timeout) || - (mstp_port->ReceivedInvalidFrame == TRUE))) - { - // to indicate that this station is the only master - mstp_port->SoleMaster = TRUE; - mstp_port->FrameCount = 0; - mstp_port->ReceivedInvalidFrame = FALSE; - mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; - } - break; - // The ANSWER_DATA_REQUEST state is entered when a - // BACnet Data Expecting Reply, a Test_Request, or - // a proprietary frame that expects a reply is received. - case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: - if (mstp_port->ReplyPostponedTimer <= Treply_delay) - { - // Reply - // If a reply is available from the higher layers - // within Treply_delay after the reception of the - // final octet of the requesting frame - // (the mechanism used to determine this is a local matter), - // then call RS485_Send_Frame to transmit the reply frame - // and enter the IDLE state to wait for the next frame. - - // Test Request - // If a receiving node can successfully receive and return - // the information field, it shall do so. If it cannot receive - // and return the entire information field but can detect - // the reception of a valid Test_Request frame - // (for example, by computing the CRC on octets as - // they are received), then the receiving node shall discard - // the information field and return a Test_Response containing - // no information field. If the receiving node cannot detect - // the valid reception of frames with overlength information fields, - // then no response shall be returned. - if (mstp_port->FrameType == FRAME_TYPE_TEST_REQUEST) - { - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_TEST_RESPONSE, - mstp_port->SourceAddress, - mstp_port->This_Station, - mstp_port->InputBuffer, - mstp_port->Index); - } - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - - // - // DeferredReply - // If no reply will be available from the higher layers - // within Treply_delay after the reception of the - // final octet of the requesting frame (the mechanism - // used to determine this is a local matter), - // then an immediate reply is not possible. - // Any reply shall wait until this node receives the token. - // Call RS485_Send_Frame to transmit a Reply Postponed frame, - // and enter the IDLE state. - - else - { - RS485_Send_Frame( - mstp_port, - FRAME_TYPE_REPLY_POSTPONED, - mstp_port->SourceAddress, - mstp_port->This_Station, - NULL,0); - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - } - break; - default: - mstp_port->master_state = MSTP_MASTER_STATE_IDLE; - break; - } - - return; -} - -void MSTP_Init( - struct mstp_port_struct_t *mstp_port, - uint8_t this_station_mac) -{ - int i; //loop counter - - if (mstp_port) - { - mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; - mstp_port->master_state = MSTP_MASTER_STATE_INITIALIZE; - mstp_port->ReceiveError = FALSE; - mstp_port->DataAvailable = FALSE; - mstp_port->DataRegister = 0; - mstp_port->DataCRC = 0; - mstp_port->DataCRC = 0; - mstp_port->DataLength = 0; - mstp_port->DestinationAddress = 0; - mstp_port->EventCount = 0; - mstp_port->FrameType = FRAME_TYPE_TOKEN; - mstp_port->FrameCount = 0; - mstp_port->HeaderCRC = 0; - mstp_port->Index = 0; - mstp_port->Index = 0; - for (i = 0; i < sizeof(mstp_port->InputBuffer); i++) - { - mstp_port->InputBuffer[i] = 0; - } - mstp_port->Next_Station = this_station_mac; - mstp_port->Poll_Station = this_station_mac; - mstp_port->ReceivedInvalidFrame = FALSE; - mstp_port->ReceivedValidFrame = FALSE; - mstp_port->RetryCount = 0; - mstp_port->SilenceTimer = 0; - mstp_port->ReplyPostponedTimer = 0; - mstp_port->SoleMaster = FALSE; - mstp_port->SourceAddress = 0; - mstp_port->TokenCount = 0; - mstp_port->This_Station = this_station_mac; - mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES; - mstp_port->Nmax_master = DEFAULT_MAX_MASTER; - } -} - -unsigned MSTP_Create_Frame( - uint8_t *buffer, // where frame is loaded - unsigned buffer_len, // amount of space available - uint8_t frame_type, // type of frame to send - see defines - 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) -{ - 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 - if (buffer_len < 8) - return 0; - - buffer[0] = 0x55; - buffer[1] = 0xFF; - buffer[2] = frame_type; - crc8 = CRC_Calc_Header(buffer[2],crc8); - buffer[3] = destination; - crc8 = CRC_Calc_Header(buffer[3],crc8); - buffer[4] = source; - crc8 = CRC_Calc_Header(buffer[4],crc8); - buffer[5] = data_len / 256; - crc8 = CRC_Calc_Header(buffer[5],crc8); - buffer[6] = data_len % 256; - crc8 = CRC_Calc_Header(buffer[6],crc8); - buffer[7] = ~crc8; - - index = 8; - while (data_len && data && (index < buffer_len)) - { - buffer[index] = *data; - crc16 = CRC_Calc_Data(buffer[index],crc16); - data++; - index++; - data_len--; - } - // append the data CRC if necessary - if (index > 8) - { - if ((index + 2) <= buffer_len) - { - crc16 = ~crc16; - buffer[index] = LO_BYTE(crc16); - index++; - buffer[index] = HI_BYTE(crc16); - index++; - } - else - return 0; - } - - return index; // returns the frame length -} - - -#ifdef TEST -#include -#include -#include "ctest.h" - -// test stub functions -void RS485_Send_Frame( - struct mstp_port_struct_t *mstp_port, // port specific data - uint8_t frame_type, // type of frame to send - see defines - 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) -{ - (void)mstp_port; - (void)frame_type; - (void)destination; - (void)source; - (void)data; - (void)data_len; -} - -#define RING_BUFFER_DATA_SIZE 1 -#define RING_BUFFER_SIZE INPUT_BUFFER_SIZE -static RING_BUFFER Test_Buffer; -static uint8_t Test_Buffer_Data[RING_BUFFER_DATA_SIZE * RING_BUFFER_SIZE]; -static void Load_Input_Buffer(uint8_t *buffer,size_t len) -{ - static bool initialized = FALSE; // tracks our init - - - if (!initialized) - { - initialized = TRUE; - Ringbuf_Init( - &Test_Buffer, - (char *)Test_Buffer_Data, - RING_BUFFER_DATA_SIZE, - RING_BUFFER_SIZE); - } - - // empty any the existing data - while (!Ringbuf_Empty(&Test_Buffer)) - { - (void)Ringbuf_Pop_Front(&Test_Buffer); - } - - if (buffer) - { - while (len) - { - (void)Ringbuf_Put(&Test_Buffer,(char *)buffer); - len--; - buffer++; - } - } -} - -void RS485_Check_UART_Data( - struct mstp_port_struct_t *mstp_port) // port specific data -{ - char *data; - if (!Ringbuf_Empty(&Test_Buffer) && mstp_port && - (mstp_port->DataAvailable == FALSE)) - { - data = Ringbuf_Pop_Front(&Test_Buffer); - if (data) - { - mstp_port->DataRegister = *data; - mstp_port->DataAvailable = TRUE; - } - } -} - -void testReceiveNodeFSM(Test* pTest) -{ - struct mstp_port_struct_t mstp_port; // port data - unsigned EventCount = 0; // local counter - uint8_t my_mac = 0x05; // local MAC address - uint8_t HeaderCRC = 0; // for local CRC calculation - uint8_t FrameType = 0; // type of packet that was sent - unsigned len; // used for the size of the message packet - size_t i; // used to loop through the message bytes - uint8_t buffer[INPUT_BUFFER_SIZE] = {0}; - uint8_t data[INPUT_BUFFER_SIZE - 8 /*header*/ - 2 /*CRC*/] = {0}; - - MSTP_Init(&mstp_port,my_mac); - - // check the receive error during idle - mstp_port.receive_state = MSTP_RECEIVE_STATE_IDLE; - mstp_port.ReceiveError = TRUE; - mstp_port.SilenceTimer = 255; - mstp_port.EventCount = 0; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.ReceiveError == FALSE); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for bad packet header - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x11; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header, but timeout - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // force the timeout - mstp_port.SilenceTimer = Tframe_abort + 1; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble, but receive error - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // force the error - mstp_port.ReceiveError = TRUE; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceiveError == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble1, but bad preamble2 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // no change of state if no data yet - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // repeated preamble1 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // repeated preamble1 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - // bad data - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x11; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceiveError == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble, but timeout in packet - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // preamble2 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0xFF; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 0); - ct_test(pTest,mstp_port.HeaderCRC == 0xFF); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // force the timeout - mstp_port.SilenceTimer = Tframe_abort + 1; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == TRUE); - - // check for good packet header preamble, but error in packet - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // preamble2 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0xFF; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 0); - ct_test(pTest,mstp_port.HeaderCRC == 0xFF); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // force the error - mstp_port.ReceiveError = TRUE; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceiveError == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // check for good packet header preamble - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x55; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_PREAMBLE); - MSTP_Receive_Frame_FSM(&mstp_port); - // preamble2 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0xFF; - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 0); - ct_test(pTest,mstp_port.HeaderCRC == 0xFF); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // no change of state if no data yet - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - // Data is received - index is incremented - // FrameType - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = FRAME_TYPE_TOKEN; - HeaderCRC = 0xFF; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 1); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,FrameType == FRAME_TYPE_TOKEN); - // Destination - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0x10; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 2); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.DestinationAddress == 0x10); - // Source - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = my_mac; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 3); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.SourceAddress == my_mac); - // Length1 = length*256 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 4); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.DataLength == 0); - // Length2 - mstp_port.DataAvailable = TRUE; - mstp_port.DataRegister = 0; - HeaderCRC = CRC_Calc_Header(mstp_port.DataRegister,HeaderCRC); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 5); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER); - ct_test(pTest,mstp_port.DataLength == 0); - // HeaderCRC - mstp_port.DataAvailable = TRUE; - ct_test(pTest,HeaderCRC == 0x73); // per Annex G example - mstp_port.DataRegister = ~HeaderCRC; // one's compliment of CRC is sent - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - ct_test(pTest,mstp_port.Index == 5); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - ct_test(pTest,mstp_port.HeaderCRC == 0x55); - // NotForUs - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // BadCRC in header check - mstp_port.ReceivedInvalidFrame = FALSE; - mstp_port.ReceivedValidFrame = FALSE; - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_TOKEN, - 0x10, // destination - my_mac, // source - NULL, // data - 0); // data size - ct_test(pTest,len > 0); - // make the header CRC bad - buffer[7] = 0x00; - Load_Input_Buffer(buffer,len); - for (i = 0; i < len; i++) - { - RS485_Check_UART_Data(&mstp_port); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - } - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == TRUE); - ct_test(pTest,mstp_port.ReceivedValidFrame == FALSE); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // NoData for us - mstp_port.ReceivedInvalidFrame = FALSE; - mstp_port.ReceivedValidFrame = FALSE; - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_TOKEN, - my_mac, // destination - my_mac, // source - NULL, // data - 0); // data size - ct_test(pTest,len > 0); - Load_Input_Buffer(buffer,len); - for (i = 0; i < len; i++) - { - RS485_Check_UART_Data(&mstp_port); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - } - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == FALSE); - ct_test(pTest,mstp_port.ReceivedValidFrame == TRUE); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // FrameTooLong - mstp_port.ReceivedInvalidFrame = FALSE; - mstp_port.ReceivedValidFrame = FALSE; - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_TOKEN, - my_mac, // destination - my_mac, // source - NULL, // data - 0); // data size - ct_test(pTest,len > 0); - // make the header data length bad - buffer[5] = 0x02; - Load_Input_Buffer(buffer,len); - for (i = 0; i < len; i++) - { - RS485_Check_UART_Data(&mstp_port); - EventCount++; - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.DataAvailable == FALSE); - ct_test(pTest,mstp_port.SilenceTimer == 0); - ct_test(pTest,mstp_port.EventCount == EventCount); - } - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_HEADER_CRC); - MSTP_Receive_Frame_FSM(&mstp_port); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == TRUE); - ct_test(pTest,mstp_port.ReceivedValidFrame == FALSE); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - // Data - mstp_port.ReceivedInvalidFrame = FALSE; - mstp_port.ReceivedValidFrame = FALSE; - memset(data,0,sizeof(data)); - len = MSTP_Create_Frame( - buffer, - sizeof(buffer), - FRAME_TYPE_PROPRIETARY_MIN, - my_mac, // destination - my_mac, // source - data, // data - sizeof(data)); // data size - ct_test(pTest,len > 0); - Load_Input_Buffer(buffer,len); - RS485_Check_UART_Data(&mstp_port); - MSTP_Receive_Frame_FSM(&mstp_port); - while (mstp_port.receive_state != MSTP_RECEIVE_STATE_IDLE) - { - RS485_Check_UART_Data(&mstp_port); - MSTP_Receive_Frame_FSM(&mstp_port); - } - ct_test(pTest,mstp_port.DataLength == sizeof(data)); - ct_test(pTest,mstp_port.ReceivedInvalidFrame == FALSE); - ct_test(pTest,mstp_port.ReceivedValidFrame == TRUE); - ct_test(pTest,mstp_port.receive_state == MSTP_RECEIVE_STATE_IDLE); - - return; -} - -void testMasterNodeFSM(Test* pTest) -{ - struct mstp_port_struct_t mstp_port; // port data - uint8_t my_mac = 0x05; // local MAC address - - MSTP_Init(&mstp_port,my_mac); - ct_test(pTest,mstp_port.master_state == MSTP_MASTER_STATE_INITIALIZE); - -} - -#endif - -#ifdef TEST_MSTP -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("mstp", NULL); - - /* individual tests */ - rc = ct_addTestFunction(pTest, testReceiveNodeFSM); - assert(rc); - rc = ct_addTestFunction(pTest, testMasterNodeFSM); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); - - ct_destroy(pTest); - - return 0; -} -#endif diff --git a/bacnet-stack/.svn/text-base/mstp.h.svn-base b/bacnet-stack/.svn/text-base/mstp.h.svn-base deleted file mode 100644 index 6ec810c3..00000000 --- a/bacnet-stack/.svn/text-base/mstp.h.svn-base +++ /dev/null @@ -1,240 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 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####*/ - -#ifndef MSTP_H -#define MSTP_H - -#include -#include -#include - -// The number of elements in the array InputBuffer[]. -#define INPUT_BUFFER_SIZE (501) - -// The value 255 is used to denote broadcast when used as a -// destination address but is not allowed as a value for a station. -#define MSTP_BROADCAST_ADDRESS 255 - -// MS/TP Frame Type -// Frame Types 8 through 127 are reserved by ASHRAE. -#define FRAME_TYPE_TOKEN 0 -#define FRAME_TYPE_POLL_FOR_MASTER 1 -#define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2 -#define FRAME_TYPE_TEST_REQUEST 3 -#define FRAME_TYPE_TEST_RESPONSE 4 -#define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5 -#define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6 -#define FRAME_TYPE_REPLY_POSTPONED 7 -// Frame Types 128 through 255: Proprietary Frames -// These frames are available to vendors as proprietary (non-BACnet) frames. -// The first two octets of the Data field shall specify the unique vendor -// identification code, most significant octet first, for the type of -// vendor-proprietary frame to be conveyed. The length of the data portion -// of a Proprietary frame shall be in the range of 2 to 501 octets. -#define FRAME_TYPE_PROPRIETARY_MIN 128 -#define FRAME_TYPE_PROPRIETARY_MAX 255 - -// receive FSM states -typedef enum -{ - MSTP_RECEIVE_STATE_IDLE, - MSTP_RECEIVE_STATE_PREAMBLE, - MSTP_RECEIVE_STATE_HEADER, - MSTP_RECEIVE_STATE_HEADER_CRC, - MSTP_RECEIVE_STATE_DATA, - MSTP_RECEIVE_STATE_DATA_CRC, -} MSTP_RECEIVE_STATE; - -// master node FSM states -typedef enum -{ - MSTP_MASTER_STATE_INITIALIZE, - MSTP_MASTER_STATE_IDLE, - MSTP_MASTER_STATE_USE_TOKEN, - MSTP_MASTER_STATE_WAIT_FOR_REPLY, - MSTP_MASTER_STATE_DONE_WITH_TOKEN, - MSTP_MASTER_STATE_PASS_TOKEN, - MSTP_MASTER_STATE_NO_TOKEN, - MSTP_MASTER_STATE_POLL_FOR_MASTER, - MSTP_MASTER_STATE_ANSWER_DATA_REQUEST, -} MSTP_MASTER_STATE; - -// data for a given MS/TP port -struct mstp_port_struct_t -{ - MSTP_RECEIVE_STATE receive_state; - // When a master node is powered up or reset, - // it shall unconditionally enter the INITIALIZE state. - MSTP_MASTER_STATE master_state; - - bool ReceiveError; // TRUE when error detected during Rx octet - - bool DataAvailable; // There is data in the buffer - - uint8_t DataRegister; // stores the latest data - - // Used to accumulate the CRC on the data field of a frame. - uint16_t DataCRC; - - // Used to store the data length of a received frame. - unsigned DataLength; - - // Used to store the destination address of a received frame. - uint8_t DestinationAddress; - - // Used to count the number of received octets or errors. - // This is used in the detection of link activity. - unsigned EventCount; - - // Used to store the frame type of a received frame. - uint8_t FrameType; - - // The number of frames sent by this node during a single token hold. - // When this counter reaches the value Nmax_info_frames, the node must - // pass the token. - unsigned FrameCount; - - // Used to accumulate the CRC on the header of a frame. - uint8_t HeaderCRC; - - // Used as an index by the Receive State Machine, up to a maximum value of - // InputBufferSize. - unsigned Index; - - - // An array of octets, used to store octets as they are received. - // InputBuffer is indexed from 0 to InputBufferSize-1. - // The maximum size of a frame is 501 octets. - // A smaller value for InputBufferSize may be used by some implementations. - uint8_t InputBuffer[INPUT_BUFFER_SIZE]; - - // "Next Station," the MAC address of the node to which This Station passes - // the token. If the Next_Station is unknown, Next_Station shall be equal to - // This_Station. - uint8_t Next_Station; - - // "Poll Station," the MAC address of the node to which This Station last - // sent a Poll For Master. This is used during token maintenance. - uint8_t Poll_Station; - - // A Boolean flag set to TRUE by the Receive State Machine if an error is - // detected during the reception of a frame. Set to FALSE by the main - // state machine. - bool ReceivedInvalidFrame; - - // A Boolean flag set to TRUE by the Receive State Machine if a valid frame - // is received. Set to FALSE by the main state machine. - bool ReceivedValidFrame; - - // A counter of transmission retries used for Token and Poll For Master - // transmission. - unsigned RetryCount; - - // A timer with nominal 5 millisecond resolution used to measure and - // generate silence on the medium between octets. It is incremented by a - // timer process and is cleared by the Receive State Machine when activity - // is detected and by the SendFrame procedure as each octet is transmitted. - // Since the timer resolution is limited and the timer is not necessarily - // synchronized to other machine events, a timer value of N will actually - // denote intervals between N-1 and N - unsigned SilenceTimer; - - // A timer used to measure and generate Reply Postponed frames. It is - // incremented by a timer process and is cleared by the Master Node State - // Machine when a Data Expecting Reply Answer activity is completed. - unsigned ReplyPostponedTimer; - - // A Boolean flag set to TRUE by the master machine if this node is the - // only known master node. - bool SoleMaster; - - // Used to store the Source Address of a received frame. - uint8_t SourceAddress; - - // The number of tokens received by this node. When this counter reaches the - // value Npoll, the node polls the address range between TS and NS for - // additional master nodes. TokenCount is set to zero at the end of the - // polling process. - unsigned TokenCount; - - // "This Station," the MAC address of this node. TS is generally read from a - // hardware DIP switch, or from nonvolatile memory. Valid values for TS are - // 0 to 254. The value 255 is used to denote broadcast when used as a - // destination address but is not allowed as a value for TS. - uint8_t This_Station; - - // 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 - // maximum number of information frames the node may send before it must - // pass the token. Max_Info_Frames may have different values on different - // nodes. This may be used to allocate more or less of the available link - // bandwidth to particular nodes. If Max_Info_Frames is not writable in a - // node, its value shall be 1. - unsigned Nmax_info_frames; - - // This parameter represents the value of the Max_Master property of the - // node's Device object. The value of Max_Master specifies the highest - // 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, - // its value shall be 127. - unsigned Nmax_master; - - // After receiving a frame this value will be TRUE until Tturnaround - // has expired - bool Turn_Around_Waiting; -}; - -#define DEFAULT_MAX_INFO_FRAMES 1 -#define DEFAULT_MAX_MASTER 127 - -// The minimum time after the end of the stop bit of the final octet of a -// received frame before a node may enable its EIA-485 driver: 40 bit times. -// At 9600 baud, 40 bit times would be about 4.166 milliseconds -#define Tturnaround 40; - -void MSTP_Millisecond_Timer(struct mstp_port_struct_t *mstp_port); -void MSTP_Receive_Frame_FSM(struct mstp_port_struct_t *mstp_port); -void MSTP_Master_Node_FSM(struct mstp_port_struct_t *mstp_port); - -unsigned MSTP_Create_Frame( - uint8_t *buffer, // where frame is loaded - unsigned buffer_len, // amount of space available - uint8_t frame_type, // type of frame to send - see defines - 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) - -#endif diff --git a/bacnet-stack/.svn/text-base/mstp.ide.svn-base b/bacnet-stack/.svn/text-base/mstp.ide.svn-base deleted file mode 100644 index 986ae620..00000000 Binary files a/bacnet-stack/.svn/text-base/mstp.ide.svn-base and /dev/null differ diff --git a/bacnet-stack/.svn/text-base/mstp.mak.svn-base b/bacnet-stack/.svn/text-base/mstp.mak.svn-base deleted file mode 100644 index d93124de..00000000 --- a/bacnet-stack/.svn/text-base/mstp.mak.svn-base +++ /dev/null @@ -1,29 +0,0 @@ -#Makefile to build BACnet MS/TP tests -CC = gcc -BASEDIR = . -#CFLAGS = -Wall -I. -# -g for debugging with gdb -#CFLAGS = -Wall -I. -g -CFLAGS = -Wall -I. -Itest -DTEST -DTEST_MSTP -g - -OBJS = mstp.o crc.o ringbuf.o test/ctest.o - -TARGET = mstp - -all: ${TARGET} - -${TARGET}: ${OBJS} - ${CC} -o $@ ${OBJS} - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini - -include: .depend - diff --git a/bacnet-stack/.svn/text-base/ringbuf.c.svn-base b/bacnet-stack/.svn/text-base/ringbuf.c.svn-base deleted file mode 100644 index ea3745b4..00000000 --- a/bacnet-stack/.svn/text-base/ringbuf.c.svn-base +++ /dev/null @@ -1,287 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 by 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####*/ - -/* Functional Description: Generic ring buffer library for deeply - embedded system. See the unit tests for usage examples. */ - -#include "stdint.h" -#include "ringbuf.h" - -/**************************************************************************** -* DESCRIPTION: Returns the empty/full status of the ring buffer -* RETURN: TRUE if the ring buffer is empty, FALSE if it is not. -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool Ringbuf_Empty(RING_BUFFER const *b) -{ - return (b->count == 0); -} - -/**************************************************************************** -* DESCRIPTION: Looks at the data from the head of the list without removing it -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -char *Ringbuf_Get_Front(RING_BUFFER const *b) -{ - return (b->count ? &(b->data[b->head * b->element_size]) : NULL); -} - -/**************************************************************************** -* DESCRIPTION: Gets the data from the front of the list, and removes it -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -char *Ringbuf_Pop_Front(RING_BUFFER *b) -{ - char *data = NULL; // return value - - if (b->count) - { - data = &(b->data[b->head * b->element_size]); - b->head++; - if (b->head >= b->element_count) - b->head = 0; - b->count--; - } - - return data; -} - -/**************************************************************************** -* DESCRIPTION: Adds an element of data to the ring buffer -* RETURN: TRUE on succesful add, FALSE if not added -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool Ringbuf_Put( - RING_BUFFER *b, // ring buffer structure - char *data_element) // one element to add to the ring -{ - bool status = FALSE; // return value - unsigned offset = 0; // offset into array of data - char *ring_data = NULL; // used to help point ring data - unsigned i; // loop counter - - if (b && data_element) - { - // limit the amount of data that we accept - if (b->count < b->element_count) - { - offset = b->head + b->count; - if (offset >= b->element_count) - offset -= b->element_count; - ring_data = b->data + offset * b->element_size; - for(i = 0; i < b->element_size; i++) - { - ring_data[i] = data_element[i]; - } - b->count++; - status = TRUE; - } - } - - return status; -} - -/**************************************************************************** -* DESCRIPTION: Configures the ring buffer -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void Ringbuf_Init( - RING_BUFFER *b, // ring buffer structure - char *data, // data block or array of data - unsigned element_size, // size of one element in the data block - unsigned element_count) // number of elements in the data block -{ - b->head = 0; - b->count = 0; - b->data = data; - b->element_size = element_size; - b->element_count = element_count; - - return; -} - -#ifdef TEST -#include -#include - -#include "ctest.h" - -// test the FIFO -#define RING_BUFFER_DATA_SIZE 5 -#define RING_BUFFER_SIZE 16 -void testRingBuf(Test* pTest) -{ - RING_BUFFER test_buffer; - char data_store[RING_BUFFER_DATA_SIZE * RING_BUFFER_SIZE]; - char data[RING_BUFFER_DATA_SIZE]; - char *test_data; - unsigned index; - unsigned data_index; - unsigned count; - unsigned dummy; - bool status; - - Ringbuf_Init(&test_buffer,data_store,RING_BUFFER_DATA_SIZE,RING_BUFFER_SIZE); - ct_test(pTest,Ringbuf_Empty(&test_buffer)); - - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = data_index; - } - status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == TRUE); - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - - test_data = Ringbuf_Get_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == data[data_index]); - } - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - - test_data = Ringbuf_Pop_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == data[data_index]); - } - ct_test(pTest,Ringbuf_Empty(&test_buffer)); - - // fill to max - for (index = 0; index < RING_BUFFER_SIZE; index++) - { - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = index; - } - status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == TRUE); - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - } - // verify actions on full buffer - for (index = 0; index < RING_BUFFER_SIZE; index++) - { - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = index; - } - status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == FALSE); - ct_test(pTest,!Ringbuf_Empty(&test_buffer)); - } - - // check buffer full - for (index = 0; index < RING_BUFFER_SIZE; index++) - { - test_data = Ringbuf_Get_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == index); - } - - test_data = Ringbuf_Pop_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == index); - } - } - ct_test(pTest,Ringbuf_Empty(&test_buffer)); - - // test the ring around the buffer - for (index = 0; index < RING_BUFFER_SIZE; index++) - { - for (count = 1; count < 4; count++) - { - dummy = index * count; - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - data[data_index] = dummy; - } - status = Ringbuf_Put(&test_buffer, data); - ct_test(pTest,status == TRUE); - } - - for (count = 1; count < 4; count++) - { - dummy = index * count; - test_data = Ringbuf_Get_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == dummy); - } - - test_data = Ringbuf_Pop_Front(&test_buffer); - for (data_index = 0; data_index < RING_BUFFER_DATA_SIZE; data_index++) - { - ct_test(pTest,test_data[data_index] == dummy); - } - } - } - ct_test(pTest,Ringbuf_Empty(&test_buffer)); - - - return; -} - -#ifdef TEST_RINGBUF -int main(void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("ringbuf", NULL); - - /* individual tests */ - rc = ct_addTestFunction(pTest, testRingBuf); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void)ct_report(pTest); - - ct_destroy(pTest); - - return 0; -} -#endif -#endif - diff --git a/bacnet-stack/.svn/text-base/ringbuf.h.svn-base b/bacnet-stack/.svn/text-base/ringbuf.h.svn-base deleted file mode 100644 index 68b9ae34..00000000 --- a/bacnet-stack/.svn/text-base/ringbuf.h.svn-base +++ /dev/null @@ -1,66 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 by 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####*/ - -/* Functional Description: Generic ring buffer library for deeply - embedded system. See the unit tests for usage examples. */ - -#ifndef RINGBUF_H -#define RINGBUF_H - -#include "stdint.h" - -struct ring_buffer_t -{ - char *data; // block of memory or array of data - unsigned element_size; // how many bytes for each chunk - unsigned element_count; // number of chunks of data - unsigned head; // first chunk of data - unsigned count; // number of chunks in use -}; -typedef struct ring_buffer_t RING_BUFFER; - -extern bool Ringbuf_Empty(RING_BUFFER const *b); -extern char *Ringbuf_Get_Front(RING_BUFFER const *b); -extern char *Ringbuf_Pop_Front(RING_BUFFER *b); -extern bool Ringbuf_Put( - RING_BUFFER *b, // ring buffer structure - char *data_element); // one element to add to the ring -extern void Ringbuf_Init( - RING_BUFFER *b, // ring buffer structure - char *data, // data block or array of data - unsigned element_size, // size of one element in the data block - unsigned element_count); // number of elements in the data block - -#endif diff --git a/bacnet-stack/.svn/text-base/ringbuf.mak.svn-base b/bacnet-stack/.svn/text-base/ringbuf.mak.svn-base deleted file mode 100644 index 26c685c4..00000000 --- a/bacnet-stack/.svn/text-base/ringbuf.mak.svn-base +++ /dev/null @@ -1,29 +0,0 @@ -#Makefile to build ringbuf tests -CC = gcc -BASEDIR = . -#CFLAGS = -Wall -I. -# -g for debugging with gdb -#CFLAGS = -Wall -I. -g -CFLAGS = -Wall -I. -Itest -DTEST -DTEST_RINGBUF -g - -OBJS = ringbuf.o test/ctest.o - -TARGET = ringbuf - -all: ${TARGET} - -${TARGET}: ${OBJS} - ${CC} -o $@ ${OBJS} - -.c.o: - ${CC} -c ${CFLAGS} $*.c -o $@ - -depend: - rm -f .depend - ${CC} -MM ${CFLAGS} *.c >> .depend - -clean: - rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini - -include: .depend - diff --git a/bacnet-stack/.svn/text-base/rs485.h.svn-base b/bacnet-stack/.svn/text-base/rs485.h.svn-base deleted file mode 100644 index 59b0c55f..00000000 --- a/bacnet-stack/.svn/text-base/rs485.h.svn-base +++ /dev/null @@ -1,53 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 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####*/ - -#ifndef RS485_H -#define RS485_H - -#include -#include "mstp.h" - -void RS485_Send_Frame( - struct mstp_port_struct_t *mstp_port, // port specific data - uint8_t frame_type, // type of frame to send - see defines - 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) - -void RS485_Check_UART_Data( - struct mstp_port_struct_t *mstp_port); // port specific data - -#endif diff --git a/bacnet-stack/.svn/text-base/stdbool.h.svn-base b/bacnet-stack/.svn/text-base/stdbool.h.svn-base deleted file mode 100644 index 29b9a5e4..00000000 --- a/bacnet-stack/.svn/text-base/stdbool.h.svn-base +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef STDBOOL_H -#define STDBOOL_H - -// C99 Boolean types for compilers without C99 support - -#ifndef __cplusplus - typedef int _Bool; - #ifndef bool - #define bool _Bool - #endif - #ifndef true - #define true 1 - #endif - #ifndef false - #define false 0 - #endif - #define __bool_true_false_are_defined 1 -#endif - -#ifndef FALSE - #define FALSE 0 -#endif - -#ifndef TRUE - #define TRUE 1 -#endif - -#endif diff --git a/bacnet-stack/.svn/text-base/stdint.h.svn-base b/bacnet-stack/.svn/text-base/stdint.h.svn-base deleted file mode 100644 index b66446d4..00000000 --- a/bacnet-stack/.svn/text-base/stdint.h.svn-base +++ /dev/null @@ -1,26 +0,0 @@ -// Defines the standard integer types that are used in code -// for the x86 processor and Borland Compiler - -#ifndef STDINT_H -#define STDINT_H - -#include - -#define TRUE 1 -#define FALSE 0 - -#define MSB 7 -#define LSB 0 - -typedef int bool; -typedef unsigned char uint8_t; // 1 byte 0 to 255 -typedef signed char int8_t; // 1 byte -127 to 127 -typedef unsigned short uint16_t; // 2 bytes 0 to 65535 -typedef signed short int16_t; // 2 bytes -32767 to 32767 -//typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215 -typedef unsigned long uint32_t; // 4 bytes 0 to 4294967295 -typedef signed long int32_t; // 4 bytes -2147483647 to 2147483647 -// typedef signed long long int64_t; -// typedef unsigned long long uint64_t; - -#endif // STDINT_H diff --git a/bacnet-stack/.svn/text-base/test.sh.svn-base b/bacnet-stack/.svn/text-base/test.sh.svn-base deleted file mode 100644 index 4e7739f1..00000000 --- a/bacnet-stack/.svn/text-base/test.sh.svn-base +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# Unit tests builder / runner for this project - -rm test.log -touch test.log - -make -f crc.mak -./crc >> test.log -make -f crc.mak clean - -make -f ringbuf.mak -./ringbuf >> test.log -make -f ringbuf.mak clean - -make -f mstp.mak -./mstp >> test.log -make -f mstp.mak clean - - diff --git a/bacnet-stack/ports/.svn/README.txt b/bacnet-stack/ports/.svn/README.txt deleted file mode 100644 index 271a8ce9..00000000 --- a/bacnet-stack/ports/.svn/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -This is a Subversion working copy administrative directory. -Visit http://subversion.tigris.org/ for more information. diff --git a/bacnet-stack/ports/.svn/empty-file b/bacnet-stack/ports/.svn/empty-file deleted file mode 100644 index e69de29b..00000000 diff --git a/bacnet-stack/ports/.svn/entries b/bacnet-stack/ports/.svn/entries deleted file mode 100644 index c9a3bd67..00000000 --- a/bacnet-stack/ports/.svn/entries +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - diff --git a/bacnet-stack/ports/.svn/format b/bacnet-stack/ports/.svn/format deleted file mode 100644 index b8626c4c..00000000 --- a/bacnet-stack/ports/.svn/format +++ /dev/null @@ -1 +0,0 @@ -4 diff --git a/bacnet-stack/ports/linux/.svn/README.txt b/bacnet-stack/ports/linux/.svn/README.txt deleted file mode 100644 index 271a8ce9..00000000 --- a/bacnet-stack/ports/linux/.svn/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -This is a Subversion working copy administrative directory. -Visit http://subversion.tigris.org/ for more information. diff --git a/bacnet-stack/ports/linux/.svn/empty-file b/bacnet-stack/ports/linux/.svn/empty-file deleted file mode 100644 index e69de29b..00000000 diff --git a/bacnet-stack/ports/linux/.svn/entries b/bacnet-stack/ports/linux/.svn/entries deleted file mode 100644 index ac53629f..00000000 --- a/bacnet-stack/ports/linux/.svn/entries +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - diff --git a/bacnet-stack/ports/linux/.svn/format b/bacnet-stack/ports/linux/.svn/format deleted file mode 100644 index b8626c4c..00000000 --- a/bacnet-stack/ports/linux/.svn/format +++ /dev/null @@ -1 +0,0 @@ -4 diff --git a/bacnet-stack/ports/linux/.svn/prop-base/readme.txt.svn-base b/bacnet-stack/ports/linux/.svn/prop-base/readme.txt.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/ports/linux/.svn/prop-base/readme.txt.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/ports/linux/.svn/prop-base/rs485.c.svn-base b/bacnet-stack/ports/linux/.svn/prop-base/rs485.c.svn-base deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/ports/linux/.svn/prop-base/rs485.c.svn-base +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/ports/linux/.svn/props/readme.txt.svn-work b/bacnet-stack/ports/linux/.svn/props/readme.txt.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/ports/linux/.svn/props/readme.txt.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/ports/linux/.svn/props/rs485.c.svn-work b/bacnet-stack/ports/linux/.svn/props/rs485.c.svn-work deleted file mode 100644 index dce2c1d5..00000000 --- a/bacnet-stack/ports/linux/.svn/props/rs485.c.svn-work +++ /dev/null @@ -1 +0,0 @@ -END diff --git a/bacnet-stack/ports/linux/.svn/text-base/readme.txt.svn-base b/bacnet-stack/ports/linux/.svn/text-base/readme.txt.svn-base deleted file mode 100644 index c24be5af..00000000 --- a/bacnet-stack/ports/linux/.svn/text-base/readme.txt.svn-base +++ /dev/null @@ -1,2 +0,0 @@ -This is a port to Linux for testing. -The unit tests can be run via the test.sh script. \ No newline at end of file diff --git a/bacnet-stack/ports/linux/.svn/text-base/rs485.c.svn-base b/bacnet-stack/ports/linux/.svn/text-base/rs485.c.svn-base deleted file mode 100644 index 710828f2..00000000 --- a/bacnet-stack/ports/linux/.svn/text-base/rs485.c.svn-base +++ /dev/null @@ -1,115 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 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####*/ - -// The module handles sending data out the RS-485 port -// and handles receiving data from the RS-485 port. -// Customize this file for your specific hardware -#include -#include -#include -#include - -#include "mstp.h" - -// Transmits a Frame on the wire -void RS485_Send_Frame( - struct mstp_port_struct_t *mstp_port, // port to send from - uint8_t frame_type, // type of frame to send - see defines - 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) -{ - uint8_t buffer[INPUT_BUFFER_SIZE] = {0}; - uint8_t *pbuf = NULL; // used for pointer arithmatic - unsigned len = 0; // number of bytes to send - - // in order to avoid line contention - while (mstp_port->Turn_Around_Waiting) - { - // wait, yield, or whatever - } - - // Disable the receiver, and enable the transmit line driver. - - len = MSTP_Create_Frame( - buffer, // where frame is loaded - sizeof(buffer), // amount of space available - frame_type, // type of frame to send - see defines - destination, // destination address - source, // source address - data, // any data to be sent - may be null - data_len); // number of bytes of data (up to 501) - - pbuf = &buffer[0]; - while (len) - { - putc(*pbuf,stderr); - pbuf++; - len--; - } - - // Wait until the final stop bit of the most significant CRC octet - // has been transmitted but not more than Tpostdrive. - - // Disable the transmit line driver. - - return; -} - -// called by timer, interrupt(?) or other thread -void RS485_Check_UART_Data(struct mstp_port_struct_t *mstp_port) -{ - if (mstp_port->ReceiveError == true) - { - // wait for state machine to clear this - } - // wait for state machine to read from the DataRegister - else if (mstp_port->DataAvailable == false) - { - // check for data - - // if error, - // ReceiveError = TRUE; - // return; - - mstp_port->DataRegister = 0; // FIXME: Get this data from UART or buffer - - // if data is ready, - // DataAvailable = TRUE; - // return; - } -} -