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
1216
avr-code/Makefile
1216
avr-code/Makefile
File diff suppressed because it is too large
Load Diff
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
|
255
avr-code/main.c
255
avr-code/main.c
@ -2,142 +2,159 @@
|
|||||||
* ralf@binary-kitchen.de
|
* ralf@binary-kitchen.de
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <avr/sleep.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define GREEN_ON (PORTB &= ~(1<<PB1))
|
#include "io.h"
|
||||||
#define GREEN_OFF (PORTB |= (1<<PB1))
|
#include "uart.h"
|
||||||
|
|
||||||
#define RED_ON (PORTB &= ~(1<<PB0))
|
static volatile enum {LOCKED, UNLOCKED} state = LOCKED;
|
||||||
#define RED_OFF (PORTB |= (1<<PB0))
|
static volatile bool schnapper = false;
|
||||||
|
|
||||||
#define DOORLIGHT_ON (PORTD |= (1<<PD6))
|
static inline void reset_timeout(void)
|
||||||
#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()
|
|
||||||
{
|
{
|
||||||
RED_OFF;
|
TCNT1 = 0;
|
||||||
GREEN_ON;
|
|
||||||
OPEN_BOLZEN;
|
|
||||||
DOORLIGHT_ON;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_door()
|
void uart_handler(const unsigned char c)
|
||||||
{
|
{
|
||||||
RED_ON;
|
char retval = c;
|
||||||
GREEN_OFF;
|
switch ((char)c) {
|
||||||
DOORLIGHT_OFF;
|
case 'u':
|
||||||
CLOSE_SCHNAPPER;
|
state = UNLOCKED;
|
||||||
CLOSE_BOLZEN;
|
reset_timeout();
|
||||||
}
|
break;
|
||||||
|
|
||||||
void schnapper(unsigned int i)
|
case 'l':
|
||||||
{
|
state = LOCKED;
|
||||||
OPEN_SCHNAPPER;
|
break;
|
||||||
while (i--) {
|
|
||||||
_delay_ms(1000);
|
case 'p':
|
||||||
}
|
break;
|
||||||
CLOSE_SCHNAPPER;
|
|
||||||
_delay_ms(100);
|
case 's':
|
||||||
}
|
if (state == UNLOCKED)
|
||||||
|
schnapper = true;
|
||||||
ISR(USI_OVERFLOW_vect)
|
else
|
||||||
{
|
retval = '?';
|
||||||
// Clear interrupt flag
|
break;
|
||||||
USISR |= (1<<USIOIF);
|
|
||||||
// Reset counter
|
case 'i':
|
||||||
TCNT1 = 0;
|
retval = (state == LOCKED) ? 'l' : 'u';
|
||||||
open = 1;
|
break;
|
||||||
|
|
||||||
uint8_t in = USIDR;
|
default:
|
||||||
// Depending on the clock, a klacker either can be 10101010 or 01010101
|
retval = '?';
|
||||||
if (in == 0x55 || in == 0xAA)
|
break;
|
||||||
{
|
}
|
||||||
klacker = 1;
|
|
||||||
}
|
uart_putc(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alle 1.137 Sekunden
|
||||||
ISR(TIMER1_OVF_vect)
|
ISR(TIMER1_OVF_vect)
|
||||||
{
|
{
|
||||||
open = 0;
|
state = LOCKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
// Notzu
|
||||||
// disable all interrupts
|
ISR(INT0_vect)
|
||||||
cli();
|
{
|
||||||
|
cli();
|
||||||
|
|
||||||
// PD4-6 as Output
|
// This code is used to prevent spurious interrupts
|
||||||
DDRD = (1<<PD5)|(1<<PD4)|(1<<PD6);
|
_delay_ms(50);
|
||||||
// PD2,3 Pullup
|
if (!is_button_lock())
|
||||||
PORTD |= (1<<PD2)|(1<<PD3);
|
goto out;
|
||||||
|
|
||||||
// PB0-1 as Output
|
uart_putc('L');
|
||||||
DDRB = (1<<PB0)|(1<<PB1);
|
state = LOCKED;
|
||||||
// PB5,7 Pullup
|
|
||||||
PORTB |= (1<<PB7)|(1<<PB5);
|
|
||||||
|
|
||||||
// first action: close door
|
out:
|
||||||
close_door();
|
sei();
|
||||||
|
}
|
||||||
// Configure USI
|
|
||||||
USICR = (1<<USICS1) | (1<<USIOIE) | (1<<USIWM0);
|
// Notauf
|
||||||
|
ISR(INT1_vect)
|
||||||
// Configure Timer
|
{
|
||||||
TIMSK |= (1<<TOIE1);
|
cli();
|
||||||
TIFR |= (1<<TOV1);
|
|
||||||
TCNT1 = 0;
|
// This code is used to prevent spurious interrupts
|
||||||
TCCR1A = 0;
|
_delay_ms(50);
|
||||||
TCCR1B = (1<<CS01)|(1<<CS00);
|
if (!is_button_unlock())
|
||||||
|
goto out;
|
||||||
// wait a bit to settle down
|
|
||||||
_delay_ms(1000);
|
uart_putc('U');
|
||||||
|
|
||||||
// enable interrupts
|
bolzen_off();
|
||||||
sei();
|
schnapper_on();
|
||||||
|
|
||||||
for(;;) {
|
_delay_ms(3000);
|
||||||
if (open == 0) {
|
|
||||||
close_door();
|
schnapper_off();
|
||||||
} else if (open == 1) {
|
|
||||||
open_door();
|
out:
|
||||||
if (klacker == 1)
|
sei();
|
||||||
{
|
}
|
||||||
schnapper(3);
|
|
||||||
klacker = 0;
|
int main(void)
|
||||||
}
|
{
|
||||||
}
|
cli();
|
||||||
|
io_init();
|
||||||
if (IS_RESCUE) {
|
|
||||||
cli();
|
// Wait a bit to settle down
|
||||||
open_door();
|
_delay_ms(1000);
|
||||||
schnapper(3);
|
uart_init();
|
||||||
sei();
|
uart_set_recv_handler(uart_handler);
|
||||||
} else if (IS_SWITCH && open == 0) {
|
|
||||||
_delay_ms(300);
|
// Timer config
|
||||||
if(IS_SWITCH && open == 0) {
|
TIMSK |= (1<<TOIE1);
|
||||||
cli();
|
TIFR |= (1<<TOV1);
|
||||||
open_door();
|
TCCR1A = 0;
|
||||||
schnapper(5);
|
TCCR1B = (1<<CS12);
|
||||||
sei();
|
|
||||||
}
|
TCNT1 = 0;
|
||||||
}
|
|
||||||
_delay_ms(50);
|
// falling edge
|
||||||
}
|
MCUCR = (1<<ISC11)|(1<<ISC01);
|
||||||
|
GIMSK |= (1<<INT0)|(1<<INT1);
|
||||||
return 0;
|
|
||||||
|
sei();
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
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();
|
||||||
|
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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