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

How to make Multiple Transmission and Single Receiver Using NRFx_SPIM Example for NRF52840-DK Board?

Hi,

I am Using NRF52840-DK Board. We are trying to transmit multiple data using NRFx_SPIM Example. for single reg read it is working fine.

please check below code is it correct or not?.

void MAX30003_Reg_Read(uint8_t Reg_address)
{
  nrfx_err_t err_code = 0;	
  uint32_t data=0xFF;
	//Prepare the tx buffer
  memset(SPI_TX_Buff, 0x00, sizeof(SPI_TX_Buff)); // Erases the buffer
  memset(SPI_RX_Buff, 0x00, sizeof(SPI_TX_Buff)); // Erases the buffer
  SPI_TX_Buff[0] = (Reg_address<<1) | 0x1; // should be SPI_TXBuff[0], I assume RREG = 0x1;
//Create the transfer descriptor
  nrfx_spim_xfer_desc_t xfer_desc4 = NRFX_SPIM_XFER_TRX(SPI_TX_Buff, sizeof(SPI_TX_Buff), SPI_RX_Buff, sizeof(SPI_TX_Buff));
	nrfx_spim_xfer_desc_t xfer_desc5 = NRFX_SPIM_XFER_TRX((data << 16), sizeof(data), SPI_RX_Buff, sizeof(data));
	nrfx_spim_xfer_desc_t xfer_desc6 = NRFX_SPIM_XFER_TRX((data << 8), sizeof(data), SPI_RX_Buff, sizeof(data));
	nrfx_spim_xfer_desc_t xfer_desc7 = NRFX_SPIM_XFER_TRX(data, sizeof(data), SPI_RX_Buff, sizeof(data));
//Initiate the transfer
  err_code = nrfx_spim_xfer(&spi, &xfer_desc4, 0);
	err_code = nrfx_spim_xfer(&spi, &xfer_desc5, 0);
	err_code = nrfx_spim_xfer(&spi, &xfer_desc6, 0);
	err_code = nrfx_spim_xfer(&spi, &xfer_desc7, 0);
  APP_ERROR_CHECK(err_code);
//  while (spi_xfer_done == true);
}

I am refer below code :

uint32_t MAX30003::readRegister(const Registers_e reg)
{
    uint32_t data = 0;
    
    m_cs = 0;
    m_spiBus.write((reg << 1) | 1);
    data |= (m_spiBus.write(0xFF) << 16);
    data |= (m_spiBus.write(0xFF) << 8);
    data |= m_spiBus.write(0xFF);
    m_cs = 1;
    
    return data;
}   

please help me for that. 

Thanks 

rohit

Parents
  • Hi,

    You are over-complicating the transfer. Just create a large enough receive buffer and to the transfer and receive in a single operation.

    Something like this should work:

    uint8_t SPI_TX_Buff;
    uint8_t SPI_RX_Buff[4];
    
    uint32_t MAX30003_Reg_Read(uint8_t Reg_address)
    {
      nrfx_err_t err_code = 0;	
      uint32_t data = 0;
    
      //Prepare the tx buffer
      memset(SPI_RX_Buff, 0x00, sizeof(SPI_RX_Buff)); // Erases the buffer
      SPI_TX_Buff = ((Reg_address << 1) | 0x01); 
    
      //Create the transfer descriptor
      nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(&SPI_TX_Buff, sizeof(SPI_TX_Buff), SPI_RX_Buff, sizeof(SPI_TX_Buff));
    
      //Initiate the transfer
      spi_xfer_done == false;
      err_code = nrfx_spim_xfer(&spi, &xfer_desc, 0);
      APP_ERROR_CHECK(err_code);
      
      while (spi_xfer_done == false);
      
      data |= (SPI_RX_Buff[1] << 16);
      data |= (SPI_RX_Buff[2] << 8);
      data |= SPI_RX_Buff[3];
      
      return data;
    }

    Best regards,
    Jørgen

  • That depends on how you set spi_xfer_done in the SPIM callback handler. Normally you should set it false before transfer, then set it true in the callback. You will then have to loop in the while as long as the flag is not set true. Now you will skip the loop as the flag is not set true (you set it to false right before nrfx_spim_xfer).

    Regarding SPI_TX_Buff, this will depend on how you have declared the variable. If it is declared as a on-byte array, you will have to do it like that. You should then also change declaration of xfer_desc to:

    nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(SPI_TX_Buff, sizeof(SPI_TX_Buff), SPI_RX_Buff, sizeof(SPI_TX_Buff));

  • Hi,

    Thanks for my driver recovery. I have changed the code as per your suggestion. And Its work fine.

    I get data in TX and RX buffer.

    I am a beginner on NRF52840. I am using Nrfx_spim example for interfacing sensor with NRF Board.

    I have done some driver about Reg_read and Reg_write. I tried to read the device ID of the sensor through SPI yielding improper results.

    Hence I probed on the SPI_SCK line and I found that the duty cycle of SPI_SCK is not proper and also set up and hold times are not proper. 

    In my requirement timing of the SPI should be as in the attached image below. 

    To be more specific I need to meet the timing requirements as of detailed in the image below.

    Presently The waveform what I am observing on probing MISO Channel 3 , CS channel 7, SCK Channel  9 and Channel  13 MOSI is as below.

    I am pretty sure that my SPI configurations are not proper, please provide me a pointer where I can do the SPI configurations to meet the timing requirements detailed above.

    Please check my below code:

    #include "nrfx_spim.h"
    #include "app_util_platform.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.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"
    #include "MAX30003.h"
    
    
    #define NRFX_SPIM_SCK_PIN  3
    #define NRFX_SPIM_MOSI_PIN 4
    #define NRFX_SPIM_MISO_PIN 28
    #define NRFX_SPIM_SS_PIN   29
    #define NRFX_SPIM_DCX_PIN  30
    
    #define SPI_INSTANCE  3                                           /**< SPI instance index. */
    const nrfx_spim_t spi = NRFX_SPIM_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    
    volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    uint8_t m_tx_buf[4]; //= {0xff,0x01,0x02}; // ={0x0F}; // 32 bit transfers
    uint8_t       m_rx_buf[sizeof(m_tx_buf)];  /**< RX buffer. */
    const uint8_t m_length = sizeof(m_tx_buf);        /**< Transfer length. */
    nrfx_spim_xfer_desc_t xfer_desc=NRFX_SPIM_XFER_TRX(m_tx_buf, sizeof(m_tx_buf), m_rx_buf, sizeof(m_tx_buf));
    
    
    void spim_event_handler(nrfx_spim_evt_t const * p_event,
                           void *                  p_context)
    {
    	
    
        spi_xfer_done = true;
        NRF_LOG_INFO("Transfer completed.");
        if (m_rx_buf[0] != 0)
        {
            NRF_LOG_INFO(" Received:");
            NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
        }
    }
    uint8_t MAX30003_Reg_Read(uint8_t Reg_address)
    {
      nrfx_err_t err_code = 0;	
      uint32_t data;
      //Prepare the tx buffer
       memset(m_rx_buf, 0x00, sizeof(m_rx_buf)); // Erases the buffer
      m_tx_buf[0] = ((Reg_address << 1) | 0x01); 
      //Create the transfer descriptor
     // nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_tx_buf, sizeof(m_tx_buf), m_rx_buf, sizeof(m_tx_buf));
      //Initiate the transfer
      spi_xfer_done = false;
      err_code = nrfx_spim_xfer(&spi, &xfer_desc, 0);
      APP_ERROR_CHECK(err_code);
      while (spi_xfer_done == false);
      data |= (m_rx_buf[1] << 16);
      data |= (m_rx_buf[2] << 8);
      data |= m_rx_buf[3];
      return data;
    }
    
    uint8_t MAX30003_Reg_Write(uint8_t Reg_address,  uint32_t data)
    {
      nrfx_err_t err_code = 0;	
      //Prepare the tx buffer
      memset(m_rx_buf, 0x00, sizeof(m_rx_buf)); // Erases the buffer
      m_tx_buf[0] = ((Reg_address << 1) | 0x01); 
    //  //Create the transfer descriptor
    //   nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_tx_buf, sizeof(m_tx_buf), m_rx_buf, sizeof(m_tx_buf));
    //  //Initiate the transfer
      spi_xfer_done = false;
      err_code = nrfx_spim_xfer(&spi, &xfer_desc, 0);
      APP_ERROR_CHECK(err_code);
      while (spi_xfer_done == false);
      data |= (m_rx_buf[1] >> 16);
      data |= (m_rx_buf[2] >> 8);
      data |= m_rx_buf[3];
      return data;
    }
    void max30003_sw_reset(void)
    {
        MAX30003_Reg_Write(SW_RST,0x000000);     
        nrf_delay_ms(100);
    }
    
    void max30003_synch(void)
    {
        MAX30003_Reg_Write(SYNCH,0x000000);
    }
    void MAX30003_begin()
    {    
        max30003_sw_reset();
        MAX30003_Reg_Write(CNFG_GEN, 0x081007);
        nrf_delay_ms(100);
        MAX30003_Reg_Write(CNFG_CAL, 0x720000);  // 0x700000  
        nrf_delay_ms(100);
        MAX30003_Reg_Write(CNFG_EMUX,0x0B0000);
        nrf_delay_ms(100);
        MAX30003_Reg_Write(CNFG_ECG, 0x805000);  // 
        nrf_delay_ms(100);
        MAX30003_Reg_Write(CNFG_RTOR1,0x3fc600);
        max30003_synch();
        nrf_delay_ms(100);
    }
    
    int main(void)
    {
    bsp_board_init(BSP_INIT_LEDS);
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
    spi_config.frequency = SPIM_FREQUENCY_FREQUENCY_M1;
    spi_config.ss_pin = NRFX_SPIM_SS_PIN;
    spi_config.miso_pin = NRFX_SPIM_MISO_PIN;
    spi_config.mosi_pin = NRFX_SPIM_MOSI_PIN;
    spi_config.sck_pin = NRFX_SPIM_SCK_PIN;
    spi_config.dcx_pin = NRFX_SPIM_DCX_PIN;
    spi_config.use_hw_ss = true;
    spi_config.ss_active_high = false;
    spi_config.mode = NRF_SPIM_MODE_0; // SCK active high, sample on leading edge of clock, CPOL=0/CPHA=0
    spi_config.bit_order=NRF_SPIM_BIT_ORDER_LSB_FIRST; 
    //nrfx_spim_xfer_desc_t xfer_desc=NRFX_SPIM_XFER_TRX(m_tx_buf, sizeof(m_tx_buf), m_rx_buf, sizeof(m_tx_buf));
    	
    APP_ERROR_CHECK(nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL));
    
    	NRF_LOG_INFO("NRFX SPIM example started.");
    while (1)
    {
    // Reset rx buffer and transfer done flag
    memset(m_rx_buf, 0, m_length);
    spi_xfer_done = false;
    MAX30003_Reg_Read(INFO); //0x0F
    APP_ERROR_CHECK(nrfx_spim_xfer_dcx(&spi, &xfer_desc, 0, 15)); 
    
    while (!spi_xfer_done)
    {
    	
    __WFE();
    }
    NRF_LOG_FLUSH();
    bsp_board_led_invert(BSP_BOARD_LED_0);
    nrf_delay_ms(200);
    }
    }
    

    Expecting your kind help.

    Thanks,

    Rohit 

  • Your images have very low resolution. Can you please post full resolution images?

Reply Children
No Data
Related