Added display firmware skeleton
This commit is contained in:
parent
f94aca6887
commit
c1053d1963
3 changed files with 291 additions and 0 deletions
116
display/firmware/Makefile
Normal file
116
display/firmware/Makefile
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
PRG = display
|
||||||
|
PROJ_ROOT = ../..
|
||||||
|
AVRCANLIB_PATH = $(PROJ_ROOT)/avr-can-lib
|
||||||
|
OBJ = main.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_buffer.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_disable_dyn_filter.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_error_register.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_get_buf_message.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_get_dyn_filter.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_get_message.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_send_buf_message.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_send_message.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_set_dyn_filter.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/at90can_set_mode.o \
|
||||||
|
$(AVRCANLIB_PATH)/src/can_buffer.o
|
||||||
|
# These were defined for the avr-can-lib, but they really, really
|
||||||
|
# shouldn't be used there because they affect the whole program.
|
||||||
|
OPTIMIZE = -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||||
|
PROGRAMMER = usbtiny
|
||||||
|
|
||||||
|
MCU_TARGET = atmega32m1
|
||||||
|
DEFS = -DF_CPU=16000000UL -DHAS_CAN_CONFIG_H
|
||||||
|
|
||||||
|
INCLUDES = -I. -I$(PROJ_ROOT) -I$(AVRCANLIB_PATH)
|
||||||
|
LIBS =
|
||||||
|
|
||||||
|
LFUSE = 0xdf
|
||||||
|
HFUSE = 0xd9
|
||||||
|
EFUSE = 0xfe
|
||||||
|
|
||||||
|
EXTRA_CLEAN_FILES =
|
||||||
|
|
||||||
|
# You should not have to change anything below here.
|
||||||
|
|
||||||
|
CC = avr-gcc
|
||||||
|
DUDE = avrdude
|
||||||
|
|
||||||
|
HOST_CC = gcc
|
||||||
|
HOST_CFLAGS = -O0 -g
|
||||||
|
HOST_LDFLAGS =
|
||||||
|
|
||||||
|
# Override is only needed by avr-lib build system.
|
||||||
|
|
||||||
|
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS) $(INCLUDES)
|
||||||
|
override LDFLAGS = -Wl,-Map,$(PRG).map
|
||||||
|
|
||||||
|
DUDEFLAGS = -c $(PROGRAMMER) -p $(MCU_TARGET)
|
||||||
|
|
||||||
|
OBJCOPY = avr-objcopy
|
||||||
|
OBJDUMP = avr-objdump
|
||||||
|
|
||||||
|
all: $(PRG).elf lst text eeprom
|
||||||
|
|
||||||
|
$(PRG).elf: $(OBJ) $(LIBS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJ) $(PRG).elf $(PRG).lst $(PRG).map $(PRG).bin $(PRG).hex $(PRG).srec $(PRG)_eeprom.bin $(PRG)_eeprom.hex $(PRG)_eeprom.srec $(EXTRA_CLEAN_FILES)
|
||||||
|
|
||||||
|
lst: $(PRG).lst
|
||||||
|
|
||||||
|
%.lst: %.elf
|
||||||
|
$(OBJDUMP) -h -S $< > $@
|
||||||
|
|
||||||
|
# Rules for flashing, EEPROM writing and fuse bit setting
|
||||||
|
|
||||||
|
flash: $(PRG).hex $(PRG)_eeprom.hex
|
||||||
|
$(DUDE) $(DUDEFLAGS) -U eeprom:w:$(PRG)_eeprom.hex:i -U flash:w:$(PRG).hex:i
|
||||||
|
|
||||||
|
flashprg: $(PRG).hex
|
||||||
|
$(DUDE) $(DUDEFLAGS) -U flash:w:$(PRG).hex:i
|
||||||
|
|
||||||
|
flasheep: $(PRG)_eeprom.hex
|
||||||
|
$(DUDE) $(DUDEFLAGS) -U eeprom:w:$(PRG)_eeprom.hex:i
|
||||||
|
|
||||||
|
fuse:
|
||||||
|
$(DUDE) $(DUDEFLAGS) -U hfuse:w:$(HFUSE):m -U lfuse:w:$(LFUSE):m -U efuse:w:$(EFUSE):m
|
||||||
|
|
||||||
|
# Rules for building the .text rom images
|
||||||
|
|
||||||
|
text: hex bin srec
|
||||||
|
|
||||||
|
hex: $(PRG).hex
|
||||||
|
bin: $(PRG).bin
|
||||||
|
srec: $(PRG).srec
|
||||||
|
|
||||||
|
%.hex: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -O ihex $< $@
|
||||||
|
|
||||||
|
%.srec: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -O srec $< $@
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
$(OBJCOPY) -j .text -j .data -O binary $< $@
|
||||||
|
|
||||||
|
# Rules for building the .eeprom rom images
|
||||||
|
|
||||||
|
eeprom: ehex ebin esrec
|
||||||
|
|
||||||
|
ehex: $(PRG)_eeprom.hex
|
||||||
|
ebin: $(PRG)_eeprom.bin
|
||||||
|
esrec: $(PRG)_eeprom.srec
|
||||||
|
|
||||||
|
%_eeprom.hex: %.elf
|
||||||
|
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ \
|
||||||
|
|| { echo empty $@ not generated; exit 0; }
|
||||||
|
|
||||||
|
%_eeprom.srec: %.elf
|
||||||
|
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ \
|
||||||
|
|| { echo empty $@ not generated; exit 0; }
|
||||||
|
|
||||||
|
%_eeprom.bin: %.elf
|
||||||
|
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ \
|
||||||
|
|| { echo empty $@ not generated; exit 0; }
|
||||||
|
|
79
display/firmware/can_config.h
Normal file
79
display/firmware/can_config.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#define CAN_CONFIG_LOADED
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
/* Global settings for building the can-lib and application program.
|
||||||
|
*
|
||||||
|
* The following two #defines must be set identically for the can-lib and
|
||||||
|
* your application program. They control the underlying CAN struct. If the
|
||||||
|
* settings disagree, the underlying CAN struct will be broken, with
|
||||||
|
* unpredictable results.
|
||||||
|
* If can.h detects that any of the #defines is not defined, it will set them
|
||||||
|
* to the default values shown here, so it is in your own interest to have a
|
||||||
|
* consistent setting. Ommiting the #defines in both can-lib and application
|
||||||
|
* program will apply the defaults in a consistent way too.
|
||||||
|
*
|
||||||
|
* Select if you want to use 29 bit identifiers.
|
||||||
|
*/
|
||||||
|
#define SUPPORT_EXTENDED_CANID 1
|
||||||
|
|
||||||
|
/* Select if you want to use timestamps.
|
||||||
|
* Timestamps are sourced from a register internal to the AT90CAN.
|
||||||
|
* Selecting them on any other controller will have no effect, they will
|
||||||
|
* be 0 all the time.
|
||||||
|
*/
|
||||||
|
#define SUPPORT_TIMESTAMPS 0
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
/* Global settings for building the can-lib.
|
||||||
|
*
|
||||||
|
* Select ONE CAN controller for which you are building the can-lib.
|
||||||
|
*/
|
||||||
|
#define SUPPORT_MCP2515 0
|
||||||
|
#define SUPPORT_AT90CAN 1
|
||||||
|
#define SUPPORT_SJA1000 0
|
||||||
|
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
/* Setting for MCP2515
|
||||||
|
*
|
||||||
|
* Declare which pins you are using for communication.
|
||||||
|
* Remember NOT to use them in your application!
|
||||||
|
* It is a good idea to use bits from the port that carries MOSI, MISO, SCK.
|
||||||
|
*/
|
||||||
|
#define MCP2515_CS B,4
|
||||||
|
#define MCP2515_INT B,2
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Setting for SJA1000
|
||||||
|
|
||||||
|
#define SJA1000_INT E,0
|
||||||
|
#define SJA1000_MEMORY_MAPPED 1
|
||||||
|
|
||||||
|
// memory-mapped interface
|
||||||
|
#define SJA1000_BASE_ADDR 0x8000 // for ATMega162
|
||||||
|
|
||||||
|
/*
|
||||||
|
// port-interface
|
||||||
|
#define SJA1000_WR D,6
|
||||||
|
#define SJA1000_RD D,7
|
||||||
|
|
||||||
|
#define SJA1000_ALE E,1
|
||||||
|
#define SJA1000_CS C,0
|
||||||
|
#define SJA1000_DATA A
|
||||||
|
*/
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Setting for AT90CAN
|
||||||
|
|
||||||
|
// Number of CAN messages which are buffered in RAM additinally to the MObs
|
||||||
|
#define CAN_RX_BUFFER_SIZE 16
|
||||||
|
#define CAN_TX_BUFFER_SIZE 8
|
||||||
|
|
||||||
|
// only available if CAN_TX_BUFFER_SIZE > 0
|
||||||
|
#define CAN_FORCE_TX_ORDER 1
|
||||||
|
|
||||||
|
#endif // CONFIG_H
|
96
display/firmware/main.c
Normal file
96
display/firmware/main.c
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <can.h>
|
||||||
|
#include <messages.h>
|
||||||
|
|
||||||
|
static bool report_change = false;
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
// Enable GPIO: PB2, PB3, PB4 output, low; PB5 input, pull-up on
|
||||||
|
PORTB = (PORTB & ~(_BV(PB2) | _BV(PB3) | _BV(PB4))) | _BV(PB5);
|
||||||
|
DDRB = (DDRB & ~_BV(PB5)) | (_BV(PB2) | _BV(PB3) | _BV(PB4));
|
||||||
|
|
||||||
|
// 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 = 0;
|
||||||
|
|
||||||
|
if (can_check_free_buffer()) {
|
||||||
|
can_t msg = {
|
||||||
|
.id = CAN_MSG_DISPLAY_STATUS,
|
||||||
|
.flags = {
|
||||||
|
.rtr = 0,
|
||||||
|
},
|
||||||
|
.length = 2,
|
||||||
|
.data = { (uint8_t) (status >> 8), (uint8_t) status, },
|
||||||
|
};
|
||||||
|
can_send_message(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_display(uint8_t command, const uint8_t *data, uint8_t length) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loop() {
|
||||||
|
// 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) {
|
||||||
|
write_display(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init();
|
||||||
|
while (1) {
|
||||||
|
loop();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue