diff --git a/bacnet-stack/ports/arduino_uno/Makefile b/bacnet-stack/ports/arduino_uno/Makefile new file mode 100644 index 00000000..135c4ba1 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/Makefile @@ -0,0 +1,209 @@ +############################################################################### +# Makefile for BACnet +############################################################################### + +## General Flags +MCU = atmega328p +AVRDUDE_MCU = m328 +TARGET = bacnet +## Tools +CC = avr-gcc +AR = avr-ar +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AVRDUDE = avrdude +LINT = splint + +# programmer id--check the avrdude for complete list +# # of available opts. These should include stk500, +# # avr910, avrisp, bsd, pony and more. Set this to +# # one of the valid "-c PROGRAMMER-ID" values +# # described in the avrdude info page. +# # +AVRDUDE_PROGRAMMERID = avrispmkII +# +# # port--serial or parallel port to which your +# # hardware programmer is attached +# # +AVRDUDE_PORT = /dev/ttyUSB0 + +# Source locations +BACNET_CORE = ../../src +BACNET_INCLUDE = ../../include +BACNET_HANDLER = ../../demo/handler +BACNET_OBJECT = ../../demo/object +BACNET_DEMO = ../../demo +ARDUINO_CORE = external/Arduino/core +ARDUINO_ETHERNET = external/Arduino/Ethernet + +# local files for this project +CSRC = main.c \ + uart.c \ + apdu.c \ + h_rp.c \ + device.c \ + av.c \ + bv.c \ + h_whois.c \ + h_wp.c \ + bip.c \ + bip-init.c \ + bvlc-arduino.c + +# common demo files needed +DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c \ + $(BACNET_DEMO)/handler/h_npdu.c \ + $(BACNET_DEMO)/handler/s_iam.c \ + $(BACNET_DEMO)/handler/noserv.c + +# core BACnet stack files +CORESRC = \ + $(BACNET_CORE)/crc.c \ + $(BACNET_CORE)/npdu.c \ + $(BACNET_CORE)/bacdcode.c \ + $(BACNET_CORE)/bacint.c \ + $(BACNET_CORE)/bacreal.c \ + $(BACNET_CORE)/bacstr.c \ + $(BACNET_CORE)/iam.c \ + $(BACNET_CORE)/rp.c \ + $(BACNET_CORE)/wp.c \ + $(BACNET_CORE)/whois.c \ + $(BACNET_CORE)/bacaddr.c \ + $(BACNET_CORE)/abort.c \ + $(BACNET_CORE)/reject.c \ + $(BACNET_CORE)/bacerror.c \ + $(BACNET_CORE)/bacapp.c \ +# $(BACNET_CORE)/ethernet.c + + +## Include Directories +INCLUDES = -I. -I$(BACNET_INCLUDE) +INCLUDES += -I$(BACNET_OBJECT) +INCLUDES += -I$(BACNET_HANDLER) +INCLUDES += -I$(ARDUINO_CORE)/include +INCLUDES += -I$(ARDUINO_ETHERNET)/include + +# Source to Object conversion +COBJ = $(CSRC:.c=.o) +DEMOOBJ = $(DEMOSRC:.c=.o) +COREOBJ = $(CORESRC:.c=.o) + + +LIBRARY = lib$(TARGET).a + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) -DF_CPU=16000000UL + +#OPTIMIZE_FLAGS = -mcall-prologues +#OPTIMIZE_FLAGS += -finline-functions-called-once -ffunction-sections -fdata-sections +#OPTIMIZATION = -Os $(OPTIMIZE_FLAGS) +OPTIMIZATION = -Os + +#OPTIMIZATION = -O3 $(OPTIMIZE_FLAGS) + +## Compile options common for all C compilation units. +# BFLAGS = -DBACDL_MSTP +#BFLAGS = -DBACDL_ETHERNET=1 +BFLAGS = -DBACDL_BIP=1 +BFLAGS += -DMAX_APDU=100 +BFLAGS += -DBIG_ENDIAN=0 +BFLAGS += -DMAX_TSM_TRANSACTIONS=0 +#BFLAGS += -DCRC_USE_TABLE +BFLAGS += -DBACAPP_REAL +BFLAGS += -DBACAPP_OBJECT_ID +BFLAGS += -DBACAPP_UNSIGNED +BFLAGS += -DBACAPP_ENUMERATED +BFLAGS += -DBACAPP_CHARACTER_STRING +BFLAGS += -DWRITE_PROPERTY +BFLAGS += -DMAX_ANALOG_VALUES=4 +BFLAGS += -DMAX_BINARY_VALUES=4 +#BFLAGS += -DDEBUG +CFLAGS = $(COMMON) +# dead code removal +CFLAGS += -ffunction-sections -fdata-sections +CFLAGS += -Wall -g2 -gstabs -std=gnu99 $(BFLAGS) $(OPTIMIZATION) +CFLAGS += -MMD -MP -MT $(*F).o -MF dep/$(@F).d +#CFLAGS += -Wall -gdwarf-2 $(BFLAGS) $(OPTIMIZATION) -fsigned-char +#CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +#dead code removal +LDFLAGS += -Wl,--gc-sections,-static +LDFLAGS += -Wl,-Map=$(TARGET).map,-L.,-l$(TARGET) +LDFLAGS += -Wl,-L$(ARDUINO_ETHERNET)/lib,-lArduinoEthernet +LDFLAGS += -Wl,-L$(ARDUINO_CORE)/lib,-lArduinoUnoCore,-lm + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom +HEX_EEPROM_FLAGS = -j .eeprom +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) + +## Build +TARGET_ELF=$(TARGET).elf + +all: EthernetLib $(LIBRARY) $(TARGET_ELF) $(TARGET).hex $(TARGET).eep $(TARGET).lst \ + size Makefile + +EthernetLib: + $(MAKE) -s -C external/Arduino/Ethernet all + +##Link +$(TARGET_ELF): $(OBJECTS) $(LIBRARY) + $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + +%.hex: $(TARGET_ELF) + $(OBJCOPY) -O ihex $(HEX_FLASH_FLAGS) $< $@ + +%.eep: $(TARGET_ELF) + -$(OBJCOPY) $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 + +%.lst: $(TARGET_ELF) + $(OBJDUMP) -h -S $< > $@ + +lib: $(LIBRARY) + +$(LIBRARY): $(COREOBJ) Makefile + $(AR) rcs $@ $(COREOBJ) + $(OBJDUMP) --syms $@ > $(LIBRARY:.a=.lst) + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $*.c -o $@ + +.cpp.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $*.cpp -o $@ + +size: ${TARGET_ELF} + @echo + @${SIZE} -C --mcu=${MCU} ${TARGET_ELF} + +lint: + $(LINT) $(BFLAGS) $(CSRC) + +install: $(TARGET_ELF) + $(AVRDUDE) -c $(AVRDUDE_PROGRAMMERID) \ + -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -e \ + -U flash:w:$(TARGET).hex + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJECTS) $(TARGET_ELF) dep/* + -rm -rf $(LIBRARY) $(COREOBJ) +# -rm -rf $(LIBRARY) $(COREOBJ) $(LIBRARY:.a=.lst) + -rm -rf $(TARGET).hex $(TARGET).eep $(TARGET).lst $(TARGET).map + cd external/Arduino/Ethernet; make clean + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/bacnet-stack/ports/arduino_uno/apdu.c b/bacnet-stack/ports/arduino_uno/apdu.c new file mode 100644 index 00000000..a4379137 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/apdu.c @@ -0,0 +1,144 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2007 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#include +#include +#include +#include "bits.h" +#include "apdu.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "handlers.h" + +bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported) +{ + bool status = false; + + if (service_supported == SERVICE_SUPPORTED_READ_PROPERTY) { + status = true; + } + if (service_supported == SERVICE_SUPPORTED_WHO_IS) { + status = true; + } +#ifdef WRITE_PROPERTY + if (service_supported == SERVICE_SUPPORTED_WRITE_PROPERTY) { + status = true; + } +#endif + + return status; +} + +uint16_t apdu_decode_confirmed_service_request(uint8_t * apdu, /* APDU data */ + + uint16_t apdu_len, + BACNET_CONFIRMED_SERVICE_DATA * service_data, + uint8_t * service_choice, + uint8_t ** service_request, + uint16_t * service_request_len) +{ + uint16_t len = 0; /* counts where we are in PDU */ + + service_data->segmented_message = (apdu[0] & BIT3) ? true : false; + service_data->more_follows = (apdu[0] & BIT2) ? true : false; + service_data->segmented_response_accepted = + (apdu[0] & BIT1) ? true : false; + service_data->max_segs = decode_max_segs(apdu[1]); + service_data->max_resp = decode_max_apdu(apdu[1]); + service_data->invoke_id = apdu[2]; + len = 3; + if (service_data->segmented_message) { + service_data->sequence_number = apdu[len++]; + service_data->proposed_window_number = apdu[len++]; + } + *service_choice = apdu[len++]; + *service_request = &apdu[len]; + *service_request_len = apdu_len - len; + + return len; +} + +void apdu_handler(BACNET_ADDRESS * src, + uint8_t * apdu, /* APDU data */ + + uint16_t apdu_len) +{ + BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; + uint8_t service_choice = 0; + uint8_t *service_request = NULL; + uint16_t service_request_len = 0; + uint16_t len = 0; /* counts where we are in PDU */ + + if (apdu) { + /* PDU Type */ + switch (apdu[0] & 0xF0) { + case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: + len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ + apdu_len, &service_data, &service_choice, &service_request, + &service_request_len); + if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { + handler_read_property(service_request, service_request_len, + src, &service_data); + } +#ifdef WRITE_PROPERTY + else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) { + handler_write_property(service_request, + service_request_len, src, &service_data); + } +#endif + else { + handler_unrecognized_service(service_request, + service_request_len, src, &service_data); + } + break; + case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: + service_choice = apdu[1]; + service_request = &apdu[2]; + service_request_len = apdu_len - 2; + if (service_choice == SERVICE_UNCONFIRMED_WHO_IS) { + handler_who_is(service_request, service_request_len, src); + } + break; + case PDU_TYPE_SIMPLE_ACK: + case PDU_TYPE_COMPLEX_ACK: + case PDU_TYPE_SEGMENT_ACK: + case PDU_TYPE_ERROR: + case PDU_TYPE_REJECT: + case PDU_TYPE_ABORT: + default: + break; + } + } + return; +} diff --git a/bacnet-stack/ports/arduino_uno/av.c b/bacnet-stack/ports/arduino_uno/av.c new file mode 100644 index 00000000..5f5c8d7d --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/av.c @@ -0,0 +1,254 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +/* Analog Value Objects - customize for your use */ + +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "bacapp.h" +#include "config.h" /* the custom stuff */ +#include "wp.h" +#include "av.h" + +#if (MAX_ANALOG_VALUES > 10) +#error Modify the Analog_Value_Name to handle multiple digits +#endif + +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 */ +/* given instance exists */ +bool Analog_Value_Valid_Instance(uint32_t object_instance) +{ + if (object_instance < MAX_ANALOG_VALUES) + return true; + + return false; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then count how many you have */ +unsigned Analog_Value_Count(void) +{ + return MAX_ANALOG_VALUES; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the instance */ +/* that correlates to the correct index */ +uint32_t Analog_Value_Index_To_Instance(unsigned index) +{ + return index; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the index */ +/* that correlates to the correct instance number */ +unsigned Analog_Value_Instance_To_Index(uint32_t object_instance) +{ + return object_instance; +} + +/* note: the object name must be unique within this device */ +char *Analog_Value_Name(uint32_t object_instance) +{ + static char text_string[5] = "AV-"; /* okay for single thread */ + + text_string[3] = '0' + (uint8_t) object_instance; + + return text_string; +} + +/* return apdu len, or -1 on error */ +int Analog_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + uint32_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; + unsigned object_index; + + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = + encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, + object_instance); + break; + case PROP_OBJECT_NAME: + characterstring_init_ansi(&char_string, + Analog_Value_Name(object_instance)); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = + encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); + break; + case PROP_PRESENT_VALUE: + object_index = Analog_Value_Instance_To_Index(object_instance); + apdu_len = + encode_application_real(&apdu[0], + AV_Present_Value[object_index]); + 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_application_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + apdu_len = + encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_application_boolean(&apdu[0], false); + break; + case PROP_UNITS: + apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + /* only array properties can have array options */ + if ((apdu_len >= 0) && (array_index != BACNET_ARRAY_ALL)) { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + apdu_len = -1; + } + + return apdu_len; +} + +/* returns true if successful */ +bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code) +{ + bool status = false; /* return value */ + unsigned int object_index = 0; + int len = 0; + BACNET_APPLICATION_DATA_VALUE value; + + if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNKNOWN_OBJECT; + return false; + } + /* decode the some of the request */ + len = + bacapp_decode_application_data(wp_data->application_data, + wp_data->application_data_len, &value); + /* FIXME: len < application_data_len: more data? */ + if (len < 0) { + /* error while decoding - a value larger than we can handle */ + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + return false; + } + switch (wp_data->object_property) { + case PROP_PRESENT_VALUE: + if (value.tag == BACNET_APPLICATION_TAG_REAL) { + object_index = + Analog_Value_Instance_To_Index(wp_data->object_instance); + AV_Present_Value[object_index] = value.type.Real; + status = true; + } 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; + } + + return status; +} + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testAnalog_Value(Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + len = + Analog_Value_Encode_Property_APDU(&apdu[0], instance, + PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len != 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = + decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_ANALOG_VALUE +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Analog Value", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testAnalog_Value); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_ANALOG_VALUE */ +#endif /* TEST */ diff --git a/bacnet-stack/ports/arduino_uno/av.h b/bacnet-stack/ports/arduino_uno/av.h new file mode 100644 index 00000000..54745113 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/av.h @@ -0,0 +1,75 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#ifndef AV_H +#define AV_H + +#include +#include +#include "bacdef.h" +#include "bacerror.h" +#include "wp.h" + +#ifndef MAX_ANALOG_VALUES +#define MAX_ANALOG_VALUES 4 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + void Analog_Value_Property_Lists(const int **pRequired, + const int **pOptional, + const int **pProprietary); + bool Analog_Value_Valid_Instance(uint32_t object_instance); + unsigned Analog_Value_Count(void); + uint32_t Analog_Value_Index_To_Instance(unsigned index); + char *Analog_Value_Name(uint32_t object_instance); + + int Analog_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + uint32_t array_index, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code); + + bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code); + + bool Analog_Value_Present_Value_Set(uint32_t object_instance, + float value, + uint8_t priority); + float Analog_Value_Present_Value(uint32_t object_instance); + + void Analog_Value_Init(void); + +#ifdef TEST +#include "ctest.h" + void testAnalog_Value(Test * pTest); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/ports/arduino_uno/bip-init.c b/bacnet-stack/ports/arduino_uno/bip-init.c new file mode 100644 index 00000000..31ea035e --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/bip-init.c @@ -0,0 +1,166 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2005 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include /* for standard integer types uint8_t etc. */ +#include /* for the standard bool type. */ +#include +#include "bacdcode.h" +#include "bip.h" +#include "socketWrapper.h" +#include "w5100Wrapper.h" +//#include "net.h" + +/** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */ + +bool BIP_Debug = false; + +/* gets an IP address by name, where name can be a + string that is an IP address in dotted form, or + a name that is a domain name + returns 0 if not found, or + an IP address in network byte order */ +long bip_getaddrbyname(const char *host_name) +{ + return 0; +} + +/** Gets the local IP address and local broadcast address from the system, + * and saves it into the BACnet/IP data structures. + * + * @param ifname [in] The named interface to use for the network layer. + * Eg, for Linux, ifname is eth0, ath0, arc0, and others. + */ +void bip_set_interface(char *ifname) +{ + + uint8_t local_address[] = { 0, 0, 0, 0 }; + uint8_t broadcast_address[] = { 0, 0, 0, 0 }; + uint8_t netmask[] = { 0, 0, 0, 0 }; + uint8_t invertedNetmask[] = { 0, 0, 0, 0 }; + + getIPAddress_func(CW5100Class_new(), local_address); + bip_set_addr(local_address); + if (BIP_Debug) { + fprintf(stderr, "Interface: %s\n", ifname); + fprintf(stderr, "IP Address: %d.%d.%d.%d\n", local_address[0], + local_address[1], local_address[2], local_address[3]); + } + + /* setup local broadcast address */ + getSubnetMask_func(CW5100Class_new(), netmask); + for (int i = 0; i < 4; i++) { //FIXME: IPv4 ? + invertedNetmask[i] = ~netmask[i]; + broadcast_address[i] = (local_address[i] | invertedNetmask[i]); + } + + bip_set_broadcast_addr(broadcast_address); + if (BIP_Debug) { + fprintf(stderr, "IP Broadcast Address: %d.%d.%d.%d\n", + broadcast_address[0], broadcast_address[1], broadcast_address[2], + broadcast_address[3]); + } +} + +/** Initialize the BACnet/IP services at the given interface. + * @ingroup DLBIP + * -# Gets the local IP address and local broadcast address from the system, + * and saves it into the BACnet/IP data structures. + * -# Opens a UDP socket + * -# Configures the socket for sending and receiving + * -# Configures the socket so it can send broadcasts + * -# Binds the socket to the local IP address at the specified port for + * BACnet/IP (by default, 0xBAC0 = 47808). + * + * @note For Linux, ifname is eth0, ath0, arc0, and others. + * + * @param ifname [in] The named interface to use for the network layer. + * If NULL, the "eth0" interface is assigned. + * @return True if the socket is successfully opened for BACnet/IP, + * else False if the socket functions fail. + */ +bool bip_init(char *ifname) +{ + uint8_t sock_fd = 0; + bool isOpen = false; + + if (ifname) + bip_set_interface(ifname); + else + bip_set_interface("eth0"); + + /* assumes that the driver has already been initialized */ + for (sock_fd = 0; sock_fd < MAX_SOCK_NUM; sock_fd++) { + if (readSnSR_func(CW5100Class_new(), sock_fd) == SnSR_CLOSED()) { + socket_func(sock_fd, SnMR_UDP(), (uint16_t) 47808, 0); + listen_func(sock_fd); + isOpen = true; + break; + } + } + + if (!isOpen) { + bip_set_socket(MAX_SOCK_NUM); + return false; + } else { + bip_set_socket(sock_fd); + } + + return true; +} + +/** Cleanup and close out the BACnet/IP services by closing the socket. + * @ingroup DLBIP + */ +void bip_cleanup(void) +{ + int sock_fd = 0; + + if (bip_valid()) { + sock_fd = bip_socket(); + close_func(sock_fd); + } + bip_set_socket(MAX_SOCK_NUM); + + return; +} + +/** Get the netmask of the BACnet/IP's interface via an ioctl() call. + * @param netmask [out] The netmask, in host order. + * @return 0 on success, else the error from the ioctl() call. + */ +int bip_get_local_netmask(uint8_t * netmask) +{ + getSubnetMask_func(CW5100Class_new(), netmask); + return 0; +} diff --git a/bacnet-stack/ports/arduino_uno/bip.c b/bacnet-stack/ports/arduino_uno/bip.c new file mode 100644 index 00000000..13872395 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/bip.c @@ -0,0 +1,413 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2005 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include /* for standard integer types uint8_t etc. */ +#include /* for the standard bool type. */ +#include +#include "bacdcode.h" +#include "bacint.h" +#include "bip.h" +#include "bvlc-arduino.h" +#include "socketWrapper.h" +#include "w5100Wrapper.h" + + +#if PRINT_ENABLED | DEBUG +#include /* for standard i/o, like printing */ +#endif + +/** @file bip.c Configuration and Operations for BACnet/IP */ + +static uint8_t BIP_Socket = MAX_SOCK_NUM; +/* port to use - stored in network byte order */ +static uint16_t BIP_Port = 0; /* this will force initialization in demos */ +/* IP Address - stored in network byte order */ +//static struct in_addr BIP_Address; +static uint8_t BIP_Address[4] = { 0, 0, 0, 0 }; +/* Broadcast Address - stored in network byte order */ +//static struct in_addr BIP_Broadcast_Address; +static uint8_t BIP_Broadcast_Address[4] = { 0, 0, 0, 0 }; + +/** Converter from uint8_t[4] type address to uint32_t + * + */ +uint32_t convertBIP_Address2uint32(uint8_t * bip_address) +{ + return (uint32_t) ((bip_address[0] * 2 ^ 24) + (bip_address[1] * 2 ^ 16) + + (bip_address[2] * 2 ^ 8) + bip_address[3]); +} + +/** Convert from uint32_t IPv4 address to uint8_t[4] address + * + */ +void convertUint32Address_2_uint8Address(uint32_t ip, + uint8_t * address) +{ + address[0] = (uint8_t) (ip >> 24); + address[1] = (uint8_t) (ip >> 16); + address[2] = (uint8_t) (ip >> 8); + address[3] = (uint8_t) (ip >> 0); +} + +/** Setter for the BACnet/IP socket handle. + * + * @param sock_fd [in] Handle for the BACnet/IP socket. + */ +void bip_set_socket(uint8_t sock_fd) +{ + BIP_Socket = sock_fd; +} + +/** Getter for the BACnet/IP socket handle. + * + * @return The handle to the BACnet/IP socket. + */ +uint8_t bip_socket(void) +{ + return BIP_Socket; +} + +bool bip_valid(void) +{ + return (BIP_Socket < MAX_SOCK_NUM); +} + +void bip_set_addr(uint8_t * net_address) +{ /* in network byte order */ + for (uint8_t i = 0; i < 4; i++) + BIP_Address[i] = net_address[i]; +} + +/* returns network byte order */ +uint8_t *bip_get_addr(void) +{ + return BIP_Address; +} + +void bip_set_broadcast_addr(uint8_t * net_address) +{ /* in network byte order */ + for (uint8_t i = 0; i < 4; i++) + BIP_Broadcast_Address[i] = net_address[i]; +} + +/* returns network byte order */ +uint8_t *bip_get_broadcast_addr(void) +{ + return BIP_Broadcast_Address; +} + + +void bip_set_port(uint16_t port) +{ /* in network byte order */ + BIP_Port = port; +} + +/* returns network byte order */ +uint16_t bip_get_port(void) +{ + return BIP_Port; +} + +static int bip_decode_bip_address(BACNET_ADDRESS * bac_addr, + uint8_t * address, /* in network format */ + + uint16_t * port) +{ /* in network format */ + int len = 0; + + if (bac_addr) { + memcpy(address, &bac_addr->mac[0], 4); + memcpy(port, &bac_addr->mac[4], 2); + len = 6; + } + + return len; +} + +/** Function to send a packet out the BACnet/IP socket (Annex J). + * @ingroup DLBIP + * + * @param dest [in] Destination address (may encode an IP address and port #). + * @param npdu_data [in] The NPDU header (Network) information (not used). + * @param pdu [in] Buffer of data to be sent - may be null (why?). + * @param pdu_len [in] Number of bytes in the pdu buffer. + * @return Number of bytes sent on success, negative number on failure. + */ +int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */ + + BACNET_NPDU_DATA * npdu_data, /* network information */ + + uint8_t * pdu, /* any data to be sent - may be null */ + + unsigned pdu_len) +{ /* number of bytes of data */ + + uint8_t mtu[MAX_MPDU] = { 0 }; + int mtu_len = 0; + int bytes_sent = 0; + /* addr and port in host format */ + uint8_t address[] = { 0, 0, 0, 0 }; + uint16_t port = 0; + + (void) npdu_data; + /* assumes that the driver has already been initialized */ + if (BIP_Socket < 0) { + return BIP_Socket; + } + + mtu[0] = BVLL_TYPE_BACNET_IP; + if ((dest->net == BACNET_BROADCAST_NETWORK) || ((dest->net > 0) && + (dest->len == 0)) || (dest->mac_len == 0)) { + /* broadcast */ + for (uint8_t i = 0; i < 4; i++) + address[i] = BIP_Broadcast_Address[i]; + port = BIP_Port; + mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU; +#ifdef DEBUG + fprintf(stderr, "Send Broadcast NPDU to %d.%d.%d.%d:%d\n", address[0], + address[1] + , address[2], address[3], port); +#endif + } else if (dest->mac_len == 6) { + bip_decode_bip_address(dest, address, &port); + mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU; +#ifdef DEBUG + fprintf(stderr, "Send Unicast NPDU to %d.%d.%d.%d:%d\n", address[0], + address[1] + , address[2], address[3], port); +#endif + } else { + /* invalid address */ + return -1; + } + + mtu_len = 2; + mtu_len += + encode_unsigned16(&mtu[mtu_len], + (uint16_t) (pdu_len + 4 /*inclusive */ )); + memcpy(&mtu[mtu_len], pdu, pdu_len); + mtu_len += pdu_len; + +#ifdef DEBUG + fprintf(stderr, "MTU size %d\n", mtu_len); +#endif + + /* Send the packet */ + bytes_sent = + sendto_func(BIP_Socket, mtu, (uint16_t) mtu_len, address, port); + + return bytes_sent; +} + +/** Implementation of the receive() function for BACnet/IP; receives one + * packet, verifies its BVLC header, and removes the BVLC header from + * the PDU data before returning. + * + * @param src [out] Source of the packet - who should receive any response. + * @param pdu [out] A buffer to hold the PDU portion of the received packet, + * after the BVLC portion has been stripped off. + * @param max_pdu [in] Size of the pdu[] buffer. + * @param timeout [in] The number of milliseconds to wait for a packet. + * @return The number of octets (remaining) in the PDU, or zero on failure. + */ +uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */ + + uint8_t * pdu, /* PDU data */ + + uint16_t max_pdu, /* amount of space available in the PDU */ + + unsigned timeout) +{ + int received_bytes = 0; + uint16_t pdu_len = 0; /* return value */ + uint8_t src_addr[] = { 0, 0, 0, 0 }; + uint16_t src_port = 0; + uint16_t i = 0; + int function = 0; + + /* Make sure the socket is open */ + if (BIP_Socket < 0) + return 0; + + if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) { + memcpy(&src_addr, &src->mac[0], 4); + memcpy(&src_port, &src->mac[4], 2); + received_bytes = + (int) recvfrom_func(BIP_Socket, &pdu[0], max_pdu, src_addr, + &src_port); + } + + /* See if there is a problem */ + if (received_bytes < 0) { + return 0; + } + + /* no problem, just no bytes */ + if (received_bytes == 0) + return 0; + + /* the signature of a BACnet/IP packet */ + if (pdu[0] != BVLL_TYPE_BACNET_IP) + return 0; + + if (bvlc_for_non_bbmd(src_addr, &src_port, pdu, received_bytes) > 0) { + /* Handled, usually with a NACK. */ +#if PRINT_ENABLED + fprintf(stderr, "BIP: BVLC discarded!\n"); +#endif + return 0; + } + + function = bvlc_get_function_code(); /* aka, pdu[1] */ + if ((function == BVLC_ORIGINAL_UNICAST_NPDU) || + (function == BVLC_ORIGINAL_BROADCAST_NPDU)) { + /* ignore messages from me */ + if ((convertBIP_Address2uint32(src_addr) == + convertBIP_Address2uint32(BIP_Address)) && + (src_port == BIP_Port)) { + pdu_len = 0; +#if 0 + fprintf(stderr, "BIP: src is me. Discarded!\n"); +#endif + } else { + /* data in src->mac[] is in network format */ + src->mac_len = 6; + memcpy(&src->mac[0], &src_addr, 4); + memcpy(&src->mac[4], &src_port, 2); +#ifdef DEBUG + fprintf(stderr, "BIP receive from %d.%d.%d.%d\n", src->mac[0], + src->mac[1], src->mac[2], src->mac[3]); +#endif + /* FIXME: check destination address */ + /* see if it is broadcast or for us */ + /* decode the length of the PDU - length is inclusive of BVLC */ + (void) decode_unsigned16(&pdu[2], &pdu_len); + /* subtract off the BVLC header */ + pdu_len -= 4; + if (pdu_len < max_pdu) { +#if 0 + fprintf(stderr, "BIP: NPDU[%hu]:", pdu_len); +#endif + /* shift the buffer to return a valid PDU */ + for (i = 0; i < pdu_len; i++) { + pdu[i] = pdu[4 + i]; +#if 0 + fprintf(stderr, "%02X ", pdu[i]); +#endif + } +#if 0 + fprintf(stderr, "\n"); +#endif + } + /* ignore packets that are too large */ + /* clients should check my max-apdu first */ + else { + pdu_len = 0; +#if PRINT_ENABLED + fprintf(stderr, "BIP: PDU too large. Discarded!.\n"); +#endif + } + } + } else if (function == BVLC_FORWARDED_NPDU) { + memcpy(&src_addr, &pdu[4], 4); + memcpy(&src_port, &pdu[8], 2); + if ((convertBIP_Address2uint32(src_addr) == + convertBIP_Address2uint32(BIP_Address)) && + (src_port == BIP_Port)) { + /* ignore messages from me */ + pdu_len = 0; + } else { + /* data in src->mac[] is in network format */ + src->mac_len = 6; + memcpy(&src->mac[0], &src_addr, 4); + memcpy(&src->mac[4], &src_port, 2); + /* FIXME: check destination address */ + /* see if it is broadcast or for us */ + /* decode the length of the PDU - length is inclusive of BVLC */ + (void) decode_unsigned16(&pdu[2], &pdu_len); + /* subtract off the BVLC header */ + pdu_len -= 10; + if (pdu_len < max_pdu) { + /* shift the buffer to return a valid PDU */ + for (i = 0; i < pdu_len; i++) { + pdu[i] = pdu[4 + 6 + i]; + } + } else { + /* ignore packets that are too large */ + /* clients should check my max-apdu first */ + pdu_len = 0; + } + } + } + + return pdu_len; +} + +void bip_get_my_address(BACNET_ADDRESS * my_address) +{ + int i = 0; + + if (my_address) { + my_address->mac_len = 6; + memcpy(&my_address->mac[0], &BIP_Address, 4); + memcpy(&my_address->mac[4], &BIP_Port, 2); + my_address->net = 0; /* local only, no routing */ + my_address->len = 0; /* no SLEN */ + for (i = 0; i < MAX_MAC_LEN; i++) { + /* no SADR */ + my_address->adr[i] = 0; + } + } + + return; +} + +void bip_get_broadcast_address(BACNET_ADDRESS * dest) +{ /* destination address */ + int i = 0; /* counter */ + + if (dest) { + dest->mac_len = 6; + memcpy(&dest->mac[0], &BIP_Broadcast_Address, 4); + memcpy(&dest->mac[4], &BIP_Port, 2); + dest->net = BACNET_BROADCAST_NETWORK; + dest->len = 0; /* no SLEN */ + for (i = 0; i < MAX_MAC_LEN; i++) { + /* no SADR */ + dest->adr[i] = 0; + } + } + + return; +} diff --git a/bacnet-stack/ports/arduino_uno/bv.c b/bacnet-stack/ports/arduino_uno/bv.c new file mode 100644 index 00000000..d07c4c9e --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/bv.c @@ -0,0 +1,302 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +/* Binary Value Objects - customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" /* the custom stuff */ +#include "wp.h" +#include "bv.h" + +#if (MAX_BINARY_VALUES > 10) +#error Modify the Binary_Value_Name to handle multiple digits +#endif + +static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES]; + +/* we simply have 0-n object instances. */ +bool Binary_Value_Valid_Instance(uint32_t object_instance) +{ + if (object_instance < MAX_BINARY_VALUES) + return true; + + return false; +} + +/* we simply have 0-n object instances. */ +unsigned Binary_Value_Count(void) +{ + return MAX_BINARY_VALUES; +} + +/* we simply have 0-n object instances. */ +uint32_t Binary_Value_Index_To_Instance(unsigned index) +{ + return index; +} + +/* we simply have 0-n object instances. */ +unsigned Binary_Value_Instance_To_Index(uint32_t object_instance) +{ + unsigned index = MAX_BINARY_VALUES; + + if (object_instance < MAX_BINARY_VALUES) + index = object_instance; + + return index; +} + +static BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance) +{ + BACNET_BINARY_PV value = BINARY_INACTIVE; + + if (object_instance < MAX_BINARY_VALUES) { + value = Present_Value[object_instance]; + } + + return value; +} + +/* note: the object name must be unique within this device */ +char *Binary_Value_Name(uint32_t object_instance) +{ + static char text_string[5] = "BV-0"; /* okay for single thread */ + + if (object_instance < MAX_BINARY_VALUES) { + text_string[3] = '0' + (uint8_t) object_instance; + return text_string; + } + + return NULL; +} + +/* return apdu len, or -1 on error */ +int Binary_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + uint32_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; + BACNET_BINARY_PV present_value = BINARY_INACTIVE; + BACNET_POLARITY polarity = POLARITY_NORMAL; + + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = + encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, + 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: + characterstring_init_ansi(&char_string, + Binary_Value_Name(object_instance)); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = + encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE); + break; + case PROP_PRESENT_VALUE: + present_value = Binary_Value_Present_Value(object_instance); + apdu_len = encode_application_enumerated(&apdu[0], present_value); + break; + case PROP_STATUS_FLAGS: + /* note: see the details in the standard on how to use these */ + 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_application_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + /* note: see the details in the standard on how to use this */ + apdu_len = + encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_application_boolean(&apdu[0], false); + break; + case PROP_POLARITY: + /* FIXME: figure out the polarity */ + apdu_len = encode_application_enumerated(&apdu[0], polarity); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + /* only array properties can have array options */ + if ((apdu_len >= 0) && (array_index != BACNET_ARRAY_ALL)) { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; + apdu_len = -1; + } + + return apdu_len; +} + +/* returns true if successful */ +bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code) +{ + bool status = false; /* return value */ + unsigned int object_index = 0; + int len = 0; + BACNET_APPLICATION_DATA_VALUE value; + + if (!Binary_Value_Valid_Instance(wp_data->object_instance)) { + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNKNOWN_OBJECT; + return false; + } + /* decode the some of the request */ + len = + bacapp_decode_application_data(wp_data->application_data, + wp_data->application_data_len, &value); + /* FIXME: len < application_data_len: more data? */ + if (len < 0) { + /* error while decoding - a value larger than we can handle */ + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + return false; + } + switch (wp_data->object_property) { + case PROP_PRESENT_VALUE: + if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { + if ((value.type.Enumerated == BINARY_ACTIVE) || + (value.type.Enumerated == BINARY_INACTIVE)) { + object_index = + Binary_Value_Instance_To_Index(wp_data-> + object_instance); + /* NOTE: this Binary value has no priority array */ + Present_Value[object_index] = + (BACNET_BINARY_PV) value.type.Enumerated; + /* 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. */ + if (Present_Value[0] == BINARY_ACTIVE) { +// LED_GREEN_ON(); + } else { +// LED_GREEN_OFF(); + } + status = true; + } 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; +#if 0 + case PROP_OUT_OF_SERVICE: + if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { + object_index = + Binary_Value_Instance_To_Index(wp_data->object_instance); + Binary_Value_Out_Of_Service[object_index] = value.type.Boolean; + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; +#endif + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + break; + } + + return status; +} + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testBinary_Value(Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_VALUE; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + + len = + Binary_Value_Encode_Property_APDU(&apdu[0], instance, + PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len != 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = + decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_BINARY_VALUE +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Binary_Value", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testBinary_Value); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_BINARY_VALUE */ +#endif /* TEST */ diff --git a/bacnet-stack/ports/arduino_uno/bv.h b/bacnet-stack/ports/arduino_uno/bv.h new file mode 100644 index 00000000..24704896 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/bv.h @@ -0,0 +1,72 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#ifndef BV_H +#define BV_H + +#include +#include +#include "bacdef.h" +#include "bacerror.h" +#include "wp.h" + +#ifndef MAX_BINARY_VALUES +#define MAX_BINARY_VALUES 10 +#endif + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void Binary_Value_Property_Lists(const int **pRequired, + const int **pOptional, + const int **pProprietary); + bool Binary_Value_Valid_Instance(uint32_t object_instance); + unsigned Binary_Value_Count(void); + uint32_t Binary_Value_Index_To_Instance(unsigned index); + char *Binary_Value_Name(uint32_t object_instance); + + void Binary_Value_Init(void); + + int Binary_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + uint32_t array_index, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code); + + bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code); + +#ifdef TEST +#include "ctest.h" + void testBinary_Value(Test * pTest); +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/ports/arduino_uno/bvlc-arduino.c b/bacnet-stack/ports/arduino_uno/bvlc-arduino.c new file mode 100644 index 00000000..81a02c39 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/bvlc-arduino.c @@ -0,0 +1,124 @@ +/** + * @file + * @author Miguel Fernandes + * @date 6 de Jun de 2013 + * @brief BACnet Virtual Link Control for Wiznet on Arduino-Uno + */ +#include +#include +#include + +#include "bvlc-arduino.h" +#include "bip.h" +#include "bacint.h" +#include "socketWrapper.h" +#include "w5100Wrapper.h" + +/** result from a client request */ +BACNET_BVLC_RESULT BVLC_Result_Code = BVLC_RESULT_SUCCESSFUL_COMPLETION; +/** The current BVLC Function Code being handled. */ +BACNET_BVLC_FUNCTION BVLC_Function_Code = BVLC_RESULT; /* A safe default */ + +static int bvlc_encode_bvlc_result(uint8_t * pdu, + BACNET_BVLC_RESULT result_code) +{ + if (pdu) { + pdu[0] = BVLL_TYPE_BACNET_IP; + pdu[1] = BVLC_RESULT; + /* The 2-octet BVLC Length field is the length, in octets, + of the entire BVLL message, including the two octets of the + length field itself, most significant octet first. */ + encode_unsigned16(&pdu[2], 6); + encode_unsigned16(&pdu[4], (uint16_t) result_code); + } + + return 6; +} + +static int bvlc_send_mpdu(uint8_t * dest_addr, /* the destination address */ + + uint16_t * dest_port, /* the destination port */ + + uint8_t * mtu, /* the data */ + + uint16_t mtu_len) +{ /* amount of data to send */ + /* assumes that the driver has already been initialized */ + if (bip_valid()) { + return 0; + } + + return sendto_func(bip_socket(), mtu, mtu_len, dest_addr, *dest_port); +} + +static void bvlc_send_result(uint8_t * dest_addr, + uint16_t * dest_port, /* the destination address */ + + BACNET_BVLC_RESULT result_code) +{ + uint8_t mtu[MAX_MPDU] = { 0 }; + uint16_t mtu_len = 0; + + mtu_len = (uint16_t) bvlc_encode_bvlc_result(&mtu[0], result_code); + bvlc_send_mpdu(dest_addr, dest_port, mtu, mtu_len); + + return; +} + +uint16_t bvlc_for_non_bbmd(uint8_t * addr, + uint16_t * port, + uint8_t * npdu, + uint16_t received_bytes) +{ + + uint16_t result_code = 0; /* aka, BVLC_RESULT_SUCCESSFUL_COMPLETION */ + BVLC_Function_Code = npdu[1]; /* The BVLC function */ + switch (BVLC_Function_Code) { + case BVLC_RESULT: + if (received_bytes >= 6) { + /* This is the result of our foreign device registration */ + (void) decode_unsigned16(&npdu[4], &result_code); + BVLC_Result_Code = (BACNET_BVLC_RESULT) result_code; + fprintf(stderr, "BVLC: Result Code=%d\n", BVLC_Result_Code); + /* But don't send any response */ + result_code = 0; + } + break; + case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE: + result_code = BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK; + break; + case BVLC_READ_BROADCAST_DIST_TABLE: + result_code = BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK; + break; + /* case BVLC_READ_BROADCAST_DIST_TABLE_ACK: */ + case BVLC_REGISTER_FOREIGN_DEVICE: + result_code = BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK; + break; + case BVLC_READ_FOREIGN_DEVICE_TABLE: + result_code = BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK; + break; + /* case BVLC_READ_FOREIGN_DEVICE_TABLE_ACK: */ + case BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY: + result_code = BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK; + break; + case BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK: + result_code = BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK; + break; + /* case BVLC_FORWARDED_NPDU: */ + /* case BVLC_ORIGINAL_UNICAST_NPDU: */ + /* case BVLC_ORIGINAL_BROADCAST_NPDU: */ + default: + break; + } + + if (result_code > 0) { + bvlc_send_result(addr, port, result_code); + fprintf(stderr, "BVLC: NAK code=%d\n", result_code); + } + return result_code; +} + +BACNET_BVLC_FUNCTION bvlc_get_function_code(void) +{ + return BVLC_Function_Code; +} diff --git a/bacnet-stack/ports/arduino_uno/bvlc-arduino.h b/bacnet-stack/ports/arduino_uno/bvlc-arduino.h new file mode 100644 index 00000000..ae6a0c62 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/bvlc-arduino.h @@ -0,0 +1,29 @@ +/** + * @file + * @author Miguel Fernandes + * @date 6 de Jun de 2013 + * @brief BACnet Virtual Link Control for Wiznet on Arduino-Uno + */ +#ifndef BVLCARDUINO_H_ +#define BVLCARDUINO_H_ + +#include +#include "bacenum.h" +#include "bacdef.h" +#include "npdu.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +uint16_t bvlc_for_non_bbmd(uint8_t * addr, + uint16_t * port, + uint8_t * npdu, + uint16_t received_bytes); + +BACNET_BVLC_FUNCTION bvlc_get_function_code(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* BVLCARDUINO_H_ */ diff --git a/bacnet-stack/ports/arduino_uno/datalink.h b/bacnet-stack/ports/arduino_uno/datalink.h new file mode 100644 index 00000000..092770a6 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/datalink.h @@ -0,0 +1,136 @@ +/************************************************************************** +* +* Copyright (C) 2012 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 DATALINK_H +#define DATALINK_H + +#include "config.h" +#include "bacdef.h" + +#if defined(BACDL_ETHERNET) +#include "ethernet.h" + +#define datalink_init ethernet_init +#define datalink_send_pdu ethernet_send_pdu +#define datalink_receive ethernet_receive +#define datalink_cleanup ethernet_cleanup +#define datalink_get_broadcast_address ethernet_get_broadcast_address +#define datalink_get_my_address ethernet_get_my_address + +#elif defined(BACDL_ARCNET) +#include "arcnet.h" + +#define datalink_init arcnet_init +#define datalink_send_pdu arcnet_send_pdu +#define datalink_receive arcnet_receive +#define datalink_cleanup arcnet_cleanup +#define datalink_get_broadcast_address arcnet_get_broadcast_address +#define datalink_get_my_address arcnet_get_my_address + +#elif defined(BACDL_MSTP) +#include "dlmstp.h" + +#define datalink_init dlmstp_init +#define datalink_send_pdu dlmstp_send_pdu +#define datalink_receive dlmstp_receive +#define datalink_cleanup dlmstp_cleanup +#define datalink_get_broadcast_address dlmstp_get_broadcast_address +#define datalink_get_my_address dlmstp_get_my_address + +#elif defined(BACDL_BIP) +#include "bip.h" +#include "bvlc-arduino.h" + +#define datalink_init bip_init +//#if defined(BBMD_ENABLED) && BBMD_ENABLED +//#define datalink_send_pdu bvlc_send_pdu +//#define datalink_receive bvlc_receive +//#else +#define datalink_send_pdu bip_send_pdu +#define datalink_receive bip_receive +//#endif +#define datalink_cleanup bip_cleanup +#define datalink_get_broadcast_address bip_get_broadcast_address +#ifdef BAC_ROUTING +extern void routed_get_my_address(BACNET_ADDRESS * my_address); +#define datalink_get_my_address routed_get_my_address +#else +#define datalink_get_my_address bip_get_my_address +#endif + +#else /* Ie, BACDL_ALL */ +#include "npdu.h" + +#define MAX_HEADER (8) +#define MAX_MPDU (MAX_HEADER+MAX_PDU) + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int datalink_send_pdu(BACNET_ADDRESS * dest, + BACNET_NPDU_DATA * npdu_data, + uint8_t * pdu, + unsigned pdu_len); + extern uint16_t datalink_receive(BACNET_ADDRESS * src, + uint8_t * pdu, + uint16_t max_pdu, + unsigned timeout); + extern void datalink_cleanup(void); + extern void datalink_get_broadcast_address(BACNET_ADDRESS * dest); + extern void datalink_get_my_address(BACNET_ADDRESS * my_address); + extern void datalink_set_interface(char *ifname); + extern void datalink_set(char *datalink_string); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif +/** @defgroup DataLink The BACnet Network (DataLink) Layer + * 6 THE NETWORK LAYER
+ * The purpose of the BACnet network layer is to provide the means by which + * messages can be relayed from one BACnet network to another, regardless of + * the BACnet data link technology in use on that network. Whereas the data + * link layer provides the capability to address messages to a single device + * or broadcast them to all devices on the local network, the network layer + * allows messages to be directed to a single remote device, broadcast on a + * remote network, or broadcast globally to all devices on all networks. + * A BACnet Device is uniquely located by a network number and a MAC address. + * + * Each client or server application must define exactly one of these + * DataLink settings, which will control which parts of the code will be built: + * - BACDL_ETHERNET -- for Clause 7 ISO 8802-3 ("Ethernet") LAN + * - BACDL_ARCNET -- for Clause 8 ARCNET LAN + * - BACDL_MSTP -- for Clause 9 MASTER-SLAVE/TOKEN PASSING (MS/TP) LAN + * - BACDL_BIP -- for ANNEX J - BACnet/IP + * - BACDL_ALL -- Unspecified for the build, so the transport can be + * chosen at runtime from among these choices. + * - Clause 10 POINT-TO-POINT (PTP) and Clause 11 EIA/CEA-709.1 ("LonTalk") LAN + * are not currently supported by this project. + *//** @defgroup DLTemplates DataLink Template Functions + * @ingroup DataLink + * Most of the functions in this group are function templates which are assigned + * to a specific DataLink network layer implementation either at compile time or + * at runtime. + */ +#endif diff --git a/bacnet-stack/ports/arduino_uno/device.h b/bacnet-stack/ports/arduino_uno/device.h new file mode 100644 index 00000000..ba460159 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/device.h @@ -0,0 +1,140 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2005 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#ifndef DEVICE_H +#define DEVICE_H + +#include +#include +#include "bacdef.h" +#include "bacenum.h" +#include "wp.h" +#include "readrange.h" + +typedef unsigned (*object_count_function) (void); +typedef uint32_t(*object_index_to_instance_function) + (unsigned index); +typedef char *(*object_name_function) + (uint32_t object_instance); + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void Device_Object_Function_Set(BACNET_OBJECT_TYPE object_type, + object_count_function count_function, + object_index_to_instance_function index_function, + object_name_function name_function); + + void Device_Init(void); + + void Device_Property_Lists(const int **pRequired, + const int **pOptional, + const int **pProprietary); + + uint32_t Device_Object_Instance_Number(void); + bool Device_Set_Object_Instance_Number(uint32_t object_id); + bool Device_Valid_Object_Instance_Number(uint32_t object_id); + unsigned Device_Object_List_Count(void); + bool Device_Object_List_Identifier(unsigned array_index, + int *object_type, + uint32_t * instance); + + BACNET_DEVICE_STATUS Device_System_Status(void); + void Device_Set_System_Status(BACNET_DEVICE_STATUS status); + + const char *Device_Vendor_Name(void); + + uint16_t Device_Vendor_Identifier(void); + + const char *Device_Model_Name(void); + bool Device_Set_Model_Name(const char *name, + size_t length); + + const char *Device_Firmware_Revision(void); + + const char *Device_Application_Software_Version(void); + bool Device_Set_Application_Software_Version(const char *name, + size_t length); + + bool Device_Set_Object_Name(const char *name, + size_t length); + const char *Device_Object_Name(void); + + const char *Device_Description(void); + bool Device_Set_Description(const char *name, + size_t length); + + const char *Device_Location(void); + bool Device_Set_Location(const char *name, + size_t length); + + /* some stack-centric constant values - no set methods */ + uint8_t Device_Protocol_Version(void); + uint8_t Device_Protocol_Revision(void); + BACNET_SEGMENTATION Device_Segmentation_Supported(void); + + uint8_t Device_Database_Revision(void); + void Device_Set_Database_Revision(uint8_t revision); + + bool Device_Valid_Object_Name(const char *object_name, + int *object_type, + uint32_t * object_instance); + char *Device_Valid_Object_Id(int object_type, + uint32_t object_instance); + + int Device_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + uint32_t array_index, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code); + + bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code); + + bool DeviceGetRRInfo(uint32_t Object, /* Which particular object - obviously not important for device object */ + + BACNET_PROPERTY_ID Property, /* Which property */ + + RR_PROP_INFO * pInfo, /* Where to put the information */ + + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/Makefile b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/Makefile new file mode 100644 index 00000000..2ea14957 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/Makefile @@ -0,0 +1,118 @@ +############################################################################### +# Makefile for BACnet +############################################################################### + +## General Flags +MCU = atmega328p +AVRDUDE_MCU = m328 +TARGET = ArduinoEthernet +## Tools +CC = avr-gcc +AR = avr-ar +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AVRDUDE = avrdude +LINT = splint + +# programmer id--check the avrdude for complete list +# # of available opts. These should include stk500, +# # avr910, avrisp, bsd, pony and more. Set this to +# # one of the valid "-c PROGRAMMER-ID" values +# # described in the avrdude info page. +# # +AVRDUDE_PROGRAMMERID = avrispmkII +# +# # port--serial or parallel port to which your +# # hardware programmer is attached +# # +AVRDUDE_PORT = /dev/ttyUSB0 + +# local files for this project +#CSRC = main.c + +ARDUINOSRC = \ + src/socket.cpp \ + src/w5100.cpp \ + src/SPI.cpp \ + src/w5100Wrapper.cpp \ + src/socketWrapper.cpp + +## Include Directories +INCLUDES = -Iinclude +INCLUDES += -I../core/include + +LIBRARY = lib$(TARGET).a + +## Options common to compile, link and assembly rules +COMMON = -mmcu=$(MCU) + +OPTIMIZE_FLAGS = -mcall-prologues +#OPTIMIZE_FLAGS += -finline-functions +OPTIMIZE_FLAGS += -finline-functions-called-once +#OPTIMIZATION = -O0 +#OPTIMIZATION = -Os +OPTIMIZATION = -Os $(OPTIMIZE_FLAGS) +#OPTIMIZATION = -O3 $(OPTIMIZE_FLAGS) + +## Compile options common for all C compilation units. +CFLAGS = $(COMMON) +# dead code removal +CFLAGS += -ffunction-sections -fdata-sections +CFLAGS += -Wall -gdwarf-2 $(OPTIMIZATION) -fsigned-char +CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d + +## Assembly specific flags +ASMFLAGS = $(COMMON) +ASMFLAGS += $(CFLAGS) +ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 + +## Linker flags +LDFLAGS = $(COMMON) +#dead code removal +#LDFLAGS += -Wl,-nostartfiles,-nostdlib +LDFLAGS += -Wl,--gc-sections,-static +LDFLAGS += -Wl,-Map=$(TARGET).map,-L.,-l$(TARGET) +#LDFLAGS += -Wl,-Map=$(TARGET).map +LDFLAGS += -L../core/lib,-lArduinoUnoCore + +## Intel Hex file production flags +HEX_FLASH_FLAGS = -R .eeprom +HEX_EEPROM_FLAGS = -j .eeprom +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 +OBJS := ${SRCS:.cpp=.o} + +all: $(LIBRARY) size Makefile + +default: all + +lib: $(LIBRARY) + +$(LIBRARY): $(OBJS) Makefile + $(AR) rcs lib/$@ $(OBJS) + $(OBJDUMP) --syms lib/$@ > lib/$(LIBRARY:.a=.lst) + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $*.c -o $@ + +.cpp.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $*.cpp -o $@ + +size: ${TARGET_ELF} + @echo + @${SIZE} ${TARGET_ELF} + +lint: + $(LINT) $(BFLAGS) $(CSRC) + +## Clean target +.PHONY: clean +clean: + -rm -rf $(OBJS) dep/* + -rm -rf $(LIBRARY) $(OBJS) + +## Other dependencies +-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/SPI.h b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/SPI.h new file mode 100644 index 00000000..e0797cfb --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/SPI.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2010 by Cristian Maglie + * SPI Master library for arduino. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#ifndef _SPI_H_INCLUDED +#define _SPI_H_INCLUDED + +#include +#include +#include + +#define SPI_CLOCK_DIV4 0x00 +#define SPI_CLOCK_DIV16 0x01 +#define SPI_CLOCK_DIV64 0x02 +#define SPI_CLOCK_DIV128 0x03 +#define SPI_CLOCK_DIV2 0x04 +#define SPI_CLOCK_DIV8 0x05 +#define SPI_CLOCK_DIV32 0x06 +//#define SPI_CLOCK_DIV64 0x07 + +#define SPI_MODE0 0x00 +#define SPI_MODE1 0x04 +#define SPI_MODE2 0x08 +#define SPI_MODE3 0x0C + +#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR +#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR +#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR + +class SPIClass { + public: + inline static byte transfer(byte _data); + + // SPI Configuration methods + + inline static void attachInterrupt(); + inline static void detachInterrupt(); // Default + + static void begin(); // Default + static void end(); + + static void setBitOrder(uint8_t); + static void setDataMode(uint8_t); + static void setClockDivider(uint8_t); +}; + +extern SPIClass SPI; + +byte SPIClass::transfer(byte _data) +{ + SPDR = _data; + while (!(SPSR & _BV(SPIF))); + return SPDR; +} + +void SPIClass::attachInterrupt() +{ + SPCR |= _BV(SPIE); +} + +void SPIClass::detachInterrupt() +{ + SPCR &= ~_BV(SPIE); +} + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/util.h b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/util.h new file mode 100644 index 00000000..f1303032 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/util.h @@ -0,0 +1,13 @@ +#ifndef UTIL_H +#define UTIL_H + +#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) ) +#define ntohs(x) htons(x) + +#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ + ((x)<< 8 & 0x00FF0000UL) | \ + ((x)>> 8 & 0x0000FF00UL) | \ + ((x)>>24 & 0x000000FFUL) ) +#define ntohl(x) htonl(x) + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/w5100.h b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/w5100.h new file mode 100644 index 00000000..80d3c123 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/w5100.h @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2010 by Cristian Maglie + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#ifndef W5100_H_INCLUDED +#define W5100_H_INCLUDED + +#include +#include + +#define MAX_SOCK_NUM 4 + +typedef uint8_t SOCKET; + +#define IDM_OR 0x8000 +#define IDM_AR0 0x8001 +#define IDM_AR1 0x8002 +#define IDM_DR 0x8003 +/* +class MR { +public: + static const uint8_t RST = 0x80; + static const uint8_t PB = 0x10; + static const uint8_t PPPOE = 0x08; + static const uint8_t LB = 0x04; + static const uint8_t AI = 0x02; + static const uint8_t IND = 0x01; +}; +*/ +/* +class IR { +public: + static const uint8_t CONFLICT = 0x80; + static const uint8_t UNREACH = 0x40; + static const uint8_t PPPoE = 0x20; + static const uint8_t SOCK0 = 0x01; + static const uint8_t SOCK1 = 0x02; + static const uint8_t SOCK2 = 0x04; + static const uint8_t SOCK3 = 0x08; + static inline uint8_t SOCK(SOCKET ch) { return (0x01 << ch); }; +}; +*/ + +class SnMR { + public: + static const uint8_t CLOSE = 0x00; + static const uint8_t TCP = 0x01; + static const uint8_t UDP = 0x02; + static const uint8_t IPRAW = 0x03; + static const uint8_t MACRAW = 0x04; + static const uint8_t PPPOE = 0x05; + static const uint8_t ND = 0x20; + static const uint8_t MULTI = 0x80; +}; + +enum SockCMD { + Sock_OPEN = 0x01, + Sock_LISTEN = 0x02, + Sock_CONNECT = 0x04, + Sock_DISCON = 0x08, + Sock_CLOSE = 0x10, + Sock_SEND = 0x20, + Sock_SEND_MAC = 0x21, + Sock_SEND_KEEP = 0x22, + Sock_RECV = 0x40 +}; + +/*class SnCmd { +public: + static const uint8_t OPEN = 0x01; + static const uint8_t LISTEN = 0x02; + static const uint8_t CONNECT = 0x04; + static const uint8_t DISCON = 0x08; + static const uint8_t CLOSE = 0x10; + static const uint8_t SEND = 0x20; + static const uint8_t SEND_MAC = 0x21; + static const uint8_t SEND_KEEP = 0x22; + static const uint8_t RECV = 0x40; +}; +*/ + +class SnIR { + public: + static const uint8_t SEND_OK = 0x10; + static const uint8_t TIMEOUT = 0x08; + static const uint8_t RECV = 0x04; + static const uint8_t DISCON = 0x02; + static const uint8_t CON = 0x01; +}; + +class SnSR { + public: + static const uint8_t CLOSED = 0x00; + static const uint8_t INIT = 0x13; + static const uint8_t LISTEN = 0x14; + static const uint8_t SYNSENT = 0x15; + static const uint8_t SYNRECV = 0x16; + static const uint8_t ESTABLISHED = 0x17; + static const uint8_t FIN_WAIT = 0x18; + static const uint8_t CLOSING = 0x1A; + static const uint8_t TIME_WAIT = 0x1B; + static const uint8_t CLOSE_WAIT = 0x1C; + static const uint8_t LAST_ACK = 0x1D; + static const uint8_t UDP = 0x22; + static const uint8_t IPRAW = 0x32; + static const uint8_t MACRAW = 0x42; + static const uint8_t PPPOE = 0x5F; +}; + +class IPPROTO { + public: + static const uint8_t IP = 0; + static const uint8_t ICMP = 1; + static const uint8_t IGMP = 2; + static const uint8_t GGP = 3; + static const uint8_t TCP = 6; + static const uint8_t PUP = 12; + static const uint8_t UDP = 17; + static const uint8_t IDP = 22; + static const uint8_t ND = 77; + static const uint8_t RAW = 255; +}; + +class W5100Class { + + public: + void init(); + + /** + * @brief This function is being used for copy the data form Receive buffer of the chip to application buffer. + * + * It calculate the actual physical address where one has to read + * the data from Receive buffer. Here also take care of the condition while it exceed + * the Rx memory uper-bound of socket. + */ + void read_data(SOCKET s, + volatile uint8_t * src, + volatile uint8_t * dst, + uint16_t len); + + /** + * @brief This function is being called by send() and sendto() function also. + * + * This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer + * register. User should read upper byte first and lower byte later to get proper value. + */ + void send_data_processing(SOCKET s, + const uint8_t * data, + uint16_t len); + /** + * @brief A copy of send_data_processing that uses the provided ptr for the + * write offset. Only needed for the "streaming" UDP API, where + * a single UDP packet is built up over a number of calls to + * send_data_processing_ptr, because TX_WR doesn't seem to get updated + * correctly in those scenarios + * @param ptr value to use in place of TX_WR. If 0, then the value is read + * in from TX_WR + * @return New value for ptr, to be used in the next call + */ +// FIXME Update documentation + void send_data_processing_offset(SOCKET s, + uint16_t data_offset, + const uint8_t * data, + uint16_t len); + + /** + * @brief This function is being called by recv() also. + * + * This function read the Rx read pointer register + * and after copy the data from receive buffer update the Rx write pointer register. + * User should read upper byte first and lower byte later to get proper value. + */ + void recv_data_processing(SOCKET s, + uint8_t * data, + uint16_t len, + uint8_t peek = 0); + + inline void setGatewayIp(uint8_t * _addr); + inline void getGatewayIp(uint8_t * _addr); + + inline void setSubnetMask(uint8_t * _addr); + inline void getSubnetMask(uint8_t * _addr); + + inline void setMACAddress(uint8_t * addr); + inline void getMACAddress(uint8_t * addr); + + inline void setIPAddress(uint8_t * addr); + inline void getIPAddress(uint8_t * addr); + + inline void setRetransmissionTime(uint16_t timeout); + inline void setRetransmissionCount(uint8_t _retry); + + void execCmdSn(SOCKET s, + SockCMD _cmd); + + uint16_t getTXFreeSize(SOCKET s); + uint16_t getRXReceivedSize(SOCKET s); + + + // W5100 Registers + // --------------- + private: + static uint8_t write(uint16_t _addr, + uint8_t _data); + static uint16_t write(uint16_t addr, + const uint8_t * buf, + uint16_t len); + static uint8_t read(uint16_t addr); + static uint16_t read(uint16_t addr, + uint8_t * buf, + uint16_t len); + +#define __GP_REGISTER8(name, address) \ + static inline void write##name(uint8_t _data) { \ + write(address, _data); \ + } \ + static inline uint8_t read##name() { \ + return read(address); \ + } +#define __GP_REGISTER16(name, address) \ + static void write##name(uint16_t _data) { \ + write(address, _data >> 8); \ + write(address+1, _data & 0xFF); \ + } \ + static uint16_t read##name() { \ + uint16_t res = read(address); \ + res = (res << 8) + read(address + 1); \ + return res; \ + } +#define __GP_REGISTER_N(name, address, size) \ + static uint16_t write##name(uint8_t *_buff) { \ + return write(address, _buff, size); \ + } \ + static uint16_t read##name(uint8_t *_buff) { \ + return read(address, _buff, size); \ + } + + public: + __GP_REGISTER8(MR, + 0x0000); // Mode + __GP_REGISTER_N(GAR, + 0x0001, + 4); // Gateway IP address + __GP_REGISTER_N(SUBR, + 0x0005, + 4); // Subnet mask address + __GP_REGISTER_N(SHAR, + 0x0009, + 6); // Source MAC address + __GP_REGISTER_N(SIPR, + 0x000F, + 4); // Source IP address + __GP_REGISTER8(IR, + 0x0015); // Interrupt + __GP_REGISTER8(IMR, + 0x0016); // Interrupt Mask + __GP_REGISTER16(RTR, + 0x0017); // Timeout address + __GP_REGISTER8(RCR, + 0x0019); // Retry count + __GP_REGISTER8(RMSR, + 0x001A); // Receive memory size + __GP_REGISTER8(TMSR, + 0x001B); // Transmit memory size + __GP_REGISTER8(PATR, + 0x001C); // Authentication type address in PPPoE mode + __GP_REGISTER8(PTIMER, + 0x0028); // PPP LCP Request Timer + __GP_REGISTER8(PMAGIC, + 0x0029); // PPP LCP Magic Number + __GP_REGISTER_N(UIPR, + 0x002A, + 4); // Unreachable IP address in UDP mode + __GP_REGISTER16(UPORT, + 0x002E); // Unreachable Port address in UDP mode + +#undef __GP_REGISTER8 +#undef __GP_REGISTER16 +#undef __GP_REGISTER_N + + // W5100 Socket registers + // ---------------------- + private: + static inline uint8_t readSn(SOCKET _s, + uint16_t _addr); + static inline uint8_t writeSn(SOCKET _s, + uint16_t _addr, + uint8_t _data); + static inline uint16_t readSn(SOCKET _s, + uint16_t _addr, + uint8_t * _buf, + uint16_t len); + static inline uint16_t writeSn(SOCKET _s, + uint16_t _addr, + uint8_t * _buf, + uint16_t len); + + static const uint16_t CH_BASE = 0x0400; + static const uint16_t CH_SIZE = 0x0100; + +#define __SOCKET_REGISTER8(name, address) \ + static inline void write##name(SOCKET _s, uint8_t _data) { \ + writeSn(_s, address, _data); \ + } \ + static inline uint8_t read##name(SOCKET _s) { \ + return readSn(_s, address); \ + } +#define __SOCKET_REGISTER16(name, address) \ + static void write##name(SOCKET _s, uint16_t _data) { \ + writeSn(_s, address, _data >> 8); \ + writeSn(_s, address+1, _data & 0xFF); \ + } \ + static uint16_t read##name(SOCKET _s) { \ + uint16_t res = readSn(_s, address); \ + uint16_t res2 = readSn(_s,address + 1); \ + res = res << 8; \ + res2 = res2 & 0xFF; \ + res = res | res2; \ + return res; \ + } +#define __SOCKET_REGISTER_N(name, address, size) \ + static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \ + return writeSn(_s, address, _buff, size); \ + } \ + static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \ + return readSn(_s, address, _buff, size); \ + } + + public: + __SOCKET_REGISTER8(SnMR, + 0x0000) // Mode + __SOCKET_REGISTER8(SnCR, + 0x0001) // Command + __SOCKET_REGISTER8(SnIR, + 0x0002) // Interrupt + __SOCKET_REGISTER8(SnSR, + 0x0003) // Status + __SOCKET_REGISTER16(SnPORT, + 0x0004) // Source Port + __SOCKET_REGISTER_N(SnDHAR, + 0x0006, + 6) // Destination Hardw Addr + __SOCKET_REGISTER_N(SnDIPR, + 0x000C, + 4) // Destination IP Addr + __SOCKET_REGISTER16(SnDPORT, + 0x0010) // Destination Port + __SOCKET_REGISTER16(SnMSSR, + 0x0012) // Max Segment Size + __SOCKET_REGISTER8(SnPROTO, + 0x0014) // Protocol in IP RAW Mode + __SOCKET_REGISTER8(SnTOS, + 0x0015) // IP TOS + __SOCKET_REGISTER8(SnTTL, + 0x0016) // IP TTL + __SOCKET_REGISTER16(SnTX_FSR, + 0x0020) // TX Free Size + __SOCKET_REGISTER16(SnTX_RD, + 0x0022) // TX Read Pointer + __SOCKET_REGISTER16(SnTX_WR, + 0x0024) // TX Write Pointer + __SOCKET_REGISTER16(SnRX_RSR, + 0x0026) // RX Free Size + __SOCKET_REGISTER16(SnRX_RD, + 0x0028) // RX Read Pointer + __SOCKET_REGISTER16(SnRX_WR, + 0x002A) // RX Write Pointer (supported?) +#undef __SOCKET_REGISTER8 +#undef __SOCKET_REGISTER16 +#undef __SOCKET_REGISTER_N + private: + static const uint8_t RST = 7; // Reset BIT + + static const int SOCKETS = 4; + static const uint16_t SMASK = 0x07FF; // Tx buffer MASK + static const uint16_t RMASK = 0x07FF; // Rx buffer MASK + public: + static const uint16_t SSIZE = 2048; // Max Tx buffer size + private: + static const uint16_t RSIZE = 2048; // Max Rx buffer size + uint16_t SBASE[SOCKETS]; // Tx buffer base address + uint16_t RBASE[SOCKETS]; // Rx buffer base address + + private: +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + inline static void initSS() { + DDRB |= _BV(4); + }; + inline static void setSS() { + PORTB &= ~_BV(4); + }; + inline static void resetSS() { + PORTB |= _BV(4); + }; +#elif defined(__AVR_ATmega32U4__) + inline static void initSS() { + DDRB |= _BV(6); + }; + inline static void setSS() { + PORTB &= ~_BV(6); + }; + inline static void resetSS() { + PORTB |= _BV(6); + }; +#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__) + inline static void initSS() { + DDRB |= _BV(0); + }; + inline static void setSS() { + PORTB &= ~_BV(0); + }; + inline static void resetSS() { + PORTB |= _BV(0); + }; +#else + inline static void initSS() { + DDRB |= _BV(2); + }; + inline static void setSS() { + PORTB &= ~_BV(2); + }; + inline static void resetSS() { + PORTB |= _BV(2); + }; +#endif + +}; + +extern W5100Class W5100; + +uint8_t W5100Class::readSn(SOCKET _s, + uint16_t _addr) +{ + return read(CH_BASE + _s * CH_SIZE + _addr); +} + +uint8_t W5100Class::writeSn(SOCKET _s, + uint16_t _addr, + uint8_t _data) +{ + return write(CH_BASE + _s * CH_SIZE + _addr, _data); +} + +uint16_t W5100Class::readSn(SOCKET _s, + uint16_t _addr, + uint8_t * _buf, + uint16_t _len) +{ + return read(CH_BASE + _s * CH_SIZE + _addr, _buf, _len); +} + +uint16_t W5100Class::writeSn(SOCKET _s, + uint16_t _addr, + uint8_t * _buf, + uint16_t _len) +{ + return write(CH_BASE + _s * CH_SIZE + _addr, _buf, _len); +} + +void W5100Class::getGatewayIp(uint8_t * _addr) +{ + readGAR(_addr); +} + +void W5100Class::setGatewayIp(uint8_t * _addr) +{ + writeGAR(_addr); +} + +void W5100Class::getSubnetMask(uint8_t * _addr) +{ + readSUBR(_addr); +} + +void W5100Class::setSubnetMask(uint8_t * _addr) +{ + writeSUBR(_addr); +} + +void W5100Class::getMACAddress(uint8_t * _addr) +{ + readSHAR(_addr); +} + +void W5100Class::setMACAddress(uint8_t * _addr) +{ + writeSHAR(_addr); +} + +void W5100Class::getIPAddress(uint8_t * _addr) +{ + readSIPR(_addr); +} + +void W5100Class::setIPAddress(uint8_t * _addr) +{ + writeSIPR(_addr); +} + +void W5100Class::setRetransmissionTime(uint16_t _timeout) +{ + writeRTR(_timeout); +} + +void W5100Class::setRetransmissionCount(uint8_t _retry) +{ + writeRCR(_retry); +} + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/w5100Wrapper.h b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/w5100Wrapper.h new file mode 100644 index 00000000..315f34b3 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/include/w5100Wrapper.h @@ -0,0 +1,139 @@ +/* + * w5100Wrapper.h + * + * Created on: 26 de Mai de 2013 + * Author: mgf + */ + +#ifndef W5100WRAPPER_H_ +#define W5100WRAPPER_H_ + +#include + +typedef uint8_t SOCKET; +typedef void CSnMR; +typedef void CSnIR; +typedef void CSnSR; +typedef void CIPPROTO; +typedef void CW5100Class; + +#define MAX_SOCK_NUM 4 + +#ifdef __cplusplus +extern "C" { +#endif + + CSnMR *CSnMR_new(); + void CSnMR_delete(const CSnMR * obj); + uint8_t SnMR_CLOSE(); + uint8_t SnMR_UDP(); + uint8_t SnMR_TCP(); + uint8_t SnMR_IPRAW(); + uint8_t SnMR_MACRAW(); + uint8_t SnMR_PPPOE(); + uint8_t SnMR_ND(); + uint8_t SnMR_MULTI(); + + CSnIR *CSnIR_new(); + void CSnIR_delete(const CSnIR * obj); + uint8_t SnIR_SEND_OK(); + uint8_t SnIR_TIMEOUT(); + uint8_t SnIR_RECV(); + uint8_t SnIR_DISCON(); + uint8_t SnIR_CON(); + + + CSnSR *CSnSR_new(); + void CSnSR_delete(const CSnSR * obj); + uint8_t SnSR_CLOSED(); + uint8_t SnSR_INIT(); + uint8_t SnSR_LISTEN(); + uint8_t SnSR_SYNSENT(); + uint8_t SnSR_SYNRECV(); + uint8_t SnSR_ESTABLISHED(); + uint8_t SnSR_FIN_WAIT(); + uint8_t SnSR_CLOSING(); + uint8_t SnSR_TIME_WAIT(); + uint8_t SnSR_CLOSE_WAIT(); + uint8_t SnSR_LAST_ACK(); + uint8_t SnSR_UDP(); + uint8_t SnSR_IPRAW(); + uint8_t SnSR_MACRAW(); + uint8_t SnSR_PPPOE(); + + CIPPROTO *CIPPROTO_new(); + void CIPPROTO_delete(const CIPPROTO * obj); + uint8_t IPPROTO_IP(); + uint8_t IPPROTO_ICMP(); + uint8_t IPPROTO_IGMP(); + uint8_t IPPROTO_GGP(); + uint8_t IPPROTO_TCP(); + uint8_t IPPROTO_PUP(); + uint8_t IPPROTO_UDP(); + uint8_t IPPROTO_IDP(); + uint8_t IPPROTO_ND(); + uint8_t IPPROTO_RAW(); + + CW5100Class *CW5100Class_new(); + void init_func(const CW5100Class * obj); + void CW5100Class_delete(const CW5100Class * obj); + + void read_data_func(const CW5100Class * obj, + SOCKET s, + volatile uint8_t * src, + volatile uint8_t * dst, + uint16_t len); + + void send_data_processing_func(const CW5100Class * obj, + SOCKET s, + const uint8_t * data, + uint16_t len); + void send_data_processing_offset_func(const CW5100Class * obj, + SOCKET s, + uint16_t data_offset, + const uint8_t * data, + uint16_t len); +//FIXME: Removed defaul value of 0(zero) from the peek argument + void recv_data_processing_func(const CW5100Class * obj, + SOCKET s, + uint8_t * data, + uint16_t len, + uint8_t peek); + void setGatewayIp_func(const CW5100Class * obj, + uint8_t * _addr); + void getGatewayIp_func(const CW5100Class * obj, + uint8_t * _addr); +// + void setSubnetMask_func(const CW5100Class * obj, + uint8_t * _addr); + void getSubnetMask_func(const CW5100Class * obj, + uint8_t * _addr); +// + void setMACAddress_func(const CW5100Class * obj, + uint8_t * addr); + void getMACAddress_func(const CW5100Class * obj, + uint8_t * addr); +// + void setIPAddress_func(const CW5100Class * obj, + uint8_t * addr); + void getIPAddress_func(const CW5100Class * obj, + uint8_t * addr); +// + void setRetransmissionTime_func(const CW5100Class * obj, + uint16_t timeout); + void setRetransmissionCount_func(const CW5100Class * obj, + uint8_t _retry); +// + + uint16_t getTXFreeSize_func(const CW5100Class * obj, + SOCKET s); + uint16_t getRXReceivedSize_func(const CW5100Class * obj, + SOCKET s); + + uint8_t readSnSR_func(const CW5100Class * obj, + SOCKET s); + +#ifdef __cplusplus +} +#endif +#endif /* W5100WRAPPER_H_ */ diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/SPI.cpp b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/SPI.cpp new file mode 100644 index 00000000..5e48073f --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/SPI.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010 by Cristian Maglie + * SPI Master library for arduino. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#include "pins_arduino.h" +#include "SPI.h" + +SPIClass SPI; + +void SPIClass::begin() { + + // Set SS to high so a connected chip will be "deselected" by default + digitalWrite(SS, HIGH); + + // When the SS pin is set as OUTPUT, it can be used as + // a general purpose output port (it doesn't influence + // SPI operations). + pinMode(SS, OUTPUT); + + // Warning: if the SS pin ever becomes a LOW INPUT then SPI + // automatically switches to Slave, so the data direction of + // the SS pin MUST be kept as OUTPUT. + SPCR |= _BV(MSTR); + SPCR |= _BV(SPE); + + // Set direction register for SCK and MOSI pin. + // MISO pin automatically overrides to INPUT. + // By doing this AFTER enabling SPI, we avoid accidentally + // clocking in a single bit since the lines go directly + // from "input" to SPI control. + // http://code.google.com/p/arduino/issues/detail?id=888 + pinMode(SCK, OUTPUT); + pinMode(MOSI, OUTPUT); +} + + +void SPIClass::end() { + SPCR &= ~_BV(SPE); +} + +void SPIClass::setBitOrder(uint8_t bitOrder) +{ + if(bitOrder == LSBFIRST) { + SPCR |= _BV(DORD); + } else { + SPCR &= ~(_BV(DORD)); + } +} + +void SPIClass::setDataMode(uint8_t mode) +{ + SPCR = (SPCR & ~SPI_MODE_MASK) | mode; +} + +void SPIClass::setClockDivider(uint8_t rate) +{ + SPCR = (SPCR & ~SPI_CLOCK_MASK) | (rate & SPI_CLOCK_MASK); + SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((rate >> 2) & SPI_2XCLOCK_MASK); +} + diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/socket.cpp b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/socket.cpp new file mode 100644 index 00000000..fd3e4426 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/socket.cpp @@ -0,0 +1,400 @@ +#include "w5100.h" +#include "socket.h" + +static uint16_t local_port; + +/** + * @brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it. + * @return 1 for success else 0. + */ +uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag) +{ + if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE)) + { + close(s); + W5100.writeSnMR(s, protocol | flag); + if (port != 0) { + W5100.writeSnPORT(s, port); + } + else { + local_port++; // if don't set the source port, set local_port number. + W5100.writeSnPORT(s, local_port); + } + + W5100.execCmdSn(s, Sock_OPEN); + + return 1; + } + + return 0; +} + + +/** + * @brief This function close the socket and parameter is "s" which represent the socket number + */ +void close(SOCKET s) +{ + W5100.execCmdSn(s, Sock_CLOSE); + W5100.writeSnIR(s, 0xFF); +} + + +/** + * @brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer. + * @return 1 for success else 0. + */ +uint8_t listen(SOCKET s) +{ + if (W5100.readSnSR(s) != SnSR::INIT) + return 0; + W5100.execCmdSn(s, Sock_LISTEN); + return 1; +} + + +/** + * @brief This function established the connection for the channel in Active (client) mode. + * This function waits for the untill the connection is established. + * + * @return 1 for success else 0. + */ +uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port) +{ + if + ( + ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) || + ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || + (port == 0x00) + ) + return 0; + + // set destination IP + W5100.writeSnDIPR(s, addr); + W5100.writeSnDPORT(s, port); + W5100.execCmdSn(s, Sock_CONNECT); + + return 1; +} + + + +/** + * @brief This function used for disconnect the socket and parameter is "s" which represent the socket number + * @return 1 for success else 0. + */ +void disconnect(SOCKET s) +{ + W5100.execCmdSn(s, Sock_DISCON); +} + + +/** + * @brief This function used to send the data in TCP mode + * @return 1 for success else 0. + */ +uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len) +{ + uint8_t status=0; + uint16_t ret=0; + uint16_t freesize=0; + + if (len > W5100.SSIZE) + ret = W5100.SSIZE; // check size not to exceed MAX size. + else + ret = len; + + // if freebuf is available, start. + do + { + freesize = W5100.getTXFreeSize(s); + status = W5100.readSnSR(s); + if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT)) + { + ret = 0; + break; + } + } + while (freesize < ret); + + // copy data + W5100.send_data_processing(s, (uint8_t *)buf, ret); + W5100.execCmdSn(s, Sock_SEND); + + /* +2008.01 bj */ + while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) + { + /* m2008.01 [bj] : reduce code */ + if ( W5100.readSnSR(s) == SnSR::CLOSED ) + { + close(s); + return 0; + } + } + /* +2008.01 bj */ + W5100.writeSnIR(s, SnIR::SEND_OK); + return ret; +} + + +/** + * @brief This function is an application I/F function which is used to receive the data in TCP mode. + * It continues to wait for data as much as the application wants to receive. + * + * @return received data size for success else -1. + */ +int16_t recv(SOCKET s, uint8_t *buf, int16_t len) +{ + // Check how much data is available + int16_t ret = W5100.getRXReceivedSize(s); + if ( ret == 0 ) + { + // No data available. + uint8_t status = W5100.readSnSR(s); + if ( status == SnSR::LISTEN || status == SnSR::CLOSED || status == SnSR::CLOSE_WAIT ) + { + // The remote end has closed its side of the connection, so this is the eof state + ret = 0; + } + else + { + // The connection is still up, but there's no data waiting to be read + ret = -1; + } + } + else if (ret > len) + { + ret = len; + } + + if ( ret > 0 ) + { + W5100.recv_data_processing(s, buf, ret); + W5100.execCmdSn(s, Sock_RECV); + } + return ret; +} + + +/** + * @brief Returns the first byte in the receive queue (no checking) + * + * @return + */ +uint16_t peek(SOCKET s, uint8_t *buf) +{ + W5100.recv_data_processing(s, buf, 1, 1); + + return 1; +} + + +/** + * @brief This function is an application I/F function which is used to send the data for other then TCP mode. + * Unlike TCP transmission, The peer's destination address and the port is needed. + * + * @return This function return send data size for success else -1. + */ +uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port) +{ + uint16_t ret=0; + + if (len > W5100.SSIZE) ret = W5100.SSIZE; // check size not to exceed MAX size. + else ret = len; + + if + ( + ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || + ((port == 0x00)) ||(ret == 0) + ) + { + /* +2008.01 [bj] : added return value */ + ret = 0; + } + else + { + W5100.writeSnDIPR(s, addr); + W5100.writeSnDPORT(s, port); + + // copy data + W5100.send_data_processing(s, (uint8_t *)buf, ret); + W5100.execCmdSn(s, Sock_SEND); + + /* +2008.01 bj */ + while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) + { + if (W5100.readSnIR(s) & SnIR::TIMEOUT) + { + /* +2008.01 [bj]: clear interrupt */ + W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */ + return 0; + } + } + + /* +2008.01 bj */ + W5100.writeSnIR(s, SnIR::SEND_OK); + } + return ret; +} + + +/** + * @brief This function is an application I/F function which is used to receive the data in other then + * TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well. + * + * @return This function return received data size for success else -1. + */ +uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port) +{ + uint8_t head[8]; + uint16_t data_len=0; + uint16_t ptr=0; + + if ( len > 0 ) + { + ptr = W5100.readSnRX_RD(s); + switch (W5100.readSnMR(s) & 0x07) + { + case SnMR::UDP : + W5100.read_data(s, (uint8_t *)ptr, head, 0x08); + ptr += 8; + // read peer's IP address, port number. + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + data_len = head[6]; + data_len = (data_len << 8) + head[7]; + + W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy. + ptr += data_len; + + W5100.writeSnRX_RD(s, ptr); + break; + + case SnMR::IPRAW : + W5100.read_data(s, (uint8_t *)ptr, head, 0x06); + ptr += 6; + + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + data_len = head[4]; + data_len = (data_len << 8) + head[5]; + + W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy. + ptr += data_len; + + W5100.writeSnRX_RD(s, ptr); + break; + + case SnMR::MACRAW: + W5100.read_data(s,(uint8_t*)ptr,head,2); + ptr+=2; + data_len = head[0]; + data_len = (data_len<<8) + head[1] - 2; + + W5100.read_data(s,(uint8_t*) ptr,buf,data_len); + ptr += data_len; + W5100.writeSnRX_RD(s, ptr); + break; + + default : + break; + } + W5100.execCmdSn(s, Sock_RECV); + } + return data_len; +} + + +uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len) +{ + uint8_t status=0; + uint16_t ret=0; + + if (len > W5100.SSIZE) + ret = W5100.SSIZE; // check size not to exceed MAX size. + else + ret = len; + + if (ret == 0) + return 0; + + W5100.send_data_processing(s, (uint8_t *)buf, ret); + W5100.execCmdSn(s, Sock_SEND); + + while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) + { + status = W5100.readSnSR(s); + if (W5100.readSnIR(s) & SnIR::TIMEOUT) + { + /* in case of igmp, if send fails, then socket closed */ + /* if you want change, remove this code. */ + close(s); + return 0; + } + } + + W5100.writeSnIR(s, SnIR::SEND_OK); + return ret; +} + +uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len) +{ + uint16_t ret =0; + if (len > W5100.getTXFreeSize(s)) + { + ret = W5100.getTXFreeSize(s); // check size not to exceed MAX size. + } + else + { + ret = len; + } + W5100.send_data_processing_offset(s, offset, buf, ret); + return ret; +} + +int startUDP(SOCKET s, uint8_t* addr, uint16_t port) +{ + if + ( + ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || + ((port == 0x00)) + ) + { + return 0; + } + else + { + W5100.writeSnDIPR(s, addr); + W5100.writeSnDPORT(s, port); + return 1; + } +} + +int sendUDP(SOCKET s) +{ + W5100.execCmdSn(s, Sock_SEND); + + /* +2008.01 bj */ + while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) + { + if (W5100.readSnIR(s) & SnIR::TIMEOUT) + { + /* +2008.01 [bj]: clear interrupt */ + W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT)); + return 0; + } + } + + /* +2008.01 bj */ + W5100.writeSnIR(s, SnIR::SEND_OK); + + /* Sent ok */ + return 1; +} + diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/w5100.cpp b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/w5100.cpp new file mode 100644 index 00000000..9c748fd2 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/w5100.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2010 by Cristian Maglie + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include "w5100.h" + +// W5100 controller instance +W5100Class W5100; + +#define TX_RX_MAX_BUF_SIZE 2048 +#define TX_BUF 0x1100 +#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE) + +#define TXBUF_BASE 0x4000 +#define RXBUF_BASE 0x6000 + +void W5100Class::init(void) +{ + delay(300); + + SPI.begin(); + initSS(); + + writeMR(1< SSIZE) + { + // Wrap around circular buffer + uint16_t size = SSIZE - offset; + write(dstAddr, data, size); + write(SBASE[s], data + size, len - size); + } + else { + write(dstAddr, data, len); + } + + ptr += len; + writeSnTX_WR(s, ptr); +} + + +void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) +{ + uint16_t ptr; + ptr = readSnRX_RD(s); + read_data(s, (uint8_t *)ptr, data, len); + if (!peek) + { + ptr += len; + writeSnRX_RD(s, ptr); + } +} + +void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len) +{ + uint16_t size; + uint16_t src_mask; + uint16_t src_ptr; + + src_mask = (uint16_t)src & RMASK; + src_ptr = RBASE[s] + src_mask; + + if( (src_mask + len) > RSIZE ) + { + size = RSIZE - src_mask; + read(src_ptr, (uint8_t *)dst, size); + dst += size; + read(RBASE[s], (uint8_t *) dst, len - size); + } + else + read(src_ptr, (uint8_t *) dst, len); +} + + +uint8_t W5100Class::write(uint16_t _addr, uint8_t _data) +{ + setSS(); + SPI.transfer(0xF0); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer(_data); + resetSS(); + return 1; +} + +uint16_t W5100Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len) +{ + for (uint16_t i=0; i<_len; i++) + { + setSS(); + SPI.transfer(0xF0); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + _addr++; + SPI.transfer(_buf[i]); + resetSS(); + } + return _len; +} + +uint8_t W5100Class::read(uint16_t _addr) +{ + setSS(); + SPI.transfer(0x0F); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + uint8_t _data = SPI.transfer(0); + resetSS(); + return _data; +} + +uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len) +{ + for (uint16_t i=0; i<_len; i++) + { + setSS(); + SPI.transfer(0x0F); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + _addr++; + _buf[i] = SPI.transfer(0); + resetSS(); + } + return _len; +} + +void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) { + // Send command to socket + writeSnCR(s, _cmd); + // Wait for command to complete + while (readSnCR(s)) + ; +} diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/w5100Wrapper.cpp b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/w5100Wrapper.cpp new file mode 100644 index 00000000..0022e654 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/Ethernet/src/w5100Wrapper.cpp @@ -0,0 +1,176 @@ +/* + * w5100Wrapper.cpp + * + * Created on: 26 de Mai de 2013 + * Author: mgf + */ + + +#include "w5100.h" +#include "w5100Wrapper.h" + +extern "C"{ + +CSnMR * CSnMR_new(){ + SnMR* s = new SnMR(); + return (CSnMR*)s; +} +void CSnMR_delete(const CSnMR* obj){ + SnMR* s = (SnMR*)obj; + delete s; +} +uint8_t SnMR_CLOSE(){ return SnMR::CLOSE; } +uint8_t SnMR_UDP(){ return SnMR::UDP; } +uint8_t SnMR_TCP(){ return SnMR::TCP; } +uint8_t SnMR_IPRAW(){ return SnMR::IPRAW; } +uint8_t SnMR_MACRAW(){ return SnMR::MACRAW; } +uint8_t SnMR_PPPOE(){ return SnMR::PPPOE; } +uint8_t SnMR_ND(){ return SnMR::ND; } +uint8_t SnMR_MULTI(){ return SnMR::MULTI; } + +CSnIR * CSnIR_new(){ + SnIR* s = new SnIR(); + return (CSnIR*) s; +} +void CSnIR_delete(const CSnIR* obj){ + SnIR* s = (SnIR*)obj; + delete s; +} +uint8_t SnIR_SEND_OK(){ return SnIR::SEND_OK; } +uint8_t SnIR_TIMEOUT(){ return SnIR::TIMEOUT; } +uint8_t SnIR_RECV(){ return SnIR::RECV; } +uint8_t SnIR_DISCON(){ return SnIR::DISCON; } +uint8_t SnIR_CON(){ return SnIR::CON; } + +CSnSR * CSnSR_new(){ + SnSR* s = new SnSR(); + return (CSnSR*) s; +} +void CSnSR_delete(const CSnSR* obj){ + SnSR* s = (SnSR*)obj; + delete s; +} +uint8_t SnSR_CLOSED(){ return SnSR::CLOSED; } +uint8_t SnSR_INIT(){ return SnSR::INIT; } +uint8_t SnSR_LISTEN(){ return SnSR::LISTEN; } +uint8_t SnSR_SYNSENT(){ return SnSR::SYNSENT; } +uint8_t SnSR_SYNRECV(){ return SnSR::SYNRECV; } +uint8_t SnSR_ESTABLISHED(){ return SnSR::ESTABLISHED; } +uint8_t SnSR_FIN_WAIT(){ return SnSR::FIN_WAIT; } +uint8_t SnSR_CLOSING(){ return SnSR::CLOSING; } +uint8_t SnSR_TIME_WAIT(){ return SnSR::TIME_WAIT; } +uint8_t SnSR_CLOSE_WAIT(){ return SnSR::CLOSE_WAIT; } +uint8_t SnSR_LAST_ACK(){ return SnSR::LAST_ACK; } +uint8_t SnSR_UDP(){ return SnSR::UDP; } +uint8_t SnSR_IPRAW(){ return SnSR::IPRAW; } +uint8_t SnSR_MACRAW(){ return SnSR::MACRAW; } +uint8_t SnSR_PPPOE(){ return SnSR::PPPOE; } + +CIPPROTO * CIPPROTO_new(){ + IPPROTO* i = new IPPROTO(); + return (CIPPROTO*) i; +} +void CIPPROTO_delete(const CIPPROTO* obj){ + IPPROTO* i = (IPPROTO*) obj; + delete i; +} +uint8_t IPPROTO_IP(){ return IPPROTO::IP; } +uint8_t IPPROTO_ICMP(){ return IPPROTO::ICMP; } +uint8_t IPPROTO_IGMP(){ return IPPROTO::IGMP; } +uint8_t IPPROTO_GGP(){ return IPPROTO::GGP; } +uint8_t IPPROTO_TCP(){ return IPPROTO::TCP; } +uint8_t IPPROTO_PUP(){ return IPPROTO::PUP; } +uint8_t IPPROTO_UDP(){ return IPPROTO::UDP; } +uint8_t IPPROTO_IDP(){ return IPPROTO::IDP; } +uint8_t IPPROTO_ND(){ return IPPROTO::ND; } +uint8_t IPPROTO_RAW(){ return IPPROTO::RAW; } + +CW5100Class * CW5100Class_new(){ + return (CW5100Class*) &W5100; +} + +void init_func(const CW5100Class * obj){ + W5100Class* w = (W5100Class*) obj; + w->init(); +} + +void read_data_func(const CW5100Class * obj, SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, + uint16_t len){ + W5100Class* w = (W5100Class*) obj; + w->read_data(s, src, dst, len); +} + +void send_data_processing_func(const CW5100Class * obj, SOCKET s, const uint8_t *data, uint16_t len){ + W5100Class* w = (W5100Class*) obj; + w->send_data_processing(s, data, len); +} +void send_data_processing_offset_func(const CW5100Class * obj, SOCKET s, uint16_t data_offset, + const uint8_t *data, uint16_t len){ + W5100Class* w = (W5100Class*) obj; + w->send_data_processing_offset(s, data_offset, data, len); +} +//FIXME: Removed defaul value of 0(zero) from the peek argument +void recv_data_processing_func(const CW5100Class * obj, SOCKET s, uint8_t *data, uint16_t len, + uint8_t peek){ + W5100Class* w = (W5100Class*) obj; + w->recv_data_processing(s, data, len, peek); +} +void setGatewayIp_func(const CW5100Class * obj, uint8_t *_addr){ + W5100Class* w = (W5100Class*) obj; + w->setGatewayIp(_addr); +} +void getGatewayIp_func(const CW5100Class * obj, uint8_t *_addr){ + W5100Class* w = (W5100Class*) obj; + w->getGatewayIp(_addr); +} + +void setSubnetMask_func(const CW5100Class * obj, uint8_t *_addr){ + W5100Class* w = (W5100Class*) obj; + w->setSubnetMask(_addr); +} +void getSubnetMask_func(const CW5100Class * obj, uint8_t *_addr){ + W5100Class* w = (W5100Class*) obj; + w->getSubnetMask(_addr); +} + +void setMACAddress_func(const CW5100Class * obj, uint8_t * addr){ + W5100Class* w = (W5100Class*) obj; + w->setMACAddress(addr); +} +void getMACAddress_func(const CW5100Class * obj, uint8_t * addr){ + W5100Class* w = (W5100Class*) obj; + w->getMACAddress(addr); +} +void setIPAddress_func(const CW5100Class * obj, uint8_t * addr){ + W5100Class* w = (W5100Class*) obj; + w->setIPAddress(addr); +} +void getIPAddress_func(const CW5100Class * obj, uint8_t * addr){ + W5100Class* w = (W5100Class*) obj; + w->getIPAddress(addr); +} +void setRetransmissionTime_func(const CW5100Class * obj, uint16_t timeout){ + W5100Class* w = (W5100Class*) obj; + w->setRetransmissionTime(timeout); +} +void setRetransmissionCount_func(const CW5100Class * obj, uint8_t _retry){ + W5100Class* w = (W5100Class*) obj; + w->setRetransmissionCount(_retry); +} + +uint16_t getTXFreeSize_func(const CW5100Class * obj,SOCKET s){ + W5100Class* w = (W5100Class*) obj; + return w->getTXFreeSize(s); +} +uint16_t getRXReceivedSize_func(const CW5100Class * obj,SOCKET s){ + W5100Class* w = (W5100Class*) obj; + return w->getRXReceivedSize(s); +} + +uint8_t readSnSR_func(const CW5100Class* obj, SOCKET s){ + W5100Class* w = (W5100Class*) obj; + return w->readSnSR(s); +} + +}//externC + diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Arduino.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Arduino.h new file mode 100644 index 00000000..b8ed0204 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Arduino.h @@ -0,0 +1,235 @@ +#ifndef Arduino_h +#define Arduino_h + +#include +#include +#include + +#include +#include +#include + +#include "binary.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define HIGH 0x1 +#define LOW 0x0 + +#define INPUT 0x0 +#define OUTPUT 0x1 +#define INPUT_PULLUP 0x2 + +#define true 0x1 +#define false 0x0 + +#define PI 3.1415926535897932384626433832795 +#define HALF_PI 1.5707963267948966192313216916398 +#define TWO_PI 6.283185307179586476925286766559 +#define DEG_TO_RAD 0.017453292519943295769236907684886 +#define RAD_TO_DEG 57.295779513082320876798154814105 + +#define SERIAL 0x0 +#define DISPLAY 0x1 + +#define LSBFIRST 0 +#define MSBFIRST 1 + +#define CHANGE 1 +#define FALLING 2 +#define RISING 3 + +#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) +#define DEFAULT 0 +#define EXTERNAL 1 +#define INTERNAL 2 +#else +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) +#define INTERNAL1V1 2 +#define INTERNAL2V56 3 +#else +#define INTERNAL 3 +#endif +#define DEFAULT 1 +#define EXTERNAL 0 +#endif + +// undefine stdlib's abs if encountered +#ifdef abs +#undef abs +#endif + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) +#define abs(x) ((x)>0?(x):-(x)) +#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) +#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) +#define radians(deg) ((deg)*DEG_TO_RAD) +#define degrees(rad) ((rad)*RAD_TO_DEG) +#define sq(x) ((x)*(x)) + +#define interrupts() sei() +#define noInterrupts() cli() + +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) + +#define lowByte(w) ((uint8_t) ((w) & 0xff)) +#define highByte(w) ((uint8_t) ((w) >> 8)) + +#define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#define bitSet(value, bit) ((value) |= (1UL << (bit))) +#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) +#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) + + + typedef unsigned int word; + +#define bit(b) (1UL << (b)) + + typedef uint8_t boolean; + typedef uint8_t byte; + + void init(void); + + void pinMode(uint8_t, + uint8_t); + void digitalWrite(uint8_t, + uint8_t); + int digitalRead(uint8_t); + int analogRead(uint8_t); + void analogReference(uint8_t mode); + void analogWrite(uint8_t, + int); + + unsigned long millis(void); + unsigned long micros(void); + void delay(unsigned long); + void delayMicroseconds(unsigned int us); + unsigned long pulseIn(uint8_t pin, + uint8_t state, + unsigned long timeout); + + void shiftOut(uint8_t dataPin, + uint8_t clockPin, + uint8_t bitOrder, + uint8_t val); + uint8_t shiftIn(uint8_t dataPin, + uint8_t clockPin, + uint8_t bitOrder); + + void attachInterrupt(uint8_t, + void (*)(void), + int mode); + void detachInterrupt(uint8_t); + + void setup(void); + void loop(void); + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. + +#define analogInPinToBit(P) (P) + +// On the ATmega1280, the addresses of some of the port registers are +// greater than 255, so we can't store them in uint8_t's. + extern const uint16_t PROGMEM port_to_mode_PGM[]; + extern const uint16_t PROGMEM port_to_input_PGM[]; + extern const uint16_t PROGMEM port_to_output_PGM[]; + + extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; +// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; + extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; + extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; + +// Get the bit location within the hardware port of the given virtual pin. +// This comes from the pins_*.c file for the active board configuration. +// +// These perform slightly better as macros compared to inline functions +// +#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) +#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) +#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) +#define analogInPinToBit(P) (P) +#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) +#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) +#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) + +#define NOT_A_PIN 0 +#define NOT_A_PORT 0 + +#ifdef ARDUINO_MAIN +#define PA 1 +#define PB 2 +#define PC 3 +#define PD 4 +#define PE 5 +#define PF 6 +#define PG 7 +#define PH 8 +#define PJ 10 +#define PK 11 +#define PL 12 +#endif + +#define NOT_ON_TIMER 0 +#define TIMER0A 1 +#define TIMER0B 2 +#define TIMER1A 3 +#define TIMER1B 4 +#define TIMER2 5 +#define TIMER2A 6 +#define TIMER2B 7 + +#define TIMER3A 8 +#define TIMER3B 9 +#define TIMER3C 10 +#define TIMER4A 11 +#define TIMER4B 12 +#define TIMER4C 13 +#define TIMER4D 14 +#define TIMER5A 15 +#define TIMER5B 16 +#define TIMER5C 17 + +#ifdef __cplusplus +} // extern "C" +#endif +#ifdef __cplusplus +#include "WCharacter.h" +#include "WString.h" +#include "HardwareSerial.h" +uint16_t makeWord(uint16_t w); +uint16_t makeWord(byte h, + byte l); + +#define word(...) makeWord(__VA_ARGS__) + +unsigned long pulseIn(uint8_t pin, + uint8_t state, + unsigned long timeout = 1000000L); + +void tone(uint8_t _pin, + unsigned int frequency, + unsigned long duration = 0); +void noTone(uint8_t _pin); + +// WMath prototypes +long random(long); +long random(long, + long); +void randomSeed(unsigned int); +long map(long, + long, + long, + long, + long); + +#endif + +#include "pins_arduino.h" + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/HardwareSerial.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/HardwareSerial.h new file mode 100644 index 00000000..3b4f4f81 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/HardwareSerial.h @@ -0,0 +1,130 @@ +/* + HardwareSerial.h - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 28 September 2010 by Mark Sproul + Modified 14 August 2012 by Alarus +*/ + +#ifndef HardwareSerial_h +#define HardwareSerial_h + +#include + +#include "Stream.h" + +struct ring_buffer; + +class HardwareSerial:public Stream { + private: + ring_buffer * _rx_buffer; + ring_buffer *_tx_buffer; + volatile uint8_t *_ubrrh; + volatile uint8_t *_ubrrl; + volatile uint8_t *_ucsra; + volatile uint8_t *_ucsrb; + volatile uint8_t *_ucsrc; + volatile uint8_t *_udr; + uint8_t _rxen; + uint8_t _txen; + uint8_t _rxcie; + uint8_t _udrie; + uint8_t _u2x; + bool transmitting; + public: + HardwareSerial(ring_buffer * rx_buffer, + ring_buffer * tx_buffer, + volatile uint8_t * ubrrh, + volatile uint8_t * ubrrl, + volatile uint8_t * ucsra, + volatile uint8_t * ucsrb, + volatile uint8_t * ucsrc, + volatile uint8_t * udr, + uint8_t rxen, + uint8_t txen, + uint8_t rxcie, + uint8_t udrie, + uint8_t u2x); + void begin(unsigned long); + void begin(unsigned long, + uint8_t); + void end(); + virtual int available(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); + inline size_t write(unsigned long n) { + return write((uint8_t) n); + } inline size_t write(long n) { + return write((uint8_t) n); + } + inline size_t write(unsigned int n) { + return write((uint8_t) n); + } + inline size_t write(int n) { + return write((uint8_t) n); + } + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool(); +}; + +// Define config for Serial.begin(baud, config); +#define SERIAL_5N1 0x00 +#define SERIAL_6N1 0x02 +#define SERIAL_7N1 0x04 +#define SERIAL_8N1 0x06 +#define SERIAL_5N2 0x08 +#define SERIAL_6N2 0x0A +#define SERIAL_7N2 0x0C +#define SERIAL_8N2 0x0E +#define SERIAL_5E1 0x20 +#define SERIAL_6E1 0x22 +#define SERIAL_7E1 0x24 +#define SERIAL_8E1 0x26 +#define SERIAL_5E2 0x28 +#define SERIAL_6E2 0x2A +#define SERIAL_7E2 0x2C +#define SERIAL_8E2 0x2E +#define SERIAL_5O1 0x30 +#define SERIAL_6O1 0x32 +#define SERIAL_7O1 0x34 +#define SERIAL_8O1 0x36 +#define SERIAL_5O2 0x38 +#define SERIAL_6O2 0x3A +#define SERIAL_7O2 0x3C +#define SERIAL_8O2 0x3E + +#if defined(UBRRH) || defined(UBRR0H) +extern HardwareSerial Serial; +#elif defined(USBCON) +#include "USBAPI.h" +// extern HardwareSerial Serial_; +#endif +#if defined(UBRR1H) +extern HardwareSerial Serial1; +#endif +#if defined(UBRR2H) +extern HardwareSerial Serial2; +#endif +#if defined(UBRR3H) +extern HardwareSerial Serial3; +#endif + +extern void serialEventRun(void) __attribute__ ((weak)); + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Server.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Server.h new file mode 100644 index 00000000..976000b3 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Server.h @@ -0,0 +1,9 @@ +#ifndef server_h +#define server_h + +class Server:public Print { + public: + virtual void begin() = 0; +}; + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/USBAPI.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/USBAPI.h new file mode 100644 index 00000000..b0863155 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/USBAPI.h @@ -0,0 +1,202 @@ + + +#ifndef __USBAPI__ +#define __USBAPI__ + +#if defined(USBCON) + +//================================================================================ +//================================================================================ +// USB + +class USBDevice_ { + public: + USBDevice_(); + bool configured(); + + void attach(); + void detach(); // Serial port goes down too... + void poll(); +}; +extern USBDevice_ USBDevice; + +//================================================================================ +//================================================================================ +// Serial over CDC (Serial1 is the physical port) + +class Serial_:public Stream { + private: + ring_buffer * _cdc_rx_buffer; + public: + void begin(uint16_t baud_count); + void end(void); + + virtual int available(void); + virtual void accept(void); + virtual int peek(void); + virtual int read(void); + virtual void flush(void); + virtual size_t write(uint8_t); + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool(); +}; +extern Serial_ Serial; + +//================================================================================ +//================================================================================ +// Mouse + +#define MOUSE_LEFT 1 +#define MOUSE_RIGHT 2 +#define MOUSE_MIDDLE 4 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + +class Mouse_ { + private: + uint8_t _buttons; + void buttons(uint8_t b); + public: + Mouse_(void); + void begin(void); + void end(void); + void click(uint8_t b = MOUSE_LEFT); + void move(signed char x, + signed char y, + signed char wheel = 0); + void press(uint8_t b = MOUSE_LEFT); // press LEFT by default + void release(uint8_t b = MOUSE_LEFT); // release LEFT by default + bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default +}; +extern Mouse_ Mouse; + +//================================================================================ +//================================================================================ +// Keyboard + +#define KEY_LEFT_CTRL 0x80 +#define KEY_LEFT_SHIFT 0x81 +#define KEY_LEFT_ALT 0x82 +#define KEY_LEFT_GUI 0x83 +#define KEY_RIGHT_CTRL 0x84 +#define KEY_RIGHT_SHIFT 0x85 +#define KEY_RIGHT_ALT 0x86 +#define KEY_RIGHT_GUI 0x87 + +#define KEY_UP_ARROW 0xDA +#define KEY_DOWN_ARROW 0xD9 +#define KEY_LEFT_ARROW 0xD8 +#define KEY_RIGHT_ARROW 0xD7 +#define KEY_BACKSPACE 0xB2 +#define KEY_TAB 0xB3 +#define KEY_RETURN 0xB0 +#define KEY_ESC 0xB1 +#define KEY_INSERT 0xD1 +#define KEY_DELETE 0xD4 +#define KEY_PAGE_UP 0xD3 +#define KEY_PAGE_DOWN 0xD6 +#define KEY_HOME 0xD2 +#define KEY_END 0xD5 +#define KEY_CAPS_LOCK 0xC1 +#define KEY_F1 0xC2 +#define KEY_F2 0xC3 +#define KEY_F3 0xC4 +#define KEY_F4 0xC5 +#define KEY_F5 0xC6 +#define KEY_F6 0xC7 +#define KEY_F7 0xC8 +#define KEY_F8 0xC9 +#define KEY_F9 0xCA +#define KEY_F10 0xCB +#define KEY_F11 0xCC +#define KEY_F12 0xCD + +// Low level key report: up to 6 keys and shift, ctrl etc at once +typedef struct { + uint8_t modifiers; + uint8_t reserved; + uint8_t keys[6]; +} KeyReport; + +class Keyboard_:public Print { + private: + KeyReport _keyReport; + void sendReport(KeyReport * keys); + public: + Keyboard_(void); + void begin(void); + void end(void); + virtual size_t write(uint8_t k); + virtual size_t press(uint8_t k); + virtual size_t release(uint8_t k); + virtual void releaseAll(void); +}; +extern Keyboard_ Keyboard; + +//================================================================================ +//================================================================================ +// Low level API + +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + uint8_t wValueL; + uint8_t wValueH; + uint16_t wIndex; + uint16_t wLength; +} Setup; + +//================================================================================ +//================================================================================ +// HID 'Driver' + +int HID_GetInterface(uint8_t * interfaceNum); +int HID_GetDescriptor(int i); +bool HID_Setup(Setup & setup); +void HID_SendReport(uint8_t id, + const void *data, + int len); + +//================================================================================ +//================================================================================ +// MSC 'Driver' + +int MSC_GetInterface(uint8_t * interfaceNum); +int MSC_GetDescriptor(int i); +bool MSC_Setup(Setup & setup); +bool MSC_Data(uint8_t rx, + uint8_t tx); + +//================================================================================ +//================================================================================ +// CSC 'Driver' + +int CDC_GetInterface(uint8_t * interfaceNum); +int CDC_GetDescriptor(int i); +bool CDC_Setup(Setup & setup); + +//================================================================================ +//================================================================================ + +#define TRANSFER_PGM 0x80 +#define TRANSFER_RELEASE 0x40 +#define TRANSFER_ZERO 0x20 + +int USB_SendControl(uint8_t flags, + const void *d, + int len); +int USB_RecvControl(void *d, + int len); + +uint8_t USB_Available(uint8_t ep); +int USB_Send(uint8_t ep, + const void *data, + int len); // blocking +int USB_Recv(uint8_t ep, + void *data, + int len); // non-blocking +int USB_Recv(uint8_t ep); // non-blocking +void USB_Flush(uint8_t ep); + +#endif + +#endif /* if defined(USBCON) */ diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/USBCore.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/USBCore.h new file mode 100644 index 00000000..d2ecaab7 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/USBCore.h @@ -0,0 +1,292 @@ + +// Copyright (c) 2010, Peter Barrett +/* +** Permission to use, copy, modify, and/or distribute this software for +** any purpose with or without fee is hereby granted, provided that the +** above copyright notice and this permission notice appear in all copies. +** +** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR +** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +** SOFTWARE. +*/ + +#ifndef __USBCORE_H__ +#define __USBCORE_H__ + +// Standard requests +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define SET_DESCRIPTOR 7 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 + + +// bmRequestType +#define REQUEST_HOSTTODEVICE 0x00 +#define REQUEST_DEVICETOHOST 0x80 +#define REQUEST_DIRECTION 0x80 + +#define REQUEST_STANDARD 0x00 +#define REQUEST_CLASS 0x20 +#define REQUEST_VENDOR 0x40 +#define REQUEST_TYPE 0x60 + +#define REQUEST_DEVICE 0x00 +#define REQUEST_INTERFACE 0x01 +#define REQUEST_ENDPOINT 0x02 +#define REQUEST_OTHER 0x03 +#define REQUEST_RECIPIENT 0x03 + +#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST + REQUEST_CLASS + REQUEST_INTERFACE) +#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE + REQUEST_CLASS + REQUEST_INTERFACE) + +// Class requests + +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 + +#define MSC_RESET 0xFF +#define MSC_GET_MAX_LUN 0xFE + +#define HID_GET_REPORT 0x01 +#define HID_GET_IDLE 0x02 +#define HID_GET_PROTOCOL 0x03 +#define HID_SET_REPORT 0x09 +#define HID_SET_IDLE 0x0A +#define HID_SET_PROTOCOL 0x0B + +// Descriptors + +#define USB_DEVICE_DESC_SIZE 18 +#define USB_CONFIGUARTION_DESC_SIZE 9 +#define USB_INTERFACE_DESC_SIZE 9 +#define USB_ENDPOINT_DESC_SIZE 7 + +#define USB_DEVICE_DESCRIPTOR_TYPE 1 +#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 +#define USB_STRING_DESCRIPTOR_TYPE 3 +#define USB_INTERFACE_DESCRIPTOR_TYPE 4 +#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 + +#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 +#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 +#define USB_DEVICE_CLASS_STORAGE 0x08 +#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF + +#define USB_CONFIG_POWERED_MASK 0x40 +#define USB_CONFIG_BUS_POWERED 0x80 +#define USB_CONFIG_SELF_POWERED 0xC0 +#define USB_CONFIG_REMOTE_WAKEUP 0x20 + +// bMaxPower in Configuration Descriptor +#define USB_CONFIG_POWER_MA(mA) ((mA)/2) + +// bEndpointAddress in Endpoint Descriptor +#define USB_ENDPOINT_DIRECTION_MASK 0x80 +#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) +#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) + +#define USB_ENDPOINT_TYPE_MASK 0x03 +#define USB_ENDPOINT_TYPE_CONTROL 0x00 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_TYPE_BULK 0x02 +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 + +#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF) + +#define CDC_V1_10 0x0110 +#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02 + +#define CDC_CALL_MANAGEMENT 0x01 +#define CDC_ABSTRACT_CONTROL_MODEL 0x02 +#define CDC_HEADER 0x00 +#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02 +#define CDC_UNION 0x06 +#define CDC_CS_INTERFACE 0x24 +#define CDC_CS_ENDPOINT 0x25 +#define CDC_DATA_INTERFACE_CLASS 0x0A + +#define MSC_SUBCLASS_SCSI 0x06 +#define MSC_PROTOCOL_BULK_ONLY 0x50 + +#define HID_HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESCRIPTOR_TYPE 0x22 +#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 + + +// Device +typedef struct { + u8 len; // 18 + u8 dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE + u16 usbVersion; // 0x200 + u8 deviceClass; + u8 deviceSubClass; + u8 deviceProtocol; + u8 packetSize0; // Packet 0 + u16 idVendor; + u16 idProduct; + u16 deviceVersion; // 0x100 + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +} DeviceDescriptor; + +// Config +typedef struct { + u8 len; // 9 + u8 dtype; // 2 + u16 clen; // total length + u8 numInterfaces; + u8 config; + u8 iconfig; + u8 attributes; + u8 maxPower; +} ConfigDescriptor; + +// String + +// Interface +typedef struct { + u8 len; // 9 + u8 dtype; // 4 + u8 number; + u8 alternate; + u8 numEndpoints; + u8 interfaceClass; + u8 interfaceSubClass; + u8 protocol; + u8 iInterface; +} InterfaceDescriptor; + +// Endpoint +typedef struct { + u8 len; // 7 + u8 dtype; // 5 + u8 addr; + u8 attr; + u16 packetSize; + u8 interval; +} EndpointDescriptor; + +// Interface Association Descriptor +// Used to bind 2 interfaces together in CDC compostite device +typedef struct { + u8 len; // 8 + u8 dtype; // 11 + u8 firstInterface; + u8 interfaceCount; + u8 functionClass; + u8 funtionSubClass; + u8 functionProtocol; + u8 iInterface; +} IADDescriptor; + +// CDC CS interface descriptor +typedef struct { + u8 len; // 5 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; + u8 d1; +} CDCCSInterfaceDescriptor; + +typedef struct { + u8 len; // 4 + u8 dtype; // 0x24 + u8 subtype; + u8 d0; +} CDCCSInterfaceDescriptor4; + +typedef struct { + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; + u8 bDataInterface; +} CMFunctionalDescriptor; + +typedef struct { + u8 len; + u8 dtype; // 0x24 + u8 subtype; // 1 + u8 bmCapabilities; +} ACMFunctionalDescriptor; + +typedef struct { + // IAD + IADDescriptor iad; // Only needed on compound device + + // Control + InterfaceDescriptor cif; // + CDCCSInterfaceDescriptor header; + CMFunctionalDescriptor callManagement; // Call Management + ACMFunctionalDescriptor controlManagement; // ACM + CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION + EndpointDescriptor cifin; + + // Data + InterfaceDescriptor dif; + EndpointDescriptor in; + EndpointDescriptor out; +} CDCDescriptor; + +typedef struct { + InterfaceDescriptor msc; + EndpointDescriptor in; + EndpointDescriptor out; +} MSCDescriptor; + +typedef struct { + u8 len; // 9 + u8 dtype; // 0x21 + u8 addr; + u8 versionL; // 0x101 + u8 versionH; // 0x101 + u8 country; + u8 desctype; // 0x22 report + u8 descLenL; + u8 descLenH; +} HIDDescDescriptor; + +typedef struct { + InterfaceDescriptor hid; + HIDDescDescriptor desc; + EndpointDescriptor in; +} HIDDescriptor; + + +#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \ + { 18, 1, 0x200, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs } + +#define D_CONFIG(_totalLength,_interfaces) \ + { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED, USB_CONFIG_POWER_MA(500) } + +#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \ + { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 } + +#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \ + { 7, 5, _addr,_attr,_packetSize, _interval } + +#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \ + { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 } + +#define D_HIDREPORT(_descriptorLength) \ + { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } + +#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 } +#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 } + + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Udp.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Udp.h new file mode 100644 index 00000000..2840a4ab --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/Udp.h @@ -0,0 +1,95 @@ +/* + * Udp.cpp: Library to send/receive UDP packets. + * + * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) + * 1) UDP does not guarantee the order in which assembled UDP packets are received. This + * might not happen often in practice, but in larger network topologies, a UDP + * packet can be received out of sequence. + * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being + * aware of it. Again, this may not be a concern in practice on small local networks. + * For more information, see http://www.cafeaulait.org/course/week12/35.html + * + * MIT License: + * Copyright (c) 2008 Bjoern Hartmann + * 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. + * + * bjoern@cs.stanford.edu 12/30/2008 + */ + +#ifndef udp_h +#define udp_h + +#include +#include + +class UDP:public Stream { + + public: + virtual uint8_t begin(uint16_t) = 0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop() = 0; // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, + uint16_t port) = 0; + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, + uint16_t port) = 0; + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket() = 0; + // Write a single byte into the packet + virtual size_t write(uint8_t) = 0; + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t * buffer, + size_t size) = 0; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket() = 0; + // Number of bytes remaining in the current packet + virtual int available() = 0; + // Read a single byte from the current packet + virtual int read() = 0; + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char *buffer, + size_t len) = 0; + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char *buffer, + size_t len) = 0; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek() = 0; + virtual void flush() = 0; // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() = 0; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() = 0; + protected: + uint8_t * rawIPAddress(IPAddress & addr) { + return addr.raw_address(); + }; +}; + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/binary.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/binary.h new file mode 100644 index 00000000..815a0daa --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/binary.h @@ -0,0 +1,515 @@ +#ifndef Binary_h +#define Binary_h + +#define B0 0 +#define B00 0 +#define B000 0 +#define B0000 0 +#define B00000 0 +#define B000000 0 +#define B0000000 0 +#define B00000000 0 +#define B1 1 +#define B01 1 +#define B001 1 +#define B0001 1 +#define B00001 1 +#define B000001 1 +#define B0000001 1 +#define B00000001 1 +#define B10 2 +#define B010 2 +#define B0010 2 +#define B00010 2 +#define B000010 2 +#define B0000010 2 +#define B00000010 2 +#define B11 3 +#define B011 3 +#define B0011 3 +#define B00011 3 +#define B000011 3 +#define B0000011 3 +#define B00000011 3 +#define B100 4 +#define B0100 4 +#define B00100 4 +#define B000100 4 +#define B0000100 4 +#define B00000100 4 +#define B101 5 +#define B0101 5 +#define B00101 5 +#define B000101 5 +#define B0000101 5 +#define B00000101 5 +#define B110 6 +#define B0110 6 +#define B00110 6 +#define B000110 6 +#define B0000110 6 +#define B00000110 6 +#define B111 7 +#define B0111 7 +#define B00111 7 +#define B000111 7 +#define B0000111 7 +#define B00000111 7 +#define B1000 8 +#define B01000 8 +#define B001000 8 +#define B0001000 8 +#define B00001000 8 +#define B1001 9 +#define B01001 9 +#define B001001 9 +#define B0001001 9 +#define B00001001 9 +#define B1010 10 +#define B01010 10 +#define B001010 10 +#define B0001010 10 +#define B00001010 10 +#define B1011 11 +#define B01011 11 +#define B001011 11 +#define B0001011 11 +#define B00001011 11 +#define B1100 12 +#define B01100 12 +#define B001100 12 +#define B0001100 12 +#define B00001100 12 +#define B1101 13 +#define B01101 13 +#define B001101 13 +#define B0001101 13 +#define B00001101 13 +#define B1110 14 +#define B01110 14 +#define B001110 14 +#define B0001110 14 +#define B00001110 14 +#define B1111 15 +#define B01111 15 +#define B001111 15 +#define B0001111 15 +#define B00001111 15 +#define B10000 16 +#define B010000 16 +#define B0010000 16 +#define B00010000 16 +#define B10001 17 +#define B010001 17 +#define B0010001 17 +#define B00010001 17 +#define B10010 18 +#define B010010 18 +#define B0010010 18 +#define B00010010 18 +#define B10011 19 +#define B010011 19 +#define B0010011 19 +#define B00010011 19 +#define B10100 20 +#define B010100 20 +#define B0010100 20 +#define B00010100 20 +#define B10101 21 +#define B010101 21 +#define B0010101 21 +#define B00010101 21 +#define B10110 22 +#define B010110 22 +#define B0010110 22 +#define B00010110 22 +#define B10111 23 +#define B010111 23 +#define B0010111 23 +#define B00010111 23 +#define B11000 24 +#define B011000 24 +#define B0011000 24 +#define B00011000 24 +#define B11001 25 +#define B011001 25 +#define B0011001 25 +#define B00011001 25 +#define B11010 26 +#define B011010 26 +#define B0011010 26 +#define B00011010 26 +#define B11011 27 +#define B011011 27 +#define B0011011 27 +#define B00011011 27 +#define B11100 28 +#define B011100 28 +#define B0011100 28 +#define B00011100 28 +#define B11101 29 +#define B011101 29 +#define B0011101 29 +#define B00011101 29 +#define B11110 30 +#define B011110 30 +#define B0011110 30 +#define B00011110 30 +#define B11111 31 +#define B011111 31 +#define B0011111 31 +#define B00011111 31 +#define B100000 32 +#define B0100000 32 +#define B00100000 32 +#define B100001 33 +#define B0100001 33 +#define B00100001 33 +#define B100010 34 +#define B0100010 34 +#define B00100010 34 +#define B100011 35 +#define B0100011 35 +#define B00100011 35 +#define B100100 36 +#define B0100100 36 +#define B00100100 36 +#define B100101 37 +#define B0100101 37 +#define B00100101 37 +#define B100110 38 +#define B0100110 38 +#define B00100110 38 +#define B100111 39 +#define B0100111 39 +#define B00100111 39 +#define B101000 40 +#define B0101000 40 +#define B00101000 40 +#define B101001 41 +#define B0101001 41 +#define B00101001 41 +#define B101010 42 +#define B0101010 42 +#define B00101010 42 +#define B101011 43 +#define B0101011 43 +#define B00101011 43 +#define B101100 44 +#define B0101100 44 +#define B00101100 44 +#define B101101 45 +#define B0101101 45 +#define B00101101 45 +#define B101110 46 +#define B0101110 46 +#define B00101110 46 +#define B101111 47 +#define B0101111 47 +#define B00101111 47 +#define B110000 48 +#define B0110000 48 +#define B00110000 48 +#define B110001 49 +#define B0110001 49 +#define B00110001 49 +#define B110010 50 +#define B0110010 50 +#define B00110010 50 +#define B110011 51 +#define B0110011 51 +#define B00110011 51 +#define B110100 52 +#define B0110100 52 +#define B00110100 52 +#define B110101 53 +#define B0110101 53 +#define B00110101 53 +#define B110110 54 +#define B0110110 54 +#define B00110110 54 +#define B110111 55 +#define B0110111 55 +#define B00110111 55 +#define B111000 56 +#define B0111000 56 +#define B00111000 56 +#define B111001 57 +#define B0111001 57 +#define B00111001 57 +#define B111010 58 +#define B0111010 58 +#define B00111010 58 +#define B111011 59 +#define B0111011 59 +#define B00111011 59 +#define B111100 60 +#define B0111100 60 +#define B00111100 60 +#define B111101 61 +#define B0111101 61 +#define B00111101 61 +#define B111110 62 +#define B0111110 62 +#define B00111110 62 +#define B111111 63 +#define B0111111 63 +#define B00111111 63 +#define B1000000 64 +#define B01000000 64 +#define B1000001 65 +#define B01000001 65 +#define B1000010 66 +#define B01000010 66 +#define B1000011 67 +#define B01000011 67 +#define B1000100 68 +#define B01000100 68 +#define B1000101 69 +#define B01000101 69 +#define B1000110 70 +#define B01000110 70 +#define B1000111 71 +#define B01000111 71 +#define B1001000 72 +#define B01001000 72 +#define B1001001 73 +#define B01001001 73 +#define B1001010 74 +#define B01001010 74 +#define B1001011 75 +#define B01001011 75 +#define B1001100 76 +#define B01001100 76 +#define B1001101 77 +#define B01001101 77 +#define B1001110 78 +#define B01001110 78 +#define B1001111 79 +#define B01001111 79 +#define B1010000 80 +#define B01010000 80 +#define B1010001 81 +#define B01010001 81 +#define B1010010 82 +#define B01010010 82 +#define B1010011 83 +#define B01010011 83 +#define B1010100 84 +#define B01010100 84 +#define B1010101 85 +#define B01010101 85 +#define B1010110 86 +#define B01010110 86 +#define B1010111 87 +#define B01010111 87 +#define B1011000 88 +#define B01011000 88 +#define B1011001 89 +#define B01011001 89 +#define B1011010 90 +#define B01011010 90 +#define B1011011 91 +#define B01011011 91 +#define B1011100 92 +#define B01011100 92 +#define B1011101 93 +#define B01011101 93 +#define B1011110 94 +#define B01011110 94 +#define B1011111 95 +#define B01011111 95 +#define B1100000 96 +#define B01100000 96 +#define B1100001 97 +#define B01100001 97 +#define B1100010 98 +#define B01100010 98 +#define B1100011 99 +#define B01100011 99 +#define B1100100 100 +#define B01100100 100 +#define B1100101 101 +#define B01100101 101 +#define B1100110 102 +#define B01100110 102 +#define B1100111 103 +#define B01100111 103 +#define B1101000 104 +#define B01101000 104 +#define B1101001 105 +#define B01101001 105 +#define B1101010 106 +#define B01101010 106 +#define B1101011 107 +#define B01101011 107 +#define B1101100 108 +#define B01101100 108 +#define B1101101 109 +#define B01101101 109 +#define B1101110 110 +#define B01101110 110 +#define B1101111 111 +#define B01101111 111 +#define B1110000 112 +#define B01110000 112 +#define B1110001 113 +#define B01110001 113 +#define B1110010 114 +#define B01110010 114 +#define B1110011 115 +#define B01110011 115 +#define B1110100 116 +#define B01110100 116 +#define B1110101 117 +#define B01110101 117 +#define B1110110 118 +#define B01110110 118 +#define B1110111 119 +#define B01110111 119 +#define B1111000 120 +#define B01111000 120 +#define B1111001 121 +#define B01111001 121 +#define B1111010 122 +#define B01111010 122 +#define B1111011 123 +#define B01111011 123 +#define B1111100 124 +#define B01111100 124 +#define B1111101 125 +#define B01111101 125 +#define B1111110 126 +#define B01111110 126 +#define B1111111 127 +#define B01111111 127 +#define B10000000 128 +#define B10000001 129 +#define B10000010 130 +#define B10000011 131 +#define B10000100 132 +#define B10000101 133 +#define B10000110 134 +#define B10000111 135 +#define B10001000 136 +#define B10001001 137 +#define B10001010 138 +#define B10001011 139 +#define B10001100 140 +#define B10001101 141 +#define B10001110 142 +#define B10001111 143 +#define B10010000 144 +#define B10010001 145 +#define B10010010 146 +#define B10010011 147 +#define B10010100 148 +#define B10010101 149 +#define B10010110 150 +#define B10010111 151 +#define B10011000 152 +#define B10011001 153 +#define B10011010 154 +#define B10011011 155 +#define B10011100 156 +#define B10011101 157 +#define B10011110 158 +#define B10011111 159 +#define B10100000 160 +#define B10100001 161 +#define B10100010 162 +#define B10100011 163 +#define B10100100 164 +#define B10100101 165 +#define B10100110 166 +#define B10100111 167 +#define B10101000 168 +#define B10101001 169 +#define B10101010 170 +#define B10101011 171 +#define B10101100 172 +#define B10101101 173 +#define B10101110 174 +#define B10101111 175 +#define B10110000 176 +#define B10110001 177 +#define B10110010 178 +#define B10110011 179 +#define B10110100 180 +#define B10110101 181 +#define B10110110 182 +#define B10110111 183 +#define B10111000 184 +#define B10111001 185 +#define B10111010 186 +#define B10111011 187 +#define B10111100 188 +#define B10111101 189 +#define B10111110 190 +#define B10111111 191 +#define B11000000 192 +#define B11000001 193 +#define B11000010 194 +#define B11000011 195 +#define B11000100 196 +#define B11000101 197 +#define B11000110 198 +#define B11000111 199 +#define B11001000 200 +#define B11001001 201 +#define B11001010 202 +#define B11001011 203 +#define B11001100 204 +#define B11001101 205 +#define B11001110 206 +#define B11001111 207 +#define B11010000 208 +#define B11010001 209 +#define B11010010 210 +#define B11010011 211 +#define B11010100 212 +#define B11010101 213 +#define B11010110 214 +#define B11010111 215 +#define B11011000 216 +#define B11011001 217 +#define B11011010 218 +#define B11011011 219 +#define B11011100 220 +#define B11011101 221 +#define B11011110 222 +#define B11011111 223 +#define B11100000 224 +#define B11100001 225 +#define B11100010 226 +#define B11100011 227 +#define B11100100 228 +#define B11100101 229 +#define B11100110 230 +#define B11100111 231 +#define B11101000 232 +#define B11101001 233 +#define B11101010 234 +#define B11101011 235 +#define B11101100 236 +#define B11101101 237 +#define B11101110 238 +#define B11101111 239 +#define B11110000 240 +#define B11110001 241 +#define B11110010 242 +#define B11110011 243 +#define B11110100 244 +#define B11110101 245 +#define B11110110 246 +#define B11110111 247 +#define B11111000 248 +#define B11111001 249 +#define B11111010 250 +#define B11111011 251 +#define B11111100 252 +#define B11111101 253 +#define B11111110 254 +#define B11111111 255 + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/new.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/new.h new file mode 100644 index 00000000..36adefa6 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/new.h @@ -0,0 +1,21 @@ +/* Header to define new/delete operators as they aren't provided by avr-gcc by default + Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453 + */ + +#ifndef NEW_H +#define NEW_H + +#include + +void *operator new(size_t size); +void operator delete(void *ptr); + +__extension__ typedef int __guard __attribute__ ((mode(__DI__))); + +extern "C" int __cxa_guard_acquire(__guard *); +extern "C" void __cxa_guard_release(__guard *); +extern "C" void __cxa_guard_abort(__guard *); + +extern "C" void __cxa_pure_virtual(void); + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/pins_arduino.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/pins_arduino.h new file mode 100644 index 00000000..d9fe8f4b --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/pins_arduino.h @@ -0,0 +1,218 @@ +/* + pins_arduino.h - Pin definition functions for Arduino + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2007 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ +*/ + +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define NUM_DIGITAL_PINS 20 +#define NUM_ANALOG_INPUTS 6 +#define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1) + +#if defined(__AVR_ATmega8__) +#define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11) +#else +#define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) +#endif + +static const uint8_t SS = 10; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 12; +static const uint8_t SCK = 13; + +static const uint8_t SDA = 18; +static const uint8_t SCL = 19; +static const uint8_t LED_BUILTIN = 13; + +static const uint8_t A0 = 14; +static const uint8_t A1 = 15; +static const uint8_t A2 = 16; +static const uint8_t A3 = 17; +static const uint8_t A4 = 18; +static const uint8_t A5 = 19; +static const uint8_t A6 = 20; +static const uint8_t A7 = 21; + +#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0)) +#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1)) +#define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0)))) +#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14))) + +#ifdef ARDUINO_MAIN + +// On the Arduino board, digital pins are also used +// for the analog output (software PWM). Analog input +// pins are a separate set. + +// ATMEL ATMEGA8 & 168 / ARDUINO +// +// +-\/-+ +// PC6 1| |28 PC5 (AI 5) +// (D 0) PD0 2| |27 PC4 (AI 4) +// (D 1) PD1 3| |26 PC3 (AI 3) +// (D 2) PD2 4| |25 PC2 (AI 2) +// PWM+ (D 3) PD3 5| |24 PC1 (AI 1) +// (D 4) PD4 6| |23 PC0 (AI 0) +// VCC 7| |22 GND +// GND 8| |21 AREF +// PB6 9| |20 AVCC +// PB7 10| |19 PB5 (D 13) +// PWM+ (D 5) PD5 11| |18 PB4 (D 12) +// PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM +// (D 7) PD7 13| |16 PB2 (D 10) PWM +// (D 8) PB0 14| |15 PB1 (D 9) PWM +// +----+ +// +// (PWM+ indicates the additional PWM pins on the ATmega168.) + +// ATMEL ATMEGA1280 / ARDUINO +// +// 0-7 PE0-PE7 works +// 8-13 PB0-PB5 works +// 14-21 PA0-PA7 works +// 22-29 PH0-PH7 works +// 30-35 PG5-PG0 works +// 36-43 PC7-PC0 works +// 44-51 PJ7-PJ0 works +// 52-59 PL7-PL0 works +// 60-67 PD7-PD0 works +// A0-A7 PF0-PF7 +// A8-A15 PK0-PK7 + + +// these arrays map port names (e.g. port B) to the +// appropriate addresses for various functions (e.g. reading +// and writing) +const uint16_t PROGMEM port_to_mode_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) & DDRB, + (uint16_t) & DDRC, + (uint16_t) & DDRD, +}; + +const uint16_t PROGMEM port_to_output_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) & PORTB, + (uint16_t) & PORTC, + (uint16_t) & PORTD, +}; + +const uint16_t PROGMEM port_to_input_PGM[] = { + NOT_A_PORT, + NOT_A_PORT, + (uint16_t) & PINB, + (uint16_t) & PINC, + (uint16_t) & PIND, +}; + +const uint8_t PROGMEM digital_pin_to_port_PGM[] = { + PD, /* 0 */ + PD, + PD, + PD, + PD, + PD, + PD, + PD, + PB, /* 8 */ + PB, + PB, + PB, + PB, + PB, + PC, /* 14 */ + PC, + PC, + PC, + PC, + PC, +}; + +const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { + _BV(0), /* 0, port D */ + _BV(1), + _BV(2), + _BV(3), + _BV(4), + _BV(5), + _BV(6), + _BV(7), + _BV(0), /* 8, port B */ + _BV(1), + _BV(2), + _BV(3), + _BV(4), + _BV(5), + _BV(0), /* 14, port C */ + _BV(1), + _BV(2), + _BV(3), + _BV(4), + _BV(5), +}; + +const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { + NOT_ON_TIMER, /* 0 - port D */ + NOT_ON_TIMER, + NOT_ON_TIMER, + // on the ATmega168, digital pin 3 has hardware pwm +#if defined(__AVR_ATmega8__) + NOT_ON_TIMER, +#else + TIMER2B, +#endif + NOT_ON_TIMER, + // on the ATmega168, digital pins 5 and 6 have hardware pwm +#if defined(__AVR_ATmega8__) + NOT_ON_TIMER, + NOT_ON_TIMER, +#else + TIMER0B, + TIMER0A, +#endif + NOT_ON_TIMER, + NOT_ON_TIMER, /* 8 - port B */ + TIMER1A, + TIMER1B, +#if defined(__AVR_ATmega8__) + TIMER2, +#else + TIMER2A, +#endif + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, /* 14 - port C */ + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, + NOT_ON_TIMER, +}; + +#endif + +#endif diff --git a/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/wiring_private.h b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/wiring_private.h new file mode 100644 index 00000000..ec522a8c --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/external/Arduino/core/include/wiring_private.h @@ -0,0 +1,70 @@ +/* + wiring_private.h - Internal header file. + Part of Arduino - http://www.arduino.cc/ + + Copyright (c) 2005-2006 David A. Mellis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $ +*/ + +#ifndef WiringPrivate_h +#define WiringPrivate_h + +#include +#include +#include +#include + +#include "Arduino.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#define EXTERNAL_INT_0 0 +#define EXTERNAL_INT_1 1 +#define EXTERNAL_INT_2 2 +#define EXTERNAL_INT_3 3 +#define EXTERNAL_INT_4 4 +#define EXTERNAL_INT_5 5 +#define EXTERNAL_INT_6 6 +#define EXTERNAL_INT_7 7 + +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define EXTERNAL_NUM_INTERRUPTS 8 +#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) +#define EXTERNAL_NUM_INTERRUPTS 3 +#elif defined(__AVR_ATmega32U4__) +#define EXTERNAL_NUM_INTERRUPTS 4 +#else +#define EXTERNAL_NUM_INTERRUPTS 2 +#endif + + typedef void (*voidFuncPtr) (void); + +#ifdef __cplusplus +} // extern "C" +#endif +#endif diff --git a/bacnet-stack/ports/arduino_uno/h_whois.c b/bacnet-stack/ports/arduino_uno/h_whois.c new file mode 100644 index 00000000..60ad35dc --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/h_whois.c @@ -0,0 +1,97 @@ +/************************************************************************** +* +* 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. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include "config.h" +#include "txbuf.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "whois.h" +#include "iam.h" +#include "device.h" +#include "client.h" +#include "txbuf.h" + +bool Send_I_Am_Flag = true; + +void sendIamUnicast(uint8_t * buffer, + BACNET_ADDRESS * src) +{ + BACNET_ADDRESS dest; + int pdu_len = 0; + BACNET_NPDU_DATA npdu_data; + + /* encode the data */ + int npdu_len = 0; + int apdu_len = 0; + BACNET_ADDRESS my_address; + /* The destination will be the same as the src, so copy it over. */ + memcpy(&dest, src, sizeof(BACNET_ADDRESS)); + /* dest->net = 0; - no, must direct back to src->net to meet BTL tests */ + + datalink_get_my_address(&my_address); + /* encode the NPDU portion of the packet */ + npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); + npdu_len = npdu_encode_pdu(&buffer[0], &dest, &my_address, &npdu_data); + /* encode the APDU portion of the packet */ + apdu_len = + iam_encode_apdu(&buffer[npdu_len], Device_Object_Instance_Number(), + MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); + /* send data */ + pdu_len = npdu_len + apdu_len; + int bytes = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); +} + +void handler_who_is(uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src) +{ + int len = 0; + int32_t low_limit = 0; + int32_t high_limit = 0; + int32_t target_device; + + len = + whois_decode_service_request(service_request, service_len, &low_limit, + &high_limit); + if (len == 0) { + sendIamUnicast(&Handler_Transmit_Buffer[0], src); + } else if (len != -1) { + /* is my device id within the limits? */ + target_device = Device_Object_Instance_Number(); + if (((target_device >= low_limit) && (target_device <= high_limit)) + || + /* BACnet wildcard is the max instance number - everyone responds */ + ((BACNET_MAX_INSTANCE >= (uint32_t) low_limit) && + (BACNET_MAX_INSTANCE <= (uint32_t) high_limit))) { + sendIamUnicast(&Handler_Transmit_Buffer[0], src); + } + } + + return; +} diff --git a/bacnet-stack/ports/arduino_uno/h_wp.c b/bacnet-stack/ports/arduino_uno/h_wp.c new file mode 100644 index 00000000..2c9ed9ac --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/h_wp.c @@ -0,0 +1,135 @@ +/************************************************************************** +* +* 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. +* +*********************************************************************/ +#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 "wp.h" +/* demo objects */ +#include "device.h" +#include "av.h" +#include "bv.h" + +/* too big to reside on stack frame for PIC */ +static BACNET_WRITE_PROPERTY_DATA wp_data; + +void handler_write_property(uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data) +{ + int len = 0; + int pdu_len = 0; + BACNET_NPDU_DATA npdu_data; + BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; + BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; + BACNET_ADDRESS my_address; + + /* decode the service request only */ + len = wp_decode_service_request(service_request, service_len, &wp_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); + /* 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); + } else if (service_data->segmented_message) { + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); + } else { + switch (wp_data.object_type) { + case OBJECT_DEVICE: + if (Device_Write_Property(&wp_data, &error_class, &error_code)) { + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + } else { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + } + break; + case OBJECT_ANALOG_VALUE: + if (Analog_Value_Write_Property(&wp_data, &error_class, + &error_code)) { + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + } else { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + } + break; + case OBJECT_BINARY_VALUE: + if (Binary_Value_Write_Property(&wp_data, &error_class, + &error_code)) { + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + } else { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + } + break; + default: + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, + error_class, error_code); + break; + } + } + pdu_len += len; + datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); + + return; +} diff --git a/bacnet-stack/ports/arduino_uno/main.c b/bacnet-stack/ports/arduino_uno/main.c new file mode 100644 index 00000000..6911bab8 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/main.c @@ -0,0 +1,94 @@ +/** + * @file + * @author Miguel Fernandes + * @date 6 de Jun de 2013 + * @brief BACnet/IP for Wiznet on Arduino-Uno + * + * This port is for BACnet/ip and uses part of the Arduino Ethernet + * library so it needs the stock Arduino Etherenet Shield + * (the one with the W5100 chip). The port was done by writting a C + * wrapper around the c++ Ethernet library and adapting the + * existing port for Atmega168 (mainly functions bip.c and bip-init.c) + * to use the wrapper functions. The port also needs Arduino core and + * Ethernet libraries to compile. + */ +#include +#include +#include "datalink.h" +#include "npdu.h" +#include "handlers.h" +#include "txbuf.h" +#include "iam.h" +#include "device.h" +#include "av.h" +#include "uart.h" +#include "w5100Wrapper.h" +#include "Arduino.h" +#include +#define BAUD 9600 +#include + +/* From the WhoIs hander - performed by the DLMSTP module */ +extern bool Send_I_Am_Flag; +/* local version override */ +const char *BACnet_Version = "1.0"; +static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; +uint8_t ipAddress[] = { 192, 168, 0, 185 }; +uint8_t gateway[] = { 192, 168, 0, 1 }; +uint8_t netmask[] = { 255, 255, 255, 0 }; + +FILE uart_output = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); +FILE uart_input = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_READ); +FILE uart_io = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); + +/* For porting to IAR, see: + http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ + +/* dummy function - so we can use default demo handlers */ +bool dcc_communication_enabled(void) +{ + return true; +} + +void setup() +{ + //INIT W5100 + init_func(CW5100Class_new()); + setMACAddress_func(CW5100Class_new(), Ethernet_MAC_Address); + setIPAddress_func(CW5100Class_new(), ipAddress); + setGatewayIp_func(CW5100Class_new(), gateway); + setSubnetMask_func(CW5100Class_new(), netmask); + + uart_init(); + stdout = &uart_output; + stdin = &uart_input; + stderr = &uart_output; + +#ifdef DEBUG + fprintf(stderr, "Starting BACNET application..\n"); +#endif + +} + +static uint8_t PDUBuffer[MAX_MPDU]; +int main(void) +{ + uint16_t pdu_len = 0; + BACNET_ADDRESS src; /* source address */ + + init(); + + setup(); + + datalink_init(NULL); + for (;;) { + + /* other tasks */ + /* BACnet handling */ + pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); + if (pdu_len) { + npdu_handler(&src, &PDUBuffer[0], pdu_len); + } + } +} diff --git a/bacnet-stack/ports/arduino_uno/stdbool.h b/bacnet-stack/ports/arduino_uno/stdbool.h new file mode 100644 index 00000000..80e1ee96 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/stdbool.h @@ -0,0 +1,28 @@ +#ifndef STDBOOL_H +#define STDBOOL_H + +/* C99 Boolean types for compilers without C99 support */ + +#ifndef __cplusplus +/* typedef char _Bool; */ +#ifndef bool +#define bool _Bool +#endif +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif +#define __bool_true_false_are_defined 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#endif diff --git a/bacnet-stack/ports/arduino_uno/stdint.h b/bacnet-stack/ports/arduino_uno/stdint.h new file mode 100644 index 00000000..93556b05 --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/stdint.h @@ -0,0 +1,15 @@ +/* Defines the standard integer types that are used in code */ + +#ifndef STDINT_H +#define STDINT_H 1 + +#include + +typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ +typedef signed char int8_t; /* 1 byte -127 to 127 */ +typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ +typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ +typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ +typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ + +#endif /* STDINT_H */ diff --git a/bacnet-stack/ports/arduino_uno/txbuf.h b/bacnet-stack/ports/arduino_uno/txbuf.h new file mode 100644 index 00000000..c23f629f --- /dev/null +++ b/bacnet-stack/ports/arduino_uno/txbuf.h @@ -0,0 +1,35 @@ +/************************************************************************** +* +* 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. +* +*********************************************************************/ +#ifndef TXBUF_H +#define TXBUF_H + +#include +#include +#include "config.h" +#include "datalink.h" + +extern uint8_t Handler_Transmit_Buffer[MAX_PDU]; + +#endif