Adapted poweriface firmware to use new specs

This commit is contained in:
Gregor Riepl 2021-01-17 15:38:11 +01:00
parent 42726c06c2
commit 0dc044e43f

View file

@ -4,65 +4,40 @@
#include <util/delay.h> #include <util/delay.h>
#include <can.h> #include <can.h>
#if ENABLE_SLEEP static void init() {
#include <avr/sleep.h> // Enable GPIO: PB2, PB3, PB4 output, low; PB5 input, pull-up on
#endif PORTB = (PORTB & ~(_BV(PB2) | _BV(PB3) | _BV(PB4))) | _BV(PB5);
#if ENABLE_WATCHDOG DDRB = (DDRB & ~_BV(PB5)) | (_BV(PB2) | _BV(PB3) | _BV(PB4));
#include <avr/watchdog.h>
#endif
// Global state // Initialize CAN interface
struct { can_init(BITRATE_125_KBPS);
#if ENABLE_SHUTDOWN // Regular receive/transmit mode
// Main loop run state (1 = running, 0 = shutdown) can_set_mode(NORMAL_MODE);
uint8_t run;
#endif
// Message ready?
uint8_t ready;
// Receive buffer
uint8_t buffer[8];
// Message address
uint32_t address;
} state; //__attribute__ ((section (".noinit")));
inline void init(); // __attribute__((always_inline)); // Filter for status requests and dispense commands
inline void shutdown(); // __attribute__((always_inline)); can_filter_t filter = {
.id = 0x11,
.mask = 0x7ff,
.flags = {
.rtr = 1,
.extended = 0,
},
};
can_set_filter(0, &filter);
can_filter_t disp = {
.id = 0x21,
.mask = 0x7ff,
.flags = {
.rtr = 0,
.extended = 0,
},
};
can_set_filter(1, &disp);
inline void init() { // Enable interrupts to start reception
// Disable interrupts before init sei();
cli();
// Set state
//state.run = 0;
#if ENABLE_WATCHDOG
// Enable watchdog timer
wdt_enable(WDTO_500MS);
#endif
// Set clock divider to 1 after startup
// This is an alternative to clearing the CLKDIV8 fuse
// CLKPR = _BV(CLKPCE);
// CLKPR = 0x00;
// Enable GPIO and set low
// PORTB |= _BV(PB5);
PORTB &= ~(_BV(PB2) | _BV(PB3) | _BV(PB4));
DDRB |= (_BV(PB2) | _BV(PB3) | _BV(PB4));
} }
inline void shutdown() {
// Disable interrupts
// Not needed when not using sleep, the compiler will generate a cli+busy loop
#if ENABLE_SLEEP
cli();
#endif
#if ENABLE_WATCHDOG
// Disable watchdog
wdt_disable();
#endif
}
// UART bit-uart_bang 8 bits on the debug port, LSB first, 1 stop bit, no parity, 9600 baud // UART bit-uart_bang 8 bits on the debug port, LSB first, 1 stop bit, no parity, 9600 baud
void uart_bang(uint8_t data) { void uart_bang(uint8_t data) {
@ -83,7 +58,7 @@ void uart_bang(uint8_t data) {
_delay_us(102); _delay_us(102);
} }
// Bit-bang pattern (LSB first) out the data line and strobe // Bit-bang pattern (LSB first) out the data line
uint16_t bang(uint16_t data) { uint16_t bang(uint16_t data) {
uint16_t in = 0; uint16_t in = 0;
for (uint8_t i = 0; i < 16; i++) { for (uint8_t i = 0; i < 16; i++) {
@ -93,9 +68,10 @@ uint16_t bang(uint16_t data) {
} else { } else {
PORTB &= ~_BV(PB4); PORTB &= ~_BV(PB4);
} }
// Clock // Clock up
PORTB |= _BV(PB2); PORTB |= _BV(PB2);
_delay_us(4); _delay_us(4);
// Clock down
PORTB &= ~_BV(PB2); PORTB &= ~_BV(PB2);
_delay_us(4); _delay_us(4);
// Read // Read
@ -106,114 +82,67 @@ uint16_t bang(uint16_t data) {
data >>= 1; data >>= 1;
in <<= 1; in <<= 1;
} }
// Strobe // Clear data
PORTB |= _BV(PB3);
_delay_us(4);
PORTB &= ~_BV(PB3);
// Clear
PORTB &= ~_BV(PB4); PORTB &= ~_BV(PB4);
return in; return in;
} }
int main() { // Strobe output
// Initialize hardware void strobe() {
init(); // Strobe
// Initialize CAN interface PORTB |= _BV(PB3);
can_init(BITRATE_125_KBPS); _delay_us(4);
// Set up command filter PORTB &= ~_BV(PB3);
can_set_mode(NORMAL_MODE); }
can_filter_t filter = {
.id = 0x100,
.mask = 0x1ff,
.flags = {
.rtr = 0,
.extended = 0,
},
};
can_set_filter(0, &filter);
// wait before start
//_delay_ms(10000);
// Enable interrupts to start reception static void send_status() {
sei(); // Bit-bang register contents in (also send out zeros, but don't strobe)
uint16_t status = bang(0);
// Main loop
#if ENABLE_SHUTDOWN
state.run = 1;
while (state.run) {
#else
while (1) {
#endif
#if 0
// Test pattern
for (uint8_t i = 0; i < 5; i++) {
bang(0x0080 >> i);
_delay_ms(1000);
bang(0x0000);
_delay_ms(1000);
}
#else
// Check for new messages
if (can_check_message()) {
can_t msg = { 0 };
uint8_t status = can_get_message(&msg);
// uart_bang(status);
uint16_t in = 0;
if (status != 0 && msg.id == 0x100 && msg.length == 1) {
// uart_bang(msg.id & 0xff);
// uart_bang((msg.id >> 8) & 0xff);
// uart_bang((msg.id >> 16) & 0xff);
// uart_bang((msg.id >> 24) & 0xff);
// uart_bang(msg.flags.rtr);
// uart_bang(msg.flags.extended);
// uart_bang(msg.length);
// for (uint8_t i = 0; i < msg.length; i++) {
// uart_bang(msg.data[i]);
// }
//uint16_t out = msg.data[0] | ((uint16_t) msg.data[1] << 8);
if (msg.data[0] < 5) {
uint16_t out = 0x0080 >> msg.data[0];
bang(out);
_delay_ms(3000);
in = bang(0x0000);
}
//in = bang(0xffff);
}
if (can_check_free_buffer()) { if (can_check_free_buffer()) {
can_t msg = { can_t msg = {
.id = 0x11, .id = 0x11,
.flags = { .flags = {
.rtr = 0, .rtr = 0,
.extended = 0,
}, },
.length = 5, .length = 2,
.data = { 0xc0, 0xff, 0xee, in & 0xff, (in >> 8) & 0xff, }, .data = { (uint8_t) (status >> 8), (uint8_t) status, },
}; };
uint8_t status = can_send_message(&msg); can_send_message(&msg);
// uart_bang(status);
} else {
// uart_bang(0xff);
} }
} }
#endif
#if ENABLE_SLEEP static void fire_relay(uint8_t num) {
// Let the MCU take a nap if (num < 5) {
set_sleep_mode(SLEEP_MODE_IDLE); uint16_t out = 0x0080 >> num;
sleep_mode(); bang(out);
#endif strobe();
}
} }
// Disable all peripherals and interrupts static void loop() {
shutdown(); // Check for new messages
if (can_check_message()) {
can_t msg = { 0 };
uint8_t status = can_get_message(&msg);
if (status != 0) {
switch (msg.id) {
case 0x11:
if (msg.flags.rtr) {
send_status();
}
case 0x21:
if (msg.length == 1) {
fire_relay(msg.data[0]);
}
}
}
}
}
// Power the MCU down int main() {
#if ENABLE_SLEEP init();
while (1) { while (1) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); loop();
sleep_mode();
} }
__builtin_unreachable();
#endif
} }