/* CLRC66303 SPI register access example, C99. * Adapt every board_hal_* function to the target MCU. * Configure SPI mode 0, MSB first, initially 100 kHz (bring-up choice). * This is a transport example, not a complete NFC protocol driver. */ #include #include #include /* Blocking transfer; return only after the last SCK edge. * Return false on timeout/error. Do not toggle NSS inside this function. */ extern bool board_hal_spi_transfer(const uint8_t *tx, uint8_t *rx, size_t length); extern void board_hal_nss(bool high); /* Meet the datasheet NSS-high interval: at least 50 ns. * Account for GPIO, timer and compiler behavior on the actual MCU. */ extern void board_hal_nss_high_gap(void); #define CLRC663_VERSION_REG UINT8_C(0x7F) #define CLRC66303_EXPECTED_VERSION UINT8_C(0x1A) /* Serialize access to this SPI bus for the whole transaction. */ static bool clrc663_frame(const uint8_t tx[2], uint8_t rx[2]) { board_hal_nss(false); const bool ok = board_hal_spi_transfer(tx, rx, 2u); board_hal_nss(true); /* Release NSS even after a bus error. */ board_hal_nss_high_gap(); return ok; } bool clrc663_read_reg(uint8_t reg, uint8_t *value) { if (reg > UINT8_C(0x7F) || value == NULL) { return false; } const uint8_t tx[2] = { (uint8_t)((reg << 1u) | 1u), /* LSB = 1: read. */ UINT8_C(0x00) /* Dummy byte generates clocks. */ }; uint8_t rx[2] = {0u, 0u}; if (!clrc663_frame(tx, rx)) { return false; } *value = rx[1]; /* Address-phase MISO is not the value. */ return true; } bool clrc663_write_reg(uint8_t reg, uint8_t value) { if (reg > UINT8_C(0x7F)) { return false; } const uint8_t tx[2] = { (uint8_t)(reg << 1u), /* LSB = 0: write. */ value }; uint8_t rx[2] = {0u, 0u}; return clrc663_frame(tx, rx); } /* Call after valid rails, settled IFSEL straps and PDOWN release. * 0 = expected CLRC66303 version; -1 = bus error; -2 = other version. * Log the observed byte; VersionReg is not an authenticity test. */ int clrc66303_check_version(uint8_t *observed) { uint8_t version = 0u; if (!clrc663_read_reg(CLRC663_VERSION_REG, &version)) { return -1; } if (observed != NULL) { *observed = version; } return version == CLRC66303_EXPECTED_VERSION ? 0 : -2; }