Compare commits

...

No commits in common. '4a9572c40fde82ca106253cd1239a241fff034c6' and '48d1fc0bb060f6165a63e8077b4a7467d4564968' have entirely different histories.

@ -9,8 +9,9 @@ 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
all: testnode.hex relaisnode.hex
testnode.o: testnode.c hbw.h hw.h testhw.h
$(CC) $(CFLAGS) -DTESTNODE -c $< -o $@
@ -21,6 +22,15 @@ testhbw.o: hbw.c hbw.h hw.h testhw.h
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 $< $@

210
hbw.c

@ -6,12 +6,12 @@
#include <string.h>
#include "hbw.h"
uint8_t my_address[4];
uint32_t my_address;
uint8_t rind;
uint16_t rcrc;
uint8_t raddress[4];
uint8_t rdest[4];
uint32_t raddress;
uint32_t rdest;
uint8_t resc;
uint8_t rctl;
volatile uint8_t rready;
@ -23,16 +23,23 @@ uint8_t sdisc;
uint8_t sctl;
uint16_t scrc;
uint8_t sesc;
uint8_t saddress[4];
uint32_t saddress;
uint8_t slen;
uint8_t smessage[62];
uint16_t sdelay;
uint8_t asent;
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;
@ -53,16 +60,14 @@ static uint16_t crc16shift(uint16_t crc, uint8_t data)
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;
// 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)
@ -124,7 +129,7 @@ void rloop(void)
}
if (sind < 5) {
send(saddress[sind-1],1);
send(((uint8_t*)&saddress)[sind-1],1);
return;
}
if (sind == 5) {
@ -132,7 +137,7 @@ void rloop(void)
return;
}
if (sind < 10) {
send(my_address[sind-6],1);
send(((uint8_t*)&my_address)[sind-6],1);
return;
}
if (sind == 10) {
@ -208,10 +213,7 @@ static void announce(void)
{
sctl = 0xF8;
saddress[0] = 0xFF;
saddress[1] = 0xFF;
saddress[2] = 0xFF;
saddress[3] = 0xFF;
saddress = 0xFFFFFFFF;
slen = 16;
@ -244,6 +246,16 @@ void hbw_init(void)
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);
@ -260,9 +272,14 @@ void hbw_init(void)
rready = 0;
asent = 0;
hbw_timer = 0;
gotack = 0;
waitack = 0;
configled = 0;
configbutton = 0;
configstate = 0;
readaddr();
srand(my_address[3]);
srand(my_address);
sdelay = 1000 + (rand() & 0x1F);
sei();
}
@ -272,30 +289,23 @@ 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 == my_address) &&
(raddress == aaddress) &&
waitack) {
waitack = 0;
gotack = 1;
}
if ((rdest[0] == my_address[0]) &&
(rdest[1] == my_address[1]) &&
(rdest[2] == my_address[2]) &&
(rdest[3] == my_address[3]) &&
if ((rdest == my_address) &&
((rctl & 0x11) == 0x10)) {
saddress[0] = raddress[0];
saddress[1] = raddress[1];
saddress[2] = raddress[2];
saddress[3] = raddress[3];
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]);
@ -332,6 +342,8 @@ static void process(void)
sendmsg();
break;
case 'v':
if (rlen != 2)
return;
smessage[0] = HBWMAJOR;
smessage[1] = HBWMINOR;
slen = 2;
@ -340,6 +352,10 @@ static void process(void)
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);
@ -349,6 +365,10 @@ static void process(void)
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]);
@ -358,8 +378,12 @@ static void process(void)
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;
@ -368,6 +392,7 @@ static void process(void)
sendmsg();
break;
case 'C':
hbw_read_config();
slen = 0;
sctl = 0x19 | (seq << 5);
sendmsg();
@ -376,6 +401,14 @@ static void process(void)
}
}
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();
@ -388,33 +421,111 @@ void hbw_loop(void)
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<<ConfigLED);
else
PORTD &= ~(1<<ConfigLED);
#endif
}
uint8_t hbw_send_channel(uint8_t channel, uint8_t length, uint8_t const * const data, uint32_t target_address)
{
if (gotack) {
gotack = 0;
waitack = 0;
return 1;
}
if (!is_bus_free())
return 0;
if (waitack)
return 0;
if(waitack > 2) {
waitack = 0;
return 2;
}
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);
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();
waitack = 1;
if (aaddress == 0xFFFFFFFF)
return 1;
waitack++;
gotack = 0;
sdelay = hbw_timer + 100 + (rand() & 0x1F);
return 0;
}
@ -449,7 +560,7 @@ ISR(USART_RX_vect)
if ((rind == 1) || (rind == 255))
return;
if (rind < 6) {
rdest[rind-2] = c;
((uint8_t*)&rdest)[rind-2] = c;
return;
}
if (rind == 6) {
@ -457,7 +568,7 @@ ISR(USART_RX_vect)
return;
}
if (rind < 11) {
raddress[rind-7] = c;
((uint8_t*)&raddress)[rind-7] = c;
return;
}
if (rind == 11) {
@ -479,6 +590,7 @@ ISR(USART_RX_vect)
if (rcrc)
return;
rready = 1;
rlen = rlen - 2;
return;
}
}

@ -11,9 +11,10 @@ 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, 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[]);
void hbw_read_config(void);
#endif

@ -1,13 +1,13 @@
<?xml version="1.0"?>
<device eep_size="512" version="01">
<supported_types>
<type priority="2" id="HBW-EBRELAY" name="Elektor EBus Relais Board">
<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-EBRELAY_dev_master" type="MASTER">
<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">
@ -62,7 +62,7 @@
</parameter>
</paramset>
</channel>
<channel index="2" type="SENSOR" count="2" physical_index_offset="-1">
<channel index="3" 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">

@ -1,7 +1,23 @@
#ifndef __RELAISHW_H__
#define __RELAISHW_H__
#define TestLED PD4
#define TestButton PD5
#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

@ -1,28 +1,70 @@
#include "hw.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "relaishw.h"
#include "rs485.h"
#include "eb.h"
#include "hbw.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;
void hbw_read_config(void)
{
}
int main(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[])
{
uint8_t i;
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);
}
}
init_rs485();
DDRD |= (1<<TestLED);
DDRD &= ~(1<<TestButton);
int main(void)
{
uint8_t state;
DDRB |= (1<<Relais1);
DDRB |= (1<<Relais2);
@ -30,145 +72,52 @@ int main(void)
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;
hbw_init();
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;
}
hbw_loop();
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;
state = 200;
if (hbw_send_channel(2, 1, &state, 0)) {
pc0state = ~0;
}
}
if (bit_is_set(PINC, PC0) && (pc0state)) {
pc0state = 0;
waitforsend = ~0;
if (bit_is_set(PINC, PC0) && pc0state) {
state = 0;
if (hbw_send_channel(2, 1, &state, 0)) {
pc0state = 0;
}
}
if (bit_is_clear(PINC, PC1) && (!pc1state)) {
pc1state = ~0;
waitforsend = ~0;
state = 200;
if (hbw_send_channel(3, 1, &state, 0)) {
pc1state = ~0;
}
}
if (bit_is_set(PINC, PC1) && (pc1state)) {
pc1state = 0;
waitforsend = ~0;
if (bit_is_set(PINC, PC1) && pc1state) {
state = 0;
if (hbw_send_channel(3, 1, &state, 0)) {
pc1state = 0;
}
}
}
}

@ -7,11 +7,15 @@
uint8_t expled;
uint8_t expbutton;
void hbw_read_config(void)
{
}
uint8_t hbw_get_channel(uint8_t channel, uint8_t data[])
{
if (channel == 1) {
if (bit_is_clear(PIND, ExpButton))
data[0] = 0xC8;
data[0] = 200;
else
data[0] = 0;
return 1;
@ -20,7 +24,7 @@ uint8_t hbw_get_channel(uint8_t channel, uint8_t data[])
if (bit_is_clear(PIND, ExpLED))
data[0] = 0;
else
data[0] = 0xC8;
data[0] = 200;
return 1;
}
return 0;
@ -40,13 +44,9 @@ int main(void)
{
uint8_t state;
DDRD |= (1<<ConfigLED);
DDRD &= ~(1<<ConfigButton);
DDRD |= (1<<ExpLED);
DDRD &= ~(1<<ExpButton);
PORTD &= ~(1<<ConfigLED);
PORTD |= (1<<ConfigButton);
PORTD &= ~(1<<ExpLED);
PORTD |= (1<<ExpButton);
@ -59,7 +59,7 @@ int main(void)
hbw_loop();
if (bit_is_clear(PIND, ExpButton) && (!expbutton)) {
state = 0xC8;
state = 200;
if (hbw_send_channel(1, 1, &state, 0)) {
expbutton = ~0;

Loading…
Cancel
Save