This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Strange SPI clocking w/S140 (Update: S132 as well) enabled

I'm having a strange issue with getting SPI running through the transaction manager whilst running a S140 softdevice (SDK13 w/ nrf52840 5.0.0-2Alpha - I know there's a newer version but it's not being used just yet. It's there so I don't accidentally code something that's not compatible with the SD when I eventually get around to the BT part of the project)

I am able to get SPI and SPI manager running normally without the SD - they work perfectly into my current test which is CLK and MOSI into a logic analyser (the target will be a screen with no read line - very similar to the screen in the SPI manager example code).

However, when I load up the SD + base code from 'experimental_ble_nfc_pairing_reference' and modify to init. SPI after all of the BT + NFC etc (as you can see, nothing extra on the example apart from the "testing()" call to start the SPI:

int main(void)
{
logs_init();
timer_init();
bool erase_bonds = buttons_init();
ble_stack_init();

/* Set BLE device name. */
ble_set_device_name(DEVICE_NAME);

gap_params_init();
gatt_init();
advertising_init();
conn_params_init();
peer_manager_init(erase_bonds);
nfc_pairing_init();

	// Init SPI
	testing();

// Start execution.
NRF_LOG_INFO("NFC Connection Handover BLE peripheral device example.\r\n");

// Enter main loop.
while(true)
{
    UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
}
}

This then goes into the following test function:

NRF_SPI_MNGR_DEF(m_nrf_spi_mngr, 1, 0);

static ret_code_t init_spi0_master(void)
{
// SPI0 (with transaction manager) initialization.
nrf_drv_spi_config_t const m_master0_config =
{
    .sck_pin        = 3,
    .mosi_pin       = 4,
    .miso_pin       = NRF_DRV_SPI_PIN_NOT_USED,
    .ss_pin         = NRF_DRV_SPI_PIN_NOT_USED,
    .irq_priority   = APP_IRQ_PRIORITY_HIGHEST,
    .orc            = 0xFF,
    .frequency      = NRF_DRV_SPI_FREQ_500K,
    .mode           = NRF_DRV_SPI_MODE_0,
    .bit_order      = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST
};
return nrf_spi_mngr_init(&m_nrf_spi_mngr, &m_master0_config);
}

void testing(void) {

uint8_t test_str[] = "HELLO";

nrf_spi_mngr_transfer_t transfers =
    {
.p_tx_data = (uint8_t const *) &test_str,
.tx_length = (uint8_t)        sizeof(&test_str)+1, 
	.p_rx_data = (uint8_t *)      NULL,
.rx_length = (uint8_t)        0, 
	};

ret_code_t ret = init_spi0_master();

APP_ERROR_CHECK(ret);

ret = nrf_spi_mngr_perform(&m_nrf_spi_mngr, &transfers, 1, NULL);
APP_ERROR_CHECK(ret);
NRF_LOG_FLUSH();

However the issue I'm having is I'm getting terrible synchronisation issues: image description

And at higher speeds, this becomes even more noticable (the 500K speed in the code is for the sake of making sure it's not something silly like my logic analyser underperforming etc.)

At 8mhz:

image description

Closer look at the data packet:

image description

This early clock firing causes an offset between the data and clock as well which is causing the logic analyser to decode the "HELLO" as garbage.

Interestingly, if I run the transfer in a loop, I have a tiny bit more luck in the fact that the first packet will be the same messed-up clock, but subsequent packets are correctly lined up. This being said, the original clock shift is there causing decoding to fail.

One final thing, enabling / disabling EasyDMA has no impact. As far as the debug logs go? They think everything's alright:

PI:INFO:Transfer tx_len:5, rx_len:0.
SPI:DEBUG:Tx data:
SPI:DEBUG:
48 45 4C 4C 4F 00 00 00 00 00 00 00 E9 69 02 00  HELLO.......éi..
00 00 00 00                                      ....            
SPI:INFO:Function: nrf_drv_spi_xfer, error code: NRF_SUCCESS.
SPI:DEBUG:SPI: Event: NRF_SPI_EVENT_READY.
SPI:DEBUG:SPI: Event: NRF_SPI_EVENT_READY.
SPI:DEBUG:SPI: Event: NRF_SPI_EVENT_READY.
SPI:DEBUG:SPI: Event: NRF_SPI_EVENT_READY.
SPI:DEBUG:SPI: Event: NRF_SPI_EVENT_READY.
SPI:INFO:Transfer rx_len:0.
SPI:DEBUG:Rx data:

Update: Just attempted to recompile with SD 132 - Still having the same issue.

Update 2: Project folder uploaded (project relative path'd to ../sdk/nRF5_SDK_13.0.0_04a0bfd/components etc.)

hardware_token.zip

image description image description

  • Can you zip the project folder from SDK v13 and attach it to the question? I would like to see if I can reproduce the behavior.

  • Hi Bjørn, thank you for looking into this. It's really appreciated. I'm at a loss having traced it all the way back to the DMA controller. It looks like the clock is generated in hardware?

    The code in the zip is a little different to the code in the post. I've simplified it all the way down to a single nrf_drv_spi_transfer.

    Please ignore the warnings about unused variables - it's just code paths I've commented out.

    My environment is the nRF52840 PDK using pin 3 (P0.3) as SPI CLK and pin 4 (P0.4) as SPI MOSI (no other lines). I have tested on other ports and have the same issue.

    Thank you again.

  • I changed the pins to P0.03 and P0.04 and compiled the project. You can see the logic trace below, I see no synchronisation issues. I just have to flash the example to the NRF52840 kit and then to the trace right? image description

  • Wow, this is a rediculously weird one. After blowing away my project folder and replacing it with the zip and still getting the same issue, I removed literally every line from the board (an unused I2C bus and a couple of buttons as well as the control lines for the display (all of which were inactive)) and like magic I'm getting a clean trace again.

    sigh you can chalk this up to "user neglecting to troubleshoot absolutely EVERYTHING before asking for support". Thank you for your time you wasted on me :) (as a developer myself I know how annoying people like myself are)

Related