From 69ddb269b7071205fa334d80e0752aafbfb3bf19 Mon Sep 17 00:00:00 2001 From: skarg Date: Wed, 5 Sep 2007 23:47:15 +0000 Subject: [PATCH] Creating ATmega demo. --- bacnet-stack/ports/atmega168/Makefile | 11 +- bacnet-stack/ports/atmega168/ai.c | 148 ++++++++++++++++++++++++++ bacnet-stack/ports/atmega168/device.c | 34 +++--- bacnet-stack/ports/atmega168/h_rp.c | 36 +------ bacnet-stack/ports/atmega168/main.c | 9 +- 5 files changed, 180 insertions(+), 58 deletions(-) create mode 100644 bacnet-stack/ports/atmega168/ai.c diff --git a/bacnet-stack/ports/atmega168/Makefile b/bacnet-stack/ports/atmega168/Makefile index 236e66c2..7fd3e5a0 100644 --- a/bacnet-stack/ports/atmega168/Makefile +++ b/bacnet-stack/ports/atmega168/Makefile @@ -25,6 +25,7 @@ CSRC = main.c \ DEMOSRC = h_rp.c \ h_wp.c \ device.c \ + ai.c \ ../../demo/handler/txbuf.c \ ../../demo/handler/h_whois.c \ ../../demo/handler/h_rd.c \ @@ -65,7 +66,7 @@ COMMON = -mmcu=$(MCU) OPTIMIZATION = -Os -mcall-prologues ## Compile options common for all C compilation units. -BFLAGS = -DBACDL_MSTP -DMAX_APDU=50 -DBIG_ENDIAN=0 +BFLAGS = -DBACDL_MSTP -DMAX_APDU=50 -DBIG_ENDIAN=0 -DMAX_TSM_TRANSACTIONS=0 CFLAGS = $(COMMON) CFLAGS += -Wall -gdwarf-2 $(BFLAGS) $(OPTIMIZATION) -fsigned-char CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d @@ -77,8 +78,8 @@ ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 ## Linker flags LDFLAGS = $(COMMON) -#LDFLAGS += -Wl,-Map=$(TARGET).map,-L=.,-l$(TARGET) -LDFLAGS += -Wl,-Map=$(TARGET).map +LDFLAGS += -Wl,-Map=$(TARGET).map,-L=.,-l$(TARGET) +#LDFLAGS += -Wl,-Map=$(TARGET).map ## Intel Hex file production flags HEX_FLASH_FLAGS = -R .eeprom @@ -87,8 +88,8 @@ HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings ## Objects that must be built in order to link -#OBJECTS = $(COBJ) $(DEMOOBJ) -OBJECTS = $(COBJ) +OBJECTS = $(COBJ) $(DEMOOBJ) +#OBJECTS = $(COBJ) ## Build TARGET_ELF=$(TARGET).elf diff --git a/bacnet-stack/ports/atmega168/ai.c b/bacnet-stack/ports/atmega168/ai.c new file mode 100644 index 00000000..e6a839af --- /dev/null +++ b/bacnet-stack/ports/atmega168/ai.c @@ -0,0 +1,148 @@ +/************************************************************************** +* +* Copyright (C) 2005 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. +* +*********************************************************************/ + +/* Analog Input Objects customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" + +/* Analog Input = Photocell */ +#define MAX_ANALOG_INPUTS 2 +#if (MAX_ANALOG_INPUTS > 9) + #error Modify the Analog_Input_Name to handle multiple digits +#endif + +static uint8_t Present_Value[MAX_ANALOG_INPUTS]; + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need validate that the */ +/* given instance exists */ +bool Analog_Input_Valid_Instance(uint32_t object_instance) +{ + if (object_instance < MAX_ANALOG_INPUTS) + return true; + + return false; +} + +/* we simply have 0-n object instances. */ +unsigned Analog_Input_Count(void) +{ + return MAX_ANALOG_INPUTS; +} + +/* we simply have 0-n object instances. */ +uint32_t Analog_Input_Index_To_Instance(unsigned index) +{ + return index; +} + +char *Analog_Input_Name(uint32_t object_instance) +{ + static char text_string[5] = "AI-0"; /* okay for single thread */ + + if (object_instance < MAX_ANALOG_INPUTS) { + text_string[3] = '0' + (uint8_t)object_instance; + return text_string; + } + + return NULL; +} + +static float Analog_Input_Present_Value(uint32_t object_instance) +{ + float value = 0.0; + + if (object_instance < MAX_ANALOG_INPUTS) + value = Present_Value[object_instance]; + + return value; +} + +/* return apdu length, or -1 on error */ +/* assumption - object has already exists */ +int Analog_Input_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + + (void) array_index; + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_ANALOG_INPUT, + object_instance); + break; + /* note: Name and Description don't have to be the same. + You could make Description writable and different */ + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + characterstring_init_ansi(&char_string, + Analog_Input_Name(object_instance)); + apdu_len = encode_tagged_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = encode_tagged_enumerated(&apdu[0], + OBJECT_ANALOG_INPUT); + break; + case PROP_PRESENT_VALUE: + apdu_len = encode_tagged_real(&apdu[0], + Analog_Input_Present_Value(object_instance)); + break; + case PROP_STATUS_FLAGS: + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_tagged_boolean(&apdu[0], false); + break; + case PROP_UNITS: + apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} diff --git a/bacnet-stack/ports/atmega168/device.c b/bacnet-stack/ports/atmega168/device.c index a9323c07..de4365e2 100644 --- a/bacnet-stack/ports/atmega168/device.c +++ b/bacnet-stack/ports/atmega168/device.c @@ -36,8 +36,8 @@ #include "version.h" /* objects */ #include "device.h" -#if 0 #include "ai.h" +#if 0 #include "av.h" #include "bi.h" #include "bv.h" @@ -162,10 +162,10 @@ unsigned Device_Object_List_Count(void) unsigned count = 1; /* at least 1 for device object */ /* FIXME: add objects as needed */ + count += Analog_Input_Count(); #if 0 count += Binary_Input_Count(); count += Binary_Value_Count(); - count += Analog_Input_Count(); count += Analog_Value_Count(); #endif @@ -176,10 +176,8 @@ bool Device_Object_List_Identifier(unsigned array_index, int *object_type, uint32_t * instance) { bool status = false; -#if 0 unsigned object_index = 0; unsigned object_count = 0; -#endif /* device object */ if (array_index == 1) { @@ -187,7 +185,6 @@ bool Device_Object_List_Identifier(unsigned array_index, *instance = Object_Instance_Number; status = true; } -#if 0 /* normalize the index since we know it is not the previous objects */ /* array index starts at 1 */ @@ -195,6 +192,18 @@ bool Device_Object_List_Identifier(unsigned array_index, /* 1 for the device object */ object_count = 1; /* FIXME: add objects as needed */ + /* analog input objects */ + if (!status) { + /* array index starts at 1, and 1 for the device object */ + object_index -= object_count; + object_count = Analog_Input_Count(); + if (object_index < object_count) { + *object_type = OBJECT_ANALOG_INPUT; + *instance = Analog_Input_Index_To_Instance(object_index); + status = true; + } + } +#if 0 /* binary value objects */ if (!status) { object_index -= object_count; @@ -206,7 +215,7 @@ bool Device_Object_List_Identifier(unsigned array_index, status = true; } } - /* analog input objects */ + /* analog value objects */ if (!status) { /* array index starts at 1, and 1 for the device object */ object_index -= object_count; @@ -217,17 +226,6 @@ bool Device_Object_List_Identifier(unsigned array_index, status = true; } } - /* analog input objects */ - if (!status) { - /* array index starts at 1, and 1 for the device object */ - object_index -= object_count; - object_count = Analog_Input_Count(); - if (object_index < object_count) { - *object_type = OBJECT_ANALOG_INPUT; - *instance = Analog_Input_Index_To_Instance(object_index); - status = true; - } - } /* binary input objects */ if (!status) { /* normalize the index since @@ -341,10 +339,10 @@ int Device_Encode_Property_APDU(uint8_t * apdu, } /* FIXME: indicate the objects that YOU support */ bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); + bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); #if 0 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); #endif apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); diff --git a/bacnet-stack/ports/atmega168/h_rp.c b/bacnet-stack/ports/atmega168/h_rp.c index 42a0c9a6..a9197741 100644 --- a/bacnet-stack/ports/atmega168/h_rp.c +++ b/bacnet-stack/ports/atmega168/h_rp.c @@ -38,8 +38,8 @@ #include "rp.h" /* demo objects */ #include "device.h" -#if 0 #include "ai.h" +#if 0 #include "av.h" #include "bi.h" #include "bv.h" @@ -75,8 +75,7 @@ int Encode_Property_APDU( error_class, error_code); } break; -#if 0 - case OBJECT_ANALOG_INPUT: + case OBJECT_ANALOG_INPUT: if (Analog_Input_Valid_Instance(object_instance)) { apdu_len = Analog_Input_Encode_Property_APDU( &apdu[0], @@ -86,36 +85,7 @@ int Encode_Property_APDU( error_class, error_code); } break; - case OBJECT_ANALOG_VALUE: - if (Analog_Value_Valid_Instance(object_instance)) { - apdu_len = Analog_Value_Encode_Property_APDU(&Temp_Buf[0], - object_instance, - property, - array_index, - error_class, error_code); - } - break; - case OBJECT_BINARY_INPUT: - if (Binary_Input_Valid_Instance(object_instance)) { - apdu_len = Binary_Input_Encode_Property_APDU( - &apdu[0], - object_instance, - property, - array_index, - error_class, error_code); - } - break; - case OBJECT_BINARY_VALUE: - if (Binary_Value_Valid_Instance(object_instance)) { - apdu_len = Binary_Value_Encode_Property_APDU(&Temp_Buf[0], - object_instance, - property, - array_index, - error_class, error_code); - } - break; -#endif - default: + default: *error_class = ERROR_CLASS_OBJECT; *error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; break; diff --git a/bacnet-stack/ports/atmega168/main.c b/bacnet-stack/ports/atmega168/main.c index 4f88449e..42e95d89 100644 --- a/bacnet-stack/ports/atmega168/main.c +++ b/bacnet-stack/ports/atmega168/main.c @@ -30,6 +30,8 @@ #include "rs485.h" #include "datalink.h" #include "npdu.h" +#include "txbuf.h" +#include "iam.h" /* For porting to IAR, see: http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ @@ -89,6 +91,7 @@ void task_milliseconds(void) } } +#if 0 void apdu_handler(BACNET_ADDRESS * src, /* source address */ uint8_t * apdu, /* APDU data */ uint16_t pdu_len) /* for confirmed messages */ @@ -97,7 +100,7 @@ void apdu_handler(BACNET_ADDRESS * src, /* source address */ (void)apdu; (void)pdu_len; } - +#endif static uint8_t PDUBuffer[MAX_MPDU]; int main(void) @@ -113,13 +116,15 @@ int main(void) dlmstp_set_max_info_frames(1); #endif datalink_init(NULL); + /* broadcast an I-Am on startup */ + iam_send(&Handler_Transmit_Buffer[0]); for (;;) { task_milliseconds(); /* other tasks */ /* BACnet handling */ pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); if (pdu_len) { - //npdu_handler(&src, &PDUBuffer[0], pdu_len); + npdu_handler(&src, &PDUBuffer[0], pdu_len); } }