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

nRFGo SDK nRF24LE1 SPI questions

Dear All,

Could some one help to answer my commented questions below ? thank you so much !

1.

//Definition at line 743 of file hal_nrf.c.

uint8_t hal_nrf_read_reg  ( uint8_t  reg )  

{
  uint8_t temp;

  CSN_LOW();

  HAL_NRF_HW_SPI_WRITE(reg);
  while(HAL_NRF_HW_SPI_BUSY) {}
  temp = HAL_NRF_HW_SPI_READ();     

  HAL_NRF_HW_SPI_WRITE(0U);         // Why this second SPI write operation is needed? what is the Parameter 0U means ? reg or command? or dummy ?
  while(HAL_NRF_HW_SPI_BUSY) {}     
  temp = HAL_NRF_HW_SPI_READ();     // Seems the temp above already got the value, why need this temp and returned ?  does this related to SPIRDAT have both two bytes deep?

  CSN_HIGH();

  return temp;
}

-------------------------------------------------------------------------
2.
//Definition at line 762 of file hal_nrf.c.
uint8_t hal_nrf_write_reg(uint8_t reg, uint8_t value)
{
uint8_t retval;
/*lint -esym(550,dummy) symbol not accessed*/
/*lint -esym(438,dummy) last assigned value not used*/
/*lint -esym(838,dummy) previously assigned value not used*/
uint8_t volatile dummy;

CSN_LOW();

HAL_NRF_HW_SPI_WRITE((W_REGISTER + reg));
while(HAL_NRF_HW_SPI_BUSY) {}
retval = HAL_NRF_HW_SPI_READ();

HAL_NRF_HW_SPI_WRITE(value);
while(HAL_NRF_HW_SPI_BUSY) {}
dummy = HAL_NRF_HW_SPI_READ();

CSN_HIGH();

return retval; // Why return retval rather than dummy ?
}

Best regards,
Kevin.
Parents
  • Hi,

    SPI read or write typically always is minimum 2bytes: First byte is the command byte that indicate the register address to access (read or write), second byte (or several bytes) contain the data (value) of that register.

    So to answer your questions:

    1. The first temp = HAL_NRF_HW_SPI_READ(); is basically a dummy read, but to save RAM the same variable 'temp' is updated two times (used as dummy first time, then actual value to read 'temp' the second time).

    2. When writing the first byte to indicate the register address to access, then the return dummy byte actually contains a STATUS register that can be used.

    As an example of SPI transfer see below sequence when read or write to the Radio (nRF24L01).

    Best regards,
    Kenneth

  • Hi Kenneth,

    Thank you very much for your answer !

    There are still few points haven't yet got the answer, would you please help ?

    HAL_NRF_HW_SPI_WRITE(0U);  //  what is the Parameter 0U means ? reg or command? or dummy ?

    Regarding the function hal_nrf_write_reg(uint8_t reg, uint8_t value), i'm still not quite understand the logic of SPI operations,

    like why the value shift in at last and return the retval rather than dummy? 

    HAL_NRF_HW_SPI_WRITE((W_REGISTER + reg));
    while(HAL_NRF_HW_SPI_BUSY) {}
    retval = HAL_NRF_HW_SPI_READ();

    HAL_NRF_HW_SPI_WRITE(value);
    while(HAL_NRF_HW_SPI_BUSY) {}
    dummy = HAL_NRF_HW_SPI_READ();

    Best Regards,
    Kevin.

  • Hi Kevin,

    I can't explain this to you, you will need to first understand how SPI works in general. Then once you understand how SPI works, then much of this is self explanatory.

    To create an SPI clock, you will need to write some data on the SPI, the data can be a command, a value, or dummy. SPI is always bidirectional, so for each byte written, there is one byte received. Whether you want to keep any or all of the values received depends on the command.

    Best regards,
    Kenneth

  • Hi Kenneth,

    Thank you so much for update!

    Actually i have some basic understanding of SPI protocol and the SPI time sequence, but just confused why nRFGo spi written like this.  in detail for example,

    The  SPI register READ function  hal_nrf_read_reg  ( uint8_t  reg ) 

    let's pass a real register address like  hal_nrf_read_reg  ( 0x07 )   [Register STATUS]

    hal_nrf_read_reg  ( STATUS ) 

    {
    uint8_t temp;

    CSN_LOW();

    HAL_NRF_HW_SPI_WRITE(STATUS);
    while(HAL_NRF_HW_SPI_BUSY) {}
    temp = HAL_NRF_HW_SPI_READ();        //  we can get the STATUS result here

    HAL_NRF_HW_SPI_WRITE(0U);             //    why we still need this one ? what does 0U means?
    while(HAL_NRF_HW_SPI_BUSY) {}
    temp = HAL_NRF_HW_SPI_READ();        //    during the second section's execution, maybe there is other 

    interrupts have happened, but we still return the second temp , is that still accurate ?

    CSN_HIGH();

    return temp;
    }

    Best Regards,
    Kevin.

  • You will need to call 'input' = HAL_NRF_HW_SPI_WRITE('output') every time you want to clock the next 8bit on the SPI interface, at the same time you then transmit 'output' and receive 'input'. If the output or input is don't care, you use can use any value (e.g. 0 or dummy value).

    Best regards,
    Kenneth

Reply Children
  • Hi Kenneth, 

    Thanks a lot for your answers !

    i updated comments according my understanding, please correct me if anything wrong, thanks.

    1:
    uint8_t hal_nrf_read_reg ( uint8_t reg )

    {
    uint8_t temp;

    CSN_LOW();

    HAL_NRF_HW_SPI_WRITE(reg);           // SPIRDAT = reg;
    while(HAL_NRF_HW_SPI_BUSY) {}
    temp = HAL_NRF_HW_SPI_READ();     // temp is the value of STATUS

    HAL_NRF_HW_SPI_WRITE(0U);           // Here write a extra dummy value in order to get the output from above command.
    while(HAL_NRF_HW_SPI_BUSY) {}
    temp = HAL_NRF_HW_SPI_READ();      // Here this temp stored the real reg value.
    CSN_HIGH();

    return temp;
    }


    2:
    uint8_t hal_nrf_write_reg(uint8_t reg, uint8_t value)
    {
    uint8_t retval;

    uint8_t volatile dummy;

    CSN_LOW();

    HAL_NRF_HW_SPI_WRITE((W_REGISTER + reg));          // SPIRDAT = W_REGISTER + reg;
    while(HAL_NRF_HW_SPI_BUSY) {}
    retval = HAL_NRF_HW_SPI_READ();                             // retval is the value of STATUS

    HAL_NRF_HW_SPI_WRITE(value);                                 // SPIRDAT = value;
    while(HAL_NRF_HW_SPI_BUSY) {}
    dummy = HAL_NRF_HW_SPI_READ();                            // dummy is not useful, because our value already wrote in. one of this extra READ Operation's purpose i think maybe for clearing up the SPIRDAT

    CSN_HIGH();

    return retval;
    }

  • I agree with your comments.

    Best regards,
    Kenneth

Related