mirror of
https://github.com/binary-kitchen/doorlockd
synced 2024-12-22 10:24:26 +01:00
Added new AVR software
This commit is contained in:
parent
6b8e45ef42
commit
07cddb29f8
@ -79,7 +79,7 @@ OBJDIR = obj
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = main.c
|
||||
SRC = main.c uart.c
|
||||
|
||||
|
||||
# List C++ source files here. (C dependencies are automatically generated.)
|
||||
@ -268,7 +268,7 @@ AVRDUDE_PROGRAMMER = avr910
|
||||
AVRDUDE_PORT = /dev/ttyUSB0 # programmer connected to serial device
|
||||
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
|
||||
|
||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||
|
106
avr-code/io.h
Normal file
106
avr-code/io.h
Normal file
@ -0,0 +1,106 @@
|
||||
#ifndef IO_H
|
||||
#define IO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
/*
|
||||
* Macros
|
||||
*/
|
||||
#define PIN(x) (*(&x - 2)) // Address Of Data Direction Register Of Port x
|
||||
#define DDR(x) (*(&x - 1)) // Address Of Input Register Of Port x
|
||||
|
||||
/*
|
||||
* Outputs
|
||||
*/
|
||||
#define PORT_BOLZEN PORTB
|
||||
#define PIN_BOLZEN PB0
|
||||
|
||||
#define PORT_SCHNAPPER PORTB
|
||||
#define PIN_SCHNAPPER PB1
|
||||
|
||||
#define PORT_STATUS PORTB
|
||||
#define PIN_STATUS PB2
|
||||
|
||||
/*
|
||||
* Inputs
|
||||
*/
|
||||
#define PORT_BUTTON_LOCK PORTD
|
||||
#define PIN_BUTTON_LOCK PD2
|
||||
|
||||
#define PORT_BUTTON_UNLOCK PORTD
|
||||
#define PIN_BUTTON_UNLOCK PD3
|
||||
|
||||
#define PORT_EMERGENCY_UNLOCK PORTD
|
||||
#define PIN_EMERGENCY_UNLOCK PD4
|
||||
|
||||
static inline bool is_emergency_unlock(void)
|
||||
{
|
||||
return !(PIN(PORT_EMERGENCY_UNLOCK) & (1<<PIN_EMERGENCY_UNLOCK));
|
||||
}
|
||||
|
||||
static inline bool is_button_unlock(void)
|
||||
{
|
||||
return !(PIN(PORT_BUTTON_UNLOCK) & (1<<PIN_BUTTON_UNLOCK));
|
||||
}
|
||||
|
||||
static inline bool is_button_lock(void)
|
||||
{
|
||||
return !(PIN(PORT_BUTTON_LOCK) & (1<<PIN_BUTTON_LOCK));
|
||||
}
|
||||
|
||||
|
||||
static inline void schnapper_off(void)
|
||||
{
|
||||
PORT_SCHNAPPER &= ~(1<<PIN_SCHNAPPER);
|
||||
}
|
||||
|
||||
static inline void schnapper_on(void)
|
||||
{
|
||||
PORT_SCHNAPPER |= (1<<PIN_SCHNAPPER);
|
||||
}
|
||||
|
||||
static inline void bolzen_off(void)
|
||||
{
|
||||
PORT_BOLZEN &= ~(1<<PIN_BOLZEN);
|
||||
}
|
||||
|
||||
static inline void bolzen_on(void)
|
||||
{
|
||||
PORT_BOLZEN |= (1<<PIN_BOLZEN);
|
||||
}
|
||||
|
||||
static inline void status_off(void)
|
||||
{
|
||||
PORT_STATUS &= ~(1<<PIN_STATUS);
|
||||
}
|
||||
|
||||
static inline void status_on(void)
|
||||
{
|
||||
PORT_STATUS |= (1<<PIN_STATUS);
|
||||
}
|
||||
|
||||
static inline void io_init(void)
|
||||
{
|
||||
// Set output directions
|
||||
DDR(PORT_SCHNAPPER) |= (1<<PIN_SCHNAPPER);
|
||||
schnapper_off();
|
||||
|
||||
DDR(PORT_SCHNAPPER) |= (1<<PIN_BOLZEN);
|
||||
bolzen_off();
|
||||
|
||||
DDR(PORT_STATUS) |= (1<<PIN_STATUS);
|
||||
status_off();
|
||||
|
||||
// Set input directions and activate pull-ups
|
||||
DDR(PORT_BUTTON_UNLOCK) &= ~(1<<PIN_BUTTON_UNLOCK);
|
||||
PORT_BUTTON_UNLOCK |= (1<<PIN_BUTTON_UNLOCK);
|
||||
|
||||
DDR(PORT_BUTTON_LOCK) &= ~(1<<PIN_BUTTON_LOCK);
|
||||
PORT_BUTTON_LOCK |= (1<<PIN_BUTTON_LOCK);
|
||||
|
||||
DDR(PORT_EMERGENCY_UNLOCK) &= ~(1<<PIN_EMERGENCY_UNLOCK);
|
||||
PORT_EMERGENCY_UNLOCK |= (1<<PIN_EMERGENCY_UNLOCK);
|
||||
}
|
||||
|
||||
#endif
|
223
avr-code/main.c
223
avr-code/main.c
@ -2,141 +2,158 @@
|
||||
* ralf@binary-kitchen.de
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GREEN_ON (PORTB &= ~(1<<PB1))
|
||||
#define GREEN_OFF (PORTB |= (1<<PB1))
|
||||
#include "io.h"
|
||||
#include "uart.h"
|
||||
|
||||
#define RED_ON (PORTB &= ~(1<<PB0))
|
||||
#define RED_OFF (PORTB |= (1<<PB0))
|
||||
static volatile enum {LOCKED, UNLOCKED} state = LOCKED;
|
||||
static volatile bool schnapper = false;
|
||||
|
||||
#define DOORLIGHT_ON (PORTD |= (1<<PD6))
|
||||
#define DOORLIGHT_OFF (PORTD &= ~(1<<PD6))
|
||||
|
||||
#define OPEN_BOLZEN (PORTD &= ~(1<<PD4))
|
||||
#define CLOSE_BOLZEN (PORTD |= (1<<PD4))
|
||||
|
||||
#define OPEN_SCHNAPPER (PORTD |= (1<<PD5))
|
||||
#define CLOSE_SCHNAPPER (PORTD &= ~(1<<PD5))
|
||||
|
||||
#define IS_RESCUE (!(PIND & (1<<PD3)))
|
||||
#define IS_SWITCH (!(PIND & (1<<PD2)))
|
||||
|
||||
static uint8_t open = 0;
|
||||
static uint8_t klacker = 0;
|
||||
|
||||
void open_door()
|
||||
static inline void reset_timeout(void)
|
||||
{
|
||||
RED_OFF;
|
||||
GREEN_ON;
|
||||
OPEN_BOLZEN;
|
||||
DOORLIGHT_ON;
|
||||
}
|
||||
|
||||
void close_door()
|
||||
{
|
||||
RED_ON;
|
||||
GREEN_OFF;
|
||||
DOORLIGHT_OFF;
|
||||
CLOSE_SCHNAPPER;
|
||||
CLOSE_BOLZEN;
|
||||
}
|
||||
|
||||
void schnapper(unsigned int i)
|
||||
{
|
||||
OPEN_SCHNAPPER;
|
||||
while (i--) {
|
||||
_delay_ms(1000);
|
||||
}
|
||||
CLOSE_SCHNAPPER;
|
||||
_delay_ms(100);
|
||||
}
|
||||
|
||||
ISR(USI_OVERFLOW_vect)
|
||||
{
|
||||
// Clear interrupt flag
|
||||
USISR |= (1<<USIOIF);
|
||||
// Reset counter
|
||||
TCNT1 = 0;
|
||||
open = 1;
|
||||
|
||||
uint8_t in = USIDR;
|
||||
// Depending on the clock, a klacker either can be 10101010 or 01010101
|
||||
if (in == 0x55 || in == 0xAA)
|
||||
{
|
||||
klacker = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_handler(const unsigned char c)
|
||||
{
|
||||
char retval = c;
|
||||
switch ((char)c) {
|
||||
case 'u':
|
||||
state = UNLOCKED;
|
||||
reset_timeout();
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
state = LOCKED;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (state == UNLOCKED)
|
||||
schnapper = true;
|
||||
else
|
||||
retval = '?';
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
retval = (state == LOCKED) ? 'l' : 'u';
|
||||
break;
|
||||
|
||||
default:
|
||||
retval = '?';
|
||||
break;
|
||||
}
|
||||
|
||||
uart_putc(retval);
|
||||
}
|
||||
|
||||
// Alle 1.137 Sekunden
|
||||
ISR(TIMER1_OVF_vect)
|
||||
{
|
||||
open = 0;
|
||||
state = LOCKED;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// disable all interrupts
|
||||
// Notzu
|
||||
ISR(INT0_vect)
|
||||
{
|
||||
cli();
|
||||
|
||||
// PD4-6 as Output
|
||||
DDRD = (1<<PD5)|(1<<PD4)|(1<<PD6);
|
||||
// PD2,3 Pullup
|
||||
PORTD |= (1<<PD2)|(1<<PD3);
|
||||
// This code is used to prevent spurious interrupts
|
||||
_delay_ms(50);
|
||||
if (!is_button_lock())
|
||||
goto out;
|
||||
|
||||
// PB0-1 as Output
|
||||
DDRB = (1<<PB0)|(1<<PB1);
|
||||
// PB5,7 Pullup
|
||||
PORTB |= (1<<PB7)|(1<<PB5);
|
||||
uart_putc('L');
|
||||
state = LOCKED;
|
||||
|
||||
// first action: close door
|
||||
close_door();
|
||||
out:
|
||||
sei();
|
||||
}
|
||||
|
||||
// Configure USI
|
||||
USICR = (1<<USICS1) | (1<<USIOIE) | (1<<USIWM0);
|
||||
// Notauf
|
||||
ISR(INT1_vect)
|
||||
{
|
||||
cli();
|
||||
|
||||
// Configure Timer
|
||||
// This code is used to prevent spurious interrupts
|
||||
_delay_ms(50);
|
||||
if (!is_button_unlock())
|
||||
goto out;
|
||||
|
||||
uart_putc('U');
|
||||
|
||||
bolzen_off();
|
||||
schnapper_on();
|
||||
|
||||
_delay_ms(3000);
|
||||
|
||||
schnapper_off();
|
||||
|
||||
out:
|
||||
sei();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cli();
|
||||
io_init();
|
||||
|
||||
// Wait a bit to settle down
|
||||
_delay_ms(1000);
|
||||
uart_init();
|
||||
uart_set_recv_handler(uart_handler);
|
||||
|
||||
// Timer config
|
||||
TIMSK |= (1<<TOIE1);
|
||||
TIFR |= (1<<TOV1);
|
||||
TCNT1 = 0;
|
||||
TCCR1A = 0;
|
||||
TCCR1B = (1<<CS01)|(1<<CS00);
|
||||
TCCR1B = (1<<CS12);
|
||||
|
||||
// wait a bit to settle down
|
||||
_delay_ms(1000);
|
||||
TCNT1 = 0;
|
||||
|
||||
// falling edge
|
||||
MCUCR = (1<<ISC11)|(1<<ISC01);
|
||||
GIMSK |= (1<<INT0)|(1<<INT1);
|
||||
|
||||
// enable interrupts
|
||||
sei();
|
||||
|
||||
for(;;) {
|
||||
if (open == 0) {
|
||||
close_door();
|
||||
} else if (open == 1) {
|
||||
open_door();
|
||||
if (klacker == 1)
|
||||
{
|
||||
schnapper(3);
|
||||
klacker = 0;
|
||||
}
|
||||
}
|
||||
if (state == LOCKED) {
|
||||
bolzen_on();
|
||||
schnapper = false;
|
||||
if (is_emergency_unlock()) {
|
||||
_delay_ms(200);
|
||||
if (is_emergency_unlock()) {
|
||||
uart_putc('N');
|
||||
cli();
|
||||
|
||||
bolzen_off();
|
||||
schnapper_on();
|
||||
|
||||
_delay_ms(3000);
|
||||
|
||||
schnapper_off();
|
||||
bolzen_on();
|
||||
|
||||
if (IS_RESCUE) {
|
||||
cli();
|
||||
open_door();
|
||||
schnapper(3);
|
||||
sei();
|
||||
} else if (IS_SWITCH && open == 0) {
|
||||
_delay_ms(300);
|
||||
if(IS_SWITCH && open == 0) {
|
||||
cli();
|
||||
open_door();
|
||||
schnapper(5);
|
||||
sei();
|
||||
}
|
||||
}
|
||||
_delay_ms(50);
|
||||
} else if (state == UNLOCKED) {
|
||||
bolzen_off();
|
||||
if (schnapper == true) {
|
||||
schnapper = false;
|
||||
schnapper_on();
|
||||
_delay_ms(2000);
|
||||
schnapper_off();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
53
avr-code/uart.c
Normal file
53
avr-code/uart.c
Normal file
@ -0,0 +1,53 @@
|
||||
#include <stddef.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "uart.h"
|
||||
|
||||
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
|
||||
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
|
||||
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
|
||||
|
||||
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
|
||||
#error Choose another crystal. Baud error too high.
|
||||
#endif
|
||||
|
||||
static void (*recv_handler)(unsigned char c) = NULL;
|
||||
|
||||
ISR(USART_RX_vect)
|
||||
{
|
||||
cli();
|
||||
if(recv_handler)
|
||||
recv_handler(UDR);
|
||||
sei();
|
||||
}
|
||||
|
||||
void uart_init()
|
||||
{
|
||||
// Enable receive and transmit
|
||||
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
|
||||
|
||||
// Asynchronous mode, 8N1
|
||||
UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
|
||||
|
||||
UBRRH = UBRR_VAL >> 8;
|
||||
UBRRL = UBRR_VAL & 0xFF;
|
||||
}
|
||||
|
||||
void uart_set_recv_handler(void (*handler)(unsigned char c))
|
||||
{
|
||||
recv_handler = handler;
|
||||
}
|
||||
|
||||
void uart_putc(const char c)
|
||||
{
|
||||
while ( !(UCSRA & (1<<UDRE)) );
|
||||
UDR = (const unsigned char)c;
|
||||
}
|
||||
|
||||
void uart_puts(const char* str)
|
||||
{
|
||||
do {
|
||||
uart_putc(*str);
|
||||
} while(*++str);
|
||||
}
|
13
avr-code/uart.h
Normal file
13
avr-code/uart.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
#define BAUD 9600UL
|
||||
|
||||
void uart_set_recv_handler(void (*handler)(unsigned char c));
|
||||
|
||||
void uart_init(void);
|
||||
|
||||
void uart_putc(const char c);
|
||||
void uart_puts(const char* str);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user