commit 65be3ae3fc1ec141a5c6aad498cc0fcf0bf63f97 Author: Jochen Friedrich Date: Sun Apr 1 17:49:20 2018 +0000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8956788 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.hex +*.lst +*.elf +*.o +*.map diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9787a52 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +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 +IO6OBJS += io6node.o io6hbw.o + +all: testnode.hex relaisnode.hex io6node.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) + +io6node.o: io6node.c hbw.h hw.h io6hw.h + $(CC) $(CFLAGS) -DIO6NODE -c $< -o $@ + +io6hbw.o: hbw.c hbw.h hw.h io6hw.h + $(CC) $(CFLAGS) -DIO6NODE -c $< -o $@ + +io6node.elf: $(IO6OBJS) + $(CC) $(CLDFLAGS) -o $@ $(IO6OBJS) + +%hex:%elf + $(OBJCOPY) -j .text -j .data -O srec $< $@ + +clean: + rm -f *.hex *.elf *.o *.lst *.map diff --git a/hbw.c b/hbw.c new file mode 100644 index 0000000..bb09b9f --- /dev/null +++ b/hbw.c @@ -0,0 +1,762 @@ +#include "hw.h" +#include +#include +#include +#include +#include +#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<> 8) & 0xFF,2); + return; + } + if (sind == slen+12) { + send(scrc & 0xFF,0); + return; + } + if (bit_is_set(UCSR0A, TXC0)) { + PORTD &= ~(1<> 4) & 0x0F); + smessage[15] = 0x30 + (((uint8_t*)&my_address)[3] & 0x0F); + if(smessage[14] > 0x39) smessage[14] += 7; + if(smessage[15] > 0x39) smessage[15] += 7; + + if (sendmsg()) + asent = 1; +} + +void hbw_init(void) +{ + DDRD |= (1< 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] = 0x30 + ((((uint8_t*)&my_address)[3] >> 4) & 0x0F); + smessage[9] = 0x30 + (((uint8_t*)&my_address)[3] & 0x0F); + if(smessage[8] > 0x39) smessage[8] += 7; + if(smessage[9] > 0x39) smessage[9] += 7; + 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< 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(); +} diff --git a/hbw.h b/hbw.h new file mode 100644 index 0000000..5491ae4 --- /dev/null +++ b/hbw.h @@ -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 diff --git a/hbw_el_io6.xml b/hbw_el_io6.xml new file mode 100644 index 0000000..e035235 --- /dev/null +++ b/hbw_el_io6.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + +
+ + + +