Skip to content

Commit

Permalink
fix fm11 operations
Browse files Browse the repository at this point in the history
  • Loading branch information
dangfan committed Nov 23, 2023
1 parent eaf150a commit f4a3c06
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 51 deletions.
30 changes: 21 additions & 9 deletions include/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,19 @@ void led_on(void);
void led_off(void);
void device_set_timeout(void (*callback)(void), uint16_t timeout);

// NFC related
/**
* Enable FM chip by pull down CSN
*/
void fm_csn_low(void);

/**
* Disable FM chip by pull up CSN
*/
void fm_csn_high(void);
#if _NFC_CHIP == NFC_CHIP_FM11NC
void fm_transmit(uint8_t *buf, uint8_t len);
void fm_receive(uint8_t *buf, uint8_t len);
void spi_transmit(uint8_t *buf, uint8_t len);
void spi_receive(uint8_t *buf, uint8_t len);
#elif _NFC_CHIP == NFC_CHIP_FM11NT
void i2c_start(void);
void i2c_stop(void);
Expand All @@ -78,6 +86,8 @@ void testmode_set_initial_ticks(uint32_t ticks);
void testmode_inject_error(uint8_t p1, uint8_t p2, uint16_t len, const uint8_t *data);
bool testmode_err_triggered(const char* filename, bool file_wr);

// -----------------------------------------------------------------------------------

// platform independent functions
uint8_t wait_for_user_presence(uint8_t entry);
int strong_user_presence_test(void);
Expand All @@ -102,16 +112,18 @@ static inline void start_quick_blinking(uint8_t sec) {
}
void stop_blinking(void);
uint8_t device_is_blinking(void);
#if _NFC_CHIP == NFC_CHIP_FM11NC
void fm_read_reg(uint8_t reg, uint8_t *buf, uint8_t len);
void fm_write_reg(uint8_t reg, uint8_t *buf, uint8_t len);
void fm11_init(void);
uint8_t fm_read_reg(uint16_t reg);
void fm_read_regs(uint16_t reg, uint8_t *buf, uint8_t len);
void fm_write_reg(uint16_t reg, uint8_t val);
void fm_write_regs(uint16_t reg, const uint8_t *buf, uint8_t len);
void fm_read_eeprom(uint16_t addr, uint8_t *buf, uint8_t len);
void fm_write_eeprom(uint16_t addr, uint8_t *buf, uint8_t len);
void fm_write_eeprom(uint16_t addr, const uint8_t *buf, uint8_t len);
void fm_read_fifo(uint8_t *buf, uint8_t len);
void fm_write_fifo(uint8_t *buf, uint8_t len);
#elif _NFC_CHIP == NFC_CHIP_FM11NT
void fm_read(uint16_t addr, uint8_t *buf, uint8_t len);
void fm_write(uint16_t addr, const uint8_t *buf, uint8_t len);
#if _NFC_CHIP == NFC_CHIP_FM11NT
void fm11nt_read(uint16_t addr, uint8_t *buf, uint8_t len);
void fm11nt_write(uint16_t addr, const uint8_t *buf, uint8_t len);
uint8_t fm_crc8(const uint8_t *data, const uint8_t data_length);
#endif

Expand Down
106 changes: 94 additions & 12 deletions interfaces/NFC/fm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,78 @@
#include "device.h"
#include <stdint.h>

#if _NFC_CHIP == NFC_CHIP_FM11NC

static void device_delay_us(int us) {
for (int i = 0; i < us * 10; ++i)
asm volatile("nop");
}

void fm_read_reg(uint8_t reg, uint8_t *buf, uint8_t len) {
uint8_t fm_read_reg(uint16_t reg) {
uint8_t val;
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
reg |= 0x20;
fm_transmit(&reg, 1);
uint8_t addr = reg;
addr |= 0x20;
fm_transmit(&addr, 1);
fm_receive(&val, 1);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_read(reg, &val, 1);
#endif
return val;
}

void fm_read_regs(uint16_t reg, uint8_t *buf, uint8_t len) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
uint8_t addr = reg;
addr |= 0x20;
fm_transmit(&addr, 1);
fm_receive(buf, len);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_read(reg, buf, len);
#endif
}

void fm_write_reg(uint16_t reg, uint8_t val) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
uint8_t addr = reg;
fm_transmit(&addr, 1);
fm_transmit(&val, 1);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_write(reg, &val, 1);
#endif
}

void fm_write_reg(uint8_t reg, uint8_t *buf, uint8_t len) {
void fm_write_regs(uint16_t reg, const uint8_t *buf, uint8_t len) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
fm_transmit(&reg, 1);
uint8_t addr = reg;
fm_transmit(&addr, 1);
fm_transmit(buf, len);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_write(reg, buf, len);
#endif
}

void fm_read_eeprom(uint16_t addr, uint8_t *buf, uint8_t len) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
device_delay_us(100);
uint8_t data[2] = {0x60 | (addr >> 8), addr & 0xFF};
fm_transmit(data, 2);
fm_receive(buf, len);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_read(addr, buf, len);
#endif
}

void fm_write_eeprom(uint16_t addr, uint8_t *buf, uint8_t len) {
void fm_write_eeprom(uint16_t addr, const uint8_t *buf, uint8_t len) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
device_delay_us(100);
uint8_t data[2] = {0xCE, 0x55};
Expand All @@ -48,29 +88,72 @@ void fm_write_eeprom(uint16_t addr, uint8_t *buf, uint8_t len) {
fm_transmit(data, 2);
fm_transmit(buf, len);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_write(addr, buf, len);
device_delay(10);
#endif
}

void fm_read_fifo(uint8_t *buf, uint8_t len) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
uint8_t addr = 0xA0;
fm_transmit(&addr, 1);
fm_receive(buf, len);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_read(FM_REG_FIFO_ACCESS, buf, len);
#endif
}

void fm_write_fifo(uint8_t *buf, uint8_t len) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_nss_low();
uint8_t addr = 0x80;
fm_transmit(&addr, 1);
fm_transmit(buf, len);
fm_nss_high();
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm11nt_write(FM_REG_FIFO_ACCESS, buf, len);
#endif
}

void fm11_init(void) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
uint8_t buf[7];
uint8_t data1[] = {0x44, 0x00, 0x04, 0x20};
uint8_t data2[] = {0x05, 0x72, 0x02, 0x00, 0xB3, 0x99, 0x00};
do {
fm_write_eeprom(0x3A0, data1, sizeof(data1));
fm_read_eeprom(0x3A0, buf, sizeof(data1));
} while (memcmp(data1, buf, sizeof(data1)) != 0);
do {
fm_write_eeprom(0x3B0, data2, sizeof(data2));
fm_read_eeprom(0x3B0, buf, sizeof(data2));
} while (memcmp(data2, buf, sizeof(data2)) != 0);
#elif _NFC_CHIP == NFC_CHIP_FM11NT
uint8_t crc_buffer[13];
const uint8_t user_cfg[] = {0x91, 0x82, 0x21, 0xCD};
const uint8_t atqa_sak[] = {0x44, 0x00, 0x04, 0x20};
fm_csn_low();
device_delay_us(200);
fm_write_regs(FM_EEPROM_USER_CFG0, user_cfg, sizeof(user_cfg));
fm_write_eeprom(FM_EEPROM_ATQA, atqa_sak, sizeof(atqa_sak));
fm_read_eeprom(FM_EEPROM_SN, crc_buffer, 9);
DBG_MSG("SN: "); PRINT_HEX(crc_buffer, 9);
memcpy(crc_buffer + 9, atqa_sak, sizeof(atqa_sak));
const uint8_t crc8 = fm_crc8(crc_buffer, sizeof(crc_buffer));
fm_write_eeprom(FM_EEPROM_CRC8, &crc8, 1);
device_delay_us(1000);
fm_csn_high();
#endif
}

#if _NFC_CHIP == NFC_CHIP_FM11NT

#define I2C_ADDR 0x57

void fm_read(uint16_t addr, uint8_t *buf, uint8_t len) {
void fm11nt_read(uint16_t addr, uint8_t *buf, uint8_t len) {
uint8_t slave_id = (I2C_ADDR << 1) | 0;
i2c_start();
i2c_write_byte(slave_id);
Expand Down Expand Up @@ -102,7 +185,7 @@ void fm_read(uint16_t addr, uint8_t *buf, uint8_t len) {
}
}

void fm_write(uint16_t addr, const uint8_t *buf, uint8_t len) {
void fm11nt_write(const uint16_t addr, const uint8_t *buf, const uint8_t len) {
const uint8_t slave_id = (I2C_ADDR << 1) | 0;
i2c_start();
i2c_write_byte(slave_id);
Expand Down Expand Up @@ -134,5 +217,4 @@ uint8_t fm_crc8(const uint8_t *data, const uint8_t data_length) {
return crc8 & 0xff;
}


#endif
#endif
35 changes: 5 additions & 30 deletions interfaces/NFC/nfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,7 @@ void nfc_init(void) {
// NFC interface uses global_buffer w/o calling acquire_apdu_buffer(), because NFC mode is exclusive with USB mode
apdu_cmd.data = global_buffer;
apdu_resp.data = global_buffer;
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_write_reg(FM_REG_FIFO_FLUSH, &inf_sending, 1); // writing anything to this reg will flush FIFO buffer
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm_write(FM_REG_FIFO_FLUSH, &inf_sending, 1); // writing anything to this reg will flush FIFO buffer
#endif
fm_write_reg(FM_REG_FIFO_FLUSH, 0); // writing anything to this reg will flush FIFO buffer
}

static void nfc_error_handler(int code) {
Expand All @@ -52,14 +48,8 @@ static void do_nfc_send_frame(uint8_t prologue, uint8_t *data, uint8_t len) {
DBG_MSG("TX: ");
PRINT_HEX(tx_frame_buf, len + 1);

uint8_t val = 0x55;
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_write_fifo(tx_frame_buf, len + 1);
fm_write_reg(REG_RF_TXEN, &val, 1);
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm_write(FM_REG_FIFO_ACCESS, tx_frame_buf, len + 1);
fm_write(FM_REG_RF_TXEN, &val, 1);
#endif
fm_write_reg(FM_REG_RF_TXEN, 0x55);
}

void nfc_send_frame(uint8_t prologue, uint8_t *data, uint8_t len) {
Expand Down Expand Up @@ -132,9 +122,7 @@ void nfc_loop(void) {
SW = SW_WRONG_LENGTH;
} else {
device_set_timeout(send_wtx, WTX_PERIOD);
// process_apdu(capdu, rapdu);
rapdu->len = 0;
rapdu->sw = 0x6a82;
process_apdu(capdu, rapdu);
device_set_timeout(NULL, 0);
}

Expand Down Expand Up @@ -174,28 +162,15 @@ void nfc_loop(void) {

void nfc_handler(void) {
uint8_t irq[3];
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_read_reg(FM_REG_MAIN_IRQ, irq, sizeof(irq));
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm_read(FM_REG_MAIN_IRQ, irq, sizeof(irq));
#endif
DBG_MSG("IRQ: ");
PRINT_HEX(irq, 3);
fm_read_regs(FM_REG_MAIN_IRQ, irq, sizeof(irq));
if (!is_nfc()) {
ERR_MSG("IRQ %02x in non-NFC mode\n", irq[0]);
return;
}
fm_read(FM_REG_RF_STATUS, irq, 1);
DBG_MSG("RF Stat: %02X\n", irq[0]);

if (irq[0] & MAIN_IRQ_RX_DONE) {
#if _NFC_CHIP == NFC_CHIP_FM11NC
fm_read_reg(REG_FIFO_WORDCNT, &rx_frame_size, 1);
rx_frame_size = fm_read_reg(FM_REG_FIFO_WORDCNT);
fm_read_fifo(rx_frame_buf, rx_frame_size);
#elif _NFC_CHIP == NFC_CHIP_FM11NT
fm_read(FM_REG_FIFO_WORDCNT, &rx_frame_size, 1);
fm_read(FM_REG_FIFO_ACCESS, rx_frame_buf, rx_frame_size);
#endif
DBG_MSG("RX: ");
PRINT_HEX(rx_frame_buf, rx_frame_size);
if (next_state == TO_SEND) DBG_MSG("Wrong State!\n");
Expand Down

0 comments on commit f4a3c06

Please sign in to comment.