Initial commit
commit
b5b9383d4e
@ -0,0 +1,5 @@
|
||||
*.hex
|
||||
*.lst
|
||||
*.elf
|
||||
*.o
|
||||
*.map
|
@ -0,0 +1,38 @@
|
||||
PROJ = avr-eb
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
CPU = atmega88
|
||||
|
||||
CFLAGS += -Os -g -mmcu=$(CPU) -Wall
|
||||
CFLAGS += -Wa,-adhlns=$(<:%.c=%.lst)
|
||||
|
||||
CLDFLAGS += -mmcu=$(CPU) -Wl,-Map=$(@:%.elf=%.map)
|
||||
|
||||
TESTOBJS += testnode.o testhbw.o
|
||||
RELAISOBJS += relaisnode.o relaishbw.o
|
||||
|
||||
all: testnode.hex relaisnode.hex
|
||||
|
||||
testnode.o: testnode.c hbw.h hw.h testhw.h
|
||||
$(CC) $(CFLAGS) -DTESTNODE -c $< -o $@
|
||||
|
||||
testhbw.o: hbw.c hbw.h hw.h testhw.h
|
||||
$(CC) $(CFLAGS) -DTESTNODE -c $< -o $@
|
||||
|
||||
testnode.elf: $(TESTOBJS)
|
||||
$(CC) $(CLDFLAGS) -o $@ $(TESTOBJS)
|
||||
|
||||
relaisnode.o: relaisnode.c hbw.h hw.h relaishw.h
|
||||
$(CC) $(CFLAGS) -DRELAISNODE -c $< -o $@
|
||||
|
||||
relaishbw.o: hbw.c hbw.h hw.h relaishw.h
|
||||
$(CC) $(CFLAGS) -DRELAISNODE -c $< -o $@
|
||||
|
||||
relaisnode.elf: $(RELAISOBJS)
|
||||
$(CC) $(CLDFLAGS) -o $@ $(RELAISOBJS)
|
||||
|
||||
%hex:%elf
|
||||
$(OBJCOPY) -j .text -j .data -O srec $< $@
|
||||
|
||||
clean:
|
||||
rm -f *.hex *.elf *.o *.lst *.map
|
@ -0,0 +1,7 @@
|
||||
#ifndef __ALARMHW_H__
|
||||
#define __ALARMHW_H__
|
||||
#define RedLED PD4
|
||||
#define GreenLED PD5
|
||||
#define BuzzerON PD6
|
||||
#define ReedSwitch PD7
|
||||
#endif
|
@ -0,0 +1,130 @@
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include "alarmhw.h"
|
||||
#include "rs485.h"
|
||||
#include "eb.h"
|
||||
|
||||
uint8_t reedstate;
|
||||
uint8_t buzzerstate;
|
||||
|
||||
uint8_t waitforack;
|
||||
uint8_t waitforsend;
|
||||
uint8_t acktimer;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
init_rs485();
|
||||
DDRD |= (1<<RedLED);
|
||||
DDRD |= (1<<GreenLED);
|
||||
DDRD |= (1<<BuzzerON);
|
||||
DDRD &= ~(1<<ReedSwitch);
|
||||
|
||||
PORTD &= ~(1<<RedLED);
|
||||
PORTD |= (1<<GreenLED);
|
||||
PORTD &= ~(1<<BuzzerON);
|
||||
PORTD |= (1<<ReedSwitch);
|
||||
|
||||
ADMUX = (0<<REFS1) | (1<<REFS0);
|
||||
ADCSRA = (1<<ADPS2) | (1<<ADPS1);
|
||||
ADCSRA |= (1<<ADEN);
|
||||
ADCSRA |= (1<<ADSC);
|
||||
loop_until_bit_is_clear(ADCSRA, ADSC);
|
||||
svalue = ADCW;
|
||||
|
||||
my_address = eeprom_read_byte((const uint8_t *)0);
|
||||
my_prio = eeprom_read_byte((const uint8_t *)1);
|
||||
master = eeprom_read_byte((const uint8_t *)2);
|
||||
|
||||
buzzerstate = 0;
|
||||
reedstate = 0;
|
||||
|
||||
waitforsend = 0;
|
||||
acktimer = 0;
|
||||
|
||||
sei();
|
||||
while(1) {
|
||||
rs485_loop();
|
||||
if (rflag) {
|
||||
if (rsender)
|
||||
srecv = rsender;
|
||||
else
|
||||
srecv = master;
|
||||
smode = 0;
|
||||
if ((rrecv == my_address) && (rmode == 2)) {
|
||||
acktimer = 0;
|
||||
waitforsend = 0;
|
||||
}
|
||||
|
||||
if ((rrecv == my_address) && (rmode == 0)) {
|
||||
for (i=0; i<4; i++) {
|
||||
decodepart(i);
|
||||
scommand = 0;
|
||||
schannel = rchannel;
|
||||
if ((rcommand == 0x40) && (rchannel == 0)) {
|
||||
scommand = 0x40;
|
||||
svalue = 2; /* 2 LED keys + 4 ADCs */
|
||||
}
|
||||
if ((rcommand == 0x60) && (rchannel == 1)) {
|
||||
if (rvalue & 0x02) {
|
||||
buzzerstate = ~0;
|
||||
PORTD |= (1<<BuzzerON);
|
||||
} else {
|
||||
buzzerstate = 0;
|
||||
PORTD &= ~(1<<BuzzerON);
|
||||
}
|
||||
scommand = 0x40;
|
||||
svalue = (reedstate & 0x01) | (buzzerstate & 0x02);
|
||||
}
|
||||
if ((rcommand == 0x40) && (rchannel == 1)) {
|
||||
scommand = 0x40;
|
||||
svalue = (reedstate & 0x01) | (buzzerstate & 0x02);
|
||||
}
|
||||
if ((rcommand == 0x40) && ((rchannel > 1) && (rchannel < 6))) {
|
||||
ADMUX = (ADMUX & ~(0x1F)) | (rchannel - 2);
|
||||
ADCSRA |= (1<<ADSC);
|
||||
loop_until_bit_is_clear(ADCSRA, ADSC);
|
||||
scommand = 0x40;
|
||||
svalue = ADCW;
|
||||
}
|
||||
encodepart(i);
|
||||
}
|
||||
smode = 0;
|
||||
sendmsg();
|
||||
acktimer = 0;
|
||||
waitforsend = 0;
|
||||
}
|
||||
if ((rrecv == 0) && (rmode == 0) && waitforsend) {
|
||||
if (!acktimer) {
|
||||
scommand = 0x40;
|
||||
schannel = 1;
|
||||
svalue = (reedstate & 0x01) | (buzzerstate & 0x02);
|
||||
encodepart(0);
|
||||
scommand = 0;
|
||||
encodepart(1);
|
||||
encodepart(2);
|
||||
encodepart(3);
|
||||
smode = 1;
|
||||
sendmsg();
|
||||
acktimer = my_prio;
|
||||
} else
|
||||
acktimer--;
|
||||
}
|
||||
rflag = 0;
|
||||
}
|
||||
if (bit_is_clear(PIND, ReedSwitch) && (!reedstate)) {
|
||||
reedstate = ~0;
|
||||
waitforsend = ~0;
|
||||
PORTD |= (1<<RedLED);
|
||||
PORTD &= ~(1<<GreenLED);
|
||||
}
|
||||
if (bit_is_set(PIND, ReedSwitch) && reedstate) {
|
||||
reedstate = 0;
|
||||
waitforsend = ~0;
|
||||
PORTD &= ~(1<<RedLED);
|
||||
PORTD |= (1<<GreenLED);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,758 @@
|
||||
#include "hw.h"
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "hbw.h"
|
||||
|
||||
uint32_t my_address;
|
||||
|
||||
uint8_t rind;
|
||||
uint16_t rcrc;
|
||||
uint32_t raddress;
|
||||
uint32_t rdest;
|
||||
uint8_t resc;
|
||||
uint8_t rctl;
|
||||
volatile uint8_t rready;
|
||||
uint8_t rmessage[62];
|
||||
uint8_t rlen;
|
||||
|
||||
uint8_t sind;
|
||||
uint8_t sdisc;
|
||||
uint8_t sctl;
|
||||
uint16_t scrc;
|
||||
uint8_t sesc;
|
||||
uint32_t saddress;
|
||||
uint8_t slen;
|
||||
uint8_t smessage[62];
|
||||
uint8_t slocked;
|
||||
uint8_t sbusy;
|
||||
|
||||
volatile uint16_t sdelay;
|
||||
|
||||
uint8_t waitack;
|
||||
uint32_t aaddress;
|
||||
uint8_t actl;
|
||||
uint8_t alen;
|
||||
uint8_t alink;
|
||||
uint8_t amessage[62];
|
||||
|
||||
uint8_t asent;
|
||||
uint8_t dsent;
|
||||
uint8_t gotack;
|
||||
|
||||
uint8_t configled;
|
||||
uint8_t configbutton;
|
||||
uint8_t configstate;
|
||||
uint16_t configtimer;
|
||||
|
||||
static uint16_t crc16shift(uint16_t crc, uint8_t data)
|
||||
{
|
||||
int stat, i;
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
stat = crc & 0x8000;
|
||||
crc = crc << 1;
|
||||
if (data & 0x80)
|
||||
crc = crc | 1;
|
||||
|
||||
if (stat)
|
||||
crc = crc ^ 0x1002;
|
||||
|
||||
data = data << 1;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
static void readaddr(void)
|
||||
{
|
||||
((uint8_t*)&my_address)[0]=eeprom_read_byte((const uint8_t *)EESIZE-4);
|
||||
((uint8_t*)&my_address)[1]=eeprom_read_byte((const uint8_t *)EESIZE-3);
|
||||
((uint8_t*)&my_address)[2]=eeprom_read_byte((const uint8_t *)EESIZE-2);
|
||||
((uint8_t*)&my_address)[3]=eeprom_read_byte((const uint8_t *)EESIZE-1);
|
||||
|
||||
if (my_address == 0xFFFFFFFF)
|
||||
((uint8_t*)&my_address)[0] = 0x42;
|
||||
}
|
||||
|
||||
static void send(uint8_t i,uint8_t crc)
|
||||
{
|
||||
if (bit_is_set(UCSR0A, UDRE0)) {
|
||||
if (sesc) {
|
||||
UDR0 = i & 0x7F;
|
||||
sind++;
|
||||
sesc = 0;
|
||||
return;
|
||||
}
|
||||
if (crc == 1) {
|
||||
scrc = crc16shift(scrc, i);
|
||||
}
|
||||
if (crc == 2) {
|
||||
scrc = crc16shift(scrc, 0);
|
||||
scrc = crc16shift(scrc, 0);
|
||||
i = (scrc >> 8) & 0xFF;
|
||||
}
|
||||
if ((i == 0xFD) || (i == 0xFC) || (i == 0xFE)) {
|
||||
UDR0 = 0xFC;
|
||||
sesc = 1;
|
||||
return;
|
||||
}
|
||||
UDR0 = i;
|
||||
sind++;
|
||||
}
|
||||
}
|
||||
|
||||
void rloop(void)
|
||||
{
|
||||
if (!sind)
|
||||
return;
|
||||
|
||||
if (sdisc) {
|
||||
if (sind == 1) {
|
||||
send(0x04,1);
|
||||
return;
|
||||
}
|
||||
if (sind == 2) {
|
||||
send(0x01,1);
|
||||
return;
|
||||
}
|
||||
if (sind == 3) {
|
||||
send((scrc >> 8) & 0xFF,2);
|
||||
return;
|
||||
}
|
||||
if (sind == 4) {
|
||||
send(scrc & 0xFF,0);
|
||||
return;
|
||||
}
|
||||
if (bit_is_set(UCSR0A, TXC0)) {
|
||||
PORTD &= ~(1<<SenderEnable);
|
||||
PORTD &= ~(1<<ReceiverDisable);
|
||||
sind = 0;
|
||||
sdisc = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (sind < 5) {
|
||||
send(((uint8_t*)&saddress)[sind-1],1);
|
||||
return;
|
||||
}
|
||||
if (sind == 5) {
|
||||
send(sctl,1);
|
||||
return;
|
||||
}
|
||||
if (sind < 10) {
|
||||
send(((uint8_t*)&my_address)[sind-6],1);
|
||||
return;
|
||||
}
|
||||
if (sind == 10) {
|
||||
send(slen+2,1);
|
||||
return;
|
||||
}
|
||||
if (sind < slen+10) {
|
||||
send(smessage[sind-11],1);
|
||||
return;
|
||||
}
|
||||
if (sind == slen+10) {
|
||||
send(smessage[sind-11],1);
|
||||
return;
|
||||
}
|
||||
if (sind == slen+11) {
|
||||
send((scrc >> 8) & 0xFF,2);
|
||||
return;
|
||||
}
|
||||
if (sind == slen+12) {
|
||||
send(scrc & 0xFF,0);
|
||||
return;
|
||||
}
|
||||
if (bit_is_set(UCSR0A, TXC0)) {
|
||||
PORTD &= ~(1<<SenderEnable);
|
||||
PORTD &= ~(1<<ReceiverDisable);
|
||||
sind = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t sendmsg(void)
|
||||
{
|
||||
if (sind)
|
||||
return 0;
|
||||
|
||||
PORTD |= (1<<SenderEnable);
|
||||
PORTD |= (1<<ReceiverDisable);
|
||||
UCSR0A = (1<<TXC0);
|
||||
|
||||
scrc = crc16shift(0xFFFF, 0xFD);
|
||||
UDR0 = 0xFD;
|
||||
sind = 1;
|
||||
sesc = 0;
|
||||
sdisc = 0;
|
||||
return ~0;
|
||||
}
|
||||
|
||||
static uint8_t senddsc(void)
|
||||
{
|
||||
if (sind)
|
||||
return 0;
|
||||
|
||||
PORTD |= (1<<SenderEnable);
|
||||
PORTD |= (1<<ReceiverDisable);
|
||||
UCSR0A = (1<<TXC0);
|
||||
|
||||
scrc = crc16shift(0xFFFF, 0xFE);
|
||||
UDR0 = 0xFE;
|
||||
sind = 1;
|
||||
sesc = 0;
|
||||
dsent = 1;
|
||||
sdisc = 1;
|
||||
sdelay = 1000 + (rand() & 0x1F);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
static uint8_t is_bus_free(void)
|
||||
{
|
||||
|
||||
if(sdelay || slocked || sind)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void announce(void)
|
||||
{
|
||||
sctl = 0xF8;
|
||||
|
||||
saddress = 0xFFFFFFFF;
|
||||
|
||||
slen = 16;
|
||||
|
||||
smessage[0] = 0x41;
|
||||
smessage[1] = 0;
|
||||
smessage[2] = HBWTYPE;
|
||||
smessage[3] = 0;
|
||||
smessage[4] = HBWMAJOR;
|
||||
smessage[5] = HBWMINOR;
|
||||
smessage[6] = HBWSERIAL0;
|
||||
smessage[7] = HBWSERIAL1;
|
||||
smessage[8] = HBWSERIAL2;
|
||||
smessage[9] = HBWSERIAL3;
|
||||
smessage[10] = HBWSERIAL4;
|
||||
smessage[11] = HBWSERIAL5;
|
||||
smessage[12] = HBWSERIAL6;
|
||||
smessage[13] = HBWSERIAL7;
|
||||
smessage[14] = HBWSERIAL8;
|
||||
smessage[15] = HBWSERIAL9;
|
||||
|
||||
if (sendmsg())
|
||||
asent = 1;
|
||||
}
|
||||
|
||||
void hbw_init(void)
|
||||
{
|
||||
DDRD |= (1<<SenderEnable);
|
||||
DDRD |= (1<<ReceiverDisable);
|
||||
|
||||
PORTD &= ~(1<<SenderEnable);
|
||||
PORTD &= ~(1<<ReceiverDisable);
|
||||
|
||||
#ifdef ConfigButton
|
||||
DDRD &= ~(1<<ConfigButton);
|
||||
PORTD |= (1<<ConfigButton);
|
||||
#endif
|
||||
|
||||
#ifdef ConfigLED
|
||||
DDRD |= (1<<ConfigLED);
|
||||
PORTD &= ~(1<<ConfigLED);
|
||||
#endif
|
||||
|
||||
UBRR0L = ((F_CPU/(BAUDRATE*16))-1) & 0xFF;
|
||||
UBRR0H = 0;
|
||||
UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0);
|
||||
UCSR0C = (1 << UPM01) | (1 << UCSZ01) | (1 << UCSZ00);
|
||||
|
||||
OCR2A = 249;
|
||||
TIMSK2 |= (1 << OCIE2A);
|
||||
TCCR2A |= (1 << WGM21);
|
||||
TCCR2B = TCCR2B | (1 << CS22);
|
||||
|
||||
rind = 0;
|
||||
sind = 0;
|
||||
sdisc = 0;
|
||||
rready = 0;
|
||||
asent = 0;
|
||||
dsent = 0;
|
||||
hbw_timer = 0;
|
||||
gotack = 0;
|
||||
waitack = 0;
|
||||
configled = 0;
|
||||
configbutton = 0;
|
||||
configstate = 0;
|
||||
slocked = 0;
|
||||
sbusy = 0;
|
||||
alink = 0;
|
||||
|
||||
readaddr();
|
||||
hbw_read_config();
|
||||
srand(my_address);
|
||||
sdelay = 1000 + (rand() & 0x1F);
|
||||
sei();
|
||||
}
|
||||
|
||||
void snext(void)
|
||||
{
|
||||
#ifdef HBW_MAXLINKS
|
||||
uint8_t linkchannel;
|
||||
|
||||
if (amessage[0] != 'K') {
|
||||
alink = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
while (alink < HBW_MAXLINKS) {
|
||||
linkchannel = eeprom_read_byte((const uint8_t *)(alink*6)+HBW_LINKOFFS);
|
||||
if (amessage[1] == linkchannel) {
|
||||
((uint8_t*)&aaddress)[0]=eeprom_read_byte((const uint8_t *)(alink*6)+HBW_LINKOFFS+1);
|
||||
((uint8_t*)&aaddress)[1]=eeprom_read_byte((const uint8_t *)(alink*6)+HBW_LINKOFFS+2);
|
||||
((uint8_t*)&aaddress)[2]=eeprom_read_byte((const uint8_t *)(alink*6)+HBW_LINKOFFS+3);
|
||||
((uint8_t*)&aaddress)[3]=eeprom_read_byte((const uint8_t *)(alink*6)+HBW_LINKOFFS+4);
|
||||
linkchannel=eeprom_read_byte((const uint8_t *)(alink*6)+HBW_LINKOFFS+5);
|
||||
if(aaddress == my_address) {
|
||||
hbw_receive_key(aaddress, amessage[1], linkchannel, amessage[3]);
|
||||
} else {
|
||||
amessage[2] = linkchannel;
|
||||
sbusy = 1;
|
||||
alink++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
alink++;
|
||||
}
|
||||
#endif
|
||||
alink = 0;
|
||||
}
|
||||
|
||||
void sprocess(void)
|
||||
{
|
||||
if (gotack) {
|
||||
gotack = 0;
|
||||
waitack = 0;
|
||||
sbusy= 0;
|
||||
snext();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_bus_free())
|
||||
return;
|
||||
|
||||
if(waitack > 2) {
|
||||
waitack = 0;
|
||||
sbusy= 0;
|
||||
snext();
|
||||
return;
|
||||
}
|
||||
|
||||
saddress = aaddress;
|
||||
sctl = actl;
|
||||
slen = alen;
|
||||
memcpy(smessage,amessage,slen);
|
||||
|
||||
if (!sendmsg())
|
||||
return;
|
||||
|
||||
if (aaddress == 0xFFFFFFFF) {
|
||||
sbusy = 0;
|
||||
snext();
|
||||
return;
|
||||
}
|
||||
waitack++;
|
||||
gotack = 0;
|
||||
sdelay = 100 + (rand() & 0x1F);
|
||||
}
|
||||
|
||||
void emessage(void)
|
||||
{
|
||||
uint8_t blocksize;
|
||||
uint8_t blocknum;
|
||||
uint8_t b,i;
|
||||
|
||||
blocksize = rmessage[3];
|
||||
blocknum = rmessage[4];
|
||||
|
||||
slen = 4 + blocknum / 8;
|
||||
if(blocknum % 8) slen++;
|
||||
memset(smessage,0,slen);
|
||||
smessage[0] = 'e';
|
||||
smessage[1] = rmessage[1];;
|
||||
smessage[2] = rmessage[2];;
|
||||
smessage[3] = rmessage[3];;
|
||||
|
||||
for(b = 0; b <= blocknum; b++) {
|
||||
for(i = 0; i < blocksize; i++) {
|
||||
if(eeprom_read_byte((const uint8_t *)(b * blocksize + i)) != 0xFF) {
|
||||
smessage[4 + b / 8] |= (1 << b % 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rprocess(void)
|
||||
{
|
||||
uint8_t seq,i;
|
||||
uint16_t addr;
|
||||
|
||||
if ((rdest == my_address) &&
|
||||
(raddress == aaddress) &&
|
||||
waitack) {
|
||||
waitack = 0;
|
||||
gotack = 1;
|
||||
}
|
||||
if ((rdest == my_address) &&
|
||||
((rctl & 0x11) == 0x10)) {
|
||||
saddress = raddress;
|
||||
seq = (rctl >> 1) & 3;
|
||||
if(!rlen)
|
||||
return;
|
||||
|
||||
switch (rmessage[0]) {
|
||||
case '@':
|
||||
if (rlen != 6)
|
||||
return;
|
||||
if (rmessage[1] == 'a') {
|
||||
eeprom_write_byte((uint8_t *)EESIZE-4, rmessage[2]);
|
||||
eeprom_write_byte((uint8_t *)EESIZE-3, rmessage[3]);
|
||||
eeprom_write_byte((uint8_t *)EESIZE-2, rmessage[4]);
|
||||
eeprom_write_byte((uint8_t *)EESIZE-1, rmessage[5]);
|
||||
|
||||
readaddr();
|
||||
}
|
||||
slen = 0;
|
||||
sctl = 0x19 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'h':
|
||||
smessage[0] = HBWTYPE;
|
||||
smessage[1] = 0;
|
||||
slen = 2;
|
||||
sctl = 0x18 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'n':
|
||||
smessage[0] = HBWSERIAL0;
|
||||
smessage[1] = HBWSERIAL1;
|
||||
smessage[2] = HBWSERIAL2;
|
||||
smessage[3] = HBWSERIAL3;
|
||||
smessage[4] = HBWSERIAL4;
|
||||
smessage[5] = HBWSERIAL5;
|
||||
smessage[6] = HBWSERIAL6;
|
||||
smessage[7] = HBWSERIAL7;
|
||||
smessage[8] = HBWSERIAL8;
|
||||
smessage[9] = HBWSERIAL9;
|
||||
slen = 10;
|
||||
seq = (rctl >> 1) & 3;
|
||||
sctl = 0x18 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'v':
|
||||
smessage[0] = HBWMAJOR;
|
||||
smessage[1] = HBWMINOR;
|
||||
slen = 2;
|
||||
seq = (rctl >> 1) & 3;
|
||||
sctl = 0x18 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'R':
|
||||
if (rlen != 4)
|
||||
return;
|
||||
if (rmessage[3] > 62)
|
||||
return;
|
||||
addr = (rmessage[1] >> 8) | rmessage[2];
|
||||
for (i = 0; i < rmessage[3]; i++)
|
||||
smessage[i] = eeprom_read_byte((const uint8_t *)addr+i);
|
||||
slen = rmessage[3];
|
||||
seq = (rctl >> 1) & 3;
|
||||
sctl = 0x18 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'W':
|
||||
if (rlen <= 4)
|
||||
return;
|
||||
if (rlen != rmessage[3] + 4)
|
||||
return;
|
||||
addr = (rmessage[1] >> 8) | rmessage[2];
|
||||
for (i = 0; i < rmessage[3]; i++)
|
||||
eeprom_write_byte((uint8_t *)addr+i, rmessage[4+i]);
|
||||
slen = 0;
|
||||
sctl = 0x19 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'x':
|
||||
case 's':
|
||||
if (rlen <= 2)
|
||||
return;
|
||||
hbw_set_channel(rmessage[1], rlen - 2, &(rmessage[2]));
|
||||
case 'S':
|
||||
if (rlen < 2)
|
||||
return;
|
||||
smessage[0] = 'i';
|
||||
smessage[1] = rmessage[1];
|
||||
slen = hbw_get_channel(rmessage[1], &(smessage[2])) + 2;
|
||||
seq = (rctl >> 1) & 3;
|
||||
sctl = 0x18 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'C':
|
||||
hbw_read_config();
|
||||
slen = 0;
|
||||
sctl = 0x19 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'K':
|
||||
case 0xCB:
|
||||
if (rlen != 4)
|
||||
return;
|
||||
hbw_receive_key(raddress, rmessage[1], rmessage[2], rmessage[3]);
|
||||
slen = 0;
|
||||
sctl = 0x19 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
case 'E':
|
||||
if (rlen != 4)
|
||||
return;
|
||||
emessage();
|
||||
seq = (rctl >> 1) & 3;
|
||||
sctl = 0x18 | (seq << 5);
|
||||
sendmsg();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((rdest == 0xFFFFFFFF) &&
|
||||
((rctl & 0x11) == 0x10)) {
|
||||
if(!rlen)
|
||||
return;
|
||||
|
||||
switch (rmessage[0]) {
|
||||
case 'z':
|
||||
slocked = 1;
|
||||
break;
|
||||
case 'Z':
|
||||
slocked = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void eeprom_clear(void)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i=0; i < EESIZE-4; i++)
|
||||
eeprom_write_byte((uint8_t *)i, 0xFF);
|
||||
}
|
||||
|
||||
void hbw_loop(void)
|
||||
{
|
||||
rloop();
|
||||
if (rready) {
|
||||
rprocess();
|
||||
rready = 0;
|
||||
}
|
||||
if (sbusy) {
|
||||
sprocess();
|
||||
} else {
|
||||
if (!dsent) {
|
||||
if (is_bus_free()) {
|
||||
senddsc();
|
||||
}
|
||||
}
|
||||
if (!asent) {
|
||||
if (is_bus_free()) {
|
||||
announce();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ConfigButton
|
||||
switch (configstate) {
|
||||
case 0:
|
||||
if (bit_is_clear(PIND, ConfigButton)) {
|
||||
configtimer = hbw_timer;
|
||||
configstate = 1;
|
||||
configled = 1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (((hbw_timer - configtimer) > 20) &&
|
||||
(bit_is_set(PIND, ConfigButton))) {
|
||||
asent = 0;
|
||||
configstate = 2;
|
||||
configtimer = hbw_timer;
|
||||
}
|
||||
if ((hbw_timer - configtimer) > 8000) {
|
||||
configstate = 3;
|
||||
configtimer = hbw_timer;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if ((hbw_timer - configtimer) > 2000) {
|
||||
configstate = 0;
|
||||
configled = 0;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
configled = (hbw_timer & 128)?0:1;
|
||||
if (bit_is_set(PIND, ConfigButton)) {
|
||||
configstate = 4;
|
||||
configtimer = hbw_timer;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
configled = (hbw_timer & 128)?0:1;
|
||||
if (((hbw_timer - configtimer) > 2000) &&
|
||||
(bit_is_set(PIND, ConfigButton))) {
|
||||
configstate = 0;
|
||||
configled = 0;
|
||||
}
|
||||
if (((hbw_timer - configtimer) > 20) &&
|
||||
(bit_is_clear(PIND, ConfigButton))) {
|
||||
configstate = 5;
|
||||
configled = 0;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
configled = (hbw_timer & 512)?0:1;
|
||||
if (((hbw_timer - configtimer) > 20) &&
|
||||
(bit_is_set(PIND, ConfigButton))) {
|
||||
eeprom_clear();
|
||||
configstate = 0;
|
||||
configled = 0;
|
||||
asent = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ConfigLED
|
||||
if (configled)
|
||||
PORTD |= (1<<ConfigLED);
|
||||
else
|
||||
PORTD &= ~(1<<ConfigLED);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t hbw_send_key(uint8_t channel, uint8_t count, uint8_t flag)
|
||||
{
|
||||
if (sbusy)
|
||||
return 0;
|
||||
|
||||
if (alink)
|
||||
return 0;
|
||||
|
||||
alen = 4;
|
||||
actl = 0xF8;
|
||||
amessage[0] = 'K';
|
||||
amessage[1] = channel;
|
||||
amessage[2] = 0;
|
||||
amessage[3] = (flag & 3) | (count << 2);
|
||||
|
||||
aaddress = 0xFFFFFFFF;
|
||||
sbusy = 1;
|
||||
alink = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t hbw_send_channel(uint8_t channel, uint8_t length, uint8_t const * const data)
|
||||
{
|
||||
if (sbusy)
|
||||
return 0;
|
||||
|
||||
if (alink)
|
||||
return 0;
|
||||
|
||||
alen = length + 2;
|
||||
actl = 0xF8;
|
||||
((uint8_t*)&aaddress)[0]=eeprom_read_byte((const uint8_t *)2);
|
||||
((uint8_t*)&aaddress)[1]=eeprom_read_byte((const uint8_t *)3);
|
||||
((uint8_t*)&aaddress)[2]=eeprom_read_byte((const uint8_t *)4);
|
||||
((uint8_t*)&aaddress)[3]=eeprom_read_byte((const uint8_t *)5);
|
||||
|
||||
amessage[0] = 'i';
|
||||
amessage[1] = channel;
|
||||
memcpy(&(amessage[2]), data, length);
|
||||
sbusy = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ISR(USART_RX_vect)
|
||||
{
|
||||
uint8_t c;
|
||||
|
||||
sdelay = 100 + (rand() & 0x1F);
|
||||
|
||||
c = UDR0;
|
||||
if (c == 0xFE) {
|
||||
rind = 255;
|
||||
resc = 0;
|
||||
}
|
||||
if (c == 0xFD) {
|
||||
rind = 0;
|
||||
resc = 0;
|
||||
rready = 0;
|
||||
rcrc =0xFFFF;
|
||||
}
|
||||
if (rind < 255) {
|
||||
if (c == 0xFC) {
|
||||
resc = 1;
|
||||
return;
|
||||
}
|
||||
if (resc)
|
||||
c = c | 0x80;
|
||||
rcrc = crc16shift(rcrc, c);
|
||||
resc = 0;
|
||||
rind++;
|
||||
}
|
||||
if ((rind == 1) || (rind == 255))
|
||||
return;
|
||||
if (rind < 6) {
|
||||
((uint8_t*)&rdest)[rind-2] = c;
|
||||
return;
|
||||
}
|
||||
if (rind == 6) {
|
||||
rctl = c;
|
||||
return;
|
||||
}
|
||||
if (rind < 11) {
|
||||
((uint8_t*)&raddress)[rind-7] = c;
|
||||
return;
|
||||
}
|
||||
if (rind == 11) {
|
||||
rlen = c;
|
||||
return;
|
||||
}
|
||||
if ((rlen < 2) || (rlen > 64)) {
|
||||
rind = 255;
|
||||
return;
|
||||
}
|
||||
if ((rind < rlen + 10)) {
|
||||
rmessage[rind-12] = c;
|
||||
return;
|
||||
}
|
||||
if (rind == rlen + 10)
|
||||
return;
|
||||
if (rind == rlen + 11) {
|
||||
rind = 255;
|
||||
if (rcrc)
|
||||
return;
|
||||
rready = 1;
|
||||
rlen = rlen - 2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ISR(TIMER2_COMPA_vect)
|
||||
{
|
||||
cli();
|
||||
hbw_timer++;
|
||||
if (sdelay)
|
||||
sdelay--;
|
||||
sei();
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#ifndef __HBW_H__
|
||||
#define __HBW_H__
|
||||
|
||||
#define BAUDRATE 19200L
|
||||
|
||||
uint8_t hbw_rmessage[62];
|
||||
uint8_t hbw_rlen;
|
||||
|
||||
uint8_t hbw_slen;
|
||||
uint8_t hbw_smessage[62];
|
||||
|
||||
volatile uint16_t hbw_timer;
|
||||
|
||||
void hbw_init(void);
|
||||
void hbw_loop(void);
|
||||
uint8_t hbw_send_channel(uint8_t channel, uint8_t length, uint8_t const * const data);
|
||||
uint8_t hbw_send_key(uint8_t channel, uint8_t count, uint8_t flag);
|
||||
void hbw_receive_key(uint32_t saddress, uint8_t schannel, uint8_t channel, uint8_t countflag);
|
||||
uint8_t hbw_get_channel(uint8_t channel, uint8_t data[]);
|
||||
void hbw_set_channel(uint8_t channel, uint8_t len, uint8_t data[]);
|
||||
void hbw_read_config(void);
|
||||
#endif
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0"?>
|
||||
<device eep_size="512" version="01">
|
||||
<supported_types>
|
||||
<type priority="2" id="HBW-EBALARM" name="EBus Alarm HBW">
|
||||
<parameter const_value="0xAB" size="1" index="0"/>
|
||||
<parameter const_value="0" size="1" index="1"/>
|
||||
</type>
|
||||
</supported_types>
|
||||
|
||||
<paramset id="HBW-EBALARM_dev_master" type="MASTER">
|
||||
<parameter id="LOGGING_TIME">
|
||||
<logical type="float" unit="s" default="5.0" max="25.5" min="0.1"/>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="0x0001"/>
|
||||
</physical>
|
||||
<conversion type="float_integer_scale" offset="0.0" factor="10"/>
|
||||
</parameter>
|
||||
<parameter id="CENTRAL_ADDRESS" hidden="true">
|
||||
<logical type="integer"/>
|
||||
<physical size="4" type="integer" interface="eeprom">
|
||||
<address index="0x0002"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<enforce id="CENTRAL_ADDRESS" value="1"/>
|
||||
</paramset>
|
||||
|
||||
<channels>
|
||||
<channel index="0" type="MAINTENANCE" count="1" class="maintenance" ui_flags="internal">
|
||||
</channel>
|
||||
<channel index="1" type="SWITCH" count="1" physical_index_offset="-1">
|
||||
</channel>
|
||||
</channels>
|
||||
|
||||
</device>
|
@ -0,0 +1,152 @@
|
||||
<?xml version="1.0"?>
|
||||
<device eep_size="512" version="01">
|
||||
<supported_types>
|
||||
<type priority="2" id="HBW-EBRELAIS" name="Elektor EBus Relais Board">
|
||||
<parameter const_value="0xE1" size="1" index="0"/>
|
||||
<parameter const_value="0" size="1" index="1"/>
|
||||
</type>
|
||||
</supported_types>
|
||||
|
||||
<paramset id="HBW-EBRELAIS_dev_master" type="MASTER">
|
||||
<parameter id="LOGGING_TIME">
|
||||
<logical type="float" unit="s" default="5.0" max="25.5" min="0.1"/>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="0x0001"/>
|
||||
</physical>
|
||||
<conversion type="float_integer_scale" offset="0.0" factor="10"/>
|
||||
</parameter>
|
||||
<parameter id="CENTRAL_ADDRESS" hidden="true">
|
||||
<logical type="integer"/>
|
||||
<physical size="4" type="integer" interface="eeprom">
|
||||
<address index="0x0002"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<enforce id="CENTRAL_ADDRESS" value="1"/>
|
||||
</paramset>
|
||||
|
||||
<frames>
|
||||
<frame id="LEVEL_SET" type="#x" channel_field="10" direction="to_device">
|
||||
<parameter size="1.0" index="11.0" type="integer" param="LEVEL"/>
|
||||
</frame>
|
||||
<frame id="LEVEL_GET" type="#S" channel_field="10" direction="to_device"/>
|
||||
<frame id="INFO_LEVEL" type="#i" channel_field="10" direction="from_device" event="true">
|
||||
<parameter size="1.0" index="11.0" type="integer" param="LEVEL"/>
|
||||
</frame>
|
||||
</frames>
|
||||
|
||||
|
||||
<channels>
|
||||
<channel index="0" type="MAINTENANCE" count="1" class="maintenance" ui_flags="internal">
|
||||
</channel>
|
||||
<channel index="1" type="SWITCH" count="2" physical_index_offset="-1">
|
||||
<paramset id="hmw_switch_ch_master" type="MASTER" address_step="2" address_start="0x06">
|
||||
<parameter id="LOGGING">
|
||||
<logical type="option">
|
||||
<option id="OFF"/>
|
||||
<option id="ON" default="true"/>
|
||||
</logical>
|
||||
<physical size="0.1" type="integer" interface="eeprom">
|
||||
<address index="+0"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
</paramset>
|
||||
<paramset id="hmw_switch_ch_link" type="LINK" count="16" address_start="0x10" address_step="7" peer_param="SENSOR" channel_param="CHANNEL">
|
||||
<parameter id="SENSOR" hidden="true" operations="none">
|
||||
<logical type="address"/>
|
||||
<physical type="array">
|
||||
<physical size="4.0" type="integer" interface="eeprom">
|
||||
<address index="+0"/>
|
||||
</physical>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="+4"/>
|
||||
</physical>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="CHANNEL" hidden="true" operations="none">
|
||||
<logical type="integer" min="0" max="255" default="255"/>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="+5"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="SHORT_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE"/>
|
||||
<option id="TOGGLE" default="true"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="LONG_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE"/>
|
||||
<option id="TOGGLE" default="true"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6.2"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="LONGRELEASE_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE" default="true"/>
|
||||
<option id="TOGGLE"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6.4"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="DOUBLE_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE" default="true"/>
|
||||
<option id="TOGGLE"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6.6"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
</paramset>
|
||||
<paramset id="hmw_switch_ch_values" type="VALUES">
|
||||
<parameter id="STATE" operations="read,write,event" control="SWITCH.STATE">
|
||||
<logical type="boolean" default="false"/>
|
||||
<physical type="integer" interface="command" value_id="LEVEL">
|
||||
<set request="LEVEL_SET"/>
|
||||
<get request="LEVEL_GET" response="INFO_LEVEL"/>
|
||||
<event frame="INFO_LEVEL"/>
|
||||
</physical>
|
||||
<conversion type="boolean_integer" true="200" false="0" threshold="1"/>
|
||||
</parameter>
|
||||
</paramset>
|
||||
</channel>
|
||||
<channel index="3" type="SENSOR" count="2" physical_index_offset="-1">
|
||||
<paramset id="hmw_sensor_ch_master" type="MASTER" address_step="2" address_start="0x0a">
|
||||
<parameter id="LOGGING">
|
||||
<logical type="option">
|
||||
<option id="OFF"/>
|
||||
<option id="ON" default="true"/>
|
||||
</logical>
|
||||
<physical size="0.1" type="integer" interface="eeprom">
|
||||
<address index="+0"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
</paramset>
|
||||
<paramset id="hmw_sensor_ch_values" type="VALUES">
|
||||
<parameter id="STATE" operations="read,event" control="SWITCH.STATE">
|
||||
<logical type="boolean" default="false"/>
|
||||
<physical type="integer" interface="command" value_id="LEVEL">
|
||||
<get request="LEVEL_GET" response="INFO_LEVEL"/>
|
||||
<event frame="INFO_LEVEL"/>
|
||||
</physical>
|
||||
<conversion type="boolean_integer" true="200" false="0" threshold="1"/>
|
||||
</parameter>
|
||||
</paramset>
|
||||
</channel>
|
||||
</channels>
|
||||
</device>
|
@ -0,0 +1,210 @@
|
||||
<?xml version="1.0"?>
|
||||
<device eep_size="512" version="01">
|
||||
<supported_types>
|
||||
<type priority="2" id="HBW-EBTEST" name="Elektor EBus Test Board">
|
||||
<parameter const_value="0xE0" size="1" index="0"/>
|
||||
<parameter const_value="0" size="1" index="1"/>
|
||||
</type>
|
||||
</supported_types>
|
||||
|
||||
<paramset id="HBW-EBTEST_dev_master" type="MASTER">
|
||||
<parameter id="LOGGING_TIME">
|
||||
<logical type="float" unit="s" default="5.0" max="25.5" min="0.1"/>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="0x0001"/>
|
||||
</physical>
|
||||
<conversion type="float_integer_scale" offset="0.0" factor="10"/>
|
||||
</parameter>
|
||||
<parameter id="CENTRAL_ADDRESS" hidden="true">
|
||||
<logical type="integer"/>
|
||||
<physical size="4" type="integer" interface="eeprom">
|
||||
<address index="0x0002"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<enforce id="CENTRAL_ADDRESS" value="1"/>
|
||||
</paramset>
|
||||
|
||||
<frames>
|
||||
<frame id="LEVEL_SET" type="#x" channel_field="10" direction="to_device">
|
||||
<parameter size="1.0" index="11.0" type="integer" param="LEVEL"/>
|
||||
</frame>
|
||||
<frame id="LEVEL_GET" type="#S" channel_field="10" direction="to_device"/>
|
||||
<frame id="INFO_LEVEL" type="#i" channel_field="10" direction="from_device" event="true">
|
||||
<parameter size="1.0" index="11.0" type="integer" param="LEVEL"/>
|
||||
</frame>
|
||||
<frame id="KEY_EVENT_SHORT" type="#K" channel_field="10" direction="from_device" event="true">
|
||||
<parameter const_value="2" size="0.2" index="12.0" type="integer"/>
|
||||
<parameter size="0.6" index="12.2" type="integer" param="COUNTER"/>
|
||||
</frame>
|
||||
<frame id="KEY_EVENT_LONG" type="#K" channel_field="10" direction="from_device" event="true">
|
||||
<parameter const_value="3" size="0.2" index="12.0" type="integer"/>
|
||||
<parameter size="0.6" index="12.2" type="integer" param="COUNTER"/>
|
||||
</frame>
|
||||
<frame id="KEY_EVENT_LONGRELEASE" type="#K" channel_field="10" direction="from_device" event="true">
|
||||
<parameter const_value="0" size="0.2" index="12.0" type="integer"/>
|
||||
<parameter size="0.6" index="12.2" type="integer" param="COUNTER"/>
|
||||
</frame>
|
||||
<frame id="KEY_EVENT_DOUBLE" type="#K" channel_field="10" direction="from_device" event="true">
|
||||
<parameter const_value="1" size="0.2" index="12.0" type="integer"/>
|
||||
<parameter size="0.6" index="12.2" type="integer" param="COUNTER"/>
|
||||
</frame>
|
||||
</frames>
|
||||
|
||||
<channels>
|
||||
<channel index="0" type="MAINTENANCE" count="1" class="maintenance" ui_flags="internal">
|
||||
</channel>
|
||||
<channel index="1" type="SWITCH" count="1" physical_index_offset="-1">
|
||||
<paramset id="hmw_switch_ch_master" type="MASTER" address_step="1" address_start="0x06">
|
||||
<parameter id="LOGGING">
|
||||
<logical type="option">
|
||||
<option id="OFF"/>
|
||||
<option id="ON" default="true"/>
|
||||
</logical>
|
||||
<physical size="0.1" type="integer" interface="eeprom">
|
||||
<address index="+0"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
</paramset>
|
||||
<paramset id="hmw_switch_ch_link" type="LINK" count="16" address_start="0x10" address_step="7" peer_param="SENSOR" channel_param="CHANNEL">
|
||||
<parameter id="SENSOR" hidden="true" operations="none">
|
||||
<logical type="address"/>
|
||||
<physical type="array">
|
||||
<physical size="4.0" type="integer" interface="eeprom">
|
||||
<address index="+0"/>
|
||||
</physical>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="+4"/>
|
||||
</physical>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="CHANNEL" hidden="true" operations="none">
|
||||
<logical type="integer" min="0" max="255" default="255"/>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="+5"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="SHORT_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE"/>
|
||||
<option id="TOGGLE" default="true"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="LONG_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE"/>
|
||||
<option id="TOGGLE" default="true"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6.2"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="LONGRELEASE_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE" default="true"/>
|
||||
<option id="TOGGLE"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6.4"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter id="DOUBLE_ACTION_TYPE">
|
||||
<logical type="option">
|
||||
<option id="ON"/>
|
||||
<option id="OFF"/>
|
||||
<option id="INACTIVE" default="true"/>
|
||||
<option id="TOGGLE"/>
|
||||
</logical>
|
||||
<physical size="0.2" type="integer" interface="eeprom">
|
||||
<address index="+6.6"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
</paramset>
|
||||
<paramset id="hmw_switch_ch_values" type="VALUES">
|
||||
<parameter id="STATE" operations="read,write,event" control="SWITCH.STATE">
|
||||
<logical type="boolean" default="false"/>
|
||||
<physical type="integer" interface="command" value_id="LEVEL">
|
||||
<set request="LEVEL_SET"/>
|
||||
<get request="LEVEL_GET" response="INFO_LEVEL"/>
|
||||
<event frame="INFO_LEVEL"/>
|
||||
</physical>
|
||||
<conversion type="boolean_integer" true="200" false="0" threshold="1"/>
|
||||
</parameter>
|
||||
</paramset>
|
||||
</channel>
|
||||
<channel index="2" type="KEY" count="1" physical_index_offset="-1">
|
||||
<link_roles>
|
||||
<source name="SWITCH"/>
|
||||
</link_roles>
|
||||
<paramset id="hmw_input_ch_master" type="MASTER" address_step="1" address_start="0x07">
|
||||
<parameter id="LONG_PRESS_TIME">
|
||||
<logical type="float" unit="s" default="1.0" max="5.0" min="0.4"/>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="+1"/>
|
||||
</physical>
|
||||
<conversion type="float_integer_scale" factor="10"/>
|
||||
<conversion type="integer_integer_map">
|
||||
<value_map to_device="false" from_device="true" parameter_value="10" device_value="0xff"/>
|
||||
</conversion>
|
||||
</parameter>
|
||||
</paramset>
|
||||
<paramset id="hmw_input_ch_link" type="LINK" count="16" address_step="6" address_start="0x80" channel_param="CHANNEL" peer_param="ACTUATOR">
|
||||
<parameter hidden="true" id="CHANNEL" operations="none">
|
||||
<logical type="integer" default="255" max="255" min="0"/>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="+0"/>
|
||||
</physical>
|
||||
</parameter>
|
||||
<parameter hidden="true" id="ACTUATOR" operations="none">
|
||||
<logical type="address"/>
|
||||
<physical type="array">
|
||||
<physical size="4.0" type="integer" interface="eeprom">
|
||||
<address index="+1"/>
|
||||
</physical>
|
||||
<physical size="1.0" type="integer" interface="eeprom">
|
||||
<address index="+5"/>
|
||||
</physical>
|
||||
</physical>
|
||||
</parameter>
|
||||
</paramset>
|
||||
<paramset id="hmw_input_ch_values" type="VALUES">
|
||||
<parameter id="PRESS_SHORT" operations="event,write" loopback="true" control="BUTTON.SHORT">
|
||||
<logical type="action"/>
|
||||
<physical type="integer" interface="command" value_id="COUNTER">
|
||||
<event frame="KEY_EVENT_SHORT"/>
|
||||
</physical>
|
||||
<conversion type="action_key_counter" counter_size="6" sim_counter="SIM_COUNTER"/>
|
||||
</parameter>
|
||||
<parameter id="PRESS_LONG" operations="event,write" loopback="true" control="BUTTON.LONG">
|
||||
<logical type="action"/>
|
||||
<physical type="integer" interface="command" value_id="COUNTER">
|
||||
<event frame="KEY_EVENT_LONG"/>
|
||||
</physical>
|
||||
<conversion type="action_key_counter" counter_size="6" sim_counter="SIM_COUNTER"/>
|
||||
</parameter>
|
||||
<parameter id="RELEASE_LONG" operations="event" loopback="true" control="BUTTON.RELEASE">
|
||||
<logical type="action"/>
|
||||
<physical type="integer" interface="command" value_id="COUNTER">
|
||||
<event frame="KEY_EVENT_LONGRELEASE"/>
|
||||
</physical>
|
||||
<conversion type="action_key_counter" counter_size="6" sim_counter="SIM_COUNTER"/>
|
||||
</parameter>
|
||||
<parameter id="DOUBLECLICK" operations="event" loopback="true" control="BUTTON.DOUBLE">
|
||||
<logical type="action"/>
|
||||
<physical type="integer" interface="command" value_id="COUNTER">
|
||||
<event frame="KEY_EVENT_DOUBLE"/>
|
||||
</physical>
|
||||
<conversion type="action_key_counter" counter_size="6" sim_counter="SIM_COUNTER"/>
|
||||
</parameter>
|
||||
</paramset>
|
||||
</channel>
|
||||
</channels>
|
||||
</device>
|
@ -0,0 +1,46 @@
|
||||
#ifndef __HW_H__
|
||||
#define __HW_H__
|
||||
#define SenderEnable PD2
|
||||
#define ReceiverDisable PD3
|
||||
|
||||
#ifdef TESTNODE
|
||||
#include "testhw.h"
|
||||
#endif
|
||||
#ifdef RELAISNODE
|
||||
#include "relaishw.h"
|
||||
#endif
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 16000000L
|
||||
#endif
|
||||
|
||||
#ifndef HBWTYPE
|
||||
#define HBWTYPE 0xAB
|
||||
#endif
|
||||
|
||||
#ifndef HBWSERIAL0
|
||||
#define HBWSERIAL0 'C'
|
||||
#define HBWSERIAL1 'O'
|
||||
#define HBWSERIAL2 'L'
|
||||
#define HBWSERIAL3 'A'
|
||||
#define HBWSERIAL4 'B'
|
||||
#define HBWSERIAL5 'D'
|
||||
#define HBWSERIAL6 'E'
|
||||
#define HBWSERIAL7 'V'
|
||||
#define HBWSERIAL8 '0'
|
||||
#define HBWSERIAL9 '0'
|
||||
#endif
|
||||
|
||||
#ifndef HBWMAJOR
|
||||
#define HBWMAJOR 0
|
||||
#endif
|
||||
|
||||
#ifndef HBWMINOR
|
||||
#define HBWMINOR 0
|
||||
#endif
|
||||
|
||||
#ifndef EESIZE
|
||||
#define EESIZE 512
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,23 @@
|
||||
#ifndef __RELAISHW_H__
|
||||
#define __RELAISHW_H__
|
||||
|
||||
#define ConfigLED PD4
|
||||
#define ConfigButton PD5
|
||||
#define Relais1 PB0
|
||||
#define Relais2 PB1
|
||||
|
||||
#define HBWTYPE 0xE1
|
||||
#define HBWMAJOR 1
|
||||
#define HBWMINOR 2
|
||||
#define HBWSERIAL0 'C'
|
||||
#define HBWSERIAL1 'O'
|
||||
#define HBWSERIAL2 'L'
|
||||
#define HBWSERIAL3 'A'
|
||||
#define HBWSERIAL4 'B'
|
||||
#define HBWSERIAL5 'R'
|
||||
#define HBWSERIAL6 'E'
|
||||
#define HBWSERIAL7 'L'
|
||||
#define HBWSERIAL8 '0'
|
||||
#define HBWSERIAL9 '1'
|
||||
|
||||
#endif
|
@ -0,0 +1,179 @@
|
||||
#include "hw.h"
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include "hbw.h"
|
||||
|
||||
uint8_t relais1state;
|
||||
uint8_t relais2state;
|
||||
uint8_t pc0state;
|
||||
uint8_t pc1state;
|
||||
uint8_t scount;
|
||||
|
||||
void hbw_read_config(void)
|
||||
{
|
||||
}
|
||||
|
||||
uint8_t hbw_get_channel(uint8_t channel, uint8_t data[])
|
||||
{
|
||||
if (channel == 0) {
|
||||
if (bit_is_clear(PINB, Relais1))
|
||||
data[0] = 0;
|
||||
else
|
||||
data[0] = 200;
|
||||
return 1;
|
||||
}
|
||||
if (channel == 1) {
|
||||
if (bit_is_clear(PINB, Relais2))
|
||||
data[0] = 200;
|
||||
else
|
||||
data[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
if (channel == 2) {
|
||||
if (bit_is_clear(PINC, PC0))
|
||||
data[0] = 200;
|
||||
else
|
||||
data[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
if (channel == 3) {
|
||||
if (bit_is_clear(PINC, PC1))
|
||||
data[0] = 200;
|
||||
else
|
||||
data[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hbw_set_channel(uint8_t channel, uint8_t len, uint8_t data[])
|
||||
{
|
||||
if (channel == 0) {
|
||||
if (data[0])
|
||||
PORTB |= (1<<Relais1);
|
||||
else
|
||||
PORTB &= ~(1<<Relais1);
|
||||
}
|
||||
if (channel == 1) {
|
||||
if (data[0])
|
||||
PORTB |= (1<<Relais2);
|
||||
else
|
||||
PORTB &= ~(1<<Relais2);
|
||||
}
|
||||
}
|
||||
|
||||
void hbw_receive_key(uint32_t saddress, uint8_t schannel, uint8_t channel, uint8_t countflag)
|
||||
{
|
||||
uint8_t i, type;
|
||||
|
||||
if (channel > 1)
|
||||
return;
|
||||
|
||||
if (scount == countflag)
|
||||
return;
|
||||
|
||||
for (i=0; i < 16; i++) {
|
||||
if ((eeprom_read_byte((const uint8_t *)(i*7)+0x10) == ((uint8_t*)&saddress)[0]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x11) == ((uint8_t*)&saddress)[1]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x12) == ((uint8_t*)&saddress)[2]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x13) == ((uint8_t*)&saddress)[3]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x14) == schannel) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x15) == channel)) {
|
||||
type = eeprom_read_byte((const uint8_t *)(i*7)+0x16);
|
||||
switch (countflag & 3) {
|
||||
case 1:
|
||||
type = (type >> 6) & 0x3;
|
||||
break;
|
||||
case 0:
|
||||
type = (type >> 4) & 0x3;
|
||||
break;
|
||||
case 3:
|
||||
type = (type >> 2) & 0x3;
|
||||
break;
|
||||
case 2:
|
||||
type = type & 0x3;
|
||||
}
|
||||
switch (type) {
|
||||
case 0:
|
||||
if(channel == 0)
|
||||
PORTB |= (1<<Relais1);
|
||||
else
|
||||
PORTB |= (1<<Relais2);
|
||||
break;
|
||||
case 1:
|
||||
if(channel == 0)
|
||||
PORTB &= ~(1<<Relais1);
|
||||
else
|
||||
PORTB &= ~(1<<Relais2);
|
||||
break;
|
||||
case 3:
|
||||
if(channel == 0)
|
||||
PORTB ^= (1<<Relais1);
|
||||
else
|
||||
PORTB ^= (1<<Relais2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t state;
|
||||
|
||||
DDRB |= (1<<Relais1);
|
||||
DDRB |= (1<<Relais2);
|
||||
|
||||
DDRC &= ~(1<<PC0);
|
||||
DDRC &= ~(1<<PC1);
|
||||
|
||||
PORTB &= ~(1<<Relais1);
|
||||
PORTB &= ~(1<<Relais2);
|
||||
|
||||
PORTC |= (1<<PC0);
|
||||
PORTC |= (1<<PC1);
|
||||
|
||||
relais1state = 0;
|
||||
relais2state = 0;
|
||||
pc0state = 0;
|
||||
pc1state = 0;
|
||||
|
||||
hbw_init();
|
||||
|
||||
while(1) {
|
||||
hbw_loop();
|
||||
|
||||
if (bit_is_clear(PINC, PC0) && (!pc0state)) {
|
||||
state = 200;
|
||||
|
||||
if (hbw_send_channel(2, 1, &state)) {
|
||||
pc0state = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_is_set(PINC, PC0) && pc0state) {
|
||||
state = 0;
|
||||
|
||||
if (hbw_send_channel(2, 1, &state)) {
|
||||
pc0state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_is_clear(PINC, PC1) && (!pc1state)) {
|
||||
state = 200;
|
||||
|
||||
if (hbw_send_channel(3, 1, &state)) {
|
||||
pc1state = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_is_set(PINC, PC1) && pc1state) {
|
||||
state = 0;
|
||||
|
||||
if (hbw_send_channel(3, 1, &state)) {
|
||||
pc1state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
#ifndef __TESTHW_H__
|
||||
#define __TESTHW_H__
|
||||
|
||||
#define ConfigLED PD4
|
||||
#define ConfigButton PD5
|
||||
#define ExpLED PD6
|
||||
#define ExpButton PD7
|
||||
|
||||
#define HBWTYPE 0xE0
|
||||
#define HBWMAJOR 1
|
||||
#define HBWMINOR 2
|
||||
#define HBWSERIAL0 'C'
|
||||
#define HBWSERIAL1 'O'
|
||||
#define HBWSERIAL2 'L'
|
||||
#define HBWSERIAL3 'A'
|
||||
#define HBWSERIAL4 'B'
|
||||
#define HBWSERIAL5 'T'
|
||||
#define HBWSERIAL6 'S'
|
||||
#define HBWSERIAL7 'T'
|
||||
#define HBWSERIAL8 '0'
|
||||
#define HBWSERIAL9 '1'
|
||||
|
||||
#define HBW_MAXLINKS 16
|
||||
#define HBW_LINKOFFS 0x80
|
||||
#endif
|
@ -0,0 +1,169 @@
|
||||
#include "hw.h"
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include "hbw.h"
|
||||
|
||||
uint8_t expled;
|
||||
uint8_t expbutton;
|
||||
uint16_t exptime;
|
||||
uint16_t explong;
|
||||
uint16_t longtime;
|
||||
uint16_t logtime;
|
||||
uint8_t logging;
|
||||
uint8_t scount;
|
||||
|
||||
void hbw_read_config(void)
|
||||
{
|
||||
uint8_t ee;
|
||||
|
||||
ee = eeprom_read_byte((const uint8_t *)1);
|
||||
logtime = 100L * ee;
|
||||
|
||||
ee = eeprom_read_byte((const uint8_t *)6);
|
||||
logging = ee & 0x01;
|
||||
|
||||
ee = eeprom_read_byte((const uint8_t *)8);
|
||||
|
||||
if (ee == 0xFF)
|
||||
longtime = 1000;
|
||||
else
|
||||
longtime = 100L * ee;
|
||||
}
|
||||
|
||||
uint8_t hbw_get_channel(uint8_t channel, uint8_t data[])
|
||||
{
|
||||
if (channel == 1) {
|
||||
if (bit_is_clear(PIND, ExpButton))
|
||||
data[0] = 200;
|
||||
else
|
||||
data[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
if (channel == 0) {
|
||||
if (bit_is_clear(PIND, ExpLED))
|
||||
data[0] = 0;
|
||||
else
|
||||
data[0] = 200;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hbw_set_channel(uint8_t channel, uint8_t len, uint8_t data[])
|
||||
{
|
||||
if (channel == 0) {
|
||||
if (data[0])
|
||||
PORTD |= (1<<ExpLED);
|
||||
else
|
||||
PORTD &= ~(1<<ExpLED);
|
||||
}
|
||||
}
|
||||
|
||||
void hbw_receive_key(uint32_t saddress, uint8_t schannel, uint8_t channel, uint8_t countflag)
|
||||
{
|
||||
uint8_t i, type;
|
||||
|
||||
if (channel != 0)
|
||||
return;
|
||||
|
||||
if (scount == countflag)
|
||||
return;
|
||||
|
||||
for (i=0; i < 16; i++) {
|
||||
if ((eeprom_read_byte((const uint8_t *)(i*7)+0x10) == ((uint8_t*)&saddress)[0]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x11) == ((uint8_t*)&saddress)[1]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x12) == ((uint8_t*)&saddress)[2]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x13) == ((uint8_t*)&saddress)[3]) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x14) == schannel) &&
|
||||
(eeprom_read_byte((const uint8_t *)(i*7)+0x15) == channel)) {
|
||||
type = eeprom_read_byte((const uint8_t *)(i*7)+0x16);
|
||||
switch (countflag & 3) {
|
||||
case 1:
|
||||
type = (type >> 6) & 0x3;
|
||||
break;
|
||||
case 0:
|
||||
type = (type >> 4) & 0x3;
|
||||
break;
|
||||
case 3:
|
||||
type = (type >> 2) & 0x3;
|
||||
break;
|
||||
case 2:
|
||||
type = type & 0x3;
|
||||
}
|
||||
switch (type) {
|
||||
case 0:
|
||||
PORTD |= (1<<ExpLED);
|
||||
break;
|
||||
case 1:
|
||||
PORTD &= ~(1<<ExpLED);
|
||||
break;
|
||||
case 3:
|
||||
PORTD ^= (1<<ExpLED);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint16_t now;
|
||||
uint8_t state;
|
||||
|
||||
DDRD |= (1<<ExpLED);
|
||||
DDRD &= ~(1<<ExpButton);
|
||||
|
||||
PORTD &= ~(1<<ExpLED);
|
||||
PORTD |= (1<<ExpButton);
|
||||
|
||||
expled = 0;
|
||||
expbutton = 0;
|
||||
exptime = 0;
|
||||
explong = 0;
|
||||
|
||||
hbw_init();
|
||||
|
||||
state = 255;
|
||||
|
||||
while(1) {
|
||||
hbw_loop();
|
||||
|
||||
now = hbw_timer?hbw_timer:1;
|
||||
|
||||
if (bit_is_clear(PIND, ExpButton)) {
|
||||
if (exptime) {
|
||||
if (explong) {
|
||||
if (now - explong >= 300) {
|
||||
explong = now;
|
||||
state = 3;
|
||||
}
|
||||
} else {
|
||||
if (now - exptime > longtime) {
|
||||
explong = now;
|
||||
expbutton++;
|
||||
state = 3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
exptime = now;
|
||||
explong = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_is_set(PIND, ExpButton)) {
|
||||
if (exptime) {
|
||||
if (now - exptime > 50 && !explong) {
|
||||
expbutton++;
|
||||
state = 2;
|
||||
}
|
||||
if (now - exptime > 50 && explong)
|
||||
state = 0;
|
||||
exptime = 0;
|
||||
}
|
||||
}
|
||||
if (state != 255)
|
||||
if (hbw_send_key(1, expbutton, state))
|
||||
state = 255;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue