summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lock/Bend.Makefile1
-rw-r--r--lock/Fend.Makefile4
-rw-r--r--lock/fpm.c189
-rw-r--r--lock/fpm.h24
-rw-r--r--lock/nrfm.c1
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)
diff --git a/lock/fpm.c b/lock/fpm.c
index 814119f..5d6fafd 100644
--- a/lock/fpm.c
+++ b/lock/fpm.c
@@ -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;
}
diff --git a/lock/fpm.h b/lock/fpm.h
index eb69ae2..b3fcd91 100644
--- a/lock/fpm.h
+++ b/lock/fpm.h
@@ -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(".");