37 changed files with 237 additions and 2552 deletions
-
3.gitmodules
-
3.vscode/settings.json
-
258app/app.uvoptx
-
78app/app.uvprojx
-
9app/main.c
-
4app/main.hardtest.c
-
99app/src/basic/ads1293/ads1293.c
-
124app/src/basic/ads1293/ads1293.h
-
350app/src/basic/board.c
-
67app/src/basic/board.h
-
10app/src/basic/device_info_mgr.c
-
13app/src/basic/device_info_mgr.h
-
0app/src/basic/heart_rate_sensor.c
-
190app/src/basic/heart_rate_sensor_protocol.h
-
3app/src/basic/project_cfg.h
-
237app/src/basic/zble_module.c
-
20app/src/basic/zble_module.h
-
225app/src/basic/zdatachannel_service.c
-
96app/src/basic/zdatachannel_service.h
-
24app/src/board/board.h
-
24app/src/one_conduction/ble_cmd_process_service.c
-
1app/src/one_conduction/ble_cmd_process_service.h
-
21app/src/one_conduction/config.h
-
16app/src/one_conduction/heart_wave_sample_service.c
-
17app/src/one_conduction/one_conduction_main.c
-
101app/src/three_lead/TI_ADS1293_register_settings.h
-
148app/src/three_lead/ads_cfg.h
-
538app/src/three_lead/three_lead_board.c
-
56app/src/three_lead/three_lead_board.h
-
0app/src/three_lead/three_lead_main.c
-
48ble_app_uart_c/ble_app_uart_c_pca10100_s122.uvguix.h_zha
-
1ify_hrs_protocol
-
2libznordic
-
1sample_bin_parser/README.md
-
0sample_bin_parser/sample_bin_parse.c
-
2sdk
@ -1,99 +0,0 @@ |
|||
/* |
|||
* ADS1293.h |
|||
* |
|||
* Created on: Jun 6, 2022 |
|||
* Author: Hans Hüttmann |
|||
*/ |
|||
#include "ads1293.h" |
|||
|
|||
#include <stdbool.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
static uint8_t txcache[256]; |
|||
static uint8_t rxcache[256]; |
|||
|
|||
void ads1293_spi_init(ads1293_t* ads, ads1293_spi_tx_rx_t spi_tx_rx) { ads->spi_tx_rx = spi_tx_rx; } |
|||
|
|||
void ads1293_spi_writereg(ads1293_t* ads, uint8_t addr, uint8_t data) { |
|||
uint8_t txcache[2]; |
|||
txcache[0] = ADS1293_WRITE_BIT & addr; |
|||
txcache[1] = data; |
|||
ads->spi_tx_rx(txcache, NULL, 2); |
|||
} |
|||
uint8_t ads1293_spi_readreg(ads1293_t* ads, uint8_t addr) { |
|||
uint8_t txcache[2]; |
|||
txcache[0] = ADS1293_READ_BIT | addr; |
|||
txcache[1] = 0; |
|||
uint8_t rxcache[2]; |
|||
ads->spi_tx_rx(txcache, rxcache, 2); |
|||
return rxcache[1]; |
|||
} |
|||
void ads1293_spi_writereg_and_readbak(ads1293_t* ads, uint8_t addr, uint8_t data, uint8_t* readbak) { |
|||
ads1293_spi_writereg(ads, addr, data); |
|||
*readbak = ads1293_spi_readreg(ads, addr); |
|||
} |
|||
|
|||
void ads1293_spi_autoinc_writereg(ads1293_t* ads, uint8_t addr, uint8_t* data, uint8_t len) { // |
|||
len = len > 255 ? 255 : len; |
|||
uint8_t addbyte = ADS1293_WRITE_BIT & addr; |
|||
|
|||
txcache[0] = addbyte; |
|||
memcpy(txcache + 1, data, len); |
|||
|
|||
ads->spi_tx_rx(txcache, NULL, len + 1); |
|||
} |
|||
void ads1293_spi_autoinc_readreg(ads1293_t* ads, uint8_t addr, uint8_t* data, uint8_t len) { |
|||
len = len > 255 ? 255 : len; |
|||
uint8_t addbyte = ADS1293_READ_BIT | addr; |
|||
|
|||
txcache[0] = addbyte; |
|||
memset(txcache + 1, 0, len); |
|||
|
|||
ads->spi_tx_rx(txcache, rxcache, len + 1); |
|||
|
|||
memcpy(data, rxcache + 1, len); |
|||
} |
|||
void ads1293_spi_stream_readreg(ads1293_t* ads, uint8_t* data, uint8_t len) { |
|||
len = len > 255 ? 255 : len; |
|||
|
|||
memset(txcache, 0, len); |
|||
memset(rxcache, 0, len); |
|||
|
|||
uint8_t addbyte = ADS1293_READ_BIT | TI_ADS1293_DATA_LOOP_REG; |
|||
|
|||
ads->spi_tx_rx(&addbyte, rxcache, len); |
|||
memcpy(data, rxcache, len); |
|||
} |
|||
|
|||
void ads1293_read_ecg(ads1293_t* ads, uint32_t ch, uint32_t* data) { |
|||
uint8_t add = 0; |
|||
if (ch == 1) { |
|||
add = TI_ADS1293_DATA_CH1_ECG_H_REG; |
|||
} else if (ch == 2) { |
|||
add = TI_ADS1293_DATA_CH2_ECG_H_REG; |
|||
} else if (ch == 3) { |
|||
add = TI_ADS1293_DATA_CH3_ECG_H_REG; |
|||
} else { |
|||
return; |
|||
} |
|||
|
|||
uint8_t readbak[3] = {0}; |
|||
ads1293_spi_autoinc_readreg(ads, add, readbak, 3); |
|||
|
|||
*data = 0; |
|||
*data = (readbak[0] << 16) + (readbak[0] << 8) + (readbak[0] << 0); |
|||
} |
|||
|
|||
void ads1293_start_conversion(ads1293_t* ads) { |
|||
uint8_t data = 0; |
|||
data = 0x01; |
|||
ads1293_spi_writereg(ads, TI_ADS1293_CONFIG_REG, data); |
|||
} |
|||
void ads1293_start_power_off(ads1293_t* ads) { |
|||
uint8_t data = 0; |
|||
data |= 0x01 << 2; |
|||
ads1293_spi_writereg(ads, TI_ADS1293_CONFIG_REG, data); |
|||
} |
|||
|
|||
uint8_t ads1293_read_error_lod(ads1293_t* ads) { return ads1293_spi_readreg(ads, TI_ADS1293_ERROR_LOD_REG); } |
@ -1,124 +0,0 @@ |
|||
//---------------------------------------------------------------------------- |
|||
// Description: This file contains definitions specific to the ADS1293. |
|||
// All the ADS1293 registers are defined as well as some common masks |
|||
// for these registers. |
|||
// |
|||
// MSP430/ADS1293 Interface Code Library v1.0 |
|||
// |
|||
// Vishy Natarajan |
|||
// Texas Instruments Inc. |
|||
// April 2013 |
|||
// Built with IAR Embedded Workbench Version: 5.5x |
|||
//------------------------------------------------------------------------------ |
|||
// Change Log: |
|||
//------------------------------------------------------------------------------ |
|||
// Version: 1.00 |
|||
// Comments: Initial Release Version |
|||
//------------------------------------------------------------------------------ |
|||
#ifndef HEADER_FILE_TI_ADS1293_H |
|||
|
|||
#define HEADER_FILE_TI_ADS1293_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
/************************************************************ |
|||
* TI ADS1293 REGISTER SET ADDRESSES |
|||
************************************************************/ |
|||
|
|||
#define TI_ADS1293_CONFIG_REG (0x00) /* Main Configuration */ |
|||
|
|||
#define TI_ADS1293_FLEX_CH1_CN_REG (0x01) /* Flex Routing Swich Control for Channel 1 */ |
|||
#define TI_ADS1293_FLEX_CH2_CN_REG (0x02) /* Flex Routing Swich Control for Channel 2 */ |
|||
#define TI_ADS1293_FLEX_CH3_CN_REG (0x03) /* Flex Routing Swich Control for Channel 3 */ |
|||
#define TI_ADS1293_FLEX_PACE_CN_REG (0x04) /* Flex Routing Swich Control for Pace Channel */ |
|||
#define TI_ADS1293_FLEX_VBAT_CN_REG (0x05) /* Flex Routing Swich Control for Battery Monitoriing */ |
|||
|
|||
#define TI_ADS1293_LOD_CN_REG (0x06) /* Lead Off Detect Control */ |
|||
#define TI_ADS1293_LOD_EN_REG (0x07) /* Lead Off Detect Enable */ |
|||
#define TI_ADS1293_LOD_CURRENT_REG (0x08) /* Lead Off Detect Current */ |
|||
#define TI_ADS1293_LOD_AC_CN_REG (0x09) /* AC Lead Off Detect Current */ |
|||
|
|||
#define TI_ADS1293_CMDET_EN_REG (0x0A) /* Common Mode Detect Enable */ |
|||
#define TI_ADS1293_CMDET_CN_REG (0x0B) /* Commond Mode Detect Control */ |
|||
#define TI_ADS1293_RLD_CN_REG (0x0C) /* Right Leg Drive Control */ |
|||
|
|||
#define TI_ADS1293_WILSON_EN1_REG (0x0D) /* Wilson Reference Input one Selection */ |
|||
#define TI_ADS1293_WILSON_EN2_REG (0x0E) /* Wilson Reference Input two Selection */ |
|||
#define TI_ADS1293_WILSON_EN3_REG (0x0F) /* Wilson Reference Input three Selection */ |
|||
#define TI_ADS1293_WILSON_CN_REG (0x10) /* Wilson Reference Input Control */ |
|||
|
|||
#define TI_ADS1293_REF_CN_REG (0x11) /* Internal Reference Voltage Control */ |
|||
|
|||
#define TI_ADS1293_OSC_CN_REG (0x12) /* Clock Source and Output Clock Control */ |
|||
|
|||
#define TI_ADS1293_AFE_RES_REG (0x13) /* Analog Front-End Frequency and Resolution */ |
|||
#define TI_ADS1293_AFE_SHDN_CN_REG (0x14) /* Analog Front-End Shutdown Control */ |
|||
#define TI_ADS1293_AFE_FAULT_CN_REG (0x15) /* Analog Front-End Fault Detection Control */ |
|||
#define TI_ADS1293_AFE_DITHER_EN_REG (0x16) /* Enable Dithering in Signma-Delta */ |
|||
#define TI_ADS1293_AFE_PACE_CN_REG (0x17) /* Analog Pace Channel Output Routing Control */ |
|||
|
|||
#define TI_ADS1293_ERROR_LOD_REG (0x18) /* Lead Off Detect Error Status */ |
|||
#define TI_ADS1293_ERROR_STATUS_REG (0x19) /* Other Error Status */ |
|||
#define TI_ADS1293_ERROR_RANGE1_REG (0x1A) /* Channel 1 Amplifier Out of Range Status */ |
|||
#define TI_ADS1293_ERROR_RANGE2_REG (0x1B) /* Channel 1 Amplifier Out of Range Status */ |
|||
#define TI_ADS1293_ERROR_RANGE3_REG (0x1C) /* Channel 1 Amplifier Out of Range Status */ |
|||
#define TI_ADS1293_ERROR_SYNC_REG (0x1D) /* Synchronization Error */ |
|||
|
|||
#define TI_ADS1293_R2_RATE_REG (0x21) /* R2 Decimation Rate */ |
|||
#define TI_ADS1293_R3_RATE1_REG (0x22) /* R3 Decimation Rate for Channel 1 */ |
|||
#define TI_ADS1293_R3_RATE2_REG (0x23) /* R3 Decimation Rate for Channel 2 */ |
|||
#define TI_ADS1293_R3_RATE3_REG (0x24) /* R3 Decimation Rate for Channel 3 */ |
|||
#define TI_ADS1293_P_DRATE_REG (0x25) /* 2x Pace Data Rate */ |
|||
#define TI_ADS1293_DIS_EFILTER_REG (0x26) /* ECG Filter Disable */ |
|||
#define TI_ADS1293_DRDYB_SRC_REG (0x27) /* Data Ready Pin Source */ |
|||
#define TI_ADS1293_SYNCOUTB_SRC_REG (0x28) /* Sync Out Pin Source */ |
|||
#define TI_ADS1293_MASK_DRDYB_REG (0x29) /* Optional Mask Control for DRDYB Output */ |
|||
#define TI_ADS1293_MASK_ERR_REG (0x2A) /* Mask Error on ALARMB Pin */ |
|||
|
|||
#define TI_ADS1293_ALARM_FILTER_REG (0x2E) /* Digital Filter for Analog Alarm Signals */ |
|||
#define TI_ADS1293_CH_CNFG_REG (0x2F) /* Configure Channel for Loop Read Back Mode */ |
|||
|
|||
#define TI_ADS1293_DATA_STATUS_REG (0x30) /* ECG and Pace Data Ready Status */ |
|||
#define TI_ADS1293_DATA_CH1_PACE_H_REG (0x31) /* Channel1 Pace Data High [15:8] */ |
|||
#define TI_ADS1293_DATA_CH1_PACE_L_REG (0x32) /* Channel1 Pace Data Low [7:0] */ |
|||
#define TI_ADS1293_DATA_CH2_PACE_H_REG (0x33) /* Channel2 Pace Data High [15:8] */ |
|||
#define TI_ADS1293_DATA_CH2_PACE_L_REG (0x34) /* Channel2 Pace Data Low [7:0] */ |
|||
#define TI_ADS1293_DATA_CH3_PACE_H_REG (0x35) /* Channel3 Pace Data High [15:8] */ |
|||
#define TI_ADS1293_DATA_CH3_PACE_L_REG (0x36) /* Channel3 Pace Data Low [7:0] */ |
|||
#define TI_ADS1293_DATA_CH1_ECG_H_REG (0x37) /* Channel1 ECG Data High [23:16] */ |
|||
#define TI_ADS1293_DATA_CH1_ECG_M_REG (0x38) /* Channel1 ECG Data Medium [15:8] */ |
|||
#define TI_ADS1293_DATA_CH1_ECG_L_REG (0x39) /* Channel1 ECG Data Low [7:0] */ |
|||
#define TI_ADS1293_DATA_CH2_ECG_H_REG (0x3A) /* Channel2 ECG Data High [23:16] */ |
|||
#define TI_ADS1293_DATA_CH2_ECG_M_REG (0x3B) /* Channel2 ECG Data Medium [15:8] */ |
|||
#define TI_ADS1293_DATA_CH2_ECG_L_REG (0x3C) /* Channel2 ECG Data Low [7:0] */ |
|||
#define TI_ADS1293_DATA_CH3_ECG_H_REG (0x3D) /* Channel3 ECG Data High [23:16] */ |
|||
#define TI_ADS1293_DATA_CH3_ECG_M_REG (0x3E) /* Channel3 ECG Data Medium [15:8] */ |
|||
#define TI_ADS1293_DATA_CH3_ECG_L_REG (0x3F) /* Channel3 ECG Data Low [7:0] */ |
|||
|
|||
#define TI_ADS1293_REVID_REG (0x40) /* Revision ID */ |
|||
#define TI_ADS1293_DATA_LOOP_REG (0x50) /* Loop Read Back Address */ |
|||
|
|||
// Useful definitions |
|||
#define ADS1293_READ_BIT (0x80) |
|||
#define ADS1293_WRITE_BIT (0x7F) |
|||
|
|||
typedef void (*ads1293_spi_tx_rx_t)(uint8_t* tx, uint8_t* rx, uint8_t len); |
|||
typedef struct { |
|||
ads1293_spi_tx_rx_t spi_tx_rx; |
|||
int id; |
|||
} ads1293_t; |
|||
|
|||
void ads1293_spi_init(ads1293_t* ads, ads1293_spi_tx_rx_t spi_tx_rx); |
|||
|
|||
void ads1293_spi_writereg_and_readbak(ads1293_t* ads, uint8_t addr, uint8_t data, uint8_t* readbak); |
|||
void ads1293_spi_writereg(ads1293_t* ads, uint8_t addr, uint8_t data); |
|||
uint8_t ads1293_spi_readreg(ads1293_t* ads, uint8_t addr); |
|||
|
|||
void ads1293_spi_autoinc_writereg(ads1293_t* ads, uint8_t addr, uint8_t* data, uint8_t len); |
|||
void ads1293_spi_autoinc_readreg(ads1293_t* ads, uint8_t addr, uint8_t* data, uint8_t len); |
|||
void ads1293_spi_stream_readreg(ads1293_t* ads, uint8_t* data, uint8_t len); |
|||
|
|||
void ads1293_read_ecg(ads1293_t* ads, uint32_t ch, uint32_t* data); |
|||
uint8_t ads1293_read_error_lod(ads1293_t* ads); |
|||
|
|||
#endif // HEADER_FILE_TI_ADS1293_H |
@ -1,350 +0,0 @@ |
|||
#include "board.h" |
|||
|
|||
#include "app_timer.h" |
|||
#include "nrf_gpio.h" |
|||
#include "znordic.h" |
|||
// |
|||
#include "diskio_blkdev.h" |
|||
#include "ff.h" |
|||
#include "nrf_block_dev_sdc.h" |
|||
#include "nrf_delay.h" |
|||
#include "nrf_drv_pwm.h" |
|||
#include "nrf_drv_wdt.h" |
|||
|
|||
static int16_t adc_channel_read_val(uint16_t channel) { |
|||
nrf_saadc_value_t value; |
|||
ret_code_t err_code; |
|||
err_code = nrfx_saadc_sample_convert(channel, &value); |
|||
if (err_code != NRF_SUCCESS) { |
|||
ZLOGE("nrfx_saadc_sample_convert(%d) fail err_code:%d", channel, err_code); |
|||
return 0; |
|||
} |
|||
return value; |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* DEBUG_LIGHT * |
|||
*******************************************************************************/ |
|||
APP_TIMER_DEF(m_debug_light_tmr); |
|||
static int32_t m_debug_light_io_index; |
|||
static void debug_light_tmr_cb_handler(void* p_context) { |
|||
static bool state = false; |
|||
if (state) { |
|||
nrf_gpio_pin_set(m_debug_light_io_index); |
|||
} else { |
|||
nrf_gpio_pin_clear(m_debug_light_io_index); |
|||
} |
|||
state = !state; |
|||
} |
|||
|
|||
void debug_light_init(int io_index) { |
|||
m_debug_light_io_index = io_index; |
|||
|
|||
nrf_gpio_cfg(m_debug_light_io_index, // |
|||
NRF_GPIO_PIN_DIR_OUTPUT, // |
|||
NRF_GPIO_PIN_INPUT_DISCONNECT, // |
|||
NRF_GPIO_PIN_PULLUP, // |
|||
NRF_GPIO_PIN_S0S1, // |
|||
NRF_GPIO_PIN_NOSENSE); |
|||
|
|||
ret_code_t err_code; |
|||
err_code = app_timer_create(&m_debug_light_tmr, APP_TIMER_MODE_REPEATED, debug_light_tmr_cb_handler); |
|||
APP_ERROR_CHECK(err_code); |
|||
|
|||
app_timer_start(m_debug_light_tmr, APP_TIMER_TICKS(100), NULL); |
|||
} |
|||
/******************************************************************************* |
|||
* zbsp_enter_sleep * |
|||
*******************************************************************************/ |
|||
APP_TIMER_DEF(enter_sleep_mode_tmr); |
|||
static int32_t m_wakeup_io_index; |
|||
static bool m_wakeup_io_mirror; |
|||
static void enter_sleep_tmr_cb(void* p_context) { |
|||
ZLOGI("enter sleep mode, wakeup io index: %d", m_wakeup_io_index); |
|||
|
|||
if (m_wakeup_io_mirror) { |
|||
nrf_gpio_cfg_sense_input(m_wakeup_io_index, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); |
|||
nrf_gpio_cfg_sense_set(m_wakeup_io_index, NRF_GPIO_PIN_SENSE_LOW); |
|||
} else { |
|||
nrf_gpio_cfg_sense_input(m_wakeup_io_index, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_HIGH); |
|||
nrf_gpio_cfg_sense_set(m_wakeup_io_index, NRF_GPIO_PIN_SENSE_HIGH); |
|||
} |
|||
|
|||
// Go to system-off mode (this function will not return; wakeup will cause a reset). |
|||
ret_code_t err_code; |
|||
err_code = sd_power_system_off(); |
|||
if (err_code != NRF_SUCCESS) { |
|||
ZLOGE("sd_power_system_off err_code: %x", err_code); |
|||
} |
|||
} |
|||
void zbsp_enter_sleep(int32_t after_ms, int32_t wakeup_io_index, bool mirror) { |
|||
m_wakeup_io_index = wakeup_io_index; |
|||
m_wakeup_io_mirror = mirror; |
|||
ret_code_t err_code; |
|||
APP_ERROR_CHECK(app_timer_create(&enter_sleep_mode_tmr, APP_TIMER_MODE_SINGLE_SHOT, enter_sleep_tmr_cb)); |
|||
APP_ERROR_CHECK(app_timer_start(enter_sleep_mode_tmr, APP_TIMER_TICKS(after_ms), NULL)); |
|||
|
|||
ZLOGI("enter sleep mode after %d ms", after_ms); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* gpio_io_state_monitor * |
|||
*******************************************************************************/ |
|||
APP_TIMER_DEF(gpio_io_state_monitor_tmr); |
|||
static uint8_t* m_io_index; |
|||
static int32_t m_nio; |
|||
static void gpio_io_state_monitor_tmr_cb(void* p_context) { |
|||
// ioindex:state ioindex:state ioindex:state |
|||
if (m_nio == 1) { |
|||
ZLOGI("iostate %d:%d ", m_io_index[0], nrf_gpio_pin_read(m_io_index[0])); |
|||
} else if (m_nio == 2) { |
|||
ZLOGI("iostate %d:%d %d:%d", m_io_index[0], nrf_gpio_pin_read(m_io_index[0]), // |
|||
m_io_index[1], nrf_gpio_pin_read(m_io_index[1])); |
|||
} else if (m_nio >= 3) { |
|||
ZLOGI("iostate %d:%d %d:%d %d:%d", m_io_index[0], nrf_gpio_pin_read(m_io_index[0]), // |
|||
m_io_index[1], nrf_gpio_pin_read(m_io_index[1]), // |
|||
m_io_index[2], nrf_gpio_pin_read(m_io_index[2])); |
|||
} |
|||
} |
|||
|
|||
void zbsp_gpio_state_monitor_without_initio(int dumpstate_period, uint8_t* io_index, int32_t nio) { |
|||
m_io_index = io_index; |
|||
m_nio = nio; |
|||
APP_ERROR_CHECK(app_timer_create(&gpio_io_state_monitor_tmr, APP_TIMER_MODE_REPEATED, gpio_io_state_monitor_tmr_cb)); |
|||
APP_ERROR_CHECK(app_timer_start(gpio_io_state_monitor_tmr, APP_TIMER_TICKS(dumpstate_period), NULL)); |
|||
} |
|||
void zbsp_gpio_state_monitor(int dumpstate_period, uint8_t* io_index, int32_t nio) { |
|||
m_io_index = io_index; |
|||
m_nio = nio; |
|||
for (int i = 0; i < nio; i++) { |
|||
nrf_gpio_cfg_input(io_index[i], NRF_GPIO_PIN_PULLUP); |
|||
} |
|||
zbsp_gpio_state_monitor_without_initio(dumpstate_period, io_index, nio); |
|||
} |
|||
|
|||
void board_init() {} |
|||
|
|||
/******************************************************************************* |
|||
* ADC * |
|||
*******************************************************************************/ |
|||
|
|||
static void saadc_callback(nrf_drv_saadc_evt_t const* p_event) { |
|||
if (p_event->type == NRF_DRV_SAADC_EVT_DONE) { |
|||
} |
|||
} |
|||
|
|||
void adc_module_init() { |
|||
nrf_drv_saadc_config_t adccfg = NRFX_SAADC_DEFAULT_CONFIG; |
|||
adccfg.resolution = NRF_SAADC_RESOLUTION_12BIT; // 4096 等于满采样率 |
|||
ZERROR_CHECK(nrf_drv_saadc_init(&adccfg, saadc_callback)); |
|||
} |
|||
|
|||
void adc_module_battery_channel_init(nrf_saadc_input_t channelpin) { |
|||
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(channelpin); |
|||
ZERROR_CHECK(nrfx_saadc_channel_init(0, &channel_config)); |
|||
} |
|||
int16_t adc_module_battery_channel_read_val() { return adc_channel_read_val(0); } |
|||
|
|||
void adc_module_heart_elect_channel_init(nrf_saadc_input_t channelpin) { |
|||
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(channelpin); |
|||
channel_config.acq_time = NRF_SAADC_ACQTIME_40US; |
|||
ZERROR_CHECK(nrfx_saadc_channel_init(1, &channel_config)); |
|||
} |
|||
int16_t adc_module_heart_elect_channel_read_val() { return adc_channel_read_val(1); } |
|||
/******************************************************************************* |
|||
* SPI * |
|||
*******************************************************************************/ |
|||
#define SPI_MISO_PIN 31 |
|||
#define SPI_SS_PIN 20 |
|||
#define SPI_SCK_PIN 29 |
|||
#define SPI_MOSI_PIN 30 |
|||
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(0); /**< SPI instance. */ |
|||
|
|||
// static volatile bool m_spi_translate_done = false; |
|||
// static void spi_event_handler(nrf_drv_spi_evt_t const* p_event, void* p_context) { m_spi_translate_done = true; } |
|||
void board_spi_init() { |
|||
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 = SPI_MISO_PIN; |
|||
spi_config.mosi_pin = SPI_MOSI_PIN; |
|||
spi_config.sck_pin = SPI_SCK_PIN; |
|||
spi_config.frequency = NRF_DRV_SPI_FREQ_1M; |
|||
ZERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL)); |
|||
} |
|||
ret_code_t board_spi_transfer(uint8_t const* p_tx_buffer, uint8_t tx_buffer_length, uint8_t* p_rx_buffer, uint8_t rx_buffer_length) { |
|||
// m_spi_translate_done = false; |
|||
ZERROR_CHECK(nrf_drv_spi_transfer(&spi, p_tx_buffer, tx_buffer_length, p_rx_buffer, rx_buffer_length)); |
|||
// while (!m_spi_translate_done) |
|||
// ; |
|||
return NRF_SUCCESS; |
|||
} |
|||
|
|||
ret_code_t board_spi_transfer_test() { |
|||
uint8_t tx_data[] = {0x01, 0x02, 0x03}; |
|||
uint8_t rx_data[3]; |
|||
ZERROR_CHECK(board_spi_transfer(tx_data, 3, rx_data, 3)); |
|||
} |
|||
|
|||
void screen_init() {} |
|||
void screen_spi_translate_onebyte() {} |
|||
|
|||
static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0); |
|||
static nrf_pwm_values_individual_t m_demo1_seq_values; |
|||
|
|||
void pwm_trigger() { |
|||
nrf_drv_pwm_config_t const config0 = { |
|||
.output_pins = {11}, |
|||
.irq_priority = APP_IRQ_PRIORITY_LOWEST, |
|||
.base_clock = NRF_PWM_CLK_125kHz, |
|||
.count_mode = NRF_PWM_MODE_UP, |
|||
.top_value = 10, |
|||
.load_mode = NRF_PWM_LOAD_INDIVIDUAL, |
|||
.step_mode = NRF_PWM_STEP_AUTO, |
|||
}; |
|||
APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL)); |
|||
|
|||
static nrf_pwm_sequence_t const m_demo1_seq = { |
|||
.values.p_individual = &m_demo1_seq_values, |
|||
.length = NRF_PWM_VALUES_LENGTH(m_demo1_seq_values), |
|||
.repeats = 0, |
|||
.end_delay = 0, |
|||
}; |
|||
|
|||
m_demo1_seq_values.channel_0 = 8; |
|||
m_demo1_seq_values.channel_1 = 0; |
|||
m_demo1_seq_values.channel_2 = 0; |
|||
m_demo1_seq_values.channel_3 = 0; |
|||
|
|||
(void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1, NRF_DRV_PWM_FLAG_LOOP); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* I2C * |
|||
*******************************************************************************/ |
|||
|
|||
#define TWI_SCL_M 30 // I2C SCL引脚 |
|||
#define TWI_SDA_M 31 // I2C SDA引脚 |
|||
static const nrf_drv_twi_t m_twi_master = NRF_DRV_TWI_INSTANCE(1); |
|||
|
|||
void board_i2c_init() { |
|||
const nrf_drv_twi_config_t config = { |
|||
.scl = TWI_SCL_M, |
|||
.sda = TWI_SDA_M, |
|||
.frequency = NRF_DRV_TWI_FREQ_100K, |
|||
.interrupt_priority = APP_IRQ_PRIORITY_HIGH, |
|||
.clear_bus_init = false, |
|||
}; |
|||
|
|||
ZERROR_CHECK(nrf_drv_twi_init(&m_twi_master, &config, NULL, NULL)); |
|||
|
|||
nrf_drv_twi_enable(&m_twi_master); |
|||
} |
|||
|
|||
void board_i2c_write(uint8_t addr, uint8_t* data, uint8_t len) { nrf_drv_twi_tx(&m_twi_master, addr, data, len, false); } |
|||
|
|||
#define FILE_NAME "NORDIC.TXT" |
|||
#define TEST_STRING "SD card example." |
|||
|
|||
// #define SPI_MISO_PIN 31 |
|||
// #define SPI_SS_PIN 20 |
|||
// #define SPI_SCK_PIN 29 |
|||
// #define SPI_MOSI_PIN 30 |
|||
|
|||
#define SDC_SCK_PIN 29 ///< SDC serial clock (SCK) pin. |
|||
#define SDC_MOSI_PIN 30 ///< SDC serial data in (DI) pin. |
|||
#define SDC_MISO_PIN 31 ///< SDC serial data out (DO) pin. |
|||
#define SDC_CS_PIN 20 ///< SDC chip select (CS) pin. |
|||
|
|||
NRF_BLOCK_DEV_SDC_DEFINE(m_block_dev_sdc, NRF_BLOCK_DEV_SDC_CONFIG(SDC_SECTOR_SIZE, APP_SDCARD_CONFIG(SDC_MOSI_PIN, SDC_MISO_PIN, SDC_SCK_PIN, SDC_CS_PIN)), NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00")); |
|||
void fatfs_init() { |
|||
// // Initialize FATFS disk I/O interface by providing the block device. |
|||
static diskio_blkdev_t drives[] = {DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev), NULL)}; |
|||
|
|||
diskio_blockdev_register(drives, ARRAY_SIZE(drives)); |
|||
fatfs_test_write(); |
|||
} |
|||
void fatfs_test_write() { |
|||
static FATFS fs; |
|||
static DIR dir; |
|||
static FILINFO fno; |
|||
static FIL file; |
|||
|
|||
uint32_t bytes_written; |
|||
FRESULT ff_result; |
|||
DSTATUS disk_state = STA_NOINIT; |
|||
|
|||
for (uint32_t retries = 3; retries && disk_state; --retries) { |
|||
disk_state = disk_initialize(0); |
|||
} |
|||
if (disk_state) { |
|||
NRF_LOG_INFO("Disk initialization failed. %d", disk_state); |
|||
return; |
|||
} |
|||
return; |
|||
// NRF_LOG_INFO("Initializing disk 0 (SDC)..."); |
|||
|
|||
uint32_t blocks_per_mb = (1024uL * 1024uL) / m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_size; |
|||
uint32_t capacity = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count / blocks_per_mb; |
|||
NRF_LOG_INFO("Capacity: %d MB", capacity); |
|||
|
|||
NRF_LOG_INFO("Mounting volume..."); |
|||
ff_result = f_mount(&fs, "", 1); |
|||
if (ff_result) { |
|||
NRF_LOG_INFO("Mount failed."); |
|||
return; |
|||
} |
|||
|
|||
NRF_LOG_INFO("\r\n Listing directory: /"); |
|||
ff_result = f_opendir(&dir, "/"); |
|||
if (ff_result) { |
|||
NRF_LOG_INFO("Directory listing failed!"); |
|||
return; |
|||
} |
|||
|
|||
do { |
|||
ff_result = f_readdir(&dir, &fno); |
|||
if (ff_result != FR_OK) { |
|||
NRF_LOG_INFO("Directory read failed."); |
|||
return; |
|||
} |
|||
|
|||
if (fno.fname[0]) { |
|||
if (fno.fattrib & AM_DIR) { |
|||
NRF_LOG_RAW_INFO(" <DIR> %s", (uint32_t)fno.fname); |
|||
} else { |
|||
NRF_LOG_RAW_INFO("%9lu %s", fno.fsize, (uint32_t)fno.fname); |
|||
} |
|||
} |
|||
} while (fno.fname[0]); |
|||
NRF_LOG_RAW_INFO(""); |
|||
|
|||
NRF_LOG_INFO("Writing to file " FILE_NAME "..."); |
|||
ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND); |
|||
if (ff_result != FR_OK) { |
|||
NRF_LOG_INFO("Unable to open or create file: " FILE_NAME "."); |
|||
return; |
|||
} |
|||
|
|||
ff_result = f_write(&file, TEST_STRING, sizeof(TEST_STRING) - 1, (UINT*)&bytes_written); |
|||
if (ff_result != FR_OK) { |
|||
NRF_LOG_INFO("Write failed\r\n."); |
|||
} else { |
|||
NRF_LOG_INFO("%d bytes written.", bytes_written); |
|||
} |
|||
|
|||
(void)f_close(&file); |
|||
return; |
|||
} |
|||
nrf_drv_wdt_channel_id m_channel_id; |
|||
|
|||
void wd_init() { |
|||
// WDT_CONFIG_RELOAD_VALUE 修改这个数值修改喂狗周期,单位ms |
|||
nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG; |
|||
config.reload_value = WDT_CONFIG_RELOAD_VALUE; |
|||
ret_code_t err_code = nrf_drv_wdt_init(&config, NULL); |
|||
ZERROR_CHECK(err_code); |
|||
err_code = nrf_drv_wdt_channel_alloc(&m_channel_id); |
|||
ZERROR_CHECK(err_code); |
|||
nrf_drv_wdt_enable(); |
|||
} |
|||
void wd_feed() { nrfx_wdt_feed(); } |
@ -1,67 +0,0 @@ |
|||
#pragma once |
|||
#include <stdio.h> |
|||
|
|||
#include "nrf_drv_saadc.h" |
|||
#include "nrf_drv_twi.h" |
|||
#include "znordic.h" |
|||
|
|||
/******************************************************************************* |
|||
* DEBUG_LIGHT * |
|||
*******************************************************************************/ |
|||
void debug_light_init(int io_index); |
|||
|
|||
/******************************************************************************* |
|||
* zbsp_enter_sleep * |
|||
*******************************************************************************/ |
|||
|
|||
/** |
|||
* @brief 调用此方法前,需要确保底层协议栈已经初始化 |
|||
* |
|||
* @param after_ms |
|||
* @param wakeup_io_index |
|||
*/ |
|||
void zbsp_enter_sleep(int32_t after_ms, int32_t wakeup_io_index, bool mirror); |
|||
|
|||
/******************************************************************************* |
|||
* gpio_io_state_monitor * |
|||
*******************************************************************************/ |
|||
void zbsp_gpio_state_monitor(int dumpstate_period, uint8_t* io_index, int32_t nio); |
|||
void zbsp_gpio_state_monitor_without_initio(int dumpstate_period, uint8_t* io_index, int32_t nio); |
|||
|
|||
void board_init(); |
|||
|
|||
/******************************************************************************* |
|||
* ADC * |
|||
*******************************************************************************/ |
|||
|
|||
void adc_module_init(); |
|||
|
|||
void adc_module_battery_channel_init(nrf_saadc_input_t channelpin); |
|||
int16_t adc_module_battery_channel_read_val(); |
|||
|
|||
void adc_module_heart_elect_channel_init(nrf_saadc_input_t channelpin); |
|||
int16_t adc_module_heart_elect_channel_read_val(); |
|||
|
|||
/******************************************************************************* |
|||
* SPI * |
|||
*******************************************************************************/ |
|||
|
|||
void board_spi_init(); |
|||
ret_code_t board_spi_transfer(uint8_t const* p_tx_buffer, uint8_t tx_buffer_length, uint8_t* p_rx_buffer, uint8_t rx_buffer_length); |
|||
ret_code_t board_spi_transfer_test(); |
|||
|
|||
void board_i2c_init(); |
|||
void board_i2c_write(uint8_t addr, uint8_t* data, uint8_t len); |
|||
|
|||
void screen_init(); |
|||
void screen_spi_translate_onebyte(); |
|||
|
|||
/******************************************************************************* |
|||
* FATFS * |
|||
*******************************************************************************/ |
|||
void fatfs_init(); |
|||
void fatfs_test_write(); |
|||
void pwm_trigger(); |
|||
|
|||
void wd_init(); |
|||
void wd_feed(); |
@ -1,10 +0,0 @@ |
|||
#include "device_info_mgr.h" |
|||
|
|||
void device_info_read_sn(sn_t* sn) { |
|||
const char* sn_str = "M1001000000001"; |
|||
memcpy(sn->sn, sn_str, sizeof(sn->sn)); |
|||
} |
|||
uint16_t device_info_read_blestack_version(void) { return 1; } |
|||
uint16_t device_info_read_bootloader_version(void) { return 1; } |
|||
uint16_t device_info_read_firmware_version(void) { return 1; } |
|||
uint16_t device_info_read_hardware_version(void) { return 1; } |
@ -1,13 +0,0 @@ |
|||
#pragma once |
|||
#include "znordic.h" |
|||
|
|||
typedef struct { |
|||
uint8_t sn[14]; |
|||
} sn_t; |
|||
|
|||
|
|||
void device_info_read_sn(sn_t *sn); |
|||
uint16_t device_info_read_blestack_version(void); |
|||
uint16_t device_info_read_bootloader_version(void); |
|||
uint16_t device_info_read_firmware_version(void); |
|||
uint16_t device_info_read_hardware_version(void); |
@ -1,190 +0,0 @@ |
|||
#pragma once |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#pragma pack(push, 1) |
|||
|
|||
typedef struct { |
|||
uint8_t frame_type; |
|||
uint8_t frame_index; |
|||
uint8_t cmd; |
|||
uint8_t data[]; |
|||
} ify_hrs_packet_t; |
|||
|
|||
typedef enum { |
|||
kifyhrs_ecode_success = 0, |
|||
kifyhrs_ecode_unkown_error = 1, |
|||
kifyhrs_ecode_cmd_not_support = 2, |
|||
kifyhrs_ecode_illegal_parameter = 3, |
|||
kifyhrs_ecode_device_busy = 4, |
|||
kifyhrs_ecode_hardware_error = 5, |
|||
kifyhrs_ecode_sensor_drop = 6, |
|||
kifyhrs_ecode_no_record_find = 7, |
|||
} ify_hrs_error_code_t; |
|||
|
|||
typedef enum { |
|||
kifyhrs_pt_cmd = 1, |
|||
kifyhrs_pt_cmd_receipt = 2, |
|||
kifyhrs_pt_report = 3, |
|||
kifyhrs_pt_error_receipt = 4, |
|||
} ify_hrs_packet_type_t; |
|||
|
|||
typedef enum { |
|||
kifyhrs_sensor_pos_none = 0, // 无指定位置 |
|||
kifyhrs_sensor_pos_I = 1, // I |
|||
kifyhrs_sensor_pos_II = 2, // II |
|||
kifyhrs_sensor_pos_III = 3, // III |
|||
kifyhrs_sensor_pos_V1 = 4, // V1 |
|||
kifyhrs_sensor_pos_V5 = 5, // V5 |
|||
} ify_hrs_sensor_pos_t; |
|||
|
|||
typedef enum { |
|||
ify_hrs_cmd_read_device_version = 1, |
|||
ify_hrs_cmd_read_sensor_info = 2, |
|||
ify_hrs_cmd_read_device_state = 3, |
|||
ify_hrs_cmd_read_time = 4, |
|||
ify_hrs_cmd_sync_time = 5, |
|||
ify_hrs_cmd_start_capture = 6, |
|||
ify_hrs_cmd_stop_capture = 7, |
|||
ify_hrs_cmd_start_realtime_report = 8, |
|||
ify_hrs_cmd_stop_realtime_report = 9, |
|||
ify_hrs_cmd_read_records_info = 10, |
|||
ify_hrs_cmd_del_record = 11, |
|||
ify_hrs_cmd_start_upload_record = 12, |
|||
ify_hrs_cmd_enter_ota = 13, |
|||
ify_hrs_cmd_read_sn = 14, |
|||
ify_hrs_cmd_reset = 15, |
|||
|
|||
ify_hrs_report_heartrate_data = 101, |
|||
ify_hrs_report_battery_level = 102, |
|||
ify_hrs_report_low_battey_level = 103, |
|||
ify_hrs_report_sample_finish_end = 104, |
|||
ify_hrs_report_sensor_drop_detect = 105, |
|||
ify_hrs_report_record_upload_end = 106, |
|||
|
|||
} ify_hrs_cmd_t; |
|||
|
|||
/******************************************************************************* |
|||
* packet_struct * |
|||
*******************************************************************************/ |
|||
typedef struct { |
|||
uint16_t placeholder; |
|||
uint16_t blestack_version; |
|||
uint16_t bootloader_version; |
|||
uint16_t firmware_version; |
|||
uint16_t hardware_version; |
|||
} device_version_info_receipt_t; |
|||
|
|||
typedef struct { |
|||
uint8_t sensor_num; // 数量 |
|||
uint8_t sensor_precision; // 精度 |
|||
uint8_t sensor_sample_rate; // 采样率 |
|||
uint8_t sensor0_pos; // 位置 |
|||
uint8_t sensor1_pos; // 位置 |
|||
uint8_t sensor2_pos; // 位置 |
|||
} sensor_info_receipt_t; |
|||
|
|||
typedef struct { |
|||
struct { |
|||
uint8_t sensor0_pos : 1; // 位置 |
|||
uint8_t sensor1_pos : 1; // 位置 |
|||
uint8_t sensor2_pos : 1; // 位置 |
|||
uint8_t sensor3_pos : 1; // 位置 |
|||
uint8_t sensor4_pos : 1; // 位置 |
|||
uint8_t sensor5_pos : 1; // 位置 |
|||
uint8_t sensor6_pos : 1; // 位置 |
|||
uint8_t sensor7_pos : 1; // 位置 |
|||
} drop_state0; |
|||
uint8_t drop_state1; |
|||
struct { |
|||
uint8_t sampling_state : 1; // 位置 |
|||
uint8_t report_state : 1; // 位置 |
|||
uint8_t low_battery : 1; // 位置 |
|||
uint8_t full_storge : 1; // 位置 |
|||
uint8_t holder : 4; // 位置 |
|||
} device_state0; |
|||
uint8_t device_state1; // 预留 |
|||
uint8_t powerlevel; // 电量 |
|||
uint8_t storage_item_num; // 记录存储条数 |
|||
} device_state_receipt_t; |
|||
|
|||
typedef struct { |
|||
uint8_t year; |
|||
uint8_t month; |
|||
uint8_t day; |
|||
uint8_t hour; |
|||
uint8_t minute; |
|||
uint8_t second; |
|||
} read_time_receipt_t; |
|||
|
|||
typedef struct { |
|||
uint8_t year; |
|||
uint8_t month; |
|||
uint8_t day; |
|||
uint8_t hour; |
|||
uint8_t minute; |
|||
uint8_t second; |
|||
} sync_time_cmd_t; |
|||
|
|||
typedef struct { |
|||
uint8_t year; |
|||
uint8_t month; |
|||
uint8_t day; |
|||
uint8_t hour; |
|||
uint8_t minute; |
|||
uint8_t second; |
|||
} start_capture_cmd_t; |
|||
|
|||
typedef struct { |
|||
uint8_t record_index; // 最近第几条记录 |
|||
} read_record_info_cmd_t; |
|||
|
|||
typedef struct { |
|||
uint8_t record_id[6]; |
|||
uint32_t frameNum; |
|||
uint32_t dataSize; |
|||
uint8_t sensorNum; |
|||
uint8_t captureRate; // N*10HZ |
|||
uint8_t capturePrecision; |
|||
uint8_t compressAlgorithm; // 压缩算法 |
|||
} read_record_info_receipt_t; |
|||
|
|||
typedef struct { |
|||
uint8_t record_id[6]; |
|||
} del_record_cmd_t; |
|||
|
|||
typedef struct { |
|||
uint8_t record_id[6]; |
|||
} start_upload_record_cmd_t; |
|||
|
|||
typedef struct { |
|||
uint8_t sn[14]; |
|||
} read_sn_receipt_t; |
|||
|
|||
typedef struct { |
|||
uint8_t errorcode; |
|||
} error_receipt_t; |
|||
|
|||
/******************************************************************************* |
|||
* 上报相关结构体 * |
|||
*******************************************************************************/ |
|||
|
|||
typedef struct { |
|||
uint8_t frame_type; |
|||
uint8_t frame_index; |
|||
uint8_t cmd; |
|||
|
|||
uint32_t sample_data_index; |
|||
uint8_t data[]; // 上报的数据 |
|||
} heartrate_report_packet_t; |
|||
|
|||
typedef struct { |
|||
uint8_t frame_type; |
|||
uint8_t frame_index; |
|||
uint8_t cmd; |
|||
|
|||
uint8_t drop_state0; |
|||
uint8_t drop_state1; |
|||
} sensor_drop_event_report_packet_t; |
|||
|
|||
#pragma pack(pop) |
@ -1,3 +0,0 @@ |
|||
#pragma once |
|||
|
|||
#define DEBUG_LIGHT_IO_INDEX 13 |
@ -1,237 +0,0 @@ |
|||
|
|||
|
|||
#include "zble_module.h" |
|||
|
|||
#include <stdint.h> |
|||
#include <string.h> |
|||
|
|||
#include "znordic.h" |
|||
/******************************************************************************* |
|||
* 广播包配?? * |
|||
*******************************************************************************/ |
|||
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */ |
|||
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */ |
|||
#define SLAVE_LATENCY 0 /**< Slave latency. */ |
|||
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */ |
|||
#define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */ |
|||
static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */ |
|||
{{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; |
|||
#define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ |
|||
#define APP_ADV_DURATION 18000 /**< The advertising duration (180 seconds) in units of 10 milliseconds. */ |
|||
BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */ |
|||
|
|||
/******************************************************************************* |
|||
* GATT配置 * |
|||
*******************************************************************************/ |
|||
NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */ |
|||
|
|||
/******************************************************************************* |
|||
* 连接参数配置 * |
|||
*******************************************************************************/ |
|||
#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */ |
|||
#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ |
|||
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ |
|||
|
|||
/******************************************************************************* |
|||
* CODE * |
|||
*******************************************************************************/ |
|||
|
|||
static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< 当前连接句柄 */ |
|||
static uint16_t m_mtu_size = BLE_GATT_ATT_MTU_DEFAULT - 3; |
|||
|
|||
static void ble_evt_handler(ble_evt_t const* p_ble_evt, void* p_context) { |
|||
uint32_t err_code; |
|||
switch (p_ble_evt->header.evt_id) { |
|||
case BLE_GAP_EVT_CONNECTED: |
|||
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; |
|||
break; |
|||
|
|||
case BLE_GAP_EVT_DISCONNECTED: |
|||
m_conn_handle = BLE_CONN_HANDLE_INVALID; |
|||
break; |
|||
|
|||
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { |
|||
NRF_LOG_DEBUG("PHY update request."); |
|||
ble_gap_phys_t const phys = { |
|||
.rx_phys = BLE_GAP_PHY_AUTO, |
|||
.tx_phys = BLE_GAP_PHY_AUTO, |
|||
}; |
|||
err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); |
|||
ZERROR_CHECK(err_code); |
|||
} break; |
|||
|
|||
case BLE_GAP_EVT_SEC_PARAMS_REQUEST: |
|||
// Pairing not supported |
|||
err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); |
|||
ZERROR_CHECK(err_code); |
|||
break; |
|||
|
|||
case BLE_GATTS_EVT_SYS_ATTR_MISSING: |
|||
// No system attributes have been stored. |
|||
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); |
|||
ZERROR_CHECK(err_code); |
|||
break; |
|||
|
|||
case BLE_GATTC_EVT_TIMEOUT: |
|||
// Disconnect on GATT Client timeout event. |
|||
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); |
|||
ZERROR_CHECK(err_code); |
|||
break; |
|||
|
|||
case BLE_GATTS_EVT_TIMEOUT: |
|||
// Disconnect on GATT Server timeout event. |
|||
err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); |
|||
ZERROR_CHECK(err_code); |
|||
break; |
|||
|
|||
default: |
|||
// No implementation needed. |
|||
break; |
|||
} |
|||
} |
|||
static void gatt_evt_handler(nrf_ble_gatt_t* p_gatt, nrf_ble_gatt_evt_t const* p_evt) { |
|||
/******************************************************************************* |
|||
* MTU SIZE 更新 * |
|||
*******************************************************************************/ |
|||
if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) { |
|||
m_mtu_size = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; |
|||
NRF_LOG_DEBUG("ATT MTU exchange completed. central %d peripheral %d", p_gatt->att_mtu_desired_central, p_gatt->att_mtu_desired_periph); |
|||
} |
|||
} |
|||
static void on_conn_params_evt(ble_conn_params_evt_t* p_evt) { |
|||
uint32_t err_code; |
|||
if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) { |
|||
err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); |
|||
ZERROR_CHECK(err_code); |
|||
} |
|||
} |
|||
static void conn_params_error_handler(uint32_t nrf_error) { APP_ERROR_HANDLER(nrf_error); } |
|||
static void on_adv_evt(ble_adv_evt_t ble_adv_evt) { |
|||
switch (ble_adv_evt) { |
|||
case BLE_ADV_EVT_FAST: |
|||
// err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); |
|||
// ZERROR_CHECK(err_code); |
|||
break; |
|||
case BLE_ADV_EVT_IDLE: |
|||
// sleep_mode_enter(); |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
void zble_module_start_adv() { |
|||
uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); |
|||
ZERROR_CHECK(err_code); |
|||
} |
|||
void zble_module_stop_adv() { |
|||
uint32_t err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle); |
|||
ZERROR_CHECK(err_code); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* INIT * |
|||
*******************************************************************************/ |
|||
void zble_module_init(zble_module_cfg_t* cfg) { |
|||
/** |
|||
* @brief |
|||
* 初始化蓝牙协议栈,并注册蓝牙事件处理函数,固定代码,勿修?? |
|||
*/ |
|||
{ NRF_SDH_BLE_OBSERVER(m_ble_observer, 3, ble_evt_handler, NULL); } |
|||
/******************************************************************************* |
|||
* GAP初始?? * |
|||
*******************************************************************************/ |
|||
{ |
|||
uint32_t err_code; |
|||
ble_gap_conn_params_t gap_conn_params; |
|||
ble_gap_conn_sec_mode_t sec_mode; |
|||
|
|||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); |
|||
|
|||
err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t*)cfg->deviceName, strlen(cfg->deviceName)); |
|||
ZERROR_CHECK(err_code); |
|||
|
|||
memset(&gap_conn_params, 0, sizeof(gap_conn_params)); |
|||
|
|||
gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; |
|||
gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; |
|||
gap_conn_params.slave_latency = SLAVE_LATENCY; |
|||
gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; |
|||
|
|||
err_code = sd_ble_gap_ppcp_set(&gap_conn_params); |
|||
ZERROR_CHECK(err_code); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* GATT 初始?? * |
|||
*******************************************************************************/ |
|||
{ |
|||
ret_code_t err_code; |
|||
|
|||
err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler); |
|||
ZERROR_CHECK(err_code); |
|||
|
|||
err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); |
|||
ZERROR_CHECK(err_code); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 蓝牙服务初始?? * |
|||
*******************************************************************************/ |
|||
{ |
|||
if (cfg->on_service_init) cfg->on_service_init(); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 广播初始?? * |
|||
*******************************************************************************/ |
|||
{ |
|||
uint32_t err_code; |
|||
ble_advertising_init_t init; |
|||
|
|||
memset(&init, 0, sizeof(init)); |
|||
|
|||
init.advdata.name_type = BLE_ADVDATA_FULL_NAME; |
|||
init.advdata.include_appearance = false; |
|||
// init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; |
|||
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; |
|||
|
|||
init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); |
|||
init.srdata.uuids_complete.p_uuids = m_adv_uuids; |
|||
|
|||
init.config.ble_adv_fast_enabled = true; |
|||
init.config.ble_adv_fast_interval = APP_ADV_INTERVAL; |
|||
init.config.ble_adv_fast_timeout = 0; |
|||
init.evt_handler = on_adv_evt; |
|||
|
|||
err_code = ble_advertising_init(&m_advertising, &init); |
|||
ZERROR_CHECK(err_code); |
|||
|
|||
ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); |
|||
} |
|||
/******************************************************************************* |
|||
* 连接参数初始?? * |
|||
*******************************************************************************/ |
|||
{ |
|||
uint32_t err_code; |
|||
ble_conn_params_init_t cp_init; |
|||
|
|||
memset(&cp_init, 0, sizeof(cp_init)); |
|||
|
|||
cp_init.p_conn_params = NULL; |
|||
cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; |
|||
cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; |
|||
cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; |
|||
cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; |
|||
cp_init.disconnect_on_fail = false; |
|||
cp_init.evt_handler = on_conn_params_evt; |
|||
cp_init.error_handler = conn_params_error_handler; |
|||
|
|||
err_code = ble_conn_params_init(&cp_init); |
|||
ZERROR_CHECK(err_code); |
|||
} |
|||
|
|||
// zble_module_start_adv(); |
|||
} |
|||
|
|||
int32_t zble_module_get_mtu_size() { return m_mtu_size; } |
@ -1,20 +0,0 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
|
|||
/** |
|||
* @brief |
|||
*/ |
|||
|
|||
typedef void (*on_service_init_t)(void); |
|||
|
|||
typedef struct { |
|||
const char* deviceName; |
|||
on_service_init_t on_service_init; |
|||
} zble_module_cfg_t; |
|||
|
|||
void zble_module_init(zble_module_cfg_t* cfg); |
|||
|
|||
void zble_module_start_adv(); |
|||
void zble_module_stop_adv(); |
|||
|
|||
int32_t zble_module_get_mtu_size(); |
@ -1,225 +0,0 @@ |
|||
#include "zdatachannel_service.h" |
|||
|
|||
#include "ble.h" |
|||
#include "ble_srv_common.h" |
|||
#include "nrf_log.h" |
|||
#include "sdk_common.h" |
|||
#include "znordic.h" |
|||
|
|||
#define ZDATACHANNEL_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */ |
|||
#define ZDATACHANNEL_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */ |
|||
#define ZDATACHANNEL_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */ |
|||
#define ZDATACHANNEL_DATABLOCK_TX_CHARACTERISTIC 0x0004 /**< The UUID of the RX Characteristic. */ |
|||
|
|||
#define ZDATACHANNEL_MAX_RX_CHAR_LEN ZDATACHANNEL_MAX_DATA_LEN /**< Maximum length of the RX Characteristic (in bytes). */ |
|||
#define ZDATACHANNEL_MAX_TX_CHAR_LEN ZDATACHANNEL_MAX_DATA_LEN /**< Maximum length of the TX Characteristic (in bytes). */ |
|||
#define ZDATACHANNEL_DATABLOCK_TX_CHAR_LEN ZDATACHANNEL_MAX_DATA_LEN /**< Maximum length of the TX Characteristic (in bytes). */ |
|||
|
|||
#define NUS_BASE_UUID \ |
|||
{ \ |
|||
{ 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E } \ |
|||
} /**< Used vendor specific UUID. */ |
|||
|
|||
static zdatachannel_t *p_datachannel; |
|||
static uint32_t m_mtusize; |
|||
|
|||
static bool notification_enable(uint16_t conn_handle, uint16_t cccd_handle) { |
|||
ret_code_t err_code; |
|||
ble_gatts_value_t gatts_val; |
|||
uint8_t cccd_value[2]; |
|||
memset(&gatts_val, 0, sizeof(ble_gatts_value_t)); |
|||
gatts_val.p_value = cccd_value; |
|||
gatts_val.len = sizeof(cccd_value); |
|||
gatts_val.offset = 0; |
|||
err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &gatts_val); |
|||
if ((err_code == NRF_SUCCESS) && ble_srv_is_notification_enabled(gatts_val.p_value)) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice. |
|||
* |
|||
* @param[in] p_nus Nordic UART Service structure. |
|||
* @param[in] p_ble_evt Pointer to the event received from BLE stack. |
|||
*/ |
|||
static void on_write(zdatachannel_t *p_nus, ble_evt_t const *p_ble_evt) { |
|||
zdatachannel_evt_t evt; |
|||
ble_gatts_evt_write_t const *p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; |
|||
|
|||
memset(&evt, 0, sizeof(zdatachannel_evt_t)); |
|||
|
|||
if ((p_evt_write->handle == p_nus->cmd_tx_handles.cccd_handle) && (p_evt_write->len == 2)) { |
|||
if (ble_srv_is_notification_enabled(p_evt_write->data)) { |
|||
p_nus->cmd_tx_channel_is_notification_enabled = true; |
|||
} else { |
|||
p_nus->cmd_tx_channel_is_notification_enabled = false; |
|||
} |
|||
} else if ((p_evt_write->handle == p_nus->datablock_tx_handles.cccd_handle) && (p_evt_write->len == 2)) { |
|||
if (ble_srv_is_notification_enabled(p_evt_write->data)) { |
|||
p_nus->datablock_tx_channel_is_notification_enabled = true; |
|||
} else { |
|||
p_nus->datablock_tx_channel_is_notification_enabled = false; |
|||
} |
|||
} else if ((p_evt_write->handle == p_nus->cmd_rx_handles.value_handle) && (p_nus->data_handler != NULL)) { |
|||
evt.type = ZDATACHANNEL_EVT_RX_DATA; |
|||
evt.params.rx_data.p_data = p_evt_write->data; |
|||
evt.params.rx_data.length = p_evt_write->len; |
|||
|
|||
p_nus->data_handler(&evt); |
|||
} else { |
|||
// Do Nothing. This event is not relevant for this service. |
|||
} |
|||
} |
|||
|
|||
void zdatachannel_on_ble_evt(ble_evt_t const *p_ble_evt, void *p_context) { |
|||
if ((p_context == NULL) || (p_ble_evt == NULL)) { |
|||
return; |
|||
} |
|||
|
|||
zdatachannel_t *p_nus = (zdatachannel_t *)p_context; |
|||
|
|||
switch (p_ble_evt->header.evt_id) { |
|||
case BLE_GAP_EVT_CONNECTED: |
|||
ZLOGI("BLE_GAP_EVT_CONNECTED"); |
|||
p_nus->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; |
|||
p_nus->cmd_tx_channel_is_notification_enabled = notification_enable(p_ble_evt->evt.gap_evt.conn_handle, p_nus->cmd_tx_handles.cccd_handle); |
|||
p_nus->datablock_tx_channel_is_notification_enabled = notification_enable(p_ble_evt->evt.gap_evt.conn_handle, p_nus->cmd_tx_handles.cccd_handle); |
|||
break; |
|||
case BLE_GAP_EVT_DISCONNECTED: |
|||
ZLOGI("BLE_GAP_EVT_DISCONNECTED"); |
|||
p_nus->conn_handle = BLE_CONN_HANDLE_INVALID; |
|||
// ZLOGI("-----%d %d", p_datachannel->conn_handle, BLE_CONN_HANDLE_INVALID); |
|||
break; |
|||
case BLE_GATTS_EVT_WRITE: |
|||
on_write(p_nus, p_ble_evt); |
|||
break; |
|||
default: |
|||
// No implementation needed. |
|||
break; |
|||
} |
|||
} |
|||
|
|||
bool zdatachannel_is_connected() { |
|||
// ZLOGI("%d %d", p_datachannel->conn_handle, BLE_CONN_HANDLE_INVALID); |
|||
return p_datachannel->conn_handle != (int16_t)BLE_CONN_HANDLE_INVALID; |
|||
} |
|||
|
|||
uint32_t zdatachannel_init(zdatachannel_t *p_nus, zdatachannel_init_t const *p_nus_init) { |
|||
p_datachannel = p_nus; |
|||
p_datachannel->conn_handle = BLE_CONN_HANDLE_INVALID; |
|||
ret_code_t err_code; |
|||
ble_uuid_t ble_uuid; |
|||
ble_uuid128_t nus_base_uuid = NUS_BASE_UUID; |
|||
ble_add_char_params_t add_char_params; |
|||
|
|||
VERIFY_PARAM_NOT_NULL(p_nus); |
|||
VERIFY_PARAM_NOT_NULL(p_nus_init); |
|||
|
|||
// Initialize the service structure. |
|||
p_nus->data_handler = p_nus_init->data_handler; |
|||
|
|||
/**@snippet [Adding proprietary Service to the SoftDevice] */ |
|||
// Add a custom base UUID. |
|||
err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type); |
|||
VERIFY_SUCCESS(err_code); |
|||
|
|||
ble_uuid.type = p_nus->uuid_type; |
|||
ble_uuid.uuid = ZDATACHANNEL_UUID_NUS_SERVICE; |
|||
|
|||
// Add the service. |
|||
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_nus->service_handle); |
|||
/**@snippet [Adding proprietary Service to the SoftDevice] */ |
|||
VERIFY_SUCCESS(err_code); |
|||
|
|||
// Add the RX Characteristic. |
|||
memset(&add_char_params, 0, sizeof(add_char_params)); |
|||
add_char_params.uuid = ZDATACHANNEL_RX_CHARACTERISTIC; |
|||
add_char_params.uuid_type = p_nus->uuid_type; |
|||
add_char_params.max_len = ZDATACHANNEL_MAX_RX_CHAR_LEN; |
|||
add_char_params.init_len = sizeof(uint8_t); |
|||
add_char_params.is_var_len = true; |
|||
add_char_params.char_props.write = 1; |
|||
add_char_params.char_props.write_wo_resp = 1; |
|||
|
|||
add_char_params.read_access = SEC_NO_ACCESS; |
|||
add_char_params.write_access = SEC_OPEN; |
|||
|
|||
VERIFY_SUCCESS(characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->cmd_rx_handles)); |
|||
|
|||
// Add the TX Characteristic. |
|||
/**@snippet [Adding proprietary characteristic to the SoftDevice] */ |
|||
memset(&add_char_params, 0, sizeof(add_char_params)); |
|||
add_char_params.uuid = ZDATACHANNEL_TX_CHARACTERISTIC; |
|||
add_char_params.uuid_type = p_nus->uuid_type; |
|||
add_char_params.max_len = ZDATACHANNEL_MAX_TX_CHAR_LEN; |
|||
add_char_params.init_len = sizeof(uint8_t); |
|||
add_char_params.is_var_len = true; |
|||
add_char_params.char_props.notify = 1; |
|||
|
|||
add_char_params.read_access = SEC_OPEN; |
|||
add_char_params.write_access = SEC_OPEN; |
|||
add_char_params.cccd_write_access = SEC_OPEN; |
|||
|
|||
VERIFY_SUCCESS(characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->cmd_tx_handles)); |
|||
|
|||
// Add the TX Characteristic. |
|||
/**@snippet [Adding proprietary characteristic to the SoftDevice] */ |
|||
memset(&add_char_params, 0, sizeof(add_char_params)); |
|||
add_char_params.uuid = ZDATACHANNEL_DATABLOCK_TX_CHARACTERISTIC; |
|||
add_char_params.uuid_type = p_nus->uuid_type; |
|||
add_char_params.max_len = ZDATACHANNEL_DATABLOCK_TX_CHAR_LEN; |
|||
add_char_params.init_len = sizeof(uint8_t); |
|||
add_char_params.is_var_len = true; |
|||
add_char_params.char_props.notify = 1; |
|||
|
|||
add_char_params.read_access = SEC_OPEN; |
|||
add_char_params.write_access = SEC_OPEN; |
|||
add_char_params.cccd_write_access = SEC_OPEN; |
|||
|
|||
VERIFY_SUCCESS(characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->datablock_tx_handles)); |
|||
|
|||
return NRF_SUCCESS; |
|||
/**@snippet [Adding proprietary characteristic to the SoftDevice] */ |
|||
} |
|||
|
|||
uint32_t zdatachannel_data_send(uint8_t *p_data, uint16_t *p_length) { |
|||
ble_gatts_hvx_params_t hvx_params; |
|||
|
|||
if (!p_datachannel->cmd_tx_channel_is_notification_enabled) { |
|||
return NRF_ERROR_INVALID_STATE; |
|||
} |
|||
|
|||
if (*p_length > ZDATACHANNEL_MAX_DATA_LEN) { |
|||
return NRF_ERROR_INVALID_PARAM; |
|||
} |
|||
|
|||
memset(&hvx_params, 0, sizeof(hvx_params)); |
|||
|
|||
hvx_params.handle = p_datachannel->cmd_tx_handles.value_handle; |
|||
hvx_params.p_data = p_data; |
|||
hvx_params.p_len = p_length; |
|||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION; |
|||
|
|||
return sd_ble_gatts_hvx(p_datachannel->conn_handle, &hvx_params); |
|||
} |
|||
|
|||
uint32_t zdatachannel_block_data_send(uint8_t *p_data, uint16_t *p_length) { |
|||
ble_gatts_hvx_params_t hvx_params; |
|||
|
|||
if (!p_datachannel->datablock_tx_channel_is_notification_enabled) { |
|||
return NRF_ERROR_INVALID_STATE; |
|||
} |
|||
|
|||
if (*p_length > ZDATACHANNEL_MAX_DATA_LEN) { |
|||
return NRF_ERROR_INVALID_PARAM; |
|||
} |
|||
memset(&hvx_params, 0, sizeof(hvx_params)); |
|||
|
|||
hvx_params.handle = p_datachannel->datablock_tx_handles.value_handle; |
|||
hvx_params.p_data = p_data; |
|||
hvx_params.p_len = p_length; |
|||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION; |
|||
|
|||
return sd_ble_gatts_hvx(p_datachannel->conn_handle, &hvx_params); |
|||
} |
@ -1,96 +0,0 @@ |
|||
#ifndef ZDATACHANNEL_H__ |
|||
#define ZDATACHANNEL_H__ |
|||
|
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "ble.h" |
|||
#include "ble_link_ctx_manager.h" |
|||
#include "ble_srv_common.h" |
|||
#include "nrf_sdh_ble.h" |
|||
#include "sdk_config.h" |
|||
|
|||
#ifdef __cplusplus |
|||
extern "C" { |
|||
#endif |
|||
|
|||
/**@brief Macro for defining a ble_nus instance. |
|||
* |
|||
* @param _name Name of the instance. |
|||
* @param[in] _nus_max_clients Maximum number of NUS clients connected at a time. |
|||
* @hideinitializer |
|||
*/ |
|||
#define ZDATACHANNEL_DEF(_name, _ble_observer_prio, _nus_max_clients) \ |
|||
static zdatachannel_t _name; \ |
|||
NRF_SDH_BLE_OBSERVER(_name##_obs, _ble_observer_prio, zdatachannel_on_ble_evt, &_name) |
|||
|
|||
#define OPCODE_LENGTH 1 |
|||
#define HANDLE_LENGTH 2 |
|||
|
|||
/**@brief Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ |
|||
#if defined(NRF_SDH_BLE_GATT_MAX_MTU_SIZE) && (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 0) |
|||
#define ZDATACHANNEL_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH) |
|||
#else |
|||
#define ZDATACHANNEL_MAX_DATA_LEN (BLE_GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) |
|||
#warning NRF_SDH_BLE_GATT_MAX_MTU_SIZE is not defined. |
|||
#endif |
|||
|
|||
/**@brief Nordic UART Service event types. */ |
|||
typedef enum { |
|||
ZDATACHANNEL_EVT_RX_DATA, /**< Data received. */ |
|||
} zdatachannel_evt_type_t; |
|||
|
|||
typedef struct zdatachannel_s zdatachannel_t; |
|||
|
|||
typedef struct { |
|||
uint8_t const* p_data; /**< A pointer to the buffer with received data. */ |
|||
uint16_t length; /**< Length of received data. */ |
|||
} zdatachannel_evt_rx_data_t; |
|||
|
|||
typedef struct { |
|||
zdatachannel_evt_type_t type; /**< Event type. */ |
|||
union { |
|||
zdatachannel_evt_rx_data_t rx_data; /**< @ref ZDATACHANNEL_EVT_RX_DATA event data. */ |
|||
} params; |
|||
} zdatachannel_evt_t; |
|||
|
|||
typedef void (*zdatachannel_data_handler_t)(zdatachannel_evt_t* p_evt); |
|||
|
|||
typedef struct { |
|||
zdatachannel_data_handler_t data_handler; |
|||
} zdatachannel_init_t; |
|||
|
|||
struct zdatachannel_s { |
|||
uint8_t uuid_type; /**< UUID type for Nordic UART Service Base UUID. */ |
|||
uint16_t service_handle; /**< Handle of Nordic UART Service (as provided by the SoftDevice). */ |
|||
ble_gatts_char_handles_t cmd_tx_handles; /**< 指令发送句柄 */ |
|||
ble_gatts_char_handles_t cmd_rx_handles; /**< 指令接收句柄 */ |
|||
ble_gatts_char_handles_t datablock_tx_handles; /**< 数据块发送句柄 */ |
|||
zdatachannel_data_handler_t data_handler; /**< Event handler to be called for handling received data. */ |
|||
|
|||
// 状态 |
|||
int16_t conn_handle; |
|||
bool cmd_tx_channel_is_notification_enabled; |
|||
bool datablock_tx_channel_is_notification_enabled; |
|||
}; |
|||
|
|||
uint32_t zdatachannel_init(zdatachannel_t* p_nus, zdatachannel_init_t const* p_nus_init); |
|||
void zdatachannel_on_ble_evt(ble_evt_t const* p_ble_evt, void* p_context); |
|||
bool zdatachannel_is_connected(); |
|||
|
|||
uint32_t zdatachannel_data_send(uint8_t* p_data, uint16_t* p_length); |
|||
static inline uint32_t zdatachannel_data_send2(uint8_t* p_data, uint16_t p_length){ |
|||
return zdatachannel_data_send(p_data, &p_length); |
|||
} |
|||
uint32_t zdatachannel_block_data_send(uint8_t* p_data, uint16_t* p_length); |
|||
static inline uint32_t zdatachannel_block_data_send2(uint8_t* p_data, uint16_t p_length){ |
|||
return zdatachannel_block_data_send(p_data, &p_length); |
|||
} |
|||
|
|||
#ifdef __cplusplus |
|||
} |
|||
#endif |
|||
|
|||
#endif // ZDATACHANNEL_H__ |
|||
|
|||
/** @} */ |
@ -0,0 +1,24 @@ |
|||
#pragma once |
|||
|
|||
/** |
|||
* @brief |
|||
* |
|||
* 200HZ,16bit |
|||
* -> |
|||
* 1s => 200*2 => 400BYTE |
|||
* 248k |
|||
* -> |
|||
* 1s => 248*1024/400 => 634_S => 10.5min |
|||
*/ |
|||
|
|||
#define MAX_STORAGE_TIMEOUT_S (60 * 10) |
|||
#define MAX_STORAGE_SIZE (MAX_STORAGE_TIMEOUT_S * 400) // 存储最大限制为 (256-8)kbyte |
|||
#define MAX_FILE_NUM 10 |
|||
|
|||
#define SAMPLE_RATE 500 |
|||
#define SAMPLE_PRECISION 12 |
|||
|
|||
#define AUTOMATIC_SLEEP_TIME 15000 |
|||
#define SAMPLE_MIN_TIME_S (30.0) |
|||
|
|||
#define ENABLE_SLEEP |
@ -1,22 +1,3 @@ |
|||
#pragma once |
|||
|
|||
/** |
|||
* @brief |
|||
* |
|||
* 200HZ,16bit |
|||
* -> |
|||
* 1s => 200*2 => 400BYTE |
|||
* 248k |
|||
* -> |
|||
* 1s => 248*1024/400 => 634_S => 10.5min |
|||
*/ |
|||
|
|||
#define MAX_STORAGE_TIMEOUT_S (60 * 10) |
|||
#define MAX_STORAGE_SIZE (MAX_STORAGE_TIMEOUT_S * 400) // 存储最大限制为 (256-8)kbyte |
|||
#define MAX_FILE_NUM 10 |
|||
|
|||
#define SAMPLE_RATE 200 |
|||
#define SAMPLE_PRECISION 12 |
|||
|
|||
#define AUTOMATIC_SLEEP_TIME 15000 |
|||
#define SAMPLE_MIN_TIME_S (30.0) |
|||
#include "board/board.h" |
@ -1,101 +0,0 @@ |
|||
//---------------------------------------------------------------------------- |
|||
// Description: This file contains the initialization values for the |
|||
// ADS1293 registers. |
|||
// |
|||
// MSP430/ADS1293 Interface Code Library v1.0 |
|||
// |
|||
// Vishy Natarajan |
|||
// Texas Instruments Inc. |
|||
// April 2013 |
|||
// Built with IAR Embedded Workbench Version: 5.5x |
|||
//------------------------------------------------------------------------------ |
|||
// Change Log: |
|||
//------------------------------------------------------------------------------ |
|||
// Version: 1.00 |
|||
// Comments: Initial Release Version |
|||
//------------------------------------------------------------------------------ |
|||
#ifndef HEADER_FILE_TI_ADS1293_REGISTER_SETTINGS_H |
|||
|
|||
#define HEADER_FILE_TI_ADS1293_REGISTER_SETTINGS_H |
|||
|
|||
/************************************************************ |
|||
* TI ADS1293 REGISTER SET INITIALIZATION VALUES |
|||
************************************************************/ |
|||
|
|||
#define TI_ADS1293_CONFIG_REG_VALUE (0x00) /* Main Configuration */ |
|||
|
|||
#define TI_ADS1293_FLEX_CH1_CN_REG_VALUE (0x0A) /* Flex Routing Swich Control for Channel 1 */ |
|||
#define TI_ADS1293_FLEX_CH2_CN_REG_VALUE (0x1A) /* Flex Routing Swich Control for Channel 2 */ |
|||
#define TI_ADS1293_FLEX_CH3_CN_REG_VALUE (0x00) /* Flex Routing Swich Control for Channel 3 */ |
|||
#define TI_ADS1293_FLEX_PACE_CN_REG_VALUE (0x00) /* Flex Routing Swich Control for Pace Channel */ |
|||
#define TI_ADS1293_FLEX_VBAT_CN_REG_VALUE (0x00) /* Flex Routing Swich Control for Battery Monitoriing */ |
|||
|
|||
#define TI_ADS1293_LOD_CN_REG_VALUE (0x08) /* Lead Off Detect Control */ |
|||
#define TI_ADS1293_LOD_EN_REG_VALUE (0x00) /* Lead Off Detect Enable */ |
|||
#define TI_ADS1293_LOD_CURRENT_REG_VALUE (0x00) /* Lead Off Detect Current */ |
|||
#define TI_ADS1293_LOD_AC_CN_REG_VALUE (0x00) /* AC Lead Off Detect Current */ |
|||
|
|||
#define TI_ADS1293_CMDET_EN_REG_VALUE (0x07) /* Common Mode Detect Enable */ |
|||
#define TI_ADS1293_CMDET_CN_REG_VALUE (0x00) /* Commond Mode Detect Control */ |
|||
#define TI_ADS1293_RLD_CN_REG_VALUE (0x04) /* Right Leg Drive Control */ |
|||
|
|||
#define TI_ADS1293_WILSON_EN1_REG_VALUE (0x00) /* Wilson Reference Input one Selection */ |
|||
#define TI_ADS1293_WILSON_EN2_REG_VALUE (0x00) /* Wilson Reference Input two Selection */ |
|||
#define TI_ADS1293_WILSON_EN3_REG_VALUE (0x00) /* Wilson Reference Input three Selection */ |
|||
#define TI_ADS1293_WILSON_CN_REG_VALUE (0x00) /* Wilson Reference Input Control */ |
|||
|
|||
#define TI_ADS1293_REF_CN_REG_VALUE (0x00) /* Internal Reference Voltage Control */ |
|||
|
|||
#define TI_ADS1293_OSC_CN_REG_VALUE (0x04) /* Clock Source and Output Clock Control */ |
|||
|
|||
#define TI_ADS1293_AFE_RES_REG_VALUE (0x00) /* Analog Front-End Frequency and Resolution */ |
|||
#define TI_ADS1293_AFE_SHDN_CN_REG_VALUE (0x00) /* Analog Front-End Shutdown Control */ |
|||
#define TI_ADS1293_AFE_FAULT_CN_REG_VALUE (0x00) /* Analog Front-End Fault Detection Control */ |
|||
#define TI_ADS1293_AFE_DITHER_EN_REG_VALUE (0x00) /* Enable Dithering in Signma-Delta */ |
|||
#define TI_ADS1293_AFE_PACE_CN_REG_VALUE (0x05) /* Analog Pace Channel Output Routing Control */ |
|||
|
|||
//#define TI_ADS1293_ERROR_LOD_REG_VALUE (0x00) /* Lead Off Detect Error Status */ |
|||
//#define TI_ADS1293_ERROR_STATUS_REG_VALUE (0x72) /* Other Error Status */ |
|||
//#define TI_ADS1293_ERROR_RANGE1_REG_VALUE (0x12) /* Channel 1 Amplifier Out of Range Status */ |
|||
//#define TI_ADS1293_ERROR_RANGE2_REG_VALUE (0x12) /* Channel 1 Amplifier Out of Range Status */ |
|||
//#define TI_ADS1293_ERROR_RANGE3_REG_VALUE (0x36) /* Channel 1 Amplifier Out of Range Status */ |
|||
//#define TI_ADS1293_ERROR_SYNC_REG_VALUE (0x00) /* Synchronization Error */ |
|||
|
|||
|
|||
#define TI_ADS1293_R2_RATE_REG_VALUE (0x02) /* R2 Decimation Rate */ |
|||
#define TI_ADS1293_R3_RATE1_REG_VALUE (0x02) /* R3 Decimation Rate for Channel 1 */ |
|||
#define TI_ADS1293_R3_RATE2_REG_VALUE (0x02) /* R3 Decimation Rate for Channel 2 */ |
|||
#define TI_ADS1293_R3_RATE3_REG_VALUE (0x02) /* R3 Decimation Rate for Channel 3 */ |
|||
#define TI_ADS1293_P_DRATE_REG_VALUE (0x00) /* 2x Pace Data Rate for all channels */ |
|||
#define TI_ADS1293_DIS_EFILTER_REG_VALUE (0x00) /* ECG Filters Disabled */ |
|||
#define TI_ADS1293_DRDYB_SRC_REG_VALUE (0x08) /* Data Ready Pin Source */ |
|||
#define TI_ADS1293_SYNCOUTB_SRC_REG_VALUE (0x00) /* Sync Out Pin Source */ |
|||
#define TI_ADS1293_MASK_DRDYB_REG_VALUE (0x00) /* Optional Mask Control for DRDYB Output */ |
|||
#define TI_ADS1293_MASK_ERR_REG_VALUE (0x00) /* Mask Error on ALARMB Pin */ |
|||
|
|||
#define TI_ADS1293_ALARM_FILTER_REG_VALUE (0x33) /* Digital Filter for Analog Alarm Signals */ |
|||
#define TI_ADS1293_CH_CNFG_REG_VALUE (0x30) /* Configure Channel for Loop Read Back Mode */ |
|||
|
|||
//#define TI_ADS1293_DATA_STATUS_REG_VALUE (0x00) /* ECG and Pace Data Ready Status */ |
|||
//#define TI_ADS1293_DATA_CH1_PACE_H_REG_VALUE (0x00) /* Channel1 Pace Data High [15:8] */ |
|||
//#define TI_ADS1293_DATA_CH1_PACE_L_REG_VALUE (0x00) /* Channel1 Pace Data Low [7:0] */ |
|||
//#define TI_ADS1293_DATA_CH2_PACE_H_REG_VALUE (0x00) /* Channel2 Pace Data High [15:8] */ |
|||
//#define TI_ADS1293_DATA_CH2_PACE_L_REG_VALUE (0x00) /* Channel2 Pace Data Low [7:0] */ |
|||
//#define TI_ADS1293_DATA_CH3_PACE_H_REG_VALUE (0x00) /* Channel3 Pace Data High [15:8] */ |
|||
//#define TI_ADS1293_DATA_CH3_PACE_L_REG_VALUE (0x00) /* Channel3 Pace Data Low [7:0] */ |
|||
//#define TI_ADS1293_DATA_CH1_ECG_H_REG_VALUE (0x00) /* Channel1 ECG Data High [23:16] */ |
|||
//#define TI_ADS1293_DATA_CH1_ECG_M_REG_VALUE (0x00) /* Channel1 ECG Data Medium [15:8] */ |
|||
//#define TI_ADS1293_DATA_CH1_ECG_L_REG_VALUE (0x00) /* Channel1 ECG Data Low [7:0] */ |
|||
//#define TI_ADS1293_DATA_CH2_ECG_H_REG_VALUE (0x00) /* Channel2 ECG Data High [23:16] */ |
|||
//#define TI_ADS1293_DATA_CH2_ECG_M_REG_VALUE (0x00) /* Channel2 ECG Data Medium [15:8] */ |
|||
//#define TI_ADS1293_DATA_CH2_ECG_L_REG_VALUE (0x00) /* Channel2 ECG Data Low [7:0] */ |
|||
//#define TI_ADS1293_DATA_CH3_ECG_H_REG_VALUE (0x00) /* Channel3 ECG Data High [23:16] */ |
|||
//#define TI_ADS1293_DATA_CH3_ECG_M_REG_VALUE (0x00) /* Channel3 ECG Data Medium [15:8] */ |
|||
//#define TI_ADS1293_DATA_CH3_ECG_L_REG_VALUE (0x00) /* Channel3 ECG Data Low [7:0] */ |
|||
|
|||
#define TI_ADS1293_REVID_REG_VALUE (0x40) /* Revision ID */ |
|||
#define TI_ADS1293_DATA_LOOP_REG_VALUE (0x50) /* Loop Read Back Address */ |
|||
|
|||
// Useful definitions |
|||
#define ADS1293_START_CONV (0x01) // Start Conversion Bit |
|||
#endif |
@ -1,148 +0,0 @@ |
|||
#pragma once |
|||
#include <stdint.h> |
|||
|
|||
typedef struct { |
|||
uint8_t add; |
|||
uint8_t data; |
|||
} adscfg_t; |
|||
#if 1 |
|||
static adscfg_t ads0cfg[] = { |
|||
{0x00, 0x00}, // |
|||
{0x01, 0x0a}, // |
|||
{0x02, 0x1a}, // |
|||
{0x03, 0x00}, // |
|||
{0x04, 0x00}, // |
|||
{0x05, 0x00}, // |
|||
{0x06, 0x04}, // |
|||
{0x07, 0x0f}, // |
|||
{0x08, 0xff}, // |
|||
{0x09, 0x00}, // |
|||
{0x0a, 0x07}, // |
|||
{0x0b, 0x00}, // |
|||
{0x0c, 0x04}, // |
|||
{0x0d, 0x00}, // |
|||
{0x0e, 0x00}, // |
|||
{0x0f, 0x00}, // |
|||
{0x10, 0x00}, // |
|||
{0x11, 0x00}, // |
|||
{0x12, 0x04}, // |
|||
{0x13, 0x00}, // |
|||
{0x14, 0x00}, // |
|||
{0x15, 0x00}, // |
|||
{0x16, 0x00}, // |
|||
{0x17, 0x05}, // |
|||
{0x18, 0x00}, // |
|||
{0x19, 0x00}, // |
|||
{0x1a, 0x00}, // |
|||
{0x1b, 0x00}, // |
|||
{0x1c, 0x00}, // |
|||
{0x1d, 0x00}, // |
|||
{0x21, 0x02}, // |
|||
{0x22, 0x02}, // |
|||
{0x23, 0x02}, // |
|||
{0x24, 0x02}, // |
|||
{0x25, 0x00}, // |
|||
{0x26, 0x00}, // |
|||
{0x27, 0x08}, // |
|||
{0x28, 0x00}, // |
|||
{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 ads1cfg[] = { |
|||
{0x00, 0x00}, // |
|||
{0x01, 0x0c}, // |
|||
{0x02, 0x14}, // |
|||
{0x03, 0x04}, // |
|||
{0x04, 0x00}, // |
|||
{0x05, 0x00}, // |
|||
{0x06, 0x02}, // |
|||
{0x07, 0x0f}, // |
|||
{0x08, 0x13}, // |
|||
{0x09, 0x01}, // |
|||
{0x0a, 0x0f}, // |
|||
{0x0b, 0x00}, // |
|||
{0x0c, 0x00}, // |
|||
{0x0d, 0x00}, // |
|||
{0x0e, 0x00}, // |
|||
{0x0f, 0x00}, // |
|||
{0x10, 0x01}, // |
|||
|
|||
{0x11, 0x00}, // |
|||
{0x12, 0x07}, // |
|||
{0x13, 0x00}, // |
|||
{0x14, 0x00}, // |
|||
{0x15, 0x00}, // |
|||
{0x16, 0x00}, // |
|||
{0x17, 0x05}, // |
|||
{0x18, 0x00}, // |
|||
{0x19, 0x00}, // |
|||
{0x1a, 0x00}, // |
|||
{0x1b, 0x00}, // |
|||
{0x1c, 0x00}, // |
|||
{0x1d, 0x00}, // |
|||
{0x21, 0x02}, // |
|||
{0x22, 0x02}, // |
|||
{0x23, 0x02}, // |
|||
{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}, // |
|||
|
|||
}; |
|||
#endif |
@ -1,538 +0,0 @@ |
|||
#include "three_lead_board.h" |
|||
|
|||
#include "znordic.h" |
|||
// |
|||
#include "app_timer.h" |
|||
#include "basic\ads1293\ads1293.h" |
|||
#include "diskio_blkdev.h" |
|||
#include "ff.h" |
|||
#include "nrf_block_dev_sdc.h" |
|||
#include "nrf_delay.h" |
|||
#include "nrf_drv_pwm.h" |
|||
#include "nrf_drv_saadc.h" |
|||
#include "nrf_drv_twi.h" |
|||
#include "nrf_drv_wdt.h" |
|||
#include "nrf_gpio.h" |
|||
|
|||
#define LED_GREEN_PIN 9 |
|||
|
|||
#define BATTERY_ADC_PIN NRF_SAADC_INPUT_AIN0 |
|||
#define BATTERY_ADC_CHANNEL 1 // 不重复即可 |
|||
|
|||
#define BUTTON_PIN 0 |
|||
|
|||
#define BEEP_PWM_INSTANCE 0 |
|||
#define BEEP_PIN 18 |
|||
|
|||
#define SDCARD_SPI_SCK_PIN 4 |
|||
#define SDCARD_SPI_CS_PIN 5 |
|||
#define SDCARD_SPI_MISO_PIN 11 |
|||
#define SDCARD_SPI_MOSI_PIN 17 |
|||
|
|||
#define SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN 1 |
|||
#define SDCARD_USBDRIVER_IC_RESET_PIN 28 |
|||
#define SDCARD_POWER_CTRL_PIN 30 |
|||
|
|||
#define ADS1293_SPI_SCK_PIN (32 + 9) |
|||
#define ADS1293_SPI_MOSI_PIN 15 |
|||
#define ADS1293_SPI_MISO_PIN 20 |
|||
#define ADS1293_SPI_CS0_PIN 3 |
|||
#define ADS1293_SPI_CS1_PIN 29 |
|||
#define ADS1293_READY_PIN 31 |
|||
|
|||
#define LINE_DET_PIN 10 |
|||
|
|||
/******************************************************************************* |
|||
* TOOLS * |
|||
*******************************************************************************/ |
|||
|
|||
/******************************************************************************* |
|||
* ADC * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_adc_module_init() { |
|||
nrf_drv_saadc_config_t adccfg = NRFX_SAADC_DEFAULT_CONFIG; |
|||
adccfg.resolution = NRF_SAADC_RESOLUTION_12BIT; // 4096 等于满采样率 |
|||
ZERROR_CHECK(nrf_drv_saadc_init(&adccfg, NULL)); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* BUTTON * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_button_init() { // |
|||
nrf_gpio_cfg_sense_input(BUTTON_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); |
|||
} |
|||
bool ThreeLeadECG_button_get_state() { |
|||
// 低电平有效 |
|||
return nrf_gpio_pin_read(BUTTON_PIN) == 0; |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 蜂鸣器 * |
|||
*******************************************************************************/ |
|||
static nrf_drv_pwm_t m_beep_pwm0 = NRF_DRV_PWM_INSTANCE(BEEP_PWM_INSTANCE); |
|||
static nrf_pwm_values_individual_t m_beep_pwm0_seq_values = {0}; |
|||
static nrf_pwm_sequence_t const m_beep_pwm0_seq = { |
|||
.values.p_individual = &m_beep_pwm0_seq_values, |
|||
.length = NRF_PWM_VALUES_LENGTH(m_beep_pwm0_seq_values), |
|||
.repeats = 0, |
|||
.end_delay = 0, |
|||
}; |
|||
static nrf_drv_pwm_config_t const m_beep_pwm0_config0 = { |
|||
.output_pins = {BEEP_PIN}, |
|||
.irq_priority = APP_IRQ_PRIORITY_LOWEST, |
|||
.base_clock = NRF_PWM_CLK_125kHz, |
|||
.count_mode = NRF_PWM_MODE_UP, |
|||
.top_value = 46, // 125kHz / 46 = 2.717k |
|||
.load_mode = NRF_PWM_LOAD_INDIVIDUAL, |
|||
.step_mode = NRF_PWM_STEP_AUTO, |
|||
}; |
|||
void ThreeLeadECG_beep_init() { |
|||
znrf_gpio_cfg_output(BEEP_PIN, NRF_GPIO_PIN_NOPULL); |
|||
nrf_gpio_pin_set(BEEP_PIN); |
|||
|
|||
APP_ERROR_CHECK(nrfx_pwm_init(&m_beep_pwm0, &m_beep_pwm0_config0, NULL)); |
|||
} |
|||
void ThreeLeadECG_beep_set_state(bool state) { |
|||
if (state) { |
|||
m_beep_pwm0_seq_values.channel_0 = 23; // 设置占空比,数值最大不超过 top_value |
|||
nrfx_pwm_simple_playback(&m_beep_pwm0, &m_beep_pwm0_seq, 1, NRF_DRV_PWM_FLAG_LOOP); |
|||
} else { |
|||
nrfx_pwm_stop(&m_beep_pwm0, true); |
|||
} |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* LED * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_led_init() { znrf_gpio_cfg_output(LED_GREEN_PIN, NRF_GPIO_PIN_NOPULL); } |
|||
void ThreeLeadECG_led_green_set_state(bool state) { |
|||
if (state) { |
|||
nrf_gpio_pin_set(LED_GREEN_PIN); |
|||
} else { |
|||
nrf_gpio_pin_clear(LED_GREEN_PIN); |
|||
} |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* BATTERY * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_battery_init() { |
|||
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(BATTERY_ADC_PIN); |
|||
channel_config.acq_time = NRF_SAADC_ACQTIME_10US; |
|||
ZERROR_CHECK(nrfx_saadc_channel_init(BATTERY_ADC_CHANNEL, &channel_config)); |
|||
} |
|||
int16_t ThreeLeadECG_battery_get_adc_val() { |
|||
int16_t val = znrf_adc_channel_read_val(BATTERY_ADC_CHANNEL); |
|||
return val; |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* SDCARD * |
|||
*******************************************************************************/ |
|||
|
|||
/** |
|||
* @brief |
|||
* |
|||
* SPI |
|||
* nand flash |
|||
* sd card |
|||
* switch |
|||
*/ |
|||
|
|||
void ThreeLeadECG_sdcard_base_init() { // |
|||
/** |
|||
* @brief spi引脚切换成输入 |
|||
*/ |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_CS_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_MISO_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_MOSI_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_SCK_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
/** |
|||
* @brief USBDRIVER_IC_RESET_PIN ctrl pin |
|||
*/ |
|||
znrf_gpio_cfg_output(SDCARD_USBDRIVER_IC_RESET_PIN, NRF_GPIO_PIN_NOPULL); |
|||
nrf_gpio_pin_write(SDCARD_USBDRIVER_IC_RESET_PIN, 1); |
|||
/** |
|||
* @brief 初始化 SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN |
|||
*/ |
|||
znrf_gpio_cfg_output(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN, NRF_GPIO_PIN_NOPULL); |
|||
nrf_gpio_pin_write(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN, 0); // OE = 0 |
|||
/** |
|||
* @brief SDCARD电源控制引脚 |
|||
*/ |
|||
znrf_gpio_cfg_output(SDCARD_POWER_CTRL_PIN, NRF_GPIO_PIN_NOPULL); |
|||
nrf_gpio_pin_write(SDCARD_POWER_CTRL_PIN, 0); // POWER = 0 |
|||
} |
|||
void ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic_reset() { |
|||
nrf_gpio_pin_clear(SDCARD_USBDRIVER_IC_RESET_PIN); |
|||
nrf_delay_ms(10); |
|||
nrf_gpio_pin_set(SDCARD_USBDRIVER_IC_RESET_PIN); |
|||
} |
|||
void ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic(bool connect) { |
|||
if (!connect) { |
|||
nrf_gpio_pin_clear(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN); |
|||
} else { |
|||
nrf_gpio_pin_set(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN); |
|||
} |
|||
} |
|||
void ThreeLeadECG_sdcard_flash_power_ctrl(bool power) { |
|||
if (!power) { |
|||
nrf_gpio_pin_set(SDCARD_POWER_CTRL_PIN); |
|||
} else { |
|||
nrf_gpio_pin_clear(SDCARD_POWER_CTRL_PIN); |
|||
} |
|||
} |
|||
|
|||
void ThreeLeadECG_sdcard_spi_umount() { |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_CS_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_MISO_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_MOSI_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
nrf_gpio_cfg_sense_input(SDCARD_SPI_SCK_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
} |
|||
|
|||
void ThreeLeadECG_sdcard_init() { |
|||
/** |
|||
* @brief |
|||
* 0. 必要引脚初始化 |
|||
* 1. spi引脚切换成输入 |
|||
* 2. 连接flash和usbflash驱动器连接 |
|||
* <----option----> |
|||
* 4. 打开flash电源 |
|||
* |
|||
*/ |
|||
ThreeLeadECG_sdcard_base_init(); // 必要引脚初始化 |
|||
// ThreeLeadECG_sdcard_spi_umount(); // |
|||
// ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic(true); |
|||
// ThreeLeadECG_sdcard_flash_power_ctrl(true); |
|||
} |
|||
|
|||
NRF_BLOCK_DEV_SDC_DEFINE(m_block_dev_sdc, // |
|||
NRF_BLOCK_DEV_SDC_CONFIG(SDC_SECTOR_SIZE, // |
|||
APP_SDCARD_CONFIG(SDCARD_SPI_MOSI_PIN, // |
|||
SDCARD_SPI_MISO_PIN, // |
|||
SDCARD_SPI_SCK_PIN, // |
|||
SDCARD_SPI_CS_PIN)), |
|||
NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00")); |
|||
static FATFS fs; |
|||
|
|||
void sdcard_test_write_text() { |
|||
#define FILE_NAME "/6.TXT" |
|||
static FIL file; |
|||
uint32_t bytes_written; |
|||
static DIR dir; |
|||
static FILINFO fno; |
|||
|
|||
NRF_LOG_INFO("\r\n Listing directory: /"); |
|||
FRESULT ff_result = f_opendir(&dir, "/"); |
|||
if (ff_result) { |
|||
NRF_LOG_INFO("Directory listing failed!"); |
|||
return; |
|||
} |
|||
|
|||
do { |
|||
ff_result = f_readdir(&dir, &fno); |
|||
if (ff_result != FR_OK) { |
|||
NRF_LOG_INFO("Directory read failed."); |
|||
return; |
|||
} |
|||
|
|||
if (fno.fname[0]) { |
|||
if (fno.fattrib & AM_DIR) { |
|||
NRF_LOG_RAW_INFO(" <DIR> %s", (uint32_t)fno.fname); |
|||
} else { |
|||
NRF_LOG_RAW_INFO("%9lu %s", fno.fsize, (uint32_t)fno.fname); |
|||
} |
|||
} |
|||
} while (fno.fname[0]); |
|||
NRF_LOG_RAW_INFO(""); |
|||
NRF_LOG_INFO("read from file " FILE_NAME "..."); |
|||
{ |
|||
ff_result = f_open(&file, FILE_NAME, FA_READ); |
|||
if (ff_result == FR_OK) { |
|||
static char rxbuf[20] = {0}; |
|||
UINT rxsize; |
|||
ff_result = f_read(&file, rxbuf, 19, &rxsize); |
|||
if (ff_result != FR_OK) { |
|||
NRF_LOG_INFO("read failed\r\n."); |
|||
} else { |
|||
NRF_LOG_INFO("read %s(%d)", rxbuf, rxsize); |
|||
} |
|||
(void)f_close(&file); |
|||
} |
|||
} |
|||
|
|||
NRF_LOG_INFO("Writing to file " FILE_NAME "..."); |
|||
{ |
|||
ff_result = f_open(&file, FILE_NAME, FA_CREATE_ALWAYS | FA_READ | FA_WRITE); |
|||
if (ff_result != FR_OK) { |
|||
NRF_LOG_INFO("Unable to open or create file: " FILE_NAME ". %d", ff_result); |
|||
return; |
|||
} |
|||
|
|||
ff_result = f_write(&file, "iflytop", sizeof("iflytop") - 1, (UINT*)&bytes_written); |
|||
if (ff_result != FR_OK) { |
|||
NRF_LOG_INFO("Write failed\r\n."); |
|||
} else { |
|||
NRF_LOG_INFO("%d bytes written.", bytes_written); |
|||
} |
|||
|
|||
(void)f_close(&file); |
|||
} |
|||
} |
|||
bool mountsuc = false; |
|||
/** |
|||
* @brief 对接 get_fattime |
|||
* @return DWORD |
|||
*/ |
|||
|
|||
static DWORD get_fattime_0(uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t min, uint32_t sec) { |
|||
// return ((DWORD)(year - 1980) << 25 | (DWORD)month << 21 | (DWORD)day << 16); |
|||
DWORD fattime = 0; |
|||
fattime |= ((DWORD)(year - 1980) << 25); // 年份从1980年开始 |
|||
fattime |= ((DWORD)(month + 1) << 21); // 月份范围是1-12 |
|||
fattime |= ((DWORD)day << 16); // 日 |
|||
fattime |= ((DWORD)hour << 11); // 时 |
|||
fattime |= ((DWORD)min << 5); // 分 |
|||
fattime |= ((DWORD)sec / 2); // 秒,以2秒为单位 |
|||
|
|||
return fattime; |
|||
} |
|||
|
|||
DWORD get_fattime(void) { |
|||
return get_fattime_0(2024, 1, 23, 23, 29, 31); |
|||
// ((DWORD)(_NORTC_YEAR - 1980) << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16) |
|||
} |
|||
|
|||
void ThreeLeadECG_sdcard_mount() { |
|||
/** |
|||
* @brief |
|||
* 1. 关闭flash电源 |
|||
* 2. 断开flash和usbflash驱动器连接 |
|||
* 3. 打开flash电源 |
|||
* 4. 初始化SPI引脚,驱动flash |
|||
*/ |
|||
|
|||
nrf_gpio_pin_write(SDCARD_POWER_CTRL_PIN, 1); // 关 |
|||
nrf_gpio_pin_write(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN, 1); |
|||
nrf_gpio_pin_write(SDCARD_POWER_CTRL_PIN, 0); // 开 |
|||
|
|||
/** |
|||
* @brief |
|||
* 1. 初始化SPI引脚,驱动flash |
|||
*/ |
|||
if (!mountsuc) { |
|||
static diskio_blkdev_t drives[] = // |
|||
{DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev), NULL)}; |
|||
|
|||
diskio_blockdev_register(drives, ARRAY_SIZE(drives)); |
|||
|
|||
DSTATUS disk_state = STA_NOINIT; |
|||
for (uint32_t retries = 3; retries && disk_state; --retries) { |
|||
disk_state = disk_initialize(0); |
|||
} |
|||
if (disk_state) { |
|||
NRF_LOG_INFO("Disk initialization failed. %d", disk_state); |
|||
return; |
|||
} |
|||
NRF_LOG_INFO("Disk initialization succeeded."); |
|||
|
|||
FRESULT ff_result; |
|||
// ff_result = f_mkfs("0:", FM_FAT, 4096, NULL, 0); |
|||
// if (ff_result) { |
|||
// NRF_LOG_INFO("mkfs failed. %d",ff_result); |
|||
// return; |
|||
// } |
|||
|
|||
ff_result = f_mount(&fs, "", 1); |
|||
if (ff_result) { |
|||
NRF_LOG_INFO("Mount failed."); |
|||
return; |
|||
} |
|||
ZLOGI("Mount success"); |
|||
|
|||
uint32_t blocks_per_mb = (1024uL * 1024uL) / m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_size; |
|||
uint32_t capacity = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count / blocks_per_mb; |
|||
NRF_LOG_INFO("Capacity: %d MB", capacity); |
|||
|
|||
mountsuc = true; |
|||
} |
|||
|
|||
sdcard_test_write_text(); |
|||
} |
|||
void ThreeLeadECG_sdcard_umount() { |
|||
/** |
|||
* @brief |
|||
* 1. 卸载磁盘 |
|||
* 2. 失能SPI引脚 |
|||
* 3. SPI引脚切换成输入高阻 |
|||
* 4. 关闭flash电源 |
|||
* 5. 连接flash和usbflash驱动器连接 |
|||
* <----option----> |
|||
* 6. 打开flash电源(硬件改版后,flash的电可以从USB上取,就不需要再打开flash电源了) |
|||
*/ |
|||
// umount |
|||
f_mount(NULL, "", 1); |
|||
disk_uninitialize(0); |
|||
ThreeLeadECG_sdcard_spi_umount(); |
|||
|
|||
nrf_gpio_pin_write(SDCARD_POWER_CTRL_PIN, 1); // 关 |
|||
nrf_gpio_pin_write(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_NOE_PIN, 0); |
|||
nrf_delay_ms(100); |
|||
nrf_gpio_pin_write(SDCARD_POWER_CTRL_PIN, 0); // 开 |
|||
|
|||
nrf_gpio_pin_write(SDCARD_USBDRIVER_IC_RESET_PIN, 0); |
|||
nrf_delay_ms(10); |
|||
nrf_gpio_pin_write(SDCARD_USBDRIVER_IC_RESET_PIN, 1); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* ecg * |
|||
*******************************************************************************/ |
|||
|
|||
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(2); /**< SPI instance. */ |
|||
|
|||
static ads1293_t m_ads1293_0; // U2 |
|||
static ads1293_t m_ads1293_1; // U3 |
|||
|
|||
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); |
|||
} |
|||
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); |
|||
} |
|||
void ads1293_spi_writereg_and_check(ads1293_t* ads, uint8_t addr, uint8_t data) { |
|||
uint8_t readbak = 0; |
|||
// readonly add |
|||
if (addr == 0x19 || addr == 0x1a || addr == 0x1b || addr == 0x1c || addr == 0x40 || addr == 0x30) { |
|||
return; |
|||
} |
|||
ads1293_spi_writereg_and_readbak(ads, addr, data, &readbak); |
|||
if (readbak != data) { |
|||
ZLOGE("ads_%d write %x failed,w:%x readbak:%x", ads->id, addr, data, readbak); |
|||
} |
|||
} |
|||
#include "ads_cfg.h" |
|||
#include "TI_ADS1293_register_settings.h" |
|||
void ThreeLeadECG_ecg_reg_config() { |
|||
for (uint16_t i = 0; i < ZARRAY_SIZE(ads0cfg); i++) { |
|||
ads1293_spi_writereg_and_check(&m_ads1293_0, ads0cfg[i].add, ads0cfg[i].data); |
|||
} |
|||
for (uint16_t i = 0; i < ZARRAY_SIZE(ads1cfg); i++) { |
|||
ads1293_spi_writereg_and_check(&m_ads1293_1, ads1cfg[i].add, ads1cfg[i].data); |
|||
} |
|||
|
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_CONFIG_REG, TI_ADS1293_CONFIG_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_FLEX_CH1_CN_REG, TI_ADS1293_FLEX_CH1_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_FLEX_CH2_CN_REG, TI_ADS1293_FLEX_CH2_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_FLEX_CH3_CN_REG, TI_ADS1293_FLEX_CH3_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_FLEX_PACE_CN_REG, TI_ADS1293_FLEX_PACE_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_FLEX_VBAT_CN_REG, TI_ADS1293_FLEX_VBAT_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_LOD_CN_REG, TI_ADS1293_LOD_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_LOD_EN_REG, TI_ADS1293_LOD_EN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_LOD_CURRENT_REG, TI_ADS1293_LOD_CURRENT_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_LOD_AC_CN_REG, TI_ADS1293_LOD_AC_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_CMDET_EN_REG, TI_ADS1293_CMDET_EN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_CMDET_CN_REG, TI_ADS1293_CMDET_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_RLD_CN_REG, TI_ADS1293_RLD_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_WILSON_EN1_REG, TI_ADS1293_WILSON_EN1_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_WILSON_EN2_REG, TI_ADS1293_WILSON_EN2_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_WILSON_EN3_REG, TI_ADS1293_WILSON_EN3_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_WILSON_CN_REG, TI_ADS1293_WILSON_CN_REG_VALUE); |
|||
|
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_REF_CN_REG, TI_ADS1293_REF_CN_REG_VALUE); |
|||
|
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_OSC_CN_REG, TI_ADS1293_OSC_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_AFE_RES_REG, TI_ADS1293_AFE_RES_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_AFE_SHDN_CN_REG, TI_ADS1293_AFE_SHDN_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_AFE_FAULT_CN_REG, TI_ADS1293_AFE_FAULT_CN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_AFE_DITHER_EN_REG, TI_ADS1293_AFE_DITHER_EN_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_AFE_PACE_CN_REG, TI_ADS1293_AFE_PACE_CN_REG_VALUE); |
|||
|
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_R2_RATE_REG, TI_ADS1293_R2_RATE_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_R3_RATE1_REG, TI_ADS1293_R3_RATE1_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_R3_RATE2_REG, TI_ADS1293_R3_RATE2_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_R3_RATE3_REG, TI_ADS1293_R3_RATE3_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_P_DRATE_REG, TI_ADS1293_P_DRATE_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_DIS_EFILTER_REG, TI_ADS1293_DIS_EFILTER_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_DRDYB_SRC_REG, TI_ADS1293_DRDYB_SRC_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_SYNCOUTB_SRC_REG, TI_ADS1293_SYNCOUTB_SRC_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_MASK_DRDYB_REG, TI_ADS1293_MASK_DRDYB_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_MASK_ERR_REG, TI_ADS1293_MASK_ERR_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_ALARM_FILTER_REG, TI_ADS1293_ALARM_FILTER_REG_VALUE); |
|||
// ads1293_spi_writereg_and_check(&m_ads1293_1,TI_ADS1293_CH_CNFG_REG, TI_ADS1293_CH_CNFG_REG_VALUE); |
|||
} |
|||
|
|||
void ThreeLeadECG_ads1293_start_convert() { |
|||
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_CONFIG_REG, 0x01); |
|||
ads1293_spi_writereg(&m_ads1293_1, TI_ADS1293_CONFIG_REG, 0x01); |
|||
} |
|||
void ThreeLeadECG_ecg_init() { |
|||
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_cfg_input(ADS1293_READY_PIN, NRF_GPIO_PIN_PULLUP); |
|||
|
|||
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); |
|||
NRF_LOG_INFO("ads1293_0 revid: %d", revid); |
|||
revid = ads1293_spi_readreg(&m_ads1293_1, TI_ADS1293_REVID_REG); |
|||
NRF_LOG_INFO("ads1293_1 revid: %d", revid); |
|||
|
|||
ThreeLeadECG_ecg_reg_config(); |
|||
ThreeLeadECG_ads1293_start_convert(); |
|||
} |
|||
uint32_t ThreeLeadECG_ready_pin_state_get() { return nrf_gpio_pin_read(ADS1293_READY_PIN); } |
|||
|
|||
uint32_t ThreeLeadECG_ads1293_init() {} |
|||
|
|||
void ThreeLeadECG_ads1293_get_lod_state(uint16_t* state) { // |
|||
uint8_t lod0 = ads1293_read_error_lod(&m_ads1293_0); |
|||
uint8_t lod1 = ads1293_read_error_lod(&m_ads1293_1); |
|||
*state = (lod0) | (lod1 << 8); |
|||
} |
|||
|
|||
void ThreeLeadECG_ads1293_sample_all(uint32_t* sample0, uint32_t* sample1, uint32_t* sample2, uint32_t* sample10, uint32_t* sample11, uint32_t* sample12) { |
|||
// *sample0 |
|||
ads1293_read_ecg(&m_ads1293_0, 1, sample0); |
|||
ads1293_read_ecg(&m_ads1293_0, 2, sample1); |
|||
ads1293_read_ecg(&m_ads1293_0, 3, sample2); |
|||
// *sample1 |
|||
ads1293_read_ecg(&m_ads1293_1, 1, sample10); |
|||
ads1293_read_ecg(&m_ads1293_1, 2, sample11); |
|||
ads1293_read_ecg(&m_ads1293_1, 3, sample12); |
|||
} |
|||
void ThreeLeadECG_ads1293_sample(uint32_t* sample0, uint32_t* sample1, uint32_t* sample2) { |
|||
// *sample0 |
|||
ads1293_read_ecg(&m_ads1293_0, 1, sample0); |
|||
ads1293_read_ecg(&m_ads1293_1, 1, sample1); |
|||
ads1293_read_ecg(&m_ads1293_1, 2, sample2); |
|||
} |
|||
|
|||
void ThreeLeadECG_LineInputDet_init() { |
|||
// LINE_DET_PIN |
|||
nrf_gpio_cfg_input(LINE_DET_PIN, NRF_GPIO_PIN_PULLUP); |
|||
} |
|||
uint32_t ThreeLeadECG_LineInputDet_get_state() { return nrf_gpio_pin_read(LINE_DET_PIN); } |
@ -1,56 +0,0 @@ |
|||
#pragma once |
|||
#define VERSION 1 |
|||
#define MANUFACTURER_NAME "iflytop" |
|||
#define BLE_NAME "iflytop_test" |
|||
|
|||
/******************************************************************************* |
|||
* INCLUDE * |
|||
*******************************************************************************/ |
|||
#include <stdbool.h> |
|||
|
|||
#include "basic/ssd1306/driver_ssd1306_interface.h" |
|||
|
|||
/******************************************************************************* |
|||
* basic * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_adc_module_init(); |
|||
/******************************************************************************* |
|||
* BUTTON * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_button_init(); |
|||
bool ThreeLeadECG_button_get_state(); |
|||
/******************************************************************************* |
|||
* 蜂鸣器 * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_beep_init(); |
|||
void ThreeLeadECG_beep_set_state(bool state); |
|||
|
|||
/******************************************************************************* |
|||
* LED * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_led_init(); |
|||
void ThreeLeadECG_led_green_set_state(bool state); |
|||
/******************************************************************************* |
|||
* BATTERY * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_battery_init(); |
|||
int16_t ThreeLeadECG_battery_get_adc_val(); |
|||
/******************************************************************************* |
|||
* SDCARD * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic_reset(); |
|||
void ThreeLeadECG_sdcard_init(); |
|||
void ThreeLeadECG_sdcard_mount(); |
|||
void ThreeLeadECG_sdcard_umount(); |
|||
/******************************************************************************* |
|||
* ECG * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_ecg_init(); |
|||
uint32_t ThreeLeadECG_ready_pin_state_get(); |
|||
void ThreeLeadECG_ads1293_get_lod_state(uint16_t* state); |
|||
|
|||
// |
|||
void ThreeLeadECG_LineInputDet_init(); |
|||
uint32_t ThreeLeadECG_LineInputDet_get_state(); |
|||
void ThreeLeadECG_ads1293_sample(uint32_t* sample0, uint32_t* sample1, uint32_t* sample2); |
|||
void ThreeLeadECG_ads1293_sample_all(uint32_t* sample0, uint32_t* sample1, uint32_t* sample2, uint32_t* sample10, uint32_t* sample11, uint32_t* sample12); |
48
ble_app_uart_c/ble_app_uart_c_pca10100_s122.uvguix.h_zha
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1 +1 @@ |
|||
Subproject commit 9fccfb3e530ffd0289bc36ba3b13509f90bb4323 |
|||
Subproject commit dd5788e214bada44f7f8906702a52fed9b3a91ae |
@ -0,0 +1 @@ |
|||
g++ -static -static-libgcc -static-libstdc++ -lwsock32 -lstdc++ .\sample_bin_parse.c -o sample_bin_parse.exe |
@ -1 +1 @@ |
|||
Subproject commit 45186701cdfa870204e0975dbf12a0feb50be71d |
|||
Subproject commit 4f5e973ddbe1d68ac130618c5db82f075821e976 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue