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

Interfacing a Sensor Hub with TWI drivers?

Hi,

I am trying to adapt the read register function that use the TwoWire lib of Arduino in order to read a Sensor Hub Response Byte of a defined Host Command :

uint8_t readByte(uint8_t _familyByte, uint8_t _indexByte,\
                                           uint8_t _writeByte)
{

    uint8_t returnByte;
    uint8_t statusByte;

    _i2cPort->beginTransmission(_address);
    _i2cPort->write(_familyByte);
    _i2cPort->write(_indexByte);
    _i2cPort->write(_writeByte);
    _i2cPort->endTransmission();
    delay(CMD_DELAY);

    _i2cPort->requestFrom(_address, sizeof(returnByte) + sizeof(statusByte));
    statusByte = _i2cPort->read();
    if (statusByte)// SUCCESS (0x00)
        return statusByte; // Return the error, see: READ_STATUS_BYTE_VALUE 

    returnByte = _i2cPort->read();
    return returnByte; // If good then return the actual byte. 

}

to have a function that uses the nrf_dr_twi, like this: 

uint32_t nrf_drv_read_registers(uint8_t reg, uint8_t* p_data, uint32_t length)
{
    uint32_t err_code;
    uint32_t timeout = OXI_TWI_TIMEOUT;

    err_code = nrf_drv_twi_tx(&m_twi_instance, OXI_ADDRESS, &reg, 1, false);
    if (err_code != NRF_SUCCESS) return err_code;

    while ((!twi_tx_done) && --timeout) ;
    if (!timeout) return NRF_ERROR_TIMEOUT;
    twi_tx_done = false;

    err_code = nrf_drv_twi_rx(&m_twi_instance, OXI_ADDRESS, p_data, length);
    if (err_code != NRF_SUCCESS) return err_code;

    timeout = OXI_TWI_TIMEOUT;
    while ((!twi_rx_done) && --timeout) ;
    if (!timeout) return NRF_ERROR_TIMEOUT;
    twi_rx_done = false;

    return err_code;
}

Have you some ideas on how i can use the family and index byte of the Sensor Hub in order to retrieve the correct byte? 

Thank you very much in advance,

Kind regards

Parents
  • Hello Polimarte,

    Have you some ideas on how i can use the family and index byte of the Sensor Hub in order to retrieve the correct byte? 

    It is as @awneil says - we do not support Arduino, unfortunately.
    However, as awneil mentions, I would recommend reading the Sensor Hubs documentation, to figure out how to implement the interface.
    It will be easier for you to see what the Sensor Hub is expecting to receive from its datasheet, rather than reading it and translating it directly from an Arduino implementation.

    Best regards,
    Karl

  • Hi i'am sorry to have given a very vague question. I have understood a bit more, now i can describe well my problem, maybe.

    The read and write action on my sensor hub are described as:

    and i want to use the nrf_drv_tx and rx in order to implement these actions.

    If i have the function 

    ret_code_t nrf_drv_twi_tx	(	nrf_drv_twi_t const * 	p_instance,
            uint8_t 	address,
            uint8_t const * 	p_data,
            uint8_t 	length,
            bool 	no_stop 
    )

    where

    [in] p_instance Pointer to the driver instance structure.
    [in] address Address of a specific slave device (only 7 LSB).
    [in] p_data Pointer to a transmit buffer.
    [in] length Number of bytes to send.
    [in] no_stop If set, the stop condition is not generated on the bus after the transfer has completed successfully (allowing for a repeated start in the next transfer).

    If i need to transmit a series if byte as for example only the Family and Index Byte in order to write,  would i need a buffer (p_data) as an array of dimension 2, able to store these two bytes? 

    and so for the reception if i want to retrieve the Status and the Response byte would i need another buffer with same dimension?

    Hope to hear you again and thanks for help me!

    polimarte

  • Hi awneil thanks for the hint!

    Unfortunately I will have to use ANT modules in a following part of my project, but i have some source code that can be very helpful to me when i ll arrive at that point. I have little experience with ATMega and STmicrocontoller but you are right this SoC's are not easy at all. Thanks to the excellent Nordic costumer service I am sure i ll made it. 

    polimarte

  • Hi Karl!

    I followed your hints and i modified my code, hope to present a better solution now. What i wanted to do is to modify the read and write function for Arduino, that use the library Wire.h to implement the transactions TXRX. The read function of the Arduino code is in my original question. The write function is implemented in this way: 

    uint8_t SparkFun_Bio_Sensor_Hub::writeByte(uint8_t _familyByte,uint8_t _indexByte,uint8_t _writeByte)
    {
    
      _i2cPort->beginTransmission(_address);     
      _i2cPort->write(_familyByte);    
      _i2cPort->write(_indexByte);    
      _i2cPort->write(_writeByte); 
      _i2cPort->endTransmission(); 
      delay(CMD_DELAY); 
    
      // Status Byte, success or no? 0x00 is a successful transmit
      _i2cPort->requestFrom(_address, static_cast<uint8_t>(1)); 
      uint8_t statusByte = _i2cPort->read(); 
      return statusByte; 
    
    }

    and i have used the NRFX_TWIM_XFER_DESC_TXRX in this way for Read:

    uint8_t readByte_WB(uint8_t familyByte, uint8_t indexByte, uint8_t writeByte)
    {
    
    		nrfx_err_t err_code
    		uint8_t StatusByte;    
            uint8_t ReturnByte;
       
            uint8_t rx_buffer[2];
    		size_t rx_lenght =2;
    
    		uint8_t tx_buffer[] = {familyByte, indexByte, writeByte};    
    		size_t tx_lenght = sizeof(familyByte) + sizeof(indexByte) + sizeof(writeByte);
    
    		nrfx_twim_xfer_desc_t transferType = NRFX_TWIM_XFER_DESC_TXRX(address, tx_buffer, tx_lenght, rx_buffer,rx_lenght);
    		err_code = nrfx_twim_xfer(&twim_instance, &transferType, 0);
    		NRF_LOG_INFO("Xfer error code: %s \n", errorcode_printer(err_code));
    
        
    		StatusByte = int(rx_buffer[0]);
            NRF_LOG_INFO("Status Byte: %lu \n",StatusByte); //0x00 for SUCCESS
        
    		ReturnByte = rx_buffer[1];  
    		return ReturnByte;
    }

    and for write: 

    uint8_t writeByte( uint8_t familyByte, uint8_t indexByte, uint8_t writeByte)
    {
    
    		nrfx_err_t err_code
    		
    		uint8_t StatusByte;    
        
    		uint8_t rx_buffer[1];
    		size_t rx_lenght =1;
    
    		uint8_t tx_buffer[] = {familyByte, indexByte, writeByte};    
    		size_t tx_lenght = sizeof(familyByte) + sizeof(indexByte) + sizeof(writeByte);
    
    		nrfx_twim_xfer_desc_t transferType = NRFX_TWIM_XFER_DESC_TXRX(address, tx_buffer, tx_lenght, rx_buffer,rx_lenght);
    		err_code = nrfx_twim_xfer(&twim_instance, &transferType, 0);
    		NRF_LOG_INFO("Xfer error code: %s \n", errorcode_printer(err_code));
    
    		StatusByte = rx_buffer[0];
            
            return StatusByte;
    
    }

    I understand that formally it would be more correct use pointers in order to retrieve the bytes with buffers but i need a non void return function for my adaptation to the original code. I use the StatusByte only to check the SUCCESS the TXRX and eventually i return the unsigned integer whose Byte length is predetermined (the bytes that follow the StatusByte). This Write function only write Family, Index and Write Byte, checking the StatusByte. The Read function in this case is used only to retrieve the first byte after the StatusByte which value luckly will be 0x00 (SUCCESS Transmission). I made other similar functions (following the method of the Arduino Code) in case of the need to retrieve different byte lengths (uint16_t,uint32_t..) or to fill arrays passed as input.

    It is the right way for the implementation or i am missing something?

    Thanks to help me again!

    polimarte

  • Hello Polimarte,

    Sorry for my late reply, I was out of office for some days.

    polimarte said:
    Thanks to the excellent Nordic costumer service I am sure i ll made it.

    I am happy to hear you say that, thank you!

    polimarte said:
    I followed your hints and i modified my code, hope to present a better solution now. What i wanted to do is to modify the read and write function for Arduino, that use the library Wire.h to implement the transactions TXRX. The read function of the Arduino code is in my original question. The write function is implemented in this way:

    I am glad to see the changes you have made to your functions, they are huge improvements!

    I will include some comments below:

    You are absolutely on the right track here, this looks a lot better!

    polimarte said:
    I understand that formally it would be more correct use pointers in order to retrieve the bytes with buffers but i need a non void return function for my adaptation to the original code.

    I understand, and I see that you function still returns the StatusByte instead of the err_code. I assume this is done for compatibility with other ported functions from the Arduino Library.
    However, I would suggest that you include an APP_ERROR_CHECK on the err_code returned from nrfx_twim_xfer, to catch any errors being generated.

    I also notice your use of magic numbers for the size/length of rx_buffer - I would advise against doing this for any piece of code. Preferably, if you have a static array length that your twim transactions always will return, then it is preferable that you create a define for this, for increased readability.

    Other than that, this use of the nrfx_twim driver seems fine!

    However, I am not sure that this will behave as expected, since when you are using the TXRX transfer description there is no STOP condition generated in between the TX and RX - this is not as shown in the illustration you posted earlier. From the illustration, it seems very much like you will need a stop condition before doing the next operation.
    So, you might have to do this in separate transfers after all ( first completing a TX of length three, then completing a RX of length two )  - Sorry that I did not catch this when I recommended you the TXRX description, my mistake.

    polimarte said:
    It is the right way for the implementation or i am missing something?

    Your usage of the nrfx_twim driver seems to be implemented correctly now.
    What are you seeing when you run this code - are you getting any errors, or unexpected behavior?

    polimarte said:
    I made other similar functions (following the method of the Arduino Code) in case of the need to retrieve different byte lengths (uint16_t,uint32_t..) or to fill arrays passed as input.

    Make sure to give these functions clear and descriptive names, to differentiate them from each other.

    Best regards,
    Karl

  • Hi my dear Karl! 

    Thanks for helping me again!

    However, I am not sure that this will behave as expected, since when you are using the TXRX transfer description there is no STOP condition generated in between the TX and RX - this is not as shown in the illustration you posted earlier.

    I used the TX and RX transfers separately in this way:

    uint8_t readByte_WB(uint8_t familyByte, uint8_t indexByte, uint8_t writeByte)
    {
    
    		nrfx_err_t err_code;
    		uint8_t StatusByte;    
            uint8_t ReturnByte;
       
            uint8_t rx_buffer[2];
    		size_t rx_lenght =2;
    
    		uint8_t tx_buffer[] = {familyByte, indexByte, writeByte};    
    		size_t tx_lenght = sizeof(familyByte) + sizeof(indexByte) + sizeof(writeByte);
    
    		nrfx_twim_xfer_desc_t tx_xfer = NRFX_TWIM_XFER_DESC_TX(address, tx_buffer, tx_lenght);
    		err_code = nrfx_twim_xfer(&twim_instance, &tx_xfer, 0);
    		APP_ERROR_CHECK(err_code);
    		
    		nrfx_twim_xfer_desc_t rx_xfer = NRFX_TWIM_XFER_DESC_RX(address, rx_buffer, rx_lenght);
    		err_code = nrfx_twim_xfer(&twim_instance, &rx_xfer, 0);
    		APP_ERROR_CHECK(err_code);
        
    		StatusByte = rx_buffer[0];
            NRF_LOG_INFO("Status Byte: %lu \n",StatusByte); //0x00 for SUCCESS
        
    		ReturnByte = rx_buffer[1];  
    		return ReturnByte;
    }

    Can be a good solution for the read function? the write one it ll be very similar following this logic.

    Unfortunately i am stack with other ( many) errors in a previous part of my code and i cannot verify the correctness of these functions, but i ll do that very soon and i ll let you know if there are some problems!

    I just want to know if the logic behind this is correct, than i ll debug this part of the code properly.

    if you have a static array length that your twim transactions always will return, then it is preferable that you create a define for this, for increased readability.

    I will do that, thanks for the advice!

    thanks, 

    polimarte

  • Hello Polimarte,

    polimarte said:
    Thanks for helping me again!

    It is no problem at all, Polimarte! I am happy to help, and glad to see that you appreciate and implement the advice and suggestions you get in the forum - it is great!

    polimarte said:
    Can be a good solution for the read function? the write one it ll be very similar following this logic.

    The logic / approach seems all right in this function, you might have to add a delay / wait in between the two xfer calls, as shown in your illustration. It will be easier to debug once you are able to compile and flash you program, and monitor how it behaves.

    polimarte said:
    Unfortunately i am stack with other ( many) errors in a previous part of my code and i cannot verify the correctness of these functions, but i ll do that very soon and i ll let you know if there are some problems!

    I am sorry to hear that you are experiencing some other issues, and I look forward to hearing if this works as intended when you have cleared out the other errors.

    Good luck with your debugging and development!

    Best regards,
    Karl

Reply
  • Hello Polimarte,

    polimarte said:
    Thanks for helping me again!

    It is no problem at all, Polimarte! I am happy to help, and glad to see that you appreciate and implement the advice and suggestions you get in the forum - it is great!

    polimarte said:
    Can be a good solution for the read function? the write one it ll be very similar following this logic.

    The logic / approach seems all right in this function, you might have to add a delay / wait in between the two xfer calls, as shown in your illustration. It will be easier to debug once you are able to compile and flash you program, and monitor how it behaves.

    polimarte said:
    Unfortunately i am stack with other ( many) errors in a previous part of my code and i cannot verify the correctness of these functions, but i ll do that very soon and i ll let you know if there are some problems!

    I am sorry to hear that you are experiencing some other issues, and I look forward to hearing if this works as intended when you have cleared out the other errors.

    Good luck with your debugging and development!

    Best regards,
    Karl

Children
No Data
Related