Updated bdk port for version 2, along with test.
This commit is contained in:
@@ -64,6 +64,13 @@ extern "C" {
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
|
||||
void Binary_Output_Level_Sync(
|
||||
unsigned int index);
|
||||
void Binary_Output_Level_Set(
|
||||
unsigned int object_index,
|
||||
unsigned int priority,
|
||||
BACNET_BINARY_PV level);
|
||||
|
||||
#ifdef TEST
|
||||
#include "ctest.h"
|
||||
void testBinaryOutput(
|
||||
|
||||
@@ -28,7 +28,10 @@ LINT = splint
|
||||
# avrispmkII = AVR ISP MKII
|
||||
# avr109 = bootloader
|
||||
#AVRDUDE_PROGRAMMERID = avr109
|
||||
AVRDUDE_PROGRAMMERID = jtag2fast
|
||||
#AVRDUDE_PROGRAMMERID = jtag2fast
|
||||
#AVRDUDE_PROGRAMMERID = avrispmkII
|
||||
#AVRDUDE_PROGRAMMERID = dragon_isp
|
||||
AVRDUDE_PROGRAMMERID = dragon_jtag
|
||||
#
|
||||
# port--serial or parallel port to which your
|
||||
# hardware programmer is attached
|
||||
@@ -36,7 +39,6 @@ AVRDUDE_PROGRAMMERID = jtag2fast
|
||||
AVRDUDE_PORT = usb
|
||||
#AVRDUDE_PORT = /dev/ttyUSB0
|
||||
|
||||
|
||||
# Source locations
|
||||
BACNET_CORE = ../../src
|
||||
BACNET_INCLUDE = ../../include
|
||||
@@ -133,13 +135,18 @@ DEFINES =
|
||||
|
||||
OPTIMIZE_FLAGS = -mcall-prologues
|
||||
OPTIMIZE_FLAGS += -finline-functions-called-once
|
||||
# default optimization is for debugging from AVR Studio
|
||||
# default is for debugging from AVR Studio
|
||||
OPTIMIZATION = -O0
|
||||
DEBUGGING = -g
|
||||
ifeq (${BUILD},debug)
|
||||
OPTIMIZATION = -O0
|
||||
DEBUGGING = -g
|
||||
endif
|
||||
ifeq (${BUILD},release)
|
||||
OPTIMIZATION = -Os $(OPTIMIZE_FLAGS)
|
||||
DEBUGGING =
|
||||
endif#
|
||||
endif
|
||||
|
||||
|
||||
## BACnet options
|
||||
BFLAGS = -DBACDL_MSTP
|
||||
@@ -201,7 +208,7 @@ AVRDUDE_FLAGS += -p $(AVRDUDE_MCU)
|
||||
AVRDUDE_FLAGS += -P $(AVRDUDE_PORT)
|
||||
|
||||
# Fuse high byte (0=enable,1=disable):
|
||||
# 0x92 = 1 0 0 1 0 0 1 0
|
||||
# 0x93 = 1 0 0 1 0 0 1 1
|
||||
# ^ ^ ^ ^ ^ \+/ ^
|
||||
# | | | | | | |---- BOOTRST (Enable Bootloader Reset Vector)
|
||||
# | | | | | +------- BOOTSZ 1..0 (Select Boot Size)
|
||||
@@ -238,7 +245,9 @@ AVRDUDE_FLAGS += -P $(AVRDUDE_PORT)
|
||||
# | | +----------------
|
||||
# | +------------------
|
||||
# +--------------------
|
||||
AVRDUDE_WRITE_FUSES = -U hfuse:w:0x92:m -U lfuse:w:0xC7:m -U efuse:w:0xFC:m
|
||||
AVRDUDE_WRITE_FUSES = -U hfuse:w:0x93:m -U lfuse:w:0xC7:m -U efuse:w:0xFC:m
|
||||
|
||||
AVRDUDE_BOOTL_FUSES = -U hfuse:w:0x92:m -U lfuse:w:0xC7:m -U efuse:w:0xFC:m
|
||||
|
||||
AVRDUDE_READ_FUSES = -U lfuse:r:-:h -U hfuse:r:-:h -U efuse:r:-:h
|
||||
|
||||
@@ -295,6 +304,9 @@ install: $(TARGET_ELF)
|
||||
writefuses:
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES)
|
||||
|
||||
bootloadfuses:
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_BOOTL_FUSES)
|
||||
|
||||
showfuses:
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_READ_FUSES)
|
||||
|
||||
|
||||
@@ -169,15 +169,13 @@ unsigned Binary_Output_Instance_To_Index(
|
||||
return index;
|
||||
}
|
||||
|
||||
static BACNET_BINARY_PV Binary_Output_Present_Value(
|
||||
uint32_t object_instance)
|
||||
static BACNET_BINARY_PV Present_Value(
|
||||
unsigned int index)
|
||||
{
|
||||
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
|
||||
BACNET_BINARY_PV current_value = RELINQUISH_DEFAULT;
|
||||
unsigned index = 0;
|
||||
unsigned i = 0;
|
||||
|
||||
index = Binary_Output_Instance_To_Index(object_instance);
|
||||
|
||||
if (index < MAX_BINARY_OUTPUTS) {
|
||||
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
|
||||
current_value = Binary_Output_Level[index][i];
|
||||
@@ -191,16 +189,26 @@ static BACNET_BINARY_PV Binary_Output_Present_Value(
|
||||
return value;
|
||||
}
|
||||
|
||||
static void Binary_Output_Sync(
|
||||
static BACNET_BINARY_PV Binary_Output_Present_Value(
|
||||
uint32_t object_instance)
|
||||
{
|
||||
BACNET_BINARY_PV pv = Binary_Output_Present_Value(object_instance);
|
||||
unsigned index = Binary_Output_Instance_To_Index(object_instance);
|
||||
unsigned index = 0;
|
||||
|
||||
index = Binary_Output_Instance_To_Index(object_instance);
|
||||
|
||||
return Present_Value(index);
|
||||
}
|
||||
|
||||
void Binary_Output_Level_Sync(
|
||||
unsigned int index)
|
||||
{
|
||||
BACNET_BINARY_PV pv;
|
||||
|
||||
if (index < MAX_BINARY_OUTPUTS) {
|
||||
if (Out_Of_Service[index]) {
|
||||
return;
|
||||
}
|
||||
pv = Present_Value(index);
|
||||
if (Polarity[index] == POLARITY_REVERSE) {
|
||||
if (pv == BINARY_INACTIVE) {
|
||||
pv = BINARY_ACTIVE;
|
||||
@@ -421,7 +429,7 @@ bool Binary_Output_Write_Property(
|
||||
level = (BACNET_BINARY_PV) value.type.Enumerated;
|
||||
priority--;
|
||||
Binary_Output_Level_Set(object_index, priority, level);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
Binary_Output_Level_Sync(object_index);
|
||||
status = true;
|
||||
} else if (priority == 6) {
|
||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||
@@ -439,7 +447,7 @@ bool Binary_Output_Write_Property(
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||
priority--;
|
||||
Binary_Output_Level_Set(object_index, priority, level);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
Binary_Output_Level_Sync(object_index);
|
||||
status = true;
|
||||
} else if (priority == 6) {
|
||||
/* Command priority 6 is reserved for use by Minimum On/Off
|
||||
@@ -460,7 +468,7 @@ bool Binary_Output_Write_Property(
|
||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||
Binary_Output_Out_Of_Service_Set(object_index,
|
||||
value.type.Boolean);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
Binary_Output_Level_Sync(object_index);
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
@@ -472,7 +480,7 @@ bool Binary_Output_Write_Property(
|
||||
if (value.type.Enumerated < MAX_POLARITY) {
|
||||
Binary_Output_Polarity_Set(object_index,
|
||||
value.type.Enumerated);
|
||||
Binary_Output_Sync(wp_data->object_instance);
|
||||
Binary_Output_Level_Sync(object_index);
|
||||
status = true;
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
@@ -514,7 +522,7 @@ void Binary_Output_Init(
|
||||
NV_SEEPROM_BO_PRIORITY_ARRAY_1 + j),
|
||||
&Binary_Output_Level[i][j], 1);
|
||||
}
|
||||
Binary_Output_Sync(i);
|
||||
Binary_Output_Level_Sync(i);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -90,7 +90,10 @@ LDFLAGS = -Ttext=$(BASEADDR) $(EXTMEMOPTS) $(LDMAP) $(PRINTF_LIB) $(SCANF_LIB) $
|
||||
# jtag2fast = Atmel JTAG ICE mkII, running at 115200 Bd
|
||||
# jtag2slow = Atmel JTAG ICE mkII, running at 19200 Bd
|
||||
# avrispmkII = AVR ISP MKII
|
||||
AVRDUDE_PROGRAMMER = jtag2fast
|
||||
#AVRDUDE_PROGRAMMER = jtag2fast
|
||||
#AVRDUDE_PROGRAMMER = avrispmkII
|
||||
#AVRDUDE_PROGRAMMER = dragon_isp
|
||||
AVRDUDE_PROGRAMMER = dragon_jtag
|
||||
#
|
||||
# # port--serial or parallel port to which your
|
||||
# # hardware programmer is attached
|
||||
@@ -109,7 +112,7 @@ AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level. Please use this when submitting bug
|
||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||
|
||||
@@ -189,7 +189,7 @@ static uint8_t TransmitPacketDest;
|
||||
/* node must wait for a remote node to begin using a token or replying to */
|
||||
/* a Poll For Master frame: 20 milliseconds. (Implementations may use */
|
||||
/* larger values for this timeout, not to exceed 100 milliseconds.) */
|
||||
#define Tusage_timeout 25
|
||||
#define Tusage_timeout 60
|
||||
|
||||
/* The number of tokens received or used before a Poll For Master cycle */
|
||||
/* is executed: 50. */
|
||||
|
||||
@@ -52,4 +52,15 @@
|
||||
#define SEEPROM_PAGE_SIZE 16
|
||||
#define SEEPROM_WORD_ADDRESS_16BIT 0
|
||||
|
||||
/* reserve the millisecond timer indexes as needed for each module */
|
||||
#define TIMER_SILENCE 0
|
||||
#define TIMER_DEBOUNCE 1
|
||||
#define TIMER_LED_1 2
|
||||
#define TIMER_LED_2 3
|
||||
#define TIMER_LED_3 4
|
||||
#define TIMER_LED_4 5
|
||||
#define TIMER_DCC 6
|
||||
#define TIMER_TEST 7
|
||||
#define MAX_MILLISECOND_TIMERS 8
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,10 +25,46 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "hardware.h"
|
||||
#include "timer.h"
|
||||
|
||||
static uint8_t Address_Switch;
|
||||
static uint8_t Buttons;
|
||||
|
||||
#define BDK_V1_HACK 0
|
||||
|
||||
#if BDK_V1_HACK
|
||||
/* version 1 BDK workaournd for floating inputs */
|
||||
static void input_switch_workaround(void)
|
||||
{
|
||||
/* configure the port pins for the switch - as outputs */
|
||||
BIT_SET(DDRA, DDA0);
|
||||
BIT_SET(DDRA, DDA1);
|
||||
BIT_SET(DDRA, DDA2);
|
||||
BIT_SET(DDRA, DDA3);
|
||||
BIT_SET(DDRA, DDA4);
|
||||
BIT_SET(DDRA, DDA5);
|
||||
BIT_SET(DDRA, DDA6);
|
||||
/* turn off the outputs */
|
||||
BIT_CLEAR(PORTA, PA0);
|
||||
BIT_CLEAR(PORTA, PA1);
|
||||
BIT_CLEAR(PORTA, PA2);
|
||||
BIT_CLEAR(PORTA, PA3);
|
||||
BIT_CLEAR(PORTA, PA4);
|
||||
BIT_CLEAR(PORTA, PA5);
|
||||
BIT_CLEAR(PORTA, PA6);
|
||||
/* configure the port pins for the switch - as inputs */
|
||||
BIT_CLEAR(DDRA, DDA0);
|
||||
BIT_CLEAR(DDRA, DDA1);
|
||||
BIT_CLEAR(DDRA, DDA2);
|
||||
BIT_CLEAR(DDRA, DDA3);
|
||||
BIT_CLEAR(DDRA, DDA4);
|
||||
BIT_CLEAR(DDRA, DDA5);
|
||||
BIT_CLEAR(DDRA, DDA6);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* debounce the inputs */
|
||||
void input_task(
|
||||
void)
|
||||
@@ -37,23 +73,32 @@ void input_task(
|
||||
static uint8_t old_address = 0;
|
||||
static uint8_t old_buttons = 0;
|
||||
|
||||
value = BITMASK_CHECK(PINA, 0x7F);
|
||||
if (value != old_address) {
|
||||
old_address = value;
|
||||
} else {
|
||||
if (old_address != Address_Switch) {
|
||||
/* only check the inputs every debounce time */
|
||||
if (timer_elapsed_milliseconds(TIMER_DEBOUNCE,30)) {
|
||||
timer_reset(TIMER_DEBOUNCE);
|
||||
/* pins used are PA6, PA5, PA4, PA3, PA2, PA1, PA0 */
|
||||
#if BDK_V1_HACK
|
||||
/* version 1 BDK - workaround */
|
||||
value = (PINA&0x7F);
|
||||
#else
|
||||
/* version 2 BDK - has inverted inputs */
|
||||
value = ~PINA;
|
||||
value &= 0x7F;
|
||||
#endif
|
||||
if (value == old_address) {
|
||||
/* stable value */
|
||||
Address_Switch = old_address;
|
||||
}
|
||||
}
|
||||
/* pins used are PB4, PB3, PB2, PB1, PB0 */
|
||||
value = BITMASK_CHECK(PINB, 0x1F);
|
||||
if (value != old_buttons) {
|
||||
old_buttons = value;
|
||||
} else {
|
||||
if (old_buttons != Buttons) {
|
||||
old_address = value;
|
||||
/* pins used are PB4, PB3, PB2, PB1, PB0 */
|
||||
value = BITMASK_CHECK(PINB, 0x1F);
|
||||
if (value == old_buttons) {
|
||||
Buttons = old_buttons;
|
||||
}
|
||||
}
|
||||
#if BDK_V1_HACK
|
||||
input_switch_workaround();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t input_address(
|
||||
@@ -102,9 +147,18 @@ void input_init(
|
||||
BIT_CLEAR(DDRA, DDA4);
|
||||
BIT_CLEAR(DDRA, DDA5);
|
||||
BIT_CLEAR(DDRA, DDA6);
|
||||
/* activate the internal pull up resistors */
|
||||
BIT_SET(PORTA, PA0);
|
||||
BIT_SET(PORTA, PA1);
|
||||
BIT_SET(PORTA, PA2);
|
||||
BIT_SET(PORTA, PA3);
|
||||
BIT_SET(PORTA, PA4);
|
||||
BIT_SET(PORTA, PA5);
|
||||
BIT_SET(PORTA, PA6);
|
||||
/* configure the port pins for binary inputs */
|
||||
BIT_CLEAR(DDRB, DDB1);
|
||||
BIT_CLEAR(DDRB, DDB2);
|
||||
BIT_CLEAR(DDRB, DDB3);
|
||||
BIT_CLEAR(DDRB, DDB4);
|
||||
timer_reset(TIMER_DEBOUNCE);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ static void bacnet_task(
|
||||
|
||||
mstp_mac_address = input_address();
|
||||
if (MSTP_MAC_Address != mstp_mac_address) {
|
||||
/* address changed! */
|
||||
MSTP_MAC_Address = mstp_mac_address;
|
||||
dlmstp_set_mac_address(MSTP_MAC_Address);
|
||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||
@@ -153,24 +154,63 @@ static void bacnet_task(
|
||||
void idle_init(
|
||||
void)
|
||||
{
|
||||
timer_reset(TIMER_LED_3);
|
||||
timer_reset(TIMER_LED_4);
|
||||
}
|
||||
|
||||
void idle_task(
|
||||
void)
|
||||
{
|
||||
#if 0
|
||||
/* blink the leds */
|
||||
if (timer_elapsed_seconds(TIMER_LED_3, 1)) {
|
||||
timer_reset(TIMER_LED_3);
|
||||
led_toggle(LED_3);
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
void test_init(void)
|
||||
{
|
||||
timer_reset(TIMER_LED_3);
|
||||
timer_reset(TIMER_LED_4);
|
||||
timer_reset(TIMER_TEST);
|
||||
}
|
||||
|
||||
void test_task(
|
||||
void)
|
||||
{
|
||||
uint8_t buffer[32] = "BACnet: 0000000\r\n";
|
||||
uint8_t nbytes = 17;
|
||||
uint8_t data_register = 0;
|
||||
|
||||
if (timer_elapsed_seconds(TIMER_TEST, 1)) {
|
||||
timer_reset(TIMER_TEST);
|
||||
buffer[8] = (MSTP_MAC_Address&BIT0)?'1':'0';
|
||||
buffer[9] = (MSTP_MAC_Address&BIT1)?'1':'0';
|
||||
buffer[10] = (MSTP_MAC_Address&BIT2)?'1':'0';
|
||||
buffer[11] = (MSTP_MAC_Address&BIT3)?'1':'0';
|
||||
buffer[12] = (MSTP_MAC_Address&BIT4)?'1':'0';
|
||||
buffer[13] = (MSTP_MAC_Address&BIT5)?'1':'0';
|
||||
buffer[14] = (MSTP_MAC_Address&BIT6)?'1':'0';
|
||||
serial_bytes_send(buffer, nbytes);
|
||||
}
|
||||
if (timer_elapsed_milliseconds(TIMER_LED_4, 125)) {
|
||||
timer_reset(TIMER_LED_4);
|
||||
led_toggle(LED_4);
|
||||
if (serial_byte_get(&data_register)) {
|
||||
if (data_register == '0') {
|
||||
Binary_Output_Level_Set(0, 1, BINARY_INACTIVE);
|
||||
Binary_Output_Level_Sync(0);
|
||||
Binary_Output_Level_Set(1, 1, BINARY_INACTIVE);
|
||||
Binary_Output_Level_Sync(1);
|
||||
}
|
||||
if (data_register == '1') {
|
||||
Binary_Output_Level_Set(0, 1, BINARY_ACTIVE);
|
||||
Binary_Output_Level_Sync(0);
|
||||
Binary_Output_Level_Set(1, 1, BINARY_ACTIVE);
|
||||
Binary_Output_Level_Sync(1);
|
||||
}
|
||||
if (data_register == '2') {
|
||||
Binary_Output_Level_Set(0, 1, BINARY_NULL);
|
||||
Binary_Output_Level_Sync(0);
|
||||
Binary_Output_Level_Set(1, 1, BINARY_NULL);
|
||||
Binary_Output_Level_Sync(1);
|
||||
}
|
||||
serial_byte_send(data_register);
|
||||
serial_byte_send('\r');
|
||||
serial_byte_send('\n');
|
||||
serial_byte_transmit_complete();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(
|
||||
@@ -186,6 +226,7 @@ int main(
|
||||
serial_init();
|
||||
bacnet_init();
|
||||
idle_init();
|
||||
test_init();
|
||||
/* Enable global interrupts */
|
||||
__enable_interrupt();
|
||||
for (;;) {
|
||||
@@ -193,5 +234,6 @@ int main(
|
||||
bacnet_task();
|
||||
led_task();
|
||||
idle_task();
|
||||
test_task();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,14 +108,26 @@ void serial_bytes_send(
|
||||
void serial_byte_send(
|
||||
uint8_t ch)
|
||||
{
|
||||
uint8_t buffer[1];
|
||||
|
||||
buffer[0] = ch;
|
||||
serial_bytes_send(&buffer[0], 1);
|
||||
while (!BIT_CHECK(UCSR1A, UDRE1)) {
|
||||
/* do nothing - wait until Tx buffer is empty */
|
||||
}
|
||||
/* Send the data byte */
|
||||
UDR1 = ch;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void serial_byte_transmit_complete(void)
|
||||
{
|
||||
/* was the frame sent? */
|
||||
while (!BIT_CHECK(UCSR1A, TXC1)) {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
uint32_t serial_baud_rate(
|
||||
void)
|
||||
{
|
||||
|
||||
@@ -38,8 +38,11 @@ extern "C" {
|
||||
void serial_bytes_send(
|
||||
uint8_t * buffer, /* data to send */
|
||||
uint16_t nbytes); /* number of bytes of data */
|
||||
|
||||
/* byte transmit */
|
||||
void serial_byte_send(
|
||||
uint8_t ch);
|
||||
void serial_byte_transmit_complete(void);
|
||||
|
||||
uint32_t serial_baud_rate(
|
||||
void);
|
||||
|
||||
@@ -26,17 +26,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "hardware.h"
|
||||
|
||||
/* Timer Module */
|
||||
/* reserve the millisecond timer indexes as needed for each module */
|
||||
#define TIMER_SILENCE 0
|
||||
#define TIMER_DEBOUNCE 1
|
||||
#define TIMER_LED_1 2
|
||||
#define TIMER_LED_2 3
|
||||
#define TIMER_LED_3 4
|
||||
#define TIMER_LED_4 5
|
||||
#define TIMER_DCC 6
|
||||
#define MAX_MILLISECOND_TIMERS 7
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
Reference in New Issue
Block a user