Compare commits

...

No commits in common. '221905f27c17e9d396b218dbbfb6c23831532266' and '4a9572c40fde82ca106253cd1239a241fff034c6' have entirely different histories.

@ -8,15 +8,18 @@ CFLAGS += -Wa,-adhlns=$(<:%.c=%.lst)
CLDFLAGS += -mmcu=$(CPU) -Wl,-Map=$(@:%.elf=%.map)
HBWOBJS += testnode.o hbw.o
TESTOBJS += testnode.o testhbw.o
all: testnode.hex
testnode.o: testnode.c hbw.h hw.h testhw.h
$(CC) $(CFLAGS) -DTESTNODE -c $< -o $@
testnode.elf: $(HBWOBJS)
$(CC) $(CLDFLAGS) -o $@ $(HBWOBJS)
testhbw.o: hbw.c hbw.h hw.h testhw.h
$(CC) $(CFLAGS) -DTESTNODE -c $< -o $@
testnode.elf: $(TESTOBJS)
$(CC) $(CLDFLAGS) -o $@ $(TESTOBJS)
%hex:%elf
$(OBJCOPY) -j .text -j .data -O srec $< $@

@ -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);
}
}
}

257
hbw.c

@ -1,9 +1,38 @@
#include "hw.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <stdlib.h>
#include <string.h>
#include "hbw.h"
uint8_t my_address[4];
uint8_t rind;
uint16_t rcrc;
uint8_t raddress[4];
uint8_t rdest[4];
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;
uint8_t saddress[4];
uint8_t slen;
uint8_t smessage[62];
uint16_t sdelay;
uint8_t asent;
uint8_t waitack;
uint8_t gotack;
static uint16_t crc16shift(uint16_t crc, uint8_t data)
{
int stat, i;
@ -22,12 +51,27 @@ static uint16_t crc16shift(uint16_t crc, uint8_t data)
return crc;
}
void hbw_send(uint8_t i,uint8_t crc)
static void readaddr(void)
{
my_address[0]=eeprom_read_byte((const uint8_t *)EESIZE-4);
my_address[1]=eeprom_read_byte((const uint8_t *)EESIZE-3);
my_address[2]=eeprom_read_byte((const uint8_t *)EESIZE-2);
my_address[3]=eeprom_read_byte((const uint8_t *)EESIZE-1);
if ((my_address[0] == 0xFF) &&
(my_address[1] == 0xFF) &&
(my_address[2] == 0xFF) &&
(my_address[3] == 0xFF))
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) {
@ -48,26 +92,26 @@ void hbw_send(uint8_t i,uint8_t crc)
}
}
void hbw_loop(void)
void rloop(void)
{
if (!sind)
return;
if (sdisc) {
if (sind == 1) {
hbw_send(0x04,1);
send(0x04,1);
return;
}
if (sind == 2) {
hbw_send(0x01,1);
send(0x01,1);
return;
}
if (sind == 3) {
hbw_send((scrc >> 8) & 0xFF,2);
send((scrc >> 8) & 0xFF,2);
return;
}
if (sind == 4) {
hbw_send(scrc & 0xFF,0);
send(scrc & 0xFF,0);
return;
}
if (bit_is_set(UCSR0A, TXC0)) {
@ -80,35 +124,35 @@ void hbw_loop(void)
}
if (sind < 5) {
hbw_send(saddress[sind-1],1);
send(saddress[sind-1],1);
return;
}
if (sind == 5) {
hbw_send(sctl,1);
send(sctl,1);
return;
}
if (sind < 10) {
hbw_send(my_address[sind-6],1);
send(my_address[sind-6],1);
return;
}
if (sind == 10) {
hbw_send(slen+2,1);
send(slen+2,1);
return;
}
if (sind < slen+10) {
hbw_send(smessage[sind-11],1);
send(smessage[sind-11],1);
return;
}
if (sind == slen+10) {
hbw_send(smessage[sind-11],1);
send(smessage[sind-11],1);
return;
}
if (sind == slen+11) {
hbw_send((scrc >> 8) & 0xFF,2);
send((scrc >> 8) & 0xFF,2);
return;
}
if (sind == slen+12) {
hbw_send(scrc & 0xFF,0);
send(scrc & 0xFF,0);
return;
}
if (bit_is_set(UCSR0A, TXC0)) {
@ -118,7 +162,7 @@ void hbw_loop(void)
}
}
char sendmsg(void)
static uint8_t sendmsg(void)
{
if (sind)
return 0;
@ -133,10 +177,9 @@ char sendmsg(void)
sesc = 0;
sdisc = 0;
return ~0;
rwant = 20 + (rand() & 0x0F);
}
char senddsc(void)
static uint8_t senddsc(void)
{
if (sind)
return 0;
@ -153,15 +196,15 @@ char senddsc(void)
return ~0;
}
char is_bus_free(void)
static uint8_t is_bus_free(void)
{
if(rlast < rwant)
return 0;
return 1;
if(sdelay - hbw_timer > 0x7FFF)
return 1;
return 0;
}
void announce(void)
static void announce(void)
{
sctl = 0xF8;
@ -188,11 +231,12 @@ void announce(void)
smessage[13] = HBWSERIAL7;
smessage[14] = HBWSERIAL8;
smessage[15] = HBWSERIAL9;
while (!is_bus_free()) ;
sendmsg();
asent = 1;
}
void init_hbw(void)
void hbw_init(void)
{
DDRD |= (1<<SenderEnable);
DDRD |= (1<<ReceiverDisable);
@ -205,7 +249,7 @@ void init_hbw(void)
UCSR0B = (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0);
UCSR0C = (1 << UPM01) | (1 << UCSZ01) | (1 << UCSZ00);
OCR2A = 0x96;
OCR2A = 0xF9;
TIMSK2 |= (1 << OCIE2A);
TCCR2A |= (1 << WGM21);
TCCR2B = TCCR2B | (1 << CS21) | (1 << CS20);
@ -214,19 +258,171 @@ void init_hbw(void)
sind = 0;
sdisc = 0;
rready = 0;
rlast = 0;
asent = 0;
hbw_timer = 0;
readaddr();
srand(my_address[3]);
rwant = 20 + (rand() & 0x0F);
sdelay = 1000 + (rand() & 0x1F);
sei();
announce();
}
static void process(void)
{
uint8_t seq,i;
uint16_t addr;
if ((rdest[0] == my_address[0]) &&
(rdest[1] == my_address[1]) &&
(rdest[2] == my_address[2]) &&
(rdest[3] == my_address[3]) &&
((rctl & 0x13) == 0x11)) {
if (waitack) {
waitack = 0;
gotack = 1;
}
return;
}
if ((rdest[0] == my_address[0]) &&
(rdest[1] == my_address[1]) &&
(rdest[2] == my_address[2]) &&
(rdest[3] == my_address[3]) &&
((rctl & 0x11) == 0x10)) {
saddress[0] = raddress[0];
saddress[1] = raddress[1];
saddress[2] = raddress[2];
saddress[3] = raddress[3];
seq = (rctl >> 1) & 3;
switch (rmessage[0]) {
case '@':
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':
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':
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':
hbw_set_channel(rmessage[1], rlen - 2, &(rmessage[2]));
case 'S':
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':
slen = 0;
sctl = 0x19 | (seq << 5);
sendmsg();
break;
}
}
}
void hbw_loop(void)
{
rloop();
if (rready) {
process();
rready = 0;
}
if (!asent) {
if (is_bus_free()) {
announce();
}
}
}
uint8_t hbw_send_channel(uint8_t channel, uint8_t length, uint8_t const * const data, uint32_t target_address)
{
if (gotack) {
gotack = 0;
return 1;
}
if (!is_bus_free())
return 0;
if (waitack)
return 0;
slen = length + 2;
sctl = 0xF8;
saddress[0] = eeprom_read_byte((const uint8_t *)2);
saddress[1] = eeprom_read_byte((const uint8_t *)3);
saddress[2] = eeprom_read_byte((const uint8_t *)4);
saddress[3] = eeprom_read_byte((const uint8_t *)5);
smessage[0] = 'i';
smessage[1] = channel;
memcpy(&(smessage[2]), data, length);
sendmsg();
waitack = 1;
gotack = 0;
return 0;
}
ISR(USART_RX_vect)
{
uint8_t c;
rlast = 0;
sdelay = hbw_timer + 100 + (rand() & 0x1F);
c = UDR0;
if (c == 0xFE) {
@ -291,7 +487,6 @@ ISR(USART_RX_vect)
ISR(TIMER2_COMPA_vect)
{
cli();
if (rlast < rwant)
rlast++;
hbw_timer++;
sei();
}

32
hbw.h

@ -3,31 +3,17 @@
#define BAUDRATE 19200L
uint8_t my_address[4];
uint8_t hbw_rmessage[62];
uint8_t hbw_rlen;
uint8_t rind;
uint16_t rcrc;
uint8_t rmessage[62];
uint8_t raddress[4];
uint8_t rdest[4];
uint8_t rlen;
uint8_t resc;
uint8_t rctl;
uint8_t rwant;
volatile uint8_t rready;
volatile uint8_t rlast;
uint8_t hbw_slen;
uint8_t hbw_smessage[62];
uint8_t sind;
uint8_t sdisc;
uint8_t sctl;
uint16_t scrc;
uint8_t slen;
uint8_t sesc;
uint8_t saddress[4];
uint8_t smessage[62];
volatile uint16_t hbw_timer;
void hbw_loop(void);
char sendmsg(void);
char senddsc(void);
void init_hbw(void);
uint8_t hbw_send_channel(uint8_t channel, uint8_t length, uint8_t const * const data, uint32_t target_address);
void hbw_init(void);
uint8_t hbw_get_channel(uint8_t channel, uint8_t data[]);
void hbw_set_channel(uint8_t channel, uint8_t len, uint8_t data[]);
#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,90 @@
<?xml version="1.0"?>
<device eep_size="512" version="01">
<supported_types>
<type priority="2" id="HBW-EBRELAY" 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-EBRELAY_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_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="SENSOR" count="2" physical_index_offset="-1">
<paramset id="hmw_sensor_ch_master" type="MASTER" address_step="2" address_start="0x08">
<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,89 @@
<?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>
</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="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_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="SENSOR" count="1" physical_index_offset="-1">
<paramset id="hmw_sensor_ch_master" type="MASTER" address_step="2" address_start="0x08">
<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>

@ -39,4 +39,8 @@
#define HBWMINOR 0
#endif
#ifndef EESIZE
#define EESIZE 512
#endif
#endif

@ -0,0 +1,7 @@
#ifndef __RELAISHW_H__
#define __RELAISHW_H__
#define TestLED PD4
#define TestButton PD5
#define Relais1 PB0
#define Relais2 PB1
#endif

@ -0,0 +1,174 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "relaishw.h"
#include "rs485.h"
#include "eb.h"
uint8_t testled;
uint8_t testbutton;
uint8_t relais1state;
uint8_t relais2state;
uint8_t pc0state;
uint8_t pc1state;
uint8_t waitforack;
uint8_t waitforsend;
uint8_t acktimer;
int main(void)
{
uint8_t i;
init_rs485();
DDRD |= (1<<TestLED);
DDRD &= ~(1<<TestButton);
DDRB |= (1<<Relais1);
DDRB |= (1<<Relais2);
DDRC &= ~(1<<PC0);
DDRC &= ~(1<<PC1);
PORTD &= ~(1<<TestLED);
PORTD |= (1<<TestButton);
PORTB &= ~(1<<Relais1);
PORTB &= ~(1<<Relais2);
PORTC |= (1<<PC0);
PORTC |= (1<<PC1);
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);
testled = 0;
relais1state = 0;
relais2state = 0;
pc0state = 0;
pc1state = 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 = 4; /* Relais mit 2 Schalt-IO und 2 ADC*/
}
if ((rcommand == 0x60) && (rchannel == 1)) {
if (rvalue & 0x01) {
testled = ~0;
PORTD |= (1<<TestLED);
} else {
testled = 0;
PORTD &= ~(1<<TestLED);
}
if (rvalue & 0x02) {
relais1state = ~0;
PORTB |= (1<<Relais1);
} else {
relais1state = 0;
PORTB &= ~(1<<Relais1);
}
if (rvalue & 0x04) {
relais2state = ~0;
PORTB |= (1<<Relais2);
} else {
relais2state = 0;
PORTB &= ~(1<<Relais2);
}
scommand = 0x40;
svalue = (testled & 0x01) | (relais1state & 0x02) | (relais2state & 0x04) | (pc0state & 0x08) | (pc1state & 0x10);
}
if ((rcommand == 0x40) && (rchannel == 1)) {
scommand = 0x40;
svalue = (testled & 0x01) | (relais1state & 0x02) | (relais2state & 0x04) | (pc0state & 0x08) | (pc1state & 0x10);
}
if ((rcommand == 0x40) && ((rchannel > 1) && (rchannel < 4))) {
ADMUX = (ADMUX & ~(0x1F)) | (rchannel);
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 = (testled & 0x01) | (relais1state & 0x02) | (relais2state & 0x04) | (pc0state & 0x08) | (pc1state & 0x10);
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, TestButton) && (!testbutton)) {
testbutton = ~0;
testled = ~testled;
waitforsend = ~0;
if (testled)
PORTD |= (1<<TestLED);
else
PORTD &= ~(1<<TestLED);
}
if (bit_is_set(PIND, TestButton) && testbutton)
testbutton = 0;
if (bit_is_clear(PINC, PC0) && (!pc0state)) {
pc0state = ~0;
waitforsend = ~0;
}
if (bit_is_set(PINC, PC0) && (pc0state)) {
pc0state = 0;
waitforsend = ~0;
}
if (bit_is_clear(PINC, PC1) && (!pc1state)) {
pc1state = ~0;
waitforsend = ~0;
}
if (bit_is_set(PINC, PC1) && (pc1state)) {
pc1state = 0;
waitforsend = ~0;
}
}
}

@ -6,7 +6,7 @@
#define ExpLED PD6
#define ExpButton PD7
#define HBWTYPE 0xB0
#define HBWTYPE 0xE0
#define HBWMAJOR 1
#define HBWMINOR 2
#define HBWSERIAL0 'C'

@ -7,24 +7,38 @@
uint8_t expled;
uint8_t expbutton;
uint8_t waitforack;
uint8_t waitforsend;
uint8_t acktimer;
int main(void)
uint8_t hbw_get_channel(uint8_t channel, uint8_t data[])
{
uint8_t seq;
if (channel == 1) {
if (bit_is_clear(PIND, ExpButton))
data[0] = 0xC8;
else
data[0] = 0;
return 1;
}
if (channel == 0) {
if (bit_is_clear(PIND, ExpLED))
data[0] = 0;
else
data[0] = 0xC8;
return 1;
}
return 0;
}
my_address[0]=eeprom_read_byte((const uint8_t *)0);
my_address[1]=eeprom_read_byte((const uint8_t *)1);
my_address[2]=eeprom_read_byte((const uint8_t *)2);
my_address[3]=eeprom_read_byte((const uint8_t *)3);
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);
}
}
if ((my_address[0] == 0xFF) &&
(my_address[1] == 0xFF) &&
(my_address[2] == 0xFF) &&
(my_address[3] == 0xFF))
my_address[0] = 0x74;
int main(void)
{
uint8_t state;
DDRD |= (1<<ConfigLED);
DDRD &= ~(1<<ConfigButton);
@ -36,68 +50,28 @@ int main(void)
PORTD &= ~(1<<ExpLED);
PORTD |= (1<<ExpButton);
init_hbw();
expled = 0;
expbutton = 0;
hbw_init();
while(1) {
hbw_loop();
if (rready) {
if ((rdest[0] == my_address[0]) &&
(rdest[1] == my_address[1]) &&
(rdest[2] == my_address[2]) &&
(rdest[3] == my_address[3]) &&
(rmessage[0] == 'h')) {
saddress[0] = raddress[0];
saddress[1] = raddress[1];
saddress[2] = raddress[2];
saddress[3] = raddress[3];
seq = (rctl >> 1) & 3;
sctl = 0x18 | (seq << 5);
smessage[0] = HBWTYPE;
smessage[1] = 0;
slen = 2;
sendmsg();
}
if ((rdest[0] == my_address[0]) &&
(rdest[1] == my_address[1]) &&
(rdest[2] == my_address[2]) &&
(rdest[3] == my_address[3]) &&
(rmessage[0] == 'n')) {
saddress[0] = raddress[0];
saddress[1] = raddress[1];
saddress[2] = raddress[2];
saddress[3] = raddress[3];
seq = (rctl >> 1) & 3;
sctl = 0x18 | (seq << 5);
smessage[0] = 'h';
smessage[1] = 'b';
smessage[2] = 'w';
smessage[3] = 'b';
smessage[4] = 'o';
smessage[5] = 'c';
smessage[6] = 'c';
smessage[7] = '0';
smessage[8] = '0';
smessage[9] = '1';
slen = 10;
sendmsg();
if (bit_is_clear(PIND, ExpButton) && (!expbutton)) {
state = 0xC8;
if (hbw_send_channel(1, 1, &state, 0)) {
expbutton = ~0;
}
if ((rdest[0] == my_address[0]) &&
(rdest[1] == my_address[1]) &&
(rdest[2] == my_address[2]) &&
(rdest[3] == my_address[3]) &&
(rmessage[0] == 'v')) {
saddress[0] = raddress[0];
saddress[1] = raddress[1];
saddress[2] = raddress[2];
saddress[3] = raddress[3];
seq = (rctl >> 1) & 3;
sctl = 0x18 | (seq << 5);
smessage[0] = 1;
smessage[1] = 2;
slen = 2;
sendmsg();
}
if (bit_is_set(PIND, ExpButton) && expbutton) {
state = 0;
if (hbw_send_channel(1, 1, &state, 0)) {
expbutton = 0;
}
rready = 0;
}
}
}

Loading…
Cancel
Save