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

nRF52832 SPI 4-Wire Master Issue with SPI Sample

I have been trying to adapt the following example project to work with my SPI peripheral device (LIS2DE12 Accelerometer): nRF5_SDK_11.0.0_89a8197\examples\peripheral\spi\pca10040\arm5_no_packs

My device has been flashed with S132 2.0.

Info on this peripheral is here: www.st.com/.../en.DM00153214.pdf

I am using a custom device with the following nRF to ST pin connections:

PO.02 (SS) to Pin 2 (CS)

PO.03 (MOSI) to Pin 4 (SDI)

PO.04 (SCK) to Pin 1 (SLC)

PO.05 (MISO) to Pin 3 (SDO)

I have defined these pins within nrf_drv_config.h as per docs.

#define SPI0_ENABLED 1

#if (SPI0_ENABLED == 1)
#define SPI0_USE_EASY_DMA 1		

#define SPI0_CONFIG_SCK_PIN 4
#define SPI0_CONFIG_MOSI_PIN 3
#define SPI0_CONFIG_MISO_PIN 5
#define SPI0_CONFIG_IRQ_PRIORITY    APP_IRQ_PRIORITY_LOW

Note that the only other peripheral enabled is UART0 and it is not using any pins that the SPI interface is using.

#define UART0_ENABLED 1

#if (UART0_ENABLED == 1)
#define UART0_CONFIG_HWFC         NRF_UART_HWFC_DISABLED
#define UART0_CONFIG_PARITY       NRF_UART_PARITY_EXCLUDED
#define UART0_CONFIG_BAUDRATE     NRF_UART_BAUDRATE_115200
#define UART0_CONFIG_PSEL_TXD 10	// RxN Tag Config Tx
#define UART0_CONFIG_PSEL_RXD 8		// RxN Tag Config Rx
#define UART0_CONFIG_PSEL_CTS 9		// RxN Tag Config Unused
#define UART0_CONFIG_PSEL_RTS 14	// RxN Tag Config Unused
#define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW
#ifdef NRF52
#define UART0_CONFIG_USE_EASY_DMA false

Also note that I had tried disabling DMA using:

#define SPI0_USE_EASY_DMA 0

... but found that I was only able to get a clock output during my MOSI buffer transfer but the clock was not continuing to support incoming MISO bytes. Enabling DMA seemed to fix this.

Code used for SPI init and read/write is here:

#define SPI_CS_PIN   2  	
#define SPI_INSTANCE  0 
#if (SPI0_ENABLED == 1)
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); 
#endif
static volatile bool spi_xfer_done; 

static uint8_t		m_tx_buf[2];	// Control/Addr byte plus optionally used data byte for reg writes.
static uint8_t		m_rx_buf[1];	// Always just 1 data byte returned.

void spi_event_handler(nrf_drv_spi_evt_t const * p_event)
{
	nrf_delay_ms(10);
	
    spi_xfer_done = true;
    NRF_LOG_PRINTF(" Transfer completed.\r\n");
	NRF_LOG_PRINTF(" Received: 0x%02X\r\n",m_rx_buf[0]);
}

int main(void)
{
	ret_code_t err_code;
	
	err_code = NRF_LOG_INIT();
    APP_ERROR_CHECK(err_code);
    NRF_LOG_PRINTF("Altered SPI example\r\n");

    nrf_drv_spi_config_t spi_config;
    spi_config.ss_pin = SPI_CS_PIN;
	spi_config.mosi_pin = SPI0_CONFIG_MOSI_PIN;
	spi_config.sck_pin = SPI0_CONFIG_SCK_PIN;
	spi_config.miso_pin = SPI0_CONFIG_MISO_PIN;
	spi_config.frequency = NRF_DRV_SPI_FREQ_8M;			// Default 4M
	spi_config.mode = NRF_DRV_SPI_MODE_3;				// Default mode 0 
	spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST; // Matches Default.
	spi_config.irq_priority = SPI0_CONFIG_IRQ_PRIORITY;
	
	err_code = nrf_drv_spi_init(&spi, &spi_config, spi_event_handler);
	APP_ERROR_CHECK(err_code);

    while(1)
    {
        // Reset rx buffer and transfer done flag
        memset(m_rx_buf, 0, 1);
        spi_xfer_done = false;
	
		m_tx_buf[0] = 0x8F;	// 1 = Read, 0 = No Addr Inc, 001111 = WhoAmI Reg Add
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 1, m_rx_buf, 1));

        while (!spi_xfer_done)
        {
            __WFE();
        }

        nrf_delay_ms(100);
    }
}

There are 2 issues that I am having when issuing a read of peripheral register 0x0F (using cmd 0x8F):

  1. Response data printed within the callback should always be 0x33 (the fixed value in register 0x0F), but is often erroneous.

  2. Voltage levels on the clock, MISO and MOSI lines look incorrect during peripheral responses.

Relating to "1." - I repeatably read a register value of 0xFF and then the correct 0x33 (and then 0xFF again and the cycle repeats) when using the fastest Nordic SPI rate of 8 Mbps. At lower rates, inconsistent register values are read.

Relating to "2." (which may be the cause of "1."), I believe that there may be contention on the lines as indicated in scope caps.

Please ignore the apparent offset from ground as there is an outstanding scope setup issue.

In this first capture, the yellow line shows my clock and the blue line shows chip select. It is driven low by the Nordic SPI driver as required. image description TagSPI_6.bmp

In this second capture, the blue line now shows the MOSI signal. It seems good until a response comes in from the peripheral and then it is driven to a strange state instead of O Vdc. The command is 0x8F (10001111) denoting read from register 0x0F. image descriptionTagSPI_7.bmp

In this last capture, the blue line now shows the MISO signal. It's timing and indicated value is correct (byte value 0x33), but its levels seem strange. image descriptionTagSPI_5.bmp

Could this indicate contention on the clock and MISO lines - only when the peripheral is responding to a read command over MOSI? The driver init seems to leave the MISO pin floating.

// - MISO (optional) - input,
    if (p_config->miso_pin != NRF_DRV_SPI_PIN_NOT_USED)
    {
        miso_pin = p_config->miso_pin;
        nrf_gpio_cfg_input(miso_pin, NRF_GPIO_PIN_NOPULL);
    }

Is this ok, or perhaps would a pull up help?

Changing data rates to below 8 Mbps does not seem to affect the traces, so maybe there a two distinct issues here.

Any help and suggestions are appreciated.

Parents
  • Last time I had levels doing something silly like that I had a grounding issue, are you sure your dev board and your sensor have the same VDD and their grounds connected directly and firmly together? When I didn't have that right, the whole sensor chip floated up and down as GPIOs went high and low.

    You should also fix your outstanding scope setup issue because it makes the results at least a little suspect.

    SPI is a driven protocol, so pullups/pulldowns aren't required.

Reply
  • Last time I had levels doing something silly like that I had a grounding issue, are you sure your dev board and your sensor have the same VDD and their grounds connected directly and firmly together? When I didn't have that right, the whole sensor chip floated up and down as GPIOs went high and low.

    You should also fix your outstanding scope setup issue because it makes the results at least a little suspect.

    SPI is a driven protocol, so pullups/pulldowns aren't required.

Children
No Data
Related