Browse Source

update

master
zhaohe 1 year ago
parent
commit
6189ddf36b
  1. 4
      .vscode/settings.json
  2. 7
      README.md
  3. 217
      app/app.uvoptx
  4. 30
      app/app.uvprojx
  5. 14
      app/config/sdk_config.h
  6. 8
      app/src/ble_cmd_process_service.c
  7. 16
      app/src/board/board.h
  8. 55
      app/src/board/board_adc_module_ctrl.c
  9. 13
      app/src/board/board_adc_module_ctrl.h
  10. 68
      app/src/board/board_battery_state.c
  11. 17
      app/src/board/board_battery_state.h
  12. 7
      app/src/board/board_beep_ctrl.c
  13. 60
      app/src/board/board_ecg_sensor.c
  14. 20
      app/src/board/board_ecg_sensor.h
  15. 1
      app/src/device_state.h
  16. 10
      app/src/display_manager.c
  17. 45
      app/src/heart_wave_sample_service.c
  18. 105
      app/src/one_conduction_board.c
  19. 15
      app/src/one_conduction_board.h
  20. 174
      app/src/one_conduction_main.c
  21. 2
      libznordic

4
.vscode/settings.json

@ -115,7 +115,9 @@
"filter.h": "c",
"filters.h": "c",
"nrfx_rtc.h": "c",
"device_state.h": "c"
"device_state.h": "c",
"board_adc_module_ctrl.h": "c",
"board_ecg_sensor.h": "c"
},
"files.encoding": "gbk"
}

7
README.md

@ -2,14 +2,17 @@
```
TODO
0. 支持无线升级,修改SN码
6. 开始采集蜂鸣器响响三声,结束采集蜂鸣器响三声
0. 支持无线升级,修改SN码 OK
6. 开始采集蜂鸣器响响一声,结束采集蜂鸣器响一声 OK
2. 不足三十30,响三声 OK
3. 添加是否充电检测
1. 添加逻辑,如果未配置时间,设备进入深度休眠。
2. 修改电池电量相关逻辑,校准电池电量。
3. 修改心率采样ADC参考电压
4. 修改屏幕显示位置
5. 充电中,限制用户操作
6. 调整ADC放大倍数
7. 开机时进行低电量检测
测试:

217
app/app.uvoptx

@ -148,24 +148,7 @@
<Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN2 -FF0nrf52xxx -FS00 -FL0200000 -FF1nrf52xxx_uicr -FS110001000 -FL11000 -FP0($$Device:nRF52833_xxAA$Flash\nrf52xxx.flm) -FP1($$Device:nRF52833_xxAA$Flash\nrf52xxx_uicr.flm))</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint>
<Bp>
<Number>0</Number>
<Type>0</Type>
<LineNumber>19</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>189332</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename>.\src\main.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\app\src/main.c\19</Expression>
</Bp>
</Breakpoint>
<Breakpoint/>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>
@ -624,6 +607,42 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\src\board\board_adc_module_ctrl.c</PathWithFileName>
<FilenameWithoutPath>board_adc_module_ctrl.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\src\board\board_battery_state.c</PathWithFileName>
<FilenameWithoutPath>board_battery_state.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\src\board\board_ecg_sensor.c</PathWithFileName>
<FilenameWithoutPath>board_ecg_sensor.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
@ -634,7 +653,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>21</FileNumber>
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -654,7 +673,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>22</FileNumber>
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -666,7 +685,7 @@
</File>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>23</FileNumber>
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -686,7 +705,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>4</GroupNumber>
<FileNumber>24</FileNumber>
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -706,7 +725,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>25</FileNumber>
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -718,7 +737,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>26</FileNumber>
<FileNumber>29</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -730,7 +749,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>27</FileNumber>
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -742,7 +761,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>28</FileNumber>
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -754,7 +773,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>29</FileNumber>
<FileNumber>32</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -766,7 +785,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>30</FileNumber>
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -778,7 +797,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>31</FileNumber>
<FileNumber>34</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -790,7 +809,7 @@
</File>
<File>
<GroupNumber>5</GroupNumber>
<FileNumber>32</FileNumber>
<FileNumber>35</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -810,7 +829,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>6</GroupNumber>
<FileNumber>33</FileNumber>
<FileNumber>36</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -830,7 +849,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>34</FileNumber>
<FileNumber>37</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -842,7 +861,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>35</FileNumber>
<FileNumber>38</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -854,7 +873,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>36</FileNumber>
<FileNumber>39</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -866,7 +885,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>37</FileNumber>
<FileNumber>40</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -878,7 +897,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>38</FileNumber>
<FileNumber>41</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -890,7 +909,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>39</FileNumber>
<FileNumber>42</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -902,7 +921,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>40</FileNumber>
<FileNumber>43</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -914,7 +933,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>41</FileNumber>
<FileNumber>44</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -926,7 +945,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>42</FileNumber>
<FileNumber>45</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -938,7 +957,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>43</FileNumber>
<FileNumber>46</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -950,7 +969,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>44</FileNumber>
<FileNumber>47</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -962,7 +981,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>45</FileNumber>
<FileNumber>48</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -974,7 +993,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>46</FileNumber>
<FileNumber>49</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -986,7 +1005,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>47</FileNumber>
<FileNumber>50</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -998,7 +1017,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>48</FileNumber>
<FileNumber>51</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1010,7 +1029,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>49</FileNumber>
<FileNumber>52</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1022,7 +1041,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>50</FileNumber>
<FileNumber>53</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1034,7 +1053,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>51</FileNumber>
<FileNumber>54</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1046,7 +1065,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>52</FileNumber>
<FileNumber>55</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1058,7 +1077,7 @@
</File>
<File>
<GroupNumber>7</GroupNumber>
<FileNumber>53</FileNumber>
<FileNumber>56</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1078,7 +1097,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>54</FileNumber>
<FileNumber>57</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1090,7 +1109,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>55</FileNumber>
<FileNumber>58</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1102,7 +1121,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>56</FileNumber>
<FileNumber>59</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1114,7 +1133,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>57</FileNumber>
<FileNumber>60</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1126,7 +1145,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>58</FileNumber>
<FileNumber>61</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1138,7 +1157,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>59</FileNumber>
<FileNumber>62</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1150,7 +1169,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>60</FileNumber>
<FileNumber>63</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1162,7 +1181,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>61</FileNumber>
<FileNumber>64</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1174,7 +1193,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>62</FileNumber>
<FileNumber>65</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1186,7 +1205,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>63</FileNumber>
<FileNumber>66</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1198,7 +1217,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>64</FileNumber>
<FileNumber>67</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1210,7 +1229,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>65</FileNumber>
<FileNumber>68</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1222,7 +1241,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>66</FileNumber>
<FileNumber>69</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1234,7 +1253,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>67</FileNumber>
<FileNumber>70</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1246,7 +1265,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>68</FileNumber>
<FileNumber>71</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1258,7 +1277,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>69</FileNumber>
<FileNumber>72</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1270,7 +1289,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>70</FileNumber>
<FileNumber>73</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1282,7 +1301,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>71</FileNumber>
<FileNumber>74</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1294,7 +1313,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>72</FileNumber>
<FileNumber>75</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1306,7 +1325,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>73</FileNumber>
<FileNumber>76</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1318,7 +1337,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>74</FileNumber>
<FileNumber>77</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1330,7 +1349,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>75</FileNumber>
<FileNumber>78</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1342,7 +1361,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>76</FileNumber>
<FileNumber>79</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1354,7 +1373,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>77</FileNumber>
<FileNumber>80</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1366,7 +1385,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>78</FileNumber>
<FileNumber>81</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1378,7 +1397,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>79</FileNumber>
<FileNumber>82</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1390,7 +1409,7 @@
</File>
<File>
<GroupNumber>8</GroupNumber>
<FileNumber>80</FileNumber>
<FileNumber>83</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1410,7 +1429,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>81</FileNumber>
<FileNumber>84</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1422,7 +1441,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>82</FileNumber>
<FileNumber>85</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1434,7 +1453,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>83</FileNumber>
<FileNumber>86</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1446,7 +1465,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>84</FileNumber>
<FileNumber>87</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1458,7 +1477,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>85</FileNumber>
<FileNumber>88</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1470,7 +1489,7 @@
</File>
<File>
<GroupNumber>9</GroupNumber>
<FileNumber>86</FileNumber>
<FileNumber>89</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1490,7 +1509,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>87</FileNumber>
<FileNumber>90</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1502,7 +1521,7 @@
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>88</FileNumber>
<FileNumber>91</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1514,7 +1533,7 @@
</File>
<File>
<GroupNumber>10</GroupNumber>
<FileNumber>89</FileNumber>
<FileNumber>92</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1534,7 +1553,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>11</GroupNumber>
<FileNumber>90</FileNumber>
<FileNumber>93</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1546,7 +1565,7 @@
</File>
<File>
<GroupNumber>11</GroupNumber>
<FileNumber>91</FileNumber>
<FileNumber>94</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1558,7 +1577,7 @@
</File>
<File>
<GroupNumber>11</GroupNumber>
<FileNumber>92</FileNumber>
<FileNumber>95</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1578,7 +1597,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>12</GroupNumber>
<FileNumber>93</FileNumber>
<FileNumber>96</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1590,7 +1609,7 @@
</File>
<File>
<GroupNumber>12</GroupNumber>
<FileNumber>94</FileNumber>
<FileNumber>97</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1602,7 +1621,7 @@
</File>
<File>
<GroupNumber>12</GroupNumber>
<FileNumber>95</FileNumber>
<FileNumber>98</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1622,7 +1641,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>13</GroupNumber>
<FileNumber>96</FileNumber>
<FileNumber>99</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1634,7 +1653,7 @@
</File>
<File>
<GroupNumber>13</GroupNumber>
<FileNumber>97</FileNumber>
<FileNumber>100</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1654,7 +1673,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>98</FileNumber>
<FileNumber>101</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1666,7 +1685,7 @@
</File>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>99</FileNumber>
<FileNumber>102</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1678,7 +1697,7 @@
</File>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>100</FileNumber>
<FileNumber>103</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@ -1690,7 +1709,7 @@
</File>
<File>
<GroupNumber>14</GroupNumber>
<FileNumber>101</FileNumber>
<FileNumber>104</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>

30
app/app.uvprojx

@ -483,6 +483,21 @@
<FileType>1</FileType>
<FilePath>.\src\board\board_beep_ctrl.c</FilePath>
</File>
<File>
<FileName>board_adc_module_ctrl.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\board\board_adc_module_ctrl.c</FilePath>
</File>
<File>
<FileName>board_battery_state.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\board\board_battery_state.c</FilePath>
</File>
<File>
<FileName>board_ecg_sensor.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\board\board_ecg_sensor.c</FilePath>
</File>
</Files>
</Group>
<Group>
@ -4347,6 +4362,21 @@
<FileType>1</FileType>
<FilePath>.\src\board\board_beep_ctrl.c</FilePath>
</File>
<File>
<FileName>board_adc_module_ctrl.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\board\board_adc_module_ctrl.c</FilePath>
</File>
<File>
<FileName>board_battery_state.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\board\board_battery_state.c</FilePath>
</File>
<File>
<FileName>board_ecg_sensor.c</FileName>
<FileType>1</FileType>
<FilePath>.\src\board\board_ecg_sensor.c</FilePath>
</File>
</Files>
</Group>
<Group>

14
app/config/sdk_config.h

@ -3992,21 +3992,21 @@
#ifndef NRFX_TIMER1_ENABLED
#define NRFX_TIMER1_ENABLED 0
#define NRFX_TIMER1_ENABLED 1
#endif
// <q> NRFX_TIMER2_ENABLED - Enable TIMER2 instance
#ifndef NRFX_TIMER2_ENABLED
#define NRFX_TIMER2_ENABLED 0
#define NRFX_TIMER2_ENABLED 1
#endif
// <q> NRFX_TIMER3_ENABLED - Enable TIMER3 instance
#ifndef NRFX_TIMER3_ENABLED
#define NRFX_TIMER3_ENABLED 0
#define NRFX_TIMER3_ENABLED 1
#endif
// <q> NRFX_TIMER4_ENABLED - Enable TIMER4 instance
@ -5772,14 +5772,14 @@
#ifndef TIMER2_ENABLED
#define TIMER2_ENABLED 0
#define TIMER2_ENABLED 1
#endif
// <q> TIMER3_ENABLED - Enable TIMER3 instance
#ifndef TIMER3_ENABLED
#define TIMER3_ENABLED 0
#define TIMER3_ENABLED 1
#endif
// <q> TIMER4_ENABLED - Enable TIMER4 instance
@ -7734,7 +7734,7 @@
// <e> NRF_LOG_BACKEND_RTT_ENABLED - nrf_log_backend_rtt - Log RTT backend
//==========================================================
#ifndef NRF_LOG_BACKEND_RTT_ENABLED
#define NRF_LOG_BACKEND_RTT_ENABLED 0
#define NRF_LOG_BACKEND_RTT_ENABLED 1
#endif
// <o> NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings.
// <i> Size of the buffer is a trade-off between RAM usage and processing.
@ -7812,7 +7812,7 @@
// <e> NRF_LOG_ENABLED - nrf_log - Logger
//==========================================================
#ifndef NRF_LOG_ENABLED
#define NRF_LOG_ENABLED 0
#define NRF_LOG_ENABLED 1
#endif
// <h> Log message pool - Configuration of log message pool

8
app/src/ble_cmd_process_service.c

@ -8,6 +8,8 @@
#include "zble_module.h"
#include "zdatachannel_service.h"
#include "basic/device_version_info_mgr.h"
#include "board/board_ecg_sensor.h"
#include "board/board_battery_state.h"
APP_TIMER_DEF(m_record_upload_tmr); //
APP_TIMER_DEF(m_record_upload_finish_packet_report_tmr); //
@ -296,15 +298,15 @@ void ble_cmder_process_rx(uint8_t* rx, int len) {
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 = (!SingleLeadECG_ecg_plod_get_connected_state());
receipt->drop_state0 = (!BoardEcgSensor_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.low_battery = (BoardBattery_get_battery_level() < 20);
receipt->device_state0.full_storge = (sample_data_mgr_storage_is_full());
receipt->device_state1 = 0;
receipt->powerlevel = SingleLeadECG_battery_val();
receipt->powerlevel = BoardBattery_get_battery_level();
receipt->storage_item_num = sample_data_mgr_get_file_num();
zdatachannel_data_send2(txbuf, sendlen);

16
app/src/board/board.h

@ -6,7 +6,18 @@
#define BEEP_PIN 1
#define BEEP_PWM_INSTANCE 0
/*******************************************************************************
* ADC *
*******************************************************************************/
#define ECG_NLOD_PIN 3
#define ECG_PLOD_PIN 28
#define ECG_ADC_PIN NRF_SAADC_INPUT_AIN0
#define ECG_ADC_CHANNEL 0 // 不重复即可
#define BATTERY_ADC_PIN NRF_SAADC_INPUT_AIN3
#define BATTERY_ADC_CHANNEL 1 // 不重复即可
#define BATTERY_CHARGE_DETECT_PIN 18
/**
* @brief
@ -21,4 +32,7 @@
#define SAMPLE_MIN_TIME_S (30.0) // 采样最小时间
#define LITTLE_DATA_BLOCK_FRAME_NUM 5 // 每次多少帧上报一次
#define KEEP_STILL_OVERTIME_MS_1P5 2000 // 保持静止超时时间的1/6
#define KEEP_STILL_OVERTIME_MS_1P5 2000 // 保持静止超时时间的1/6
#define HEART_WAVE_SAMPLE_TMR_INSTANCE 3

55
app/src/board/board_adc_module_ctrl.c

@ -0,0 +1,55 @@
#include "board_adc_module_ctrl.h"
/*******************************************************************************
* ADC *
*******************************************************************************/
static uint8_t m_now_adc_channel = 0xff;
static int32_t m_load_times = 0;
void BoardAdc_set_ch(uint8_t ch);
void BoardAdc_init() {}
void BoardAdc_load() {
if (m_load_times == 0) {
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));
m_load_times++;
} else {
m_load_times += 1;
}
}
void BoardAdc_unload() {
if (m_load_times == 1) {
BoardAdc_set_ch(0xff);
nrf_drv_saadc_uninit();
m_load_times = 0;
} else {
m_load_times -= 1;
}
if (m_load_times < 0) {
m_load_times = 0;
}
}
void BoardAdc_set_ch(uint8_t ch) {
if (m_now_adc_channel != ch) {
if (m_now_adc_channel != 0xff) nrfx_saadc_channel_uninit(m_now_adc_channel);
if (ch == ECG_ADC_CHANNEL) {
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ECG_ADC_PIN);
channel_config.acq_time = NRF_SAADC_ACQTIME_40US;
ZERROR_CHECK(nrfx_saadc_channel_init(ECG_ADC_CHANNEL, &channel_config));
} else if (ch == BATTERY_ADC_CHANNEL) {
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(BATTERY_ADC_PIN);
channel_config.acq_time = NRF_SAADC_ACQTIME_40US;
ZERROR_CHECK(nrfx_saadc_channel_init(BATTERY_ADC_CHANNEL, &channel_config));
}
}
m_now_adc_channel = ch;
}
int16_t BoardAdc_get_val(uint8_t ch) {
BoardAdc_set_ch(ch);
return znrf_adc_channel_read_val(ch);
}

13
app/src/board/board_adc_module_ctrl.h

@ -0,0 +1,13 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "board/board.h"
#include "znordic.h"
void BoardAdc_init();
void BoardAdc_load();
void BoardAdc_unload();
int16_t BoardAdc_get_val(uint8_t ch);

68
app/src/board/board_battery_state.c

@ -0,0 +1,68 @@
#include "board_battery_state.h"
#include "app_event.h"
#include "board_adc_module_ctrl.h"
/*******************************************************************************
* Battery *
*******************************************************************************/
APP_TIMER_DEF(battery_state_detect_tmr); //
static bool m_battery_is_chargeing = false; //
static bool battery_get_chargeing_state() { return !nrf_gpio_pin_read(BATTERY_CHARGE_DETECT_PIN); }
static void module_tmr_cb(void *context) { //
bool chargeing_state = battery_get_chargeing_state();
if (chargeing_state != m_battery_is_chargeing) {
app_event_t event;
memset(&event, 0, sizeof(event));
if (chargeing_state) {
ZLOGI("battery is charging");
event.eventType = kbattery_start_charge_event;
} else {
ZLOGI("battery end charging");
event.eventType = kbattery_end_charge_event;
}
AppEvent_pushEvent(&event);
}
m_battery_is_chargeing = chargeing_state;
}
void BoardBattery_init() {
/**
* @brief 500ms启动定时器500ms检查一次当前是否正在充电
*/
nrf_gpio_cfg_sense_input(BATTERY_CHARGE_DETECT_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);
app_timer_create(&battery_state_detect_tmr, APP_TIMER_MODE_REPEATED, module_tmr_cb);
app_timer_start(battery_state_detect_tmr, APP_TIMER_TICKS(500), NULL);
}
void BoardBattery_load() { BoardAdc_load(); }
void BoardBattery_unload() { BoardAdc_unload(); }
int16_t BoardBattery_sence_gpio_init_before_sleep() { nrf_gpio_cfg_sense_input(BATTERY_CHARGE_DETECT_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); }
int16_t BoardBattery_get_adc_val() {
int16_t val = BoardAdc_get_val(BATTERY_ADC_CHANNEL);
return val;
}
int16_t BoardBattery_get_charging_state() { //
return !nrf_gpio_pin_read(BATTERY_CHARGE_DETECT_PIN);
}
int16_t BoardBattery_get_battery_level() {
static const float maxv = 4.0;
static const float minv = 3.3;
int16_t rawval = BoardBattery_get_adc_val();
float voltage = rawval / 4096.0 * 3.6 / 2.0 * 3;
if (voltage > maxv) voltage = maxv;
if (voltage < minv) voltage = minv;
float percent = (voltage - minv) / (maxv - minv) * 100 + (float)0.1 /*加0.1是为了避免999.999时显示电量为90*/;
int16_t percent_int = (int16_t)percent;
if (percent_int < 0) {
percent_int = 0;
} else if (percent_int > 100) {
percent_int = 100;
}
return percent_int;
}

17
app/src/board/board_battery_state.h

@ -0,0 +1,17 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "board/board.h"
#include "znordic.h"
void BoardBattery_init();
void BoardBattery_load();
void BoardBattery_unload();
int16_t BoardBattery_get_adc_val();
int16_t BoardBattery_get_battery_level(); // 0->100
int16_t BoardBattery_get_charging_state();
int16_t BoardBattery_sence_gpio_init_before_sleep();

7
app/src/board/board_beep_ctrl.c

@ -129,12 +129,5 @@ void BoardBeepCtrl_setEffect(BoardBeepEffect_t effect) {
#else
void BoardBeepCtrl_init(void) {}
void BoardBeepCtrl_load() {}
void BoardBeepCtrl_unload() {}
void BoardBeepCtrl_set(uint8_t state) {}
void BoardBeepCtrl_setEffect(BoardBeepEffect_t effect) {}
#endif

60
app/src/board/board_ecg_sensor.c

@ -0,0 +1,60 @@
#include "board_ecg_sensor.h"
#include "app_event_distribute.h"
#include "board_adc_module_ctrl.h"
APP_TIMER_DEF(module_tmr); //
//
static bool m_plod_state_connected_state = false;
static uint32_t m_connecte_state_last_trigger_timepoint = 0;
static uint32_t plod_state_has_disconnected_ms() { return znordic_haspassed_ms(m_connecte_state_last_trigger_timepoint); }
static bool plod_state_is_connected() { return m_plod_state_connected_state; }
static void module_tmr_cb(void *context) { //
static uint32_t connecte_state_trigger_cnt = 0;
static app_event_t appevent;
memset(&appevent, 0, sizeof(appevent));
if (BoardEcgSensor_plod_get_connected_state()) {
connecte_state_trigger_cnt++;
m_connecte_state_last_trigger_timepoint = znordic_getpower_on_ms();
} else {
connecte_state_trigger_cnt = 0;
}
if (!m_plod_state_connected_state && connecte_state_trigger_cnt >= 10) {
//
appevent.eventType = kplod_connected_event;
m_plod_state_connected_state = true;
AppEvent_pushEvent(&appevent);
} else if (m_plod_state_connected_state && connecte_state_trigger_cnt == 0) {
//
appevent.eventType = kplod_disconnected_event;
m_plod_state_connected_state = false;
AppEvent_pushEvent(&appevent);
}
}
void BoardEcgSensor_init() {
nrf_gpio_cfg_sense_input(ECG_NLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE); //
app_timer_create(&module_tmr, APP_TIMER_MODE_REPEATED, module_tmr_cb);
app_timer_start(module_tmr, APP_TIMER_TICKS(100), NULL);
}
void BoardEcgSensor_load() { BoardAdc_load(); }
void BoardEcgSensor_unload() { BoardAdc_unload(); }
int16_t BoardEcgSensor_nlod_get_connected_state() { return nrf_gpio_pin_read(ECG_NLOD_PIN); }
int16_t BoardEcgSensor_plod_get_connected_state() { return !nrf_gpio_pin_read(ECG_PLOD_PIN); }
int16_t BoardEcgSensor_plod_get_ecg_val() { return BoardAdc_get_val(ECG_ADC_CHANNEL); }
int16_t BoardEcgSensor_plod_get_connected_state_after_filter() { return plod_state_is_connected(); }
int16_t BoardEcgSensor_plod_state_has_disconnected_ms() { return plod_state_has_disconnected_ms(); }
int16_t BoardEcgSensor_set_sence_state() {
nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
return 0;
}

20
app/src/board/board_ecg_sensor.h

@ -0,0 +1,20 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "board/board.h"
#include "znordic.h"
void BoardEcgSensor_init();
void BoardEcgSensor_load();
void BoardEcgSensor_unload();
int16_t BoardEcgSensor_nlod_get_connected_state();
int16_t BoardEcgSensor_plod_get_connected_state();
int16_t BoardEcgSensor_plod_get_connected_state_after_filter();
int16_t BoardEcgSensor_plod_state_has_disconnected_ms();
int16_t BoardEcgSensor_plod_get_ecg_val();
int16_t BoardEcgSensor_set_sence_state();

1
app/src/device_state.h

@ -9,7 +9,6 @@ typedef enum {
kplod_connecting_event, //
kbattery_start_charge_event, //
kbattery_charging_event, //
kbattery_end_charge_event, //
kevent_tmr_scheduler_event, //

10
app/src/display_manager.c

@ -11,6 +11,7 @@
#include "font.h"
#include "heart_wave_sample_service.h"
#include "one_conduction_board.h"
#include "board/board_battery_state.h"
PageState_t g_pageState;
void dsp_mgr_change_to_page(page_t page) { //
@ -58,6 +59,7 @@ int compute_y_pos_by_center(int16_t y, int16_t height) { return y - height / 2;
* 1.
*
*/
static uint32_t m_nowshowbatterylevel; //
void dsp_mgr_change_to_chargingPage() {
@ -65,8 +67,8 @@ void dsp_mgr_change_to_chargingPage() {
uint8_t x = compute_x_pos_by_center(SCREEN_CENTER_X, CHARGE_BATTERY_WIDTH);
uint8_t y = compute_y_pos_by_center(SCREEN_CENTER_Y, CHARGE_BATTERY_HEIGHT);
uint8_t xchange, ychange;
ssd1306_basic_draw_battery_level(x, y, &xchange, &ychange, SingleLeadECG_battery_val(), CHARGE_BATTERY_WIDTH, CHARGE_BATTERY_HEIGHT);
m_nowshowbatterylevel = SingleLeadECG_battery_val();
ssd1306_basic_draw_battery_level(x, y, &xchange, &ychange, BoardBattery_get_battery_level(), CHARGE_BATTERY_WIDTH, CHARGE_BATTERY_HEIGHT);
m_nowshowbatterylevel = BoardBattery_get_battery_level();
ssd1306_basic_gram_update();
dsp_mgr_change_to_page(kPage_chargingPage);
}
@ -88,7 +90,7 @@ void chargingPage_schedule() { //
last_update_time = znordic_getpower_on_ms();
m_nowshowbatterylevel += 5;
if (m_nowshowbatterylevel > 100) {
m_nowshowbatterylevel = SingleLeadECG_battery_val();
m_nowshowbatterylevel = BoardBattery_get_battery_level();
}
chargingPage_set_batteryLevel(m_nowshowbatterylevel);
}
@ -125,7 +127,7 @@ void mainPage_show(bool colon_state) {
x = compute_x_pos_by_center(SCREEN_CENTER_X, fontclocklib.widthPixel * 5 + MAIN_PAGE_BATTERY_WIDTH);
y = compute_y_pos_by_center(SCREEN_CENTER_Y, fontclocklib.heightPixel + 1);
znordic_rtc_gettime(&now);
batterylevel = SingleLeadECG_battery_val();
batterylevel = BoardBattery_get_battery_level();
ssd1306_basic_clear_gram();

45
app/src/heart_wave_sample_service.c

@ -2,10 +2,9 @@
#include "app_event.h"
#include "app_event_distribute.h"
#include "board/board_ecg_sensor.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];
@ -93,7 +92,7 @@ static inline void prvf_light_block_trigger_event() {
}
void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) { //
uint16_t val = SingleLeadECG_ecg_plod_get_ecg_val(); // 12bit
uint16_t val = BoardEcgSensor_plod_get_ecg_val(); // 12bit
m_frame_index++;
/*******************************************************************************
@ -135,30 +134,28 @@ void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) {
prvf_light_block_cache_clear();
}
}
static const nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(HEART_WAVE_SAMPLE_TMR_INSTANCE);
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);
static bool m_timer_inited = false;
if (!m_timer_inited) {
/**
* @brief
*/
static nrfx_timer_config_t timer_cfg = {
.frequency = NRF_TIMER_FREQ_500kHz,
.mode = NRF_TIMER_MODE_TIMER,
.bit_width = NRF_TIMER_BIT_WIDTH_24,
.p_context = NULL,
.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY,
};
// nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler);
ZERROR_CHECK(nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler));
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_inited = true;
}
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); }

105
app/src/one_conduction_board.c

@ -26,68 +26,16 @@
#define LED_GREEN_PIN 9
#define LED_BLUE_PIN 10
// #define LED_GREEN_PIN 27
// #define LED_BLUE_PIN 28
#define ECG_NLOD_PIN 3
#define ECG_PLOD_PIN 28
#define ECG_ADC_PIN NRF_SAADC_INPUT_AIN0
#define ECG_ADC_CHANNEL 0 // 不重复即可
#define BATTERY_ADC_PIN NRF_SAADC_INPUT_AIN3
#define BATTERY_ADC_CHANNEL 1 // 不重复即可
#define EEPROM_I2C_SCL_M 15 // I2C SCL引脚
#define EEPROM_I2C_SDA_M 17 // I2C SDA引脚
#define EEPROM_I2C_INSTANCE 1 // I2C使用的硬件控制器ID
#define BATTERY_CHARGE_DETECT_PIN 18
/*******************************************************************************
* TOOLS *
*******************************************************************************/
/*******************************************************************************
* ADC *
*******************************************************************************/
uint8_t m_now_adc_channel = 0xff;
void SingleLeadECG_adc_set_ch(uint8_t ch);
void SingleLeadECG_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));
// SingleLeadECG_adc_set_ch(BATTERY_ADC_CHANNEL);
}
void SingleLeadECG_adc_set_ch(uint8_t ch) {
if (m_now_adc_channel != ch) {
if (m_now_adc_channel != 0xff) nrfx_saadc_channel_uninit(m_now_adc_channel);
if (ch == ECG_ADC_CHANNEL) {
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ECG_ADC_PIN);
channel_config.acq_time = NRF_SAADC_ACQTIME_40US;
ZERROR_CHECK(nrfx_saadc_channel_init(ECG_ADC_CHANNEL, &channel_config));
} else if (ch == BATTERY_ADC_CHANNEL) {
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(BATTERY_ADC_PIN);
channel_config.acq_time = NRF_SAADC_ACQTIME_40US;
ZERROR_CHECK(nrfx_saadc_channel_init(BATTERY_ADC_CHANNEL, &channel_config));
}
}
m_now_adc_channel = ch;
}
int16_t SingleLeadECG_adc_get_val(uint8_t ch) {
SingleLeadECG_adc_set_ch(ch);
return znrf_adc_channel_read_val(ch);
}
void SingleLeadECG_adc_module_deinit() {
SingleLeadECG_adc_set_ch(0xff);
nrf_drv_saadc_uninit();
}
/*******************************************************************************
* SCREEN *
@ -189,59 +137,6 @@ void SingleLeadECG_led_blue_set_state(bool state) {
}
/*******************************************************************************
* ecg *
*******************************************************************************/
/**
* @brief
* PLOD: 01
*/
void SingleLeadECG_ecg_init() {}
void SingleLeadECG_ecg_deinit() {}
void SingleLeadECG_ecg_io_init() {
nrf_gpio_cfg_sense_input(ECG_NLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);
nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);
}
uint32_t SingleLeadECG_ecg_nlod_get_connected_state() { return nrf_gpio_pin_read(ECG_NLOD_PIN); }
uint32_t SingleLeadECG_ecg_plod_get_connected_state() { return !nrf_gpio_pin_read(ECG_PLOD_PIN); }
int16_t SingleLeadECG_ecg_plod_get_ecg_val() { return SingleLeadECG_adc_get_val(ECG_ADC_CHANNEL); }
/*******************************************************************************
* BATTERY *
*******************************************************************************/
void SingleLeadECG_battery_init() {}
void SingleLeadECG_battery_deinit() {}
int16_t SingleLeadECG_battery_get_adc_val() { return SingleLeadECG_adc_get_val(BATTERY_ADC_CHANNEL); }
int16_t SingleLeadECG_battery_val() { //
static const float maxv = 4.0;
static const float minv = 3.5;
float voltage = SingleLeadECG_battery_get_adc_val() / 4096.0 * 3.3 / 2.0 * 3;
if (voltage > maxv) voltage = maxv;
if (voltage < minv) voltage = minv;
float percent = (voltage - minv) / (maxv - minv) * 100 + (float)0.1 /*加0.1是为了避免999.999时显示电量为90*/;
int16_t percent_int = (int16_t)percent;
if (percent_int < 10 && percent_int != 0) {
percent_int = 3;
} else {
percent_int = percent_int / 10 * 10;
}
// ZLOGI("battery %d ", SingleLeadECG_battery_get_adc_val());
return percent_int;
}
void SingleLeadECG_battery_charge_detect_io_init() { //
nrf_gpio_cfg_sense_input(BATTERY_CHARGE_DETECT_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE);
}
bool SingleLeadECG_battery_charge_get_state() { return nrf_gpio_pin_read(BATTERY_CHARGE_DETECT_PIN) == 0; }
/*******************************************************************************
* eeprom *
*******************************************************************************/
static const nrf_drv_twi_t m_eeprom_twi_master = NRF_DRV_TWI_INSTANCE(EEPROM_I2C_INSTANCE);

15
app/src/one_conduction_board.h

@ -17,7 +17,6 @@ void SingleLeadECG_adc_module_init();
void SingleLeadECG_adc_module_deinit();
/*******************************************************************************
* EEPROM *
*******************************************************************************/
@ -47,25 +46,15 @@ void SingleLeadECG_led_deinit();
void SingleLeadECG_led_green_set_state(bool state);
void SingleLeadECG_led_blue_set_state(bool state);
#if 0
/*******************************************************************************
* ECG *
*******************************************************************************/
void SingleLeadECG_ecg_init();
void SingleLeadECG_ecg_deinit();
void SingleLeadECG_ecg_io_init();
uint32_t SingleLeadECG_ecg_nlod_get_connected_state();
uint32_t SingleLeadECG_ecg_plod_get_connected_state();
int16_t SingleLeadECG_ecg_plod_get_ecg_val();
/*******************************************************************************
* BATTERY *
*******************************************************************************/
void SingleLeadECG_battery_init();
void SingleLeadECG_battery_deinit();
int16_t SingleLeadECG_battery_get_adc_val();
int16_t SingleLeadECG_battery_val();
void SingleLeadECG_battery_charge_detect_io_init();
bool SingleLeadECG_battery_charge_get_state();
#endif

174
app/src/one_conduction_main.c

@ -4,7 +4,10 @@
#include "app_event_distribute.h"
#include "basic/device_version_info_mgr.h"
#include "ble_cmd_process_service.h"
#include "board/board_adc_module_ctrl.h"
#include "board/board_battery_state.h"
#include "board/board_beep_ctrl.h"
#include "board/board_ecg_sensor.h"
#include "config.h"
#include "display_manager.h"
#include "heart_wave_sample_service.h"
@ -18,9 +21,9 @@
* GLOBAL *
*******************************************************************************/
APP_TIMER_DEF(m_state_machine_driver_tmr); //
APP_TIMER_DEF(m_plod_state_event_detect_tmr); //
APP_TIMER_DEF(m_charge_event_detect_tmr); //
APP_TIMER_DEF(m_state_machine_driver_tmr); //
// APP_TIMER_DEF(m_plod_state_event_detect_tmr); //
// APP_TIMER_DEF(m_charge_event_detect_tmr); //
static int m_cur_fd;
static sample_data_filename_t sampledata_file_name;
@ -36,74 +39,17 @@ static sample_data_filename_t sampledata_file_name;
/*******************************************************************************
* *
*******************************************************************************/
//
static bool m_plod_state_connected_state = false;
static uint32_t m_connecte_state_last_trigger_timepoint = 0;
static uint32_t plod_state_has_disconnected_ms() { return znordic_haspassed_ms(m_connecte_state_last_trigger_timepoint); }
static bool plod_state_is_connected() { return m_plod_state_connected_state; }
static void m_plod_state_event_detect_tmr_cb(void* p_context) { //
static uint32_t connecte_state_trigger_cnt = 0;
static app_event_t appevent;
memset(&appevent, 0, sizeof(appevent));
if (SingleLeadECG_ecg_plod_get_connected_state()) {
connecte_state_trigger_cnt++;
m_connecte_state_last_trigger_timepoint = znordic_getpower_on_ms();
} else {
connecte_state_trigger_cnt = 0;
}
if (!m_plod_state_connected_state && connecte_state_trigger_cnt >= 10) {
//
appevent.eventType = kplod_connected_event;
m_plod_state_connected_state = true;
AppEvent_pushEvent(&appevent);
} else if (m_plod_state_connected_state && connecte_state_trigger_cnt == 0) {
//
appevent.eventType = kplod_disconnected_event;
m_plod_state_connected_state = false;
AppEvent_pushEvent(&appevent);
}
// else if (connecte_state_trigger_cnt >= 10 && connecte_state_trigger_cnt % 10 == 0) {
// //
// appevent.eventType = kplod_connecting_event;
// appevent.val.plod_connected_accumulation_time = connecte_state_trigger_cnt / 10;
// AppEvent_pushEvent(&appevent);
// }
}
static void m_charge_event_detect_tmr_cb(void* p_context) { //
static app_event_t appevent;
memset(&appevent, 0, sizeof(appevent));
static bool ischarging = false;
// if (!SingleLeadECG_battery_charge_get_state()) {
// if (!ischarging) {
// appevent.eventType = kbattery_start_charge_event;
// ischarging = true;
// AppEvent_pushEvent(&appevent);
// } else {
// appevent.eventType = kbattery_charging_event;
// AppEvent_pushEvent(&appevent);
// }
// } else {
// if (ischarging) {
// ischarging = false;
// appevent.eventType = kbattery_end_charge_event;
// AppEvent_pushEvent(&appevent);
// }
// }
}
// static void m_charge_event_detect_tmr_cb(void* p_context) { //
// static app_event_t appevent;
// memset(&appevent, 0, sizeof(appevent));
// static bool ischarging = false;
// }
static void state_machine_driver_tmr_cb(void* p_context) { //
static app_event_t appevent;
appevent.eventType = kevent_tmr_scheduler_event;
AppEvent_pushEvent(&appevent);
}
/*******************************************************************************
* *
*******************************************************************************/
@ -112,35 +58,31 @@ static void power_on() {
if (m_poweronflag) {
return;
}
SingleLeadECG_adc_module_init();
hwss_init();
BoardBeepCtrl_load();
BoardEcgSensor_load();
BoardBattery_load();
SingleLeadECG_led_init();
SingleLeadECG_ecg_init();
SingleLeadECG_battery_init();
hwss_init();
sample_data_mgr_init();
dsp_mgr_init();
ble_cmder_init();
ble_cmder_start_adv();
// SingleLeadECG_beep_trigger_once();
m_poweronflag = true;
ZERROR_CHECK(app_timer_start(m_state_machine_driver_tmr, APP_TIMER_TICKS(100), NULL)); // 200HZ采样
}
static void power_off() {
dsp_mgr_uninit();
sample_data_mgr_uninit();
hwss_uninit();
SingleLeadECG_battery_deinit();
SingleLeadECG_ecg_deinit();
BoardEcgSensor_unload();
BoardBattery_unload();
SingleLeadECG_led_deinit();
BoardBeepCtrl_unload();
SingleLeadECG_adc_module_deinit();
ble_cmder_stop_adv();
ble_cmder_uninit();
ZERROR_CHECK(app_timer_stop(m_state_machine_driver_tmr));
m_poweronflag = false;
}
/*******************************************************************************
@ -188,42 +130,56 @@ static void state_machine__change_to_home_state() {
ds_change_to_state(kdevice_state_home);
dsp_mgr_change_to_main();
}
void ENTER_DEEP_SLEEP() {
// 使
BoardEcgSensor_set_sence_state();
BoardBattery_sence_gpio_init_before_sleep();
// nrf_sdh_disable_request();
app_timer_stop_all();
nrf_sdh_disable_request();
sd_power_system_off();
NVIC_SystemReset();
}
static void app_event_listener(void* p_event_data, uint16_t event_size) {
if (!p_event_data) return;
app_event_t* p_event = (app_event_t*)p_event_data;
if (zdatachannel_is_connected()) {
SingleLeadECG_led_blue_set_state(true);
} else {
SingleLeadECG_led_blue_set_state(false);
}
// if (zdatachannel_is_connected()) {
// SingleLeadECG_led_blue_set_state(true);
// } else {
// SingleLeadECG_led_blue_set_state(false);
// }
/*******************************************************************************
* *
*******************************************************************************/
if (ds_now_state() == kdevice_state_standby) {
/**
* @brief
* -->
* -->
*
*/
// if (!SingleLeadECG_battery_charge_get_state()) {
// state_machine__change_to_charging_state();
// }
if (p_event->eventType == kplod_connected_event) {
ZLOGI("standby......");
// -->
if (BoardBattery_get_charging_state()) {
state_machine__change_to_charging_state();
}
// -->
else if (BoardEcgSensor_plod_get_connected_state()) {
state_machine__change_to_poweroning_state();
}
// 10RTC未被设置过
else if (ds_cur_state_haspassed_ms() >= 10000) {
if (!znordic_rtc_has_setted()) {
// ENTER_DEEP_SLEEP();
}
}
}
/*******************************************************************************
* *
*******************************************************************************/
else if (ds_now_state() == kdevice_state_charging) {
if (!SingleLeadECG_battery_charge_get_state()) {
if (!BoardBattery_get_charging_state()) {
state_machine__change_to_standby_state();
}
}
@ -244,26 +200,26 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) {
else if (ds_now_state() == kdevice_state_home) {
//
if (!zdatachannel_is_connected() && //
!plod_state_is_connected() && //
plod_state_has_disconnected_ms() >= 3000 && //
if (!zdatachannel_is_connected() && //
!BoardEcgSensor_plod_get_connected_state_after_filter() && //
BoardEcgSensor_plod_state_has_disconnected_ms() >= 3000 && //
ds_cur_state_haspassed_ms() >= AUTOMATIC_SLEEP_TIME) {
state_machine__change_to_standby_state();
}
//
else if (plod_state_is_connected() && ds_cur_state_haspassed_ms() > 1500) {
else if (BoardEcgSensor_plod_get_connected_state_after_filter() && ds_cur_state_haspassed_ms() > 1500) {
// dsp_mgr_change_to_preparePage
ds_change_to_state(kdevice_state_keep_still);
dsp_mgr_change_to_preparePage();
}
// ZLOGI("bt:%d plod:%d has_disc:%d state:%d", zdatachannel_is_connected(), plod_state_is_connected(), plod_state_has_disconnected_ms(), ds_cur_state_haspassed_ms());
// ZLOGI("bt:%d plod:%d has_disc:%d state:%d", zdatachannel_is_connected(), BoardEcgSensor_plod_get_connected_state_after_filter(), plod_state_has_disconnected_ms(), ds_cur_state_haspassed_ms());
}
/*******************************************************************************
* *
*******************************************************************************/
else if (ds_now_state() == kdevice_state_keep_still) {
if (!plod_state_is_connected()) {
if (!BoardEcgSensor_plod_get_connected_state_after_filter()) {
//
state_machine__change_to_home_state();
} else {
@ -403,7 +359,8 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) {
* *
*******************************************************************************/
else if (ds_now_state() == kdevice_state_sampling_error) {
if ((ds_cur_state_haspassed_ms() >= 3000) || (ds_cur_state_haspassed_ms() >= 1000 && m_plod_state_connected_state)) {
if ((ds_cur_state_haspassed_ms() >= 3000) || //
(ds_cur_state_haspassed_ms() >= 1000 && BoardEcgSensor_plod_get_connected_state_after_filter())) {
ZLOGI("ds_cur_state_haspassed_ms() %d> 3000", ds_cur_state_haspassed_ms());
state_machine__change_to_home_state();
ble_cmder_report_sample_finish_event();
@ -416,17 +373,14 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) {
void one_conduction_main() {
BoardBeepCtrl_init();
SingleLeadECG_ecg_io_init();
SingleLeadECG_battery_charge_detect_io_init();
AppEvent_regListener(app_event_listener);
ZERROR_CHECK(app_timer_create(&m_state_machine_driver_tmr, APP_TIMER_MODE_REPEATED, state_machine_driver_tmr_cb));
ZERROR_CHECK(app_timer_create(&m_plod_state_event_detect_tmr, APP_TIMER_MODE_REPEATED, m_plod_state_event_detect_tmr_cb));
ZERROR_CHECK(app_timer_create(&m_charge_event_detect_tmr, APP_TIMER_MODE_REPEATED, m_charge_event_detect_tmr_cb));
BoardBattery_init();
BoardEcgSensor_init();
ZERROR_CHECK(app_timer_start(m_plod_state_event_detect_tmr, APP_TIMER_TICKS(30), NULL));
ZERROR_CHECK(app_timer_start(m_charge_event_detect_tmr, APP_TIMER_TICKS(100), NULL));
ZERROR_CHECK(app_timer_create(&m_state_machine_driver_tmr, APP_TIMER_MODE_REPEATED, state_machine_driver_tmr_cb));
ZERROR_CHECK(app_timer_start(m_state_machine_driver_tmr, APP_TIMER_TICKS(300), NULL));
state_machine__change_to_poweroning_state();
state_machine__change_to_standby_state();
znordic_loop();
}

2
libznordic

@ -1 +1 @@
Subproject commit 2e93f83bd44b54f4b6bec2d338d674e7a884bd42
Subproject commit 52d18110e10b67278d7eafad5a88cb01a7395137
Loading…
Cancel
Save