diff options
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | door.c | 116 |
2 files changed, 131 insertions, 6 deletions
@@ -1,21 +1,30 @@ .PHONY: flash love -TARGET=lightctrl +TARGETS=door lightctrl + CFLAGS_OPT=-Os \ -fpredictive-commoning -fmerge-all-constants -fmodulo-sched -fmodulo-sched-allow-regmoves \ -fgcse-sm -fgcse-las -fgcse-after-reload -fconserve-stack \ -fwhole-program CFLAGS_WARN=-std=gnu99 -Wall -Wextra -Wno-unused -pedantic CFLAGS_LD=-Wl,-T,avr4-signature.x -CFLAGS=-mmcu=atmega48 ${CFLAGS_WARN} ${CFLAGS_OPT} ${CFLAGS_LD} +CFLAGS=${CFLAGS_WARN} ${CFLAGS_OPT} ${CFLAGS_LD} +MCU_door=48 +MCU_lightctrl=88 -love: ${TARGET}.elf +love: $(foreach target,$(TARGETS),$(target).elf) + avr-size $^ +ifdef TARGET flash: ${TARGET}.flash - avrdude -p m48 -c stk500v2 -P avrdoper -y -U flash:w:$< + avrdude -p m$(MCU_$(basename $<)) -c stk500v2 -P avrdoper -y -U flash:w:$< +else +flash: + @echo the flash target is available only with TARGET set to something. use e.g. \"make flash TARGET=door\" >&2 + @false +endif %.flash: %.elf Makefile avr-objcopy -j .text -j .data -O ihex $< $@ %.elf: %.c *.c *.x Makefile - avr-gcc ${CFLAGS} -o $@ $< - avr-size $@ + avr-gcc -mmcu=atmega$(MCU_$(basename $@)) ${CFLAGS} -o $@ $< @@ -0,0 +1,116 @@ +#define F_CPU 8000000 +#include <stdint.h> +#include <stdbool.h> +#include <avr/io.h> +#include <avr/interrupt.h> +#include <avr/pgmspace.h> +#include <util/delay.h> + +const uint8_t __signature[3] __attribute__((section (".signature"), used)) = + { SIGNATURE_2, SIGNATURE_1, SIGNATURE_0 }; + +#define B_SCK 5 +#define B_MISO 4 +#define B_MOSI 3 +#define B_SS 2 + +#define B_EXITLIGHT 1 +#define B_LIGHTBARRIER 0 + +#define B_IN (1 << B_LIGHTBARRIER) + +#define D_LED 4 +#define D_DOORLOCK 5 +#define D_DOORRIGHT 6 +#define D_DOORLEFT 7 + +#define D_IN ((1 << D_DOORLOCK) | (1 << D_DOORRIGHT) | (1 << D_DOORLEFT)) + +#include "uart.c" +#include "can.c" + +static uint16_t tick = 4; + +static uint8_t pinstat; +static struct sendbuf { + uint8_t door_lock; + uint8_t door_left; + uint8_t door_right; + uint8_t lightbarrier; +} sendbuf; + +ISR(TIMER1_OVF_vect) +{ + uint8_t newpin; + + tick++; + if (tick == 0) + tick = 16; + + if (tick < 4096 || ((tick & 16383) < 1024)) + PORTD |= (1 << D_LED); + else + PORTD &= ~(1 << D_LED); + + newpin = (PIND & D_IN) | (PINB & B_IN); + pinstat ^= newpin; +#define pin_to_field(pin, field) \ + if (pinstat & (1 << pin)) { \ + sendbuf.field++; \ + if (newpin & (1 << pin)) \ + sendbuf.field |= 1; \ + else \ + sendbuf.field &= ~1; \ + } + + pin_to_field(D_DOORLOCK, door_lock); + pin_to_field(D_DOORRIGHT, door_right); + pin_to_field(D_DOORLEFT, door_left); + pin_to_field(B_LIGHTBARRIER, lightbarrier); + + if (pinstat) { + if (tick >= 128 && tick < 65408) + tick = 4; + else if (tick < 128) + tick = 65408; + } + + pinstat = newpin; + + if (tick == 8 || tick == 16) + can_send(CANA_SENSOR_F(0x100), sizeof(sendbuf), (uint8_t *)&sendbuf); +} + +int main(void) +{ + DDRB = (1 << B_SCK) | (1 << B_MOSI) | (1 << B_SS) | (1 << B_EXITLIGHT); + PORTB = (1 << B_SS) | (1 << B_EXITLIGHT) | B_IN; + DDRD = (1 << D_LED); + PORTD = D_IN; + + uart_init(); + can_preinit(); + + sei(); + uart_puts("\ninit done\n"); + + can_init(); + can_CANSTAT(); + + TCNT1 = 0; + OCR1A = 128; + TIMSK1 = (1 << TOIE1); + TIFR1 = (1 << TOV1); + // 8 MHz / 8 / 256 = 3906.25 Hz + // Fast PWM (8-bit) mode + TCCR1A = (1 << COM1A1) | (1 << WGM10); + TCCR1B = (1 << WGM12) | (1 << CS11); + + while (1) { + if (canint) { + canint = false; + can_int(); + } + _delay_ms(1); + } +} |