10 changed files with 62 additions and 1604 deletions
-
14app/src/app_event.h
-
455app/src/bak/ble_cmd_process_service.c
-
16app/src/bak/ble_cmd_process_service.h
-
152app/src/bak/heart_wave_sample_service.c
-
15app/src/bak/heart_wave_sample_service.h
-
372app/src/bak/main.bak.c
-
527app/src/bak/three_lead_board.c
-
56app/src/bak/three_lead_board.h
-
24app/src/device_ctrl_service.c
-
35app/src/heart_wave_sample_service.c
@ -1,455 +0,0 @@ |
|||
#include "ble_cmd_process_service.h" |
|||
|
|||
#include "basic/device_info_mgr.h" |
|||
#include "basic/heart_rate_sensor_protocol.h" |
|||
#include "basic/zble_module.h" |
|||
#include "basic/zdatachannel_service.h" |
|||
#include "config.h" |
|||
#include "one_conduction_board.h" |
|||
#include "sample_data_manager.h" |
|||
|
|||
APP_TIMER_DEF(m_record_upload_tmr); // 数据上报定时器 |
|||
APP_TIMER_DEF(m_record_upload_finish_packet_report_tmr); // 数据上报完成上报定时器 |
|||
static uint8_t txbuf[128]; |
|||
static uint8_t reportbuf[128]; |
|||
static bool m_realtime_report_state = false; |
|||
static bool m_isupload_data_state = false; |
|||
static bool m_ble_cmder_is_inited = false; |
|||
static uint32_t m_report_data_sumcheckcode = 0; |
|||
|
|||
static void record_upload_tmr_cb(void* p_context); |
|||
static void record_upload_finish_packet_report_tmr_cb(void* p_context); |
|||
int ble_stop_upload_record(); |
|||
/******************************************************************************* |
|||
* 广播控制 * |
|||
*******************************************************************************/ |
|||
void ble_cmder_start_adv() { |
|||
m_realtime_report_state = false; |
|||
zble_module_start_adv(); |
|||
} |
|||
void ble_cmder_stop_adv() { |
|||
zble_module_stop_adv(); |
|||
m_realtime_report_state = false; |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 模块初始化 * |
|||
*******************************************************************************/ |
|||
void ble_cmder_init() { |
|||
if (!m_ble_cmder_is_inited) { |
|||
ZERROR_CHECK(app_timer_create(&m_record_upload_tmr, APP_TIMER_MODE_REPEATED, record_upload_tmr_cb)); |
|||
ZERROR_CHECK(app_timer_create(&m_record_upload_finish_packet_report_tmr, APP_TIMER_MODE_SINGLE_SHOT, record_upload_finish_packet_report_tmr_cb)); |
|||
} |
|||
m_ble_cmder_is_inited = true; |
|||
} |
|||
void ble_cmder_uninit() {} |
|||
|
|||
/******************************************************************************* |
|||
* 实时上报控制 * |
|||
*******************************************************************************/ |
|||
int ble_start_realtime_report() { |
|||
m_realtime_report_state = true; |
|||
return 0; |
|||
} |
|||
int ble_stop_realtime_report() { |
|||
m_realtime_report_state = false; |
|||
return 0; |
|||
} |
|||
void ble_cmder_try_report_one_sample_data(uint32_t frameIndex, uint16_t data) { |
|||
if (!m_realtime_report_state) { |
|||
return; |
|||
} |
|||
|
|||
heartrate_report_packet_t* reportpacket = (heartrate_report_packet_t*)reportbuf; |
|||
reportpacket->cmd = ify_hrs_report_heartrate_data; |
|||
reportpacket->frame_index = 0; |
|||
reportpacket->frame_type = kifyhrs_pt_report; |
|||
reportpacket->sample_data_index = frameIndex; |
|||
|
|||
/** |
|||
* @brief 第一导联数据 |
|||
*/ |
|||
reportpacket->data[0] = (data >> 0) & 0xFF; |
|||
reportpacket->data[1] = (data >> 8) & 0xFF; |
|||
reportpacket->data[2] = 0; |
|||
reportpacket->data[3] = 0; |
|||
|
|||
uint16_t sendlen = sizeof(heartrate_report_packet_t) + 4; |
|||
zdatachannel_data_send2(reportbuf, sendlen); |
|||
return; |
|||
} |
|||
|
|||
void ble_cmder_try_report_sensor_drop_event(uint8_t dropstate0, uint8_t dropstate1) { |
|||
sensor_drop_event_report_packet_t* reportpacket = (sensor_drop_event_report_packet_t*)reportbuf; |
|||
reportpacket->cmd = ify_hrs_report_sensor_drop_detect; |
|||
reportpacket->frame_index = 0; |
|||
reportpacket->frame_type = kifyhrs_pt_report; |
|||
reportpacket->drop_state0 = dropstate0; |
|||
reportpacket->drop_state1 = dropstate1; |
|||
|
|||
uint16_t sendlen = sizeof(sensor_drop_event_report_packet_t); |
|||
zdatachannel_data_send2(reportbuf, sendlen); |
|||
return; |
|||
} |
|||
void ble_cmder_report_upload_finish_event(uint32_t sumcheckcode) { |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)txbuf; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + 4; |
|||
|
|||
txheader->cmd = ify_hrs_report_record_upload_end; // 6A |
|||
txheader->frame_index = 0; |
|||
txheader->frame_type = kifyhrs_pt_report; |
|||
|
|||
// txheader->data[0] = errorcode; |
|||
*(uint32_t*)txheader->data = sumcheckcode; |
|||
|
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
return; |
|||
} |
|||
|
|||
void ble_cmder_report_sample_finish_event() { |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)txbuf; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t); |
|||
|
|||
txheader->cmd = ify_hrs_report_sample_finish_end; |
|||
txheader->frame_index = 0; |
|||
txheader->frame_type = kifyhrs_pt_report; |
|||
|
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
return; |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 上传数据控制 * |
|||
*******************************************************************************/ |
|||
static int m_upload_fd; |
|||
static uint8_t datacache[256]; |
|||
static int m_remaindatalen = 0; |
|||
/** |
|||
* @brief 数据上报定时器回调 |
|||
* |
|||
* @param p_context |
|||
*/ |
|||
static void record_upload_finish_packet_report_tmr_cb(void* p_context) { // |
|||
ble_cmder_report_upload_finish_event(m_report_data_sumcheckcode); |
|||
} |
|||
|
|||
static void record_upload_tmr_cb(void* p_context) { // |
|||
|
|||
if (!m_isupload_data_state) return; |
|||
|
|||
// sample_data_mgr_read |
|||
if (m_remaindatalen == 0) { |
|||
memset(datacache, 0, sizeof(datacache)); |
|||
int32_t rdsize = sample_data_mgr_read(m_upload_fd, datacache, sizeof(datacache)); |
|||
if (rdsize <= 0) { |
|||
ZLOGI("read file end,stop upload"); |
|||
ZERROR_CHECK(app_timer_start(m_record_upload_finish_packet_report_tmr, APP_TIMER_TICKS(30), (void*)m_report_data_sumcheckcode)); |
|||
ble_stop_upload_record(); |
|||
return; |
|||
} |
|||
m_remaindatalen = rdsize; |
|||
} |
|||
if (m_remaindatalen == 0) { |
|||
return; |
|||
} |
|||
|
|||
int32_t mtusize = zble_module_get_mtu_size(); |
|||
mtusize = mtusize < 128 ? mtusize : 128; |
|||
|
|||
uint8_t* data = datacache + (sizeof(datacache) - m_remaindatalen); |
|||
int len = m_remaindatalen > mtusize ? mtusize : m_remaindatalen; |
|||
|
|||
ZLOGI("upload %d %d %d", len, m_remaindatalen, mtusize); |
|||
if (!zdatachannel_is_connected()) { |
|||
ZLOGI("ble is disconnected,stop upload"); |
|||
ble_stop_upload_record(); |
|||
return; |
|||
} |
|||
|
|||
uint32_t suc = zdatachannel_block_data_send2(data, len); |
|||
if (suc != NRF_SUCCESS) { |
|||
if (suc == NRF_ERROR_INVALID_STATE) { |
|||
// 未使能notify |
|||
ZLOGI("ble unenable notify,stop upload"); |
|||
ble_stop_upload_record(); |
|||
return; |
|||
} else if (suc == NRF_ERROR_BUSY || suc == NRF_ERROR_RESOURCES) { |
|||
// 等待下次发送 |
|||
return; |
|||
} else { |
|||
ZLOGI("ble send error,stop upload %x", suc); |
|||
ble_stop_upload_record(); |
|||
return; |
|||
} |
|||
} |
|||
for (uint32_t i = 0; i < len; i++) { |
|||
m_report_data_sumcheckcode += data[i]; |
|||
} |
|||
m_remaindatalen -= len; |
|||
} |
|||
|
|||
int ble_start_upload_record(sample_data_filename_t* recordid) { |
|||
// |
|||
// 启动 |
|||
// |
|||
if (ds_now_state() != kdevice_state_home) { |
|||
return kifyhrs_ecode_device_busy; |
|||
} |
|||
|
|||
m_upload_fd = sample_data_mgr_open(recordid, kwrflag_read_only); |
|||
if (m_upload_fd <= 0) { |
|||
return kifyhrs_ecode_no_record_find; |
|||
} |
|||
|
|||
ZERROR_CHECK(app_timer_start(m_record_upload_tmr, APP_TIMER_TICKS(2), NULL)); |
|||
m_isupload_data_state = true; |
|||
m_remaindatalen = 0; |
|||
m_report_data_sumcheckcode = 0; |
|||
return 0; |
|||
} |
|||
int ble_stop_upload_record() { |
|||
m_isupload_data_state = false; |
|||
app_timer_stop(m_record_upload_tmr); |
|||
return 0; |
|||
} |
|||
bool ble_is_upload_record() { return m_isupload_data_state; } |
|||
|
|||
/******************************************************************************* |
|||
* UTILS * |
|||
*******************************************************************************/ |
|||
static void send_error_receipt(ify_hrs_packet_t* rxpacket, int32_t errorcode) { |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)txbuf; |
|||
error_receipt_t* receipt = (error_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(error_receipt_t); |
|||
|
|||
txheader->cmd = rxpacket->cmd; |
|||
txheader->frame_index = rxpacket->frame_index; |
|||
txheader->frame_type = kifyhrs_pt_error_receipt; |
|||
|
|||
txheader->frame_type = kifyhrs_pt_error_receipt; |
|||
receipt->errorcode = kifyhrs_ecode_cmd_not_support; |
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
static void send_success_receipt(ify_hrs_packet_t* rxpacket, int32_t emptydatasize) { |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)txbuf; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + emptydatasize; |
|||
|
|||
txheader->cmd = rxpacket->cmd; |
|||
txheader->frame_index = rxpacket->frame_index; |
|||
txheader->frame_type = kifyhrs_pt_cmd_receipt; |
|||
|
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 下发消息处理 * |
|||
*******************************************************************************/ |
|||
void ble_cmder_process_rx(uint8_t* rx, int len) { |
|||
ify_hrs_packet_t* rxheader = (ify_hrs_packet_t*)rx; |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)txbuf; |
|||
ify_hrs_cmd_t cmd = (ify_hrs_cmd_t)rxheader->cmd; |
|||
memset(txbuf, 0, sizeof(txbuf)); |
|||
|
|||
txheader->cmd = rxheader->cmd; |
|||
txheader->frame_index = rxheader->frame_index; |
|||
txheader->frame_type = kifyhrs_pt_cmd_receipt; |
|||
|
|||
ZLOGI("rx cmd:%d index:%d datalen:%d", cmd, rxheader->frame_index, len - sizeof(ify_hrs_packet_t)); |
|||
NRF_LOG_HEXDUMP_INFO(rxheader->data, len - sizeof(ify_hrs_packet_t)); |
|||
|
|||
if (cmd == ify_hrs_cmd_read_device_version) { |
|||
device_version_info_receipt_t* receipt = (device_version_info_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_version_info_receipt_t); |
|||
|
|||
receipt->blestack_version = device_info_read_blestack_version(); |
|||
receipt->bootloader_version = device_info_read_bootloader_version(); |
|||
receipt->firmware_version = device_info_read_firmware_version(); |
|||
receipt->hardware_version = device_info_read_hardware_version(); |
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_read_sensor_info) { |
|||
sensor_info_receipt_t* receipt = (sensor_info_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(sensor_info_receipt_t); |
|||
|
|||
receipt->sensor_num = 1; |
|||
receipt->sensor_precision = SAMPLE_PRECISION; |
|||
receipt->sensor_sample_rate = SAMPLE_RATE / 10; |
|||
receipt->sensor0_pos = kifyhrs_sensor_pos_none; |
|||
receipt->sensor1_pos = kifyhrs_sensor_pos_none; |
|||
receipt->sensor2_pos = kifyhrs_sensor_pos_none; |
|||
|
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_read_device_state) { |
|||
device_state_receipt_t* receipt = (device_state_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_state_receipt_t); |
|||
|
|||
receipt->drop_state0.sensor0_pos = (!SingleLeadECG_ecg_plod_get_connected_state()); |
|||
receipt->drop_state1 = 0x00; |
|||
receipt->device_state0.sampling_state = (ds_now_state() == kdevice_state_sampling); |
|||
receipt->device_state0.report_state = m_realtime_report_state; |
|||
receipt->device_state0.low_battery = (SingleLeadECG_battery_val() < 20); |
|||
receipt->device_state0.full_storge = (sample_data_mgr_storage_is_full()); |
|||
|
|||
receipt->device_state1 = 0; |
|||
receipt->powerlevel = SingleLeadECG_battery_val(); |
|||
receipt->storage_item_num = sample_data_mgr_get_file_num(); |
|||
|
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_read_time) { |
|||
read_time_receipt_t* receipt = (read_time_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_time_receipt_t); |
|||
static ztm_t ztm; |
|||
znordic_rtc_gettime(&ztm); |
|||
|
|||
receipt->year = (ztm.tm_year + 1900 - 2000); |
|||
receipt->month = ztm.tm_mon + 1; |
|||
receipt->day = ztm.tm_mday; |
|||
receipt->hour = ztm.tm_hour; |
|||
receipt->minute = ztm.tm_min; |
|||
receipt->second = ztm.tm_sec; |
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_sync_time) { |
|||
sync_time_cmd_t* cmd = (sync_time_cmd_t*)rxheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t); |
|||
|
|||
znordic_rtc_settime(cmd->year + 2000, cmd->month, cmd->day, cmd->hour, cmd->minute, cmd->second); |
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_start_capture) { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_stop_capture) { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_start_realtime_report) { |
|||
// unsupport cmd |
|||
int ecode = ble_start_realtime_report(); |
|||
if (ecode == 0) { |
|||
send_success_receipt(rxheader,8);//凑8个字节,使这个回执的字节长度同上报包长度一致,方便调试 |
|||
} else { |
|||
send_error_receipt(rxheader, ecode); |
|||
} |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_stop_realtime_report) { |
|||
int ecode = ble_stop_realtime_report(); |
|||
if (ecode == 0) { |
|||
send_success_receipt(rxheader,0); |
|||
} else { |
|||
send_error_receipt(rxheader, ecode); |
|||
} |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_read_records_info) { |
|||
// 指令 10-读取采样记录头部信息 |
|||
read_record_info_cmd_t* cmd = (read_record_info_cmd_t*)rxheader->data; |
|||
read_record_info_receipt_t* receipt = (read_record_info_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_record_info_receipt_t); |
|||
|
|||
uint8_t recordoff = cmd->record_index; |
|||
|
|||
// 采样时不支持 |
|||
if (ds_now_state() != kdevice_state_home) { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_device_busy); |
|||
return; |
|||
} |
|||
|
|||
sample_data_fileinfo_list_t* recordlist = sample_data_mgr_get_fileinfo_list(); |
|||
if (recordoff >= recordlist->count) { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_no_record_find); |
|||
return; |
|||
} |
|||
|
|||
sample_data_fileinfo_t* fileinfo = recordlist->fileinfo[recordoff]; |
|||
memcpy(receipt->record_id, fileinfo->filename, 6); |
|||
receipt->frameNum = fileinfo->size / 2; // 2byte per frame |
|||
receipt->dataSize = fileinfo->size; |
|||
receipt->sensorNum = 1; |
|||
receipt->captureRate = SAMPLE_RATE / 10; |
|||
receipt->capturePrecision = SAMPLE_PRECISION; |
|||
receipt->compressAlgorithm = 0; |
|||
|
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
|
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_del_record) { |
|||
// 指令 11-删除采样记录 |
|||
del_record_cmd_t* cmd = (del_record_cmd_t*)rxheader->data; |
|||
|
|||
static sample_data_filename_t filename; |
|||
memset(&filename, 0, sizeof(filename)); |
|||
memcpy(&filename, cmd->record_id, sizeof(cmd->record_id)); |
|||
|
|||
// 采样时不支持 |
|||
if (ds_now_state() != kdevice_state_home) { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_device_busy); |
|||
return; |
|||
} |
|||
|
|||
int ecode = sample_data_mgr_delete_file(&filename); |
|||
if (ecode == 0) { |
|||
send_success_receipt(rxheader,0); |
|||
} else { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_unkown_error); |
|||
} |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_start_upload_record) { |
|||
// 指令 12-上传采集记录 |
|||
start_upload_record_cmd_t* cmd = (start_upload_record_cmd_t*)rxheader->data; |
|||
|
|||
static sample_data_filename_t filename; |
|||
memset(&filename, 0, sizeof(filename)); |
|||
memcpy(&filename, cmd->record_id, sizeof(cmd->record_id)); |
|||
|
|||
// 采样时不支持 |
|||
if (ds_now_state() != kdevice_state_home) { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_device_busy); |
|||
return; |
|||
} |
|||
|
|||
int ecode = ble_start_upload_record(&filename); |
|||
if (ecode == 0) { |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)txbuf; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + 1; // 凑齐4BYTE,方便调试 |
|||
txheader->cmd = rxheader->cmd; |
|||
txheader->frame_index = rxheader->frame_index; |
|||
txheader->frame_type = kifyhrs_pt_cmd_receipt; |
|||
|
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} else { |
|||
send_error_receipt(rxheader, ecode); |
|||
} |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_enter_ota) { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_read_sn) { |
|||
read_sn_receipt_t* receipt = (read_sn_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_sn_receipt_t); |
|||
device_info_read_sn((sn_t*)&receipt->sn); |
|||
zdatachannel_data_send2(txbuf, sendlen); |
|||
} |
|||
|
|||
else if (cmd == ify_hrs_cmd_reset) { |
|||
NVIC_SystemReset(); |
|||
} |
|||
// |
|||
else { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); |
|||
} |
|||
} |
@ -1,16 +0,0 @@ |
|||
#pragma once |
|||
|
|||
#include "basic/heart_rate_sensor_protocol.h" |
|||
#include "device_state.h" |
|||
|
|||
void ble_cmder_init(); |
|||
void ble_cmder_uninit(); |
|||
|
|||
void ble_cmder_process_rx(uint8_t* rx, int len); |
|||
void ble_cmder_start_adv(); |
|||
void ble_cmder_stop_adv(); |
|||
|
|||
void ble_cmder_try_report_one_sample_data(uint32_t frameIndex, uint16_t data); |
|||
void ble_cmder_try_report_sensor_drop_event(uint8_t dropstate0, uint8_t dropstate1); |
|||
void ble_cmder_report_upload_finish_event(uint32_t sumcheckcode); |
|||
void ble_cmder_report_sample_finish_event(); |
@ -1,152 +0,0 @@ |
|||
#include "heart_wave_sample_service.h" |
|||
|
|||
#include "app_event.h" |
|||
#include "nrfx_timer.h" |
|||
#include "one_conduction_board.h" |
|||
|
|||
static const nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(1); /**< Timer used for channel sweeps and tx with duty cycle. */ |
|||
static bool m_timer_started = false; /**< True if timer is running. */ |
|||
|
|||
static uint16_t m_capture_buffer_a[128]; |
|||
static uint16_t m_capture_buffer_b[128]; |
|||
|
|||
static uint16_t* m_capture_buffer; |
|||
static uint16_t m_capture_buffer_index = 0; |
|||
|
|||
volatile static float m_sensor_display_data = 0; // 0->100 |
|||
static uint32_t m_start_capture_tp; |
|||
static uint32_t m_frameindex = 0; |
|||
|
|||
static void swap_buffer() { |
|||
if (m_capture_buffer == NULL) { |
|||
m_capture_buffer = m_capture_buffer_a; |
|||
m_capture_buffer_index = 0; |
|||
return; |
|||
} |
|||
|
|||
if (m_capture_buffer == m_capture_buffer_a) { |
|||
m_capture_buffer = m_capture_buffer_b; |
|||
} else { |
|||
m_capture_buffer = m_capture_buffer_a; |
|||
} |
|||
m_capture_buffer_index = 0; |
|||
return; |
|||
} |
|||
static float amp_val(uint16_t val, uint16_t valcener, float amp) { |
|||
float valf = (float)val - valcener; |
|||
valf = valf * amp; |
|||
valf += valcener; |
|||
|
|||
if (valf >= 100) { |
|||
valf = 100; |
|||
} |
|||
|
|||
if (valf <= 0) { |
|||
valf = 0; |
|||
} |
|||
return valf; |
|||
} |
|||
|
|||
typedef struct { |
|||
float value; |
|||
float efectiveFactor; |
|||
} filter_t; |
|||
|
|||
filter_t m_filter = {0, 0.8}; |
|||
|
|||
static float Filter(filter_t* filter, float newInput) { |
|||
float newv = ((float)filter->value * (1.0f - filter->efectiveFactor)) + ((float)newInput * filter->efectiveFactor); |
|||
filter->value = newv; |
|||
return newv; |
|||
} |
|||
|
|||
void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) { // |
|||
uint16_t val = SingleLeadECG_ecg_plod_get_ecg_val(); // 12bit |
|||
m_frameindex++; |
|||
|
|||
/******************************************************************************* |
|||
* 显示数据计算并赋值 * |
|||
*******************************************************************************/ |
|||
float val_af100 = (float)val / 4096.0f * 100; |
|||
val_af100 = amp_val(val_af100, 50, 1.8f); |
|||
val_af100 = Filter(&m_filter, val_af100); |
|||
m_sensor_display_data = val_af100; |
|||
|
|||
/******************************************************************************* |
|||
* 采样数据缓存 * |
|||
*******************************************************************************/ |
|||
if (m_capture_buffer == NULL) { |
|||
swap_buffer(); |
|||
} |
|||
|
|||
if (m_capture_buffer_index < 128) { |
|||
m_capture_buffer[m_capture_buffer_index++] = val; |
|||
} |
|||
|
|||
if (m_capture_buffer_index == 128) { |
|||
app_event_t evt; |
|||
evt.eventType = kevent_capture_256data_event; |
|||
evt.val.capture_data_cache = (uint8_t*)m_capture_buffer; |
|||
swap_buffer(); |
|||
app_sched_event_put(&evt, sizeof(evt), app_event_process_cb); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 实时采样数据事件上报 * |
|||
*******************************************************************************/ |
|||
{ |
|||
app_event_t evt; |
|||
evt.eventType = kevent_capture_1data_event; |
|||
evt.val.frame_data.frameIndex = m_frameindex; |
|||
evt.val.frame_data.data = val; |
|||
swap_buffer(); |
|||
app_sched_event_put(&evt, sizeof(evt), app_event_process_cb); |
|||
} |
|||
} |
|||
|
|||
void hwss_init(void) { |
|||
if (m_timer_started) { |
|||
return; |
|||
} |
|||
/** |
|||
* @brief 初始化定时器 |
|||
*/ |
|||
nrfx_err_t err; |
|||
nrfx_timer_config_t timer_cfg = { |
|||
.frequency = NRF_TIMER_FREQ_125kHz, |
|||
.mode = NRF_TIMER_MODE_TIMER, |
|||
.bit_width = NRF_TIMER_BIT_WIDTH_24, |
|||
.p_context = NULL, |
|||
.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, |
|||
}; |
|||
|
|||
err = nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler); |
|||
if (err != NRFX_SUCCESS) { |
|||
NRF_LOG_ERROR("nrfx_timer_init failed with: %d\n", err); |
|||
} |
|||
uint32_t timer_ticks = nrfx_timer_ms_to_ticks(&m_timer, 5); // 200HZ |
|||
nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, timer_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true); |
|||
m_timer_started = true; |
|||
} |
|||
void hwss_uninit(void) { nrfx_timer_disable(&m_timer); } |
|||
|
|||
void hwss_start_capture(void) { |
|||
m_start_capture_tp = znordic_getpower_on_s(); |
|||
swap_buffer(); |
|||
m_frameindex = 0; |
|||
nrfx_timer_enable(&m_timer); |
|||
} |
|||
void hwss_stop_capture(void) { |
|||
nrfx_timer_disable(&m_timer); |
|||
m_frameindex = 0; |
|||
} |
|||
|
|||
float hwss_read_val(void) { |
|||
__disable_irq(); |
|||
float val = m_sensor_display_data; |
|||
__enable_irq(); |
|||
return val; |
|||
} |
|||
float hwss_read_heart_rate(void) { return 0; } |
|||
|
|||
int hwss_has_captured_time_ms() { return (znordic_getpower_on_s() - m_start_capture_tp) * 1000; } |
@ -1,15 +0,0 @@ |
|||
#pragma once |
|||
#include "one_conduction_board.h" |
|||
|
|||
// 每256个字节触发一次回调 |
|||
typedef void (*heart_wave_sample_service_callback_t)(uint16_t *p_data, uint16_t length); |
|||
|
|||
void hwss_init(void); |
|||
void hwss_uninit(void); |
|||
|
|||
void hwss_start_capture(void); |
|||
void hwss_stop_capture(void); |
|||
|
|||
float hwss_read_val(void); |
|||
float hwss_read_heart_rate(void); |
|||
int hwss_has_captured_time_ms(); |
@ -1,372 +0,0 @@ |
|||
#include "znordic.h" |
|||
// |
|||
#include <stdarg.h> |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
// |
|||
#include "app_uart.h" |
|||
#include "basic/ads1293/ads1293.h" |
|||
#include "zble_module.h" |
|||
#include "zdatachannel_service.h" |
|||
#include "znordic_device_info_mgr.h" |
|||
|
|||
#if defined(UART_PRESENT) |
|||
#include "nrf_uart.h" |
|||
#endif |
|||
#if defined(UARTE_PRESENT) |
|||
#include "nrf_uarte.h" |
|||
#endif |
|||
|
|||
#if 0 |
|||
|
|||
int main() { return 0; } |
|||
#endif |
|||
|
|||
#if 1 |
|||
|
|||
#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 |
|||
|
|||
#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ |
|||
#define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */ |
|||
|
|||
#include "board/ads_cfg.h" |
|||
void uart_error_handle(app_uart_evt_t* p_event) {} |
|||
|
|||
/**@brief Function for initializing the UART. */ |
|||
static void uart_init(void) { |
|||
ret_code_t err_code; |
|||
|
|||
app_uart_comm_params_t const comm_params = { |
|||
.rx_pin_no = UART_PIN_DISCONNECTED, |
|||
.tx_pin_no = 0, |
|||
.rts_pin_no = UART_PIN_DISCONNECTED, |
|||
.cts_pin_no = UART_PIN_DISCONNECTED, |
|||
.flow_control = APP_UART_FLOW_CONTROL_DISABLED, |
|||
.use_parity = false, |
|||
.baud_rate = UART_BAUDRATE_BAUDRATE_Baud115200, |
|||
}; |
|||
APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_error_handle, APP_IRQ_PRIORITY_HIGHEST, err_code); |
|||
APP_ERROR_CHECK(err_code); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 3µ¼Áª-ADS1293-²âÊÔ * |
|||
*******************************************************************************/ |
|||
APP_TIMER_DEF(m_init_tmr); |
|||
APP_TIMER_DEF(m_report_tmr); |
|||
ZDATACHANNEL_DEF(m_zhrs, 2 /**/, 1 /*client num*/); |
|||
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 |
|||
static void zdatachanel_send_log(const char* fmt, ...); |
|||
static void three_lead_ecg_ecg_init(); |
|||
|
|||
uint32_t get_ready_pin_state_get() { return nrf_gpio_pin_read(ADS1293_READY_PIN); } |
|||
|
|||
static void on_service_init(void) { |
|||
ZLOGI("init zdatachannel service"); |
|||
zdatachannel_init_t zdatachannle_init; |
|||
memset(&zdatachannle_init, 0, sizeof(zdatachannle_init)); |
|||
zdatachannle_init.data_handler = NULL; |
|||
ZERROR_CHECK(zdatachannel_init(&m_zhrs, &zdatachannle_init)); |
|||
} |
|||
static int changecount = 0; |
|||
void dump_state() { |
|||
static uint32_t last = 0; |
|||
uint32_t nows = znordic_rtc_gettime_s(); |
|||
if (nows != last) { |
|||
zdatachanel_send_log("%d\n", changecount); |
|||
|
|||
uint8_t leadoffstate = ads1293_spi_readreg(&m_ads1293_0, TI_ADS1293_ERROR_LOD_REG); |
|||
zdatachanel_send_log("%d%d%d%d_%d%d%d%d\n", // |
|||
leadoffstate >> 7 & 0x1, leadoffstate >> 6 & 0x1, leadoffstate >> 5 & 0x1, leadoffstate >> 4 & 0x1, // |
|||
leadoffstate >> 3 & 0x1, leadoffstate >> 2 & 0x1, leadoffstate >> 1 & 0x1, leadoffstate >> 0 & 0x1); // |
|||
|
|||
last = nows; |
|||
changecount = 0; |
|||
} |
|||
} |
|||
|
|||
int main() { |
|||
APP_SCHED_INIT(APP_TIMER_SCHED_EVENT_DATA_SIZE, 20); |
|||
znordic_init(); |
|||
static zble_module_cfg_t cfg = // |
|||
{ |
|||
.deviceName = "ThreeLeadECG", |
|||
.on_service_init = on_service_init, |
|||
}; |
|||
zble_module_init(&cfg); |
|||
NRF_LOG_INFO("compile time :%s", __TIME__); |
|||
uart_init(); |
|||
|
|||
nrf_gpio_cfg_input(LINE_DET_PIN, NRF_GPIO_PIN_PULLUP); |
|||
three_lead_ecg_ecg_init(); |
|||
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_CONFIG_REG, 0x01); |
|||
ads1293_spi_writereg(&m_ads1293_1, TI_ADS1293_CONFIG_REG, 0x01); |
|||
|
|||
while (true) { |
|||
app_sched_execute(); |
|||
if (NRF_LOG_PROCESS() == false) { |
|||
// nrf_pwr_mgmt_run(); |
|||
} |
|||
static bool state = false; |
|||
bool now = get_ready_pin_state_get(); |
|||
if (state != now) { |
|||
state = now; |
|||
changecount++; |
|||
|
|||
if (now) { |
|||
uint32_t val = 0; |
|||
ads1293_read_ecg(&m_ads1293_0, 1, &val); |
|||
zdatachanel_send_log("%d\n", val); |
|||
} |
|||
} |
|||
// dump_state(); |
|||
} |
|||
} |
|||
|
|||
static void ads1293_spi_tx_rx_0(uint8_t* tx, uint8_t* rx, uint8_t len) { |
|||
nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN); |
|||
nrf_drv_spi_transfer(&spi, tx, len, rx, len); |
|||
nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); |
|||
} |
|||
static void ads1293_spi_tx_rx_1(uint8_t* tx, uint8_t* rx, uint8_t len) { |
|||
nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN); |
|||
nrf_drv_spi_transfer(&spi, tx, len, rx, len); |
|||
nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); |
|||
} |
|||
|
|||
static void ads1293_spi_writereg_and_check(ads1293_t* ads, uint8_t addr, uint8_t data) { |
|||
uint8_t readbak = 0; |
|||
// readonly add |
|||
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) { |
|||
zdatachanel_send_log("ads_%d write %x failed,w:%x readbak:%x\n", ads->id, addr, data, readbak); |
|||
} |
|||
} |
|||
|
|||
static adscfg_t prvads0cfg[] = { |
|||
{0x00, 0x00}, // |
|||
{0x01, 0x19}, // |
|||
{0x02, 0x11}, // |
|||
{0x03, 0x00}, // |
|||
{0x04, 0x00}, // |
|||
{0x05, 0x00}, // |
|||
{0x06, 0x00}, // |
|||
{0x07, 0x0f}, // |
|||
{0x08, 0xff}, // |
|||
{0x09, 0x00}, // |
|||
{0x0a, 0x07}, // |
|||
{0x0b, 0x07}, // |
|||
{0x0c, 0x74}, // |
|||
{0x0d, 0x01}, // |
|||
{0x0e, 0x02}, // |
|||
{0x0f, 0x03}, // |
|||
{0x10, 0x04}, // |
|||
{0x11, 0x00}, // |
|||
{0x12, 0x05}, // |
|||
{0x13, 0x39}, // |
|||
{0x14, 0x36}, // |
|||
{0x15, 0x06}, // |
|||
{0x16, 0x00}, // |
|||
{0x17, 0x05}, // |
|||
{0x18, 0x00}, // |
|||
{0x19, 0x00}, // |
|||
{0x1a, 0x00}, // |
|||
{0x1b, 0x00}, // |
|||
{0x1c, 0x00}, // |
|||
{0x1d, 0x00}, // |
|||
{0x21, 0x01}, // |
|||
{0x22, 0x20}, // |
|||
{0x23, 0x20}, // |
|||
{0x24, 0x02}, // |
|||
{0x25, 0x00}, // |
|||
{0x26, 0x00}, // |
|||
{0x27, 0x08}, // |
|||
{0x28, 0x08}, // |
|||
{0x29, 0x00}, // |
|||
{0x2a, 0x00}, // |
|||
{0x2b, 0x00}, // |
|||
{0x2c, 0x00}, // |
|||
{0x2d, 0x00}, // |
|||
{0x2e, 0x33}, // |
|||
{0x2f, 0x30}, // |
|||
{0x30, 0x00}, // |
|||
{0x31, 0x00}, // |
|||
{0x32, 0x00}, // |
|||
{0x33, 0x00}, // |
|||
{0x34, 0x00}, // |
|||
{0x35, 0x00}, // |
|||
{0x36, 0x00}, // |
|||
{0x37, 0x00}, // |
|||
{0x38, 0x00}, // |
|||
{0x39, 0x00}, // |
|||
{0x3a, 0x00}, // |
|||
{0x3b, 0x00}, // |
|||
{0x3c, 0x00}, // |
|||
{0x3d, 0x00}, // |
|||
{0x3e, 0x00}, // |
|||
{0x3f, 0x00}, // |
|||
{0x40, 0xff}, // |
|||
{0x50, 0x00}, // |
|||
{0x60, 0x00}, // |
|||
{0x62, 0x00} // |
|||
}; |
|||
|
|||
static adscfg_t prvads1cfg[] = { |
|||
{0x00, 0x00}, // |
|||
{0x01, 0x0c}, // |
|||
{0x02, 0x14}, // |
|||
{0x03, 0x00}, // |
|||
{0x04, 0x00}, // |
|||
{0x05, 0x00}, // |
|||
{0x06, 0x00}, // |
|||
{0x07, 0x0f}, // |
|||
{0x08, 0xff}, // |
|||
{0x09, 0x00}, // |
|||
{0x0a, 0x00}, // |
|||
{0x0b, 0x07}, // |
|||
{0x0c, 0x78}, // |
|||
{0x0d, 0x00}, // |
|||
{0x0e, 0x00}, // |
|||
{0x0f, 0x00}, // |
|||
{0x10, 0x04}, // |
|||
{0x11, 0x00}, // |
|||
{0x12, 0x07}, // |
|||
{0x13, 0x3b}, // |
|||
{0x14, 0x24}, // |
|||
{0x15, 0x04}, // |
|||
{0x16, 0x00}, // |
|||
{0x17, 0x05}, // |
|||
{0x18, 0x00}, // |
|||
{0x19, 0x00}, // |
|||
{0x1a, 0x00}, // |
|||
{0x1b, 0x00}, // |
|||
{0x1c, 0x00}, // |
|||
{0x1d, 0x00}, // |
|||
{0x21, 0x01}, // |
|||
{0x22, 0x20}, // |
|||
{0x23, 0x20}, // |
|||
{0x24, 0x02}, // |
|||
{0x25, 0x00}, // |
|||
{0x26, 0x00}, // |
|||
{0x27, 0x08}, // |
|||
{0x28, 0x40}, // |
|||
{0x29, 0x00}, // |
|||
{0x2a, 0x00}, // |
|||
{0x2b, 0x00}, // |
|||
{0x2c, 0x00}, // |
|||
{0x2d, 0x00}, // |
|||
{0x2e, 0x33}, // |
|||
{0x2f, 0x30}, // |
|||
{0x30, 0x00}, // |
|||
{0x31, 0x00}, // |
|||
{0x32, 0x00}, // |
|||
{0x33, 0x00}, // |
|||
{0x34, 0x00}, // |
|||
{0x35, 0x00}, // |
|||
{0x36, 0x00}, // |
|||
{0x37, 0x00}, // |
|||
{0x38, 0x00}, // |
|||
{0x39, 0x00}, // |
|||
{0x3a, 0x00}, // |
|||
{0x3b, 0x00}, // |
|||
{0x3c, 0x00}, // |
|||
{0x3d, 0x00}, // |
|||
{0x3e, 0x00}, // |
|||
{0x3f, 0x00}, // |
|||
{0x40, 0xff}, // |
|||
{0x50, 0x00}, // |
|||
{0x60, 0x00}, // |
|||
{0x62, 0x00}, // |
|||
}; |
|||
|
|||
void config_lod(uint8_t aclvl_lod, uint8_t selac_lod, uint8_t shdn_lod, uint8_t acad_lod) { |
|||
uint8_t reg = 0; |
|||
reg |= aclvl_lod; |
|||
reg |= selac_lod << 2; |
|||
reg |= shdn_lod << 3; |
|||
reg |= acad_lod << 4; |
|||
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_LOD_CN_REG, reg); |
|||
} |
|||
|
|||
void enable_lod(void) { |
|||
uint8_t reg = ads1293_spi_readreg(&m_ads1293_0, TI_ADS1293_CONFIG_REG); |
|||
reg |= 1 << 3; |
|||
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_LOD_EN_REG, reg); |
|||
} |
|||
|
|||
void three_lead_ecg_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); |
|||
zdatachanel_send_log("ads1293_0 revid: %d\n", revid); |
|||
revid = ads1293_spi_readreg(&m_ads1293_1, TI_ADS1293_REVID_REG); |
|||
zdatachanel_send_log("ads1293_1 revid: %d\n", revid); |
|||
|
|||
zdatachanel_send_log("reset ads1293_0\n"); |
|||
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_CONFIG_REG, 0); |
|||
nrf_delay_ms(1000); |
|||
|
|||
for (uint16_t i = 0; i < ZARRAY_SIZE(prvads0cfg); i++) { |
|||
ads1293_spi_writereg_and_check(&m_ads1293_0, prvads0cfg[i].add, prvads0cfg[i].data); |
|||
} |
|||
for (uint16_t i = 0; i < ZARRAY_SIZE(prvads1cfg); i++) { |
|||
ads1293_spi_writereg_and_check(&m_ads1293_1, prvads1cfg[i].add, prvads1cfg[i].data); |
|||
} |
|||
|
|||
// ads1293_spi_writereg(&m_ads1293_1, TI_ADS1293_CONFIG_REG, 0x01); |
|||
} |
|||
|
|||
static void zdatachanel_send_log(const char* fmt, ...) { |
|||
static char tx[256] = {0}; |
|||
int len = 0; |
|||
va_list args; |
|||
va_start(args, fmt); |
|||
len = vsprintf(tx, fmt, args); |
|||
len = strlen(tx); |
|||
int ret_val; |
|||
if (len >= 0) { |
|||
for (uint16_t i = 0; i < len; i++) { |
|||
do { |
|||
ret_val = app_uart_put(tx[i]); |
|||
} while (ret_val != NRF_SUCCESS); |
|||
} |
|||
return; |
|||
} |
|||
va_end(args); |
|||
} |
|||
#endif |
@ -1,527 +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); |
|||
} |
|||
} |
|||
|
|||
void ThreeLeadECG_led_green_toggle(){ |
|||
nrf_gpio_pin_toggle(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 |
|||
*/ |
|||
|
|||
|
|||
|
|||
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 |
|||
#include <stdint.h> |
|||
#define VERSION 1 |
|||
#define MANUFACTURER_NAME "iflytop" |
|||
#define BLE_NAME "iflytop_test" |
|||
|
|||
/******************************************************************************* |
|||
* INCLUDE * |
|||
*******************************************************************************/ |
|||
#include <stdbool.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); |
|||
void ThreeLeadECG_led_green_toggle(); |
|||
/******************************************************************************* |
|||
* 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); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue