[58] SPIM: An additional byte is clocked out when RXD.MAXCNT = 1

This anomaly applies to IC Rev. Engineering A, build codes QFAA-AA0, QFAA-AC0, CGAA-AA0.

Symptoms

SPIM clocks out additional byte.

Conditions

RXD.MAXCNT = 1

TXD.MAXCNT <= 1

Consequences

Additional byte is redundant.

Workaround

Use the SPI module (deprecated but still available) or use the following workaround with SPIM:

/**
 * @brief Work-around for transmitting 1 byte with SPIM.
 *
 * @param spim: The SPIM instance that is in use.
 * @param ppi_channel: An unused PPI channel that will be used by the workaround.
 * @param gpiote_channel: An unused GPIOTE channel that will be used by the workaround.
 * 
 * @warning Must not be used when transmitting multiple bytes.
 * @warning After this workaround is used, the user must reset the PPI channel and the GPIOTE channel before attempting to transmit multiple bytes.
 */
void setup_workaround_for_ftpan_58(NRF_SPIM_Type * spim, uint32_t ppi_channel, uint32_t gpiote_channel)
{
    // Create an event when SCK toggles.
    NRF_GPIOTE->CONFIG[gpiote_channel] = (
        GPIOTE_CONFIG_MODE_Event <<
        GPIOTE_CONFIG_MODE_Pos
        ) | (
        spim->PSEL.SCK <<
        GPIOTE_CONFIG_PSEL_Pos
        ) | (
        GPIOTE_CONFIG_POLARITY_Toggle <<
        GPIOTE_CONFIG_POLARITY_Pos
        );

    // Stop the spim instance when SCK toggles.
    NRF_PPI->CH[ppi_channel].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[gpiote_channel];
    NRF_PPI->CH[ppi_channel].TEP = (uint32_t)&spim->TASKS_STOP;
    NRF_PPI->CHENSET = 1U << ppi_channel;

    // The spim instance cannot be stopped mid-byte, so it will finish
    // transmitting the first byte and then stop. Effectively ensuring
    // that only 1 byte is transmitted.
}