More RC522 stuff
This commit is contained in:
parent
2823a0e276
commit
9daec49f3e
@ -219,11 +219,33 @@ int rc522_send_baudrate(struct nfc_device * pnd, uint32_t baudrate) {
|
||||
}
|
||||
|
||||
int rc522_soft_reset(struct nfc_device * pnd) {
|
||||
return
|
||||
// 1. Send soft reset
|
||||
rc522_start_command(pnd, CMD_SOFTRESET) ||
|
||||
CHIP_DATA(pnd)->io->reset_baud_rate(pnd) ||
|
||||
rc522_wait_wakeup(pnd);
|
||||
int ret;
|
||||
|
||||
// 1. Execute reset command
|
||||
if ((ret = rc522_start_command(pnd, CMD_SOFTRESET)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 2. If using an UART, reset baud rate to RC522 default speed
|
||||
if (CHIP_DATA(pnd)->io->reset_baud_rate) {
|
||||
if ((ret = CHIP_DATA(pnd)->io->reset_baud_rate(pnd)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Wait for the RC522 to come back to life, as we shouldn't modify any register till that happens
|
||||
if ((ret = rc522_wait_wakeup(pnd)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 4. If using an UART, restore baud rate to user's choice
|
||||
if (CHIP_DATA(pnd)->io->upgrade_baud_rate) {
|
||||
if ((ret = CHIP_DATA(pnd)->io->upgrade_baud_rate(pnd)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
int rc522_set_baud_rate(struct nfc_device * pnd, nfc_baud_rate speed) {
|
||||
@ -259,8 +281,7 @@ int rc522_set_baud_rate(struct nfc_device * pnd, nfc_baud_rate speed) {
|
||||
rc522_write_reg(pnd, REG_RxModeReg, rxVal, REG_RxModeReg_RxSpeed_MASK);
|
||||
}
|
||||
|
||||
int rc522_initiator_select_passive_target_ext(struct nfc_device * pnd, const nfc_modulation nm, const uint8_t * pbtInitData, const size_t szInitData, nfc_target * pnt, int timeout)
|
||||
{
|
||||
int rc522_initiator_select_passive_target_ext(struct nfc_device * pnd, const nfc_modulation nm, const uint8_t * pbtInitData, const size_t szInitData, nfc_target * pnt, int timeout) {
|
||||
int ret;
|
||||
|
||||
if (nm.nmt != NMT_ISO14443A) {
|
||||
@ -276,6 +297,25 @@ int rc522_initiator_select_passive_target_ext(struct nfc_device * pnd, const nfc
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
|
||||
int rc522_initiator_transceive_bits(struct nfc_device * pnd, const uint8_t * txData, const size_t txBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, uint8_t *pbtRxPar) {
|
||||
return NFC_ENOTIMPL;
|
||||
}
|
||||
|
||||
int rc522_initiator_transceive_bytes(struct nfc_device * pnd, const uint8_t * txData, const size_t txSize, uint8_t * rxData, const size_t rxMaxSize, int timeout) {
|
||||
int ret;
|
||||
|
||||
if (txSize > FIFO_SIZE) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Attempted to send %d bytes, but FIFO has only %d bytes.", txSize, FIFO_SIZE);
|
||||
return NFC_EOVFLOW;
|
||||
}
|
||||
|
||||
if ((ret = rc522_write_bulk(pnd, REG_FIFODataReg, txData, txSize)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
int rc522_get_supported_modulation(struct nfc_device * pnd, const nfc_mode mode, const nfc_modulation_type ** const supported_mt) {
|
||||
switch (mode) {
|
||||
case N_INITIATOR:
|
||||
@ -388,7 +428,9 @@ int rc522_set_property_int(struct nfc_device * pnd, const nfc_property property,
|
||||
|
||||
int rc522_abort(struct nfc_device * pnd) {
|
||||
return
|
||||
// Halt any running commands
|
||||
rc522_start_command(pnd, CMD_IDLE) ||
|
||||
// Clear FIFO
|
||||
rc522_write_reg(pnd, REG_FIFOLevelReg, REG_FIFOLevelReg_FlushBuffer, 0xFF);
|
||||
}
|
||||
|
||||
@ -422,6 +464,7 @@ int rc522_self_test(struct nfc_device * pnd) {
|
||||
break;
|
||||
|
||||
default:
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Aborting self test for unknown version %02X.", CHIP_DATA(pnd)->version);
|
||||
return NFC_EDEVNOTSUPP;
|
||||
}
|
||||
|
||||
@ -454,6 +497,7 @@ int rc522_self_test(struct nfc_device * pnd) {
|
||||
|
||||
while (1) {
|
||||
if (!timeout_check(&to)) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Self test timeout");
|
||||
return NFC_ETIMEOUT;
|
||||
}
|
||||
|
||||
@ -478,8 +522,26 @@ int rc522_self_test(struct nfc_device * pnd) {
|
||||
}
|
||||
|
||||
if (memcmp(correct, response, FIFO_SIZE) != 0) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Self test values didn't match");
|
||||
return NFC_ECHIP;
|
||||
}
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Self test executed successfully!");
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
int rc522_init(struct nfc_device * pnd) {
|
||||
int version = rc522_read_reg(pnd, REG_VersionReg);
|
||||
if (version < 0) {
|
||||
return version;
|
||||
}
|
||||
CHIP_DATA(pnd)->version = version;
|
||||
|
||||
int ret = rc522_self_test(pnd);
|
||||
if (ret == NFC_EDEVNOTSUPP) {
|
||||
// TODO: Implement another test, maybe?
|
||||
ret = rc522_soft_reset(pnd);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -26,13 +26,13 @@ struct rc522_io {
|
||||
int (*read)(struct nfc_device * pnd, uint8_t reg, uint8_t * data, size_t size);
|
||||
int (*write)(struct nfc_device * pnd, uint8_t reg, const uint8_t * data, size_t size);
|
||||
int (*reset_baud_rate)(struct nfc_device * pnd);
|
||||
int (*upgrade_baud_rate)(struct nfc_device * pnd);
|
||||
};
|
||||
|
||||
int rc522_data_new(struct nfc_device * pnd, const struct rc522_io * io);
|
||||
void rc522_data_free(struct nfc_device * pnd);
|
||||
int rc522_self_test(struct nfc_device * pnd);
|
||||
int rc522_wait_wakeup(struct nfc_device * pnd);
|
||||
int rc522_send_baudrate(struct nfc_device * pnd, uint32_t baudrate);
|
||||
int rc522_init(struct nfc_device * pnd);
|
||||
|
||||
int rc522_get_supported_modulation(nfc_device * pnd, const nfc_mode mode, const nfc_modulation_type ** const supported_mt);
|
||||
int rc522_get_supported_baud_rate(nfc_device * pnd, const nfc_mode mode, const nfc_modulation_type nmt, const nfc_baud_rate ** const supported_br);
|
||||
|
||||
@ -49,16 +49,16 @@
|
||||
// Internal data structs
|
||||
const struct rc522_io rc522_uart_io;
|
||||
struct rc522_uart_data {
|
||||
serial_port port;
|
||||
uint32_t baudrate;
|
||||
serial_port port;
|
||||
uint32_t baudrate;
|
||||
};
|
||||
|
||||
#define DRIVER_DATA(pnd) ((struct rc522_uart_data*)(pnd->driver_data))
|
||||
|
||||
/*
|
||||
int rc522_uart_wakeup(struct nfc_device * pnd) {
|
||||
int ret;
|
||||
|
||||
/* High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for RC522 being wakeup. */
|
||||
// High Speed Unit (HSU) wake up consist to send 0x55 and wait a "long" delay for RC522 being wakeup.
|
||||
const uint8_t rc522_wakeup_preamble[] = { 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
ret = uart_send(DRIVER_DATA(pnd)->port, rc522_wakeup_preamble, sizeof(rc522_wakeup_preamble), RC522_UART_IO_TIMEOUT);
|
||||
if (ret < 0) {
|
||||
@ -67,48 +67,7 @@ int rc522_uart_wakeup(struct nfc_device * pnd) {
|
||||
|
||||
return rc522_wait_wakeup(pnd);
|
||||
}
|
||||
|
||||
bool rc522_uart_test_baudrate(struct nfc_device * pnd, uint32_t baudrate) {
|
||||
int ret;
|
||||
|
||||
if ((ret = uart_set_speed(DRIVER_DATA(pnd)->port, baudrate)) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = rc522_wait_wakeup(pnd);
|
||||
if (ret != NFC_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DRIVER_DATA(pnd)->baudrate = baudrate;
|
||||
return true;
|
||||
}
|
||||
|
||||
int rc522_uart_change_baudrate(struct nfc_device * pnd, uint32_t newBaudRate) {
|
||||
uint32_t oldBaudRate = DRIVER_DATA(pnd)->baudrate;
|
||||
int ret;
|
||||
|
||||
if (oldBaudRate == newBaudRate) {
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Switching baud rate from %dbps to %dbps.", oldBaudRate, newBaudRate);
|
||||
|
||||
if ((ret = rc522_send_baudrate(pnd, newBaudRate)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = uart_set_speed(DRIVER_DATA(pnd)->port, newBaudRate)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = rc522_wait_wakeup(pnd)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
DRIVER_DATA(pnd)->baudrate = newBaudRate;
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
void rc522_uart_close(nfc_device * pnd) {
|
||||
rc522_powerdown(pnd);
|
||||
@ -118,6 +77,26 @@ void rc522_uart_close(nfc_device * pnd) {
|
||||
nfc_device_free(pnd);
|
||||
}
|
||||
|
||||
bool rc522_uart_test_baudrate(struct nfc_device * pnd, uint32_t baudrate) {
|
||||
int ret;
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Attempting to establish a connection at %d bps.", baudrate);
|
||||
|
||||
// Update UART baudrate
|
||||
if ((ret = uart_set_speed(DRIVER_DATA(pnd)->port, baudrate)) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to test and initialize the device
|
||||
if (rc522_init(pnd) != NFC_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Connection with a RC522 at %d bps established successfully.", baudrate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int rc522_uart_create(const nfc_context * context, const nfc_connstring connstring, const char * portPath, uint32_t userBaudRate, struct nfc_device ** pndPtr) {
|
||||
int ret;
|
||||
serial_port sp;
|
||||
@ -155,6 +134,7 @@ int rc522_uart_create(const nfc_context * context, const nfc_connstring connstri
|
||||
return NFC_ESOFT;
|
||||
}
|
||||
DRIVER_DATA(pnd)->port = sp;
|
||||
DRIVER_DATA(pnd)->baudrate = userBaudRate;
|
||||
|
||||
// Alloc and init chip's data
|
||||
if (rc522_data_new(pnd, &rc522_uart_io)) {
|
||||
@ -179,22 +159,6 @@ int rc522_uart_create(const nfc_context * context, const nfc_connstring connstri
|
||||
return NFC_EIO;
|
||||
}
|
||||
|
||||
// Change now the baud rate
|
||||
/* TODO - Check why this doesn't work on my FM17522 and try it with a real MFRC522
|
||||
if ((ret = rc522_uart_change_baudrate(pnd, userBaudRate)) < 0) {
|
||||
rc522_uart_close(pnd);
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
|
||||
// Now the device is awake and listening at a known baudrate, execute a selftest
|
||||
// Note that some devices (FM17522 for instance) aren't able to run it
|
||||
ret = rc522_self_test(pnd);
|
||||
if (ret != NFC_SUCCESS && ret != NFC_EDEVNOTSUPP) {
|
||||
rc522_uart_close(pnd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*pndPtr = pnd;
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
@ -341,16 +305,27 @@ error:
|
||||
}
|
||||
|
||||
int rc522_uart_reset_baud_rate(struct nfc_device * pnd) {
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Restoring baud rate to default of %d bps.", RC522_UART_BOOT_SPEED);
|
||||
return uart_set_speed(DRIVER_DATA(pnd)->port, RC522_UART_BOOT_SPEED);
|
||||
}
|
||||
|
||||
int rc522_uart_upgrade_baud_rate(struct nfc_device * pnd) {
|
||||
uint32_t userBaudRate = DRIVER_DATA(pnd)->baudrate;
|
||||
if (userBaudRate == RC522_UART_BOOT_SPEED) {
|
||||
return NFC_SUCCESS;
|
||||
}
|
||||
|
||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Upgrading baud rate to user-specified %d bps.", userBaudRate);
|
||||
return
|
||||
rc522_uart_test_baudrate(pnd, RC522_UART_BOOT_SPEED) ||
|
||||
rc522_uart_change_baudrate(pnd, userBaudRate);
|
||||
uart_set_speed(DRIVER_DATA(pnd)->port, userBaudRate) ||
|
||||
rc522_send_baudrate(pnd, userBaudRate);
|
||||
}
|
||||
|
||||
const struct rc522_io rc522_uart_io = {
|
||||
.read = rc522_uart_read,
|
||||
.write = rc522_uart_write,
|
||||
.reset_baud_rate = rc522_uart_reset_baud_rate,
|
||||
.reset_baud_rate = rc522_uart_reset_baud_rate,
|
||||
.upgrade_baud_rate = rc522_uart_upgrade_baud_rate,
|
||||
};
|
||||
|
||||
const struct nfc_driver rc522_uart_driver = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user