242 lines
4.1 KiB
C
242 lines
4.1 KiB
C
#include <inttypes.h>
|
|
#include <stdbool.h>
|
|
#include <avr/io.h>
|
|
#include <avr/interrupt.h>
|
|
#include <util/delay.h>
|
|
#include <can.h>
|
|
#include <messages.h>
|
|
#include "display.h"
|
|
#include "button.h"
|
|
|
|
static bool report_change = false;
|
|
static uint8_t last_buttons = 0;
|
|
|
|
static void init();
|
|
static void send_status();
|
|
static void loop();
|
|
|
|
/* I/O map version 1 (non-working):
|
|
PB2 BUTTON0
|
|
PB3 BUTTON1
|
|
PB4 BUTTON2
|
|
PB5 BUTTON3
|
|
PB6 BUTTON4
|
|
PC0 BUTTON5
|
|
PC1 BUTTON6
|
|
PC2 CANTX
|
|
PC3 CANRX
|
|
PC4 BUTTON7
|
|
PC5 VFDRS
|
|
PC6 VFDRW
|
|
PC7 VFDE
|
|
PD0 VFDDB0
|
|
PD1 VFDDB1
|
|
PD2 VFDDB2
|
|
PD3 VFDDB3
|
|
PD4 VFDDB4
|
|
PD5 VFDDB5
|
|
PD6 VFDDB6
|
|
PD7 VFDDB7
|
|
*/
|
|
|
|
/* I/O map version 1 (patched):
|
|
PB0 VFDDB2
|
|
PB1 VFDDB3
|
|
PB2 BUTTON0
|
|
PB3 BUTTON1
|
|
PB4 BUTTON2
|
|
PB5 BUTTON3
|
|
PB6 BUTTON4
|
|
PB7 VFDDB4
|
|
PC0 BUTTON5
|
|
PC1 BUTTON6
|
|
PC2 CANTX
|
|
PC3 CANRX
|
|
PC4 BUTTON7
|
|
PC5 VFDRS
|
|
PC6 VFDRW
|
|
PC7 VFDE
|
|
PD0 VFDDB0
|
|
PD1 VFDDB1
|
|
PD2 -
|
|
PD3 -
|
|
PD4 -
|
|
PD5 VFDDB5
|
|
PD6 VFDDB6
|
|
PD7 VFDDB7
|
|
*/
|
|
|
|
/* I/O map version 2:
|
|
PB0 VFDDB0
|
|
PB1 VFDDB1
|
|
PB2 VFDDB2
|
|
PB3 VFDDB3
|
|
PB4 VFDDB4
|
|
PB5 VFDDB5
|
|
PB6 VFDDB6
|
|
PB7 VFDDB7
|
|
PC0 BUTTON5
|
|
PC1 BUTTON7
|
|
PC2 CANTX
|
|
PC3 CANRX
|
|
PC4 BUTTON6
|
|
PC5 VFDRS
|
|
PC6 VFDRW
|
|
PC7 VFDE
|
|
PD0 BUTTON0
|
|
PD1 BUTTON1
|
|
PD2 -
|
|
PD3 -
|
|
PD4 -
|
|
PD5 BUTTON2
|
|
PD6 BUTTON3
|
|
PD7 BUTTON4
|
|
*/
|
|
|
|
static void init() {
|
|
// initialize buttons
|
|
button_init();
|
|
last_buttons = button_get();
|
|
|
|
// initialize VFD
|
|
display_init();
|
|
// clear
|
|
display_write(0x01, 0, 0);
|
|
// display on, no cursor
|
|
display_write(0x0c, 0, 0);
|
|
|
|
// Initialize CAN interface
|
|
can_init(BITRATE_125_KBPS);
|
|
// Regular receive/transmit mode
|
|
can_set_mode(NORMAL_MODE);
|
|
|
|
// Filter for messages addressed to us (RTR on)
|
|
can_filter_t us = {
|
|
.id = CAN_HOSTID_DISPLAY,
|
|
.mask = CAN_HOSTID_MASK,
|
|
.flags = {
|
|
.rtr = 1,
|
|
.extended = 0,
|
|
},
|
|
};
|
|
can_set_filter(0, &us);
|
|
// Filter for public messages (RTR off)
|
|
can_filter_t pub = {
|
|
.id = CAN_HOSTID_BROADCAST,
|
|
.mask = CAN_HOSTID_MASK,
|
|
.flags = {
|
|
.rtr = 0,
|
|
.extended = 0,
|
|
},
|
|
};
|
|
can_set_filter(1, &pub);
|
|
|
|
// Enable interrupts to start reception
|
|
sei();
|
|
}
|
|
|
|
static void send_status() {
|
|
uint8_t status = button_get();
|
|
|
|
if (can_check_free_buffer()) {
|
|
can_t msg = {
|
|
.id = CAN_MSG_DISPLAY_STATUS,
|
|
.flags = {
|
|
.rtr = 0,
|
|
},
|
|
.length = 1,
|
|
.data = { (uint8_t) status, },
|
|
};
|
|
can_send_message(&msg);
|
|
}
|
|
}
|
|
|
|
static void loop() {
|
|
// Report button state changes first
|
|
if (report_change) {
|
|
uint8_t current = button_get();
|
|
if (current != last_buttons) {
|
|
send_status();
|
|
last_buttons = current;
|
|
}
|
|
}
|
|
// 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 CAN_MSG_DISPLAY_STATUS:
|
|
send_status();
|
|
break;
|
|
case CAN_MSG_DISPLAY_CMD:
|
|
if (msg.length >= 1) {
|
|
display_write(msg.data[0], &msg.data[1], msg.length - 1);
|
|
}
|
|
break;
|
|
case CAN_MSG_AUTO_STATUS:
|
|
if (msg.length == 1) {
|
|
report_change = msg.data[0] ? true : false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void test() {
|
|
static uint8_t test_char = 0;
|
|
display_write(0x80, (const uint8_t *) "Hello, world", 12);
|
|
display_write(0xc0, (const uint8_t *) &test_char, 1);
|
|
test_char++;
|
|
_delay_ms(100);
|
|
}
|
|
|
|
static void test2() {
|
|
// PC5, PC6, PC7: output (VFD RS, RW, E), RS=0, RW=1, E=1
|
|
// PD0, PD1, PB0, PB1, PB7, PD5, PD6, PD7: output (VFD DB) - can be switched to input (pullup not needed)
|
|
PORTC &= ~(_BV(PC5) | _BV(PC6) | _BV(PC7));
|
|
PORTB &= ~(_BV(PB0) | _BV(PB1) | _BV(PB7));
|
|
PORTD &= ~(_BV(PD0) | _BV(PD1) | _BV(PD5) | _BV(PD6) | _BV(PD7));
|
|
PORTC |= _BV(PC5);
|
|
_delay_us(10);
|
|
PORTC &= ~_BV(PC5);
|
|
PORTC |= _BV(PC6);
|
|
_delay_us(10);
|
|
PORTC &= ~_BV(PC6);
|
|
PORTC |= _BV(PC7);
|
|
_delay_us(10);
|
|
PORTC &= ~_BV(PC7);
|
|
PORTD |= _BV(PD0);
|
|
_delay_us(10);
|
|
PORTD &= ~_BV(PD0);
|
|
PORTD |= _BV(PD1);
|
|
_delay_us(10);
|
|
PORTD &= ~_BV(PD1);
|
|
PORTB |= _BV(PB0);
|
|
_delay_us(10);
|
|
PORTB &= ~_BV(PB0);
|
|
PORTB |= _BV(PB1);
|
|
_delay_us(10);
|
|
PORTB &= ~_BV(PB1);
|
|
PORTB |= _BV(PB7);
|
|
_delay_us(10);
|
|
PORTB &= ~_BV(PB7);
|
|
PORTD |= _BV(PD5);
|
|
_delay_us(10);
|
|
PORTD &= ~_BV(PD5);
|
|
PORTD |= _BV(PD6);
|
|
_delay_us(10);
|
|
PORTD &= ~_BV(PD6);
|
|
PORTD |= _BV(PD7);
|
|
_delay_us(10);
|
|
PORTD &= ~_BV(PD7);
|
|
}
|
|
|
|
int main() {
|
|
init();
|
|
while (1) {
|
|
test();
|
|
loop();
|
|
}
|
|
}
|