[WIP] Add ADS1298 testing code.
This commit is contained in:
parent
9f5d281a62
commit
a1db776196
84
ads1298.c
84
ads1298.c
@ -11,12 +11,17 @@
|
|||||||
#include "nrf_log_ctrl.h"
|
#include "nrf_log_ctrl.h"
|
||||||
#include "nrf_log_default_backends.h"
|
#include "nrf_log_default_backends.h"
|
||||||
#include "nrf_gpio.h"
|
#include "nrf_gpio.h"
|
||||||
|
|
||||||
#include "nrf_drv_gpiote.h"
|
#include "nrf_drv_gpiote.h"
|
||||||
|
|
||||||
|
#include "base/usb_logging.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
//#include "usb_logging.h"
|
String create_string(char* data) {
|
||||||
|
s32 count = strlen(data);
|
||||||
|
String s = {count, data};
|
||||||
|
return s;
|
||||||
|
} // #MOVE.
|
||||||
|
|
||||||
uint8_t ads1298_default_regs[] = {
|
uint8_t ads1298_default_regs[] = {
|
||||||
ADS1298_REGDEFAULT_CONFIG1,
|
ADS1298_REGDEFAULT_CONFIG1,
|
||||||
@ -58,11 +63,11 @@ static void spi_event_handler(nrf_drv_spi_evt_t const *p_event, void *p_context)
|
|||||||
{
|
{
|
||||||
spi_xfer_done = true;
|
spi_xfer_done = true;
|
||||||
#if ADS1298_LOG_DEBUG
|
#if ADS1298_LOG_DEBUG
|
||||||
NRF_LOG_DEBUG("SPI transfer completed.");
|
JIIM_LOG(" > SPI transfer completed.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ads1298_initialize(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
void ads1298_initialize(ads1298_info_t *p_info) {
|
||||||
NRF_LOG_INFO("Initializing ADS1298...");
|
NRF_LOG_INFO("Initializing ADS1298...");
|
||||||
// 1. Power up the ADS1298:
|
// 1. Power up the ADS1298:
|
||||||
ads1298_power_up();
|
ads1298_power_up();
|
||||||
@ -77,7 +82,9 @@ void ads1298_initialize(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
|||||||
spi_config.miso_pin = ADS1298_MISO_PIN;
|
spi_config.miso_pin = ADS1298_MISO_PIN;
|
||||||
spi_config.mosi_pin = ADS1298_MOSI_PIN;
|
spi_config.mosi_pin = ADS1298_MOSI_PIN;
|
||||||
spi_config.sck_pin = ADS1298_SCK_PIN;
|
spi_config.sck_pin = ADS1298_SCK_PIN;
|
||||||
spi_config.frequency = NRF_DRV_SPI_FREQ_2M;
|
//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.mode = NRF_DRV_SPI_MODE_1;
|
||||||
spi_config.orc = 0x55;
|
spi_config.orc = 0x55;
|
||||||
@ -89,9 +96,9 @@ void ads1298_initialize(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
|||||||
NRF_LOG_FLUSH();
|
NRF_LOG_FLUSH();
|
||||||
#endif
|
#endif
|
||||||
// 4. Init registers:
|
// 4. Init registers:
|
||||||
// Copy default registers into p_exg->ads1298_settings (first 25 bytes)
|
// Copy default registers into p_info->registers (first 25 bytes)
|
||||||
memset(p_exg->ads1298_settings, 0, ADS1298_SETTINGS_SIZE);
|
memset(p_info->registers, 0, sizeof(p_info->registers));
|
||||||
memcpy(p_exg->ads1298_settings, ads1298_default_regs, ADS1298_REGISTER_COUNT);
|
memcpy(p_info->registers, ads1298_default_regs, ADS1298_REGISTER_COUNT);
|
||||||
ads1298_init_default_registers();
|
ads1298_init_default_registers();
|
||||||
#if ADS1298_LOG_DEBUG
|
#if ADS1298_LOG_DEBUG
|
||||||
NRF_LOG_FLUSH();
|
NRF_LOG_FLUSH();
|
||||||
@ -99,28 +106,26 @@ void ads1298_initialize(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
|||||||
// 5. Soft start:
|
// 5. Soft start:
|
||||||
ads1298_soft_start_conversion();
|
ads1298_soft_start_conversion();
|
||||||
// 6. Check ID: (sets lower 3 bits of ads1298_settings[25])
|
// 6. Check ID: (sets lower 3 bits of ads1298_settings[25])
|
||||||
ads1298_check_id(p_exg, p_info);
|
ads1298_check_id(p_info);
|
||||||
// 7. Start read data continuous mode (rdatac):
|
// 7. Start read data continuous mode (rdatac):
|
||||||
ads1298_start_rdatac();
|
ads1298_start_rdatac();
|
||||||
// 8. Place on standby mode:
|
// 8. Place on standby mode:
|
||||||
ads1298_standby();
|
ads1298_standby();
|
||||||
// 9. Set remainder of ads1298_settings[25]:
|
|
||||||
p_exg->ads1298_settings[25] |= 0x80; // 16-bit mode
|
|
||||||
// ads1298_settings[25] &= 0b10011111; // TODO: sets downsample to zero
|
|
||||||
#if ADS1298_LOG_DEBUG
|
#if ADS1298_LOG_DEBUG
|
||||||
NRF_LOG_FLUSH();
|
NRF_LOG_FLUSH();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ads1298_uninitialize(void) {
|
void ads1298_uninitialize(void) {
|
||||||
NRF_LOG_INFO("Uninitializing ADS1298...");
|
JIIM_LOG("Uninitializing ADS1298...");
|
||||||
nrf_drv_spi_uninit(&spi0);
|
nrf_drv_spi_uninit(&spi0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ads1298_check_id(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
bool ads1298_check_id(ads1298_info_t *p_info) {
|
||||||
bool device_found = false;
|
bool device_found = false;
|
||||||
#if ADS1298_LOG_DEBUG
|
#if ADS1298_LOG_DEBUG
|
||||||
NRF_LOG_INFO("Checking ADS129xR? ID:");
|
JIIM_LOG("Checking ADS129xR? ID:");
|
||||||
#endif
|
#endif
|
||||||
uint8_t tx_buf[6] = {ADS1298_OPC_RREG|ADS1298_REGADDR_ID, 0x01, 0, 0, 0, 0};
|
uint8_t tx_buf[6] = {ADS1298_OPC_RREG|ADS1298_REGADDR_ID, 0x01, 0, 0, 0, 0};
|
||||||
uint8_t rx_buf[6] = {0,0,0,0,0,0};
|
uint8_t rx_buf[6] = {0,0,0,0,0,0};
|
||||||
@ -130,13 +135,14 @@ bool ads1298_check_id(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
|||||||
__WFE();
|
__WFE();
|
||||||
}
|
}
|
||||||
#if ADS1298_LOG_DEBUG
|
#if ADS1298_LOG_DEBUG
|
||||||
NRF_LOG_INFO("rx_buf[3] = 0x%X", rx_buf[3]);
|
JIIM_LOG("rx_buf[3] = 0x%X", rx_buf[3]);
|
||||||
NRF_LOG_INFO("rx_buf dump:");
|
JIIM_LOG("rx_buf dump:");
|
||||||
NRF_LOG_HEXDUMP_INFO(rx_buf, 6);
|
JIIM_LOG("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
|
#endif
|
||||||
// Check lower 3 bits 0x[...]..[???]
|
// Check lower 3 bits 0x[...]..[xxx]
|
||||||
uint8_t nch_check = rx_buf[3] & 0x07; // 0x.....111
|
uint8_t nch_check = rx_buf[3] & 0x07; // 0x.....111
|
||||||
p_exg->ads1298_settings[25] |= nch_check;
|
|
||||||
p_info->nChs = 0;
|
p_info->nChs = 0;
|
||||||
if (nch_check == ADS129x_4CH_BITMASK) {
|
if (nch_check == ADS129x_4CH_BITMASK) {
|
||||||
p_info->nChs = 4; // ADS1294
|
p_info->nChs = 4; // ADS1294
|
||||||
@ -145,28 +151,26 @@ bool ads1298_check_id(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
|||||||
} else if (nch_check == ADS129x_8CH_BITMASK) {
|
} else if (nch_check == ADS129x_8CH_BITMASK) {
|
||||||
p_info->nChs = 8; // ADS1298
|
p_info->nChs = 8; // ADS1298
|
||||||
} else {
|
} else {
|
||||||
NRF_LOG_ERROR("Expected ADS129xX not detected! E0");
|
JIIM_LOG("[ERROR] Expected ADS129xX not detected! E0");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check middle bits 0x[...]10[...] < always should be 10
|
// Check middle bits 0x[...]10[...] < always should be 10
|
||||||
if ((rx_buf[3] & 0x10) != 0x10 || p_info->nChs == 0) {
|
if ((rx_buf[3] & 0x10) != 0x10 || p_info->nChs == 0) {
|
||||||
NRF_LOG_ERROR("Expected ADS129xX not detected! E1");
|
JIIM_LOG("[ERROR] Expected ADS129xX not detected! E1");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check first three bits: 0x[???]..[...]
|
// Check first three bits: 0x[xxx]..[...]
|
||||||
uint8_t r_ver_chk = rx_buf[3] & 0xE0;
|
uint8_t r_ver_chk = rx_buf[3] & 0xE0;
|
||||||
if (r_ver_chk == ADS129x_DEVICE_FAMILY_BITMASK) {
|
if (r_ver_chk == ADS129x_DEVICE_FAMILY_BITMASK) {
|
||||||
p_info->name_len = sprintf(p_info->name, "ADS129%d", p_info->nChs);
|
p_info->name_len = sprintf(p_info->name, "ADS129%d", p_info->nChs);
|
||||||
NRF_LOG_INFO("%s detected! (name_len: %d)", p_info->name, p_info->name_len);
|
JIIM_LOG("%s detected! (name_len: %d)", p_info->name, p_info->name_len);
|
||||||
device_found = true;
|
device_found = true;
|
||||||
p_exg->ads1298_settings[25] &= (~0x08);
|
|
||||||
} else if (r_ver_chk == ADS129xR_DEVICE_FAMILY_BITMASK) {
|
} else if (r_ver_chk == ADS129xR_DEVICE_FAMILY_BITMASK) {
|
||||||
p_info->name_len = sprintf(p_info->name, "ADS129%dR", p_info->nChs);
|
p_info->name_len = sprintf(p_info->name, "ADS129%dR", p_info->nChs);
|
||||||
NRF_LOG_INFO("%s detected! (name_len: %d)", p_info->name, p_info->name_len);
|
JIIM_LOG("%s detected! (name_len: %d)", p_info->name, p_info->name_len);
|
||||||
p_exg->ads1298_settings[25] |= 0x08;
|
|
||||||
device_found = true;
|
device_found = true;
|
||||||
} else {
|
} else {
|
||||||
NRF_LOG_ERROR("Expected ADS129xX not detected! E2");
|
JIIM_LOG("[ERROR] Expected ADS129xX not detected! E2");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +181,7 @@ bool ads1298_check_id(ble_exg_t *p_exg, ads1298_info_t *p_info) {
|
|||||||
__STATIC_INLINE bool ads1298_check_channel(ads1298_info_t *p_info, uint8_t chNumber) {
|
__STATIC_INLINE bool ads1298_check_channel(ads1298_info_t *p_info, uint8_t chNumber) {
|
||||||
if (chNumber > p_info->nChs) return false;
|
if (chNumber > p_info->nChs) return false;
|
||||||
if (chNumber > 8) {
|
if (chNumber > 8) {
|
||||||
NRF_LOG_INFO("[ads1298_check_channel] INVALID CHANNEL NUMBER: %d!", chNumber);
|
JIIM_LOG("[ads1298_check_channel] INVALID CHANNEL NUMBER: %d!", chNumber);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !((p_info->registers[3 + chNumber] & 0x80) == 0x80);
|
return !((p_info->registers[3 + chNumber] & 0x80) == 0x80);
|
||||||
@ -198,7 +202,7 @@ void ads1298_update_active_chs(ads1298_info_t *p_info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ads1298_update_registers(ads1298_info_t *p_info) {
|
void ads1298_update_registers(ads1298_info_t *p_info) {
|
||||||
NRF_LOG_INFO("Updating ADS1298 registers...");
|
JIIM_LOG("Updating ADS1298 registers...");
|
||||||
ads1298_update_active_chs(p_info);
|
ads1298_update_active_chs(p_info);
|
||||||
uint8_t i = 0; // Register index
|
uint8_t i = 0; // Register index
|
||||||
uint8_t tx_data[ADS1298_REGISTER_COUNT + 2]; // plus 2 for opcodes
|
uint8_t tx_data[ADS1298_REGISTER_COUNT + 2]; // plus 2 for opcodes
|
||||||
@ -218,12 +222,12 @@ void ads1298_update_registers(ads1298_info_t *p_info) {
|
|||||||
__WFE();
|
__WFE();
|
||||||
}
|
}
|
||||||
#if ADS1298_LOG_DEBUG
|
#if ADS1298_LOG_DEBUG
|
||||||
NRF_LOG_INFO("[ADS1298] Registers updated!");
|
JIIM_LOG("[ADS1298] Registers updated!");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ads1298_init_default_registers(void) {
|
void ads1298_init_default_registers(void) {
|
||||||
NRF_LOG_INFO("Initializing ADS1298 registers...");
|
JIIM_LOG("Initializing ADS1298 registers...");
|
||||||
uint8_t i = 0; // Register index
|
uint8_t i = 0; // Register index
|
||||||
uint8_t tx_data[ADS1298_REGISTER_COUNT + 2]; // plus 2 for opcodes
|
uint8_t tx_data[ADS1298_REGISTER_COUNT + 2]; // plus 2 for opcodes
|
||||||
uint8_t rx_data[ADS1298_REGISTER_COUNT + 2];
|
uint8_t rx_data[ADS1298_REGISTER_COUNT + 2];
|
||||||
@ -242,7 +246,7 @@ void ads1298_init_default_registers(void) {
|
|||||||
__WFE();
|
__WFE();
|
||||||
}
|
}
|
||||||
#if ADS1298_LOG_DEBUG
|
#if ADS1298_LOG_DEBUG
|
||||||
NRF_LOG_INFO("[ADS1298] Registers initialized.");
|
JIIM_LOG("[ADS1298] Registers initialized.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +263,7 @@ void ads1298_power_up(void) {
|
|||||||
|
|
||||||
// Standby/Wakeup controls:
|
// Standby/Wakeup controls:
|
||||||
void ads1298_wakeup(void) {
|
void ads1298_wakeup(void) {
|
||||||
NRF_LOG_INFO("Waking up ADS1298...");
|
JIIM_LOG("Waking up ADS1298...");
|
||||||
uint8_t cmd = ADS1298_OPC_WAKEUP;
|
uint8_t cmd = ADS1298_OPC_WAKEUP;
|
||||||
uint8_t rx_buf;
|
uint8_t rx_buf;
|
||||||
spi_xfer_done = false;
|
spi_xfer_done = false;
|
||||||
@ -271,7 +275,7 @@ void ads1298_wakeup(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ads1298_standby(void) {
|
void ads1298_standby(void) {
|
||||||
NRF_LOG_INFO("Placing ADS1298 in standby mode...");
|
JIIM_LOG("Placing ADS1298 in standby mode...");
|
||||||
uint8_t cmd = ADS1298_OPC_STANDBY;
|
uint8_t cmd = ADS1298_OPC_STANDBY;
|
||||||
uint8_t rx_buf;
|
uint8_t rx_buf;
|
||||||
spi_xfer_done = false;
|
spi_xfer_done = false;
|
||||||
@ -284,7 +288,7 @@ void ads1298_standby(void) {
|
|||||||
|
|
||||||
// Start/stop conversions
|
// Start/stop conversions
|
||||||
void ads1298_soft_start_conversion(void) {
|
void ads1298_soft_start_conversion(void) {
|
||||||
NRF_LOG_INFO("[ADS1298] Starting conversion...");
|
JIIM_LOG("[ADS1298] Starting conversion...");
|
||||||
uint8_t cmd = ADS1298_OPC_START;
|
uint8_t cmd = ADS1298_OPC_START;
|
||||||
uint8_t rx_buf;
|
uint8_t rx_buf;
|
||||||
spi_xfer_done = false;
|
spi_xfer_done = false;
|
||||||
@ -296,7 +300,7 @@ void ads1298_soft_start_conversion(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ads1298_start_rdatac(void) {
|
void ads1298_start_rdatac(void) {
|
||||||
NRF_LOG_INFO("[ADS1298] Starting Read Data Continuous Mode...");
|
JIIM_LOG("[ADS1298] Starting Read Data Continuous Mode...");
|
||||||
uint8_t cmd = ADS1298_OPC_RDATAC;
|
uint8_t cmd = ADS1298_OPC_RDATAC;
|
||||||
uint8_t rx_buf;
|
uint8_t rx_buf;
|
||||||
spi_xfer_done = false;
|
spi_xfer_done = false;
|
||||||
@ -308,7 +312,7 @@ void ads1298_start_rdatac(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ads1298_stop_rdatac(void) {
|
void ads1298_stop_rdatac(void) {
|
||||||
NRF_LOG_INFO("[ADS1298] Stopping Read Data Continuous Mode...");
|
JIIM_LOG("[ADS1298] Stopping Read Data Continuous Mode...");
|
||||||
uint8_t cmd = ADS1298_OPC_SDATAC;
|
uint8_t cmd = ADS1298_OPC_SDATAC;
|
||||||
uint8_t rx_buf;
|
uint8_t rx_buf;
|
||||||
spi_xfer_done = false;
|
spi_xfer_done = false;
|
||||||
@ -331,7 +335,8 @@ void ads1298_stop_rdatac(void) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// TODO: Add option for 2 bytes (low resolution)
|
// TODO: Add option for 2 bytes (low resolution)
|
||||||
__STATIC_INLINE void copy_relevant_data(ble_exg_t *p_exg, uint8_t active_chs/*, bool hi_res*/) {
|
/*
|
||||||
|
__STATIC_INLINE void copy_relevant_data(ble_exg_t *p_exg, uint8_t active_chs) {
|
||||||
if ((active_chs & 0x80) == 0x80) memcpy(&p_exg->exg_ch1_buffer[p_exg->data_buffer_count], &rx_buffer[3], 3);
|
if ((active_chs & 0x80) == 0x80) memcpy(&p_exg->exg_ch1_buffer[p_exg->data_buffer_count], &rx_buffer[3], 3);
|
||||||
if ((active_chs & 0x40) == 0x40) memcpy(&p_exg->exg_ch2_buffer[p_exg->data_buffer_count], &rx_buffer[6], 3);
|
if ((active_chs & 0x40) == 0x40) memcpy(&p_exg->exg_ch2_buffer[p_exg->data_buffer_count], &rx_buffer[6], 3);
|
||||||
if ((active_chs & 0x20) == 0x20) memcpy(&p_exg->exg_ch3_buffer[p_exg->data_buffer_count], &rx_buffer[9], 3);
|
if ((active_chs & 0x20) == 0x20) memcpy(&p_exg->exg_ch3_buffer[p_exg->data_buffer_count], &rx_buffer[9], 3);
|
||||||
@ -368,3 +373,4 @@ void ads1294_get_data(ble_exg_t *p_exg, uint8_t active_chs) {
|
|||||||
// Check mode p_exg->ads1298_settings[26] b0
|
// Check mode p_exg->ads1298_settings[26] b0
|
||||||
copy_relevant_data(p_exg, active_chs);
|
copy_relevant_data(p_exg, active_chs);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
40
ads1298.h
40
ads1298.h
@ -8,13 +8,12 @@
|
|||||||
#define ADS1298_LOG_DEBUG 1
|
#define ADS1298_LOG_DEBUG 1
|
||||||
|
|
||||||
// Testing with nRF52840-DK:
|
// Testing with nRF52840-DK:
|
||||||
#define ADS1298_MISO_PIN 29
|
#define ADS1298_DRDY_PIN 11
|
||||||
#define ADS1298_DRDY_PIN 12
|
#define ADS1298_MISO_PIN 12
|
||||||
#define ADS1298_CS_PIN 19
|
#define ADS1298_SCK_PIN 13
|
||||||
#define ADS1298_SCK_PIN 11
|
#define ADS1298_CS_PIN 14
|
||||||
#define ADS1298_MOSI_PIN 26
|
#define ADS1298_PWDN_PIN 15
|
||||||
#define ADS1298_PWDN_PIN 03
|
#define ADS1298_MOSI_PIN 16
|
||||||
|
|
||||||
|
|
||||||
// Number of WRITABLE registers (Not inc. ID register)
|
// Number of WRITABLE registers (Not inc. ID register)
|
||||||
#define ADS1298_REGISTER_COUNT 25
|
#define ADS1298_REGISTER_COUNT 25
|
||||||
@ -101,23 +100,6 @@
|
|||||||
#define ADS1298_BUFFER_SIZE 64
|
#define ADS1298_BUFFER_SIZE 64
|
||||||
#define ADS1298_SETTINGS_SIZE 26
|
#define ADS1298_SETTINGS_SIZE 26
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t service_handle; /**< Handle of ble_exg Service (as provided by the BLE stack). */
|
|
||||||
uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
|
|
||||||
uint8_t uuid_type; /**< UUID type for the ble_exg Service. */
|
|
||||||
uint8_t exg_ch1_buffer[ADS1298_BUFFER_SIZE]; /**< Buffer for sending data to the peer device. */
|
|
||||||
uint8_t exg_ch2_buffer[ADS1298_BUFFER_SIZE];
|
|
||||||
uint8_t exg_ch3_buffer[ADS1298_BUFFER_SIZE];
|
|
||||||
uint8_t exg_ch4_buffer[ADS1298_BUFFER_SIZE];
|
|
||||||
uint8_t exg_ch5_buffer[ADS1298_BUFFER_SIZE];
|
|
||||||
uint8_t exg_ch6_buffer[ADS1298_BUFFER_SIZE];
|
|
||||||
uint8_t exg_ch7_buffer[ADS1298_BUFFER_SIZE];
|
|
||||||
uint8_t exg_ch8_buffer[ADS1298_BUFFER_SIZE];
|
|
||||||
uint8_t ads1298_settings[ADS1298_SETTINGS_SIZE];
|
|
||||||
uint16_t data_buffer_count; /**< Counter for data buffer. */
|
|
||||||
uint16_t data_buffer_length; /**< Length of the data buffer. */
|
|
||||||
} ble_exg_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t nChs; // 4, 6, or 8 channels depending on variant.
|
uint8_t nChs; // 4, 6, or 8 channels depending on variant.
|
||||||
uint8_t state; // Powered on or off!
|
uint8_t state; // Powered on or off!
|
||||||
@ -130,11 +112,11 @@ typedef struct {
|
|||||||
} ads1298_info_t;
|
} ads1298_info_t;
|
||||||
|
|
||||||
/** FUNCTION PROTOTYPES **/
|
/** FUNCTION PROTOTYPES **/
|
||||||
void ads1298_initialize(ble_exg_t *p_exg, ads1298_info_t *p_info);
|
void ads1298_initialize(ads1298_info_t *p_info);
|
||||||
|
|
||||||
void ads1298_uninitialize(void);
|
void ads1298_uninitialize(void);
|
||||||
|
|
||||||
bool ads1298_check_id(ble_exg_t *p_exg, 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);
|
||||||
|
|
||||||
@ -154,10 +136,10 @@ void ads1298_start_rdatac(void);
|
|||||||
|
|
||||||
void ads1298_stop_rdatac(void);
|
void ads1298_stop_rdatac(void);
|
||||||
|
|
||||||
void ads1294_get_data(ble_exg_t *p_exg, uint8_t active_chs);
|
// void ads1294_get_data(ble_exg_t *p_exg, uint8_t active_chs);
|
||||||
|
|
||||||
void ads1296_get_data(ble_exg_t *p_exg, uint8_t active_chs);
|
// void ads1296_get_data(ble_exg_t *p_exg, uint8_t active_chs);
|
||||||
|
|
||||||
void ads1298_get_data(ble_exg_t *p_exg, uint8_t active_chs);
|
// void ads1298_get_data(ble_exg_t *p_exg, uint8_t active_chs);
|
||||||
|
|
||||||
#endif // ADS1298_H_
|
#endif // ADS1298_H_
|
||||||
|
|||||||
11
base/types.h
11
base/types.h
@ -1,3 +1,6 @@
|
|||||||
|
#ifndef __TYPES_H
|
||||||
|
#define __TYPES_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@ -24,8 +27,6 @@ typedef struct {
|
|||||||
u8* data;
|
u8* data;
|
||||||
} String;
|
} String;
|
||||||
|
|
||||||
String create_string(char* data) {
|
String create_string(char* data);
|
||||||
s32 count = strlen(data);
|
|
||||||
String s = {count, data};
|
#endif
|
||||||
return s;
|
|
||||||
}
|
|
||||||
@ -1,4 +1,8 @@
|
|||||||
|
#ifndef USB_LOGGING_H_
|
||||||
|
#define USB_LOGGING_H_
|
||||||
|
|
||||||
// Helper code for saving data to USB
|
// Helper code for saving data to USB
|
||||||
|
#include "base/types.h"
|
||||||
|
|
||||||
// Global log buffer and usage:
|
// Global log buffer and usage:
|
||||||
static u8 log_buffer[4096];
|
static u8 log_buffer[4096];
|
||||||
@ -14,25 +18,6 @@ static bool full_tx_complete = false;
|
|||||||
// Mode 0: do not wrap around, do not append to buffer
|
// Mode 0: do not wrap around, do not append to buffer
|
||||||
// Mode 1: wrap around to beginning.
|
// Mode 1: wrap around to beginning.
|
||||||
|
|
||||||
static void reset_log_buffer(void) {
|
|
||||||
// If debug, then memset buffer
|
|
||||||
memset(log_buffer, 0, sizeof(log_buffer));
|
|
||||||
m_log_usage = 0;
|
|
||||||
m_log_buffer_send_index = 0;
|
|
||||||
tx_complete = true;
|
|
||||||
full_tx_complete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_to_log_buffer(String str) {
|
|
||||||
// Bounds check the buffer:
|
|
||||||
if (m_log_usage + str.count >= sizeof(log_buffer)) {
|
|
||||||
// Failure!.. How to handle? Turn on LEDs?
|
|
||||||
return; // Do not add to buffer
|
|
||||||
}
|
|
||||||
memcpy(&log_buffer[m_log_usage], str.data, str.count);
|
|
||||||
m_log_usage += str.count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FOR STRING LITERALS ONLY
|
// FOR STRING LITERALS ONLY
|
||||||
// #define JIIM_LOG_USB(strlit) add_to_log_buffer(Create_String(strlit))
|
// #define JIIM_LOG_USB(strlit) add_to_log_buffer(Create_String(strlit))
|
||||||
|
|
||||||
@ -40,19 +25,14 @@ static void add_to_log_buffer(String str) {
|
|||||||
static u8 sprint_buffer[128];
|
static u8 sprint_buffer[128];
|
||||||
static s32 sprint_length;
|
static s32 sprint_length;
|
||||||
|
|
||||||
// #TODO: Inline
|
// #TODO: I need to append a \n here
|
||||||
void add_format_string_to_log_buffer(void) {
|
|
||||||
// Replace null terminator with \n where required.
|
|
||||||
sprint_buffer[sprint_length] = '\n';
|
|
||||||
String s = {sprint_length+1, sprint_buffer};
|
|
||||||
add_to_log_buffer(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #TODO: I need to append a \n here
|
|
||||||
#define JIIM_LOG(fmt, ...) \
|
#define JIIM_LOG(fmt, ...) \
|
||||||
sprint_length = sprintf(sprint_buffer, fmt, ##__VA_ARGS__); \
|
sprint_length = sprintf(sprint_buffer, fmt, ##__VA_ARGS__); \
|
||||||
add_format_string_to_log_buffer()
|
add_format_string_to_log_buffer()
|
||||||
|
|
||||||
|
void reset_log_buffer(void);
|
||||||
|
void add_to_log_buffer(String str);
|
||||||
|
void add_format_string_to_log_buffer(void);
|
||||||
/*
|
/*
|
||||||
void send_usb_log(String str) {
|
void send_usb_log(String str) {
|
||||||
// Zero buffer:
|
// Zero buffer:
|
||||||
@ -66,5 +46,7 @@ void send_usb_log(String str) {
|
|||||||
void log_usb(char* data) {
|
void log_usb(char* data) {
|
||||||
send_usb_log(create_string(data));
|
send_usb_log(create_string(data));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
*/
|
|
||||||
|
#endif // USB_LOGGING_H_
|
||||||
132
main.c
132
main.c
@ -1,9 +1,6 @@
|
|||||||
// What I want is to be able to send logs ONLY in log mode, so I need to keep a buffer of strings
|
|
||||||
// String logs[64], pointing to different strings.
|
|
||||||
// I just fucking hate strlen for this kind of thing
|
|
||||||
// If only there's a way to precompute string lengths.
|
|
||||||
|
|
||||||
// Nordic drivers and application code:
|
// Nordic drivers and application code:
|
||||||
|
// Note: see throughput testing in musa_usbd_cdc_acm
|
||||||
|
|
||||||
#include "nrf.h"
|
#include "nrf.h"
|
||||||
#include "nrf_drv_usbd.h"
|
#include "nrf_drv_usbd.h"
|
||||||
#include "nrf_drv_clock.h"
|
#include "nrf_drv_clock.h"
|
||||||
@ -30,7 +27,18 @@
|
|||||||
#include "base/usb_logging.h"
|
#include "base/usb_logging.h"
|
||||||
|
|
||||||
// **** Sensor driver APIs ****
|
// **** Sensor driver APIs ****
|
||||||
#include "ads1298.h"
|
#define ADS1298 0
|
||||||
|
#define ADS1292 0
|
||||||
|
|
||||||
|
#if ADS1298
|
||||||
|
#include "ads1298.h"
|
||||||
|
#include "nrf_gpio.h"
|
||||||
|
#include "nrf_drv_gpiote.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADS1292
|
||||||
|
#include "ads1292.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable power USB detection
|
* @brief Enable power USB detection
|
||||||
@ -156,13 +164,6 @@ static void usbd_user_ev_handler(app_usbd_event_type_t event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ads1298_info_t m_info;
|
|
||||||
static ble_exg_t m_exg;
|
|
||||||
|
|
||||||
// Global Data:
|
|
||||||
// Unfortunately I need to precompute these strlens manually :skull-emoji:
|
|
||||||
// String hello_string = {21, "Hello, I am a string\n"};
|
|
||||||
|
|
||||||
void Send_USB_Logs(void) {
|
void Send_USB_Logs(void) {
|
||||||
if (!tx_complete) return;
|
if (!tx_complete) return;
|
||||||
// We should check that the USB data is
|
// We should check that the USB data is
|
||||||
@ -177,13 +178,70 @@ void Send_USB_Logs(void) {
|
|||||||
tx_complete = false;
|
tx_complete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ADS1298 || ADS1292
|
||||||
|
void drdy_pin_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
||||||
|
UNUSED_PARAMETER(pin);
|
||||||
|
UNUSED_PARAMETER(action);
|
||||||
|
JIIM_LOG("drdy!");
|
||||||
|
// drdy_flag = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADS1298
|
||||||
|
ads1298_info_t m_info;
|
||||||
|
|
||||||
|
void ads1298_init_gpio(void) {
|
||||||
|
nrf_gpio_cfg_output(ADS1298_PWDN_PIN);
|
||||||
|
nrf_gpio_pin_clear(ADS1298_PWDN_PIN);
|
||||||
|
nrf_gpio_cfg_input(ADS1298_DRDY_PIN, NRF_GPIO_PIN_PULLUP);
|
||||||
|
// Initialize GPIOTE:
|
||||||
|
ret_code_t err_code = NRF_SUCCESS;
|
||||||
|
if (!nrf_drv_gpiote_is_init())
|
||||||
|
{
|
||||||
|
err_code = nrf_drv_gpiote_init();
|
||||||
|
}
|
||||||
|
JIIM_LOG("GPIOTE error code: %d", err_code);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
|
||||||
|
in_config.is_watcher = true;
|
||||||
|
in_config.pull = NRF_GPIO_PIN_NOPULL;
|
||||||
|
err_code = nrf_drv_gpiote_in_init(ADS1298_DRDY_PIN, &in_config, drdy_pin_handler);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
nrf_drv_gpiote_in_event_enable(ADS1298_DRDY_PIN, true);
|
||||||
|
ads1298_power_down();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ADS1292
|
||||||
|
ads129x_info_t m_info;
|
||||||
|
|
||||||
|
void ads1292_interrupt_setup(void) {
|
||||||
|
nrf_gpio_cfg_output(ADS1292_PWDN_PIN);
|
||||||
|
nrf_gpio_pin_clear(ADS1292_PWDN_PIN); // Powers down the ADS1292
|
||||||
|
nrf_gpio_cfg_input(ADS1292_DRDY_PIN, NRF_GPIO_PIN_PULLUP);
|
||||||
|
// Initialize GPIOTE:
|
||||||
|
ret_code_t err_code = NRF_SUCCESS;
|
||||||
|
if (!nrf_drv_gpiote_is_init()) {
|
||||||
|
err_code = nrf_drv_gpiote_init();
|
||||||
|
}
|
||||||
|
NRF_LOG_INFO("GPIOTE error code: %d", err_code);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
|
||||||
|
in_config.is_watcher = true;
|
||||||
|
in_config.pull = NRF_GPIO_PIN_NOPULL;
|
||||||
|
err_code = nrf_drv_gpiote_in_init(ADS1292_DRDY_PIN, &in_config, drdy_pin_handler);
|
||||||
|
APP_ERROR_CHECK(err_code);
|
||||||
|
nrf_drv_gpiote_in_event_enable(ADS1292_DRDY_PIN, true);
|
||||||
|
ads1292_power_down();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
ret_code_t ret;
|
ret_code_t ret;
|
||||||
static const app_usbd_config_t usbd_config = {
|
static const app_usbd_config_t usbd_config = {
|
||||||
.ev_state_proc = usbd_user_ev_handler
|
.ev_state_proc = usbd_user_ev_handler
|
||||||
};
|
};
|
||||||
|
|
||||||
// #TODO: remove logging maybe?
|
|
||||||
ret = NRF_LOG_INIT(NULL);
|
ret = NRF_LOG_INIT(NULL);
|
||||||
APP_ERROR_CHECK(ret);
|
APP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
@ -222,43 +280,34 @@ int main(void) {
|
|||||||
JIIM_LOG("Hello world!");
|
JIIM_LOG("Hello world!");
|
||||||
JIIM_LOG("HELLO WORLD %d FORMATTED", 2);
|
JIIM_LOG("HELLO WORLD %d FORMATTED", 2);
|
||||||
JIIM_LOG("sizeof(log_buffer): %d", sizeof(log_buffer));
|
JIIM_LOG("sizeof(log_buffer): %d", sizeof(log_buffer));
|
||||||
// TODO#: ads1298_init_gpio().
|
|
||||||
// TODO#: Push logs over USB.
|
|
||||||
|
|
||||||
JIIM_LOG("Hello, I am a string2");
|
JIIM_LOG("Hello, I am a string2");
|
||||||
JIIM_LOG("Hello, I am a string2");
|
|
||||||
JIIM_LOG("Hello, I am a string2");
|
#if ADS1292
|
||||||
JIIM_LOG("Hello, I am a string2");
|
ads1292_interrupt_setup();
|
||||||
JIIM_LOG("Hello, I am a string2");
|
|
||||||
JIIM_LOG("Hello, I am a string2");
|
ads1292_initialize(&m_info);
|
||||||
|
#endif
|
||||||
|
#if ADS1298
|
||||||
|
ads1298_init_gpio();
|
||||||
|
|
||||||
|
memset(&m_info, 0, sizeof(ads1298_info_t));
|
||||||
|
ads1298_initialize(&m_info);
|
||||||
|
#endif
|
||||||
|
|
||||||
// String hello_string = Create_String("Hello, I am a string2\n");
|
#if ADS1292 || ADS1298
|
||||||
// add_to_log_buffer(hello_string);
|
|
||||||
// add_to_log_buffer(hello_string);
|
|
||||||
// add_to_log_buffer(hello_string);
|
|
||||||
ads1298_initialize(&m_exg, &m_info);
|
|
||||||
|
|
||||||
if (m_info.nChs > 0) {
|
if (m_info.nChs > 0) {
|
||||||
// #TODO: replace with sprintf()...
|
|
||||||
JIIM_LOG("Number of channels available: %d", m_info.nChs);
|
JIIM_LOG("Number of channels available: %d", m_info.nChs);
|
||||||
} else {
|
} else {
|
||||||
JIIM_LOG("ERROR: ADS129x NOT DETECTED!");
|
JIIM_LOG("ERROR: ADS129x NOT DETECTED!");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
//memset(m_tx_buffer, 0x41/*"A"*/, NRF_DRV_USBD_EPSIZE);
|
|
||||||
//size_t size = NRF_DRV_USBD_EPSIZE;
|
|
||||||
|
|
||||||
//s32 count = 0;
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
while (app_usbd_event_queue_process()) {/* Nothing to do */}
|
while (app_usbd_event_queue_process()) {/* Nothing to do */}
|
||||||
|
|
||||||
if (m_send_flag) {
|
//if (m_send_flag) {
|
||||||
|
// static int frame_counter;
|
||||||
}
|
|
||||||
|
|
||||||
if (m_send_logs) {
|
|
||||||
// static int frame_counter;
|
|
||||||
|
|
||||||
// size_t size = sprintf(m_tx_buffer, "Hello USB CDC FA demo: %u\r\n", frame_counter);
|
// size_t size = sprintf(m_tx_buffer, "Hello USB CDC FA demo: %u\r\n", frame_counter);
|
||||||
|
|
||||||
@ -269,8 +318,9 @@ int main(void) {
|
|||||||
// send_usb_log(hello_string);
|
// send_usb_log(hello_string);
|
||||||
//log_usb("TestTestTest");
|
//log_usb("TestTestTest");
|
||||||
// count += 1;
|
// count += 1;
|
||||||
Send_USB_Logs();
|
//}
|
||||||
}
|
|
||||||
|
if (m_send_logs) { Send_USB_Logs(); }
|
||||||
|
|
||||||
UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
|
UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
|
||||||
/* Sleep CPU only if there was no interrupt since last loop processing */
|
/* Sleep CPU only if there was no interrupt since last loop processing */
|
||||||
|
|||||||
@ -46,6 +46,7 @@
|
|||||||
<file file_name="../../../ads1298.h" />
|
<file file_name="../../../ads1298.h" />
|
||||||
<file file_name="../../../main.c" />
|
<file file_name="../../../main.c" />
|
||||||
<file file_name="../config/sdk_config.h" />
|
<file file_name="../config/sdk_config.h" />
|
||||||
|
<file file_name="../../../usb_logging.c" />
|
||||||
</folder>
|
</folder>
|
||||||
<folder Name="Board Definition">
|
<folder Name="Board Definition">
|
||||||
<file file_name="../../../../../../components/boards/boards.c" />
|
<file file_name="../../../../../../components/boards/boards.c" />
|
||||||
|
|||||||
29
usb_logging.c
Normal file
29
usb_logging.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "base/usb_logging.h"
|
||||||
|
|
||||||
|
void reset_log_buffer(void) {
|
||||||
|
// If debug, then memset buffer
|
||||||
|
memset(log_buffer, 0, sizeof(log_buffer));
|
||||||
|
m_log_usage = 0;
|
||||||
|
m_log_buffer_send_index = 0;
|
||||||
|
tx_complete = true;
|
||||||
|
full_tx_complete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_to_log_buffer(String str) {
|
||||||
|
// Bounds check the buffer:
|
||||||
|
if (m_log_usage + str.count >= sizeof(log_buffer)) {
|
||||||
|
// Failure!.. How to handle? Turn on LEDs?
|
||||||
|
return; // Do not add to buffer
|
||||||
|
}
|
||||||
|
memcpy(&log_buffer[m_log_usage], str.data, str.count);
|
||||||
|
m_log_usage += str.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #TODO: Inline
|
||||||
|
void add_format_string_to_log_buffer(void) {
|
||||||
|
// Replace null terminator with \n where required.
|
||||||
|
sprint_buffer[sprint_length] = '\n';
|
||||||
|
String s = {sprint_length+1, sprint_buffer};
|
||||||
|
add_to_log_buffer(s);
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user