From c8677814a6e1272eff9ca1495234414899ad3ed7 Mon Sep 17 00:00:00 2001 From: skarg Date: Fri, 14 Mar 2008 22:15:49 +0000 Subject: [PATCH] Corrected bug in ATmega168 port demo project, which required some code reduction to fit using GCC compiler. --- bacnet-stack/ports/atmega168/Makefile | 6 +- bacnet-stack/ports/atmega168/av.c | 19 +++--- bacnet-stack/ports/atmega168/bacnet.aps | 2 +- bacnet-stack/ports/atmega168/device.c | 31 ++++------ bacnet-stack/ports/atmega168/h_rp.c | 81 ++++++++++++------------- bacnet-stack/ports/atmega168/main.c | 58 +++++++++--------- 6 files changed, 89 insertions(+), 108 deletions(-) diff --git a/bacnet-stack/ports/atmega168/Makefile b/bacnet-stack/ports/atmega168/Makefile index 0849f991..8e90d91b 100644 --- a/bacnet-stack/ports/atmega168/Makefile +++ b/bacnet-stack/ports/atmega168/Makefile @@ -48,9 +48,9 @@ CORESRC = \ $(BACNET_CORE)/abort.c \ $(BACNET_CORE)/reject.c \ $(BACNET_CORE)/bacerror.c \ - $(BACNET_CORE)/bacapp.c \ - $(BACNET_CORE)/version.c + $(BACNET_CORE)/bacapp.c +# $(BACNET_CORE)/version.c # $(BACNET_CORE)/bacprop.c \ # $(BACNET_CORE)/bactext.c \ # $(BACNET_CORE)/datetime.c \ @@ -98,6 +98,7 @@ BFLAGS += -DBIG_ENDIAN=0 BFLAGS += -DMAX_TSM_TRANSACTIONS=0 #BFLAGS += -DCRC_USE_TABLE BFLAGS += -DBACAPP_REAL +BFLAGS += -DMAX_ANALOG_VALUES=10 CFLAGS = $(COMMON) # dead code removal CFLAGS += -ffunction-sections -fdata-sections @@ -162,7 +163,6 @@ size: ${TARGET_ELF} ## Clean target .PHONY: clean clean: - touch Makefile -rm -rf $(OBJECTS) $(TARGET_ELF) dep/* -rm -rf $(LIBRARY) $(COREOBJ) $(LIBRARY:.a=.lst) -rm -rf $(TARGET).hex $(TARGET).eep $(TARGET).lst $(TARGET).map diff --git a/bacnet-stack/ports/atmega168/av.c b/bacnet-stack/ports/atmega168/av.c index 2551e567..78b09296 100644 --- a/bacnet-stack/ports/atmega168/av.c +++ b/bacnet-stack/ports/atmega168/av.c @@ -34,12 +34,11 @@ #include "config.h" /* the custom stuff */ #include "wp.h" -#define MAX_ANALOG_VALUES 9 -#if (MAX_ANALOG_VALUES > 9) +#if (MAX_ANALOG_VALUES > 10) #error Modify the Analog_Value_Name to handle multiple digits #endif -float Present_Value[MAX_ANALOG_VALUES]; +float AV_Present_Value[MAX_ANALOG_VALUES]; /* we simply have 0-n object instances. Yours might be */ /* more complex, and then you need validate that the */ @@ -83,14 +82,11 @@ unsigned Analog_Value_Instance_To_Index( char *Analog_Value_Name( uint32_t object_instance) { - static char text_string[5] = "AV-0"; /* okay for single thread */ + static char text_string[5] = "AV-"; /* okay for single thread */ - if (object_instance < MAX_ANALOG_VALUES) { - text_string[3] = '0' + (uint8_t) object_instance; - return text_string; - } + text_string[3] = '0' + (uint8_t) object_instance; - return NULL; + return text_string; } /* return apdu len, or -1 on error */ @@ -114,7 +110,6 @@ int Analog_Value_Encode_Property_APDU( object_instance); break; case PROP_OBJECT_NAME: - case PROP_DESCRIPTION: characterstring_init_ansi(&char_string, Analog_Value_Name(object_instance)); apdu_len = @@ -127,7 +122,7 @@ int Analog_Value_Encode_Property_APDU( case PROP_PRESENT_VALUE: object_index = Analog_Value_Instance_To_Index(object_instance); apdu_len = - encode_application_real(&apdu[0], Present_Value[object_index]); + encode_application_real(&apdu[0], AV_Present_Value[object_index]); break; case PROP_STATUS_FLAGS: bitstring_init(&bit_string); @@ -184,7 +179,7 @@ bool Analog_Value_Write_Property( if (value.tag == BACNET_APPLICATION_TAG_REAL) { object_index = Analog_Value_Instance_To_Index(wp_data->object_instance); - Present_Value[object_index] = value.type.Real; + AV_Present_Value[object_index] = value.type.Real; status = true; } else { *error_class = ERROR_CLASS_PROPERTY; diff --git a/bacnet-stack/ports/atmega168/bacnet.aps b/bacnet-stack/ports/atmega168/bacnet.aps index 5de9c8e0..19bdf7d4 100644 --- a/bacnet-stack/ports/atmega168/bacnet.aps +++ b/bacnet-stack/ports/atmega168/bacnet.aps @@ -1 +1 @@ -13-Aug-2007 15:08:2719-Oct-2007 09:38:42013-Aug-2007 15:08:2744, 13, 0, 528AVR GCC241bacnet13-Aug-2007 15:11:0713-Aug-2007 15:11:07241013-Aug-2007 15:11:0744, 13, 0, 528AVR GCCbacnet.elfC:\code\bacnet-stack\ports\atmega168\ATmega168falseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31AVR DragonAVR SimulatorATmega168.xmlAuto000main.crs485.ctimer.cdlmstp.cC:\code\bacnet-stack\demo\handler\txbuf.cdevice.cC:\code\bacnet-stack\src\crc.cC:\code\bacnet-stack\src\npdu.cai.capdu.ch_rp.cC:\code\bacnet-stack\src\iam.cav.ch_wp.cC:\code\bacnet-stack\src\bacapp.cavr035.hhardware.hrs485.htimer.hC:\code\bacnet-stack\include\crc.hC:\code\bacnet-stack\include\dlmstp.hC:\code\bacnet-stack\include\iam.hC:\code\bacnet-stack\include\npdu.hC:\code\bacnet-stack\include\txbuf.hC:\code\bacnet-stack\include\bacenum.hC:\code\bacnet-stack\include\bacdcode.hMakefiledefaultYESMakefileatmega168100bacnet.elfdefault\1..\..\demo\handler\.\..\..\..\..\demo\object\-Wall -gdwarf-2 -DMAX_APDU=50 -DBACDL_MSTP -DBIG_ENDIAN=0 -DF_CPU=7372800UL -O0 -fsigned-chardefault1C:\WinAVR-20070525\bin\avr-gcc.exeC:\WinAVR-20070525\utils\bin\make.exe0282161937372800011000001920010000000001011main100000C:\WinAVR-20070525\avr\include\avr\eeprom.h100001C:\WinAVR-20070525\avr\include\avr\iomx8.h100002C:\WinAVR-20070525\examples\stdiodemo\uart.c100003main.c100004C:\WinAVR-20070525\avr\include\avr\interrupt.h100005C:\WinAVR-20070525\avr\include\avr\io.h100006rs485.c25800007dlmstp.c25800008timer.c25800009avr035.h100010C:\code\bacnet-stack\src\iam.c25800011C:\code\bacnet-stack\src\crc.c25800012av.c100013Makefile100014C:\code\bacnet-stack\src\bacapp.c100015C:\code\bacnet-stack\include\av.h1580 912 740 9390 0565 677 725 7040 0649 628 809 6550 0654 231 1436 613122 01033 428 1193 4550 0647 657 807 6840 0566 677 726 7010 0742 319 1524 70136 27588 165 1370 54750 16610 187 1392 569220 0698 275 1480 6570 0 +13-Aug-2007 15:08:2714-Mar-2008 17:14:04013-Aug-2007 15:08:2744, 13, 0, 528AVR GCC241bacnet13-Aug-2007 15:11:0713-Aug-2007 15:11:07241013-Aug-2007 15:11:0744, 13, 0, 528AVR GCCbacnet.elfC:\code\bacnet-stack\ports\atmega168\ATmega168falseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31AVR DragonAVR SimulatorATmega168.xmlAuto00property_len0main.crs485.ctimer.cdlmstp.cC:\code\bacnet-stack\demo\handler\txbuf.cdevice.cC:\code\bacnet-stack\src\crc.cC:\code\bacnet-stack\src\npdu.capdu.ch_rp.cC:\code\bacnet-stack\src\iam.cav.ch_wp.cC:\code\bacnet-stack\src\bacapp.cavr035.hhardware.hrs485.htimer.hC:\code\bacnet-stack\include\crc.hC:\code\bacnet-stack\include\dlmstp.hC:\code\bacnet-stack\include\iam.hC:\code\bacnet-stack\include\npdu.hC:\code\bacnet-stack\include\txbuf.hC:\code\bacnet-stack\include\bacenum.hC:\code\bacnet-stack\include\bacdcode.hMakefiledefaultYESMakefileatmega168100bacnet.elfdefault\1..\..\demo\handler\.\..\..\..\..\demo\object\-Wall -gdwarf-2 -DMAX_APDU=50 -DBACDL_MSTP -DBIG_ENDIAN=0 -DF_CPU=7372800UL -O0 -fsigned-chardefault1C:\WinAVR-20071221rc1\bin\avr-gcc.exeC:\WinAVR-20071221rc1\utils\bin\make.exe0282161937372800011000001920010000000001011main100000main.c25700001dlmstp.c25800002timer.c25700003C:\code\bacnet-stack\src\iam.c25800004C:\code\bacnet-stack\src\crc.c25800005av.c25700006Makefile100007rs485.c257 diff --git a/bacnet-stack/ports/atmega168/device.c b/bacnet-stack/ports/atmega168/device.c index a31fddd6..4bb023c2 100644 --- a/bacnet-stack/ports/atmega168/device.c +++ b/bacnet-stack/ports/atmega168/device.c @@ -222,7 +222,6 @@ int Device_Encode_Property_APDU( Object_Instance_Number); break; case PROP_OBJECT_NAME: - case PROP_DESCRIPTION: characterstring_init_ansi(&char_string, Object_Name); apdu_len = encode_application_character_string(&apdu[0], &char_string); @@ -249,7 +248,7 @@ int Device_Encode_Property_APDU( encode_application_character_string(&apdu[0], &char_string); break; case PROP_FIRMWARE_REVISION: - characterstring_init_ansi(&char_string, BACnet_Version); + characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; @@ -304,24 +303,16 @@ int Device_Encode_Property_APDU( /* your maximum APDU size. */ else if (array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= count; i++) { - if (Device_Object_List_Identifier(i, &object_type, - &instance)) { - len = - encode_application_object_id(&apdu[apdu_len], - object_type, instance); - apdu_len += len; - /* assume next one is the same size as this one */ - /* can we all fit into the APDU? */ - if ((apdu_len + len) >= MAX_APDU) { - *error_class = ERROR_CLASS_SERVICES; - *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; - apdu_len = -1; - break; - } - } else { - /* error: internal error? */ + Device_Object_List_Identifier(i, &object_type, &instance); + len = + encode_application_object_id(&apdu[apdu_len], + object_type, instance); + apdu_len += len; + /* assume next one is the same size as this one */ + /* can we all fit into the APDU? */ + if ((apdu_len + len) >= MAX_APDU) { *error_class = ERROR_CLASS_SERVICES; - *error_code = ERROR_CODE_OTHER; + *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; apdu_len = -1; break; } @@ -367,10 +358,12 @@ int Device_Encode_Property_APDU( apdu_len = encode_application_unsigned(&apdu[0], dlmstp_max_master()); break; +#if 0 case 9600: apdu_len = encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate()); break; +#endif default: *error_class = ERROR_CLASS_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY; diff --git a/bacnet-stack/ports/atmega168/h_rp.c b/bacnet-stack/ports/atmega168/h_rp.c index a3cc31d3..e27def72 100644 --- a/bacnet-stack/ports/atmega168/h_rp.c +++ b/bacnet-stack/ports/atmega168/h_rp.c @@ -49,33 +49,31 @@ or sets the error, and returns -1 */ int Encode_Property_APDU( uint8_t * apdu, - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_ID property, - int32_t array_index, + BACNET_READ_PROPERTY_DATA *rp_data, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) { int apdu_len = -1; - /* initialize the default return values */ - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; /* handle each object type */ - switch (object_type) { + switch (rp_data->object_type) { case OBJECT_DEVICE: - if (Device_Valid_Object_Instance_Number(object_instance)) { + if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) { apdu_len = - Device_Encode_Property_APDU(&apdu[0], property, - array_index, error_class, error_code); + Device_Encode_Property_APDU(&apdu[0], + rp_data->object_property, + rp_data->array_index, + error_class, error_code); } break; case OBJECT_ANALOG_VALUE: - if (Analog_Value_Valid_Instance(object_instance)) { + if (Analog_Value_Valid_Instance(rp_data->object_instance)) { apdu_len = Analog_Value_Encode_Property_APDU(&apdu[0], - object_instance, property, array_index, error_class, - error_code); + rp_data->object_instance, + rp_data->object_property, + rp_data->array_index, + error_class, error_code); } break; default: @@ -99,51 +97,48 @@ void handler_read_property( int property_len = 0; int pdu_len = 0; BACNET_NPDU_DATA npdu_data; - bool error = false; int bytes_sent = 0; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ADDRESS my_address; - len = rp_decode_service_request(service_request, service_len, &data); /* 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 (len < 0) { - /* bad decoding - send an abort */ - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, true); - } else if (service_data->segmented_message) { + if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); - } else { - /* most cases will be error */ - error = true; - ack_len = - rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); - /* FIXME: add buffer len as passed into function or use smart buffer */ - property_len = - Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], - data.object_type, data.object_instance, data.object_property, - data.array_index, &error_class, &error_code); - if (len >= 0) { - len = - rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer - [pdu_len + property_len + ack_len]); - len += ack_len + property_len; - error = false; - } + goto RP_ABORT; + } + len = rp_decode_service_request(service_request, service_len, &data); + if (len < 0) { + /* bad decoding - send an abort */ + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_OTHER, true); + goto RP_ABORT; } - if (error) { - switch (len) { + /* most cases will be error */ + ack_len = + rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, &data); + /* FIXME: add buffer len as passed into function or use smart buffer */ + property_len = + Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], + &data, &error_class, &error_code); + if (property_len >= 0) { + len = + rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer + [pdu_len + property_len + ack_len]); + len += ack_len + property_len; + } else { + switch (property_len) { /* BACnet APDU too small to fit data, so proper response is Abort */ case -2: len = @@ -151,7 +146,6 @@ void handler_read_property( service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); break; - case -1: default: len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], @@ -160,6 +154,7 @@ void handler_read_property( break; } } +RP_ABORT: pdu_len += len; bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], diff --git a/bacnet-stack/ports/atmega168/main.c b/bacnet-stack/ports/atmega168/main.c index ccc7746c..41599fdf 100644 --- a/bacnet-stack/ports/atmega168/main.c +++ b/bacnet-stack/ports/atmega168/main.c @@ -34,9 +34,18 @@ #include "iam.h" #include "device.h" +const char *BACnet_Version = "1.0"; /* For porting to IAR, see: http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ + +#define LED_NPDU_INIT() BIT_SET(DDRD, DDD5) +#define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5) +#define LED_NPDU_OFF() BIT_SET(PORTD, PD5) + +#define LED_GREEN_INIT() BIT_SET(DDRD, DDD4) +#define LED_GREEN_ON() BIT_CLEAR(PORTD, PD4) +#define LED_GREEN_OFF() BIT_SET(PORTD, PD4) /* dummy function */ bool dcc_communication_enabled( @@ -81,43 +90,24 @@ static void init( BIT_CLEAR(MCUSR, WDRF); WDTCSR = 0; - /* Configure USART */ + /* Configure Specialized Hardware */ RS485_Initialize(); + + /* configure one LED for NPDU indication */ + /* default: off, output */ + LED_NPDU_OFF(); + LED_NPDU_INIT(); + /* Configure Software active LED */ + LED_GREEN_INIT(); + LED_GREEN_ON(); /* Configure Timer0 for millisecond timer */ Timer_Initialize(); - /* Set the LED ports OFF */ - BIT_SET(PORTD, PD4); - BIT_SET(PORTD, PD5); - /* Configure the LED ports as outputs */ - BIT_SET(DDRD, DDD4); - BIT_SET(DDRD, DDD5); - /* Enable global interrupts */ __enable_interrupt(); } -static uint8_t NPDU_Timer; - -static void NDPU_Timers( - void) -{ - if (NPDU_Timer) { - NPDU_Timer--; - if (NPDU_Timer == 0) { - BIT_SET(PORTD, PD5); - } - } -} - -static void NPDU_LED_On( - void) -{ - BIT_CLEAR(PORTD, PD5); - NPDU_Timer = 20; -} - static void task_milliseconds( void) { @@ -125,7 +115,6 @@ static void task_milliseconds( Timer_Milliseconds--; /* add other millisecond timer tasks here */ RS485_LED_Timers(); - NDPU_Timers(); } } @@ -152,6 +141,13 @@ static void input_switch_read( } } +static void Analog_Value_Task(void) +{ + extern float AV_Present_Value[MAX_ANALOG_VALUES]; + + AV_Present_Value[0] = 3.14159F; +} + static uint8_t PDUBuffer[MAX_MPDU]; int main( void) @@ -169,12 +165,14 @@ int main( for (;;) { input_switch_read(); task_milliseconds(); + Analog_Value_Task(); /* other tasks */ /* BACnet handling */ pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); if (pdu_len) { + LED_NPDU_ON(); npdu_handler(&src, &PDUBuffer[0], pdu_len); - NPDU_LED_On(); + LED_NPDU_OFF(); } } }