Add timer via ADS1298_STATS flag

This commit is contained in:
Musa Mahmood 2025-04-13 20:46:59 -04:00
parent e7e4053f60
commit 3688db710a
4 changed files with 80 additions and 39 deletions

View File

@ -76,10 +76,11 @@ void ads1298_initialize(ads1298_info_t *p_info) {
spi_config.miso_pin = ADS1298_MISO_PIN;
spi_config.mosi_pin = ADS1298_MOSI_PIN;
spi_config.sck_pin = ADS1298_SCK_PIN;
spi_config.frequency = NRF_DRV_SPI_FREQ_500K;
//spi_config.frequency = NRF_DRV_SPI_FREQ_1M;
//spi_config.frequency = NRF_DRV_SPI_FREQ_125K;
//spi_config.frequency = NRF_DRV_SPI_FREQ_500K;
spi_config.frequency = NRF_DRV_SPI_FREQ_1M;
//spi_config.frequency = NRF_DRV_SPI_FREQ_2M;
spi_config.irq_priority = APP_IRQ_PRIORITY_HIGHEST;
//spi_config.irq_priority = APP_IRQ_PRIORITY_HIGHEST;
spi_config.mode = NRF_DRV_SPI_MODE_1;
spi_config.orc = 0x55;

View File

@ -65,19 +65,18 @@
#define ADS129x_8CH_BITMASK 0x02 // 0x[...]10[010]
/** DEFAULT REGISTER VALUES **/
//#define ADS1298_REGDEFAULT_CONFIG1 0x05 // Low power mode, Daisy-chain mode, clk output disabled, LP: 250 SPS
#define ADS1298_REGDEFAULT_CONFIG1 0x46 // Low power mode, Multiple readback mode, clk output disabled, LP: 250 SPS
#define ADS1298_REGDEFAULT_CONFIG1 0xC6 // High-res mode, Multiple readback mode, clk output disabled, LP: 250 SPS
#define ADS1298_REGDEFAULT_CONFIG2 0x00 // Test signals
#define ADS1298_REGDEFAULT_CONFIG3 0xCC //
#define ADS1298_REGDEFAULT_CONFIG3 0xCE //
#define ADS1298_REGDEFAULT_LOFF 0x00
#define ADS1298_REGDEFAULT_CH1SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH2SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH3SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH4SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH5SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH6SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH7SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH8SET 0x01 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH1SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH2SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH3SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH4SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH5SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH6SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH7SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_CH8SET 0x81 // Input Short (for startup)
#define ADS1298_REGDEFAULT_RLD_SENSP 0x00
#define ADS1298_REGDEFAULT_RLD_SENSN 0x00
#define ADS1298_REGDEFAULT_LOFF_SENSP 0x00
@ -110,7 +109,10 @@ typedef struct {
char usb_buffer[USBD_MAX_SIZE];
uint8_t usb_buffer_count;
uint8_t usb_buffer_size_max;
#if ADS1298_STATS
uint32_t drdy_trigger_count;
uint32_t seconds_elapsed;
#endif
} ads1298_info_t;
/** FUNCTION PROTOTYPES **/

85
main.c
View File

@ -86,6 +86,7 @@ void reset_counters(void) {
reset_buffer_count(m_info.usb_buffer);
// #TODO: Clear stats:
m_info.drdy_trigger_count = 0;
m_info.seconds_elapsed = 0;
// #TODO: elapsed time Milliseconds (need last second timer).
#endif
}
@ -115,11 +116,14 @@ void write_ic_settings(uint8_t* new_packet) {
case TN_IC_ADS1298: {
// #TODO: &new_packet[1]
#if ADS1298
ads1298_stop_rdatac();
NRF_LOG_INFO("Writing new ADS1298 registers:");
NRF_LOG_HEXDUMP_INFO(&new_packet[1], ADS1298_REGISTER_COUNT);
memcpy(m_info.registers, &new_packet[1], ADS1298_REGISTER_COUNT);
ads1298_update_registers(&m_info);
ads1298_set_data_buffer_length(&m_info);
ads1298_start_rdatac();
ads1298_standby();
// #TODO: readback registers into m_info.registers to confirm correct write.
#endif
} break;
@ -132,9 +136,9 @@ void read_ic_settings(uint8_t* new_packet) {
switch (SECOND_NIBBLE(new_packet[0])) {
case TN_IC_ADS1298: {
// #NOTE: you will not be able to read registers while in RDATAC mode.
ads1298_stop_rdatac();
// ads1298_check_id(&m_info);
// ads1298_check_id(&m_info);
ads1298_stop_rdatac();
// read all registers into m_info.registers
ads1298_readback_registers(&m_info);
// Send back over USB.
@ -172,6 +176,7 @@ static void process_new_packet(uint8_t* new_packet) {
NRF_LOG_INFO("[ADS129x] Active channels: 0x%X", m_info.active_chs);
}
#endif
reset_counters();
}
if (SECOND_NIBBLE(new_packet[0]) == TN_STREAM_STOP) {
recording_mode = RECORDING_MODE_DISABLED;
@ -236,18 +241,6 @@ static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
process_new_packet(usb_read_buffer);
// if (usb_read_buffer[0] == 0xBE) {
// }
// if (usb_read_buffer[0] == 0xEF) {
// run_throughput_test = true;
// }
// if (usb_read_buffer[0] == 0xE1) {
// run_throughput_test = false;
// }
// NRF_LOG_INFO("Received packet; first byte: 0x%X", new_packet[0]);
/* Fetch data until internal buffer is empty */
ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, usb_read_buffer, READ_SIZE);
} while (ret == NRF_SUCCESS);
@ -291,15 +284,12 @@ static void usbd_user_ev_handler(app_usbd_event_type_t event) {
}
}
void idle_state_handle(void) {
}
#if ADS1298
void drdy_pin_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
UNUSED_PARAMETER(pin);
UNUSED_PARAMETER(action);
drdy_flag = true;
m_info.drdy_trigger_count += 1;
}
void ads1298_interrupt_setup(void) {
@ -323,6 +313,38 @@ void ads1298_interrupt_setup(void) {
}
#endif
#if ADS1298_STATS
APP_TIMER_DEF(ads_timer_id);
#define APP_TIMER_INTERVAL APP_TIMER_TICKS(1000) // 1 second.
static volatile bool ads_timer_timeout = false;
static void ads_timer_timeout_handler(void* p_context) {
UNUSED_PARAMETER(p_context);
ads_timer_timeout = true;
m_info.seconds_elapsed += 1;
}
#endif
static void application_timers_start(void) {
#if ADS1298_STATS
ret_code_t err_code;
err_code = app_timer_start(ads_timer_id, APP_TIMER_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
#endif
}
static void timers_init(void) {
ret_code_t ret = app_timer_init();
APP_ERROR_CHECK(ret);
#if ADS1298_STATS
ret_code_t err_code =
app_timer_create(&ads_timer_id, APP_TIMER_MODE_REPEATED, ads_timer_timeout_handler);
APP_ERROR_CHECK(err_code);
#endif
}
int main(void) {
ret_code_t ret;
static const app_usbd_config_t usbd_config = {
@ -342,8 +364,7 @@ int main(void) {
// Wait for LFCLK to init.
while(!nrf_drv_clock_lfclk_is_running()) { }
ret = app_timer_init();
APP_ERROR_CHECK(ret);
timers_init();
app_usbd_serial_num_generate();
@ -368,6 +389,7 @@ int main(void) {
// Init peripherals:
#if ADS1298
ads1298_interrupt_setup();
nrf_delay_ms(200);
ads1298_initialize(&m_info);
#endif
@ -375,15 +397,26 @@ int main(void) {
reset_counters();
// #TEMP: application_timers_start
application_timers_start();
while (true) {
while (app_usbd_event_queue_process()) { /* Nothing to do */ }
if (recording_mode == RECORDING_MODE_ALL) {
// if (recording_mode & drdy_flag) { // may be faster if we're just using ADS1298
if (drdy_flag) {
#if ADS1298
// #TODO: Count samples
// #Maybe this should select based on the number of *active* channels?
if (drdy_flag) {
drdy_flag = false;
#if ADS1298_STATS
if (ads_timer_timeout) {
ads_timer_timeout = false;
//NRF_LOG_INFO("[ADS1298] Collected %lu samples in %d seconds", m_info.drdy_trigger_count, m_info.seconds_elapsed);
NRF_LOG_INFO("[ADS1298] DR: %lu", m_info.drdy_trigger_count / m_info.seconds_elapsed);
}
#endif
switch (m_info.nChs) {
case 4:
ads1294_get_data(&m_info);
@ -400,11 +433,13 @@ int main(void) {
if (m_info.usb_buffer_count >= m_info.usb_buffer_size_max) {
m_info.usb_buffer_count = ADS1298_PACKET_OFFSET;
app_usbd_cdc_acm_write(&m_app_cdc_acm, m_info.usb_buffer, NRF_DRV_USBD_EPSIZE);
app_usbd_cdc_acm_write(&m_app_cdc_acm, m_info.usb_buffer, m_info.usb_buffer_size_max);
increment_packet(m_info.usb_buffer);
// NRF_LOG_INFO("Current time tick: %lu", app_timer_cnt_get());
}
#endif
}
#endif
}
if (run_throughput_test) {

View File

@ -3,6 +3,9 @@
#define NRF52840_BREAKOUT_BOARD 1
#define ADS1298 1
#if ADS1298
#define ADS1298_STATS 1
#endif
// Testing with nRF52840:
#if NRF52840_BREAKOUT_BOARD