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

TWI starting

Hello guys I tried to start TWI bus and got a lot of questions. (NRF51 1422 AC)

I added necessary libraries, could You tell me what more i need to include in my code :

    #define TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER (0U)
#define TWI_MASTER_CONFIG_DATA_PIN_NUMBER (2U)
//
static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(0);
static nrf_drv_twi_config_t nrf_drv_twi_config =
{	.scl = TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER,
	.sda = TWI_MASTER_CONFIG_DATA_PIN_NUMBER,
	.frequency = NRF_TWI_FREQ_100K,
	.interrupt_priority = 0};

 void nrf_drv_twi_initialize(void){
	 
 nrf_drv_twi_init(&m_twi, &nrf_drv_twi_config, 0, NULL);
	nrf_drv_twi_enable(&m_twi);
	 
 }
 
 void nrf_drv_twi_uninitialize(void){
	 
	nrf_drv_twi_uninit(&m_twi);
	nrf_drv_twi_disable(&m_twi);
	 
 } 

and

nrf_drv_twi_tx(&m_twi,(0x49<<1),&read_adress,1,true);

nrf_drv_twi_rx(&m_twi,(0x49<<1),&value1, 1);

But is not working for me. Could u answer me too, operation (0x49<<1) with sensor adress is necessary with our example ?

  • Hi

    The left shifting of the address is always a source of confusion (and of good reasons). The thing is that the TWI operates with 7-bit addresses, but whenever you perform a TX or RX the address is left shifted once. This is usually done for you by hardware (or the driver). Then the Least Significant Bit (LSB) is set to either '0' or '1' to indicate whether you want to do a RX or a TX operation respectively.

    So in binary, address 0x49 equals: 1001001b

    • During a RX operation the address + LSB exposed on the TWI lines will be 10010010b
    • During a TX operation the address + LSB exposed on the TWI lines will be 10010011b

    Since the LSB of 0x49 is a '1' I think it is safe to assume that the address you use is a 7-bit address.

    Now to the confusing part; The datasheets of TWI devices haven't really decided on how to define the device address. Some manufacturers define the address as a 7-bit value meant to be left shifted before setting LSB to '0' or '1'. Others define the address as an 8-bit value where you are not meant to do any left shifting, but only set the LSB to '0' or '1'. In addition to this, TWI drivers might not always clarify whether it wants a 7 or 8-bit address, with or without the read/write bit already set.

    I looks like you use SDK 11(?) though, so the transfer functions want a 7-bit address, e.g. 0x49.

    From the brief of nrf_drv_twi_tx():

     * @param[in] address    Address of a specific slave device **(only 7 LSB).**
    

    Other than that your code looks fine, but it seems like you have initiated your TWI driver in blocking mode, as you have not passed a TWI event handler to nrf_drv_twi_init(). This means that your code will stay in nrf_drv_twi_xx() forever if something goes wrong (e.g. if you use the wrong address).

    Finally I would suggest that you try to debug your code like this. It might give you a clue of what the TWI driver is up to.

  • Thank You very much for answer ! I know Keil IDE, debugger is primary tool for me. Anyway, could You explain me three more questions ?

    1st : While I'm sure with my code, using event hander in trasmission is necessary ?

    2nd : I know first frame of transmission is :

    (Adr)(Adr)(Adr)(Adr)(Adr)(Adr)(Adr)(R/W) where Adr are bytes of device adress

    In sdk is written :

    * @param[in] address    Address of a specific slave device **(only 7 LSB).**
    

    How to understand it ?

    In datasheet i have adress like 00110101x where last bit is not important.

    But input param need 7 LSB with adress then if I impart paramter with adress i must make it like this :

    x00110101
    

    Where x is R/W bit ? In Twi_sensor example we have

    #define MMA7660_ADDR        (0x98U >> 1)
    

    What is compatible with my idea.

    3rd : I checked lines using a oscilloscope, they looks good. I tried example from this topic : devzone.nordicsemi.com/.../

    Is this solution correct ?

    1. If you use an event handler you are able to see what errors might occur and respond to these. If you don't use an error handler and something goes wrong on your TWI bus you will end up in an endless loop. Your application will not work and you have no way of figuring out what is wrong.

    2. If the address is given as 00110101x in the datasheet then I would assume that your device address is actually 00110101 (0x35). The x represents the R/W bit and is not really a part of the address. So in this case you should pass 0x35 as the address to nrf_drv_twi_tx(). Here is some example code that you can use to find your device's address and debug your application.

    EDIT: Forgot to link to the examples.

Related