NRF52840 SPI max transfer length issue

Hi guys.

I've a pretty simple issue: i'm trying to keep my mcu in low power while I receive 4kb of data via SPI.

After some checking, turns out that 52832 only allowed 8bit transfer sizes (due to DMA), but the register for 52840 is 16bit wide (TXD.MAXCNT).

And while there were some suggestions (years ago) that future iterations of the SDK (which has now reached version 17) will support 16bit transfer sizes for 52840, it seems that there's still this pesky limitation.

Do you guys have a solution/ workaround?

  • You mean you want to transfer all 4kb at once over SPI using the 52840?  Because it already does this in the nrfx driver (below code is SDK 17.0.2).  Just  make a buffer big enough and go to town.  This works fine for me:

    #include <stdint.h>
    #include "nrf_gpio.h"
    #include "nrfx_spim.h"
    #define SPIM3_SCK_PIN                     NRF_GPIO_PIN_MAP(1, 12)
    #define SPIM3_MOSI_PIN                    NRF_GPIO_PIN_MAP(1, 13)
    #define SPIM3_MISO_PIN                    NRF_GPIO_PIN_MAP(1, 11)
    #define SPIM3_CS_PIN                      NRF_GPIO_PIN_MAP(1, 14)
    /* SPIM3 to show the extended features */
    const nrfx_spim_t m_spim3 = NRFX_SPIM_INSTANCE(3);
     * @brief Function for application main entry.
    int main(void)
        nrfx_spim_xfer_desc_t desc;
        uint8_t tx_buff[1]; // if you needed to transmit something
        uint8_t rx_buff[4097];
        nrfx_spim_config_t spim_cfg = NRFX_SPIM_DEFAULT_CONFIG;
        ret_code_t error;
        /* Configure SPIM */
        spim_cfg.frequency  = NRF_SPIM_FREQ_8M;
        spim_cfg.ss_pin     = SPIM3_CS_PIN;
        spim_cfg.sck_pin    = SPIM3_SCK_PIN;
        spim_cfg.mosi_pin   = SPIM3_MOSI_PIN;
        spim_cfg.miso_pin   = SPIM3_MISO_PIN;
        spim_cfg.mode       = NRF_SPIM_MODE_0;
        spim_cfg.use_hw_ss  = true;
        //spim_cfg.rx_delay   = 0x07;
        //spim_cfg.ss_duration = 0x07;
        /* Pass a handler instead of NULL for interrupts instead of blocking */
        error = nrfx_spim_init(&m_spim3, &spim_cfg, NULL, NULL);
        /* Build the transfer description and kick it off */
        desc.p_tx_buffer  = NULL;
        desc.tx_length    = 0;
        desc.p_rx_buffer  = rx_buff;
        desc.rx_length    = 4096;
        nrfx_spim_xfer(&m_spim3, &desc, 0);
        /* Uninit SPIM and disable to save power */
        m_spim3.p_reg->TASKS_STOP = SPIM_TASKS_STOP_TASKS_STOP_Trigger;
        while (!m_spim3.p_reg->EVENTS_STOPPED);
        m_spim3.p_reg->ENABLE = SPIM_ENABLE_ENABLE_Disabled;
        /* Loop */
        for (;;)

    If you are having trouble getting it setup right with the include directories and stuff in SES and with sdk_config hit me up and I'll zip up the example and send it to you.

  • Thanks a million! This seems pretty straightforward. As the current consumption is a big issue, i really hoped for a solution using DMA and keeping the mcu in a WFE loop. I'll test your solution right away.

    Thanks again!

Reply Children
No Data