I use nordic5340 SPI read ADS1298R ecg data, using nrf5340 p0.13 to connect ADS1298R data ready pin . when ADS1298R data ready pin high to low mean ADS1298R data ready .i config GPIOE interrupt ,and in interrupt give a semophere to ecg thread to read data :
K_SEM_DEFINE(ADS129xdataRdy_sem, 0,10);
void ADS129XdataRdy(const struct device *dev, struct gpio_callback *cb,uint32_t pins)
{
LOG_INF("dataRdy at %" PRIu32 "\n", k_cycle_get_32());
k_sem_give(&ADS129xdataRdy_sem);
}
interrupt setting like below:
ADS129xDRDY_dev = device_get_binding("GPIO_0");
if (ADS129xDRDY_dev == NULL) {
LOG_INF("ads129xR data ready didn't find GPIO_0\n" );
return 1;
}
ret = gpio_pin_configure(ADS129xDRDY_dev, 13, GPIO_INPUT|GPIO_PULL_UP );
if (ret != 0) {
LOG_INF("Error %d: failed to configure GPIO_0 13 pin \n",ret);
return 1;
}
ret = gpio_pin_interrupt_configure(ADS129xDRDY_dev,13,GPIO_INT_EDGE_TO_INACTIVE );
if (ret != 0) {
LOG_INF("Error %d: failed to configure interrupt on GPIO_0 13 pin \n",ret );
return 1;
}
gpio_init_callback(&ADS129xDRDY_cb_data, ADS129XdataRdy, BIT(13));
gpio_add_callback(ADS129xDRDY_dev, &ADS129xDRDY_cb_data);
in ecg thread take the semophere and read data:
for (;;) {
if(k_sem_take(&ADS129xdataRdy_sem, K_MSEC(5))==0 )
{
ADS129x_Read_Data( ) ;
LOG_INF("read at %" PRIu32 "\n", k_cycle_get_32());
}
but every 4ms can enter interrupt,but need 30ms read a time data:
the debug log out information :always 4ms enter interupt a time ,but 30ms read data a time ,so most of ecg data are not read and lost.
time interval but each "dataRdy at "almost 131 ,every 32768 mean one second, so 131/32768=0.004s . but enter many time interrupt,in ecg thread take one time semophere and only read one time . "read at %" and "dataRdy at " log out not same step mean enter many times interrupt and read a few time data.
i want every semophere from interrupt ecg thread can take ,and ecg thread can read every interrupt data,so ECG data will not lost.
I try to place function ADS129x_Read_Data( ) directly in interrupt to improve read speed , but system reset . even make ADS129x_Read_Data( ) become interrupt cb ,,there is SPI tranceive function in ADS129x_Read_Data( ), system also reset . zephyr OS seem not can place function in interrupt .set SPI tranceive function (child function in ADS129x_Read_Data( ) )become static inline function also reset . zephyr os reset if place ADS129x_Read_Data( ) in interrupt or make ADS129x_Read_Data( ) become GPIOE interrupt cb.
I try to use k_sem_count_get (&ADS129xdataRdy_sem) in ecg thread, and use k_sem_take(&ADS129xdataRdy_sem) till k_sem_count_get (&ADS129xdataRdy_sem) ==0 ,but not effect.
try to make ecg thread priority higher than other thread to improve read speed .but i chang ecg thread priority high ,there is no effect.
is nrf5340 CPU slow? these project use nrf52840 can read data from every GPIOE interrupt .these project have only a few thread and not much work need CPU to deal with
I try to delete all other work in ecg thread only one work of take GPIOE semophere and ADS129x_Read_Data( ),this time can read fast ,but alway continuous enter interrupt sereral times and give several semoheres . while continuous take semohere and ADS129x_Read_Data( ) several time . give semophere and take semophere did not synchronize 。maybe is broken by other thread. not synchronize mean error data read . try to lock thread switch in interrupt and unlock thread switch after read data in loop of ecg thread .but system reset.
why a little code or function placed in a k_timer cb(2ms period) interrupt or placed in GPIOE interrupt can lead zephyr os reset? zephyr os reset in below shortcut imagine happen is i place function
ADS129x_Read_Data( ) in void timer_readInterruptHandler(struct k_timer *timer_id)