diff options
Diffstat (limited to 'fpm.c')
| -rw-r--r-- | fpm.c | 261 |
1 files changed, 0 insertions, 261 deletions
@@ -1,261 +0,0 @@ -#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))) - ; - UDR0 = c; -} - -static inline void write_bulk(uint8_t *data, uint16_t n) -{ - int i; - - for (i = 0; i < n; i++) - write(data[i]); -} - -static inline void send(uint8_t pktid, uint8_t *data, uint8_t n) -{ - int i; - uint16_t pktlen, sum; - - write_bulk(start_code, 2); - write_bulk(addr, 4); - write(pktid); - - pktlen = n + 3; - write((uint8_t)(pktlen >> 8)); - write((uint8_t)pktlen); - - sum = (pktlen >> 8) + (pktlen & 0xFF) + pktid; - for (i = 0; i < n; i++) { - write(data[i]); - sum += data[i]; - } - - write((uint8_t)(sum >> 8)); - write((uint8_t)sum); -} - -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); - recv(buf, &n); - return buf[0] == OK; -} - -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); - - uint8_t buf[5]; - buf[0] = 0x35; - buf[1] = 0x03; - buf[2] = 0x00; - buf[3] = 0x01; - buf[4] = 0x00; - send(0x01, buf, 5); - - return check_pwd(); -} - -uint8_t fpm_get_cfg(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_set_pwd(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_get_count(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; -} - -uint8_t fpm_clear_db(void) -{ - uint16_t n; - uint8_t buf[MAXPDLEN]; - - buf[0] = 0x0D; - send(0x01, buf, 1); - recv(buf, &n); - return buf[0] == OK; -} |
