diff --git a/ads1298.c b/ads1298.c index cd0037a..c3ce6bd 100644 --- a/ads1298.c +++ b/ads1298.c @@ -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); diff --git a/ads1298.h b/ads1298.h index 68386a8..151999e 100644 --- a/ads1298.h +++ b/ads1298.h @@ -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); diff --git a/main.c b/main.c index 6ff370d..3bf1c93 100644 --- a/main.c +++ b/main.c @@ -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); diff --git a/pca10056/blank/config/custom_board.h b/pca10056/blank/config/custom_board.h index 804a938..43d3ff5 100644 --- a/pca10056/blank/config/custom_board.h +++ b/pca10056/blank/config/custom_board.h @@ -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 };