diff options
Diffstat (limited to 'lock')
| -rw-r--r-- | lock/Bend.Makefile | 1 | ||||
| -rw-r--r-- | lock/Fend.Makefile | 4 | ||||
| -rw-r--r-- | lock/fpm.c | 189 | ||||
| -rw-r--r-- | lock/fpm.h | 24 | ||||
| -rw-r--r-- | lock/nrfm.c | 1 |
5 files changed, 211 insertions, 8 deletions
diff --git a/lock/Bend.Makefile b/lock/Bend.Makefile index 4b5b222..e4df116 100644 --- a/lock/Bend.Makefile +++ b/lock/Bend.Makefile @@ -11,6 +11,7 @@ CFLAGS += -Os CFLAGS += -Wall CFLAGS += -mmcu=$(MCU) CFLAGS += -DBAUD=115200 +CFLAGS += -DDEBUG=0 CFLAGS += -DF_CPU=16000000UL CFLAGS += -ffunction-sections -fdata-sections diff --git a/lock/Fend.Makefile b/lock/Fend.Makefile index b6601af..8bc3e72 100644 --- a/lock/Fend.Makefile +++ b/lock/Fend.Makefile @@ -10,8 +10,10 @@ CFLAGS = -std=gnu99 CFLAGS += -Os CFLAGS += -Wall CFLAGS += -mmcu=$(MCU) -CFLAGS += -DBAUD=9600 +CFLAGS += -DBAUD=57600 CFLAGS += -DF_CPU=16000000UL +CFLAGS += -DDEBUG=0 +CFLAGS += -DFPM_PWD=$(FPM_PWD) CFLAGS += -ffunction-sections -fdata-sections LDFLAGS = -mmcu=$(MCU) @@ -1,11 +1,24 @@ #include <avr/io.h> +#include <util/delay.h> #include <util/setbaud.h> #include "fpm.h" +#define MAXPDLEN 64 +#define RST_DELAY_MS 500 + +#define OK 0x00 + static uint8_t start_code[] = { 0xEF, 0x01 }; static uint8_t addr[] = { 0xFF, 0xFF, 0xFF, 0xFF }; +static inline uint8_t read(void) +{ + while (!(UCSR0A & (1 << RXC0))) + ; + return UDR0; +} + static inline void write(uint8_t c) { while (!(UCSR0A & (1 << UDRE0))) @@ -26,11 +39,11 @@ static inline void send(uint8_t pktid, uint8_t *data, uint8_t n) int i; uint16_t pktlen, sum; - pktlen = n + 2; - write_bulk(start_code, 2); write_bulk(addr, 4); write(pktid); + + pktlen = n + 2; write((uint8_t)(pktlen >> 8)); write((uint8_t)pktlen); @@ -44,7 +57,79 @@ static inline void send(uint8_t pktid, uint8_t *data, uint8_t n) write((uint8_t)sum); } -void fpm_init(void) +static inline void recv(uint8_t buf[MAXPDLEN], uint16_t *n) +{ + int i; + uint16_t len; + uint8_t byte; + + i = 0, len = 0; + + for (;;) { + byte = read(); + switch (i) { + case 0: + if (byte != start_code[0]) + continue; + break; + case 1: + if (byte != start_code[1]) + goto bad_pkt; + break; + case 2: + case 3: + case 4: + case 5: + // toss the address + break; + case 6: + // toss the 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) { + *n = len; + return; + } + } else { + goto bad_pkt; + } + break; + } + i++; + } + +bad_pkt: + *n = 0; + return; +} + +static inline uint8_t check_pwd(void) +{ + unsigned int n; + 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(0x01, buf, 5); + + n = 0; + recv(buf, &n); + return buf[0] == OK; +} + +uint8_t fpm_init(void) { UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; @@ -55,9 +140,105 @@ void fpm_init(void) #endif UCSR0B = (1 << TXEN0) | (1 << RXEN0); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + + _delay_ms(RST_DELAY_MS); + return check_pwd(); } -void fpm_print_config(void) +uint8_t fpm_getcfg(struct fpm_cfg *cfg) { + uint16_t n; + uint8_t buf[MAXPDLEN]; + + buf[0] = 0x0F; + send(0x01, buf, 1); + recv(buf, &n); + + 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_setpwd(uint32_t pwd) +{ + uint16_t n; + 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(0x01, buf, 5); + recv(buf, &n); + return buf[0] == OK; +} + +uint16_t fpm_getcount(void) +{ + uint16_t n, count; + uint8_t buf[MAXPDLEN]; + + buf[0] = 0x1D; + send(0x01, buf, 1); + recv(buf, &n); + + count = 0; + if (buf[0] == OK && n >= 2) { + count = buf[1]; + count <<= 8; + count |= buf[2]; + } + return count; +} + +uint8_t fpm_enroll(void) +{ + uint16_t n, retries; + uint8_t buf[MAXPDLEN]; + + retries = 0; + + do { + _delay_ms(100); + buf[0] = 0x10; + send(0x01, buf, 1); + recv(buf, &n); + retries++; + } while (buf[0] != OK && retries < 50); + + return buf[0] == OK; +} + +uint8_t fpm_match(void) +{ + uint16_t n, retries; + uint8_t buf[MAXPDLEN]; + + retries = 0; + + do { + _delay_ms(100); + buf[0] = 0x11; + send(0x01, buf, 1); + recv(buf, &n); + retries++; + } while (buf[0] != OK && retries < 10); + + return buf[0] == OK; } @@ -1,8 +1,28 @@ #ifndef FPM_H #define FPM_H -void fpm_init(void); +#include <stdint.h> -void fpm_print_config(void); +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; +}; + +uint8_t fpm_init(void); + +uint8_t fpm_getcfg(struct fpm_cfg *cfg); + +uint8_t fpm_setpwd(uint32_t pwd); + +uint16_t fpm_getcount(void); + +uint8_t fpm_enroll(void); + +uint8_t fpm_match(void); #endif /* FPM_H */ diff --git a/lock/nrfm.c b/lock/nrfm.c index 5ae5737..3795fd2 100644 --- a/lock/nrfm.c +++ b/lock/nrfm.c @@ -261,7 +261,6 @@ uint8_t radio_sendto(const uint8_t addr[ADDRLEN], const char *msg, uint8_t n) #if DEBUG char s[4]; - uart_write("DEBUG: sending to "); uart_write(itoa(addr[0], s, 10)); uart_write("."); |
