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

S210 & twi - timing / speed

Dear all,

I use nrf51422 with S210 soft device. I need to read an attached sensor via TWI. The sensor returns 32 bits of data. I need to read that 100 times a second. I defined a timer running off the low speed clock source ( which is needed for the soft device anyway) to trigger the sensor reads:

// APP_TIMER_INIT already done in main.c with prescaler value 0
APP_TIMER_DEF(LDC_Sample_timer);	    // define another timer for the LDC sampling frequency 
APP_ERROR_CHECK(app_timer_create(&LDC_Sample_timer,APP_TIMER_MODE_REPEATED,ldc_sample_handler));		// create the new timer
app_timer_start(LDC_Sample_timer(int)32768/10,NULL);			// 0.1 second

I then read the sensor in the timer ISR:

void ldc_sample_handler(void * p_context){
	UNUSED_PARAMETER(p_context);
	NRF_TWI1->POWER  = 1;
	NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
	ldc_read_all();
	NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
	NRF_TWI1->POWER  = 0;
}


void ldc_read_all(void){
	ldc_register_address = LDC_DATA_MSB_CH1;					// TODO : make this a parameter
  static app_twi_transfer_t const transfers[] =			// transfer definition
  {
    APP_TWI_WRITE(ldc_device_address, &ldc_register_address, 1, APP_TWI_NO_STOP),
    APP_TWI_READ (ldc_device_address, ldc_p_buffer, 4, 0)
  };
	static app_twi_transaction_t const transaction =
  {
     .callback            = ldc_twi_callback_func,
     .p_user_data         = NULL,
     .p_transfers         = transfers,
     .number_of_transfers = 2
  };
	APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &transaction));	// read the MSB
	ldc_register_address = ldc_register_address + 1;							// next register address for the LSB
	APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &transaction));	// read the LSB. We can modify the register address without creating a new instance as it is accessed by a pointer.
}

Now, what happens is this:

  1. Whenever I set the LDC_sample_timer to less than 32768/15, the ANT+ communication breaks down and it seems the NRF resets all the time.

  2. If I keep the sample timer interval above 67 msec,the TWI functions but has some strange behavior, see attached images:

TWI block1: write register address to TWI device

TWI block2: read 32 bytes from TWI device

The datasheet of the device states it can do 400kHz TWI and all the timings are easily fast enough to not cause this ( so, the TWI device does for sure not cause this behaviour by using clock stretching ):

datasheet of connected TWI device

As you can see in the code, I defined the entire 48 bit transaction as one "app_twi" transaction. But in fact the individual bytes show up on the bus with different delays in between them (the TWI clock pauses). Some of these delays are pretty big like the one after sending the first two bytes to the sensor. Strangely, there is zero delay between sending byte #3 ( device read command) and the first received byte from the slave, but all subsequent received bytes do have a delay.

So, I have these questions:

  • Is there any documentation showing TWI (or in general peripherals) timing restrictions if a soft device is running ? I found the "between 1 and 6 msec CPU blocking" for BLE softdevices, but nothing for S210/S310.
  • Why does the thing reset if I set my sample timer to be faster than approx 67 msec ? The M0 core should be way,way fast enough to do 100 TWI transfers per second.
  • What does influence the delays between the individual bytes of the multi-byte TWI transfer ? These delays are NOT related to TWI clock speed, they stay the same if I run the TWI with 400kHz..

Thanks, Wolfgang Ebersbach

Parents
  • I think you have answered most of your question in your comment. I will try to add some more details.

    The TWI transmitter and receiver are single buffered so the CPU has to do some work between every byte. As stated in Section 28.4 of the reference manual for write:

    If the CPU is prevented from writing to TXD when the TWI master is ready to clock out a byte, the TWI master will stretch the clock until the CPU has written a byte to the TXD register.

    and read:

    After receiving a byte, the TWI master will delay sending the ACK/NACK bit by stretching the clock until the CPU has extracted the received byte, that is, by reading the RXD register.

    Section 11.2 of the SoftDevice Specification describes the processor availability and latencies for the interrupts/priorities available to the application. This seems to match with the pauses you sometimes see in the TWI transfers.

Reply
  • I think you have answered most of your question in your comment. I will try to add some more details.

    The TWI transmitter and receiver are single buffered so the CPU has to do some work between every byte. As stated in Section 28.4 of the reference manual for write:

    If the CPU is prevented from writing to TXD when the TWI master is ready to clock out a byte, the TWI master will stretch the clock until the CPU has written a byte to the TXD register.

    and read:

    After receiving a byte, the TWI master will delay sending the ACK/NACK bit by stretching the clock until the CPU has extracted the received byte, that is, by reading the RXD register.

    Section 11.2 of the SoftDevice Specification describes the processor availability and latencies for the interrupts/priorities available to the application. This seems to match with the pauses you sometimes see in the TWI transfers.

Children
No Data
Related