SPI and I2C communication in background
Posted: Wed Aug 23, 2023 1:34 pm
Hello,
I would like to know more about SPI and I2C peripherals design.
Are they capable to work simultaneously in background?
In the project I collect samples from 2 devices:
1. ADC (AD7124-4) connected via SPI
2. Accelerometer (ADXL345) connected via I2C
Samples will be processed by FFT later, so there mustn't be any sample misses.
I've pinned all tasks to CPU0 and only two tasks are pinned to CPU1 (ADC task and Acc task).
Lets call ADC task a "Task A" and Acc. task a "Task B".
For now I focus to optimize Task A, so the Task B is suspended and the only task running on CPU1 should be Task A.
And yet, when I measure time delay between receiving interrupt from ADC, and finished reading of sample, it is typically 170 us (which is OK), but sometimes it is up to 4000 us (4 ms), which means that we've already missed at least 4 samples (sampling frequency is 1200 Hz).
So it seems something else is running on CPU1 besides Task A.
This longer delay usually happens after printing task stats to console (vTaskList). But that print is called from app_main(), which should be pinned to CPU0, at least it is set so in sdkconfig.
How I can check which tasks are actually running (pinned or unpinned) on particular core?
Does SPI and UART peripheral share some resources? (spi_device_transmit() takes longer when something is printed to console)
Is it safe to call "spi_device_queue_trans()" in ISR handler?
And regarding I2C I would like to know, if the transaction is blocking CPU or not. Since the Task B is going to spend 99% of time on I2C communication, will be the CPU able to switch to Task A while Task B is waiting for next bit or byte?
Is I2C peripheral able to handle transaction in the background after setting up the "link", or it needs CPU's attention for each bit?
I would like to know more about SPI and I2C peripherals design.
Are they capable to work simultaneously in background?
In the project I collect samples from 2 devices:
1. ADC (AD7124-4) connected via SPI
2. Accelerometer (ADXL345) connected via I2C
Samples will be processed by FFT later, so there mustn't be any sample misses.
I've pinned all tasks to CPU0 and only two tasks are pinned to CPU1 (ADC task and Acc task).
Lets call ADC task a "Task A" and Acc. task a "Task B".
For now I focus to optimize Task A, so the Task B is suspended and the only task running on CPU1 should be Task A.
And yet, when I measure time delay between receiving interrupt from ADC, and finished reading of sample, it is typically 170 us (which is OK), but sometimes it is up to 4000 us (4 ms), which means that we've already missed at least 4 samples (sampling frequency is 1200 Hz).
So it seems something else is running on CPU1 besides Task A.
This longer delay usually happens after printing task stats to console (vTaskList). But that print is called from app_main(), which should be pinned to CPU0, at least it is set so in sdkconfig.
How I can check which tasks are actually running (pinned or unpinned) on particular core?
Does SPI and UART peripheral share some resources? (spi_device_transmit() takes longer when something is printed to console)
Is it safe to call "spi_device_queue_trans()" in ISR handler?
And regarding I2C I would like to know, if the transaction is blocking CPU or not. Since the Task B is going to spend 99% of time on I2C communication, will be the CPU able to switch to Task A while Task B is waiting for next bit or byte?
Is I2C peripheral able to handle transaction in the background after setting up the "link", or it needs CPU's attention for each bit?