Added readback for peripheral info, 'who am i' and HW/FW versions
This commit is contained in:
parent
cf50064365
commit
3428fa968f
26
ads1298.c
26
ads1298.c
@ -121,19 +121,18 @@ bool ads1298_check_id(ads1298_info_t *p_info) {
|
||||
#if ADS1298_LOG_DEBUG
|
||||
NRF_LOG_INFO("Checking ADS129xR? ID:");
|
||||
#endif
|
||||
uint8_t tx_buf[6] = {ADS1298_OPC_RREG|ADS1298_REGADDR_ID, 0x01, 0, 0, 0, 0};
|
||||
// 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 rx_buf[6] = {0,0,0,0,0,0};
|
||||
spi_xfer_done = false;
|
||||
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, tx_buf, 6, rx_buf, 6));
|
||||
while(!spi_xfer_done) {
|
||||
__WFE();
|
||||
}
|
||||
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, tx_buf, 3, rx_buf, 3));
|
||||
while(!spi_xfer_done) { __WFE(); }
|
||||
uint8_t register_data = rx_buf[2];
|
||||
memcpy(p_info->id_buffer, rx_buf, 6);
|
||||
#if ADS1298_LOG_DEBUG
|
||||
NRF_LOG_INFO("register_data[0] = 0x%X", register_data);
|
||||
NRF_LOG_INFO(">rx_buf dump:");
|
||||
NRF_LOG_INFO(">rx_buf[0:5] = 0x[%X %X %X %X %X]", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3], rx_buf[4], rx_buf[5]);
|
||||
|
||||
// NRF_LOG_HEXDUMP_INFO(rx_buf, 6);
|
||||
#endif
|
||||
|
||||
@ -152,6 +151,7 @@ bool ads1298_check_id(ads1298_info_t *p_info) {
|
||||
}
|
||||
// Check middle bits 0x[...]10[...] < always should be 10
|
||||
if ((register_data & 0x10) != 0x10 || p_info->nChs == 0) {
|
||||
p_info->nChs = 8;
|
||||
NRF_LOG_INFO("[ERROR] Expected ADS129xX not detected! E1");
|
||||
return false;
|
||||
}
|
||||
@ -220,6 +220,8 @@ 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);
|
||||
@ -236,13 +238,12 @@ void ads1298_update_registers(ads1298_info_t *p_info) {
|
||||
// Transaction size = 2 + number of registers to write
|
||||
spi_xfer_done = false;
|
||||
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, tx_data, ADS1298_REGISTER_COUNT + 2, rx_data, ADS1298_REGISTER_COUNT + 2));
|
||||
while (!spi_xfer_done)
|
||||
{
|
||||
__WFE();
|
||||
}
|
||||
while (!spi_xfer_done) { __WFE(); }
|
||||
#if ADS1298_LOG_DEBUG
|
||||
NRF_LOG_INFO("[ADS1298] Registers updated!");
|
||||
#endif
|
||||
|
||||
// #TODO: Readback registers?
|
||||
}
|
||||
|
||||
void ads1298_init_default_registers(void) {
|
||||
@ -276,8 +277,9 @@ void ads1298_power_down(void) {
|
||||
}
|
||||
|
||||
void ads1298_power_up(void) {
|
||||
nrf_delay_ms(100); // wait for power supplies to stabilize
|
||||
nrf_gpio_pin_set(ADS1298_PWDN_PIN);
|
||||
nrf_delay_ms(80);
|
||||
nrf_delay_ms(100);
|
||||
}
|
||||
|
||||
// Standby/Wakeup controls:
|
||||
@ -418,6 +420,8 @@ void ads1298_set_data_buffer_length(ads1298_info_t* p_info) {
|
||||
break;
|
||||
}
|
||||
NRF_LOG_INFO("[ADS129x] Sampling rate is %d", sampling_rate);
|
||||
NRF_LOG_INFO("[ADS129x] p_info->nChs is %d", p_info->nChs);
|
||||
NRF_LOG_INFO("[ADS129x] Channel count is %d, active_channels: 0x%X", channel_count, p_info->active_chs);
|
||||
NRF_LOG_INFO("[ADS129x] p_info->usb_buffer_size_max is %d", p_info->usb_buffer_size_max);
|
||||
}
|
||||
|
||||
|
||||
19
ads1298.h
19
ads1298.h
@ -68,16 +68,16 @@
|
||||
//#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_CONFIG2 0x00 // Test signals
|
||||
#define ADS1298_REGDEFAULT_CONFIG3 0x40 //
|
||||
#define ADS1298_REGDEFAULT_CONFIG3 0xCC //
|
||||
#define ADS1298_REGDEFAULT_LOFF 0x00
|
||||
#define ADS1298_REGDEFAULT_CH1SET 0x00
|
||||
#define ADS1298_REGDEFAULT_CH2SET 0x00
|
||||
#define ADS1298_REGDEFAULT_CH3SET 0x00
|
||||
#define ADS1298_REGDEFAULT_CH4SET 0x00
|
||||
#define ADS1298_REGDEFAULT_CH5SET 0x00
|
||||
#define ADS1298_REGDEFAULT_CH6SET 0x00
|
||||
#define ADS1298_REGDEFAULT_CH7SET 0x00
|
||||
#define ADS1298_REGDEFAULT_CH8SET 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_RLD_SENSP 0x00
|
||||
#define ADS1298_REGDEFAULT_RLD_SENSN 0x00
|
||||
#define ADS1298_REGDEFAULT_LOFF_SENSP 0x00
|
||||
@ -106,6 +106,7 @@ typedef struct {
|
||||
uint8_t active_chs;
|
||||
uint8_t registers[ADS1298_REGISTER_COUNT];
|
||||
char name[12];
|
||||
uint8_t id_buffer[6];
|
||||
char usb_buffer[USBD_MAX_SIZE];
|
||||
uint8_t usb_buffer_count;
|
||||
uint8_t usb_buffer_size_max;
|
||||
|
||||
64
main.c
64
main.c
@ -36,8 +36,11 @@ static enum recording_mode_t recording_mode = RECORDING_MODE_DISABLED;
|
||||
ads1298_info_t m_info;
|
||||
#endif
|
||||
|
||||
static bool send_peripheral_info = false;
|
||||
// static uint8_t message_length = 0;
|
||||
// #TEMP!
|
||||
char g_Peripheral_Info[] = "ADS1298|";
|
||||
char g_WhoAmI[] = "multimodal_cv_dev0_ecg";
|
||||
uint8_t g_HWFW_Ver[] = {1,0,0,1}; // HW Maj, HW Min, FW Maj, FW Min
|
||||
|
||||
static volatile bool run_throughput_test = false;
|
||||
static char usb_tx_buffer[NRF_DRV_USBD_EPSIZE];
|
||||
|
||||
@ -49,7 +52,6 @@ static char usb_read_buffer[READ_SIZE];
|
||||
#define USBD_POWER_DETECTION true
|
||||
#endif
|
||||
|
||||
|
||||
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
|
||||
app_usbd_cdc_acm_user_event_t event);
|
||||
|
||||
@ -71,12 +73,33 @@ APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
|
||||
APP_USBD_CDC_COMM_PROTOCOL_AT_V250);
|
||||
|
||||
|
||||
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;
|
||||
usb_tx_buffer[1] = message_part_two;
|
||||
usb_tx_buffer[2] = message_length + 3;
|
||||
memcpy(&usb_tx_buffer[3], message, message_length);
|
||||
ret_code_t ret = app_usbd_cdc_acm_write(&m_app_cdc_acm, usb_tx_buffer, message_length + 3);
|
||||
|
||||
NRF_LOG_INFO("[ex]Writing message of length %d, ret: %d", message_length + 3, ret);
|
||||
}
|
||||
|
||||
void usb_transmit_message(uint8_t message_prefix, uint8_t* message, uint8_t message_length) {
|
||||
usb_tx_buffer[0] = message_prefix;
|
||||
usb_tx_buffer[1] = message_length + 2;
|
||||
memcpy(&usb_tx_buffer[2], message, message_length);
|
||||
ret_code_t ret = app_usbd_cdc_acm_write(&m_app_cdc_acm, usb_tx_buffer, message_length + 2);
|
||||
|
||||
NRF_LOG_INFO("[0]Writing message of length %d, ret: %d", message_length + 2, ret);
|
||||
}
|
||||
|
||||
// length is always `READ_SIZE`
|
||||
void write_ic_settings(uint8_t* new_packet) {
|
||||
switch (SECOND_NIBBLE(new_packet[0])) {
|
||||
case TN_IC_ADS1298: {
|
||||
// #TODO: &new_packet[1]
|
||||
#if ADS1298
|
||||
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);
|
||||
@ -90,7 +113,13 @@ void write_ic_settings(uint8_t* new_packet) {
|
||||
void read_ic_settings(uint8_t* new_packet) {
|
||||
switch (SECOND_NIBBLE(new_packet[0])) {
|
||||
case TN_IC_ADS1298: {
|
||||
// #TODO:
|
||||
// #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));
|
||||
usb_transmit_message_ex(REGISTER_READBACK_PREFIX, REGISTER_READBACK_ADS1298,
|
||||
m_info.registers, ADS1298_REGISTER_COUNT);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
@ -129,9 +158,9 @@ static void process_new_packet(uint8_t* new_packet) {
|
||||
#endif
|
||||
}
|
||||
if (SECOND_NIBBLE(new_packet[0]) == TN_STREAM_REQUEST_INFO) {
|
||||
// #TODO: Set peripheral info send flag
|
||||
// Can we just send it from here?
|
||||
send_peripheral_info = true;
|
||||
usb_transmit_message(CTRL_STAT_INFO_PERIPHERALS, g_Peripheral_Info, strlen(g_Peripheral_Info));
|
||||
usb_transmit_message(CTRL_STAT_INFO_WHO_AM_I, g_WhoAmI, strlen(g_WhoAmI));
|
||||
usb_transmit_message(CTRL_STAT_INFO_HW_FW_VERSION, g_HWFW_Ver, sizeof(g_HWFW_Ver));
|
||||
}
|
||||
if (SECOND_NIBBLE(new_packet[0]) == TN_STREAM_REQUEST_BATTERY_LEVEL) {
|
||||
// #NOTE: Will not use. This is not a battery-powered device. (I mean, it can
|
||||
@ -320,15 +349,6 @@ int main(void) {
|
||||
while (true) {
|
||||
while (app_usbd_event_queue_process()) { /* Nothing to do */ }
|
||||
|
||||
if (send_peripheral_info) {
|
||||
send_peripheral_info = false;
|
||||
// #TODO: Prefix relevant correct bytes; copy into static buffer.
|
||||
// should this be a static buffer?
|
||||
char info_buffer[] = "ADS1298|";
|
||||
memset(usb_tx_buffer, 0, NRF_DRV_USBD_EPSIZE);
|
||||
memcpy(usb_tx_buffer, info_buffer, strlen(info_buffer));
|
||||
app_usbd_cdc_acm_write(&m_app_cdc_acm, usb_tx_buffer, strlen(info_buffer));
|
||||
}
|
||||
/*
|
||||
// I think this check is totally irrelevant?
|
||||
if (recording_mode == RECORDING_MODE_ALL) {
|
||||
@ -352,15 +372,7 @@ int main(void) {
|
||||
}*/
|
||||
|
||||
if (run_throughput_test) {
|
||||
//NRF_LOG_INFO("Running throughput test!");
|
||||
// static int frame_counter;
|
||||
|
||||
// size_t size = sprintf(m_tx_buffer, "Hello USB CDC FA demo: %u\r\n", frame_counter);
|
||||
|
||||
// ret = app_usbd_cdc_acm_write(&m_app_cdc_acm, m_tx_buffer, size);
|
||||
// if (ret == NRF_SUCCESS) { ++frame_counter; }
|
||||
app_usbd_cdc_acm_write(&m_app_cdc_acm, usb_tx_buffer, NRF_DRV_USBD_EPSIZE);
|
||||
// if (rc != NRF_SUCCESS) { NRF_LOG_INFO("rc: %d", rc); }
|
||||
/*ret = */app_usbd_cdc_acm_write(&m_app_cdc_acm, usb_tx_buffer, NRF_DRV_USBD_EPSIZE);
|
||||
}
|
||||
|
||||
UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
|
||||
@ -370,3 +382,5 @@ int main(void) {
|
||||
}
|
||||
|
||||
/** @} */
|
||||
// size_t size = sprintf(m_tx_buffer, "Hello USB CDC FA demo: %u\r\n", frame_counter);
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#define ADS1298_MISO_PIN 12
|
||||
#define ADS1298_SCK_PIN 13
|
||||
#define ADS1298_CS_PIN 14
|
||||
// I don't think you're supposed to tie PWDN and reset together on ADS1298
|
||||
#define ADS1298_PWDN_PIN 15
|
||||
#define ADS1298_MOSI_PIN 16
|
||||
|
||||
@ -33,10 +34,19 @@
|
||||
#define TN_STREAM_REQUEST_BATTERY_LEVEL 0xB
|
||||
#define TN_STREAM_REQUEST_INFO 0xE
|
||||
|
||||
// #TODO:
|
||||
#define TN_MISC_THROUGHPUT_TEST 0xF
|
||||
#define TN_MISC_RTT_REQUEST 0x1
|
||||
|
||||
// #################### RESPONSE CODES ####################
|
||||
|
||||
#define CTRL_STAT_INFO_PERIPHERALS 0x03
|
||||
#define CTRL_STAT_INFO_HW_FW_VERSION 0x04
|
||||
#define CTRL_STAT_INFO_WHO_AM_I 0x05
|
||||
|
||||
#define REGISTER_READBACK_PREFIX 0xC8
|
||||
#define ID_REGISTER_READBACK_PREFIX 0xC9
|
||||
#define REGISTER_READBACK_ADS1298 TN_IC_ADS1298
|
||||
|
||||
#define FIRST_NIBBLE(x) ((x >> 4) & 0xF)
|
||||
#define SECOND_NIBBLE(x) (x & 0xF)
|
||||
// For IC controls, we want to prefix the registers with the length: [u16???]
|
||||
|
||||
@ -3092,7 +3092,7 @@
|
||||
|
||||
|
||||
#ifndef SPI0_USE_EASY_DMA
|
||||
#define SPI0_USE_EASY_DMA 1
|
||||
#define SPI0_USE_EASY_DMA 0
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
@ -3114,7 +3114,7 @@
|
||||
// <e> SPI2_ENABLED - Enable SPI2 instance
|
||||
//==========================================================
|
||||
#ifndef SPI2_ENABLED
|
||||
#define SPI2_ENABLED 1
|
||||
#define SPI2_ENABLED 0
|
||||
#endif
|
||||
// <q> SPI2_USE_EASY_DMA - Use EasyDMA
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user