#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]; uint16_t sdelay; uint8_t waitack; uint32_t aaddress; uint8_t asent; 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) { // my_address=eeprom_read_dword((const uint32_t *)EESIZE-4); ((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< 0x7FFF) return 1; return 0; } 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; sendmsg(); asent = 1; } void hbw_init(void) { DDRD |= (1<> 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': if (rlen != 2) return; 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; } } } 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) { process(); rready = 0; } 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 % 400) > 200)?0:1; if (bit_is_set(PIND, ConfigButton)) { configstate = 4; configtimer = hbw_timer; } break; case 4: configled = ((hbw_timer % 400) > 200)?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; eeprom_clear(); } break; case 5: if (((hbw_timer - configtimer) > 20) && (bit_is_set(PIND, ConfigButton))) { configstate = 0; configled = 0; asent = 0; } } #endif #ifdef ConfigLED if (configled) PORTD |= (1< 2) { waitack = 0; return 2; } slen = length + 2; sctl = 0xF8; aaddress = target_address; if(aaddress == 0) { ((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); // aaddress = eeprom_read_dword((const uint32_t *)2); } saddress = aaddress; smessage[0] = 'i'; smessage[1] = channel; memcpy(&(smessage[2]), data, length); sendmsg(); if (aaddress == 0xFFFFFFFF) return 1; waitack++; gotack = 0; sdelay = hbw_timer + 100 + (rand() & 0x1F); return 0; } ISR(USART_RX_vect) { uint8_t c; sdelay = hbw_timer + 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++; sei(); }