[WIP] Send data over USB, reset counters, readback all registers

This commit is contained in:
Musa Mahmood 2025-04-13 07:23:30 -04:00
parent 3428fa968f
commit e7e4053f60
4 changed files with 90 additions and 32 deletions

View File

@ -109,6 +109,9 @@ void ads1298_initialize(ads1298_info_t *p_info) {
#if ADS1298_LOG_DEBUG
NRF_LOG_FLUSH();
#endif
// Prepare packet header to ID as "ADS1298"
p_info->usb_buffer[0] = TN_IC_ADS1298;
}
void ads1298_uninitialize(void) {
@ -116,16 +119,34 @@ void ads1298_uninitialize(void) {
nrf_drv_spi_uninit(&spi0);
}
void ads1298_readback_registers(ads1298_info_t* p_info) {
// Copies into USB Buffer:
uint8_t registers_to_read = ADS1298_REGISTER_COUNT;
uint8_t tx_buf[ADS1298_REGISTER_COUNT + 2] = {0};
tx_buf[0] = ADS1298_OPC_RREG|ADS1298_REGADDR_ID;
tx_buf[1] = registers_to_read-1;
uint8_t rx_buf[ADS1298_REGISTER_COUNT + 2] = {0};
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, tx_buf, ADS1298_REGISTER_COUNT + 2, rx_buf, ADS1298_REGISTER_COUNT + 2));
while(!spi_xfer_done) { __WFE(); }
memcpy(p_info->registers, &rx_buf[2], ADS1298_REGISTER_COUNT);
NRF_LOG_INFO("Reading ADS1298 registers:");
NRF_LOG_HEXDUMP_INFO(&rx_buf[2], ADS1298_REGISTER_COUNT);
}
bool ads1298_check_id(ads1298_info_t *p_info) {
bool device_found = false;
#if ADS1298_LOG_DEBUG
NRF_LOG_INFO("Checking ADS129xR? ID:");
#endif
// Read two registers starting from ID register
uint8_t tx_buf[6] = {ADS1298_OPC_RREG|ADS1298_REGADDR_ID, 0x00, 0, 0, 0, 0};
uint8_t registers_to_read = 4;
// opcode1, registers to read minus 1
uint8_t tx_buf[6] = {ADS1298_OPC_RREG|ADS1298_REGADDR_ID, registers_to_read-1, 0, 0, 0, 0};
uint8_t rx_buf[6] = {0,0,0,0,0,0};
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, tx_buf, 3, rx_buf, 3));
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, tx_buf, 6, rx_buf, 6));
while(!spi_xfer_done) { __WFE(); }
uint8_t register_data = rx_buf[2];
memcpy(p_info->id_buffer, rx_buf, 6);
@ -220,8 +241,6 @@ static inline uint8_t ads1298_channel_count(ads1298_info_t *p_info) {
return popcount_table[p_info->active_chs];
}
// void ads1298_readback_registers
void ads1298_update_registers(ads1298_info_t *p_info) {
NRF_LOG_INFO("Updating ADS1298 registers...");
ads1298_update_active_chs(p_info);

View File

@ -7,7 +7,7 @@
#include "custom_board.h"
// Debug flag for logging:
#define ADS1298_LOG_DEBUG 1
#define ADS1298_LOG_DEBUG 0
// Number of WRITABLE registers (Not inc. ID register)
#define ADS1298_REGISTER_COUNT 25
@ -110,19 +110,22 @@ typedef struct {
char usb_buffer[USBD_MAX_SIZE];
uint8_t usb_buffer_count;
uint8_t usb_buffer_size_max;
uint32_t drdy_trigger_count;
} ads1298_info_t;
/** FUNCTION PROTOTYPES **/
void ads1298_initialize(ads1298_info_t *p_info);
void ads1298_initialize(ads1298_info_t* p_info);
void ads1298_uninitialize(void);
bool ads1298_check_id(ads1298_info_t *p_info);
bool ads1298_check_id(ads1298_info_t* p_info);
void ads1298_update_registers(ads1298_info_t *p_info);
void ads1298_update_registers(ads1298_info_t* p_info);
void ads1298_init_default_registers(void);
void ads1298_readback_registers(ads1298_info_t* p_info);
void ads1298_power_down(void);
void ads1298_power_up(void);

78
main.c
View File

@ -72,6 +72,23 @@ APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
CDC_ACM_DATA_EPOUT,
APP_USBD_CDC_COMM_PROTOCOL_AT_V250);
__STATIC_INLINE void reset_buffer_count(uint8_t *buffer_start) {
buffer_start[0] = 0;
}
__STATIC_INLINE void increment_packet(uint8_t *buffer_start) {
buffer_start[1] += 1;
}
void reset_counters(void) {
#if ADS1298
m_info.usb_buffer_count = ADS1298_PACKET_OFFSET;
reset_buffer_count(m_info.usb_buffer);
// #TODO: Clear stats:
m_info.drdy_trigger_count = 0;
// #TODO: elapsed time Milliseconds (need last second timer).
#endif
}
void usb_transmit_message_ex(uint8_t message_prefix, uint8_t message_part_two, uint8_t* message, uint8_t message_length) {
usb_tx_buffer[0] = message_prefix;
@ -103,6 +120,7 @@ void write_ic_settings(uint8_t* new_packet) {
memcpy(m_info.registers, &new_packet[1], ADS1298_REGISTER_COUNT);
ads1298_update_registers(&m_info);
ads1298_set_data_buffer_length(&m_info);
// #TODO: readback registers into m_info.registers to confirm correct write.
#endif
} break;
default:
@ -115,11 +133,18 @@ void read_ic_settings(uint8_t* new_packet) {
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);
usb_transmit_message_ex(ID_REGISTER_READBACK_PREFIX, REGISTER_READBACK_ADS1298,
m_info.id_buffer, sizeof(m_info.id_buffer));
// ads1298_check_id(&m_info);
// read all registers into m_info.registers
ads1298_readback_registers(&m_info);
// Send back over USB.
usb_transmit_message_ex(REGISTER_READBACK_PREFIX, REGISTER_READBACK_ADS1298,
m_info.registers, ADS1298_REGISTER_COUNT);
// This is totally unnecessary:
// usb_transmit_message_ex(ID_REGISTER_READBACK_PREFIX, REGISTER_READBACK_ADS1298,
// m_info.id_buffer, sizeof(m_info.id_buffer));
ads1298_start_rdatac();
ads1298_standby();
} break;
default:
break;
@ -156,6 +181,7 @@ static void process_new_packet(uint8_t* new_packet) {
ads1298_standby();
}
#endif
reset_counters();
}
if (SECOND_NIBBLE(new_packet[0]) == TN_STREAM_REQUEST_INFO) {
usb_transmit_message(CTRL_STAT_INFO_PERIPHERALS, g_Peripheral_Info, strlen(g_Peripheral_Info));
@ -234,6 +260,7 @@ static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
}
static void usbd_user_ev_handler(app_usbd_event_type_t event) {
// #TODO: should reset_counters() somewhere here?
switch (event) {
case APP_USBD_EVT_DRV_SUSPEND:
break;
@ -346,30 +373,39 @@ int main(void) {
memset(usb_tx_buffer, 0x41, NRF_DRV_USBD_EPSIZE); // #TEMP
reset_counters();
while (true) {
while (app_usbd_event_queue_process()) { /* Nothing to do */ }
/*
// I think this check is totally irrelevant?
if (recording_mode == RECORDING_MODE_ALL) {
// #TODO: Count samples
// if (recording_mode & drdy_flag) { // may be faster if we're just using ADS1298
if (drdy_flag) {
#if ADS1298
switch (m_info.nChs) {
case 4:
ads1294_get_data(&m_info);
break;
case 6:
ads1296_get_data(&m_info);
break;
case 8:
ads1298_get_data(&m_info);
break;
default:
break;
}
// #TODO: Count samples
// #Maybe this should select based on the number of *active* channels?
switch (m_info.nChs) {
case 4:
ads1294_get_data(&m_info);
break;
case 6:
ads1296_get_data(&m_info);
break;
case 8:
ads1298_get_data(&m_info);
break;
default:
break;
}
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);
increment_packet(m_info.usb_buffer);
}
#endif
// #TODO: if buffer full transfer via `app_usbd_cdc_acm_write`
}*/
}
}
if (run_throughput_test) {
/*ret = */app_usbd_cdc_acm_write(&m_app_cdc_acm, usb_tx_buffer, NRF_DRV_USBD_EPSIZE);

View File

@ -59,8 +59,8 @@
#endif // NRF52840_BREAKOUT_BOARD
enum recording_mode_t {
RECORDING_MODE_ALL,
RECORDING_MODE_DISABLED
RECORDING_MODE_DISABLED = 0,
RECORDING_MODE_ALL = 1
};