From 276856de6c63bbbf3e56cc08dcca00ba10080b7e Mon Sep 17 00:00:00 2001 From: Sadeep Madurange Date: Sun, 7 Sep 2025 17:04:34 +0800 Subject: Door lock with MOSFETs and and without RFM. --- lock/Client.Makefile | 46 -------- lock/Server.Makefile | 44 ------- lock/client.c | 198 ------------------------------- lock/fpm.c | 324 --------------------------------------------------- lock/fpm.h | 38 ------ lock/nrfm.c | 303 ----------------------------------------------- lock/nrfm.h | 21 ---- lock/server.c | 191 ------------------------------ lock/uart.h | 8 -- lock/util.c | 89 -------------- lock/util.h | 27 ----- 11 files changed, 1289 deletions(-) delete mode 100644 lock/Client.Makefile delete mode 100644 lock/Server.Makefile delete mode 100644 lock/client.c delete mode 100644 lock/fpm.c delete mode 100644 lock/fpm.h delete mode 100644 lock/nrfm.c delete mode 100644 lock/nrfm.h delete mode 100644 lock/server.c delete mode 100644 lock/uart.h delete mode 100644 lock/util.c delete mode 100644 lock/util.h (limited to 'lock') diff --git a/lock/Client.Makefile b/lock/Client.Makefile deleted file mode 100644 index a6758fd..0000000 --- a/lock/Client.Makefile +++ /dev/null @@ -1,46 +0,0 @@ -CC = avr-gcc -MCU = atmega328p -PORT = /dev/cuaU0 -TARGET = client - -SRC = client.c fpm.c nrfm.c util.c -OBJ = $(SRC:.c=.o) - -CFLAGS = -std=gnu99 -CFLAGS += -Os -CFLAGS += -Wall -CFLAGS += -mmcu=$(MCU) -CFLAGS += -DBAUD=57600 -CFLAGS += -DF_CPU=16000000UL -CFLAGS += -DFPM_PWD=$(FPM_PWD) -CFLAGS += -ffunction-sections -fdata-sections - -LDFLAGS = -mmcu=$(MCU) -LDFLAGS += -Wl,--gc-sections - -HEX_FLAGS = -O ihex -HEX_FLAGS += -j .text -j .data - -AVRDUDE_FLAGS = -p $(MCU) -AVRDUDE_FLAGS += -c arduino -AVRDUDE_FLAGS += -P $(PORT) -AVRDUDE_FLAGS += -D -U - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -elf: $(OBJ) - $(CC) $(LDFLAGS) $(OBJ) -o $(TARGET).elf - -hex: elf - avr-objcopy $(HEX_FLAGS) $(TARGET).elf $(TARGET).hex - -upload: hex - avrdude $(AVRDUDE_FLAGS) flash:w:$(TARGET).hex:i - -.PHONY: clean - -clean: - rm -f *.o *.elf *.hex - - diff --git a/lock/Server.Makefile b/lock/Server.Makefile deleted file mode 100644 index f853a34..0000000 --- a/lock/Server.Makefile +++ /dev/null @@ -1,44 +0,0 @@ -CC = avr-gcc -MCU = atmega328p -PORT = /dev/cuaU0 -TARGET = server - -SRC = server.c nrfm.c util.c -OBJ = $(SRC:.c=.o) - -CFLAGS = -std=gnu99 -CFLAGS += -Os -CFLAGS += -Wall -CFLAGS += -mmcu=$(MCU) -CFLAGS += -DF_CPU=16000000UL -CFLAGS += -ffunction-sections -fdata-sections - -LDFLAGS = -mmcu=$(MCU) -LDFLAGS += -Wl,--gc-sections - -HEX_FLAGS = -O ihex -HEX_FLAGS += -j .text -j .data - -AVRDUDE_FLAGS = -p $(MCU) -AVRDUDE_FLAGS += -c arduino -AVRDUDE_FLAGS += -P $(PORT) -AVRDUDE_FLAGS += -D -U - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -elf: $(OBJ) - $(CC) $(LDFLAGS) $(OBJ) -o $(TARGET).elf - -hex: elf - avr-objcopy $(HEX_FLAGS) $(TARGET).elf $(TARGET).hex - -upload: hex - avrdude $(AVRDUDE_FLAGS) flash:w:$(TARGET).hex:i - -.PHONY: clean - -clean: - rm -f *.o *.elf *.hex - - diff --git a/lock/client.c b/lock/client.c deleted file mode 100644 index 91fe040..0000000 --- a/lock/client.c +++ /dev/null @@ -1,198 +0,0 @@ -/* Lock front, connected to the fingerprint scanner */ - -#include -#include - -#include -#include -#include -#include - -#include "fpm.h" -#include "nrfm.h" -#include "util.h" - -#define LOCK_PIN PD3 -#define UNLOCK_PIN PD2 -#define ENROLL_PIN PD4 - -#define RX_IRQ_PIN PC0 -#define RX_DDR DDRC -#define RX_PIN PINC -#define RX_ICR PCICR -#define RX_IE PCIE1 -#define RX_INT PCINT8 -#define RX_MSK PCMSK1 -#define RX_INTVEC PCINT1_vect - -#define VCC_MIN 4000 - -static volatile uint8_t rxd = 0; -static volatile uint8_t sync = 0; -static volatile uint8_t islock = 0; -static volatile uint8_t isunlock = 0; - -static inline void wdt_off(void) -{ - cli(); - wdt_reset(); - MCUSR &= ~(1 << WDRF); - WDTCSR |= (1 << WDCE) | (1 << WDE); - WDTCSR = 0x00; -} - -static inline void init_rx(void) -{ - RX_DDR &= ~(1 << RX_IRQ_PIN); - RX_ICR |= (1 << RX_IE); - RX_MSK |= (1 << RX_INT); -} - -static inline void init_btns(void) -{ - DDRD &= ~((1 << LOCK_PIN) | (1 << UNLOCK_PIN) | (1 << ENROLL_PIN)); - PORTD |= ((1 << LOCK_PIN) | (1 << UNLOCK_PIN) | (1 << ENROLL_PIN)); - - EICRA = 0b00000000; - EIMSK = (1 << INT0) | (1 << INT1); - - PCICR |= (1 << PCIE2); - PCMSK2 |= (1 << PCINT20); -} - -static inline void fpm_ok(void) -{ - fpm_led_on(BLUE); - _delay_ms(500); - fpm_led_off(); -} - -static inline void fpm_nok(void) -{ - fpm_led_on(RED); - _delay_ms(500); - fpm_led_off(); -} - -int main(void) -{ - int i, retries; - uint8_t rxaddr[ADDRLEN] = { 194, 178, 82 }; - uint8_t txaddr[ADDRLEN] = { 194, 178, 83 }; - - char buf[WDLEN], key[WDLEN]; - - wdt_off(); - led_init(); - - fpm_init(); - if (fpm_get_count() == 0) - fpm_enroll(); - - init_rx(); - init_btns(); - - radio_init(rxaddr); - - sei(); - radio_listen(); - - for (;;) { - if (!sync && (islock || isunlock)) { - if (isunlock) { - if (!fpm_match()) { - isunlock = 0; - fpm_nok(); - continue; - } - else - fpm_ok(); - } - - xor(KEY, SYN, buf, WDLEN); - retries = 0; - do { - sync = radio_sendto(txaddr, buf, WDLEN); - retries++; - } while (!sync && retries < 2); - - if (!sync) { - islock = 0; - isunlock = 0; - } - } - - if (rxd) { - radio_recv(buf, WDLEN); - rxd = 0; - if (sync && (islock || isunlock)) { - sync = 0; - xor(KEY, buf, key, WDLEN); - if (islock) { - islock = 0; - xor(key, LOCK, buf, WDLEN); - if (radio_sendto(txaddr, buf, WDLEN)) - led_locked(); - } else if (isunlock) { - isunlock = 0; - xor(key, UNLOCK, buf, WDLEN); - if (radio_sendto(txaddr, buf, WDLEN)) - led_unlocked(); - } - } - } - - if (!sync) { - if (getvcc() < VCC_MIN) { - for (i = 0; i < 5; i++) { - led_bat(); - _delay_ms(100); - } - } - - radio_pwr_dwn(); - sleep_bod_disable(); - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - sleep_mode(); - radio_listen(); - } - } - return 0; -} - -ISR(RX_INTVEC) -{ - if (!(RX_PIN & (1 << RX_IRQ_PIN))) - rxd = 1; -} - -ISR(INT0_vect) -{ - sync = 0; - isunlock = 1; -} - -ISR(INT1_vect) -{ - if (is_btn_pressed(PIND, LOCK_PIN)) { - sync = 0; - islock = 1; - } -} - -ISR(PCINT2_vect) -{ - uint16_t id; - - if (is_btn_pressed(PIND, ENROLL_PIN)) { - id = fpm_match(); - if (id == 1 || id == 2) { - fpm_ok(); - _delay_ms(1000); - if (fpm_enroll()) - fpm_ok(); - } else - fpm_nok(); - } -} - diff --git a/lock/fpm.c b/lock/fpm.c deleted file mode 100644 index 73a175a..0000000 --- a/lock/fpm.c +++ /dev/null @@ -1,324 +0,0 @@ -#include -#include -#include - -#include "fpm.h" - -#define MAXPDLEN 64 -#define RST_DELAY_MS 500 - -#define HEADER_HO 0xEF -#define HEADER_LO 0x01 -#define ADDR 0xFFFFFFFF - -#define OK 0x00 -#define PACKID 0x01 - -static inline uint8_t read(void) -{ - while (!(UCSR0A & (1 << RXC0))) - ; - return UDR0; -} - -static inline void write(uint8_t c) -{ - while (!(UCSR0A & (1 << UDRE0))) - ; - UDR0 = c; -} - -static inline void send(uint8_t *data, uint8_t n) -{ - int i; - uint16_t pktlen, sum; - - write(HEADER_HO); - write(HEADER_LO); - - write((uint8_t)(ADDR >> 24)); - write((uint8_t)(ADDR >> 16)); - write((uint8_t)(ADDR >> 8)); - write((uint8_t)(ADDR & 0xFF)); - - write(PACKID); - - pktlen = n + 2; - write((uint8_t)(pktlen >> 8)); - write((uint8_t)pktlen); - - sum = (pktlen >> 8) + (pktlen & 0xFF) + PACKID; - for (i = 0; i < n; i++) { - write(data[i]); - sum += data[i]; - } - - write((uint8_t)(sum >> 8)); - write((uint8_t)sum); -} - -static inline uint16_t recv(uint8_t buf[MAXPDLEN]) -{ - int i; - uint16_t len; - uint8_t byte; - - i = 0, len = 0; - - for (;;) { - byte = read(); - switch (i) { - case 0: - if (byte != HEADER_HO) - continue; - break; - case 1: - if (byte != HEADER_LO) - return 0; - case 2: - case 3: - case 4: - case 5: - // toss address - break; - case 6: - // toss packet id - break; - case 7: - len = (uint16_t)byte << 8; - break; - case 8: - len |= byte; - break; - default: - if ((i - 9) < MAXPDLEN) { - buf[i - 9] = byte; - if ((i - 8) == len) - return len; - } else - return 0; - break; - } - i++; - } - return 0; -} - -static inline void led_ctrl(uint8_t mode, COLOR color) -{ - uint8_t buf[MAXPDLEN]; - - buf[0] = 0x35; - buf[1] = mode; - buf[2] = 0x60; - buf[3] = color; - buf[4] = 0x00; - - send(buf, 5); - recv(buf); -} - -static inline uint8_t check_pwd(void) -{ - uint8_t buf[MAXPDLEN]; - - buf[0] = 0x13; - buf[1] = (uint8_t)((uint32_t)FPM_PWD >> 24); - buf[2] = (uint8_t)((uint32_t)FPM_PWD >> 16); - buf[3] = (uint8_t)((uint32_t)FPM_PWD >> 8); - buf[4] = (uint8_t)((uint32_t)FPM_PWD & 0xFF); - - send(buf, 5); - recv(buf); - return buf[0] == OK; -} - -static inline uint8_t scan(void) -{ - uint16_t retries; - uint8_t buf[MAXPDLEN]; - - retries = 0; - led_ctrl(0x01, PURPLE); - - do { - buf[0] = 0x28; - send(buf, 1); - recv(buf); - if (buf[0] != OK) { - retries++; - _delay_ms(100); - } - } while(buf[0] != OK && retries < 100); - - led_ctrl(0x06, PURPLE); - return buf[0] == OK; -} - -static inline uint8_t img2tz(uint8_t bufid) -{ - uint8_t buf[MAXPDLEN]; - - buf[0] = 0x02; - buf[1] = bufid; - send(buf, 2); - recv(buf); - return buf[0] == OK; -} - -void fpm_led_on(COLOR color) -{ - led_ctrl(0x03, color); -} - -void fpm_led_off(void) -{ - led_ctrl(0x04, 0x00); -} - -uint8_t fpm_init(void) -{ - UBRR0H = UBRRH_VALUE; - UBRR0L = UBRRL_VALUE; -#if USE_2X - UCSR0A |= (1 << U2X0); -#else - UCSR0A &= ~(1 << U2X0); -#endif - UCSR0B = (1 << TXEN0) | (1 << RXEN0); - UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); - - _delay_ms(RST_DELAY_MS); - return check_pwd(); -} - -uint8_t fpm_get_cfg(struct fpm_cfg *cfg) -{ - uint16_t n; - uint8_t buf[MAXPDLEN]; - - buf[0] = 0x0F; - send(buf, 1); - n = recv(buf); - - if (buf[0] == OK && n >= 17) { - cfg->status = ((uint16_t)buf[1] << 8) | buf[2]; - cfg->sysid = ((uint16_t)buf[3] << 8) | buf[4]; - cfg->cap = ((uint16_t)buf[5] << 8) | buf[6]; - cfg->sec_level = ((uint16_t)buf[7] << 8) | buf[8]; - cfg->addr[0] = buf[9]; - cfg->addr[1] = buf[10]; - cfg->addr[2] = buf[11]; - cfg->addr[3] = buf[12]; - cfg->pkt_size = ((uint16_t)buf[13] << 8) | buf[14]; - cfg->pkt_size = 1 << (cfg->pkt_size + 5); - cfg->baud = (((uint16_t)buf[15] << 8) | buf[16]); - - return 1; - } - return 0; -} - -uint8_t fpm_set_pwd(uint32_t pwd) -{ - uint8_t buf[MAXPDLEN]; - - buf[0] = 0x12; - buf[1] = (uint8_t)(pwd >> 24); - buf[2] = (uint8_t)(pwd >> 16); - buf[3] = (uint8_t)(pwd >> 8); - buf[4] = (uint8_t)(pwd & 0xFF); - - send(buf, 5); - recv(buf); - return buf[0] == OK; -} - -uint16_t fpm_get_count(void) -{ - uint16_t n, count; - uint8_t buf[MAXPDLEN]; - - buf[0] = 0x1D; - send(buf, 1); - n = recv(buf); - - count = 0; - if (buf[0] == OK && n >= 2) { - count = buf[1]; - count <<= 8; - count |= buf[2]; - } - return count; -} - -uint8_t fpm_enroll(void) -{ - struct fpm_cfg cfg; - uint16_t n; - uint8_t buf[MAXPDLEN]; - - fpm_get_cfg(&cfg); - n = fpm_get_count() + 1; - if (n >= cfg.cap) - return 0; - - if (!scan()) - return 0; - - if (!img2tz(1)) - return 0; - - _delay_ms(2000); - - if (!scan()) - return 0; - - if (!img2tz(2)) - return 0; - - buf[0] = 0x05; - send(buf, 1); - recv(buf); - if (buf[0] != OK) - return 0; - - buf[0] = 0x06; - buf[1] = 1; - buf[2] = (uint8_t)(n >> 8); - buf[3] = (uint8_t)(n & 0xFF); - send(buf, 4); - recv(buf); - - return buf[0] == OK; -} - -uint16_t fpm_match(void) -{ - struct fpm_cfg cfg; - uint8_t buf[MAXPDLEN]; - - if (!fpm_get_cfg(&cfg)) - return 0; - - if (!scan()) - return 0; - - if (!img2tz(1)) - return 0; - - buf[0] = 0x04; - buf[1] = 1; - buf[2] = 0x00; - buf[3] = 0x00; - buf[4] = (uint8_t)(cfg.cap >> 8); - buf[5] = (uint8_t)(cfg.cap & 0xFF); - - send(buf, 6); - recv(buf); - - if (buf[0] != OK) - return 0; - - return ((uint16_t)buf[1] << 8) | buf[2]; -} diff --git a/lock/fpm.h b/lock/fpm.h deleted file mode 100644 index 31f53eb..0000000 --- a/lock/fpm.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef FPM_R503_H -#define FPM_R503_H - -#include - -struct fpm_cfg { - uint16_t status; - uint16_t sysid; - uint16_t cap; - uint16_t sec_level; - uint8_t addr[4]; - uint16_t pkt_size; - uint16_t baud; -}; - -typedef enum { - RED = 0x01, - BLUE = 0x02, - PURPLE = 0x03 -} COLOR; - -uint8_t fpm_init(void); - -uint8_t fpm_get_cfg(struct fpm_cfg *cfg); - -uint8_t fpm_set_pwd(uint32_t pwd); - -void fpm_led_on(COLOR color); - -void fpm_led_off(void); - -uint16_t fpm_get_count(void); - -uint8_t fpm_enroll(void); - -uint16_t fpm_match(void); - -#endif /* FPM_R50_H */ diff --git a/lock/nrfm.c b/lock/nrfm.c deleted file mode 100644 index d1bb5c3..0000000 --- a/lock/nrfm.c +++ /dev/null @@ -1,303 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "nrfm.h" - -#define SPI_SS PB2 -#define SPI_SCK PB5 -#define SPI_MISO PB4 -#define SPI_MOSI PB3 -#define SPI_DDR DDRB -#define SPI_PORT PORTB - -#define NRF_CE PC1 -#define NRF_CE_DDR DDRC -#define NRF_CE_PORT PORTC - -#define NOP 0xFF -#define R_REGISTER 0x1F -#define W_REGISTER 0x20 - -#define PWR_UP 1 -#define PRIM_RX 0 - -#define MODCHG_DELAY_MS 5 - -#define LEN(a) (sizeof(a) / sizeof(a[0])) - -const char *bittab[16] = { - [ 0] = "0000", [ 1] = "0001", [ 2] = "0010", [ 3] = "0011", - [ 4] = "0100", [ 5] = "0101", [ 6] = "0110", [ 7] = "0111", - [ 8] = "1000", [ 9] = "1001", [10] = "1010", [11] = "1011", - [12] = "1100", [13] = "1101", [14] = "1110", [15] = "1111", -}; - -static inline uint8_t read_reg(uint8_t reg) -{ - SPI_PORT &= ~(1 << SPI_SS); - SPDR = reg & R_REGISTER; - while (!(SPSR & (1 << SPIF))) - ; - SPDR = NOP; - while (!(SPSR & (1 << SPIF))) - ; - SPI_PORT |= (1 << SPI_SS); - return SPDR; -} - -static inline void write_reg(uint8_t reg, uint8_t val) -{ - SPI_PORT &= ~(1 << SPI_SS); - SPDR = (reg & 0x1F) | W_REGISTER; - while (!(SPSR & (1 << SPIF))) - ; - SPDR = val; - while (!(SPSR & (1 << SPIF))) - ; - SPI_PORT |= (1 << SPI_SS); -} - -static inline void read_reg_bulk(uint8_t reg, uint8_t *data, uint8_t n) -{ - uint8_t i; - - SPI_PORT &= ~(1 << SPI_SS); - SPDR = reg & R_REGISTER; - while (!(SPSR & (1 << SPIF))) - ; - for (i = 0; i < n; i++) { - SPDR = NOP; - while (!(SPSR & (1 << SPIF))) - ; - data[i] = SPDR; - } - SPI_PORT |= (1 << SPI_SS); -} - -static inline void setaddr(uint8_t reg, const uint8_t addr[ADDRLEN]) -{ - int i; - - SPI_PORT &= ~(1 << SPI_SS); - SPDR = (reg & 0x1F) | W_REGISTER; - while (!(SPSR & (1 << SPIF))) - ; - for (i = ADDRLEN - 1; i >= 0; i--) { - SPDR = addr[i]; - while (!(SPSR & (1 << SPIF))) - ; - } - SPI_PORT |= (1 << SPI_SS); -} - -static inline void reset_irqs(void) -{ - uint8_t rv; - - rv = read_reg(0x07); - if (rv != 0b00001110) - write_reg(0x07, 0b01111110); -} - -static inline void tx_mode(void) -{ - uint8_t rv; - - rv = read_reg(0x00); - if ((rv & 0x03) != 0x02) { - rv |= (1 << PWR_UP); - rv &= ~(1 << PRIM_RX); - write_reg(0x00, rv); - _delay_ms(MODCHG_DELAY_MS); - } -} - -static inline void rx_mode(void) -{ - uint8_t rv; - - rv = read_reg(0x00); - if ((rv & 0x03) != 0x02) { - rv |= (1 << PWR_UP); - rv |= (1 << PRIM_RX); - write_reg(0x00, rv); - _delay_ms(MODCHG_DELAY_MS); - } -} - -static inline void enable_chip(void) -{ - NRF_CE_PORT |= (1 << NRF_CE); - _delay_us(130); -} - -static inline void disable_chip(void) -{ - NRF_CE_PORT &= ~(1 << NRF_CE); -} - -static inline void flush_tx(void) -{ - SPI_PORT &= ~(1 << SPI_SS); - SPDR = 0b11100001; - while (!(SPSR & (1 << SPIF))) - ; - SPI_PORT |= (1 << SPI_SS); - - reset_irqs(); -} - -void radio_flush_rx(void) -{ - SPI_PORT &= ~(1 << SPI_SS); - SPDR = 0b11100010; - while (!(SPSR & (1 << SPIF))) - ; - SPI_PORT |= (1 << SPI_SS); - - reset_irqs(); -} - -static inline uint8_t rx_pdlen(void) -{ - SPI_PORT &= ~(1 << SPI_SS); - SPDR = 0b01100000; - while (!(SPSR & (1 << SPIF))) - ; - SPDR = NOP; - while (!(SPSR & (1 << SPIF))) - ; - SPI_PORT |= (1 << SPI_SS); - return SPDR; -} - -void radio_init(const uint8_t rxaddr[ADDRLEN]) -{ - SPI_DDR |= (1 << SPI_SS) | (1 << SPI_SCK) | (1 << SPI_MOSI); - SPI_PORT |= (1 << SPI_SS); - SPCR |= (1 << SPE) | (1 << MSTR); - - NRF_CE_DDR |= (1 << NRF_CE); - NRF_CE_PORT &= ~(1 << NRF_CE); - - _delay_ms(110); /* power on reset delay */ - - write_reg(0x00, 0b00111100); /* use 2-byte CRC, enable only the rx interrupt */ - write_reg(0x01, 0b00111111); /* enable auto ack on all pipes */ - write_reg(0x02, 0b00000011); /* enable rx address on pipes 0 and 1 */ - write_reg(0x03, 0b00000001); /* set address width to 3 bytes */ - write_reg(0x04, 0b11111111); /* 4000uS retransmission delay, 15 tries */ - write_reg(0x05, 0b01110011); /* use 2.515GHz channel */ - write_reg(0x06, 0b00001110); /* set data rate to 1Mbps */ - write_reg(0x1D, 0b00000100); /* enable dynamic payload length */ - write_reg(0x1C, 0b00111111); /* enable dynamic payload length for all pipes */ - - reset_irqs(); - setaddr(0x0B, rxaddr); /* pipe 1 for rx, pipe 0 for auto-ack */ -} - -void radio_listen(void) -{ - disable_chip(); - rx_mode(); - enable_chip(); -} - -void radio_pwr_dwn(void) -{ - uint8_t rv; - - disable_chip(); - rv = read_reg(0x00); - rv &= ~(1 << PWR_UP); - write_reg(0x00, rv); -} - -uint8_t radio_sendto(const uint8_t addr[ADDRLEN], const char *msg, uint8_t n) -{ - int i, imax; - uint8_t cfg, rv, maxrt, txds; - - disable_chip(); - - cfg = read_reg(0x00); - - tx_mode(); - flush_tx(); - - setaddr(0x10, addr); - setaddr(0x0A, addr); - - imax = n < MAXPDLEN ? n : MAXPDLEN; - - SPI_PORT &= ~(1 << SPI_SS); - SPDR = 0b10100000; - while (!(SPSR & (1 << SPIF))) - ; - for (i = 0; i < imax; i++) { - SPDR = msg[i]; - while (!(SPSR & (1 << SPIF))) - ; - } - SPI_PORT |= (1 << SPI_SS); - - enable_chip(); - _delay_us(12); - disable_chip(); - - txds = 0, maxrt = 0; - do { - rv = read_reg(0x07); - txds = rv & (1 << 5); - maxrt = rv & (1 << 4); - } while (txds == 0 && maxrt == 0); - - if (maxrt) - flush_tx(); - - // restore config, typically rx mode - write_reg(0x00, cfg); - enable_chip(); - return txds; -} - -uint8_t radio_recv(char *buf, uint8_t n) -{ - int readlen, pdlen, readmax; - - pdlen = 0; - disable_chip(); - - pdlen = rx_pdlen(); - if (pdlen == 0) { - radio_flush_rx(); - return 0; - } - - if (pdlen > MAXPDLEN) { - radio_flush_rx(); - return 0; - } - - readmax = n < pdlen ? n : pdlen; - - SPI_PORT &= ~(1 << SPI_SS); - SPDR = 0b01100001; - while (!(SPSR & (1 << SPIF))) - ; - for (readlen = 0; readlen < readmax; readlen++) { - SPDR = NOP; - while (!(SPSR & (1 << SPIF))) - ; - buf[readlen] = SPDR; - } - SPI_PORT |= (1 << SPI_SS); - - radio_flush_rx(); - enable_chip(); - return readlen; -} diff --git a/lock/nrfm.h b/lock/nrfm.h deleted file mode 100644 index 52d4edb..0000000 --- a/lock/nrfm.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef NRFM_H -#define NRFM_H - -#include - -#define ADDRLEN 3 -#define MAXPDLEN 32 - -void radio_init(const uint8_t rxaddr[ADDRLEN]); - -void radio_listen(void); - -void radio_pwr_dwn(void); - -uint8_t radio_recv(char *buf, uint8_t n); - -void radio_flush_rx(void); - -uint8_t radio_sendto(const uint8_t addr[ADDRLEN], const char *msg, uint8_t n); - -#endif /* NRFM_H */ diff --git a/lock/server.c b/lock/server.c deleted file mode 100644 index 6d51c00..0000000 --- a/lock/server.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Lock back, connected to the servo */ - -#include -#include - -#include -#include -#include -#include - -#include "nrfm.h" -#include "util.h" - -#define PWM_MIN 500 -#define PWM_MID 1500 -#define PWM_MAX 2500 -#define PWM_TOP 20000 - -#define SERVO_PIN PB1 -#define LOCK_PIN PD3 -#define UNLOCK_PIN PD4 - -#define RX_IRQ_PIN PC0 -#define RX_DDR DDRC -#define RX_PIN PINC -#define RX_ICR PCICR -#define RX_IE PCIE1 -#define RX_INT PCINT8 -#define RX_MSK PCMSK1 -#define RX_INTVEC PCINT1_vect - -#define VCC_MIN 4000 - -static char tab[] = { - '0', '8', '3', '6', 'a', 'Z', '$', '4', 'v', 'R', '@', - 'E', '1', 'o', '#', ')', '2', '5', 'q', ';', '.', 'I', - 'c', '7', '9', '*', 'L', 'V', '&', 'k', 'K', '!', 'm', - 'N', '(', 'O', 'Q', 'A', '>', 'T', 't', '?', 'S', 'h', - 'w', '/', 'n', 'W', 'l', 'M', 'e', 'H', 'j', 'g', '[', - 'P', 'f', ':', 'B', ']', 'Y', '^', 'F', '%', 'C', 'x' -}; - -static volatile uint8_t rxd = 0; -static uint16_t tablen = sizeof(tab) / sizeof(tab[0]); - -static inline void keygen(char *buf, uint8_t n) -{ - int i, imax; - uint8_t sreg; - uint16_t seed; - - sreg = SREG; - cli(); - seed = TCNT1; - SREG = sreg; - - for (i = 0, imax = n - 1; i < imax; i++, seed++) - buf[i] = tab[(seed % tablen)]; - buf[imax] = '\0'; -} - -static inline void keydel(char *buf, uint8_t n) -{ - int i; - - for (i = 0; i < n; i++) - buf[i] = 0; -} - -static inline void init_wdt(void) -{ - cli(); - wdt_reset(); - - WDTCSR |= (1 << WDCE) | ( 1 << WDE); - WDTCSR = (1 << WDE) | (1 << WDP1); /* reset after 64ms */ -} - -static inline void init_rx(void) -{ - RX_DDR &= ~(1 << RX_IRQ_PIN); - RX_ICR |= (1 << RX_IE); - RX_MSK |= (1 << RX_INT); -} - -static inline void init_btns(void) -{ - DDRD &= ~((1 << LOCK_PIN) | (1 << UNLOCK_PIN)); - PORTD |= ((1 << LOCK_PIN) | (1 << UNLOCK_PIN)); - - EICRA = 0b00000000; - EIMSK = (1 << INT1); - - PCICR |= (1 << PCIE2); - PCMSK2 |= (1 << PCINT20); -} - -static inline void init_servo(void) -{ - ICR1 = PWM_TOP; - TCCR1A |= (1 << WGM11) | (1 << COM1A1); - TCCR1B |= (1 << WGM13) | (1 << CS11); - - DDRB |= (1 << SERVO_PIN); -} - -static inline void lock(void) -{ - OCR1A = PWM_MID; - _delay_ms(100); - OCR1A = PWM_TOP; -} - -static inline void unlock(void) -{ - OCR1A = PWM_MAX - 50; - _delay_ms(100); - OCR1A = PWM_TOP; -} - -int main(void) -{ - uint8_t rxaddr[ADDRLEN] = { 194, 178, 83 }; - uint8_t txaddr[ADDRLEN] = { 194, 178, 82 }; - - char buf[WDLEN], key[WDLEN], msg[WDLEN]; - - init_wdt(); - init_rx(); - init_btns(); - init_servo(); - - led_init(); - radio_init(rxaddr); - - sei(); - radio_listen(); - - for (;;) { - if (rxd) { - radio_recv(buf, WDLEN); - rxd = 0; - xor(KEY, buf, msg, WDLEN); - if (memcmp(msg, SYN, WDLEN) == 0) { - keygen(key, WDLEN); - xor(KEY, key, buf, WDLEN); - radio_sendto(txaddr, buf, WDLEN); - } else { - xor(key, buf, msg, WDLEN); - if (memcmp(msg, LOCK, WDLEN) == 0) { - lock(); - keydel(key, WDLEN); - } else if (memcmp(msg, UNLOCK, WDLEN) == 0) { - unlock(); - keydel(key, WDLEN); - } - } - } else { - radio_pwr_dwn(); - if (getvcc() < VCC_MIN) - led_bat(); - sleep_bod_disable(); - set_sleep_mode(SLEEP_MODE_PWR_DOWN); - sleep_mode(); - } - } - return 0; -} - -ISR(RX_INTVEC) -{ - if (!(RX_PIN & (1 << RX_IRQ_PIN))) - rxd = 1; -} - -ISR(INT1_vect) -{ - if (is_btn_pressed(PIND, LOCK_PIN)) { - lock(); - led_locked(); - } -} - -ISR(PCINT2_vect) -{ - if (is_btn_pressed(PIND, UNLOCK_PIN)) { - unlock(); - led_unlocked(); - } -} - diff --git a/lock/uart.h b/lock/uart.h deleted file mode 100644 index a88a3c6..0000000 --- a/lock/uart.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef UART_H -#define UART_H - -void uart_init(void); -void uart_write(const char *s); -void uart_write_line(const char *s); - -#endif /* UART_H */ diff --git a/lock/util.c b/lock/util.c deleted file mode 100644 index ec5369e..0000000 --- a/lock/util.c +++ /dev/null @@ -1,89 +0,0 @@ -#include -#include -#include - -#include "util.h" - -#define LOCK_LED PC3 -#define UNLOCK_LED PC4 -#define BATLOW_LED PC5 -#define LED_DDR DDRC -#define LED_PORT PORTC - -int is_btn_pressed(uint8_t pin, uint8_t btn) -{ - if (!((pin >> btn) & 0x01)) { - _delay_ms(100); - return !((pin >> btn) & 0x01); - } - return 0; -} - -void xor(const char *k, const char *s, char *d, uint8_t n) -{ - int i; - - for (i = 0; i < n; i++) - d[i] = s[i] ^ k[i]; -} - -/* Measure vcc by measuring known internal 1.1v bandgap - * reference voltage against AVCC. - * Place a 100nF bypass capacitor on AREF. - */ -uint16_t getvcc(void) -{ - uint16_t vcc; - - ADMUX |= (1 << REFS0); - ADMUX |= (1 << MUX3) | (1 << MUX2) | (1 << MUX1); - ADCSRA |= (1 << ADEN) | (1 << ADPS2) | (1 << ADPS0); - - // https://www.sciencetronics.com/greenphotons/?p=1521 - _delay_us(500); - - ADCSRA |= (1 << ADSC); - while (ADCSRA & (1 << ADSC)) - ; - vcc = (1100UL * 1023 / ADC); - - ADCSRA &= ~(1 << ADEN); - return vcc; -} - -void led_init(void) -{ - LED_DDR |= (1 << LOCK_LED) | (1 << UNLOCK_LED); - LED_DDR |= (1 << BATLOW_LED); - - LED_PORT &= ~(1 << LOCK_LED); - LED_PORT &= ~(1 << UNLOCK_LED); - LED_PORT &= ~(1 << BATLOW_LED); -} - -void led_locked(void) -{ - LED_PORT |= (1 << LOCK_LED); - _delay_ms(100); - LED_PORT &= ~(1 << LOCK_LED); - _delay_ms(100); - LED_PORT |= (1 << LOCK_LED); - _delay_ms(100); - LED_PORT &= ~(1 << LOCK_LED); -} - -void led_unlocked(void) -{ - LED_PORT |= (1 << UNLOCK_LED); - _delay_ms(70); - LED_PORT &= ~(1 << UNLOCK_LED); - _delay_ms(70); - LED_PORT |= (1 << UNLOCK_LED); - _delay_ms(70); - LED_PORT &= ~(1 << UNLOCK_LED); -} - -void led_bat(void) -{ - LED_PORT ^= (1 << BATLOW_LED); -} diff --git a/lock/util.h b/lock/util.h deleted file mode 100644 index 84584aa..0000000 --- a/lock/util.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef MY_UTIL_H -#define MY_UTIL_H - -#include - -#define KEY "dM>}jdb,6gsnC$J^K 8(I5vyPemPs%;K" -#define SYN "dM>}jdb,6gsnC$J^K 8(I5vyPemPs%;O" -#define LOCK "R,I7l^E4j]KyLR9'*Q{Jd'zu.~!84}Ij" -#define UNLOCK "R,I7l^E4j]KyLR9'*Q{Jd'zu.~!84}IL" - -#define WDLEN 32 - -int is_btn_pressed(uint8_t pin, uint8_t btn); - -void xor(const char *k, const char *s, char *d, uint8_t n); - -uint16_t getvcc(void); - -void led_init(void); - -void led_locked(void); - -void led_unlocked(void); - -void led_bat(void); - -#endif /* MY_UTIL_H */ -- cgit v1.2.3