Browse Source

update

3lead_uart_test_ok_version
zhaohe 1 year ago
parent
commit
fc8d9ab3f2
  1. 3
      .vscode/settings.json
  2. 10
      app/src/basic/device_info_mgr.c
  3. 13
      app/src/basic/device_info_mgr.h
  4. 124
      app/src/basic/heart_rate_sensor_protocol.h
  5. 8
      app/src/basic/zdatachannel_service.h
  6. 225
      app/src/one_conduction/ble_cmd_process_service.c
  7. 2
      app/src/one_conduction/ble_cmd_process_service.h
  8. 5
      app/src/one_conduction/config.h
  9. 2
      app/src/one_conduction/one_conduction_main.c
  10. 4
      app/src/one_conduction/sample_data_manager.c
  11. 18
      app/src/one_conduction/sample_data_manager.h
  12. 2
      libznordic

3
.vscode/settings.json

@ -87,7 +87,8 @@
"zeeprom_fs.h": "c", "zeeprom_fs.h": "c",
"config.h": "c", "config.h": "c",
"stdarg.h": "c", "stdarg.h": "c",
"nrf_uarte.h": "c"
"nrf_uarte.h": "c",
"heart_rate_sensor_protocol.h": "c"
}, },
"files.encoding": "gbk" "files.encoding": "gbk"
} }

10
app/src/basic/device_info_mgr.c

@ -0,0 +1,10 @@
#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; }

13
app/src/basic/device_info_mgr.h

@ -0,0 +1,13 @@
#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);

124
app/src/basic/heart_rate_sensor_protocol.h

@ -19,6 +19,7 @@ typedef enum {
kifyhrs_ecode_device_busy = 4, kifyhrs_ecode_device_busy = 4,
kifyhrs_ecode_hardware_error = 5, kifyhrs_ecode_hardware_error = 5,
kifyhrs_ecode_sensor_drop = 6, kifyhrs_ecode_sensor_drop = 6,
kifyhrs_ecode_no_record_find = 7,
} ify_hrs_error_code_t; } ify_hrs_error_code_t;
typedef enum { typedef enum {
@ -49,7 +50,130 @@ typedef enum {
ify_hrs_cmd_stop_realtime_report = 9, ify_hrs_cmd_stop_realtime_report = 9,
ify_hrs_cmd_read_records_info = 10, ify_hrs_cmd_read_records_info = 10,
ify_hrs_cmd_del_record = 11, 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_upload_report_end = 104,
ify_hrs_report_sensor_drop_detect = 105,
ify_hrs_report_record_upload_end = 106,
} ify_hrs_cmd_t; } 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 drop0 : 1; // 0
uint8_t drop1 : 1; // 1
uint8_t drop2 : 1; // 2
uint8_t drop3 : 1; // 3
uint8_t drop4 : 1; // 4
uint8_t drop5 : 1; // 5
uint8_t drop6 : 1; // 6
uint8_t drop7 : 1; // 7
} drop0_state;
struct {
uint8_t drop0 : 1;
uint8_t drop1 : 1;
uint8_t drop2 : 1;
uint8_t drop3 : 1;
uint8_t drop4 : 1;
uint8_t drop5 : 1;
uint8_t drop6 : 1;
uint8_t drop7 : 1;
} drop1_state;
struct {
uint8_t sample_state : 1;
uint8_t report_state : 1;
uint8_t lowbattery_state : 1;
uint8_t full_storage : 1;
uint8_t placeholder : 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;
#pragma pack(pop) #pragma pack(pop)

8
app/src/basic/zdatachannel_service.h

@ -63,12 +63,12 @@ typedef struct {
struct zdatachannel_s { struct zdatachannel_s {
uint8_t uuid_type; /**< UUID type for Nordic UART Service Base UUID. */ 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). */ 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; /**< 数�����柄 */
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. */ zdatachannel_data_handler_t data_handler; /**< Event handler to be called for handling received data. */
// çŠæ
// ״̬
int16_t conn_handle; int16_t conn_handle;
bool cmd_tx_channel_is_notification_enabled; bool cmd_tx_channel_is_notification_enabled;
bool datablock_tx_channel_is_notification_enabled; bool datablock_tx_channel_is_notification_enabled;

225
app/src/one_conduction/ble_cmd_process_service.c

@ -0,0 +1,225 @@
#include "ble_cmd_process_service.h"
#include "basic/device_info_mgr.h"
#include "basic/heart_rate_sensor_protocol.h"
#include "basic/zdatachannel_service.h"
#include "config.h"
#include "one_conduction_board.h"
#include "sample_data_manager.h"
static uint8_t txbuf[128];
void ble_cmder_try_start_adv() {}
int ble_start_realtime_report() { return 0; }
int ble_stop_realtime_report() { return 0; }
int ble_start_upload_record(sample_data_filename_t* recordid) { return 0; }
int ble_stop_upload_record() { return 0; }
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_send(txbuf, sendlen);
}
static void send_success_receipt(ify_hrs_packet_t* rxpacket) {
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)txbuf;
uint16_t sendlen = sizeof(ify_hrs_packet_t);
txheader->cmd = rxpacket->cmd;
txheader->frame_index = rxpacket->frame_index;
txheader->frame_type = kifyhrs_pt_cmd_receipt;
zdatachannel_data_send(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;
int packetdata_len = len - sizeof(ify_hrs_packet_t);
ify_hrs_cmd_t cmd = rxheader->cmd;
txheader->cmd = rxheader->cmd;
txheader->frame_index = rxheader->frame_index;
txheader->frame_type = kifyhrs_pt_cmd_receipt;
memset(txbuf, 0, sizeof(txbuf));
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_send(txbuf, sendlen);
}
else if (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_send(txbuf, sendlen);
}
else if (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->drop0_state.drop0 = 0;
receipt->device_state0.sample_state = 1;
receipt->device_state0.report_state = 1;
receipt->device_state0.lowbattery_state = 0;
receipt->device_state0.full_storage = sample_data_mgr_storage_is_full();
receipt->powerlevel = SingleLeadECG_battery_val();
receipt->storage_item_num = sample_data_mgr_get_file_num();
zdatachannel_data_send(txbuf, sendlen);
}
else if (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_send(txbuf, sendlen);
}
else if (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_send(txbuf, sendlen);
}
else if (ify_hrs_cmd_start_capture) {
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
}
else if (ify_hrs_cmd_stop_capture) {
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
}
else if (ify_hrs_cmd_start_realtime_report) {
// unsupport cmd
int ecode = ble_start_realtime_report();
if (ecode == 0) {
send_success_receipt(rxheader);
} else {
send_error_receipt(rxheader, ecode);
}
}
else if (ify_hrs_cmd_stop_realtime_report) {
int ecode = ble_stop_realtime_report();
if (ecode == 0) {
send_success_receipt(rxheader);
} else {
send_error_receipt(rxheader, ecode);
}
}
else if (ify_hrs_cmd_read_records_info) {
// send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
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;
sample_data_fileinfo_list_t* recordlist = sample_data_mgr_get_fileinfo_list();
if (recordoff >= recordlist->count) {
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
return;
}
sample_data_fileinfo_t* fileinfo = recordlist->fileinfo[recordoff];
memcpy(receipt->record_id, fileinfo->filename, 6);
receipt->frameNum = fileinfo->size / 16; // 16 bytes per frame
receipt->dataSize = fileinfo->size;
receipt->sensorNum = 1;
receipt->captureRate = SAMPLE_RATE / 10;
receipt->capturePrecision = SAMPLE_PRECISION;
receipt->compressAlgorithm = 0;
zdatachannel_data_send(txbuf, sendlen);
}
else if (ify_hrs_cmd_del_record) {
del_record_cmd_t* cmd = (del_record_cmd_t*)rxheader->data;
uint16_t sendlen = sizeof(ify_hrs_packet_t);
static sample_data_filename_t filename;
memset(&filename, 0, sizeof(filename));
memcpy(&filename, cmd->record_id, sizeof(cmd->record_id));
int ecode = sample_data_mgr_delete_file(&filename);
if (ecode == 0) {
send_success_receipt(rxheader);
} else {
send_error_receipt(rxheader, kifyhrs_ecode_unkown_error);
}
}
else if (ify_hrs_cmd_start_upload_record) {
start_upload_record_cmd_t* cmd = (start_upload_record_cmd_t*)rxheader->data;
uint16_t sendlen = sizeof(ify_hrs_packet_t);
static sample_data_filename_t filename;
memset(&filename, 0, sizeof(filename));
memcpy(&filename, cmd->record_id, sizeof(cmd->record_id));
int ecode = ble_start_upload_record(&filename);
if (ecode == 0) {
send_success_receipt(rxheader);
} else {
send_error_receipt(rxheader, ecode);
}
}
else if (ify_hrs_cmd_enter_ota) {
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
}
else if (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_send(txbuf, sendlen);
}
else if (ify_hrs_cmd_reset) {
NVIC_SystemReset();
}
//
else {
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
}
}

2
app/src/one_conduction/ble_cmd_process_service.h

@ -3,3 +3,5 @@
#include "basic/heart_rate_sensor_protocol.h" #include "basic/heart_rate_sensor_protocol.h"
#include "device_state.h" #include "device_state.h"
void ble_cmder_process_rx(uint8_t* rx, int len);
void ble_cmder_try_start_adv();

5
app/src/one_conduction/config.h

@ -13,4 +13,7 @@
#define MAX_STORAGE_TIMEOUT_S (60 * 10) #define MAX_STORAGE_TIMEOUT_S (60 * 10)
#define MAX_STORAGE_SIZE (MAX_STORAGE_TIMEOUT_S * 400) // 存储最大限制为 (256-8)kbyte #define MAX_STORAGE_SIZE (MAX_STORAGE_TIMEOUT_S * 400) // 存储最大限制为 (256-8)kbyte
#define MAX_FILE_NUM 10
#define MAX_FILE_NUM 10
#define SAMPLE_RATE 200
#define SAMPLE_PRECISION 12

2
app/src/one_conduction/one_conduction_main.c

@ -253,7 +253,7 @@ void app_event_process_cb(void* p_event_data, uint16_t event_size) {
memset(&sampledata_file_name, 0, sizeof(sampledata_file_name)); memset(&sampledata_file_name, 0, sizeof(sampledata_file_name));
znordic_rtc_gettime(&tm); znordic_rtc_gettime(&tm);
sampledata_file_name.year = tm.tm_year;
sampledata_file_name.year = tm.tm_year + 1900 - 2000;
sampledata_file_name.month = tm.tm_mon; sampledata_file_name.month = tm.tm_mon;
sampledata_file_name.day = tm.tm_mday; sampledata_file_name.day = tm.tm_mday;
sampledata_file_name.hour = tm.tm_hour; sampledata_file_name.hour = tm.tm_hour;

4
app/src/one_conduction/sample_data_manager.c

@ -43,6 +43,10 @@ sample_data_fileinfo_list_t* sample_data_mgr_get_fileinfo_list() { //
} }
return &fileinfo_list; return &fileinfo_list;
} }
int32_t sample_data_mgr_storage_is_full() { return zeeprom_fs_get_file_num() >= FILE_MAX_COUNT; }
int32_t sample_data_mgr_get_file_num() { return zeeprom_fs_get_file_num(); }
#if 1 #if 1
static const char* filename2str(uint8_t* filename) { static const char* filename2str(uint8_t* filename) {
static char filename_str[32]; static char filename_str[32];

18
app/src/one_conduction/sample_data_manager.h

@ -1,21 +1,21 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include "zeeprom_fs.h"
#include "config.h" #include "config.h"
#include "zeeprom_fs.h"
void sample_data_mgr_init(); void sample_data_mgr_init();
#define FILE_MAX_COUNT MAX_FILE_NUM #define FILE_MAX_COUNT MAX_FILE_NUM
typedef struct { typedef struct {
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
uint8_t placeholder[2];
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
uint8_t placeholder[2];
} sample_data_filename_t; } sample_data_filename_t;
typedef struct { typedef struct {
@ -33,6 +33,8 @@ void sample_data_mgr_init();
void sample_data_mgr_uninit(); void sample_data_mgr_uninit();
sample_data_fileinfo_list_t* sample_data_mgr_get_fileinfo_list(); sample_data_fileinfo_list_t* sample_data_mgr_get_fileinfo_list();
int32_t sample_data_mgr_storage_is_full();
int32_t sample_data_mgr_get_file_num();
int32_t sample_data_mgr_open(sample_data_filename_t* filename, wrflag_t flag); int32_t sample_data_mgr_open(sample_data_filename_t* filename, wrflag_t flag);
int32_t sample_data_mgr_close(int32_t fd); int32_t sample_data_mgr_close(int32_t fd);

2
libznordic

@ -1 +1 @@
Subproject commit 1eb8d83d8d82aecd5a0da03be2a9399e061f91a8
Subproject commit 195d28909c8ed31853420141b4902fb8d61e6975
Loading…
Cancel
Save