From 469627a6cfa29e6dc0f7a0fa93f6b492f8f5332a Mon Sep 17 00:00:00 2001 From: skarg Date: Mon, 11 May 2009 22:32:06 +0000 Subject: [PATCH] Updated port for BACnet Development Kit. --- bacnet-stack/demo/readprop/main.c | 2 +- bacnet-stack/include/bacenum.h | 6 +- bacnet-stack/include/bits.h | 4 + bacnet-stack/include/bo.h | 2 + bacnet-stack/include/device.h | 3 + bacnet-stack/ports/bdk-atxx4-mstp/Makefile | 11 +- bacnet-stack/ports/bdk-atxx4-mstp/ai.c | 37 ++ bacnet-stack/ports/bdk-atxx4-mstp/bacnet.aps | 2 +- bacnet-stack/ports/bdk-atxx4-mstp/bi.c | 40 ++ bacnet-stack/ports/bdk-atxx4-mstp/bits.h | 89 ---- bacnet-stack/ports/bdk-atxx4-mstp/bo.c | 88 +++- .../ports/bdk-atxx4-mstp/bootloader/Makefile | 231 ++++++++ .../ports/bdk-atxx4-mstp/bootloader/defines.h | 46 ++ .../ports/bdk-atxx4-mstp/bootloader/flash.h | 74 +++ .../ports/bdk-atxx4-mstp/bootloader/main.c | 496 ++++++++++++++++++ .../ports/bdk-atxx4-mstp/bootloader/parts.txt | 24 + .../bdk-atxx4-mstp/bootloader/preprocessor.sh | 171 ++++++ .../bootloader/preprocessor.xls | Bin 0 -> 39424 bytes .../ports/bdk-atxx4-mstp/bootloader/serial.c | 42 ++ .../ports/bdk-atxx4-mstp/bootloader/serial.h | 22 + bacnet-stack/ports/bdk-atxx4-mstp/device.c | 220 +++++--- bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c | 4 +- bacnet-stack/ports/bdk-atxx4-mstp/h_rd.c | 113 ++++ .../ports/bdk-atxx4-mstp/hardware.ods | Bin 18767 -> 16311 bytes bacnet-stack/ports/bdk-atxx4-mstp/input.c | 5 - bacnet-stack/ports/bdk-atxx4-mstp/main.c | 69 ++- bacnet-stack/ports/bdk-atxx4-mstp/nvdata.h | 104 ++++ bacnet-stack/ports/bdk-atxx4-mstp/rs485.c | 64 ++- 28 files changed, 1758 insertions(+), 211 deletions(-) delete mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bits.h create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/Makefile create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/defines.h create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/flash.h create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/main.c create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/parts.txt create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/preprocessor.sh create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/preprocessor.xls create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.c create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.h create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/h_rd.c create mode 100644 bacnet-stack/ports/bdk-atxx4-mstp/nvdata.h diff --git a/bacnet-stack/demo/readprop/main.c b/bacnet-stack/demo/readprop/main.c index f3abfb32..17db21dc 100644 --- a/bacnet-stack/demo/readprop/main.c +++ b/bacnet-stack/demo/readprop/main.c @@ -284,7 +284,7 @@ int main(int argc, char *argv[]) { Target_Object_Property = strtol(argv[4], NULL, 0); if (argc > 5) Target_Object_Index = strtol(argv[5], NULL, 0); - if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { + if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; diff --git a/bacnet-stack/include/bacenum.h b/bacnet-stack/include/bacenum.h index ba7f1149..01fa1a0b 100644 --- a/bacnet-stack/include/bacenum.h +++ b/bacnet-stack/include/bacenum.h @@ -644,7 +644,8 @@ typedef enum { typedef enum { POLARITY_NORMAL = 0, - POLARITY_REVERSE = 1 + POLARITY_REVERSE = 1, + MAX_POLARITY = 2 } BACNET_POLARITY; typedef enum { @@ -932,7 +933,8 @@ typedef enum { CHARACTER_JISC_6226 = 2, CHARACTER_UCS4 = 3, CHARACTER_UCS2 = 4, - CHARACTER_ISO8859 = 5 + CHARACTER_ISO8859 = 5, + MAX_CHARACTER_STRING_ENCODING = 6 } BACNET_CHARACTER_STRING_ENCODING; typedef enum { diff --git a/bacnet-stack/include/bits.h b/bacnet-stack/include/bits.h index 0e6357db..ecf2fe74 100644 --- a/bacnet-stack/include/bits.h +++ b/bacnet-stack/include/bits.h @@ -82,4 +82,8 @@ #define BITMASK_FLIP(x,y) ((x) ^= (y)) #define BITMASK_CHECK(x,y) ((x) & (y)) +#ifndef _BV +#define _BV(x) (1<<(x)) +#endif + #endif diff --git a/bacnet-stack/include/bo.h b/bacnet-stack/include/bo.h index 846ab657..4cb90c89 100644 --- a/bacnet-stack/include/bo.h +++ b/bacnet-stack/include/bo.h @@ -35,6 +35,8 @@ extern "C" { #endif /* __cplusplus */ + void Binary_Output_Init(void); + void Binary_Output_Property_Lists( const int **pRequired, const int **pOptional, diff --git a/bacnet-stack/include/device.h b/bacnet-stack/include/device.h index f98a9702..6421dd6d 100644 --- a/bacnet-stack/include/device.h +++ b/bacnet-stack/include/device.h @@ -44,6 +44,9 @@ extern "C" { #endif /* __cplusplus */ + + void Device_Init(void); + void Device_Property_Lists( const int **pRequired, const int **pOptional, diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/Makefile b/bacnet-stack/ports/bdk-atxx4-mstp/Makefile index 65aac914..14e5cbeb 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/Makefile +++ b/bacnet-stack/ports/bdk-atxx4-mstp/Makefile @@ -50,6 +50,8 @@ CSRC = main.c \ dlmstp.c \ h_wp.c \ h_rp.c \ + h_rpm.c \ + h_rd.c \ device.c \ ai.c \ bi.c \ @@ -59,7 +61,6 @@ CSRC = main.c \ DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c \ $(BACNET_DEMO)/handler/h_npdu.c \ $(BACNET_DEMO)/handler/h_whois.c \ - $(BACNET_DEMO)/handler/h_rd.c \ $(BACNET_DEMO)/handler/h_dcc.c \ $(BACNET_DEMO)/handler/s_iam.c \ $(BACNET_DEMO)/handler/noserv.c @@ -67,6 +68,7 @@ DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c \ # core BACnet stack files CORESRC = \ $(BACNET_CORE)/fifo.c \ + $(BACNET_CORE)/memcopy.c \ $(BACNET_CORE)/crc.c \ $(BACNET_CORE)/apdu.c \ $(BACNET_CORE)/npdu.c \ @@ -77,9 +79,10 @@ CORESRC = \ $(BACNET_CORE)/iam.c \ $(BACNET_CORE)/dcc.c \ $(BACNET_CORE)/rp.c \ + $(BACNET_CORE)/rd.c \ + $(BACNET_CORE)/rpm.c \ $(BACNET_CORE)/wp.c \ $(BACNET_CORE)/whois.c \ - $(BACNET_CORE)/rd.c \ $(BACNET_CORE)/bacaddr.c \ $(BACNET_CORE)/abort.c \ $(BACNET_CORE)/reject.c \ @@ -97,8 +100,6 @@ CORESRC = \ # $(BACNET_CORE)/cov.c \ # $(BACNET_CORE)/iam/iam_client.c \ # $(BACNET_CORE)/ihave.c \ -# $(BACNET_CORE)/rd.c \ -# $(BACNET_CORE)/rpm.c \ # $(BACNET_CORE)/timesync.c \ # $(BACNET_CORE)/whohas.c \ # $(BACNET_CORE)/filename.c \ @@ -129,7 +130,7 @@ DEFINES = ## Compile options common for all C compilation units. BFLAGS = -DBACDL_MSTP -BFLAGS += -DMAX_APDU=50 +BFLAGS += -DMAX_APDU=128 BFLAGS += -DBIG_ENDIAN=0 BFLAGS += -DMAX_TSM_TRANSACTIONS=0 #BFLAGS += -DCRC_USE_TABLE diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/ai.c b/bacnet-stack/ports/bdk-atxx4-mstp/ai.c index ff329247..7d6deb22 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/ai.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/ai.c @@ -39,6 +39,43 @@ #error Modify the Analog_Input_Name to handle multiple digits #endif +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Analog_Input_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, + PROP_STATUS_FLAGS, + PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, + PROP_UNITS, + -1 +}; + +static const int Analog_Input_Properties_Optional[] = { + PROP_DESCRIPTION, + -1 +}; + +static const int Analog_Input_Properties_Proprietary[] = { + -1 +}; + +void Analog_Input_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) + *pRequired = Analog_Input_Properties_Required; + if (pOptional) + *pOptional = Analog_Input_Properties_Optional; + if (pProprietary) + *pProprietary = Analog_Input_Properties_Proprietary; + + return; +} + static uint8_t Present_Value[MAX_ANALOG_INPUTS]; /* we simply have 0-n object instances. Yours might be */ diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bacnet.aps b/bacnet-stack/ports/bdk-atxx4-mstp/bacnet.aps index 4736fd42..396188fc 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/bacnet.aps +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bacnet.aps @@ -1 +1 @@ -bacnet29-Apr-2009 08:16:5303-May-2009 15:12:17241029-Apr-2009 08:16:5344, 15, 0, 623AVR GCCD:\code\bacnet-stack\ports\bdk-atxx4-mstp\JTAGICE mkIIATmega644P.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000main.ctimer2.ceeprom.cinit.cinput.cled.crs485.cseeprom.cserial.cstack.cdlmstp.cbo.cbi.cai.cdevice.ch_rp.ch_wp.cMakefiledefaultYESMakefileatmega644p111bacnet.elfdefault\1-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault1C:\WinAVR-20090313\bin\avr-gcc.exeC:\WinAVR-20090313\utils\bin\make.exeD:\code\bacnet-stack\ports\bdk-atxx4-mstp\main.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\timer2.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\eeprom.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\init.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\input.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\led.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\rs485.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\seeprom.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\serial.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\stack.c00000main.c1 +bacnet29-Apr-2009 08:16:5311-May-2009 13:31:34241029-Apr-2009 08:16:5344, 15, 0, 623AVR GCCD:\code\bacnet-stack\ports\bdk-atxx4-mstp\JTAGICE mkIIATmega644P.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000main.ctimer2.ceeprom.cinit.cinput.cled.crs485.cseeprom.cserial.cstack.cdlmstp.cbo.cbi.cai.cdevice.ch_rp.ch_wp.ctimer.heeprom.hhardware.hiar2gcc.hinit.hinput.hled.hnvdata.hrs485.hseeprom.hserial.hMakefiledefaultYESMakefileatmega644p111bacnet.elfdefault\1-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault1C:\WinAVR-20090313\bin\avr-gcc.exeC:\WinAVR-20090313\utils\bin\make.exeD:\code\bacnet-stack\ports\bdk-atxx4-mstp\main.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\timer2.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\eeprom.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\init.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\input.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\led.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\rs485.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\seeprom.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\serial.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\stack.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\dlmstp.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\bo.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\bi.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\ai.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\device.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\h_rp.cD:\code\bacnet-stack\ports\bdk-atxx4-mstp\h_wp.c00000main.c1 diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bi.c b/bacnet-stack/ports/bdk-atxx4-mstp/bi.c index 65d4163c..37421245 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/bi.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bi.c @@ -40,6 +40,46 @@ static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Binary_Input_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_PRESENT_VALUE, + PROP_STATUS_FLAGS, + PROP_EVENT_STATE, + PROP_OUT_OF_SERVICE, + PROP_POLARITY, + -1 +}; + +static const int Binary_Input_Properties_Optional[] = { + PROP_DESCRIPTION, + -1 +}; + +static const int Binary_Input_Properties_Proprietary[] = { + -1 +}; + +void Binary_Input_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) { + *pRequired = Binary_Input_Properties_Required; + } + if (pOptional) { + *pOptional = Binary_Input_Properties_Optional; + } + if (pProprietary) { + *pProprietary = Binary_Input_Properties_Proprietary; + } + + return; +} + static void Binary_Input_Initialize( void) { diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bits.h b/bacnet-stack/ports/bdk-atxx4-mstp/bits.h deleted file mode 100644 index 2a9b62d2..00000000 --- a/bacnet-stack/ports/bdk-atxx4-mstp/bits.h +++ /dev/null @@ -1,89 +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 BITS_H -#define BITS_H - -/******************************************************************** -* Bit Masks -*********************************************************************/ -#define BIT0 (0x01) -#define BIT1 (0x02) -#define BIT2 (0x04) -#define BIT3 (0x08) -#define BIT4 (0x10) -#define BIT5 (0x20) -#define BIT6 (0x40) -#define BIT7 (0x80) -#define BIT8 (0x0100) -#define BIT9 (0x0200) -#define BIT10 (0x0400) -#define BIT11 (0x0800) -#define BIT12 (0x1000) -#define BIT13 (0x2000) -#define BIT14 (0x4000) -#define BIT15 (0x8000) -#define BIT16 (0x010000UL) -#define BIT17 (0x020000UL) -#define BIT18 (0x040000UL) -#define BIT19 (0x080000UL) -#define BIT20 (0x100000UL) -#define BIT21 (0x200000UL) -#define BIT22 (0x400000UL) -#define BIT23 (0x800000UL) -#define BIT24 (0x01000000UL) -#define BIT25 (0x02000000UL) -#define BIT26 (0x04000000UL) -#define BIT27 (0x08000000UL) -#define BIT28 (0x10000000UL) -#define BIT29 (0x20000000UL) -#define BIT30 (0x40000000UL) -#define BIT31 (0x80000000UL) - -/* a=register, b=bit number to act upon 0-n */ -#define BIT_SET(a,b) ((a) |= (1<<(b))) -#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b))) -#define BIT_FLIP(a,b) ((a) ^= (1<<(b))) -#define BIT_CHECK(a,b) ((a) & (1<<(b))) - -/* x=target variable, y=mask */ -#define BITMASK_SET(x,y) ((x) |= (y)) -#define BITMASK_CLEAR(x,y) ((x) &= (~(y))) -#define BITMASK_FLIP(x,y) ((x) ^= (y)) -#define BITMASK_CHECK(x,y) ((x) & (y)) - -#ifndef _BV -#define _BV(x) (1<<(x)) -#endif - -#endif diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bo.c b/bacnet-stack/ports/bdk-atxx4-mstp/bo.c index 1c111dbd..5dd0d605 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/bo.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bo.c @@ -33,8 +33,9 @@ #include "bacenum.h" #include "config.h" /* the custom stuff */ #include "wp.h" +#include "led.h" -#define MAX_BINARY_OUTPUTS 8 +#define MAX_BINARY_OUTPUTS 2 #if (MAX_BINARY_OUTPUTS > 9) #error Modify the Binary_Output_Name to handle multiple digits #endif @@ -48,6 +49,8 @@ static BACNET_BINARY_PV /* Writable out-of-service allows others to play with our Present Value */ /* without changing the physical output */ static bool Binary_Output_Out_Of_Service[MAX_BINARY_OUTPUTS]; +/* polarity - normal or inverse */ +static BACNET_POLARITY Polarity[MAX_BINARY_OUTPUTS]; /* These three arrays are used by the ReadPropertyMultiple handler */ static const int Binary_Output_Properties_Required[] = { @@ -167,6 +170,44 @@ static BACNET_BINARY_PV Binary_Output_Present_Value( return value; } +static void Binary_Output_Sync( + uint32_t object_instance) +{ + BACNET_BINARY_PV pv = Binary_Output_Present_Value(object_instance); + unsigned index = Binary_Output_Instance_To_Index(object_instance); + + if (index < MAX_BINARY_OUTPUTS) { + if (Binary_Output_Out_Of_Service[index]) { + return; + } + if (Polarity[index] == POLARITY_REVERSE) { + if (pv == BINARY_INACTIVE) { + pv = BINARY_ACTIVE; + } else if (pv == BINARY_ACTIVE) { + pv = BINARY_INACTIVE; + } + } + switch (index) { + case 0: + if (pv == BINARY_INACTIVE) { + led_off(LED_3); + } else if (pv == BINARY_ACTIVE) { + led_on(LED_3); + } + break; + case 1: + if (pv == BINARY_INACTIVE) { + led_off(LED_4); + } else if (pv == BINARY_ACTIVE) { + led_on(LED_4); + } + break; + default: + break; + } + } +} + /* note: the object name must be unique within this device */ char *Binary_Output_Name( uint32_t object_instance) @@ -195,7 +236,6 @@ int Binary_Output_Encode_Property_APDU( BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; BACNET_BINARY_PV present_value = BINARY_INACTIVE; - BACNET_POLARITY polarity = POLARITY_NORMAL; unsigned object_index = 0; unsigned i = 0; bool state = false; @@ -244,8 +284,8 @@ int Binary_Output_Encode_Property_APDU( apdu_len = encode_application_boolean(&apdu[0], state); break; case PROP_POLARITY: - /* FIXME: figure out the polarity */ - apdu_len = encode_application_enumerated(&apdu[0], polarity); + apdu_len = encode_application_enumerated(&apdu[0], + Polarity[object_index]); break; case PROP_PRIORITY_ARRAY: /* Array element zero is the number of elements in the array */ @@ -336,7 +376,8 @@ bool Binary_Output_Write_Property( int len = 0; BACNET_APPLICATION_DATA_VALUE value; - if (!Binary_Output_Valid_Instance(wp_data->object_instance)) { + object_index = Binary_Output_Instance_To_Index(wp_data->object_instance); + if (object_index >= MAX_BINARY_OUTPUTS) { *error_class = ERROR_CLASS_OBJECT; *error_code = ERROR_CODE_UNKNOWN_OBJECT; return false; @@ -358,16 +399,9 @@ bool Binary_Output_Write_Property( (priority != 6 /* reserved */ ) && (value.type.Enumerated <= MAX_BINARY_PV)) { level = (BACNET_BINARY_PV) value.type.Enumerated; - object_index = - Binary_Output_Instance_To_Index(wp_data-> - object_instance); priority--; Binary_Output_Level[object_index][priority] = level; - /* Note: you could set the physical output here if we - are the highest priority. - However, if Out of Service is TRUE, then don't set the - physical output. This comment may apply to the - main loop (i.e. check out of service before changing output) */ + Binary_Output_Sync(wp_data->object_instance); status = true; } else if (priority == 6) { /* Command priority 6 is reserved for use by Minimum On/Off @@ -381,18 +415,11 @@ bool Binary_Output_Write_Property( } } else if (value.tag == BACNET_APPLICATION_TAG_NULL) { level = BINARY_NULL; - object_index = - Binary_Output_Instance_To_Index(wp_data->object_instance); priority = wp_data->priority; if (priority && (priority <= BACNET_MAX_PRIORITY)) { priority--; Binary_Output_Level[object_index][priority] = level; - /* Note: you could set the physical output here to the next - highest priority, or to the relinquish default if no - priorities are set. - However, if Out of Service is TRUE, then don't set the - physical output. This comment may apply to the - main loop (i.e. check out of service before changing output) */ + Binary_Output_Sync(wp_data->object_instance); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; @@ -405,17 +432,30 @@ bool Binary_Output_Write_Property( break; case PROP_OUT_OF_SERVICE: if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { - object_index = - Binary_Output_Instance_To_Index(wp_data->object_instance); Binary_Output_Out_Of_Service[object_index] = value.type.Boolean; + Binary_Output_Sync(wp_data->object_instance); status = true; } else { *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_INVALID_DATA_TYPE; } break; - default: + case PROP_POLARITY: + if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { + if (value.type.Enumerated <= MAX_POLARITY) { + Polarity[object_index] = + (BACNET_POLARITY)value.type.Enumerated; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + default: *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; break; diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/Makefile b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/Makefile new file mode 100644 index 00000000..c0d49662 --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/Makefile @@ -0,0 +1,231 @@ +# Hey Emacs, this is a -*- makefile -*- + +# AVR-GCC Makefile template, derived from the WinAVR template (which +# is public domain), believed to be neutral to any flavor of "make" +# (GNU make, BSD make, SysV make) + + +MCU = atmega644p +FORMAT = ihex +TARGET = bootloader +SRC = main.c serial.c +ASRC = +OPT = s +BASEADDR = 0xF800 + +# Name of this Makefile (used for "make depend"). +MAKEFILE = Makefile + +# Debugging format. +# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. +# AVR (extended) COFF requires stabs, plus an avr-objcopy run. +DEBUG = stabs + +# Compiler flag to set the C Standard level. +# c89 - "ANSI" C +# gnu89 - c89 plus GCC extensions +# c99 - ISO C99 standard (not yet fully implemented) +# gnu99 - c99 plus GCC extensions +CSTANDARD = -std=gnu99 + +# Place -D or -U options here +CDEFS = +#CDEFS += -DREMOVE_FLASH_BYTE_SUPPORT +#CDEFS += -DREMOVE_EEPROM_BYTE_SUPPORT +#CDEFS += -DREMOVE_FUSE_AND_LOCK_BIT_SUPPORT +#CDEFS += -DREMOVE_AVRPROG_SUPPORT +#CDEFS += -DREMOVE_BLOCK_SUPPORT + +# Place -I options here +CINCS = + + +CDEBUG = -g$(DEBUG) +CWARN = -Wall -Wstrict-prototypes +CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums +#CEXTRA = -Wa,-adhlns=$(<:.c=.lst) +CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CTUNING) $(CEXTRA) + + +#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs + + +#Additional libraries. + +# Minimalistic printf version +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min + +# Floating point printf version (requires MATH_LIB = -lm below) +PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt + +PRINTF_LIB = + +# Minimalistic scanf version +SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min + +# Floating point + %[ scanf version (requires MATH_LIB = -lm below) +SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt + +SCANF_LIB = + +MATH_LIB = -lm + +# External memory options + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + +#LDMAP = $(LDFLAGS) -Wl,-Map=$(TARGET).map,--cref +LDFLAGS = -Ttext=$(BASEADDR) $(EXTMEMOPTS) $(LDMAP) $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) + + +# Programming support using avrdude. Settings and variables. + +AVRDUDE_PROGRAMMER = stk500 +AVRDUDE_PORT = /dev/ttya + +AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex +#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep + + +# Uncomment the following if you want avrdude's erase cycle counter. +# Note that this counter needs to be initialized first using -Yn, +# see avrdude manual. +#AVRDUDE_ERASE_COUNTER = -y + +# Uncomment the following if you do /not/ wish a verification to be +# performed after programming the device. +#AVRDUDE_NO_VERIFY = -V + +# Increase verbosity level. Please use this when submitting bug +# reports about avrdude. See +# to submit bug reports. +#AVRDUDE_VERBOSE = -v -v + +AVRDUDE_BASIC = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) +AVRDUDE_FLAGS = $(AVRDUDE_BASIC) $(AVRDUDE_NO_VERIFY) $(AVRDUDE_VERBOSE) $(AVRDUDE_ERASE_COUNTER) + + +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +NM = avr-nm +AVRDUDE = avrdude +REMOVE = rm -f +MV = mv -f + +# Define all object files. +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) + +# Define all listing files. +LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) + +# Combine all necessary flags and optional flags. +# Add target processor to flags. +ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) +ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) + + +# Default target. +all: build + +build: elf hex eep + +elf: $(TARGET).elf +hex: $(TARGET).hex +eep: $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + + +# Program the device. +program: $(TARGET).hex $(TARGET).eep + $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT=$(OBJCOPY) --debugging \ +--change-section-address .data-0x800000 \ +--change-section-address .bss-0x800000 \ +--change-section-address .noinit-0x800000 \ +--change-section-address .eeprom-0x810000 + + +coff: $(TARGET).elf + $(COFFCONVERT) -O coff-avr $(TARGET).elf $(TARGET).cof + + +extcoff: $(TARGET).elf + $(COFFCONVERT) -O coff-ext-avr $(TARGET).elf $(TARGET).cof + + +.SUFFIXES: .elf .hex .eep .lss .sym + +.elf.hex: + $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ + +.elf.eep: + -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ + --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ + +# Create extended listing file from ELF output file. +.elf.lss: + $(OBJDUMP) -h -S $< > $@ + +# Create a symbol table from ELF output file. +.elf.sym: + $(NM) -n $< > $@ + + + +# Link: create ELF output file from object files. +$(TARGET).elf: $(OBJ) + $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) + + +# Compile: create object files from C source files. +.c.o: + $(CC) -c $(ALL_CFLAGS) $< -o $@ + + +# Compile: create assembler files from C source files. +.c.s: + $(CC) -S $(ALL_CFLAGS) $< -o $@ + + +# Assemble: create object files from assembler source files. +.S.o: + $(CC) -c $(ALL_ASFLAGS) $< -o $@ + + + +# Target: clean project. +clean: + $(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \ + $(TARGET).map $(TARGET).sym $(TARGET).lss \ + $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) + +depend: + if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \ + then \ + sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \ + $(MAKEFILE).$$$$ && \ + $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \ + fi + echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \ + >> $(MAKEFILE); \ + $(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE) + +.PHONY: all build elf hex eep lss sym program coff extcoff clean depend + + diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/defines.h b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/defines.h new file mode 100644 index 00000000..80ccaafd --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/defines.h @@ -0,0 +1,46 @@ +/* definitions generated by preprocessor, copy into defines.h */ +#ifndef PPINC +#define _ATMEGA644P // device select: _ATMEGAxxxx +#define _B2048 // boot size select: _Bxxxx (words), powers of two only +#ifdef __ICCAVR__ +#include "iom644.h" +#endif +#if __GNUC__ +#include +#endif + +/* define pin for enter-self-prog-mode */ +#define PROGPORT PORTB +#define PROGPIN PINB +#define PROG_NO PB0 + +/* baud rate register value calculation */ +#define CPU_FREQ 18430000 +#define BAUD_RATE 115200 +#define BRREG_VALUE 9 + +/* definitions for UART control */ +#define BAUD_RATE_LOW_REG UBRR1 +#define UART_CONTROL_REG UCSR1B +#define ENABLE_TRANSMITTER_BIT TXEN1 +#define ENABLE_RECEIVER_BIT RXEN1 +#define UART_STATUS_REG UCSR1A +#define TRANSMIT_COMPLETE_BIT TXC1 +#define RECEIVE_COMPLETE_BIT RXC1 +#define UART_DATA_REG UDR1 + +/* definitions for SPM control */ +#define SPMCR_REG SPMCSR +#define PAGESIZE 256 +#define APP_END 61440 +//#define LARGE_MEMORY + +/* definitions for device recognition */ +#define PARTCODE 0 +#define SIGNATURE_BYTE_1 0x1E +#define SIGNATURE_BYTE_2 0x96 +#define SIGNATURE_BYTE_3 0x0A + +/* indicate that preprocessor result is included */ +#define PPINC +#endif diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/flash.h b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/flash.h new file mode 100644 index 00000000..f3433b2c --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/flash.h @@ -0,0 +1,74 @@ +/***************************************************************************** +* +* Atmel Corporation +* +* File : flash.h +* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5) +* Revision : $Revision: 1.7 $ +* Date : $Date: Tuesday, June 07, 200 $ +* Updated by : $Author: raapeland $ +* +* Support mail : avr@atmel.com +* +* Target platform : All AVRs with bootloader support +* +* AppNote : AVR109 - Self-programming +* +* Description : Flash operations for AVR109 Self-programming +****************************************************************************/ + +#if defined(__ICCAVR__) + +/* IAR Embedded Workbench */ +# include + +# define _GET_LOCK_BITS() __AddrToZByteToSPMCR_LPM( (void __flash *) 0x0001, 0x09 ) +# define _GET_LOW_FUSES() __AddrToZByteToSPMCR_LPM( (void __flash *) 0x0000, 0x09 ) +# define _GET_HIGH_FUSES() __AddrToZByteToSPMCR_LPM( (void __flash *) 0x0003, 0x09 ) +# define _GET_EXTENDED_FUSES() __AddrToZByteToSPMCR_LPM( (void __flash *) 0x0002, 0x09 ) +# define _SET_LOCK_BITS(data) __DataToR0ByteToSPMCR_SPM( data, 0x09 ) +# define _ENABLE_RWW_SECTION() __DataToR0ByteToSPMCR_SPM( 0x00, 0x11 ) + +# define _WAIT_FOR_SPM() while( SPMCR_REG & (1< 0 + +/* AVR-GCC/avr-libc */ +# include +# include + +# if defined(GET_LOCK_BITS) /* avr-libc >= 1.2.5 */ +# define _GET_LOCK_BITS() boot_lock_fuse_bits_get(GET_LOCK_BITS) +# define _GET_LOW_FUSES() boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS) +# define _GET_HIGH_FUSES() boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS) +# define _GET_EXTENDED_FUSES() boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS) +# endif /* defined(GET_LOCK_BITS) */ +# define _SET_LOCK_BITS(data) boot_lock_bits_set(~data) +# define _ENABLE_RWW_SECTION() boot_rww_enable() + +# define _WAIT_FOR_SPM() boot_spm_busy_wait() + +# ifndef LARGE_MEMORY +# define _LOAD_PROGRAM_MEMORY(addr) pgm_read_byte_near(addr) +# else /* LARGE_MEMORY */ +# define _LOAD_PROGRAM_MEMORY(addr) pgm_read_byte_far(addr) +# endif /* LARGE_MEMORY */ +# define _FILL_TEMP_WORD(addr,data) boot_page_fill(addr, data) +# define _PAGE_ERASE(addr) boot_page_erase(addr) +# define _PAGE_WRITE(addr) boot_page_write(addr) + +#else +# error "Don't know your compiler." +#endif diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/main.c b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/main.c new file mode 100644 index 00000000..f247d973 --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/main.c @@ -0,0 +1,496 @@ +/***************************************************************************** +* +* Atmel Corporation +* +* File : main.c +* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5) +* Revision : $Revision: 1.7 $ +* Date : $Date: Tuesday, June 07, 200 $ +* Updated by : $Author: raapeland $ +* +* Support mail : avr@atmel.com +* +* Target platform : All AVRs with bootloader support +* +* AppNote : AVR109 - Self-programming +* +* Description : This Program allows an AVR with bootloader capabilities to +* Read/write its own Flash/EEprom. To enter Programming mode +* an input pin is checked. If this pin is pulled low, programming mode +* is entered. If not, normal execution is done from $0000 +* "reset" vector in Application area. +* +* Preparations : Use the preprocessor.xls file for obtaining a customized +* defines.h file and linker-file code-segment definition for +* the device you are compiling for. +****************************************************************************/ +#include "defines.h" +#include "serial.h" +#include "flash.h" + + + +/* Uncomment the following to save code space */ +//#define REMOVE_AVRPROG_SUPPORT +//#define REMOVE_FUSE_AND_LOCK_BIT_SUPPORT +//#define REMOVE_BLOCK_SUPPORT +//#define REMOVE_EEPROM_BYTE_SUPPORT +//#define REMOVE_FLASH_BYTE_SUPPORT + +/* + * GCC doesn't optimize long int arithmetics very clever. As the + * address only needs to be larger than 16 bits for the ATmega128 and + * above (where flash consumptions isn't much of an issue as the + * entire boot loader will still fit even into the smallest possible + * boot loader section), save space by using a 16-bit variable for the + * smaller devices. + */ +#ifdef LARGE_MEMORY +# define ADDR_T unsigned long +#else /* !LARGE_MEMORY */ +# define ADDR_T unsigned int +#endif /* LARGE_MEMORY */ + +#ifndef REMOVE_BLOCK_SUPPORT +unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address); +void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address); + +/* BLOCKSIZE should be chosen so that the following holds: BLOCKSIZE*n = PAGESIZE, where n=1,2,3... */ +#define BLOCKSIZE PAGESIZE + +#endif /* REMOVE_BLOCK_SUPPORT */ + +#ifdef __ICCAVR__ +__C_task void main(void) +#else /* ! __ICCAVR__ */ +int main(void) +#endif /* __ICCAVR__ */ + +{ + ADDR_T address; + unsigned int temp_int; + unsigned char val; + + + /* Initialization */ + void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector. + PROGPORT |= (1<>8) & 0xFF); // MSB first. + sendchar(BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes). + } + + + // Start block load. + else if(val=='B') + { + temp_int = (recchar()<<8) | recchar(); // Get block size. + val = recchar(); // Get memtype. + sendchar( BlockLoad(temp_int,val,&address) ); // Block load. + } + + + // Start block read. + else if(val=='g') + { + temp_int = (recchar()<<8) | recchar(); // Get block size. + val = recchar(); // Get memtype + BlockRead(temp_int,val,&address); // Block read + } +#endif /* REMOVE_BLOCK_SUPPORT */ + +#ifndef REMOVE_FLASH_BYTE_SUPPORT + // Read program memory. + else if(val=='R') + { + // Send high byte, then low byte of flash word. + _WAIT_FOR_SPM(); + _ENABLE_RWW_SECTION(); +#ifdef __ICCAVR__ +#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. +#endif + sendchar( _LOAD_PROGRAM_MEMORY( (address << 1)+1 ) ); + sendchar( _LOAD_PROGRAM_MEMORY( (address << 1)+0 ) ); +#ifdef __ICCAVR__ +#pragma diag_default=Pe1053 // Back to default. +#endif + + address++; // Auto-advance to next Flash word. + } + + + // Write program memory, low byte. + else if(val=='c') + { // NOTE: Always use this command before sending high byte. + temp_int=recchar(); // Get low byte for later _FILL_TEMP_WORD. + sendchar('\r'); // Send OK back. + } + + + // Write program memory, high byte. + else if(val=='C') + { + temp_int |= (recchar()<<8); // Get and insert high byte. + _WAIT_FOR_SPM(); +#ifdef __ICCAVR__ +#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. +#endif + _FILL_TEMP_WORD( (address << 1), temp_int ); // Convert word-address to byte-address and fill. +#ifdef __ICCAVR__ +#pragma diag_default=Pe1053 // Back to default. +#endif + address++; // Auto-advance to next Flash word. + sendchar('\r'); // Send OK back. + } + + + // Write page. + else if(val== 'm') + { + if( address >= (APP_END>>1) ) // Protect bootloader area. + { + sendchar('?'); + } else + { + _WAIT_FOR_SPM(); +#ifdef __ICCAVR__ +#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. +#endif + _PAGE_WRITE( address << 1 ); // Convert word-address to byte-address and write. +#ifdef __ICCAVR__ +#pragma diag_default=Pe1053 // Back to default. +#endif + } + + sendchar('\r'); // Send OK back. + } +#endif /* REMOVE_FLASH_BYTE_SUPPORT */ + +#ifndef REMOVE_EEPROM_BYTE_SUPPORT + // Write EEPROM memory. + else if (val == 'D') + { + _WAIT_FOR_SPM(); + EEARL = address; // Setup EEPROM address. + EEARH = (address >> 8); + EEDR = recchar(); // Get byte. + EECR |= (1<> 8); + EECR |= (1< 0 + sendchar( PARTCODE ); // Supports only this device, of course. +#endif /* PARTCODE */ + sendchar( 0 ); // Send list terminator. + } + + + // Set LED, clear LED and set device type. + else if((val=='x')||(val=='y')||(val=='T')) + { + recchar(); // Ignore the command and it's parameter. + sendchar('\r'); // Send OK back. + } +#endif /* REMOVE_AVRPROG_SUPPORT */ + + // Return programmer identifier. + else if(val=='S') + { + sendchar('A'); // Return 'AVRBOOT'. + sendchar('V'); // Software identifier (aka programmer signature) is always 7 characters. + sendchar('R'); + sendchar('B'); + sendchar('O'); + sendchar('O'); + sendchar('T'); + } + + + // Return software version. + else if(val=='V') + { + sendchar('1'); + sendchar('5'); + } + + + // Return signature bytes. + else if(val=='s') + { + sendchar( SIGNATURE_BYTE_3 ); + sendchar( SIGNATURE_BYTE_2 ); + sendchar( SIGNATURE_BYTE_1 ); + } + + + // The last command to accept is ESC (synchronization). + else if(val!=0x1b) // If not ESC, then it is unrecognized... + { + sendchar('?'); + } + } // end: for(;;) + } + else + { + _WAIT_FOR_SPM(); + _ENABLE_RWW_SECTION(); + funcptr(); // Jump to Reset vector 0x0000 in Application Section. + } +} // end: main + + +#ifndef REMOVE_BLOCK_SUPPORT +unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address) +{ + unsigned char buffer[BLOCKSIZE]; + unsigned int data; + ADDR_T tempaddress; + + // EEPROM memory type. + if(mem=='E') + { + /* Fill buffer first, as EEPROM is too slow to copy with UART speed */ + for(tempaddress=0;tempaddress> 8); + EEDR = buffer[tempaddress]; // Get byte. + EECR |= (1<>= 1; // Convert address back to Flash words again. + return '\r'; // Report programming OK + } + + // Invalid memory type? + else + { + return '?'; + } +} + + +void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address) +{ + // EEPROM memory type. + if (mem=='E') // Read EEPROM + { + do + { + EEARL = *address; // Setup EEPROM address + EEARH = ((*address) >> 8); + (*address)++; // Select next EEPROM byte + EECR |= (1<>= 1; // Convert address back to Flash words again. + } +} +#endif /* REMOVE_BLOCK_SUPPORT */ + + +/* end of file */ diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/parts.txt b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/parts.txt new file mode 100644 index 00000000..b9d06010 --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/parts.txt @@ -0,0 +1,24 @@ +#Extracted from "Part definitions" of preprocessor.xls +#dev include pagesz nrwwpag totpag avr910 sig1 sig2 sig3 baudlo uartc uarts txen rxen txc rxc udr spmcr +ATmega8 iom8.h 32 32 128 0x77 0x1E 0x93 0x07 UBRRL UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCR +ATmega8515 iom8515.h 32 32 128 0x3B 0x1E 0x93 0x06 UBRRL UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCR +ATmega8535 iom8535.h 32 32 128 0x6A 0x1E 0x93 0x08 UBRRL UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCR +ATmega88 iom88.h 32 32 128 0x1E 0x93 0x0A UBRR0L UCSR0B UCSR0A TXEN0 RXEN0 TXC0 RXC0 UDR0 SPMCSR +ATmega16 iom16.h 64 16 128 0x75 0x1E 0x94 0x03 UBRRL UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCR +ATmega162 iom162.h 64 16 128 0x63 0x1E 0x94 0x04 UBRR0L UCSR0B UCSR0A TXEN0 RXEN0 TXC0 RXC0 UDR0 SPMCR +ATmega163 iom163.h 64 16 128 0x66 0x1E 0x94 0x02 UBRRLO UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCR +ATmega165 iom165.h 64 16 128 0x1E 0x94 0x07 UBRRL UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCSR +ATmega168 iom168.h 64 16 128 0x1E 0x94 0x06 UBRR0L UCSR0B UCSR0A TXEN0 RXEN0 TXC0 RXC0 UDR0 SPMCSR +ATmega169 iom169.h 64 16 128 0x79 0x1E 0x94 0x05 UBRR0L UCSR0B UCSR0A TXEN0 RXEN0 TXC0 RXC0 UDR0 SPMCSR +ATmega32 iom32.h 64 32 256 0x7F 0x1E 0x95 0x02 UBRRL UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCR +ATmega323 iom323.h 64 16 256 0x73 0x1E 0x95 0x01 UBRRL UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCR +ATmega329 iom329.h 64 32 256 0x1E 0x95 0x03 UBRR UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCSR +ATmega3290 iom3290.h 64 32 256 0x1E 0x95 0x04 UBRR UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCSR +ATmega64 iom64.h 128 32 256 0x46 0x1E 0x96 0x02 UBRR0L UCSR0B UCSR0A TXEN0 RXEN0 TXC0 RXC0 UDR0 SPMCR +ATmega644 iom644.h 128 32 256 0x1E 0x96 0x09 UBRR0 UCSR0B UCSR0A TXEN0 RXEN0 TXC0 RXC0 UDR0 SPMCSR +ATmega644P iom644.h 128 32 256 0x1E 0x96 0x0A UBRR1 UCSR1B UCSR1A TXEN1 RXEN1 TXC1 RXC1 UDR1 SPMCSR +ATmega649 iom649.h 128 32 256 0x1E 0x96 0x03 UBRR UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCSR +ATmega6490 iom6490.h 128 32 256 0x1E 0x96 0x04 UBRR UCSRB UCSRA TXEN RXEN TXC RXC UDR SPMCSR +ATmega128 iom128.h 128 32 512 0x44 0x1E 0x97 0x02 UBRR0L UCSR0B UCSR0A TXEN0 RXEN0 TXC0 RXC0 UDR0 SPMCSR +ATmega128_1 iom128.h 128 32 512 0x44 0x1E 0x97 0x02 UBRR1L UCSR1B UCSR1A TXEN1 RXEN1 TXC1 RXC1 UDR1 SPMCSR + diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/preprocessor.sh b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/preprocessor.sh new file mode 100644 index 00000000..0a8db489 --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/preprocessor.sh @@ -0,0 +1,171 @@ +#! /bin/sh + +# Equivalent script to what preprocessor.xls might do. +# +# Run e.g. like +# sh preprocessor.sh ATmega128 4096 PORTD PD4 3686400 9600 > defines.h +# +# Written by Joerg Wunsch, 2005-07-29 + +PARTFILE=parts.txt + +usage() +{ + echo "usage: preprocessor.sh device bootsize progport prog_no cpu_freq baud_rate" >& 2 + exit 1 +} + +if [ $# -ne 6 ] +then + usage +fi + +if [ ! -f ${PARTFILE} ] +then + echo "part definition file ${PARTFILE} not found" >& 2 + exit 1 +fi + +device="$1" +bootsize="$2" +progport="$3" +prog_no="$4" +cpu_freq="$5" +baud_rate="$6" + +# is there a device at all? +if grep -i "^${device} " ${PARTFILE} >/dev/null +then + : +else + echo "device ${device} not found in ${PARTFILE}" >& 2 + exit 1 +fi +devupper=`echo $device | tr '[a-z]' '[A-Z]'` + +# find an awk to use, out of nawk, gawk, or awk +AWK=none +for name in nawk gawk awk +do + set -- `type $name 2>/dev/null` + if [ "x$2" = 'xis' ] + then + AWK=$name + break + fi +done +if [ $AWK = 'none' ] +then + echo "Sorry, no useable awk found" >& 2 + exit 1 +fi + +# OK, now get the individual fields. Unfortunately, the AVR910 device ID +# is optional, and the shell cannot parse that natively. Use awk to +# re-order the fields, and sort the avr910 column last (so we'll get an +# empty variable in read if it is not present). +set -- `grep -i "^${device} " ${PARTFILE} |\ +${AWK} -F ' ' \ +'{print $1 " " $2 " " $3 " " $4 " " $5 " " $7 " " $8 " " $9 " " $10 " " $11 " " $12 " " $13 " " $14 " " $15 " " $16 " " $17 " " $18 " " $6; exit}'` +dev=$1 +include=$2 +pagesz=$3 +nrwwpag=$4 +totpag=$5 +sig1=$6 +sig2=$7 +sig3=$8 +baudlo=$9 +shift 9 +uartc=$1 +uarts=$2 +txen=$3 +rxen=$4 +txc=$5 +rxc=$6 +udr=$7 +spmcr=$8 +avr910=$9 + +# Verify boot size +pagebytes=`expr $pagesz \* 2` +maxboot=`expr $nrwwpag \* $pagebytes` +bootbytes=`expr 2 \* $bootsize` || exit 1 +if [ \( $bootbytes -ne $maxboot \) -a \ + \( $bootbytes -ne `expr $maxboot / 4` \) -a \ + \( $bootbytes -ne `expr $maxboot / 2` \) -a \ + \( $bootbytes -ne `expr $maxboot \* 3 / 4` \) ] +then + echo "Invalid boot size ${bootsize}, valid: `expr $maxboot / 8`, `expr $maxboot / 4`, `expr $maxboot \* 3 / 8`, `expr $maxboot / 2` words" >& 2 + exit 1 +fi + +if p=`expr $progport : 'PORT\(.\)'` +then + : # ok +else + echo "Invalid port name ${progport}, must be PORTx" >& 2 + exit 1 +fi +progpin="PIN$p" + +brreg=`expr $cpu_freq / \( 16 \* $baud_rate \) - 1` || exit 1 +memsize=`expr $totpag \* $pagebytes` +append=`expr $memsize - $bootbytes` + +echo "/* definitions generated by preprocessor, copy into defines.h */ +#ifndef PPINC +#define _${devupper} // device select: _ATMEGAxxxx +#define _B${bootsize} // boot size select: _Bxxxx (words), powers of two only +#ifdef __ICCAVR__ +#include \"${include}\" +#endif +#if __GNUC__ +#include +#endif + +/* define pin for enter-self-prog-mode */ +#define PROGPORT ${progport} +#define PROGPIN ${progpin} +#define PROG_NO ${prog_no} + +/* baud rate register value calculation */ +#define CPU_FREQ ${cpu_freq} +#define BAUD_RATE ${baud_rate} +#define BRREG_VALUE ${brreg} + +/* definitions for UART control */ +#define BAUD_RATE_LOW_REG ${baudlo} +#define UART_CONTROL_REG ${uartc} +#define ENABLE_TRANSMITTER_BIT ${txen} +#define ENABLE_RECEIVER_BIT ${rxen} +#define UART_STATUS_REG ${uarts} +#define TRANSMIT_COMPLETE_BIT ${txc} +#define RECEIVE_COMPLETE_BIT ${rxc} +#define UART_DATA_REG ${udr} + +/* definitions for SPM control */ +#define SPMCR_REG ${spmcr} +#define PAGESIZE ${pagebytes} +#define APP_END ${append}" + +if [ $memsize -gt 65536 ] +then + echo "#define LARGE_MEMORY" +else + echo "//#define LARGE_MEMORY" +fi + +echo " +/* definitions for device recognition */ +#define PARTCODE ${avr910} +#define SIGNATURE_BYTE_1 ${sig1} +#define SIGNATURE_BYTE_2 ${sig2} +#define SIGNATURE_BYTE_3 ${sig3} + +/* indicate that preprocessor result is included */ +#define PPINC +#endif" + +echo "(IAR) Replace all code segment definitions in the linker file with the following line:" >& 2 +${AWK} 'BEGIN {printf "-Z(CODE)INTVEC,FAR_F,SWITCH,CODE=%X-%X\n", '$append', '$memsize' - 1; exit}' >& 2 diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/preprocessor.xls b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/preprocessor.xls new file mode 100644 index 0000000000000000000000000000000000000000..5bed7ef396b1063edf885483f955f7f4a894d748 GIT binary patch literal 39424 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 P?guW1Zn-qS%lZF*U-J>% literal 0 HcmV?d00001 diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.c b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.c new file mode 100644 index 00000000..59b0c8b3 --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.c @@ -0,0 +1,42 @@ +/***************************************************************************** +* +* Atmel Corporation +* +* File : serial.c +* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5) +* Revision : $Revision: 1.7 $ +* Date : $Date: Tuesday, June 07, 200 $ +* Updated by : $Author: raapeland $ +* +* Support mail : avr@atmel.com +* +* Target platform : All AVRs with bootloader support +* +* AppNote : AVR109 - Self-programming +* +* Description : UART communication routines +****************************************************************************/ +#include "defines.h" + + +void initbootuart(void) +{ + BAUD_RATE_LOW_REG = BRREG_VALUE; + UART_CONTROL_REG = (1 << ENABLE_RECEIVER_BIT) | + (1 << ENABLE_TRANSMITTER_BIT); // enable receive and transmit +} + + +void sendchar(unsigned char c) +{ + UART_DATA_REG = c; // prepare transmission + while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT)));// wait until byte sendt + UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT); // delete TXCflag +} + + +unsigned char recchar(void) +{ + while(!(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT))); // wait for data + return UART_DATA_REG; +} diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.h b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.h new file mode 100644 index 00000000..c7a78aa7 --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/bootloader/serial.h @@ -0,0 +1,22 @@ +/***************************************************************************** +* +* Atmel Corporation +* +* File : serial.h +* Compiler : IAR C 3.10C Kickstart, AVR-GCC/avr-libc(>= 1.2.5) +* Revision : $Revision: 1.7 $ +* Date : $Date: Tuesday, June 07, 200 $ +* Updated by : $Author: raapeland $ +* +* Support mail : avr@atmel.com +* +* Target platform : All AVRs with bootloader support +* +* AppNote : AVR109 - Self-programming +* +* Description : Header file for serial.c +****************************************************************************/ + +void initbootuart( void ); +void sendchar( unsigned char ); +unsigned char recchar( void ); diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/device.c b/bacnet-stack/ports/bdk-atxx4-mstp/device.c index 9187421b..0a4e45b7 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/device.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/device.c @@ -34,6 +34,7 @@ #include "datalink.h" #include "rs485.h" #include "version.h" +#include "nvdata.h" /* objects */ #include "device.h" #include "ai.h" @@ -44,13 +45,69 @@ properties that are writable or that may change. The properties that are constant can be hard coded into the read-property encoding. */ -static uint32_t Object_Instance_Number = BACNET_MAX_INSTANCE; -static char Object_Name[32] = "bdk-atxx4-mstp"; +static uint32_t Object_Instance_Number; +static uint8_t Object_Name[NV_EEPROM_DEVICE_NAME_SIZE]; +static uint8_t Object_Name_Encoding; +static uint8_t Object_Name_Length; static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; -BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State = +static BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State = REINITIALIZED_STATE_IDLE; + +/* These three arrays are used by the ReadPropertyMultiple handler */ +static const int Device_Properties_Required[] = { + PROP_OBJECT_IDENTIFIER, + PROP_OBJECT_NAME, + PROP_OBJECT_TYPE, + PROP_SYSTEM_STATUS, + PROP_VENDOR_NAME, + PROP_VENDOR_IDENTIFIER, + PROP_MODEL_NAME, + PROP_FIRMWARE_REVISION, + PROP_APPLICATION_SOFTWARE_VERSION, + PROP_PROTOCOL_VERSION, + PROP_PROTOCOL_REVISION, + PROP_PROTOCOL_SERVICES_SUPPORTED, + PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, + PROP_OBJECT_LIST, + PROP_MAX_APDU_LENGTH_ACCEPTED, + PROP_SEGMENTATION_SUPPORTED, + PROP_APDU_TIMEOUT, + PROP_NUMBER_OF_APDU_RETRIES, +#if defined(BACDL_MSTP) + PROP_MAX_MASTER, + PROP_MAX_INFO_FRAMES, +#endif + PROP_DEVICE_ADDRESS_BINDING, + PROP_DATABASE_REVISION, + -1 +}; +static const int Device_Properties_Optional[] = { + PROP_DESCRIPTION, + PROP_PROTOCOL_CONFORMANCE_CLASS, + -1 +}; + +static const int Device_Properties_Proprietary[] = { + -1 +}; + +void Device_Property_Lists( + const int **pRequired, + const int **pOptional, + const int **pProprietary) +{ + if (pRequired) + *pRequired = Device_Properties_Required; + if (pOptional) + *pOptional = Device_Properties_Optional; + if (pProprietary) + *pProprietary = Device_Properties_Proprietary; + + return; +} + void Device_Reinit( void) { @@ -63,11 +120,43 @@ void Device_Init( { Reinitialize_State = REINITIALIZED_STATE_IDLE; dcc_set_status_duration(COMMUNICATION_ENABLE, 0); - /* FIXME: Get the data from the eeprom */ - /* I2C_Read_Block(EEPROM_DEVICE_ADDRESS, - (char *)&Object_Instance_Number, - sizeof(Object_Instance_Number), - EEPROM_BACNET_ID_ADDR); */ + /* Get the data from the eeprom */ + eeprom_bytes_read( + NV_EEPROM_DEVICE_0, + (uint8_t *)&Object_Instance_Number, + sizeof(Object_Instance_Number)); + if (Object_Instance_Number >= BACNET_MAX_INSTANCE) { + Object_Instance_Number = 0; + eeprom_bytes_write( + NV_EEPROM_DEVICE_0, + (uint8_t *)&Object_Instance_Number, + sizeof(Object_Instance_Number)); + } + eeprom_bytes_read( + NV_EEPROM_DEVICE_NAME_ENCODING, + &Object_Name_Encoding, + 1); + eeprom_bytes_read( + NV_EEPROM_DEVICE_NAME_LENGTH, + &Object_Name_Length, + 1); + eeprom_bytes_read( + NV_EEPROM_DEVICE_NAME_0, + (uint8_t *)&Object_Name[0], + NV_EEPROM_DEVICE_NAME_SIZE); + if ((Object_Name_Encoding >= MAX_CHARACTER_STRING_ENCODING) || + (Object_Name_Length > NV_EEPROM_DEVICE_NAME_SIZE)) { + Object_Name_Encoding = CHARACTER_ANSI_X34; + Object_Name_Length = 0; + eeprom_bytes_write( + NV_EEPROM_DEVICE_NAME_ENCODING, + &Object_Name_Encoding, + 1); + eeprom_bytes_write( + NV_EEPROM_DEVICE_NAME_LENGTH, + &Object_Name_Length, + 1); + } } /* methods to manipulate the data */ @@ -84,12 +173,10 @@ bool Device_Set_Object_Instance_Number( if (object_id <= BACNET_MAX_INSTANCE) { Object_Instance_Number = object_id; - /* FIXME: Write the data to the eeprom */ - /* I2C_Write_Block( - EEPROM_DEVICE_ADDRESS, - (char *)&Object_Instance_Number, - sizeof(Object_Instance_Number), - EEPROM_BACNET_ID_ADDR); */ + eeprom_bytes_write( + NV_EEPROM_DEVICE_0, + (uint8_t *)&Object_Instance_Number, + sizeof(Object_Instance_Number)); } else status = false; @@ -237,8 +324,6 @@ int Device_Encode_Property_APDU( int object_type = 0; uint32_t instance = 0; unsigned count = 0; - BACNET_TIME local_time; - BACNET_DATE local_date; /* FIXME: change the hardcoded names to suit your application */ switch (property) { @@ -248,7 +333,10 @@ int Device_Encode_Property_APDU( Object_Instance_Number); break; case PROP_OBJECT_NAME: - characterstring_init_ansi(&char_string, Object_Name); + characterstring_init(&char_string, + Object_Name_Encoding, + (char *)&Object_Name[0], + Object_Name_Length); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -256,7 +344,7 @@ int Device_Encode_Property_APDU( apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE); break; case PROP_DESCRIPTION: - characterstring_init_ansi(&char_string, "BACnet Demo"); + characterstring_init_ansi(&char_string, "BACnet Development Kit"); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -276,7 +364,7 @@ int Device_Encode_Property_APDU( Device_Vendor_Identifier()); break; case PROP_MODEL_NAME: - characterstring_init_ansi(&char_string, "GNU Demo"); + characterstring_init_ansi(&char_string, "bdk-atxx4-mstp"); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -290,11 +378,6 @@ int Device_Encode_Property_APDU( apdu_len = encode_application_character_string(&apdu[0], &char_string); break; - case PROP_LOCATION: - characterstring_init_ansi(&char_string, "USA"); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; case PROP_PROTOCOL_VERSION: apdu_len = encode_application_unsigned(&apdu[0], @@ -330,10 +413,9 @@ int Device_Encode_Property_APDU( } /* FIXME: indicate the objects that YOU support */ bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); - bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); - bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true); + bitstring_set_bit(&bit_string, OBJECT_BINARY_OUTPUT, true); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_OBJECT_LIST: @@ -413,30 +495,6 @@ int Device_Encode_Property_APDU( apdu_len = encode_application_unsigned(&apdu[0], dlmstp_max_master()); break; - case PROP_LOCAL_TIME: - /* FIXME: if you support time */ - local_time.hour = 0; - local_time.min = 0; - local_time.sec = 0; - local_time.hundredths = 0; - apdu_len = encode_application_time(&apdu[0], &local_time); - break; - case PROP_UTC_OFFSET: - /* Note: BACnet Time Zone is inverse of everybody else */ - apdu_len = encode_application_signed(&apdu[0], 5 /* EST */ ); - break; - case PROP_LOCAL_DATE: - /* FIXME: if you support date */ - local_date.year = 2006; /* AD */ - local_date.month = 4; /* Jan=1..Dec=12 */ - local_date.day = 11; /* 1..31 */ - local_date.wday = 0; /* 1=Mon..7=Sun */ - apdu_len = encode_application_date(&apdu[0], &local_date); - break; - case PROP_DAYLIGHT_SAVINGS_STATUS: - /* FIXME: if you support time/date */ - apdu_len = encode_application_boolean(&apdu[0], false); - break; default: *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY; @@ -515,27 +573,55 @@ bool Device_Write_Property( break; case PROP_OBJECT_NAME: if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { - uint8_t encoding; - size_t len; - - encoding = - characterstring_encoding(&value.type.Character_String); - len = characterstring_length(&value.type.Character_String); - if (encoding == CHARACTER_ANSI_X34) { - if (len <= 20) { - /* FIXME: set the name */ - /* Display_Set_Name( - characterstring_value(&value.type.Character_String)); */ - /* FIXME: All the object names in a device must be unique. - Disallow setting the Device Object Name to any objects in - the device. */ - } else { + size_t length = + characterstring_length(&value.type.Character_String); + if (length < NV_EEPROM_DEVICE_NAME_SIZE) { + uint8_t encoding = + characterstring_encoding(&value.type.Character_String); + if (encoding < MAX_CHARACTER_STRING_ENCODING) { + uint8_t i; + char *pCharString; + Object_Name_Encoding = encoding; + Object_Name_Length = length; + eeprom_bytes_write( + NV_EEPROM_DEVICE_NAME_ENCODING, + &Object_Name_Encoding, + 1); + eeprom_bytes_write( + NV_EEPROM_DEVICE_NAME_LENGTH, + &Object_Name_Length, + 1); + pCharString = + characterstring_value(&value.type.Character_String); + for (i = 0; i < Object_Name_Length; i++) { + Object_Name[i] = pCharString[i]; + } + eeprom_bytes_write( + NV_EEPROM_DEVICE_NAME_0, + (uint8_t *)&Object_Name[0], + length); + status = true; + } else { *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; + *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; } } else { *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; + *error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; + } + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + case 9600: + if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { + if ((value.type.Unsigned_Int > 115200) && + (rs485_baud_rate_set(value.type.Unsigned_Int))) { + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; } } else { *error_class = ERROR_CLASS_PROPERTY; diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c index cd17ced0..62af6916 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/dlmstp.c @@ -157,13 +157,13 @@ static uint8_t This_Station; /* 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. */ -static uint8_t Nmax_info_frames; +static uint8_t Nmax_info_frames = 1; /* 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. */ -static uint8_t Nmax_master; +static uint8_t Nmax_master = 127; /* An array of octets, used to store octets for transmitting */ /* OutputBuffer is indexed from 0 to OutputBufferSize-1. */ /* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */ diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/h_rd.c b/bacnet-stack/ports/bdk-atxx4-mstp/h_rd.c new file mode 100644 index 00000000..b26d3edc --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/h_rd.c @@ -0,0 +1,113 @@ +/************************************************************************** +* +* Copyright (C) 2009 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include "config.h" +#include "txbuf.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "bacerror.h" +#include "apdu.h" +#include "npdu.h" +#include "abort.h" +#include "reject.h" +#include "rd.h" + +static char *Password = "rehmite"; +static BACNET_CHARACTER_STRING My_Password; + +void handler_reinitialize_device( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data) +{ + BACNET_REINITIALIZED_STATE state; + BACNET_CHARACTER_STRING their_password; + int len = 0; + int pdu_len = 0; + BACNET_NPDU_DATA npdu_data; + int bytes_sent = 0; + BACNET_ADDRESS my_address; + + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = + npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, + &npdu_data); + if (service_data->segmented_message) { + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); + goto RD_ABORT; + } + /* decode the service request only */ + len = + rd_decode_service_request(service_request, service_len, &state, + &their_password); + /* bad decoding or something we didn't understand - send an abort */ + if (len < 0) { + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_OTHER, true); + goto RD_ABORT; + } + /* check the data from the request */ + if (state >= MAX_BACNET_REINITIALIZED_STATE) { + len = + reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); + } else { + characterstring_init_ansi(&My_Password, Password); + if (characterstring_same(&their_password, &My_Password)) { + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_REINITIALIZE_DEVICE); + /* FIXME: now you can reboot, restart, quit, or something clever */ + /* Note: you can use a mix of state and password to do specific stuff */ + /* Note: if you don't do something clever like actually restart, + you probably should clear any DCC status and timeouts */ + /* Note: you probably need to send the reply BEFORE restarting */ + } else { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE, + ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE); + } + } +RD_ABORT: + pdu_len += len; + bytes_sent = + datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], + pdu_len); + + return; +} diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/hardware.ods b/bacnet-stack/ports/bdk-atxx4-mstp/hardware.ods index 9b97124416181f69da27f34aa6399af7f23be8eb..3e2ab070582108d2a645b464a6d0427e77b117bb 100644 GIT binary patch delta 13356 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 delta 15899 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 Y0QbM%MBqDEpGb0)041c1*uSFx2jaJIkN^Mx diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/input.c b/bacnet-stack/ports/bdk-atxx4-mstp/input.c index 52173fc5..6c401668 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/input.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/input.c @@ -38,11 +38,6 @@ void input_task( } else { if (old_value != Address_Switch) { Address_Switch = old_value; -#if defined(BACDL_MSTP) -// dlmstp_set_mac_address(Address_Switch); -#endif -// Device_Set_Object_Instance_Number(86000 + Address_Switch); -// Send_I_Am_Flag = true; } } } diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/main.c b/bacnet-stack/ports/bdk-atxx4-mstp/main.c index dac96e61..dca4fc5f 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/main.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/main.c @@ -1,4 +1,4 @@ -/************************************************************************** +/************************************************************************ * * Copyright (C) 2009 Steve Karg * @@ -21,7 +21,7 @@ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -*********************************************************************/ +*************************************************************************/ #include #include @@ -54,25 +54,72 @@ static uint8_t MSTP_MAC_Address; /* For porting to IAR, see: http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ +#if defined(__GNUC__) +/* AVR fuse settings */ +FUSES = +{ + /* External Ceramic Resonator - configuration */ + /* Full Swing Crystal Oscillator Clock Selection */ + /* Ceramic resonator, slowly rising power 1K CK 14CK + 65 ms */ + /* note: fuses are enabled by clearing the bit, so + any fuses listed below are cleared fuses. */ + .low = (FUSE_CKSEL3 & + FUSE_SUT0 & + FUSE_SUT1), + + /* FIXME: bootrst */ + /* BOOTSZ configuration: + BOOTSZ1 BOOTSZ0 Boot Size + ------- ------- --------- + 1 1 512 + 1 0 1024 + 0 1 2048 + 0 0 4096 + */ + /* note: fuses are enabled by clearing the bit, so + any fuses listed below are cleared fuses. */ + .high = ( + FUSE_BOOTSZ1 & + FUSE_BOOTRST & + FUSE_EESAVE & + FUSE_SPIEN & + FUSE_JTAGEN), + + /* Brown-out detection VCC=2.7V */ + /* BODLEVEL configuration + BODLEVEL2 BODLEVEL1 BODLEVEL0 Voltage + --------- --------- --------- -------- + 1 1 1 disabled + 1 1 0 1.8V + 1 0 1 2.7V + 1 0 0 4.3V + */ + /* note: fuses are enabled by clearing the bit, so + any fuses listed below are cleared fuses. */ + .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0), +}; +/* AVR lock bits - unlocked */ +LOCKBITS = LOCKBITS_DEFAULT; +#endif + static void bacnet_init( void) { -#if defined(BACDL_MSTP) MSTP_MAC_Address = input_address(); - /* configure the BACnet Datalink */ - rs485_baud_rate_set(9600); - dlmstp_set_max_master(127); - dlmstp_set_max_info_frames(1); dlmstp_set_mac_address(MSTP_MAC_Address); dlmstp_init(NULL); -#endif - Device_Set_Object_Instance_Number(4194303); + /* initialize objects */ + Device_Init(); + Binary_Output_Init(); + /* we need to handle who-is to support dynamic device binding */ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); /* Set the handlers for any confirmed services that we support. */ /* We must implement read property - it's required! */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); + apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, + handler_read_property_multiple); apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device); apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, @@ -94,6 +141,7 @@ static void bacnet_task(void) mstp_mac_address = input_address(); if (MSTP_MAC_Address != mstp_mac_address) { MSTP_MAC_Address = mstp_mac_address; + dlmstp_set_mac_address(MSTP_MAC_Address); Send_I_Am(&Handler_Transmit_Buffer[0]); } if (timer_elapsed_seconds(TIMER_DCC, 1)) { @@ -113,6 +161,8 @@ void idle_init(void) void idle_task(void) { +#if 0 + /* blink the leds */ if (timer_elapsed_seconds(TIMER_LED_3, 1)) { timer_reset(TIMER_LED_3); led_toggle(LED_3); @@ -121,6 +171,7 @@ void idle_task(void) timer_reset(TIMER_LED_4); led_toggle(LED_4); } +#endif } int main( diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/nvdata.h b/bacnet-stack/ports/bdk-atxx4-mstp/nvdata.h new file mode 100644 index 00000000..1cfdbccd --- /dev/null +++ b/bacnet-stack/ports/bdk-atxx4-mstp/nvdata.h @@ -0,0 +1,104 @@ +/************************************************************************ +* +* Copyright (C) 2009 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*************************************************************************/ +#ifndef NVDATA_H +#define NVDATA_H + +#include "seeprom.h" +#include "eeprom.h" + +/* data version - use to check valid version */ +#define SEEPROM_ID 0xBAC0 +#define SEEPROM_VERSION 0x0001 + +#define SEEPROM_BYTES_MAX (2*1024) + +/* list of SEEPROM addresses */ +/* note to developers: define each byte, + even if they are not used explicitly */ +#define NV_SEEPROM_TYPE_0 0 +#define NV_SEEPROM_TYPE_1 1 +#define NV_SEEPROM_VERSION_0 2 +#define NV_SEEPROM_VERSION_1 3 +/* --- */ +/* define the MAC, BAUD, MAX Master, Device Instance internal + so that bootloader *could* use them. */ +/* note: MAC could come from DIP switch, or be in non-volatile memory */ +#define NV_EEPROM_MAC 0 +/* 9=9.6k, 19=19.2k, 38=38.4k, 57=57.6k, 76=76.8k, 115=115.2k */ +#define NV_EEPROM_BAUD_K 1 +#define NV_EEPROM_MAX_MASTER 2 +/* device instance is only 22 bits - easier if we use 32 bits */ +#define NV_EEPROM_DEVICE_0 3 +#define NV_EEPROM_DEVICE_1 4 +#define NV_EEPROM_DEVICE_2 5 +#define NV_EEPROM_DEVICE_3 6 +/* Device Name */ +#define NV_EEPROM_DEVICE_NAME_LENGTH 8 +#define NV_EEPROM_DEVICE_NAME_ENCODING 9 +#define NV_EEPROM_DEVICE_NAME_0 10 +#define NV_EEPROM_DEVICE_NAME_1 11 +#define NV_EEPROM_DEVICE_NAME_2 12 +#define NV_EEPROM_DEVICE_NAME_3 13 +#define NV_EEPROM_DEVICE_NAME_4 14 +#define NV_EEPROM_DEVICE_NAME_5 15 +#define NV_EEPROM_DEVICE_NAME_6 16 +#define NV_EEPROM_DEVICE_NAME_7 17 +#define NV_EEPROM_DEVICE_NAME_8 18 +#define NV_EEPROM_DEVICE_NAME_9 19 +#define NV_EEPROM_DEVICE_NAME_10 20 +#define NV_EEPROM_DEVICE_NAME_11 21 +#define NV_EEPROM_DEVICE_NAME_12 22 +#define NV_EEPROM_DEVICE_NAME_13 23 +#define NV_EEPROM_DEVICE_NAME_14 24 +#define NV_EEPROM_DEVICE_NAME_15 25 +#define NV_EEPROM_DEVICE_NAME_16 26 +#define NV_EEPROM_DEVICE_NAME_17 27 +#define NV_EEPROM_DEVICE_NAME_18 28 +#define NV_EEPROM_DEVICE_NAME_19 29 +#define NV_EEPROM_DEVICE_NAME_20 30 +#define NV_EEPROM_DEVICE_NAME_21 31 +#define NV_EEPROM_DEVICE_NAME_22 32 +#define NV_EEPROM_DEVICE_NAME_23 33 +#define NV_EEPROM_DEVICE_NAME_24 34 +#define NV_EEPROM_DEVICE_NAME_25 35 +#define NV_EEPROM_DEVICE_NAME_26 36 +#define NV_EEPROM_DEVICE_NAME_27 37 +#define NV_EEPROM_DEVICE_NAME_28 38 +#define NV_EEPROM_DEVICE_NAME_29 39 +#define NV_EEPROM_DEVICE_NAME_30 40 +#define NV_EEPROM_DEVICE_NAME_31 41 +#define NV_EEPROM_DEVICE_NAME_SIZE 32 + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c index c16ce208..7fadea85 100644 --- a/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c +++ b/bacnet-stack/ports/bdk-atxx4-mstp/rs485.c @@ -28,6 +28,7 @@ #include "fifo.h" #include "timer.h" #include "led.h" +#include "nvdata.h" /* baud rate */ static uint32_t Baud_Rate = 9600; @@ -152,10 +153,19 @@ uint32_t rs485_baud_rate( return Baud_Rate; } +static void rs485_baud_rate_configure(void) +{ + /* 2x speed mode */ + BIT_SET(UCSR0A, U2X0); + /* configure baud rate */ + UBRR0 = (F_CPU / (8UL * Baud_Rate)) - 1; +} + bool rs485_baud_rate_set( uint32_t baud) { bool valid = true; + uint8_t baud_k = 0; switch (baud) { case 9600: @@ -165,11 +175,13 @@ bool rs485_baud_rate_set( case 76800: case 115200: Baud_Rate = baud; - /* 2x speed mode */ - BIT_SET(UCSR0A, U2X0); - /* configure baud rate */ - UBRR0 = (F_CPU / (8UL * Baud_Rate)) - 1; - /* FIXME: store the baud rate */ + rs485_baud_rate_configure(); + /* store the baud rate */ + baud_k = baud/1000; + eeprom_bytes_write( + NV_EEPROM_BAUD_K, + &baud_k, + 1); break; default: valid = false; @@ -195,13 +207,53 @@ static void rs485_usart_init(void) BIT_CLEAR(PRR, PRUSART0); } +static void rs485_init_nvdata(void) +{ + uint8_t baud_k = 9; /* from EEPROM value */ + + eeprom_bytes_read( + NV_EEPROM_BAUD_K, + &baud_k, + 1); + switch (baud_k) { + case 9: + Baud_Rate = 9600; + break; + case 19: + Baud_Rate = 19200; + break; + case 38: + Baud_Rate = 38400; + break; + case 57: + Baud_Rate = 57600; + break; + case 76: + Baud_Rate = 76800; + break; + case 115: + Baud_Rate = 115200; + break; + default: + /* not configured yet */ + Baud_Rate = 38400; + baud_k = 38400/1000; + eeprom_bytes_write( + NV_EEPROM_BAUD_K, + &baud_k, + 1); + break; + } + rs485_baud_rate_configure(); +} + void rs485_init(void) { FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], (unsigned)sizeof(Receive_Buffer_Data)); rs485_rts_init(); rs485_usart_init(); - rs485_baud_rate_set(Baud_Rate); + rs485_init_nvdata(); rs485_receiver_enable(); rs485_rts_enable(false); }