Hi,
I'm using two dev kits to test out some SPI firmware before I deploy it to our custom boards and I've been running into a weird issue where my SPIS sends out corrupted data. The data corruption exists at an SCK of 1MHz and it gets worse when I go up to 4MHz and even worse at 8MHz.
An example of the data corruption is as follows:
I fill up the SPIS's m_tx_buf with: 0x41410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202
but when a spi transaction is triggered, the SPI peripheral shifts out the following over the MISO line:
0xff41410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002
I've probed the MISO line with an oscope and here's a screenshot of the first couple bytes. In it you can see that the spis actually 'adds' ff to the beginning.
sometimes the data is corrupted differently and I will receive something like:
0xffa0a08000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 which has 9 bits of 1 at the front (right?).
I've tried printing out these bytes in debug mode (using NRF_LOG_INFO()) and those report the correct bytes back regardless of when I query the buffer. My spis code is built off the example in SDK 17.1 and it's really really quite similar - is there some limitation for SPI packets >= 65 bytes? Here is a copy of my code as reference:#include "sdk_config.h"
#include "nrf_drv_spis.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#define SPIS_INSTANCE 1 /**< SPIS instance index. */
static const nrf_drv_spis_t spis = NRF_DRV_SPIS_INSTANCE(SPIS_INSTANCE);/**< SPIS instance. */
/*
#define TEST_STRING "Nordic"
static uint8_t m_tx_buf[] = TEST_STRING; //< TX buffer. >
static uint8_t m_rx_buf[sizeof(TEST_STRING) + 1]; //< RX buffer. >
static const uint8_t m_length = sizeof(m_tx_buf); //< Transfer length. >
*/
static uint8_t m_tx_buf[] = {65,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,2,2};
static uint8_t m_rx_buf[sizeof(m_tx_buf) + 1]; // RX buffer.
static const uint8_t m_length = sizeof(m_tx_buf); // Transfer length.
static volatile bool spis_xfer_done; /**< Flag used to indicate that SPIS instance completed the transfer. */
/**
* @brief SPIS user event handler.
*
* @param event
*/
void spis_event_handler(nrf_drv_spis_event_t event)
{
if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
{
spis_xfer_done = true;
//NRF_LOG_INFO(" Transfer completed. Received: %s",(uint32_t)m_rx_buf);
}
}
int main(void)
{
// Enable the constant latency sub power mode to minimize the time it takes
// for the SPIS peripheral to become active after the CSN line is asserted
// (when the CPU is in sleep mode).
NRF_POWER->TASKS_CONSTLAT = 1;
bsp_board_init(BSP_INIT_LEDS);
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("SPIS example");
nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;
spis_config.csn_pin = APP_SPIS_CS_PIN;
spis_config.miso_pin = APP_SPIS_MISO_PIN;
spis_config.mosi_pin = APP_SPIS_MOSI_PIN;
spis_config.sck_pin = APP_SPIS_SCK_PIN;
APP_ERROR_CHECK(nrf_drv_spis_init(&spis, &spis_config, spis_event_handler));
while (1)
{
memset(m_rx_buf, 0, m_length);
spis_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, m_tx_buf, m_length, m_rx_buf, m_length));
while (!spis_xfer_done)
{
__WFE();
}
NRF_LOG_FLUSH();
bsp_board_led_invert(BSP_BOARD_LED_0);
}
}