Rename project files, add ADS1298 drivers, update .gitignore

This commit is contained in:
Musa Mahmood 2025-03-21 05:19:17 -04:00
parent aa699467f1
commit 44b5e30ded
7 changed files with 732 additions and 56 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
Output/
*.jlink
*.eww
*.eww
*.emSession

369
ads1298.c Normal file
View File

@ -0,0 +1,369 @@
/* Author: Musa Mahmood - JIIM, Inc.
* Date: 11/11/2023
* License: This is proprietary code and may not be used without express written permission.
*/
#include "ads1298.h"
#include "app_util_platform.h"
#include "nrf_delay.h"
#include "app_error.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "nrf_gpio.h"
#include "nrf_drv_gpiote.h"
#include <string.h>
uint8_t ads1298_default_regs[] = {
ADS1298_REGDEFAULT_CONFIG1,
ADS1298_REGDEFAULT_CONFIG2,
ADS1298_REGDEFAULT_CONFIG3,
ADS1298_REGDEFAULT_LOFF,
ADS1298_REGDEFAULT_CH1SET,
ADS1298_REGDEFAULT_CH2SET,
ADS1298_REGDEFAULT_CH3SET,
ADS1298_REGDEFAULT_CH4SET,
ADS1298_REGDEFAULT_CH5SET,
ADS1298_REGDEFAULT_CH6SET,
ADS1298_REGDEFAULT_CH7SET,
ADS1298_REGDEFAULT_CH8SET,
ADS1298_REGDEFAULT_RLD_SENSP,
ADS1298_REGDEFAULT_RLD_SENSN,
ADS1298_REGDEFAULT_LOFF_SENSP,
ADS1298_REGDEFAULT_LOFF_SENSN,
ADS1298_REGDEFAULT_LOFF_FLIP,
ADS1298_REGDEFAULT_LOFF_STATP,
ADS1298_REGDEFAULT_LOFF_STATN,
ADS1298_REGDEFAULT_GPIO,
ADS1298_REGDEFAULT_PACE,
ADS1298_REGDEFAULT_RESP,
ADS1298_REGDEFAULT_CONFIG4,
ADS1298_REGDEFAULT_WCT1,
ADS1298_REGDEFAULT_WCT2
};
// SPI flags:
static volatile bool spi_xfer_done;
static uint8_t rx_buffer[27+2];
// SPI Instance:
static const nrf_drv_spi_t spi0 = NRF_DRV_SPI_INSTANCE(0);
// SPI Event Handler:
static void spi_event_handler(nrf_drv_spi_evt_t const *p_event, void *p_context)
{
spi_xfer_done = true;
#if ADS1298_LOG_DEBUG
NRF_LOG_DEBUG("SPI transfer completed.");
#endif
}
void ads1298_initialize(ble_exg_t *p_exg, ads1298_info_t *p_info) {
NRF_LOG_INFO("Initializing ADS1298...");
// 1. Power up the ADS1298:
ads1298_power_up();
#if ADS1298_LOG_DEBUG
NRF_LOG_FLUSH();
#endif
nrf_drv_spi_config_t spi_config;
memset(&spi_config, 0, sizeof(spi_config));
// 2. Initialize SPI
spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
spi_config.ss_pin = ADS1298_CS_PIN;
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_2M;
spi_config.irq_priority = APP_IRQ_PRIORITY_HIGHEST;
spi_config.mode = NRF_DRV_SPI_MODE_1;
spi_config.orc = 0x55;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi0, &spi_config, spi_event_handler, NULL));
// 3. Stop read data continuous mode (rdatac)
ads1298_stop_rdatac();
#if ADS1298_LOG_DEBUG
NRF_LOG_FLUSH();
#endif
// 4. Init registers:
// Copy default registers into p_exg->ads1298_settings (first 25 bytes)
memset(p_exg->ads1298_settings, 0, ADS1298_SETTINGS_SIZE);
memcpy(p_exg->ads1298_settings, ads1298_default_regs, ADS1298_REGISTER_COUNT);
ads1298_init_default_registers();
#if ADS1298_LOG_DEBUG
NRF_LOG_FLUSH();
#endif
// 5. Soft start:
ads1298_soft_start_conversion();
// 6. Check ID: (sets lower 3 bits of ads1298_settings[25])
ads1298_check_id(p_exg, p_info);
// 7. Start read data continuous mode (rdatac):
ads1298_start_rdatac();
// 8. Place on standby mode:
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
NRF_LOG_FLUSH();
#endif
}
void ads1298_uninitialize(void) {
NRF_LOG_INFO("Uninitializing ADS1298...");
nrf_drv_spi_uninit(&spi0);
}
bool ads1298_check_id(ble_exg_t *p_exg, ads1298_info_t *p_info) {
bool device_found = false;
#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};
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, 2, rx_buf, 6));
while(!spi_xfer_done) {
__WFE();
}
#if ADS1298_LOG_DEBUG
NRF_LOG_INFO("rx_buf[3] = 0x%X", rx_buf[3]);
NRF_LOG_INFO("rx_buf dump:");
NRF_LOG_HEXDUMP_INFO(rx_buf, 6);
#endif
// Check lower 3 bits 0x[...]..[???]
uint8_t nch_check = rx_buf[3] & 0x07; // 0x.....111
p_exg->ads1298_settings[25] |= nch_check;
p_info->nChs = 0;
if (nch_check == ADS129x_4CH_BITMASK) {
p_info->nChs = 4; // ADS1294
} else if (nch_check == ADS129x_6CH_BITMASK) {
p_info->nChs = 6; // ADS1296
} else if (nch_check == ADS129x_8CH_BITMASK) {
p_info->nChs = 8; // ADS1298
} else {
NRF_LOG_ERROR("Expected ADS129xX not detected! E0");
return false;
}
// Check middle bits 0x[...]10[...] < always should be 10
if ((rx_buf[3] & 0x10) != 0x10 || p_info->nChs == 0) {
NRF_LOG_ERROR("Expected ADS129xX not detected! E1");
return false;
}
// Check first three bits: 0x[???]..[...]
uint8_t r_ver_chk = rx_buf[3] & 0xE0;
if (r_ver_chk == ADS129x_DEVICE_FAMILY_BITMASK) {
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);
device_found = true;
p_exg->ads1298_settings[25] &= (~0x08);
} else if (r_ver_chk == ADS129xR_DEVICE_FAMILY_BITMASK) {
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);
p_exg->ads1298_settings[25] |= 0x08;
device_found = true;
} else {
NRF_LOG_ERROR("Expected ADS129xX not detected! E2");
return false;
}
return device_found;
}
// chNumber = 1:8
__STATIC_INLINE bool ads1298_check_channel(ads1298_info_t *p_info, uint8_t chNumber) {
if (chNumber > p_info->nChs) return false;
if (chNumber > 8) {
NRF_LOG_INFO("[ads1298_check_channel] INVALID CHANNEL NUMBER: %d!", chNumber);
return false;
}
return !((p_info->registers[3 + chNumber] & 0x80) == 0x80);
}
void ads1298_update_active_chs(ads1298_info_t *p_info) {
p_info->active_chs = 0;
if (ads1298_check_channel(p_info, 1)) p_info->active_chs |= 0x80;
if (ads1298_check_channel(p_info, 2)) p_info->active_chs |= 0x40;
if (ads1298_check_channel(p_info, 3)) p_info->active_chs |= 0x20;
if (ads1298_check_channel(p_info, 4)) p_info->active_chs |= 0x10;
if (p_info->nChs == 4) return;
if (ads1298_check_channel(p_info, 5)) p_info->active_chs |= 0x08;
if (ads1298_check_channel(p_info, 6)) p_info->active_chs |= 0x04;
if (p_info->nChs == 6) return;
if (ads1298_check_channel(p_info, 7)) p_info->active_chs |= 0x02;
if (ads1298_check_channel(p_info, 8)) p_info->active_chs |= 0x01;
}
void ads1298_update_registers(ads1298_info_t *p_info) {
NRF_LOG_INFO("Updating ADS1298 registers...");
ads1298_update_active_chs(p_info);
uint8_t i = 0; // Register index
uint8_t tx_data[ADS1298_REGISTER_COUNT + 2]; // plus 2 for opcodes
uint8_t rx_data[ADS1298_REGISTER_COUNT + 2];
memset(tx_data, 0, ADS1298_REGISTER_COUNT + 2);
memset(rx_data, 0, ADS1298_REGISTER_COUNT + 2);
// Write Register Opcode | Register Address:
tx_data[0] = ADS1298_OPC_WREG | ADS1298_REGADDR_CONFIG1;
tx_data[1] = ADS1298_REGISTER_COUNT;
// Copy default register values:
memcpy(&tx_data[2], p_info->registers, ADS1298_REGISTER_COUNT);
// 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();
}
#if ADS1298_LOG_DEBUG
NRF_LOG_INFO("[ADS1298] Registers updated!");
#endif
}
void ads1298_init_default_registers(void) {
NRF_LOG_INFO("Initializing ADS1298 registers...");
uint8_t i = 0; // Register index
uint8_t tx_data[ADS1298_REGISTER_COUNT + 2]; // plus 2 for opcodes
uint8_t rx_data[ADS1298_REGISTER_COUNT + 2];
memset(tx_data, 0, ADS1298_REGISTER_COUNT + 2);
memset(rx_data, 0, ADS1298_REGISTER_COUNT + 2);
// Write Register Opcode | Register Address:
tx_data[0] = ADS1298_OPC_WREG | ADS1298_REGADDR_CONFIG1;
tx_data[1] = ADS1298_REGISTER_COUNT;
// Copy default register values:
memcpy(&tx_data[2], ads1298_default_regs, ADS1298_REGISTER_COUNT);
// 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();
}
#if ADS1298_LOG_DEBUG
NRF_LOG_INFO("[ADS1298] Registers initialized.");
#endif
}
// Power controls:
void ads1298_power_down(void) {
nrf_gpio_pin_clear(ADS1298_PWDN_PIN);
nrf_delay_ms(5);
}
void ads1298_power_up(void) {
nrf_gpio_pin_set(ADS1298_PWDN_PIN);
nrf_delay_ms(80);
}
// Standby/Wakeup controls:
void ads1298_wakeup(void) {
NRF_LOG_INFO("Waking up ADS1298...");
uint8_t cmd = ADS1298_OPC_WAKEUP;
uint8_t rx_buf;
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, &cmd, 1, &rx_buf, 1));
while (!spi_xfer_done)
{
__WFE();
}
}
void ads1298_standby(void) {
NRF_LOG_INFO("Placing ADS1298 in standby mode...");
uint8_t cmd = ADS1298_OPC_STANDBY;
uint8_t rx_buf;
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, &cmd, 1, &rx_buf, 1));
while (!spi_xfer_done)
{
__WFE();
}
}
// Start/stop conversions
void ads1298_soft_start_conversion(void) {
NRF_LOG_INFO("[ADS1298] Starting conversion...");
uint8_t cmd = ADS1298_OPC_START;
uint8_t rx_buf;
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, &cmd, 1, &rx_buf, 1));
while (!spi_xfer_done)
{
__WFE();
}
}
void ads1298_start_rdatac(void) {
NRF_LOG_INFO("[ADS1298] Starting Read Data Continuous Mode...");
uint8_t cmd = ADS1298_OPC_RDATAC;
uint8_t rx_buf;
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, &cmd, 1, &rx_buf, 1));
while (!spi_xfer_done)
{
__WFE();
}
}
void ads1298_stop_rdatac(void) {
NRF_LOG_INFO("[ADS1298] Stopping Read Data Continuous Mode...");
uint8_t cmd = ADS1298_OPC_SDATAC;
uint8_t rx_buf;
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi0, &cmd, 1, &rx_buf, 1));
while (!spi_xfer_done)
{
__WFE();
}
}
// __STATIC_INLINE uint8_t get_channel_count_from_settings(uint8_t settings) {
// uint8_t lower_bits = settings & 0x07;
// if (lower_bits == ADS129x_4CH_BITMASK) {
// return 4;
// } else if (lower_bits == ADS129x_6CH_BITMASK) {
// return 6;
// } else if (lower_bits == ADS129x_8CH_BITMASK) {
// return 8;
// }
// }
// 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*/) {
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 & 0x20) == 0x20) memcpy(&p_exg->exg_ch3_buffer[p_exg->data_buffer_count], &rx_buffer[9], 3);
if ((active_chs & 0x10) == 0x10) memcpy(&p_exg->exg_ch4_buffer[p_exg->data_buffer_count], &rx_buffer[12], 3);
if ((active_chs & 0x08) == 0x08) memcpy(&p_exg->exg_ch5_buffer[p_exg->data_buffer_count], &rx_buffer[15], 3);
if ((active_chs & 0x04) == 0x04) memcpy(&p_exg->exg_ch6_buffer[p_exg->data_buffer_count], &rx_buffer[18], 3);
if ((active_chs & 0x02) == 0x02) memcpy(&p_exg->exg_ch7_buffer[p_exg->data_buffer_count], &rx_buffer[21], 3);
if ((active_chs & 0x01) == 0x01) memcpy(&p_exg->exg_ch8_buffer[p_exg->data_buffer_count], &rx_buffer[24], 3);
p_exg->data_buffer_count += 3;
}
// Buffer size depends on version (27 bytes for ADS1298, 21 for ADS1296, and 15 for ADS1294)
void ads1298_get_data(ble_exg_t *p_exg, uint8_t active_chs) {
spi_xfer_done = false;
memset(rx_buffer, 0, 27);
nrf_drv_spi_transfer(&spi0, rx_buffer, 27, rx_buffer, 27);
while (!spi_xfer_done) { __WFE(); }
copy_relevant_data(p_exg, active_chs);
}
void ads1296_get_data(ble_exg_t *p_exg, uint8_t active_chs) {
spi_xfer_done = false;
memset(rx_buffer, 0, 21);
nrf_drv_spi_transfer(&spi0, rx_buffer, 21, rx_buffer, 21);
while (!spi_xfer_done) { __WFE(); }
copy_relevant_data(p_exg, active_chs);
}
void ads1294_get_data(ble_exg_t *p_exg, uint8_t active_chs) {
spi_xfer_done = false;
memset(rx_buffer, 0, 15);
nrf_drv_spi_transfer(&spi0, rx_buffer, 15, rx_buffer, 15);
while (!spi_xfer_done) { __WFE(); }
// Check mode p_exg->ads1298_settings[26] b0
copy_relevant_data(p_exg, active_chs);
}

163
ads1298.h Normal file
View File

@ -0,0 +1,163 @@
#ifndef ADS1298_H_
#define ADS1298_H_
#include <stdint.h>
#include "nrf_drv_spi.h"
// Debug flag for logging:
#define ADS1298_LOG_DEBUG 1
// Testing with nRF52840-DK:
#define ADS1298_MISO_PIN 29
#define ADS1298_DRDY_PIN 12
#define ADS1298_CS_PIN 19
#define ADS1298_SCK_PIN 11
#define ADS1298_MOSI_PIN 26
#define ADS1298_PWDN_PIN 03
// Number of WRITABLE registers (Not inc. ID register)
#define ADS1298_REGISTER_COUNT 25
/** REGISTER ADDRESSES **/
#define ADS1298_REGADDR_ID 0x00
#define ADS1298_REGADDR_CONFIG1 0x01
#define ADS1298_REGADDR_CONFIG2 0x02
#define ADS1298_REGADDR_CONFIG3 0x03
#define ADS1298_REGADDR_LOFF 0x04
#define ADS1298_REGADDR_CH1SET 0x05
#define ADS1298_REGADDR_CH2SET 0x06
#define ADS1298_REGADDR_CH3SET 0x07
#define ADS1298_REGADDR_CH4SET 0x08
#define ADS1298_REGADDR_CH5SET 0x09
#define ADS1298_REGADDR_CH6SET 0x0A
#define ADS1298_REGADDR_CH7SET 0x0B
#define ADS1298_REGADDR_CH8SET 0x0C
#define ADS1298_REGADDR_RLD_SENSP 0x0D
#define ADS1298_REGADDR_RLD_SENSN 0x0E
#define ADS1298_REGADDR_LOFF_SENSP 0x0F
#define ADS1298_REGADDR_LOFF_SENSN 0x10
#define ADS1298_REGADDR_LOFF_FLIP 0x11
#define ADS1298_REGADDR_LOFF_STATP 0x12
#define ADS1298_REGADDR_LOFF_STATN 0x13
#define ADS1298_REGADDR_GPIO 0x14
#define ADS1298_REGADDR_PACE 0x15
#define ADS1298_REGADDR_RESP 0x16
#define ADS1298_REGADDR_CONFIG4 0x17
#define ADS1298_REGADDR_WCT1 0x18
#define ADS1298_REGADDR_WCT2 0x19
/** SPI OPCODES **/
// TODO: Double check!
#define ADS1298_OPC_WAKEUP 0x02 // Wake up from standby.
#define ADS1298_OPC_STANDBY 0x04 // Enter standby.
#define ADS1298_OPC_RESET 0x06 // Reset all registers.
#define ADS1298_OPC_START 0x08 // Start data conversions.
#define ADS1298_OPC_STOP 0x0A // Stop data conversions.
#define ADS1298_OPC_RDATAC 0x10 // Read data continuously (registers cannot be read or written in this mode).
#define ADS1298_OPC_SDATAC 0x11 // Stop continuous data read.
#define ADS1298_OPC_RDATA 0x12 // Read single data value.
#define ADS1298_OPC_RREG 0x20 // Read register value. System must not be in RDATAC mode.
#define ADS1298_OPC_WREG 0x40 // Write register value. System must not be in RDATAC mode.
/** FACTORY IDs FOR ADS129x **/
#define ADS129x_DEVICE_FAMILY_BITMASK 0x80 // 0x[100]10[...]
#define ADS129xR_DEVICE_FAMILY_BITMASK 0xC0 // 0x[110]10[...]
#define ADS129x_4CH_BITMASK 0x00 // 0x[...]10[000]
#define ADS129x_6CH_BITMASK 0x01 // 0x[...]10[001]
#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_CONFIG2 0x00 // Test signals
#define ADS1298_REGDEFAULT_CONFIG3 0x40 //
#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_RLD_SENSP 0x00
#define ADS1298_REGDEFAULT_RLD_SENSN 0x00
#define ADS1298_REGDEFAULT_LOFF_SENSP 0x00
#define ADS1298_REGDEFAULT_LOFF_SENSN 0x00
#define ADS1298_REGDEFAULT_LOFF_FLIP 0x00
#define ADS1298_REGDEFAULT_LOFF_STATP 0x00
#define ADS1298_REGDEFAULT_LOFF_STATN 0x00
#define ADS1298_REGDEFAULT_GPIO 0x0F
#define ADS1298_REGDEFAULT_PACE 0x00
#define ADS1298_REGDEFAULT_RESP 0x00
#define ADS1298_REGDEFAULT_CONFIG4 0x00
#define ADS1298_REGDEFAULT_WCT1 0x00
#define ADS1298_REGDEFAULT_WCT2 0x00
#define ADS1298_BUFFER_SIZE 64
#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 {
uint8_t nChs; // 4, 6, or 8 channels depending on variant.
uint8_t state; // Powered on or off!
uint8_t name_len; // does not include null terminator
// [active_chs] bit-packed array of active channels 1:8:
// Chs: [1,2,3,4,5,6,7,8]. Ch1 active |= 0x80, ch2 |= 0x40 and so on..
uint8_t active_chs;
uint8_t registers[ADS1298_REGISTER_COUNT];
char name[12];
} ads1298_info_t;
/** FUNCTION PROTOTYPES **/
void ads1298_initialize(ble_exg_t *p_exg, ads1298_info_t *p_info);
void ads1298_uninitialize(void);
bool ads1298_check_id(ble_exg_t *p_exg, ads1298_info_t *p_info);
void ads1298_update_registers(ads1298_info_t *p_info);
void ads1298_init_default_registers(void);
void ads1298_power_down(void);
void ads1298_power_up(void);
void ads1298_standby(void);
void ads1298_wakeup(void);
void ads1298_soft_start_conversion(void);
void ads1298_start_rdatac(void);
void ads1298_stop_rdatac(void);
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 ads1298_get_data(ble_exg_t *p_exg, uint8_t active_chs);
#endif // ADS1298_H_

6
main.c
View File

@ -1,9 +1,3 @@
// ~TODO
// [ ] Add SPI files (see: fw-mvp), enable SPI interface.
// [ ] Add ADS1292 driver, and test (just print for now)
// [ ] Increase size of USB receive buffer, and see if we can program the ADS1292 via USB.
//
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

View File

@ -2881,6 +2881,123 @@
#define SAADC_CONFIG_DEBUG_COLOR 0
#endif
// </e>
// <e> NRFX_SPIM_ENABLED - nrfx_spim - SPIM peripheral driver
//==========================================================
#ifndef NRFX_SPIM_ENABLED
#define NRFX_SPIM_ENABLED 0
#endif
// <q> NRFX_SPIM0_ENABLED - Enable SPIM0 instance
#ifndef NRFX_SPIM0_ENABLED
#define NRFX_SPIM0_ENABLED 0
#endif
// <q> NRFX_SPIM1_ENABLED - Enable SPIM1 instance
#ifndef NRFX_SPIM1_ENABLED
#define NRFX_SPIM1_ENABLED 0
#endif
// <q> NRFX_SPIM2_ENABLED - Enable SPIM2 instance
#ifndef NRFX_SPIM2_ENABLED
#define NRFX_SPIM2_ENABLED 0
#endif
// <o> NRFX_SPIM_MISO_PULL_CFG - MISO pin pull configuration.
// <0=> NRF_GPIO_PIN_NOPULL
// <1=> NRF_GPIO_PIN_PULLDOWN
// <3=> NRF_GPIO_PIN_PULLUP
#ifndef NRFX_SPIM_MISO_PULL_CFG
#define NRFX_SPIM_MISO_PULL_CFG 1
#endif
// <o> NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7
#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY
#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif
// <e> NRFX_SPIM_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED
#define NRFX_SPIM_CONFIG_LOG_ENABLED 0
#endif
// <o> NRFX_SPIM_CONFIG_LOG_LEVEL - Default Severity level
// <0=> Off
// <1=> Error
// <2=> Warning
// <3=> Info
// <4=> Debug
#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL
#define NRFX_SPIM_CONFIG_LOG_LEVEL 3
#endif
// <o> NRFX_SPIM_CONFIG_INFO_COLOR - ANSI escape code prefix.
// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White
#ifndef NRFX_SPIM_CONFIG_INFO_COLOR
#define NRFX_SPIM_CONFIG_INFO_COLOR 0
#endif
// <o> NRFX_SPIM_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White
#ifndef NRFX_SPIM_CONFIG_DEBUG_COLOR
#define NRFX_SPIM_CONFIG_DEBUG_COLOR 0
#endif
// </e>
// <q> NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 anomaly 109 workaround for SPIM.
// <i> The workaround uses interrupts to wake up the CPU by catching
// <i> a start event of zero-length transmission to start the clock. This
// <i> ensures that the DMA transfer will be executed without issues and
// <i> that the proper transfer will be started. See more in the Errata
// <i> document or Anomaly 109 Addendum located at
// <i> https://infocenter.nordicsemi.com/
#ifndef NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED
#define NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0
#endif
// </e>
// <e> SPIS_CONFIG_LOG_ENABLED - Enables logging in the module.
@ -2934,6 +3051,80 @@
// </e>
// <e> SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver - legacy layer
//==========================================================
#ifndef SPI_ENABLED
#define SPI_ENABLED 1
#endif
// <o> SPI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7
#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY
#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif
// <o> NRF_SPI_DRV_MISO_PULLUP_CFG - MISO PIN pull-up configuration.
// <0=> NRF_GPIO_PIN_NOPULL
// <1=> NRF_GPIO_PIN_PULLDOWN
// <3=> NRF_GPIO_PIN_PULLUP
#ifndef NRF_SPI_DRV_MISO_PULLUP_CFG
#define NRF_SPI_DRV_MISO_PULLUP_CFG 1
#endif
// <e> SPI0_ENABLED - Enable SPI0 instance
//==========================================================
#ifndef SPI0_ENABLED
#define SPI0_ENABLED 1
#endif
// <q> SPI0_USE_EASY_DMA - Use EasyDMA
#ifndef SPI0_USE_EASY_DMA
#define SPI0_USE_EASY_DMA 1
#endif
// </e>
// <e> SPI1_ENABLED - Enable SPI1 instance
//==========================================================
#ifndef SPI1_ENABLED
#define SPI1_ENABLED 0
#endif
// <q> SPI1_USE_EASY_DMA - Use EasyDMA
#ifndef SPI1_USE_EASY_DMA
#define SPI1_USE_EASY_DMA 1
#endif
// </e>
// <e> SPI2_ENABLED - Enable SPI2 instance
//==========================================================
#ifndef SPI2_ENABLED
#define SPI2_ENABLED 1
#endif
// <q> SPI2_USE_EASY_DMA - Use EasyDMA
#ifndef SPI2_USE_EASY_DMA
#define SPI2_USE_EASY_DMA 1
#endif
// </e>
// <e> SPI_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef SPI_CONFIG_LOG_ENABLED

View File

@ -1,5 +1,5 @@
<!DOCTYPE CrossStudio_Project_File>
<solution Name="usbd_cdc_acm_pca10056" target="8" version="2">
<solution Name="Multimodal_CV_USB_ADS1298R_pca10056" target="8" version="2">
<configuration
Name="Debug"
c_preprocessor_definitions="DEBUG; DEBUG_NRF"
@ -9,7 +9,7 @@
c_preprocessor_definitions="NDEBUG"
gcc_optimization_level="Optimize For Size"
link_time_optimization="No" />
<project Name="usbd_cdc_acm_pca10056">
<project Name="Multimodal_CV_USB_ADS1298R_pca10056">
<configuration
Name="Common"
arm_architecture="v7EM"
@ -42,6 +42,8 @@
project_directory=""
project_type="Executable" />
<folder Name="Application">
<file file_name="../../../ads1298.c" />
<file file_name="../../../ads1298.h" />
<file file_name="../../../main.c" />
<file file_name="../config/sdk_config.h" />
</folder>
@ -60,6 +62,7 @@
<folder Name="nRF_Drivers">
<file file_name="../../../../../../integration/nrfx/legacy/nrf_drv_clock.c" />
<file file_name="../../../../../../integration/nrfx/legacy/nrf_drv_power.c" />
<file file_name="../../../../../../integration/nrfx/legacy/nrf_drv_spi.c" />
<file file_name="../../../../../../integration/nrfx/legacy/nrf_drv_uart.c" />
<file file_name="../../../../../../components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c" />
<file file_name="../../../../../../components/drivers_nrf/nrf_soc_nosd/nrf_soc.c" />
@ -68,6 +71,8 @@
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_gpiote.c" />
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_power.c" />
<file file_name="../../../../../../modules/nrfx/drivers/src/prs/nrfx_prs.c" />
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_spi.c" />
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_spim.c" />
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_systick.c" />
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_uart.c" />
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_uarte.c" />

View File

@ -1,47 +0,0 @@
<!DOCTYPE CrossStudio_Session_File>
<session>
<Bookmarks/>
<Breakpoints groups="Breakpoints" active_group="Breakpoints"/>
<ExecutionProfileWindow/>
<FrameBuffer/>
<Memory1/>
<Memory2/>
<Memory3/>
<Memory4/>
<Project>
<ProjectSessionItem path="usbd_cdc_acm_pca10056"/>
<ProjectSessionItem path="usbd_cdc_acm_pca10056;usbd_cdc_acm_pca10056"/>
<ProjectSessionItem path="usbd_cdc_acm_pca10056;usbd_cdc_acm_pca10056;Application"/>
<ProjectSessionItem path="usbd_cdc_acm_pca10056;usbd_cdc_acm_pca10056;nRF_Drivers"/>
<ProjectSessionItem path="usbd_cdc_acm_pca10056;usbd_cdc_acm_pca10056;nRF_Libraries"/>
<ProjectSessionItem path="usbd_cdc_acm_pca10056;usbd_cdc_acm_pca10056;Segger Startup Files"/>
</Project>
<Register1/>
<Register2/>
<Register3/>
<Register4/>
<Threads>
<ThreadsWindow showLists=""/>
</Threads>
<TraceWindow>
<Trace enabled="Yes"/>
</TraceWindow>
<Watch1>
<Watches active="1" update="Never"/>
</Watch1>
<Watch2>
<Watches active="0" update="Never"/>
</Watch2>
<Watch3>
<Watches active="0" update="Never"/>
</Watch3>
<Watch4>
<Watches active="0" update="Never"/>
</Watch4>
<Files>
<SessionOpenFile windowGroup="DockEditLeft" x="9" y="97" useTextEdit="1" path="../../../main.c" left="0" selected="1" top="46" codecName="Default"/>
<SessionOpenFile windowGroup="DockEditLeft" x="4" y="103" useTextEdit="1" openedFrom="D:/Firmware/nRF5_SDK_17.1.0/1.Musa/fw_in_progress/musa_usbd_cdc_acm/main.c" path="../../../../../../components/libraries/usbd/class/cdc/app_usbd_cdc_types.h" left="0" top="64" codecName="Default"/>
<SessionOpenFile windowGroup="DockEditLeft" x="30" y="1425" useTextEdit="1" path="../config/sdk_config.h" left="0" top="1425" codecName="Default"/>
</Files>
<EMStudioWindow activeProject="usbd_cdc_acm_pca10056" fileDialogDefaultFilter="*.c" autoConnectTarget="J-Link" buildConfiguration="Release" sessionSettings="" debugSearchFileMap="" fileDialogInitialDirectory="" debugSearchPath="" autoConnectCapabilities="3711"/>
</session>