Issue 2 move folders and use deep path include file names to prevent collisions (#4)
* moving folders and files and adjust server demo build * Fix Makefile for apps/server on Linux * fix unit test source file folders * fix datetime convert UTC functions. Add Code::Blocks project for datetime testing * added some ignore extensions * disable parallel make option * fix build for abort, dcc, and epics apps * fix build for dcc, epics, error, and getevent apps. * Fixed building of all apps * fix the ipv4 to ipv6 router app build * Change indent style from Google to Webkit * make pretty to re-format style * removed common Makefile since we already had one and two was too many * remove scripts from root folder that are no longer maintained or used * remove mercurial EOL and ignore files for git repo * remove .vscodeconfig files from repo * tweak clang-format style * clang-format src and apps with tweaked style * added clang-tidy to fix readability if braces in src * result of make tidy for src and apps * fix clang-tidy mangling * Added code::blocks project for BACnet server simulation * added code::blocks linux project for WhoIs app * update text files for EOL * fix EOL in some files * fixed make win32 apps for older gcc * Removed Borland C++ Makefile in apps. Unable to maintain support for Borland C++ compiler. * created codeblocks project for apps/epics for Windows * fixing ports/xplained to work with new data structure. * fix ports/xplained example for Atmel Studio compile * fix ports/stm32f10x example for gcc Makefile compile * fix ports/stm32f10x example for IAR EWARM compile * fix ports/xplained timer callback * fix ports/bdk_atxx_mspt build with subdirs * fix ports/bdk_atxx_mspt build with subdirs * updated git ignore for IAR build artifacts * updated gitignore for non-tracked files and folders * fixed bdk-atxx4-mstp port for Rowley Crossworks project file * fixed bdk-atxx4-mstp port for GCC AVR Makefile * fixed atmega168 port for IAR AVR and GCC AVR Makefile * fixed at91sam7s port for IAR ARM and GCC ARM Makefile * removed unmaintainable DOS, RTOS32, and atmega8 ports. Updated rx62n (untested). * changed arm7 to uip port
This commit is contained in:
@@ -34,12 +34,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "bits.h"
|
||||
#include "apdu.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bits.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
|
||||
{
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "bacapp.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "wp.h"
|
||||
#include "av.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
|
||||
#if (MAX_ANALOG_VALUES > 10)
|
||||
#error Modify the Analog_Value_Name to handle multiple digits
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacerror.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
#ifndef MAX_ANALOG_VALUES
|
||||
#define MAX_ANALOG_VALUES 4
|
||||
|
||||
@@ -35,11 +35,11 @@
|
||||
#include <stdint.h> /* for standard integer types uint8_t etc. */
|
||||
#include <stdbool.h> /* for the standard bool type. */
|
||||
#include <stdio.h>
|
||||
#include "bacdcode.h"
|
||||
#include "bip.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/datalink/bip.h"
|
||||
#include "socketWrapper.h"
|
||||
#include "w5100Wrapper.h"
|
||||
//#include "net.h"
|
||||
//#include "bacport.h"
|
||||
|
||||
/** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
#include <stdint.h> /* for standard integer types uint8_t etc. */
|
||||
#include <stdbool.h> /* for the standard bool type. */
|
||||
#include <string.h>
|
||||
#include "bacdcode.h"
|
||||
#include "bacint.h"
|
||||
#include "bip.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacint.h"
|
||||
#include "bacnet/datalink/bip.h"
|
||||
#include "bvlc-arduino.h"
|
||||
#include "socketWrapper.h"
|
||||
#include "w5100Wrapper.h"
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "bacdef.h"
|
||||
#include "npdu.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/npdu.h"
|
||||
|
||||
/* specific defines for BACnet/IP over Ethernet */
|
||||
#define MAX_HEADER (1 + 1 + 2)
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "wp.h"
|
||||
#include "bv.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
|
||||
#if (MAX_BINARY_VALUES > 10)
|
||||
#error Modify the Binary_Value_Name to handle multiple digits
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacerror.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
#ifndef MAX_BINARY_VALUES
|
||||
#define MAX_BINARY_VALUES 10
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "bvlc-arduino.h"
|
||||
#include "bip.h"
|
||||
#include "bacint.h"
|
||||
#include "bacnet/datalink/bip.h"
|
||||
#include "bacnet/bacint.h"
|
||||
#include "socketWrapper.h"
|
||||
#include "w5100Wrapper.h"
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
#define BVLCARDUINO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bacenum.h"
|
||||
#include "bacdef.h"
|
||||
#include "npdu.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/npdu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
#ifndef DATALINK_H
|
||||
#define DATALINK_H
|
||||
|
||||
#include "config.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
|
||||
#if defined(BACDL_ETHERNET)
|
||||
#include "ethernet.h"
|
||||
#include "bacnet/datalink/ethernet.h"
|
||||
|
||||
#define datalink_init ethernet_init
|
||||
#define datalink_send_pdu ethernet_send_pdu
|
||||
@@ -38,7 +38,7 @@
|
||||
#define datalink_get_my_address ethernet_get_my_address
|
||||
|
||||
#elif defined(BACDL_ARCNET)
|
||||
#include "arcnet.h"
|
||||
#include "bacnet/datalink/arcnet.h"
|
||||
|
||||
#define datalink_init arcnet_init
|
||||
#define datalink_send_pdu arcnet_send_pdu
|
||||
@@ -48,7 +48,7 @@
|
||||
#define datalink_get_my_address arcnet_get_my_address
|
||||
|
||||
#elif defined(BACDL_MSTP)
|
||||
#include "dlmstp.h"
|
||||
#include "bacnet/datalink/dlmstp.h"
|
||||
|
||||
#define datalink_init dlmstp_init
|
||||
#define datalink_send_pdu dlmstp_send_pdu
|
||||
@@ -58,7 +58,7 @@
|
||||
#define datalink_get_my_address dlmstp_get_my_address
|
||||
|
||||
#elif defined(BACDL_BIP)
|
||||
#include "bip.h"
|
||||
#include "bacnet/datalink/bip.h"
|
||||
#include "bvlc-arduino.h"
|
||||
|
||||
#define datalink_init bip_init
|
||||
@@ -79,7 +79,7 @@ extern void routed_get_my_address(BACNET_ADDRESS * my_address);
|
||||
#endif
|
||||
|
||||
#else /* Ie, BACDL_ALL */
|
||||
#include "npdu.h"
|
||||
#include "bacnet/npdu.h"
|
||||
|
||||
#define MAX_HEADER (8)
|
||||
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
|
||||
|
||||
+12
-12
@@ -25,20 +25,20 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacstr.h"
|
||||
#include "bacenum.h"
|
||||
#include "apdu.h"
|
||||
#include "dcc.h"
|
||||
#include "dlmstp.h"
|
||||
#include "version.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacstr.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/datalink/dlmstp.h"
|
||||
#include "bacnet/version.h"
|
||||
|
||||
/* objects */
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bv.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
/* note: you really only need to define variables for
|
||||
properties that are writable or that may change.
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacenum.h"
|
||||
#include "wp.h"
|
||||
#include "readrange.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/readrange.h"
|
||||
|
||||
typedef unsigned (*object_count_function) (void);
|
||||
typedef uint32_t(*object_index_to_instance_function)
|
||||
|
||||
+11
-11
@@ -27,19 +27,19 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "config.h"
|
||||
#include "txbuf.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacerror.h"
|
||||
#include "apdu.h"
|
||||
#include "npdu.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "abort.h"
|
||||
#include "rp.h"
|
||||
#include "bacnet/rp.h"
|
||||
/* demo objects */
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bv.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
|
||||
/* Encodes the property APDU and returns the length,
|
||||
or sets the error, and returns -1 */
|
||||
|
||||
@@ -27,15 +27,15 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/whois.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
|
||||
bool Send_I_Am_Flag = true;
|
||||
|
||||
|
||||
+11
-11
@@ -27,19 +27,19 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "config.h"
|
||||
#include "txbuf.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacerror.h"
|
||||
#include "apdu.h"
|
||||
#include "npdu.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "abort.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/wp.h"
|
||||
/* demo objects */
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bv.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
|
||||
/* too big to reside on stack frame for PIC */
|
||||
static BACNET_WRITE_PROPERTY_DATA wp_data;
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "datalink.h"
|
||||
#include "npdu.h"
|
||||
#include "handlers.h"
|
||||
#include "txbuf.h"
|
||||
#include "iam.h"
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "uart.h"
|
||||
#include "w5100Wrapper.h"
|
||||
#include "Arduino.h"
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "config.h"
|
||||
#include "datalink.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
|
||||
extern uint8_t Handler_Transmit_Buffer[MAX_PDU];
|
||||
|
||||
|
||||
+16
-16
@@ -1,16 +1,16 @@
|
||||
# gdb setup for J-Link - start JLinkGDBServer first
|
||||
target remote localhost:2331
|
||||
monitor reset
|
||||
monitor speed 5
|
||||
monitor speed auto
|
||||
monitor long 0xffffff60 0x00320100
|
||||
monitor long 0xfffffd44 0xa0008000
|
||||
monitor long 0xfffffc20 0xa0000601
|
||||
monitor sleep 100
|
||||
monitor long 0xfffffc2c 0x00480a0e
|
||||
monitor sleep 200
|
||||
monitor long 0xfffffc30 0x7
|
||||
monitor sleep 100
|
||||
monitor long 0xfffffd08 0xa5000401
|
||||
monitor sleep 100
|
||||
|
||||
# gdb setup for J-Link - start JLinkGDBServer first
|
||||
target remote localhost:2331
|
||||
monitor reset
|
||||
monitor speed 5
|
||||
monitor speed auto
|
||||
monitor long 0xffffff60 0x00320100
|
||||
monitor long 0xfffffd44 0xa0008000
|
||||
monitor long 0xfffffc20 0xa0000601
|
||||
monitor sleep 100
|
||||
monitor long 0xfffffc2c 0x00480a0e
|
||||
monitor sleep 200
|
||||
monitor long 0xfffffc30 0x7
|
||||
monitor sleep 100
|
||||
monitor long 0xfffffd08 0xa5000401
|
||||
monitor sleep 100
|
||||
|
||||
|
||||
+17
-19
@@ -25,10 +25,8 @@ BACNET_FLAGS += -DCRC_USE_TABLE
|
||||
#BACNET_FLAGS += -DDLMSTP_TEST
|
||||
|
||||
BACNET_CORE = ../../src
|
||||
BACNET_DEMO = ../../demo
|
||||
BACNET_INCLUDE = ../../include
|
||||
BACNET_OBJECT = ../../demo/object
|
||||
BACNET_HANDLER = ../../demo/handler
|
||||
BACNET_BASIC = $(BACNET_CORE)/basic
|
||||
BACNET_INCLUDE = $(BACNET_CORE)
|
||||
INCLUDES = -I.
|
||||
INCLUDES += -I$(BACNET_INCLUDE)
|
||||
INCLUDES += -I$(BACNET_OBJECT)
|
||||
@@ -66,21 +64,22 @@ DEMOSRC = ai.c \
|
||||
bi.c \
|
||||
bv.c \
|
||||
device.c \
|
||||
$(BACNET_DEMO)/handler/txbuf.c \
|
||||
$(BACNET_DEMO)/handler/noserv.c \
|
||||
$(BACNET_DEMO)/handler/h_npdu.c \
|
||||
$(BACNET_DEMO)/handler/h_whohas.c \
|
||||
$(BACNET_DEMO)/handler/h_whois.c \
|
||||
$(BACNET_DEMO)/handler/h_rd.c \
|
||||
$(BACNET_DEMO)/handler/h_rp.c \
|
||||
$(BACNET_DEMO)/handler/h_rpm.c \
|
||||
$(BACNET_DEMO)/handler/h_wp.c \
|
||||
$(BACNET_DEMO)/handler/h_dcc.c \
|
||||
$(BACNET_DEMO)/handler/s_iam.c \
|
||||
$(BACNET_DEMO)/handler/s_ihave.c
|
||||
$(BACNET_BASIC)/tsm/tsm.c \
|
||||
$(BACNET_BASIC)/sys/ringbuf.c \
|
||||
$(BACNET_BASIC)/npdu/h_npdu.c \
|
||||
$(BACNET_BASIC)/service/h_noserv.c \
|
||||
$(BACNET_BASIC)/service/h_apdu.c \
|
||||
$(BACNET_BASIC)/service/h_whohas.c \
|
||||
$(BACNET_BASIC)/service/h_whois.c \
|
||||
$(BACNET_BASIC)/service/h_rd.c \
|
||||
$(BACNET_BASIC)/service/h_rp.c \
|
||||
$(BACNET_BASIC)/service/h_rpm.c \
|
||||
$(BACNET_BASIC)/service/h_wp.c \
|
||||
$(BACNET_BASIC)/service/h_dcc.c \
|
||||
$(BACNET_BASIC)/service/s_iam.c \
|
||||
$(BACNET_BASIC)/service/s_ihave.c
|
||||
|
||||
CORESRC = $(BACNET_CORE)/abort.c \
|
||||
$(BACNET_CORE)/apdu.c \
|
||||
$(BACNET_CORE)/bacaddr.c \
|
||||
$(BACNET_CORE)/bacapp.c \
|
||||
$(BACNET_CORE)/bacdcode.c \
|
||||
@@ -88,7 +87,7 @@ CORESRC = $(BACNET_CORE)/abort.c \
|
||||
$(BACNET_CORE)/bacint.c \
|
||||
$(BACNET_CORE)/bacreal.c \
|
||||
$(BACNET_CORE)/bacstr.c \
|
||||
$(BACNET_CORE)/crc.c \
|
||||
$(BACNET_CORE)/datalink/crc.c \
|
||||
$(BACNET_CORE)/datetime.c \
|
||||
$(BACNET_CORE)/dcc.c \
|
||||
$(BACNET_CORE)/iam.c \
|
||||
@@ -99,7 +98,6 @@ CORESRC = $(BACNET_CORE)/abort.c \
|
||||
$(BACNET_CORE)/proplist.c \
|
||||
$(BACNET_CORE)/rd.c \
|
||||
$(BACNET_CORE)/reject.c \
|
||||
$(BACNET_CORE)/ringbuf.c \
|
||||
$(BACNET_CORE)/rp.c \
|
||||
$(BACNET_CORE)/rpm.c \
|
||||
$(BACNET_CORE)/version.c \
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h"
|
||||
#include "ai.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/object/ai.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
#ifndef MAX_ANALOG_INPUTS
|
||||
#define MAX_ANALOG_INPUTS 2
|
||||
|
||||
+156
-156
@@ -1,156 +1,156 @@
|
||||
/* ****************************************************************************************************** */
|
||||
/* LINKER SCRIPT */
|
||||
/* */
|
||||
/* */
|
||||
/* The Linker Script defines how the code and data emitted by the GNU C compiler and assembler are */
|
||||
/* to be loaded into memory (code goes into FLASH, variables go into RAM). */
|
||||
/* */
|
||||
/* Any symbols defined in the Linker Script are automatically global and available to the rest of the */
|
||||
/* program. */
|
||||
/* */
|
||||
/* To force the linker to use this LINKER SCRIPT, just add the -T AT91SAM7S256.LD */
|
||||
/* directive to the linker flags in the makefile. For example, */
|
||||
/* */
|
||||
/* LFLAGS = -Map main.map -nostartfiles -T AT91SAM7S256.LD */
|
||||
/* */
|
||||
/* */
|
||||
/* The order that the object files are listed in the makefile determines what .text section is */
|
||||
/* placed first. */
|
||||
/* */
|
||||
/* For example: $(LD) $(LFLAGS) -o main.out crt.o main.o lowlevelinit.o */
|
||||
/* */
|
||||
/* crt.o is first in the list of objects, so it will be placed at address 0x00000000 */
|
||||
/* */
|
||||
/* */
|
||||
/* The top of the stack (_stack_end) is (last_byte_of_ram +1) - 4 */
|
||||
/* */
|
||||
/* Therefore: _stack_end = (0x00020FFFF + 1) - 4 = 0x00210000 - 4 = 0x0020FFFC */
|
||||
/* Therefore: _stack_end = (0x000203FFF + 1) - 4 = 0x00204000 - 4 = 0x00203FFC */
|
||||
/* */
|
||||
/* Note that this symbol (_stack_end) is automatically GLOBAL and will be used by the crt.s */
|
||||
/* startup assembler routine to specify all stacks for the various ARM modes */
|
||||
/* */
|
||||
/* MEMORY MAP */
|
||||
/* | | */
|
||||
/* .-------->|---------------------------------|0x00210000 */
|
||||
/* . | |0x0020FFFC <---------- _stack_end */
|
||||
/* . | UDF Stack 16 bytes | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FFEC */
|
||||
/* . | | */
|
||||
/* . | ABT Stack 16 bytes | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FFDC */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | FIQ Stack 128 bytes | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* RAM |---------------------------------|0x0020FF5C */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | IRQ Stack 128 bytes | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FEDC */
|
||||
/* . | | */
|
||||
/* . | SVC Stack 16 bytes | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FECC */
|
||||
/* . | | */
|
||||
/* . | stack area for user program | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | free ram | */
|
||||
/* . | | */
|
||||
/* . |.................................|0x002006D8 <---------- _bss_end */
|
||||
/* . | | */
|
||||
/* . | .bss uninitialized variables | */
|
||||
/* . |.................................|0x002006D0 <---------- _bss_start, _edata */
|
||||
/* . | | */
|
||||
/* . | .data initialized variables | */
|
||||
/* . | | */
|
||||
/* .-------->|_________________________________|0x00200000 */
|
||||
/* */
|
||||
/* */
|
||||
/* .-------->|---------------------------------|0x00100000 */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | free flash | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . |.................................|0x000006D0 <---------- _bss_start, _edata */
|
||||
/* . | | */
|
||||
/* . | .data initialized variables | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x000006C4 <----------- _etext */
|
||||
/* . | | */
|
||||
/* . | C code | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x00000118 main() */
|
||||
/* . | | */
|
||||
/* . | Startup Code (crt.s) | */
|
||||
/* . | (assembler) | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x00000020 */
|
||||
/* . | | */
|
||||
/* . | Interrupt Vector Table | */
|
||||
/* . | 32 bytes | */
|
||||
/* .-------->|---------------------------------|0x00000000 _vec_reset */
|
||||
/* */
|
||||
/* */
|
||||
/* Author: James P. Lynch May 12, 2007 */
|
||||
/* */
|
||||
/* ****************************************************************************************************** */
|
||||
|
||||
|
||||
/* identify the Entry Point (_vec_reset is defined in file crt.s) */
|
||||
ENTRY(_vec_reset)
|
||||
|
||||
/* specify the AT91SAM7S64 memory areas */
|
||||
MEMORY
|
||||
{
|
||||
flash : ORIGIN = 0, LENGTH = 64K /* FLASH EPROM */
|
||||
ram : ORIGIN = 0x00200000, LENGTH = 16K /* static RAM area */
|
||||
}
|
||||
|
||||
|
||||
/* define a global symbol _stack_end (see analysis in annotation above) */
|
||||
/*_stack_end = 0x20FFFC;*/
|
||||
_stack_end = 0x203FFC;
|
||||
|
||||
/* now define the output sections */
|
||||
SECTIONS
|
||||
{
|
||||
. = 0; /* set location counter to address zero */
|
||||
|
||||
.text : /* collect all sections that should go into FLASH after startup */
|
||||
{
|
||||
*(.text*) /* all .text sections (code) */
|
||||
*(.rodata) /* all .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* all .rodata* sections (constants, strings, etc.) */
|
||||
*(.glue_7) /* all .glue_7 sections (no idea what these are) */
|
||||
*(.glue_7t) /* all .glue_7t sections (no idea what these are) */
|
||||
_etext = .; /* define a global symbol _etext just after the last code byte */
|
||||
} >flash /* put all the above into FLASH */
|
||||
|
||||
.data : /* collect all initialized .data sections that go into RAM */
|
||||
{
|
||||
_data = .; /* create a global symbol marking the start of the .data section */
|
||||
*(.data*) /* all .data sections */
|
||||
_edata = .; /* define a global symbol marking the end of the .data section */
|
||||
} >ram AT >flash /* put all the above into RAM (but load the LMA initializer copy into FLASH) */
|
||||
|
||||
.bss : /* collect all uninitialized .bss sections that go into RAM */
|
||||
{
|
||||
_bss_start = .; /* define a global symbol marking the start of the .bss section */
|
||||
*(.bss*) /* all .bss sections */
|
||||
} >ram /* put all the above in RAM (it will be cleared in the startup code */
|
||||
|
||||
. = ALIGN(4); /* advance location counter to the next 32-bit boundary */
|
||||
_bss_end = . ; /* define a global symbol marking the end of the .bss section */
|
||||
}
|
||||
_end = .; /* define a global symbol marking the end of application RAM */
|
||||
|
||||
/* ****************************************************************************************************** */
|
||||
/* LINKER SCRIPT */
|
||||
/* */
|
||||
/* */
|
||||
/* The Linker Script defines how the code and data emitted by the GNU C compiler and assembler are */
|
||||
/* to be loaded into memory (code goes into FLASH, variables go into RAM). */
|
||||
/* */
|
||||
/* Any symbols defined in the Linker Script are automatically global and available to the rest of the */
|
||||
/* program. */
|
||||
/* */
|
||||
/* To force the linker to use this LINKER SCRIPT, just add the -T AT91SAM7S256.LD */
|
||||
/* directive to the linker flags in the makefile. For example, */
|
||||
/* */
|
||||
/* LFLAGS = -Map main.map -nostartfiles -T AT91SAM7S256.LD */
|
||||
/* */
|
||||
/* */
|
||||
/* The order that the object files are listed in the makefile determines what .text section is */
|
||||
/* placed first. */
|
||||
/* */
|
||||
/* For example: $(LD) $(LFLAGS) -o main.out crt.o main.o lowlevelinit.o */
|
||||
/* */
|
||||
/* crt.o is first in the list of objects, so it will be placed at address 0x00000000 */
|
||||
/* */
|
||||
/* */
|
||||
/* The top of the stack (_stack_end) is (last_byte_of_ram +1) - 4 */
|
||||
/* */
|
||||
/* Therefore: _stack_end = (0x00020FFFF + 1) - 4 = 0x00210000 - 4 = 0x0020FFFC */
|
||||
/* Therefore: _stack_end = (0x000203FFF + 1) - 4 = 0x00204000 - 4 = 0x00203FFC */
|
||||
/* */
|
||||
/* Note that this symbol (_stack_end) is automatically GLOBAL and will be used by the crt.s */
|
||||
/* startup assembler routine to specify all stacks for the various ARM modes */
|
||||
/* */
|
||||
/* MEMORY MAP */
|
||||
/* | | */
|
||||
/* .-------->|---------------------------------|0x00210000 */
|
||||
/* . | |0x0020FFFC <---------- _stack_end */
|
||||
/* . | UDF Stack 16 bytes | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FFEC */
|
||||
/* . | | */
|
||||
/* . | ABT Stack 16 bytes | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FFDC */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | FIQ Stack 128 bytes | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* RAM |---------------------------------|0x0020FF5C */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | IRQ Stack 128 bytes | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FEDC */
|
||||
/* . | | */
|
||||
/* . | SVC Stack 16 bytes | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x0020FECC */
|
||||
/* . | | */
|
||||
/* . | stack area for user program | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | free ram | */
|
||||
/* . | | */
|
||||
/* . |.................................|0x002006D8 <---------- _bss_end */
|
||||
/* . | | */
|
||||
/* . | .bss uninitialized variables | */
|
||||
/* . |.................................|0x002006D0 <---------- _bss_start, _edata */
|
||||
/* . | | */
|
||||
/* . | .data initialized variables | */
|
||||
/* . | | */
|
||||
/* .-------->|_________________________________|0x00200000 */
|
||||
/* */
|
||||
/* */
|
||||
/* .-------->|---------------------------------|0x00100000 */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . | free flash | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . |.................................|0x000006D0 <---------- _bss_start, _edata */
|
||||
/* . | | */
|
||||
/* . | .data initialized variables | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x000006C4 <----------- _etext */
|
||||
/* . | | */
|
||||
/* . | C code | */
|
||||
/* . | | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x00000118 main() */
|
||||
/* . | | */
|
||||
/* . | Startup Code (crt.s) | */
|
||||
/* . | (assembler) | */
|
||||
/* . | | */
|
||||
/* . |---------------------------------|0x00000020 */
|
||||
/* . | | */
|
||||
/* . | Interrupt Vector Table | */
|
||||
/* . | 32 bytes | */
|
||||
/* .-------->|---------------------------------|0x00000000 _vec_reset */
|
||||
/* */
|
||||
/* */
|
||||
/* Author: James P. Lynch May 12, 2007 */
|
||||
/* */
|
||||
/* ****************************************************************************************************** */
|
||||
|
||||
|
||||
/* identify the Entry Point (_vec_reset is defined in file crt.s) */
|
||||
ENTRY(_vec_reset)
|
||||
|
||||
/* specify the AT91SAM7S64 memory areas */
|
||||
MEMORY
|
||||
{
|
||||
flash : ORIGIN = 0, LENGTH = 64K /* FLASH EPROM */
|
||||
ram : ORIGIN = 0x00200000, LENGTH = 16K /* static RAM area */
|
||||
}
|
||||
|
||||
|
||||
/* define a global symbol _stack_end (see analysis in annotation above) */
|
||||
/*_stack_end = 0x20FFFC;*/
|
||||
_stack_end = 0x203FFC;
|
||||
|
||||
/* now define the output sections */
|
||||
SECTIONS
|
||||
{
|
||||
. = 0; /* set location counter to address zero */
|
||||
|
||||
.text : /* collect all sections that should go into FLASH after startup */
|
||||
{
|
||||
*(.text*) /* all .text sections (code) */
|
||||
*(.rodata) /* all .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* all .rodata* sections (constants, strings, etc.) */
|
||||
*(.glue_7) /* all .glue_7 sections (no idea what these are) */
|
||||
*(.glue_7t) /* all .glue_7t sections (no idea what these are) */
|
||||
_etext = .; /* define a global symbol _etext just after the last code byte */
|
||||
} >flash /* put all the above into FLASH */
|
||||
|
||||
.data : /* collect all initialized .data sections that go into RAM */
|
||||
{
|
||||
_data = .; /* create a global symbol marking the start of the .data section */
|
||||
*(.data*) /* all .data sections */
|
||||
_edata = .; /* define a global symbol marking the end of the .data section */
|
||||
} >ram AT >flash /* put all the above into RAM (but load the LMA initializer copy into FLASH) */
|
||||
|
||||
.bss : /* collect all uninitialized .bss sections that go into RAM */
|
||||
{
|
||||
_bss_start = .; /* define a global symbol marking the start of the .bss section */
|
||||
*(.bss*) /* all .bss sections */
|
||||
} >ram /* put all the above in RAM (it will be cleared in the startup code */
|
||||
|
||||
. = ALIGN(4); /* advance location counter to the next 32-bit boundary */
|
||||
_bss_end = . ; /* define a global symbol marking the end of the .bss section */
|
||||
}
|
||||
_end = .; /* define a global symbol marking the end of application RAM */
|
||||
|
||||
|
||||
@@ -27,13 +27,13 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "bacapp.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "av.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
#ifndef MAX_ANALOG_VALUES
|
||||
#define MAX_ANALOG_VALUES 4
|
||||
|
||||
+138
-1008
File diff suppressed because it is too large
Load Diff
@@ -28,12 +28,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h"
|
||||
#include "bi.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/object/bi.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
#define MAX_BINARY_INPUTS 8
|
||||
#if (MAX_BINARY_INPUTS > 9)
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "bv.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
#ifndef MAX_BINARY_VALUES
|
||||
#define MAX_BINARY_VALUES 8
|
||||
|
||||
+319
-319
@@ -1,319 +1,319 @@
|
||||
/* ****************************************************************************************************** */
|
||||
/* crt.s */
|
||||
/* */
|
||||
/* Assembly Language Startup Code for Atmel AT91SAM7S256 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* Author: James P Lynch May 12, 2007 */
|
||||
/* ****************************************************************************************************** */
|
||||
|
||||
/* Stack Sizes */
|
||||
.set UND_STACK_SIZE, 0x00000010 /* stack for "undefined instruction" interrupts is 16 bytes */
|
||||
.set ABT_STACK_SIZE, 0x00000010 /* stack for "abort" interrupts is 16 bytes */
|
||||
.set FIQ_STACK_SIZE, 0x00000080 /* stack for "FIQ" interrupts is 128 bytes */
|
||||
.set IRQ_STACK_SIZE, 0X00000080 /* stack for "IRQ" normal interrupts is 128 bytes */
|
||||
.set SVC_STACK_SIZE, 0x00000080 /* stack for "SVC" supervisor mode is 128 bytes */
|
||||
|
||||
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
|
||||
.set ARM_MODE_USR, 0x10 /* Normal User Mode */
|
||||
.set ARM_MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
|
||||
.set ARM_MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
|
||||
.set ARM_MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
|
||||
.set ARM_MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
|
||||
.set ARM_MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
|
||||
.set ARM_MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
|
||||
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
|
||||
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
|
||||
|
||||
/* Addresses and offsets of AIC and PIO */
|
||||
.set AT91C_BASE_AIC, 0xFFFFF000 /* (AIC) Base Address */
|
||||
.set AT91C_PIOA_CODR, 0xFFFFF434 /* (PIO) Clear Output Data Register */
|
||||
.set AT91C_AIC_IVR, 0xFFFFF100 /* (AIC) IRQ Interrupt Vector Register */
|
||||
.set AT91C_AIC_FVR, 0xFFFFF104 /* (AIC) FIQ Interrupt Vector Register */
|
||||
.set AIC_IVR, 256 /* IRQ Vector Register offset from base above */
|
||||
.set AIC_FVR, 260 /* FIQ Vector Register offset from base above */
|
||||
.set AIC_EOICR, 304 /* End of Interrupt Command Register */
|
||||
|
||||
/* identify all GLOBAL symbols */
|
||||
.global _vec_reset
|
||||
.global _vec_undef
|
||||
.global _vec_swi
|
||||
.global _vec_pabt
|
||||
.global _vec_dabt
|
||||
.global _vec_rsv
|
||||
.global _vec_irq
|
||||
.global _vec_fiq
|
||||
.global AT91F_Irq_Handler
|
||||
.global AT91F_Fiq_Handler
|
||||
.global AT91F_Default_FIQ_handler
|
||||
.global AT91F_Default_IRQ_handler
|
||||
.global AT91F_Spurious_handler
|
||||
.global AT91F_Dabt_Handler
|
||||
.global AT91F_Pabt_Handler
|
||||
.global AT91F_Undef_Handler
|
||||
|
||||
|
||||
/* GNU assembler controls */
|
||||
.text /* all assembler code that follows will go into .text section */
|
||||
.arm /* compile for 32-bit ARM instruction set */
|
||||
.align /* align section on 32-bit boundary */
|
||||
|
||||
/* ============================================================ */
|
||||
/* VECTOR TABLE */
|
||||
/* */
|
||||
/* Must be located in FLASH at address 0x00000000 */
|
||||
/* */
|
||||
/* Easy to do if this file crt.s is first in the list */
|
||||
/* for the linker step in the makefile, e.g. */
|
||||
/* */
|
||||
/* $(LD) $(LFLAGS) -o main.out crt.o main.o */
|
||||
/* */
|
||||
/* ============================================================ */
|
||||
|
||||
_vec_reset: b _init_reset /* RESET vector - must be at 0x00000000 */
|
||||
_vec_undef: b AT91F_Undef_Handler /* Undefined Instruction vector */
|
||||
_vec_swi: b _vec_swi /* Software Interrupt vector */
|
||||
_vec_pabt: b AT91F_Pabt_Handler /* Prefetch abort vector */
|
||||
_vec_dabt: b AT91F_Dabt_Handler /* Data abort vector */
|
||||
_vec_rsv: nop /* Reserved vector */
|
||||
_vec_irq: b AT91F_Irq_Handler /* Interrupt Request (IRQ) vector */
|
||||
_vec_fiq: /* Fast interrupt request (FIQ) vector */
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Fiq_Handler */
|
||||
/* */
|
||||
/* The FIQ interrupt asserts when switch SW1 is pressed. */
|
||||
/* */
|
||||
/* This simple FIQ handler turns on LED3 (Port PA2). The LED3 will be */
|
||||
/* turned off by the background loop in main() thus giving a visual */
|
||||
/* indication that the interrupt has occurred. */
|
||||
/* */
|
||||
/* This FIQ_Handler supports non-nested FIQ interrupts (a FIQ interrupt */
|
||||
/* cannot itself be interrupted). */
|
||||
/* */
|
||||
/* The Fast Interrupt Vector Register (AIC_FVR) is read to clear the */
|
||||
/* interrupt. */
|
||||
/* */
|
||||
/* A global variable FiqCount is also incremented. */
|
||||
/* */
|
||||
/* Remember that switch SW1 is not debounced, so the FIQ interrupt may */
|
||||
/* occur more than once for a single button push. */
|
||||
/* */
|
||||
/* Programmer: James P Lynch */
|
||||
/* ======================================================================== */
|
||||
AT91F_Fiq_Handler:
|
||||
|
||||
/* Adjust LR_irq */
|
||||
sub lr, lr, #4
|
||||
|
||||
/* Read the AIC Fast Interrupt Vector register to clear the interrupt */
|
||||
ldr r12, =AT91C_AIC_FVR
|
||||
ldr r11, [r12]
|
||||
|
||||
/* Return from Fiq interrupt */
|
||||
movs pc, lr
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* _init_reset Handler */
|
||||
/* */
|
||||
/* RESET vector 0x00000000 branches to here. */
|
||||
/* */
|
||||
/* ARM microprocessor begins execution after RESET at address 0x00000000 */
|
||||
/* in Supervisor mode with interrupts disabled! */
|
||||
/* */
|
||||
/* _init_reset handler: creates a stack for each ARM mode. */
|
||||
/* sets up a stack pointer for each ARM mode. */
|
||||
/* turns off interrupts in each mode. */
|
||||
/* leaves CPU in SYS (System) mode. */
|
||||
/* */
|
||||
/* block copies the initializers to .data section */
|
||||
/* clears the .bss section to zero */
|
||||
/* */
|
||||
/* branches to main( ) */
|
||||
/* ======================================================================== */
|
||||
.text /* all assembler code that follows will go into .text section */
|
||||
.align /* align section on 32-bit boundary */
|
||||
_init_reset:
|
||||
/* Setup a stack for each mode with interrupts initially disabled. */
|
||||
ldr r0, =_stack_end /* r0 = top-of-stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_UND|I_BIT|F_BIT /* switch to Undefined Instruction Mode */
|
||||
mov sp, r0 /* set stack pointer for UND mode */
|
||||
sub r0, r0, #UND_STACK_SIZE /* adjust r0 past UND stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_ABT|I_BIT|F_BIT /* switch to Abort Mode */
|
||||
mov sp, r0 /* set stack pointer for ABT mode */
|
||||
sub r0, r0, #ABT_STACK_SIZE /* adjust r0 past ABT stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_FIQ|I_BIT|F_BIT /* switch to FIQ Mode */
|
||||
mov sp, r0 /* set stack pointer for FIQ mode */
|
||||
sub r0, r0, #FIQ_STACK_SIZE /* adjust r0 past FIQ stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_IRQ|I_BIT|F_BIT /* switch to IRQ Mode */
|
||||
mov sp, r0 /* set stack pointer for IRQ mode */
|
||||
sub r0, r0, #IRQ_STACK_SIZE /* adjust r0 past IRQ stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_SVC|I_BIT|F_BIT /* switch to Supervisor Mode */
|
||||
mov sp, r0 /* set stack pointer for SVC mode */
|
||||
sub r0, r0, #SVC_STACK_SIZE /* adjust r0 past SVC stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_SYS|I_BIT|F_BIT /* switch to System Mode */
|
||||
mov sp, r0 /* set stack pointer for SYS mode */
|
||||
/* we now start execution in SYSTEM mode */
|
||||
/* This is exactly like USER mode (same stack) */
|
||||
/* but SYSTEM mode has more privileges */
|
||||
|
||||
/* copy initialized variables .data section (Copy from ROM to RAM) */
|
||||
ldr R1, =_etext
|
||||
ldr R2, =_data
|
||||
ldr R3, =_edata
|
||||
1: cmp R2, R3
|
||||
ldrlo R0, [R1], #4
|
||||
strlo R0, [R2], #4
|
||||
blo 1b
|
||||
|
||||
/* Clear uninitialized variables .bss section (Zero init) */
|
||||
mov R0, #0
|
||||
ldr R1, =_bss_start
|
||||
ldr R2, =_bss_end
|
||||
2: cmp R1, R2
|
||||
strlo R0, [R1], #4
|
||||
blo 2b
|
||||
|
||||
/* Enter the C code */
|
||||
b main
|
||||
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Irq_Handler */
|
||||
/* */
|
||||
/* This IRQ_Handler supports nested interrupts (an IRQ interrupt can itself */
|
||||
/* be interrupted). */
|
||||
/* */
|
||||
/* This handler re-enables interrupts and switches to "Supervisor" mode to */
|
||||
/* prevent any corruption to the link and IP registers. */
|
||||
/* */
|
||||
/* The Interrupt Vector Register (AIC_IVR) is read to determine the address */
|
||||
/* of the required interrupt service routine. The ISR routine can be a */
|
||||
/* standard C function since this handler minds all the save/restore */
|
||||
/* protocols. */
|
||||
/* */
|
||||
/* */
|
||||
/* Programmers: */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* ATMEL Microcontroller Software Support - ROUSSET - */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS */
|
||||
/* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
||||
/* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
|
||||
/* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR */
|
||||
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */
|
||||
/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT */
|
||||
/* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */
|
||||
/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */
|
||||
/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE */
|
||||
/* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
|
||||
/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
/* File source : Cstartup.s79 */
|
||||
/* Object : Generic CStartup to AT91SAM7S256 */
|
||||
/* 1.0 09/May/06 JPP : Creation */
|
||||
/* */
|
||||
/* */
|
||||
/* Note: taken from Atmel web site (www.at91.com) */
|
||||
/* Keil example project: AT91SAM7S-Interrupt_SAM7S */
|
||||
/* ======================================================================== */
|
||||
AT91F_Irq_Handler:
|
||||
|
||||
/* Manage Exception Entry */
|
||||
/* Adjust and save LR_irq in IRQ stack */
|
||||
sub lr, lr, #4
|
||||
stmfd sp!, {lr}
|
||||
|
||||
/* Save r0 and SPSR (need to be saved for nested interrupt) */
|
||||
mrs r14, SPSR
|
||||
stmfd sp!, {r0,r14}
|
||||
|
||||
/* Write in the IVR to support Protect Mode */
|
||||
/* No effect in Normal Mode */
|
||||
/* De-assert the NIRQ and clear the source in Protect Mode */
|
||||
ldr r14, =AT91C_BASE_AIC
|
||||
ldr r0 , [r14, #AIC_IVR]
|
||||
str r14, [r14, #AIC_IVR]
|
||||
|
||||
/* Enable Interrupt and Switch in Supervisor Mode */
|
||||
msr CPSR_c, #ARM_MODE_SVC
|
||||
|
||||
/* Save scratch/used registers and LR in User Stack */
|
||||
stmfd sp!, { r1-r3, r12, r14}
|
||||
|
||||
/* Branch to the routine pointed by the AIC_IVR */
|
||||
mov r14, pc
|
||||
bx r0
|
||||
|
||||
/* Manage Exception Exit */
|
||||
/* Restore scratch/used registers and LR from User Stack */
|
||||
ldmia sp!, { r1-r3, r12, r14}
|
||||
|
||||
/* Disable Interrupt and switch back in IRQ mode */
|
||||
msr CPSR_c, #I_BIT | ARM_MODE_IRQ
|
||||
|
||||
/* Mark the End of Interrupt on the AIC */
|
||||
ldr r14, =AT91C_BASE_AIC
|
||||
str r14, [r14, #AIC_EOICR]
|
||||
|
||||
/* Restore SPSR_irq and r0 from IRQ stack */
|
||||
ldmia sp!, {r0,r14}
|
||||
msr SPSR_cxsf, r14
|
||||
|
||||
/* Restore adjusted LR_irq from IRQ stack directly in the PC */
|
||||
ldmia sp!, {pc}^
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Dabt_Handler */
|
||||
/* */
|
||||
/* Entered on Data Abort exception. */
|
||||
/* Enters blink routine (3 blinks followed by a pause) */
|
||||
/* processor hangs in the blink loop forever */
|
||||
/* */
|
||||
/* ======================================================================== */
|
||||
AT91F_Dabt_Handler: mov R0, #3
|
||||
b blinker
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Pabt_Handler */
|
||||
/* */
|
||||
/* Entered on Prefetch Abort exception. */
|
||||
/* Enters blink routine (2 blinks followed by a pause) */
|
||||
/* processor hangs in the blink loop forever */
|
||||
/* */
|
||||
/* ======================================================================== */
|
||||
AT91F_Pabt_Handler: mov R0, #2
|
||||
b blinker
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Undef_Handler */
|
||||
/* */
|
||||
/* Entered on Undefined Instruction exception. */
|
||||
/* Enters blink routine (1 blinks followed by a pause) */
|
||||
/* processor hangs in the blink loop forever */
|
||||
/* */
|
||||
/* ======================================================================== */
|
||||
AT91F_Undef_Handler: mov R0, #1
|
||||
b blinker
|
||||
|
||||
|
||||
AT91F_Default_FIQ_handler: b AT91F_Default_FIQ_handler
|
||||
|
||||
AT91F_Default_IRQ_handler: b AT91F_Default_IRQ_handler
|
||||
|
||||
AT91F_Spurious_handler: b AT91F_Spurious_handler
|
||||
.end
|
||||
/* ****************************************************************************************************** */
|
||||
/* crt.s */
|
||||
/* */
|
||||
/* Assembly Language Startup Code for Atmel AT91SAM7S256 */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* Author: James P Lynch May 12, 2007 */
|
||||
/* ****************************************************************************************************** */
|
||||
|
||||
/* Stack Sizes */
|
||||
.set UND_STACK_SIZE, 0x00000010 /* stack for "undefined instruction" interrupts is 16 bytes */
|
||||
.set ABT_STACK_SIZE, 0x00000010 /* stack for "abort" interrupts is 16 bytes */
|
||||
.set FIQ_STACK_SIZE, 0x00000080 /* stack for "FIQ" interrupts is 128 bytes */
|
||||
.set IRQ_STACK_SIZE, 0X00000080 /* stack for "IRQ" normal interrupts is 128 bytes */
|
||||
.set SVC_STACK_SIZE, 0x00000080 /* stack for "SVC" supervisor mode is 128 bytes */
|
||||
|
||||
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
|
||||
.set ARM_MODE_USR, 0x10 /* Normal User Mode */
|
||||
.set ARM_MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
|
||||
.set ARM_MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
|
||||
.set ARM_MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
|
||||
.set ARM_MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
|
||||
.set ARM_MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
|
||||
.set ARM_MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
|
||||
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
|
||||
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
|
||||
|
||||
/* Addresses and offsets of AIC and PIO */
|
||||
.set AT91C_BASE_AIC, 0xFFFFF000 /* (AIC) Base Address */
|
||||
.set AT91C_PIOA_CODR, 0xFFFFF434 /* (PIO) Clear Output Data Register */
|
||||
.set AT91C_AIC_IVR, 0xFFFFF100 /* (AIC) IRQ Interrupt Vector Register */
|
||||
.set AT91C_AIC_FVR, 0xFFFFF104 /* (AIC) FIQ Interrupt Vector Register */
|
||||
.set AIC_IVR, 256 /* IRQ Vector Register offset from base above */
|
||||
.set AIC_FVR, 260 /* FIQ Vector Register offset from base above */
|
||||
.set AIC_EOICR, 304 /* End of Interrupt Command Register */
|
||||
|
||||
/* identify all GLOBAL symbols */
|
||||
.global _vec_reset
|
||||
.global _vec_undef
|
||||
.global _vec_swi
|
||||
.global _vec_pabt
|
||||
.global _vec_dabt
|
||||
.global _vec_rsv
|
||||
.global _vec_irq
|
||||
.global _vec_fiq
|
||||
.global AT91F_Irq_Handler
|
||||
.global AT91F_Fiq_Handler
|
||||
.global AT91F_Default_FIQ_handler
|
||||
.global AT91F_Default_IRQ_handler
|
||||
.global AT91F_Spurious_handler
|
||||
.global AT91F_Dabt_Handler
|
||||
.global AT91F_Pabt_Handler
|
||||
.global AT91F_Undef_Handler
|
||||
|
||||
|
||||
/* GNU assembler controls */
|
||||
.text /* all assembler code that follows will go into .text section */
|
||||
.arm /* compile for 32-bit ARM instruction set */
|
||||
.align /* align section on 32-bit boundary */
|
||||
|
||||
/* ============================================================ */
|
||||
/* VECTOR TABLE */
|
||||
/* */
|
||||
/* Must be located in FLASH at address 0x00000000 */
|
||||
/* */
|
||||
/* Easy to do if this file crt.s is first in the list */
|
||||
/* for the linker step in the makefile, e.g. */
|
||||
/* */
|
||||
/* $(LD) $(LFLAGS) -o main.out crt.o main.o */
|
||||
/* */
|
||||
/* ============================================================ */
|
||||
|
||||
_vec_reset: b _init_reset /* RESET vector - must be at 0x00000000 */
|
||||
_vec_undef: b AT91F_Undef_Handler /* Undefined Instruction vector */
|
||||
_vec_swi: b _vec_swi /* Software Interrupt vector */
|
||||
_vec_pabt: b AT91F_Pabt_Handler /* Prefetch abort vector */
|
||||
_vec_dabt: b AT91F_Dabt_Handler /* Data abort vector */
|
||||
_vec_rsv: nop /* Reserved vector */
|
||||
_vec_irq: b AT91F_Irq_Handler /* Interrupt Request (IRQ) vector */
|
||||
_vec_fiq: /* Fast interrupt request (FIQ) vector */
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Fiq_Handler */
|
||||
/* */
|
||||
/* The FIQ interrupt asserts when switch SW1 is pressed. */
|
||||
/* */
|
||||
/* This simple FIQ handler turns on LED3 (Port PA2). The LED3 will be */
|
||||
/* turned off by the background loop in main() thus giving a visual */
|
||||
/* indication that the interrupt has occurred. */
|
||||
/* */
|
||||
/* This FIQ_Handler supports non-nested FIQ interrupts (a FIQ interrupt */
|
||||
/* cannot itself be interrupted). */
|
||||
/* */
|
||||
/* The Fast Interrupt Vector Register (AIC_FVR) is read to clear the */
|
||||
/* interrupt. */
|
||||
/* */
|
||||
/* A global variable FiqCount is also incremented. */
|
||||
/* */
|
||||
/* Remember that switch SW1 is not debounced, so the FIQ interrupt may */
|
||||
/* occur more than once for a single button push. */
|
||||
/* */
|
||||
/* Programmer: James P Lynch */
|
||||
/* ======================================================================== */
|
||||
AT91F_Fiq_Handler:
|
||||
|
||||
/* Adjust LR_irq */
|
||||
sub lr, lr, #4
|
||||
|
||||
/* Read the AIC Fast Interrupt Vector register to clear the interrupt */
|
||||
ldr r12, =AT91C_AIC_FVR
|
||||
ldr r11, [r12]
|
||||
|
||||
/* Return from Fiq interrupt */
|
||||
movs pc, lr
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* _init_reset Handler */
|
||||
/* */
|
||||
/* RESET vector 0x00000000 branches to here. */
|
||||
/* */
|
||||
/* ARM microprocessor begins execution after RESET at address 0x00000000 */
|
||||
/* in Supervisor mode with interrupts disabled! */
|
||||
/* */
|
||||
/* _init_reset handler: creates a stack for each ARM mode. */
|
||||
/* sets up a stack pointer for each ARM mode. */
|
||||
/* turns off interrupts in each mode. */
|
||||
/* leaves CPU in SYS (System) mode. */
|
||||
/* */
|
||||
/* block copies the initializers to .data section */
|
||||
/* clears the .bss section to zero */
|
||||
/* */
|
||||
/* branches to main( ) */
|
||||
/* ======================================================================== */
|
||||
.text /* all assembler code that follows will go into .text section */
|
||||
.align /* align section on 32-bit boundary */
|
||||
_init_reset:
|
||||
/* Setup a stack for each mode with interrupts initially disabled. */
|
||||
ldr r0, =_stack_end /* r0 = top-of-stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_UND|I_BIT|F_BIT /* switch to Undefined Instruction Mode */
|
||||
mov sp, r0 /* set stack pointer for UND mode */
|
||||
sub r0, r0, #UND_STACK_SIZE /* adjust r0 past UND stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_ABT|I_BIT|F_BIT /* switch to Abort Mode */
|
||||
mov sp, r0 /* set stack pointer for ABT mode */
|
||||
sub r0, r0, #ABT_STACK_SIZE /* adjust r0 past ABT stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_FIQ|I_BIT|F_BIT /* switch to FIQ Mode */
|
||||
mov sp, r0 /* set stack pointer for FIQ mode */
|
||||
sub r0, r0, #FIQ_STACK_SIZE /* adjust r0 past FIQ stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_IRQ|I_BIT|F_BIT /* switch to IRQ Mode */
|
||||
mov sp, r0 /* set stack pointer for IRQ mode */
|
||||
sub r0, r0, #IRQ_STACK_SIZE /* adjust r0 past IRQ stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_SVC|I_BIT|F_BIT /* switch to Supervisor Mode */
|
||||
mov sp, r0 /* set stack pointer for SVC mode */
|
||||
sub r0, r0, #SVC_STACK_SIZE /* adjust r0 past SVC stack */
|
||||
|
||||
msr CPSR_c, #ARM_MODE_SYS|I_BIT|F_BIT /* switch to System Mode */
|
||||
mov sp, r0 /* set stack pointer for SYS mode */
|
||||
/* we now start execution in SYSTEM mode */
|
||||
/* This is exactly like USER mode (same stack) */
|
||||
/* but SYSTEM mode has more privileges */
|
||||
|
||||
/* copy initialized variables .data section (Copy from ROM to RAM) */
|
||||
ldr R1, =_etext
|
||||
ldr R2, =_data
|
||||
ldr R3, =_edata
|
||||
1: cmp R2, R3
|
||||
ldrlo R0, [R1], #4
|
||||
strlo R0, [R2], #4
|
||||
blo 1b
|
||||
|
||||
/* Clear uninitialized variables .bss section (Zero init) */
|
||||
mov R0, #0
|
||||
ldr R1, =_bss_start
|
||||
ldr R2, =_bss_end
|
||||
2: cmp R1, R2
|
||||
strlo R0, [R1], #4
|
||||
blo 2b
|
||||
|
||||
/* Enter the C code */
|
||||
b main
|
||||
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Irq_Handler */
|
||||
/* */
|
||||
/* This IRQ_Handler supports nested interrupts (an IRQ interrupt can itself */
|
||||
/* be interrupted). */
|
||||
/* */
|
||||
/* This handler re-enables interrupts and switches to "Supervisor" mode to */
|
||||
/* prevent any corruption to the link and IP registers. */
|
||||
/* */
|
||||
/* The Interrupt Vector Register (AIC_IVR) is read to determine the address */
|
||||
/* of the required interrupt service routine. The ISR routine can be a */
|
||||
/* standard C function since this handler minds all the save/restore */
|
||||
/* protocols. */
|
||||
/* */
|
||||
/* */
|
||||
/* Programmers: */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* ATMEL Microcontroller Software Support - ROUSSET - */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS */
|
||||
/* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
|
||||
/* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
|
||||
/* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR */
|
||||
/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR */
|
||||
/* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT */
|
||||
/* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */
|
||||
/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, */
|
||||
/* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE */
|
||||
/* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
|
||||
/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
/* File source : Cstartup.s79 */
|
||||
/* Object : Generic CStartup to AT91SAM7S256 */
|
||||
/* 1.0 09/May/06 JPP : Creation */
|
||||
/* */
|
||||
/* */
|
||||
/* Note: taken from Atmel web site (www.at91.com) */
|
||||
/* Keil example project: AT91SAM7S-Interrupt_SAM7S */
|
||||
/* ======================================================================== */
|
||||
AT91F_Irq_Handler:
|
||||
|
||||
/* Manage Exception Entry */
|
||||
/* Adjust and save LR_irq in IRQ stack */
|
||||
sub lr, lr, #4
|
||||
stmfd sp!, {lr}
|
||||
|
||||
/* Save r0 and SPSR (need to be saved for nested interrupt) */
|
||||
mrs r14, SPSR
|
||||
stmfd sp!, {r0,r14}
|
||||
|
||||
/* Write in the IVR to support Protect Mode */
|
||||
/* No effect in Normal Mode */
|
||||
/* De-assert the NIRQ and clear the source in Protect Mode */
|
||||
ldr r14, =AT91C_BASE_AIC
|
||||
ldr r0 , [r14, #AIC_IVR]
|
||||
str r14, [r14, #AIC_IVR]
|
||||
|
||||
/* Enable Interrupt and Switch in Supervisor Mode */
|
||||
msr CPSR_c, #ARM_MODE_SVC
|
||||
|
||||
/* Save scratch/used registers and LR in User Stack */
|
||||
stmfd sp!, { r1-r3, r12, r14}
|
||||
|
||||
/* Branch to the routine pointed by the AIC_IVR */
|
||||
mov r14, pc
|
||||
bx r0
|
||||
|
||||
/* Manage Exception Exit */
|
||||
/* Restore scratch/used registers and LR from User Stack */
|
||||
ldmia sp!, { r1-r3, r12, r14}
|
||||
|
||||
/* Disable Interrupt and switch back in IRQ mode */
|
||||
msr CPSR_c, #I_BIT | ARM_MODE_IRQ
|
||||
|
||||
/* Mark the End of Interrupt on the AIC */
|
||||
ldr r14, =AT91C_BASE_AIC
|
||||
str r14, [r14, #AIC_EOICR]
|
||||
|
||||
/* Restore SPSR_irq and r0 from IRQ stack */
|
||||
ldmia sp!, {r0,r14}
|
||||
msr SPSR_cxsf, r14
|
||||
|
||||
/* Restore adjusted LR_irq from IRQ stack directly in the PC */
|
||||
ldmia sp!, {pc}^
|
||||
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Dabt_Handler */
|
||||
/* */
|
||||
/* Entered on Data Abort exception. */
|
||||
/* Enters blink routine (3 blinks followed by a pause) */
|
||||
/* processor hangs in the blink loop forever */
|
||||
/* */
|
||||
/* ======================================================================== */
|
||||
AT91F_Dabt_Handler: mov R0, #3
|
||||
b blinker
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Pabt_Handler */
|
||||
/* */
|
||||
/* Entered on Prefetch Abort exception. */
|
||||
/* Enters blink routine (2 blinks followed by a pause) */
|
||||
/* processor hangs in the blink loop forever */
|
||||
/* */
|
||||
/* ======================================================================== */
|
||||
AT91F_Pabt_Handler: mov R0, #2
|
||||
b blinker
|
||||
|
||||
|
||||
/* ======================================================================== */
|
||||
/* Function: AT91F_Undef_Handler */
|
||||
/* */
|
||||
/* Entered on Undefined Instruction exception. */
|
||||
/* Enters blink routine (1 blinks followed by a pause) */
|
||||
/* processor hangs in the blink loop forever */
|
||||
/* */
|
||||
/* ======================================================================== */
|
||||
AT91F_Undef_Handler: mov R0, #1
|
||||
b blinker
|
||||
|
||||
|
||||
AT91F_Default_FIQ_handler: b AT91F_Default_FIQ_handler
|
||||
|
||||
AT91F_Default_IRQ_handler: b AT91F_Default_IRQ_handler
|
||||
|
||||
AT91F_Spurious_handler: b AT91F_Spurious_handler
|
||||
.end
|
||||
|
||||
+19
-16
@@ -27,24 +27,27 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacstr.h"
|
||||
#include "bacenum.h"
|
||||
#include "apdu.h"
|
||||
#include "dcc.h"
|
||||
#include "datalink.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacstr.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "rs485.h"
|
||||
#include "version.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/version.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
/* objects */
|
||||
#include "device.h"
|
||||
#include "ai.h"
|
||||
#include "av.h"
|
||||
#include "bi.h"
|
||||
#include "bv.h"
|
||||
#include "wp.h"
|
||||
#include "dcc.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/ai.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/object/bi.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/dcc.h"
|
||||
|
||||
/* current version of the BACnet stack */
|
||||
static const char *BACnet_Version = BACNET_VERSION_TEXT;
|
||||
|
||||
/* forward prototype */
|
||||
int Device_Read_Property_Local(
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "bacdef.h"
|
||||
#include "dlmstp.h"
|
||||
#include "mstpdef.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/datalink/dlmstp.h"
|
||||
#include "bacnet/datalink/mstpdef.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/bits.h"
|
||||
#include "bacnet/bytes.h"
|
||||
#include "bacnet/bacaddr.h"
|
||||
#include "bacnet/basic/sys/ringbuf.h"
|
||||
#include "bacnet/datalink/crc.h"
|
||||
#include "rs485.h"
|
||||
#include "crc.h"
|
||||
#include "npdu.h"
|
||||
#include "bits.h"
|
||||
#include "bytes.h"
|
||||
#include "bacaddr.h"
|
||||
#include "ringbuf.h"
|
||||
#include "timer.h"
|
||||
#include "board.h"
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
/* Taken from the Yahoo LPC2000 User's Group - Files Section 'UT050418A.ZIP' */
|
||||
/* Specifically, the module armVIC.c with the include file references removed */
|
||||
/* ********************************************************************************************** */
|
||||
#include "at91sam7s256.h"
|
||||
#include "isr.h"
|
||||
|
||||
#define IRQ_MASK 0x00000080
|
||||
|
||||
+11
-11
@@ -33,17 +33,17 @@
|
||||
#include <stdint.h>
|
||||
/* BACnet */
|
||||
#include "rs485.h"
|
||||
#include "datalink.h"
|
||||
#include "npdu.h"
|
||||
#include "apdu.h"
|
||||
#include "dcc.h"
|
||||
#include "iam.h"
|
||||
#include "handlers.h"
|
||||
#include "client.h"
|
||||
#include "device.h"
|
||||
#include "dcc.h"
|
||||
#include "iam.h"
|
||||
#include "txbuf.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
|
||||
/* ******************************************************* */
|
||||
/* FIXME: use header files? External References */
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "timer.h"
|
||||
#include "bacnet/basic/sys/mstimer.h"
|
||||
|
||||
/* This file has been customized for use with UART0
|
||||
on the AT91SAM7S-EK */
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
**********************************************************/
|
||||
#include <stdint.h>
|
||||
#include "board.h"
|
||||
#include "dlmstp.h"
|
||||
#include "bacnet/datalink/dlmstp.h"
|
||||
|
||||
/* global variable counts interrupts */
|
||||
volatile unsigned long Timer_Milliseconds;
|
||||
|
||||
+13
-13
@@ -1,13 +1,13 @@
|
||||
-sysdirs C:\WinAVR~1\avr\include;C:\WinAVR~1\lib\gcc\avr\4.2.2\include;C:\WinAVR~1\avr\include\avr;C:\WinAVR~1\avr\include\compat;C:\WinAVR~1\avr\include\util
|
||||
-IC:\WinAVR~1\avr\include
|
||||
-IC:\WinAVR~1\avr\include\avr
|
||||
-IC:\WinAVR~1\avr\include\compat
|
||||
-IC:\WinAVR~1\avr\include\util
|
||||
-IC:\WinAVR~1\lib\gcc\avr\4.2.2\include
|
||||
-I../../include
|
||||
-I.
|
||||
-castfcnptr
|
||||
-fullinitblock
|
||||
-weak
|
||||
-D__AVR_ATmega168__
|
||||
-D__GNUC__
|
||||
-sysdirs C:\WinAVR~1\avr\include;C:\WinAVR~1\lib\gcc\avr\4.2.2\include;C:\WinAVR~1\avr\include\avr;C:\WinAVR~1\avr\include\compat;C:\WinAVR~1\avr\include\util
|
||||
-IC:\WinAVR~1\avr\include
|
||||
-IC:\WinAVR~1\avr\include\avr
|
||||
-IC:\WinAVR~1\avr\include\compat
|
||||
-IC:\WinAVR~1\avr\include\util
|
||||
-IC:\WinAVR~1\lib\gcc\avr\4.2.2\include
|
||||
-I../../include
|
||||
-I.
|
||||
-castfcnptr
|
||||
-fullinitblock
|
||||
-weak
|
||||
-D__AVR_ATmega168__
|
||||
-D__GNUC__
|
||||
|
||||
@@ -30,10 +30,8 @@ AVRDUDE_PORT = /dev/ttyUSB0
|
||||
|
||||
# Source locations
|
||||
BACNET_CORE = ../../src
|
||||
BACNET_INCLUDE = ../../include
|
||||
BACNET_HANDLER = ../../demo/handler
|
||||
BACNET_OBJECT = ../../demo/object
|
||||
BACNET_DEMO = ../../demo
|
||||
BACNET_INCLUDE = $(BACNET_CORE)
|
||||
BACNET_BASIC = $(BACNET_CORE)/basic
|
||||
|
||||
# local files for this project
|
||||
CSRC = main.c \
|
||||
@@ -50,14 +48,14 @@ CSRC = main.c \
|
||||
h_wp.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
|
||||
BASICSRC = $(BACNET_BASIC)/tsm/tsm.c \
|
||||
$(BACNET_BASIC)/npdu/h_npdu.c \
|
||||
$(BACNET_BASIC)/service/s_iam.c \
|
||||
$(BACNET_BASIC)/service/h_noserv.c
|
||||
|
||||
# core BACnet stack files
|
||||
CORESRC = \
|
||||
$(BACNET_CORE)/crc.c \
|
||||
$(BACNET_CORE)/datalink/crc.c \
|
||||
$(BACNET_CORE)/npdu.c \
|
||||
$(BACNET_CORE)/bacdcode.c \
|
||||
$(BACNET_CORE)/bacint.c \
|
||||
@@ -73,34 +71,12 @@ CORESRC = \
|
||||
$(BACNET_CORE)/bacerror.c \
|
||||
$(BACNET_CORE)/bacapp.c
|
||||
|
||||
# $(BACNET_CORE)/version.c
|
||||
# $(BACNET_CORE)/bacprop.c \
|
||||
# $(BACNET_CORE)/bactext.c \
|
||||
# $(BACNET_CORE)/datetime.c \
|
||||
# $(BACNET_CORE)/indtext.c \
|
||||
# $(BACNET_CORE)/bigend.c \
|
||||
# $(BACNET_CORE)/arf.c \
|
||||
# $(BACNET_CORE)/awf.c \
|
||||
# $(BACNET_CORE)/cov.c \
|
||||
# $(BACNET_CORE)/dcc.c \
|
||||
# $(BACNET_CORE)/iam/iam_client.c \
|
||||
# $(BACNET_CORE)/ihave.c \
|
||||
# $(BACNET_CORE)/rd.c \
|
||||
# $(BACNET_CORE)/rpm.c \
|
||||
# $(BACNET_CORE)/timesync.c \
|
||||
# $(BACNET_CORE)/whohas.c \
|
||||
# $(BACNET_CORE)/filename.c \
|
||||
# $(BACNET_CORE)/tsm.c \
|
||||
# $(BACNET_CORE)/address.c \
|
||||
|
||||
## Include Directories
|
||||
INCLUDES = -I. -I$(BACNET_INCLUDE)
|
||||
INCLUDES += -I$(BACNET_OBJECT)
|
||||
INCLUDES += -I$(BACNET_HANDLER)
|
||||
|
||||
# Source to Object conversion
|
||||
COBJ = $(CSRC:.c=.o)
|
||||
DEMOOBJ = $(DEMOSRC:.c=.o)
|
||||
BASICOBJ = $(BASICSRC:.c=.o)
|
||||
COREOBJ = $(CORESRC:.c=.o)
|
||||
|
||||
LIBRARY = lib$(TARGET).a
|
||||
@@ -156,7 +132,7 @@ 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) $(BASICOBJ)
|
||||
#OBJECTS = $(COBJ)
|
||||
|
||||
## Build
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h"
|
||||
|
||||
/* Analog Input = Photocell */
|
||||
#define MAX_ANALOG_INPUTS 9
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "rp.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/rp.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -34,12 +34,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "bits.h"
|
||||
#include "apdu.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bits.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
bool apdu_service_supported(
|
||||
BACNET_SERVICES_SUPPORTED service_supported)
|
||||
|
||||
+41
-40
@@ -28,13 +28,17 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "bacapp.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "wp.h"
|
||||
#include "av.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
|
||||
#ifndef MAX_ANALOG_VALUES
|
||||
#define MAX_ANALOG_VALUES 10
|
||||
#endif
|
||||
|
||||
#if (MAX_ANALOG_VALUES > 10)
|
||||
#error Modify the Analog_Value_Name to handle multiple digits
|
||||
@@ -92,28 +96,25 @@ char *Analog_Value_Name(
|
||||
}
|
||||
|
||||
/* 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 Analog_Value_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
unsigned object_index;
|
||||
uint8_t *apdu;
|
||||
|
||||
switch (property) {
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
|
||||
object_instance);
|
||||
rpdata->object_instance);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string,
|
||||
Analog_Value_Name(object_instance));
|
||||
Analog_Value_Name(rpdata->object_instance));
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
@@ -122,7 +123,8 @@ int Analog_Value_Encode_Property_APDU(
|
||||
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
|
||||
break;
|
||||
case PROP_PRESENT_VALUE:
|
||||
object_index = Analog_Value_Instance_To_Index(object_instance);
|
||||
object_index = Analog_Value_Instance_To_Index(
|
||||
rpdata->object_instance);
|
||||
apdu_len =
|
||||
encode_application_real(&apdu[0],
|
||||
AV_Present_Value[object_index]);
|
||||
@@ -146,16 +148,17 @@ int Analog_Value_Encode_Property_APDU(
|
||||
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;
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
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;
|
||||
if ((apdu_len >= 0) &&
|
||||
(rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
@@ -163,9 +166,7 @@ int Analog_Value_Encode_Property_APDU(
|
||||
|
||||
/* 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)
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
unsigned int object_index = 0;
|
||||
@@ -173,8 +174,8 @@ bool Analog_Value_Write_Property(
|
||||
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;
|
||||
wp_data->error_class = ERROR_CLASS_OBJECT;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
return false;
|
||||
}
|
||||
/* decode the some of the request */
|
||||
@@ -184,15 +185,15 @@ bool Analog_Value_Write_Property(
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
if ((wp_data->object_property != PROP_PRIORITY_ARRAY) &&
|
||||
(wp_data->array_index != BACNET_ARRAY_ALL)) {
|
||||
/* only array properties can have array options */
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
}
|
||||
switch (wp_data->object_property) {
|
||||
@@ -203,8 +204,8 @@ bool Analog_Value_Write_Property(
|
||||
AV_Present_Value[object_index] = value.type.Real;
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
@@ -215,12 +216,12 @@ bool Analog_Value_Write_Property(
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
case PROP_DESCRIPTION:
|
||||
case PROP_PRIORITY_ARRAY:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacerror.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
#ifndef MAX_ANALOG_VALUES
|
||||
#define MAX_ANALOG_VALUES 4
|
||||
|
||||
File diff suppressed because one or more lines are too long
+154
-59
@@ -10,9 +10,9 @@
|
||||
<debug>1</debug>
|
||||
<settings>
|
||||
<name>General</name>
|
||||
<archiveVersion>11</archiveVersion>
|
||||
<archiveVersion>12</archiveVersion>
|
||||
<data>
|
||||
<version>9</version>
|
||||
<version>10</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
@@ -132,7 +132,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>RTDescription</name>
|
||||
<state>Use the normal configuration of the C/EC++</state>
|
||||
<state>Use the normal configuration of the C/C++</state>
|
||||
<state>runtime library. No locale interface,</state>
|
||||
<state>C locale, no file descriptor support,</state>
|
||||
<state>no multibytes in printf and scanf, and</state>
|
||||
@@ -153,7 +153,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>Input description</name>
|
||||
<state>Full formatting.</state>
|
||||
<state>Full formatting</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>Output variant</name>
|
||||
@@ -162,7 +162,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>Output description</name>
|
||||
<state> specifier a or A, no specifier n, no float or long long.</state>
|
||||
<state>No specifier a, A, no specifier n, no float nor long long.</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>GRuntimeLibSelectSlave</name>
|
||||
@@ -219,6 +219,14 @@
|
||||
<name>GenDeviceSelectMenu</name>
|
||||
<state>m168 ATmega168</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OGProductVersion</name>
|
||||
<state>6.80.1.1057</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OGLastSavedByProductVersion</name>
|
||||
<state>6.80.1.1057</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
@@ -246,7 +254,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>CCDefines</name>
|
||||
<state>BACDL_MSTP</state>
|
||||
<state>BACDL_MSTP=1</state>
|
||||
<state>MAX_APDU=50</state>
|
||||
<state>BIG_ENDIAN=0</state>
|
||||
<state>MAX_TSM_TRANSACTIONS=0</state>
|
||||
@@ -411,7 +419,7 @@
|
||||
<option>
|
||||
<name>newCCIncludePaths</name>
|
||||
<state>$PROJ_DIR$</state>
|
||||
<state>$PROJ_DIR$\..\..\include</state>
|
||||
<state>$PROJ_DIR$\..\..\src</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCStdIncCheck</name>
|
||||
@@ -702,6 +710,7 @@
|
||||
<data>
|
||||
<extensions></extensions>
|
||||
<cmdline></cmdline>
|
||||
<hasPrio>0</hasPrio>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
@@ -719,9 +728,9 @@
|
||||
</settings>
|
||||
<settings>
|
||||
<name>XLINK</name>
|
||||
<archiveVersion>2</archiveVersion>
|
||||
<archiveVersion>3</archiveVersion>
|
||||
<data>
|
||||
<version>14</version>
|
||||
<version>16</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>1</debug>
|
||||
<option>
|
||||
@@ -739,7 +748,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>FormatVariant</name>
|
||||
<version>8</version>
|
||||
<version>9</version>
|
||||
<state>2</state>
|
||||
</option>
|
||||
<option>
|
||||
@@ -921,7 +930,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>ExtraFormatVariant</name>
|
||||
<version>8</version>
|
||||
<version>9</version>
|
||||
<state>2</state>
|
||||
</option>
|
||||
<option>
|
||||
@@ -985,6 +994,46 @@
|
||||
<version>0</version>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogInputFiles</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogModuleSelection</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogPrintfScanf</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogSegmentSelection</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogStackDepth</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkStackUsageEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkControlFiles</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkCallGraphFileEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkCallGraphFileName</name>
|
||||
<state>$LIST_DIR$\$PROJ_FNAME$.call_graph.cgx</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
@@ -1022,9 +1071,9 @@
|
||||
<debug>0</debug>
|
||||
<settings>
|
||||
<name>General</name>
|
||||
<archiveVersion>11</archiveVersion>
|
||||
<archiveVersion>12</archiveVersion>
|
||||
<data>
|
||||
<version>9</version>
|
||||
<version>10</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
@@ -1231,6 +1280,14 @@
|
||||
<name>GenDeviceSelectMenu</name>
|
||||
<state>m168 ATmega168</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OGProductVersion</name>
|
||||
<state>6.80.1.1057</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>OGLastSavedByProductVersion</name>
|
||||
<state></state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
@@ -1424,7 +1481,7 @@
|
||||
<option>
|
||||
<name>newCCIncludePaths</name>
|
||||
<state>$PROJ_DIR$</state>
|
||||
<state>$PROJ_DIR$\..\..\include</state>
|
||||
<state>$PROJ_DIR$\..\..\src</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>CCStdIncCheck</name>
|
||||
@@ -1715,6 +1772,7 @@
|
||||
<data>
|
||||
<extensions></extensions>
|
||||
<cmdline></cmdline>
|
||||
<hasPrio>0</hasPrio>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
@@ -1732,9 +1790,9 @@
|
||||
</settings>
|
||||
<settings>
|
||||
<name>XLINK</name>
|
||||
<archiveVersion>2</archiveVersion>
|
||||
<archiveVersion>3</archiveVersion>
|
||||
<data>
|
||||
<version>14</version>
|
||||
<version>16</version>
|
||||
<wantNonLocal>1</wantNonLocal>
|
||||
<debug>0</debug>
|
||||
<option>
|
||||
@@ -1752,7 +1810,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>FormatVariant</name>
|
||||
<version>8</version>
|
||||
<version>9</version>
|
||||
<state>2</state>
|
||||
</option>
|
||||
<option>
|
||||
@@ -1936,7 +1994,7 @@
|
||||
</option>
|
||||
<option>
|
||||
<name>ExtraFormatVariant</name>
|
||||
<version>8</version>
|
||||
<version>9</version>
|
||||
<state>2</state>
|
||||
</option>
|
||||
<option>
|
||||
@@ -2000,6 +2058,46 @@
|
||||
<version>0</version>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogInputFiles</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogModuleSelection</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogPrintfScanf</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogSegmentSelection</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkLogStackDepth</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkStackUsageEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkControlFiles</name>
|
||||
<state></state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkCallGraphFileEnable</name>
|
||||
<state>0</state>
|
||||
</option>
|
||||
<option>
|
||||
<name>XlinkCallGraphFileName</name>
|
||||
<state>$LIST_DIR$\$PROJ_FNAME$.call_graph.cgx</state>
|
||||
</option>
|
||||
</data>
|
||||
</settings>
|
||||
<settings>
|
||||
@@ -2030,63 +2128,63 @@
|
||||
</settings>
|
||||
</configuration>
|
||||
<group>
|
||||
<name>BACnet-Core</name>
|
||||
<name>BACnet-Basic</name>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\abort.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\datalink\crc.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacapp.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\basic\service\h_noserv.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacdcode.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\basic\npdu\h_npdu.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacerror.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\basic\service\s_iam.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacint.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacreal.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacstr.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\crc.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\iam.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\npdu.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\reject.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\rp.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\whois.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\wp.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\basic\tsm\tsm.c</name>
|
||||
</file>
|
||||
</group>
|
||||
<group>
|
||||
<name>BACnet-Handlers</name>
|
||||
<name>BACnet-Core</name>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\demo\handler\h_npdu.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\abort.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\demo\handler\noserv.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\bacapp.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\demo\handler\s_iam.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\bacdcode.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\demo\handler\txbuf.c</name>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\bacerror.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\bacint.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\bacreal.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\bacstr.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\iam.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\npdu.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\reject.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\rp.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\whois.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\src\bacnet\wp.c</name>
|
||||
</file>
|
||||
</group>
|
||||
<file>
|
||||
@@ -2095,9 +2193,6 @@
|
||||
<file>
|
||||
<name>$PROJ_DIR$\av.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\avr035.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\bv.c</name>
|
||||
</file>
|
||||
|
||||
+42
-43
@@ -29,12 +29,16 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "hardware.h"
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "wp.h"
|
||||
#include "bv.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
|
||||
#ifndef MAX_BINARY_VALUES
|
||||
#define MAX_BINARY_VALUES 10
|
||||
#endif
|
||||
|
||||
#if (MAX_BINARY_VALUES > 10)
|
||||
#error Modify the Binary_Value_Name to handle multiple digits
|
||||
@@ -105,31 +109,28 @@ char *Binary_Value_Name(
|
||||
}
|
||||
|
||||
/* 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 Binary_Value_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
{
|
||||
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;
|
||||
uint8_t *apdu;
|
||||
|
||||
switch (property) {
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE,
|
||||
object_instance);
|
||||
rpdata->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));
|
||||
Binary_Value_Name(rpdata->object_instance));
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
@@ -138,7 +139,7 @@ int Binary_Value_Encode_Property_APDU(
|
||||
encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
|
||||
break;
|
||||
case PROP_PRESENT_VALUE:
|
||||
present_value = Binary_Value_Present_Value(object_instance);
|
||||
present_value = Binary_Value_Present_Value(rpdata->object_instance);
|
||||
apdu_len = encode_application_enumerated(&apdu[0], present_value);
|
||||
break;
|
||||
case PROP_STATUS_FLAGS:
|
||||
@@ -163,16 +164,16 @@ int Binary_Value_Encode_Property_APDU(
|
||||
apdu_len = encode_application_enumerated(&apdu[0], polarity);
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = -1;
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
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;
|
||||
if ((apdu_len >= 0) && (rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
@@ -180,9 +181,7 @@ int Binary_Value_Encode_Property_APDU(
|
||||
|
||||
/* 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)
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
unsigned int object_index = 0;
|
||||
@@ -190,8 +189,8 @@ bool Binary_Value_Write_Property(
|
||||
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;
|
||||
wp_data->error_class = ERROR_CLASS_OBJECT;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
return false;
|
||||
}
|
||||
/* decode the some of the request */
|
||||
@@ -201,15 +200,15 @@ bool Binary_Value_Write_Property(
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
if ((wp_data->object_property != PROP_PRIORITY_ARRAY) &&
|
||||
(wp_data->array_index != BACNET_ARRAY_ALL)) {
|
||||
/* only array properties can have array options */
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
}
|
||||
switch (wp_data->object_property) {
|
||||
@@ -234,12 +233,12 @@ bool Binary_Value_Write_Property(
|
||||
}
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case PROP_OUT_OF_SERVICE:
|
||||
@@ -250,8 +249,8 @@ bool Binary_Value_Write_Property(
|
||||
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;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -261,12 +260,12 @@ bool Binary_Value_Write_Property(
|
||||
case PROP_STATUS_FLAGS:
|
||||
case PROP_EVENT_STATE:
|
||||
case PROP_POLARITY:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacerror.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
#ifndef MAX_BINARY_VALUES
|
||||
#define MAX_BINARY_VALUES 10
|
||||
|
||||
+70
-75
@@ -25,21 +25,22 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacstr.h"
|
||||
#include "bacenum.h"
|
||||
#include "apdu.h"
|
||||
#include "dcc.h"
|
||||
#include "dlmstp.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacstr.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/dcc.h"
|
||||
#include "bacnet/datalink/dlmstp.h"
|
||||
#include "rs485.h"
|
||||
#include "version.h"
|
||||
#include "bacnet/version.h"
|
||||
#include "stack.h"
|
||||
/* objects */
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bv.h"
|
||||
#include "wp.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
#include "bacnet/wp.h"
|
||||
|
||||
/* note: you really only need to define variables for
|
||||
properties that are writable or that may change.
|
||||
@@ -50,8 +51,9 @@ static char Object_Name[20] = "My Device";
|
||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||
|
||||
void Device_Init(
|
||||
void)
|
||||
object_functions_t * object_table)
|
||||
{
|
||||
(void)object_table;
|
||||
/* Reinitialize_State = BACNET_REINIT_IDLE; */
|
||||
/* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */
|
||||
/* FIXME: Get the data from the eeprom */
|
||||
@@ -161,14 +163,10 @@ bool Device_Object_List_Identifier(
|
||||
}
|
||||
|
||||
/* return the length of the apdu encoded or -1 for error */
|
||||
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)
|
||||
int Device_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
{
|
||||
uint8_t * apdu;
|
||||
int apdu_len = 0; /* return value */
|
||||
int len = 0; /* apdu len intermediate value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
@@ -178,9 +176,8 @@ int Device_Encode_Property_APDU(
|
||||
uint32_t instance = 0;
|
||||
uint32_t count = 0;
|
||||
|
||||
object_instance = object_instance;
|
||||
/* FIXME: change the hardcoded names to suit your application */
|
||||
switch (property) {
|
||||
apdu = rpdata->application_data;
|
||||
switch (rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
|
||||
@@ -259,13 +256,13 @@ int Device_Encode_Property_APDU(
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
/* Array element zero is the number of objects in the list */
|
||||
if (array_index == 0)
|
||||
if (rpdata->array_index == 0)
|
||||
apdu_len = encode_application_unsigned(&apdu[0], count);
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. Note that more than likely you will have */
|
||||
/* to return an error if the number of encoded objects exceeds */
|
||||
/* your maximum APDU size. */
|
||||
else if (array_index == BACNET_ARRAY_ALL) {
|
||||
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
for (i = 1; i <= count; i++) {
|
||||
Device_Object_List_Identifier(i, &object_type, &instance);
|
||||
len =
|
||||
@@ -276,21 +273,21 @@ int Device_Encode_Property_APDU(
|
||||
/* can we all fit into the APDU? */
|
||||
if ((apdu_len + len) >= MAX_APDU) {
|
||||
/* Abort response */
|
||||
*error_code =
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
apdu_len = BACNET_STATUS_ABORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Device_Object_List_Identifier(array_index, &object_type,
|
||||
&instance))
|
||||
if (Device_Object_List_Identifier(rpdata->array_index,
|
||||
&object_type, &instance))
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], object_type,
|
||||
instance);
|
||||
else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -323,27 +320,27 @@ int Device_Encode_Property_APDU(
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0], dlmstp_max_master());
|
||||
break;
|
||||
case 9600:
|
||||
case (BACNET_PROPERTY_ID)9600:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate());
|
||||
break;
|
||||
case 512:
|
||||
case (BACNET_PROPERTY_ID)512:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], stack_size());
|
||||
break;
|
||||
case 513:
|
||||
case (BACNET_PROPERTY_ID)513:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = -1;
|
||||
break;
|
||||
}
|
||||
/* only array properties can have array options */
|
||||
if ((apdu_len >= 0) && (property != PROP_OBJECT_LIST) &&
|
||||
(array_index != BACNET_ARRAY_ALL)) {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) &&
|
||||
(rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
|
||||
@@ -351,17 +348,15 @@ int Device_Encode_Property_APDU(
|
||||
}
|
||||
|
||||
bool Device_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
BACNET_WRITE_PROPERTY_DATA * wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
int len = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value;
|
||||
|
||||
if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) {
|
||||
*error_class = ERROR_CLASS_OBJECT;
|
||||
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
wp_data->error_class = ERROR_CLASS_OBJECT;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
return false;
|
||||
}
|
||||
/* decode the some of the request */
|
||||
@@ -371,15 +366,15 @@ bool Device_Write_Property(
|
||||
/* FIXME: len < application_data_len: more data? */
|
||||
if (len < 0) {
|
||||
/* error while decoding - a value larger than we can handle */
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
if ((wp_data->object_property != PROP_OBJECT_LIST) &&
|
||||
(wp_data->array_index != BACNET_ARRAY_ALL)) {
|
||||
/* only array properties can have array options */
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
return false;
|
||||
}
|
||||
switch (wp_data->object_property) {
|
||||
@@ -391,12 +386,12 @@ bool Device_Write_Property(
|
||||
/* we could send an I-Am broadcast to let the world know */
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case PROP_MAX_INFO_FRAMES:
|
||||
@@ -405,12 +400,12 @@ bool Device_Write_Property(
|
||||
dlmstp_set_max_info_frames(value.type.Unsigned_Int);
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case PROP_MAX_MASTER:
|
||||
@@ -420,12 +415,12 @@ bool Device_Write_Property(
|
||||
dlmstp_set_max_master(value.type.Unsigned_Int);
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
@@ -440,30 +435,30 @@ bool Device_Write_Property(
|
||||
&value.type.Character_String)) {
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case 9600:
|
||||
case (BACNET_PROPERTY_ID)9600:
|
||||
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||
if (value.type.Unsigned_Int > 115200) {
|
||||
RS485_Set_Baud_Rate(value.type.Unsigned_Int);
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
break;
|
||||
case PROP_NUMBER_OF_APDU_RETRIES:
|
||||
@@ -490,12 +485,12 @@ bool Device_Write_Property(
|
||||
case PROP_DEVICE_ADDRESS_BINDING:
|
||||
case PROP_DATABASE_REVISION:
|
||||
case PROP_ACTIVE_COV_SUBSCRIPTIONS:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacenum.h"
|
||||
#include "wp.h"
|
||||
#include "readrange.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/readrange.h"
|
||||
|
||||
typedef unsigned (
|
||||
*object_count_function) (
|
||||
|
||||
+10
-10
@@ -36,18 +36,18 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "bacdef.h"
|
||||
#include "mstpdef.h"
|
||||
#include "dlmstp.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/datalink/mstpdef.h"
|
||||
#include "bacnet/datalink/dlmstp.h"
|
||||
#include "rs485.h"
|
||||
#include "crc.h"
|
||||
#include "npdu.h"
|
||||
#include "bits.h"
|
||||
#include "bytes.h"
|
||||
#include "bacaddr.h"
|
||||
#include "bacnet/datalink/crc.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/bits.h"
|
||||
#include "bacnet/bytes.h"
|
||||
#include "bacnet/bacaddr.h"
|
||||
/* special optimization - I-Am response in this module */
|
||||
#include "client.h"
|
||||
#include "txbuf.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
|
||||
/* This file has been customized for use with small microprocessors */
|
||||
/* Assumptions:
|
||||
|
||||
+29
-39
@@ -27,63 +27,53 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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 "rp.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/abort.h"
|
||||
#include "bacnet/rp.h"
|
||||
/* demo objects */
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bv.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
|
||||
/* Encodes the property APDU and returns the length,
|
||||
or sets the error, and returns -1 */
|
||||
int Encode_Property_APDU(
|
||||
uint8_t * apdu,
|
||||
BACNET_READ_PROPERTY_DATA * rp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code)
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
{
|
||||
int apdu_len = -1;
|
||||
|
||||
/* handle each object type */
|
||||
switch (rp_data->object_type) {
|
||||
switch (rpdata->object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
/* Test for case of indefinite Device object instance */
|
||||
if (rp_data->object_instance == BACNET_MAX_INSTANCE) {
|
||||
rp_data->object_instance = Device_Object_Instance_Number();
|
||||
if (rpdata->object_instance == BACNET_MAX_INSTANCE) {
|
||||
rpdata->object_instance = Device_Object_Instance_Number();
|
||||
}
|
||||
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
||||
apdu_len =
|
||||
Device_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
if (Device_Valid_Object_Instance_Number(rpdata->object_instance)) {
|
||||
apdu_len = Device_Read_Property(rpdata);
|
||||
}
|
||||
break;
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
|
||||
apdu_len =
|
||||
Analog_Value_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
if (Analog_Value_Valid_Instance(rpdata->object_instance)) {
|
||||
apdu_len = Analog_Value_Read_Property(rpdata);
|
||||
}
|
||||
break;
|
||||
case OBJECT_BINARY_VALUE:
|
||||
if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
|
||||
apdu_len =
|
||||
Binary_Value_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
if (Binary_Value_Valid_Instance(rpdata->object_instance)) {
|
||||
apdu_len = Binary_Value_Read_Property(rpdata);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*error_class = ERROR_CLASS_OBJECT;
|
||||
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
rpdata->error_class = ERROR_CLASS_OBJECT;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -103,8 +93,6 @@ void handler_read_property(
|
||||
int pdu_len = 0;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
int bytes_sent = 0;
|
||||
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
BACNET_ADDRESS my_address;
|
||||
|
||||
/* encode the NPDU portion of the packet */
|
||||
@@ -134,9 +122,11 @@ void handler_read_property(
|
||||
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, &data);
|
||||
/* FIXME: add buffer len as passed into function or use smart buffer */
|
||||
data.error_class = ERROR_CLASS_OBJECT;
|
||||
data.error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
property_len =
|
||||
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len],
|
||||
&data, &error_class, &error_code);
|
||||
&data);
|
||||
if (property_len >= 0) {
|
||||
len =
|
||||
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer
|
||||
@@ -155,7 +145,7 @@ void handler_read_property(
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
error_class, error_code);
|
||||
data.error_class, data.error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +27,15 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/whois.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
|
||||
bool Send_I_Am_Flag = true;
|
||||
|
||||
|
||||
+25
-26
@@ -27,19 +27,20 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#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"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacerror.h"
|
||||
#include "bacnet/apdu.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/abort.h"
|
||||
#include "bacnet/wp.h"
|
||||
/* demo objects */
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bv.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/object/bv.h"
|
||||
|
||||
/* too big to reside on stack frame for PIC */
|
||||
static BACNET_WRITE_PROPERTY_DATA wp_data;
|
||||
@@ -53,8 +54,6 @@ void handler_write_property(
|
||||
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;
|
||||
int bytes_sent = 0;
|
||||
BACNET_ADDRESS my_address;
|
||||
|
||||
@@ -77,9 +76,11 @@ void handler_write_property(
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
} else {
|
||||
wp_data.error_class = ERROR_CLASS_OBJECT;
|
||||
wp_data.error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
switch (wp_data.object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
|
||||
if (Device_Write_Property(&wp_data)) {
|
||||
len =
|
||||
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
@@ -88,13 +89,12 @@ void handler_write_property(
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class,
|
||||
wp_data.error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
if (Analog_Value_Write_Property(&wp_data, &error_class,
|
||||
&error_code)) {
|
||||
if (Analog_Value_Write_Property(&wp_data)) {
|
||||
len =
|
||||
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
@@ -103,13 +103,12 @@ void handler_write_property(
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class,
|
||||
wp_data.error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_BINARY_VALUE:
|
||||
if (Binary_Value_Write_Property(&wp_data, &error_class,
|
||||
&error_code)) {
|
||||
if (Binary_Value_Write_Property(&wp_data)) {
|
||||
len =
|
||||
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
@@ -118,15 +117,15 @@ void handler_write_property(
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class,
|
||||
wp_data.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);
|
||||
wp_data.error_class, wp_data.error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#endif
|
||||
#endif
|
||||
#include "iar2gcc.h"
|
||||
#include "avr035.h"
|
||||
#include "bacnet/bits.h"
|
||||
|
||||
#define LED_NPDU_INIT() BIT_SET(DDRD, DDD5)
|
||||
#define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5)
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
#include "hardware.h"
|
||||
#include "timer.h"
|
||||
#include "rs485.h"
|
||||
#include "datalink.h"
|
||||
#include "npdu.h"
|
||||
#include "handlers.h"
|
||||
#include "txbuf.h"
|
||||
#include "iam.h"
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/basic/tsm/tsm.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
|
||||
/* From the WhoIs hander - performed by the DLMSTP module */
|
||||
extern bool Send_I_Am_Flag;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
/*#include "mstp.h" */
|
||||
/*#include "bacnet/datalink/mstp.h" */
|
||||
|
||||
/* This file has been customized for use with ATMEGA168 */
|
||||
#include "hardware.h"
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
###############################################################################
|
||||
# Makefile for BACnet
|
||||
###############################################################################
|
||||
|
||||
## General Flags
|
||||
PROJECT = bacnet
|
||||
MCU = atmega168
|
||||
TARGET = bacnet
|
||||
## Tools
|
||||
CC = avr-gcc
|
||||
AR = avr-ar
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
|
||||
# Source locations
|
||||
BACNET_CORE = ../../src
|
||||
BACNET_INCLUDE = ../../include
|
||||
BACNET_OBJECT_INCLUDE = ../../demo/object
|
||||
BACNET_DEMO = ../../demo
|
||||
|
||||
# local files for this project
|
||||
CSRC = apdu.c \
|
||||
device.c \
|
||||
dlmstp.c \
|
||||
main.c \
|
||||
rs485.c \
|
||||
timer.c
|
||||
|
||||
# common demo files needed
|
||||
DEMOSRC = \
|
||||
$(BACNET_DEMO)/handler/h_rp.c \
|
||||
$(BACNET_DEMO)/handler/txbuf.c \
|
||||
$(BACNET_DEMO)/handler/h_npdu.c \
|
||||
$(BACNET_DEMO)/handler/noserv.c
|
||||
|
||||
# core BACnet stack files - place into library
|
||||
CORESRC = \
|
||||
$(BACNET_CORE)/crc.c \
|
||||
$(BACNET_CORE)/abort.c \
|
||||
$(BACNET_CORE)/apdu.c \
|
||||
$(BACNET_CORE)/bacapp.c \
|
||||
$(BACNET_CORE)/bacdcode.c \
|
||||
$(BACNET_CORE)/bacerror.c \
|
||||
$(BACNET_CORE)/bacint.c \
|
||||
$(BACNET_CORE)/bacreal.c \
|
||||
$(BACNET_CORE)/bacstr.c \
|
||||
$(BACNET_CORE)/bacaddr.c \
|
||||
$(BACNET_CORE)/npdu.c \
|
||||
$(BACNET_CORE)/reject.c \
|
||||
$(BACNET_CORE)/rp.c
|
||||
|
||||
# $(BACNET_CORE)/iam.c \
|
||||
# $(BACNET_CORE)/whois.c \
|
||||
# $(BACNET_CORE)/wp.c \
|
||||
# $(BACNET_CORE)/version.c
|
||||
# $(BACNET_CORE)/bacprop.c \
|
||||
# $(BACNET_CORE)/bactext.c \
|
||||
# $(BACNET_CORE)/datetime.c \
|
||||
# $(BACNET_CORE)/indtext.c \
|
||||
# $(BACNET_CORE)/bigend.c \
|
||||
# $(BACNET_CORE)/arf.c \
|
||||
# $(BACNET_CORE)/awf.c \
|
||||
# $(BACNET_CORE)/cov.c \
|
||||
# $(BACNET_CORE)/dcc.c \
|
||||
# $(BACNET_CORE)/iam/iam_client.c \
|
||||
# $(BACNET_CORE)/ihave.c \
|
||||
# $(BACNET_CORE)/rd.c \
|
||||
# $(BACNET_CORE)/rpm.c \
|
||||
# $(BACNET_CORE)/timesync.c \
|
||||
# $(BACNET_CORE)/whohas.c \
|
||||
# $(BACNET_CORE)/filename.c \
|
||||
# $(BACNET_CORE)/tsm.c \
|
||||
# $(BACNET_CORE)/address.c \
|
||||
|
||||
## Include Directories
|
||||
INCLUDES = -I. -I$(BACNET_INCLUDE) -I$(BACNET_OBJECT_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)
|
||||
|
||||
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.
|
||||
BFLAGS = -DBACDL_MSTP
|
||||
BFLAGS += -DMAX_APDU=50
|
||||
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=0
|
||||
BFLAGS += -DMAX_BINARY_VALUES=0
|
||||
CFLAGS = $(COMMON)
|
||||
# dead code removal
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
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,-nostartfiles,-nostdlib
|
||||
LDFLAGS += -Wl,--gc-sections,-static
|
||||
LDFLAGS += -Wl,-Map=$(TARGET).map,-L.,-l$(TARGET)
|
||||
#LDFLAGS += -Wl,-Map=$(TARGET).map
|
||||
|
||||
## 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: $(LIBRARY) $(TARGET_ELF) $(TARGET).hex $(TARGET).eep $(TARGET).lst \
|
||||
size Makefile
|
||||
|
||||
##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 $@
|
||||
|
||||
size: ${TARGET_ELF}
|
||||
@echo
|
||||
@${SIZE} -C --mcu=${MCU} ${TARGET_ELF}
|
||||
|
||||
## Clean target
|
||||
.PHONY: clean
|
||||
clean:
|
||||
-rm -rf $(OBJECTS) $(TARGET_ELF) dep/*
|
||||
-rm -rf $(LIBRARY) $(COREOBJ) $(LIBRARY:.a=.lst)
|
||||
-rm -rf $(TARGET).hex $(TARGET).eep $(TARGET).lst $(TARGET).map
|
||||
|
||||
## Other dependencies
|
||||
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)
|
||||
@@ -1,123 +0,0 @@
|
||||
/*####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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
handler_unrecognized_service(service_request,
|
||||
service_request_len, src, &service_data);
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
|
||||
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;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef AVR035_H
|
||||
#define AVR035_H
|
||||
|
||||
/* from AVR035: Efficient C Coding for AVR */
|
||||
|
||||
/* a=register, b=bit number to act upon */
|
||||
#define BIT_SET(a,b) ((a) |= (1<<(b)))
|
||||
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
|
||||
#define BIT_FLIP(a,b) ((a) ^= (1<<(b)))
|
||||
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
|
||||
|
||||
/* x=target variable, y=mask */
|
||||
#define BITMASK_SET(x,y) ((x) |= (y))
|
||||
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
|
||||
#define BITMASK_FLIP(x,y) ((x) ^= (y))
|
||||
#define BITMASK_CHECK(x,y) ((x) & (y))
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
|
||||
<workspace>
|
||||
<project>
|
||||
<path>$WS_DIR$\bacnet.ewp</path>
|
||||
</project>
|
||||
<batchBuild/>
|
||||
</workspace>
|
||||
|
||||
|
||||
@@ -1,343 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacstr.h"
|
||||
#include "bacenum.h"
|
||||
#include "apdu.h"
|
||||
#include "dcc.h"
|
||||
#include "dlmstp.h"
|
||||
#include "rs485.h"
|
||||
#include "version.h"
|
||||
/* objects */
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
|
||||
/* note: you really only need to define variables for
|
||||
properties that are writable or that may change.
|
||||
The properties that are constant can be hard coded
|
||||
into the read-property encoding. */
|
||||
static uint32_t Object_Instance_Number = 260001;
|
||||
static char *Object_Name = "My Device";
|
||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||
|
||||
void Device_Init(
|
||||
object_functions_t * object_table)
|
||||
{
|
||||
(void) object_table;
|
||||
/* Reinitialize_State = BACNET_REINIT_IDLE; */
|
||||
/* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */
|
||||
/* FIXME: Get the data from the eeprom */
|
||||
/* I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
|
||||
(char *)&Object_Instance_Number,
|
||||
sizeof(Object_Instance_Number),
|
||||
EEPROM_BACNET_ID_ADDR); */
|
||||
}
|
||||
|
||||
/* methods to manipulate the data */
|
||||
uint32_t Device_Object_Instance_Number(
|
||||
void)
|
||||
{
|
||||
return Object_Instance_Number;
|
||||
}
|
||||
|
||||
bool Device_Set_Object_Instance_Number(
|
||||
uint32_t object_id)
|
||||
{
|
||||
bool status = true; /* return value */
|
||||
|
||||
if (object_id <= BACNET_MAX_INSTANCE) {
|
||||
Object_Instance_Number = object_id;
|
||||
/* FIXME: Write the data to the eeprom */
|
||||
/* I2C_Write_Block(
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
(char *)&Object_Instance_Number,
|
||||
sizeof(Object_Instance_Number),
|
||||
EEPROM_BACNET_ID_ADDR); */
|
||||
} else
|
||||
status = false;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool Device_Valid_Object_Instance_Number(
|
||||
uint32_t object_id)
|
||||
{
|
||||
/* BACnet allows for a wildcard instance number */
|
||||
return ((Object_Instance_Number == object_id) ||
|
||||
(object_id == BACNET_MAX_INSTANCE));
|
||||
}
|
||||
|
||||
uint16_t Device_Vendor_Identifier(
|
||||
void)
|
||||
{
|
||||
return BACNET_VENDOR_ID;
|
||||
}
|
||||
|
||||
unsigned Device_Object_List_Count(
|
||||
void)
|
||||
{
|
||||
unsigned count = 1; /* at least 1 for device object */
|
||||
|
||||
#if MAX_ANALOG_VALUES
|
||||
/* FIXME: add objects as needed */
|
||||
count += Analog_Value_Count();
|
||||
#endif
|
||||
#if MAX_BINARY_VALUES
|
||||
/* FIXME: add objects as needed */
|
||||
count += Binary_Value_Count();
|
||||
#endif
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Device_Object_List_Identifier(
|
||||
uint32_t array_index,
|
||||
int *object_type,
|
||||
uint32_t * instance)
|
||||
{
|
||||
bool status = false;
|
||||
uint32_t object_index = 0;
|
||||
uint32_t object_count = 0;
|
||||
|
||||
/* device object */
|
||||
if (array_index == 1) {
|
||||
*object_type = OBJECT_DEVICE;
|
||||
*instance = Object_Instance_Number;
|
||||
status = true;
|
||||
}
|
||||
/* normalize the index since
|
||||
we know it is not the previous objects */
|
||||
/* array index starts at 1 */
|
||||
object_index = array_index - 1;
|
||||
/* 1 for the device object */
|
||||
object_count = 1;
|
||||
/* FIXME: add objects as needed */
|
||||
#if MAX_ANALOG_VALUES
|
||||
/* analog value objects */
|
||||
if (!status) {
|
||||
/* array index starts at 1, and 1 for the device object */
|
||||
object_index -= object_count;
|
||||
object_count = Analog_Value_Count();
|
||||
if (object_index < object_count) {
|
||||
*object_type = OBJECT_ANALOG_VALUE;
|
||||
*instance = Analog_Value_Index_To_Instance(object_index);
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if MAX_BINARY_VALUES
|
||||
/* binary value objects */
|
||||
if (!status) {
|
||||
object_index -= object_count;
|
||||
object_count = Binary_Value_Count();
|
||||
/* is it a valid index for this object? */
|
||||
if (object_index < object_count) {
|
||||
*object_type = OBJECT_BINARY_VALUE;
|
||||
*instance = Binary_Value_Index_To_Instance(object_index);
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* return the length of the apdu encoded or -1 for error */
|
||||
int Device_Read_Property(
|
||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||
{
|
||||
int apdu_len = 0; /* return value */
|
||||
int len = 0; /* apdu len intermediate value */
|
||||
BACNET_BIT_STRING bit_string;
|
||||
BACNET_CHARACTER_STRING char_string;
|
||||
uint32_t i = 0;
|
||||
int object_type = 0;
|
||||
uint32_t instance = 0;
|
||||
uint32_t count = 0;
|
||||
uint8_t *apdu = NULL;
|
||||
|
||||
if ((rpdata->application_data == NULL) ||
|
||||
(rpdata->application_data_len == 0)) {
|
||||
return 0;
|
||||
}
|
||||
apdu = rpdata->application_data;
|
||||
/* FIXME: change the hardcoded names to suit your application */
|
||||
switch ((int) rpdata->object_property) {
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], rpdata->object_type,
|
||||
rpdata->object_instance);
|
||||
break;
|
||||
case PROP_OBJECT_NAME:
|
||||
characterstring_init_ansi(&char_string, Object_Name);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_OBJECT_TYPE:
|
||||
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
|
||||
break;
|
||||
case PROP_SYSTEM_STATUS:
|
||||
apdu_len = encode_application_enumerated(&apdu[0], System_Status);
|
||||
break;
|
||||
case PROP_VENDOR_NAME:
|
||||
characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_VENDOR_IDENTIFIER:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0],
|
||||
Device_Vendor_Identifier());
|
||||
break;
|
||||
case PROP_MODEL_NAME:
|
||||
characterstring_init_ansi(&char_string, "GNU Demo");
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_FIRMWARE_REVISION:
|
||||
characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT);
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_APPLICATION_SOFTWARE_VERSION:
|
||||
characterstring_init_ansi(&char_string, "1.0");
|
||||
apdu_len =
|
||||
encode_application_character_string(&apdu[0], &char_string);
|
||||
break;
|
||||
case PROP_PROTOCOL_VERSION:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_VERSION);
|
||||
break;
|
||||
case PROP_PROTOCOL_REVISION:
|
||||
apdu_len =
|
||||
encode_application_unsigned(&apdu[0],
|
||||
BACNET_PROTOCOL_REVISION);
|
||||
break;
|
||||
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
||||
/* Note: list of services that are executed, not initiated. */
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* automatic lookup based on handlers set */
|
||||
bitstring_set_bit(&bit_string, (uint8_t) i,
|
||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
|
||||
}
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
|
||||
/* Note: this is the list of objects that can be in this device,
|
||||
not a list of objects that this device can access */
|
||||
bitstring_init(&bit_string);
|
||||
/* must have the bit string as big as it can be */
|
||||
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
|
||||
/* initialize all the object types to not-supported */
|
||||
bitstring_set_bit(&bit_string, (uint8_t) i, false);
|
||||
}
|
||||
/* FIXME: indicate the objects that YOU support */
|
||||
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
|
||||
#if MAX_ANALOG_VALUES
|
||||
bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true);
|
||||
#endif
|
||||
#if MAX_BINARY_VALUES
|
||||
bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true);
|
||||
#endif
|
||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
break;
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
/* Array element zero is the number of objects in the list */
|
||||
if (rpdata->array_index == 0)
|
||||
apdu_len = encode_application_unsigned(&apdu[0], count);
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. Note that more than likely you will have */
|
||||
/* to return an error if the number of encoded objects exceeds */
|
||||
/* your maximum APDU size. */
|
||||
else if (rpdata->array_index == BACNET_ARRAY_ALL) {
|
||||
for (i = 1; i <= count; i++) {
|
||||
Device_Object_List_Identifier(i, &object_type, &instance);
|
||||
len =
|
||||
encode_application_object_id(&apdu[apdu_len],
|
||||
object_type, instance);
|
||||
apdu_len += len;
|
||||
/* assume next one is the same size as this one */
|
||||
/* can we all fit into the APDU? */
|
||||
if ((apdu_len + len) >= MAX_APDU) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
apdu_len = BACNET_STATUS_ABORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Device_Object_List_Identifier(rpdata->array_index,
|
||||
&object_type, &instance))
|
||||
apdu_len =
|
||||
encode_application_object_id(&apdu[0], object_type,
|
||||
instance);
|
||||
else {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PROP_MAX_APDU_LENGTH_ACCEPTED:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
|
||||
break;
|
||||
case PROP_SEGMENTATION_SUPPORTED:
|
||||
apdu_len =
|
||||
encode_application_enumerated(&apdu[0], SEGMENTATION_NONE);
|
||||
break;
|
||||
case PROP_APDU_TIMEOUT:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], 60000);
|
||||
break;
|
||||
case PROP_NUMBER_OF_APDU_RETRIES:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
||||
break;
|
||||
case PROP_DEVICE_ADDRESS_BINDING:
|
||||
/* FIXME: encode the list here, if it exists */
|
||||
break;
|
||||
case PROP_DATABASE_REVISION:
|
||||
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
||||
break;
|
||||
default:
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||
apdu_len = -1;
|
||||
break;
|
||||
}
|
||||
/* only array properties can have array options */
|
||||
if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) &&
|
||||
(rpdata->array_index != BACNET_ARRAY_ALL)) {
|
||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
@@ -1,607 +0,0 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2008 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "bacdef.h"
|
||||
#include "mstpdef.h"
|
||||
#include "dlmstp.h"
|
||||
#include "rs485.h"
|
||||
#include "crc.h"
|
||||
#include "npdu.h"
|
||||
#include "bits.h"
|
||||
#include "bytes.h"
|
||||
#include "bacaddr.h"
|
||||
/* special optimization - I-Am response in this module */
|
||||
#include "client.h"
|
||||
#include "txbuf.h"
|
||||
|
||||
/* This file has been customized for use with small microprocessors */
|
||||
/* Assumptions:
|
||||
Only one slave node MS/TP datalink layer
|
||||
*/
|
||||
#include "hardware.h"
|
||||
#include "timer.h"
|
||||
|
||||
/* The state of the Receive State Machine */
|
||||
static MSTP_RECEIVE_STATE Receive_State;
|
||||
static struct mstp_flag_t {
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if an invalid frame is received. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceivedInvalidFrame:1;
|
||||
/* A Boolean flag set to TRUE by the Receive State Machine */
|
||||
/* if a valid frame is received. */
|
||||
/* Set to FALSE by the main state machine. */
|
||||
unsigned ReceivedValidFrame:1;
|
||||
/* A Boolean flag set TRUE by the datalink transmit if a
|
||||
frame is pending */
|
||||
unsigned TransmitPacketPending:1;
|
||||
/* A Boolean flag set TRUE by the datalink transmit if a
|
||||
pending packet is DataExpectingReply */
|
||||
unsigned TransmitPacketDER:1;
|
||||
/* A Boolean flag set TRUE by the datalink if a
|
||||
packet has been received, but not processed. */
|
||||
unsigned ReceivePacketPending:1;
|
||||
} MSTP_Flag;
|
||||
|
||||
/* Used to store the data length of a received frame. */
|
||||
static uint16_t DataLength;
|
||||
/* Used to store the destination address of a received frame. */
|
||||
static uint8_t DestinationAddress;
|
||||
/* Used to store the frame type of a received frame. */
|
||||
static uint8_t FrameType;
|
||||
/* An array of octets, used to store octets as they are received. */
|
||||
/* InputBuffer is indexed from 0 to InputBufferSize-1. */
|
||||
/* FIXME: assign this to an actual array of bytes! */
|
||||
/* Note: the buffer is designed as a pointer since some compilers
|
||||
and microcontroller architectures have limits as to places to
|
||||
hold contiguous memory. */
|
||||
static uint8_t *InputBuffer;
|
||||
static uint16_t InputBufferSize;
|
||||
/* Used to store the Source Address of a received frame. */
|
||||
static uint8_t SourceAddress;
|
||||
/* "This Station," the MAC address of this node. TS is generally read from a */
|
||||
/* hardware DIP switch, or from nonvolatile memory. Valid values for TS are */
|
||||
/* 0 to 254. The value 255 is used to denote broadcast when used as a */
|
||||
/* destination address but is not allowed as a value for TS. */
|
||||
static uint8_t This_Station;
|
||||
/* An array of octets, used to store octets for transmitting */
|
||||
/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */
|
||||
/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */
|
||||
/* FIXME: assign this to an actual array of bytes! */
|
||||
/* Note: the buffer is designed as a pointer since some compilers
|
||||
and microcontroller architectures have limits as to places to
|
||||
hold contiguous memory. */
|
||||
static uint8_t *TransmitPacket;
|
||||
static uint16_t TransmitPacketLen;
|
||||
static uint8_t TransmitPacketDest;
|
||||
|
||||
/* The minimum time without a DataAvailable or ReceiveError event within */
|
||||
/* a frame before a receiving node may discard the frame: 60 bit times. */
|
||||
/* (Implementations may use larger values for this timeout, */
|
||||
/* not to exceed 100 milliseconds.) */
|
||||
/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */
|
||||
/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */
|
||||
#define Tframe_abort 30
|
||||
|
||||
/* The maximum time a node may wait after reception of a frame that expects */
|
||||
/* a reply before sending the first octet of a reply or Reply Postponed */
|
||||
/* frame: 250 milliseconds. */
|
||||
#define Treply_delay 250
|
||||
|
||||
/* we need to be able to increment without rolling over */
|
||||
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;}
|
||||
|
||||
bool dlmstp_init(
|
||||
char *ifname)
|
||||
{
|
||||
ifname = ifname;
|
||||
/* initialize hardware */
|
||||
RS485_Initialize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dlmstp_cleanup(
|
||||
void)
|
||||
{
|
||||
/* nothing to do for static buffers */
|
||||
}
|
||||
|
||||
void dlmstp_fill_bacnet_address(
|
||||
BACNET_ADDRESS * src,
|
||||
uint8_t mstp_address)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (mstp_address == MSTP_BROADCAST_ADDRESS) {
|
||||
/* mac_len = 0 if broadcast address */
|
||||
src->mac_len = 0;
|
||||
src->mac[0] = 0;
|
||||
} else {
|
||||
src->mac_len = 1;
|
||||
src->mac[0] = mstp_address;
|
||||
}
|
||||
/* fill with 0's starting with index 1; index 0 filled above */
|
||||
for (i = 1; i < MAX_MAC_LEN; i++) {
|
||||
src->mac[i] = 0;
|
||||
}
|
||||
src->net = 0;
|
||||
src->len = 0;
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
src->adr[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* MS/TP Frame Format */
|
||||
/* All frames are of the following format: */
|
||||
/* */
|
||||
/* Preamble: two octet preamble: X`55', X`FF' */
|
||||
/* Frame Type: one octet */
|
||||
/* Destination Address: one octet address */
|
||||
/* Source Address: one octet address */
|
||||
/* Length: two octets, most significant octet first, of the Data field */
|
||||
/* Header CRC: one octet */
|
||||
/* Data: (present only if Length is non-zero) */
|
||||
/* Data CRC: (present only if Length is non-zero) two octets, */
|
||||
/* least significant octet first */
|
||||
/* (pad): (optional) at most one octet of padding: X'FF' */
|
||||
static void MSTP_Send_Frame(
|
||||
uint8_t frame_type, /* type of frame to send - see defines */
|
||||
uint8_t destination, /* destination address */
|
||||
uint8_t source, /* source address */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
uint16_t pdu_len)
|
||||
{ /* number of bytes of data (up to 501) */
|
||||
uint8_t crc8 = 0xFF; /* used to calculate the crc value */
|
||||
uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */
|
||||
uint8_t buffer[8]; /* stores the header and crc */
|
||||
uint8_t datacrc[2]; /* stores the data crc */
|
||||
uint16_t i = 0; /* used to calculate CRC for data */
|
||||
|
||||
/* create the MS/TP header */
|
||||
buffer[0] = 0x55;
|
||||
buffer[1] = 0xFF;
|
||||
buffer[2] = frame_type;
|
||||
crc8 = CRC_Calc_Header(buffer[2], crc8);
|
||||
buffer[3] = destination;
|
||||
crc8 = CRC_Calc_Header(buffer[3], crc8);
|
||||
buffer[4] = source;
|
||||
crc8 = CRC_Calc_Header(buffer[4], crc8);
|
||||
|
||||
buffer[5] = HI_BYTE(pdu_len);
|
||||
crc8 = CRC_Calc_Header(buffer[5], crc8);
|
||||
buffer[6] = LO_BYTE(pdu_len);
|
||||
crc8 = CRC_Calc_Header(buffer[6], crc8);
|
||||
buffer[7] = ~crc8;
|
||||
if (pdu_len) {
|
||||
/* calculate CRC for any data */
|
||||
for (i = 0; i < pdu_len; i++) {
|
||||
crc16 = CRC_Calc_Data(pdu[i], crc16);
|
||||
}
|
||||
crc16 = ~crc16;
|
||||
datacrc[0] = (crc16 & 0x00FF);
|
||||
datacrc[1] = ((crc16 & 0xFF00) >> 8);
|
||||
}
|
||||
/* now transmit the frame */
|
||||
RS485_Turnaround_Delay();
|
||||
RS485_Transmitter_Enable(true);
|
||||
RS485_Send_Data(buffer, 8);
|
||||
/* send any data */
|
||||
if (pdu_len) {
|
||||
RS485_Send_Data(pdu, pdu_len);
|
||||
RS485_Send_Data(datacrc, 2);
|
||||
}
|
||||
RS485_Transmitter_Enable(false);
|
||||
}
|
||||
|
||||
static void MSTP_Receive_Frame_FSM(
|
||||
void)
|
||||
{
|
||||
/* stores the latest received data octet */
|
||||
uint8_t DataRegister = 0;
|
||||
/* Used to accumulate the CRC on the data field of a frame. */
|
||||
static uint16_t DataCRC = 0;
|
||||
/* Used to accumulate the CRC on the header of a frame. */
|
||||
static uint8_t HeaderCRC = 0;
|
||||
/* Used as an index by the Receive State Machine,
|
||||
up to a maximum value of the MPDU */
|
||||
static uint16_t Index = 0;
|
||||
|
||||
switch (Receive_State) {
|
||||
case MSTP_RECEIVE_STATE_IDLE:
|
||||
/* In the IDLE state, the node waits for the beginning of a frame. */
|
||||
if (RS485_ReceiveError()) {
|
||||
/* EatAnError */
|
||||
timer_silence_reset();
|
||||
} else if (RS485_DataAvailable(&DataRegister)) {
|
||||
timer_silence_reset();
|
||||
if (DataRegister == 0x55) {
|
||||
/* Preamble1 */
|
||||
/* receive the remainder of the frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_PREAMBLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_PREAMBLE:
|
||||
/* In the PREAMBLE state, the node waits for the
|
||||
second octet of the preamble. */
|
||||
if (timer_silence_elapsed(Tframe_abort)) {
|
||||
/* Timeout */
|
||||
/* a correct preamble has not been received */
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else if (RS485_ReceiveError()) {
|
||||
/* Error */
|
||||
timer_silence_reset();
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else if (RS485_DataAvailable(&DataRegister)) {
|
||||
timer_silence_reset();
|
||||
if (DataRegister == 0xFF) {
|
||||
/* Preamble2 */
|
||||
Index = 0;
|
||||
HeaderCRC = 0xFF;
|
||||
/* receive the remainder of the frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_HEADER;
|
||||
} else if (DataRegister == 0x55) {
|
||||
/* ignore RepeatedPreamble1 */
|
||||
/* wait for the second preamble octet. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_PREAMBLE;
|
||||
} else {
|
||||
/* NotPreamble */
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_HEADER:
|
||||
/* In the HEADER state, the node waits for the fixed message header. */
|
||||
if (timer_silence_elapsed(Tframe_abort)) {
|
||||
/* Timeout */
|
||||
/* indicate that an error has occurred during the reception of a frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else if (RS485_ReceiveError()) {
|
||||
/* Error */
|
||||
timer_silence_reset();
|
||||
/* indicate that an error has occurred during the reception of a frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else if (RS485_DataAvailable(&DataRegister)) {
|
||||
timer_silence_reset();
|
||||
if (Index == 0) {
|
||||
/* FrameType */
|
||||
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
|
||||
FrameType = DataRegister;
|
||||
Index = 1;
|
||||
} else if (Index == 1) {
|
||||
/* Destination */
|
||||
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
|
||||
DestinationAddress = DataRegister;
|
||||
Index = 2;
|
||||
} else if (Index == 2) {
|
||||
/* Source */
|
||||
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
|
||||
SourceAddress = DataRegister;
|
||||
Index = 3;
|
||||
} else if (Index == 3) {
|
||||
/* Length1 */
|
||||
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
|
||||
DataLength = DataRegister * 256;
|
||||
Index = 4;
|
||||
} else if (Index == 4) {
|
||||
/* Length2 */
|
||||
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
|
||||
DataLength += DataRegister;
|
||||
Index = 5;
|
||||
} else if (Index == 5) {
|
||||
/* HeaderCRC */
|
||||
HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC);
|
||||
/* In the HEADER_CRC state, the node validates the CRC
|
||||
on the fixed message header. */
|
||||
if (HeaderCRC != 0x55) {
|
||||
/* BadCRC */
|
||||
/* indicate that an error has occurred during
|
||||
the reception of a frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of the next frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else {
|
||||
/* Note: proposed change to BACnet MSTP state machine!
|
||||
If we don't decode data that is not for us, we could
|
||||
get confused about the start if the Preamble 55 FF
|
||||
is part of the data. */
|
||||
if ((DataLength) && (DataLength <= InputBufferSize)) {
|
||||
/* Data */
|
||||
Index = 0;
|
||||
DataCRC = 0xFFFF;
|
||||
/* receive the data portion of the frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_DATA;
|
||||
} else {
|
||||
if (DataLength == 0) {
|
||||
/* NoData */
|
||||
if ((DestinationAddress == This_Station) ||
|
||||
(DestinationAddress ==
|
||||
MSTP_BROADCAST_ADDRESS)) {
|
||||
/* ForUs */
|
||||
/* indicate that a frame with
|
||||
no data has been received */
|
||||
MSTP_Flag.ReceivedValidFrame = true;
|
||||
} else {
|
||||
/* NotForUs - drop */
|
||||
}
|
||||
} else {
|
||||
/* FrameTooLong */
|
||||
/* indicate that a frame with an illegal or */
|
||||
/* unacceptable data length has been received */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
}
|
||||
/* wait for the start of the next frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* indicate that an error has occurred during */
|
||||
/* the reception of a frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of a frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSTP_RECEIVE_STATE_DATA:
|
||||
/* In the DATA state, the node waits for the data portion of a frame. */
|
||||
if (timer_silence_elapsed(Tframe_abort)) {
|
||||
/* Timeout */
|
||||
/* indicate that an error has occurred during the reception of a frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of the next frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else if (RS485_ReceiveError()) {
|
||||
/* Error */
|
||||
timer_silence_reset();
|
||||
/* indicate that an error has occurred during
|
||||
the reception of a frame */
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
/* wait for the start of the next frame. */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
} else if (RS485_DataAvailable(&DataRegister)) {
|
||||
timer_silence_reset();
|
||||
if (Index < DataLength) {
|
||||
/* DataOctet */
|
||||
DataCRC = CRC_Calc_Data(DataRegister, DataCRC);
|
||||
InputBuffer[Index] = DataRegister;
|
||||
Index++;
|
||||
} else if (Index == DataLength) {
|
||||
/* CRC1 */
|
||||
DataCRC = CRC_Calc_Data(DataRegister, DataCRC);
|
||||
Index++;
|
||||
} else if (Index == (DataLength + 1)) {
|
||||
/* CRC2 */
|
||||
DataCRC = CRC_Calc_Data(DataRegister, DataCRC);
|
||||
/* STATE DATA CRC - no need for new state */
|
||||
/* indicate the complete reception of a valid frame */
|
||||
if (DataCRC == 0xF0B8) {
|
||||
if ((DestinationAddress == This_Station) ||
|
||||
(DestinationAddress == MSTP_BROADCAST_ADDRESS)) {
|
||||
/* ForUs */
|
||||
/* indicate that a frame with no data
|
||||
has been received */
|
||||
MSTP_Flag.ReceivedValidFrame = true;
|
||||
}
|
||||
} else {
|
||||
MSTP_Flag.ReceivedInvalidFrame = true;
|
||||
}
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* shouldn't get here - but if we do... */
|
||||
Receive_State = MSTP_RECEIVE_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void MSTP_Slave_Node_FSM(
|
||||
void)
|
||||
{
|
||||
if (MSTP_Flag.ReceivedValidFrame) {
|
||||
MSTP_Flag.ReceivedValidFrame = false;
|
||||
switch (FrameType) {
|
||||
case FRAME_TYPE_TOKEN:
|
||||
break;
|
||||
case FRAME_TYPE_POLL_FOR_MASTER:
|
||||
break;
|
||||
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
|
||||
break;
|
||||
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||
/* indicate successful reception to the higher layers */
|
||||
MSTP_Flag.ReceivePacketPending = true;
|
||||
break;
|
||||
case FRAME_TYPE_TEST_REQUEST:
|
||||
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress,
|
||||
This_Station, &InputBuffer[0], DataLength);
|
||||
break;
|
||||
case FRAME_TYPE_TEST_RESPONSE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (MSTP_Flag.TransmitPacketPending) {
|
||||
/* Reply */
|
||||
/* If a reply is available from the higher layers */
|
||||
/* within Treply_delay after the reception of the */
|
||||
/* final octet of the requesting frame */
|
||||
/* (the mechanism used to determine this is a local matter), */
|
||||
/* then call MSTP_Send_Frame to transmit the reply frame */
|
||||
/* and enter the IDLE state to wait for the next frame. */
|
||||
/* Note: optimized such that we are never a client */
|
||||
MSTP_Send_Frame(FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY,
|
||||
TransmitPacketDest, This_Station, (uint8_t *) & TransmitPacket[0],
|
||||
TransmitPacketLen);
|
||||
MSTP_Flag.TransmitPacketPending = false;
|
||||
MSTP_Flag.ReceivePacketPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* returns number of bytes sent on success, zero on failure */
|
||||
int dlmstp_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 */
|
||||
int bytes_sent = 0;
|
||||
|
||||
if (MSTP_Flag.TransmitPacketPending == false) {
|
||||
MSTP_Flag.TransmitPacketDER = npdu_data->data_expecting_reply;
|
||||
TransmitPacket = pdu;
|
||||
TransmitPacketLen = pdu_len;
|
||||
bytes_sent = pdu_len;
|
||||
TransmitPacketDest = dest->mac[0];
|
||||
MSTP_Flag.TransmitPacketPending = true;
|
||||
}
|
||||
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
/* Return the length of the packet */
|
||||
uint16_t dlmstp_receive(
|
||||
BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
uint16_t pdu_len = 0; /* return value */
|
||||
|
||||
/* dummy - unused parameter */
|
||||
timeout = timeout;
|
||||
/* set the input buffer to the same data storage for zero copy */
|
||||
if (!InputBuffer) {
|
||||
InputBuffer = pdu;
|
||||
InputBufferSize = max_pdu;
|
||||
}
|
||||
/* only do receive state machine while we don't have a frame */
|
||||
if ((MSTP_Flag.ReceivedValidFrame == false) &&
|
||||
(MSTP_Flag.ReceivedInvalidFrame == false) &&
|
||||
(MSTP_Flag.ReceivePacketPending == false)) {
|
||||
for (;;) {
|
||||
MSTP_Receive_Frame_FSM();
|
||||
if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame)
|
||||
break;
|
||||
/* if we are not idle, then we are
|
||||
receiving a frame or timing out */
|
||||
if (Receive_State == MSTP_RECEIVE_STATE_IDLE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* only do master state machine while rx is idle */
|
||||
if (Receive_State == MSTP_RECEIVE_STATE_IDLE) {
|
||||
MSTP_Slave_Node_FSM();
|
||||
}
|
||||
/* if there is a packet that needs processed, do it now. */
|
||||
if (MSTP_Flag.ReceivePacketPending) {
|
||||
MSTP_Flag.ReceivePacketPending = false;
|
||||
pdu_len = DataLength;
|
||||
src->mac_len = 1;
|
||||
src->mac[0] = SourceAddress;
|
||||
/* data is already in the pdu pointer */
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
void dlmstp_set_mac_address(
|
||||
uint8_t mac_address)
|
||||
{
|
||||
/* Master Nodes can only have address 0-127 */
|
||||
if (mac_address <= 127) {
|
||||
This_Station = mac_address;
|
||||
/* FIXME: implement your data storage */
|
||||
/* I2C_Write_Byte(
|
||||
EEPROM_DEVICE_ADDRESS,
|
||||
mac_address,
|
||||
EEPROM_MSTP_MAC_ADDR); */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t dlmstp_mac_address(
|
||||
void)
|
||||
{
|
||||
return This_Station;
|
||||
}
|
||||
|
||||
void dlmstp_get_my_address(
|
||||
BACNET_ADDRESS * my_address)
|
||||
{
|
||||
int i = 0; /* counter */
|
||||
|
||||
my_address->mac_len = 1;
|
||||
my_address->mac[0] = This_Station;
|
||||
my_address->net = 0; /* local only, no routing */
|
||||
my_address->len = 0;
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
my_address->adr[i] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dlmstp_get_broadcast_address(
|
||||
BACNET_ADDRESS * dest)
|
||||
{ /* destination address */
|
||||
int i = 0; /* counter */
|
||||
|
||||
if (dest) {
|
||||
dest->mac_len = 1;
|
||||
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
|
||||
dest->net = BACNET_BROADCAST_NETWORK;
|
||||
dest->len = 0; /* always zero when DNET is broadcast */
|
||||
for (i = 0; i < MAX_MAC_LEN; i++) {
|
||||
dest->adr[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* 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 HARDWARE_H
|
||||
#define HARDWARE_H
|
||||
|
||||
#if !defined(F_CPU)
|
||||
/* The processor clock frequency */
|
||||
#define F_CPU 7372800UL
|
||||
#endif
|
||||
|
||||
#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__)
|
||||
#include <ioavr.h>
|
||||
#if defined(__ATmega168__)
|
||||
#define WATCHDOG_INIT() {BIT_CLEAR(MCUSR, WDRF); WDTCSR = 0;}
|
||||
#else
|
||||
#define WATCHDOG_INIT()
|
||||
#endif
|
||||
#else
|
||||
#if !defined(__AVR_ATmega168__)
|
||||
#error Firmware is configured for ATmega168 only (-mmcu=atmega168)
|
||||
#endif
|
||||
#if defined(__AVR_ATmega168__)
|
||||
#define WATCHDOG_INIT() {BIT_CLEAR(MCUSR, WDRF); WDTCSR = 0;}
|
||||
#else
|
||||
#define WATCHDOG_INIT() {BIT_CLEAR(MCUCSR, WDRF); WDTCR = 0;}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "iar2gcc.h"
|
||||
#include "bits.h"
|
||||
|
||||
#define LED_NPDU_INIT() BIT_SET(DDRD, DDD5)
|
||||
#define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5)
|
||||
#define LED_NPDU_OFF() BIT_SET(PORTD, PD5)
|
||||
/* #define LED_NPDU PORTD_Bit5 */
|
||||
/* #define LED_NPDU_OFF() {LED_NPDU = false;} */
|
||||
/* #define LED_NPDU_ON() {LED_NPDU = true;} */
|
||||
|
||||
#define LED_GREEN_INIT() BIT_SET(DDRD, DDD4)
|
||||
#define LED_GREEN_ON() BIT_CLEAR(PORTD, PD4)
|
||||
#define LED_GREEN_OFF() BIT_SET(PORTD, PD4)
|
||||
|
||||
#endif
|
||||
Binary file not shown.
@@ -1,345 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* 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 IAR2GCC_H
|
||||
#define IAR2GCC_H
|
||||
|
||||
/* common embedded extensions for different compilers */
|
||||
|
||||
#if !defined(F_CPU)
|
||||
#error You must define F_CPU - clock frequency!
|
||||
#endif
|
||||
|
||||
#if defined (__CROSSWORKS_AVR)
|
||||
#include <inavr.h>
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* IAR */
|
||||
#if defined(__ICCAVR__)
|
||||
#include <inavr.h>
|
||||
#include <intrinsics.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* inline function */
|
||||
static inline void _delay_us(
|
||||
uint8_t microseconds)
|
||||
{
|
||||
do {
|
||||
__delay_cycles(F_CPU / 1000000UL);
|
||||
} while (microseconds--);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <util/delay.h>
|
||||
#endif
|
||||
|
||||
/* adjust some definitions to common versions */
|
||||
#if defined (__CROSSWORKS_AVR)
|
||||
#if (__TARGET_PROCESSOR == ATmega644P)
|
||||
#define PRR PRR0
|
||||
#define UBRR0 UBRR0W
|
||||
#define UBRR1 UBRR1W
|
||||
|
||||
#define PA0 PORTA0
|
||||
#define PA1 PORTA1
|
||||
#define PA2 PORTA2
|
||||
#define PA3 PORTA3
|
||||
#define PA4 PORTA4
|
||||
#define PA5 PORTA5
|
||||
#define PA6 PORTA6
|
||||
#define PA7 PORTA7
|
||||
|
||||
#define PB0 PORTB0
|
||||
#define PB1 PORTB1
|
||||
#define PB2 PORTB2
|
||||
#define PB3 PORTB3
|
||||
#define PB4 PORTB4
|
||||
#define PB5 PORTB5
|
||||
#define PB6 PORTB6
|
||||
#define PB7 PORTB7
|
||||
|
||||
#define PC0 PORTC0
|
||||
#define PC1 PORTC1
|
||||
#define PC2 PORTC2
|
||||
#define PC3 PORTC3
|
||||
#define PC4 PORTC4
|
||||
#define PC5 PORTC5
|
||||
#define PC6 PORTC6
|
||||
#define PC7 PORTC7
|
||||
|
||||
#define PD0 PORTD0
|
||||
#define PD1 PORTD1
|
||||
#define PD2 PORTD2
|
||||
#define PD3 PORTD3
|
||||
#define PD4 PORTD4
|
||||
#define PD5 PORTD5
|
||||
#define PD6 PORTD6
|
||||
#define PD7 PORTD7
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Input/Output Registers */
|
||||
#if defined(__GNUC__)
|
||||
#include <avr/io.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned char bit0:1;
|
||||
unsigned char bit1:1;
|
||||
unsigned char bit2:1;
|
||||
unsigned char bit3:1;
|
||||
unsigned char bit4:1;
|
||||
unsigned char bit5:1;
|
||||
unsigned char bit6:1;
|
||||
unsigned char bit7:1;
|
||||
} BitRegisterType;
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#define GPIO_BITREG(port,bitnum) \
|
||||
((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \
|
||||
)->bit ## bitnum
|
||||
|
||||
#define PINA_Bit0 GPIO_BITREG(PINA,0)
|
||||
#define PINA_Bit1 GPIO_BITREG(PINA,1)
|
||||
#define PINA_Bit2 GPIO_BITREG(PINA,2)
|
||||
#define PINA_Bit3 GPIO_BITREG(PINA,3)
|
||||
#define PINA_Bit4 GPIO_BITREG(PINA,4)
|
||||
#define PINA_Bit5 GPIO_BITREG(PINA,5)
|
||||
#define PINA_Bit6 GPIO_BITREG(PINA,6)
|
||||
#define PINA_Bit7 GPIO_BITREG(PINA,7)
|
||||
|
||||
#define PORTA_Bit0 GPIO_BITREG(PORTA,0)
|
||||
#define PORTA_Bit1 GPIO_BITREG(PORTA,1)
|
||||
#define PORTA_Bit2 GPIO_BITREG(PORTA,2)
|
||||
#define PORTA_Bit3 GPIO_BITREG(PORTA,3)
|
||||
#define PORTA_Bit4 GPIO_BITREG(PORTA,4)
|
||||
#define PORTA_Bit5 GPIO_BITREG(PORTA,5)
|
||||
#define PORTA_Bit6 GPIO_BITREG(PORTA,6)
|
||||
#define PORTA_Bit7 GPIO_BITREG(PORTA,7)
|
||||
|
||||
#define PINB_Bit0 GPIO_BITREG(PINB,0)
|
||||
#define PINB_Bit1 GPIO_BITREG(PINB,1)
|
||||
#define PINB_Bit2 GPIO_BITREG(PINB,2)
|
||||
#define PINB_Bit3 GPIO_BITREG(PINB,3)
|
||||
#define PINB_Bit4 GPIO_BITREG(PINB,4)
|
||||
#define PINB_Bit5 GPIO_BITREG(PINB,5)
|
||||
#define PINB_Bit6 GPIO_BITREG(PINB,6)
|
||||
#define PINB_Bit7 GPIO_BITREG(PINB,7)
|
||||
|
||||
#define PORTB_Bit0 GPIO_BITREG(PORTB,0)
|
||||
#define PORTB_Bit1 GPIO_BITREG(PORTB,1)
|
||||
#define PORTB_Bit2 GPIO_BITREG(PORTB,2)
|
||||
#define PORTB_Bit3 GPIO_BITREG(PORTB,3)
|
||||
#define PORTB_Bit4 GPIO_BITREG(PORTB,4)
|
||||
#define PORTB_Bit5 GPIO_BITREG(PORTB,5)
|
||||
#define PORTB_Bit6 GPIO_BITREG(PORTB,6)
|
||||
#define PORTB_Bit7 GPIO_BITREG(PORTB,7)
|
||||
|
||||
#define PINC_Bit0 GPIO_BITREG(PINC,0)
|
||||
#define PINC_Bit1 GPIO_BITREG(PINC,1)
|
||||
#define PINC_Bit2 GPIO_BITREG(PINC,2)
|
||||
#define PINC_Bit3 GPIO_BITREG(PINC,3)
|
||||
#define PINC_Bit4 GPIO_BITREG(PINC,4)
|
||||
#define PINC_Bit5 GPIO_BITREG(PINC,5)
|
||||
#define PINC_Bit6 GPIO_BITREG(PINC,6)
|
||||
#define PINC_Bit7 GPIO_BITREG(PINC,7)
|
||||
|
||||
#define PORTC_Bit0 GPIO_BITREG(PORTC,0)
|
||||
#define PORTC_Bit1 GPIO_BITREG(PORTC,1)
|
||||
#define PORTC_Bit2 GPIO_BITREG(PORTC,2)
|
||||
#define PORTC_Bit3 GPIO_BITREG(PORTC,3)
|
||||
#define PORTC_Bit4 GPIO_BITREG(PORTC,4)
|
||||
#define PORTC_Bit5 GPIO_BITREG(PORTC,5)
|
||||
#define PORTC_Bit6 GPIO_BITREG(PORTC,6)
|
||||
#define PORTC_Bit7 GPIO_BITREG(PORTC,7)
|
||||
|
||||
#define PIND_Bit0 GPIO_BITREG(PIND,0)
|
||||
#define PIND_Bit1 GPIO_BITREG(PIND,1)
|
||||
#define PIND_Bit2 GPIO_BITREG(PIND,2)
|
||||
#define PIND_Bit3 GPIO_BITREG(PIND,3)
|
||||
#define PIND_Bit4 GPIO_BITREG(PIND,4)
|
||||
#define PIND_Bit5 GPIO_BITREG(PIND,5)
|
||||
#define PIND_Bit6 GPIO_BITREG(PIND,6)
|
||||
#define PIND_Bit7 GPIO_BITREG(PIND,7)
|
||||
|
||||
#define PORTD_Bit0 GPIO_BITREG(PORTD,0)
|
||||
#define PORTD_Bit1 GPIO_BITREG(PORTD,1)
|
||||
#define PORTD_Bit2 GPIO_BITREG(PORTD,2)
|
||||
#define PORTD_Bit3 GPIO_BITREG(PORTD,3)
|
||||
#define PORTD_Bit4 GPIO_BITREG(PORTD,4)
|
||||
#define PORTD_Bit5 GPIO_BITREG(PORTD,5)
|
||||
#define PORTD_Bit6 GPIO_BITREG(PORTD,6)
|
||||
#define PORTD_Bit7 GPIO_BITREG(PORTD,7)
|
||||
|
||||
#define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0)
|
||||
#define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1)
|
||||
#define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2)
|
||||
#define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3)
|
||||
#define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4)
|
||||
#define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5)
|
||||
#define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6)
|
||||
#define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7)
|
||||
|
||||
#define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0)
|
||||
#define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1)
|
||||
#define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2)
|
||||
#define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3)
|
||||
#define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4)
|
||||
#define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5)
|
||||
#define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6)
|
||||
#define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7)
|
||||
|
||||
#define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0)
|
||||
#define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1)
|
||||
#define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2)
|
||||
#define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3)
|
||||
#define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4)
|
||||
#define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5)
|
||||
#define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6)
|
||||
#define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7)
|
||||
|
||||
#endif
|
||||
|
||||
/* Global Interrupts */
|
||||
#if defined(__GNUC__)
|
||||
#define __enable_interrupt() sei()
|
||||
#define __disable_interrupt() cli()
|
||||
#endif
|
||||
|
||||
/* Interrupts */
|
||||
#if defined(__ICCAVR__)
|
||||
#define PRAGMA(x) _Pragma( #x )
|
||||
#define ISR(vec) \
|
||||
/* function prototype for use with "require protoptypes" option. */ \
|
||||
PRAGMA( vector=vec ) __interrupt void handler_##vec(void); \
|
||||
PRAGMA( vector=vec ) __interrupt void handler_##vec(void)
|
||||
#elif defined(__GNUC__)
|
||||
#include <avr/interrupt.h>
|
||||
#elif defined (__CROSSWORKS_AVR)
|
||||
#define ISR(vec) void handler_##vec(void) __interrupt[vec]
|
||||
#else
|
||||
#error ISR() not defined!
|
||||
#endif
|
||||
|
||||
/* Flash */
|
||||
#if defined(__ICCAVR__)
|
||||
#define FLASH_DECLARE(x) __flash x
|
||||
#elif defined(__GNUC__)
|
||||
#define FLASH_DECLARE(x) x __attribute__((__progmem__))
|
||||
#elif defined (__CROSSWORKS_AVR)
|
||||
#define FLASH_DECLARE (x) const __code x
|
||||
#endif
|
||||
|
||||
/* EEPROM */
|
||||
#if defined(__ICCAVR__)
|
||||
#define EEPROM_DECLARE(x) __eeprom x
|
||||
#elif defined(__GNUC__)
|
||||
#include <avr/eeprom.h>
|
||||
#define EEPROM_DECLARE(x) x __attribute__((section (".eeprom")))
|
||||
#if ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3)) || \
|
||||
((__GNUC__ == 4) && (__GNUC_MINOR__ == 3) && (__GNUC_PATCHLEVEL__ <= 3)))
|
||||
/* bug in WinAVR - not quite IAR compatible */
|
||||
#ifndef __EEPUT
|
||||
#define __EEPUT _EEPUT
|
||||
#endif
|
||||
#ifndef __EEGET
|
||||
#define __EEGET _EEGET
|
||||
#endif
|
||||
#endif
|
||||
#elif defined (__CROSSWORKS_AVR)
|
||||
/* use functions defined in crt0.s to mimic IAR macros */
|
||||
void __uint8_eeprom_store(
|
||||
unsigned char byte,
|
||||
unsigned addr);
|
||||
unsigned char __uint8_eeprom_load(
|
||||
unsigned addr);
|
||||
#define __EEPUT(addr, var) \
|
||||
__uint8_eeprom_store((unsigned char)(var), (unsigned)(addr))
|
||||
#define __EEGET(var, addr) \
|
||||
(var) = __uint8_eeprom_load((unsigned)(addr))
|
||||
#endif
|
||||
|
||||
/* IAR intrinsic routines */
|
||||
#if defined(__GNUC__)
|
||||
/* FIXME: intrinsic routines: map to assembler for size/speed */
|
||||
#define __multiply_unsigned(x,y) ((x)*(y))
|
||||
/* FIXME: __root means to not optimize or strip */
|
||||
#define __root
|
||||
#endif
|
||||
|
||||
/* watchdog defines in GCC */
|
||||
#if defined(__ICCAVR__) || defined(__CROSSWORKS_AVR)
|
||||
#define WDTO_15MS 0
|
||||
#define WDTO_30MS 1
|
||||
#define WDTO_60MS 2
|
||||
#define WDTO_120MS 3
|
||||
#define WDTO_250MS 4
|
||||
#define WDTO_500MS 5
|
||||
#define WDTO_1S 6
|
||||
#define WDTO_2S 7
|
||||
#endif
|
||||
|
||||
/* power macros in GCC-AVR */
|
||||
#if (defined(__ICCAVR__) && (defined(__ATmega644P__))) || \
|
||||
(defined(__CROSSWORKS_AVR) && (__TARGET_PROCESSOR == ATmega644P))
|
||||
#define power_adc_enable() (PRR &= (uint8_t)~(1 << PRADC))
|
||||
#define power_spi_enable() (PRR &= (uint8_t)~(1 << PRSPI))
|
||||
#define power_usart0_enable() (PRR &= (uint8_t)~(1 << PRUSART0))
|
||||
#define power_usart1_enable() (PRR &= (uint8_t)~(1 << PRUSART1))
|
||||
#define power_timer0_enable() (PRR &= (uint8_t)~(1 << PRTIM0))
|
||||
#define power_timer1_enable() (PRR &= (uint8_t)~(1 << PRTIM1))
|
||||
#define power_timer2_enable() (PRR &= (uint8_t)~(1 << PRTIM2))
|
||||
#endif
|
||||
#if (defined(__ICCAVR__) && (defined(__ATmega1284P__))) || \
|
||||
(defined(__CROSSWORKS_AVR) && (__TARGET_PROCESSOR == ATmega1284P))
|
||||
#define power_adc_enable() (PRR0 &= (uint8_t)~(1 << PRADC))
|
||||
#define power_spi_enable() (PRR0 &= (uint8_t)~(1 << PRSPI))
|
||||
#define power_usart0_enable() (PRR0 &= (uint8_t)~(1 << PRUSART0))
|
||||
#define power_usart1_enable() (PRR0 &= (uint8_t)~(1 << PRUSART1))
|
||||
#define power_timer0_enable() (PRR0 &= (uint8_t)~(1 << PRTIM0))
|
||||
#define power_timer1_enable() (PRR0 &= (uint8_t)~(1 << PRTIM1))
|
||||
#define power_timer2_enable() (PRR0 &= (uint8_t)~(1 << PRTIM2))
|
||||
#endif
|
||||
#if (defined(__GNUC__) && ((__GNUC__ == 4) && (__GNUC_MINOR__ < 5)))
|
||||
#if defined(__AVR_ATmega644P__)
|
||||
/* bug in WinAVR - fixed in later versions */
|
||||
#define power_usart1_enable() (PRR &= (uint8_t)~(1 << PRUSART1))
|
||||
#elif defined(__AVR_ATmega1284P__)
|
||||
#define power_usart1_enable() (PRR0 &= (uint8_t)~(1 << PRUSART1))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__CROSSWORKS_AVR)
|
||||
#define inline
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,116 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
#include "timer.h"
|
||||
#include "rs485.h"
|
||||
#include "datalink.h"
|
||||
#include "npdu.h"
|
||||
#include "txbuf.h"
|
||||
#include "iam.h"
|
||||
#include "device.h"
|
||||
#include "av.h"
|
||||
#include "handlers.h"
|
||||
|
||||
/* local version override */
|
||||
const char *BACnet_Version = "1.0";
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static void init(
|
||||
void)
|
||||
{
|
||||
/* FIXME: Initialize the Clock Prescaler for ATmega8 */
|
||||
#if defined(__AVR_ATmega168__)
|
||||
/* The default CLKPSx bits are factory set to 0011 */
|
||||
/* Enbable the Clock Prescaler */
|
||||
CLKPR = _BV(CLKPCE);
|
||||
/* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor
|
||||
------ ------ ------ ------ ---------------------
|
||||
0 0 0 0 1
|
||||
0 0 0 1 2
|
||||
0 0 1 0 4
|
||||
0 0 1 1 8
|
||||
0 1 0 0 16
|
||||
0 1 0 1 32
|
||||
0 1 1 0 64
|
||||
0 1 1 1 128
|
||||
1 0 0 0 256
|
||||
1 x x x Reserved
|
||||
*/
|
||||
/* Set the CLKPS3..0 bits to Prescaler of 1 */
|
||||
CLKPR = 0;
|
||||
#endif
|
||||
/* Initialize I/O ports */
|
||||
/* For Port DDRx (Data Direction) Input=0, Output=1 */
|
||||
/* For Port PORTx (Bit Value) TriState=0, High=1 */
|
||||
DDRB = 0;
|
||||
PORTB = 0;
|
||||
DDRC = 0;
|
||||
PORTC = 0;
|
||||
DDRD = 0;
|
||||
PORTD = 0;
|
||||
|
||||
/* Configure the watchdog timer - Disabled for testing */
|
||||
WATCHDOG_INIT();
|
||||
|
||||
/* Configure Specialized Hardware */
|
||||
RS485_Initialize();
|
||||
RS485_Set_Baud_Rate(38400);
|
||||
/* Configure Timer0 for millisecond timer */
|
||||
timer_init();
|
||||
/* Enable global interrupts */
|
||||
__enable_interrupt();
|
||||
}
|
||||
|
||||
static uint8_t PDUBuffer[MAX_MPDU];
|
||||
|
||||
int main(
|
||||
void)
|
||||
{
|
||||
uint16_t pdu_len = 0;
|
||||
BACNET_ADDRESS src; /* source address */
|
||||
|
||||
init();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
This port was originally done with the Atmel ATmega168
|
||||
I used the following tools:
|
||||
1. The WinAVR compiler avr-gcc (GCC) 4.1.2 (WinAVR 20070525)
|
||||
and tools from <http://winavr.sourceforge.net/>, hints and
|
||||
sample code from <http://www.avrfreaks.net/> and
|
||||
<http://savannah.gnu.org/projects/avr-libc/>.
|
||||
"avr-binutils, avr-gcc, and avr-libc form the heart of the
|
||||
Free Software toolchain for the Atmel AVR microcontrollers."
|
||||
2. AVR Studio 4 from Atmel <http://atmel.com/>
|
||||
|
||||
The hardware is expected to utilize the signals as defined
|
||||
in the spreadsheet hardware.ods (OpenOffice.org calc).
|
||||
Attach a DS75176 RS-485 transceiver (or similar) to the USART.
|
||||
DS75176 ATmega168
|
||||
------ ---------
|
||||
RO RXD
|
||||
/RE --choice of I/O
|
||||
DE --choice of I/O
|
||||
DI TXD
|
||||
GND GND
|
||||
DO --to RS-485 wire
|
||||
DO --to RS-485 wire
|
||||
+5V From 5V Regulator
|
||||
|
||||
The makefile allows you to build a simple server.
|
||||
dlmstp is the datalink layer for MS/TP over RS-485.
|
||||
This project uses an MS/TP Slave Node.
|
||||
|
||||
I used the makefile from the command line on Windows:
|
||||
C:\code\bacnet-stack\ports\atmega168> make clean all
|
||||
|
||||
The BACnet Capabilities include ReadProperty support.
|
||||
The BACnet objects include only a Device object.
|
||||
All required object properties can be retrieved using ReadProperty.
|
||||
|
||||
With full optimization, the statistics on the demo are:
|
||||
|
||||
avr-gcc (GCC) 4.2.2 (WinAVR 20071221rc1)
|
||||
Device: atmega168
|
||||
Program: 8734 bytes (53.3% Full)
|
||||
Data: 254 bytes (24.8% Full) (does not include CStack)
|
||||
|
||||
Hopefully you find this code useful!
|
||||
|
||||
Steve Karg <skarg@users.sourceforge.net>
|
||||
@@ -1,302 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
/* The module handles sending data out the RS-485 port */
|
||||
/* and handles receiving data from the RS-485 port. */
|
||||
/* Customize this file for your specific hardware */
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "bits.h"
|
||||
|
||||
/* This file has been customized for use with ATMEGA168 */
|
||||
#if (defined(__ICCAVR__) && (defined(__ATmega168__))) || \
|
||||
(defined(__GNUC__) && defined(__AVR_ATmega168__))
|
||||
/* USART defines for RS-485 port */
|
||||
#define UCSRB UCSR0B
|
||||
#define TXEN TXEN0
|
||||
#define RXEN RXEN0
|
||||
#define UCSRC UCSR0C
|
||||
#define UCSZ1 UCSZ01
|
||||
#define UCSZ0 UCSZ00
|
||||
#define UCSRA UCSR0A
|
||||
#define U2X U2X0
|
||||
#define UBRRL UBRR0
|
||||
#define UCSRA UCSR0A
|
||||
#define UDRE UDRE0
|
||||
#define UDR UDR0
|
||||
#define TXC TXC0
|
||||
#define FE FE0
|
||||
#define DOR DOR0
|
||||
#define UPE UPE0
|
||||
#define DOR DOR0
|
||||
#define RXC RXC0
|
||||
#endif
|
||||
|
||||
#include "hardware.h"
|
||||
#include "timer.h"
|
||||
|
||||
/* baud rate */
|
||||
static uint32_t RS485_Baud;
|
||||
|
||||
/* The minimum time after the end of the stop bit of the final octet of a */
|
||||
/* received frame before a node may enable its EIA-485 driver: 40 bit times. */
|
||||
/* At 9600 baud, 40 bit times would be about 4.166 milliseconds */
|
||||
/* At 19200 baud, 40 bit times would be about 2.083 milliseconds */
|
||||
/* At 38400 baud, 40 bit times would be about 1.041 milliseconds */
|
||||
/* At 57600 baud, 40 bit times would be about 0.694 milliseconds */
|
||||
/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */
|
||||
/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */
|
||||
/* 40 bits is 4 octets including a start and stop bit with each octet */
|
||||
#define Tturnaround (40UL)
|
||||
/* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
|
||||
* receive mode.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Initialize(
|
||||
void)
|
||||
{
|
||||
/* enable Transmit and Receive */
|
||||
UCSRB = _BV(TXEN) | _BV(RXEN);
|
||||
|
||||
/* Set USART Control and Status Register n C */
|
||||
/* Asynchronous USART 8-bit data, No parity, 1 stop */
|
||||
/* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */
|
||||
/* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */
|
||||
/* Set Stop Bit Select: USBSn = 0 for 1 stop bit */
|
||||
/* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */
|
||||
/* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */
|
||||
UCSRC = _BV(UCSZ1) | _BV(UCSZ0);
|
||||
#if defined(__AVR_ATmega168__)
|
||||
/* Clear Power Reduction USART0 */
|
||||
BIT_CLEAR(PRR, PRUSART0);
|
||||
#endif
|
||||
/* Use port PD2 for RTS - enable and disable of Transceiver Tx/Rx */
|
||||
/* Set port bit as Output - initially receiving */
|
||||
BIT_CLEAR(PORTD, PD2);
|
||||
BIT_SET(DDRD, DDD2);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Returns the baud rate that we are currently running at
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
uint32_t RS485_Get_Baud_Rate(
|
||||
void)
|
||||
{
|
||||
return RS485_Baud;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Sets the baud rate for the chip USART
|
||||
* RETURN: true if valid baud rate
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
bool RS485_Set_Baud_Rate(
|
||||
uint32_t baud)
|
||||
{
|
||||
bool valid = true;
|
||||
|
||||
switch (baud) {
|
||||
case 9600:
|
||||
case 19200:
|
||||
case 38400:
|
||||
case 57600:
|
||||
case 76800:
|
||||
case 115200:
|
||||
RS485_Baud = baud;
|
||||
/* 2x speed mode */
|
||||
BIT_SET(UCSRA, U2X);
|
||||
/* configure baud rate */
|
||||
UBRRL = (F_CPU / (8UL * RS485_Baud)) - 1;
|
||||
/* FIXME: store the baud rate */
|
||||
break;
|
||||
default:
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Enable or disable the transmitter
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Transmitter_Enable(
|
||||
bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
BIT_SET(PORTD, PD2);
|
||||
} else {
|
||||
BIT_CLEAR(PORTD, PD2);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Waits on the SilenceTimer for 40 bits.
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Turnaround_Delay(
|
||||
void)
|
||||
{
|
||||
uint8_t nbytes = 4;
|
||||
|
||||
RS485_Transmitter_Enable(false);
|
||||
while (nbytes) {
|
||||
while (!BIT_CHECK(UCSRA, UDRE)) {
|
||||
/* do nothing - wait until Tx buffer is empty */
|
||||
}
|
||||
/* Send the data byte */
|
||||
UDR = 0xff;
|
||||
nbytes--;
|
||||
}
|
||||
/* was the frame sent? */
|
||||
while (!BIT_CHECK(UCSRA, TXC)) {
|
||||
/* do nothing - wait until the entire frame in the
|
||||
Transmit Shift Register has been shifted out */
|
||||
}
|
||||
/* Clear the Transmit Complete flag by writing a one to it. */
|
||||
BIT_SET(UCSRA, TXC);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Send some data and wait until it is sent
|
||||
* RETURN: none
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
void RS485_Send_Data(
|
||||
uint8_t * buffer, /* data to send */
|
||||
uint16_t nbytes)
|
||||
{ /* number of bytes of data */
|
||||
while (nbytes) {
|
||||
while (!BIT_CHECK(UCSRA, UDRE)) {
|
||||
/* do nothing - wait until Tx buffer is empty */
|
||||
}
|
||||
/* Send the data byte */
|
||||
UDR = *buffer;
|
||||
buffer++;
|
||||
nbytes--;
|
||||
}
|
||||
/* was the frame sent? */
|
||||
while (!BIT_CHECK(UCSRA, TXC)) {
|
||||
/* do nothing - wait until the entire frame in the
|
||||
Transmit Shift Register has been shifted out */
|
||||
}
|
||||
/* Clear the Transmit Complete flag by writing a one to it. */
|
||||
BIT_SET(UCSRA, TXC);
|
||||
/* per MSTP spec, sort of */
|
||||
timer_silence_reset();
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Return true if a framing or overrun error is present
|
||||
* RETURN: true if error
|
||||
* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate
|
||||
* NOTES: Clears any error flags.
|
||||
*****************************************************************************/
|
||||
bool RS485_ReceiveError(
|
||||
void)
|
||||
{
|
||||
bool ReceiveError = false;
|
||||
uint8_t dummy_data;
|
||||
|
||||
/* check for framing error */
|
||||
#if 0
|
||||
if (BIT_CHECK(UCSRA, FE0)) {
|
||||
/* FIXME: how do I clear the error flags? */
|
||||
BITMASK_CLEAR(UCSRA, (_BV(FE) | _BV(DOR) | _BV(UPE)));
|
||||
ReceiveError = true;
|
||||
}
|
||||
#endif
|
||||
/* check for overrun error */
|
||||
if (BIT_CHECK(UCSRA, DOR)) {
|
||||
/* flush the receive buffer */
|
||||
do {
|
||||
dummy_data = UDR;
|
||||
} while (BIT_CHECK(UCSRA, RXC));
|
||||
ReceiveError = true;
|
||||
}
|
||||
|
||||
return ReceiveError;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* DESCRIPTION: Return true if data is available
|
||||
* RETURN: true if data is available, with the data in the parameter set
|
||||
* ALGORITHM: none
|
||||
* NOTES: none
|
||||
*****************************************************************************/
|
||||
bool RS485_DataAvailable(
|
||||
uint8_t * data)
|
||||
{
|
||||
bool DataAvailable = false;
|
||||
|
||||
/* check for data */
|
||||
if (BIT_CHECK(UCSRA, RXC)) {
|
||||
*data = UDR;
|
||||
DataAvailable = true;
|
||||
}
|
||||
|
||||
return DataAvailable;
|
||||
}
|
||||
|
||||
#ifdef TEST_RS485
|
||||
int main(
|
||||
void)
|
||||
{
|
||||
unsigned i = 0;
|
||||
uint8_t DataRegister;
|
||||
|
||||
RS485_Set_Baud_Rate(38400);
|
||||
RS485_Initialize();
|
||||
/* receive task */
|
||||
for (;;) {
|
||||
if (RS485_ReceiveError()) {
|
||||
fprintf(stderr, "ERROR ");
|
||||
} else if (RS485_DataAvailable(&DataRegister)) {
|
||||
fprintf(stderr, "%02X ", DataRegister);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* TEST_RS485 */
|
||||
@@ -1,70 +0,0 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2004 Steve Karg
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
The Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307
|
||||
USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or
|
||||
use macros or inline functions from this file, or you compile
|
||||
this file and link it with other works to produce a work based
|
||||
on this file, this file does not by itself cause the resulting
|
||||
work to be covered by the GNU General Public License. However
|
||||
the source code for this file must still be made available in
|
||||
accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work
|
||||
based on this file might be covered by the GNU General Public
|
||||
License.
|
||||
-------------------------------------------
|
||||
####COPYRIGHTEND####*/
|
||||
|
||||
#ifndef RS485_H
|
||||
#define RS485_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void RS485_Initialize(
|
||||
void);
|
||||
|
||||
void RS485_Transmitter_Enable(
|
||||
bool enable);
|
||||
|
||||
void RS485_Send_Data(
|
||||
uint8_t * buffer, /* data to send */
|
||||
uint16_t nbytes); /* number of bytes of data */
|
||||
|
||||
bool RS485_ReceiveError(
|
||||
void);
|
||||
bool RS485_DataAvailable(
|
||||
uint8_t * data);
|
||||
|
||||
void RS485_Turnaround_Delay(
|
||||
void);
|
||||
uint32_t RS485_Get_Baud_Rate(
|
||||
void);
|
||||
bool RS485_Set_Baud_Rate(
|
||||
uint32_t baud);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
#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
|
||||
@@ -1,15 +0,0 @@
|
||||
/* Defines the standard integer types that are used in code */
|
||||
|
||||
#ifndef STDINT_H
|
||||
#define STDINT_H 1
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
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 */
|
||||
@@ -1,110 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
|
||||
/* This module is a 1 millisecond timer */
|
||||
|
||||
/* Prescaling: 1, 8, 64, 256, 1024 */
|
||||
#define TIMER_PRESCALER 64
|
||||
/* Count: Timer0 counts up to 0xFF and then signals overflow */
|
||||
#define TIMER_TICKS (F_CPU/TIMER_PRESCALER/1000)
|
||||
#if (TIMER_TICKS > 0xFF)
|
||||
#error Timer Prescaler value is too small
|
||||
#endif
|
||||
#define TIMER_COUNT (0xFF-TIMER_TICKS)
|
||||
/* millisecond timer count */
|
||||
static volatile uint16_t Timer_Silence;
|
||||
|
||||
/* FIXME: Configure the Timer */
|
||||
void timer_init(
|
||||
void)
|
||||
{
|
||||
/* Normal Operation */
|
||||
TCCR1A = 0;
|
||||
/* CSn2 CSn1 CSn0 Description
|
||||
---- ---- ---- -----------
|
||||
0 0 0 No Clock Source
|
||||
0 0 1 No prescaling
|
||||
0 1 0 CLKio/8
|
||||
0 1 1 CLKio/64
|
||||
1 0 0 CLKio/256
|
||||
1 0 1 CLKio/1024
|
||||
1 1 0 Falling Edge of T0 (external)
|
||||
1 1 1 Rising Edge of T0 (external)
|
||||
*/
|
||||
#if defined(__AVR_ATmega168__)
|
||||
TCCR0B = _BV(CS01) | _BV(CS00);
|
||||
/* Clear any TOV1 Flag set when the timer overflowed */
|
||||
BIT_CLEAR(TIFR0, TOV0);
|
||||
/* Initial value */
|
||||
TCNT0 = TIMER_COUNT;
|
||||
/* Enable the overflow interrupt */
|
||||
BIT_SET(TIMSK0, TOIE0);
|
||||
/* Clear the Power Reduction Timer/Counter0 */
|
||||
BIT_CLEAR(PRR, PRTIM0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Timer interupt */
|
||||
/* note: Global interupts must be enabled - sei() */
|
||||
/* Timer Overflowed! Increment the time. */
|
||||
ISR(TIMER0_OVF_vect)
|
||||
{
|
||||
/* Set the counter for the next interrupt */
|
||||
TCNT0 = TIMER_COUNT;
|
||||
/* Overflow Flag is automatically cleared */
|
||||
/* Update the global timer */
|
||||
Timer_Silence++;
|
||||
}
|
||||
|
||||
/* return true if time has expired */
|
||||
bool timer_silence_elapsed(
|
||||
uint16_t value)
|
||||
{
|
||||
bool status = false;
|
||||
uint8_t sreg;
|
||||
|
||||
sreg = SREG;
|
||||
__disable_interrupt();
|
||||
if (Timer_Silence >= value) {
|
||||
status = true;
|
||||
}
|
||||
SREG = sreg;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void timer_silence_reset(
|
||||
void)
|
||||
{
|
||||
uint8_t sreg;
|
||||
|
||||
sreg = SREG;
|
||||
__disable_interrupt();
|
||||
Timer_Silence = 0;
|
||||
SREG = sreg;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* 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 TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void timer_init(
|
||||
void);
|
||||
bool timer_silence_elapsed(
|
||||
uint16_t value);
|
||||
void timer_silence_reset(
|
||||
void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
||||
@@ -68,13 +68,11 @@ endif
|
||||
|
||||
# Source locations
|
||||
BACNET_CORE = ../../src
|
||||
BACNET_INCLUDE = ../../include
|
||||
BACNET_HANDLER = ../../demo/handler
|
||||
BACNET_OBJECT = ../../demo/object
|
||||
BACNET_DEMO = ../../demo
|
||||
BACNET_INCLUDE = $(BACNET_CORE)
|
||||
BACNET_BASIC = $(BACNET_CORE)/basic
|
||||
|
||||
# local files for this project
|
||||
CSRC = main.c \
|
||||
HALSRC = main.c \
|
||||
fuses.c \
|
||||
init.c \
|
||||
stack.c \
|
||||
@@ -82,8 +80,7 @@ CSRC = main.c \
|
||||
input.c \
|
||||
serial.c \
|
||||
rs485.c \
|
||||
timer2.c \
|
||||
timer.c \
|
||||
mstimer-init.c \
|
||||
led.c \
|
||||
eeprom.c \
|
||||
seeprom.c \
|
||||
@@ -99,23 +96,27 @@ CSRC = main.c \
|
||||
bo.c
|
||||
|
||||
# common demo files needed
|
||||
DEMOSRC = $(BACNET_DEMO)/handler/h_dcc.c \
|
||||
$(BACNET_DEMO)/handler/h_npdu.c \
|
||||
$(BACNET_DEMO)/handler/h_rd.c \
|
||||
$(BACNET_DEMO)/handler/h_rp.c \
|
||||
$(BACNET_DEMO)/handler/h_rpm.c \
|
||||
$(BACNET_DEMO)/handler/h_whohas.c \
|
||||
$(BACNET_DEMO)/handler/h_whois.c \
|
||||
$(BACNET_DEMO)/handler/h_wp.c \
|
||||
$(BACNET_DEMO)/handler/noserv.c \
|
||||
$(BACNET_DEMO)/handler/s_iam.c \
|
||||
$(BACNET_DEMO)/handler/s_ihave.c \
|
||||
$(BACNET_DEMO)/handler/txbuf.c
|
||||
BASICSRC = $(BACNET_BASIC)/service/h_dcc.c \
|
||||
$(BACNET_BASIC)/service/h_apdu.c \
|
||||
$(BACNET_BASIC)/service/h_rd.c \
|
||||
$(BACNET_BASIC)/service/h_rp.c \
|
||||
$(BACNET_BASIC)/service/h_rpm.c \
|
||||
$(BACNET_BASIC)/service/h_whohas.c \
|
||||
$(BACNET_BASIC)/service/h_whois.c \
|
||||
$(BACNET_BASIC)/service/h_wp.c \
|
||||
$(BACNET_BASIC)/service/h_noserv.c \
|
||||
$(BACNET_BASIC)/service/s_iam.c \
|
||||
$(BACNET_BASIC)/service/s_ihave.c \
|
||||
$(BACNET_BASIC)/sys/fifo.c \
|
||||
$(BACNET_BASIC)/sys/mstimer.c \
|
||||
$(BACNET_BASIC)/sys/ringbuf.c \
|
||||
$(BACNET_BASIC)/npdu/h_npdu.c \
|
||||
$(BACNET_BASIC)/tsm/tsm.c
|
||||
|
||||
# core BACnet stack files
|
||||
CORESRC = \
|
||||
$(BACNET_CORE)/datalink/crc.c \
|
||||
$(BACNET_CORE)/abort.c \
|
||||
$(BACNET_CORE)/apdu.c \
|
||||
$(BACNET_CORE)/bacaddr.c \
|
||||
$(BACNET_CORE)/bacapp.c \
|
||||
$(BACNET_CORE)/bacdcode.c \
|
||||
@@ -123,16 +124,13 @@ CORESRC = \
|
||||
$(BACNET_CORE)/bacint.c \
|
||||
$(BACNET_CORE)/bacreal.c \
|
||||
$(BACNET_CORE)/bacstr.c \
|
||||
$(BACNET_CORE)/crc.c \
|
||||
$(BACNET_CORE)/dcc.c \
|
||||
$(BACNET_CORE)/fifo.c \
|
||||
$(BACNET_CORE)/iam.c \
|
||||
$(BACNET_CORE)/ihave.c \
|
||||
$(BACNET_CORE)/memcopy.c \
|
||||
$(BACNET_CORE)/npdu.c \
|
||||
$(BACNET_CORE)/rd.c \
|
||||
$(BACNET_CORE)/reject.c \
|
||||
$(BACNET_CORE)/ringbuf.c \
|
||||
$(BACNET_CORE)/rp.c \
|
||||
$(BACNET_CORE)/rpm.c \
|
||||
$(BACNET_CORE)/whohas.c \
|
||||
@@ -157,11 +155,11 @@ CORESRC = \
|
||||
# $(BACNET_CORE)/address.c \
|
||||
|
||||
## Include Directories
|
||||
INCLUDES = -I. -I$(BACNET_INCLUDE) -I$(BACNET_HANDLER) -I$(BACNET_OBJECT)
|
||||
INCLUDES = -I. -I$(BACNET_INCLUDE)
|
||||
|
||||
# Source to Object conversion
|
||||
COBJ = $(CSRC:%.c=%.o)
|
||||
DEMOOBJ = $(DEMOSRC:.c=.o)
|
||||
HALOBJ = $(HALSRC:%.c=%.o)
|
||||
BASICOBJ = $(BASICSRC:.c=.o)
|
||||
COREOBJ = $(CORESRC:.c=.o)
|
||||
|
||||
LIBRARY = lib$(TARGET).a
|
||||
@@ -327,7 +325,7 @@ AVRDUDE_INSTALL = $(AVRDUDE_WRITE_FLASH)
|
||||
#AVRDUDE_INSTALL += $(AVRDUDE_WRITE_FUSES)
|
||||
|
||||
## Objects not in library that must be built in order to link
|
||||
OBJECTS = $(COBJ) $(DEMOOBJ)
|
||||
OBJECTS = $(HALOBJ) $(BASICOBJ)
|
||||
|
||||
## Build
|
||||
TARGET_ELF=$(TARGET).elf
|
||||
@@ -370,7 +368,7 @@ size: ${TARGET_ELF}
|
||||
@${SIZE} ${SIZE_OPTIONS} ${TARGET_ELF}
|
||||
|
||||
lint:
|
||||
$(LINT) -exportlocal -D$(LINT_MCU) $(BFLAGS) $(CSRC)
|
||||
$(LINT) -exportlocal -D$(LINT_MCU) $(BFLAGS) $(HALSRC)
|
||||
|
||||
install: $(TARGET_ELF)
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_INSTALL)
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "config.h"
|
||||
#include "ai.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/config.h"
|
||||
#include "bacnet/basic/object/ai.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
|
||||
#ifndef MAX_ANALOG_INPUTS
|
||||
#define MAX_ANALOG_INPUTS 2
|
||||
|
||||
@@ -29,14 +29,14 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bacdef.h"
|
||||
#include "bacdcode.h"
|
||||
#include "bacenum.h"
|
||||
#include "bacapp.h"
|
||||
#include "config.h" /* the custom stuff */
|
||||
#include "wp.h"
|
||||
#include "av.h"
|
||||
#include "handlers.h"
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/bacenum.h"
|
||||
#include "bacnet/bacapp.h"
|
||||
#include "bacnet/config.h" /* the custom stuff */
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/basic/object/av.h"
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "hardware.h"
|
||||
|
||||
#ifndef MAX_ANALOG_VALUES
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,84 +1,84 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRBootloader.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing an interface to the AVR bootloader
|
||||
* described in Application Note AVR109.
|
||||
* This class is derived from AVRPRogrammer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRBOOTLOADER_HPP
|
||||
#define AVRBOOTLOADER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "AVRProgrammer.hpp"
|
||||
#include "Utility.hpp"
|
||||
|
||||
class AVRBootloader : public AVRProgrammer
|
||||
{
|
||||
protected:
|
||||
virtual void setAddress( long address );
|
||||
virtual void writeFlashLowByte( long value ); // Alwyas low byte first...
|
||||
virtual void writeFlashHighByte( long value ); // ...then high byte.
|
||||
virtual void writeFlashPage();
|
||||
|
||||
virtual bool writeFlashBlock( HEXFile * data );
|
||||
virtual bool readFlashBlock( HEXFile * data );
|
||||
virtual bool writeEEPROMBlock( HEXFile * data );
|
||||
virtual bool readEEPROMBlock( HEXFile * data );
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRBootloader( CommChannel * _comm );
|
||||
|
||||
/* Destructor */
|
||||
~AVRBootloader();
|
||||
|
||||
/* Methods */
|
||||
virtual bool enterProgrammingMode();
|
||||
virtual bool leaveProgrammingMode();
|
||||
|
||||
virtual bool chipErase();
|
||||
|
||||
virtual bool readOSCCAL( long pos, long * value );
|
||||
virtual bool readSignature( long * sig0, long * sig1, long * sig2 );
|
||||
virtual bool checkSignature( long sig0, long sig1, long sig2 );
|
||||
|
||||
virtual bool writeFlashByte( long address, long value );
|
||||
virtual bool writeEEPROMByte( long address, long value );
|
||||
|
||||
virtual bool writeFlash( HEXFile * data );
|
||||
virtual bool readFlash( HEXFile * data );
|
||||
|
||||
virtual bool writeEEPROM( HEXFile * data );
|
||||
virtual bool readEEPROM( HEXFile * data );
|
||||
|
||||
virtual bool writeLockBits( long bits );
|
||||
virtual bool readLockBits( long * bits );
|
||||
|
||||
virtual bool writeFuseBits( long bits );
|
||||
virtual bool readFuseBits( long * bits );
|
||||
virtual bool writeExtendedFuseBits( long bits );
|
||||
virtual bool readExtendedFuseBits( long * bits );
|
||||
|
||||
virtual bool programmerSoftwareVersion( long * major, long * minor );
|
||||
virtual bool programmerHardwareVersion( long * major, long * minor );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRBootloader.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing an interface to the AVR bootloader
|
||||
* described in Application Note AVR109.
|
||||
* This class is derived from AVRPRogrammer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRBOOTLOADER_HPP
|
||||
#define AVRBOOTLOADER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "AVRProgrammer.hpp"
|
||||
#include "Utility.hpp"
|
||||
|
||||
class AVRBootloader : public AVRProgrammer
|
||||
{
|
||||
protected:
|
||||
virtual void setAddress( long address );
|
||||
virtual void writeFlashLowByte( long value ); // Alwyas low byte first...
|
||||
virtual void writeFlashHighByte( long value ); // ...then high byte.
|
||||
virtual void writeFlashPage();
|
||||
|
||||
virtual bool writeFlashBlock( HEXFile * data );
|
||||
virtual bool readFlashBlock( HEXFile * data );
|
||||
virtual bool writeEEPROMBlock( HEXFile * data );
|
||||
virtual bool readEEPROMBlock( HEXFile * data );
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRBootloader( CommChannel * _comm );
|
||||
|
||||
/* Destructor */
|
||||
~AVRBootloader();
|
||||
|
||||
/* Methods */
|
||||
virtual bool enterProgrammingMode();
|
||||
virtual bool leaveProgrammingMode();
|
||||
|
||||
virtual bool chipErase();
|
||||
|
||||
virtual bool readOSCCAL( long pos, long * value );
|
||||
virtual bool readSignature( long * sig0, long * sig1, long * sig2 );
|
||||
virtual bool checkSignature( long sig0, long sig1, long sig2 );
|
||||
|
||||
virtual bool writeFlashByte( long address, long value );
|
||||
virtual bool writeEEPROMByte( long address, long value );
|
||||
|
||||
virtual bool writeFlash( HEXFile * data );
|
||||
virtual bool readFlash( HEXFile * data );
|
||||
|
||||
virtual bool writeEEPROM( HEXFile * data );
|
||||
virtual bool readEEPROM( HEXFile * data );
|
||||
|
||||
virtual bool writeLockBits( long bits );
|
||||
virtual bool readLockBits( long * bits );
|
||||
|
||||
virtual bool writeFuseBits( long bits );
|
||||
virtual bool readFuseBits( long * bits );
|
||||
virtual bool writeExtendedFuseBits( long bits );
|
||||
virtual bool readExtendedFuseBits( long * bits );
|
||||
|
||||
virtual bool programmerSoftwareVersion( long * major, long * minor );
|
||||
virtual bool programmerHardwareVersion( long * major, long * minor );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,157 +1,157 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRDevice.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 4017 $
|
||||
* Date : $Date: 2008-06-02 14:26:03 +0200 (ma, 02 jun 2008) $
|
||||
* Updated by : $Author: khole $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class containing information of device memory sizes etc.
|
||||
* It also provides funcitons for reading these parameters from
|
||||
* the PartDescriptionFiles supplied with AVR Studio 4.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "AVRDevice.hpp"
|
||||
|
||||
|
||||
/* Constructor */
|
||||
AVRDevice::AVRDevice( const string & _deviceName ) :
|
||||
deviceName( _deviceName )
|
||||
{
|
||||
flashSize =
|
||||
eepromSize = 0;
|
||||
hasFuseBits = false;
|
||||
hasExtendedFuseBits = false;
|
||||
signature0 =
|
||||
signature1 =
|
||||
signature2 = 0;
|
||||
pagesize = -1;
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
AVRDevice::~AVRDevice()
|
||||
{
|
||||
/* no code here */
|
||||
}
|
||||
|
||||
/* Read parameters from AVR Studio XML files */
|
||||
void AVRDevice::readParametersFromAVRStudio( vector<string> & searchpath )
|
||||
{
|
||||
string path;
|
||||
string signature;
|
||||
string cache;
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
/* Locate the directory containing the XML files from the Windows registry database */
|
||||
try
|
||||
{
|
||||
path = Util.getRegistryValue( "SOFTWARE\\Atmel\\AVRTools\\", "AVRToolsPath" );
|
||||
path += "\\PartDescriptionFiles";
|
||||
searchpath.push_back( path );
|
||||
} catch( ErrorMsg * e )
|
||||
{
|
||||
delete e;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Search for file */
|
||||
path.erase();
|
||||
int i;
|
||||
for( i = 0; i < searchpath.size(); i++ )
|
||||
{
|
||||
path = searchpath[i] + "\\" + deviceName + ".xml";
|
||||
if( Util.fileExists( path ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == searchpath.size() )
|
||||
throw new ErrorMsg( "Device XML file not found in search path!" );
|
||||
|
||||
/* Parse the file for required info */
|
||||
Util.log( "Parsing '" + path + "'...\r\n" );
|
||||
XMLFile f( path ); // Load XML info
|
||||
|
||||
flashSize = atoi( f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" ).c_str() );
|
||||
eepromSize = atoi( f.getValue( "AVRPART\\MEMORY\\EEPROM" ).c_str() );
|
||||
|
||||
cache += "<AVRPART><MEMORY><PROG_FLASH>";
|
||||
cache += f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" );
|
||||
cache += "</PROG_FLASH><EEPROM>";
|
||||
cache += f.getValue( "AVRPART\\MEMORY\\EEPROM" );
|
||||
cache += "</EEPROM>";
|
||||
|
||||
if( f.exists( "AVRPART\\MEMORY\\BOOT_CONFIG" ) )
|
||||
{
|
||||
pagesize = atoi( f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" ).c_str() );
|
||||
pagesize <<= 1; // We want pagesize in bytes.
|
||||
|
||||
cache += "<BOOT_CONFIG><PAGESIZE>";
|
||||
cache += f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" );
|
||||
cache += "</PAGESIZE></BOOT_CONFIG>";
|
||||
}
|
||||
|
||||
cache += "</MEMORY>";
|
||||
|
||||
if( f.exists( "AVRPART\\FUSE" ) )
|
||||
{
|
||||
hasFuseBits = true;
|
||||
|
||||
cache += "<FUSE>";
|
||||
|
||||
if( f.exists( "AVRPART\\FUSE\\EXTENDED" ) )
|
||||
{
|
||||
hasExtendedFuseBits = true;
|
||||
cache += "<EXTENDED></EXTENDED>";
|
||||
}
|
||||
|
||||
cache += "</FUSE>";
|
||||
}
|
||||
|
||||
signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" );
|
||||
signature.erase( 0, 1 ); // Remove the $ character.
|
||||
signature0 = Util.convertHex( signature );
|
||||
|
||||
signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" );
|
||||
signature.erase( 0, 1 ); // Remove the $ character.
|
||||
signature1 = Util.convertHex( signature );
|
||||
|
||||
signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" );
|
||||
signature.erase( 0, 1 ); // Remove the $ character.
|
||||
signature2 = Util.convertHex( signature );
|
||||
|
||||
cache += "<ADMIN><SIGNATURE><ADDR000>";
|
||||
cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" );
|
||||
cache += "</ADDR000><ADDR001>";
|
||||
cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" );
|
||||
cache += "</ADDR001><ADDR002>";
|
||||
cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" );
|
||||
cache += "</ADDR002></SIGNATURE></ADMIN></AVRPART>\r\n";
|
||||
|
||||
/* Save cached file to application directory */
|
||||
Util.log( "Saving cached XML parameters...\r\n" );
|
||||
Util.saveString( cache, searchpath[1] + "\\" + deviceName + ".xml" );
|
||||
}
|
||||
|
||||
|
||||
void AVRDevice::getSignature( long * sig0, long * sig1, long * sig2 )
|
||||
{
|
||||
if( sig0 == NULL || sig1 == NULL || sig2 == NULL )
|
||||
throw new ErrorMsg( "Cannot copy signature bytes to NULL-pointers!" );
|
||||
|
||||
*sig0 = signature0;
|
||||
*sig1 = signature1;
|
||||
*sig2 = signature2;
|
||||
}
|
||||
|
||||
|
||||
/* end of file */
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRDevice.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 4017 $
|
||||
* Date : $Date: 2008-06-02 14:26:03 +0200 (ma, 02 jun 2008) $
|
||||
* Updated by : $Author: khole $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class containing information of device memory sizes etc.
|
||||
* It also provides funcitons for reading these parameters from
|
||||
* the PartDescriptionFiles supplied with AVR Studio 4.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "AVRDevice.hpp"
|
||||
|
||||
|
||||
/* Constructor */
|
||||
AVRDevice::AVRDevice( const string & _deviceName ) :
|
||||
deviceName( _deviceName )
|
||||
{
|
||||
flashSize =
|
||||
eepromSize = 0;
|
||||
hasFuseBits = false;
|
||||
hasExtendedFuseBits = false;
|
||||
signature0 =
|
||||
signature1 =
|
||||
signature2 = 0;
|
||||
pagesize = -1;
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
AVRDevice::~AVRDevice()
|
||||
{
|
||||
/* no code here */
|
||||
}
|
||||
|
||||
/* Read parameters from AVR Studio XML files */
|
||||
void AVRDevice::readParametersFromAVRStudio( vector<string> & searchpath )
|
||||
{
|
||||
string path;
|
||||
string signature;
|
||||
string cache;
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
/* Locate the directory containing the XML files from the Windows registry database */
|
||||
try
|
||||
{
|
||||
path = Util.getRegistryValue( "SOFTWARE\\Atmel\\AVRTools\\", "AVRToolsPath" );
|
||||
path += "\\PartDescriptionFiles";
|
||||
searchpath.push_back( path );
|
||||
} catch( ErrorMsg * e )
|
||||
{
|
||||
delete e;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Search for file */
|
||||
path.erase();
|
||||
int i;
|
||||
for( i = 0; i < searchpath.size(); i++ )
|
||||
{
|
||||
path = searchpath[i] + "\\" + deviceName + ".xml";
|
||||
if( Util.fileExists( path ) )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == searchpath.size() )
|
||||
throw new ErrorMsg( "Device XML file not found in search path!" );
|
||||
|
||||
/* Parse the file for required info */
|
||||
Util.log( "Parsing '" + path + "'...\r\n" );
|
||||
XMLFile f( path ); // Load XML info
|
||||
|
||||
flashSize = atoi( f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" ).c_str() );
|
||||
eepromSize = atoi( f.getValue( "AVRPART\\MEMORY\\EEPROM" ).c_str() );
|
||||
|
||||
cache += "<AVRPART><MEMORY><PROG_FLASH>";
|
||||
cache += f.getValue( "AVRPART\\MEMORY\\PROG_FLASH" );
|
||||
cache += "</PROG_FLASH><EEPROM>";
|
||||
cache += f.getValue( "AVRPART\\MEMORY\\EEPROM" );
|
||||
cache += "</EEPROM>";
|
||||
|
||||
if( f.exists( "AVRPART\\MEMORY\\BOOT_CONFIG" ) )
|
||||
{
|
||||
pagesize = atoi( f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" ).c_str() );
|
||||
pagesize <<= 1; // We want pagesize in bytes.
|
||||
|
||||
cache += "<BOOT_CONFIG><PAGESIZE>";
|
||||
cache += f.getValue( "AVRPART\\MEMORY\\BOOT_CONFIG\\PAGESIZE" );
|
||||
cache += "</PAGESIZE></BOOT_CONFIG>";
|
||||
}
|
||||
|
||||
cache += "</MEMORY>";
|
||||
|
||||
if( f.exists( "AVRPART\\FUSE" ) )
|
||||
{
|
||||
hasFuseBits = true;
|
||||
|
||||
cache += "<FUSE>";
|
||||
|
||||
if( f.exists( "AVRPART\\FUSE\\EXTENDED" ) )
|
||||
{
|
||||
hasExtendedFuseBits = true;
|
||||
cache += "<EXTENDED></EXTENDED>";
|
||||
}
|
||||
|
||||
cache += "</FUSE>";
|
||||
}
|
||||
|
||||
signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" );
|
||||
signature.erase( 0, 1 ); // Remove the $ character.
|
||||
signature0 = Util.convertHex( signature );
|
||||
|
||||
signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" );
|
||||
signature.erase( 0, 1 ); // Remove the $ character.
|
||||
signature1 = Util.convertHex( signature );
|
||||
|
||||
signature = f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" );
|
||||
signature.erase( 0, 1 ); // Remove the $ character.
|
||||
signature2 = Util.convertHex( signature );
|
||||
|
||||
cache += "<ADMIN><SIGNATURE><ADDR000>";
|
||||
cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR000" );
|
||||
cache += "</ADDR000><ADDR001>";
|
||||
cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR001" );
|
||||
cache += "</ADDR001><ADDR002>";
|
||||
cache += f.getValue( "AVRPART\\ADMIN\\SIGNATURE\\ADDR002" );
|
||||
cache += "</ADDR002></SIGNATURE></ADMIN></AVRPART>\r\n";
|
||||
|
||||
/* Save cached file to application directory */
|
||||
Util.log( "Saving cached XML parameters...\r\n" );
|
||||
Util.saveString( cache, searchpath[1] + "\\" + deviceName + ".xml" );
|
||||
}
|
||||
|
||||
|
||||
void AVRDevice::getSignature( long * sig0, long * sig1, long * sig2 )
|
||||
{
|
||||
if( sig0 == NULL || sig1 == NULL || sig2 == NULL )
|
||||
throw new ErrorMsg( "Cannot copy signature bytes to NULL-pointers!" );
|
||||
|
||||
*sig0 = signature0;
|
||||
*sig1 = signature1;
|
||||
*sig2 = signature2;
|
||||
}
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRDevice.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class containing information of device memory sizes etc.
|
||||
* It also provides funcitons for reading these parameters from
|
||||
* the PartDescriptionFiles supplied with AVR Studio 4.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRDEVICE_HPP
|
||||
#define AVRDEVICE_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Utility.hpp"
|
||||
#include "XMLParser.hpp"
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
class AVRDevice
|
||||
{
|
||||
protected:
|
||||
string deviceName; // The name of the device, eg. ATmega128.
|
||||
|
||||
long flashSize; // Size of Flash memory in bytes.
|
||||
long eepromSize; // Size of EEPROM memory in bytes.
|
||||
bool hasFuseBits; // Does this device have fuse bits at all?
|
||||
bool hasExtendedFuseBits; // Does this device have extended fuses?
|
||||
long signature0;
|
||||
long signature1;
|
||||
long signature2; // The three signature bytes, read from XML PartDescriptionFiles.
|
||||
long pagesize; // Flash page size.
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRDevice( const string & _deviceName );
|
||||
|
||||
/* Destructor */
|
||||
~AVRDevice();
|
||||
|
||||
/* Methods */
|
||||
void readParametersFromAVRStudio( vector<string> & searchpath );
|
||||
|
||||
long getFlashSize() { return flashSize; }
|
||||
long getEEPROMSize() { return eepromSize; }
|
||||
long getPageSize() { return pagesize; }
|
||||
bool getFuseStatus() { return hasFuseBits; }
|
||||
bool getXFuseStatus() { return hasExtendedFuseBits; }
|
||||
|
||||
void getSignature( long * sig0, long * sig1, long * sig2 );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRDevice.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class containing information of device memory sizes etc.
|
||||
* It also provides funcitons for reading these parameters from
|
||||
* the PartDescriptionFiles supplied with AVR Studio 4.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRDEVICE_HPP
|
||||
#define AVRDEVICE_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Utility.hpp"
|
||||
#include "XMLParser.hpp"
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
class AVRDevice
|
||||
{
|
||||
protected:
|
||||
string deviceName; // The name of the device, eg. ATmega128.
|
||||
|
||||
long flashSize; // Size of Flash memory in bytes.
|
||||
long eepromSize; // Size of EEPROM memory in bytes.
|
||||
bool hasFuseBits; // Does this device have fuse bits at all?
|
||||
bool hasExtendedFuseBits; // Does this device have extended fuses?
|
||||
long signature0;
|
||||
long signature1;
|
||||
long signature2; // The three signature bytes, read from XML PartDescriptionFiles.
|
||||
long pagesize; // Flash page size.
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRDevice( const string & _deviceName );
|
||||
|
||||
/* Destructor */
|
||||
~AVRDevice();
|
||||
|
||||
/* Methods */
|
||||
void readParametersFromAVRStudio( vector<string> & searchpath );
|
||||
|
||||
long getFlashSize() { return flashSize; }
|
||||
long getEEPROMSize() { return eepromSize; }
|
||||
long getPageSize() { return pagesize; }
|
||||
bool getFuseStatus() { return hasFuseBits; }
|
||||
bool getXFuseStatus() { return hasExtendedFuseBits; }
|
||||
|
||||
void getSignature( long * sig0, long * sig1, long * sig2 );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,78 +1,78 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRInSystemProg.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing an interface to the AVR ISP described
|
||||
* in Application Note AVR910. This class is derived from AVRPRogrammer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRINSYSTEMPROG_HPP
|
||||
#define AVRINSYSTEMPROG_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "AVRProgrammer.hpp"
|
||||
#include "Utility.hpp"
|
||||
|
||||
class AVRInSystemProg : public AVRProgrammer
|
||||
{
|
||||
protected:
|
||||
void setAddress( long address );
|
||||
void writeFlashLowByte( long value ); // Alwyas low byte first...
|
||||
void writeFlashHighByte( long value ); // ...then high byte.
|
||||
void writeFlashPage();
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRInSystemProg( CommChannel * _comm );
|
||||
|
||||
/* Destructor */
|
||||
~AVRInSystemProg();
|
||||
|
||||
/* Methods */
|
||||
virtual bool enterProgrammingMode();
|
||||
virtual bool leaveProgrammingMode();
|
||||
|
||||
virtual bool chipErase();
|
||||
|
||||
virtual bool readOSCCAL( long pos, long * value );
|
||||
virtual bool readSignature( long * sig0, long * sig1, long * sig2 );
|
||||
virtual bool checkSignature( long sig0, long sig1, long sig2 );
|
||||
|
||||
virtual bool writeFlashByte( long address, long value );
|
||||
virtual bool writeEEPROMByte( long address, long value );
|
||||
|
||||
virtual bool writeFlash( HEXFile * data );
|
||||
virtual bool readFlash( HEXFile * data );
|
||||
|
||||
virtual bool writeEEPROM( HEXFile * data );
|
||||
virtual bool readEEPROM( HEXFile * data );
|
||||
|
||||
virtual bool writeLockBits( long bits );
|
||||
virtual bool readLockBits( long * bits );
|
||||
|
||||
virtual bool writeFuseBits( long bits );
|
||||
virtual bool readFuseBits( long * bits );
|
||||
virtual bool writeExtendedFuseBits( long bits );
|
||||
virtual bool readExtendedFuseBits( long * bits );
|
||||
|
||||
virtual bool programmerSoftwareVersion( long * major, long * minor );
|
||||
virtual bool programmerHardwareVersion( long * major, long * minor );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRInSystemProg.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing an interface to the AVR ISP described
|
||||
* in Application Note AVR910. This class is derived from AVRPRogrammer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRINSYSTEMPROG_HPP
|
||||
#define AVRINSYSTEMPROG_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "AVRProgrammer.hpp"
|
||||
#include "Utility.hpp"
|
||||
|
||||
class AVRInSystemProg : public AVRProgrammer
|
||||
{
|
||||
protected:
|
||||
void setAddress( long address );
|
||||
void writeFlashLowByte( long value ); // Alwyas low byte first...
|
||||
void writeFlashHighByte( long value ); // ...then high byte.
|
||||
void writeFlashPage();
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRInSystemProg( CommChannel * _comm );
|
||||
|
||||
/* Destructor */
|
||||
~AVRInSystemProg();
|
||||
|
||||
/* Methods */
|
||||
virtual bool enterProgrammingMode();
|
||||
virtual bool leaveProgrammingMode();
|
||||
|
||||
virtual bool chipErase();
|
||||
|
||||
virtual bool readOSCCAL( long pos, long * value );
|
||||
virtual bool readSignature( long * sig0, long * sig1, long * sig2 );
|
||||
virtual bool checkSignature( long sig0, long sig1, long sig2 );
|
||||
|
||||
virtual bool writeFlashByte( long address, long value );
|
||||
virtual bool writeEEPROMByte( long address, long value );
|
||||
|
||||
virtual bool writeFlash( HEXFile * data );
|
||||
virtual bool readFlash( HEXFile * data );
|
||||
|
||||
virtual bool writeEEPROM( HEXFile * data );
|
||||
virtual bool readEEPROM( HEXFile * data );
|
||||
|
||||
virtual bool writeLockBits( long bits );
|
||||
virtual bool readLockBits( long * bits );
|
||||
|
||||
virtual bool writeFuseBits( long bits );
|
||||
virtual bool readFuseBits( long * bits );
|
||||
virtual bool writeExtendedFuseBits( long bits );
|
||||
virtual bool readExtendedFuseBits( long * bits );
|
||||
|
||||
virtual bool programmerSoftwareVersion( long * major, long * minor );
|
||||
virtual bool programmerHardwareVersion( long * major, long * minor );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,169 +1,169 @@
|
||||
[Project]
|
||||
FileName=AVROSP.dev
|
||||
Name=AVROSP
|
||||
UnitCount=12
|
||||
Type=1
|
||||
Ver=1
|
||||
ObjFiles=
|
||||
Includes=
|
||||
Libs=
|
||||
PrivateResource=
|
||||
ResourceIncludes=
|
||||
MakeIncludes=
|
||||
Compiler=
|
||||
CppCompiler=
|
||||
Linker=
|
||||
IsCpp=1
|
||||
Icon=
|
||||
ExeOutput=
|
||||
ObjectOutput=
|
||||
OverrideOutput=0
|
||||
OverrideOutputName=AVROSP.exe
|
||||
HostApplication=
|
||||
Folders=
|
||||
CommandLine= -dATmega16 -if\temp\rnd8KB.hex -pf
|
||||
IncludeVersionInfo=0
|
||||
SupportXPThemes=0
|
||||
CompilerSet=0
|
||||
CompilerSettings=000000000000000100
|
||||
UseCustomMakefile=0
|
||||
CustomMakefile=
|
||||
|
||||
[Unit1]
|
||||
FileName=main.cpp
|
||||
CompileCpp=1
|
||||
Folder=
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[VersionInfo]
|
||||
Major=0
|
||||
Minor=1
|
||||
Release=1
|
||||
Build=1
|
||||
LanguageID=1033
|
||||
CharsetID=1252
|
||||
CompanyName=
|
||||
FileVersion=
|
||||
FileDescription=Developed using the Dev-C++ IDE
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=
|
||||
AutoIncBuildNr=0
|
||||
|
||||
[Unit2]
|
||||
FileName=CommChannel.cpp
|
||||
CompileCpp=1
|
||||
Folder=Serialtest
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit3]
|
||||
FileName=ErrorMsg.cpp
|
||||
CompileCpp=1
|
||||
Folder=Serialtest
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit4]
|
||||
FileName=JobInfo.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit5]
|
||||
FileName=AVRDevice.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit6]
|
||||
FileName=HEXParser.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit7]
|
||||
FileName=XMLParser.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit8]
|
||||
FileName=AVRBootloader.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit9]
|
||||
FileName=AVRProgrammer.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit10]
|
||||
FileName=Utility.cpp
|
||||
CompileCpp=1
|
||||
Folder=
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit11]
|
||||
FileName=SerialPort.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit12]
|
||||
FileName=AVRInSystemProg.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Project]
|
||||
FileName=AVROSP.dev
|
||||
Name=AVROSP
|
||||
UnitCount=12
|
||||
Type=1
|
||||
Ver=1
|
||||
ObjFiles=
|
||||
Includes=
|
||||
Libs=
|
||||
PrivateResource=
|
||||
ResourceIncludes=
|
||||
MakeIncludes=
|
||||
Compiler=
|
||||
CppCompiler=
|
||||
Linker=
|
||||
IsCpp=1
|
||||
Icon=
|
||||
ExeOutput=
|
||||
ObjectOutput=
|
||||
OverrideOutput=0
|
||||
OverrideOutputName=AVROSP.exe
|
||||
HostApplication=
|
||||
Folders=
|
||||
CommandLine= -dATmega16 -if\temp\rnd8KB.hex -pf
|
||||
IncludeVersionInfo=0
|
||||
SupportXPThemes=0
|
||||
CompilerSet=0
|
||||
CompilerSettings=000000000000000100
|
||||
UseCustomMakefile=0
|
||||
CustomMakefile=
|
||||
|
||||
[Unit1]
|
||||
FileName=main.cpp
|
||||
CompileCpp=1
|
||||
Folder=
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[VersionInfo]
|
||||
Major=0
|
||||
Minor=1
|
||||
Release=1
|
||||
Build=1
|
||||
LanguageID=1033
|
||||
CharsetID=1252
|
||||
CompanyName=
|
||||
FileVersion=
|
||||
FileDescription=Developed using the Dev-C++ IDE
|
||||
InternalName=
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=
|
||||
ProductName=
|
||||
ProductVersion=
|
||||
AutoIncBuildNr=0
|
||||
|
||||
[Unit2]
|
||||
FileName=CommChannel.cpp
|
||||
CompileCpp=1
|
||||
Folder=Serialtest
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit3]
|
||||
FileName=ErrorMsg.cpp
|
||||
CompileCpp=1
|
||||
Folder=Serialtest
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit4]
|
||||
FileName=JobInfo.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit5]
|
||||
FileName=AVRDevice.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit6]
|
||||
FileName=HEXParser.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit7]
|
||||
FileName=XMLParser.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit8]
|
||||
FileName=AVRBootloader.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit9]
|
||||
FileName=AVRProgrammer.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit10]
|
||||
FileName=Utility.cpp
|
||||
CompileCpp=1
|
||||
Folder=
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit11]
|
||||
FileName=SerialPort.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
[Unit12]
|
||||
FileName=AVRInSystemProg.cpp
|
||||
CompileCpp=1
|
||||
Folder=AVROSP
|
||||
Compile=1
|
||||
Link=1
|
||||
Priority=1000
|
||||
OverrideBuildCmd=0
|
||||
BuildCmd=
|
||||
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRProgrammer.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class containing a framework for a generic
|
||||
* programmer for AVR parts. Reading and writing Flash, EEPROM
|
||||
* lock bits and all fuse bits and reading OSCCAL and reading
|
||||
* signature bytes are supported.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "AVRProgrammer.hpp"
|
||||
|
||||
|
||||
/* Constructor */
|
||||
AVRProgrammer::AVRProgrammer( CommChannel * _comm ) :
|
||||
pagesize( -1 )
|
||||
{
|
||||
if( _comm == NULL )
|
||||
throw new ErrorMsg( "NULL pointer provided for communication channel!" );
|
||||
|
||||
comm = _comm;
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
AVRProgrammer::~AVRProgrammer()
|
||||
{
|
||||
/* No code here */
|
||||
}
|
||||
|
||||
|
||||
string AVRProgrammer::readProgrammerID( CommChannel * _comm )
|
||||
{
|
||||
string id( "1234567" ); // Reserve 7 characters.
|
||||
|
||||
if( _comm == NULL )
|
||||
throw new ErrorMsg( "NULL pointer provided for communication channel!" );
|
||||
|
||||
/* Synchonize with programmer */
|
||||
for( int i = 0; i < 10; i++ )
|
||||
_comm->sendByte( 27 ); // Send ESC
|
||||
|
||||
/* Send 'S' command to programmer */
|
||||
_comm->sendByte( 'S' );
|
||||
_comm->flushTX();
|
||||
|
||||
/* Read 7 characters */
|
||||
for( long i = 0; i < id.size(); i++ )
|
||||
{
|
||||
id[i] = _comm->getByte();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRProgrammer.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class containing a framework for a generic
|
||||
* programmer for AVR parts. Reading and writing Flash, EEPROM
|
||||
* lock bits and all fuse bits and reading OSCCAL and reading
|
||||
* signature bytes are supported.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "AVRProgrammer.hpp"
|
||||
|
||||
|
||||
/* Constructor */
|
||||
AVRProgrammer::AVRProgrammer( CommChannel * _comm ) :
|
||||
pagesize( -1 )
|
||||
{
|
||||
if( _comm == NULL )
|
||||
throw new ErrorMsg( "NULL pointer provided for communication channel!" );
|
||||
|
||||
comm = _comm;
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
AVRProgrammer::~AVRProgrammer()
|
||||
{
|
||||
/* No code here */
|
||||
}
|
||||
|
||||
|
||||
string AVRProgrammer::readProgrammerID( CommChannel * _comm )
|
||||
{
|
||||
string id( "1234567" ); // Reserve 7 characters.
|
||||
|
||||
if( _comm == NULL )
|
||||
throw new ErrorMsg( "NULL pointer provided for communication channel!" );
|
||||
|
||||
/* Synchonize with programmer */
|
||||
for( int i = 0; i < 10; i++ )
|
||||
_comm->sendByte( 27 ); // Send ESC
|
||||
|
||||
/* Send 'S' command to programmer */
|
||||
_comm->sendByte( 'S' );
|
||||
_comm->flushTX();
|
||||
|
||||
/* Read 7 characters */
|
||||
for( long i = 0; i < id.size(); i++ )
|
||||
{
|
||||
id[i] = _comm->getByte();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRProgrammer.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class containing a framework for a generic
|
||||
* programmer for AVR parts. Reading and writing Flash, EEPROM
|
||||
* lock bits and all fuse bits and reading OSCCAL and reading
|
||||
* signature bytes are supported.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRPROGRAMMER_HPP
|
||||
#define AVRPROGRAMMER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "HEXParser.hpp"
|
||||
#include "CommChannel.hpp"
|
||||
|
||||
class AVRProgrammer
|
||||
{
|
||||
protected:
|
||||
long pagesize; // Flash page size.
|
||||
CommChannel * comm;
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRProgrammer( CommChannel * _comm );
|
||||
|
||||
/* Destructor */
|
||||
~AVRProgrammer();
|
||||
|
||||
/* Static member */
|
||||
static string readProgrammerID( CommChannel * _comm ); // Reads 7-character ID.
|
||||
|
||||
/* Methods */
|
||||
void setPagesize( long _pagesize ) { pagesize = _pagesize; }
|
||||
|
||||
virtual bool enterProgrammingMode() = 0;
|
||||
virtual bool leaveProgrammingMode() = 0;
|
||||
|
||||
virtual bool chipErase() = 0;
|
||||
|
||||
virtual bool readOSCCAL( long pos, long * value ) = 0;
|
||||
virtual bool readSignature( long * sig0, long * sig1, long * sig2 ) = 0;
|
||||
virtual bool checkSignature( long sig0, long sig1, long sig2 ) = 0;
|
||||
|
||||
virtual bool writeFlashByte( long address, long value ) = 0;
|
||||
virtual bool writeEEPROMByte( long address, long value ) = 0;
|
||||
|
||||
virtual bool writeFlash( HEXFile * data ) = 0;
|
||||
virtual bool readFlash( HEXFile * data ) = 0;
|
||||
|
||||
virtual bool writeEEPROM( HEXFile * data ) = 0;
|
||||
virtual bool readEEPROM( HEXFile * data ) = 0;
|
||||
|
||||
virtual bool writeLockBits( long bits ) = 0;
|
||||
virtual bool readLockBits( long * bits ) = 0;
|
||||
|
||||
virtual bool writeFuseBits( long bits ) = 0;
|
||||
virtual bool readFuseBits( long * bits ) = 0;
|
||||
virtual bool writeExtendedFuseBits( long bits ) = 0;
|
||||
virtual bool readExtendedFuseBits( long * bits ) = 0;
|
||||
|
||||
virtual bool programmerSoftwareVersion( long * major, long * minor ) = 0;
|
||||
virtual bool programmerHardwareVersion( long * major, long * minor ) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : AVRProgrammer.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class containing a framework for a generic
|
||||
* programmer for AVR parts. Reading and writing Flash, EEPROM
|
||||
* lock bits and all fuse bits and reading OSCCAL and reading
|
||||
* signature bytes are supported.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef AVRPROGRAMMER_HPP
|
||||
#define AVRPROGRAMMER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "HEXParser.hpp"
|
||||
#include "CommChannel.hpp"
|
||||
|
||||
class AVRProgrammer
|
||||
{
|
||||
protected:
|
||||
long pagesize; // Flash page size.
|
||||
CommChannel * comm;
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
AVRProgrammer( CommChannel * _comm );
|
||||
|
||||
/* Destructor */
|
||||
~AVRProgrammer();
|
||||
|
||||
/* Static member */
|
||||
static string readProgrammerID( CommChannel * _comm ); // Reads 7-character ID.
|
||||
|
||||
/* Methods */
|
||||
void setPagesize( long _pagesize ) { pagesize = _pagesize; }
|
||||
|
||||
virtual bool enterProgrammingMode() = 0;
|
||||
virtual bool leaveProgrammingMode() = 0;
|
||||
|
||||
virtual bool chipErase() = 0;
|
||||
|
||||
virtual bool readOSCCAL( long pos, long * value ) = 0;
|
||||
virtual bool readSignature( long * sig0, long * sig1, long * sig2 ) = 0;
|
||||
virtual bool checkSignature( long sig0, long sig1, long sig2 ) = 0;
|
||||
|
||||
virtual bool writeFlashByte( long address, long value ) = 0;
|
||||
virtual bool writeEEPROMByte( long address, long value ) = 0;
|
||||
|
||||
virtual bool writeFlash( HEXFile * data ) = 0;
|
||||
virtual bool readFlash( HEXFile * data ) = 0;
|
||||
|
||||
virtual bool writeEEPROM( HEXFile * data ) = 0;
|
||||
virtual bool readEEPROM( HEXFile * data ) = 0;
|
||||
|
||||
virtual bool writeLockBits( long bits ) = 0;
|
||||
virtual bool readLockBits( long * bits ) = 0;
|
||||
|
||||
virtual bool writeFuseBits( long bits ) = 0;
|
||||
virtual bool readFuseBits( long * bits ) = 0;
|
||||
virtual bool writeExtendedFuseBits( long bits ) = 0;
|
||||
virtual bool readExtendedFuseBits( long * bits ) = 0;
|
||||
|
||||
virtual bool programmerSoftwareVersion( long * major, long * minor ) = 0;
|
||||
virtual bool programmerHardwareVersion( long * major, long * minor ) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : CommChannel.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class for general byte-by-byte communication.
|
||||
* Serialport, USB, TCP/IP or similar implementations can be derived
|
||||
* from this class to create a technology-independent
|
||||
* communication interface.
|
||||
*
|
||||
* This abstract class does not provide any constructor as it is
|
||||
* too specific for this generalized class. Derived classes should
|
||||
* implement their own constructors for specific communication devices.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "CommChannel.hpp"
|
||||
|
||||
|
||||
/* Destructor */
|
||||
CommChannel::~CommChannel()
|
||||
{
|
||||
/* no code here */
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : CommChannel.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class for general byte-by-byte communication.
|
||||
* Serialport, USB, TCP/IP or similar implementations can be derived
|
||||
* from this class to create a technology-independent
|
||||
* communication interface.
|
||||
*
|
||||
* This abstract class does not provide any constructor as it is
|
||||
* too specific for this generalized class. Derived classes should
|
||||
* implement their own constructors for specific communication devices.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "CommChannel.hpp"
|
||||
|
||||
|
||||
/* Destructor */
|
||||
CommChannel::~CommChannel()
|
||||
{
|
||||
/* no code here */
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : CommChannel.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class for general byte-by-byte communication.
|
||||
* Serialport, USB, TCP/IP or similar implementations can be derived
|
||||
* from this class to create a technology-independent
|
||||
* communication interface.
|
||||
*
|
||||
* This abstract class does not provide any constructor as it is
|
||||
* too specific for this generalized class. Derived classes should
|
||||
* implement their own constructors for specific communication devices.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef COMMCHANNEL_HPP
|
||||
#define COMMCHANNEL_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CommChannel
|
||||
{
|
||||
public:
|
||||
// Destructor
|
||||
virtual ~CommChannel() = 0;
|
||||
|
||||
// Open the communication channel.
|
||||
virtual void openChannel() = 0;
|
||||
|
||||
// Close the communication channel.
|
||||
virtual void closeChannel() = 0;
|
||||
|
||||
// Transmit a single byte.
|
||||
virtual void sendByte( long data ) = 0;
|
||||
|
||||
// Receive a single byte.
|
||||
virtual long getByte() = 0;
|
||||
|
||||
// Flush the transmit buffer.
|
||||
virtual void flushTX() = 0;
|
||||
|
||||
// Flush the receive buffer.
|
||||
virtual void flushRX() = 0;
|
||||
|
||||
// Transmit multiple bytes.
|
||||
virtual void sendMultiple( unsigned char * data, long bufsize ) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : CommChannel.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : An abstract class for general byte-by-byte communication.
|
||||
* Serialport, USB, TCP/IP or similar implementations can be derived
|
||||
* from this class to create a technology-independent
|
||||
* communication interface.
|
||||
*
|
||||
* This abstract class does not provide any constructor as it is
|
||||
* too specific for this generalized class. Derived classes should
|
||||
* implement their own constructors for specific communication devices.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef COMMCHANNEL_HPP
|
||||
#define COMMCHANNEL_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CommChannel
|
||||
{
|
||||
public:
|
||||
// Destructor
|
||||
virtual ~CommChannel() = 0;
|
||||
|
||||
// Open the communication channel.
|
||||
virtual void openChannel() = 0;
|
||||
|
||||
// Close the communication channel.
|
||||
virtual void closeChannel() = 0;
|
||||
|
||||
// Transmit a single byte.
|
||||
virtual void sendByte( long data ) = 0;
|
||||
|
||||
// Receive a single byte.
|
||||
virtual long getByte() = 0;
|
||||
|
||||
// Flush the transmit buffer.
|
||||
virtual void flushTX() = 0;
|
||||
|
||||
// Flush the receive buffer.
|
||||
virtual void flushRX() = 0;
|
||||
|
||||
// Transmit multiple bytes.
|
||||
virtual void sendMultiple( unsigned char * data, long bufsize ) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : ErrorMsg.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing a container for general error messages. This
|
||||
* class can be thrown as an exception.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
|
||||
ErrorMsg::ErrorMsg( const string & _message ) :
|
||||
message( _message )
|
||||
{
|
||||
// No code here.
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
ErrorMsg::~ErrorMsg()
|
||||
{
|
||||
// No code here.
|
||||
}
|
||||
|
||||
|
||||
/* Get message */
|
||||
const string & ErrorMsg::What()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : ErrorMsg.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing a container for general error messages. This
|
||||
* class can be thrown as an exception.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
|
||||
ErrorMsg::ErrorMsg( const string & _message ) :
|
||||
message( _message )
|
||||
{
|
||||
// No code here.
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
ErrorMsg::~ErrorMsg()
|
||||
{
|
||||
// No code here.
|
||||
}
|
||||
|
||||
|
||||
/* Get message */
|
||||
const string & ErrorMsg::What()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : ErrorMsg.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing a container for general error messages. This
|
||||
* class can be thrown as an exception.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef ERRORMSG_HPP
|
||||
#define ERRORMSG_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
||||
class ErrorMsg
|
||||
{
|
||||
protected:
|
||||
string message; // Contains the error message.
|
||||
|
||||
public:
|
||||
// Constructors taking the string as parameter.
|
||||
ErrorMsg( const string & _message );
|
||||
|
||||
// Destructor
|
||||
~ErrorMsg();
|
||||
|
||||
// Function returning the error msg.
|
||||
virtual const string & What();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : ErrorMsg.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing a container for general error messages. This
|
||||
* class can be thrown as an exception.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef ERRORMSG_HPP
|
||||
#define ERRORMSG_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
||||
class ErrorMsg
|
||||
{
|
||||
protected:
|
||||
string message; // Contains the error message.
|
||||
|
||||
public:
|
||||
// Constructors taking the string as parameter.
|
||||
ErrorMsg( const string & _message );
|
||||
|
||||
// Destructor
|
||||
~ErrorMsg();
|
||||
|
||||
// Function returning the error msg.
|
||||
virtual const string & What();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,364 +1,364 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : HEXParser.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A simple Intel HEX file format reader/writer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "HEXParser.hpp"
|
||||
|
||||
|
||||
/* Internal struct for managing HEX records */
|
||||
struct HEXRecord // Intel HEX file record
|
||||
{
|
||||
unsigned char length; // Record length in number of data bytes.
|
||||
unsigned long offset; // Offset address.
|
||||
unsigned char type; // Record type.
|
||||
unsigned char * data; // Optional data bytes.
|
||||
};
|
||||
|
||||
|
||||
void HEXFile::writeRecord( ofstream & f, HEXRecord * recp )
|
||||
{
|
||||
unsigned char checksum;
|
||||
long recordPos; // Position inside record data field
|
||||
|
||||
/* Calculate checksum */
|
||||
checksum = recp->length;
|
||||
checksum += (unsigned char) ((recp->offset >> 8) & 0xff);
|
||||
checksum += (unsigned char) (recp->offset & 0xff);
|
||||
checksum += recp->type;
|
||||
|
||||
/* Write record header */
|
||||
f.fill('0');
|
||||
f << ":" << hex
|
||||
<< setw(2) << (long) recp->length
|
||||
<< setw(4) << (long) recp->offset
|
||||
<< setw(2) << (long) recp->type;
|
||||
|
||||
/* Write data bytes */
|
||||
for( recordPos = 0; recordPos < recp->length; recordPos++ )
|
||||
{
|
||||
checksum += recp->data[ recordPos ]; // Further checksum calculation
|
||||
f << hex << setw(2) << (long) recp->data[ recordPos ];
|
||||
}
|
||||
|
||||
/* Write checksum */
|
||||
checksum = 0 - checksum; // Final checksum preparation
|
||||
f << setw(2) << (long) checksum << endl;
|
||||
|
||||
/* Check for errors */
|
||||
if( !f.good() )
|
||||
throw new ErrorMsg( "Error writing HEX record to file!" );
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::parseRecord( const string & hexLine, HEXRecord * recp )
|
||||
{
|
||||
unsigned char checksum;
|
||||
long recordPos; // Position inside record data fields.
|
||||
|
||||
if( hexLine.size() < 11 ) // At least 11 characters.
|
||||
throw new ErrorMsg( "Wrong HEX file format, missing fields! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
/* Check format for line */
|
||||
if( hexLine[0] != ':' ) // Always start with colon.
|
||||
throw new ErrorMsg( "Wrong HEX file format, does not start with colon! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
/* Parse length, offset and type */
|
||||
recp->length = Util.convertHex( hexLine.substr( 1, 2 ) );
|
||||
recp->offset = Util.convertHex( hexLine.substr( 3, 4 ) );
|
||||
recp->type = Util.convertHex( hexLine.substr( 7, 2 ) );
|
||||
|
||||
/* We now know how long the record should be */
|
||||
if( hexLine.size() < (11+recp->length*2) )
|
||||
throw new ErrorMsg( "Wrong HEX file format, missing fields! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
/* Process checksum */
|
||||
checksum = recp->length;
|
||||
checksum += (unsigned char) ((recp->offset >> 8) & 0xff);
|
||||
checksum += (unsigned char) (recp->offset & 0xff);
|
||||
checksum += recp->type;
|
||||
|
||||
/* Parse data fields */
|
||||
if( recp->length )
|
||||
{
|
||||
recp->data = new unsigned char[ recp->length ];
|
||||
|
||||
/* Read data from record */
|
||||
for( recordPos = 0; recordPos < recp->length; recordPos++ )
|
||||
{
|
||||
recp->data[ recordPos ] = Util.convertHex( hexLine.substr( 9 + recordPos*2, 2 ) );
|
||||
checksum += recp->data[ recordPos ];
|
||||
}
|
||||
}
|
||||
|
||||
/* Correct checksum? */
|
||||
checksum += Util.convertHex( hexLine.substr( 9 + recp->length*2, 2 ) );
|
||||
if( checksum != 0 )
|
||||
{
|
||||
throw new ErrorMsg( "Wrong checksum for HEX record! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Constructor */
|
||||
HEXFile::HEXFile( long buffersize, long value )
|
||||
{
|
||||
if( buffersize <= 0 )
|
||||
throw new ErrorMsg( "Cannot have zero-size HEX buffer!" );
|
||||
|
||||
data = new unsigned char[ buffersize ];
|
||||
|
||||
if( !data )
|
||||
throw new ErrorMsg( "Memory allocation failed for HEX-line-buffer!" );
|
||||
|
||||
size = buffersize;
|
||||
|
||||
clearAll( value );
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
HEXFile::~HEXFile()
|
||||
{
|
||||
if( data ) delete data;
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::readFile( const string & _filename )
|
||||
{
|
||||
ifstream f;
|
||||
string hexLine; // Contains one line of the HEX file.
|
||||
HEXRecord rec; // Temp record.
|
||||
|
||||
long baseAddress; // Base address for extended addressing modes.
|
||||
long dataPos; // Data position in record.
|
||||
|
||||
/* Attempt to open file */
|
||||
f.open( _filename.c_str(), ios::in );
|
||||
if( !f )
|
||||
throw new ErrorMsg( "Error opening HEX file for input!" );
|
||||
|
||||
/* Prepare */
|
||||
baseAddress = 0;
|
||||
start = size;
|
||||
end = 0;
|
||||
|
||||
/* Parse records */
|
||||
f >> hexLine; // Read one line.
|
||||
while( !f.eof() )
|
||||
{
|
||||
Util.progress( "#" ); // Advance progress indicator.
|
||||
|
||||
/* Process record according to type */
|
||||
parseRecord( hexLine, &rec );
|
||||
|
||||
switch( rec.type )
|
||||
{
|
||||
case 0x00 : // Data record ?
|
||||
/* Copy data */
|
||||
if( baseAddress + rec.offset + rec.length > size )
|
||||
throw new ErrorMsg( "HEX file defines data outside buffer limits! "
|
||||
"Make sure file does not contain data outside device "
|
||||
"memory limits. "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
for( dataPos = 0; dataPos < rec.length; dataPos++ )
|
||||
data[ baseAddress + rec.offset + dataPos ] = rec.data[ dataPos ];
|
||||
|
||||
/* Update byte usage */
|
||||
if( baseAddress + rec.offset < start )
|
||||
start = baseAddress + rec.offset;
|
||||
|
||||
if( baseAddress + rec.offset + rec.length - 1 > end )
|
||||
end = baseAddress + rec.offset + rec.length - 1;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 0x02 : // Extended segment address record ?
|
||||
baseAddress = (rec.data[0] << 8) | rec.data[1];
|
||||
baseAddress <<= 4;
|
||||
break;
|
||||
|
||||
case 0x03 : // Start segment address record ?
|
||||
break; // Ignore it, since we have no influence on execution start address.
|
||||
|
||||
case 0x04 : // Extended linear address record ?
|
||||
baseAddress = (rec.data[0] << 8) | rec.data[1];
|
||||
baseAddress <<= 16;
|
||||
break;
|
||||
|
||||
case 0x05 : // Start linear address record ?
|
||||
break; // Ignore it, since we have no influence on exectuion start address.
|
||||
|
||||
case 0x01 : // End of file record ?
|
||||
f.close();
|
||||
Util.progress( "\r\n" ); // Finish progress indicator.
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new ErrorMsg( "Unsupported HEX record format! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
}
|
||||
|
||||
f >> hexLine; // Read next line.
|
||||
}
|
||||
|
||||
|
||||
/* We should not end up here */
|
||||
throw new ErrorMsg( "Premature end of file encountered! Make sure file "
|
||||
"contains an EOF-record." );
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::writeFile( const string & _filename )
|
||||
{
|
||||
ofstream f;
|
||||
HEXRecord rec; // Temp record.
|
||||
|
||||
long baseAddress; // Absolute data position.
|
||||
long offset; // Offset from base address.
|
||||
long dataPos; // Position inside data record.
|
||||
|
||||
enum
|
||||
{
|
||||
_first,
|
||||
_writing,
|
||||
_passed64k
|
||||
} status; // Write status, see usage below.
|
||||
|
||||
/* Attempt to create file */
|
||||
f.open( _filename.c_str(), ios::out );
|
||||
if( !f )
|
||||
throw new ErrorMsg( "Error opening HEX file for output!" );
|
||||
|
||||
/* Prepare */
|
||||
status = _first;
|
||||
rec.data = new unsigned char[ 16 ]; // Use only 16 byte records.
|
||||
|
||||
baseAddress = start & ~0xffff; // 64K aligned address.
|
||||
offset = start & 0xffff; // Offset from the aligned address.
|
||||
dataPos = 0;
|
||||
|
||||
/* Write first base address record to HEX file */
|
||||
rec.length = 2;
|
||||
rec.offset = 0;
|
||||
rec.type = 0x02;
|
||||
rec.data[1] = 0x00;
|
||||
rec.data[0] = baseAddress >> 12; // Give 4k page index.
|
||||
writeRecord( f, &rec ); // Write the HEX record to file.
|
||||
|
||||
|
||||
/* Write all bytes in used range */
|
||||
do
|
||||
{
|
||||
/* Put data into record */
|
||||
rec.data[ dataPos ] = data[ baseAddress + offset + dataPos ];
|
||||
dataPos++;
|
||||
|
||||
/* Check if we need to write out the current data record */
|
||||
if( offset + dataPos >= 0x10000 || // Reached 64k boundary?
|
||||
dataPos >= 16 || // Data record full?
|
||||
baseAddress + offset + dataPos > end ) // End of used range reached?
|
||||
{
|
||||
/* Write current data record */
|
||||
rec.length = dataPos;
|
||||
rec.offset = offset;
|
||||
rec.type = 0x00; // Data record.
|
||||
|
||||
Util.progress( "#" ); // Advance progress indicator.
|
||||
writeRecord( f, &rec );
|
||||
|
||||
offset += dataPos;
|
||||
dataPos = 0;
|
||||
}
|
||||
|
||||
/* Check if we have passed a 64k boundary */
|
||||
if( offset + dataPos >= 0x10000 )
|
||||
{
|
||||
/* Update address pointers */
|
||||
offset -= 0x10000;
|
||||
baseAddress += 0x10000;
|
||||
|
||||
/* Write new base address record to HEX file */
|
||||
rec.length = 2;
|
||||
rec.offset = 0;
|
||||
rec.type = 0x02;
|
||||
rec.data[0] = baseAddress >> 12; // Give 4k page index.
|
||||
rec.data[1] = 0x00;
|
||||
|
||||
writeRecord( f, &rec ); // Write the HEX record to file.
|
||||
}
|
||||
} while( baseAddress + offset + dataPos <= end );
|
||||
|
||||
|
||||
/* Write EOF record */
|
||||
rec.length = 0;
|
||||
rec.offset = 0;
|
||||
rec.type = 0x01;
|
||||
|
||||
writeRecord( f, &rec );
|
||||
|
||||
f.close();
|
||||
Util.progress( "\r\n" ); // Finish progress indicator.
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::setUsedRange( long _start, long _end )
|
||||
{
|
||||
if( _start < 0 || _end >= size || _start > _end )
|
||||
throw new ErrorMsg( "Invalid range! Start must be 0 or larger, end must be "
|
||||
"inside allowed memory range." );
|
||||
|
||||
start = _start;
|
||||
end = _end;
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::clearAll( long value )
|
||||
{
|
||||
for( long i = 0; i < size; i++ )
|
||||
data[i] = (unsigned char) (value & 0xff);
|
||||
}
|
||||
|
||||
|
||||
long HEXFile::getData( long address )
|
||||
{
|
||||
if( address < 0 || address >= size )
|
||||
throw new ErrorMsg( "Address outside legal range!" );
|
||||
|
||||
return data[ address ];
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::setData( long address, long value )
|
||||
{
|
||||
if( address < 0 || address >= size )
|
||||
throw new ErrorMsg( "Address outside legal range!" );
|
||||
|
||||
data[ address ] = (unsigned char) (value & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : HEXParser.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A simple Intel HEX file format reader/writer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "HEXParser.hpp"
|
||||
|
||||
|
||||
/* Internal struct for managing HEX records */
|
||||
struct HEXRecord // Intel HEX file record
|
||||
{
|
||||
unsigned char length; // Record length in number of data bytes.
|
||||
unsigned long offset; // Offset address.
|
||||
unsigned char type; // Record type.
|
||||
unsigned char * data; // Optional data bytes.
|
||||
};
|
||||
|
||||
|
||||
void HEXFile::writeRecord( ofstream & f, HEXRecord * recp )
|
||||
{
|
||||
unsigned char checksum;
|
||||
long recordPos; // Position inside record data field
|
||||
|
||||
/* Calculate checksum */
|
||||
checksum = recp->length;
|
||||
checksum += (unsigned char) ((recp->offset >> 8) & 0xff);
|
||||
checksum += (unsigned char) (recp->offset & 0xff);
|
||||
checksum += recp->type;
|
||||
|
||||
/* Write record header */
|
||||
f.fill('0');
|
||||
f << ":" << hex
|
||||
<< setw(2) << (long) recp->length
|
||||
<< setw(4) << (long) recp->offset
|
||||
<< setw(2) << (long) recp->type;
|
||||
|
||||
/* Write data bytes */
|
||||
for( recordPos = 0; recordPos < recp->length; recordPos++ )
|
||||
{
|
||||
checksum += recp->data[ recordPos ]; // Further checksum calculation
|
||||
f << hex << setw(2) << (long) recp->data[ recordPos ];
|
||||
}
|
||||
|
||||
/* Write checksum */
|
||||
checksum = 0 - checksum; // Final checksum preparation
|
||||
f << setw(2) << (long) checksum << endl;
|
||||
|
||||
/* Check for errors */
|
||||
if( !f.good() )
|
||||
throw new ErrorMsg( "Error writing HEX record to file!" );
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::parseRecord( const string & hexLine, HEXRecord * recp )
|
||||
{
|
||||
unsigned char checksum;
|
||||
long recordPos; // Position inside record data fields.
|
||||
|
||||
if( hexLine.size() < 11 ) // At least 11 characters.
|
||||
throw new ErrorMsg( "Wrong HEX file format, missing fields! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
/* Check format for line */
|
||||
if( hexLine[0] != ':' ) // Always start with colon.
|
||||
throw new ErrorMsg( "Wrong HEX file format, does not start with colon! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
/* Parse length, offset and type */
|
||||
recp->length = Util.convertHex( hexLine.substr( 1, 2 ) );
|
||||
recp->offset = Util.convertHex( hexLine.substr( 3, 4 ) );
|
||||
recp->type = Util.convertHex( hexLine.substr( 7, 2 ) );
|
||||
|
||||
/* We now know how long the record should be */
|
||||
if( hexLine.size() < (11+recp->length*2) )
|
||||
throw new ErrorMsg( "Wrong HEX file format, missing fields! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
/* Process checksum */
|
||||
checksum = recp->length;
|
||||
checksum += (unsigned char) ((recp->offset >> 8) & 0xff);
|
||||
checksum += (unsigned char) (recp->offset & 0xff);
|
||||
checksum += recp->type;
|
||||
|
||||
/* Parse data fields */
|
||||
if( recp->length )
|
||||
{
|
||||
recp->data = new unsigned char[ recp->length ];
|
||||
|
||||
/* Read data from record */
|
||||
for( recordPos = 0; recordPos < recp->length; recordPos++ )
|
||||
{
|
||||
recp->data[ recordPos ] = Util.convertHex( hexLine.substr( 9 + recordPos*2, 2 ) );
|
||||
checksum += recp->data[ recordPos ];
|
||||
}
|
||||
}
|
||||
|
||||
/* Correct checksum? */
|
||||
checksum += Util.convertHex( hexLine.substr( 9 + recp->length*2, 2 ) );
|
||||
if( checksum != 0 )
|
||||
{
|
||||
throw new ErrorMsg( "Wrong checksum for HEX record! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Constructor */
|
||||
HEXFile::HEXFile( long buffersize, long value )
|
||||
{
|
||||
if( buffersize <= 0 )
|
||||
throw new ErrorMsg( "Cannot have zero-size HEX buffer!" );
|
||||
|
||||
data = new unsigned char[ buffersize ];
|
||||
|
||||
if( !data )
|
||||
throw new ErrorMsg( "Memory allocation failed for HEX-line-buffer!" );
|
||||
|
||||
size = buffersize;
|
||||
|
||||
clearAll( value );
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
HEXFile::~HEXFile()
|
||||
{
|
||||
if( data ) delete data;
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::readFile( const string & _filename )
|
||||
{
|
||||
ifstream f;
|
||||
string hexLine; // Contains one line of the HEX file.
|
||||
HEXRecord rec; // Temp record.
|
||||
|
||||
long baseAddress; // Base address for extended addressing modes.
|
||||
long dataPos; // Data position in record.
|
||||
|
||||
/* Attempt to open file */
|
||||
f.open( _filename.c_str(), ios::in );
|
||||
if( !f )
|
||||
throw new ErrorMsg( "Error opening HEX file for input!" );
|
||||
|
||||
/* Prepare */
|
||||
baseAddress = 0;
|
||||
start = size;
|
||||
end = 0;
|
||||
|
||||
/* Parse records */
|
||||
f >> hexLine; // Read one line.
|
||||
while( !f.eof() )
|
||||
{
|
||||
Util.progress( "#" ); // Advance progress indicator.
|
||||
|
||||
/* Process record according to type */
|
||||
parseRecord( hexLine, &rec );
|
||||
|
||||
switch( rec.type )
|
||||
{
|
||||
case 0x00 : // Data record ?
|
||||
/* Copy data */
|
||||
if( baseAddress + rec.offset + rec.length > size )
|
||||
throw new ErrorMsg( "HEX file defines data outside buffer limits! "
|
||||
"Make sure file does not contain data outside device "
|
||||
"memory limits. "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
|
||||
for( dataPos = 0; dataPos < rec.length; dataPos++ )
|
||||
data[ baseAddress + rec.offset + dataPos ] = rec.data[ dataPos ];
|
||||
|
||||
/* Update byte usage */
|
||||
if( baseAddress + rec.offset < start )
|
||||
start = baseAddress + rec.offset;
|
||||
|
||||
if( baseAddress + rec.offset + rec.length - 1 > end )
|
||||
end = baseAddress + rec.offset + rec.length - 1;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 0x02 : // Extended segment address record ?
|
||||
baseAddress = (rec.data[0] << 8) | rec.data[1];
|
||||
baseAddress <<= 4;
|
||||
break;
|
||||
|
||||
case 0x03 : // Start segment address record ?
|
||||
break; // Ignore it, since we have no influence on execution start address.
|
||||
|
||||
case 0x04 : // Extended linear address record ?
|
||||
baseAddress = (rec.data[0] << 8) | rec.data[1];
|
||||
baseAddress <<= 16;
|
||||
break;
|
||||
|
||||
case 0x05 : // Start linear address record ?
|
||||
break; // Ignore it, since we have no influence on exectuion start address.
|
||||
|
||||
case 0x01 : // End of file record ?
|
||||
f.close();
|
||||
Util.progress( "\r\n" ); // Finish progress indicator.
|
||||
return;
|
||||
|
||||
default:
|
||||
throw new ErrorMsg( "Unsupported HEX record format! "
|
||||
"Line from file was: (" + hexLine + ")." );
|
||||
}
|
||||
|
||||
f >> hexLine; // Read next line.
|
||||
}
|
||||
|
||||
|
||||
/* We should not end up here */
|
||||
throw new ErrorMsg( "Premature end of file encountered! Make sure file "
|
||||
"contains an EOF-record." );
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::writeFile( const string & _filename )
|
||||
{
|
||||
ofstream f;
|
||||
HEXRecord rec; // Temp record.
|
||||
|
||||
long baseAddress; // Absolute data position.
|
||||
long offset; // Offset from base address.
|
||||
long dataPos; // Position inside data record.
|
||||
|
||||
enum
|
||||
{
|
||||
_first,
|
||||
_writing,
|
||||
_passed64k
|
||||
} status; // Write status, see usage below.
|
||||
|
||||
/* Attempt to create file */
|
||||
f.open( _filename.c_str(), ios::out );
|
||||
if( !f )
|
||||
throw new ErrorMsg( "Error opening HEX file for output!" );
|
||||
|
||||
/* Prepare */
|
||||
status = _first;
|
||||
rec.data = new unsigned char[ 16 ]; // Use only 16 byte records.
|
||||
|
||||
baseAddress = start & ~0xffff; // 64K aligned address.
|
||||
offset = start & 0xffff; // Offset from the aligned address.
|
||||
dataPos = 0;
|
||||
|
||||
/* Write first base address record to HEX file */
|
||||
rec.length = 2;
|
||||
rec.offset = 0;
|
||||
rec.type = 0x02;
|
||||
rec.data[1] = 0x00;
|
||||
rec.data[0] = baseAddress >> 12; // Give 4k page index.
|
||||
writeRecord( f, &rec ); // Write the HEX record to file.
|
||||
|
||||
|
||||
/* Write all bytes in used range */
|
||||
do
|
||||
{
|
||||
/* Put data into record */
|
||||
rec.data[ dataPos ] = data[ baseAddress + offset + dataPos ];
|
||||
dataPos++;
|
||||
|
||||
/* Check if we need to write out the current data record */
|
||||
if( offset + dataPos >= 0x10000 || // Reached 64k boundary?
|
||||
dataPos >= 16 || // Data record full?
|
||||
baseAddress + offset + dataPos > end ) // End of used range reached?
|
||||
{
|
||||
/* Write current data record */
|
||||
rec.length = dataPos;
|
||||
rec.offset = offset;
|
||||
rec.type = 0x00; // Data record.
|
||||
|
||||
Util.progress( "#" ); // Advance progress indicator.
|
||||
writeRecord( f, &rec );
|
||||
|
||||
offset += dataPos;
|
||||
dataPos = 0;
|
||||
}
|
||||
|
||||
/* Check if we have passed a 64k boundary */
|
||||
if( offset + dataPos >= 0x10000 )
|
||||
{
|
||||
/* Update address pointers */
|
||||
offset -= 0x10000;
|
||||
baseAddress += 0x10000;
|
||||
|
||||
/* Write new base address record to HEX file */
|
||||
rec.length = 2;
|
||||
rec.offset = 0;
|
||||
rec.type = 0x02;
|
||||
rec.data[0] = baseAddress >> 12; // Give 4k page index.
|
||||
rec.data[1] = 0x00;
|
||||
|
||||
writeRecord( f, &rec ); // Write the HEX record to file.
|
||||
}
|
||||
} while( baseAddress + offset + dataPos <= end );
|
||||
|
||||
|
||||
/* Write EOF record */
|
||||
rec.length = 0;
|
||||
rec.offset = 0;
|
||||
rec.type = 0x01;
|
||||
|
||||
writeRecord( f, &rec );
|
||||
|
||||
f.close();
|
||||
Util.progress( "\r\n" ); // Finish progress indicator.
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::setUsedRange( long _start, long _end )
|
||||
{
|
||||
if( _start < 0 || _end >= size || _start > _end )
|
||||
throw new ErrorMsg( "Invalid range! Start must be 0 or larger, end must be "
|
||||
"inside allowed memory range." );
|
||||
|
||||
start = _start;
|
||||
end = _end;
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::clearAll( long value )
|
||||
{
|
||||
for( long i = 0; i < size; i++ )
|
||||
data[i] = (unsigned char) (value & 0xff);
|
||||
}
|
||||
|
||||
|
||||
long HEXFile::getData( long address )
|
||||
{
|
||||
if( address < 0 || address >= size )
|
||||
throw new ErrorMsg( "Address outside legal range!" );
|
||||
|
||||
return data[ address ];
|
||||
}
|
||||
|
||||
|
||||
void HEXFile::setData( long address, long value )
|
||||
{
|
||||
if( address < 0 || address >= size )
|
||||
throw new ErrorMsg( "Address outside legal range!" );
|
||||
|
||||
data[ address ] = (unsigned char) (value & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : HEXParser.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A simple Intel HEX file format reader/writer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef HEXPARSER_HPP
|
||||
#define HEXPARSER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "Utility.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct HEXRecord; // Preliminary definition.
|
||||
|
||||
class HEXFile
|
||||
{
|
||||
protected:
|
||||
unsigned char * data; // Holds the data bytes.
|
||||
long start, end; // Used data range.
|
||||
long size; // Size of databuffer.
|
||||
|
||||
void writeRecord( ofstream & f, HEXRecord * recp );
|
||||
void parseRecord( const string & hexLine, HEXRecord * recp );
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
HEXFile( long buffersize, long value = 0xff );
|
||||
|
||||
/* Destructor */
|
||||
~HEXFile();
|
||||
|
||||
/* Methods */
|
||||
void readFile( const string & _filename ); // Read data from HEX file.
|
||||
void writeFile( const string & _filename ); // Write data to HEX file.
|
||||
|
||||
void setUsedRange( long _start, long _end ); // Sets the used range.
|
||||
void clearAll( long value = 0xff ); // Set databuffer to this value.
|
||||
|
||||
long getRangeStart() { return start; }
|
||||
long getRangeEnd() { return end; }
|
||||
long getData( long address );
|
||||
void setData( long address, long value );
|
||||
long getSize() { return size; }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : HEXParser.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A simple Intel HEX file format reader/writer.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef HEXPARSER_HPP
|
||||
#define HEXPARSER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "Utility.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
struct HEXRecord; // Preliminary definition.
|
||||
|
||||
class HEXFile
|
||||
{
|
||||
protected:
|
||||
unsigned char * data; // Holds the data bytes.
|
||||
long start, end; // Used data range.
|
||||
long size; // Size of databuffer.
|
||||
|
||||
void writeRecord( ofstream & f, HEXRecord * recp );
|
||||
void parseRecord( const string & hexLine, HEXRecord * recp );
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
HEXFile( long buffersize, long value = 0xff );
|
||||
|
||||
/* Destructor */
|
||||
~HEXFile();
|
||||
|
||||
/* Methods */
|
||||
void readFile( const string & _filename ); // Read data from HEX file.
|
||||
void writeFile( const string & _filename ); // Write data to HEX file.
|
||||
|
||||
void setUsedRange( long _start, long _end ); // Sets the used range.
|
||||
void clearAll( long value = 0xff ); // Set databuffer to this value.
|
||||
|
||||
long getRangeStart() { return start; }
|
||||
long getRangeEnd() { return end; }
|
||||
long getData( long address );
|
||||
void setData( long address, long value );
|
||||
long getSize() { return size; }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+1296
-1296
File diff suppressed because it is too large
Load Diff
@@ -1,105 +1,105 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : JobInfo.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class holding information on what the AVR Open-Source Programmer
|
||||
* should do. The information is derived from the command-line.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef JOBINFO_HPP
|
||||
#define JOBINFO_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "AVRProgrammer.hpp"
|
||||
#include "AVRBootloader.hpp"
|
||||
#include "AVRInSystemProg.hpp"
|
||||
#include "AVRDevice.hpp"
|
||||
#include "SerialPort.hpp"
|
||||
#include "Utility.hpp"
|
||||
|
||||
|
||||
class JobInfo
|
||||
{
|
||||
protected:
|
||||
long convertHex( char * txt );
|
||||
void help();
|
||||
void doDeviceIndependent( AVRProgrammer * prog );
|
||||
void doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr );
|
||||
|
||||
|
||||
bool showHelp; // Show help screen?
|
||||
bool silentMode; // No text output?
|
||||
bool noProgressIndicator; // Do not show progress indicators?
|
||||
bool readSignature; // Output signature bytes to screen?
|
||||
bool chipErase; // Erase chip before any programming operations?
|
||||
bool getHWrevision; // Get hardware revision of programmer?
|
||||
bool getSWrevision; // Get software revision of programmer?
|
||||
bool programFlash; // Flash programming desired?
|
||||
bool programEEPROM; // E2 programming desired?
|
||||
bool readFlash; // Flash readout desired?
|
||||
bool readEEPROM; // E2 readout desired?
|
||||
bool verifyFlash; // Flash verification desired?
|
||||
bool verifyEEPROM; // E2 verification desired?
|
||||
bool readLockBits; // Lock bit readout desired?
|
||||
bool readFuseBits; // Fuse bit readout desired?
|
||||
bool readOSCCAL; // Read or use specified OSCCAL value, if -O is used?
|
||||
|
||||
string deviceName; // Specified device name.
|
||||
string inputFileFlash; // Input file for Flash writing and verification.
|
||||
string inputFileEEPROM; // Input file for E2 writing and verification.
|
||||
string outputFileFlash; // Output file for Flash readout.
|
||||
string outputFileEEPROM; // Output file for E2 readout.
|
||||
|
||||
long OSCCAL_Parameter; // Value of the -O parameter, -1 if unspecified.
|
||||
|
||||
long OSCCAL_FlashAddress; // Where to put OSCCAL value in flash, -1 if not.
|
||||
long OSCCAL_EEPROMAddress; // Where to put OSCCAL value in E2, -1 if not.
|
||||
|
||||
long programLockBits; // Change lock bits to this value, -1 if not.
|
||||
long verifyLockBits; // Verify lock bits against this value, -1 if not.
|
||||
|
||||
long programFuseBits; // Change fuse bits to this value, -1 if not.
|
||||
long programExtendedFuseBits; // Same as above for extended fuse bits.
|
||||
long verifyFuseBits; // Verify fuse bits against this value, -1 if not.
|
||||
long verifyExtendedFuseBits; // Same as above for extended fuse bits.
|
||||
|
||||
long memoryFillPattern; // Fill unspecified locations, -1 if not.
|
||||
|
||||
long flashStartAddress; // Limit Flash operations, -1 if not.
|
||||
long flashEndAddress; // ...to this address, inclusive, -1 if not.
|
||||
|
||||
long eepromStartAddress; // Same as above for E2.
|
||||
long eepromEndAddress; // ...
|
||||
|
||||
long comPort; // Desired COM port to use, -1 if unspecified.
|
||||
|
||||
vector<string> searchpath; // Search path for XML-files.
|
||||
|
||||
public:
|
||||
JobInfo(); // Constructor
|
||||
|
||||
void parseCommandline( int argc, char *argv[] );
|
||||
void doJob();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : JobInfo.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class holding information on what the AVR Open-Source Programmer
|
||||
* should do. The information is derived from the command-line.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef JOBINFO_HPP
|
||||
#define JOBINFO_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "AVRProgrammer.hpp"
|
||||
#include "AVRBootloader.hpp"
|
||||
#include "AVRInSystemProg.hpp"
|
||||
#include "AVRDevice.hpp"
|
||||
#include "SerialPort.hpp"
|
||||
#include "Utility.hpp"
|
||||
|
||||
|
||||
class JobInfo
|
||||
{
|
||||
protected:
|
||||
long convertHex( char * txt );
|
||||
void help();
|
||||
void doDeviceIndependent( AVRProgrammer * prog );
|
||||
void doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr );
|
||||
|
||||
|
||||
bool showHelp; // Show help screen?
|
||||
bool silentMode; // No text output?
|
||||
bool noProgressIndicator; // Do not show progress indicators?
|
||||
bool readSignature; // Output signature bytes to screen?
|
||||
bool chipErase; // Erase chip before any programming operations?
|
||||
bool getHWrevision; // Get hardware revision of programmer?
|
||||
bool getSWrevision; // Get software revision of programmer?
|
||||
bool programFlash; // Flash programming desired?
|
||||
bool programEEPROM; // E2 programming desired?
|
||||
bool readFlash; // Flash readout desired?
|
||||
bool readEEPROM; // E2 readout desired?
|
||||
bool verifyFlash; // Flash verification desired?
|
||||
bool verifyEEPROM; // E2 verification desired?
|
||||
bool readLockBits; // Lock bit readout desired?
|
||||
bool readFuseBits; // Fuse bit readout desired?
|
||||
bool readOSCCAL; // Read or use specified OSCCAL value, if -O is used?
|
||||
|
||||
string deviceName; // Specified device name.
|
||||
string inputFileFlash; // Input file for Flash writing and verification.
|
||||
string inputFileEEPROM; // Input file for E2 writing and verification.
|
||||
string outputFileFlash; // Output file for Flash readout.
|
||||
string outputFileEEPROM; // Output file for E2 readout.
|
||||
|
||||
long OSCCAL_Parameter; // Value of the -O parameter, -1 if unspecified.
|
||||
|
||||
long OSCCAL_FlashAddress; // Where to put OSCCAL value in flash, -1 if not.
|
||||
long OSCCAL_EEPROMAddress; // Where to put OSCCAL value in E2, -1 if not.
|
||||
|
||||
long programLockBits; // Change lock bits to this value, -1 if not.
|
||||
long verifyLockBits; // Verify lock bits against this value, -1 if not.
|
||||
|
||||
long programFuseBits; // Change fuse bits to this value, -1 if not.
|
||||
long programExtendedFuseBits; // Same as above for extended fuse bits.
|
||||
long verifyFuseBits; // Verify fuse bits against this value, -1 if not.
|
||||
long verifyExtendedFuseBits; // Same as above for extended fuse bits.
|
||||
|
||||
long memoryFillPattern; // Fill unspecified locations, -1 if not.
|
||||
|
||||
long flashStartAddress; // Limit Flash operations, -1 if not.
|
||||
long flashEndAddress; // ...to this address, inclusive, -1 if not.
|
||||
|
||||
long eepromStartAddress; // Same as above for E2.
|
||||
long eepromEndAddress; // ...
|
||||
|
||||
long comPort; // Desired COM port to use, -1 if unspecified.
|
||||
|
||||
vector<string> searchpath; // Search path for XML-files.
|
||||
|
||||
public:
|
||||
JobInfo(); // Constructor
|
||||
|
||||
void parseCommandline( int argc, char *argv[] );
|
||||
void doJob();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,203 +1,203 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : SerialPort.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing serial communication through the PC COM port.
|
||||
* This class is derived from the CommChannel abstract class.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "SerialPort.hpp"
|
||||
|
||||
|
||||
/* Constructor */
|
||||
SerialPort::SerialPort( long _portNumber, long _timeout )
|
||||
{
|
||||
if( _timeout < 0 )
|
||||
throw new ErrorMsg( "Negative COM-port timeout not allowed!" );
|
||||
|
||||
if( _portNumber < 1 || _portNumber > 99 )
|
||||
throw new ErrorMsg( "Only COM1 to COM99 is supported!" );
|
||||
|
||||
/* Initialize internal parameters */
|
||||
portNumber = _portNumber;
|
||||
timeout = _timeout;
|
||||
channelOpen = false;
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
SerialPort::~SerialPort()
|
||||
{
|
||||
closeChannel();
|
||||
}
|
||||
|
||||
|
||||
/* Open the communication channel */
|
||||
void SerialPort::openChannel()
|
||||
{
|
||||
/* CreateFile expects a constant char, or char from the heap */
|
||||
static char comName[64] = "COM1";
|
||||
|
||||
COMMTIMEOUTS comTimeouts;
|
||||
|
||||
/* Check if channel already open */
|
||||
if( channelOpen )
|
||||
throw new ErrorMsg( "Channel already open! Cannot open port twice." );
|
||||
|
||||
/* Generate COM filename and attempt open */
|
||||
if (portNumber < 10) {
|
||||
comName[3] = '0' + portNumber;
|
||||
} else if (portNumber < 100) {
|
||||
/* For COM ports greater than 9 you have to use a special syntax
|
||||
for CreateFile. The syntax also works for COM ports 1-9. */
|
||||
/* http://support.microsoft.com/kb/115831 */
|
||||
sprintf(comName, "\\\\.\\COM%ld", portNumber);
|
||||
}
|
||||
serialHandle = CreateFile( comName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
|
||||
/* Print error and return if failed opening port */
|
||||
if( serialHandle == INVALID_HANDLE_VALUE )
|
||||
throw new ErrorMsg( "Error opening COM port!" );
|
||||
|
||||
channelOpen = true;
|
||||
|
||||
/* Store old COM port settings */
|
||||
if( !GetCommTimeouts( serialHandle, &oldComTimeouts ) )
|
||||
throw new ErrorMsg( "Error reading COM port settings!" );
|
||||
|
||||
/* Get another copy of the COM settings, and change them */
|
||||
if( !GetCommTimeouts( serialHandle, &comTimeouts ) )
|
||||
throw new ErrorMsg( "Error reading COM port settings!" );
|
||||
|
||||
comTimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
comTimeouts.ReadTotalTimeoutConstant = 0;
|
||||
comTimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
|
||||
/* Apply new settings */
|
||||
if( !SetCommTimeouts( serialHandle, &comTimeouts ) )
|
||||
throw new ErrorMsg( "Error changing COM port settings!" );
|
||||
}
|
||||
|
||||
|
||||
/* Close the communication channel */
|
||||
void SerialPort::closeChannel()
|
||||
{
|
||||
if( !channelOpen )
|
||||
return;
|
||||
|
||||
/* Restore old COM parameters */
|
||||
if( !SetCommTimeouts( serialHandle, &oldComTimeouts ) )
|
||||
throw new ErrorMsg( "Error changing COM port settings!" );
|
||||
|
||||
/* Release port */
|
||||
if( serialHandle != INVALID_HANDLE_VALUE )
|
||||
if( !CloseHandle( serialHandle ) )
|
||||
throw new ErrorMsg( "Error closing COM port!" );
|
||||
|
||||
channelOpen = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Transmit a single byte */
|
||||
void SerialPort::sendByte( long data )
|
||||
{
|
||||
DWORD written;
|
||||
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot send to unopened channel." );
|
||||
|
||||
/* Attempt writing */
|
||||
if( !WriteFile( serialHandle, &data, 1, &written, NULL ) )
|
||||
throw new ErrorMsg( "Error writing byte to COM port!" );
|
||||
}
|
||||
|
||||
|
||||
/* Receive a single byte */
|
||||
long SerialPort::getByte()
|
||||
{
|
||||
time_t startTime;
|
||||
startTime = time( NULL ); // Read current time in seconds
|
||||
DWORD readnum;
|
||||
unsigned char data;
|
||||
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot read from unopened channel." );
|
||||
|
||||
/* Attempt receiving byte until timeout limit exceeded */
|
||||
do
|
||||
{
|
||||
/* Read byte from port */
|
||||
if( !ReadFile( serialHandle, &data, 1, &readnum, NULL ) )
|
||||
{
|
||||
throw new ErrorMsg( "Error reading byte from COM port!" );
|
||||
}
|
||||
|
||||
if( readnum == 1 )
|
||||
return ((long) data) & 0xff;
|
||||
|
||||
} while( time(NULL) - startTime < timeout );
|
||||
|
||||
/* Timeout */
|
||||
throw new ErrorMsg( "Timeout during COM-port read operation!" );
|
||||
}
|
||||
|
||||
|
||||
/* Flush the transmit buffer */
|
||||
void SerialPort::flushTX()
|
||||
{
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." );
|
||||
|
||||
/* Purge data from write buffer */
|
||||
if( !PurgeComm( serialHandle, PURGE_TXCLEAR ) )
|
||||
throw new ErrorMsg( "Error flushing COM port TX buffer!" );
|
||||
}
|
||||
|
||||
|
||||
/* Flush the receive buffer */
|
||||
void SerialPort::flushRX()
|
||||
{
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." );
|
||||
|
||||
/* Purge data from write buffer */
|
||||
if( !PurgeComm( serialHandle, PURGE_RXCLEAR ) )
|
||||
throw new ErrorMsg( "Error flushing COM port RX buffer!" );
|
||||
}
|
||||
|
||||
|
||||
/* Transmit multiple bytes */
|
||||
void SerialPort::sendMultiple( unsigned char * data, long bufsize )
|
||||
{
|
||||
DWORD written;
|
||||
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot write to unopened channel." );
|
||||
|
||||
/* Attempt writing */
|
||||
if( !WriteFile( serialHandle, data, bufsize, &written, NULL ) )
|
||||
throw new ErrorMsg( "Error writing multiple bytes to COM port!" );
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : SerialPort.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing serial communication through the PC COM port.
|
||||
* This class is derived from the CommChannel abstract class.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "SerialPort.hpp"
|
||||
|
||||
|
||||
/* Constructor */
|
||||
SerialPort::SerialPort( long _portNumber, long _timeout )
|
||||
{
|
||||
if( _timeout < 0 )
|
||||
throw new ErrorMsg( "Negative COM-port timeout not allowed!" );
|
||||
|
||||
if( _portNumber < 1 || _portNumber > 99 )
|
||||
throw new ErrorMsg( "Only COM1 to COM99 is supported!" );
|
||||
|
||||
/* Initialize internal parameters */
|
||||
portNumber = _portNumber;
|
||||
timeout = _timeout;
|
||||
channelOpen = false;
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
SerialPort::~SerialPort()
|
||||
{
|
||||
closeChannel();
|
||||
}
|
||||
|
||||
|
||||
/* Open the communication channel */
|
||||
void SerialPort::openChannel()
|
||||
{
|
||||
/* CreateFile expects a constant char, or char from the heap */
|
||||
static char comName[64] = "COM1";
|
||||
|
||||
COMMTIMEOUTS comTimeouts;
|
||||
|
||||
/* Check if channel already open */
|
||||
if( channelOpen )
|
||||
throw new ErrorMsg( "Channel already open! Cannot open port twice." );
|
||||
|
||||
/* Generate COM filename and attempt open */
|
||||
if (portNumber < 10) {
|
||||
comName[3] = '0' + portNumber;
|
||||
} else if (portNumber < 100) {
|
||||
/* For COM ports greater than 9 you have to use a special syntax
|
||||
for CreateFile. The syntax also works for COM ports 1-9. */
|
||||
/* http://support.microsoft.com/kb/115831 */
|
||||
sprintf(comName, "\\\\.\\COM%ld", portNumber);
|
||||
}
|
||||
serialHandle = CreateFile( comName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||
|
||||
/* Print error and return if failed opening port */
|
||||
if( serialHandle == INVALID_HANDLE_VALUE )
|
||||
throw new ErrorMsg( "Error opening COM port!" );
|
||||
|
||||
channelOpen = true;
|
||||
|
||||
/* Store old COM port settings */
|
||||
if( !GetCommTimeouts( serialHandle, &oldComTimeouts ) )
|
||||
throw new ErrorMsg( "Error reading COM port settings!" );
|
||||
|
||||
/* Get another copy of the COM settings, and change them */
|
||||
if( !GetCommTimeouts( serialHandle, &comTimeouts ) )
|
||||
throw new ErrorMsg( "Error reading COM port settings!" );
|
||||
|
||||
comTimeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
comTimeouts.ReadTotalTimeoutConstant = 0;
|
||||
comTimeouts.ReadTotalTimeoutMultiplier = 0;
|
||||
|
||||
/* Apply new settings */
|
||||
if( !SetCommTimeouts( serialHandle, &comTimeouts ) )
|
||||
throw new ErrorMsg( "Error changing COM port settings!" );
|
||||
}
|
||||
|
||||
|
||||
/* Close the communication channel */
|
||||
void SerialPort::closeChannel()
|
||||
{
|
||||
if( !channelOpen )
|
||||
return;
|
||||
|
||||
/* Restore old COM parameters */
|
||||
if( !SetCommTimeouts( serialHandle, &oldComTimeouts ) )
|
||||
throw new ErrorMsg( "Error changing COM port settings!" );
|
||||
|
||||
/* Release port */
|
||||
if( serialHandle != INVALID_HANDLE_VALUE )
|
||||
if( !CloseHandle( serialHandle ) )
|
||||
throw new ErrorMsg( "Error closing COM port!" );
|
||||
|
||||
channelOpen = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Transmit a single byte */
|
||||
void SerialPort::sendByte( long data )
|
||||
{
|
||||
DWORD written;
|
||||
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot send to unopened channel." );
|
||||
|
||||
/* Attempt writing */
|
||||
if( !WriteFile( serialHandle, &data, 1, &written, NULL ) )
|
||||
throw new ErrorMsg( "Error writing byte to COM port!" );
|
||||
}
|
||||
|
||||
|
||||
/* Receive a single byte */
|
||||
long SerialPort::getByte()
|
||||
{
|
||||
time_t startTime;
|
||||
startTime = time( NULL ); // Read current time in seconds
|
||||
DWORD readnum;
|
||||
unsigned char data;
|
||||
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot read from unopened channel." );
|
||||
|
||||
/* Attempt receiving byte until timeout limit exceeded */
|
||||
do
|
||||
{
|
||||
/* Read byte from port */
|
||||
if( !ReadFile( serialHandle, &data, 1, &readnum, NULL ) )
|
||||
{
|
||||
throw new ErrorMsg( "Error reading byte from COM port!" );
|
||||
}
|
||||
|
||||
if( readnum == 1 )
|
||||
return ((long) data) & 0xff;
|
||||
|
||||
} while( time(NULL) - startTime < timeout );
|
||||
|
||||
/* Timeout */
|
||||
throw new ErrorMsg( "Timeout during COM-port read operation!" );
|
||||
}
|
||||
|
||||
|
||||
/* Flush the transmit buffer */
|
||||
void SerialPort::flushTX()
|
||||
{
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." );
|
||||
|
||||
/* Purge data from write buffer */
|
||||
if( !PurgeComm( serialHandle, PURGE_TXCLEAR ) )
|
||||
throw new ErrorMsg( "Error flushing COM port TX buffer!" );
|
||||
}
|
||||
|
||||
|
||||
/* Flush the receive buffer */
|
||||
void SerialPort::flushRX()
|
||||
{
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot flush an unopened channel." );
|
||||
|
||||
/* Purge data from write buffer */
|
||||
if( !PurgeComm( serialHandle, PURGE_RXCLEAR ) )
|
||||
throw new ErrorMsg( "Error flushing COM port RX buffer!" );
|
||||
}
|
||||
|
||||
|
||||
/* Transmit multiple bytes */
|
||||
void SerialPort::sendMultiple( unsigned char * data, long bufsize )
|
||||
{
|
||||
DWORD written;
|
||||
|
||||
/* Check if channel is open */
|
||||
if( !channelOpen )
|
||||
throw new ErrorMsg( "Channel not open! Cannot write to unopened channel." );
|
||||
|
||||
/* Attempt writing */
|
||||
if( !WriteFile( serialHandle, data, bufsize, &written, NULL ) )
|
||||
throw new ErrorMsg( "Error writing multiple bytes to COM port!" );
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : SerialPort.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing serial communication through the PC COM port.
|
||||
* This class is derived from the CommChannel abstract class.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef SERIALPORT_HPP
|
||||
#define SERIALPORT_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <iostream>
|
||||
#include "CommChannel.hpp"
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
|
||||
class SerialPort : public CommChannel
|
||||
{
|
||||
protected:
|
||||
long portNumber; // COMx port number.
|
||||
long timeout; // Desired timeout limit when receiving data.
|
||||
HANDLE serialHandle; // Win32 device handle for the com port.
|
||||
COMMTIMEOUTS oldComTimeouts; // Store old serial port timeout parameters.
|
||||
bool channelOpen; // Is channel open?
|
||||
|
||||
public:
|
||||
// Constructor taking port number, baudrate and
|
||||
// timeout limit as parameters.
|
||||
SerialPort( long portnumber, long timeout );
|
||||
|
||||
// Destructor.
|
||||
~SerialPort();
|
||||
|
||||
// Open the communication channel.
|
||||
virtual void openChannel();
|
||||
|
||||
// Close the communication channel.
|
||||
virtual void closeChannel();
|
||||
|
||||
// Transmit a single byte.
|
||||
virtual void sendByte( long data );
|
||||
|
||||
// Receive a single byte.
|
||||
virtual long getByte();
|
||||
|
||||
// Flush the transmit buffer.
|
||||
virtual void flushTX();
|
||||
|
||||
// Flush the receive buffer.
|
||||
virtual void flushRX();
|
||||
|
||||
// Transmit multiple bytes.
|
||||
virtual void sendMultiple( unsigned char * data, long bufsize );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : SerialPort.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class providing serial communication through the PC COM port.
|
||||
* This class is derived from the CommChannel abstract class.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef SERIALPORT_HPP
|
||||
#define SERIALPORT_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <iostream>
|
||||
#include "CommChannel.hpp"
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
|
||||
class SerialPort : public CommChannel
|
||||
{
|
||||
protected:
|
||||
long portNumber; // COMx port number.
|
||||
long timeout; // Desired timeout limit when receiving data.
|
||||
HANDLE serialHandle; // Win32 device handle for the com port.
|
||||
COMMTIMEOUTS oldComTimeouts; // Store old serial port timeout parameters.
|
||||
bool channelOpen; // Is channel open?
|
||||
|
||||
public:
|
||||
// Constructor taking port number, baudrate and
|
||||
// timeout limit as parameters.
|
||||
SerialPort( long portnumber, long timeout );
|
||||
|
||||
// Destructor.
|
||||
~SerialPort();
|
||||
|
||||
// Open the communication channel.
|
||||
virtual void openChannel();
|
||||
|
||||
// Close the communication channel.
|
||||
virtual void closeChannel();
|
||||
|
||||
// Transmit a single byte.
|
||||
virtual void sendByte( long data );
|
||||
|
||||
// Receive a single byte.
|
||||
virtual long getByte();
|
||||
|
||||
// Flush the transmit buffer.
|
||||
virtual void flushTX();
|
||||
|
||||
// Flush the receive buffer.
|
||||
virtual void flushRX();
|
||||
|
||||
// Transmit multiple bytes.
|
||||
virtual void sendMultiple( unsigned char * data, long bufsize );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,181 +1,181 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : Utility.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class holding misc. utility methods used in AVROSP.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "Utility.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Global object */
|
||||
Utility Util;
|
||||
|
||||
|
||||
/* Constructor */
|
||||
Utility::Utility() :
|
||||
noLog( false ),
|
||||
noProgress( false )
|
||||
{
|
||||
/* No code here */
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
Utility::~Utility()
|
||||
{
|
||||
/* No code here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Utility::log( const string & txt )
|
||||
{
|
||||
if( !noLog )
|
||||
cout << txt;
|
||||
}
|
||||
|
||||
|
||||
void Utility::progress( const string & txt )
|
||||
{
|
||||
if( !noProgress )
|
||||
cout << txt;
|
||||
}
|
||||
|
||||
|
||||
long Utility::convertHex( const string & txt )
|
||||
{
|
||||
long result = 0;
|
||||
long digit;
|
||||
long i;
|
||||
|
||||
if( txt.size() == 0 )
|
||||
throw new ErrorMsg( "Cannot convert zero-length hex-string to number!" );
|
||||
|
||||
if( txt.size() > 8 )
|
||||
throw new ErrorMsg( "Hex conversion overflow! Too many hex digits in string." );
|
||||
|
||||
|
||||
for( i = 0; i < txt.size(); i++ )
|
||||
{
|
||||
/* Convert hex digit */
|
||||
if( txt[i] >= '0' && txt[i] <= '9' )
|
||||
digit = txt[i] - '0';
|
||||
else if( txt[i] >= 'a' && txt[i] <= 'f' )
|
||||
digit = txt[i] - 'a' + 10;
|
||||
else if( txt[i] >= 'A' && txt[i] <= 'F' )
|
||||
digit = txt[i] - 'A' + 10;
|
||||
else
|
||||
throw new ErrorMsg( "Invalid hex digit found!" );
|
||||
|
||||
/* Add digit as least significant 4 bits of result */
|
||||
result = (result << 4) | digit;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
string Utility::convertLong( long num, long radix )
|
||||
{
|
||||
char buf[18];
|
||||
string res;
|
||||
|
||||
itoa( num, buf, radix );
|
||||
res = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void Utility::parsePath( vector<string> & list )
|
||||
{
|
||||
/* Get environment variable and parse if it exists */
|
||||
char * pathptr = getenv( "PATH" );
|
||||
if( pathptr != NULL && pathptr[0] != 0 ) {
|
||||
string path = pathptr;
|
||||
int pos;
|
||||
|
||||
while( (pos = path.find_first_of( ";" )) < path.length() ) {
|
||||
list.push_back( path.substr( 0, pos ) );
|
||||
path.erase( 0, pos+1 );
|
||||
}
|
||||
|
||||
list.push_back( path ); // Last directory.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Utility::fileExists( string filename )
|
||||
{
|
||||
/* Attempt to open file */
|
||||
ifstream f;
|
||||
f.open( filename.c_str(), ios::in );
|
||||
if( !f ) {
|
||||
return false;
|
||||
} else {
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Utility::saveString( string txt, string filename )
|
||||
{
|
||||
ofstream f;
|
||||
|
||||
f.open( filename.c_str(), ios::out );
|
||||
if( !f )
|
||||
throw new ErrorMsg( "Error opening HEX file for output!" );
|
||||
|
||||
f << txt;
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
string Utility::getRegistryValue( const string & path, const string & value )
|
||||
{
|
||||
/* Code modified from MSDN */
|
||||
const long BUFSIZE=1000;
|
||||
string result;
|
||||
HKEY hKey;
|
||||
char szAVRPath[BUFSIZE];
|
||||
DWORD dwBufLen=BUFSIZE;
|
||||
LONG lRet;
|
||||
|
||||
/* Open key */
|
||||
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_QUERY_VALUE, &hKey );
|
||||
if( lRet != ERROR_SUCCESS )
|
||||
throw new ErrorMsg( "Error when opening registry key: (" + path + ")!" );
|
||||
|
||||
/* Get value */
|
||||
lRet = RegQueryValueEx( hKey, value.c_str(), NULL, NULL, (LPBYTE) szAVRPath, &dwBufLen);
|
||||
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) )
|
||||
throw new ErrorMsg( "Error when reading key value: (" + value + ")!" );
|
||||
|
||||
/* Clean up and return result */
|
||||
RegCloseKey( hKey );
|
||||
result = szAVRPath;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end of file */
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : Utility.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class holding misc. utility methods used in AVROSP.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "Utility.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Global object */
|
||||
Utility Util;
|
||||
|
||||
|
||||
/* Constructor */
|
||||
Utility::Utility() :
|
||||
noLog( false ),
|
||||
noProgress( false )
|
||||
{
|
||||
/* No code here */
|
||||
}
|
||||
|
||||
|
||||
/* Destructor */
|
||||
Utility::~Utility()
|
||||
{
|
||||
/* No code here */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Utility::log( const string & txt )
|
||||
{
|
||||
if( !noLog )
|
||||
cout << txt;
|
||||
}
|
||||
|
||||
|
||||
void Utility::progress( const string & txt )
|
||||
{
|
||||
if( !noProgress )
|
||||
cout << txt;
|
||||
}
|
||||
|
||||
|
||||
long Utility::convertHex( const string & txt )
|
||||
{
|
||||
long result = 0;
|
||||
long digit;
|
||||
long i;
|
||||
|
||||
if( txt.size() == 0 )
|
||||
throw new ErrorMsg( "Cannot convert zero-length hex-string to number!" );
|
||||
|
||||
if( txt.size() > 8 )
|
||||
throw new ErrorMsg( "Hex conversion overflow! Too many hex digits in string." );
|
||||
|
||||
|
||||
for( i = 0; i < txt.size(); i++ )
|
||||
{
|
||||
/* Convert hex digit */
|
||||
if( txt[i] >= '0' && txt[i] <= '9' )
|
||||
digit = txt[i] - '0';
|
||||
else if( txt[i] >= 'a' && txt[i] <= 'f' )
|
||||
digit = txt[i] - 'a' + 10;
|
||||
else if( txt[i] >= 'A' && txt[i] <= 'F' )
|
||||
digit = txt[i] - 'A' + 10;
|
||||
else
|
||||
throw new ErrorMsg( "Invalid hex digit found!" );
|
||||
|
||||
/* Add digit as least significant 4 bits of result */
|
||||
result = (result << 4) | digit;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
string Utility::convertLong( long num, long radix )
|
||||
{
|
||||
char buf[18];
|
||||
string res;
|
||||
|
||||
itoa( num, buf, radix );
|
||||
res = buf;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void Utility::parsePath( vector<string> & list )
|
||||
{
|
||||
/* Get environment variable and parse if it exists */
|
||||
char * pathptr = getenv( "PATH" );
|
||||
if( pathptr != NULL && pathptr[0] != 0 ) {
|
||||
string path = pathptr;
|
||||
int pos;
|
||||
|
||||
while( (pos = path.find_first_of( ";" )) < path.length() ) {
|
||||
list.push_back( path.substr( 0, pos ) );
|
||||
path.erase( 0, pos+1 );
|
||||
}
|
||||
|
||||
list.push_back( path ); // Last directory.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Utility::fileExists( string filename )
|
||||
{
|
||||
/* Attempt to open file */
|
||||
ifstream f;
|
||||
f.open( filename.c_str(), ios::in );
|
||||
if( !f ) {
|
||||
return false;
|
||||
} else {
|
||||
f.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Utility::saveString( string txt, string filename )
|
||||
{
|
||||
ofstream f;
|
||||
|
||||
f.open( filename.c_str(), ios::out );
|
||||
if( !f )
|
||||
throw new ErrorMsg( "Error opening HEX file for output!" );
|
||||
|
||||
f << txt;
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
string Utility::getRegistryValue( const string & path, const string & value )
|
||||
{
|
||||
/* Code modified from MSDN */
|
||||
const long BUFSIZE=1000;
|
||||
string result;
|
||||
HKEY hKey;
|
||||
char szAVRPath[BUFSIZE];
|
||||
DWORD dwBufLen=BUFSIZE;
|
||||
LONG lRet;
|
||||
|
||||
/* Open key */
|
||||
lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_QUERY_VALUE, &hKey );
|
||||
if( lRet != ERROR_SUCCESS )
|
||||
throw new ErrorMsg( "Error when opening registry key: (" + path + ")!" );
|
||||
|
||||
/* Get value */
|
||||
lRet = RegQueryValueEx( hKey, value.c_str(), NULL, NULL, (LPBYTE) szAVRPath, &dwBufLen);
|
||||
if( (lRet != ERROR_SUCCESS) || (dwBufLen > BUFSIZE) )
|
||||
throw new ErrorMsg( "Error when reading key value: (" + value + ")!" );
|
||||
|
||||
/* Clean up and return result */
|
||||
RegCloseKey( hKey );
|
||||
result = szAVRPath;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* end of file */
|
||||
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : Utility.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class holding misc. utility methods used in AVROSP.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef UTILITY_HPP
|
||||
#define UTILITY_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
class Utility
|
||||
{
|
||||
protected:
|
||||
bool noLog;
|
||||
bool noProgress;
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
Utility();
|
||||
|
||||
/* Destructor */
|
||||
~Utility();
|
||||
|
||||
/* Methods */
|
||||
void muteLog() { noLog = true; }
|
||||
void muteProgress() { noProgress = true; }
|
||||
|
||||
void log( const string & txt );
|
||||
void progress( const string & txt );
|
||||
|
||||
long convertHex( const string & txt );
|
||||
string convertLong( long num, long radix = 10 );
|
||||
|
||||
void parsePath( vector<string> & list );
|
||||
bool fileExists( string filename );
|
||||
void saveString( string txt, string filename );
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
string getRegistryValue( const string & path, const string & value );
|
||||
#endif
|
||||
};
|
||||
|
||||
extern Utility Util;
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : Utility.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A class holding misc. utility methods used in AVROSP.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef UTILITY_HPP
|
||||
#define UTILITY_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "ErrorMsg.hpp"
|
||||
|
||||
class Utility
|
||||
{
|
||||
protected:
|
||||
bool noLog;
|
||||
bool noProgress;
|
||||
|
||||
public:
|
||||
/* Constructor */
|
||||
Utility();
|
||||
|
||||
/* Destructor */
|
||||
~Utility();
|
||||
|
||||
/* Methods */
|
||||
void muteLog() { noLog = true; }
|
||||
void muteProgress() { noProgress = true; }
|
||||
|
||||
void log( const string & txt );
|
||||
void progress( const string & txt );
|
||||
|
||||
long convertHex( const string & txt );
|
||||
string convertLong( long num, long radix = 10 );
|
||||
|
||||
void parsePath( vector<string> & list );
|
||||
bool fileExists( string filename );
|
||||
void saveString( string txt, string filename );
|
||||
|
||||
#ifndef NOREGISTRY
|
||||
string getRegistryValue( const string & path, const string & value );
|
||||
#endif
|
||||
};
|
||||
|
||||
extern Utility Util;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,65 +1,65 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : XMLParser.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 3419 $
|
||||
* Date : $Date: 2008-02-22 09:56:34 +0100 (fr, 22 feb 2008) $
|
||||
* Updated by : $Author: khole $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A simple XML DOM-like parser. It builds a complete tree from
|
||||
* the XML file. IT supports <section/> tags, but not tag attributes.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef XMLPARSER_HPP
|
||||
#define XMLPARSER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "Utility.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
|
||||
class XMLAbstractNode; // Preliminary definitions.
|
||||
class XMLTree;
|
||||
class XMLNode;
|
||||
|
||||
|
||||
/* Main XML file class. Contains search methods and entire XML tree */
|
||||
class XMLFile
|
||||
{
|
||||
protected:
|
||||
XMLTree * root; // The root node, either a subtree or an ordinary node.
|
||||
|
||||
void XMLFile::removeStartXML( string & txt ); // Remove the start xml tag.
|
||||
void removeComments( string & txt ); // Remove comment tags.
|
||||
void removeAttributes( string & txt ); // Remove attributes from tags.
|
||||
void readFile( const string & _filename ); // Read XML file.
|
||||
void parseFragment( string & fragment, XMLTree * parent );
|
||||
|
||||
public:
|
||||
/* Constructors */
|
||||
XMLFile( const string & _filename );
|
||||
|
||||
/* Destructor */
|
||||
~XMLFile();
|
||||
|
||||
/* Methods */
|
||||
bool exists( const string & path ); // Checks if node exists.
|
||||
const string & getValue( const string & path ); // Get node value.
|
||||
|
||||
void print();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : XMLParser.hpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 3419 $
|
||||
* Date : $Date: 2008-02-22 09:56:34 +0100 (fr, 22 feb 2008) $
|
||||
* Updated by : $Author: khole $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : A simple XML DOM-like parser. It builds a complete tree from
|
||||
* the XML file. IT supports <section/> tags, but not tag attributes.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef XMLPARSER_HPP
|
||||
#define XMLPARSER_HPP
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "ErrorMsg.hpp"
|
||||
#include "Utility.hpp"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
|
||||
class XMLAbstractNode; // Preliminary definitions.
|
||||
class XMLTree;
|
||||
class XMLNode;
|
||||
|
||||
|
||||
/* Main XML file class. Contains search methods and entire XML tree */
|
||||
class XMLFile
|
||||
{
|
||||
protected:
|
||||
XMLTree * root; // The root node, either a subtree or an ordinary node.
|
||||
|
||||
void XMLFile::removeStartXML( string & txt ); // Remove the start xml tag.
|
||||
void removeComments( string & txt ); // Remove comment tags.
|
||||
void removeAttributes( string & txt ); // Remove attributes from tags.
|
||||
void readFile( const string & _filename ); // Read XML file.
|
||||
void parseFragment( string & fragment, XMLTree * parent );
|
||||
|
||||
public:
|
||||
/* Constructors */
|
||||
XMLFile( const string & _filename );
|
||||
|
||||
/* Destructor */
|
||||
~XMLFile();
|
||||
|
||||
/* Methods */
|
||||
bool exists( const string & path ); // Checks if node exists.
|
||||
const string & getValue( const string & path ); // Get node value.
|
||||
|
||||
void print();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : main.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : AVROSP main entry function.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "JobInfo.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
JobInfo j;
|
||||
|
||||
try
|
||||
{
|
||||
j.parseCommandline( argc, argv );
|
||||
j.doJob();
|
||||
}
|
||||
catch( ErrorMsg * e )
|
||||
{
|
||||
cout << endl << "An error occurred:" << endl;
|
||||
cout << " [" << e->What() << "]" << endl;
|
||||
|
||||
delete e;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Atmel Corporation
|
||||
*
|
||||
* File : main.cpp
|
||||
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
|
||||
* Revision : $Revision: 1163 $
|
||||
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
|
||||
* Updated by : $Author: ohlia $
|
||||
*
|
||||
* Support mail : avr@atmel.com
|
||||
*
|
||||
* Target platform : Win32
|
||||
*
|
||||
* AppNote : AVR911 - AVR Open-source Programmer
|
||||
*
|
||||
* Description : AVROSP main entry function.
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "JobInfo.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
JobInfo j;
|
||||
|
||||
try
|
||||
{
|
||||
j.parseCommandline( argc, argv );
|
||||
j.doJob();
|
||||
}
|
||||
catch( ErrorMsg * e )
|
||||
{
|
||||
cout << endl << "An error occurred:" << endl;
|
||||
cout << " [" << e->What() << "]" << endl;
|
||||
|
||||
delete e;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,20 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Atmel Studio Solution File, Format Version 11.00
|
||||
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "BACnet Development Kit", "bacnet.cproj", "{1CEFD571-4B50-48FD-B75E-0E968EBBD698}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|AVR = Debug|AVR
|
||||
Release|AVR = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.ActiveCfg = Debug|AVR
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.Build.0 = Debug|AVR
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.ActiveCfg = Release|AVR
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.Build.0 = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Atmel Studio Solution File, Format Version 11.00
|
||||
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "BACnet Development Kit", "bacnet.cproj", "{1CEFD571-4B50-48FD-B75E-0E968EBBD698}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|AVR = Debug|AVR
|
||||
Release|AVR = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.ActiveCfg = Debug|AVR
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Debug|AVR.Build.0 = Debug|AVR
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.ActiveCfg = Release|AVR
|
||||
{1CEFD571-4B50-48FD-B75E-0E968EBBD698}.Release|AVR.Build.0 = Release|AVR
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user