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

Cannot get 400 kbps TWI_SW frequancy with clock stretching

Hi Nordic developers,

I'm using TWI software driver provided by NORDIC. I need to have 400 kbps frequancy. I have seted TWI_DELAY() to 0 and TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE to 1000. (for clock stretching)

Just checking with osciloscope SCL clock period is 3us instead of 2.5us.

When I set the TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE to 0 I'm getting exactly 2.5 us.

How can I get 2.5 us SCL clock cycle with clock stretching?

I'd be really glad, if someone can help me.

Thanks in advance,

Gor

  • Hi

    Whenever you set TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE to a non-zero value you will have an if-statement in twi_master_wait_while_scl_low(). This if-statement decrements timeout_counter and compares it to zero. These few instructions take time and are the cause of your additional 0.5us. Hence, you cannot reach 400kHz with timeout enabled.

    But may I ask why you use the software driver and not the hardware driver?

    EDIT: Example twi-nack-after-address.zip

  • Hi, Thanks a lot for your answer.

    I cannot use the hardware driver, because after sending a device address I need to get an acknowledgment. But in this case I get a TXDSENT event only after sending first databyte.

    If there is a way to check, whether device address is correct and the acknowledgment is successfuly recieved I'd very happy to use hardware driver.

  • Hi,

    I've modified a little bit the twi_sw_master.c driver and was able to reach 400kHz with timeout enabled. Instead of using twi_master_wait_while_scl_low() function I'm using the twi_master_wait_while_scl_low() macro shown bellow.

     #define twi_master_wait_while_scl_low()	do{                                             \
        TWI_SCL_HIGH();	                                                                        \
        while(TWI_SCL_READ() == 0 && timeout_counter != TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE)	\
        {								\
            timeout_counter++;		    \
        }						        \
        } while(0)
    

    And in every function were this macro is used I've added

     #if TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE != 0
        uint32_t volatile timeout_counter = 0;
     #endif
    

    Just check with the Oscilloscope I'm getting 2.4us SCL cycle. Please correct me if I'm doing something wrong.

  • You can set up a TWI interrupt handler. In the handler you can listen for TWI errors, e.g. the NACK after address event. I have attached an example in the answer above. It scans all possible TWI addresses and toggles a pin on every address NACK. If it finds a device on a specific address and an ACK is returned you will see that the pin does not toggle. The example use the TWI drivers found in SDK 9.

Related