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?

Parents
  • 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
    }

Reply
  • 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
    }

Children
No Data
Related