This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52 SPI pins incompatibility

Hi, i'm using nRF52 DK to communicate CX93510 encoder chip via SPI. I'm using nrf_drv_spi library with SPI0 connected to pins:

#define CX93510_MISO_PIN 22
#define CX93510_MOSI_PIN 23
#define CX93510_SCK_PIN 24
#define CX93510_CS_PIN 25
#define CX93510_PDRAM_PIN 26
#define CX93510_PD_PIN 27

When my development board with CX93510 not connected to NRF52 DK i can see SPI working correct:

however when i connect CX93510 to my DK board SPI communication ruins - MOSI line dont operate correctly and timings dont match the settings:

I tryied to add 120 Ohm resistors to SPI lines to be sure it is not problem with current flowing through pin - this didnt help. I know that CX93510 chip works good, because i can operate with it with STM8 controller without any problems. Anyone has suggestions how to solve this problem?

  • Hi,

    Could you post some code showing how you configure the SPI interface, and how/what you transfer to the device?

    Are you able to see data output on the SPI bus if you flash the board with the SPI example from the SDK? Also, which SDK version are you using?

    Best regards,
    Jørgen

  • Thank you for response!

    I'm using SDK 14.2, SPI0 configured as CPOL=0, CPHA=0, no pull on MISO line and not using EasyDMA.

    As i mentioned i'm able to see data output on the SPI bus when it is unplugged from slave device CX93510. Also i dont have any troubles with communication to other SPI devices without any changing initialization code (for example SX1276).

    Problem appears when i connect CX93510 IC to SPI and I know it looks like this IC is broken or something like this, BUT i'm able to communicate to it with another microcontroller. SPI mode and timings are the same, but STM8 works good and nRF52 fails.

    My initialization code:

    void cx93510_periph_config (void)
    {
    	nrf_drv_gpiote_init();
    	nrf_drv_gpiote_out_config_t cx93510_out_config = GPIOTE_CONFIG_OUT_SIMPLE(true);
    	APP_ERROR_CHECK(nrf_drv_gpiote_out_init(CX93510_CS_PIN, &cx93510_out_config));
    	APP_ERROR_CHECK(nrf_drv_gpiote_out_init(CX93510_PD_PIN, &cx93510_out_config));
    	APP_ERROR_CHECK(nrf_drv_gpiote_out_init(CX93510_PDRAM_PIN, &cx93510_out_config));
    	
    	nrf_drv_spi_config_t cx93510_spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    	cx93510_spi_config.miso_pin =	CX93510_MISO_PIN;
    	cx93510_spi_config.mosi_pin = CX93510_MOSI_PIN;
    	cx93510_spi_config.sck_pin = CX93510_SCK_PIN;
    	cx93510_spi_config.mode = NRF_DRV_SPI_MODE_0;
    	cx93510_spi_config.frequency = NRF_DRV_SPI_FREQ_1M;
    	APP_ERROR_CHECK( nrf_drv_spi_init(&spi_cx93510, &cx93510_spi_config, spi_cx93510_event_handler, NULL) );
    
    }

    SPI event handler:

    static void spi_cx93510_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context)
    {
    	spi_cx93510_busy = false;
    }

    Transmit and Recieve code:

    static void spi_recieve_buffer(uint8_t *rx_buffer, uint16_t size)
    {
    	uint32_t timeout = SPI_TIMEOUT;
    	uint8_t tx_buffer[size];
    	
    	// waiting last transmittion complete
    	while (spi_cx93510_busy && timeout--);
    	timeout = SPI_TIMEOUT;
    	
    	APP_ERROR_CHECK (nrf_drv_spi_transfer(&spi_cx93510, tx_buffer, size, rx_buffer, size) );
    	spi_cx93510_busy = true;
    	
    	while (spi_cx93510_busy && timeout--);
    }
    
    static void spi_transmite_buffer(uint8_t *tx_buffer, uint16_t size)
    {
    	uint32_t timeout = SPI_TIMEOUT;
    	uint8_t rx_buffer[size];
    	
    	// waiting last transmittion complete
    	while (spi_cx93510_busy && timeout--);
    	timeout = SPI_TIMEOUT;
    	
    	APP_ERROR_CHECK( nrf_drv_spi_transfer(&spi_cx93510, tx_buffer, size, rx_buffer, size) );
    	spi_cx93510_busy = true;
    	
    	while (spi_cx93510_busy && timeout--);
    
    }

    Accesing CX93510 registers:

    void codec_read (uint8_t* pbuf, uint8_t len)
    {
        uint8_t buf[3];
    
        buf[0] = 0;
        buf[1] = *pbuf;
        buf[2] = 0;
    
        CX93510_CS_CLEAR;
    
        spi_transmite_buffer (&buf[0], 3);
    
        spi_recieve_buffer (pbuf, len);
    
        CX93510_CS_SET;
    }
    
    void codec_write (uint8_t* pbuf, uint8_t len)
    {
        uint8_t buf[3];
    
        buf[0] = (uint8_t) 0x80;
        buf[1] = *pbuf;
        buf[2] = 0;
    
        CX93510_CS_CLEAR;
    
        spi_transmite_buffer (&buf[0], 3);
    
        spi_transmite_buffer (pbuf + 1, len - 1);
    
        CX93510_CS_SET;
    
    }

    And what i'm trying to transfer (it is shown in diagrams at topic start):

    void cx93510_init (void)
    {	
    	uint8_t tmp8;
    	uint8_t buf[6];
    	uint8_t sensor_pid_msb, sensor_pid_lsb;
    	
    	do
      {
    		CX93510_PDRAM_CLEAR;
    		CX93510_PD_CLEAR;
    		
    		nrf_delay_ms(1);
    		
    		CX93510_PDRAM_SET;
    		CX93510_PD_SET;	
    
    		nrf_delay_ms(5);
    		
    		tmp8 = (uint8_t) 0x50;
        codec_read (&tmp8, 1);
    
        tmp8 = (uint8_t) 0x50;
        codec_read (&tmp8, 1);
      } 
    	while (1);// ((tmp8 & (uint8_t) 0x03) != (uint8_t) 0x01);      // waiting Conexant to answer
    }

  • Do you have a datasheet for the CX93510 device that you could share? Is the device able to clock out data immediately after the CS line is asserted? From the two logic trances there seems to be some difference in timing. What is the device supposted to clock out? Is 0x00 transferred from the master configuring the device in any way, or does it not need any configuration? 

  • There is the datasheet file for CX93510: 4540.CX93510 Reflector DSH-202155-003.pdf . Host interfaces are described at page 45.
    This device requires not much time (a few ns) after CS goes low to clock out data.

    Yes, there are differences in timing and i dont know why, SPI configuration is the same at both diagrams.

    First 0x00 byte specifies the "read register" command, next byte (here it is 0x50) is register address, 3rd byte should be 0x00. After this actions one byte of data should be clocked out from the device.

    Below is the diagram of communicating to this device with STM8 controller. First transmittion is needed for interface selecting as described in datasheet, the second gives us valid output data (0x01)

  • Thank you. Did you try debugging the application? Please check the content of tx_buffer right before call to nrf_drv_spi_transfer().

Related