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:
-
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.
-
If I keep the sample timer interval above 67 msec,the TWI functions but has some strange behavior, see attached images:
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 ):
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