mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Bangle.js2: Switched to proprietary heart rate algorithm (from our Open Source version). It just works better.
This commit is contained in:
parent
82abd844c3
commit
21e7dd8061
@ -14,6 +14,8 @@
|
||||
Puck.js: Ensure acc/gyro doesn't cause watch events to be added to the input queue (more efficient)
|
||||
Waveform: Fix waveform input/output when not done at system start - Since 2v13 start time was set in the past
|
||||
Fix ordering of Pin check in wrapper (so autocomplete and Pin prototype works)
|
||||
Bangle.js2: Switched to 'hard' float abi from 'soft' (needed for proprietary hrm algorithm)
|
||||
Bangle.js2: Switched to proprietary heart rate algorithm (from our Open Source version). It just works better.
|
||||
|
||||
2v17 : Bangle.js: When reading file info from a filename table, do it in blocks of 8 (20% faster file search)
|
||||
Bangle.js2: Increase flash buffer size from 16->32 bytes (5% performance increase)
|
||||
|
||||
@ -68,8 +68,13 @@ info = {
|
||||
'WRAPPERSOURCES += libs/graphics/jswrap_font_12x20.c',
|
||||
'SOURCES += libs/misc/nmea.c',
|
||||
'SOURCES += libs/misc/stepcount.c',
|
||||
'SOURCES += libs/misc/heartrate.c',
|
||||
'SOURCES += libs/misc/hrm_vc31.c',
|
||||
'SOURCES += libs/misc/hrm_vc31.c',
|
||||
# Standard open-source heart rate algorithm:
|
||||
# 'SOURCES += libs/misc/heartrate.c',
|
||||
# Proprietary heart rate algorithm:
|
||||
'FLOAT_ABI_HARD=1', # needed for VC31 binary algorithm
|
||||
'SOURCES += libs/misc/heartrate_vc31_binary.c', 'DEFINES += -DHEARTRATE_VC31_BINARY=1', 'PRECOMPILED_OBJS += libs/misc/vc31_binary/algo.o libs/misc/vc31_binary/modle5_10.o libs/misc/vc31_binary/modle5_11.o libs/misc/vc31_binary/modle5_12.o libs/misc/vc31_binary/modle5_13.o libs/misc/vc31_binary/modle5_14.o libs/misc/vc31_binary/modle5_15.o libs/misc/vc31_binary/modle5_16.o libs/misc/vc31_binary/modle5_17.o libs/misc/vc31_binary/modle5_18.o libs/misc/vc31_binary/modle5_1.o libs/misc/vc31_binary/modle5_2.o libs/misc/vc31_binary/modle5_3.o libs/misc/vc31_binary/modle5_4.o libs/misc/vc31_binary/modle5_5.o libs/misc/vc31_binary/modle5_6.o libs/misc/vc31_binary/modle5_7.o libs/misc/vc31_binary/modle5_8.o libs/misc/vc31_binary/modle5_9.o',
|
||||
# ------------------------
|
||||
'SOURCES += libs/misc/unistroke.c',
|
||||
'WRAPPERSOURCES += libs/misc/jswrap_unistroke.c',
|
||||
'DEFINES += -DESPR_BANGLE_UNISTROKE=1',
|
||||
|
||||
@ -538,9 +538,6 @@ Can be used for housekeeping tasks that don't want to be run during the day.
|
||||
|
||||
#define ACCEL_HISTORY_LEN 50 ///< Number of samples of accelerometer history
|
||||
|
||||
typedef struct {
|
||||
short x,y,z;
|
||||
} Vector3;
|
||||
|
||||
// =========================================================================
|
||||
// DEVICE SPECIFIC CONFIG
|
||||
@ -794,7 +791,7 @@ bool lcdFadeHandlerActive;
|
||||
// compass data
|
||||
Vector3 mag, magmin, magmax;
|
||||
#endif
|
||||
/// accelerometer data
|
||||
/// accelerometer data. 8192 = 1G
|
||||
Vector3 acc;
|
||||
/// squared accelerometer magnitude
|
||||
int accMagSquared;
|
||||
@ -1489,7 +1486,7 @@ void peripheralPollHandler() {
|
||||
|
||||
#ifdef HEARTRATE
|
||||
static void hrmHandler(int ppgValue) {
|
||||
if (hrm_new(ppgValue)) {
|
||||
if (hrm_new(ppgValue, &acc)) {
|
||||
bangleTasks |= JSBT_HRM_DATA;
|
||||
// keep track of best HRM sample during this period
|
||||
if (hrmInfo.confidence >= healthCurrent.bpmConfidence) {
|
||||
@ -3910,13 +3907,13 @@ bool jswrap_banglejs_idle() {
|
||||
#ifdef HEARTRATE
|
||||
if (bangleTasks & JSBT_HRM_INSTANT_DATA) {
|
||||
JsVar *o = hrm_sensor_getJsVar();
|
||||
if (o) {
|
||||
if (o) {
|
||||
jsvObjectSetChildAndUnLock(o,"raw",jsvNewFromInteger(hrmInfo.raw));
|
||||
jsvObjectSetChildAndUnLock(o,"filt",jsvNewFromInteger(hrmInfo.filtered));
|
||||
jsvObjectSetChildAndUnLock(o,"avg",jsvNewFromInteger(hrmInfo.avg));
|
||||
jsvObjectSetChildAndUnLock(o,"isBeat",jsvNewFromBool(hrmInfo.isBeat));
|
||||
jsvObjectSetChildAndUnLock(o,"bpm",jsvNewFromFloat(hrmInfo.bpm10 / 10.0));
|
||||
jsvObjectSetChildAndUnLock(o,"confidence",jsvNewFromInteger(hrmInfo.confidence));
|
||||
jsvObjectSetChildAndUnLock(o,"filt",jsvNewFromInteger(hrmInfo.filtered));
|
||||
jsvObjectSetChildAndUnLock(o,"avg",jsvNewFromInteger(hrmInfo.avg));
|
||||
hrm_get_hrm_raw_info(o);
|
||||
jsiQueueObjectCallbacks(bangle, JS_EVENT_PREFIX"HRM-raw", &o, 1);
|
||||
jsvUnLock(o);
|
||||
}
|
||||
@ -3926,16 +3923,7 @@ bool jswrap_banglejs_idle() {
|
||||
if (o) {
|
||||
jsvObjectSetChildAndUnLock(o,"bpm",jsvNewFromInteger(hrmInfo.bpm10 / 10.0));
|
||||
jsvObjectSetChildAndUnLock(o,"confidence",jsvNewFromInteger(hrmInfo.confidence));
|
||||
JsVar *a = jsvNewEmptyArray();
|
||||
if (a) {
|
||||
int n = hrmInfo.timeIdx;
|
||||
for (int i=0;i<HRM_HIST_LEN;i++) {
|
||||
jsvArrayPushAndUnLock(a, jsvNewFromFloat(hrm_time_to_bpm10(hrmInfo.times[n]) / 10.0));
|
||||
n++;
|
||||
if (n==HRM_HIST_LEN) n=0;
|
||||
}
|
||||
jsvObjectSetChildAndUnLock(o,"history",a);
|
||||
}
|
||||
hrm_get_hrm_info(o);
|
||||
jsiQueueObjectCallbacks(bangle, JS_EVENT_PREFIX"HRM", &o, 1);
|
||||
jsvUnLock(o);
|
||||
}
|
||||
|
||||
@ -347,7 +347,7 @@ bool hrm_had_beat() {
|
||||
}
|
||||
|
||||
/// Add new heart rate value
|
||||
bool hrm_new(int hrmValue) {
|
||||
bool hrm_new(int hrmValue, Vector3 *acc) {
|
||||
if (hrmValue<HRMVALUE_MIN) hrmValue=HRMVALUE_MIN;
|
||||
if (hrmValue>HRMVALUE_MAX) hrmValue=HRMVALUE_MAX;
|
||||
hrmInfo.raw = hrmValue;
|
||||
@ -379,3 +379,22 @@ bool hrm_new(int hrmValue) {
|
||||
|
||||
return hadBeat;
|
||||
}
|
||||
|
||||
// Append extra information to an existing HRM event object
|
||||
void hrm_get_hrm_info(JsVar *o) {
|
||||
JsVar *a = jsvNewEmptyArray();
|
||||
if (a) {
|
||||
int n = hrmInfo.timeIdx;
|
||||
for (int i=0;i<HRM_HIST_LEN;i++) {
|
||||
jsvArrayPushAndUnLock(a, jsvNewFromFloat(hrm_time_to_bpm10(hrmInfo.times[n]) / 10.0));
|
||||
n++;
|
||||
if (n==HRM_HIST_LEN) n=0;
|
||||
}
|
||||
jsvObjectSetChildAndUnLock(o,"history",a);
|
||||
}
|
||||
}
|
||||
|
||||
// Append extra information to an existing HRM-raw event object
|
||||
void hrm_get_hrm_raw_info(JsVar *o) {
|
||||
jsvObjectSetChildAndUnLock(o,"isBeat",jsvNewFromBool(hrmInfo.isBeat));
|
||||
}
|
||||
@ -15,8 +15,10 @@
|
||||
|
||||
#include "jsutils.h"
|
||||
|
||||
#ifndef HEARTRATE_VC31_BINARY
|
||||
#define HRM_HIST_LEN 16 // how many BPM values do we keep a history of
|
||||
#define HRM_MEDIAN_LEN 8 // how many BPM values do we average in our median filter to get a BPM reading
|
||||
#endif
|
||||
|
||||
// Do we use 8 or 16 bits for data storage?
|
||||
#ifdef HEARTRATE_DEVICE_VC31
|
||||
@ -30,30 +32,42 @@
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t bpm10; // 10x BPM
|
||||
uint8_t confidence; // 0..100%
|
||||
|
||||
HrmValueType raw;
|
||||
int16_t avg; // average signal value, moving average
|
||||
int16_t filtered;
|
||||
#ifndef HEARTRATE_VC31_BINARY
|
||||
int16_t filtered1; // before filtered
|
||||
int16_t filtered2; // before filtered1
|
||||
int16_t avg; // average signal value, moving average
|
||||
|
||||
bool wasLow; // has the signal gone below the average? set =false when a beat detected
|
||||
bool isBeat; // was this sample classified as a detected beat?
|
||||
JsSysTime lastBeatTime; // timestamp of last heartbeat
|
||||
uint8_t times[HRM_HIST_LEN]; // times of previous beats, in 1/100th secs
|
||||
uint8_t timeIdx; // index in times
|
||||
uint16_t bpm10; // 10x BPM
|
||||
uint8_t confidence; // 0..100%
|
||||
#else // HEARTRATE_VC31_BINARY
|
||||
bool isWorn; // is the bangle being worn? Used to re-init if we go from not worn to worn
|
||||
JsSysTime lastPPGTime; // timestamp of last PPG sample
|
||||
/* last values we got from the algo. It doesn't tell us when there's a new
|
||||
value so we have to guess based on when it changes */
|
||||
int lastHRM, lastConfidence;
|
||||
int msSinceLastHRM; // how long was it since the last HRM reading?
|
||||
#endif
|
||||
} HrmInfo;
|
||||
|
||||
extern HrmInfo hrmInfo;
|
||||
|
||||
uint16_t hrm_time_to_bpm10(uint8_t time);
|
||||
|
||||
/// Initialise heart rate monitoring
|
||||
void hrm_init();
|
||||
|
||||
/// Add new heart rate value, return true if there was a heart beat
|
||||
bool hrm_new(int hrmValue);
|
||||
bool hrm_new(int hrmValue, Vector3 *acc);
|
||||
|
||||
void hrm_sensor_on();
|
||||
void hrm_sensor_off();
|
||||
|
||||
// Append extra information to an existing HRM event object
|
||||
void hrm_get_hrm_info(JsVar *var);
|
||||
// Append extra information to an existing HRM-raw event object
|
||||
void hrm_get_hrm_raw_info(JsVar *var);
|
||||
|
||||
89
libs/misc/heartrate_vc31_binary.c
Normal file
89
libs/misc/heartrate_vc31_binary.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of Espruino, a JavaScript interpreter for Microcontrollers
|
||||
*
|
||||
* Copyright (C) 2021 Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* heart rate monitoring using VC31 proprietary binary blob
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "heartrate.h"
|
||||
#include "hrm_vc31.h"
|
||||
#include "hrm.h"
|
||||
#include "jshardware.h"
|
||||
#include "jsinteractive.h"
|
||||
#include "vc31_binary/algo.h"
|
||||
|
||||
HrmInfo hrmInfo;
|
||||
|
||||
/// Initialise heart rate monitoring
|
||||
void hrm_init() {
|
||||
memset(&hrmInfo, 0, sizeof(hrmInfo));
|
||||
hrmInfo.isWorn = false;
|
||||
hrmInfo.lastPPGTime = jshGetSystemTime();
|
||||
}
|
||||
|
||||
/// Add new heart rate value
|
||||
bool hrm_new(int ppgValue, Vector3 *acc) {
|
||||
// work out time passed since last sample (it might not be exactly hrmUpdateInterval)
|
||||
JsSysTime time = jshGetSystemTime();
|
||||
int timeDiff = (int)(jshGetMillisecondsFromTime(time-hrmInfo.lastPPGTime)+0.5);
|
||||
hrmInfo.lastPPGTime = time;
|
||||
// if we've just started wearing again, reset the algorith
|
||||
if (vcInfo.isWearing && !hrmInfo.isWorn) {
|
||||
hrmInfo.isWorn = true;
|
||||
// initialise VC31 algorithm (should do when going from wearing to not wearing)
|
||||
Algo_Init();
|
||||
hrmInfo.lastHRM = 0;
|
||||
hrmInfo.lastConfidence = 0;
|
||||
hrmInfo.msSinceLastHRM = 0;
|
||||
hrmInfo.avg = ppgValue;
|
||||
} else {
|
||||
hrmInfo.isWorn = vcInfo.isWearing;
|
||||
if (!hrmInfo.isWorn) return false;
|
||||
}
|
||||
hrmInfo.filtered = ppgValue-hrmInfo.avg;
|
||||
hrmInfo.avg = (hrmInfo.avg*15 + ppgValue) >> 4;
|
||||
// Feed data into algorithm
|
||||
AlgoInputData_t inputData;
|
||||
inputData.axes.x = acc->y >> 5; // perpendicular to the direction of the arm
|
||||
inputData.axes.y = acc->x >> 5; // along the direction of the arm
|
||||
inputData.axes.z = acc->z >> 5;
|
||||
inputData.ppgSample = vcInfo.ppgValue | (vcInfo.wasAdjusted ? 0x1000 : 0);
|
||||
inputData.envSample = vcInfo.envValue;
|
||||
hrmInfo.msSinceLastHRM += timeDiff;
|
||||
Algo_Input(&inputData, timeDiff, SPORT_TYPE_NORMAL,0/*surfaceRecogMode*/,0/*opticalAidMode*/);
|
||||
AlgoOutputData_t outputData;
|
||||
Algo_Output(&outputData);
|
||||
jsiConsolePrintf("HRM %d %d %d\n", outputData.hrData, outputData.reliability, hrmInfo.msSinceLastHRM);
|
||||
if (outputData.hrData!=hrmInfo.lastHRM ||
|
||||
outputData.reliability!=hrmInfo.lastConfidence ||
|
||||
((hrmInfo.msSinceLastHRM > 2000) && outputData.hrData && outputData.reliability)) {
|
||||
// update when figures change OR when 2 secs have passed (readings are usually every 1 sec)
|
||||
hrmInfo.lastConfidence = outputData.reliability;
|
||||
hrmInfo.lastHRM = outputData.hrData;
|
||||
hrmInfo.bpm10 = 10 * outputData.hrData;
|
||||
hrmInfo.confidence = outputData.reliability;
|
||||
hrmInfo.msSinceLastHRM = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Append extra information to an existing HRM event object
|
||||
void hrm_get_hrm_info(JsVar *o) {
|
||||
NOT_USED(o);
|
||||
}
|
||||
|
||||
// Append extra information to an existing HRM-raw event object
|
||||
void hrm_get_hrm_raw_info(JsVar *o) {
|
||||
}
|
||||
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "hrm.h"
|
||||
#include "hrm_vc31.h"
|
||||
#include "jsutils.h"
|
||||
#include "platform_config.h"
|
||||
#include "jshardware.h"
|
||||
@ -164,25 +165,6 @@ typedef enum {
|
||||
VC31B_DEVICE
|
||||
} VC31Type;
|
||||
|
||||
// Hack to fix Eclipse syntax lint
|
||||
#ifndef PACKED_FLAGS
|
||||
#define PACKED_FLAGS
|
||||
#endif
|
||||
// ---
|
||||
|
||||
// VC31 info shared between VC31A/B
|
||||
typedef struct {
|
||||
bool isWearing;
|
||||
int8_t isWearCnt, unWearCnt; // counters for switching worn/unworn state
|
||||
uint16_t ppgValue; // current PPG value
|
||||
uint16_t ppgLastValue; // last PPG value
|
||||
int16_t ppgOffset; // PPG 'offset' value. When PPG adjusts we change the offset so it matches the last value, then slowly adjust 'ppgOffset' back down to 0
|
||||
uint8_t wasAdjusted; // true if LED/etc adjusted since the last reading
|
||||
// the meaning of these is device-dependent but it's nice to have them in one place
|
||||
uint8_t irqStatus;
|
||||
uint8_t raw[12];
|
||||
} PACKED_FLAGS VC31Info;
|
||||
|
||||
// VC31A-specific info
|
||||
typedef struct {
|
||||
uint8_t ctrl; // current VC31A_CTRL reg value
|
||||
@ -191,7 +173,6 @@ typedef struct {
|
||||
uint16_t envValue;
|
||||
uint16_t psValue;
|
||||
VC31AdjustInfo_t adjustInfo;
|
||||
|
||||
} PACKED_FLAGS VC31AInfo;
|
||||
// VC31B-specific info
|
||||
typedef struct {
|
||||
@ -591,6 +572,7 @@ void vc31_irqhandler(bool state, IOEventFlags flags) {
|
||||
vcaInfo.preValue = (buf[6] << 8) | buf[5];
|
||||
vcaInfo.psValue = (buf[8] << 8) | buf[7];
|
||||
vcaInfo.envValue = (buf[10] << 8) | buf[9];
|
||||
vcInfo.envValue = vcaInfo.envValue;
|
||||
|
||||
if (vcInfo.irqStatus & VC31A_STATUS_D_PPG_OK) {
|
||||
vc31_new_ppg(ppgValue); // send PPG value
|
||||
@ -614,7 +596,7 @@ void vc31_irqhandler(bool state, IOEventFlags flags) {
|
||||
vcbInfo.sampleData.envValue[1] = buf[4] >> 4;
|
||||
vcbInfo.sampleData.preValue[1] = buf[4] & 0x0F;
|
||||
vcbInfo.sampleData.envValue[2] = buf[5] >> 4;
|
||||
vcbInfo.sampleData.psValue = buf[5] & 0x0F;
|
||||
vcbInfo.sampleData.psValue = buf[5] & 0x0F;
|
||||
buf = &vcInfo.raw[6];
|
||||
vc31_rx(VC31B_REG17, buf, 6);
|
||||
vcbInfo.sampleData.pdResValue[0] = (buf[3] >> 4) & 0x07;
|
||||
@ -626,6 +608,7 @@ void vc31_irqhandler(bool state, IOEventFlags flags) {
|
||||
|
||||
// if we had environment sensing, check for wear status and update LEDs accordingly
|
||||
if (vcInfo.irqStatus & VC31B_INT_PS) {
|
||||
vcInfo.envValue = vcbInfo.sampleData.envValue[2];
|
||||
//jsiConsolePrintf("e %d %d\n", vcbInfo.sampleData.psValue, vcbInfo.sampleData.envValue[2] );
|
||||
vc31b_wearstatus();
|
||||
}
|
||||
|
||||
39
libs/misc/hrm_vc31.h
Normal file
39
libs/misc/hrm_vc31.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of Espruino, a JavaScript interpreter for Microcontrollers
|
||||
*
|
||||
* Copyright (C) 2019 Gordon Williams <gw@pur3.co.uk>
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* VC31 heart rate sensor - additional info
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef EMULATED
|
||||
|
||||
// Hack to fix Eclipse syntax lint
|
||||
#ifndef PACKED_FLAGS
|
||||
#define PACKED_FLAGS
|
||||
#endif
|
||||
// ---
|
||||
|
||||
// VC31 info shared between VC31A/B
|
||||
typedef struct {
|
||||
bool isWearing;
|
||||
int8_t isWearCnt, unWearCnt; // counters for switching worn/unworn state
|
||||
uint16_t ppgValue; // current PPG value
|
||||
uint16_t ppgLastValue; // last PPG value
|
||||
int16_t ppgOffset; // PPG 'offset' value. When PPG adjusts we change the offset so it matches the last value, then slowly adjust 'ppgOffset' back down to 0
|
||||
uint8_t wasAdjusted; // true if LED/etc adjusted since the last reading
|
||||
uint16_t envValue; // env value (but VC31B has 3 value slots so we just use the one we know is ok here)
|
||||
// the meaning of these is device-dependent but it's nice to have them in one place
|
||||
uint8_t irqStatus;
|
||||
uint8_t raw[12];
|
||||
} PACKED_FLAGS VC31Info;
|
||||
|
||||
extern VC31Info vcInfo;
|
||||
|
||||
#endif
|
||||
24
libs/misc/vc31_binary/README.md
Normal file
24
libs/misc/vc31_binary/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
Proprietary VC31 HRM algorithm
|
||||
===============================
|
||||
|
||||
In this directory are the object files and header for Vcare's heart rate algorithm.
|
||||
|
||||
These were created by VCare (the VC31 manufacturer) and are not part of the MPLv2 license that covers the rest of the Espruino interpreter.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Instead of the code below in the `BOARD.py` file that enables the open source heart rate algorithm:
|
||||
|
||||
```
|
||||
'SOURCES += libs/misc/heartrate.c',
|
||||
```
|
||||
|
||||
you'll need:
|
||||
|
||||
```
|
||||
'SOURCES += libs/misc/heartrate_vc31_binary.c',
|
||||
'DEFINES += -DHEARTRATE_VC31_BINARY=1',
|
||||
'PRECOMPILED_OBJS += libs/misc/vc31_binary/algo.o libs/misc/vc31_binary/modle5_10.o libs/misc/vc31_binary/modle5_11.o libs/misc/vc31_binary/modle5_12.o libs/misc/vc31_binary/modle5_13.o libs/misc/vc31_binary/modle5_14.o libs/misc/vc31_binary/modle5_15.o libs/misc/vc31_binary/modle5_16.o libs/misc/vc31_binary/modle5_17.o libs/misc/vc31_binary/modle5_18.o libs/misc/vc31_binary/modle5_1.o libs/misc/vc31_binary/modle5_2.o libs/misc/vc31_binary/modle5_3.o libs/misc/vc31_binary/modle5_4.o libs/misc/vc31_binary/modle5_5.o libs/misc/vc31_binary/modle5_6.o libs/misc/vc31_binary/modle5_7.o libs/misc/vc31_binary/modle5_8.o libs/misc/vc31_binary/modle5_9.o',
|
||||
```
|
||||
70
libs/misc/vc31_binary/algo.h
Normal file
70
libs/misc/vc31_binary/algo.h
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
#ifndef APP_ALGO_ALGO_H
|
||||
#define APP_ALGO_ALGO_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPORT_TYPE_NORMAL =0x00, // 日常
|
||||
SPORT_TYPE_RUNNING =0x01, // 跑步
|
||||
SPORT_TYPE_RIDE_BIKE =0X02, // 骑行
|
||||
SPORT_TYPE_JUMP_ROPE =0X03, // 跳绳
|
||||
SPORT_TYPE_SWIMMING =0X04, // 游泳
|
||||
SPORT_TYPE_BADMINTON =0X05, // 羽毛球
|
||||
SPORT_TYPE_TABLE_TENNIS=0X06, // 乒乓球
|
||||
SPORT_TYPE_TENNIS =0X07, // 网球
|
||||
SPORT_TYPE_CLIMBING =0X08, // 爬山
|
||||
SPORT_TYPE_WALKING =0X09, // 徒步
|
||||
SPORT_TYPE_BASKETBALL =0X0A, // 篮球
|
||||
SPORT_TYPE_FOOTBALL =0X0B, // 足球
|
||||
SPORT_TYPE_BASEBALL =0X0C, // 棒球
|
||||
SPORT_TYPE_VOLLEYBALL =0X0D, // 排球
|
||||
SPORT_TYPE_CRICKET = 0X0E, // 板球
|
||||
SPORT_TYPE_RUGBY = 0X0F, // 橄榄球
|
||||
SPORT_TYPE_HOCKEY =0X10, // 曲棍球
|
||||
SPORT_TYPE_DANCE = 0X11, // 跳舞
|
||||
SPORT_TYPE_SPINNING = 0X12, // 动感单车
|
||||
SPORT_TYPE_YOGA = 0X13, // 瑜伽
|
||||
SPORT_TYPE_SIT_UP =0X14, // 仰卧起坐
|
||||
SPORT_TYPE_TREADMILL =0X15, // 跑步机
|
||||
SPORT_TYPE_GYMNASTICS =0X16, // 体操
|
||||
SPORT_TYPE_BOATING = 0X17, // 划船
|
||||
SPORT_TYPE_JUMPING_JACK = 0X18, // 开合跳
|
||||
SPORT_TYPE_FREE_TRAINING = 0X19,// 自由训练
|
||||
} AlgoSportMode;
|
||||
//未出现在上表中的运动形式均先以跑步输入
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
}AlgoAxesData_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t hrData;
|
||||
int32_t reliability;
|
||||
}AlgoOutputData_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
AlgoAxesData_t axes;
|
||||
int32_t ppgSample;
|
||||
int32_t envSample;
|
||||
}AlgoInputData_t;
|
||||
|
||||
void Algo_Init(void);
|
||||
void Algo_Input(AlgoInputData_t *pInputData,int32_t gaptime,AlgoSportMode sportMode,int16_t surfaceRecogMode,int16_t opticalAidMode);
|
||||
void Algo_Output(AlgoOutputData_t *pOutputData);
|
||||
void Algo_Version(char *pVersionOutput);
|
||||
|
||||
|
||||
|
||||
#endif /* APP_ALGO_ALGO_H_ */
|
||||
|
||||
|
||||
|
||||
BIN
libs/misc/vc31_binary/algo.o
Normal file
BIN
libs/misc/vc31_binary/algo.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_1.o
Normal file
BIN
libs/misc/vc31_binary/modle5_1.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_10.o
Normal file
BIN
libs/misc/vc31_binary/modle5_10.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_11.o
Normal file
BIN
libs/misc/vc31_binary/modle5_11.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_12.o
Normal file
BIN
libs/misc/vc31_binary/modle5_12.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_13.o
Normal file
BIN
libs/misc/vc31_binary/modle5_13.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_14.o
Normal file
BIN
libs/misc/vc31_binary/modle5_14.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_15.o
Normal file
BIN
libs/misc/vc31_binary/modle5_15.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_16.o
Normal file
BIN
libs/misc/vc31_binary/modle5_16.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_17.o
Normal file
BIN
libs/misc/vc31_binary/modle5_17.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_18.o
Normal file
BIN
libs/misc/vc31_binary/modle5_18.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_2.o
Normal file
BIN
libs/misc/vc31_binary/modle5_2.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_3.o
Normal file
BIN
libs/misc/vc31_binary/modle5_3.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_4.o
Normal file
BIN
libs/misc/vc31_binary/modle5_4.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_5.o
Normal file
BIN
libs/misc/vc31_binary/modle5_5.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_6.o
Normal file
BIN
libs/misc/vc31_binary/modle5_6.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_7.o
Normal file
BIN
libs/misc/vc31_binary/modle5_7.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_8.o
Normal file
BIN
libs/misc/vc31_binary/modle5_8.o
Normal file
Binary file not shown.
BIN
libs/misc/vc31_binary/modle5_9.o
Normal file
BIN
libs/misc/vc31_binary/modle5_9.o
Normal file
Binary file not shown.
@ -77,14 +77,20 @@ endif
|
||||
endif
|
||||
|
||||
# ARCHFLAGS are shared by both CFLAGS and LDFLAGS.
|
||||
ARCHFLAGS = -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=softfp -mfpu=fpv4-sp-d16
|
||||
ARCHFLAGS += -mcpu=cortex-m4 -mthumb -mabi=aapcs
|
||||
ifdef FLOAT_ABI_HARD
|
||||
ARCHFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
DEFINES += -DFLOAT_ABI_HARD
|
||||
else
|
||||
ARCHFLAGS += -mfloat-abi=softfp -mfpu=fpv4-sp-d16
|
||||
endif
|
||||
|
||||
# nRF52 specific.
|
||||
INCLUDE += -I$(SOFTDEVICE_PATH)/headers
|
||||
INCLUDE += -I$(SOFTDEVICE_PATH)/headers/nrf52
|
||||
|
||||
DEFINES += -DBLE_STACK_SUPPORT_REQD
|
||||
DEFINES += -DSWI_DISABLE0 -DSOFTDEVICE_PRESENT -DFLOAT_ABI_HARD
|
||||
DEFINES += -DSWI_DISABLE0 -DSOFTDEVICE_PRESENT
|
||||
DEFINES += -DNRF52_SERIES
|
||||
# Nordic screwed over anyone who used -DNRF52 in new SDK versions
|
||||
# but then old SDKs won't work without it
|
||||
|
||||
@ -620,4 +620,8 @@ size_t jsuGetFreeStack();
|
||||
void *espruino_stackHighPtr; //Used by jsuGetFreeStack
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
short x,y,z;
|
||||
} Vector3;
|
||||
|
||||
#endif /* JSUTILS_H_ */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user