Fixed up file indent, comments, and eol-type.

This commit is contained in:
skarg
2009-05-13 03:46:02 +00:00
parent 85c9efd2b5
commit 0c4edb33d9
49 changed files with 6758 additions and 6805 deletions
+3 -3
View File
@@ -153,7 +153,7 @@ void Send_Initialize_Routing_Table(
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
uint8_t number_of_ports = 0; uint8_t number_of_ports = 0;
BACNET_ROUTER_PORT *router_port; BACNET_ROUTER_PORT *router_port;
uint8_t i = 0; /* counter */ uint8_t i = 0; /* counter */
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE, true, npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE, true,
MESSAGE_PRIORITY_NORMAL); MESSAGE_PRIORITY_NORMAL);
@@ -203,8 +203,8 @@ void Send_Initialize_Routing_Table_Ack(
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
/* FIXME: is this parameter needed? */ /* FIXME: is this parameter needed? */
router_port_list = router_port_list; router_port_list = router_port_list;
/* setup packet for sending */ /* setup packet for sending */
+2 -1
View File
@@ -325,7 +325,8 @@ static void address_parse(BACNET_ADDRESS * dst,
dst->mac_len = 6; dst->mac_len = 6;
for (index = 0; index < 4; index++) { for (index = 0; index < 4; index++) {
dst->mac[index] = mac[index]; dst->mac[index] = mac[index];
} encode_unsigned16(&dst->mac[4], }
encode_unsigned16(&dst->mac[4],
port); port);
} else { } else {
count = count =
+2 -3
View File
@@ -137,7 +137,7 @@ BACNET_DATE Local_Date; /* rely on OS, if there is one */
If your UTC offset is -5hours of GMT, If your UTC offset is -5hours of GMT,
then BACnet UTC offset is +5hours. then BACnet UTC offset is +5hours.
BACnet UTC offset is expressed in minutes. */ BACnet UTC offset is expressed in minutes. */
static int32_t UTC_Offset = 5*60; static int32_t UTC_Offset = 5 * 60;
static bool Daylight_Savings_Status = false; /* rely on OS */ static bool Daylight_Savings_Status = false; /* rely on OS */
/* List_Of_Session_Keys */ /* List_Of_Session_Keys */
/* Time_Synchronization_Recipients */ /* Time_Synchronization_Recipients */
@@ -680,8 +680,7 @@ int Device_Encode_Property_APDU(
case PROP_LOCATION: case PROP_LOCATION:
characterstring_init_ansi(&char_string, Location); characterstring_init_ansi(&char_string, Location);
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], encode_application_character_string(&apdu[0], &char_string);
&char_string);
break; break;
/* FIXME: if you support time */ /* FIXME: if you support time */
case PROP_LOCAL_TIME: case PROP_LOCAL_TIME:
+1 -2
View File
@@ -230,8 +230,7 @@ void cleanup(void) {
old_rpm_property = rpm_property; old_rpm_property = rpm_property;
rpm_property = rpm_property->next; rpm_property = rpm_property->next;
free(old_rpm_property); free(old_rpm_property);
} } old_rpm_object = rpm_object;
old_rpm_object = rpm_object;
rpm_object = rpm_object->next; rpm_object = rpm_object->next;
free(old_rpm_object); free(old_rpm_object);
} }
+2 -2
View File
@@ -212,8 +212,8 @@ int main(int argc, char *argv[]) {
filename_remove_path(argv[0]), filename_remove_path(argv[0])); filename_remove_path(argv[0]), filename_remove_path(argv[0]));
return 0; return 0;
} }
/* decode the command line parameters */ /* decode the command line parameters */ cov_data.
cov_data.subscriberProcessIdentifier = strtol(argv[1], NULL, 0); subscriberProcessIdentifier = strtol(argv[1], NULL, 0);
cov_data.initiatingDeviceIdentifier = strtol(argv[2], NULL, 0); cov_data.initiatingDeviceIdentifier = strtol(argv[2], NULL, 0);
cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0); cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0);
cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0); cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0);
+1 -1
View File
@@ -396,7 +396,7 @@ typedef enum {
BINARY_INACTIVE = 0, BINARY_INACTIVE = 0,
BINARY_ACTIVE = 1, BINARY_ACTIVE = 1,
MAX_BINARY_PV = 1, /* for validating incoming values */ MAX_BINARY_PV = 1, /* for validating incoming values */
BINARY_NULL = 255 /* our homemade way of storing this info */ BINARY_NULL = 255 /* our homemade way of storing this info */
} BACNET_BINARY_PV; } BACNET_BINARY_PV;
typedef enum { typedef enum {
+3 -2
View File
@@ -35,8 +35,9 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void Binary_Output_Init(void); void Binary_Output_Init(
void);
void Binary_Output_Property_Lists( void Binary_Output_Property_Lists(
const int **pRequired, const int **pRequired,
const int **pOptional, const int **pOptional,
+4 -3
View File
@@ -44,9 +44,10 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void Device_Init(void); void Device_Init(
void);
void Device_Property_Lists( void Device_Property_Lists(
const int **pRequired, const int **pRequired,
const int **pOptional, const int **pOptional,
+1 -1
View File
@@ -438,7 +438,7 @@ int Device_Encode_Property_APDU(
case PROP_UTC_OFFSET: case PROP_UTC_OFFSET:
/* Note: BACnet Time Zone is offset of local time and UTC, /* Note: BACnet Time Zone is offset of local time and UTC,
rather than offset of GMT. It is expressed in minutes */ rather than offset of GMT. It is expressed in minutes */
apdu_len = encode_application_signed(&apdu[0], 5*60 /* EST */ ); apdu_len = encode_application_signed(&apdu[0], 5 * 60 /* EST */ );
break; break;
case PROP_LOCAL_DATE: case PROP_LOCAL_DATE:
/* FIXME: if you support date */ /* FIXME: if you support date */
+97 -94
View File
@@ -1,94 +1,97 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include "hardware.h" #include "hardware.h"
/* stack checking */ /* stack checking */
#if defined(__GNUC__) #if defined(__GNUC__)
extern uint8_t _end; extern uint8_t _end;
extern uint8_t __stack; extern uint8_t __stack;
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#define STACK_CANARY (0xC5) #define STACK_CANARY (0xC5)
void stack_init( void stack_init(
void) __attribute__ ((naked)) __attribute__ ((section(".init1"))); void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
#endif #endif
void stack_init( void stack_init(
void) void)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if 0 #if 0
uint8_t *p = &_end; uint8_t *p = &_end;
while (p <= &__stack) { while (p <= &__stack) {
*p = STACK_CANARY; *p = STACK_CANARY;
p++; p++;
} }
#else #else
__asm volatile ( __asm volatile (
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */ " ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n" " ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n" " st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::); " cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
#endif #endif
#endif #endif
} }
unsigned stack_size(void) unsigned stack_size(
{ void)
#if defined(__GNUC__) {
return (&__stack) - (&_end); #if defined(__GNUC__)
#else return (&__stack) - (&_end);
return 0; #else
#endif return 0;
} #endif
}
uint8_t stack_byte(unsigned offset)
{ uint8_t stack_byte(
#if defined(__GNUC__) unsigned offset)
return *(&_end + offset); {
#else #if defined(__GNUC__)
offset = offset; return *(&_end + offset);
return 0; #else
#endif offset = offset;
} return 0;
#endif
unsigned stack_unused(void) }
{
unsigned count = 0; unsigned stack_unused(
#if defined(__GNUC__) void)
uint8_t *p = &_end; {
unsigned count = 0;
while (p <= &__stack) { #if defined(__GNUC__)
if ((*p) != STACK_CANARY) { uint8_t *p = &_end;
count = p - (&_end);
break; while (p <= &__stack) {
} if ((*p) != STACK_CANARY) {
p++; count = p - (&_end);
} break;
#endif }
return count; p++;
} }
#endif
return count;
}
+51 -48
View File
@@ -1,48 +1,51 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef STACK_H #ifndef STACK_H
#define STACK_H #define STACK_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* C stack checking */ /* C stack checking */
void stack_init(void); void stack_init(
void);
unsigned stack_size(void);
unsigned stack_size(
uint8_t stack_byte(unsigned offset); void);
unsigned stack_unused(void); uint8_t stack_byte(
unsigned offset);
#ifdef __cplusplus
} unsigned stack_unused(
#endif /* __cplusplus */ void);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+228 -228
View File
@@ -1,229 +1,229 @@
############################################################################### ###############################################################################
# Makefile for LM Room Controller - AVR # Makefile for LM Room Controller - AVR
############################################################################### ###############################################################################
## General Flags ## General Flags
MCU = atmega644p MCU = atmega644p
AVRDUDE_MCU = m644p AVRDUDE_MCU = m644p
# ATmega644 bootload is at word address 7000h, 7800h, 7C00h, or 7E00h # ATmega644 bootload is at word address 7000h, 7800h, 7C00h, or 7E00h
# Double that value to get the byte address # Double that value to get the byte address
BOOTLOAD = 0xF800 BOOTLOAD = 0xF800
TARGET = bacnet TARGET = bacnet
## Tools ## Tools
CC = avr-gcc CC = avr-gcc
AR = avr-ar AR = avr-ar
OBJCOPY = avr-objcopy OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump OBJDUMP = avr-objdump
SIZE = avr-size SIZE = avr-size
AVRDUDE = avrdude AVRDUDE = avrdude
LINT = splint LINT = splint
# programmer id--check the avrdude for complete list # programmer id--check the avrdude for complete list
# of available opts. These should include stk500, # of available opts. These should include stk500,
# avr910, avrisp, bsd, pony and more. Set this to # avr910, avrisp, bsd, pony and more. Set this to
# one of the valid "-c PROGRAMMER-ID" values # one of the valid "-c PROGRAMMER-ID" values
# described in the avrdude info page. # described in the avrdude info page.
# jtag2fast = Atmel JTAG ICE mkII, running at 115200 Bd # jtag2fast = Atmel JTAG ICE mkII, running at 115200 Bd
# jtag2slow = Atmel JTAG ICE mkII, running at 19200 Bd # jtag2slow = Atmel JTAG ICE mkII, running at 19200 Bd
# avrispmkII = AVR ISP MKII # avrispmkII = AVR ISP MKII
AVRDUDE_PROGRAMMERID = avrispmkII AVRDUDE_PROGRAMMERID = avrispmkII
# #
# # port--serial or parallel port to which your # # port--serial or parallel port to which your
# # hardware programmer is attached # # hardware programmer is attached
# # usb can just be usb # # usb can just be usb
AVRDUDE_PORT = usb AVRDUDE_PORT = usb
# Source locations # Source locations
BACNET_CORE = ../../src BACNET_CORE = ../../src
BACNET_INCLUDE = ../../include BACNET_INCLUDE = ../../include
BACNET_DEMO = ../../demo BACNET_DEMO = ../../demo
# local files for this project # local files for this project
CSRC = main.c \ CSRC = main.c \
init.c \ init.c \
stack.c \ stack.c \
input.c \ input.c \
serial.c \ serial.c \
rs485.c \ rs485.c \
timer2.c \ timer2.c \
led.c \ led.c \
eeprom.c \ eeprom.c \
seeprom.c \ seeprom.c \
dlmstp.c \ dlmstp.c \
h_wp.c \ h_wp.c \
h_rp.c \ h_rp.c \
h_rpm.c \ h_rpm.c \
h_rd.c \ h_rd.c \
device.c \ device.c \
ai.c \ ai.c \
bi.c \ bi.c \
bo.c bo.c
# common demo files needed # common demo files needed
DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c \ DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c \
$(BACNET_DEMO)/handler/h_npdu.c \ $(BACNET_DEMO)/handler/h_npdu.c \
$(BACNET_DEMO)/handler/h_whois.c \ $(BACNET_DEMO)/handler/h_whois.c \
$(BACNET_DEMO)/handler/h_dcc.c \ $(BACNET_DEMO)/handler/h_dcc.c \
$(BACNET_DEMO)/handler/s_iam.c \ $(BACNET_DEMO)/handler/s_iam.c \
$(BACNET_DEMO)/handler/noserv.c $(BACNET_DEMO)/handler/noserv.c
# core BACnet stack files # core BACnet stack files
CORESRC = \ CORESRC = \
$(BACNET_CORE)/fifo.c \ $(BACNET_CORE)/fifo.c \
$(BACNET_CORE)/memcopy.c \ $(BACNET_CORE)/memcopy.c \
$(BACNET_CORE)/crc.c \ $(BACNET_CORE)/crc.c \
$(BACNET_CORE)/apdu.c \ $(BACNET_CORE)/apdu.c \
$(BACNET_CORE)/npdu.c \ $(BACNET_CORE)/npdu.c \
$(BACNET_CORE)/bacdcode.c \ $(BACNET_CORE)/bacdcode.c \
$(BACNET_CORE)/bacint.c \ $(BACNET_CORE)/bacint.c \
$(BACNET_CORE)/bacreal.c \ $(BACNET_CORE)/bacreal.c \
$(BACNET_CORE)/bacstr.c \ $(BACNET_CORE)/bacstr.c \
$(BACNET_CORE)/iam.c \ $(BACNET_CORE)/iam.c \
$(BACNET_CORE)/dcc.c \ $(BACNET_CORE)/dcc.c \
$(BACNET_CORE)/rp.c \ $(BACNET_CORE)/rp.c \
$(BACNET_CORE)/rd.c \ $(BACNET_CORE)/rd.c \
$(BACNET_CORE)/rpm.c \ $(BACNET_CORE)/rpm.c \
$(BACNET_CORE)/wp.c \ $(BACNET_CORE)/wp.c \
$(BACNET_CORE)/whois.c \ $(BACNET_CORE)/whois.c \
$(BACNET_CORE)/bacaddr.c \ $(BACNET_CORE)/bacaddr.c \
$(BACNET_CORE)/abort.c \ $(BACNET_CORE)/abort.c \
$(BACNET_CORE)/reject.c \ $(BACNET_CORE)/reject.c \
$(BACNET_CORE)/bacerror.c \ $(BACNET_CORE)/bacerror.c \
$(BACNET_CORE)/bacapp.c $(BACNET_CORE)/bacapp.c
# $(BACNET_CORE)/version.c # $(BACNET_CORE)/version.c
# $(BACNET_CORE)/bacprop.c \ # $(BACNET_CORE)/bacprop.c \
# $(BACNET_CORE)/bactext.c \ # $(BACNET_CORE)/bactext.c \
# $(BACNET_CORE)/datetime.c \ # $(BACNET_CORE)/datetime.c \
# $(BACNET_CORE)/indtext.c \ # $(BACNET_CORE)/indtext.c \
# $(BACNET_CORE)/bigend.c \ # $(BACNET_CORE)/bigend.c \
# $(BACNET_CORE)/arf.c \ # $(BACNET_CORE)/arf.c \
# $(BACNET_CORE)/awf.c \ # $(BACNET_CORE)/awf.c \
# $(BACNET_CORE)/cov.c \ # $(BACNET_CORE)/cov.c \
# $(BACNET_CORE)/iam/iam_client.c \ # $(BACNET_CORE)/iam/iam_client.c \
# $(BACNET_CORE)/ihave.c \ # $(BACNET_CORE)/ihave.c \
# $(BACNET_CORE)/timesync.c \ # $(BACNET_CORE)/timesync.c \
# $(BACNET_CORE)/whohas.c \ # $(BACNET_CORE)/whohas.c \
# $(BACNET_CORE)/filename.c \ # $(BACNET_CORE)/filename.c \
# $(BACNET_CORE)/tsm.c \ # $(BACNET_CORE)/tsm.c \
# $(BACNET_CORE)/address.c \ # $(BACNET_CORE)/address.c \
## Include Directories ## Include Directories
INCLUDES = -I. -I$(BACNET_INCLUDE) INCLUDES = -I. -I$(BACNET_INCLUDE)
# Source to Object conversion # Source to Object conversion
COBJ = $(CSRC:%.c=%.o) COBJ = $(CSRC:%.c=%.o)
DEMOOBJ = $(DEMOSRC:.c=.o) DEMOOBJ = $(DEMOSRC:.c=.o)
COREOBJ = $(CORESRC:.c=.o) COREOBJ = $(CORESRC:.c=.o)
LIBRARY = lib$(TARGET).a LIBRARY = lib$(TARGET).a
## Options common to compile, link and assembly rules ## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU) COMMON = -mmcu=$(MCU)
OPTIMIZE_FLAGS = -mcall-prologues OPTIMIZE_FLAGS = -mcall-prologues
OPTIMIZE_FLAGS += -finline-functions-called-once OPTIMIZE_FLAGS += -finline-functions-called-once
# default optimization is for debugging from AVR Studio # default optimization is for debugging from AVR Studio
OPTIMIZATION = -O0 OPTIMIZATION = -O0
#OPTIMIZATION = -Os $(OPTIMIZE_FLAGS) #OPTIMIZATION = -Os $(OPTIMIZE_FLAGS)
DEBUGGING = -g DEBUGGING = -g
# define something from the Makefile or batch file # define something from the Makefile or batch file
DEFINES = DEFINES =
## Compile options common for all C compilation units. ## Compile options common for all C compilation units.
BFLAGS = -DBACDL_MSTP BFLAGS = -DBACDL_MSTP
BFLAGS += -DMAX_APDU=128 BFLAGS += -DMAX_APDU=128
BFLAGS += -DBIG_ENDIAN=0 BFLAGS += -DBIG_ENDIAN=0
BFLAGS += -DMAX_TSM_TRANSACTIONS=0 BFLAGS += -DMAX_TSM_TRANSACTIONS=0
#BFLAGS += -DCRC_USE_TABLE #BFLAGS += -DCRC_USE_TABLE
BFLAGS += -DBACAPP_BOOLEAN BFLAGS += -DBACAPP_BOOLEAN
BFLAGS += -DBACAPP_REAL BFLAGS += -DBACAPP_REAL
BFLAGS += -DBACAPP_OBJECT_ID BFLAGS += -DBACAPP_OBJECT_ID
BFLAGS += -DBACAPP_UNSIGNED BFLAGS += -DBACAPP_UNSIGNED
BFLAGS += -DBACAPP_ENUMERATED BFLAGS += -DBACAPP_ENUMERATED
BFLAGS += -DBACAPP_CHARACTER_STRING BFLAGS += -DBACAPP_CHARACTER_STRING
BFLAGS += -DWRITE_PROPERTY BFLAGS += -DWRITE_PROPERTY
CFLAGS = $(COMMON) CFLAGS = $(COMMON)
CFLAGS += $(DEFINES) CFLAGS += $(DEFINES)
CFLAGS += $(DEBUGGING) CFLAGS += $(DEBUGGING)
# dead code removal # dead code removal
CFLAGS += -ffunction-sections -fdata-sections CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -Wall -gdwarf-2 $(BFLAGS) $(OPTIMIZATION) -fsigned-char CFLAGS += -Wall -gdwarf-2 $(BFLAGS) $(OPTIMIZATION) -fsigned-char
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d
## Assembly specific flags ## Assembly specific flags
ASMFLAGS = $(COMMON) ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS) ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
## Linker flags ## Linker flags
LDFLAGS = $(COMMON) LDFLAGS = $(COMMON)
#dead code removal #dead code removal
#LDFLAGS += -Wl,-nostartfiles,-nostdlib #LDFLAGS += -Wl,-nostartfiles,-nostdlib
LDFLAGS += -Wl,--gc-sections,-static LDFLAGS += -Wl,--gc-sections,-static
LDFLAGS += -Wl,--section-start=.bootloader=$(BOOTLOAD) LDFLAGS += -Wl,--section-start=.bootloader=$(BOOTLOAD)
LDFLAGS += -Wl,-Map=$(TARGET).map LDFLAGS += -Wl,-Map=$(TARGET).map
LDFLAGS += -Wl,-L=.,-l$(TARGET) LDFLAGS += -Wl,-L=.,-l$(TARGET)
## Intel Hex file production flags ## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
HEX_EEPROM_FLAGS = -j .eeprom HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
## Objects that must be built in order to link ## Objects that must be built in order to link
OBJECTS = $(COBJ) $(DEMOOBJ) OBJECTS = $(COBJ) $(DEMOOBJ)
## Build ## Build
TARGET_ELF=$(TARGET).elf TARGET_ELF=$(TARGET).elf
all: $(LIBRARY) \ all: $(LIBRARY) \
$(TARGET_ELF) \ $(TARGET_ELF) \
$(TARGET).hex \ $(TARGET).hex \
$(TARGET).eep \ $(TARGET).eep \
$(TARGET).lst \ $(TARGET).lst \
size Makefile size Makefile
##Link ##Link
$(TARGET_ELF): $(OBJECTS) $(LIBRARY) $(TARGET_ELF): $(OBJECTS) $(LIBRARY)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
%.hex: $(TARGET_ELF) %.hex: $(TARGET_ELF)
$(OBJCOPY) -O ihex $(HEX_FLASH_FLAGS) $< $@ $(OBJCOPY) -O ihex $(HEX_FLASH_FLAGS) $< $@
%.eep: $(TARGET_ELF) %.eep: $(TARGET_ELF)
-$(OBJCOPY) $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 -$(OBJCOPY) $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
%.lst: $(TARGET_ELF) %.lst: $(TARGET_ELF)
$(OBJDUMP) -h -S $< > $@ $(OBJDUMP) -h -S $< > $@
lib: $(LIBRARY) lib: $(LIBRARY)
$(LIBRARY): $(COREOBJ) Makefile $(LIBRARY): $(COREOBJ) Makefile
$(AR) rcs $@ $(COREOBJ) $(AR) rcs $@ $(COREOBJ)
$(OBJDUMP) --syms $@ > $(LIBRARY:.a=.lst) $(OBJDUMP) --syms $@ > $(LIBRARY:.a=.lst)
%.o: %.c %.o: %.c
$(CC) -c $(INCLUDES) $(CFLAGS) $*.c -o $@ $(CC) -c $(INCLUDES) $(CFLAGS) $*.c -o $@
size: ${TARGET_ELF} size: ${TARGET_ELF}
@echo @echo
@${SIZE} ${TARGET_ELF} @${SIZE} ${TARGET_ELF}
lint: lint:
$(LINT) $(BFLAGS) $(CSRC) $(LINT) $(BFLAGS) $(CSRC)
install: $(TARGET_ELF) install: $(TARGET_ELF)
$(AVRDUDE) -c $(AVRDUDE_PROGRAMMERID) \ $(AVRDUDE) -c $(AVRDUDE_PROGRAMMERID) \
-p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -e \ -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -e \
-U flash:w:$(TARGET).hex -U flash:w:$(TARGET).hex
## Clean target ## Clean target
.PHONY: clean .PHONY: clean
clean: clean:
-rm -rf $(OBJECTS) $(TARGET_ELF) dep/* -rm -rf $(OBJECTS) $(TARGET_ELF) dep/*
-rm -rf $(LIBRARY) $(COREOBJ) $(LIBRARY:.a=.lst) -rm -rf $(LIBRARY) $(COREOBJ) $(LIBRARY:.a=.lst)
-rm -rf $(TARGET).hex $(TARGET).eep $(TARGET).lst $(TARGET).map -rm -rf $(TARGET).hex $(TARGET).eep $(TARGET).lst $(TARGET).map
## Other dependencies ## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) -include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)
+196 -196
View File
@@ -1,196 +1,196 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
/* Analog Input Objects customize for your use */ /* Analog Input Objects customize for your use */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "config.h" #include "config.h"
/* Analog Input */ /* Analog Input */
#define MAX_ANALOG_INPUTS 2 #define MAX_ANALOG_INPUTS 2
#if (MAX_ANALOG_INPUTS > 9) #if (MAX_ANALOG_INPUTS > 9)
#error Modify the Analog_Input_Name to handle multiple digits #error Modify the Analog_Input_Name to handle multiple digits
#endif #endif
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Input_Properties_Required[] = { static const int Analog_Input_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS, PROP_STATUS_FLAGS,
PROP_EVENT_STATE, PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE, PROP_OUT_OF_SERVICE,
PROP_UNITS, PROP_UNITS,
-1 -1
}; };
static const int Analog_Input_Properties_Optional[] = { static const int Analog_Input_Properties_Optional[] = {
PROP_DESCRIPTION, PROP_DESCRIPTION,
-1 -1
}; };
static const int Analog_Input_Properties_Proprietary[] = { static const int Analog_Input_Properties_Proprietary[] = {
-1 -1
}; };
void Analog_Input_Property_Lists( void Analog_Input_Property_Lists(
const int **pRequired, const int **pRequired,
const int **pOptional, const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Analog_Input_Properties_Required; *pRequired = Analog_Input_Properties_Required;
if (pOptional) if (pOptional)
*pOptional = Analog_Input_Properties_Optional; *pOptional = Analog_Input_Properties_Optional;
if (pProprietary) if (pProprietary)
*pProprietary = Analog_Input_Properties_Proprietary; *pProprietary = Analog_Input_Properties_Proprietary;
return; return;
} }
static uint8_t Present_Value[MAX_ANALOG_INPUTS]; static uint8_t Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(
uint32_t object_instance) uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
return true; return true;
return false; return false;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(
void) void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(
unsigned index) unsigned index)
{ {
return index; return index;
} }
char *Analog_Input_Name( char *Analog_Input_Name(
uint32_t object_instance) uint32_t object_instance)
{ {
static char text_string[16] = "AI-0"; /* okay for single thread */ static char text_string[16] = "AI-0"; /* okay for single thread */
if (object_instance < MAX_ANALOG_INPUTS) { if (object_instance < MAX_ANALOG_INPUTS) {
text_string[3] = '0' + (uint8_t) object_instance; text_string[3] = '0' + (uint8_t) object_instance;
return text_string; return text_string;
} }
return NULL; return NULL;
} }
static float Analog_Input_Present_Value( static float Analog_Input_Present_Value(
uint32_t object_instance) uint32_t object_instance)
{ {
float value = 0.0; float value = 0.0;
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
value = Present_Value[object_instance]; value = Present_Value[object_instance];
return value; return value;
} }
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object has already exists */ /* assumption - object has already exists */
int Analog_Input_Encode_Property_APDU( int Analog_Input_Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
int32_t array_index, int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
(void) array_index; (void) array_index;
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
object_instance); object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Analog_Input_Name(object_instance)); Analog_Input_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len =
encode_application_real(&apdu[0], encode_application_real(&apdu[0],
Analog_Input_Present_Value(object_instance)); Analog_Input_Present_Value(object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false); apdu_len = encode_application_boolean(&apdu[0], false);
break; break;
case PROP_UNITS: case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
return apdu_len; return apdu_len;
} }
+232 -232
View File
@@ -1,232 +1,232 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
/* Binary Input Objects customize for your use */ /* Binary Input Objects customize for your use */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "config.h" #include "config.h"
#define MAX_BINARY_INPUTS 8 #define MAX_BINARY_INPUTS 8
#if (MAX_BINARY_INPUTS > 9) #if (MAX_BINARY_INPUTS > 9)
#error Modify the Binary_Input_Name to handle multiple digits #error Modify the Binary_Input_Name to handle multiple digits
#endif #endif
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Input_Properties_Required[] = { static const int Binary_Input_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS, PROP_STATUS_FLAGS,
PROP_EVENT_STATE, PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE, PROP_OUT_OF_SERVICE,
PROP_POLARITY, PROP_POLARITY,
-1 -1
}; };
static const int Binary_Input_Properties_Optional[] = { static const int Binary_Input_Properties_Optional[] = {
PROP_DESCRIPTION, PROP_DESCRIPTION,
-1 -1
}; };
static const int Binary_Input_Properties_Proprietary[] = { static const int Binary_Input_Properties_Proprietary[] = {
-1 -1
}; };
void Binary_Input_Property_Lists( void Binary_Input_Property_Lists(
const int **pRequired, const int **pRequired,
const int **pOptional, const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) { if (pRequired) {
*pRequired = Binary_Input_Properties_Required; *pRequired = Binary_Input_Properties_Required;
} }
if (pOptional) { if (pOptional) {
*pOptional = Binary_Input_Properties_Optional; *pOptional = Binary_Input_Properties_Optional;
} }
if (pProprietary) { if (pProprietary) {
*pProprietary = Binary_Input_Properties_Proprietary; *pProprietary = Binary_Input_Properties_Proprietary;
} }
return; return;
} }
static void Binary_Input_Initialize( static void Binary_Input_Initialize(
void) void)
{ {
static bool initialized = false; static bool initialized = false;
unsigned i; unsigned i;
if (!initialized) { if (!initialized) {
initialized = true; initialized = true;
for (i = 0; i < MAX_BINARY_INPUTS; i++) { for (i = 0; i < MAX_BINARY_INPUTS; i++) {
Present_Value[i] = BINARY_INACTIVE; Present_Value[i] = BINARY_INACTIVE;
} }
} }
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance( bool Binary_Input_Valid_Instance(
uint32_t object_instance) uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_INPUTS) if (object_instance < MAX_BINARY_INPUTS)
return true; return true;
return false; return false;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Input_Count( unsigned Binary_Input_Count(
void) void)
{ {
return MAX_BINARY_INPUTS; return MAX_BINARY_INPUTS;
} }
/* we simply have 0-n object instances.*/ /* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance( uint32_t Binary_Input_Index_To_Instance(
unsigned index) unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index( unsigned Binary_Input_Instance_To_Index(
uint32_t object_instance) uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_INPUTS; unsigned index = MAX_BINARY_INPUTS;
if (object_instance < MAX_BINARY_INPUTS) if (object_instance < MAX_BINARY_INPUTS)
index = object_instance; index = object_instance;
return index; return index;
} }
static BACNET_BINARY_PV Binary_Input_Present_Value( static BACNET_BINARY_PV Binary_Input_Present_Value(
uint32_t object_instance) uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0; unsigned index = 0;
Binary_Input_Initialize(); Binary_Input_Initialize();
index = Binary_Input_Instance_To_Index(object_instance); index = Binary_Input_Instance_To_Index(object_instance);
if (index < MAX_BINARY_INPUTS) { if (index < MAX_BINARY_INPUTS) {
value = Present_Value[index]; value = Present_Value[index];
} }
return value; return value;
} }
char *Binary_Input_Name( char *Binary_Input_Name(
uint32_t object_instance) uint32_t object_instance)
{ {
static char text_string[16] = "BI-0"; /* okay for single thread */ static char text_string[16] = "BI-0"; /* okay for single thread */
if (object_instance < MAX_BINARY_INPUTS) { if (object_instance < MAX_BINARY_INPUTS) {
text_string[3] = '0' + (uint8_t) object_instance; text_string[3] = '0' + (uint8_t) object_instance;
return text_string; return text_string;
} }
return NULL; return NULL;
} }
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */ /* assumption - object already exists, and has been bounds checked */
int Binary_Input_Encode_Property_APDU( int Binary_Input_Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
int32_t array_index, int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
BACNET_POLARITY polarity = POLARITY_NORMAL; BACNET_POLARITY polarity = POLARITY_NORMAL;
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
(void) array_index; (void) array_index;
Binary_Input_Initialize(); Binary_Input_Initialize();
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT, encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
object_instance); object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
/* note: object name must be unique in our device */ /* note: object name must be unique in our device */
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Binary_Input_Name(object_instance)); Binary_Input_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT); encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
value = Binary_Input_Present_Value(object_instance); value = Binary_Input_Present_Value(object_instance);
apdu_len = encode_application_enumerated(&apdu[0], value); apdu_len = encode_application_enumerated(&apdu[0], value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */ /* note: see the details in the standard on how to use these */
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */ /* note: see the details in the standard on how to use this */
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false); apdu_len = encode_application_boolean(&apdu[0], false);
break; break;
case PROP_POLARITY: case PROP_POLARITY:
apdu_len = encode_application_enumerated(&apdu[0], polarity); apdu_len = encode_application_enumerated(&apdu[0], polarity);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
return apdu_len; return apdu_len;
} }
File diff suppressed because it is too large Load Diff
@@ -1,46 +1,46 @@
/* definitions generated by preprocessor, copy into defines.h */ /* definitions generated by preprocessor, copy into defines.h */
#ifndef PPINC #ifndef PPINC
#define _ATMEGA644P // device select: _ATMEGAxxxx #define _ATMEGA644P /* device select: _ATMEGAxxxx */
#define _B2048 // boot size select: _Bxxxx (words), powers of two only #define _B2048 /* boot size select: _Bxxxx (words), powers of two only */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#include "iom644.h" #include "iom644.h"
#endif #endif
#if __GNUC__ #if __GNUC__
#include <avr/io.h> #include <avr/io.h>
#endif #endif
/* define pin for enter-self-prog-mode */ /* define pin for enter-self-prog-mode */
#define PROGPORT PORTB #define PROGPORT PORTB
#define PROGPIN PINB #define PROGPIN PINB
#define PROG_NO PB0 #define PROG_NO PB0
/* baud rate register value calculation */ /* baud rate register value calculation */
#define CPU_FREQ 18430000 #define CPU_FREQ 18430000
#define BAUD_RATE 115200 #define BAUD_RATE 115200
#define BRREG_VALUE 9 #define BRREG_VALUE 9
/* definitions for UART control */ /* definitions for UART control */
#define BAUD_RATE_LOW_REG UBRR1 #define BAUD_RATE_LOW_REG UBRR1
#define UART_CONTROL_REG UCSR1B #define UART_CONTROL_REG UCSR1B
#define ENABLE_TRANSMITTER_BIT TXEN1 #define ENABLE_TRANSMITTER_BIT TXEN1
#define ENABLE_RECEIVER_BIT RXEN1 #define ENABLE_RECEIVER_BIT RXEN1
#define UART_STATUS_REG UCSR1A #define UART_STATUS_REG UCSR1A
#define TRANSMIT_COMPLETE_BIT TXC1 #define TRANSMIT_COMPLETE_BIT TXC1
#define RECEIVE_COMPLETE_BIT RXC1 #define RECEIVE_COMPLETE_BIT RXC1
#define UART_DATA_REG UDR1 #define UART_DATA_REG UDR1
/* definitions for SPM control */ /* definitions for SPM control */
#define SPMCR_REG SPMCSR #define SPMCR_REG SPMCSR
#define PAGESIZE 256 #define PAGESIZE 256
#define APP_END 61440 #define APP_END 61440
//#define LARGE_MEMORY /*#define LARGE_MEMORY */
/* definitions for device recognition */ /* definitions for device recognition */
#define PARTCODE 0 #define PARTCODE 0
#define SIGNATURE_BYTE_1 0x1E #define SIGNATURE_BYTE_1 0x1E
#define SIGNATURE_BYTE_2 0x96 #define SIGNATURE_BYTE_2 0x96
#define SIGNATURE_BYTE_3 0x0A #define SIGNATURE_BYTE_3 0x0A
/* indicate that preprocessor result is included */ /* indicate that preprocessor result is included */
#define PPINC #define PPINC
#endif #endif
@@ -31,11 +31,11 @@
/* Uncomment the following to save code space */ /* Uncomment the following to save code space */
//#define REMOVE_AVRPROG_SUPPORT /*#define REMOVE_AVRPROG_SUPPORT */
//#define REMOVE_FUSE_AND_LOCK_BIT_SUPPORT /*#define REMOVE_FUSE_AND_LOCK_BIT_SUPPORT */
//#define REMOVE_BLOCK_SUPPORT /*#define REMOVE_BLOCK_SUPPORT */
//#define REMOVE_EEPROM_BYTE_SUPPORT /*#define REMOVE_EEPROM_BYTE_SUPPORT */
//#define REMOVE_FLASH_BYTE_SUPPORT /*#define REMOVE_FLASH_BYTE_SUPPORT */
/* /*
* GCC doesn't optimize long int arithmetics very clever. As the * GCC doesn't optimize long int arithmetics very clever. As the
@@ -47,13 +47,19 @@
*/ */
#ifdef LARGE_MEMORY #ifdef LARGE_MEMORY
# define ADDR_T unsigned long # define ADDR_T unsigned long
#else /* !LARGE_MEMORY */ #else /* !LARGE_MEMORY */
# define ADDR_T unsigned int # define ADDR_T unsigned int
#endif /* LARGE_MEMORY */ #endif /* LARGE_MEMORY */
#ifndef REMOVE_BLOCK_SUPPORT #ifndef REMOVE_BLOCK_SUPPORT
unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address); unsigned char BlockLoad(
void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address); unsigned int size,
unsigned char mem,
ADDR_T * address);
void BlockRead(
unsigned int size,
unsigned char mem,
ADDR_T * address);
/* BLOCKSIZE should be chosen so that the following holds: BLOCKSIZE*n = PAGESIZE, where n=1,2,3... */ /* BLOCKSIZE should be chosen so that the following holds: BLOCKSIZE*n = PAGESIZE, where n=1,2,3... */
#define BLOCKSIZE PAGESIZE #define BLOCKSIZE PAGESIZE
@@ -61,433 +67,398 @@ void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address);
#endif /* REMOVE_BLOCK_SUPPORT */ #endif /* REMOVE_BLOCK_SUPPORT */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
__C_task void main(void) __C_task void main(
void)
#else /* ! __ICCAVR__ */ #else /* ! __ICCAVR__ */
int main(void) int main(
void)
#endif /* __ICCAVR__ */ #endif /* __ICCAVR__ */
{ {
ADDR_T address; ADDR_T address;
unsigned int temp_int; unsigned int temp_int;
unsigned char val; unsigned char val;
/* Initialization */ /* Initialization */
void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector. void (
PROGPORT |= (1<<PROG_NO); // Enable pull-up on PROG_NO line on PROGPORT. *funcptr) (
initbootuart(); // Initialize UART. void) = 0x0000; /* Set up function pointer to RESET vector. */
PROGPORT |= (1 << PROG_NO); /* Enable pull-up on PROG_NO line on PROGPORT. */
initbootuart(); /* Initialize UART. */
/* Branch to bootloader or application code? */ /* Branch to bootloader or application code? */
if( !(PROGPIN & (1<<PROG_NO)) ) // If PROGPIN is pulled low, enter programmingmode. if (!(PROGPIN & (1 << PROG_NO))) { /* If PROGPIN is pulled low, enter programmingmode. */
{
/* Main loop */ /* Main loop */
for(;;) for (;;) {
{ val = recchar(); /* Wait for command character. */
val=recchar(); // Wait for command character.
// Check autoincrement status. /* Check autoincrement status. */
if(val=='a') if (val == 'a') {
{ sendchar('Y'); /* Yes, we do autoincrement. */
sendchar('Y'); // Yes, we do autoincrement.
} }
// Set address. /* Set address. */
else if(val=='A') // Set address... else if (val == 'A') { /* Set address... *//* NOTE: Flash addresses are given in words, not bytes. */
{ // NOTE: Flash addresses are given in words, not bytes. address = (recchar() << 8) | recchar(); /* Read address high and low byte. */
address=(recchar()<<8) | recchar(); // Read address high and low byte. sendchar('\r'); /* Send OK back. */
sendchar('\r'); // Send OK back.
} }
// Chip erase. /* Chip erase. */
else if(val=='e') else if (val == 'e') {
{ for (address = 0; address < APP_END; address += PAGESIZE) { /* NOTE: Here we use address as a byte-address, not word-address, for convenience. */
for(address = 0; address < APP_END;address += PAGESIZE) _WAIT_FOR_SPM();
{ // NOTE: Here we use address as a byte-address, not word-address, for convenience.
_WAIT_FOR_SPM();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. #pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#endif #endif
_PAGE_ERASE( address ); _PAGE_ERASE(address);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default. #pragma diag_default=Pe1053 /* Back to default. */
#endif #endif
} }
sendchar('\r'); // Send OK back. sendchar('\r'); /* Send OK back. */
} }
#ifndef REMOVE_BLOCK_SUPPORT #ifndef REMOVE_BLOCK_SUPPORT
// Check block load support. /* Check block load support. */
else if(val=='b') else if (val == 'b') {
{ sendchar('Y'); /* Report block load supported. */
sendchar('Y'); // Report block load supported. sendchar((BLOCKSIZE >> 8) & 0xFF); /* MSB first. */
sendchar((BLOCKSIZE>>8) & 0xFF); // MSB first. sendchar(BLOCKSIZE & 0xFF); /* Report BLOCKSIZE (bytes). */
sendchar(BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes). }
}
// Start block load. /* Start block load. */
else if(val=='B') else if (val == 'B') {
{ temp_int = (recchar() << 8) | recchar(); /* Get block size. */
temp_int = (recchar()<<8) | recchar(); // Get block size. val = recchar(); /* Get memtype. */
val = recchar(); // Get memtype. sendchar(BlockLoad(temp_int, val, &address)); /* Block load. */
sendchar( BlockLoad(temp_int,val,&address) ); // Block load. }
}
/* Start block read. */
// Start block read. else if (val == 'g') {
else if(val=='g') temp_int = (recchar() << 8) | recchar(); /* Get block size. */
{ val = recchar(); /* Get memtype */
temp_int = (recchar()<<8) | recchar(); // Get block size. BlockRead(temp_int, val, &address); /* Block read */
val = recchar(); // Get memtype }
BlockRead(temp_int,val,&address); // Block read
}
#endif /* REMOVE_BLOCK_SUPPORT */ #endif /* REMOVE_BLOCK_SUPPORT */
#ifndef REMOVE_FLASH_BYTE_SUPPORT #ifndef REMOVE_FLASH_BYTE_SUPPORT
// Read program memory. /* Read program memory. */
else if(val=='R') else if (val == 'R') {
{ /* Send high byte, then low byte of flash word. */
// Send high byte, then low byte of flash word. _WAIT_FOR_SPM();
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION(); _ENABLE_RWW_SECTION();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. #pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#endif #endif
sendchar( _LOAD_PROGRAM_MEMORY( (address << 1)+1 ) ); sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 1));
sendchar( _LOAD_PROGRAM_MEMORY( (address << 1)+0 ) ); sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 0));
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default. #pragma diag_default=Pe1053 /* Back to default. */
#endif #endif
address++; // Auto-advance to next Flash word. address++; /* Auto-advance to next Flash word. */
} }
// Write program memory, low byte.
else if(val=='c') /* Write program memory, low byte. */
{ // NOTE: Always use this command before sending high byte. else if (val == 'c') { /* NOTE: Always use this command before sending high byte. */
temp_int=recchar(); // Get low byte for later _FILL_TEMP_WORD. temp_int = recchar(); /* Get low byte for later _FILL_TEMP_WORD. */
sendchar('\r'); // Send OK back. sendchar('\r'); /* Send OK back. */
} }
// Write program memory, high byte. /* Write program memory, high byte. */
else if(val=='C') else if (val == 'C') {
{ temp_int |= (recchar() << 8); /* Get and insert high byte. */
temp_int |= (recchar()<<8); // Get and insert high byte.
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. #pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#endif #endif
_FILL_TEMP_WORD( (address << 1), temp_int ); // Convert word-address to byte-address and fill. _FILL_TEMP_WORD((address << 1), temp_int); /* Convert word-address to byte-address and fill. */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default. #pragma diag_default=Pe1053 /* Back to default. */
#endif #endif
address++; // Auto-advance to next Flash word. address++; /* Auto-advance to next Flash word. */
sendchar('\r'); // Send OK back. sendchar('\r'); /* Send OK back. */
} }
// Write page. /* Write page. */
else if(val== 'm') else if (val == 'm') {
{ if (address >= (APP_END >> 1)) { /* Protect bootloader area. */
if( address >= (APP_END>>1) ) // Protect bootloader area.
{
sendchar('?'); sendchar('?');
} else } else {
{ _WAIT_FOR_SPM();
_WAIT_FOR_SPM();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. #pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#endif #endif
_PAGE_WRITE( address << 1 ); // Convert word-address to byte-address and write. _PAGE_WRITE(address << 1); /* Convert word-address to byte-address and write. */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default. #pragma diag_default=Pe1053 /* Back to default. */
#endif #endif
} }
sendchar('\r'); // Send OK back. sendchar('\r'); /* Send OK back. */
} }
#endif /* REMOVE_FLASH_BYTE_SUPPORT */ #endif /* REMOVE_FLASH_BYTE_SUPPORT */
#ifndef REMOVE_EEPROM_BYTE_SUPPORT #ifndef REMOVE_EEPROM_BYTE_SUPPORT
// Write EEPROM memory. /* Write EEPROM memory. */
else if (val == 'D') else if (val == 'D') {
{ _WAIT_FOR_SPM();
_WAIT_FOR_SPM(); EEARL = address; /* Setup EEPROM address. */
EEARL = address; // Setup EEPROM address.
EEARH = (address >> 8); EEARH = (address >> 8);
EEDR = recchar(); // Get byte. EEDR = recchar(); /* Get byte. */
EECR |= (1<<EEMWE); // Write byte. EECR |= (1 << EEMWE); /* Write byte. */
EECR |= (1<<EEWE); EECR |= (1 << EEWE);
while (EECR & (1<<EEWE)) // Wait for write operation to finish. while (EECR & (1 << EEWE)) /* Wait for write operation to finish. */
; ;
address++; // Auto-advance to next EEPROM byte. address++; /* Auto-advance to next EEPROM byte. */
sendchar('\r');// Send OK back. sendchar('\r'); /* Send OK back. */
} }
// Read EEPROM memory. /* Read EEPROM memory. */
else if (val == 'd') else if (val == 'd') {
{ EEARL = address; /* Setup EEPROM address. */
EEARL = address; // Setup EEPROM address.
EEARH = (address >> 8); EEARH = (address >> 8);
EECR |= (1<<EERE); // Read byte... EECR |= (1 << EERE); /* Read byte... */
sendchar(EEDR); // ...and send it back. sendchar(EEDR); /* ...and send it back. */
address++; // Auto-advance to next EEPROM byte. address++; /* Auto-advance to next EEPROM byte. */
} }
#endif /* REMOVE_EEPROM_BYTE_SUPPORT */ #endif /* REMOVE_EEPROM_BYTE_SUPPORT */
#ifndef REMOVE_FUSE_AND_LOCK_BIT_SUPPORT #ifndef REMOVE_FUSE_AND_LOCK_BIT_SUPPORT
// Write lockbits. /* Write lockbits. */
else if(val=='l') else if (val == 'l') {
{ _WAIT_FOR_SPM();
_WAIT_FOR_SPM(); _SET_LOCK_BITS(recchar()); /* Read and set lock bits. */
_SET_LOCK_BITS( recchar() ); // Read and set lock bits. sendchar('\r'); /* Send OK back. */
sendchar('\r'); // Send OK back.
} }
#if defined(_GET_LOCK_BITS) #if defined(_GET_LOCK_BITS)
// Read lock bits. /* Read lock bits. */
else if(val=='r') else if (val == 'r') {
{ _WAIT_FOR_SPM();
_WAIT_FOR_SPM(); sendchar(_GET_LOCK_BITS());
sendchar( _GET_LOCK_BITS() );
} }
// Read fuse bits. /* Read fuse bits. */
else if(val=='F') else if (val == 'F') {
{ _WAIT_FOR_SPM();
_WAIT_FOR_SPM(); sendchar(_GET_LOW_FUSES());
sendchar( _GET_LOW_FUSES() );
} }
// Read high fuse bits. /* Read high fuse bits. */
else if(val=='N') else if (val == 'N') {
{ _WAIT_FOR_SPM();
_WAIT_FOR_SPM(); sendchar(_GET_HIGH_FUSES());
sendchar( _GET_HIGH_FUSES() );
} }
// Read extended fuse bits. /* Read extended fuse bits. */
else if(val=='Q') else if (val == 'Q') {
{ _WAIT_FOR_SPM();
_WAIT_FOR_SPM(); sendchar(_GET_EXTENDED_FUSES());
sendchar( _GET_EXTENDED_FUSES() );
} }
#endif /* defined(_GET_LOCK_BITS) */ #endif /* defined(_GET_LOCK_BITS) */
#endif /* REMOVE_FUSE_AND_LOCK_BIT_SUPPORT */ #endif /* REMOVE_FUSE_AND_LOCK_BIT_SUPPORT */
#ifndef REMOVE_AVRPROG_SUPPORT #ifndef REMOVE_AVRPROG_SUPPORT
// Enter and leave programming mode. /* Enter and leave programming mode. */
else if((val=='P')||(val=='L')) else if ((val == 'P') || (val == 'L')) {
{ sendchar('\r'); /* Nothing special to do, just answer OK. */
sendchar('\r'); // Nothing special to do, just answer OK.
}
// Exit bootloader.
else if(val=='E')
{
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION();
sendchar('\r');
funcptr(); // Jump to Reset vector 0x0000 in Application Section.
} }
// Get programmer type. /* Exit bootloader. */
else if (val=='p') else if (val == 'E') {
{ _WAIT_FOR_SPM();
sendchar('S'); // Answer 'SERIAL'. _ENABLE_RWW_SECTION();
sendchar('\r');
funcptr(); /* Jump to Reset vector 0x0000 in Application Section. */
} }
// Return supported device codes. /* Get programmer type. */
else if(val=='t') else if (val == 'p') {
{ sendchar('S'); /* Answer 'SERIAL'. */
}
/* Return supported device codes. */
else if (val == 't') {
#if PARTCODE+0 > 0 #if PARTCODE+0 > 0
sendchar( PARTCODE ); // Supports only this device, of course. sendchar(PARTCODE); /* Supports only this device, of course. */
#endif /* PARTCODE */ #endif /* PARTCODE */
sendchar( 0 ); // Send list terminator. sendchar(0); /* Send list terminator. */
} }
// Set LED, clear LED and set device type. /* Set LED, clear LED and set device type. */
else if((val=='x')||(val=='y')||(val=='T')) else if ((val == 'x') || (val == 'y') || (val == 'T')) {
{ recchar(); /* Ignore the command and it's parameter. */
recchar(); // Ignore the command and it's parameter. sendchar('\r'); /* Send OK back. */
sendchar('\r'); // Send OK back.
} }
#endif /* REMOVE_AVRPROG_SUPPORT */ #endif /* REMOVE_AVRPROG_SUPPORT */
// Return programmer identifier. /* Return programmer identifier. */
else if(val=='S') else if (val == 'S') {
{ sendchar('A'); /* Return 'AVRBOOT'. */
sendchar('A'); // Return 'AVRBOOT'. sendchar('V'); /* Software identifier (aka programmer signature) is always 7 characters. */
sendchar('V'); // Software identifier (aka programmer signature) is always 7 characters.
sendchar('R'); sendchar('R');
sendchar('B'); sendchar('B');
sendchar('O'); sendchar('O');
sendchar('O'); sendchar('O');
sendchar('T'); sendchar('T');
} }
// Return software version. /* Return software version. */
else if(val=='V') else if (val == 'V') {
{
sendchar('1'); sendchar('1');
sendchar('5'); sendchar('5');
} }
// Return signature bytes. /* Return signature bytes. */
else if(val=='s') else if (val == 's') {
{ sendchar(SIGNATURE_BYTE_3);
sendchar( SIGNATURE_BYTE_3 ); sendchar(SIGNATURE_BYTE_2);
sendchar( SIGNATURE_BYTE_2 ); sendchar(SIGNATURE_BYTE_1);
sendchar( SIGNATURE_BYTE_1 ); }
}
// The last command to accept is ESC (synchronization). /* The last command to accept is ESC (synchronization). */
else if(val!=0x1b) // If not ESC, then it is unrecognized... else if (val != 0x1b) { /* If not ESC, then it is unrecognized... */
{
sendchar('?'); sendchar('?');
} }
} // end: for(;;) } /* end: for(;;) */
} } else {
else _WAIT_FOR_SPM();
{
_WAIT_FOR_SPM();
_ENABLE_RWW_SECTION(); _ENABLE_RWW_SECTION();
funcptr(); // Jump to Reset vector 0x0000 in Application Section. funcptr(); /* Jump to Reset vector 0x0000 in Application Section. */
} }
} // end: main } /* end: main */
#ifndef REMOVE_BLOCK_SUPPORT #ifndef REMOVE_BLOCK_SUPPORT
unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address) unsigned char BlockLoad(
unsigned int size,
unsigned char mem,
ADDR_T * address)
{ {
unsigned char buffer[BLOCKSIZE]; unsigned char buffer[BLOCKSIZE];
unsigned int data; unsigned int data;
ADDR_T tempaddress; ADDR_T tempaddress;
// EEPROM memory type. /* EEPROM memory type. */
if(mem=='E') if (mem == 'E') {
{
/* Fill buffer first, as EEPROM is too slow to copy with UART speed */ /* Fill buffer first, as EEPROM is too slow to copy with UART speed */
for(tempaddress=0;tempaddress<size;tempaddress++) for (tempaddress = 0; tempaddress < size; tempaddress++)
buffer[tempaddress] = recchar(); buffer[tempaddress] = recchar();
/* Then program the EEPROM */ /* Then program the EEPROM */
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
for( tempaddress=0; tempaddress < size; tempaddress++) for (tempaddress = 0; tempaddress < size; tempaddress++) {
{ EEARL = *address; /* Setup EEPROM address */
EEARL = *address; // Setup EEPROM address
EEARH = ((*address) >> 8); EEARH = ((*address) >> 8);
EEDR = buffer[tempaddress]; // Get byte. EEDR = buffer[tempaddress]; /* Get byte. */
EECR |= (1<<EEMWE); // Write byte. EECR |= (1 << EEMWE); /* Write byte. */
EECR |= (1<<EEWE); EECR |= (1 << EEWE);
while (EECR & (1<<EEWE)) // Wait for write operation to finish. while (EECR & (1 << EEWE)) /* Wait for write operation to finish. */
; ;
(*address)++; // Select next EEPROM byte (*address)++; /* Select next EEPROM byte */
} }
return '\r'; // Report programming OK return '\r'; /* Report programming OK */
} }
// Flash memory type. /* Flash memory type. */
else if(mem=='F') else if (mem == 'F') { /* NOTE: For flash programming, 'address' is given in words. */
{ // NOTE: For flash programming, 'address' is given in words. (*address) <<= 1; /* Convert address to bytes temporarily. */
(*address) <<= 1; // Convert address to bytes temporarily. tempaddress = (*address); /* Store address in page. */
tempaddress = (*address); // Store address in page.
do {
do
{
data = recchar(); data = recchar();
data |= (recchar() << 8); data |= (recchar() << 8);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. #pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#endif #endif
_FILL_TEMP_WORD(*address,data); _FILL_TEMP_WORD(*address, data);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default. #pragma diag_default=Pe1053 /* Back to default. */
#endif #endif
(*address)+=2; // Select next word in memory. (*address) += 2; /* Select next word in memory. */
size -= 2; // Reduce number of bytes to write by two. size -= 2; /* Reduce number of bytes to write by two. */
} while(size); // Loop until all bytes written. } while (size); /* Loop until all bytes written. */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr. #pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#endif #endif
_PAGE_WRITE(tempaddress); _PAGE_WRITE(tempaddress);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default. #pragma diag_default=Pe1053 /* Back to default. */
#endif #endif
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
_ENABLE_RWW_SECTION(); _ENABLE_RWW_SECTION();
(*address) >>= 1; // Convert address back to Flash words again. (*address) >>= 1; /* Convert address back to Flash words again. */
return '\r'; // Report programming OK return '\r'; /* Report programming OK */
} }
// Invalid memory type? /* Invalid memory type? */
else else {
{
return '?'; return '?';
} }
} }
void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address) void BlockRead(
unsigned int size,
unsigned char mem,
ADDR_T * address)
{ {
// EEPROM memory type. /* EEPROM memory type. */
if (mem=='E') // Read EEPROM if (mem == 'E') { /* Read EEPROM */
{ do {
do EEARL = *address; /* Setup EEPROM address */
{
EEARL = *address; // Setup EEPROM address
EEARH = ((*address) >> 8); EEARH = ((*address) >> 8);
(*address)++; // Select next EEPROM byte (*address)++; /* Select next EEPROM byte */
EECR |= (1<<EERE); // Read EEPROM EECR |= (1 << EERE); /* Read EEPROM */
sendchar(EEDR); // Transmit EEPROM dat ato PC sendchar(EEDR); /* Transmit EEPROM dat ato PC */
size--; // Decrease number of bytes to read size--; /* Decrease number of bytes to read */
} while (size); // Repeat until all block has been read } while (size); /* Repeat until all block has been read */
} }
// Flash memory type.
else if(mem=='F')
{
(*address) <<= 1; // Convert address to bytes temporarily.
do
{
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
#endif
sendchar( _LOAD_PROGRAM_MEMORY(*address) );
sendchar( _LOAD_PROGRAM_MEMORY((*address)+1) );
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 // Back to default.
#endif
(*address) += 2; // Select next word in memory.
size -= 2; // Subtract two bytes from number of bytes to read
} while (size); // Repeat until all block has been read
(*address) >>= 1; // Convert address back to Flash words again. /* Flash memory type. */
else if (mem == 'F') {
(*address) <<= 1; /* Convert address to bytes temporarily. */
do {
#ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */
#endif
sendchar(_LOAD_PROGRAM_MEMORY(*address));
sendchar(_LOAD_PROGRAM_MEMORY((*address) + 1));
#ifdef __ICCAVR__
#pragma diag_default=Pe1053 /* Back to default. */
#endif
(*address) += 2; /* Select next word in memory. */
size -= 2; /* Subtract two bytes from number of bytes to read */
} while (size); /* Repeat until all block has been read */
(*address) >>= 1; /* Convert address back to Flash words again. */
} }
} }
#endif /* REMOVE_BLOCK_SUPPORT */ #endif /* REMOVE_BLOCK_SUPPORT */
@@ -19,24 +19,26 @@
#include "defines.h" #include "defines.h"
void initbootuart(void) void initbootuart(
void)
{ {
BAUD_RATE_LOW_REG = BRREG_VALUE; BAUD_RATE_LOW_REG = BRREG_VALUE;
UART_CONTROL_REG = (1 << ENABLE_RECEIVER_BIT) | UART_CONTROL_REG = (1 << ENABLE_RECEIVER_BIT) | (1 << ENABLE_TRANSMITTER_BIT); /* enable receive and transmit */
(1 << ENABLE_TRANSMITTER_BIT); // enable receive and transmit
} }
void sendchar(unsigned char c) void sendchar(
unsigned char c)
{ {
UART_DATA_REG = c; // prepare transmission UART_DATA_REG = c; /* prepare transmission */
while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT)));// wait until byte sendt while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT))); /* wait until byte sendt */
UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT); // delete TXCflag UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT); /* delete TXCflag */
} }
unsigned char recchar(void) unsigned char recchar(
void)
{ {
while(!(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT))); // wait for data while (!(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT))); /* wait for data */
return UART_DATA_REG; return UART_DATA_REG;
} }
@@ -17,6 +17,9 @@
* Description : Header file for serial.c * Description : Header file for serial.c
****************************************************************************/ ****************************************************************************/
void initbootuart( void ); void initbootuart(
void sendchar( unsigned char ); void);
unsigned char recchar( void ); void sendchar(
unsigned char);
unsigned char recchar(
void);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+70 -70
View File
@@ -1,70 +1,70 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "hardware.h" #include "hardware.h"
#include "eeprom.h" #include "eeprom.h"
/* Internal EEPROM of the AVR - http://supp.iar.com/Support/?note=45745 */ /* Internal EEPROM of the AVR - http://supp.iar.com/Support/?note=45745 */
#if defined(__GNUC__) #if defined(__GNUC__)
/* bug in WinAVR - not quite IAR compatible */ /* bug in WinAVR - not quite IAR compatible */
#define __EEPUT _EEPUT #define __EEPUT _EEPUT
#define __EEGET _EEGET #define __EEGET _EEGET
#endif #endif
int eeprom_bytes_read( int eeprom_bytes_read(
uint16_t eeaddr, /* EEPROM starting memory address (offset of zero) */ uint16_t eeaddr, /* EEPROM starting memory address (offset of zero) */
uint8_t * buf, /* data to store */ uint8_t * buf, /* data to store */
int len) /* number of bytes of data to read */ int len)
{ { /* number of bytes of data to read */
int count = 0; /* return value */ int count = 0; /* return value */
while (len) { while (len) {
__EEGET(buf[count], eeaddr); __EEGET(buf[count], eeaddr);
count++; count++;
eeaddr++; eeaddr++;
len--; len--;
} }
return count; return count;
} }
int eeprom_bytes_write( int eeprom_bytes_write(
uint16_t eeaddr, /* EEPROM starting memory address */ uint16_t eeaddr, /* EEPROM starting memory address */
uint8_t * buf, /* data to send */ uint8_t * buf, /* data to send */
int len) /* number of bytes of data */ int len)
{ { /* number of bytes of data */
int count = 0; int count = 0;
while (len) { while (len) {
__EEPUT(eeaddr, buf[count]); __EEPUT(eeaddr, buf[count]);
count++; count++;
eeaddr++; eeaddr++;
len--; len--;
} }
return count; return count;
} }
+46 -46
View File
@@ -1,46 +1,46 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef EEPROM_H #ifndef EEPROM_H
#define EEPROM_H #define EEPROM_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int eeprom_bytes_read( int eeprom_bytes_read(
uint16_t ee_address, /* EEPROM starting memory address */ uint16_t ee_address, /* EEPROM starting memory address */
uint8_t * buffer, /* data to store */ uint8_t * buffer, /* data to store */
int nbytes); /* number of bytes of data to read */ int nbytes); /* number of bytes of data to read */
int eeprom_bytes_write( int eeprom_bytes_write(
uint16_t ee_address, /* EEPROM starting memory address */ uint16_t ee_address, /* EEPROM starting memory address */
uint8_t * buffer, /* data to send */ uint8_t * buffer, /* data to send */
int nbytes); /* number of bytes of data */ int nbytes); /* number of bytes of data */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+113 -113
View File
@@ -1,113 +1,113 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacerror.h" #include "bacerror.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
#include "reject.h" #include "reject.h"
#include "rd.h" #include "rd.h"
static char *Password = "rehmite"; static char *Password = "rehmite";
static BACNET_CHARACTER_STRING My_Password; static BACNET_CHARACTER_STRING My_Password;
void handler_reinitialize_device( void handler_reinitialize_device(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data) BACNET_CONFIRMED_SERVICE_DATA * service_data)
{ {
BACNET_REINITIALIZED_STATE state; BACNET_REINITIALIZED_STATE state;
BACNET_CHARACTER_STRING their_password; BACNET_CHARACTER_STRING their_password;
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
goto RD_ABORT; goto RD_ABORT;
} }
/* decode the service request only */ /* decode the service request only */
len = len =
rd_decode_service_request(service_request, service_len, &state, rd_decode_service_request(service_request, service_len, &state,
&their_password); &their_password);
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len < 0) { if (len < 0) {
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
goto RD_ABORT; goto RD_ABORT;
} }
/* check the data from the request */ /* check the data from the request */
if (state >= MAX_BACNET_REINITIALIZED_STATE) { if (state >= MAX_BACNET_REINITIALIZED_STATE) {
len = len =
reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION);
} else { } else {
characterstring_init_ansi(&My_Password, Password); characterstring_init_ansi(&My_Password, Password);
if (characterstring_same(&their_password, &My_Password)) { if (characterstring_same(&their_password, &My_Password)) {
len = len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_REINITIALIZE_DEVICE); SERVICE_CONFIRMED_REINITIALIZE_DEVICE);
/* FIXME: now you can reboot, restart, quit, or something clever */ /* FIXME: now you can reboot, restart, quit, or something clever */
/* Note: you can use a mix of state and password to do specific stuff */ /* Note: you can use a mix of state and password to do specific stuff */
/* Note: if you don't do something clever like actually restart, /* Note: if you don't do something clever like actually restart,
you probably should clear any DCC status and timeouts */ you probably should clear any DCC status and timeouts */
/* Note: you probably need to send the reply BEFORE restarting */ /* Note: you probably need to send the reply BEFORE restarting */
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE, service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE); ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE);
} }
} }
RD_ABORT: RD_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
return; return;
} }
+180 -180
View File
@@ -1,180 +1,180 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacerror.h" #include "bacerror.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
#include "rp.h" #include "rp.h"
/* demo objects */ /* demo objects */
#include "device.h" #include "device.h"
#include "ai.h" #include "ai.h"
#include "bi.h" #include "bi.h"
#include "bo.h" #include "bo.h"
static uint8_t Temp_Buf[MAX_APDU] = { 0 }; static uint8_t Temp_Buf[MAX_APDU] = { 0 };
/* Encodes the property APDU and returns the length, /* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */ or sets the error, and returns -1 */
int Encode_Property_APDU( int Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
int32_t array_index, int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = -1; int apdu_len = -1;
/* initialize the default return values */ /* initialize the default return values */
*error_class = ERROR_CLASS_OBJECT; *error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT; *error_code = ERROR_CODE_UNKNOWN_OBJECT;
/* handle each object type */ /* handle each object type */
switch (object_type) { switch (object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Valid_Object_Instance_Number(object_instance)) { if (Device_Valid_Object_Instance_Number(object_instance)) {
apdu_len = apdu_len =
Device_Encode_Property_APDU(&apdu[0], property, Device_Encode_Property_APDU(&apdu[0], property,
array_index, error_class, error_code); array_index, error_class, error_code);
} }
break; break;
case OBJECT_ANALOG_INPUT: case OBJECT_ANALOG_INPUT:
if (Analog_Input_Valid_Instance(object_instance)) { if (Analog_Input_Valid_Instance(object_instance)) {
apdu_len = apdu_len =
Analog_Input_Encode_Property_APDU(&apdu[0], Analog_Input_Encode_Property_APDU(&apdu[0],
object_instance, property, array_index, error_class, object_instance, property, array_index, error_class,
error_code); error_code);
} }
break; break;
case OBJECT_BINARY_INPUT: case OBJECT_BINARY_INPUT:
if (Binary_Input_Valid_Instance(object_instance)) { if (Binary_Input_Valid_Instance(object_instance)) {
apdu_len = apdu_len =
Binary_Input_Encode_Property_APDU(&apdu[0], Binary_Input_Encode_Property_APDU(&apdu[0],
object_instance, property, array_index, error_class, object_instance, property, array_index, error_class,
error_code); error_code);
} }
break; break;
case OBJECT_BINARY_OUTPUT: case OBJECT_BINARY_OUTPUT:
if (Binary_Output_Valid_Instance(object_instance)) { if (Binary_Output_Valid_Instance(object_instance)) {
apdu_len = apdu_len =
Binary_Output_Encode_Property_APDU(&apdu[0], Binary_Output_Encode_Property_APDU(&apdu[0],
object_instance, property, array_index, error_class, object_instance, property, array_index, error_class,
error_code); error_code);
} }
break; break;
default: default:
*error_class = ERROR_CLASS_OBJECT; *error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; *error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
break; break;
} }
return apdu_len; return apdu_len;
} }
void handler_read_property( void handler_read_property(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data) BACNET_CONFIRMED_SERVICE_DATA * service_data)
{ {
BACNET_READ_PROPERTY_DATA data; BACNET_READ_PROPERTY_DATA data;
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
bool error = false; bool error = false;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
goto RP_ABORT; goto RP_ABORT;
} }
len = rp_decode_service_request(service_request, service_len, &data); len = rp_decode_service_request(service_request, service_len, &data);
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
goto RP_ABORT; goto RP_ABORT;
} }
/* most cases will be error */ /* most cases will be error */
error = true; error = true;
len = len =
Encode_Property_APDU(&Temp_Buf[0], data.object_type, Encode_Property_APDU(&Temp_Buf[0], data.object_type,
data.object_instance, data.object_property, data.array_index, data.object_instance, data.object_property, data.array_index,
&error_class, &error_code); &error_class, &error_code);
if (len >= 0) { if (len >= 0) {
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0]; data.application_data = &Temp_Buf[0];
data.application_data_len = len; data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */ /* FIXME: probably need a length limitation sent with encode */
len = len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
error = false; error = false;
} }
if (error) { if (error) {
if (len == -2) { if (len == -2) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is Abort */
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RP_ABORT; goto RP_ABORT;
} }
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
error_class, error_code); error_class, error_code);
} }
RP_ABORT: RP_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
return; return;
} }
+134 -134
View File
@@ -1,134 +1,134 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacerror.h" #include "bacerror.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
#include "wp.h" #include "wp.h"
/* demo objects */ /* demo objects */
#include "device.h" #include "device.h"
#include "ai.h" #include "ai.h"
#include "bi.h" #include "bi.h"
#include "bo.h" #include "bo.h"
/* too big to reside on stack frame for PIC */ /* too big to reside on stack frame for PIC */
static BACNET_WRITE_PROPERTY_DATA wp_data; static BACNET_WRITE_PROPERTY_DATA wp_data;
void handler_write_property( void handler_write_property(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data) BACNET_CONFIRMED_SERVICE_DATA * service_data)
{ {
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
goto WP_ABORT; goto WP_ABORT;
} }
/* decode the service request only */ /* decode the service request only */
len = wp_decode_service_request(service_request, service_len, &wp_data); len = wp_decode_service_request(service_request, service_len, &wp_data);
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len <= 0) { if (len <= 0) {
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
goto WP_ABORT; goto WP_ABORT;
} }
/* handle the object type */ /* handle the object type */
switch (wp_data.object_type) { switch (wp_data.object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Write_Property(&wp_data, &error_class, &error_code)) { if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
len = len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code); error_class, error_code);
} }
break; break;
case OBJECT_ANALOG_INPUT: case OBJECT_ANALOG_INPUT:
case OBJECT_BINARY_INPUT: case OBJECT_BINARY_INPUT:
error_class = ERROR_CLASS_PROPERTY; error_class = ERROR_CLASS_PROPERTY;
error_code = ERROR_CODE_WRITE_ACCESS_DENIED; error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code); error_class, error_code);
break; break;
case OBJECT_BINARY_OUTPUT: case OBJECT_BINARY_OUTPUT:
if (Binary_Output_Write_Property(&wp_data, &error_class, if (Binary_Output_Write_Property(&wp_data, &error_class,
&error_code)) { &error_code)) {
len = len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code); error_class, error_code);
} }
break; break;
default: default:
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code); error_class, error_code);
break; break;
} }
WP_ABORT: WP_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
return; return;
} }
+55 -55
View File
@@ -1,55 +1,55 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef HARDWARE_H #ifndef HARDWARE_H
#define HARDWARE_H #define HARDWARE_H
#if !defined(F_CPU) #if !defined(F_CPU)
/* The processor clock frequency */ /* The processor clock frequency */
#define F_CPU 18430000UL #define F_CPU 18430000UL
#endif #endif
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#include <iom644p.h> #include <iom644p.h>
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#if !defined(__AVR_ATmega644P__) #if !defined(__AVR_ATmega644P__)
#error Firmware is configured for ATmega644P only (-mmcu=atmega644p) #error Firmware is configured for ATmega644P only (-mmcu=atmega644p)
#endif #endif
/* GCC specific configuration */ /* GCC specific configuration */
#include <avr/wdt.h> #include <avr/wdt.h>
#endif #endif
#include "iar2gcc.h" #include "iar2gcc.h"
#include "bits.h" #include "bits.h"
/* SEEPROM is 24LC128 */ /* SEEPROM is 24LC128 */
//#define SEEPROM_PAGE_SIZE 128 /*#define SEEPROM_PAGE_SIZE 128 */
//#define SEEPROM_WORD_ADDRESS_16BIT 1 /*#define SEEPROM_WORD_ADDRESS_16BIT 1 */
/* SEEPROM is 24C16 */ /* SEEPROM is 24C16 */
#define SEEPROM_PAGE_SIZE 16 #define SEEPROM_PAGE_SIZE 16
#define SEEPROM_WORD_ADDRESS_16BIT 0 #define SEEPROM_WORD_ADDRESS_16BIT 0
#endif #endif
+239 -239
View File
@@ -1,239 +1,239 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2007 Steve Karg Copyright (C) 2007 Steve Karg
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef IAR2GCC_H #ifndef IAR2GCC_H
#define IAR2GCC_H #define IAR2GCC_H
#if !defined(F_CPU) #if !defined(F_CPU)
#define F_CPU (7372800) #define F_CPU (7372800)
#endif #endif
/* IAR */ /* IAR */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#include <inavr.h> #include <inavr.h>
#include <stdint.h> #include <stdint.h>
/* inline function */ /* inline function */
static inline void _delay_us( static inline void _delay_us(
uint8_t microseconds) uint8_t microseconds)
{ {
do { do {
__delay_cycles(F_CPU / 1000000UL); __delay_cycles(F_CPU / 1000000UL);
} while (microseconds--); } while (microseconds--);
} }
#endif #endif
/* Input/Output Registers */ /* Input/Output Registers */
#if defined(__GNUC__) #if defined(__GNUC__)
#include <avr/io.h> #include <avr/io.h>
typedef struct { typedef struct {
unsigned char bit0:1; unsigned char bit0:1;
unsigned char bit1:1; unsigned char bit1:1;
unsigned char bit2:1; unsigned char bit2:1;
unsigned char bit3:1; unsigned char bit3:1;
unsigned char bit4:1; unsigned char bit4:1;
unsigned char bit5:1; unsigned char bit5:1;
unsigned char bit6:1; unsigned char bit6:1;
unsigned char bit7:1; unsigned char bit7:1;
} BitRegisterType; } BitRegisterType;
#ifndef true #ifndef true
#define true 1 #define true 1
#endif #endif
#ifndef false #ifndef false
#define false 0 #define false 0
#endif #endif
#define GPIO_BITREG(port,bitnum) \ #define GPIO_BITREG(port,bitnum) \
((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \ ((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \
)->bit ## bitnum )->bit ## bitnum
#define PINA_Bit0 GPIO_BITREG(PINA,0) #define PINA_Bit0 GPIO_BITREG(PINA,0)
#define PINA_Bit1 GPIO_BITREG(PINA,1) #define PINA_Bit1 GPIO_BITREG(PINA,1)
#define PINA_Bit2 GPIO_BITREG(PINA,2) #define PINA_Bit2 GPIO_BITREG(PINA,2)
#define PINA_Bit3 GPIO_BITREG(PINA,3) #define PINA_Bit3 GPIO_BITREG(PINA,3)
#define PINA_Bit4 GPIO_BITREG(PINA,4) #define PINA_Bit4 GPIO_BITREG(PINA,4)
#define PINA_Bit5 GPIO_BITREG(PINA,5) #define PINA_Bit5 GPIO_BITREG(PINA,5)
#define PINA_Bit6 GPIO_BITREG(PINA,6) #define PINA_Bit6 GPIO_BITREG(PINA,6)
#define PINA_Bit7 GPIO_BITREG(PINA,7) #define PINA_Bit7 GPIO_BITREG(PINA,7)
#define PORTA_Bit0 GPIO_BITREG(PORTA,0) #define PORTA_Bit0 GPIO_BITREG(PORTA,0)
#define PORTA_Bit1 GPIO_BITREG(PORTA,1) #define PORTA_Bit1 GPIO_BITREG(PORTA,1)
#define PORTA_Bit2 GPIO_BITREG(PORTA,2) #define PORTA_Bit2 GPIO_BITREG(PORTA,2)
#define PORTA_Bit3 GPIO_BITREG(PORTA,3) #define PORTA_Bit3 GPIO_BITREG(PORTA,3)
#define PORTA_Bit4 GPIO_BITREG(PORTA,4) #define PORTA_Bit4 GPIO_BITREG(PORTA,4)
#define PORTA_Bit5 GPIO_BITREG(PORTA,5) #define PORTA_Bit5 GPIO_BITREG(PORTA,5)
#define PORTA_Bit6 GPIO_BITREG(PORTA,6) #define PORTA_Bit6 GPIO_BITREG(PORTA,6)
#define PORTA_Bit7 GPIO_BITREG(PORTA,7) #define PORTA_Bit7 GPIO_BITREG(PORTA,7)
#define PINB_Bit0 GPIO_BITREG(PINB,0) #define PINB_Bit0 GPIO_BITREG(PINB,0)
#define PINB_Bit1 GPIO_BITREG(PINB,1) #define PINB_Bit1 GPIO_BITREG(PINB,1)
#define PINB_Bit2 GPIO_BITREG(PINB,2) #define PINB_Bit2 GPIO_BITREG(PINB,2)
#define PINB_Bit3 GPIO_BITREG(PINB,3) #define PINB_Bit3 GPIO_BITREG(PINB,3)
#define PINB_Bit4 GPIO_BITREG(PINB,4) #define PINB_Bit4 GPIO_BITREG(PINB,4)
#define PINB_Bit5 GPIO_BITREG(PINB,5) #define PINB_Bit5 GPIO_BITREG(PINB,5)
#define PINB_Bit6 GPIO_BITREG(PINB,6) #define PINB_Bit6 GPIO_BITREG(PINB,6)
#define PINB_Bit7 GPIO_BITREG(PINB,7) #define PINB_Bit7 GPIO_BITREG(PINB,7)
#define PORTB_Bit0 GPIO_BITREG(PORTB,0) #define PORTB_Bit0 GPIO_BITREG(PORTB,0)
#define PORTB_Bit1 GPIO_BITREG(PORTB,1) #define PORTB_Bit1 GPIO_BITREG(PORTB,1)
#define PORTB_Bit2 GPIO_BITREG(PORTB,2) #define PORTB_Bit2 GPIO_BITREG(PORTB,2)
#define PORTB_Bit3 GPIO_BITREG(PORTB,3) #define PORTB_Bit3 GPIO_BITREG(PORTB,3)
#define PORTB_Bit4 GPIO_BITREG(PORTB,4) #define PORTB_Bit4 GPIO_BITREG(PORTB,4)
#define PORTB_Bit5 GPIO_BITREG(PORTB,5) #define PORTB_Bit5 GPIO_BITREG(PORTB,5)
#define PORTB_Bit6 GPIO_BITREG(PORTB,6) #define PORTB_Bit6 GPIO_BITREG(PORTB,6)
#define PORTB_Bit7 GPIO_BITREG(PORTB,7) #define PORTB_Bit7 GPIO_BITREG(PORTB,7)
#define PINC_Bit0 GPIO_BITREG(PINC,0) #define PINC_Bit0 GPIO_BITREG(PINC,0)
#define PINC_Bit1 GPIO_BITREG(PINC,1) #define PINC_Bit1 GPIO_BITREG(PINC,1)
#define PINC_Bit2 GPIO_BITREG(PINC,2) #define PINC_Bit2 GPIO_BITREG(PINC,2)
#define PINC_Bit3 GPIO_BITREG(PINC,3) #define PINC_Bit3 GPIO_BITREG(PINC,3)
#define PINC_Bit4 GPIO_BITREG(PINC,4) #define PINC_Bit4 GPIO_BITREG(PINC,4)
#define PINC_Bit5 GPIO_BITREG(PINC,5) #define PINC_Bit5 GPIO_BITREG(PINC,5)
#define PINC_Bit6 GPIO_BITREG(PINC,6) #define PINC_Bit6 GPIO_BITREG(PINC,6)
#define PINC_Bit7 GPIO_BITREG(PINC,7) #define PINC_Bit7 GPIO_BITREG(PINC,7)
#define PORTC_Bit0 GPIO_BITREG(PORTC,0) #define PORTC_Bit0 GPIO_BITREG(PORTC,0)
#define PORTC_Bit1 GPIO_BITREG(PORTC,1) #define PORTC_Bit1 GPIO_BITREG(PORTC,1)
#define PORTC_Bit2 GPIO_BITREG(PORTC,2) #define PORTC_Bit2 GPIO_BITREG(PORTC,2)
#define PORTC_Bit3 GPIO_BITREG(PORTC,3) #define PORTC_Bit3 GPIO_BITREG(PORTC,3)
#define PORTC_Bit4 GPIO_BITREG(PORTC,4) #define PORTC_Bit4 GPIO_BITREG(PORTC,4)
#define PORTC_Bit5 GPIO_BITREG(PORTC,5) #define PORTC_Bit5 GPIO_BITREG(PORTC,5)
#define PORTC_Bit6 GPIO_BITREG(PORTC,6) #define PORTC_Bit6 GPIO_BITREG(PORTC,6)
#define PORTC_Bit7 GPIO_BITREG(PORTC,7) #define PORTC_Bit7 GPIO_BITREG(PORTC,7)
#define PIND_Bit0 GPIO_BITREG(PIND,0) #define PIND_Bit0 GPIO_BITREG(PIND,0)
#define PIND_Bit1 GPIO_BITREG(PIND,1) #define PIND_Bit1 GPIO_BITREG(PIND,1)
#define PIND_Bit2 GPIO_BITREG(PIND,2) #define PIND_Bit2 GPIO_BITREG(PIND,2)
#define PIND_Bit3 GPIO_BITREG(PIND,3) #define PIND_Bit3 GPIO_BITREG(PIND,3)
#define PIND_Bit4 GPIO_BITREG(PIND,4) #define PIND_Bit4 GPIO_BITREG(PIND,4)
#define PIND_Bit5 GPIO_BITREG(PIND,5) #define PIND_Bit5 GPIO_BITREG(PIND,5)
#define PIND_Bit6 GPIO_BITREG(PIND,6) #define PIND_Bit6 GPIO_BITREG(PIND,6)
#define PIND_Bit7 GPIO_BITREG(PIND,7) #define PIND_Bit7 GPIO_BITREG(PIND,7)
#define PORTD_Bit0 GPIO_BITREG(PORTD,0) #define PORTD_Bit0 GPIO_BITREG(PORTD,0)
#define PORTD_Bit1 GPIO_BITREG(PORTD,1) #define PORTD_Bit1 GPIO_BITREG(PORTD,1)
#define PORTD_Bit2 GPIO_BITREG(PORTD,2) #define PORTD_Bit2 GPIO_BITREG(PORTD,2)
#define PORTD_Bit3 GPIO_BITREG(PORTD,3) #define PORTD_Bit3 GPIO_BITREG(PORTD,3)
#define PORTD_Bit4 GPIO_BITREG(PORTD,4) #define PORTD_Bit4 GPIO_BITREG(PORTD,4)
#define PORTD_Bit5 GPIO_BITREG(PORTD,5) #define PORTD_Bit5 GPIO_BITREG(PORTD,5)
#define PORTD_Bit6 GPIO_BITREG(PORTD,6) #define PORTD_Bit6 GPIO_BITREG(PORTD,6)
#define PORTD_Bit7 GPIO_BITREG(PORTD,7) #define PORTD_Bit7 GPIO_BITREG(PORTD,7)
#define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0) #define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0)
#define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1) #define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1)
#define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2) #define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2)
#define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3) #define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3)
#define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4) #define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4)
#define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5) #define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5)
#define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6) #define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6)
#define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7) #define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7)
#define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0) #define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0)
#define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1) #define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1)
#define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2) #define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2)
#define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3) #define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3)
#define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4) #define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4)
#define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5) #define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5)
#define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6) #define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6)
#define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7) #define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7)
#define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0) #define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0)
#define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1) #define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1)
#define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2) #define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2)
#define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3) #define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3)
#define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4) #define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4)
#define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5) #define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5)
#define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6) #define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6)
#define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7) #define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7)
#endif #endif
/* Global Interrupts */ /* Global Interrupts */
#if defined(__GNUC__) #if defined(__GNUC__)
#define __enable_interrupt() sei() #define __enable_interrupt() sei()
#define __disable_interrupt() cli() #define __disable_interrupt() cli()
#endif #endif
/* Interrupts */ /* Interrupts */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#define PRAGMA(x) _Pragma( #x ) #define PRAGMA(x) _Pragma( #x )
#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void) #define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void)
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#include <avr/interrupt.h> #include <avr/interrupt.h>
#endif #endif
/* Flash */ /* Flash */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#define FLASH_DECLARE(x) __flash x #define FLASH_DECLARE(x) __flash x
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#define FLASH_DECLARE(x) x __attribute__((__progmem__)) #define FLASH_DECLARE(x) x __attribute__((__progmem__))
#endif #endif
/* EEPROM */ /* EEPROM */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#define EEPROM_DECLARE(x) __eeprom x #define EEPROM_DECLARE(x) __eeprom x
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#include <avr/eeprom.h> #include <avr/eeprom.h>
#define EEPROM_DECLARE(x) x __attribute__((section (".eeprom"))) #define EEPROM_DECLARE(x) x __attribute__((section (".eeprom")))
#endif #endif
/* IAR intrinsic routines */ /* IAR intrinsic routines */
#if defined(__GNUC__) #if defined(__GNUC__)
/* FIXME: intrinsic routines: map to assembler for size/speed */ /* FIXME: intrinsic routines: map to assembler for size/speed */
#define __multiply_unsigned(x,y) ((x)*(y)) #define __multiply_unsigned(x,y) ((x)*(y))
/* FIXME: __root means to not optimize or strip */ /* FIXME: __root means to not optimize or strip */
#define __root #define __root
#endif #endif
/* watchdog */ /* watchdog */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#include <intrinsics.h> #include <intrinsics.h>
#define watchdog_reset __watchdog_reset #define watchdog_reset __watchdog_reset
#define WDTO_15MS 0 #define WDTO_15MS 0
#define WDTO_30MS 1 #define WDTO_30MS 1
#define WDTO_60MS 2 #define WDTO_60MS 2
#define WDTO_120MS 3 #define WDTO_120MS 3
#define WDTO_250MS 4 #define WDTO_250MS 4
#define WDTO_500MS 5 #define WDTO_500MS 5
#define WDTO_1S 6 #define WDTO_1S 6
#define WDTO_2S 7 #define WDTO_2S 7
#endif #endif
#endif #endif
+63 -63
View File
@@ -1,63 +1,63 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include "hardware.h" #include "hardware.h"
void init( void init(
void) void)
{ {
/* Initialize the Clock Prescaler for ATmega48/88/168 */ /* Initialize the Clock Prescaler for ATmega48/88/168 */
/* The default CLKPSx bits are factory set to 0011 */ /* The default CLKPSx bits are factory set to 0011 */
/* Enbable the Clock Prescaler */ /* Enbable the Clock Prescaler */
CLKPR = _BV(CLKPCE); CLKPR = _BV(CLKPCE);
/* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor /* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor
------ ------ ------ ------ --------------------- ------ ------ ------ ------ ---------------------
0 0 0 0 1 0 0 0 0 1
0 0 0 1 2 0 0 0 1 2
0 0 1 0 4 0 0 1 0 4
0 0 1 1 8 0 0 1 1 8
0 1 0 0 16 0 1 0 0 16
0 1 0 1 32 0 1 0 1 32
0 1 1 0 64 0 1 1 0 64
0 1 1 1 128 0 1 1 1 128
1 0 0 0 256 1 0 0 0 256
1 x x x Reserved 1 x x x Reserved
*/ */
/* Set the CLKPS3..0 bits to Prescaler of 1 */ /* Set the CLKPS3..0 bits to Prescaler of 1 */
CLKPR = 0; CLKPR = 0;
/* Initialize I/O ports */ /* Initialize I/O ports */
/* For Port DDRx (Data Direction) Input=0, Output=1 */ /* For Port DDRx (Data Direction) Input=0, Output=1 */
/* For Port PORTx (Bit Value) TriState=0, High=1 */ /* For Port PORTx (Bit Value) TriState=0, High=1 */
DDRA = 0; DDRA = 0;
PORTA = 0; PORTA = 0;
DDRB = 0; DDRB = 0;
PORTB = 0; PORTB = 0;
DDRC = 0; DDRC = 0;
PORTC = 0; PORTC = 0;
DDRD = 0; DDRD = 0;
PORTD = 0; PORTD = 0;
/* Configure the watchdog timer - Disabled for testing */ /* Configure the watchdog timer - Disabled for testing */
BIT_CLEAR(MCUSR, WDRF); BIT_CLEAR(MCUSR, WDRF);
WDTCSR = 0; WDTCSR = 0;
} }
+39 -39
View File
@@ -1,39 +1,39 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef INIT_H #ifndef INIT_H
#define INIT_H #define INIT_H
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void init(void); void init(
void);
#ifdef __cplusplus
} #ifdef __cplusplus
#endif /* __cplusplus */ }
#endif /* __cplusplus */
#endif #endif
+59 -62
View File
@@ -1,62 +1,59 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include "hardware.h" #include "hardware.h"
static uint8_t Address_Switch; static uint8_t Address_Switch;
void input_task( void input_task(
void) void)
{ {
uint8_t value; uint8_t value;
static uint8_t old_value = 0; static uint8_t old_value = 0;
value = BITMASK_CHECK(PINA, 0x7F); value = BITMASK_CHECK(PINA, 0x7F);
if (value != old_value) { if (value != old_value) {
old_value = value; old_value = value;
} else { } else {
if (old_value != Address_Switch) { if (old_value != Address_Switch) {
Address_Switch = old_value; Address_Switch = old_value;
} }
} }
} }
uint8_t input_address(void) uint8_t input_address(
{ void)
return Address_Switch; {
} return Address_Switch;
}
void input_init(void)
{ void input_init(
/* configure the port pins */ void)
BITMASK_CLEAR(DDRA, {
_BV(DDA0) | /* configure the port pins */
_BV(DDA1) | BITMASK_CLEAR(DDRA,
_BV(DDA2) | _BV(DDA0) | _BV(DDA1) | _BV(DDA2) | _BV(DDA3) | _BV(DDA4) | _BV(DDA5) |
_BV(DDA3) | _BV(DDA6)
_BV(DDA4) | );
_BV(DDA5) | }
_BV(DDA6)
);
}
+43 -41
View File
@@ -1,41 +1,43 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef INPUT_H #ifndef INPUT_H
#define INPUT_H #define INPUT_H
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void input_init(void); void input_init(
void input_task(void); void);
uint8_t input_address(void); void input_task(
void);
#ifdef __cplusplus uint8_t input_address(
} void);
#endif /* __cplusplus */
#ifdef __cplusplus
#endif }
#endif /* __cplusplus */
#endif
+211 -211
View File
@@ -1,211 +1,211 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
#include "led.h" #include "led.h"
static uint32_t Off_Delay_Milliseconds_1; static uint32_t Off_Delay_Milliseconds_1;
static uint32_t Off_Delay_Milliseconds_2; static uint32_t Off_Delay_Milliseconds_2;
static uint32_t Off_Delay_Milliseconds_3; static uint32_t Off_Delay_Milliseconds_3;
static uint32_t Off_Delay_Milliseconds_4; static uint32_t Off_Delay_Milliseconds_4;
/************************************************************************* /*************************************************************************
* Description: Turn on an LED * Description: Turn on an LED
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_on(uint8_t index) void led_on(
{ uint8_t index)
switch (index) { {
case LED_1: switch (index) {
BIT_SET(PORTD, PD7); case LED_1:
break; BIT_SET(PORTD, PD7);
case LED_2: break;
BIT_SET(PORTD, PD6); case LED_2:
break; BIT_SET(PORTD, PD6);
case LED_3: break;
BIT_SET(PORTC, PC7); case LED_3:
break; BIT_SET(PORTC, PC7);
case LED_4: break;
BIT_SET(PORTC, PC6); case LED_4:
break; BIT_SET(PORTC, PC6);
default: break;
break; default:
} break;
} }
}
/*************************************************************************
* Description: Turn off an LED /*************************************************************************
* Returns: none * Description: Turn off an LED
* Notes: none * Returns: none
*************************************************************************/ * Notes: none
void led_off(uint8_t index) *************************************************************************/
{ void led_off(
switch (index) { uint8_t index)
case LED_1: {
BIT_CLEAR(PORTD, PD7); switch (index) {
break; case LED_1:
case LED_2: BIT_CLEAR(PORTD, PD7);
BIT_CLEAR(PORTD, PD6); break;
break; case LED_2:
case LED_3: BIT_CLEAR(PORTD, PD6);
BIT_CLEAR(PORTC, PC7); break;
break; case LED_3:
case LED_4: BIT_CLEAR(PORTC, PC7);
BIT_CLEAR(PORTC, PC6); break;
break; case LED_4:
default: BIT_CLEAR(PORTC, PC6);
break; break;
} default:
} break;
}
/************************************************************************* }
* Description: Get the state of the LED
* Returns: true if on, false if off. /*************************************************************************
* Notes: none * Description: Get the state of the LED
*************************************************************************/ * Returns: true if on, false if off.
bool led_state(uint8_t index) * Notes: none
{ *************************************************************************/
switch (index) { bool led_state(
case LED_1: uint8_t index)
return (BIT_CHECK(PIND, PD7)); {
break; switch (index) {
case LED_2: case LED_1:
return (BIT_CHECK(PIND, PD6)); return (BIT_CHECK(PIND, PD7));
break; break;
case LED_3: case LED_2:
return (BIT_CHECK(PINC, PC7)); return (BIT_CHECK(PIND, PD6));
break; break;
case LED_4: case LED_3:
return (BIT_CHECK(PINC, PC6)); return (BIT_CHECK(PINC, PC7));
break; break;
default: case LED_4:
break; return (BIT_CHECK(PINC, PC6));
} break;
default:
return false; break;
} }
/************************************************************************* return false;
* Description: Toggle the state of the setup LED }
* Returns: none
* Notes: none /*************************************************************************
*************************************************************************/ * Description: Toggle the state of the setup LED
void led_toggle(uint8_t index) * Returns: none
{ * Notes: none
if (led_state(index)) { *************************************************************************/
led_off(index); void led_toggle(
} else { uint8_t index)
led_on(index); {
} if (led_state(index)) {
} led_off(index);
} else {
/************************************************************************* led_on(index);
* Description: Delay before going off to give minimum brightness. }
* Returns: none }
* Notes: none
*************************************************************************/ /*************************************************************************
void led_off_delay(uint8_t index, uint32_t delay_ms) * Description: Delay before going off to give minimum brightness.
{ * Returns: none
switch (index) { * Notes: none
case LED_1: *************************************************************************/
Off_Delay_Milliseconds_1 = delay_ms; void led_off_delay(
timer_reset(TIMER_LED_1); uint8_t index,
break; uint32_t delay_ms)
case LED_2: {
Off_Delay_Milliseconds_2 = delay_ms; switch (index) {
timer_reset(TIMER_LED_2); case LED_1:
break; Off_Delay_Milliseconds_1 = delay_ms;
case LED_3: timer_reset(TIMER_LED_1);
Off_Delay_Milliseconds_3 = delay_ms; break;
timer_reset(TIMER_LED_3); case LED_2:
break; Off_Delay_Milliseconds_2 = delay_ms;
case LED_4: timer_reset(TIMER_LED_2);
Off_Delay_Milliseconds_4 = delay_ms; break;
timer_reset(TIMER_LED_4); case LED_3:
break; Off_Delay_Milliseconds_3 = delay_ms;
default: timer_reset(TIMER_LED_3);
break; break;
} case LED_4:
} Off_Delay_Milliseconds_4 = delay_ms;
timer_reset(TIMER_LED_4);
/************************************************************************* break;
* Description: Task for blinking LED default:
* Returns: none break;
* Notes: none }
*************************************************************************/ }
void led_task(void)
{ /*************************************************************************
if (Off_Delay_Milliseconds_1) { * Description: Task for blinking LED
if (timer_elapsed_milliseconds( * Returns: none
TIMER_LED_1, * Notes: none
Off_Delay_Milliseconds_1)) { *************************************************************************/
Off_Delay_Milliseconds_1 = 0; void led_task(
led_off(LED_1); void)
} {
} if (Off_Delay_Milliseconds_1) {
if (Off_Delay_Milliseconds_2) { if (timer_elapsed_milliseconds(TIMER_LED_1, Off_Delay_Milliseconds_1)) {
if (timer_elapsed_milliseconds( Off_Delay_Milliseconds_1 = 0;
TIMER_LED_2, led_off(LED_1);
Off_Delay_Milliseconds_2)) { }
Off_Delay_Milliseconds_2 = 0; }
led_off(LED_2); if (Off_Delay_Milliseconds_2) {
} if (timer_elapsed_milliseconds(TIMER_LED_2, Off_Delay_Milliseconds_2)) {
} Off_Delay_Milliseconds_2 = 0;
if (Off_Delay_Milliseconds_3) { led_off(LED_2);
if (timer_elapsed_milliseconds( }
TIMER_LED_3, }
Off_Delay_Milliseconds_3)) { if (Off_Delay_Milliseconds_3) {
Off_Delay_Milliseconds_3 = 0; if (timer_elapsed_milliseconds(TIMER_LED_3, Off_Delay_Milliseconds_3)) {
led_off(LED_3); Off_Delay_Milliseconds_3 = 0;
} led_off(LED_3);
} }
if (Off_Delay_Milliseconds_4) { }
if (timer_elapsed_milliseconds( if (Off_Delay_Milliseconds_4) {
TIMER_LED_4, if (timer_elapsed_milliseconds(TIMER_LED_4, Off_Delay_Milliseconds_4)) {
Off_Delay_Milliseconds_4)) { Off_Delay_Milliseconds_4 = 0;
Off_Delay_Milliseconds_4 = 0; led_off(LED_4);
led_off(LED_4); }
} }
} }
}
/*************************************************************************
/************************************************************************* * Description: Initialize the LED hardware
* Description: Initialize the LED hardware * Returns: none
* Returns: none * Notes: none
* Notes: none *************************************************************************/
*************************************************************************/ void led_init(
void led_init(void) void)
{ {
/* configure the port pins as outputs */ /* configure the port pins as outputs */
BIT_SET(DDRC, DDC7); BIT_SET(DDRC, DDC7);
BIT_SET(DDRC, DDC6); BIT_SET(DDRC, DDC6);
BIT_SET(DDRD, DDD7); BIT_SET(DDRD, DDD7);
BIT_SET(DDRD, DDD6); BIT_SET(DDRD, DDD6);
led_off(LED_1); led_off(LED_1);
led_off(LED_2); led_off(LED_2);
led_off(LED_3); led_off(LED_3);
led_off(LED_4); led_off(LED_4);
} }
+59 -52
View File
@@ -1,52 +1,59 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef LED_H #ifndef LED_H
#define LED_H #define LED_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#define LED_1 0 #define LED_1 0
#define LED_2 1 #define LED_2 1
#define LED_3 2 #define LED_3 2
#define LED_4 3 #define LED_4 3
#define MAX_LEDS 4 #define MAX_LEDS 4
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void led_on(uint8_t index); void led_on(
void led_off(uint8_t index); uint8_t index);
void led_off_delay(uint8_t index, uint32_t delay_ms); void led_off(
void led_toggle(uint8_t index); uint8_t index);
bool led_state(uint8_t index); void led_off_delay(
void led_task(void); uint8_t index,
void led_init(void); uint32_t delay_ms);
void led_toggle(
#ifdef __cplusplus uint8_t index);
} bool led_state(
#endif /* __cplusplus */ uint8_t index);
void led_task(
#endif void);
void led_init(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+217 -222
View File
@@ -1,222 +1,217 @@
/************************************************************************ /************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*************************************************************************/ *************************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "init.h" #include "init.h"
#include "stack.h" #include "stack.h"
#include "timer.h" #include "timer.h"
#include "input.h" #include "input.h"
#include "led.h" #include "led.h"
#include "nvdata.h" #include "nvdata.h"
#include "timer.h" #include "timer.h"
#include "dcc.h" #include "dcc.h"
#include "rs485.h" #include "rs485.h"
#include "serial.h" #include "serial.h"
#include "datalink.h" #include "datalink.h"
#include "npdu.h" #include "npdu.h"
#include "handlers.h" #include "handlers.h"
#include "client.h" #include "client.h"
#include "txbuf.h" #include "txbuf.h"
#include "iam.h" #include "iam.h"
#include "device.h" #include "device.h"
#include "ai.h" #include "ai.h"
#include "bi.h" #include "bi.h"
#include "bo.h" #include "bo.h"
/* local version override */ /* local version override */
const char *BACnet_Version = "1.0"; const char *BACnet_Version = "1.0";
/* MAC Address of MS/TP */ /* MAC Address of MS/TP */
static uint8_t MSTP_MAC_Address; static uint8_t MSTP_MAC_Address;
/* For porting to IAR, see: /* For porting to IAR, see:
http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/
#if defined(__GNUC__) && (__GNUC__ > 4) #if defined(__GNUC__) && (__GNUC__ > 4)
/* AVR fuse settings */ /* AVR fuse settings */
FUSES = FUSES = {
{ /* External Ceramic Resonator - configuration */
/* External Ceramic Resonator - configuration */ /* Full Swing Crystal Oscillator Clock Selection */
/* Full Swing Crystal Oscillator Clock Selection */ /* Ceramic resonator, slowly rising power 1K CK 14CK + 65 ms */
/* Ceramic resonator, slowly rising power 1K CK 14CK + 65 ms */ /* note: fuses are enabled by clearing the bit, so
/* note: fuses are enabled by clearing the bit, so any fuses listed below are cleared fuses. */
any fuses listed below are cleared fuses. */ .low = (FUSE_CKSEL3 & FUSE_SUT0 & FUSE_SUT1),
.low = (FUSE_CKSEL3 & /* BOOTSZ configuration:
FUSE_SUT0 & BOOTSZ1 BOOTSZ0 Boot Size
FUSE_SUT1), ------- ------- ---------
1 1 512
/* BOOTSZ configuration: 1 0 1024
BOOTSZ1 BOOTSZ0 Boot Size 0 1 2048
------- ------- --------- 0 0 4096
1 1 512 */
1 0 1024 /* note: fuses are enabled by clearing the bit, so
0 1 2048 any fuses listed below are cleared fuses. */
0 0 4096 .high =
*/ (FUSE_BOOTSZ1 & FUSE_BOOTRST & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN),
/* note: fuses are enabled by clearing the bit, so /* Brown-out detection VCC=2.7V */
any fuses listed below are cleared fuses. */ /* BODLEVEL configuration
.high = ( BODLEVEL2 BODLEVEL1 BODLEVEL0 Voltage
FUSE_BOOTSZ1 & --------- --------- --------- --------
FUSE_BOOTRST & 1 1 1 disabled
FUSE_EESAVE & 1 1 0 1.8V
FUSE_SPIEN & 1 0 1 2.7V
FUSE_JTAGEN), 1 0 0 4.3V
*/
/* Brown-out detection VCC=2.7V */ /* note: fuses are enabled by clearing the bit, so
/* BODLEVEL configuration any fuses listed below are cleared fuses. */
BODLEVEL2 BODLEVEL1 BODLEVEL0 Voltage .extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0),};
--------- --------- --------- --------
1 1 1 disabled /* AVR lock bits - unlocked */
1 1 0 1.8V LOCKBITS = LOCKBITS_DEFAULT;
1 0 1 2.7V #endif
1 0 0 4.3V
*/ bool seeprom_version_test(
/* note: fuses are enabled by clearing the bit, so void)
any fuses listed below are cleared fuses. */ {
.extended = (FUSE_BODLEVEL1 & FUSE_BODLEVEL0), uint16_t version = 0;
}; uint16_t id = 0;
/* AVR lock bits - unlocked */ bool status = false;
LOCKBITS = LOCKBITS_DEFAULT;
#endif seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *) & id, 2);
seeprom_bytes_read(NV_SEEPROM_VERSION_0, (uint8_t *) & version, 2);
bool seeprom_version_test(void)
{ if ((id == SEEPROM_ID) && (version == SEEPROM_VERSION)) {
uint16_t version = 0; status = true;
uint16_t id = 0; } else {
bool status = false; version = SEEPROM_VERSION;
id = SEEPROM_ID;
seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2); seeprom_bytes_write(NV_SEEPROM_TYPE_0, (uint8_t *) & id, 2);
seeprom_bytes_read(NV_SEEPROM_VERSION_0, (uint8_t *)&version, 2); seeprom_bytes_write(NV_SEEPROM_VERSION_0, (uint8_t *) & version, 2);
}
if ((id == SEEPROM_ID) && (version == SEEPROM_VERSION)) {
status = true; return status;
} else { }
version = SEEPROM_VERSION;
id = SEEPROM_ID; static void bacnet_init(
seeprom_bytes_write(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2); void)
seeprom_bytes_write(NV_SEEPROM_VERSION_0, (uint8_t *)&version, 2); {
} MSTP_MAC_Address = input_address();
dlmstp_set_mac_address(MSTP_MAC_Address);
return status; dlmstp_init(NULL);
}
if (!seeprom_version_test()) {
static void bacnet_init( /* invalid version data */
void) }
{ /* initialize objects */
MSTP_MAC_Address = input_address(); Device_Init();
dlmstp_set_mac_address(MSTP_MAC_Address); Binary_Output_Init();
dlmstp_init(NULL);
/* we need to handle who-is to support dynamic device binding */
if (!seeprom_version_test()) { apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* invalid version data */ /* Set the handlers for any confirmed services that we support. */
} /* We must implement read property - it's required! */
/* initialize objects */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
Device_Init(); handler_read_property);
Binary_Output_Init(); apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple);
/* we need to handle who-is to support dynamic device binding */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); handler_reinitialize_device);
/* Set the handlers for any confirmed services that we support. */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
/* We must implement read property - it's required! */ handler_write_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, /* handle communication so we can shutup when asked */
handler_read_property); apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_device_communication_control);
handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, Send_I_Am(&Handler_Transmit_Buffer[0]);
handler_reinitialize_device); }
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property); static uint8_t PDUBuffer[MAX_MPDU];
/* handle communication so we can shutup when asked */ static void bacnet_task(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, void)
handler_device_communication_control); {
uint8_t mstp_mac_address = 0;
Send_I_Am(&Handler_Transmit_Buffer[0]); uint16_t pdu_len = 0;
} BACNET_ADDRESS src; /* source address */
static uint8_t PDUBuffer[MAX_MPDU]; mstp_mac_address = input_address();
static void bacnet_task(void) if (MSTP_MAC_Address != mstp_mac_address) {
{ MSTP_MAC_Address = mstp_mac_address;
uint8_t mstp_mac_address = 0; dlmstp_set_mac_address(MSTP_MAC_Address);
uint16_t pdu_len = 0; Send_I_Am(&Handler_Transmit_Buffer[0]);
BACNET_ADDRESS src; /* source address */ }
if (timer_elapsed_seconds(TIMER_DCC, 1)) {
mstp_mac_address = input_address(); dcc_timer_seconds(1);
if (MSTP_MAC_Address != mstp_mac_address) { }
MSTP_MAC_Address = mstp_mac_address; pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0);
dlmstp_set_mac_address(MSTP_MAC_Address); if (pdu_len) {
Send_I_Am(&Handler_Transmit_Buffer[0]); npdu_handler(&src, &PDUBuffer[0], pdu_len);
} }
if (timer_elapsed_seconds(TIMER_DCC, 1)) { }
dcc_timer_seconds(1);
} void idle_init(
pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); void)
if (pdu_len) { {
npdu_handler(&src, &PDUBuffer[0], pdu_len); timer_reset(TIMER_LED_3);
} timer_reset(TIMER_LED_4);
} }
void idle_init(void) void idle_task(
{ void)
timer_reset(TIMER_LED_3); {
timer_reset(TIMER_LED_4); #if 0
} /* blink the leds */
if (timer_elapsed_seconds(TIMER_LED_3, 1)) {
void idle_task(void) timer_reset(TIMER_LED_3);
{ led_toggle(LED_3);
#if 0 }
/* blink the leds */ if (timer_elapsed_milliseconds(TIMER_LED_4, 125)) {
if (timer_elapsed_seconds(TIMER_LED_3, 1)) { timer_reset(TIMER_LED_4);
timer_reset(TIMER_LED_3); led_toggle(LED_4);
led_toggle(LED_3); }
} #endif
if (timer_elapsed_milliseconds(TIMER_LED_4, 125)) { }
timer_reset(TIMER_LED_4);
led_toggle(LED_4); int main(
} void)
#endif {
} init();
led_init();
int main( input_init();
void) timer_init();
{ seeprom_init();
init(); rs485_init();
led_init(); serial_init();
input_init(); bacnet_init();
timer_init(); idle_init();
seeprom_init(); /* Enable global interrupts */
rs485_init(); __enable_interrupt();
serial_init(); for (;;) {
bacnet_init(); input_task();
idle_init(); bacnet_task();
/* Enable global interrupts */ led_task();
__enable_interrupt(); idle_task();
for (;;) { }
input_task(); }
bacnet_task();
led_task();
idle_task();
}
}
+132 -132
View File
@@ -1,132 +1,132 @@
/************************************************************************ /************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*************************************************************************/ *************************************************************************/
#ifndef NVDATA_H #ifndef NVDATA_H
#define NVDATA_H #define NVDATA_H
#include "seeprom.h" #include "seeprom.h"
#include "eeprom.h" #include "eeprom.h"
/* data version - use to check valid version */ /* data version - use to check valid version */
#define SEEPROM_ID 0xBAC0 #define SEEPROM_ID 0xBAC0
#define SEEPROM_VERSION 0x0001 #define SEEPROM_VERSION 0x0001
#define SEEPROM_BYTES_MAX (2*1024) #define SEEPROM_BYTES_MAX (2*1024)
/* list of SEEPROM addresses */ /* list of SEEPROM addresses */
/* note to developers: define each byte, /* note to developers: define each byte,
even if they are not used explicitly */ even if they are not used explicitly */
#define NV_SEEPROM_TYPE_0 0 #define NV_SEEPROM_TYPE_0 0
#define NV_SEEPROM_TYPE_1 1 #define NV_SEEPROM_TYPE_1 1
#define NV_SEEPROM_VERSION_0 2 #define NV_SEEPROM_VERSION_0 2
#define NV_SEEPROM_VERSION_1 3 #define NV_SEEPROM_VERSION_1 3
/* --- */ /* --- */
/* define the MAC, BAUD, MAX Master, Device Instance internal /* define the MAC, BAUD, MAX Master, Device Instance internal
so that bootloader *could* use them. */ so that bootloader *could* use them. */
/* note: MAC could come from DIP switch, or be in non-volatile memory */ /* note: MAC could come from DIP switch, or be in non-volatile memory */
#define NV_EEPROM_MAC 0 #define NV_EEPROM_MAC 0
/* 9=9.6k, 19=19.2k, 38=38.4k, 57=57.6k, 76=76.8k, 115=115.2k */ /* 9=9.6k, 19=19.2k, 38=38.4k, 57=57.6k, 76=76.8k, 115=115.2k */
#define NV_EEPROM_BAUD_K 1 #define NV_EEPROM_BAUD_K 1
#define NV_EEPROM_MAX_MASTER 2 #define NV_EEPROM_MAX_MASTER 2
/* device instance is only 22 bits - easier if we use 32 bits */ /* device instance is only 22 bits - easier if we use 32 bits */
#define NV_EEPROM_DEVICE_0 3 #define NV_EEPROM_DEVICE_0 3
#define NV_EEPROM_DEVICE_1 4 #define NV_EEPROM_DEVICE_1 4
#define NV_EEPROM_DEVICE_2 5 #define NV_EEPROM_DEVICE_2 5
#define NV_EEPROM_DEVICE_3 6 #define NV_EEPROM_DEVICE_3 6
/* Device Name */ /* Device Name */
#define NV_EEPROM_DEVICE_NAME_LENGTH 8 #define NV_EEPROM_DEVICE_NAME_LENGTH 8
#define NV_EEPROM_DEVICE_NAME_ENCODING 9 #define NV_EEPROM_DEVICE_NAME_ENCODING 9
#define NV_EEPROM_DEVICE_NAME_0 10 #define NV_EEPROM_DEVICE_NAME_0 10
#define NV_EEPROM_DEVICE_NAME_1 11 #define NV_EEPROM_DEVICE_NAME_1 11
#define NV_EEPROM_DEVICE_NAME_2 12 #define NV_EEPROM_DEVICE_NAME_2 12
#define NV_EEPROM_DEVICE_NAME_3 13 #define NV_EEPROM_DEVICE_NAME_3 13
#define NV_EEPROM_DEVICE_NAME_4 14 #define NV_EEPROM_DEVICE_NAME_4 14
#define NV_EEPROM_DEVICE_NAME_5 15 #define NV_EEPROM_DEVICE_NAME_5 15
#define NV_EEPROM_DEVICE_NAME_6 16 #define NV_EEPROM_DEVICE_NAME_6 16
#define NV_EEPROM_DEVICE_NAME_7 17 #define NV_EEPROM_DEVICE_NAME_7 17
#define NV_EEPROM_DEVICE_NAME_8 18 #define NV_EEPROM_DEVICE_NAME_8 18
#define NV_EEPROM_DEVICE_NAME_9 19 #define NV_EEPROM_DEVICE_NAME_9 19
#define NV_EEPROM_DEVICE_NAME_10 20 #define NV_EEPROM_DEVICE_NAME_10 20
#define NV_EEPROM_DEVICE_NAME_11 21 #define NV_EEPROM_DEVICE_NAME_11 21
#define NV_EEPROM_DEVICE_NAME_12 22 #define NV_EEPROM_DEVICE_NAME_12 22
#define NV_EEPROM_DEVICE_NAME_13 23 #define NV_EEPROM_DEVICE_NAME_13 23
#define NV_EEPROM_DEVICE_NAME_14 24 #define NV_EEPROM_DEVICE_NAME_14 24
#define NV_EEPROM_DEVICE_NAME_15 25 #define NV_EEPROM_DEVICE_NAME_15 25
#define NV_EEPROM_DEVICE_NAME_16 26 #define NV_EEPROM_DEVICE_NAME_16 26
#define NV_EEPROM_DEVICE_NAME_17 27 #define NV_EEPROM_DEVICE_NAME_17 27
#define NV_EEPROM_DEVICE_NAME_18 28 #define NV_EEPROM_DEVICE_NAME_18 28
#define NV_EEPROM_DEVICE_NAME_19 29 #define NV_EEPROM_DEVICE_NAME_19 29
#define NV_EEPROM_DEVICE_NAME_20 30 #define NV_EEPROM_DEVICE_NAME_20 30
#define NV_EEPROM_DEVICE_NAME_21 31 #define NV_EEPROM_DEVICE_NAME_21 31
#define NV_EEPROM_DEVICE_NAME_22 32 #define NV_EEPROM_DEVICE_NAME_22 32
#define NV_EEPROM_DEVICE_NAME_23 33 #define NV_EEPROM_DEVICE_NAME_23 33
#define NV_EEPROM_DEVICE_NAME_24 34 #define NV_EEPROM_DEVICE_NAME_24 34
#define NV_EEPROM_DEVICE_NAME_25 35 #define NV_EEPROM_DEVICE_NAME_25 35
#define NV_EEPROM_DEVICE_NAME_26 36 #define NV_EEPROM_DEVICE_NAME_26 36
#define NV_EEPROM_DEVICE_NAME_27 37 #define NV_EEPROM_DEVICE_NAME_27 37
#define NV_EEPROM_DEVICE_NAME_28 38 #define NV_EEPROM_DEVICE_NAME_28 38
#define NV_EEPROM_DEVICE_NAME_29 39 #define NV_EEPROM_DEVICE_NAME_29 39
#define NV_EEPROM_DEVICE_NAME_30 40 #define NV_EEPROM_DEVICE_NAME_30 40
#define NV_EEPROM_DEVICE_NAME_31 41 #define NV_EEPROM_DEVICE_NAME_31 41
#define NV_EEPROM_DEVICE_NAME_SIZE 32 #define NV_EEPROM_DEVICE_NAME_SIZE 32
/*=============== SEEPROM ================*/ /*=============== SEEPROM ================*/
#define NV_SEEPROM_BINARY_OUTPUT_OFFSET 32 #define NV_SEEPROM_BINARY_OUTPUT_OFFSET 32
#define NV_SEEPROM_BINARY_OUTPUT_0 10 #define NV_SEEPROM_BINARY_OUTPUT_0 10
#define NV_SEEPROM_BINARY_OUTPUT(n,p) \ #define NV_SEEPROM_BINARY_OUTPUT(n,p) \
(NV_SEEPROM_BINARY_OUTPUT_0 + \ (NV_SEEPROM_BINARY_OUTPUT_0 + \
(NV_SEEPROM_BINARY_OUTPUT_OFFSET * (n)) + (p)) (NV_SEEPROM_BINARY_OUTPUT_OFFSET * (n)) + (p))
/* BO properties */ /* BO properties */
#define NV_SEEPROM_BO_POLARITY 0 #define NV_SEEPROM_BO_POLARITY 0
#define NV_SEEPROM_BO_OUT_OF_SERVICE 1 #define NV_SEEPROM_BO_OUT_OF_SERVICE 1
#define NV_SEEPROM_BO_PRIORITY_ARRAY_1 2 #define NV_SEEPROM_BO_PRIORITY_ARRAY_1 2
#define NV_SEEPROM_BO_PRIORITY_ARRAY_2 3 #define NV_SEEPROM_BO_PRIORITY_ARRAY_2 3
#define NV_SEEPROM_BO_PRIORITY_ARRAY_3 4 #define NV_SEEPROM_BO_PRIORITY_ARRAY_3 4
#define NV_SEEPROM_BO_PRIORITY_ARRAY_4 5 #define NV_SEEPROM_BO_PRIORITY_ARRAY_4 5
#define NV_SEEPROM_BO_PRIORITY_ARRAY_5 6 #define NV_SEEPROM_BO_PRIORITY_ARRAY_5 6
#define NV_SEEPROM_BO_PRIORITY_ARRAY_6 7 #define NV_SEEPROM_BO_PRIORITY_ARRAY_6 7
#define NV_SEEPROM_BO_PRIORITY_ARRAY_7 8 #define NV_SEEPROM_BO_PRIORITY_ARRAY_7 8
#define NV_SEEPROM_BO_PRIORITY_ARRAY_8 9 #define NV_SEEPROM_BO_PRIORITY_ARRAY_8 9
#define NV_SEEPROM_BO_PRIORITY_ARRAY_9 10 #define NV_SEEPROM_BO_PRIORITY_ARRAY_9 10
#define NV_SEEPROM_BO_PRIORITY_ARRAY_10 11 #define NV_SEEPROM_BO_PRIORITY_ARRAY_10 11
#define NV_SEEPROM_BO_PRIORITY_ARRAY_11 12 #define NV_SEEPROM_BO_PRIORITY_ARRAY_11 12
#define NV_SEEPROM_BO_PRIORITY_ARRAY_12 13 #define NV_SEEPROM_BO_PRIORITY_ARRAY_12 13
#define NV_SEEPROM_BO_PRIORITY_ARRAY_13 14 #define NV_SEEPROM_BO_PRIORITY_ARRAY_13 14
#define NV_SEEPROM_BO_PRIORITY_ARRAY_14 15 #define NV_SEEPROM_BO_PRIORITY_ARRAY_14 15
#define NV_SEEPROM_BO_PRIORITY_ARRAY_15 16 #define NV_SEEPROM_BO_PRIORITY_ARRAY_15 16
#define NV_SEEPROM_BO_PRIORITY_ARRAY_16 17 #define NV_SEEPROM_BO_PRIORITY_ARRAY_16 17
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+257 -259
View File
@@ -1,259 +1,257 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "hardware.h" #include "hardware.h"
#include "fifo.h" #include "fifo.h"
#include "timer.h" #include "timer.h"
#include "led.h" #include "led.h"
#include "nvdata.h" #include "nvdata.h"
/* baud rate */ /* baud rate */
static uint32_t Baud_Rate = 9600; static uint32_t Baud_Rate = 9600;
/* The minimum time after the end of the stop bit of the final octet of a */ /* 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. */ /* 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 9600 baud, 40 bit times would be about 4.166 milliseconds */
/* At 19200 baud, 40 bit times would be about 2.083 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 38400 baud, 40 bit times would be about 1.041 milliseconds */
/* At 57600 baud, 40 bit times would be about 0.694 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 76800 baud, 40 bit times would be about 0.520 milliseconds */
/* At 115200 baud, 40 bit times would be about 0.347 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 */ /* 40 bits is 4 octets including a start and stop bit with each octet */
#define Tturnaround (40UL) #define Tturnaround (40UL)
/* turnaround_time_milliseconds = (Tturnaround*1000UL)/Baud_Rate; */ /* turnaround_time_milliseconds = (Tturnaround*1000UL)/Baud_Rate; */
/* buffer for storing received bytes - size must be power of two */ /* buffer for storing received bytes - size must be power of two */
static uint8_t Receive_Buffer_Data[128]; static uint8_t Receive_Buffer_Data[128];
static FIFO_BUFFER Receive_Buffer; static FIFO_BUFFER Receive_Buffer;
static void rs485_rts_init(void) static void rs485_rts_init(
{ void)
/* configure the port pin as an output */ {
BIT_SET(DDRD, DDD4); /* configure the port pin as an output */
} BIT_SET(DDRD, DDD4);
}
/* enable the transmit-enable line on the RS-485 transceiver */
void rs485_rts_enable( /* enable the transmit-enable line on the RS-485 transceiver */
bool enable) void rs485_rts_enable(
{ bool enable)
if (enable) { {
BIT_SET(PORTD, PD4); if (enable) {
} else { BIT_SET(PORTD, PD4);
BIT_CLEAR(PORTD, PD4); } else {
} BIT_CLEAR(PORTD, PD4);
} }
}
static void rs485_receiver_enable(void)
{ static void rs485_receiver_enable(
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); void)
} {
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);
void rs485_turnaround_delay( }
void)
{ void rs485_turnaround_delay(
uint16_t turnaround_time; void)
{
/* delay after reception before trasmitting - per MS/TP spec */ uint16_t turnaround_time;
/* wait a minimum 40 bit times since reception */
/* at least 1 ms for errors: rounding, clock tick */ /* delay after reception before trasmitting - per MS/TP spec */
turnaround_time = 1 + ((Tturnaround * 1000UL) / Baud_Rate); /* wait a minimum 40 bit times since reception */
while (!timer_elapsed_milliseconds(TIMER_SILENCE, turnaround_time)) { /* at least 1 ms for errors: rounding, clock tick */
/* do nothing - wait for timer to increment */ turnaround_time = 1 + ((Tturnaround * 1000UL) / Baud_Rate);
}; while (!timer_elapsed_milliseconds(TIMER_SILENCE, turnaround_time)) {
} /* do nothing - wait for timer to increment */
};
ISR(USART0_RX_vect) }
{
uint8_t data_byte; ISR(USART0_RX_vect)
{
if (BIT_CHECK(UCSR0A, RXC0)) { uint8_t data_byte;
/* data is available */
data_byte = UDR0; if (BIT_CHECK(UCSR0A, RXC0)) {
(void)FIFO_Put(&Receive_Buffer, data_byte); /* data is available */
timer_reset(TIMER_SILENCE); data_byte = UDR0;
} (void) FIFO_Put(&Receive_Buffer, data_byte);
} timer_reset(TIMER_SILENCE);
}
bool rs485_byte_available( }
uint8_t * data_register)
{ bool rs485_byte_available(
bool data_available = false; /* return value */ uint8_t * data_register)
{
if (!FIFO_Empty(&Receive_Buffer)) { bool data_available = false; /* return value */
led_on(LED_1);
*data_register = FIFO_Get(&Receive_Buffer); if (!FIFO_Empty(&Receive_Buffer)) {
data_available = true; led_on(LED_1);
led_off_delay(LED_1, 10); *data_register = FIFO_Get(&Receive_Buffer);
} data_available = true;
led_off_delay(LED_1, 10);
return data_available; }
}
return data_available;
bool rs485_receive_error(void) }
{
return false; bool rs485_receive_error(
} void)
{
void rs485_bytes_send( return false;
uint8_t * buffer, /* data to send */ }
uint16_t nbytes) /* number of bytes of data */
{ void rs485_bytes_send(
led_on(LED_2); uint8_t * buffer, /* data to send */
while (!BIT_CHECK(UCSR0A, UDRE0)) { uint16_t nbytes)
/* do nothing - wait until Tx buffer is empty */ { /* number of bytes of data */
} led_on(LED_2);
while (nbytes) { while (!BIT_CHECK(UCSR0A, UDRE0)) {
/* Send the data byte */ /* do nothing - wait until Tx buffer is empty */
UDR0 = *buffer; }
while (!BIT_CHECK(UCSR0A, UDRE0)) { while (nbytes) {
/* do nothing - wait until Tx buffer is empty */ /* Send the data byte */
} UDR0 = *buffer;
buffer++; while (!BIT_CHECK(UCSR0A, UDRE0)) {
nbytes--; /* do nothing - wait until Tx buffer is empty */
} }
/* was the frame sent? */ buffer++;
while (!BIT_CHECK(UCSR0A, TXC0)) { nbytes--;
/* do nothing - wait until the entire frame in the }
Transmit Shift Register has been shifted out */ /* was the frame sent? */
} while (!BIT_CHECK(UCSR0A, TXC0)) {
/* Clear the Transmit Complete flag by writing a one to it. */ /* do nothing - wait until the entire frame in the
BIT_SET(UCSR0A, TXC0); Transmit Shift Register has been shifted out */
timer_reset(TIMER_SILENCE); }
led_off_delay(LED_2, 1); /* Clear the Transmit Complete flag by writing a one to it. */
BIT_SET(UCSR0A, TXC0);
return; timer_reset(TIMER_SILENCE);
} led_off_delay(LED_2, 1);
uint32_t rs485_baud_rate( return;
void) }
{
return Baud_Rate; uint32_t rs485_baud_rate(
} void)
{
static void rs485_baud_rate_configure(void) return Baud_Rate;
{ }
/* 2x speed mode */
BIT_SET(UCSR0A, U2X0); static void rs485_baud_rate_configure(
/* configure baud rate */ void)
UBRR0 = (F_CPU / (8UL * Baud_Rate)) - 1; {
} /* 2x speed mode */
BIT_SET(UCSR0A, U2X0);
bool rs485_baud_rate_set( /* configure baud rate */
uint32_t baud) UBRR0 = (F_CPU / (8UL * Baud_Rate)) - 1;
{ }
bool valid = true;
uint8_t baud_k = 0; bool rs485_baud_rate_set(
uint32_t baud)
switch (baud) { {
case 9600: bool valid = true;
case 19200: uint8_t baud_k = 0;
case 38400:
case 57600: switch (baud) {
case 76800: case 9600:
case 115200: case 19200:
Baud_Rate = baud; case 38400:
rs485_baud_rate_configure(); case 57600:
/* store the baud rate */ case 76800:
baud_k = baud/1000; case 115200:
eeprom_bytes_write( Baud_Rate = baud;
NV_EEPROM_BAUD_K, rs485_baud_rate_configure();
&baud_k, /* store the baud rate */
1); baud_k = baud / 1000;
break; eeprom_bytes_write(NV_EEPROM_BAUD_K, &baud_k, 1);
default: break;
valid = false; default:
break; valid = false;
} break;
}
return valid;
} return valid;
}
static void rs485_usart_init(void)
{ static void rs485_usart_init(
/* enable Transmit and Receive */ void)
UCSR0B = _BV(TXEN0) | _BV(RXEN0); {
/* Set USART Control and Status Register n C */ /* enable Transmit and Receive */
/* Asynchronous USART 8-bit data, No parity, 1 stop */ UCSR0B = _BV(TXEN0) | _BV(RXEN0);
/* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */ /* Set USART Control and Status Register n C */
/* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */ /* Asynchronous USART 8-bit data, No parity, 1 stop */
/* Set Stop Bit Select: USBSn = 0 for 1 stop bit */ /* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */
/* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */ /* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */
/* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */ /* Set Stop Bit Select: USBSn = 0 for 1 stop bit */
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */
/* Clear Power Reduction */ /* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */
BIT_CLEAR(PRR, PRUSART0); UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
} /* Clear Power Reduction */
BIT_CLEAR(PRR, PRUSART0);
static void rs485_init_nvdata(void) }
{
uint8_t baud_k = 9; /* from EEPROM value */ static void rs485_init_nvdata(
void)
eeprom_bytes_read( {
NV_EEPROM_BAUD_K, uint8_t baud_k = 9; /* from EEPROM value */
&baud_k,
1); eeprom_bytes_read(NV_EEPROM_BAUD_K, &baud_k, 1);
switch (baud_k) { switch (baud_k) {
case 9: case 9:
Baud_Rate = 9600; Baud_Rate = 9600;
break; break;
case 19: case 19:
Baud_Rate = 19200; Baud_Rate = 19200;
break; break;
case 38: case 38:
Baud_Rate = 38400; Baud_Rate = 38400;
break; break;
case 57: case 57:
Baud_Rate = 57600; Baud_Rate = 57600;
break; break;
case 76: case 76:
Baud_Rate = 76800; Baud_Rate = 76800;
break; break;
case 115: case 115:
Baud_Rate = 115200; Baud_Rate = 115200;
break; break;
default: default:
/* not configured yet */ /* not configured yet */
Baud_Rate = 38400; Baud_Rate = 38400;
baud_k = 38400/1000; baud_k = 38400 / 1000;
eeprom_bytes_write( eeprom_bytes_write(NV_EEPROM_BAUD_K, &baud_k, 1);
NV_EEPROM_BAUD_K, break;
&baud_k, }
1); rs485_baud_rate_configure();
break; }
}
rs485_baud_rate_configure(); void rs485_init(
} void)
{
void rs485_init(void) FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
{ (unsigned) sizeof(Receive_Buffer_Data));
FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], rs485_rts_init();
(unsigned)sizeof(Receive_Buffer_Data)); rs485_usart_init();
rs485_rts_init(); rs485_init_nvdata();
rs485_usart_init(); rs485_receiver_enable();
rs485_init_nvdata(); rs485_rts_enable(false);
rs485_receiver_enable(); }
rs485_rts_enable(false);
}
+67 -64
View File
@@ -1,64 +1,67 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2004 Steve Karg Copyright (C) 2004 Steve Karg
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307 Boston, MA 02111-1307
USA. USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef RS485_H #ifndef RS485_H
#define RS485_H #define RS485_H
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void rs485_init(void); void rs485_init(
void rs485_rts_enable( void);
bool enable); void rs485_rts_enable(
bool rs485_byte_available( bool enable);
uint8_t * data_register); bool rs485_byte_available(
bool rs485_receive_error(void); uint8_t * data_register);
void rs485_bytes_send( bool rs485_receive_error(
uint8_t * buffer, /* data to send */ void);
uint16_t nbytes); /* number of bytes of data */ void rs485_bytes_send(
uint32_t rs485_baud_rate(void); uint8_t * buffer, /* data to send */
bool rs485_baud_rate_set( uint16_t nbytes); /* number of bytes of data */
uint32_t baud); uint32_t rs485_baud_rate(
void);
void rs485_turnaround_delay( bool rs485_baud_rate_set(
void); uint32_t baud);
#ifdef __cplusplus void rs485_turnaround_delay(
} void);
#endif /* __cplusplus */
#endif #ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+426 -424
View File
@@ -1,424 +1,426 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "hardware.h" #include "hardware.h"
#include "seeprom.h" #include "seeprom.h"
/* the SEEPROM chip select bits A2, A1, and A0 are grounded */ /* the SEEPROM chip select bits A2, A1, and A0 are grounded */
/* control byte is 0xAx */ /* control byte is 0xAx */
#ifndef SEEPROM_I2C_ADDRESS #ifndef SEEPROM_I2C_ADDRESS
#define SEEPROM_I2C_ADDRESS 0xA0 #define SEEPROM_I2C_ADDRESS 0xA0
#endif #endif
/* SEEPROM Clock Frequency */ /* SEEPROM Clock Frequency */
#ifndef SEEPROM_I2C_CLOCK #ifndef SEEPROM_I2C_CLOCK
#define SEEPROM_I2C_CLOCK 400000UL #define SEEPROM_I2C_CLOCK 400000UL
#endif #endif
/* max number of bytes that can be written in a single write */ /* max number of bytes that can be written in a single write */
#ifndef SEEPROM_PAGE_SIZE #ifndef SEEPROM_PAGE_SIZE
#define SEEPROM_PAGE_SIZE 128 #define SEEPROM_PAGE_SIZE 128
#endif #endif
/* word addressing - is it 8-bit or 16-bit */ /* word addressing - is it 8-bit or 16-bit */
#ifndef SEEPROM_WORD_ADDRESS_16BIT #ifndef SEEPROM_WORD_ADDRESS_16BIT
#define SEEPROM_WORD_ADDRESS_16BIT 1 #define SEEPROM_WORD_ADDRESS_16BIT 1
#endif #endif
/* The lower 3 bits of TWSR are reserved on the ATmega163 */ /* The lower 3 bits of TWSR are reserved on the ATmega163 */
#define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3)) #define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3))
/* start condition transmitted */ /* start condition transmitted */
#define TW_START 0x08 #define TW_START 0x08
/* repeated start condition transmitted */ /* repeated start condition transmitted */
#define TW_REP_START 0x10 #define TW_REP_START 0x10
/* ***Master Transmitter*** */ /* ***Master Transmitter*** */
/* SLA+W transmitted, ACK received */ /* SLA+W transmitted, ACK received */
#define TW_MT_SLA_ACK 0x18 #define TW_MT_SLA_ACK 0x18
/* SLA+W transmitted, NACK received */ /* SLA+W transmitted, NACK received */
#define TW_MT_SLA_NACK 0x20 #define TW_MT_SLA_NACK 0x20
/* data transmitted, ACK received */ /* data transmitted, ACK received */
#define TW_MT_DATA_ACK 0x28 #define TW_MT_DATA_ACK 0x28
/* data transmitted, NACK received */ /* data transmitted, NACK received */
#define TW_MT_DATA_NACK 0x30 #define TW_MT_DATA_NACK 0x30
/* arbitration lost in SLA+W or data */ /* arbitration lost in SLA+W or data */
#define TW_MT_ARB_LOST 0x38 #define TW_MT_ARB_LOST 0x38
/* ***Master Receiver*** */ /* ***Master Receiver*** */
/* arbitration lost in SLA+R or NACK */ /* arbitration lost in SLA+R or NACK */
#define TW_MR_ARB_LOST 0x38 #define TW_MR_ARB_LOST 0x38
/* SLA+R transmitted, ACK received */ /* SLA+R transmitted, ACK received */
#define TW_MR_SLA_ACK 0x40 #define TW_MR_SLA_ACK 0x40
/* SLA+R transmitted, NACK received */ /* SLA+R transmitted, NACK received */
#define TW_MR_SLA_NACK 0x48 #define TW_MR_SLA_NACK 0x48
/* data received, ACK returned */ /* data received, ACK returned */
#define TW_MR_DATA_ACK 0x50 #define TW_MR_DATA_ACK 0x50
/* data received, NACK returned */ /* data received, NACK returned */
#define TW_MR_DATA_NACK 0x58 #define TW_MR_DATA_NACK 0x58
/* SLA+R address */ /* SLA+R address */
#define TW_READ 1 #define TW_READ 1
/* SLA+W address */ /* SLA+W address */
#define TW_WRITE 0 #define TW_WRITE 0
/* /*
* Maximal number of iterations to wait for a device to respond for a * Maximal number of iterations to wait for a device to respond for a
* selection. Should be large enough to allow for a pending write to * selection. Should be large enough to allow for a pending write to
* complete, but low enough to properly abort an infinite loop in case * complete, but low enough to properly abort an infinite loop in case
* a slave is broken or not present at all. With 100 kHz TWI clock, * a slave is broken or not present at all. With 100 kHz TWI clock,
* transfering the start condition and SLA+R/W packet takes about 10 * transfering the start condition and SLA+R/W packet takes about 10
* µs. The longest write period is supposed to not exceed ~ 10 ms. * µs. The longest write period is supposed to not exceed ~ 10 ms.
* Thus, normal operation should not require more than 100 iterations * Thus, normal operation should not require more than 100 iterations
* to get the device to respond to a selection. * to get the device to respond to a selection.
*/ */
#define MAX_ITER 200 #define MAX_ITER 200
/************************************************************************* /*************************************************************************
* DESCRIPTION: Return bytes from SEEPROM memory at address * DESCRIPTION: Return bytes from SEEPROM memory at address
* RETURN: number of bytes read, or -1 on error * RETURN: number of bytes read, or -1 on error
* NOTES: none * NOTES: none
**************************************************************************/ **************************************************************************/
int seeprom_bytes_read( int seeprom_bytes_read(
uint16_t eeaddr, /* SEEPROM starting memory address */ uint16_t eeaddr, /* SEEPROM starting memory address */
uint8_t * buf, /* data to store */ uint8_t * buf, /* data to store */
int len) /* number of bytes of data to read */ int len)
{ { /* number of bytes of data to read */
uint8_t sla, twcr, n = 0; uint8_t sla, twcr, n = 0;
int rv = 0; int rv = 0;
uint8_t twst; /* status - only valid while TWINT is set. */ uint8_t twst; /* status - only valid while TWINT is set. */
#if SEEPROM_WORD_ADDRESS_16BIT #if SEEPROM_WORD_ADDRESS_16BIT
/* 16bit address devices need only TWI Device Address */ /* 16bit address devices need only TWI Device Address */
sla = SEEPROM_I2C_ADDRESS; sla = SEEPROM_I2C_ADDRESS;
#else #else
/* patch high bits of EEPROM address into SLA */ /* patch high bits of EEPROM address into SLA */
sla = SEEPROM_I2C_ADDRESS | (((eeaddr >> 8) & 0x07) << 1); sla = SEEPROM_I2C_ADDRESS | (((eeaddr >> 8) & 0x07) << 1);
#endif #endif
/* Note [8] First cycle: master transmitter mode */ /* Note [8] First cycle: master transmitter mode */
restart: restart:
if (n++ >= MAX_ITER) { if (n++ >= MAX_ITER) {
return -1; return -1;
} }
begin: begin:
/* send start condition */ /* send start condition */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_REP_START: case TW_REP_START:
/* OK, but should not happen */ /* OK, but should not happen */
case TW_START: case TW_START:
break; break;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
/* Note [9] */ /* Note [9] */
goto begin; goto begin;
default: default:
/* error: not in start condition */ /* error: not in start condition */
/* NB: do /not/ send stop condition */ /* NB: do /not/ send stop condition */
return -1; return -1;
} }
/* Note [10] */ /* Note [10] */
/* send SLA+W */ /* send SLA+W */
TWDR = sla | TW_WRITE; TWDR = sla | TW_WRITE;
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_SLA_ACK: case TW_MT_SLA_ACK:
break; break;
case TW_MT_SLA_NACK: case TW_MT_SLA_NACK:
/* nack during select: device busy writing */ /* nack during select: device busy writing */
/* Note [11] */ /* Note [11] */
goto restart; goto restart;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
/* re-arbitrate */ /* re-arbitrate */
goto begin; goto begin;
default: default:
/* must send stop condition */ /* must send stop condition */
goto error; goto error;
} }
#if SEEPROM_WORD_ADDRESS_16BIT #if SEEPROM_WORD_ADDRESS_16BIT
/* 16 bit word address device, send high 8 bits of addr */ /* 16 bit word address device, send high 8 bits of addr */
TWDR = (eeaddr>>8); TWDR = (eeaddr >> 8);
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_ACK: case TW_MT_DATA_ACK:
break; break;
case TW_MT_DATA_NACK: case TW_MT_DATA_NACK:
goto quit; goto quit;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
goto begin; goto begin;
default: default:
/* must send stop condition */ /* must send stop condition */
goto error; goto error;
} }
#endif #endif
/* low 8 bits of addr */ /* low 8 bits of addr */
TWDR = eeaddr; TWDR = eeaddr;
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_ACK: case TW_MT_DATA_ACK:
break; break;
case TW_MT_DATA_NACK: case TW_MT_DATA_NACK:
goto quit; goto quit;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
goto begin; goto begin;
default: default:
/* must send stop condition */ /* must send stop condition */
goto error; goto error;
} }
/* Note [12] Next cycle(s): master receiver mode */ /* Note [12] Next cycle(s): master receiver mode */
/* send repeated start condition */ /* send repeated start condition */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_START: case TW_START:
/* OK, but should not happen */ /* OK, but should not happen */
case TW_REP_START: case TW_REP_START:
break; break;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
goto begin; goto begin;
default: default:
goto error; goto error;
} }
/* send SLA+R */ /* send SLA+R */
TWDR = sla | TW_READ; TWDR = sla | TW_READ;
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MR_SLA_ACK: case TW_MR_SLA_ACK:
break; break;
case TW_MR_SLA_NACK: case TW_MR_SLA_NACK:
goto quit; goto quit;
case TW_MR_ARB_LOST: case TW_MR_ARB_LOST:
goto begin; goto begin;
default: default:
goto error; goto error;
} }
/* Note [13] */ /* Note [13] */
twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA); twcr = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
for (;len > 0; len--) { for (; len > 0; len--) {
if (len == 1) { if (len == 1) {
/* send NAK this time */ /* send NAK this time */
twcr = _BV(TWINT) | _BV(TWEN); twcr = _BV(TWINT) | _BV(TWEN);
} }
/* clear int to start transmission */ /* clear int to start transmission */
TWCR = twcr; TWCR = twcr;
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MR_DATA_NACK: case TW_MR_DATA_NACK:
/* force end of loop */ /* force end of loop */
len = 0; len = 0;
/* FALLTHROUGH */ /* FALLTHROUGH */
case TW_MR_DATA_ACK: case TW_MR_DATA_ACK:
*buf= TWDR; *buf = TWDR;
buf++; buf++;
rv++; rv++;
break; break;
default: default:
goto error; goto error;
} }
} }
quit: quit:
/* Note [14] */ /* Note [14] */
/* send stop condition */ /* send stop condition */
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
return rv; return rv;
error: error:
rv = -1; rv = -1;
goto quit; goto quit;
} }
/************************************************************************* /*************************************************************************
* DESCRIPTION: Write some data and wait until it is sent * DESCRIPTION: Write some data and wait until it is sent
* RETURN: number of bytes written, or -1 on error * RETURN: number of bytes written, or -1 on error
* NOTES: none * NOTES: none
**************************************************************************/ **************************************************************************/
int seeprom_bytes_write( int seeprom_bytes_write(
uint16_t eeaddr, /* SEEPROM starting memory address */ uint16_t eeaddr, /* SEEPROM starting memory address */
uint8_t * buf, /* data to send */ uint8_t * buf, /* data to send */
int len) /* number of bytes of data */ int len)
{ { /* number of bytes of data */
uint8_t sla, n = 0; uint8_t sla, n = 0;
int rv = 0; int rv = 0;
uint16_t endaddr; uint16_t endaddr;
uint8_t twst; /* status - only valid while TWINT is set. */ uint8_t twst; /* status - only valid while TWINT is set. */
if ((eeaddr + len) < (eeaddr | (SEEPROM_PAGE_SIZE - 1))) { if ((eeaddr + len) < (eeaddr | (SEEPROM_PAGE_SIZE - 1))) {
endaddr = eeaddr + len; endaddr = eeaddr + len;
} else { } else {
endaddr = (eeaddr | (SEEPROM_PAGE_SIZE - 1)) + 1; endaddr = (eeaddr | (SEEPROM_PAGE_SIZE - 1)) + 1;
} }
len = endaddr - eeaddr; len = endaddr - eeaddr;
#if SEEPROM_WORD_ADDRESS_16BIT #if SEEPROM_WORD_ADDRESS_16BIT
/* 16bit address devices need only TWI Device Address */ /* 16bit address devices need only TWI Device Address */
sla = SEEPROM_I2C_ADDRESS; sla = SEEPROM_I2C_ADDRESS;
#else #else
/* patch high bits of EEPROM address into SLA */ /* patch high bits of EEPROM address into SLA */
sla = SEEPROM_I2C_ADDRESS | (((eeaddr >> 8) & 0x07) << 1); sla = SEEPROM_I2C_ADDRESS | (((eeaddr >> 8) & 0x07) << 1);
#endif #endif
restart: restart:
if (n++ >= MAX_ITER) { if (n++ >= MAX_ITER) {
return -1; return -1;
} }
begin: begin:
/* Note [15] */ /* Note [15] */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */ TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */ while ((TWCR & _BV(TWINT)) == 0); /* wait for transmission */
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_REP_START: case TW_REP_START:
/* OK, but should not happen */ /* OK, but should not happen */
case TW_START: case TW_START:
break; break;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
goto begin; goto begin;
default: default:
/* error: not in start condition */ /* error: not in start condition */
/* NB: do /not/ send stop condition */ /* NB: do /not/ send stop condition */
return -1; return -1;
} }
/* send SLA+W */ /* send SLA+W */
TWDR = sla | TW_WRITE; TWDR = sla | TW_WRITE;
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_SLA_ACK: case TW_MT_SLA_ACK:
break; break;
case TW_MT_SLA_NACK: case TW_MT_SLA_NACK:
/* nack during select: device busy writing */ /* nack during select: device busy writing */
goto restart; goto restart;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
/* re-arbitrate */ /* re-arbitrate */
goto begin; goto begin;
default: default:
/* must send stop condition */ /* must send stop condition */
goto error; goto error;
} }
#if SEEPROM_WORD_ADDRESS_16BIT #if SEEPROM_WORD_ADDRESS_16BIT
/* 16 bit word address device, send high 8 bits of addr */ /* 16 bit word address device, send high 8 bits of addr */
TWDR = (eeaddr>>8); TWDR = (eeaddr >> 8);
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) ; while ((TWCR & _BV(TWINT)) == 0);
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_ACK: case TW_MT_DATA_ACK:
break; break;
case TW_MT_DATA_NACK: case TW_MT_DATA_NACK:
goto quit; goto quit;
case TW_MT_ARB_LOST: case TW_MT_ARB_LOST:
goto begin; goto begin;
default: default:
/* must send stop condition */ /* must send stop condition */
goto error; goto error;
} }
#endif #endif
/* low 8 bits of addr */ /* low 8 bits of addr */
TWDR = eeaddr; TWDR = eeaddr;
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) {}; while ((TWCR & _BV(TWINT)) == 0) {
twst = TWSR & TW_STATUS_MASK; };
switch (twst) { twst = TWSR & TW_STATUS_MASK;
case TW_MT_DATA_ACK: switch (twst) {
break; case TW_MT_DATA_ACK:
case TW_MT_DATA_NACK: break;
goto quit; case TW_MT_DATA_NACK:
case TW_MT_ARB_LOST: goto quit;
goto begin; case TW_MT_ARB_LOST:
default: goto begin;
/* must send stop condition */ default:
goto error; /* must send stop condition */
} goto error;
for (; len > 0; len--) { }
TWDR = *buf++; for (; len > 0; len--) {
/* start transmission */ TWDR = *buf++;
TWCR = _BV(TWINT) | _BV(TWEN); /* start transmission */
/* wait for transmission */ TWCR = _BV(TWINT) | _BV(TWEN);
while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
twst = TWSR & TW_STATUS_MASK; while ((TWCR & _BV(TWINT)) == 0);
switch (twst) { twst = TWSR & TW_STATUS_MASK;
case TW_MT_DATA_NACK: switch (twst) {
/* device write protected -- Note [16] */ case TW_MT_DATA_NACK:
goto error; /* device write protected -- Note [16] */
case TW_MT_DATA_ACK: goto error;
rv++; case TW_MT_DATA_ACK:
break; rv++;
default: break;
goto error; default:
} goto error;
} }
quit: }
/* send stop condition */ quit:
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
return rv;
return rv;
error:
rv = -1; error:
goto quit; rv = -1;
} goto quit;
}
/*************************************************************************
* Description: Initialize the SEEPROM TWI connection /*************************************************************************
* Returns: none * Description: Initialize the SEEPROM TWI connection
* Notes: none * Returns: none
**************************************************************************/ * Notes: none
void seeprom_init(void) **************************************************************************/
{ void seeprom_init(
/* bit rate prescaler */ void)
TWSR=0; {
TWCR=_BV(TWEN) | _BV(TWEA); /* bit rate prescaler */
/* bit rate */ TWSR = 0;
TWBR = (F_CPU / SEEPROM_I2C_CLOCK - 16) / 2; TWCR = _BV(TWEN) | _BV(TWEA);
/* my address */ /* bit rate */
TWAR=0; TWBR = (F_CPU / SEEPROM_I2C_CLOCK - 16) / 2;
} /* my address */
TWAR = 0;
}
+48 -48
View File
@@ -1,48 +1,48 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef SEEPROM_H #ifndef SEEPROM_H
#define SEEPROM_H #define SEEPROM_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int seeprom_bytes_read( int seeprom_bytes_read(
uint16_t ee_address, /* SEEPROM starting memory address */ uint16_t ee_address, /* SEEPROM starting memory address */
uint8_t * buffer, /* data to store */ uint8_t * buffer, /* data to store */
int nbytes); /* number of bytes of data to read */ int nbytes); /* number of bytes of data to read */
int seeprom_bytes_write( int seeprom_bytes_write(
uint16_t ee_address, /* SEEPROM starting memory address */ uint16_t ee_address, /* SEEPROM starting memory address */
uint8_t * buffer, /* data to send */ uint8_t * buffer, /* data to send */
int nbytes); /* number of bytes of data */ int nbytes); /* number of bytes of data */
void seeprom_init( void seeprom_init(
void); void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+177 -173
View File
@@ -1,173 +1,177 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "hardware.h" #include "hardware.h"
#include "fifo.h" #include "fifo.h"
#include "serial.h" #include "serial.h"
/* baud rate */ /* baud rate */
static uint32_t Baud_Rate = 9600; static uint32_t Baud_Rate = 9600;
/* buffer for storing received bytes - size must be power of two */ /* buffer for storing received bytes - size must be power of two */
static uint8_t Receive_Buffer_Data[128]; static uint8_t Receive_Buffer_Data[128];
static FIFO_BUFFER Receive_Buffer; static FIFO_BUFFER Receive_Buffer;
static void serial_receiver_enable(void) static void serial_receiver_enable(
{ void)
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); {
} UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);
}
ISR(USART1_RX_vect)
{ ISR(USART1_RX_vect)
uint8_t data_byte; {
uint8_t data_byte;
if (BIT_CHECK(UCSR1A, RXC1)) {
/* data is available */ if (BIT_CHECK(UCSR1A, RXC1)) {
data_byte = UDR1; /* data is available */
(void)FIFO_Put(&Receive_Buffer, data_byte); data_byte = UDR1;
} (void) FIFO_Put(&Receive_Buffer, data_byte);
} }
}
bool serial_byte_get(
uint8_t * data_register) bool serial_byte_get(
{ uint8_t * data_register)
bool data_available = false; /* return value */ {
bool data_available = false; /* return value */
if (!FIFO_Empty(&Receive_Buffer)) {
*data_register = FIFO_Get(&Receive_Buffer); if (!FIFO_Empty(&Receive_Buffer)) {
data_available = true; *data_register = FIFO_Get(&Receive_Buffer);
} data_available = true;
}
return data_available;
} return data_available;
}
bool serial_byte_peek(
uint8_t * data_register) bool serial_byte_peek(
{ uint8_t * data_register)
bool data_available = false; /* return value */ {
bool data_available = false; /* return value */
if (!FIFO_Empty(&Receive_Buffer)) {
*data_register = FIFO_Peek(&Receive_Buffer); if (!FIFO_Empty(&Receive_Buffer)) {
data_available = true; *data_register = FIFO_Peek(&Receive_Buffer);
} data_available = true;
}
return data_available;
} return data_available;
}
void serial_bytes_send(
uint8_t * buffer, /* data to send */ void serial_bytes_send(
uint16_t nbytes) /* number of bytes of data */ uint8_t * buffer, /* data to send */
{ uint16_t nbytes)
while (!BIT_CHECK(UCSR1A, UDRE1)) { { /* number of bytes of data */
/* do nothing - wait until Tx buffer is empty */ while (!BIT_CHECK(UCSR1A, UDRE1)) {
} /* do nothing - wait until Tx buffer is empty */
while (nbytes) { }
/* Send the data byte */ while (nbytes) {
UDR1 = *buffer; /* Send the data byte */
while (!BIT_CHECK(UCSR1A, UDRE1)) { UDR1 = *buffer;
/* do nothing - wait until Tx buffer is empty */ while (!BIT_CHECK(UCSR1A, UDRE1)) {
} /* do nothing - wait until Tx buffer is empty */
buffer++; }
nbytes--; buffer++;
} nbytes--;
/* was the frame sent? */ }
while (!BIT_CHECK(UCSR1A, TXC1)) { /* was the frame sent? */
/* do nothing - wait until the entire frame in the while (!BIT_CHECK(UCSR1A, TXC1)) {
Transmit Shift Register has been shifted out */ /* 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(UCSR1A, TXC1); /* Clear the Transmit Complete flag by writing a one to it. */
BIT_SET(UCSR1A, TXC1);
return;
} return;
}
void serial_byte_send(uint8_t ch)
{ void serial_byte_send(
uint8_t buffer[1]; uint8_t ch)
{
buffer[0] = ch; uint8_t buffer[1];
serial_bytes_send(&buffer[0], 1);
buffer[0] = ch;
return; serial_bytes_send(&buffer[0], 1);
}
return;
uint32_t serial_baud_rate( }
void)
{ uint32_t serial_baud_rate(
return Baud_Rate; void)
} {
return Baud_Rate;
bool serial_baud_rate_set( }
uint32_t baud)
{ bool serial_baud_rate_set(
bool valid = true; uint32_t baud)
{
switch (baud) { bool valid = true;
case 9600:
case 19200: switch (baud) {
case 38400: case 9600:
case 57600: case 19200:
case 76800: case 38400:
case 115200: case 57600:
Baud_Rate = baud; case 76800:
/* 2x speed mode */ case 115200:
BIT_SET(UCSR1A, U2X1); Baud_Rate = baud;
/* configure baud rate */ /* 2x speed mode */
UBRR1 = (F_CPU / (8UL * Baud_Rate)) - 1; BIT_SET(UCSR1A, U2X1);
/* FIXME: store the baud rate */ /* configure baud rate */
break; UBRR1 = (F_CPU / (8UL * Baud_Rate)) - 1;
default: /* FIXME: store the baud rate */
valid = false; break;
break; default:
} valid = false;
break;
return valid; }
}
return valid;
static void serial_usart_init(void) }
{
/* enable Transmit and Receive */ static void serial_usart_init(
UCSR1B = _BV(TXEN1) | _BV(RXEN1); void)
/* Set USART Control and Status Register n C */ {
/* Asynchronous USART 8-bit data, No parity, 1 stop */ /* enable Transmit and Receive */
/* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */ UCSR1B = _BV(TXEN1) | _BV(RXEN1);
/* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */ /* Set USART Control and Status Register n C */
/* Set Stop Bit Select: USBSn = 0 for 1 stop bit */ /* Asynchronous USART 8-bit data, No parity, 1 stop */
/* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */ /* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */
/* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */ /* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */
UCSR0C = _BV(UCSZ11) | _BV(UCSZ10); /* Set Stop Bit Select: USBSn = 0 for 1 stop bit */
/* Clear Power Reduction */ /* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */
BIT_CLEAR(PRR, PRUSART1); /* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */
} UCSR0C = _BV(UCSZ11) | _BV(UCSZ10);
/* Clear Power Reduction */
void serial_init(void) BIT_CLEAR(PRR, PRUSART1);
{ }
FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
(unsigned)sizeof(Receive_Buffer_Data)); void serial_init(
serial_usart_init(); void)
serial_baud_rate_set(Baud_Rate); {
serial_receiver_enable(); FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
} (unsigned) sizeof(Receive_Buffer_Data));
serial_usart_init();
serial_baud_rate_set(Baud_Rate);
serial_receiver_enable();
}
+55 -53
View File
@@ -1,53 +1,55 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef SERIAL_H #ifndef SERIAL_H
#define SERIAL_H #define SERIAL_H
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
bool serial_byte_get( bool serial_byte_get(
uint8_t * data_register); uint8_t * data_register);
bool serial_byte_peek( bool serial_byte_peek(
uint8_t * data_register); uint8_t * data_register);
void serial_bytes_send( void serial_bytes_send(
uint8_t * buffer, /* data to send */ uint8_t * buffer, /* data to send */
uint16_t nbytes); /* number of bytes of data */ uint16_t nbytes); /* number of bytes of data */
void serial_byte_send(uint8_t ch); void serial_byte_send(
uint8_t ch);
uint32_t serial_baud_rate(void);
bool serial_baud_rate_set( uint32_t serial_baud_rate(
uint32_t baud); void);
bool serial_baud_rate_set(
void serial_init(void); uint32_t baud);
#ifdef __cplusplus void serial_init(
} void);
#endif /* __cplusplus */
#ifdef __cplusplus
#endif }
#endif /* __cplusplus */
#endif
+80 -77
View File
@@ -1,77 +1,80 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include "hardware.h" #include "hardware.h"
/* stack checking */ /* stack checking */
extern uint8_t _end; extern uint8_t _end;
extern uint8_t __stack; extern uint8_t __stack;
#define STACK_CANARY (0xC5) #define STACK_CANARY (0xC5)
void stack_init( void stack_init(
void) __attribute__ ((naked)) __attribute__ ((section(".init1"))); void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
void stack_init( void stack_init(
void) void)
{ {
#if 0 #if 0
uint8_t *p = &_end; uint8_t *p = &_end;
while (p <= &__stack) { while (p <= &__stack) {
*p = STACK_CANARY; *p = STACK_CANARY;
p++; p++;
} }
#else #else
__asm volatile ( __asm volatile (
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */ " ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n" " ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n" " st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::); " cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
#endif #endif
} }
unsigned stack_size(void) unsigned stack_size(
{ void)
return (&__stack) - (&_end); {
} return (&__stack) - (&_end);
}
uint8_t stack_byte(unsigned offset)
{ uint8_t stack_byte(
return *(&_end + offset); unsigned offset)
} {
return *(&_end + offset);
unsigned stack_unused(void) }
{
uint8_t *p = &_end; unsigned stack_unused(
unsigned count = 0; void)
{
while (p <= &__stack) { uint8_t *p = &_end;
if ((*p) != STACK_CANARY) { unsigned count = 0;
count = p - (&_end);
break; while (p <= &__stack) {
} if ((*p) != STACK_CANARY) {
p++; count = p - (&_end);
} break;
return count; }
} p++;
}
return count;
}
+50 -48
View File
@@ -1,49 +1,51 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef STACK_H #ifndef STACK_H
#define STACK_H #define STACK_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* C stack checking */ /* C stack checking */
void stack_init(void); void stack_init(
void);
unsigned stack_size(void);
unsigned stack_size(
uint8_t stack_byte(unsigned offset); void);
unsigned stack_unused(void); uint8_t stack_byte(
unsigned offset);
#ifdef __cplusplus
} unsigned stack_unused(
#endif /* __cplusplus */ void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif #endif
+67 -67
View File
@@ -1,67 +1,67 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#ifndef TIMER_H #ifndef TIMER_H
#define TIMER_H #define TIMER_H
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
/* Timer Module */ /* Timer Module */
/* reserve the millisecond timer indexes as needed for each module */ /* reserve the millisecond timer indexes as needed for each module */
#define TIMER_SILENCE 0 #define TIMER_SILENCE 0
#define TIMER_DEBOUNCE 1 #define TIMER_DEBOUNCE 1
#define TIMER_LED_1 2 #define TIMER_LED_1 2
#define TIMER_LED_2 3 #define TIMER_LED_2 3
#define TIMER_LED_3 4 #define TIMER_LED_3 4
#define TIMER_LED_4 5 #define TIMER_LED_4 5
#define TIMER_DCC 6 #define TIMER_DCC 6
#define MAX_MILLISECOND_TIMERS 7 #define MAX_MILLISECOND_TIMERS 7
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void timer_init( void timer_init(
void); void);
unsigned long timer_milliseconds( unsigned long timer_milliseconds(
unsigned index); unsigned index);
bool timer_elapsed_milliseconds( bool timer_elapsed_milliseconds(
unsigned index, unsigned index,
unsigned long value); unsigned long value);
bool timer_elapsed_seconds( bool timer_elapsed_seconds(
unsigned index, unsigned index,
unsigned long value); unsigned long value);
bool timer_elapsed_minutes( bool timer_elapsed_minutes(
unsigned index, unsigned index,
unsigned long seconds); unsigned long seconds);
unsigned long timer_milliseconds_set( unsigned long timer_milliseconds_set(
unsigned index, unsigned index,
unsigned long value); unsigned long value);
unsigned long timer_reset( unsigned long timer_reset(
unsigned index); unsigned index);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+223 -222
View File
@@ -1,222 +1,223 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
/* define various timers in timer.h file */ /* define various timers in timer.h file */
#ifndef MAX_MILLISECOND_TIMERS #ifndef MAX_MILLISECOND_TIMERS
#define MAX_MILLISECOND_TIMERS 2 #define MAX_MILLISECOND_TIMERS 2
#endif #endif
/* Timer2 Prescaling: 1, 8, 32, 64, 128, 256, or 1024 */ /* Timer2 Prescaling: 1, 8, 32, 64, 128, 256, or 1024 */
#define TIMER2_PRESCALER 128 #define TIMER2_PRESCALER 128
/* Count: Timer counts up to 0xFF and then signals overflow */ /* Count: Timer counts up to 0xFF and then signals overflow */
#define TIMER2_TICKS (F_CPU/TIMER2_PRESCALER/1000) #define TIMER2_TICKS (F_CPU/TIMER2_PRESCALER/1000)
#if (TIMER2_TICKS > 0xFF) #if (TIMER2_TICKS > 0xFF)
#error Timer2 Prescaler value is too small #error Timer2 Prescaler value is too small
#endif #endif
#define TIMER2_COUNT (0xFF-TIMER2_TICKS) #define TIMER2_COUNT (0xFF-TIMER2_TICKS)
/* counter for the various timers */ /* counter for the various timers */
static volatile unsigned long Millisecond_Counter[MAX_MILLISECOND_TIMERS]; static volatile unsigned long Millisecond_Counter[MAX_MILLISECOND_TIMERS];
/************************************************************************* /*************************************************************************
* Description: Timer Interrupt Handler * Description: Timer Interrupt Handler
* Returns: none * Returns: none
* Notes: Global interupts must be enabled * Notes: Global interupts must be enabled
*************************************************************************/ *************************************************************************/
static inline void timer_interrupt_handler(void) static inline void timer_interrupt_handler(
{ void)
unsigned i; /* loop counter */ {
unsigned i; /* loop counter */
/* increment the tick count */
for (i = 0; i < MAX_MILLISECOND_TIMERS; i++) { /* increment the tick count */
Millisecond_Counter[i]++; for (i = 0; i < MAX_MILLISECOND_TIMERS; i++) {
} Millisecond_Counter[i]++;
} }
}
/*************************************************************************
* Description: Timer Interrupt Service Routine - Timer Overflowed! /*************************************************************************
* Returns: none * Description: Timer Interrupt Service Routine - Timer Overflowed!
* Notes: Global interupts must be enabled * Returns: none
*************************************************************************/ * Notes: Global interupts must be enabled
ISR(TIMER2_OVF_vect) *************************************************************************/
{ ISR(TIMER2_OVF_vect)
/* Set the counter for the next interrupt */ {
TCNT2 = TIMER2_COUNT; /* Set the counter for the next interrupt */
timer_interrupt_handler(); TCNT2 = TIMER2_COUNT;
} timer_interrupt_handler();
}
/*************************************************************************
* Description: sets the current time count with a value /*************************************************************************
* Returns: none * Description: sets the current time count with a value
* Notes: none * Returns: none
*************************************************************************/ * Notes: none
unsigned long timer_milliseconds_set( *************************************************************************/
unsigned index, unsigned long timer_milliseconds_set(
unsigned long value) unsigned index,
{ unsigned long value)
uint8_t sreg = 0; /* holds interrupts pending */ {
unsigned long old_value = 0; /* return value */ uint8_t sreg = 0; /* holds interrupts pending */
unsigned long old_value = 0; /* return value */
if (index < MAX_MILLISECOND_TIMERS) {
sreg = SREG; if (index < MAX_MILLISECOND_TIMERS) {
__disable_interrupt(); sreg = SREG;
old_value = Millisecond_Counter[index]; __disable_interrupt();
Millisecond_Counter[index] = value; old_value = Millisecond_Counter[index];
SREG = sreg; Millisecond_Counter[index] = value;
} SREG = sreg;
}
return old_value;
} return old_value;
}
/*************************************************************************
* Description: returns the current millisecond count /*************************************************************************
* Returns: none * Description: returns the current millisecond count
* Notes: none * Returns: none
*************************************************************************/ * Notes: none
unsigned long timer_milliseconds( *************************************************************************/
unsigned index) unsigned long timer_milliseconds(
{ unsigned index)
unsigned long timer_value = 0; /* return value */ {
uint8_t sreg = 0; /* holds interrupts pending */ unsigned long timer_value = 0; /* return value */
uint8_t sreg = 0; /* holds interrupts pending */
if (index < MAX_MILLISECOND_TIMERS) {
sreg = SREG; if (index < MAX_MILLISECOND_TIMERS) {
__disable_interrupt(); sreg = SREG;
timer_value = Millisecond_Counter[index]; __disable_interrupt();
SREG = sreg; timer_value = Millisecond_Counter[index];
} SREG = sreg;
}
return timer_value;
} return timer_value;
}
/*************************************************************************
* Description: compares the current time count with a value /*************************************************************************
* Returns: true if the time has elapsed * Description: compares the current time count with a value
* Notes: none * Returns: true if the time has elapsed
*************************************************************************/ * Notes: none
bool timer_elapsed_milliseconds( *************************************************************************/
unsigned index, bool timer_elapsed_milliseconds(
unsigned long value) unsigned index,
{ unsigned long value)
return (timer_milliseconds(index) >= value); {
} return (timer_milliseconds(index) >= value);
}
/*************************************************************************
* Description: compares the current time count with a value /*************************************************************************
* Returns: true if the time has elapsed * Description: compares the current time count with a value
* Notes: none * Returns: true if the time has elapsed
*************************************************************************/ * Notes: none
bool timer_elapsed_seconds( *************************************************************************/
unsigned index, bool timer_elapsed_seconds(
unsigned long seconds) unsigned index,
{ unsigned long seconds)
return ((timer_milliseconds(index)/1000UL) >= seconds); {
} return ((timer_milliseconds(index) / 1000UL) >= seconds);
}
/*************************************************************************
* Description: compares the current time count with a value /*************************************************************************
* Returns: true if the time has elapsed * Description: compares the current time count with a value
* Notes: none * Returns: true if the time has elapsed
*************************************************************************/ * Notes: none
bool timer_elapsed_minutes( *************************************************************************/
unsigned index, bool timer_elapsed_minutes(
unsigned long minutes) unsigned index,
{ unsigned long minutes)
return ((timer_milliseconds(index)/(1000UL*60UL)) >= minutes); {
} return ((timer_milliseconds(index) / (1000UL * 60UL)) >= minutes);
}
/*************************************************************************
* Description: Sets the timer counter to zero. /*************************************************************************
* Returns: none * Description: Sets the timer counter to zero.
* Notes: none * Returns: none
*************************************************************************/ * Notes: none
unsigned long timer_reset( *************************************************************************/
unsigned index) unsigned long timer_reset(
{ unsigned index)
return timer_milliseconds_set(index,0); {
} return timer_milliseconds_set(index, 0);
}
/*************************************************************************
* Description: Initialization for Timer /*************************************************************************
* Returns: none * Description: Initialization for Timer
* Notes: none * Returns: none
*************************************************************************/ * Notes: none
static void timer2_init( *************************************************************************/
void) static void timer2_init(
{ void)
/* Normal Operation */ {
TCCR2A = 0; /* Normal Operation */
/* Timer2: prescale selections: TCCR2A = 0;
CSn2 CSn1 CSn0 Description /* Timer2: prescale selections:
---- ---- ---- ----------- CSn2 CSn1 CSn0 Description
0 0 0 No Clock Source ---- ---- ---- -----------
0 0 1 No prescaling 0 0 0 No Clock Source
0 1 0 CLKt2s/8 0 0 1 No prescaling
0 1 1 CLKt2s/32 0 1 0 CLKt2s/8
1 0 0 CLKt2s/64 0 1 1 CLKt2s/32
1 0 1 CLKt2s/128 1 0 0 CLKt2s/64
1 1 0 CLKt2s/256 1 0 1 CLKt2s/128
1 1 1 CLKt2s/1024 1 1 0 CLKt2s/256
*/ 1 1 1 CLKt2s/1024
#if (TIMER2_PRESCALER==1) */
TCCR2B = _BV(CS20); #if (TIMER2_PRESCALER==1)
#elif (TIMER2_PRESCALER==8) TCCR2B = _BV(CS20);
TCCR2B = _BV(CS21); #elif (TIMER2_PRESCALER==8)
#elif (TIMER2_PRESCALER==32) TCCR2B = _BV(CS21);
TCCR2B = _BV(CS21) | _BV(CS20); #elif (TIMER2_PRESCALER==32)
#elif (TIMER2_PRESCALER==64) TCCR2B = _BV(CS21) | _BV(CS20);
TCCR2B = _BV(CS22); #elif (TIMER2_PRESCALER==64)
#elif (TIMER2_PRESCALER==128) TCCR2B = _BV(CS22);
TCCR2B = _BV(CS22) | _BV(CS20); #elif (TIMER2_PRESCALER==128)
#elif (TIMER2_PRESCALER==256) TCCR2B = _BV(CS22) | _BV(CS20);
TCCR2B = _BV(CS22) | _BV(CS21); #elif (TIMER2_PRESCALER==256)
#elif (TIMER2_PRESCALER==1024) TCCR2B = _BV(CS22) | _BV(CS21);
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); #elif (TIMER2_PRESCALER==1024)
#else TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);
#error Timer2 Prescale: Invalid Value #else
#endif #error Timer2 Prescale: Invalid Value
/* Clear any TOV Flag set when the timer overflowed */ #endif
BIT_CLEAR(TIFR2, TOV2); /* Clear any TOV Flag set when the timer overflowed */
/* Initial value */ BIT_CLEAR(TIFR2, TOV2);
TCNT2 = TIMER2_COUNT; /* Initial value */
/* Enable the overflow interrupt */ TCNT2 = TIMER2_COUNT;
BIT_SET(TIMSK2, TOIE2); /* Enable the overflow interrupt */
/* Clear the Power Reduction Timer/Counter0 */ BIT_SET(TIMSK2, TOIE2);
BIT_CLEAR(PRR, PRTIM2); /* Clear the Power Reduction Timer/Counter0 */
} BIT_CLEAR(PRR, PRTIM2);
}
/*************************************************************************
* Description: Initialization for Timer /*************************************************************************
* Returns: none * Description: Initialization for Timer
* Notes: none * Returns: none
*************************************************************************/ * Notes: none
void timer_init( *************************************************************************/
void) void timer_init(
{ void)
timer2_init(); {
} timer2_init();
}
+1 -1
View File
@@ -450,7 +450,7 @@ int Device_Encode_Property_APDU(
case PROP_UTC_OFFSET: case PROP_UTC_OFFSET:
/* Note: BACnet Time Zone is offset of local time and UTC, /* Note: BACnet Time Zone is offset of local time and UTC,
rather than offset of GMT. It is expressed in minutes */ rather than offset of GMT. It is expressed in minutes */
apdu_len = encode_application_signed(&apdu[0], 5*60 /* EST */ ); apdu_len = encode_application_signed(&apdu[0], 5 * 60 /* EST */ );
break; break;
case PROP_LOCAL_DATE: case PROP_LOCAL_DATE:
/* FIXME: if you support date */ /* FIXME: if you support date */
+5 -11
View File
@@ -98,8 +98,8 @@ void RS485_Set_Interface(
if (ifname) { if (ifname) {
if (strncmp("COM", ifname, 3) == 0) { if (strncmp("COM", ifname, 3) == 0) {
if (strlen(ifname) > 3) { if (strlen(ifname) > 3) {
sprintf(RS485_Port_Name, "\\\\.\\COM%i", atoi(ifname+3)); sprintf(RS485_Port_Name, "\\\\.\\COM%i", atoi(ifname + 3));
fprintf(stderr, "Adjusted interface name to %s\r\n", fprintf(stderr, "Adjusted interface name to %s\r\n",
RS485_Port_Name); RS485_Port_Name);
} }
} }
@@ -119,15 +119,9 @@ static void RS485_Print_Error(
DWORD dwExtSize; DWORD dwExtSize;
DWORD dwErr; DWORD dwErr;
FormatMessage( FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, (LPTSTR) & lpMsgBuf, 0, NULL);
NULL, MessageBox(NULL, lpMsgBuf, "GetLastError", MB_OK | MB_ICONINFORMATION);
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
LocalFree(lpMsgBuf); LocalFree(lpMsgBuf);
return; return;
+5 -10
View File
@@ -809,34 +809,29 @@ bool bacapp_print_value(
if (value->type.Date.day == 255) { if (value->type.Date.day == 255) {
fprintf(stream, "(unspecified), "); fprintf(stream, "(unspecified), ");
} else { } else {
fprintf(stream, "%u, ", fprintf(stream, "%u, ", (unsigned) value->type.Date.day);
(unsigned) value->type.Date.day);
} }
if (value->type.Date.year == 255) { if (value->type.Date.year == 255) {
fprintf(stream, "(unspecified), "); fprintf(stream, "(unspecified), ");
} else { } else {
fprintf(stream, "%u", fprintf(stream, "%u", (unsigned) value->type.Date.year);
(unsigned) value->type.Date.year);
} }
break; break;
case BACNET_APPLICATION_TAG_TIME: case BACNET_APPLICATION_TAG_TIME:
if (value->type.Time.hour == 255) { if (value->type.Time.hour == 255) {
fprintf(stream, "**:"); fprintf(stream, "**:");
} else { } else {
fprintf(stream, "%02u:", fprintf(stream, "%02u:", (unsigned) value->type.Time.hour);
(unsigned) value->type.Time.hour);
} }
if (value->type.Time.min == 255) { if (value->type.Time.min == 255) {
fprintf(stream, "**:"); fprintf(stream, "**:");
} else { } else {
fprintf(stream, "%02u:", fprintf(stream, "%02u:", (unsigned) value->type.Time.min);
(unsigned) value->type.Time.min);
} }
if (value->type.Time.sec == 255) { if (value->type.Time.sec == 255) {
fprintf(stream, "**."); fprintf(stream, "**.");
} else { } else {
fprintf(stream, "%02u.", fprintf(stream, "%02u.", (unsigned) value->type.Time.sec);
(unsigned) value->type.Time.sec);
} }
if (value->type.Time.hundredths == 255) { if (value->type.Time.hundredths == 255) {
fprintf(stream, "**"); fprintf(stream, "**");