|
|
#include "znordic.h"
//
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
#include "app_ble_service.h"
#include "app_event_distribute.h"
#include "basic/ads1293/ads1293.h"
#include "board/board.h"
#include "board/board_beep_ctrl.h"
#include "board/board_light_ctrl.h"
#include "device_ctrl_service.h"
#include "nrf_drv_gpiote.h"
#include "sample_data_manager_service.h"
#include "zble_module.h"
#include "zdatachannel_service.h"
#include "znordic_device_info_mgr.h"
//
ZDATACHANNEL_DEF(m_zhrs, 2 /*���ȼ�*/, 1 /*client num*/); static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ADS1293_SPI_INSTANCE); /**< SPI instance. */ static ads1293_t m_ads1293_0; // U2
static ads1293_t m_ads1293_1; typedef struct { uint8_t add; uint8_t data; } adscfg_t;
static adscfg_t m_prvads0cfg_cache[65]; static adscfg_t m_prvads1cfg_cache[65];
static void zdatachannel_data_handler(zdatachannel_evt_t* p_evt) {} void blechannel_service_init() { ZLOGI("init zdatachannel service"); static zdatachannel_init_t zdatachannle_init; memset(&zdatachannle_init, 0, sizeof(zdatachannle_init)); zdatachannle_init.data_handler = zdatachannel_data_handler; ZERROR_CHECK(zdatachannel_init(&m_zhrs, &zdatachannle_init)); } static void ads1293_spi_tx_rx_0(uint8_t* tx, uint8_t* rx, uint8_t len) { nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN); nrf_drv_spi_transfer(&spi, tx, len, rx, len); nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); } static void ads1293_spi_tx_rx_1(uint8_t* tx, uint8_t* rx, uint8_t len) { nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN); nrf_drv_spi_transfer(&spi, tx, len, rx, len); nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); } static void ads1293_spi_writereg_and_check(ads1293_t* ads, uint8_t addr, uint8_t data) { uint8_t readbak = 0; // readonly add
readbak = data; if (addr >= 0x18 && addr <= 0x1E) { return; } if (addr >= 0x30 && addr <= 0x3f) { return; } if (addr == 0x40) { return; } if (addr == 0x50) { return; } ads1293_spi_writereg_and_readbak(ads, addr, data, &readbak); if (readbak != data) { ZLOGE("ads_%d write %x failed,w:%x readbak:%x\n", ads->id, addr, data, readbak); } } static void tryloadcfg_from_fatfs(const char* file, adscfg_t* cfg, uint16_t cfgsize, uint16_t* cfg_ret_size) { //
*cfg_ret_size = 0;
static FIL fd; FRESULT ff_result = f_open(&fd, (const TCHAR*)file, FA_READ); if (ff_result != FR_OK) { ZLOGE("open %s failed\n", file); return; }
char line[128]; int niterm = 0; f_gets(line, 128, &fd);
while (f_gets(line, 128, &fd)) { uint32_t addr; uint32_t value; sscanf(line, "%x,%x", &addr, &value); cfg[niterm].add = addr; cfg[niterm].data = value; niterm++;
if (niterm >= cfgsize) { break; } } *cfg_ret_size = niterm; ZLOGI("load %s cfg size:%d\n", file, niterm); f_close(&fd); }
uint32_t get_ready_pin_state_get() { return nrf_gpio_pin_read(ADS1293_READY_PIN); }
static adscfg_t m_prvads0cfg[] = //
{ {0x00, 0x00}, {0x01, 0x19}, {0x02, 0x11}, {0x03, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x0f}, {0x08, 0xff}, {0x09, 0x00}, {0x0a, 0x07}, {0x0b, 0x07}, {0x0c, 0x74}, {0x0d, 0x01}, {0x0e, 0x02}, {0x0f, 0x03}, {0x10, 0x04}, {0x11, 0x00}, {0x12, 0x05}, {0x13, 0x39}, {0x14, 0x36}, {0x15, 0x06}, {0x16, 0x00}, {0x17, 0x05}, {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, {0x1c, 0x00}, {0x1d, 0x00}, {0x21, 0x01}, {0x22, 0x20}, {0x23, 0x20}, {0x24, 0x02}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x08}, {0x28, 0x08}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x33}, {0x2f, 0x30}, {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, {0x40, 0xff}, {0x50, 0x00}, {0x60, 0x00}, {0x62, 0x00}, };
static adscfg_t m_prvads1cfg[] = //
{ {0x00, 0x00}, {0x01, 0x0c}, {0x02, 0x14}, {0x03, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x0b}, {0x08, 0xff}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x07}, {0x0c, 0x78}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, {0x10, 0x04}, {0x11, 0x00}, {0x12, 0x06}, {0x13, 0x3b}, {0x14, 0x24}, {0x15, 0x04}, {0x16, 0x00}, {0x17, 0x05}, {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, {0x1c, 0x00}, {0x1d, 0x00}, {0x21, 0x01}, {0x22, 0x20}, {0x23, 0x20}, {0x24, 0x02}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x40}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x33}, {0x2f, 0x30}, {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00}, {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, {0x40, 0xff}, {0x50, 0x00}, {0x60, 0x00}, {0x62, 0x00}, };
static void ads1293_init() { /*******************************************************************************
* SPI��ʼ�� * *******************************************************************************/ static nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; // NRF_DRV_SPI_PIN_NOT_USED
spi_config.miso_pin = ADS1293_SPI_MISO_PIN; spi_config.mosi_pin = ADS1293_SPI_MOSI_PIN; spi_config.sck_pin = ADS1293_SPI_SCK_PIN; spi_config.frequency = NRF_DRV_SPI_FREQ_8M; spi_config.mode = NRF_DRV_SPI_MODE_3; // spi_config.mode =
ZERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL));
znrf_gpio_cfg_output(ADS1293_SPI_CS0_PIN, NRF_GPIO_PIN_NOPULL); znrf_gpio_cfg_output(ADS1293_SPI_CS1_PIN, NRF_GPIO_PIN_NOPULL); nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN);
m_ads1293_0.spi_tx_rx = ads1293_spi_tx_rx_0; m_ads1293_0.id = 0; m_ads1293_1.spi_tx_rx = ads1293_spi_tx_rx_1; m_ads1293_1.id = 1;
ads1293_spi_init(&m_ads1293_0, ads1293_spi_tx_rx_0); ads1293_spi_init(&m_ads1293_1, ads1293_spi_tx_rx_1);
uint8_t revid = ads1293_spi_readreg(&m_ads1293_0, TI_ADS1293_REVID_REG); ZLOGI("ads1293_0 revid: %d\n", revid); revid = ads1293_spi_readreg(&m_ads1293_1, TI_ADS1293_REVID_REG); ZLOGI("ads1293_1 revid: %d\n", revid);
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_CONFIG_REG, 0);
uint16_t cfgsize = 0; tryloadcfg_from_fatfs("0.cfg", m_prvads0cfg_cache, ZARRAY_SIZE(m_prvads0cfg_cache), &cfgsize); if (cfgsize > 0) { ZLOGI("load 0.cfg from fatfs\n");
if (memcmp(m_prvads0cfg_cache, m_prvads0cfg, sizeof(m_prvads0cfg)) != 0) { ZLOGI("0.cfg is different from default\n"); } else { ZLOGI("0.cfg is same as default\n"); }
for (uint16_t i = 0; i < cfgsize; i++) { ads1293_spi_writereg_and_check(&m_ads1293_0, m_prvads0cfg_cache[i].add, m_prvads0cfg_cache[i].data); } } else { for (uint16_t i = 0; i < ZARRAY_SIZE(m_prvads0cfg); i++) { ads1293_spi_writereg_and_check(&m_ads1293_0, m_prvads0cfg[i].add, m_prvads0cfg[i].data); } } #if 1
tryloadcfg_from_fatfs("1.cfg", m_prvads1cfg_cache, ZARRAY_SIZE(m_prvads1cfg_cache), &cfgsize); if (cfgsize > 0) { ZLOGI("load 1.cfg from fatfs\n");
if (memcmp(m_prvads1cfg_cache, m_prvads1cfg, sizeof(m_prvads1cfg)) != 0) { ZLOGI("1.cfg is different from default\n"); } else { ZLOGI("1.cfg is same as default\n"); }
for (uint16_t i = 0; i < cfgsize; i++) { ads1293_spi_writereg_and_check(&m_ads1293_1, m_prvads1cfg_cache[i].add, m_prvads1cfg_cache[i].data); } } else { for (uint16_t i = 0; i < ZARRAY_SIZE(m_prvads1cfg); i++) { ads1293_spi_writereg_and_check(&m_ads1293_1, m_prvads1cfg[i].add, m_prvads1cfg[i].data); } } #endif
}
static void onServiceInitCB() { ZLOGI("init zdatachannel service"); static zdatachannel_init_t zdatachannle_init; memset(&zdatachannle_init, 0, sizeof(zdatachannle_init)); zdatachannle_init.data_handler = zdatachannel_data_handler; ZERROR_CHECK(zdatachannel_init(&m_zhrs, &zdatachannle_init)); }
void setup(); int main() { APP_SCHED_INIT(APP_MAX_EVEN_SIZE, APP_EVENT_QUEUE_SIZE); znordic_init(); NRF_LOG_INFO("compile time :%s", __TIME__); ZLOGI("CUSTOMER :%d", NRF_UICR->CUSTOMER[0]); /*******************************************************************************
* ����������ʼ�� * *******************************************************************************/ static zble_module_cfg_t cfg; cfg.deviceName = "ADS1293_TESTER_3CH_V2"; cfg.on_service_init = onServiceInitCB; zble_module_init(&cfg); AppBleService_init();
// znordic_loop();
setup(); }
static ads1293_error_t error0; static ads1293_error_t error1; static uint8_t txcache[128];
void send_ads1293_error_state(ads1293_error_t* e0, ads1293_error_t* e1) { //
txcache[0] = 0xA1; txcache[1] = 0x01; memcpy(txcache + 2, e0, sizeof(ads1293_error_t)); memcpy(txcache + 2 + sizeof(ads1293_error_t), e1, sizeof(ads1293_error_t));
zdatachannel_data_send2(txcache, 2 + sizeof(ads1293_error_t) * 2); }
void capture_error_state() { ads1293_read_error(&m_ads1293_0, &error0); ads1293_read_error(&m_ads1293_1, &error1);
#if 0
error0.estatus =1; error0.error_range1 =2; error0.error_range2 =3; error0.error_range3 =4; error0.error_sync =5; error0.error_misc =6;
error1.estatus =21; error1.error_range1 =22; error1.error_range2 =23; error1.error_range3 =24; error1.error_sync =25; error1.error_misc =26; #endif
send_ads1293_error_state(&error0, &error1); } #pragma pack(1)
typedef struct { uint32_t sample0; } one_ch_cache_t; typedef struct { uint8_t h1; uint8_t h2; one_ch_cache_t data[3]; uint8_t e1; uint8_t e2; } one_frame_cache_t;
typedef struct { one_frame_cache_t frame[8]; } one_packet_t;
#pragma unpack()
one_packet_t txpacket; int cache_data_size = 0;
void trigger_capture() { static uint32_t sample[6]; static uint8_t readystatus[2] = {0}; ads1293_read_ecgs(&m_ads1293_0, &sample[0]); ads1293_read_ecgs(&m_ads1293_1, &sample[3]);
// static int i = 0;
// static int j = 0;
// i++;
// if (i % 8 == 0) {
// j++;
// }
// sample[0] = j;
// sample[3] = j;
// sample[4] = j;
if (zdatachannel_is_connected()) { if (BoardLight_getGreenLightEffect() != kLightEffect_open) BoardLight_setGreenLightEffect(kLightEffect_open); } else { if (BoardLight_getGreenLightEffect() != kLightEffect_slowFlash) BoardLight_setGreenLightEffect(kLightEffect_slowFlash); }
{ txpacket.frame[cache_data_size].h1 = 0xA2; txpacket.frame[cache_data_size].h2 = 0x2; txpacket.frame[cache_data_size].data[0].sample0 = sample[0]; txpacket.frame[cache_data_size].data[1].sample0 = sample[3]; txpacket.frame[cache_data_size].data[2].sample0 = sample[4]; txpacket.frame[cache_data_size].e1 = 0x2; txpacket.frame[cache_data_size].e2 = 0xA2;
cache_data_size++; if (cache_data_size == 8) { zdatachannel_data_send2((uint8_t*)&txpacket, sizeof(one_packet_t)); cache_data_size = 0; } } } uint32_t m_changecount = 0; static void ads1293_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { //
m_changecount++; trigger_capture(); }
// static void ads1293_spi_tx_rx_0(uint8_t* tx, uint8_t* rx, uint8_t len) {
// nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN);
// nrf_drv_spi_transfer(&spi, tx, len, rx, len);
// nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN);
// }
// static void ads1293_spi_tx_rx_1(uint8_t* tx, uint8_t* rx, uint8_t len) {
// nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN);
// nrf_drv_spi_transfer(&spi, tx, len, rx, len);
// nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN);
// }
static void ads1293_start_all_conversion() { nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN); nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN);
uint8_t txcache[2]; txcache[0] = ADS1293_WRITE_BIT & TI_ADS1293_CONFIG_REG; txcache[1] = 0x01; nrf_drv_spi_transfer(&spi, txcache, 2, NULL, 0);
nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); }
void setup() { //
zble_module_start_adv(); SampleDataMgr_init(); SampleDataMgr_changeToLocalMode(); ads1293_init(); SampleDataMgr_changeToExtMode();
BoardBeepCtrl_init(); BoardLight_Init(); BoardBeepCtrl_load(); BoardLight_setGreenLightEffect(kLightEffect_slowFlash); BoardBeepCtrl_setEffect(kBoardBeepEffect_threeShortBeep);
// ads1293_start_conversion(&m_ads1293_0);
// ads1293_start_conversion(&m_ads1293_1);
nrf_gpio_cfg_input(ADS1293_READY_PIN, NRF_GPIO_PIN_PULLUP);
{ nrf_gpio_cfg_input(ADS1293_READY_PIN, NRF_GPIO_PIN_PULLUP); ZERROR_CHECK(nrfx_gpiote_init()); nrf_drv_gpiote_in_config_t inConfig = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); // ˫�����жϴ���
inConfig.pull = NRF_GPIO_PIN_PULLUP; // Ĭ������
inConfig.sense = NRF_GPIOTE_POLARITY_HITOLO; // �½��ش���
ZERROR_CHECK(nrfx_gpiote_in_init(ADS1293_READY_PIN, &inConfig, ads1293_ready_pin_irq)); nrfx_gpiote_in_event_enable(ADS1293_READY_PIN, true); }
ads1293_start_all_conversion();
while (true) { app_sched_execute(); NRF_LOG_PROCESS();
static bool state = false; static uint32_t last_ticket = 0;
bool now = get_ready_pin_state_get(); uint32_t nowticket = znordic_getpower_on_s();
// if (state != now) {
// state = now;
// m_changecount++;
// if (now) {
// // trigger_capture();
// }
// }
if (last_ticket != nowticket) { last_ticket = nowticket; ZLOGI("%d changecount:%d\n", znordic_getpower_on_ms(), m_changecount);
capture_error_state(); m_changecount = 0; } } }
|