CLRC663 ATQA but No UID: STM32 SPI Debug Guide

If your STM32 can read CLRC663 registers and receive ATQA, but the next anticollision request returns no usable UID bytes, start here. Follow the first failed exchange from SPI writes to receiver status, then check SELECT and SAK.

QUICK ANSWER

When CLRC663 returns ATQA but no UID, first check the transition from REQA to anticollision. REQA uses seven bits; the initial CL1 request uses two complete bytes, 0x93 0x20. Restore byte-aligned transmission without clearing DataEn, disable transmit CRC generation and receive CRC checking for this exchange, and inspect the captured result before retrying. Repeatable ATQA is a useful starting point, not proof of adequate RF margin for every frame.

Illustrative STM32 SPI debugging setup with a reader antenna, ISO 14443A card and logic analyzer
Illustrative STM32-to-reader test setup showing the MCU, antenna, card and logic analyzer. This image is not evidence of a tested board or measured performance.

An Access Reader That Detects a Card but Cannot Read Its UID

Consider an STM32-based access-control reader during board bring-up. With one ISO/IEC 14443 Type A card held at a fixed position, register reads are stable and REQA returns two ATQA bytes. The application still reports “no UID” after the first anticollision request. At this point, changing antenna components would introduce another variable before the failed exchange has been explained.

Example scope: this is an illustrative application scenario, not a NYFEA customer deployment or a measured test report. The worked example below examines one specific configuration mistake and shows how to test that explanation without inventing a successful result.

Starting observationRegister readback is stable and the same card repeatedly answers REQA.
First failed exchangeThe initial CL1 request returns no usable cascade-level bytes. SELECT has not yet been reached.
Next checkCompare the actual transmit settings and SPI writes before REQA and before 93 20.

ATQA is not a UID. It is the response to initial polling; anticollision and SELECT are separate exchanges. If five valid anticollision bytes are already available but SAK is missing, skip to the SELECT checks in the table below.

A related NXP Community discussion reports difficulty progressing from REQA to anticollision and selection. It provides symptom context, not a verified root cause for this illustrative scenario.

ATQA but No UID: Find the First Failed Exchange

Swipe to view all columns →

Observed resultHighest-priority checksDo not change first
No ATQA after REQARF field, Type A profile, seven-bit REQA, power rails, antenna connection and receiver pathUID cascade code
ATQA received; FIFO empty after 93 20Actual TxDataNum readback, FIFO writes, DataEn, IRQ handling, timeout and premature IdleLPCD thresholds
Partial bytes or invalid BCCRxBitCtrl alignment, RxColl validity, collision position, FIFO read length and bit-prefix handlingBlindly increasing RF power
Five anticollision bytes; no SAKNVB 0x70, transmitted UID/CT bytes, BCC, CRC_A configuration and SELECT response timeoutRepeating REQA indefinitely
Four-byte UID works; seven-byte UID failsCascade tag removal, SAK cascade bit, CL2 command 0x95 and final UID assemblySPI clock rate
One card works; two cards are unstableRxColl, first collision position, chosen branch bit, updated NVB and repeatable prefix constructionSingle-card-only tuning
Change one variable at a time. Keep the same card, position and protocol profile while checking the failed exchange. Save its status before retrying; compare configuration readback, not only the values your driver intended to write.

What REQA, Anticollision, SELECT and SAK Each Do

ISO 14443A command sequence from seven-bit REQA and ATQA through anticollision, SELECT and SAK
Protocol sequence drawn for this article. The command bytes identify the transaction stage; UID data and SAK values depend on the card.

Swipe to view all columns →

StageReader frame over the airExpected card response over the airWhat the result proves
PollingREQA 0x26, seven valid bits, no CRC_ATwo-byte ATQAAt least one idle card responded to the Type A short frame.
Anticollision CL10x93 0x20Four cascade-level bytes plus BCC, unless a bit collision must be resolvedThe host can receive a cascade-level value and inspect collision state.
Select CL10x93 0x70 + five bytes + CRC_ASAK + CRC_AThe chosen cascade-level value was selected.
Additional level0x95 for CL2; 0x97 for CL3Next UID fragment and BCC, then SAKThe host assembles a seven- or ten-byte UID.
Important: for a single card with no unresolved collision, the response to SEL + 0x20 is five bytes: four cascade-level bytes followed by BCC. If the first byte is the cascade tag 0x88, it is not part of the final UID.

Check the CLRC663 and STM32 Command Flow

The examples use driver-neutral pseudocode, not a complete STM32 HAL driver. Adapt each operation to your driver and device revision. Bit-field setters must preserve unrelated register bits; CRC helpers must change the enable state without overwriting the Type A preset.

1. Start from a known Type A state

  1. Read the documented device version and confirm stable results across repeated SPI reads.
  2. Apply the documented ISO 14443A 106 kbit/s protocol profile for both receive and transmit paths.
  3. After saving the previous result, set the reader idle, flush FIFO, clear relevant IRQ flags and configure a receive timeout plus a host-side deadline.
  4. Do not combine protocol bring-up with antenna retuning or LPCD changes.

2. Send REQA as a seven-bit short frame

uint8_t reqa = 0x26;

reader_idle();
flush_fifo();
clear_irq0_irq1();
configure_timeout();

disable_tx_crc();
disable_rx_crc();
set_tx_data_enabled(true);
set_tx_last_bits(7);         // REQA is a seven-bit short frame
set_rx_align(0);
set_rx_multiple(false);

write_fifo(&reqa, sizeof reqa);
start_transceive();
event = wait_for_exchange_event(host_deadline);
result = capture_exchange_result(event);

REQA does not carry CRC_A, and ATQA must be received without expecting CRC_A. NXP's AN12657, section 4.1, gives the corresponding polling configuration. Accept ATQA only after checking the receive status and two-byte payload; a wait function returning is not a success indication.

For repeated tests, also control the card state. A card in HALT does not answer REQA; use the appropriate wake-up or field-reset sequence before comparing polling attempts.

3. Start cascade-level 1 anticollision

TX9320Expected RXUID/CTUIDUIDUIDBCC
uint8_t anticoll_cl1[2] = { 0x93, 0x20 };

reader_idle();
flush_fifo();
clear_irq0_irq1();
configure_timeout();

disable_tx_crc();
disable_rx_crc();

set_tx_data_enabled(true);
set_tx_last_bits(0);         // Full final byte; preserve DataEn
set_rx_align(0);             // Initial NVB 0x20 round starts byte-aligned
set_values_after_collision(false);
set_no_collision_error(false);
set_rx_multiple(false);

write_fifo(anticoll_cl1, sizeof anticoll_cl1);
start_transceive();
event = wait_for_exchange_event(host_deadline);
result = capture_exchange_result(event);

/* A completed wait is not necessarily a valid response. */
if (result.aborted || result.truncated || result.has_frame_error) {
    report_failure(result);
} else if (result.error_coll_det) {
    inspect_collision_validity_and_resolve_branch(result);
} else if (result.rx_complete &&
           result.fifo_len == 5 &&
           result.rx_last_bits == 0 &&
           bcc_matches(result.rx_data)) {
    save_cascade_level_bytes(result.rx_data);
} else {
    report_unusable_response(result);
}

Transmit framing: TxDataNum.DataEn and TxLastBits are separate fields. For CL1, set TxLastBits=0 to send a complete final byte and keep DataEn=1. With the other bits clear, the REQA-to-CL1 change is 0x0F → 0x08, not 0x0F → 0x00. Preserve KeepBitGrid if your protocol configuration uses it. See the CLRC663 data sheet, TxDataNum register.

CRC and reception: disable transmit CRC generation and receive CRC checking for initial anticollision. Set RxAlign=0 for the initial NVB 0x20 request. Keep ValuesAfterColl=0, NoColl=0 and RxMultiple=0. Read Error.CollDet explicitly; a collision must not be treated as a valid five-byte UID response.

Helper contract: wait_for_exchange_event() observes the relevant receive, error, idle and timer events with a host-side deadline; it returns a reason, not a pass/fail verdict. capture_exchange_result() first saves IRQ0/IRQ1, Error, Status, RxBitCtrl and RxColl. On timeout or an error while reception is still active, it records an aborted exchange and stops the command before reading a stable FIFO length and bounded payload. It must report truncation, preserve the original failure status, and never clear IRQs or flush FIFO before saving the evidence.

Scope: this block starts the first CL1 anticollision round. When a collision is reported, use RxColl.CollPos only if CollPosValid=1. Select a branch bit, append the known UID prefix, update NVB and configure TxLastBits and RxAlign for the next partial-bit round. If the position is invalid, do not invent a branch from that register value. It is not a complete multi-card collision-resolution loop.

4. Check BCC, then SELECT the cascade-level value

For an uncollided five-byte response, XOR the four cascade-level bytes and compare the result with BCC. Then send:

9370UID/CTUIDUIDUIDBCCCRC_A

Enable CRC_A generation for SELECT and CRC_A checking for its response. If hardware appends CRC_A, do not also place a second CRC in the transmit FIFO. Check the receive status before accepting SAK; distinguish the over-the-air SAK-plus-CRC frame from the payload your driver exposes after CRC handling.

If the SAK cascade bit is set, retain the UID bytes and continue with 0x95 for CL2. Use 0x97 for CL3 when required. Exclude cascade tags and BCC bytes from the final UID.

Use the Logic Analyzer to Connect SPI Activity to Protocol State

Capture NSS, SCK, MOSI, MISO and the reader IRQ signal. Start by checking transaction boundaries and decoded bytes. SPI writes show what the host sent to the reader; they do not, by themselves, prove what the antenna transmitted.

Illustrative SPI and IRQ sequence for CLRC663 REQA and initial anticollision debugging
Illustrative SPI/IRQ sequence for the debugging workflow. Signal spacing is schematic; no measured timing is shown.

Separate SPI register writes from the RF command

For a CLRC663 SPI write, the first byte is the register address shifted left by one bit, with bit 0 cleared. The FIFOData register is 0x05; its SPI write-address byte is therefore 0x0A. The examples below show MOSI bytes in hexadecimal, following NXP AN12657, section 2.1.

OperationMOSI bytes during one NSS-low intervalHow to interpret it
Load REQA into FIFO0A 260A addresses FIFOData; only 26 is the protocol payload.
Load initial CL1 request into FIFO0A 93 2093 20 is the two-byte RF request. Do not transmit the SPI address byte over the air.
Start Transceive00 07Write command value 07 to Command register 00 in a separate SPI transaction.

Keep NSS low for each complete transaction and return it high between commands. These are individual write examples, not an initialization script: configure framing, clear stale state and load the intended FIFO payload before starting Transceive. Check the SPI mode and timing limits for the fitted device revision.

Log one record per protocol stage

Use one format for REQA, each anticollision round and each SELECT. Replace the placeholders with captured values; the stage and request fields identify the operation, while the receiver fields explain its outcome.

seq=captured  stage=REQA / AC_CL1_INITIAL / SELECT_CL1 / ...
tx_fifo=captured payload  tx_data_num_pre=register readback
tx_crc_pre=captured  rx_crc_pre=captured  rx_bit_ctrl_pre=captured
irq0=captured  irq1=captured  error=captured  status=captured
rx_bit_ctrl_post=captured  rx_coll=captured
fifo_len=captured full length  logged_rx_len=bytes saved  rx=captured bytes
termination=decoded event  aborted=true / false  truncated=true / false
elapsed_us=measured  result=decoded outcome

Read the record in this order: compare the configuration readback with the intended stage, identify why the wait ended, then interpret error flags, byte count and payload. An empty FIFO alone does not prove that the card is absent, and RxIRQ alone does not prove a valid frame.

Expected lengths belong in the test rules, not in fields presented as measurements: ATQA is two bytes; an uncollided initial cascade response is five bytes. For SAK, account for CRC retention in the receiver configuration. Record the original FIFO length even if the logging buffer is smaller, and flag any omitted bytes.

Worked Example: Clearing TxLastBits Also Clears DataEn

Illustrative analysis, not captured test output. Return to the access-reader scenario: polling works, but the application receives no usable UID after initial CL1. Suppose configuration readback reveals the following values, with KeepBitGrid and the other upper bits clear.

Stage or proposed changeTxDataNum valueMeaning of the configuration
REQA configuration0x0FDataEn=1, TxLastBits=7: FIFO data enabled, seven valid final bits.
Faulty initial CL1 configuration0x00TxLastBits=0, but DataEn=0: clearing the whole register also disables FIFO data transmission.
Candidate correction to test0x08DataEn=1, TxLastBits=0: FIFO data enabled, complete final byte.
  1. Check the hypothesis. Read back TxDataNum immediately before starting CL1. If DataEn is already set and the final-bit count is correct, this example does not explain your failure; continue with the fault-isolation table.
  2. Explain the evidence. Seeing 0A 93 20 on MOSI confirms a FIFO write, not transmission of those bytes over the air. With DataEn clear, a correct-looking SPI payload is insufficient.
  3. Change only the relevant fields. Set DataEn and clear TxLastBits with a masked update that preserves other required settings. Read the register back again, then repeat the exchange with the same card and position.
  4. Verify rather than assume recovery. Require a completed, error-checked response with no unresolved collision, five complete cascade bytes and valid BCC. Then test SELECT, SAK and any further cascade level. Record the actual result, including any remaining failure.

This example identifies a configuration defect; it does not claim a measured success rate or a universal fix. If the framing correction does not restore a valid response, retain the new failure record and investigate CRC configuration, receive state, command completion and RF margin in turn.

Validate More Than One Card and One UID Length

A single four-byte UID does not exercise cascade handling or multi-card collisions. Define the required card families and UID lengths before testing; mark unsupported or unavailable test cases explicitly rather than reporting an untested pass.

Illustrative multi-card UID and anticollision test setup for an NF663 reader evaluation
Illustrative multi-card reader evaluation setup, not a documentary photograph of a verified NF663 test. Use the matrix below to record results from your own hardware.

Swipe to view all columns →

Test conditionProtocol behavior to verifyEvidence to retain
One card, four-byte UIDCL1 anticollision, BCC, SELECT and final SAKRaw frames, assembled UID and elapsed time
One card, seven-byte UIDCT in CL1, cascade SAK, CL2 and correct removal of CTBoth cascade-level records and final seven bytes
One card, ten-byte UIDCL1, CL2 and CL3 progressionAll cascade-level values, BCC results and SAK values
Two cards togetherValid collision position, deterministic branch selection and eventual UID selectionRxColl, NVB progression and selected UID
Card-position sweepProtocol remains stable across the required operating volumePosition, orientation, attempt count and success rate
Power and reset cyclingProtocol profile and state machine recover without stale FIFO or IRQ stateBoot log, first-card latency and failure count
Application supply and temperature limitsPolling, selection and recovery meet the declared requirements on the final assemblyConditions, firmware revision, attempt count and failure records

Define the sample count, success-rate target and operating volume before testing. Report measured results only for the actual PCB, antenna, enclosure, firmware revision and card set.

What to Keep in the Release Record

Use the matrix above as a single acceptance checklist. Attach the PCB revision, reader order code, data-sheet revision, STM32 firmware commit, protocol settings, antenna, enclosure, card set and predefined pass limits.

Retain raw failed exchanges as well as successful selections. Report coverage and measured results for that configuration only; a bench demonstration does not establish performance across an untested operating range.

Using This Test Plan to Evaluate NYFEA NF663

NYFEA NF663 13.56 MHz RFID reader IC package appearance rendering

If you are evaluating NYFEA NF663 for an STM32 reader, reuse the protocol checks and log format above as a starting point. NF663 supports ISO/IEC 14443 Type A operation and an SPI host interface; the useful comparison is whether each reader completes the required card-selection tests, not whether a few register names look similar.

Use the NF663 product specification to check interface setup, command behavior and receiver status handling. Keep the application-level test cases, and review or adapt the low-level driver where required.

Compatibility boundary: this test plan is not a drop-in replacement claim. Verify pinout, supplies, register and EEPROM behavior, timing and RF matching against the NF663 documentation, then validate on NF663 hardware.
  1. Save the CLRC663 baseline, including firmware revision, test conditions and raw protocol records.
  2. Bring up the NF663 implementation using its documented configuration and an appropriate board and RF network.
  3. Repeat the same applicable card-selection tests and compare outcomes, timing and recovery behavior. Record hardware differences that prevent a direct comparison.

Conclusion

Start with the first failed exchange and compare what the driver intended with what the reader actually reports. Once single-card selection works, use the same records to validate longer UIDs, collisions and recovery across the intended operating conditions.

Frequently Asked Questions

Why does CLRC663 receive ATQA but not the card UID?

ATQA is a polling response, not a UID. Check the initial 0x93 0x20 request, the transition to full-byte transmission with DataEn preserved, and the receive result before proceeding to SELECT. Repeatable ATQA does not rule out RF-margin problems.

How many bits should CLRC663 transmit for REQA?

REQA is a seven-bit ISO/IEC 14443 Type A short frame. Keep DataEn enabled, set TxLastBits to 7 and disable CRC generation and checking for the REQA/ATQA exchange. For initial CL1, restore TxLastBits to 0 without clearing DataEn.

What response is expected after 0x93 0x20?

With one card and no unresolved collision, initial CL1 returns four cascade-level bytes followed by BCC. A longer UID uses the cascade tag 0x88 in CL1. Validate status, byte count and BCC; exclude cascade tags and BCC from the final UID.

Why does a seven-byte UID require another anticollision level?

A seven-byte UID is split across CL1 and CL2. After a valid CL1 SELECT response, the SAK cascade bit indicates that selection must continue with SEL 0x95. Assemble the UID without the cascade tag or BCC bytes.

Should the antenna be retuned when ATQA is received but UID is missing?

For repeatable ATQA with a fixed card and position, inspect digital framing and command handling first. If those checks pass, investigate RF margin and receiver behavior. Validate the final design across the required card and position range.

Can CLRC663 firmware be copied directly to NF663?

Do not assume direct firmware compatibility. Reuse the protocol-level test plan, check the NF663 specification and adapt the driver where needed. Validate the implementation on NF663 hardware.

Technical References and Case Context

  1. NXP - CLRC663 and CLRC663 plus Product Data Sheet, Rev. 5.4
  2. NXP AN12657 - Using the RC663 without library, Rev. 1.0
  3. NXP Community - Select ISO1443A operation with CLRC663 (reported symptoms, not a verified fix)
  4. NYFEA - NF663 Product Specification

ISO/IEC 14443A protocol summaries are provided for engineering orientation. Implementations intended for certification or regulated applications must use the applicable licensed standard and project requirements.

Discuss Your NF663 Reader Design

Evaluating NF663 for a new reader? Share your STM32 interface, target card types and current REQA/anticollision logs with NYFEA to discuss the relevant documentation and next evaluation steps.

© 2023 All Rights Reserved. www.nyfea.com Terms of Use | Privacy Policy