Compare commits

..

146 Commits

Author SHA1 Message Date
Roy 0865580637 pending: update spi code 2023-05-16 18:11:53 +08:00
LuoYiTing 5f6b3ba7e5 Doc: update README.md - install IDE
process
2023-04-27 02:17:29 +00:00
LuoYiTing 84f2016346 Doc: update README.md - install IDE
process
2023-04-25 07:41:29 +00:00
LuoYiTing 4597e042fe Doc: update README.md - install IDE
process
2023-04-24 07:35:35 +00:00
Roy bd7c6e7567 [cali] add BOARD_38/39/40 calibration data. 2023-04-18 11:46:38 +08:00
Roy faca2637d0 [cali] update BOARD_37 calibration data. 2023-04-10 14:04:54 +08:00
Roy 4bb99ccfc9 [cali] update BOARD_36 calibration data. 2023-04-10 14:01:28 +08:00
Roy 7e16710cdd [cali] update BOARD_35 calibration data. 2023-04-07 11:31:26 +08:00
Roy 8e10e98e79 [cali] update BOARD_34 calibration data. 2023-04-07 11:29:03 +08:00
ROY 9493fd9a1b [cali] update BOARD_34 calibration data. 2023-03-31 12:08:29 +08:00
ROY 98ae27edf4 [cali] update BOARD_36 calibration data. 2023-03-30 16:12:21 +08:00
ROY f5213ffe60 [cali] update BOARD_37 calibration data. 2023-03-29 14:19:05 +08:00
ROY 6e8e974e04 [cali] update BOARD_36 calibration data. 2023-03-25 13:51:08 +08:00
ROY d7c2bc3fbb [cali] add BOARD_37 calibration data. 2023-03-24 17:37:50 +08:00
ROY d18bc134b8 [cali] add BOARD_36 calibration data. 2023-03-24 10:30:26 +08:00
ROY f58407f238 [cali] update BOARD_35 calibration data. 2023-03-24 10:26:46 +08:00
ROY b9f169d8f7 [cali] update BOARD_34 calibration data. 2023-03-24 10:23:05 +08:00
ROY c5aa04e8e2 [cali] update BOARD_C7_05 calibration data. 2023-03-21 10:36:57 +08:00
ROY 550c424d32 [cali] update BOARD_F0_10 calibration data. 2023-03-21 10:33:52 +08:00
ROY 1bb045ae27 [cali] update BOARD_27 calibration data.(Vmon) 2023-03-14 16:20:36 +08:00
ROY aced7380a9 [cali] update BOARD_ED_5A & BOARD_21 & BOARD_25 & BOARD_28 & BOARD_32 calibration data.(Vmon) 2023-03-14 14:49:45 +08:00
ROY b9685340b3 [cali] update BOARD_15 & BOARD_17 & BOARD_24 & BOARD_31 calibration data.(Vmon) 2023-03-14 13:21:24 +08:00
ROY 0c690e9503 [update] update notify buff 2023-03-07 17:41:17 +08:00
ROY 52c4cba192 [cali] add BOARD_34 & BOARD_35 calibration data. 2023-03-07 16:36:28 +08:00
ROY 0dd9a20114 [update] notify Voutin data 2023-03-07 13:42:36 +08:00
ROY 4d6bd34faa [cali] update BOARD_EF_50 calibration data. 2023-03-07 10:20:00 +08:00
ROY e7ca6205d1 [cali] update BOARD_EF_30 calibration data. 2023-03-06 16:16:26 +08:00
ROY fcd6f9bd3f [cali] update BOARD_EF_50 calibration data. 2023-03-06 16:14:12 +08:00
ROY 6df8353ca7 [update] fix cp_devis & first vout - 5mV on cp mode 2023-02-24 12:38:14 +08:00
ROY 5f7cac01d3 [cali] update BOARD_14 & Voutin (Vopen) calibration data. 2023-02-24 12:36:40 +08:00
ROY 8c8cd6b55a [cali] update BOARD_14 Voutin calibration data. 2023-02-24 10:01:10 +08:00
ROY 8622ed2057 [cali] update BOARD_E7_74 Voutin calibration data. 2023-02-24 08:54:12 +08:00
ROY bb535e2c64 [update] improve speed of changing volt on cp mode 2023-02-23 15:52:35 +08:00
ROY a04cec2dad [cali] update BOARD_EE_EF calibration data. 2023-02-23 15:48:07 +08:00
ROY d62c2814ea [cali] update BOARD_33 calibration data. 2023-01-04 12:04:44 +08:00
ROY 55866be4ed [cali] add BOARD_32 calibration data. 2022-12-22 09:22:21 +08:00
ROY 2e615c7e74 [cali] add BOARD_31 calibration data. 2022-12-20 18:21:36 +08:00
ROY a17bd344af [cali] add BOARD_30 calibration data. 2022-12-20 18:12:40 +08:00
ROY 0667c9397f [cali] add BOARD_29 calibration data. 2022-12-20 18:09:54 +08:00
ROY 40ad3b62fb [update] stop condition on CC mode 2022-12-02 17:28:16 +08:00
ROY 8cddab21ab [update] revert to v1.18.0 2022-12-02 15:37:44 +08:00
ROY b09afc4699 debug cp 2022-09-21 11:24:37 +08:00
ROY ea9cc17494 [update] don't print 200ms of leading time 2022-09-19 17:07:13 +08:00
ROY 8be6e779fa [update] cp mode finished and update version 2022-09-16 10:57:02 +08:00
ROY aa864aad9a Merge branch 'dev/edc1.5re/cp_mode' into elite/edc1.5re 2022-09-16 10:55:34 +08:00
ROY a97f5a0fb1 [update] fix cp mode 2022-09-16 10:55:15 +08:00
ROY f8520cdcfd [cali] add BOARD_28 calibration data. 2022-09-13 18:20:42 +08:00
ROY 276b793687 [cali] add BOARD_27 calibration data. 2022-09-13 18:17:17 +08:00
ROY 45fc016bd5 [cali] add BOARD_26 calibration data. 2022-09-13 18:14:41 +08:00
ROY 78177025de [cali] add BOARD_25 calibration data. 2022-09-13 18:11:57 +08:00
ROY c1cd6260b7 [cali] add BOARD_24 calibration data. 2022-09-13 18:08:32 +08:00
ROY 9e1a734c3d [cali] add BOARD_23 calibration data. 2022-09-13 18:00:29 +08:00
ROY 2ba852f6d5 [cali] add BOARD_22 calibration data. 2022-09-13 17:56:54 +08:00
ROY 5495362f46 [update] ok 2022-09-13 16:23:31 +08:00
ROY e75a837994 [update] cp_mode v2 ok 2022-09-13 15:45:19 +08:00
ROY 4480b34948 [update] cp_mode v1 ok 2022-09-13 15:29:01 +08:00
ROY 5ac63bbce4 not ok 2022-09-12 16:35:39 +08:00
ROY f15971c28a [update] disconnect timeout is yellow green LED 2022-08-30 09:42:15 +08:00
ROY f6f0e47ee7 Merge remote-tracking branch 'origin/dev/edc1.5re_battery' into elite/edc1.5re 2022-08-30 09:31:39 +08:00
sss28072637 099d1ec72e [update] battery calibration 2022-08-30 09:25:13 +08:00
JayC319 fbb98c3c24 [update] fix cali_DAC mode 2022-08-22 13:46:17 +08:00
ROY c8c101ae98 [update] fix CC mode and CP mode 2022-08-18 18:50:19 +08:00
JayC319 ad1ed81f00 [update] cali mode stop issue fixed 2022-08-17 10:09:02 +08:00
ROY 69416bc58e [update] merge cali mode branch 2022-08-16 11:37:04 +08:00
ROY 9c29ad0a86 [update] new dev tool function: LED 2022-08-11 15:58:46 +08:00
ROY 6b421d73e9 [update] fix start voltage on cc/cp mode 2022-08-11 11:14:12 +08:00
ROY 34107872ec [update] rel/elite/edc1.5/v1.15.0 2022-08-10 17:16:50 +08:00
ROY f6719c3182 [update] update model name 2022-08-05 16:28:28 +08:00
ROY 79188d76b9 [update] new cp mode (cc cp separate) 2022-08-04 18:14:43 +08:00
ROY 3e5c9b9b73 [update] clean up the code 2022-08-03 17:06:08 +08:00
ROY f1fa366b8f [update] clean up the code 2022-08-03 16:22:08 +08:00
ROY 16814ad816 [cali] add BOARD_20 calibration data. 2022-08-02 16:32:08 +08:00
ROY 92ae63b7f9 [cali] add BOARD_19 calibration data. 2022-08-02 16:29:45 +08:00
ROY 1f3e7a5efe [cali] add BOARD_21 calibration data. 2022-08-02 16:03:08 +08:00
ROY c573135e98 [update] VIN_GAIN_MID1_BOUNDARY2 = 290mV 2022-08-02 11:33:04 +08:00
ROY 5d4c5b5a86 Merge branch 'dev/elite1.5re/fix_auto_gain' into elite/edc1.5re 2022-08-01 18:12:59 +08:00
ROY caf6985e66 [update] fix auto gain 2022-08-01 18:12:25 +08:00
ROY a7a1f7f2b5 [update] fix gain 2022-07-29 13:09:24 +08:00
ROY 45182935b7 [update] remove CC_ZERO mode and fix gain 2022-07-29 11:31:26 +08:00
ROY 6958c410a1 [update] move device info 2022-07-29 09:38:29 +08:00
ROY a337434903 [update] delete unused file 2022-07-28 17:55:40 +08:00
ROY 14c897c26e [update] delete unused file 2022-07-28 17:54:32 +08:00
ROY 02a6018cac [update] delete Elite.json 2022-07-28 17:53:40 +08:00
ROY 544b571f85 [note] fix mode enum 2022-07-28 17:52:41 +08:00
ROY 939de9098a [update] fix step time on IV & Cycle-IV mode 2022-07-28 16:32:55 +08:00
ROY 7441d9a5c8 [cali] add BOARD_18 calibration data. 2022-07-28 11:48:03 +08:00
ROY a680f59277 [cali] add BOARD_17 calibration data. 2022-07-28 11:45:24 +08:00
ROY b595215326 [update] limit volt = 100mV on cc mode 2022-07-28 10:57:38 +08:00
ROY 901108ea90 [update] fix main loop 2022-07-28 10:09:04 +08:00
ROY 16dc76833a [update] update device info 2022-07-27 10:16:15 +08:00
JayC319 e6993f5a4a [update] minor changes and instruction added 2022-07-22 14:39:04 +08:00
ROY a2b5a5728b [update] update adc function 2022-07-22 14:09:24 +08:00
JayC319 4d76e4585e [update] variable name changed 2022-07-22 13:14:03 +08:00
JayC319 43e72567c0 [update] ADC modulized small fix 2022-07-22 13:04:03 +08:00
ROY 311f0d1238 Merge branch 'dev/eliteedc1.5re/merge_latch_adc_dac' into elite/edc1.5re 2022-07-22 10:19:17 +08:00
ROY 7177e8549b [update] merge latch & adc & dac code 2022-07-22 10:19:01 +08:00
ROY 7106f59122 Merge branch 'dev/roy/latch' into test 2022-07-22 09:59:16 +08:00
ROY 2c203b73a1 [update] update latch process 2022-07-22 09:57:01 +08:00
JayC319 ba7552e091 [update] "latest version" 2022-07-22 09:48:14 +08:00
JayC319 4b65c8666e Merge branch 'dev/ADC_modulize' of https://gitlab.com/wisetop/microchip/application/cc2650/wtp_cc2650_development into dev/ADC_modulize 2022-07-22 09:44:09 +08:00
JayC319 5dc35425d5 [update] ADC modulized done and ADC rx buffer revised 2022-07-22 09:41:39 +08:00
JayC319 790db4bcf4 [update] DAC modulized finished and DAC rx buffer revised 2022-07-22 09:26:12 +08:00
ROY d9cc6f2ba6 [update] update latch process 2022-07-21 17:34:17 +08:00
ROY 5e04fcb7e2 [update] update latch process 2022-07-21 17:29:31 +08:00
ROY dc5cabf2ae [update] update latch process 2022-07-21 15:20:50 +08:00
ROY 7cf60e2717 [update] update latch process 2022-07-21 14:12:41 +08:00
JayC319 f1ab4be88a [update] adc modulized first version done and dac modulize revision 2022-07-19 17:47:04 +08:00
JayC319 3509b6df00 Merge branch 'dev/1.5re/DAC_modulize' into dev/elite/edc1.5re/merge_dac_and_cc_mode 2022-07-18 18:57:48 +08:00
JayC319 26b37b759f Merge branch 'dev/1.5re/DAC_modulize' into dev/elite/edc1.5re/merge_dac_and_cc_mode 2022-07-18 18:57:03 +08:00
JayC319 6321fdca51 [update] DAC_modulized function ok 2022-07-18 18:20:01 +08:00
ROY c496ccb791 [update] fix charge/discharge problem on cc mode 2022-07-15 21:48:13 +08:00
JayC319 c8aeabdfeb [update] DAC_modulized function ok 2022-07-14 18:11:22 +08:00
JayC319 9bfc251029 [update] DAC_modulized 2022-07-14 17:09:25 +08:00
JayC319 0273a9571b [update] nono 2022-07-13 19:05:06 +08:00
JayC319 5318a89132 [update] button and LED modulizing finished 2022-07-12 15:45:02 +08:00
JayC319 a4f653951e [update] finished button modulized 2022-07-12 10:46:18 +08:00
JayC319 925447817f [update] check comiler 2022-07-11 14:34:28 +08:00
JayC319 b64a3d031f [update] boardselect changed, Elite_PIN.h delete 2022-07-08 14:06:04 +08:00
JayC319 6fc7b2591f [update] gpio modulize 2022-07-07 17:58:16 +08:00
JayC319 00cc58e720 [update]modulize_LED 2022-07-06 18:06:18 +08:00
ROY fcc1477acd [cali] add BOARD_16 calibration data. 2022-07-04 17:59:09 +08:00
ROY 545fc8323c [update] remove old pulse mode 2022-07-04 10:50:02 +08:00
ROY 4c654982d2 [cali] add BOARD_15 calibration data. 2022-07-04 10:25:05 +08:00
ROY d7a4e02349 [cali] add BOARD_14 calibration data. 2022-07-04 10:22:00 +08:00
ROY ee1d052c3a [cali] add BOARD_13 calibration data. 2022-06-22 15:36:50 +08:00
ROY 7acafa81b8 [cali] add BOARD_12 calibration data. 2022-06-22 15:33:59 +08:00
ROY e97d556dd9 [cali] update BOARD_7 calibration data. 2022-06-10 18:19:46 +08:00
ROY c227d21546 [update] use red led when BT timeout 2022-06-01 10:57:35 +08:00
ROY f9e33d0ede [cali] add BOARD_11 calibration data. 2022-05-31 16:13:51 +08:00
ROY a9fd1028d1 [cali] add BOARD_8 calibration data. 2022-05-31 16:08:18 +08:00
ROY f6a20eaea5 [cali] update BOARD_2 calibration data. 2022-05-31 13:26:34 +08:00
ROY f904bbd522 [cali] update BOARD_7 calibration data. 2022-05-31 13:23:55 +08:00
ROY 6f3a1b57ae [cali] add BOARD_7 calibration data. 2022-05-26 17:31:39 +08:00
ROY b795b7eb6b [cali] update BOARD_8 & BOARD_9 & BOARD_10 calibration data. 2022-05-26 17:22:37 +08:00
ROY a1adf82f2b [update] cc & cp corrected speed 1/10/100 2022-05-23 11:00:46 +08:00
Roy 061064c27a [update] don't use GPT_MODE_PERIODIC_DOWN 2022-05-18 15:17:38 +08:00
Roy 2d1556686c [cali] update BOARD_1 calibration data. 2022-05-04 10:40:13 +08:00
Roy 0d7f334499 [cali] update BOARD_4 calibration data. 2022-05-04 10:38:25 +08:00
Roy b849231be3 [update] fix manual current stalls 2022-04-29 18:37:39 +08:00
Roy 060dde64a8 [cali] update BOARD_5 calibration data. 2022-04-29 16:48:21 +08:00
Roy 6be73528d4 [cali] update BOARD_1 calibration data. 2022-04-29 10:12:16 +08:00
Roy 7b4436920f [cali] update BOARD_2 calibration data. 2022-04-28 18:18:26 +08:00
Roy b34e947cc8 [update] fix power off led 2022-04-28 10:15:20 +08:00
Roy 8c4737e494 [cali] add BOARD_6 calibration data. 2022-04-27 16:57:55 +08:00
Roy 6f36e781b7 [cali] add BOARD_5 calibration data. 2022-04-27 16:55:25 +08:00
Roy 8403c16fa0 [update] fix highz problem 2022-04-27 13:18:24 +08:00
38 changed files with 11812 additions and 537 deletions
+235 -104
View File
@@ -1,185 +1,316 @@
# WTP_cc2650_development
## Device
## Source code path
### Device major source code path
1. Device major source code path
- main code
`E:\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\main.c`
`E:\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\simple_peripheral.c`
`E:\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\headstage\headstage.h`
- gpio table
- main code
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\boards\BOOSTXL_CC2650MA\BOOSTXL_CC2650MA.h`
`E:\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\main.c`
`E:\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\simple_peripheral.c`
`E:\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\headstage\headstage.h`
- gpio table
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\boards\CC2650_LAUNCHXL\CC2650_LAUNCHXL.h`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\boards\BOOSTXL_CC2650MA\BOOSTXL_CC2650MA.h`
- GATT
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\profiles\simple_profile\simple_gatt_profile.h`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\boards\CC2650_LAUNCHXL\CC2650_LAUNCHXL.h`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\profiles\simple_profile\cc26xx\simple_gatt_profile.c`
- GATT
### Memory board major source code path:
- cc2650 host_test
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\profiles\simple_profile\simple_gatt_profile.h`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\profiles\simple_profile\cc26xx\simple_gatt_profile.c`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\host_test\cc26xx\app\host_test_app.c`
2. Memory board major source code path
- cc2650 host_test
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\host_test\cc26xx\app\main.c`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\host_test\cc26xx\app\host_test_app.c`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\host_test\cc26xx\app\main.c`
- cc2650 central
- cc2650 central
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_central\cc26xx\app\main.c`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_central\cc26xx\app\main.c`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_central\cc26xx\app\simple_central.c`
`E:\WT_project_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_central\cc26xx\app\simple_central.c`
* * *
## How to install this project in your PC
### Prerequisite:
- Prerequisite:
anti-virus software might cause some problems, disable it while installing is recommended.
anti-virus software might cause some problems, disable it while installing is recommended.
### Install CCStudio
- Install CCStudio
1. [code composer studio](https://www.ti.com/tool/CCSTUDIO) :
1. [code composer studio](https://www.ti.com/tool/CCSTUDIO) :
choose the latest version (we use Version: 11.1.0.00011 Release date: 20 Dec 2021, Windows single file installer for CCS IDE) of Code Composer Studio.
2. unzip it
2. unzip it
3. open the folder **CCS11.1.0.00011_win64** -> Open sub-folder **CCS11.1.0.00011_win64**
3. open the folder **CCS11.1.0.00011_win64** -> Open sub-folder **CCS11.1.0.00011_win64**
4. run installer **ccs_setup_11.1.0.00011.exe**
4. run installer **ccs_setup_11.1.0.00011.exe**
5. accept the license
5. accept the license
6. install at folder `C:\ti\ccs1110`
6. install at folder `C:\ti\ccs1110`
7. select installation type: Custom installation
7. select installation type: Custom installation
8. select Components: SimpleLink CC13xx and CC26xx Wireless MCUs
8. select Components: SimpleLink CC13xx and CC26xx Wireless MCUs
9. select all Debug Probes
9. select all Debug Probes
10. finish. Wait for the install process......
10. finish. Wait for the install process......
11. select options to create desktop shortcut and launch CCStudio
11. select options to create desktop shortcut and launch CCStudio
12. at the first launch, CCStudio will ask you to select a directory as workspace. use directory `C:\Users\kimwu\workspace_ti` -> Launch
12. at the first launch, CCStudio will ask you to select a directory as workspace. use directory `C:\Users\kimwu\workspace_ti` -> Launch
### install BLE STACK
- Install BLE STACK
1. [BLE STACK](https://www.ti.com/tool/BLE-STACK-ARCHIVE):
1. [BLE STACK](https://www.ti.com/tool/BLE-STACK-ARCHIVE):
choose **BLE-STACK-2-2-2 — BLE-STACK V2.2.2 (Support for CC2640/CC2650)** Free version.
(a TI account is required)
2. run **ble_sdk_2_02_02_25_setup.exe**
2. run **ble_sdk_2_02_02_25_setup.exe**
3. accept the license agreement
3. accept the license agreement
4. install **the BLE-Stack SDK** at the directory `C:\ti\simplelink` -> wait for the install process......
4. install **the BLE-Stack SDK** at the directory `C:\ti\simplelink` -> wait for the install process......
5. **Setup - TI-RTOS for CC13xx and CC26xx Wireless MCUs 2.21.01.08** will jump out -> use installation directory `C:\ti` -> next
5. **Setup - TI-RTOS for CC13xx and CC26xx Wireless MCUs 2.21.01.08** will jump out -> use installation directory `C:\ti` -> next
at the same time, **ble_sdk_2_02_02_25_setup.exe** will still be running, don't close the window
<font color='red'> !!! </font> at the same time, **ble_sdk_2_02_02_25_setup.exe** will still be running, don't close the window
6. wait for the install process......
6. wait for the install process......
7. finish
7. finish
### First run CCStudio and setting
- First run CCStudio and setting
1. start CCStudio, Use the default.`C:\Users\kimwu\workspace_ti` -> Launch
1. start CCStudio, Use the default. `C:\Users\kimwu\workspace_ti`
2. Project -> Import CCS Projects -> Select search-directory `C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral` -> OK -> select all discovered projects -> finish
-> Launch
4. right click `simple_peripheral_cc2650em_app` -> Properties -> General -> Products -> double click **com.ti.rtsc.TIRTOSCC13XX_CC26XX [2.21.1.08]** -> Preferences -> refresh -> select ```"C:\ti\tirtos_cc13xx_cc26xx_2_21_01_08"``` and ```"C:\ti\xdctools_3_32_00_06_core"``` -> Install -> restart CCS
5. right click `simple_peripheral_cc2650em_app` -> Properties -> General -> Project: Compiler version -> Tool-chain: **Compiler version: TI v20.2.5LTS** -> apply amd close
2. Project
6. right click `simple_peripheral_cc2650em_stack` -> Properties -> General -> Project: Compiler version -> Tool-chain: **Compiler version: TI v20.2.5LTS** -> apply amd close
-> Import CCS Projects
7. click `simple_peripheral_cc2650em_app`, Click *build* and it's done
8. click `simple_peripheral_cc2650em_stack` Click *build* and it has error: "C:/ti/simplelink/ble_sdk_2_02_02_25/src/components/osal/src/common/osal.c", line 408: error #167: too few arguments in function call
modify code: osal.c line:408
return ( (unsigned char*)ltoa( l, (char *)buf) ); -> return ( (unsigned char*)ltoa( l, (char *)buf, radix) );
and then, click *build* and it's done
-> Select search-directory `C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral`
-> OK
-> select all discovered projects
-> finish
### clone this project
#### with Command line interface (git-bash)
1. clone our project to E:\MCU_code\.
3. right click `simple_peripheral_cc2650em_app`
`git clone [WTP_cc2650_development URL]`, where URL is our project url on gitlab.
2. copy `E:\MCU_code\wtp_cc2650_development\backup\examples` to `E:\MCU_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25`
-> Properties
-> General
-> Products
-> double click **com.ti.rtsc.TIRTOSCC13XX_CC26XX [2.21.1.08]**
-> Preferences
-> refresh
-> select `"C:\ti\tirtos_cc13xx_cc26xx_2_21_01_08"` and `"C:\ti\xdctools_3_32_00_06_core"`
-> Install
-> restart CCS
terminal:
$cd /e/MCU_code/wtp_cc2650_development
$cp -r ./backup/examples ./simplelink/ble_sdk_2_02_02_25/
4. right click `simple_peripheral_cc2650em_app`
-> Properties
-> General
-> Project
-> Tool-chain: **Compiler version: TI v20.2.5LTS**
Device: **Connection: Texas Instrument XDS110 USB Debug Probe[Default]**
-> apply amd close
5. click `simple_peripheral_cc2650em_app`, Click *build* and it's done
6. right click `simple_peripheral_cc2650em_stack`
-> Properties
-> General
-> Project: Compiler version
-> Tool-chain: **Compiler version: TI v20.2.5LTS**
Device: **Connection: Texas Instrument XDS110 USB Debug Probe[Default]**
-> apply amd close
### select project at CCS
1. start CCStudio, Use the directory.`C:\Users\kimwu\workspace_ti_wtp_cc2650_development` -> Launch
2. Project -> Import CCS Projects -> Select search-directory `E:\MCU_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral` -> OK
3. select all discovered projects -> finish
4. right click `simple_peripheral_cc2650em_app` -> Properties -> Build-> Arm Compiler -> Include Options
-> change `"D:\MCU_code\wtp_cc2650_simple_func\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\headstage"`
to `"E:\MCU_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\headstage"`
-> Apply and Close
7. click `simple_peripheral_cc2650em_stack` Click *build* and it has error: "C:/ti/simplelink/ble_sdk_2_02_02_25/src/components/osal/src/common/osal.c", line 408: error #167: too few arguments in function call
8. modify code: osal.c line:408
```c
return ( (unsigned char*)ltoa( l, (char *)buf) );
```
change to
```c
return ( (unsigned char*)ltoa( l, (char *)buf, radix) );
```
9. and then, click *build* and it's done
- Clone this project(with Command line interface `git-bash`)
1. clone our project to E:\MCU_code\.
`git clone [WTP_cc2650_development URL]`, where URL is our project url on gitlab.
2. copy `E:\MCU_code\wtp_cc2650_development\backup\examples` to `E:\MCU_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25`
```linux
terminal:
$cd /e/MCU_code/wtp_cc2650_development
$cp -r ./backup/examples ./simplelink/ble_sdk_2_02_02_25/
```
- select project at CCS
1. start CCStudio, Use the directory.
`C:\Users\kimwu\workspace_ti_wtp_cc2650_development`
-> Launch
2. 先設置 device compiler 環境
- switch branch to elite/edc1.5re
```linux
terminal:
$git checkout elite/edc1.5re
```
- Project
-> Import CCS Projects
-> Select search-directory `E:\MCU_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral`
-> OK
- select all discovered projects
-> finish
- right click `simple_peripheral_cc2650em_app`
-> Properties
-> Build-> Arm Compiler
-> Include Options
-> change `"D:\MCU_code\wtp_cc2650_simple_func\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\headstage"`
to `"${SRC_EX}/examples/simple_peripheral/cc26xx/app/headstage"`
-> Apply and Close
- and then, click *build* and it's done
3. 再設置 memory board compiler 環境
- switch branch to rel/mb/central/v1.7.0
```linux
terminal:
$git checkout rel/mb/central/v1.7.0
```
- Project -> Import CCS Projects
-> Select search-directory `E:\MCU_code\wtp_cc2650_development\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_central`
-> OK
- select all discovered projects
-> finish
- right click `simple_central_cc2650em_app`
-> Properties
-> Build
-> Arm Compiler
-> Advanced Options
-> Predefined Symbols
-> add "MODA_MEMORY_BOARD" 、 "BOOSTXL_CC2650MA"
-> remove "CC2650DK_7ID"
-> Apply and Close
- and then, click *build* and it's done
* * *
### Optional
#### install git if you don't install it
- install git if you don't install it
- https://git-scm.com/download/win
- https://git-scm.com/download/win
- choose corresponding version for your computer from 'Git for Windows Setup'
- choose corresponding version for your computer from 'Git for Windows Setup'
#### doxygen: tool to help documenting code
- doxygen: tool to help documenting code
- download from main page http://www.doxygen.nl/download.html
- download from main page http://www.doxygen.nl/download.html
- according to different OS, download corresponding version.
- according to different OS, download corresponding version.
- press keyboard 'ctrl' + 'shift' + 'a' to search external tool, select 'external tools-setting'
- press keyboard 'ctrl' + 'shift' + 'a' to search external tool, select 'external tools-setting'
- add external tool by pressing '+'
- add external tool by pressing '+'
- name this external tool in the column 'name'
- name this external tool in the column 'name'
- set the path of doxygen execute file in the column 'program'
- set the path of doxygen execute file in the column 'program'
- set the repository we want to generate document automatically in the column 'working directory'
- set the repository we want to generate document automatically in the column 'working directory'
- set hotkey of doxygen to run : 'File' -> 'Setting' -> 'Keymap' -> 'external tools'
- set hotkey of doxygen to run : 'File' -> 'Setting' -> 'Keymap' -> 'external tools'
- press the hotkey to run doxygen
- press the hotkey to run doxygen
### Troubleshooting
- Troubleshooting
- jump a dialog with **MSVC components failed to install.
Please install executables manually from c:/ti/ccsv8/installers before using CCS**
- jump a dialog with **MSVC components failed to install.
Please install executables manually from c:/ti/ccsv8/installers before using CCS**
ignore it.
ignore it.
- jumps a warning dialog of Windows Defender
- jumps a warning dialog of Windows Defender
Allow the network access.
@@ -50,7 +50,7 @@ extern "C" {
* ==========================================================================*/
#include <ti/drivers/PIN.h>
#include <driverlib/ioc.h>
// #include "application_config/application_config.h"
#include "boards_config/elite_boards_select.h"
/** ============================================================================
* Externs
@@ -146,6 +146,12 @@ extern const PIN_Config BoardGpioInitTable[];
#define Board_UART_TX Board_BP_UART_Rx /* RXD */
#define Board_UART_RX Board_BP_UART_Tx /* TXD */
// /* SPI Board */
// #define Board_SPI0_MISO Board_BP_SPI_MISO
// #define Board_SPI0_MOSI Board_BP_SPI_MOSI
// #define Board_SPI0_CLK Board_BP_SPI_CLK
// #define Board_SPI0_CS Board_BP_SPI_CS_Wireless
/* Power Management Board */
#define Board_SRDY Board_BP_Pin_J2_19
#define Board_MRDY Board_BP_Pin_J1_2
@@ -160,35 +166,6 @@ extern const PIN_Config BoardGpioInitTable[];
#define Board_PWMPIN6 PIN_UNASSIGNED
#define Board_PWMPIN7 PIN_UNASSIGNED
/* SPI & I2C Board */
#ifndef DEF_ELITE_MODEL
#define Board_SPI0_MISO Board_BP_SPI_MISO
#define Board_SPI0_MOSI Board_BP_SPI_MOSI
#define Board_SPI0_CLK Board_BP_SPI_CLK
#define Board_SPI0_CS Board_BP_SPI_CS_Wireless
#define Board_SPI1_MISO PIN_UNASSIGNED
#define Board_SPI1_MOSI PIN_UNASSIGNED
#define Board_SPI1_CLK PIN_UNASSIGNED
#define Board_SPI1_CS PIN_UNASSIGNED
#define Board_I2C0_SCL0 PIN_UNASSIGNED
#define Board_I2C0_SDA0 PIN_UNASSIGNED
#else
#define Board_SPI0_MISO E_SPI0_MISO
#define Board_SPI0_MOSI E_SPI0_MOSI
#define Board_SPI0_CLK E_SPI0_CLK
#define Board_SPI0_CS E_SPI0_CS
#define Board_SPI1_MISO E_SPI1_MISO
#define Board_SPI1_MOSI E_SPI1_MOSI
#define Board_SPI1_CLK E_SPI1_CLK
#define Board_SPI1_CS E_SPI1_CS
#define Board_I2C0_SCL0 E_I2C0_SCL0
#define Board_I2C0_SDA0 E_I2C0_SDA0
#endif
/** ============================================================================
* Instance identifiers
* ==========================================================================*/
@@ -0,0 +1,141 @@
#ifndef ELITE_BOARDS_SELECT_H
#define ELITE_BOARDS_SELECT_H
#ifdef __cplusplus
extern "C" {
#endif
/*
*
* product number: MAJOR_PRODUCT_NUMBER, MINOR_PRODUCT_NUMBER, MAJOR_VERSION_NUMBER, MINOR_VERSION_NUMBER
* MAJOR_PRODUCT_NUMBER -> 0:Elite, 1:other serial
* Elite:
* MINOR_PRODUCT_NUMBER -> 1:legacy, 2:EDC, 3:BAT, 4:EIS, 5:TRIG, 6:MEGAFLY
*
* +------------------------+----------------------+-------------------------+----------------+----------------------+----------------------+----------+
* | model name | hw upper board | hw lower board | product number | device name | data server lib name | UI |
* +------------------------+----------------------+-------------------------+----------------+----------------------+----------------------+----------+
* | DEF_ELITE_EDC_14 | Elite1.4-re Jun.2019 | Elite1.4-re Jun. 2019 | 0, 2, 1, 5 | "Elite-EDC" | Elite_EDC_1.4 | null |
* | DEF_ELITE_EDC_15 | Elite1.5 Dec. 2019 | Elite1.5 Dec. 2019 | 0, 2, 1, 6 | "Elite-EDC" | Elite_EDC_1.5 | EliteEDC |
* | DEF_ELITE_EDC_15RE | Elite1.5 Dec. 2019 | Elite1.5-re Jan. 2021 | 0, 2, 1, 7 | "Elite-EDC" | Elite_EDC_1.5re | EliteEDC |
* | DEF_ELITE_EDC_15R2 | Elite1.5 Dec. 2019 | Elite1.5-r2 May. 2022 | 0, 2, 1, 8 | "Elite-EDC" | Elite_EDC_1.5r2 | EliteEDC |
* | DEF_ELITE_BAT_10 | Elite2.0 Feb. 2022 | 0, 3, 1, 0 | "Elite-BAT" | Elite_BAT_1.0 | EliteEDC |
* | DEF_ELITE_EIS_10 | Elite1.5 Dec. 2019 | Elite EIS1.0 Aug. 2020 | 0, 4, 1, 0 | "Elite-EIS" | Elite_EIS_1.0 | EliteEIS |
* | DEF_ELITE_EIS_11 | Elite1.5 Dec. 2019 | Elite EIS1.1 Feb. 2022 | 0, 4, 1, 1 | "Elite-EIS" | Elite_EIS_1.1 | EliteEIS |
* | DEF_ELITE_EIS_MINI_10 | EIS MINI May. 2022 | 0, 4, 1, 2 | "Elite-EIS-MINI" | Elite_EIS_MINI_1.0 | EliteEIS |
* | DEF_ELITE_TRIG_01 | Elite TRIG01 Jan. 2021 | 0, 5, 1, 0 | "Elite-TRIG" | Elite_TRIG_0.1 | null |
* | DEF_ELITE_MEGAFLY_01 | Elite1.5 Dec. 2019 | Elite Megafly Sep. 2020 | 0, 6, 1, 0 | "Elite-MEGAFLY" | Elite_MEGAFLY_0.1 | null |
* +------------------------+----------------------+-------------------------+----------------+----------------------+----------------------+----------+
* ps.
* model name is FW engineer defined
* device name is used for controller
*/
#define DEF_ELITE_EDC_14 0
#define DEF_ELITE_EDC_15 1
#define DEF_ELITE_EDC_15RE 2
#define DEF_ELITE_EDC_15R2 3
#define DEF_ELITE_BAT_10 4
#define DEF_ELITE_EIS_10 5
#define DEF_ELITE_EIS_11 6
#define DEF_ELITE_EIS_MINI_10 7
#define DEF_ELITE_TRIG_01 8
#define DEF_ELITE_MEGAFLY_01 9
#define DEF_ELITE_MAX 10
#define DEF_ELITE_MODEL DEF_ELITE_EDC_15RE
#ifndef DEF_ELITE_MODEL
#error "DEF_ELITE_MODEL not defined"
#endif
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_14)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15RE)
#include "boards_config/pin_def_edc15re.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15R2)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_10)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_11)
#include "boards_config/pin_def_eis11.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_BAT_10)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_MEGAFLY_01)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_TRIG_01)
#error "code no support" // need fix
#else
#error "no this model"
#endif
// model information
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_14)
#define DEVICE_NAME "Elite-EDC"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 2
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 5
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15)
#define DEVICE_NAME "Elite-EDC"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 2
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 6
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15RE)
#define DEVICE_NAME "Elite-EDC"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 2
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 7
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15R2)
#define DEVICE_NAME "Elite-EDC"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 2
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 8
#elif (DEF_ELITE_MODEL == DEF_ELITE_BAT_10)
#define DEVICE_NAME "Elite-BAT"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 3
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 0
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_10)
#define DEVICE_NAME "Elite-EIS"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 4
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 0
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_11)
#define DEVICE_NAME "Elite-EIS"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 4
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 1
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_MINI_10)
#define DEVICE_NAME "Elite-EIS"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 4
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 2
#elif (DEF_ELITE_MODEL == DEF_ELITE_TRIG_01)
#define DEVICE_NAME "Elite-TRIG"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 5
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 0
#elif (DEF_ELITE_MODEL == DEF_ELITE_MEGAFLY_01)
#define DEVICE_NAME "Elite-MEGAFLY"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 6
#define MAJOR_VERSION_NUMBER 1
#define MINOR_VERSION_NUMBER 0
#endif
#ifdef __cplusplus
}
#endif
#endif // ELITE_BOARDS_SELECT_H
@@ -0,0 +1,63 @@
#ifndef PIN_DEF_EDC15RE_H
#define PIN_DEF_EDC15RE_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* +------------------------------+
* | CC2650moda |
* +-------------+----------------+
* | MISO | DIO1 |
* | D0 | DIO3 |
* | D1 | DIO4 |
* | D2/JTAG_TDO | DIO5/JTAG_TDO |
* | D3/JTAG_TDI | DIO6/JTAG_TDI |
* | D4 | DIO7 |
* | D5 | DIO8 |
* | D6 | DIO9 |
* | D7 | DIO10 |
* | LOAD2 | DIO11 |
* | LOAD1 | DIO12 |
* | LOAD0 | DIO13 |
* | SHUT_DOWN | DIO14 |
* +-------------+----------------+
*/
/* CC2650moda */
#define E_PIN_MISO DIO1
#define E_PIN_D0 DIO3
#define E_PIN_D1 DIO4
#define E_PIN_D2 DIO5
#define E_PIN_D3 DIO6
#define E_PIN_D4 DIO7
#define E_PIN_D5 DIO8
#define E_PIN_D6 DIO9
#define E_PIN_D7 DIO10
#define E_PIN_LOAD2 DIO11
#define E_PIN_LOAD1 DIO12
#define E_PIN_LOAD0 DIO13
#define E_PIN_SHUT_DOWN DIO14 // to sense switch
/* SPI Board */
#define Board_SPI0_MISO PIN_UNASSIGNED
#define Board_SPI0_MOSI E_PIN_D1
#define Board_SPI0_CLK E_PIN_D0
#define Board_SPI0_CS PIN_UNASSIGNED
#define Board_SPI1_MISO E_PIN_MISO
#define Board_SPI1_MOSI E_PIN_D3
#define Board_SPI1_CLK E_PIN_D2
#define Board_SPI1_CS PIN_UNASSIGNED
/* I2C */
#define Board_I2C0_SCL0 PIN_UNASSIGNED
#define Board_I2C0_SDA0 PIN_UNASSIGNED
#ifdef __cplusplus
}
#endif
#endif // PIN_DEF_EDC15RE_H
@@ -0,0 +1,15 @@
#ifndef GPIO_EDC15RE_H
#define GPIO_EDC15RE_H
#ifdef __cplusplus
extern "C" {
#endif
uint8_t gpio_create(void);
uint8_t add_pin_d0_d3(void);
uint8_t remove_pin_d0_d3(void);
#ifdef __cplusplus
}
#endif
#endif // GPIO_EDC15RE_H
@@ -0,0 +1,89 @@
#include <Board.h>
#include <ti/drivers/pin/PINCC26XX.h>
#include "driver/gpio_edc15re.h"
static PIN_Handle PinHandle;
static PIN_State PinStatus;
const PIN_Config BLE_IO[] = {
E_PIN_D0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_D1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_D2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_D3 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_D4 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_D5 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_D6 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_D7 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_LOAD0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_LOAD1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_LOAD2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
E_PIN_SHUT_DOWN | PIN_INPUT_EN | PIN_PULLDOWN,
PIN_TERMINATE
};
static PIN_Handle __get_gpio_handle(void)
{
return PinHandle;
}
static void __set_gpio_handle(PIN_Handle handle)
{
PinHandle = handle;
return;
}
uint8_t gpio_create(void)
{
PIN_Handle h;
h = PIN_open(&PinStatus, BLE_IO);
__set_gpio_handle(h);
if (h == NULL)
return 1;
return 0;
}
uint8_t add_pin_d0_d3(void)
{
PIN_Handle h = __get_gpio_handle();
PIN_add(h, E_PIN_D0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL);
PIN_add(h, E_PIN_D1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL);
PIN_add(h, E_PIN_D2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL);
PIN_add(h, E_PIN_D3 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL);
return 0;
}
uint8_t remove_pin_d0_d3(void)
{
PIN_Handle h = __get_gpio_handle();
PIN_remove(h, E_PIN_D0);
PIN_remove(h, E_PIN_D1);
PIN_remove(h, E_PIN_D2);
PIN_remove(h, E_PIN_D3);
return 0;
}
static uint8_t pin_set(uint8_t pin, uint8_t set_value)
{
/*
* if status = 0: success
* else: fail
*/
uint8_t p = pin;
uint8_t v = set_value;
PIN_Status status;
PIN_Handle h = __get_gpio_handle();
status = PIN_setOutputValue(h, p, v);
return (uint8_t)status;
}
@@ -0,0 +1,26 @@
#ifndef SPI_CTRL_H
#define SPI_CTRL_H
#ifdef __cplusplus
extern "C" {
#endif
#define SPI0 0
#define SPI1 1
#define SPI_POL0 0
#define SPI_POL1 1
#define SPI_PHA0 0
#define SPI_PHA1 1
#define SPI_RATE_1M 1000000
#define SPI_RATE_4M 4000000
#define SPI_RATE_6M 6000000
uint8_t spi_open(uint8_t spi_n, uint32_t b_rate, uint8_t pol, uint8_t pha);
uint8_t spi_close(uint8_t spi_n);
uint8_t spi_write(uint8_t spi_n, uint8_t *rxBuf, uint8_t *txBuf, uint8_t len);
#ifdef __cplusplus
}
#endif
#endif // SPI_CTRL_H
@@ -0,0 +1,173 @@
#include <Board.h>
#include <ti/drivers/SPI.h>
#include "driver/spi_ctrl.h"
#define CC2650_SPI_BITRATE_MAX 6e6 //Full-duplex maximum speed = 6M
static SPI_Handle SpiHandle0 = NULL;
static SPI_Params SpiParams0;
static SPI_Handle SpiHandle1 = NULL;
static SPI_Params SpiParams1;
/**
* _get_spi_mode - transfer both polarity and phase to pol_pha_combine
* @pol: polarity
* @pha: phase
* Returns: spi mode
*/
static SPI_FrameFormat _get_spi_mode(uint8_t pol, uint8_t pha)
{
SPI_FrameFormat spi_mode;
if (pol == 0 && pha == 0)
spi_mode = SPI_POL0_PHA0;
else if (pol == 0 && pha == 1)
spi_mode = SPI_POL0_PHA1;
else if (pol == 1 && pha == 0)
spi_mode = SPI_POL1_PHA0;
else if (pol == 1 && pha == 1)
spi_mode = SPI_POL1_PHA1;
return spi_mode;
}
/**
* spi_open -
* @spi_n: which SPI
* @b_rate: bit rate of SPI
* @pol: polarity
* @pha: phase
* Returns: 0 on success, 1 on no this spi module, 2 on unsupported bit rate,
* 3 on unsupported polarity and phase, 4 on spi already open,
* 5 on failure
* note: Before using PIN_open() and SPI_open(), make sure that the pins are \
* not already registered, otherwise it will crash.
*/
uint8_t spi_open(uint8_t spi_n, uint32_t b_rate, uint8_t pol, uint8_t pha)
{
SPI_Handle* h;
SPI_Params* para;
uint8_t spi_module;
if (spi_n >= 2)
return 1;
if (b_rate > CC2650_SPI_BITRATE_MAX)
return 2;
if (pol > 1 || pha > 1)
return 3;
if (spi_n == SPI0)
{
h = &SpiHandle0;
para = &SpiParams0;
spi_module = Board_SPI0;
}
else
{
h = &SpiHandle1;
para = &SpiParams1;
spi_module = Board_SPI1;
}
if (*h != NULL)
return 4;
SPI_Params_init(para);
para->bitRate = b_rate;
para->mode = SPI_MASTER;
para->dataSize = 8;
para->frameFormat = _get_spi_mode(pol, pha);
*h = SPI_open(spi_module, para);
if (*h == NULL)
return 5;
return 0;
}
/**
* spi_close -
* @spi_n: which SPI
* Returns: 0 on success, 1 on no this spi module, 2 on no instance
* note: Before using PIN_close() and SPI_close(), make sure that there is \
* an instance available, otherwise it will crash.
*/
uint8_t spi_close(uint8_t spi_n)
{
SPI_Handle *h;
if (spi_n >= 2)
return 1;
if (spi_n == SPI0)
h = &SpiHandle0;
else
h = &SpiHandle1;
if (*h == NULL)
return 2;
SPI_close(*h);
*h = NULL;
return 0;
}
/**
* spi_close -
* @spi_n: which SPI
* @*rxBuf: rxbuf
* @*txBuf: txbuf
* @len: what is the required length
* Returns: 0 on success, 1 on no this spi module, 2 on no instance,
* 3 on write failure
*/
uint8_t spi_write(uint8_t spi_n, uint8_t *rxBuf, uint8_t *txBuf, uint8_t len)
{
uint8_t ret;
SPI_Handle* h;
SPI_Transaction spi_tran;
if (spi_n >= 2)
return 1;
if (spi_n == SPI0)
h = &SpiHandle0;
else
h = &SpiHandle1;
if (*h == NULL)
return 2;
spi_tran.count = len;
spi_tran.txBuf = txBuf;
spi_tran.arg = NULL;
spi_tran.rxBuf = NULL;
ret = SPI_transfer(*h, &spi_tran) ? 0 : 3;
return ret;
}
/* utils.c.h */
/*
#include <stdio.h>
#include <stdint.h>
static void ___print_hex(uint8_t* p, int len)
{
// ___print_hex((uint8_t *)p, sizeof(struct led_series_data_t));
int i;
for (i = 0; i < len; i++) {
printf("0x%x, ", *p++);
}
printf("\n\n");
return;
}
*/
@@ -0,0 +1,40 @@
#ifndef TIMERS_H
#define TIMERS_H
#ifdef __cplusplus
extern "C" {
#endif
//timer
enum gptimer0_ctrl_e {
GPT_CTRL_START = 0,
GPT_CTRL_STOP,
GPT_CTRL_CLOSE,
GPT_CTRL_MAX,
};
void elite_gptimer_open();
uint8_t gptimer0_ctrl(enum gptimer0_ctrl_e gpt_ctrl);
//clock
/***************************************************
* Q: Why define CPU_1us = 16?
* A:
* 3 cycles per loop: 16 loops @ 48 Mhz ~= 1 us
* 3 cycles * X loops / 48Mhz = 1us(ideal value)
* 3 cycles * X loops / 48us = 1us(ideal value)
* X = 48 / 3 => X = 16 loops
***************************************************/
#define CPU_1us 16
#define CPU_1ms 16000
void CPUdelay_us(uint32_t delay_t);
void CPUdelay_ms(uint32_t delay_t);
void GPT_timerIncrement();
#ifdef __cplusplus
}
#endif
#endif // TIMERS_H
@@ -0,0 +1,90 @@
#include <Board.h>
#include <ti/drivers/timer/GPTimerCC26XX.h>
#include <xdc/runtime/Types.h>
#include <ti/sysbios/BIOS.h>
#include "driver/timers.h"
#include "simple_peripheral.h"
static GPTimerCC26XX_Handle gptimer_handle; // was defined static
#define CLOCK_FREQ 4769 // clock freq = 0.1 ms(4800), Measured(4769)
static void elite_gptimer_callback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {
elite_gptimer_task();
return;
}
void elite_gptimer_open()
{
GPTimerCC26XX_Params params;
GPTimerCC26XX_Params_init(&params);
params.width = GPT_CONFIG_16BIT;
params.mode = GPT_MODE_PERIODIC_UP;
params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
gptimer_handle = GPTimerCC26XX_open(Board_GPTIMER0A, &params);
if (gptimer_handle == NULL) {
Task_exit();
}
Types_FreqHz freq;
BIOS_getCpuFreq(&freq);
GPTimerCC26XX_Value loadVal = freq.lo / 1000 - 1; //47999 = 1ms
loadVal = CLOCK_FREQ; //0.1ms
GPTimerCC26XX_setLoadValue(gptimer_handle, loadVal);
GPTimerCC26XX_registerInterrupt(gptimer_handle, elite_gptimer_callback, GPT_INT_TIMEOUT);
GPTimerCC26XX_start(gptimer_handle);
return;
}
uint8_t gptimer0_ctrl(enum gptimer0_ctrl_e gpt_ctrl)
{
enum gptimer0_ctrl_e gc = gpt_ctrl;
if (gc > GPT_CTRL_MAX)
return 1;
switch (gc) {
case GPT_CTRL_START:
GPTimerCC26XX_start(gptimer_handle);
break;
case GPT_CTRL_STOP:
GPTimerCC26XX_stop(gptimer_handle);
break;
case GPT_CTRL_CLOSE:
GPTimerCC26XX_close(gptimer_handle);
break;
}
return 0;
}
/*******************************************************************************************/
//clock
void CPUdelay_us(uint32_t delay_t)
{
uint32_t t = delay_t;
CPUdelay(t * CPU_1us);
return;
}
void CPUdelay_ms(uint32_t delay_t)
{
uint32_t t = delay_t;
CPUdelay(t * CPU_1ms);
return;
}
void GPT_timerIncrement() {
GPT.cnt_gpt_delta = GPT.cnt_gpt - GPT.cnt_gpt0;
GPT.cnt_gpt0 = GPT.cnt_gpt;
}
@@ -0,0 +1,26 @@
#ifndef ELITE_GPTIMER_H
#define ELITE_GPTIMER_H
#ifdef __cplusplus
extern "C" {
#endif
struct gptimer0_t{
uint32_t cnt_gpt;
uint32_t cnt_gpt0;
uint8_t cnt_gpt_delta;
uint32_t cnt_adc_rate;
uint32_t cnt_notify_rate;
uint32_t cnt_v_scan_rate;
uint32_t cnt_lead_time;
uint32_t BatteryADCCounter;
uint32_t BatteryCheckCounter;
uint32_t GptimerMultiple;
};
void InitGPT();
#ifdef __cplusplus
}
#endif
#endif // ELITE_GPTIMER_H
@@ -0,0 +1,16 @@
#include "elite_task/elite_GPtimer.h"
void InitGPT()
{
GPT.cnt_gpt = 0;
GPT.cnt_gpt0 = 0;
GPT.cnt_gpt_delta = 0;
GPT.cnt_adc_rate = 0;
GPT.cnt_notify_rate = 0;
GPT.cnt_v_scan_rate = 0;
GPT.cnt_lead_time = 0;
GPT.BatteryADCCounter = 0;
GPT.BatteryCheckCounter = 0;
return;
}
@@ -0,0 +1,56 @@
#ifndef ELITE_LATCH_H
#define ELITE_LATCH_H
#ifdef __cplusplus
extern "C" {
#endif
#define LOAD0 0
#define LOAD1 1
#define LOAD2 2
#define LOAD_MAX 3
#define D0 0
#define D1 1
#define D2 2
#define D3 3
#define D4 4
#define D5 5
#define D6 6
#define D7 7
#define D_MAX 8
// latch 1 control
// #define E_LATCH_LED_SCLK_A LOAD0, D0 // not gpio
// #define E_LATCH_LED_MOSI_A LOAD0, D1 // not gpio
// #define E_LATCH_SCLK LOAD0, D2 // not gpio
// #define E_LATCH_MOSI LOAD0, D3 // not gpio
#define E_LATCH_HIGH_Z LOAD0, D4
#define E_LATCH_CS_MEM LOAD0, D5
#define E_LATCH_CS_ADC LOAD0, D6
#define E_LATCH_CS_DAC LOAD0, D7
// latch 2 control
#define E_LATCH_MEM_HOLD LOAD1, D0
#define E_LATCH_10V_ENABLE LOAD1, D5
#define E_LATCH_5V_ENABLE LOAD1, D6
// latch 3 control
#define E_LATCH_I_MID_ON LOAD2, D0
#define E_LATCH_I_LARGE_ON LOAD2, D1
#define E_LATCH_V_SMALL_ON LOAD2, D2
#define E_LATCH_V_MID_ON LOAD2, D3
#define E_LATCH_I_SMALL_ON LOAD2, D4
#define E_LATCH_OFF LOAD2, D6
#define E_LATCH_VOUT_SMALL_ON LOAD2, D7
#define HIGH_Z_OPEN() latch_single_ctrl(E_LATCH_HIGH_Z, 0);
#define HIGH_Z_CLOSE() latch_single_ctrl(E_LATCH_HIGH_Z, 1);
uint8_t update_latch_stat(uint8_t latch, uint8_t dio, uint8_t value);
uint8_t latch_single_ctrl(uint8_t latch, uint8_t dio, uint8_t value);
uint8_t latch_multi_ctrl(void);
#ifdef __cplusplus
}
#endif
#endif // ELITE_LATCH_H
@@ -0,0 +1,352 @@
#include "elite_task/elite_latch.h"
#include "driver/gpio_edc15re.h"
#include "driver/spi_ctrl.h"
enum pin_ctrl_e {
PC_LOAD0_CLR = 0,
PC_LOAD0_SET,
PC_LOAD1_CLR,
PC_LOAD1_SET,
PC_LOAD2_CLR,
PC_LOAD2_SET,
PC_D0_CLR,
PC_D0_SET,
PC_D1_CLR,
PC_D1_SET,
PC_D2_CLR,
PC_D2_SET,
PC_D3_CLR,
PC_D3_SET,
PC_D4_CLR,
PC_D4_SET,
PC_D5_CLR,
PC_D5_SET,
PC_D6_CLR,
PC_D6_SET,
PC_D7_CLR,
PC_D7_SET,
PC_MAX,
};
//d0.d1.d2.d3.d4.d5.d6.d7
struct latch_t {
uint8_t d7: 1,
d6: 1,
d5: 1,
d4: 1,
d3: 1,
d2: 1,
d1: 1,
d0: 1;
};
static struct latch_t LH0 = {0};
static struct latch_t LH1 = {0};
static struct latch_t LH2 = {0};
static uint8_t __pin_ctrl(uint8_t pin_control)
{
uint8_t pc = pin_control;
int8_t st;
if (pc >= PC_MAX)
return 1;
switch (pc) {
case PC_LOAD0_CLR:
st = pin_set(E_PIN_LOAD0, 0);
break;
case PC_LOAD0_SET:
st = pin_set(E_PIN_LOAD0, 1);
break;
case PC_LOAD1_CLR:
st = pin_set(E_PIN_LOAD1, 0);
break;
case PC_LOAD1_SET:
st = pin_set(E_PIN_LOAD1, 1);
break;
case PC_LOAD2_CLR:
st = pin_set(E_PIN_LOAD2, 0);
break;
case PC_LOAD2_SET:
st = pin_set(E_PIN_LOAD2, 1);
break;
case PC_D0_CLR:
st = pin_set(E_PIN_D0, 0);
break;
case PC_D0_SET:
st = pin_set(E_PIN_D0, 1);
break;
case PC_D1_CLR:
st = pin_set(E_PIN_D1, 0);
break;
case PC_D1_SET:
st = pin_set(E_PIN_D1, 1);
break;
case PC_D2_CLR:
st = pin_set(E_PIN_D2, 0);
break;
case PC_D2_SET:
st = pin_set(E_PIN_D2, 1);
break;
case PC_D3_CLR:
st = pin_set(E_PIN_D3, 0);
break;
case PC_D3_SET:
st = pin_set(E_PIN_D3, 1);
break;
case PC_D4_CLR:
st = pin_set(E_PIN_D4, 0);
break;
case PC_D4_SET:
st = pin_set(E_PIN_D4, 1);
break;
case PC_D5_CLR:
st = pin_set(E_PIN_D5, 0);
break;
case PC_D5_SET:
st = pin_set(E_PIN_D5, 1);
break;
case PC_D6_CLR:
st = pin_set(E_PIN_D6, 0);
break;
case PC_D6_SET:
st = pin_set(E_PIN_D6, 1);
break;
case PC_D7_CLR:
st = pin_set(E_PIN_D7, 0);
break;
case PC_D7_SET:
st = pin_set(E_PIN_D7, 1);
break;
}
if (st)
return 2;
return 0;
}
static struct latch_t *__get_lh_stat(uint8_t latch)
{
uint8_t lh = latch;
if (lh == LOAD0)
return &LH0;
if (lh == LOAD1)
return &LH1;
if (lh == LOAD2)
return &LH2;
return 0;
}
static void __latch0_set(void)
{
struct latch_t *lh_p = __get_lh_stat(LOAD0);
pin_set(E_PIN_D4, lh_p->d4);
pin_set(E_PIN_D5, lh_p->d5);
pin_set(E_PIN_D6, lh_p->d6);
pin_set(E_PIN_D7, lh_p->d7);
return;
}
static void __latch1_set(void)
{
struct latch_t *lh_p = __get_lh_stat(LOAD1);
pin_set(E_PIN_D0, lh_p->d0);
pin_set(E_PIN_D5, lh_p->d5);
pin_set(E_PIN_D6, lh_p->d6);
return;
}
static void __latch2_set(void)
{
struct latch_t *lh_p = __get_lh_stat(LOAD2);
pin_set(E_PIN_D0, lh_p->d0);
pin_set(E_PIN_D1, lh_p->d1);
pin_set(E_PIN_D2, lh_p->d2);
pin_set(E_PIN_D3, lh_p->d3);
pin_set(E_PIN_D4, lh_p->d4);
pin_set(E_PIN_D6, lh_p->d6);
pin_set(E_PIN_D7, lh_p->d7);
return;
}
static uint8_t __latch0_as_gpio(void)
{
__pin_ctrl(PC_LOAD0_CLR);
spi_close(SPI0);
spi_close(SPI1);
add_pin_d0_d3();
return 0;
}
static uint8_t __latch0_as_spi(void)
{
remove_pin_d0_d3();
Board_initSPI();
spi_open(SPI0, SPI_RATE_1M, SPI_POL0, SPI_PHA1); //SPI 1M: LED
spi_open(SPI1, SPI_RATE_4M, SPI_POL0, SPI_PHA1); //SPI 4M: ADC、DAC
__latch0_set();
__pin_ctrl(PC_LOAD0_SET);
return 0;
}
uint8_t update_latch_stat(uint8_t latch, uint8_t dio, uint8_t value)
{
uint8_t lh = latch;
uint8_t d = dio;
uint8_t val = value;
struct latch_t *lh_p;
if (lh >= LOAD_MAX)
return 1;
if (d >= D_MAX)
return 2;
if (val != 1 && value != 0)
return 3;
lh_p = __get_lh_stat(lh);
switch (d) {
case D0:
lh_p->d0 = val;
break;
case D1:
lh_p->d1 = val;
break;
case D2:
lh_p->d2 = val;
break;
case D3:
lh_p->d3 = val;
break;
case D4:
lh_p->d4 = val;
break;
case D5:
lh_p->d5 = val;
break;
case D6:
lh_p->d6 = val;
break;
case D7:
lh_p->d7 = val;
break;
}
return 0;
}
uint8_t latch_single_ctrl(uint8_t latch, uint8_t dio, uint8_t value)
{
// control one latch pin -> update_latch_stat -> what latch to update? -> latch?_ctrl
uint8_t lh = latch;
uint8_t d = dio;
uint8_t val = value;
if (lh >= LOAD_MAX)
return 1;
if (d >= D_MAX)
return 2;
if (val != 1 && value != 0)
return 3;
update_latch_stat(lh, d, val);
switch (lh) {
case LOAD0:
__latch0_set();
break;
case LOAD1:
__latch0_as_gpio();
__latch1_set();
__pin_ctrl(PC_LOAD1_SET);
__pin_ctrl(PC_LOAD1_CLR);
__latch0_as_spi();
break;
case LOAD2:
__latch0_as_gpio();
__latch2_set();
__pin_ctrl(PC_LOAD2_SET);
__pin_ctrl(PC_LOAD2_CLR);
__latch0_as_spi();
break;
}
return 0;
}
uint8_t latch_multi_ctrl(void)
{
// control many latch pin -> update_latch_stat -> update_latch_stat -> ... -> latch_ctrl 0.1.2
__latch0_set();
__pin_ctrl(PC_LOAD0_SET);
__latch0_as_gpio();
__latch1_set();
__pin_ctrl(PC_LOAD1_SET);
__pin_ctrl(PC_LOAD1_CLR);
__latch2_set();
__pin_ctrl(PC_LOAD2_SET);
__pin_ctrl(PC_LOAD2_CLR);
__latch0_as_spi();
return 0;
}
@@ -0,0 +1,41 @@
#ifndef DAC_MAX5136_H
#define DAC_MAX5136_H
#ifdef __cplusplus
extern "C" {
#endif
#include "driver/spi_ctrl.h"
#define CTRL_B_LDAC 0x01
#define CTRL_B_CLR 0x02
#define CTRL_B_POW_CTRL 0x03
#define CTRL_B_LINEARITY 0x05
#define CTRL_B_WRT(_d0, _d1) (0x10 | ((_d1) << 1) | (_d0))
#define CTRL_B_WRT_THR(_d0, _d1) (0x30 | ((_d1) << 1) | (_d0))
#define DATA_B_LDAC(_d0, _d1) ((_d1) << 9 | (_d0) << 8)
#define DATA_B_POW_CT(_d0, _d1, _rd) ((_d1) << 9 | (_d0) << 8 | (_rd) << 7)
#define DATA_B_LINE(_en) ((_en) << 9)
#define DAC0_EN 1
#define DAC0_DIS 0
#define DAC1_EN 1
#define DAC1_DIS 0
#define DAC0_W_T(_v) dac_write_through_mode(DAC0_EN, DAC1_DIS, _v);
#define DAC0_W(_v) dac_write_mode(DAC0_EN, DAC1_DIS, _v);
#define DAC0_P_C(_rdy) dac_power_control_mode(DAC0_EN, DAC1_DIS, _rdy);
#define DAC0_LDAC() dac_ldac_mode(DAC0_EN, DAC1_DIS);
int dac_ldac_mode(uint8_t dac0_enable, uint8_t dac1_enable);
int dac_clear_mode();
int dac_power_control_mode(uint8_t dac0_enable, uint8_t dac1_enable, uint8_t ready_enable);
int dac_linearity_mode(uint8_t linear_enable);
int dac_write_mode(uint8_t dac0_enable, uint8_t dac1_enable, uint16_t volts);
int dac_write_through_mode(uint8_t dac0_enable, uint8_t dac1_enable, uint16_t volts);
#ifdef __cplusplus
}
#endif
#endif //DAC_MAX5136_H
@@ -0,0 +1,110 @@
#include "hardware/dac_MAX5136.h"
struct dac_series_data_t {
uint8_t control_bits;
uint16_t data_bits;
}__attribute__((packed));
static struct dac_series_data_t dac_series_data_g = {0};
static int __dac_transfer(struct dac_series_data_t *sd)
{
latch_single_ctrl(E_LATCH_CS_DAC, 0);
#define WRITE_TO_DAC(_d, _l) spi_write(SPI1, NULL, (uint8_t *)(_d), (_l))
WRITE_TO_DAC(sd, sizeof(struct dac_series_data_t));
latch_single_ctrl(E_LATCH_CS_DAC, 1);
return 0;
}
int dac_ldac_mode(uint8_t dac0_enable, uint8_t dac1_enable)
{
uint8_t d0 = dac0_enable;
uint8_t d1 = dac1_enable;
struct dac_series_data_t *sd = &dac_series_data_g;
sd->control_bits = CTRL_B_LDAC;
sd->data_bits = REVERT_2_BYTE(DATA_B_LDAC(d0, d1));
__dac_transfer(sd);
return 0;
}
int dac_clear_mode()
{
struct dac_series_data_t *sd = &dac_series_data_g;
sd->control_bits = CTRL_B_CLR;
__dac_transfer(sd);
return 0;
}
int dac_power_control_mode(uint8_t dac0_enable, uint8_t dac1_enable, uint8_t ready_enable)
{
uint8_t d0 = dac0_enable;
uint8_t d1 = dac1_enable;
uint8_t rdy_en = ready_enable;
struct dac_series_data_t *sd = &dac_series_data_g;
sd->control_bits = CTRL_B_POW_CTRL;
sd->data_bits = REVERT_2_BYTE(DATA_B_POW_CT(d0, d1, rdy_en));
__dac_transfer(sd);
return 0;
}
int dac_linearity_mode(uint8_t linear_enable)
{
uint8_t lin_en = linear_enable;
struct dac_series_data_t *sd = &dac_series_data_g;
sd->control_bits = CTRL_B_LINEARITY;
sd->data_bits = REVERT_2_BYTE(DATA_B_LINE(lin_en));
__dac_transfer(sd);
return 0;
}
int dac_write_mode(uint8_t dac0_enable, uint8_t dac1_enable, uint16_t volts)
{
uint8_t d0 = dac0_enable;
uint8_t d1 = dac1_enable;
uint16_t v = volts;
struct dac_series_data_t *sd = &dac_series_data_g;
sd->control_bits = CTRL_B_WRT(d0, d1);
sd->data_bits = REVERT_2_BYTE(v);
__dac_transfer(sd);
return 0;
}
int dac_write_through_mode(uint8_t dac0_enable, uint8_t dac1_enable, uint16_t volts)
{
uint8_t d0 = dac0_enable;
uint8_t d1 = dac1_enable;
uint16_t v = volts;
struct dac_series_data_t *sd = &dac_series_data_g;
sd->control_bits = CTRL_B_WRT_THR(d0, d1);
sd->data_bits = REVERT_2_BYTE(v);
__dac_transfer(sd);
return 0;
}
@@ -0,0 +1,67 @@
#ifndef DAC_ADS1118_H
#define DAC_ADS1118_H
#ifdef __cplusplus
extern "C" {
#endif
#include "driver/spi_ctrl.h"
#define ADC_CH_CURR AIN0_GND
#define ADC_CH_VIN AIN1_GND
#define ADC_CH_BAT AIN3_GND
#define ADC_CH_VOUT AIN2_GND
#define MEASURE_CURRENT() read_adc_data(ADC_CH_CURR, FSR3)
#define MEASURE_VOLT() read_adc_data(ADC_CH_VIN, FSR3)
#define MEASURE_DAC() read_adc_data(ADC_CH_VOUT, FSR3)
#define MEASURE_BATTERY() read_adc_data(ADC_CH_BAT, FSR1)
enum input_mux_e {
AIN0_AIN1 = 0x00,
AIN0_AIN3 = 0x01,
AIN1_AIN3 = 0x02,
AIN2_AIN3 = 0x03,
AIN0_GND = 0x04,
AIN1_GND = 0x05,
AIN2_GND = 0x06,
AIN3_GND = 0x07,
};
/*
* [Progrmmable gain amplifier configuration]
*
* The corresponing relationship of FSRx to volt will be the form:
* FSRx <-> 0xXX <-> +- xV
*
* FSR1 <-> 0x00 <-> +-6.144V
* FSR2 <-> 0x01 <-> +-4.096V
* FSR3 <-> 0x02 <-> +-2.408V
* FSR4 <-> 0x03 <-> +-1.024V
* FSR5 <-> 0x04 <-> +-0.512V
* FSR6 <-> 0x05 <-> +-0.256V
* FSR7 <-> 0x06 <-> +-0.256V
* FSR8 <-> 0x07 <-> +-0.256V
*
*/
enum gain_amplifier_e {
FSR1 = 0x00,
FSR2 = 0x01,
FSR3 = 0x02,
FSR4 = 0X03,
FSR5 = 0x04,
FSR6 = 0x05,
FSR7 = 0x06,
FSR8 = 0x07,
};
uint16_t read_adc_data(uint8_t AdcChannel, uint8_t gainAmp);
#ifdef __cplusplus
}
#endif
#endif //ADC_ADS1118_H
@@ -0,0 +1,79 @@
#include "hardware/adc_ads1118.h"
static uint8_t spi_ADC_txbuf_l[2] = {0};
static uint8_t spi_ADC_rxbuf_l[2] = {0};
static void __ADC_read(uint8_t input_mux, uint8_t gAmp)
{
/*
* write SPI to get ADC value
* [7]~[0] should always be 0b11101011, data rate is 860 sps, other is default
*
* [15] : SS, 0 = no effect, 1 = start work, default 0b0
* [14]~[12] : MUX[2:0], default 0b000
*
* [Input multiplexer configuration]
*
* the MUX selection will correspond to a pin pair
* where the pair is positive and negative input
*
* MUX[2:0] <-> (AINp, AINn)
*
* 000 <-> AINp is AIN0, AINn is AIN1
* 001 <-> AINp is AIN0, AINn is AIN3
* 010 <-> AINp is AIN1, AINn is AIN3
* 011 <-> AINp is AIN2, AINn is AIN3
* 100 <-> AINp is AIN0, AINn is GND
* 101 <-> AINp is AIN1, AINn is GND
* 110 <-> AINp is AIN2, AINn is GND
* 111 <-> AINp is AIN3, AINn is GND
*
*
*
* [11]~[9] : PGA[2:0], default 0b010 = FSR is ±2.048
* [8] : mode, 0 = continuous, 1 = one shot, default 0b1 (Power-down and single-shot mode )
*
* [7]~[5] : data rate, default 0b100 = 128 SPS; 0b111 = 860 SPS
* [4] : Temperature? default 0b0 = ADC mode
* [3] : Pullup enable, default 0b1 = Pullup resistor enabled
* [2]~[1] : NOP, default 0b01
* [0] : reserved, default 0b1
*
*/
uint8_t *tx = spi_ADC_txbuf_l;
uint8_t *rx = spi_ADC_rxbuf_l;
uint8_t i_mux = input_mux;
uint8_t ga = gAmp;
tx[0] = i_mux << 4 | ga << 1 | 0b10000001;
tx[1] = 0b11101011;
latch_single_ctrl(E_LATCH_CS_ADC, 0);
spi_write(SPI1, NULL, tx, 2);
latch_single_ctrl(E_LATCH_CS_ADC, 1);
memset(tx, 0, sizeof(tx));
memset(rx, 0, sizeof(rx));
latch_single_ctrl(E_LATCH_CS_ADC, 0);
spi_write(SPI1, rx, tx, 2);
latch_single_ctrl(E_LATCH_CS_ADC, 1);
return;
}
uint16_t read_adc_data(uint8_t AdcChannel, uint8_t gainAmplifier)
{
uint8_t Adc_ch = AdcChannel;
uint8_t gainAmp = gainAmplifier;
uint16_t rx;
__ADC_read(Adc_ch, gainAmp);
rx = (uint16_t)spi_ADC_rxbuf_l[0] << 8 | (uint16_t)spi_ADC_rxbuf_l[1];
return rx;
}
@@ -0,0 +1,94 @@
#ifndef LED_APA_102_H
#define LED_APA_102_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* APA-102-2020-256-8A-20190612: Series data structure
* +-------------------+------------------------- ... -+-----------------+
* | start_frame(4B) | led_frame(4B) *LED_TANDEM_N | end_frame(4B) |
* +-------------------+------------------------- ... -+-----------------+
* / \
* / led_frame(4B) \
* / \
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 111 | bright | blue | green | red |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#include "driver/spi_ctrl.h"
#define DEF_LED_TANDEN_N 12
#ifdef DEF_LED_TANDEN_N
#define LED_TANDEM_N DEF_LED_TANDEN_N
#else
#define LED_TANDEM_N 12
#endif
enum led_series_nb_e {
LED_NB_1 = 0,
LED_NB_2,
LED_NB_3,
LED_NB_4,
LED_NB_5,
LED_NB_6,
LED_NB_7,
LED_NB_8,
LED_NB_9,
LED_NB_10,
LED_NB_11,
LED_NB_12,
LED_NB_MAX = LED_TANDEM_N,
};
enum led_bright_e {
LED_BR_LV0 = 0x00,
LED_BR_LV1 = 0x01,
LED_BR_LV8 = 0x08,
LED_BR_MAX = 0x1F,
};
enum led_color_e {
LED_CLR_BLACK = 0,
LED_CLR_WHITE,
LED_CLR_RED,
LED_CLR_ORANGE,
LED_CLR_YELLOW,
LED_CLR_GREEN,
LED_CLR_CYAN,
LED_CLR_BLUE,
LED_CLR_PURPLE,
LED_CLR_MAGENTA,
LED_CLR_YELLOWGREEN,
LED_CLR_EMERALD,
LED_CLR_LOW_BAT,
LED_CLR_MAX,
};
struct led_color_t {
uint8_t b;
uint8_t g;
uint8_t r;
};
struct led_frame_t {
uint8_t bright: 5,
rsvd: 3;
struct led_color_t color;
};
int led_color_set(enum led_series_nb_e led_nb, enum led_bright_e bright, enum led_color_e color);
int led_color_code_set(enum led_series_nb_e led_nb, enum led_bright_e bright, struct led_color_t *color);
int led_rainbow(enum led_bright_e bright);
#ifdef __cplusplus
}
#endif
#endif // LED_APA_102_H
@@ -0,0 +1,190 @@
#include "hardware/led_APA_102.h"
#define LED_FRME_FILL_RSVD(_f) (_f)->rsvd = 0x07 // 0x11100000 || bright
#define LED_SERIES_D_START 0x00000000
#define LED_SERIES_D_END 0xFFFFFFFF
struct led_series_data_t {
uint32_t f_start;
struct led_frame_t f_led[LED_TANDEM_N];
uint32_t f_end;
};
static struct led_series_data_t led_series_data_g = {0};
const struct led_color_t led_color_list_g[LED_CLR_MAX] = {
// {blue, green, red}
{0x00, 0x00, 0x00}, // LED_CLR_BLACK
{0xFF, 0xFF, 0xCA}, // LED_CLR_WHITE
{0x00, 0x00, 0xFF}, // LED_CLR_RED
{0x09, 0x58, 0xFF}, // LED_CLR_ORANGE
{0x00, 0xE1, 0xE1}, // LED_CLR_YELLOW
{0x00, 0xFA, 0x00}, // LED_CLR_GREEN
{0x40, 0x40, 0x00}, // LED_CLR_CYAN
{0xAA, 0x00, 0x00}, // LED_CLR_BLUE
{0x6F, 0x00, 0x3A}, // LED_CLR_PURPLE
{0xFF, 0x00, 0xFF}, // LED_CLR_MAGENTA
{0x00, 0xA6, 0x64}, // LED_CLR_YELLOWGREEN
{0x78, 0xC8, 0x50}, // LED_CLR_EMERALD
{0x05, 0x35, 0x9E}, // LED_CLR_LOW_BAT (orange)
};
static int __led_single_set(struct led_series_data_t *led_s_d, struct led_frame_t *led_f, enum led_series_nb_e led_nb)
{
struct led_series_data_t *sd = led_s_d;
struct led_frame_t *f = led_f;
enum led_series_nb_e nb = led_nb;
memcpy(&sd->f_led[nb], f, sizeof(struct led_frame_t));
return 0;
}
static int __led_multiple_set(struct led_series_data_t *led_s_d, struct led_frame_t *led_f)
{
struct led_series_data_t *sd = led_s_d;
struct led_frame_t *f = led_f;
int i;
/*
* use __led_single_set() to finish all led;
*/
for (i = LED_NB_1; i < LED_NB_MAX; i++) {
__led_single_set(sd, f, (enum led_series_nb_e)i);
}
return 0;
}
static int __led_complete(struct led_series_data_t *led_s_d)
{
struct led_series_data_t *sd = led_s_d;
struct led_frame_t *f = sd->f_led;
int i;
for (i = LED_NB_1; i < LED_NB_MAX; i++) {
LED_FRME_FILL_RSVD(f);
f++;
}
sd->f_start = LED_SERIES_D_START;
sd->f_end = LED_SERIES_D_END;
return 0;
}
static int __led_color_set(enum led_series_nb_e led_nb, struct led_frame_t *led_f)
{
enum led_series_nb_e nb = led_nb;
struct led_frame_t *f = led_f;
struct led_series_data_t *sd = &led_series_data_g;
if (f == NULL)
return -1;
/*
* nb - < LED_NB_MAX: fill one led_frame
* == LED_NB_MAX: fill multiple led_frame
*
* complete: then, fill (start_frame, end_frame and the rsvd of every led_frame)
*
* finally, write cmd to hw by spi
*/
if (nb < LED_NB_MAX) {
__led_single_set(sd, f, nb);
} else if (nb == LED_NB_MAX) {
__led_multiple_set(sd, f);
} else {
return -2;
}
__led_complete(sd);
#define WRITE_TO_HW(_d, _l) spi_write(SPI0, NULL, (uint8_t *)(_d), (_l))
WRITE_TO_HW(sd, sizeof(struct led_series_data_t));
return 0;
}
int led_color_set(enum led_series_nb_e led_nb, enum led_bright_e bright, enum led_color_e color)
{
enum led_series_nb_e nb = led_nb;
enum led_bright_e b = bright;
enum led_color_e c = color;
struct led_frame_t led_f;
if (nb > LED_NB_MAX)
return -1;
if (c >= LED_CLR_MAX)
return -2;
if (b > LED_BR_MAX)
return -3;
led_f.bright = b;
led_f.color = led_color_list_g[c];
__led_color_set(nb, &led_f);
return 0;
}
int led_color_code_set(enum led_series_nb_e led_nb, enum led_bright_e bright, struct led_color_t *color)
{
enum led_series_nb_e nb = led_nb;
enum led_bright_e b = bright;
struct led_color_t *c = color;
struct led_frame_t led_f;
// valid the input values
if (nb > LED_NB_MAX)
return -1;
if (b > LED_BR_MAX)
return -2;
led_f.bright = b;
memcpy(&led_f.color, c, sizeof(struct led_color_t));
__led_color_set(nb, &led_f);
return 0;
}
int led_rainbow(enum led_bright_e bright)
{
enum led_bright_e b = bright;
int i;
if (b > LED_BR_MAX)
return -1;
for(i=0; i<LED_NB_MAX; i++) {
led_color_set((enum led_series_nb_e)i, b, (enum led_color_e)i);
}
return 0;
}
/*
* example -
* customize color:
* struct led_color_t led_c;
* uint8_t bri;
* // { ins, ins, num, r, g, b, bri};
* uint8_t ins[20] = {0x30, 0x00, LED_NB_4, 0xFF, 0x00, 0x44, 0x3};
* led_c.r = ins[3];
* led_c.g = ins[4];
* led_c.b = ins[5];
* bri = ins[6];
* led_color_code_set(LED_NB_4, bri, &led_c);
*
* single led:
* led_color_set(LED_NB_1, LED_BR_LV1, LED_CLR_WHITE);
*
* multiple led:
* led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_BLUE);
*
* rainbow led:
* led_rainbow(LED_BR_LV1);
*/
@@ -0,0 +1,480 @@
/*=============================================================================
= EliteADC.h =
=============================================================================*/
#ifndef EliteADC
#define EliteADC
/* for Elite1.5-re */
// Iin theoretical boundary <2.67, 1.89~80, 63~2600, >1900 (uA)
#define I_GAIN_SMALL_BOUNDARY 4000 // 4 uA = 4,000,000 pA
#define I_GAIN_MID1_BOUNDARY1 2500 // 2.5 uA = 2,500,000 pA
#define I_GAIN_MID1_BOUNDARY2 100000 // 100 uA = 100,000,000 pA
#define I_GAIN_MID2_BOUNDARY1 85000 // 85 uA = 85,000,000 pA
#define I_GAIN_MID2_BOUNDARY2 2050000 // 2050 uA = 2,050,000 nA
#define I_GAIN_LARGE_BOUNDARY 1800000 // 1800 uA = 1,800,000 nA
// Vin theoretical boundary <7, 5~200, >100 (mV)
#define VIN_GAIN_SMALL_BOUNDARY 7000 // 7 mV = 7,000,000 nV
#define VIN_GAIN_MID1_BOUNDARY1 5000 // 5 mV = 5,000,000 nV
#define VIN_GAIN_MID1_BOUNDARY2 290000 // 290 mV = 290,000,000 nV
#define VIN_GAIN_LARGE_BOUNDARY 250000 // 250 mV = 250,000,000 nV
/*
* define how long damping time for automatic current stalls, to skip damping time
* high level switch to low level has 80ms damping time (CE request that skipping 50ms)
* 0 level switch to 1 level has 5ms damping time
*
*/
#define CNT_H2L_IIN_VIN_VOUT_PLOT 5 // need skip 5 * 12ms = 60ms notify data
#define CNT_L2H_IIN_VIN_VOUT_PLOT 1 // need skip 1 * 12ms = 12ms notify data
#define CNT_H2L_IIN_VIN_PLOT 7 // 7 * 8ms = 56ms
#define CNT_L2H_IIN_VIN_PLOT 1 // 1 * 8ms = 8ms
#define CNT_H2L_IT_PLOT 13 // 13 * 4ms = 52ms
#define CNT_L2H_IT_PLOT 2 // 2 * 4ms = 8ms
void IinADCGainCtrl(uint8_t IinADCLevel);
void VinADCGainCtrl(uint8_t VinADCLevel);
void AutoGainChangeIin(int32_t RealCurrent, uint16_t plot_type, uint16_t *no_rec_time);
void AutoGainChangeVin(int32_t RealVin);
/*=============================================================================
= EliteADC.c =
=============================================================================*/
static void __switch_lv0(uint8_t gain0_en, uint16_t plot, uint16_t *no_rec_cnt)
{
static int16_t gain_cnt = 0;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain0_en;
uint16_t pt = plot;
if (gain_en == 0)
return;
gain_cnt++;
if (gain_cnt > 2) {
instru.IinADCGainLv = I_GAIN_3M;
IinADCGainCtrl(instru.IinADCGainLv);
gain_cnt = 0;
if (pt == IIN_VIN_VOUT_PLOT)
*no_rec = CNT_H2L_IIN_VIN_VOUT_PLOT;
else if (pt == IIN_VIN_PLOT)
*no_rec = CNT_H2L_IIN_VIN_PLOT;
else if (pt == IT_PLOT)
*no_rec = CNT_H2L_IT_PLOT;
}
return;
}
static void __switch_lv3(uint8_t gain3_en, uint16_t plot, uint16_t *no_rec_cnt)
{
static int16_t gain_cnt = 0;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain3_en;
if (gain_en == 0)
return;
gain_cnt++;
if (gain_cnt > 2) {
instru.IinADCGainLv = I_GAIN_100R;
IinADCGainCtrl(instru.IinADCGainLv);
gain_cnt = 0;
*no_rec = 0;
}
return;
}
static void __large_switch_lv1(uint8_t gain1_en, uint16_t plot, uint16_t *no_rec_cnt)
{
static int16_t gain_cnt = 0;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain1_en;
uint16_t pt = plot;
if (gain_en == 0)
return;
gain_cnt++;
if (gain_cnt > 2) {
instru.IinADCGainLv = I_GAIN_100K;
IinADCGainCtrl(instru.IinADCGainLv);
gain_cnt = 0;
*no_rec = 0;
if (pt == IIN_VIN_VOUT_PLOT)
*no_rec = CNT_H2L_IIN_VIN_VOUT_PLOT;
else if (pt == IIN_VIN_PLOT)
*no_rec = CNT_H2L_IIN_VIN_PLOT;
else if (pt == IT_PLOT)
*no_rec = CNT_H2L_IT_PLOT;
}
return;
}
static void __small_switch_lv1(uint8_t gain1_en, uint16_t plot, uint16_t *no_rec_cnt)
{
static int16_t gain_cnt = 0;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain1_en;
uint16_t pt = plot;
if (gain_en == 0)
return;
gain_cnt++;
if (gain_cnt > 2) {
instru.IinADCGainLv = I_GAIN_100K;
IinADCGainCtrl(instru.IinADCGainLv);
gain_cnt = 0;
if (pt == IIN_VIN_VOUT_PLOT)
*no_rec = CNT_L2H_IIN_VIN_VOUT_PLOT;
else if (pt == IIN_VIN_PLOT)
*no_rec = CNT_L2H_IIN_VIN_PLOT;
else if (pt == IT_PLOT)
*no_rec = CNT_L2H_IT_PLOT;
}
return;
}
static void __large_switch_lv2(uint8_t gain2_en, uint16_t plot, uint16_t *no_rec_cnt)
{
static int16_t gain_cnt = 0;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain2_en;
uint16_t pt = plot;
if (gain_en == 0)
return;
gain_cnt++;
if (gain_cnt > 2) {
instru.IinADCGainLv = I_GAIN_3K;
IinADCGainCtrl(instru.IinADCGainLv);
gain_cnt = 0;
*no_rec = 0;
if (pt == IIN_VIN_VOUT_PLOT)
*no_rec = CNT_H2L_IIN_VIN_VOUT_PLOT;
else if (pt == IIN_VIN_PLOT)
*no_rec = CNT_H2L_IIN_VIN_PLOT;
else if (pt == IT_PLOT)
*no_rec = CNT_H2L_IT_PLOT;
}
return;
}
static void __small_switch_lv2(uint8_t gain2_en, uint16_t plot, uint16_t *no_rec_cnt)
{
static int16_t gain_cnt = 0;
uint16_t *no_rec = no_rec_cnt;
uint8_t gain_en = gain2_en;
if (gain_en == 0)
return;
gain_cnt++;
if (gain_cnt > 2) {
instru.IinADCGainLv = I_GAIN_3K;
IinADCGainCtrl(instru.IinADCGainLv);
gain_cnt = 0;
*no_rec = 0;
}
return;
}
void IinADCGainCtrl(uint8_t IinADCLevel)
{
if (IinADCLevel>= 4)
return;
/* hardware need open before close, so don't change position*/
if (IinADCLevel == 0) {
// ADC gain level = 0, using 2M resister
update_latch_stat(E_LATCH_I_LARGE_ON, 0);
update_latch_stat(E_LATCH_I_MID_ON, 0);
update_latch_stat(E_LATCH_I_SMALL_ON, 0);
latch_multi_ctrl();
} else if (IinADCLevel == 1) {
// ADC gain level = 1, using 91K resister
update_latch_stat(E_LATCH_I_SMALL_ON, 1); /* need open first */
update_latch_stat(E_LATCH_I_LARGE_ON, 0);
update_latch_stat(E_LATCH_I_MID_ON, 0);
latch_multi_ctrl();
} else if (IinADCLevel == 2) {
// ADC gain level = 2, using 4.3K resister
update_latch_stat(E_LATCH_I_MID_ON, 1); /* need open first */
update_latch_stat(E_LATCH_I_LARGE_ON, 0);
update_latch_stat(E_LATCH_I_SMALL_ON, 0);
latch_multi_ctrl();
} else if (IinADCLevel == 3) {
// ADC gain level = 3, using 200R resistor
update_latch_stat(E_LATCH_I_LARGE_ON, 1); /* need open first */
update_latch_stat(E_LATCH_I_MID_ON, 0);
update_latch_stat(E_LATCH_I_SMALL_ON, 0);
latch_multi_ctrl();
}
if (IinADCLevel == 0 || IinADCLevel == 1 || IinADCLevel == 2 || IinADCLevel == 3) {
lastIinADCGainLevel = IinADCLevel;
}
curr_rec_en = false;
return;
}
void VinADCGainCtrl(uint8_t VinADCLevel)
{
if (VinADCLevel >= 3)
return;
/* hardware need open before close, so don't change position*/
if (VinADCLevel == 0) {
// Vin ADC gain level = 0, using 1M resister
update_latch_stat(E_LATCH_V_SMALL_ON, 0);
update_latch_stat(E_LATCH_V_MID_ON, 0);
latch_multi_ctrl();
} else if (VinADCLevel == 1) {
// Vin ADC gain level = 1, using 30K resister
update_latch_stat(E_LATCH_V_MID_ON, 1); /* need open first */
update_latch_stat(E_LATCH_V_SMALL_ON, 0);
latch_multi_ctrl();
} else if (VinADCLevel == 2) {
// Vin ADC gain level = 2, using 1K resister
update_latch_stat(E_LATCH_V_SMALL_ON, 1); /* need open first */
update_latch_stat(E_LATCH_V_MID_ON, 0);
latch_multi_ctrl();
}
if (VinADCLevel == 0 || VinADCLevel == 1 || VinADCLevel == 2) {
lastVinADCGainLv = VinADCLevel;
}
volt_rec_en = false;
return;
}
void AutoGainChangeIin(int32_t RealCurrent, uint16_t plot_type, uint16_t *no_rec_time)
{
/*
* instru.IinADCGainLv == I_GAIN_100R: 3 level current(large)
* == I_GAIN_3K: 2 level current
* == I_GAIN_100K: 1 level current
* == I_GAIN_3M: 0 level current(small)
* no_rec_time: skip hardware damping
*/
int32_t curr = RealCurrent;
uint16_t plot = plot_type;
uint16_t *skip_time = no_rec_time;
int64_t small_gain = I_GAIN_SMALL_BOUNDARY;
int64_t mid1_gain1 = I_GAIN_MID1_BOUNDARY1;
int64_t mid1_gain2 = I_GAIN_MID1_BOUNDARY2;
int64_t mid2_gain1 = I_GAIN_MID2_BOUNDARY1;
int64_t mid2_gain2 = I_GAIN_MID2_BOUNDARY2;
int64_t large_gain = I_GAIN_LARGE_BOUNDARY;
uint8_t gain0_en = (instru.gain_switch_on & 0b10000000) >> 7;
uint8_t gain1_en = (instru.gain_switch_on & 0b01000000) >> 6;
uint8_t gain2_en = (instru.gain_switch_on & 0b00100000) >> 5;
uint8_t gain3_en = (instru.gain_switch_on & 0b00010000) >> 4;
if (instru.IinADCGainLv == I_GAIN_100R) {
if (curr < large_gain && curr > -1 * large_gain) {
if (curr < mid1_gain1 && curr > -1 * mid1_gain1) {
__switch_lv0(gain0_en, plot, skip_time);
} else if (curr < mid2_gain1 && curr > -1 * mid2_gain1) {
__large_switch_lv1(gain1_en, plot, skip_time);
} else {
__large_switch_lv2(gain2_en, plot, skip_time);
}
}
return;
}
if (instru.IinADCGainLv == I_GAIN_3K) {
if (curr > mid2_gain2 || curr < -1 * mid2_gain2) {
__switch_lv3(gain3_en, plot, skip_time);
} else if (curr < mid2_gain1 && curr > -1 * mid2_gain1) {
if (curr < mid1_gain1 && curr > -1 * mid1_gain1) {
__switch_lv0(gain0_en, plot, skip_time);
} else {
__large_switch_lv1(gain1_en, plot, skip_time);
}
}
return;
}
if (instru.IinADCGainLv == I_GAIN_100K) {
if (curr < mid1_gain1 && curr > -1 * mid1_gain1) {
__switch_lv0(gain0_en, plot, skip_time);
} else if (curr > mid1_gain2 || curr < -1 * mid1_gain2) {
if (curr > mid2_gain2 || curr < -1 * mid2_gain2) {
__switch_lv3(gain3_en, plot, skip_time);
} else {
__small_switch_lv2(gain2_en, plot, skip_time);
}
}
return;
}
if (instru.IinADCGainLv == I_GAIN_3M) {
if (curr > small_gain || curr < -1 * small_gain) {
if (curr > mid2_gain2 || curr < -1 * mid2_gain2) {
__switch_lv3(gain3_en, plot, skip_time);
} else if (curr > mid1_gain2 || curr < -1 * mid1_gain2) {
__small_switch_lv2(gain2_en, plot, skip_time);
} else {
__small_switch_lv1(gain1_en, plot, skip_time);
}
}
return;
}
return;
}
void AutoGainChangeVin(int32_t RealVin)
{
/*
* instru.IinADCGainLv == VIN_GAIN_1K: 2 level volt(large)
* == VIN_GAIN_30K: 1 level volt
* == VIN_GAIN_1M: 0 level volt(small)
*
*/
static int16_t VIN_GAIN_1M_counter = 0;
static int16_t VIN_GAIN_30K_counter = 0;
static int16_t VIN_GAIN_1K_counter = 0;
if(instru.VinADCGainLv == VIN_GAIN_1M){
if(RealVin > VIN_GAIN_SMALL_BOUNDARY || RealVin < -1*VIN_GAIN_SMALL_BOUNDARY){
// switch to 2 level volt(large)
if (RealVin > VIN_GAIN_MID1_BOUNDARY2 || RealVin < -1*VIN_GAIN_MID1_BOUNDARY2){
VIN_GAIN_1K_counter++;
if(VIN_GAIN_1K_counter > 2){
instru.VinADCGainLv = VIN_GAIN_1K;
VinADCGainCtrl(instru.VinADCGainLv);
VIN_GAIN_1K_counter = 0;
}
}
// switch to 1 level volt
else{
VIN_GAIN_30K_counter++;
if(VIN_GAIN_30K_counter > 2){
instru.VinADCGainLv = VIN_GAIN_30K;
VinADCGainCtrl(instru.VinADCGainLv);
VIN_GAIN_30K_counter = 0;
}
}
}else{
VIN_GAIN_1M_counter = 0;
VIN_GAIN_30K_counter = 0;
VIN_GAIN_1K_counter = 0;
}
}
else if(instru.VinADCGainLv == VIN_GAIN_30K){
// switch to 0 level volt(small)
if(RealVin < VIN_GAIN_MID1_BOUNDARY1 && RealVin > -1*VIN_GAIN_MID1_BOUNDARY1){
VIN_GAIN_1M_counter++;
if(VIN_GAIN_1M_counter > 2){
instru.VinADCGainLv = VIN_GAIN_1M;
VinADCGainCtrl(instru.VinADCGainLv);
VIN_GAIN_1M_counter = 0;
}
}
else if (RealVin > VIN_GAIN_MID1_BOUNDARY2 || RealVin < -1*VIN_GAIN_MID1_BOUNDARY2){
// switch to 2 level volt
VIN_GAIN_1K_counter++;
if(VIN_GAIN_1K_counter > 2){
instru.VinADCGainLv = VIN_GAIN_1K;
VinADCGainCtrl(instru.VinADCGainLv);
VIN_GAIN_1K_counter = 0;
}
}else{
VIN_GAIN_1M_counter = 0;
VIN_GAIN_30K_counter = 0;
VIN_GAIN_1K_counter = 0;
}
}
else if(instru.VinADCGainLv == VIN_GAIN_1K){
if(RealVin < VIN_GAIN_LARGE_BOUNDARY && RealVin > -1*VIN_GAIN_LARGE_BOUNDARY){
// switch to 0 level volt(small)
if (RealVin < VIN_GAIN_MID1_BOUNDARY1 && RealVin > -1*VIN_GAIN_MID1_BOUNDARY1){
VIN_GAIN_1M_counter++;
if(VIN_GAIN_1M_counter > 2){
instru.VinADCGainLv = VIN_GAIN_1M;
VinADCGainCtrl(instru.VinADCGainLv);
VIN_GAIN_1M_counter = 0;
}
}
// switch to 1 level volt
else{
VIN_GAIN_30K_counter++;
if(VIN_GAIN_30K_counter > 2){
instru.VinADCGainLv = VIN_GAIN_30K;
VinADCGainCtrl(instru.VinADCGainLv);
VIN_GAIN_30K_counter = 0;
}
}
}else{
VIN_GAIN_1M_counter = 0;
VIN_GAIN_30K_counter = 0;
VIN_GAIN_1K_counter = 0;
}
}
}
#endif
@@ -0,0 +1,63 @@
#ifndef EliteDAC
#define EliteDAC
static bool DACReset;
#define DACCLS 0x02
#define DACOUT 0x31
static void VoutGainControl(uint8_t VOUTLevel){
if(VOUTLevel == 0){
// VOUT gain level = 0, using 240K resister
latch_single_ctrl(E_LATCH_VOUT_SMALL_ON, 0);
}
else if(VOUTLevel == 1){
// VOUT gain level = 1, using 15K resister
latch_single_ctrl(E_LATCH_VOUT_SMALL_ON, 1);
}
else if(VOUTLevel == 2){
// VOUT gain level = 2, using 15K resister
latch_single_ctrl(E_LATCH_VOUT_SMALL_ON, 1);
}
else{
// default using 15K resister
latch_single_ctrl(E_LATCH_VOUT_SMALL_ON, 1);
}
volt_rec_en = false;
}
static int32_t User2Real(uint16_t UserCode){
/* transfer usercode to real voltage value (mV) */
return (int32_t)((UserCode - 25000) / 5);
}
// DAC Vout theoretical boundary <300, 100~ (mV)
#define DAC_VOUT_GAIN_SMALL_BOUNDARY 100000 // 25500(usercode) = 100 mV
#define DAC_VOUT_GAIN_LARGE_BOUNDARY 300000 // 26500(usercode) = 300 mV
#define DAC_VOUT_GAIN_LARGE_BOUNDARY_USERCODE 26500 // 26500(usercode) = 300 mV
#define DAC_VOUT_GAIN_LARGE_BOUNDARY1_USERCODE 23500 // 23500(usercode) = -300 mV
static void AutoGainChangeVout(int32_t userCode){
int32_t RealVolt = (userCode - 25000) * 200; // (userCode - 25000) / 5 * 1000 [1uV]
// switch to 1 level volt(small) 15K
// switch to 2 level volt(large) 240K
if(instru.VoutGainLv == VOUT_GAIN_15K){
if(RealVolt > DAC_VOUT_GAIN_LARGE_BOUNDARY || RealVolt < -1 * DAC_VOUT_GAIN_LARGE_BOUNDARY){
// switch to 2 level volt(large)
instru.VoutGainLv = VOUT_GAIN_240K;
VoutGainControl(instru.VoutGainLv);
}
}
else if(instru.VoutGainLv == VOUT_GAIN_240K){
if(RealVolt < DAC_VOUT_GAIN_SMALL_BOUNDARY && RealVolt > -1 * DAC_VOUT_GAIN_SMALL_BOUNDARY ){
// switch to 1 level volt(small)
instru.VoutGainLv = VOUT_GAIN_15K;
VoutGainControl(instru.VoutGainLv);
}
}
}
#endif
@@ -0,0 +1,201 @@
/*=============================================================================
= instr.h =
=============================================================================*/
#ifndef ELITE_INSTR_H
#define ELITE_INSTR_H
#ifdef __cpulsplus
extern "C" {
#endif
/*==============================
==== headstage instruction ====
=============================*/
struct HEADSTAGE_INSTRUCTION {
uint8_t chip_id;
uint8_t eliteFxn;
// time relation
uint8_t VsetRateIndex;
uint32_t VsetRate;
uint32_t sampleRate;
uint32_t notifyRate;
uint32_t period;
int32_t Vset;
uint16_t VoltConstant;
uint8_t directionInit;
uint32_t step;
uint16_t Ve1;
uint16_t Ve2;
int32_t Vinit;
int32_t Vmax;
int32_t Vmin;
uint32_t steptime;
uint8_t IinADCAutoGainEn;
uint8_t VinADCAutoGainEn;
uint8_t VoutAutoGainEn;
uint8_t IinADCGainLv;
uint8_t VinADCGainLv;
uint16_t VoutGainLv;
uint8_t gain_switch_on;
uint8_t AdcChannel;
bool hign_z_en;
uint16_t cycleNumber;
uint8_t charge;
int32_t constantCurrent;
// uint8_t cc_resistance;
uint8_t cc_cp_speed;
// uni pulse mode
int32_t v0;
uint32_t t_pulse[4];
int32_t v_initial[4];
int32_t v_slope[4];
int32_t v_step[4];
uint32_t t_pulse_min[4];
uint32_t t_pulse_max[4];
int32_t v_stop;
int32_t v_up;
int32_t v_low;
bool v_invert_option;
bool v_stop_direction;
int32_t v_1;
int32_t v_2;
int32_t Vout;
// not use
int32_t Currentmax;
uint8_t VoViSwitch;
} instru = {0};
/** Iin, Vin, Vout **/
#define RIS_ADC_IIN 0x00
#define RIS_ADC_VIN 0x01
#define RIS_DAC_VOUT 0x02
#define RIS_HIGH_Z 0x03
#define RIS_ADC_VOUT 0x04
#define RIS_ADC_BAT 0x05
// ADC Iin gain level !!! move to ADC.h in future
#define I_GAIN_3M 0x00 // lv0,largest gain
#define I_GAIN_100K 0x01 // lv1
#define I_GAIN_3K 0x02 // lv2
#define I_GAIN_100R 0x03 // lv3,the least gain
#define I_GAIN_AUTO 0x04
// ADC Vin gain level !!! move to ADC.h in future
#define VIN_GAIN_1M 0x00
#define VIN_GAIN_30K 0x01
#define VIN_GAIN_1K 0x02
#define VIN_GAIN_AUTO 0x03
// DAC Vout gain level !!! move to DAC.h in future
#define VOUT_GAIN_240K 0x00
#define VOUT_GAIN_15K 0x01
#define VOUT_GAIN_AUTO 0x02
/* DAC reset parameter */
#define DAC_ZERO 25000 // DAC_ZERO is about 0V
// Step time macro
#define STEPTIME_HALF_SEC 5000
#define STEPTIME_ONE_SEC 10000
#define STEPTIME_TWO_SEC 20000
/*********************************************************************
* @fn InitEliteInstruction
*
* @brief Init all INSTRUCTION variable.
*
* @param None.
*
* @return None.
*/
static void InitEliteInstruction(void)
{
instru.chip_id = 0;
instru.eliteFxn = 0; //default is a null event
instru.VsetRateIndex = 0; // vscan rate
instru.VsetRate = 2;
instru.sampleRate = 20; // ADC's sample rate
instru.notifyRate = CLOCK_ONE_SECOND; // send data's rate
instru.period = CLOCK_ONE_SECOND;
instru.Vset = 0; // vscan's volt[5nv]
instru.VoltConstant = DAC_ZERO; // DAC's volt[UC]
instru.directionInit = 1; // 0:reverse, 1:forward
instru.step = 0;
instru.Ve1 = DAC_ZERO; // user set volt[UC]
instru.Ve2 = DAC_ZERO; // user set volt[UC]
instru.Vinit = 0; // user set init volt[5nv]
instru.Vmax = 0; // user set max volt[5nv]
instru.Vmin = 0; // user set min voit[5nv]
instru.IinADCAutoGainEn = 1;
instru.VinADCAutoGainEn = 1;
instru.VoutAutoGainEn = 1;
instru.IinADCGainLv = I_GAIN_100R;
instru.VinADCGainLv = VIN_GAIN_1K;
instru.VoutGainLv = VOUT_GAIN_15K;
instru.gain_switch_on = 0b11110000; // cur auto gain switch, |lv0|lv1|lv2|lv3|none|none|none|none|
instru.AdcChannel = 0; // RIS_ADC_IIN: 0x00, RIS_ADC_VIN: 0x01, RIS_DAC_VOUT: 0x02, RIS_HIGH_Z: 0x03
instru.hign_z_en = 0;
instru.cycleNumber = 1;
instru.charge = 1; // 0:discharge, 1:charge
instru.constantCurrent = 0;
// uni pulse mode
instru.v0 = DAC_ZERO; // t < 0, volt is 0v
instru.v_stop = 0;
instru.t_pulse[0] = 0;
instru.t_pulse[1] = 0;
instru.t_pulse[2] = 0;
instru.t_pulse[3] = 0;
instru.v_initial[0] = 0;
instru.v_initial[1] = 0;
instru.v_initial[2] = 0;
instru.v_initial[3] = 0;
instru.v_slope[0] = 0;
instru.v_slope[1] = 0;
instru.v_slope[2] = 0;
instru.v_slope[3] = 0;
instru.v_step[0] = 0;
instru.v_step[1] = 0;
instru.v_step[2] = 0;
instru.v_step[3] = 0;
instru.t_pulse_min[0] = 0;
instru.t_pulse_min[1] = 0;
instru.t_pulse_min[2] = 0;
instru.t_pulse_min[3] = 0;
instru.t_pulse_max[0] = 0;
instru.t_pulse_max[1] = 0;
instru.t_pulse_max[2] = 0;
instru.t_pulse_max[3] = 0;
instru.v_invert_option = false;
instru.v_stop_direction = true;
instru.v_1 = 0;
instru.v_2 = 0;
instru.Vout = 0;
// not use
instru.Currentmax = 0;
instru.VoViSwitch = 0x01;
return;
}
#ifdef __cpulsplus
}
#endif
#endif
@@ -0,0 +1,105 @@
#ifndef ELITELED
#define ELITELED
static bool btWaitLedFlag = 0;
static bool noEventLedFlag = 0;
static bool preWorkLedFlag = 0;
static bool workingLedFlag = 0;
static bool postWorkLedFlag = 0;
static void WorkModeLED();
static void ModeLED(uint16_t modeStatus) {
btWaitLedFlag = 0;
noEventLedFlag = 0;
preWorkLedFlag = 0;
workingLedFlag = 0;
postWorkLedFlag = 0;
switch (modeStatus) {
case BT_WAIT:
btWaitLedFlag = 1;
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_YELLOWGREEN);
break;
case NO_EVENT:
noEventLedFlag = 1;
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_GREEN);
break;
case PRE_WORK:
preWorkLedFlag = 1;
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_BLUE);
break;
case WORKING:
workingLedFlag = 1;
WorkModeLED();
break;
case POST_WORK:
postWorkLedFlag = 1;
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_GREEN);
break;
default:
break;
}
}
static void checkFlafLED()
{
if(btWaitLedFlag == 1) {
ModeLED(BT_WAIT);
} else if(noEventLedFlag == 1) {
ModeLED(NO_EVENT);
} else if(preWorkLedFlag == 1) {
ModeLED(PRE_WORK);
} else if(workingLedFlag == 1) {
ModeLED(WORKING);
} else if(postWorkLedFlag == 1) {
ModeLED(POST_WORK);
}
}
static void WorkModeLED()
{
switch (instru.eliteFxn) {
case CURVE_IV:
case CURVE_VO:
case CURVE_RT:
case CURVE_VT:
case CURVE_IT:
case CURVE_CV:
case CURVE_CA:
case CURVE_CC:
case CURVE_CP:
case CURVE_OCP:
case CURVE_LSV:
case CURVE_IV_CY:
case CURVE_UNI_PULSE:
case CURVE_DPV:
case CURVE_DPV_SMPRATE:
case CURVE_DPV_ADVANCE:
case CURVE_DPV_ADVANCE_SMPRATE:
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_CYAN);
break;
case CURVE_CALI:
if (instru.AdcChannel == RIS_ADC_IIN) {
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_RED);
} else if (instru.AdcChannel == RIS_ADC_VIN) {
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_ORANGE);
} else if (instru.AdcChannel == RIS_DAC_VOUT) {
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_BLUE);
}
break;
default:
break;
}
}
#endif
@@ -0,0 +1,142 @@
/**
* notify data buffer.
* the length equals to the characteristic 4 which value is 20 bytes.
*
*/
#ifndef ELITENOTIFY
#define ELITENOTIFY
#include "headstage.h"
#include <string.h>
/*notify's input type*/
#define NOTIFY_CH1 0
#define NOTIFY_CH2 1
#define NOTIFY_CH3 2
#define NOTIFY_VOLT_BAT 3
#define NOTIFY_TEMPERATURE 4
#define FINISH_MODE_INS 0b10100000
static uint32_t not_time_stamp;
static uint8_t notify_ch1[4] = {0};
static uint8_t notify_ch2[4] = {0};
static uint8_t notify_ch3[4] = {0};
static uint16_t NotifyVoltBat = 0;
static uint16_t NotifyTemperature = 0;
static uint16_t NotifyCycleNumber = 0;
static bool finishMode = false;
static int32_t notify_ch4 = 0;
static int32_t notify_ch5 = 0;
static int32_t notify_ch6 = 0;
/*
* +--------+----------+---------+---------+---------+-----------+-----------------+
* | id(1B) | time(4B) | ch1(4B) | ch2(4B) | ch3(4B) | cycle(2B) | finish_flag(1B) |
* | bat(4B) | notify#(1B) | ch4(4B) | ch5(4B) | ch6(4B) | __(3B) |
* +---------+-------------+---------+---------+---------+--------+
*/
static void SendNotify() {
static uint8_t notify_times = 0;
uint32_t bat = NotifyVoltBat;
initDATBuf();
// 1 Timestamp = 32 usec; 31 Timestamp ~= 1 msec
not_time_stamp = (Timestamp_get32()) / 31; // msec
not_buf[0] = instru.chip_id;
memcpy(not_buf+1, (uint8_t *)&not_time_stamp, sizeof(not_time_stamp));
memcpy(not_buf+5, notify_ch1, sizeof(notify_ch1));
memcpy(not_buf+9, notify_ch2, sizeof(notify_ch2));
memcpy(not_buf+13, notify_ch3, sizeof(notify_ch3));
memcpy(not_buf+17, (uint8_t *)&NotifyCycleNumber, sizeof(NotifyCycleNumber));
if (finishMode) {
not_buf[19] = (FINISH_MODE_INS) & 0b11110000;
} else {
not_buf[19] = 0 & 0b11110000;
}
memcpy(not_buf+20, (uint8_t *)&bat, sizeof(bat));
memcpy(not_buf+24, &notify_times, sizeof(notify_times));
memcpy(not_buf+25, (uint8_t *)&notify_ch4, sizeof(notify_ch4));
memcpy(not_buf+29, (uint8_t *)&notify_ch5, sizeof(notify_ch5));
memcpy(not_buf+33, (uint8_t *)&notify_ch6, sizeof(notify_ch6));
for (int i = 37; i < BLE_DAT_BUFF_SIZE; i++){
not_buf[i] = 0;
}
SimpleProfile_SetParameter(BLE_DAT_BUFF_CHAR, BLE_DAT_BUFF_SIZE, not_buf);
notify_times++;
}
static void initDATBuf(){
for (int i = 0; i < BLE_DAT_BUFF_SIZE; i++){
not_buf[i] = 0;
}
}
static void initINSBuf(){
for (int i = 0; i < BLE_INS_BUFF_SIZE; i++){
ins_buf[i] = 0;
}
}
static void initCISBuf(){
for (int i = 0; i < BLE_CIS_BUFF_SIZE; i++){
cis_buf[i] = 0;
}
}
static void initRawDataBuf(){
not_time_stamp = 0;
NotifyCycleNumber = 0;
finishMode = false;
for (int i = 0; i < 4; i++){
notify_ch1[i] = 0;
notify_ch2[i] = 0;
notify_ch3[i] = 0;
}
notify_ch4 = 0;
notify_ch5 = 0;
notify_ch6 = 0;
}
static void FlushNotify(){
initRawDataBuf();
initDATBuf();
not_buf[0] = instru.chip_id;
SimpleProfile_SetParameter(BLE_DAT_BUFF_CHAR, BLE_DAT_BUFF_SIZE, not_buf);
}
static void InputNotify(int NotifyType, int32_t Data){
switch (NotifyType) {
case NOTIFY_CH1:
memcpy(notify_ch1, (uint8_t *)&Data, sizeof(Data));
break;
case NOTIFY_CH3:
memcpy(notify_ch3, (uint8_t *)&Data, sizeof(Data));
break;
case NOTIFY_CH2 :
memcpy(notify_ch2, (uint8_t *)&Data, sizeof(Data));
break;
case NOTIFY_VOLT_BAT :
NotifyVoltBat = (uint16_t)Data;
break;
case NOTIFY_TEMPERATURE :
NotifyTemperature = (uint16_t)Data;
break;
}
}
#endif
@@ -0,0 +1,49 @@
#ifndef ELITERESET
#define ELITERESET
static void reset() {
megaStiEnable = false;
PeriodicEvent = false; // is there an PeriodicEvent?
Free_Work_Mode = true; // Free(WorkModeData)
initINSBuf();
initDATBuf();
latch_single_ctrl(E_LATCH_HIGH_Z, 0); // HIGH Z MODE // 1: close; 0: open;
instru.VinADCGainLv = VIN_GAIN_1K;
VinADCGainCtrl(instru.VinADCGainLv);
instru.IinADCGainLv = I_GAIN_100R;
IinADCGainCtrl(instru.IinADCGainLv);
instru.VoutGainLv = VOUT_GAIN_15K;
VoutGainControl(instru.VoutGainLv);
DAC0_W_T(Usercode_Correction_to_DAC(instru.VoutGainLv, 25000));
ModeLED(NO_EVENT);
CPUdelay(1600);
}
static void Eliteinterrupt() {
megaStiEnable = false;
PeriodicEvent = false; // is there an PeriodicEvent?
Free_Work_Mode = true; // Free(WorkModeData)
initINSBuf();
initDATBuf();
latch_single_ctrl(E_LATCH_HIGH_Z, 0); // HIGH Z MODE // 1: close; 0: open;
instru.VoutGainLv = VOUT_GAIN_15K;
VoutGainControl(instru.VoutGainLv);
DAC0_W_T(Usercode_Correction_to_DAC(instru.VoutGainLv, 25000));
ADC_rxbuf = 0;
ModeLED(NO_EVENT);
CPUdelay(8000);
}
#endif
@@ -0,0 +1,877 @@
/*=============================================================================
= wm.h =
=============================================================================*/
#ifndef ELITE_WORK_DATA_H
#define ELITE_WORK_DATA_H
#ifdef __cplusplus
extern "C" {
#endif
#include "EliteInstruction.h"
/***** Template of Measure and VoltOut parameter *****/
#define VOUT_PARA \
int32_t _Vinit; \
int32_t _Vmax; \
int32_t _Vmin; \
int32_t _Vset; \
uint32_t _Vstep; \
bool _direction_up; \
bool _current_direction_up; \
uint16_t _cycleNumber
#define MEAS_CURR(_m) (((struct wm_meas_t *)(_m))->_measureCurrent)
#define MEAS_VIN(_m) (((struct wm_meas_t *)(_m))->_measureVin)
#define MEAS_VOUT(_m) (((struct wm_meas_t *)(_m))->_measureVout)
#define MEAS_BAT(_m) (((struct wm_meas_t *)(_m))->_measureBat)
#define VOLT_SW(_m) (((struct wm_meas_t *)(_m))->_VoViSwitch)
struct wm_meas_t {
int32_t _measureCurrent;
int32_t _measureVin;
int32_t _measureVout;
int32_t _measureBat;
uint8_t _VoViSwitch;
};
/* member of mode */
struct wm_vo_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vset;
int32_t _Vinit;
};
struct wm_it_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vset;
int32_t _Vinit;
};
struct wm_vt_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
};
struct wm_rt_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vset;
int32_t _Vinit;
};
struct wm_iv_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
VOUT_PARA;
};
struct wm_iv_cy_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
VOUT_PARA;
};
struct wm_cc_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vmax;
int32_t _Vmin;
int32_t _Vset;
int32_t _Iset;
uint8_t _charge;
};
struct wm_cv_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
VOUT_PARA;
};
struct wm_lsv_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
VOUT_PARA;
};
struct wm_ca_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vinit;
int32_t _Vset;
};
struct wm_pulse_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vset;
int32_t _sti_v1;
int32_t _sti_v2;
int32_t _sti_v3;
int32_t _sti_v4;
int32_t _sti_v5;
int32_t _sti_v6;
int32_t _sti_v7;
int32_t _sti_t1;
int32_t _sti_t2;
int32_t _sti_t3;
int32_t _sti_t4;
int32_t _sti_t5;
int32_t _sti_t6;
int32_t _sti_t7;
int32_t _sti_t;
int32_t _sti_v; //output voltage now
int32_t _sti_t_flag; //Where's the time stage turn
uint16_t _sti_cy;
uint16_t _sti_lp;
};
struct wm_uni_pulse_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vset;
int32_t _v0;
uint32_t _t_pulse[4];
int32_t _v_initial[4];
int32_t _v_slope[4];
int32_t _v_step[4];
uint32_t _t_period;
uint32_t _t_pa[4];
uint32_t _t_pulse_min[4];
uint32_t _t_pulse_max[4];
};
struct wm_dpv_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vset;
int32_t _v0;
uint32_t _t_pulse[4];
int32_t _v_initial[4];
int32_t _v_slope[4];
int32_t _v_step[4];
uint32_t _t_period;
uint32_t _t_pa[4];
int32_t _v_stop;
bool _v_curr_direc;
int32_t _v_amp;
uint32_t _t_pulse_min[4];
uint32_t _t_pulse_max[4];
bool _v_direc_init;
};
struct wm_dpv_advance_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vset;
int32_t _v0;
uint32_t _t_pulse[4];
int32_t _v_initial[4];
int32_t _v_slope[4];
int32_t _v_step[4];
uint32_t _t_period;
uint32_t _t_pa[4];
int32_t _v_stop;
int32_t _v_up;
int32_t _v_low;
int32_t _v_amp;
int32_t _v_1;
int32_t _v_2;
uint32_t _t_pulse_min[4];
uint32_t _t_pulse_max[4];
uint16_t _cycleNumber;
bool _v_curr_direc;
bool _v_direc_init;
bool _v_invert_option;
bool _v_stop_direction;
};
struct wm_ocp_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
};
struct wm_adc_cali_ctx_t {
struct wm_meas_t measure;
uint16_t _cali_count;
int32_t _ADCValueSUM;
};
#define GET_ADC_SUM(_m) (((struct wm_adc_cali_ctx_t *)(_m))->_ADCValueSUM)
#define GET_CALI_COUNT(_m) (((struct wm_adc_cali_ctx_t *)(_m))->_cali_count)
struct wm_cp_ctx_t {
/* WARNING: please keep MEASURE at first!! */
struct wm_meas_t measure;
int32_t _Vmax;
int32_t _Vmin;
int32_t _Vset;
int32_t _Iset;
uint8_t _charge;
};
int wm_init(void);
int wm_deinit(void);
void *wm_get(void);
/*=============================================================================
= wm.c =
=============================================================================*/
static void *workMode_p = NULL;
static bool Free_Work_Mode = false;
/* init mode func */
static int __vo_create(void)
{
struct wm_meas_t *m;
struct wm_vo_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_vo_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
*wm = p;
return 0;
}
static int __it_create(void)
{
struct wm_meas_t *m;
struct wm_it_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_it_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
*wm = p;
return 0;
}
static int __vt_create(void)
{
struct wm_meas_t *m;
struct wm_vt_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_vt_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
*wm = p;
return 0;
}
static int __rt_create(void)
{
struct wm_meas_t *m;
struct wm_rt_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_rt_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
*wm = p;
return 0;
}
static int __iv_create(void)
{
struct wm_meas_t *m;
struct wm_iv_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_iv_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vmax = (instru.Vmax - 25000) * 4 * 10000; //[5nV]
p->_Vmin = (instru.Vmin - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
p->_Vstep = 0;
p->_direction_up = true;
p->_current_direction_up = true;
p->_cycleNumber = instru.cycleNumber;
*wm = p;
return 0;
}
static int __iv_cy_create(void)
{
struct wm_meas_t *m;
struct wm_iv_cy_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_iv_cy_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vmax = (instru.Vmax - 25000) * 4 * 10000; //[5nV]
p->_Vmin = (instru.Vmin - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
p->_Vstep = 0;
p->_direction_up = true;
p->_current_direction_up = true;
p->_cycleNumber = instru.cycleNumber;
*wm = p;
return 0;
}
static int __cc_create(void)
{
struct wm_meas_t *m;
struct wm_cc_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_cc_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vmax = (instru.Vmax - 25000) * 4 * 10000; //[5nV]
p->_Vmin = (instru.Vmin - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
p->_charge = instru.charge;
p->_Iset = instru.constantCurrent * 200 ;
//[50pA] //controller UI 15000uA => Elite 1500000 => 1500000 * 10 * 1000 / 50 [50pA]
*wm = p;
return 0;
}
static int __cv_create(void)
{
struct wm_meas_t *m;
struct wm_cv_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_cv_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vmax = (instru.Vmax - 25000) * 4 * 10000; //[5nV]
p->_Vmin = (instru.Vmin - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
p->_Vstep = 0;
p->_direction_up = true;
p->_current_direction_up = true;
p->_cycleNumber = instru.cycleNumber;
*wm = p;
return 0;
}
static int __lsv_create(void)
{
struct wm_meas_t *m;
struct wm_lsv_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_lsv_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vmax = (instru.Vmax - 25000) * 4 * 10000; //[5nV]
p->_Vmin = (instru.Vmin - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
p->_Vstep = 0;
p->_direction_up = true;
p->_current_direction_up = true;
p->_cycleNumber = instru.cycleNumber;
*wm = p;
return 0;
}
static int __ca_create(void)
{
struct wm_meas_t *m;
struct wm_ca_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_ca_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vinit = (instru.Vinit - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
*wm = p;
return 0;
}
static int __uni_pulse_create(void)
{
struct wm_meas_t *m;
struct wm_uni_pulse_ctx_t *p;
void **wm = &workMode_p;
uint32_t pul_acc = 0;
int i;
p = malloc(sizeof(struct wm_uni_pulse_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vset = 0;
p->_v0 = UC_TO_5NV(instru.v0); //[5nV]
p->_t_pulse[0] = instru.t_pulse[0];
p->_t_pulse[1] = instru.t_pulse[1];
p->_t_pulse[2] = instru.t_pulse[2];
p->_t_pulse[3] = instru.t_pulse[3];
p->_v_initial[0] = UC_TO_5NV(instru.v_initial[0]); //[5nv]
p->_v_initial[1] = UC_TO_5NV(instru.v_initial[1]); //[5nv]
p->_v_initial[2] = UC_TO_5NV(instru.v_initial[2]); //[5nv]
p->_v_initial[3] = UC_TO_5NV(instru.v_initial[3]); //[5nv]
p->_v_slope[0] = instru.v_slope[0];
p->_v_slope[1] = instru.v_slope[1];
p->_v_slope[2] = instru.v_slope[2];
p->_v_slope[3] = instru.v_slope[3];
p->_v_step[0] = UC_TO_5NV(instru.v_step[0]); //[5nv]
p->_v_step[1] = UC_TO_5NV(instru.v_step[1]); //[5nv]
p->_v_step[2] = UC_TO_5NV(instru.v_step[2]); //[5nv]
p->_v_step[3] = UC_TO_5NV(instru.v_step[3]); //[5nv]
p->_t_period = 0;
for (i=0; i<4; i++) {
p->_t_pa[i] = pul_acc + p->_t_pulse[i];
pul_acc = p->_t_pa[i];
p->_t_period += p->_t_pulse[i];
}
instru.period = p->_t_period;
p->_t_pulse_min[0] = (instru.t_pulse[0] - 100) * instru.t_pulse_min[0] / 100 + 50;
p->_t_pulse_min[1] = (instru.t_pulse[1] - 100) * instru.t_pulse_min[1] / 100 + 50;
p->_t_pulse_min[2] = (instru.t_pulse[2] - 100) * instru.t_pulse_min[2] / 100 + 50;
p->_t_pulse_min[3] = (instru.t_pulse[3] - 100) * instru.t_pulse_min[3] / 100 + 50;
p->_t_pulse_max[0] = (instru.t_pulse[0] - 100) * instru.t_pulse_max[0] / 100 + 50;
p->_t_pulse_max[1] = (instru.t_pulse[1] - 100) * instru.t_pulse_max[1] / 100 + 50;
p->_t_pulse_max[2] = (instru.t_pulse[2] - 100) * instru.t_pulse_max[2] / 100 + 50;
p->_t_pulse_max[3] = (instru.t_pulse[3] - 100) * instru.t_pulse_max[3] / 100 + 50;
*wm = p;
return 0;
}
static int __dpv_create(void)
{
struct wm_meas_t *m;
struct wm_dpv_ctx_t *p;
void **wm = &workMode_p;
uint32_t pul_acc = 0;
int i;
p = malloc(sizeof(struct wm_dpv_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vset = 0;
p->_v0 = instru.v0; //[5nV]
p->_v_stop = instru.v_stop; //[5nV]
p->_t_pulse[0] = instru.t_pulse[0];
p->_t_pulse[1] = instru.t_pulse[1];
p->_v_initial[0] = instru.v_initial[0]; //[5nv]
p->_v_initial[1] = instru.v_initial[1]; //[5nv]
p->_v_slope[0] = instru.v_slope[0];
p->_v_slope[1] = instru.v_slope[1];
p->_v_step[0] = instru.v_step[0]; //[5nv]
p->_v_step[1] = instru.v_step[1]; //[5nv]
p->_t_period = 0;
for (i=0; i<4; i++) {
p->_t_pa[i] = pul_acc + p->_t_pulse[i];
pul_acc = p->_t_pa[i];
p->_t_period += p->_t_pulse[i];
}
instru.period = p->_t_period;
p->_v_direc_init = instru.directionInit;
p->_v_curr_direc = instru.directionInit;
p->_v_amp = instru.v_initial[1] - instru.v_initial[0];
p->_t_pulse_min[0] = (instru.t_pulse[0] - 100) * instru.t_pulse_min[0] / 100 + 50;
p->_t_pulse_min[1] = (instru.t_pulse[1] - 100) * instru.t_pulse_min[1] / 100 + 50;
p->_t_pulse_max[0] = (instru.t_pulse[0] - 100) * instru.t_pulse_max[0] / 100 + 50;
p->_t_pulse_max[1] = (instru.t_pulse[1] - 100) * instru.t_pulse_max[1] / 100 + 50;
*wm = p;
return 0;
}
static int __dpv_advance_create(void)
{
struct wm_meas_t *m;
struct wm_dpv_advance_ctx_t *p;
void **wm = &workMode_p;
uint32_t pul_acc = 0;
int i;
p = malloc(sizeof(struct wm_dpv_advance_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vset = 0;
p->_v0 = instru.v0; //[5nV]
p->_v_stop = instru.v_stop; //[5nV]
p->_t_pulse[0] = instru.t_pulse[0];
p->_t_pulse[1] = instru.t_pulse[1];
p->_v_initial[0] = instru.v_initial[0]; //[5nv]
p->_v_initial[1] = instru.v_initial[1]; //[5nv]
p->_v_slope[0] = instru.v_slope[0];
p->_v_slope[1] = instru.v_slope[1];
p->_v_step[0] = instru.v_step[0]; //[5nv]
p->_v_step[1] = instru.v_step[1]; //[5nv]
p->_t_period = 0;
for (i=0; i<4; i++) {
p->_t_pa[i] = pul_acc + p->_t_pulse[i];
pul_acc = p->_t_pa[i];
p->_t_period += p->_t_pulse[i];
}
instru.period = p->_t_period;
p->_v_direc_init = instru.directionInit;
p->_v_curr_direc = instru.directionInit;
p->_v_stop_direction = instru.v_stop_direction;
p->_v_up = instru.v_up;
p->_v_low = instru.v_low;
p->_v_amp = instru.v_initial[1] - instru.v_initial[0];
p->_v_1 = instru.v_1;
p->_v_2 = instru.v_2;
p->_t_pulse_min[0] = (instru.t_pulse[0] - 100) * instru.t_pulse_min[0] / 100 + 50;
p->_t_pulse_min[1] = (instru.t_pulse[1] - 100) * instru.t_pulse_min[1] / 100 + 50;
p->_t_pulse_max[0] = (instru.t_pulse[0] - 100) * instru.t_pulse_max[0] / 100 + 50;
p->_t_pulse_max[1] = (instru.t_pulse[1] - 100) * instru.t_pulse_max[1] / 100 + 50;
p->_cycleNumber = instru.cycleNumber;
p->_v_invert_option = instru.v_invert_option;
*wm = p;
return 0;
}
static int __ocp_create(void)
{
struct wm_meas_t *m;
struct wm_ocp_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_ocp_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
*wm = p;
return 0;
}
static int __adc_cali_create()
{
struct wm_meas_t *m;
struct wm_adc_cali_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_adc_cali_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_ADCValueSUM = 0;
p->_cali_count = 0;
*wm = p;
return 0;
}
static int __cp_create(void)
{
struct wm_meas_t *m;
struct wm_cp_ctx_t *p;
void **wm = &workMode_p;
p = malloc(sizeof(struct wm_cp_ctx_t));
if (!p) return -1;
m = (struct wm_meas_t *)p;
m->_measureCurrent = 0;
m->_measureVin = 0;
m->_measureVout = 0;
m->_measureBat = 0;
m->_VoViSwitch = instru.VoViSwitch;
p->_Vmax = (instru.Vmax - 25000) * 4 * 10000; //[5nV]
p->_Vmin = (instru.Vmin - 25000) * 4 * 10000; //[5nV]
p->_Vset = 0;
p->_charge = instru.charge;
p->_Iset = instru.constantCurrent * 200 ;
//[50pA] //controller UI 15000uA => Elite 1500000 => 1500000 * 10 * 1000 / 50 [50pA]
*wm = p;
return 0;
}
int wm_init(void)
{
int mode = instru.eliteFxn;
void **wm = &workMode_p;
if (*wm) return -1;
switch (mode) {
case CURVE_VO:
if (__vo_create()) return -2;
break;
case CURVE_IT:
if (__it_create()) return -2;
break;
case CURVE_VT:
if (__vt_create()) return -2;
break;
case CURVE_RT:
if (__rt_create()) return -2;
break;
case CURVE_IV:
if (__iv_create()) return -2;
break;
case CURVE_IV_CY:
if (__iv_cy_create()) return -2;
break;
case CURVE_CC:
if (__cc_create()) return -2;
break;
case CURVE_CV:
if (__cv_create()) return -2;
break;
case CURVE_LSV:
if (__lsv_create()) return -2;
break;
case CURVE_CA:
if (__ca_create()) return -2;
break;
case CURVE_UNI_PULSE:
if (__uni_pulse_create()) return -2;
break;
case CURVE_OCP:
if (__ocp_create()) return -2;
break;
case CURVE_DPV:
case CURVE_DPV_SMPRATE:
if (__dpv_create()) return -2;
break;
case CURVE_DPV_ADVANCE:
case CURVE_DPV_ADVANCE_SMPRATE:
if (__dpv_advance_create()) return -2;
break;
case CURVE_CALI:
if (__adc_cali_create()) return -2;
break;
case CURVE_CP:
if (__cp_create()) return -2;
break;
default:
// printf("DO NOT support!!");
return -3;
}
return 0;
}
int wm_deinit(void)
{
void **wm = &workMode_p;
if (*wm) {
free(*wm);
*wm = NULL;
} else {
return -1;
}
return 0;
}
void *wm_get(void)
{
void *wm = workMode_p;
return wm;
}
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,112 @@
/*
***********************************************************
Read battery's method
***********************************************************
1.read_adc_raw_data(RIS_ADC_BAT, spi_ADC_rxbuf, spi_ADC_txbuf);
let "spi_ADC_rxbuf" be 8000
8000 * 187.5uV * 2 = 3000000uV = 3V ;
2.AONBatMonBatteryVoltageGet()
let "AONBatMonBatteryVoltageGet()" be 768
768 * 125 / 320 / 100 = 768 / 256 = 3V ;
if you want to use first method, and get value 768
conversion: 8000 * 187.5 * 1e-6 * 2 / 125 * 320 * 100 = 768
=> 8000 * 12 / 125 = 768
*/
#ifndef HEADSTAGE_BATT_H
#define HEADSTAGE_BATT_H
#include <driverlib/aon_batmon.h>
#define MAX_BATTERY_CAPACITY 4200
static uint8_t headstage_battery_percent() {
static uint8_t battery_percent = 100;
uint8_t internal_battery_percent;
uint32_t internal_batt_sense = AONBatMonBatteryVoltageGet();
internal_batt_sense = (internal_batt_sense * 125) >> 5;
internal_batt_sense = (internal_batt_sense * 100) / MAX_BATTERY_CAPACITY;
internal_battery_percent = internal_batt_sense & 0xFF;
if (internal_battery_percent < battery_percent) battery_percent = internal_battery_percent;
return battery_percent;
}
static void headstage_battery_volt(){
uint32_t bat_volt = 0;
ADC_rxbuf = MEASURE_BATTERY();
bat_volt = ADC_rxbuf;
bat_volt = (400 * bat_volt) - 268300; // uV
bat_volt /= 1e3;
// initCISBuf();
// cis_buf[0] = 6; //data len
// cis_buf[1] = BAT_DEV_TEST;
// cis_buf[2] = (uint8_t)(bat_volt >> 8);
// cis_buf[3] = (uint8_t)(bat_volt);
// SimpleProfile_SetParameter(BLE_CIS_BUFF_CHAR, BLE_CIS_BUFF_SIZE, cis_buf);
InputNotify(NOTIFY_VOLT_BAT, bat_volt);
}
static void headstage_temperature(void) {
int32_t curTemp = 0;
curTemp = AONBatMonTemperatureGetDegC();
InputNotify(NOTIFY_TEMPERATURE,curTemp);
}
static bool EliteADCBattery(){
static uint8_t ADCSwitch = 0;
bool read_adc_flag = false;
if(ADCSwitch == 0){ /**read V**/
ADC_rxbuf = MEASURE_BATTERY();
ADCSwitch++;
}
else if(ADCSwitch == 1){ /**read V**/
ADC_rxbuf = MEASURE_BATTERY();
ADCSwitch++;
}
else if(ADCSwitch == 2){ /**read V(buffer)**/
headstage_battery_volt();
headstage_temperature();
ADCSwitch++;
read_adc_flag = true;
}else if(ADCSwitch == 3){
batteryCheck_flag = false;
tempCheck_flag = false;
ADCSwitch = 0;
}
return read_adc_flag;
}
static void measureBat(){
if(GPT.BatteryCheckCounter >= 50000){//5min=3000000, 5s=50000
GPT.BatteryCheckCounter = 0;
batteryCheck_flag = true;
}
if(GPT.BatteryADCCounter >= 15 && batteryCheck_flag){
GPT.BatteryADCCounter = 0; //To get the data right, ADC must be delay 1.5ms
batteryADC_flag = true;
if(batteryADC_flag){
EliteADCBattery();
batteryADC_flag = false;
}
}
uint16_t bat = NotifyVoltBat;
if( bat < 2900 && bat > 20){
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_LOW_BAT);
CPUdelay_ms(500);
latch_single_ctrl(E_LATCH_5V_ENABLE, 0);
}
}
#endif // HEADSTAGE_BATT_H
@@ -0,0 +1,111 @@
#ifndef ELITE_DEF
#define ELITE_DEF
// define BT instruction
#define INS_TYPE_RIS 0x30
#define INS_TYPE_VIS 0xC0
#define INS_TYPE_CIS 0x70
// VIS (virtual instruction)
#define VIS_RST 0xF0
#define VIS_ASK 0x30
#define VIS_STI 0xC0
#define VIS_FUH 0x90
#define VIS_INT 0x60
#define VIS_SHIFT_200K 0xA0
#define VIS_SHIFT_10K 0xE0
#define VIS_SHIFT_200R 0x80
#define VIS_DEVICE_SHINY 0x10
#define VIS_SHINY_DIS 0x20
// RIS (real instruction)
enum all_mode_e {
CURVE_IV = 0x01, // I-V Curve
CURVE_IV_CY = 0x02, // Cycle I-V
CURVE_VO = 0x03, // Function Generator
CURVE_RT = 0x04, // R-T Graph
CURVE_VT = 0x05, // V-T Graph
CURVE_IT = 0x06, // I-T Graph
CURVE_CC = 0x07, // Constant Current (CC)
CURVE_OCP = 0x08, // Open Circuit Potential (OCP)
CURVE_CV = 0x09, // Cyclic Voltammetry (CV)
CURVE_LSV = 0x0A, // Linear Sweep Voltammetry (LSV)
CURVE_CA = 0x0B, // Chronoamperometric Graph (CA)
CURVE_CP = 0x0C,
CURVE_UNI_PULSE = 0x0D, // Pulse Sensing (universal pulse)
CURVE_DPV = 0x0E, // Differential Pulse Voltammetry (DPV)
CURVE_DPV_SMPRATE = 0x0F,
CURVE_DPV_ADVANCE = 0x10,
CURVE_DPV_ADVANCE_SMPRATE = 0x11,
CURVE_CALI = 0xF1,
SET_SAMPLE_RATE = 0xE0,
SET_ADC_DAC_GAIN = 0xE1,
SET_PARA = 0xE2
};
enum set_para_e {
DAC_VOLT = 0x01,
};
enum dev_para_e {
VERSION_DEV_TEST = 0x01,
BAT_DEV_TEST = 0x02,
TEMP_DEV_TEST = 0x03,
LED_DEV_TEST = 0x04,
};
// CIS (control instruction)
#define CIS_VERSION 0x40
#define CIS_VOLT 0x10
#define CIS_TEMPERATURE 0x80
// mode parameter
#define STEP_TO_VSETRATE(step) step2VsetRate(step)
#define VMAX(v1,v2) ((v1 >= v2) ? v1 : v2)
#define VMIN(v1,v2) ((v1 < v2) ? v1 : v2)
#define VDIRECTION(v1,v2) ((v1 > v2) ? 0 : 1)
#define AFTER_READ_I 0
#define AFTER_READ_V 1
//Elite LED
#define COLOR_BLACK 0x00
#define COLOR_RED 0x01
#define COLOR_ORANGE 0x02
#define COLOR_YELLOW 0x03
#define COLOR_GREEN 0x04
#define COLOR_BLUE 0x05
#define COLOR_CYAN 0x06
#define COLOR_MAGENTA 0x07
#define COLOR_PURPLE 0x08
#define COLOR_WHITE 0x09
#define COLOR_YELLOWGREEN 0x0A
#define COLOR_EMERALD 0x0B
#define COLOR_YELLOW_DARK 0xF3
#define COLOR_GREEN_DARK 0xF4
#define COLOR_BLUE_DARK 0xF5
#define COLOR_CYAN_DARK 0xF6
#define COLOR_PURPLE_DARK 0xF8
#define BT_WAIT 0x01
#define NO_EVENT 0x02
#define PRE_WORK 0x03
#define WORKING 0x04
#define POST_WORK 0x05
#define VALUE_ZERO_TO_ONE(_v) (_v == 0) ? 1 : _v
//plot_type
#define IT_PLOT 1
#define VT_PLOT 2
#define VOUT_PLOT 3
#define IIN_VIN_PLOT 4
#define IIN_VIN_VOUT_PLOT 5
#define CLOCK_ONE_SECOND 10000
#endif
@@ -0,0 +1,900 @@
#ifndef ELITE_MODE_ADC_DAC
#define ELITE_MODE_ADC_DAC
#define Vset instru.Vset
static void volt_out() {
static uint16_t DACOutCode;
static int32_t DeltaVout;
if (DACReset) {
instru.Vout = Vset;
} else {
DeltaVout = Vset - (instru.Vout);
instru.Vout = instru.Vout + DeltaVout;
}
if (instru.Vout >= 1100000000) { //1100000000 = 5.5V
instru.Vout = 1100000000;
} else if (instru.Vout <= -1000000000) { //-1000000000 = -5V
instru.Vout = -1000000000;
}
instru.VoltConstant = instru.Vout / 40000 + 25000; //5nV=>usercode
DACOutCode = Usercode_Correction_to_DAC(instru.VoutGainLv, instru.VoltConstant);
DAC0_W_T(DACOutCode);
return;
}
static void vscan_volt_out(void)
{
void *wm = wm_get();
uint16_t DACOutCode;
int32_t DeltaVout;
int32_t Vin;
Vin = MEAS_VIN(wm) * 200;//[5nV]
if (DACReset) {
instru.Vout = Vset + Vin;
} else {
DeltaVout = Vset - (instru.Vout - Vin);
instru.Vout = instru.Vout + DeltaVout;
}
instru.VoltConstant = instru.Vout / 40000 + 25000;//5nV=>usercode
DACOutCode = Usercode_Correction_to_DAC(instru.VoutGainLv, instru.VoltConstant);
DAC0_W_T(DACOutCode);
return;
}
static void CalcuResistance()
{
/* Elite 100000 = 100R
Elite 1000000 = 1KR
Elite 10000000 = 10KR
Elite 100000000 = 100KR
Elite 1000000000 = 1MR
*/
struct wm_rt_ctx_t *rt = (struct wm_rt_ctx_t *)wm_get();
struct wm_meas_t *m = &rt->measure;
int64_t resist;
int64_t volt = instru.Vout / 200; // [uV]
int64_t current = (int64_t)(m->_measureCurrent);
resist = volt * 1000000 / current; //R = V / Iin; [mOhm]
InputNotify(NOTIFY_CH3, resist);
}
static void DACenable(uint8_t afterRead){
void *wm = wm_get();
if (afterRead == AFTER_READ_I) {
switch (instru.eliteFxn) {
case CURVE_CC:
cc_vscan();
volt_out();
break;
case CURVE_CP:
cp_vscan();
volt_out();
break;
case CURVE_UNI_PULSE:
volt_out();
break;
default:
break;
}
} else if (afterRead == AFTER_READ_V) {
switch (instru.eliteFxn) {
case CURVE_IV_CY:
case CURVE_IV:
case CURVE_IT:
case CURVE_VO:
volt_out();
break;
case CURVE_RT:
volt_out();
CalcuResistance();
break;
case CURVE_CV:
case CURVE_CA:
case CURVE_LSV:
case CURVE_DPV:
case CURVE_DPV_SMPRATE:
case CURVE_DPV_ADVANCE:
case CURVE_DPV_ADVANCE_SMPRATE:
vscan_volt_out();
break;
default:{
break;
}
}
}
}
/*
* define how long damping time for manual current stalls, to skip damping time
* any level switch to 0 level has 80ms damping time
* any level switch to 1 level has 20ms damping time
* any level switch to 2 level has 10ms damping time
* any level switch to 3 level has 10ms damping time
*/
#define CNT_TO_I_GAIN_3M_IIN_VIN_VOUT_PLOT 7 // 7 * 12ms = 84ms
#define CNT_TO_I_GAIN_100K_IIN_VIN_VOUT_PLOT 2 // 2 * 12ms = 24ms
#define CNT_TO_I_GAIN_3K_IIN_VIN_VOUT_PLOT 5 // 5 * 12ms = 60ms
#define CNT_TO_I_GAIN_100R_IIN_VIN_VOUT_PLOT 5 // 5 * 12ms = 60ms
#define CNT_TO_I_GAIN_3M_IIN_VIN_PLOT 10 // 10 * 8ms = 80ms
#define CNT_TO_I_GAIN_100K_IIN_VIN_PLOT 3 // 3 * 8ms = 24ms
#define CNT_TO_I_GAIN_3K_IIN_VIN_PLOT 5 // 5 * 8ms = 40ms
#define CNT_TO_I_GAIN_100R_IIN_VIN_PLOT 5 // 5 * 8ms = 40ms
#define CNT_TO_I_GAIN_3M_IT_PLOT 20 // 20 * 4ms = 80ms
#define CNT_TO_I_GAIN_100K_IT_PLOT 5 // 5 * 4ms = 20ms
#define CNT_TO_I_GAIN_3K_IT_PLOT 5 // 5 * 4ms = 20ms
#define CNT_TO_I_GAIN_100R_IT_PLOT 5 // 5 * 4ms = 20ms
static void read_Iin_change_gain(uint16_t plot_type)
{
/* read Iin and cali value save as MEAS_CURR(wm)
* if auto gain:
* do NOT record the Iin after changing gain, time is according to damping time
* if static gain:
* change gain if gain is different from last gain
*/
uint16_t plot = plot_type;
static uint16_t no_rec_time = 0;
static uint8_t cnt = 0;
void *wm = wm_get();
if (instru.IinADCAutoGainEn > 1)
return;
ADC_rxbuf = MEASURE_CURRENT();
MEAS_CURR(wm) = DecodeADCValue(instru.IinADCGainLv, RIS_ADC_IIN, ADC_rxbuf);
if (instru.IinADCAutoGainEn) {
AutoGainChangeIin(MEAS_CURR(wm), plot, &no_rec_time);
} else {
if (lastIinADCGainLevel != instru.IinADCGainLv) {
IinADCGainCtrl(instru.IinADCGainLv);
if (plot_type == IT_PLOT) {
if (instru.IinADCGainLv == I_GAIN_3K) {
no_rec_time = CNT_TO_I_GAIN_3K_IT_PLOT;
} else if (instru.IinADCGainLv == I_GAIN_100K) {
no_rec_time = CNT_TO_I_GAIN_100K_IT_PLOT;
} else if (instru.IinADCGainLv == I_GAIN_3M) {
no_rec_time = CNT_TO_I_GAIN_3M_IT_PLOT;
} else {
no_rec_time = CNT_TO_I_GAIN_100R_IT_PLOT;
}
}
if (plot_type == IIN_VIN_PLOT) {
if (instru.IinADCGainLv == I_GAIN_3K) {
no_rec_time = CNT_TO_I_GAIN_3K_IIN_VIN_PLOT;
} else if (instru.IinADCGainLv == I_GAIN_100K) {
no_rec_time = CNT_TO_I_GAIN_100K_IIN_VIN_PLOT;
} else if (instru.IinADCGainLv == I_GAIN_3M) {
no_rec_time = CNT_TO_I_GAIN_3M_IIN_VIN_PLOT;
} else {
no_rec_time = CNT_TO_I_GAIN_100R_IIN_VIN_PLOT;
}
}
if (plot_type == IIN_VIN_VOUT_PLOT) {
if (instru.IinADCGainLv == I_GAIN_3K) {
no_rec_time = CNT_TO_I_GAIN_3K_IIN_VIN_VOUT_PLOT;
} else if (instru.IinADCGainLv == I_GAIN_100K) {
no_rec_time = CNT_TO_I_GAIN_100K_IIN_VIN_VOUT_PLOT;
} else if (instru.IinADCGainLv == I_GAIN_3M) {
no_rec_time = CNT_TO_I_GAIN_3M_IIN_VIN_VOUT_PLOT;
} else {
no_rec_time = CNT_TO_I_GAIN_100R_IIN_VIN_VOUT_PLOT;
}
}
}
}
if (curr_rec_en == false) {
cnt++;
}
if (cnt >= no_rec_time) {
curr_rec_en = true;
cnt = 0;
}
return;
}
static void read_Vin_change_gain(void)
{
static uint8_t rec_cnt = 0;
void *wm = wm_get();
if (instru.IinADCAutoGainEn > 1)
return;
/* read Vin and do NOT record the Vin after changing gain twice */
ADC_rxbuf = MEASURE_VOLT();
MEAS_VIN(wm) = DecodeADCValue(instru.VinADCGainLv, RIS_ADC_VIN, ADC_rxbuf);
if (instru.VinADCAutoGainEn) {
AutoGainChangeVin(MEAS_VIN(wm));
} else {
if (lastVinADCGainLv != instru.VinADCGainLv) {
VinADCGainCtrl(instru.VinADCGainLv);
}
}
if (volt_rec_en == false) {
rec_cnt++;
}
if (rec_cnt == 2) {
volt_rec_en = true;
rec_cnt = 0;
}
return;
}
static void read_Vout_change_gain(void)
{
static uint8_t rec_cnt = 0;
void *wm = wm_get();
/* read Vout and do NOT record the Vout after changing gain twice */
ADC_rxbuf = MEASURE_DAC();
MEAS_VOUT(wm) = DecodeADCValue(0, RIS_ADC_VOUT, ADC_rxbuf);
if (volt_rec_en == false) {
rec_cnt++;
}
if (rec_cnt == 2) {
volt_rec_en = true;
rec_cnt = 0;
}
return;
}
void EliteCalcAvg(uint32_t time)
{
struct wm_uni_pulse_ctx_t *p = (struct wm_uni_pulse_ctx_t *)wm_get();
static uint32_t cnt = 0;
static int64_t curr_sum = 0;
void *wm = wm_get();
int64_t curr_avg = 0;
uint32_t m;
uint32_t t = time;
m = t % p->_t_period;
if (calc_avg_en) {
cnt++;
curr_sum = curr_sum + MEAS_CURR(wm);
} else {
curr_avg = curr_sum / cnt;
if (cnt == 0) {
return;
}
if (m < p->_t_pa[0]) {
InputNotify(NOTIFY_CH1, curr_avg);
SendNotify();
} else if (m < p->_t_pa[1]) {
InputNotify(NOTIFY_CH2, curr_avg);
SendNotify();
} else if (m < p->_t_pa[2]) {
} else if (m < p->_t_pa[3]) {
}
cnt = 0;
curr_sum = 0;
curr_avg = 0;
}
return;
}
void dpv_EliteCalcAvg(uint32_t time)
{
struct wm_dpv_ctx_t *p = (struct wm_dpv_ctx_t *)wm_get();
static uint32_t cnt = 0;
static int64_t curr_sum = 0;
void *wm = wm_get();
int64_t curr_avg = 0;
uint32_t m;
uint32_t t = time;
m = t % p->_t_period;
static bool first_v_rec = true;
if (calc_avg_en) {
cnt++;
curr_sum = curr_sum + MEAS_CURR(wm);
if (first_v_rec) {
InputNotify(NOTIFY_CH2, instru.Vout/200 - MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
first_v_rec = false;
}
} else {
first_v_rec = true;
curr_avg = curr_sum / cnt;
if (cnt == 0) {
return;
}
if (m < p->_t_pa[0]) {
InputNotify(NOTIFY_CH1, curr_avg);
SendNotify();
} else if (m < p->_t_pa[1]) {
InputNotify(NOTIFY_CH1, curr_avg);
SendNotify();
} else if (m < p->_t_pa[2]) {
} else if (m < p->_t_pa[3]) {
}
cnt = 0;
curr_sum = 0;
curr_avg = 0;
}
return;
}
void dpv_advance_EliteCalcAvg(uint32_t time)
{
struct wm_dpv_advance_ctx_t *p = (struct wm_dpv_advance_ctx_t *)wm_get();
static uint32_t cnt = 0;
static int64_t curr_sum = 0;
void *wm = wm_get();
int64_t curr_avg = 0;
uint32_t m;
uint32_t t = time;
m = t % p->_t_period;
static bool first_v_rec = true;
if (calc_avg_en) {
cnt++;
curr_sum = curr_sum + MEAS_CURR(wm);
if (first_v_rec) {
InputNotify(NOTIFY_CH2, instru.Vout/200 - MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
first_v_rec = false;
}
} else {
first_v_rec = true;
curr_avg = curr_sum / cnt;
if (cnt == 0) {
return;
}
if (m < p->_t_pa[0]) {
InputNotify(NOTIFY_CH1, curr_avg);
SendNotify();
} else if (m < p->_t_pa[1]) {
InputNotify(NOTIFY_CH1, curr_avg);
SendNotify();
} else if (m < p->_t_pa[2]) {
} else if (m < p->_t_pa[3]) {
}
cnt = 0;
curr_sum = 0;
curr_avg = 0;
}
return;
}
static void Iin_Vin_Vout_Plot(uint32_t time)
{
static uint8_t ADC_cnt = 0;
void *wm = wm_get();
uint32_t t = time;
bool read_adc_flag = false;
/* the time for measuring battery */
if (batteryCheck_flag && tempCheck_flag) {
read_adc_flag = EliteADCBattery();
if (!read_adc_flag) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt = 5;
}
return;
}
/* the time for Not measuring battery */
/* ADC_cnt: 0 - read Iin and do NOT buffer the Iin after changing gain twice,
* and output DAC, and read Vin, and increase ADC_cnt
* 1 - read Vin and increase ADC_cnt
* 2 - read Vin and do NOT buffer the Vin after changing gain twice,
* and output DAC, and read Vout, and increase ADC_cnt
* 3 - read Vout and increase ADC_cnt
* 4 - read Vout and do NOT buffer the Vout after changing gain twice,
* and output DAC, and read Iin, and increase ADC_cnt
* 5 - read Iin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
read_Iin_change_gain(IIN_VIN_VOUT_PLOT);
if (instru.eliteFxn == CURVE_DPV && vscanReset == false) {
dpv_EliteCalcAvg(t);
}
else if (instru.eliteFxn == CURVE_DPV_ADVANCE && vscanReset == false) {
dpv_advance_EliteCalcAvg(t);
}
DACenable(AFTER_READ_I);
ADC_cnt++;
} else if (ADC_cnt == 1) {
ADC_rxbuf = MEASURE_VOLT();
ADC_cnt++;
} else if (ADC_cnt == 2) {
read_Vin_change_gain();
DACenable(AFTER_READ_V);
ADC_cnt++;
} else if (ADC_cnt == 3) {
ADC_rxbuf = MEASURE_DAC();
ADC_cnt++;
} else if (ADC_cnt == 4) {
read_Vout_change_gain();
DACenable(AFTER_READ_V);
ADC_cnt++;
} else if (ADC_cnt == 5) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt = 0;
}
return;
}
static void Iin_Vin_Plot(void)
{
static uint8_t ADC_cnt = 0;
void *wm = wm_get();
bool read_adc_flag = false;
/* the time for measuring battery */
if (batteryCheck_flag && tempCheck_flag) {
read_adc_flag = EliteADCBattery();
if (!read_adc_flag) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt = 3;
}
return;
}
/* the time for Not measuring battery */
/* ADC_cnt: 0 - read Iin and do NOT buffer the Iin after changing gain twice,
* and output DAC, and read Vin, and increase ADC_cnt
* 1 - read Vin and increase ADC_cnt
* 2 - read Vin and do NOT buffer the Vin after changing gain twice,
* and output DAC, and read Iin, and increase ADC_cnt
* 3 - read Iin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
read_Iin_change_gain(IIN_VIN_PLOT);
DACenable(AFTER_READ_I);
ADC_cnt++;
} else if (ADC_cnt == 1) {
ADC_rxbuf = MEASURE_VOLT();
ADC_cnt++;
} else if (ADC_cnt == 2) {
read_Vin_change_gain();
DACenable(AFTER_READ_V);
ADC_cnt++;
} else if (ADC_cnt == 3) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt = 0;
}
return;
}
static void IT_Plot(uint32_t time)
{
static uint8_t ADC_cnt = 0;
void *wm = wm_get();
uint32_t t = time;
bool read_adc_flag = false;
/* measure battery if needs */
batteryCheck_flag = false;
tempCheck_flag = false;
if (batteryCheck_flag || tempCheck_flag) {
read_adc_flag = EliteADCBattery();
if (!read_adc_flag) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt = 1;
}
return;
}
/* ADC_cnt: 0 - read Iin and do NOT buffer the Iin after changing gain twice, read Iin and increase ADC_cnt
* 1 - read Iin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt++;
return;
}
if (ADC_cnt == 1) {
read_Iin_change_gain(IT_PLOT);
if (instru.eliteFxn == CURVE_UNI_PULSE && vscanReset == false) {
EliteCalcAvg(t);
}
DACenable(AFTER_READ_I);
ADC_cnt = 0;
return;
}
return;
}
static void VT_Plot(void)
{
static uint8_t ADC_cnt = 0;
void *wm = wm_get();
/* measure battery if needs */
if (batteryCheck_flag && tempCheck_flag) {
EliteADCBattery();
if (!batteryCheck_flag) {
ADC_rxbuf = MEASURE_VOLT();
ADC_cnt = 1;
}
return;
}
/* ADC_cnt: 0 - read Vin and do NOT buffer the Vin after changing gain twice, read Vin and increase ADC_cnt
* 1 - read Vin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
ADC_rxbuf = MEASURE_VOLT();
ADC_cnt++;
return;
}
if (ADC_cnt == 1) {
read_Vin_change_gain();
DACenable(AFTER_READ_V);
ADC_cnt = 0;
return;
}
return;
}
static void Vout_Plot(void)
{
static uint8_t ADC_cnt = 0;
void *wm = wm_get();
/* measure battery if needs */
if (batteryCheck_flag && tempCheck_flag) {
EliteADCBattery();
if (!batteryCheck_flag) {
ADC_rxbuf = MEASURE_DAC();
ADC_cnt = 1;
}
return;
}
/* ADC_cnt: 0 - read Vout and do NOT buffer the Vout after changing gain twice, read Vout and increase ADC_cnt
* 1 - read Vout and reset ADC_cnt
*/
if (ADC_cnt == 0) {
ADC_rxbuf = MEASURE_DAC();
ADC_cnt++;
return;
}
if (ADC_cnt == 1) {
read_Vout_change_gain();
DACenable(AFTER_READ_V);
ADC_cnt = 0;
return;
}
return;
}
static void cali_IT_plot(void) {
void *wm = wm_get();
static uint8_t ADC_cnt = 0;
static uint8_t rec_cnt = 0;
static uint16_t cali_count_max = 1000;
int32_t ADCValueAVG = 0;
/* ADC_cnt: 0 - read Iin and do NOT buffer the Iin after changing gain twice
* 1 - read Iin and increase ADC_cnt
* 2 - read Iin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
if (instru.IinADCAutoGainEn) {
MEAS_CURR(wm) = 0xFFFF;
} else {
ADC_rxbuf = MEASURE_CURRENT();
MEAS_CURR(wm) = (int32_t) ADC_rxbuf;
if (lastIinADCGainLevel != instru.IinADCGainLv) {
IinADCGainCtrl(instru.IinADCGainLv);
}
}
if (instru.IinADCGainLv == 0) {
cali_count_max = 5000;
} else {
cali_count_max = 1000;
}
if (curr_rec_en == false) {
rec_cnt++;
} else {
if (GET_CALI_COUNT(wm) >= cali_count_max) {
ADCValueAVG = GET_ADC_SUM(wm) / GET_CALI_COUNT(wm);
InputNotify(NOTIFY_CH1, ADCValueAVG);
SendNotify();
uint8_t CIS_buf[9] = {0};
CIS_buf[0] = 5; //data len
CIS_buf[1] = instru.chip_id;
CIS_buf[2] = (uint8_t) ((ADCValueAVG & 0xFF00) >> 8);
CIS_buf[3] = (uint8_t) (ADCValueAVG & 0x00FF);
CIS_buf[4] = 0x00;
CIS_buf[5] = instru.IinADCGainLv;
SimpleProfile_SetParameter(BLE_CIS_BUFF_CHAR, 9, CIS_buf);
PeriodicEvent = false;
ModeLED(NO_EVENT);
} else {
GET_CALI_COUNT(wm)++;
GET_ADC_SUM(wm) = GET_ADC_SUM(wm) + MEAS_CURR(wm);
ADCValueAVG = GET_ADC_SUM(wm) / GET_CALI_COUNT(wm);
InputNotify(NOTIFY_CH1, ADCValueAVG);
InputNotify(NOTIFY_CH2, MEAS_CURR(wm));
InputNotify(NOTIFY_CH3, (int32_t)GET_CALI_COUNT(wm));
}
}
if (rec_cnt == 2) {
volt_rec_en = true;
curr_rec_en = true;
rec_cnt = 0;
}
ADC_cnt++;
return;
}
if (ADC_cnt == 1) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt++;
return;
}
if (ADC_cnt == 2) {
ADC_rxbuf = MEASURE_CURRENT();
ADC_cnt = 0;
return;
}
return;
}
static void cali_VT_plot(void) {
void *wm = wm_get();
static uint8_t ADC_cnt = 0;
static uint8_t rec_cnt = 0;
uint16_t cali_count_max = 0;
int32_t ADCValueAVG = 0;
/* ADC_cnt: 0 - read Vin and do NOT buffer the Vin after changing gain twice
* 1 - read Vin and increase ADC_cnt
* 2 - read Vin and reset ADC_cnt
*/
if (ADC_cnt == 0) {
if (instru.VinADCAutoGainEn) {
MEAS_VIN(wm) = 0xFFFF;
} else {
ADC_rxbuf = MEASURE_VOLT();
MEAS_VIN(wm) = (int32_t) ADC_rxbuf;
if (lastVinADCGainLv != instru.VinADCGainLv) VinADCGainCtrl(instru.VinADCGainLv);
}
if (instru.VinADCGainLv == 0) {
cali_count_max = 5000;
} else {
cali_count_max = 1000;
}
if (volt_rec_en == false) {
rec_cnt++;
} else {
if (GET_CALI_COUNT(wm) >= cali_count_max) {
ADCValueAVG = GET_ADC_SUM(wm) / GET_CALI_COUNT(wm);
InputNotify(NOTIFY_CH2, ADCValueAVG);
SendNotify();
uint8_t CIS_buf[9] = {0};
CIS_buf[0] = 5; //data len
CIS_buf[1] = instru.chip_id;
CIS_buf[2] = (uint8_t) ((ADCValueAVG & 0xFF00) >> 8);
CIS_buf[3] = (uint8_t) (ADCValueAVG & 0x00FF);
CIS_buf[4] = 0x00;
CIS_buf[5] = instru.VinADCGainLv;
SimpleProfile_SetParameter(BLE_CIS_BUFF_CHAR, 9, CIS_buf);
PeriodicEvent = false;
ModeLED(NO_EVENT);
} else {
GET_CALI_COUNT(wm)++;
GET_ADC_SUM(wm) = GET_ADC_SUM(wm) + MEAS_VIN(wm);
ADCValueAVG = GET_ADC_SUM(wm) / GET_CALI_COUNT(wm);
InputNotify(NOTIFY_CH2, MEAS_VIN(wm));
InputNotify(NOTIFY_CH1, ADCValueAVG);
InputNotify(NOTIFY_CH3, (int32_t)GET_CALI_COUNT(wm));
}
}
if (rec_cnt == 2) {
volt_rec_en = true;
curr_rec_en = true;
rec_cnt = 0;
}
ADC_cnt++;
return;
}
if (ADC_cnt == 1) {
ADC_rxbuf = MEASURE_VOLT();
ADC_cnt++;
return;
}
if (ADC_cnt == 2) {
ADC_rxbuf = MEASURE_VOLT();
ADC_cnt = 0;
return;
}
return;
}
static void count_sum_clear(void) {
void *wm = wm_get();
if(wm) {
GET_CALI_COUNT(wm) = 0;
GET_ADC_SUM(wm) = 0;
}
return;
}
static void cali_Vout_plot(void) {
void *wm = wm_get();
static uint8_t ADC_cnt = 0;
static uint8_t rec_cnt = 0;
uint16_t cali_count_max = 2000;
int32_t ADCValueAVG = 0;
/* ADC_cnt: 0 - read Vin and do NOT buffer the Vin after changing gain twice
* 1 - read Vin and increase ADC_cnt
* 2 - read Vin and reset ADC_cnt
*/
if(vscanReset)
return;
if (ADC_cnt == 0) {
ADC_rxbuf = MEASURE_DAC();
MEAS_VOUT(wm) = (int32_t) ADC_rxbuf;
if (volt_rec_en == false) {
rec_cnt++;
} else {
GET_CALI_COUNT(wm)++;
GET_ADC_SUM(wm) = GET_ADC_SUM(wm) + MEAS_VOUT(wm);
ADCValueAVG = GET_ADC_SUM(wm) / GET_CALI_COUNT(wm);
InputNotify(NOTIFY_CH2, MEAS_VOUT(wm));
InputNotify(NOTIFY_CH1, ADCValueAVG);
InputNotify(NOTIFY_CH3, (int32_t)GET_CALI_COUNT(wm));
}
if (rec_cnt == 2) {
volt_rec_en = true;
curr_rec_en = true;
rec_cnt = 0;
}
ADC_cnt++;
return;
}
if (ADC_cnt == 1) {
ADC_rxbuf = MEASURE_DAC();
ADC_cnt++;
return;
}
if (ADC_cnt == 2) {
ADC_rxbuf = MEASURE_DAC();
ADC_cnt = 0;
return;
}
return;
}
#endif
@@ -0,0 +1,15 @@
#ifndef VERSION_DATE
#define VERSION_DATE
#define VERSION_DATE_YEAR 23
#define VERSION_DATE_MONTH 3
#define VERSION_DATE_DAY 7
#define VERSION_DATE_HOUR 17
#define VERSION_DATE_MINUTE 41
// this is NOT the version hash !!
// it's the last version hash
#define VERSION_HASH 8808490caa465cc94d14896de28763a5e5c4672b
#define VERSION_GIT_BRANCH Elite_OBJ_0.2mv
#endif
@@ -0,0 +1,734 @@
/*
* impedance_meter.h
*
* Created on: 2019/01/15
* Author: benny
*/
#ifndef HEADSTAGE_H
#error "headstage.h not include"
#endif
#ifdef HEADSTAGE_H_H
#error "headstage_*.h has be included"
#endif
#ifndef IMPEDANCE_METER_H_
#define HEADSTAGE_H_H
#define IMPEDANCE_METER_H_
// header
#include "EliteWorkData.h"
static void device_init(void)
{
gpio_create();
InitEliteInstruction();
update_latch_stat(E_LATCH_CS_MEM, 1);
update_latch_stat(E_LATCH_CS_ADC, 1);
update_latch_stat(E_LATCH_CS_DAC, 1);
update_latch_stat(E_LATCH_OFF, 1); // E_LATCH_OFF = 1 => turn off 6994
latch_multi_ctrl();
/* when elite open, must change vin level,
measure battery value will be right */
IinADCGainCtrl(instru.IinADCGainLv);
VinADCGainCtrl(instru.VinADCGainLv);
VoutGainControl(instru.VoutGainLv);
DAC0_W_T(Usercode_Correction_to_DAC(instru.VoutGainLv, 25000));
elite_gptimer_open();
InitGPT();
return;
}
#define IsPeriodicMode() ( \
(instru.eliteFxn == CURVE_IV) || \
(instru.eliteFxn == CURVE_IV_CY) || \
(instru.eliteFxn == CURVE_IT) || \
(instru.eliteFxn == CURVE_VT) || \
(instru.eliteFxn == CURVE_RT) || \
(instru.eliteFxn == CURVE_CC) || \
(instru.eliteFxn == CURVE_CP) || \
(instru.eliteFxn == CURVE_CV) || \
(instru.eliteFxn == CURVE_LSV) || \
(instru.eliteFxn == CURVE_CA) || \
(instru.eliteFxn == CURVE_VO) || \
(instru.eliteFxn == CURVE_OCP) || \
(instru.eliteFxn == CURVE_CALI) \
)
#define Ve1MatchVe2Mode() ( \
(instru.eliteFxn == CURVE_IV) || \
(instru.eliteFxn == CURVE_IV_CY) || \
(instru.eliteFxn == CURVE_CV) || \
(instru.eliteFxn == CURVE_LSV) \
)
static void peri_mode(void)
{
GPT.cnt_lead_time = GPT.cnt_lead_time + GPT.cnt_gpt_delta;
if (leadTimeReset && GPT.cnt_lead_time <= 2000) {
vscanReset = true;
if (first_highz_flag && GPT.cnt_lead_time >= 1000) {
if (instru.eliteFxn == CURVE_OCP || instru.eliteFxn == CURVE_CC || instru.eliteFxn == CURVE_CP) {
HIGH_Z_OPEN(); // HIGH Z MODE // 1: close; 0: open;
} else {
//latch_single_ctrl(E_LATCH_HIGH_Z, instru.hign_z_en); // HIGH Z MODE // 1: close; 0: open;
if(instru.hign_z_en == 1) {
HIGH_Z_CLOSE();
}
else{
HIGH_Z_OPEN();
}
}
first_highz_flag = false;
}
} else {
if (notifyFirst_flag) {
GPT.cnt_notify_rate = instru.notifyRate - 20;
notifyFirst_flag = false;
if (instru.eliteFxn == CURVE_CC || instru.eliteFxn == CURVE_CP) {
latch_single_ctrl(E_LATCH_HIGH_Z, instru.hign_z_en); // HIGH Z MODE // 1: close; 0: open;
}
}
vscanReset = false;
leadTimeReset = false;
}
//vscan counter
GPT.cnt_v_scan_rate = GPT.cnt_v_scan_rate + GPT.cnt_gpt_delta;
if (GPT.cnt_v_scan_rate >= instru.VsetRate) {
if (GPT.cnt_v_scan_rate >= instru.VsetRate * 2) {
GPT.GptimerMultiple = GPT.cnt_v_scan_rate / instru.VsetRate;
} else {
GPT.GptimerMultiple = 1;
}
GPT.cnt_v_scan_rate -= instru.VsetRate * GPT.GptimerMultiple; //To get right time
vscan_ctrl(0);
}
//battery counter
GPT.BatteryADCCounter = GPT.BatteryADCCounter + GPT.cnt_gpt_delta;
GPT.BatteryCheckCounter = GPT.BatteryCheckCounter + GPT.cnt_gpt_delta;
if(GPT.BatteryCheckCounter >= 50000){
GPT.BatteryCheckCounter -= 50000; //To get right time
batteryCheck_flag = true;
tempCheck_flag = true;
if ((instru.eliteFxn == CURVE_IV) ||
(instru.eliteFxn == CURVE_IV_CY) ||
(instru.eliteFxn == CURVE_CC) ||
(instru.eliteFxn == CURVE_CP) ||
(instru.eliteFxn == CURVE_CV) ||
(instru.eliteFxn == CURVE_LSV) ||
(instru.eliteFxn == CURVE_CA) ||
(instru.eliteFxn == CURVE_OCP) ||
(instru.eliteFxn == CURVE_UNI_PULSE) ||
(instru.eliteFxn == CURVE_DPV) ||
(instru.eliteFxn == CURVE_DPV_SMPRATE) ||
(instru.eliteFxn == CURVE_DPV_ADVANCE) ||
(instru.eliteFxn == CURVE_DPV_ADVANCE_SMPRATE) ||
(instru.eliteFxn == CURVE_CALI)) {
batteryCheck_flag = false;
tempCheck_flag = false;
}
}
uint16_t bat = NotifyVoltBat;
if( bat < 768 && bat > 20){
// latch_single_ctrl(E_LATCH_5V_ENABLE, 0);
}
//ADC counter
GPT.cnt_adc_rate = GPT.cnt_adc_rate + GPT.cnt_gpt_delta;
if(GPT.cnt_adc_rate >= instru.sampleRate){
GPT.cnt_adc_rate = 0; //To get right data, ADC must be delay 1.5ms
EliteADCControl(0);
}
// Over temperature protection
uint16_t CC2650temp = NotifyTemperature;
if(CC2650temp > 40) {
latch_single_ctrl(E_LATCH_5V_ENABLE, 0);
}
//Notify counter(Notify control, check if we need to send notify)
//please don't put Notify counter before ADC counter, maybe get wrong data
GPT.cnt_notify_rate = GPT.cnt_notify_rate + GPT.cnt_gpt_delta;
if(GPT.cnt_notify_rate >= instru.notifyRate){
GPT.cnt_notify_rate -= instru.notifyRate; //To get right time
notify_flag = true;
if(vscanReset){
notify_flag = false;
}
if (!volt_rec_en || !curr_rec_en) {
notify_flag = false;
}
if(notify_flag){
SendNotify();
notify_flag = false;
}
}
mode_done();
}
static void uni_pulse_mode(void)
{
// Default working flow is vscan -> ADC read -> send notify
// We will need a flag to control vscan, ADC and notify
GPT.cnt_lead_time = GPT.cnt_lead_time + GPT.cnt_gpt_delta;
if (leadTimeReset && GPT.cnt_lead_time <= 2000) {
vscanReset = true;
GPT.cnt_v_scan_rate = 0xFFFFFFFF;
dpv_step_cnt = 0;
if (first_highz_flag && GPT.cnt_lead_time >= 1000) {
latch_single_ctrl(E_LATCH_HIGH_Z, instru.hign_z_en); // HIGH Z MODE // 1: close; 0: open;
first_highz_flag = false;
}
} else {
if (notifyFirst_flag) {
GPT.cnt_notify_rate = instru.notifyRate - 20;
notifyFirst_flag = false;
}
if (vscanReset) {
GPT.cnt_v_scan_rate = 0xFFFFFFFF;
dpv_step_cnt = 0;
}
vscanReset = false;
leadTimeReset = false;
}
//vscan counter
GPT.cnt_v_scan_rate = GPT.cnt_v_scan_rate + GPT.cnt_gpt_delta;
if (GPT.cnt_v_scan_rate >= instru.period) {
GPT.cnt_v_scan_rate -= instru.period; //To get right time
dpv_step_cnt +=1;
}
vscan_ctrl(GPT.cnt_v_scan_rate);
//battery counter
GPT.BatteryADCCounter = GPT.BatteryADCCounter + GPT.cnt_gpt_delta;
GPT.BatteryCheckCounter = GPT.BatteryCheckCounter + GPT.cnt_gpt_delta;
if(GPT.BatteryCheckCounter >= 50000){
GPT.BatteryCheckCounter -= 50000; //To get right time
batteryCheck_flag = true;
tempCheck_flag = true;
if ((instru.eliteFxn == CURVE_IV) ||
(instru.eliteFxn == CURVE_IV_CY) ||
(instru.eliteFxn == CURVE_CC) ||
(instru.eliteFxn == CURVE_CV) ||
(instru.eliteFxn == CURVE_LSV) ||
(instru.eliteFxn == CURVE_CA) ||
(instru.eliteFxn == CURVE_OCP) ||
(instru.eliteFxn == CURVE_UNI_PULSE) ||
(instru.eliteFxn == CURVE_DPV) ||
(instru.eliteFxn == CURVE_DPV_SMPRATE) ||
(instru.eliteFxn == CURVE_DPV_ADVANCE) ||
(instru.eliteFxn == CURVE_DPV_ADVANCE_SMPRATE) ||
(instru.eliteFxn == CURVE_CALI)) {
batteryCheck_flag = false;
tempCheck_flag = false;
}
}
//ADC counter
GPT.cnt_adc_rate = GPT.cnt_adc_rate + GPT.cnt_gpt_delta;
if(GPT.cnt_adc_rate >= instru.sampleRate){
GPT.cnt_adc_rate = 0; //To get right data, ADC must be delay 1.5ms
EliteADCControl(GPT.cnt_v_scan_rate);
}
uint16_t bat = NotifyVoltBat;
if( bat < 768 && bat > 20){
// latch_single_ctrl(E_LATCH_5V_ENABLE, 0);
}
// Over temperature protection
uint16_t CC2650temp = NotifyTemperature;
if(CC2650temp > 40) {
latch_single_ctrl(E_LATCH_5V_ENABLE, 0);
}
if (instru.eliteFxn == CURVE_DPV || instru.eliteFxn == CURVE_DPV_ADVANCE) {
} else {
//Notify counter(Notify control, check if we need to send notify)
//please don't put Notify counter before ADC counter, maybe get wrong data
GPT.cnt_notify_rate = GPT.cnt_notify_rate + GPT.cnt_gpt_delta;
if(GPT.cnt_notify_rate >= instru.notifyRate){
GPT.cnt_notify_rate -= instru.notifyRate; //To get right time
notify_flag = true;
if (instru.eliteFxn == CURVE_UNI_PULSE) {
notify_flag = false;
}
if(vscanReset){
notify_flag = false;
}
if (!volt_rec_en || !curr_rec_en) {
notify_flag = false;
}
if(notify_flag){
SendNotify();
notify_flag = false;
}
}
}
mode_done();
}
static void mode_init_set(void)
{
batteryADC_flag = false;
volt_rec_en = true;
curr_rec_en = true;
firstTimeReset = true;
notifyFirst_flag = true;
first_highz_flag = true;
DACReset = true;
vscanReset = true;
leadTimeReset = true;
if (instru.notifyRate > 1000) {
// slow notify rate, < 10sps, auto gain changer only use ADC gain level = 1.2.3.4
// gain_switch_on: [1:4]: none
// [5]: ADC gain level = 4, if value = 1, gain 4 switch on
// [6]: ADC gain level = 3, if value = 1, gain 3 switch on
// [7]: ADC gain level = 2, if value = 1, gain 2 switch on
// [8]: ADC gain level = 1, if value = 1, gain 1 switch on
instru.gain_switch_on = 0b11110000;
} else {
// fast notify rate, >= 10sps, auto gain changer only use ADC gain level = 1.2.3
instru.gain_switch_on = 0b01110000;
}
VinADCGainCtrl(instru.VinADCGainLv);
IinADCGainCtrl(instru.IinADCGainLv);
VoutGainControl(instru.VoutGainLv);
if (Ve1MatchVe2Mode()) {
if (instru.Ve1 == instru.Ve2) {
DAC0_W_T(Usercode_Correction_to_DAC(instru.VoutGainLv, 25000));
PeriodicEvent = false;
latch_single_ctrl(E_LATCH_HIGH_Z, 0); // 0: open highz;
ModeLED(NO_EVENT);
}
}
return;
}
/*********************************************************************
* @fn SimpleBLEPeripheral_performPeriodicTask
*
* @brief Control periodic event such as DAC out, ADC read, and send notify.
*
* @param None.
*
* @return None.
*/
static void elite_task(void)
{
// GPT_timerIncrement();
if (IsPeriodicMode()) {
if (mode_init) {
mode_init = false;
mode_init_set();
InitGPT();
GPT.cnt_adc_rate = instru.sampleRate - 10;
GPT.cnt_v_scan_rate = instru.VsetRate - 1;
}
peri_mode();
return;
}
if (instru.eliteFxn == CURVE_UNI_PULSE) {
if (mode_init) {
mode_init = false;
mode_init_set();
InitGPT();
calc_avg_en = false;
}
uni_pulse_mode();
return;
}
if (instru.eliteFxn == CURVE_DPV || instru.eliteFxn == CURVE_DPV_ADVANCE) {
if (mode_init) {
mode_init = false;
mode_init_set();
InitGPT();
calc_avg_en = false;
}
uni_pulse_mode();
return;
}
if (instru.eliteFxn == CURVE_DPV_SMPRATE || instru.eliteFxn == CURVE_DPV_ADVANCE_SMPRATE) {
if (mode_init) {
mode_init = false;
mode_init_set();
InitGPT();
}
uni_pulse_mode();
return;
}
return;
}
/* Notify data:
* +--------+----------+---------+---------+---------+-----------+-----------------+
* | id(1B) | time(4B) | ch1(4B) | ch2(4B) | ch3(4B) | cycle(2B) | finish_flag(1B) |
* | bat(4B) | notify#(1B) | ch4(4B) | ch5(4B) | ch6(4B) | __(3B) |
* +---------+-------------+---------+---------+---------+--------+
*/
/*
* EliteADCControl(): use ADC plot, and send what data to controller
* +---------------------------+-----------+-----------+-----------+-----------+-----------+
* | MODE | ch1 | ch2 | ch3 | cycle | ch4 |
* +---------------------------+-----------+-----------+-----------+-----------+-----------+
* | CURVE_IV | Iin | Vout | Vin | | Vmon |
* | CURVE_IV_CY | Iin | Vout | Vin | v | Vmon |
* | CURVE_VO | Iin | Vout | Vin | | Vmon |
* | CURVE_RT | Iin | Vout | R | | Vmon |
* | CURVE_VT | Iin | Vin | | | |
* | CURVE_IT | Iin | Vin | Vout | | Vmon |
* | CURVE_CC | Iin | Vin | Vout | | Vmon |
* | CURVE_CP | Iin | Vout-Vin | Vout | | Vmon |
* | CURVE_CV | Iin | Vout-Vin | Vout | v | Vmon |
* | CURVE_LSV | Iin | Vout-Vin | Vout | | Vmon |
* | CURVE_CA | Iin | Vout-Vin | Vout | | Vmon |
* | CURVE_OCP | Iin | Vmon-Vin | Vin | | Vmon |
* | CURVE_UNI_PULSE | pul1_Iin | pul2_Iin | | | |
* | CURVE_DPV | c1&c2_avg | Vout-Vin | Vout | | Vmon |
* | CURVE_DPV_SMPRATE | Iin | Vout-Vin | Vout | | Vmon |
* | CURVE_DPV_ADVANCE | c1&c2_avg | Vout-Vin | Vout | | Vmon |
* | CURVE_DPV_ADVANCE_SMPRATE | Iin | Vout-Vin | Vout | | Vmon |
* +---------------------------+-----------+-----------+-----------+-----------+-----------+
*
* ps. c1_avg = pul1_Iin
* ps. c2_avg = pul2_Iin
*/
static void EliteADCControl(uint32_t time)
{
void *wm = wm_get();
uint32_t t = time;
switch (instru.eliteFxn) {
case CURVE_IV:
case CURVE_IV_CY:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, instru.Vout/200);
InputNotify(NOTIFY_CH3, MEAS_VIN(wm));
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_RT:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, instru.Vout/200);
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_CC:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_CP:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, instru.Vout/200 - MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_CV:
case CURVE_CA:
case CURVE_LSV:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, instru.Vout/200 - MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_IT:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if(volt_rec_en) {
InputNotify(NOTIFY_CH2, MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_VT:
Iin_Vin_Plot();
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, MEAS_VIN(wm));
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_VO:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, instru.Vout/200);
InputNotify(NOTIFY_CH3, MEAS_VIN(wm));
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_OCP:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, MEAS_VOUT(wm) - MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, MEAS_VIN(wm));
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_CALI:
if (instru.AdcChannel == RIS_ADC_IIN) {
cali_IT_plot();
} else if (instru.AdcChannel == RIS_ADC_VIN) {
cali_VT_plot();
} else if (instru.AdcChannel == RIS_DAC_VOUT) {
cali_Vout_plot();
}
break;
case CURVE_UNI_PULSE:
IT_Plot(t);
break;
case CURVE_DPV:
Iin_Vin_Vout_Plot(t);
notify_ch4 = MEAS_VOUT(wm);
break;
case CURVE_DPV_SMPRATE:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, instru.Vout/200 - MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
notify_ch4 = MEAS_VOUT(wm);
}
break;
case CURVE_DPV_ADVANCE:
Iin_Vin_Vout_Plot(t);
notify_ch4 = MEAS_VOUT(wm);
break;
case CURVE_DPV_ADVANCE_SMPRATE:
Iin_Vin_Vout_Plot(t);
if (curr_rec_en) {
InputNotify(NOTIFY_CH1, MEAS_CURR(wm));
}
if (volt_rec_en) {
InputNotify(NOTIFY_CH2, instru.Vout/200 - MEAS_VIN(wm));
InputNotify(NOTIFY_CH3, instru.Vout/200);
notify_ch4 = MEAS_VOUT(wm);
}
break;
default:
break;
}
}
static void mode_done(void)
{
if ((instru.eliteFxn == CURVE_IV) ||
(instru.eliteFxn == CURVE_CV) ||
(instru.eliteFxn == CURVE_LSV) ||
(instru.eliteFxn == CURVE_IV_CY) ||
(instru.eliteFxn == CURVE_CC) ||
(instru.eliteFxn == CURVE_DPV) ||
(instru.eliteFxn == CURVE_DPV_SMPRATE) ||
(instru.eliteFxn == CURVE_DPV_ADVANCE) ||
(instru.eliteFxn == CURVE_DPV_ADVANCE_SMPRATE) ||
(instru.eliteFxn == CURVE_CALI))
{
if (!PeriodicEvent) {
finishMode = true;
SendNotify();
Eliteinterrupt();
}
}
}
static void vscan_ctrl(uint32_t time)
{
uint32_t t = time;
switch (instru.eliteFxn) {
case CURVE_IV:
iv_vscan();
break;
case CURVE_IV_CY:
iv_cy_vscan();
break;
case CURVE_VO:
vo_vscan();
break;
case CURVE_RT:
rt_vscan();
break;
case CURVE_IT:
it_vscan();
break;
case CURVE_CV:
cv_vscan();
break;
case CURVE_LSV:
lsv_vscan();
break;
case CURVE_CA:
ca_vscan();
break;
case CURVE_UNI_PULSE:
uni_pulse_vscan(t);
break;
case CURVE_DPV:
case CURVE_DPV_SMPRATE:
dpv_vscan(t);
break;
case CURVE_DPV_ADVANCE:
case CURVE_DPV_ADVANCE_SMPRATE:
dpv_advance_vscan(t);
break;
default:{
break;
}
}
}
static uint32_t get_step_time(uint8_t StepTime){
switch (StepTime) {
case 0: { //0.5 sec
return STEPTIME_HALF_SEC;
}
case 1: { //1 sec
return STEPTIME_ONE_SEC;
}
case 2: { //2 sec
return STEPTIME_TWO_SEC;
}
default: { //1 sec
return STEPTIME_ONE_SEC;
}
}
}
static void step2VsetRate(uint32_t step){
/*step = 100 mv, index = 0, n = 2
10 mv, index = 1, n = 10
1 mv, index = 2, n = 100
0.1 mv, index = 3, n = 1000
0.01mv, index = 4, n = 10000 */
if(step >= 10000){
instru.VsetRateIndex = 0;
}else if (step >= 1000){
instru.VsetRateIndex = 1;
}else if (step >= 100){
instru.VsetRateIndex = 2;
}else if (step >= 10){
instru.VsetRateIndex = 3;
}else if (step >= 1){
instru.VsetRateIndex = 4;
}
}
#endif /* IMPEDANCE_METER_H_ */
@@ -0,0 +1,880 @@
#ifndef SCAN_VOLT_H
#define SCAN_VOLT_H
#ifdef __cplusplus
extern "C" {
#endif
#define Vset instru.Vset
static void iv_vscan(void)
{
struct wm_iv_ctx_t *iv = (struct wm_iv_ctx_t *)wm_get();
if (vscanReset) {
if (instru.directionInit == 1) {
iv->_direction_up = true;
iv->_current_direction_up = true;
} else if (instru.directionInit == 0) {
iv->_direction_up = false;
iv->_current_direction_up = false;
}
//Vsetp = x * 20 * N, x=xmV ; N=VscanRate
if (instru.step <= 10) {
iv->_Vstep = instru.step * instru.VsetRate / 5;
} else {
iv->_Vstep = instru.step / 5 * instru.VsetRate;
}
Vset = iv->_Vinit;
}
if (!vscanReset) {
if (iv->_current_direction_up) {
if (Vset >= iv->_Vmax) {
PeriodicEvent = false;
}
} else {
if (Vset <= iv->_Vmin) {
PeriodicEvent = false;
}
}
if (iv->_current_direction_up) {
Vset = Vset + iv->_Vstep * GPT.GptimerMultiple;
} else {
Vset = Vset - iv->_Vstep * GPT.GptimerMultiple;
}
}
return;
}
static void iv_cy_vscan(void)
{
struct wm_iv_cy_ctx_t *iv_cy = (struct wm_iv_cy_ctx_t *)wm_get();
static bool VminCounter;
static bool VmaxCounter;
NotifyCycleNumber = (instru.cycleNumber - iv_cy->_cycleNumber + 1);
if(vscanReset){
VmaxCounter = false;
VminCounter = false;
if(instru.directionInit == 1){
iv_cy->_direction_up = true;
iv_cy->_current_direction_up = true;
}else if(instru.directionInit == 0){
iv_cy->_direction_up = false;
iv_cy->_current_direction_up = false;
}
//Vsetp = x * 20 * N, x=xmV ; N=VscanRate
if(instru.step <= 10){
iv_cy->_Vstep = instru.step * instru.VsetRate / 5;
}else{
iv_cy->_Vstep = instru.step / 5 * instru.VsetRate;
}
if(iv_cy->_Vmin == iv_cy->_Vinit){
VminCounter = true;
}
if(iv_cy->_Vmax == iv_cy->_Vinit){
VmaxCounter = true;
}
Vset = iv_cy->_Vinit;
}
if(!vscanReset){
if (Vset >= iv_cy->_Vmax){
VmaxCounter = true;
}else if (Vset <= iv_cy->_Vmin){
VminCounter = true;
}
if (iv_cy->_current_direction_up){
Vset = Vset + iv_cy->_Vstep * GPT.GptimerMultiple;
}else{
Vset = Vset - iv_cy->_Vstep * GPT.GptimerMultiple;
}
if(VmaxCounter && VminCounter){
if(iv_cy->_direction_up && iv_cy->_current_direction_up){
if(Vset >= iv_cy->_Vinit){
iv_cy->_cycleNumber--;
VminCounter = false;
VmaxCounter = false;
}
}
if(!iv_cy->_direction_up && !iv_cy->_current_direction_up){
if(Vset <= iv_cy->_Vinit){
iv_cy->_cycleNumber--;
VminCounter = false;
VmaxCounter = false;
}
}
}
if (Vset >= iv_cy->_Vmax){
iv_cy->_current_direction_up = false;
}else if (Vset <= iv_cy->_Vmin){
iv_cy->_current_direction_up = true;
}
/*stop condition*/
if(iv_cy->_cycleNumber == 0){
PeriodicEvent = false;
}
}
return;
}
static void it_vscan(void)
{
struct wm_it_ctx_t *it = (struct wm_it_ctx_t *)wm_get();
if (vscanReset) {
Vset = it->_Vinit;
}
if(!vscanReset) {
Vset = it->_Vinit;
}
return;
}
static void rt_vscan(void)
{
struct wm_rt_ctx_t *rt = (struct wm_rt_ctx_t *)wm_get();
if (vscanReset) {
Vset = rt->_Vinit;
}
if(!vscanReset) {
Vset = rt->_Vinit;
}
return;
}
static void vo_vscan(void)
{
struct wm_vo_ctx_t *vo = (struct wm_vo_ctx_t *)wm_get();
if (vscanReset) {
Vset = vo->_Vinit;
}
if(!vscanReset) {
Vset = vo->_Vinit;
}
return;
}
#define DELTAVOLTMAX 20000000 //2000000 = 10mV //10000000 = 50mV //20000000 = 100mV
#define RESISTANCE_100R 1 // 100V/1A = 1[5nV]/50[pA]
static void cc_vscan(void)
{
/* Transform setting CC into IUC
*
* User code in CC mode : 0 ~ 3000000
* Real current value : -15.00000 ~ 15.00000 mA
* => user code = 1500000 mapping to 0.00000 mA
*/
struct wm_cc_ctx_t *cc = (struct wm_cc_ctx_t *)wm_get();
struct wm_meas_t *m = &cc->measure;
uint16_t divisionRate;
int32_t deltaI;
int32_t deltaV;
int32_t Iin;
int32_t Vin;
int32_t Voutin;
uint8_t cc_cp_speed = instru.cc_cp_speed; // 0:low 1:normal 2:high
// uint8_t cc_resistance = instru.cc_resistance; // 0:vout has 0R 1:vout has 100R
static int32_t i_set = 0;
if (vscanReset) {
if (cc->_charge == 0) {
i_set = cc->_Iset * (-1);
} else {
i_set = cc->_Iset;
}
Voutin = m->_measureVout * 200; //[5nV]
Vset = Voutin + (i_set * RESISTANCE_100R); //[5nV]
if (Vset >= 1100000000) { // 5.5V
Vset = 1100000000;
} else if (Vset <= -1000000000) { //-5V
Vset = -1000000000;
}
return;
}
Iin = m->_measureCurrent * 20; //[50pA] nA => 50pA
deltaI = Iin - i_set;
if (deltaI > 400000 || deltaI < -400000) { //20uA
if (cc_cp_speed == 0) { // 0:low 1:normal 2:high
divisionRate = 100;
} else if (cc_cp_speed == 1) {
divisionRate = 10;
} else {
divisionRate = 1;
}
} else {
if (cc_cp_speed == 0) { // 0:low 1:normal 2:high
divisionRate = 100;
} else if (cc_cp_speed == 1) {
divisionRate = 20;
} else {
divisionRate = 20;
}
}
deltaV = -1 * (deltaI / divisionRate); //-5 * deltaI / 5000 //pV=> 5nV
if (deltaV > DELTAVOLTMAX) { //2000000 = 10mV
deltaV = DELTAVOLTMAX;
} else if (deltaV < (-DELTAVOLTMAX)) {
deltaV = (-DELTAVOLTMAX);
}
Vset = Vset + deltaV; //[5nV]
if (Vset >= 1100000000) { // 5.5V
Vset = 1100000000;
} else if (Vset <= -1000000000) { //-5V
Vset = -1000000000;
}
Vin = m->_measureVin * 200; //[5nV]
if (Vin <= cc->_Vmin && cc->_charge == 0) { // discharge
PeriodicEvent = false;
} else if (Vin >= cc->_Vmax && cc->_charge == 1) { // charge
PeriodicEvent = false;
}
return;
}
static void cp_vscan(void)
{
struct wm_cp_ctx_t *cp = (struct wm_cp_ctx_t *)wm_get();
struct wm_meas_t *m = &cp->measure;
uint8_t cc_cp_speed = instru.cc_cp_speed; // 0:low 1:normal 2:high
int32_t Iin;
int32_t Voutin;
static uint8_t sum_cnt;
static int64_t sum_adc_delta_Voutin; //[5nV]
static int64_t sum_adc_delta_Iin; //[50pA]
static int32_t resis;
int16_t divisionRate;
static int64_t deltaI;
static int64_t deltaV;
static int32_t i_set;
static int64_t Rd = 0;
Iin = m->_measureCurrent * 20; //[50pA] nA => 50pA
Voutin = m->_measureVout * 200; //[5nV] uV => 5nV
if (vscanReset) {
sum_cnt = 0;
sum_adc_delta_Voutin = 0;
sum_adc_delta_Iin = 0;
resis = 1000;
if (cp->_charge == 0) { // discharge
i_set = cp->_Iset * (-1);
Vset = Voutin - 1000000; //[5nV] 1000000 = 5mV
} else if(cp->_charge == 1) { // charge
i_set = cp->_Iset;
Vset = Voutin + 1000000; //[5nV] 1000000 = 5mV
}
if (Vset >= 1100000000) { // 5.5V
Vset = 1100000000;
} else if (Vset <= -1000000000) { //-5V
Vset = -1000000000;
}
return;
}
if (cp_devis_en == TRUE) {
divisionRate = cp_devis;
} else {
if (cc_cp_speed == 0) { // 0:low 1:normal 2:high
divisionRate = 100;
} else if (cc_cp_speed == 1) {
divisionRate = 10;
} else {
divisionRate = 1;
}
}
deltaI = Iin - i_set;
sum_adc_delta_Voutin += Voutin;
sum_adc_delta_Iin += Iin;
sum_cnt++;
if (sum_cnt == 5) {
Rd = sum_adc_delta_Voutin * 100 / sum_adc_delta_Iin;
if ((sum_adc_delta_Iin >= 12000 || sum_adc_delta_Iin <= -12000) && Rd >= 0) { // sum_delIin >= 600nA
if (Rd <= 10) {
resis = 10;
} else if (Rd >= 10000000) {
resis = 10000000;
} else {
resis = Rd;
}
}
sum_cnt = 0;
sum_adc_delta_Voutin = 0;
sum_adc_delta_Iin = 0;
}
deltaV = -1 * deltaI * resis / 100 / (int64_t)divisionRate;
Vset = Vset + deltaV;
if (Vset >= 1100000000) { // 5.5V
Vset = 1100000000;
} else if (Vset <= -1000000000) { //-5V
Vset = -1000000000;
}
if (Vset <= cp->_Vmin) {
Vset = cp->_Vmin;
} else if (Vset >= cp->_Vmax) {
Vset = cp->_Vmax;
}
return;
}
static void cv_vscan(void)
{
struct wm_cv_ctx_t *cv = (struct wm_cv_ctx_t *)wm_get();
static bool VminCounter;
static bool VmaxCounter;
NotifyCycleNumber = (instru.cycleNumber - cv->_cycleNumber + 1);
if (vscanReset) {
VmaxCounter = false;
VminCounter = false;
if (instru.directionInit == 1) {
cv->_direction_up = true;
cv->_current_direction_up = true;
} else {
cv->_direction_up = false;
cv->_current_direction_up = false;
}
//Vsetp = x * 20 * N, x=xmV ; N=VscanRate
if (instru.step <= 10) {
cv->_Vstep = instru.step * instru.VsetRate / 5;
} else {
cv->_Vstep = instru.step / 5 * instru.VsetRate;
}
if (cv->_Vmin == cv->_Vinit) {
VminCounter = true;
}
if (cv->_Vmax == cv->_Vinit) {
VmaxCounter = true;
}
Vset = cv->_Vinit;
}
if (!vscanReset) {
if ((instru.Vinit < instru.Ve1 && instru.Vinit < instru.Ve2) ||
(instru.Vinit > instru.Ve1 && instru.Vinit > instru.Ve2)
) {
if (cv->_current_direction_up) {
Vset = Vset + cv->_Vstep * GPT.GptimerMultiple;
} else {
Vset = Vset - cv->_Vstep * GPT.GptimerMultiple;
}
if (instru.Vinit < instru.Ve1 && instru.Vinit < instru.Ve2) {
if (Vset == cv->_Vmin) {
VminCounter = true;
instru.Vinit = instru.Vmin;
cv->_Vinit = cv->_Vmin;
}
} else if (instru.Vinit > instru.Ve1 && instru.Vinit > instru.Ve2) {
if (Vset == cv->_Vmax) {
VmaxCounter = true;
instru.Vinit = instru.Vmax;
cv->_Vinit = cv->_Vmax;
}
}
} else {
if (Vset >= cv->_Vmax) {
VmaxCounter = true;
} else if (Vset <= cv->_Vmin) {
VminCounter = true;
}
if (cv->_current_direction_up) {
Vset = Vset + cv->_Vstep * GPT.GptimerMultiple;
} else {
Vset = Vset - cv->_Vstep * GPT.GptimerMultiple;
}
if (VmaxCounter && VminCounter) {
if (cv->_direction_up && cv->_current_direction_up) {
if (Vset >= cv->_Vinit) {
cv->_cycleNumber--;
VminCounter = false;
VmaxCounter = false;
}
}
if (!cv->_direction_up && !cv->_current_direction_up) {
if (Vset <= cv->_Vinit) {
cv->_cycleNumber--;
VminCounter = false;
VmaxCounter = false;
}
}
}
if (Vset >= cv->_Vmax) {
cv->_current_direction_up = false;
} else if (Vset <= cv->_Vmin) {
cv->_current_direction_up = true;
}
/*stop condition*/
if (cv->_cycleNumber == 0) {
PeriodicEvent = false;
}
}
}
return;
}
static void lsv_vscan(void)
{
struct wm_lsv_ctx_t *lsv = (struct wm_lsv_ctx_t *)wm_get();
if (vscanReset) {
if (instru.directionInit == 1) {
lsv->_direction_up = true;
lsv->_current_direction_up = true;
} else {
lsv->_direction_up = false;
lsv->_current_direction_up = false;
}
//Vsetp = x * 20 * N, x=xmV ; N=VscanRate
if (instru.step <= 10) {
lsv->_Vstep = instru.step * instru.VsetRate / 5;
} else {
lsv->_Vstep = instru.step / 5 * instru.VsetRate;
}
Vset = lsv->_Vinit;
}
if (!vscanReset) {
if (lsv->_current_direction_up) {
Vset = Vset + lsv->_Vstep * GPT.GptimerMultiple;
} else {
Vset = Vset - lsv->_Vstep * GPT.GptimerMultiple;
}
/*stop condition*/
if (Vset >= lsv->_Vmax) {
PeriodicEvent = false;
} else if (Vset <= lsv->_Vmin) {
PeriodicEvent = false;
}
}
return;
}
static void ca_vscan(void)
{
struct wm_ca_ctx_t *ca = (struct wm_ca_ctx_t *)wm_get();
if(vscanReset){
Vset = ca->_Vinit;
}
if(!vscanReset){
Vset = ca->_Vinit;
}
return;
}
static void uni_pulse_vscan(uint32_t time)
{
uint32_t t = time;
struct wm_uni_pulse_ctx_t *p = (struct wm_uni_pulse_ctx_t *)wm_get();
uint32_t m;
uint32_t t_min;
uint32_t t_max;
if(vscanReset){
Vset = p->_v0;
return;
}
if(!vscanReset){
if (t == 0) {
m = 0;
} else {
m = t % p->_t_period;
}
if (m < p->_t_pa[0]) {
p->_Vset = p->_v_initial[0] + p->_v_slope[0] * t + p->_v_step[0] * (int32_t)(t / p->_t_period);
Vset = p->_Vset;
t_min = p->_t_pulse_min[0];
t_max = p->_t_pulse_max[0];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
return;
}
if (m < p->_t_pa[1]) {
p->_Vset = p->_v_initial[1] + p->_v_slope[1] * t + p->_v_step[1] * (int32_t)(t / p->_t_period);
Vset = p->_Vset;
t_min = p->_t_pa[0] + p->_t_pulse_min[1];
t_max = p->_t_pa[0] + p->_t_pulse_max[1];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
return;
}
if (m < p->_t_pa[2]) {
p->_Vset = p->_v_initial[2] + p->_v_slope[2] * t + p->_v_step[2] * (int32_t)(t / p->_t_period);
Vset = p->_Vset;
t_min = p->_t_pa[1] + p->_t_pulse_min[2];
t_max = p->_t_pa[1] + p->_t_pulse_max[2];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
return;
}
if (m < p->_t_pa[3]) {
p->_Vset = p->_v_initial[3] + p->_v_slope[3] * t + p->_v_step[3] * (int32_t)(t / p->_t_period);
Vset = p->_Vset;
t_min = p->_t_pa[2] + p->_t_pulse_min[3];
t_max = p->_t_pa[2] + p->_t_pulse_max[3];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
return;
}
return;
}
return;
}
static void dpv_vscan(uint32_t time)
{
uint32_t t = time;
struct wm_dpv_ctx_t *p = (struct wm_dpv_ctx_t *)wm_get();
uint32_t m;
uint32_t t_min;
uint32_t t_max;
if(vscanReset){
Vset = p->_v0;
return;
}
if(!vscanReset){
if (t == 0) {
m = 0;
} else {
m = t % p->_t_period;
}
if (m < p->_t_pa[0]) {
p->_Vset = p->_v_initial[0] + p->_v_slope[0] * t / 1000 + p->_v_step[0] * (int32_t)dpv_step_cnt; // _v_slope/100 = slope
Vset = p->_Vset;
t_min = p->_t_pulse_min[0];
t_max = p->_t_pulse_max[0];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
if ((p->_v_curr_direc && Vset >= p->_v_stop) ||
(!p->_v_curr_direc && Vset <= p->_v_stop)) {
PeriodicEvent = false;
}
return;
}
if (m < p->_t_pa[1]) {
p->_Vset = p->_v_initial[1] + p->_v_slope[1] * t / 1000 + p->_v_step[1] * (int32_t)dpv_step_cnt;
Vset = p->_Vset;
t_min = p->_t_pa[0] + p->_t_pulse_min[1];
t_max = p->_t_pa[0] + p->_t_pulse_max[1];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
return;
}
return;
}
return;
}
static void dpv_advance_vscan(uint32_t time)
{
uint32_t t = time;
struct wm_dpv_advance_ctx_t *p = (struct wm_dpv_advance_ctx_t *)wm_get();
uint32_t m;
uint32_t t_min;
uint32_t t_max;
static bool VminCounter;
static bool VmaxCounter;
if(vscanReset){
if (p->_v_direc_init) {
if (p->_v0 <= p->_v_up && p->_v0 <= p->_v_low && p->_v_2 > p->_v_1) {
VminCounter = true;
}
} else {
if (p->_v0 >= p->_v_up && p->_v0 >= p->_v_low && p->_v_1 > p->_v_2) {
VmaxCounter = true;
}
}
p->_Vset = p->_v0;
Vset = p->_Vset;
return;
}
if(!vscanReset){
if (t == 0) {
m = 0;
} else {
m = t % p->_t_period;
}
if (m < p->_t_pa[0]) {
t_min = p->_t_pulse_min[0];
t_max = p->_t_pulse_max[0];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
p->_Vset = p->_v_initial[0] + p->_v_slope[0] * t / 1000 + p->_v_step[0] * (int32_t)dpv_step_cnt; // _v_slope/100 = slope
Vset = p->_Vset;
if (VminCounter == true && VmaxCounter == true) {
p->_cycleNumber--;
VminCounter = false;
VmaxCounter = false;
}
if (p->_cycleNumber <= 0) {
if (p->_v_stop_direction == true && p->_Vset >= p->_v_stop - p->_v_amp + p->_v_step[0]) {
PeriodicEvent = false;
} else if (p->_v_stop_direction == false && p->_Vset <= p->_v_stop - p->_v_amp + p->_v_step[0]) {
PeriodicEvent = false;
}
}
if (p->_v_curr_direc && p->_Vset >= p->_v_up - p->_v_amp + p->_v_step[0]) {
if (p->_v_invert_option) {
p->_v_amp = p->_v_amp * (-1);
}
p->_v_initial[0] = p->_Vset;
p->_v_initial[1] = p->_v_initial[0] + p->_v_amp;
dpv_step_cnt = 0;
p->_v_step[0] = (-1) * p->_v_step[0];
p->_v_step[1] = (-1) * p->_v_step[1];
p->_v_curr_direc = false;
VmaxCounter = true;
p->_Vset = p->_v_initial[0] + p->_v_slope[0] * t / 1000 * (int32_t)dpv_step_cnt; // _v_slope/100 = slope
Vset = p->_Vset;
} else if (!p->_v_curr_direc && p->_Vset <= p->_v_low - p->_v_amp + p->_v_step[0]) {
if (p->_v_invert_option) {
p->_v_amp = p->_v_amp * (-1);
}
p->_v_initial[0] = p->_Vset;
p->_v_initial[1] = p->_v_initial[0] + p->_v_amp;
dpv_step_cnt = 0;
p->_v_step[0] = (-1) * p->_v_step[0];
p->_v_step[1] = (-1) * p->_v_step[1];
p->_v_curr_direc = true;
VminCounter = true;
p->_Vset = p->_v_initial[0] + p->_v_slope[0] * t / 1000 * (int32_t)dpv_step_cnt; // _v_slope/100 = slope
Vset = p->_Vset;
}
return;
}
if (m < p->_t_pa[1]) {
p->_Vset = p->_v_initial[1] + p->_v_slope[1] * t / 1000 + p->_v_step[1] * (int32_t)dpv_step_cnt;
Vset = p->_Vset;
t_min = p->_t_pa[0] + p->_t_pulse_min[1];
t_max = p->_t_pa[0] + p->_t_pulse_max[1];
if (m > t_min && m < t_max) {
calc_avg_en = true;
} else {
calc_avg_en = false;
}
return;
}
return;
}
return;
}
static void chg_vo_para(uint16_t parameter, int32_t value)
{
uint16_t pa = parameter;
int32_t val = value;
struct wm_vo_ctx_t *vo = (struct wm_vo_ctx_t *)wm_get();
if (pa == DAC_VOLT) {
vo->_Vinit = val;
}
return;
}
static void chg_it_para(uint16_t parameter, int32_t value)
{
uint16_t pa = parameter;
int32_t val = value;
struct wm_it_ctx_t *it = (struct wm_it_ctx_t *)wm_get();
if (pa == DAC_VOLT) {
it->_Vinit = val;
}
return;
}
static void chg_rt_para(uint16_t parameter, int32_t value)
{
uint16_t pa = parameter;
int32_t val = value;
struct wm_rt_ctx_t *rt = (struct wm_rt_ctx_t *)wm_get();
if (pa == DAC_VOLT) {
rt->_Vinit = val;
}
return;
}
static void set_para(uint8_t eliteFxn, uint16_t parameter, int32_t value)
{
uint8_t mode = eliteFxn;
uint16_t pa = parameter;
int32_t val = value;
if (mode == CURVE_VO) {
chg_vo_para(pa, val);
return;
}
if (mode == CURVE_IT) {
chg_it_para(pa, val);
return;
}
if (mode == CURVE_RT) {
chg_rt_para(pa, val);
return;
}
return;
}
#endif
@@ -9,7 +9,7 @@
Target Device: CC2650, CC2640
******************************************************************************
Copyright (c) 2013-2018, Texas Instruments Incorporated
All rights reserved.
@@ -105,11 +105,11 @@
#ifndef FEATURE_OAD
// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic
// parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 6 //ori:80
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
// parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 800
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 6 //ori:800
#else //!FEATURE_OAD
// Minimum connection interval (units of 1.25ms, 8=10ms) if automatic
// parameter update request is enabled
@@ -147,7 +147,7 @@
#ifndef SBP_TASK_STACK_SIZE
#define SBP_TASK_STACK_SIZE 644
#define SBP_TASK_STACK_SIZE 844 //ori:644
#endif
// Internal Events for RTOS application
@@ -155,6 +155,7 @@
#define SBP_CHAR_CHANGE_EVT 0x0002
#define SBP_PERIODIC_EVT 0x0004
#define SBP_CONN_EVT_END_EVT 0x0008
#define SBP_KEY_CHANGE_EVT 0x0010
/*********************************************************************
* TYPEDEFS
@@ -181,7 +182,7 @@ typedef struct
static ICall_EntityID selfEntity;
// Semaphore globally used to post events to the application thread
static ICall_Semaphore sem;
static ICall_Semaphore semaphore;
// Clock instances for internal periodic events.
static Clock_Struct periodicClock;
@@ -207,6 +208,7 @@ Char sbpTaskStack[SBP_TASK_STACK_SIZE];
//static gaprole_States_t gapProfileState = GAPROLE_INIT;
// GAP - SCAN RSP data (max size = 31 bytes)
/*
static uint8_t scanRspData[] =
{
// complete name
@@ -245,6 +247,7 @@ static uint8_t scanRspData[] =
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
};
*/
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
@@ -276,7 +279,7 @@ static uint8_t advertData[] =
};
// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
// static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple BLE Peripheral";
// Globals used for ATT Response retransmission
static gattMsgEvent_t *pAttRsp = NULL;
@@ -293,9 +296,9 @@ static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg);
static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg);
static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg);
static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState);
static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
// static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID);
static void SimpleBLEPeripheral_performPeriodicTask(void);
static void SimpleBLEPeripheral_clockHandler(UArg arg);
// static void SimpleBLEPeripheral_clockHandler(UArg arg);
static void SimpleBLEPeripheral_sendAttRsp(void);
static void SimpleBLEPeripheral_freeAttRsp(uint8_t status);
@@ -393,7 +396,7 @@ static void SimpleBLEPeripheral_init(void)
// ******************************************************************
// Register the current thread as an ICall dispatcher application
// so that the application can send and receive messages.
ICall_registerApp(&selfEntity, &sem);
ICall_registerApp(&selfEntity, &semaphore);
#ifdef USE_RCOSC
RCOSC_enableCalibration();
@@ -421,8 +424,8 @@ static void SimpleBLEPeripheral_init(void)
appMsgQueue = Util_constructQueue(&appMsg);
// Create one-shot clocks for internal periodic events.
Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
// Util_constructClock(&periodicClock, SimpleBLEPeripheral_clockHandler,
// SBP_PERIODIC_EVT_PERIOD, 0, false, SBP_PERIODIC_EVT);
// dispHandle = Display_open(Display_Type_LCD, NULL);
@@ -451,8 +454,8 @@ static void SimpleBLEPeripheral_init(void)
GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
&advertOffTime);
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
scanRspData);
// GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData),
// scanRspData);
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
GAPRole_SetParameter(GAPROLE_PARAM_UPDATE_ENABLE, sizeof(uint8_t),
@@ -468,7 +471,7 @@ static void SimpleBLEPeripheral_init(void)
}
// Set the GAP Characteristics
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
// GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
// Set advertising interval
{
@@ -521,18 +524,18 @@ static void SimpleBLEPeripheral_init(void)
{
uint8_t charValue1 = 1;
uint8_t charValue2 = 2;
uint8_t charValue3 = 3;
uint8_t charValue4 = 4;
uint8_t charValue3[SIMPLEPROFILE_CHAR3_LEN] = {0};
uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = {0};
uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t),
&charValue1);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t),
&charValue2);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t),
&charValue3);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t),
&charValue4);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, SIMPLEPROFILE_CHAR3_LEN,
charValue3);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN,
charValue4);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN,
charValue5);
}
@@ -554,6 +557,7 @@ static void SimpleBLEPeripheral_init(void)
GATT_RegisterForMsgs(selfEntity);
HCI_LE_ReadMaxDataLenCmd();
/*
#if defined FEATURE_OAD
#if defined (HAL_IMAGE_A)
@@ -567,6 +571,120 @@ static void SimpleBLEPeripheral_init(void)
*/
}
// buffer size
#define BLE_CIS_BUFF_CHAR SIMPLEPROFILE_CHAR2
#define BLE_INS_BUFF_CHAR SIMPLEPROFILE_CHAR3
#define BLE_DAT_BUFF_CHAR SIMPLEPROFILE_CHAR4
#define BLE_CIS_BUFF_SIZE SIMPLEPROFILE_CHAR2_LEN
#define BLE_INS_BUFF_SIZE SIMPLEPROFILE_CHAR3_LEN
#define BLE_DAT_BUFF_SIZE SIMPLEPROFILE_CHAR4_LEN
// define for futher convention usage
//
#define REVERT_2_BYTE(_b) ((_b) >> 8 | (((_b) & 0xFF) << 8))
#define ENABLE 1
#define DISABLE 0
//
#include "driver/spi_ctrl.h"
#include "hardware/led_APA_102.h"
#include "driver/timers.h"
#include "elite_task/elite_GPtimer.h"
#include "hardware/dac_MAX5136.h"
#include "hardware/adc_ads1118.h"
#include "driver/gpio_edc15re.h"
#include "elite_task/elite_latch.h"
struct gptimer0_t GPT;
static uint16_t ADC_rxbuf = 0;
void elite_gptimer_task(void)
{
events |= SBP_PERIODIC_EVT;
Semaphore_post(semaphore);
GPT.cnt_gpt++;
}
#include "headstage.h"
#include "EliteWorkData.h"
static bool power_on(uint32_t delta_time)
{
uint32_t t = delta_time;
bool elite_on = false;
static uint32_t keyTimer = 0;
keyTimer = keyTimer + t;
if (keyTimer >= 10000) {
latch_single_ctrl(E_LATCH_5V_ENABLE, 1);
latch_single_ctrl(E_LATCH_10V_ENABLE, 1);
CPUdelay_us(320); // need delay 320us to stablize power
ModeLED(BT_WAIT);
//AD5940_Initialize();
headstage_battery_volt();
headstage_init_device_info();
elite_on = true;
}
return elite_on;
}
/*return the button status*/
uint8_t pin_button_get(void)
{
/*
* if btn = 0: press key
* if btn = 1: release key
*/
uint8_t btn;
btn = PIN_getInputValue(E_PIN_SHUT_DOWN);
return btn;
}
/* manage the button control*/
static void key_manage(uint32_t delta_time)
{
uint32_t t = delta_time;
static uint32_t keyTimer = 0;
static bool byPass1sec = false;
if (pin_button_get()!=0) {
if (keyTimer > 0) {
checkFlafLED();
byPass1sec = false;
}
keyTimer = 0;
return;
}
keyTimer = keyTimer + t;
if (keyTimer >= 30000){
latch_single_ctrl(E_LATCH_5V_ENABLE, 0);
} else if (keyTimer >= 10000 && !byPass1sec) {
led_color_set(LED_NB_MAX, LED_BR_LV1, LED_CLR_ORANGE);
byPass1sec = true;
}
return;
}
/* toggle 6994 to on*/
static void toggle_6994(uint16_t counter6994) {
if(counter6994 == CLOCK_ONE_SECOND*5) {
latch_single_ctrl(E_LATCH_OFF, 0); // OFF = 1 => turn off 6994
}
}
/*********************************************************************
* @fn SimpleBLEPeripheral_taskFxn
*
@@ -578,101 +696,134 @@ static void SimpleBLEPeripheral_init(void)
*/
static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
{
// Initialize application
SimpleBLEPeripheral_init();
uint8_t key= 0;
bool elite_on = false;
batteryADC_flag = false;
uint32_t check_key_time = 0;
uint16_t counter6994 = 0;
// Application main loop
for (;;)
{
// Waits for a signal to the semaphore associated with the calling thread.
// Note that the semaphore associated with a thread is signaled when a
// message is queued to the message receive queue of the thread or when
// ICall_signal() function is called onto the semaphore.
ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
// Initialize application
SimpleBLEPeripheral_init();
if (errno == ICALL_ERRNO_SUCCESS)
{
ICall_EntityID dest;
ICall_ServiceEnum src;
ICall_HciExtEvt *pMsg = NULL;
device_init();
if (ICall_fetchServiceMsg(&src, &dest,
(void **)&pMsg) == ICALL_ERRNO_SUCCESS)
{
uint8 safeToDealloc = TRUE;
while(1) {
if (events & SBP_PERIODIC_EVT) {
events &= ~SBP_PERIODIC_EVT;
GPT_timerIncrement();
elite_on = power_on(GPT.cnt_gpt_delta);
}
if (elite_on)
break;
}
if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
{
ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;
// Application main loop
for (;;) {
// Waits for a signal to the semaphore associated with the calling thread.
// Note that the semaphore associated with a thread is signaled when a
// message is queued to the message receive queue of the thread or when
// ICall_signal() function is called onto the semaphore.
// Check for BLE stack events first
if (pEvt->signature == 0xffff)
{
if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)
{
// Try to retransmit pending ATT Response (if any)
SimpleBLEPeripheral_sendAttRsp();
ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER); // let errno wait for infinite time, if periodicClock time up then execute below code
if (errno == ICALL_ERRNO_SUCCESS) {
ICall_EntityID dest;
ICall_ServiceEnum src;
ICall_HciExtEvt *pMsg = NULL;
if (ICall_fetchServiceMsg(&src, &dest,
(void **)&pMsg) == ICALL_ERRNO_SUCCESS) {
uint8 safeToDealloc = TRUE;
if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) {
ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;
// Check for BLE stack events first
if (pEvt->signature == 0xffff) {
if (pEvt->event_flag & SBP_CONN_EVT_END_EVT) {
// Try to retransmit pending ATT Response (if any)
SimpleBLEPeripheral_sendAttRsp();
}
} else {
// Process inter-task message
safeToDealloc = SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg);
}
}
if (pMsg && safeToDealloc) {
ICall_freeMsg(pMsg);
}
}
// If RTOS queue is not empty, process app message.
while (!Queue_empty(appMsgQueue)) {
sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
if (pMsg) {
// Process message.
SimpleBLEPeripheral_processAppMsg(pMsg);
// Free the space from the message.
ICall_free(pMsg);
}
}
}
else
{
// Process inter-task message
safeToDealloc = SimpleBLEPeripheral_processStackMsg((ICall_Hdr *)pMsg);
}
}
if (pMsg && safeToDealloc)
{
ICall_freeMsg(pMsg);
GPT_timerIncrement();
check_key_time = check_key_time + GPT.cnt_gpt_delta;
GPT.BatteryADCCounter = GPT.BatteryADCCounter + GPT.cnt_gpt_delta;
GPT.BatteryCheckCounter = GPT.BatteryCheckCounter + GPT.cnt_gpt_delta;
if (events & SBP_PERIODIC_EVT) {
events &= ~SBP_PERIODIC_EVT;
/* routinely check the button status*/
if (check_key_time >= 200) {
key_manage(200);
check_key_time = 0;
}
if (!PeriodicEvent) { // if there is no periodic event
if (counter6994 <= CLOCK_ONE_SECOND*5) {
toggle_6994(counter6994);
counter6994++;
}
key = PIN_getInputValue(E_PIN_SHUT_DOWN);
if (key != 0) { //detect Elite battery power when no periodic event
measureBat();
}
if (Free_Work_Mode) {
wm_deinit();
InitEliteInstruction();
Free_Work_Mode = false;
}
} else { // if there is periodic event
if(InitPeriodicEvent){
wm_init();
InitPeriodicEvent = false;
}
// Perform periodic application task
SimpleBLEPeripheral_performPeriodicTask();
}
}
}
// If RTOS queue is not empty, process app message.
while (!Queue_empty(appMsgQueue))
{
sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
if (pMsg)
{
// Process message.
SimpleBLEPeripheral_processAppMsg(pMsg);
// Free the space from the message.
ICall_free(pMsg);
}
}
}
if (events & SBP_PERIODIC_EVT)
{
events &= ~SBP_PERIODIC_EVT;
Util_startClock(&periodicClock);
// Perform periodic application task
SimpleBLEPeripheral_performPeriodicTask();
}
#ifdef FEATURE_OAD
while (!Queue_empty(hOadQ))
{
oadTargetWrite_t *oadWriteEvt = Queue_get(hOadQ);
while (!Queue_empty(hOadQ)) {
oadTargetWrite_t *oadWriteEvt = Queue_get(hOadQ);
// Identify new image.
if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
{
OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
}
// Write a next block request.
else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
{
OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
}
// Identify new image.
if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ) {
OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
} else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ) { // Write a next block request.
OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
}
// Free buffer.
ICall_free(oadWriteEvt);
}
// Free buffer.
ICall_free(oadWriteEvt);
}
#endif //FEATURE_OAD
}
}
}
/*********************************************************************
@@ -709,7 +860,7 @@ static uint8_t SimpleBLEPeripheral_processStackMsg(ICall_Hdr *pMsg)
AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
}
break;
default:
break;
}
@@ -863,7 +1014,8 @@ static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg) {
break;
case SBP_CHAR_CHANGE_EVT:
SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
// SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
ZM_instruction_update_handle(pMsg->hdr.state);
break;
default:
@@ -926,14 +1078,10 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
// Display device address
// Display_print0(dispHandle, 1, 0, Util_convertBdAddr2Str(ownAddress));
// Display_print0(dispHandle, 2, 0, "Initialized");
}
break;
case GAPROLE_ADVERTISING:
// Display_print0(dispHandle, 2, 0, "Advertising");
break;
#ifdef PLUS_BROADCASTER
@@ -944,7 +1092,7 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
*/
case GAPROLE_ADVERTISING_NONCONN:
{
uint8_t advertEnabled = FALSE;
uint8_t advertEnabled = true; // do some change to experiment
// Disable non-connectable advertising.
GAPRole_SetParameter(GAPROLE_ADV_NONCONN_ENABLED, sizeof(uint8_t),
@@ -969,7 +1117,7 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
linkDBInfo_t linkInfo;
uint8_t numActive = 0;
Util_startClock(&periodicClock);
// Util_startClock(&periodicClock);
numActive = linkDB_NumActive();
@@ -977,8 +1125,6 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
// connection
if ( linkDB_GetInfo( numActive - 1, &linkInfo ) == SUCCESS )
{
// Display_print1(dispHandle, 2, 0, "Num Conns: %d", (uint16_t)numActive);
// Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(linkInfo.addr));
}
else
{
@@ -986,8 +1132,6 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
// Display_print0(dispHandle, 2, 0, "Connected");
// Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(peerAddress));
}
#ifdef PLUS_BROADCASTER
@@ -1015,26 +1159,16 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
break;
case GAPROLE_CONNECTED_ADV:
// Display_print0(dispHandle, 2, 0, "Connected Advertising");
break;
case GAPROLE_WAITING:
Util_stopClock(&periodicClock);
SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
// Display_print0(dispHandle, 2, 0, "Disconnected");
// Clear remaining lines
// Display_clearLines(dispHandle, 3, 5);
ModeLED(BT_WAIT);
break;
case GAPROLE_WAITING_AFTER_TIMEOUT:
SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
// Display_print0(dispHandle, 2, 0, "Timed Out");
// Clear remaining lines
// Display_clearLines(dispHandle, 3, 5);
ModeLED(BT_WAIT);
#ifdef PLUS_BROADCASTER
// Reset flag for next connection.
@@ -1043,11 +1177,9 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
break;
case GAPROLE_ERROR:
// Display_print0(dispHandle, 2, 0, "Error");
break;
default:
// Display_clearLine(dispHandle, 2);
break;
}
@@ -1082,6 +1214,7 @@ static void SimpleBLEPeripheral_charValueChangeCB(uint8_t paramID)
*
* @return None.
*/
/*
static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
{
#ifndef FEATURE_OAD_ONCHIP
@@ -1092,13 +1225,13 @@ static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
case SIMPLEPROFILE_CHAR1:
SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue);
// Display_print1(dispHandle, 4, 0, "Char 1: %d", (uint16_t)newValue);
Display_print1(dispHandle, 4, 0, "Char 1: %d", (uint16_t)newValue);
break;
case SIMPLEPROFILE_CHAR3:
SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue);
// Display_print1(dispHandle, 4, 0, "Char 3: %d", (uint16_t)newValue);
Display_print1(dispHandle, 4, 0, "Char 3: %d", (uint16_t)newValue);
break;
default:
@@ -1107,6 +1240,7 @@ static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
}
#endif //!FEATURE_OAD_ONCHIP
}
*/
/*********************************************************************
* @fn SimpleBLEPeripheral_performPeriodicTask
@@ -1123,6 +1257,9 @@ static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
*/
static void SimpleBLEPeripheral_performPeriodicTask(void)
{
elite_task();
/*
#ifndef FEATURE_OAD_ONCHIP
uint8_t valueToCopy;
@@ -1137,6 +1274,7 @@ static void SimpleBLEPeripheral_performPeriodicTask(void)
&valueToCopy);
}
#endif //!FEATURE_OAD_ONCHIP
*/
}
@@ -1171,7 +1309,7 @@ void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
Queue_put(hOadQ, (Queue_Elem *)oadWriteEvt);
// Post the application's semaphore.
Semaphore_post(sem);
Semaphore_post(semaphore);
}
else
{
@@ -1189,14 +1327,16 @@ void SimpleBLEPeripheral_processOadWriteCB(uint8_t event, uint16_t connHandle,
*
* @return None.
*/
/*
static void SimpleBLEPeripheral_clockHandler(UArg arg)
{
// Store the event.
events |= arg;
// Wake up the application.
Semaphore_post(sem);
Semaphore_post(semaphore);
}
*/
/*********************************************************************
* @fn SimpleBLEPeripheral_enqueueMsg
@@ -1219,9 +1359,18 @@ static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state)
pMsg->hdr.state = state;
// Enqueue the message.
Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
Util_enqueueMsg(appMsgQueue, semaphore, (uint8*)pMsg);
}
}
/*********************************************************************
*********************************************************************/
#include "hardware/led_APA_102_c.h"
#include "driver/spi_ctrl_c.h"
#include "driver/timers_c.h"
#include "elite_task/elite_GPtimer_c.h"
#include "hardware/DAC_MAX5136_c.h"
#include "hardware/adc_ads1118_c.h"
#include "driver/gpio_edc15re_c.h"
#include "elite_task/elite_latch_c.h"
@@ -9,7 +9,7 @@
Target Device: CC2650, CC2640
******************************************************************************
Copyright (c) 2010-2018, Texas Instruments Incorporated
All rights reserved.
@@ -135,7 +135,6 @@ static simpleProfileCBs_t *simpleProfile_AppCBs = NULL;
// Simple Profile Service attribute
static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };
// Simple Profile Characteristic 1 Properties
// static uint8 simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE;
/*user insert*/
@@ -144,13 +143,12 @@ static uint8 simpleProfileChar1Props = GATT_PROP_READ;
// Characteristic 1 Value
// static uint8 simpleProfileChar1 = 0;
/*user insert*/
#define SIMPLEPROFILE_CHAR1_LEN 20
static uint8 simpleProfileChar1[SIMPLEPROFILE_CHAR1_LEN] = {0};
// Simple Profile Characteristic 1 User Description
static uint8 simpleProfileChar1UserDesp[17] = "Characteristic 1";
// Simple Profile Characteristic 2 Properties
static uint8 simpleProfileChar2Props = GATT_PROP_READ;
@@ -159,11 +157,9 @@ static uint8 simpleProfileChar2Props = GATT_PROP_READ;
/*user insert*/
static uint8 simpleProfileChar2[SIMPLEPROFILE_CHAR2_LEN] = {0};
// Simple Profile Characteristic 2 User Description
static uint8 simpleProfileChar2UserDesp[17] = "Characteristic 2";
// Simple Profile Characteristic 3 Properties
static uint8 simpleProfileChar3Props = GATT_PROP_WRITE;
@@ -172,11 +168,9 @@ static uint8 simpleProfileChar3Props = GATT_PROP_WRITE;
/*user insert*/
static uint8 simpleProfileChar3[SIMPLEPROFILE_CHAR3_LEN] = {0};
// Simple Profile Characteristic 3 User Description
static uint8 simpleProfileChar3UserDesp[17] = "Characteristic 3";
// Simple Profile Characteristic 4 Properties
static uint8 simpleProfileChar4Props = GATT_PROP_NOTIFY;
@@ -185,7 +179,6 @@ static uint8 simpleProfileChar4Props = GATT_PROP_NOTIFY;
/*user insert*/
static uint8 simpleProfileChar4[SIMPLEPROFILE_CHAR4_LEN] = {0};
// Simple Profile Characteristic 4 Configuration Each client has its own
// instantiation of the Client Characteristic Configuration. Reads of the
// Client Characteristic Configuration only shows the configuration for
@@ -195,7 +188,6 @@ static gattCharCfg_t *simpleProfileChar4Config;
// Simple Profile Characteristic 4 User Description
static uint8 simpleProfileChar4UserDesp[17] = "Characteristic 4";
// Simple Profile Characteristic 5 Properties
static uint8 simpleProfileChar5Props = GATT_PROP_READ;
@@ -230,17 +222,17 @@ static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
// Characteristic Value 1
{
{ ATT_BT_UUID_SIZE, simpleProfilechar1UUID },
GATT_PERMIT_READ,
0,
simpleProfileChar1
GATT_PERMIT_READ,
0,
simpleProfileChar1
},
// Characteristic 1 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar1UserDesp
GATT_PERMIT_READ,
0,
simpleProfileChar1UserDesp
},
// Characteristic 2 Declaration
@@ -254,112 +246,114 @@ static gattAttribute_t simpleProfileAttrTbl[SERVAPP_NUM_ATTR_SUPPORTED] =
// Characteristic Value 2
{
{ ATT_BT_UUID_SIZE, simpleProfilechar2UUID },
GATT_PERMIT_READ,
0,
simpleProfileChar2
},
GATT_PERMIT_READ,
0,
simpleProfileChar2
},
// Characteristic 2 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar2UserDesp
},
// Characteristic 2 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar2UserDesp
},
// Characteristic 3 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar3Props
},
// Characteristic Value 3
{
{ ATT_BT_UUID_SIZE, simpleProfilechar3UUID },
GATT_PERMIT_WRITE,
0,
simpleProfileChar3
},
// Characteristic Value 3
{
{ ATT_BT_UUID_SIZE, simpleProfilechar3UUID },
GATT_PERMIT_WRITE,
0,
simpleProfileChar3
},
// Characteristic 3 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar3UserDesp
},
// Characteristic 3 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar3UserDesp
},
// Characteristic 4 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar4Props
},
// Characteristic Value 4
{
{ ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
0,
0,
simpleProfileChar4
},
// Characteristic Value 4
{
{ ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
0,
0,
simpleProfileChar4
},
// Characteristic 4 configuration
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8 *)&simpleProfileChar4Config
},
// Characteristic 4 configuration
{
{ ATT_BT_UUID_SIZE, clientCharCfgUUID },
GATT_PERMIT_READ | GATT_PERMIT_WRITE,
0,
(uint8 *)&simpleProfileChar4Config
},
// Characteristic 4 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar4UserDesp
},
// Characteristic 4 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar4UserDesp
},
// Characteristic 5 Declaration
{
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
{ ATT_BT_UUID_SIZE, characterUUID },
GATT_PERMIT_READ,
0,
&simpleProfileChar5Props
},
// Characteristic Value 5
{
{ ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
GATT_PERMIT_AUTHEN_READ,
0,
simpleProfileChar5
},
// Characteristic Value 5
{
{ ATT_BT_UUID_SIZE, simpleProfilechar5UUID },
GATT_PERMIT_AUTHEN_READ,
0,
simpleProfileChar5
},
// Characteristic 5 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar5UserDesp
},
// Characteristic 5 User Description
{
{ ATT_BT_UUID_SIZE, charUserDescUUID },
GATT_PERMIT_READ,
0,
simpleProfileChar5UserDesp
},
};
/*********************************************************************
* LOCAL FUNCTIONS
*/
static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen,
uint16_t offset, uint16_t maxLen,
uint8_t method);
gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen,
uint16_t offset, uint16_t maxLen,
uint8_t method);
static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len,
uint16_t offset, uint8_t method);
gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len,
uint16_t offset, uint8_t method);
/*********************************************************************
* PROFILE CALLBACKS
@@ -401,7 +395,7 @@ bStatus_t SimpleProfile_AddService( uint32 services )
// Allocate Client Characteristic Configuration table
simpleProfileChar4Config = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) *
linkDBNumConns );
linkDBNumConns );
if ( simpleProfileChar4Config == NULL )
{
return ( bleMemAllocError );
@@ -414,9 +408,9 @@ bStatus_t SimpleProfile_AddService( uint32 services )
{
// Register GATT attribute list and CBs with GATT Server App
status = GATTServApp_RegisterService( simpleProfileAttrTbl,
GATT_NUM_ATTRS( simpleProfileAttrTbl ),
GATT_MAX_ENCRYPT_KEY_SIZE,
&simpleProfileCBs );
GATT_NUM_ATTRS( simpleProfileAttrTbl ),
GATT_MAX_ENCRYPT_KEY_SIZE,
&simpleProfileCBs );
}
else
{
@@ -474,7 +468,7 @@ bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
{
memcpy(simpleProfileChar1, value, len);
// simpleProfileChar1 = *((uint8*)value);
}
}
else
{
ret = bleInvalidRange;
@@ -488,7 +482,7 @@ bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
// simpleProfileChar2 = *((uint8*)value);
}
else
{
{
ret = bleInvalidRange;
}
break;
@@ -497,8 +491,7 @@ bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
if (len <= SIMPLEPROFILE_CHAR3_LEN)
{
memcpy(simpleProfileChar3, value, len);
// simpleProfileChar3 = *((uint8*)value);
}
}
else
{
ret = bleInvalidRange;
@@ -509,12 +502,9 @@ bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
if (len <= SIMPLEPROFILE_CHAR4_LEN)
{
memcpy(simpleProfileChar4, value, len);
// simpleProfileChar4 = *((uint8*)value);
// See if Notification has been enabled
GATTServApp_ProcessCharCfg( simpleProfileChar4Config, simpleProfileChar4, FALSE,
simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
INVALID_TASK_ID, simpleProfile_ReadAttrCB );
GATTServApp_ProcessCharCfg(simpleProfileChar4Config, simpleProfileChar4, FALSE, simpleProfileAttrTbl, GATT_NUM_ATTRS(simpleProfileAttrTbl), INVALID_TASK_ID, simpleProfile_ReadAttrCB);
}
else
{
@@ -523,9 +513,8 @@ bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
break;
case SIMPLEPROFILE_CHAR5:
if ( len == SIMPLEPROFILE_CHAR5_LEN )
{
VOID memcpy( simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN );
if (len == SIMPLEPROFILE_CHAR5_LEN) {
VOID memcpy(simpleProfileChar5, value, SIMPLEPROFILE_CHAR5_LEN);
}
else
{
@@ -554,41 +543,37 @@ bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void *value )
*
* @return bStatus_t
*/
bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
{
bStatus_t ret = SUCCESS;
switch ( param )
{
bStatus_t SimpleProfile_GetParameter(uint8 param, void *value) {
bStatus_t ret = SUCCESS;
switch (param) {
case SIMPLEPROFILE_CHAR1:
memcpy(value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN);
// *((uint8*)value) = simpleProfileChar1;
break;
memcpy(value, simpleProfileChar1, SIMPLEPROFILE_CHAR1_LEN);
// *((uint8*)value) = simpleProfileChar1;
break;
case SIMPLEPROFILE_CHAR2:
memcpy(value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_LEN);
// *((uint8*)value) = simpleProfileChar2;
break;
memcpy(value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_LEN);
// *((uint8*)value) = simpleProfileChar2;
break;
case SIMPLEPROFILE_CHAR3:
memcpy(value, simpleProfileChar3, SIMPLEPROFILE_CHAR3_LEN);
// *((uint8*)value) = simpleProfileChar3;
break;
memcpy(value, simpleProfileChar3, SIMPLEPROFILE_CHAR3_LEN);
break;
case SIMPLEPROFILE_CHAR4:
memcpy(value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN);
// *((uint8*)value) = simpleProfileChar4;
break;
memcpy(value, simpleProfileChar4, SIMPLEPROFILE_CHAR4_LEN);
break;
case SIMPLEPROFILE_CHAR5:
VOID memcpy( value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN );
break;
VOID memcpy(value, simpleProfileChar5, SIMPLEPROFILE_CHAR5_LEN);
break;
default:
ret = INVALIDPARAMETER;
break;
}
ret = INVALIDPARAMETER;
break;
}
return ( ret );
return (ret);
}
/*********************************************************************
@@ -606,65 +591,62 @@ bStatus_t SimpleProfile_GetParameter( uint8 param, void *value )
*
* @return SUCCESS, blePending or Failure
*/
static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen,
uint16_t offset, uint16_t maxLen,
uint8_t method)
{
bStatus_t status = SUCCESS;
static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr, uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method) {
bStatus_t status = SUCCESS;
// Make sure it's not a blob operation (no attributes in the profile are long)
if ( offset > 0 )
{
return ( ATT_ERR_ATTR_NOT_LONG );
}
if ( pAttr->type.len == ATT_BT_UUID_SIZE )
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch ( uuid )
{
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
// gattserverapp handles those reads
// characteristics 1 and 2 have read permissions
// characteritisc 3 does not have read permissions; therefore it is not
// included here
// characteristic 4 does not have read permissions, but because it
// can be sent as a notification, it is included here
case SIMPLEPROFILE_CHAR1_UUID:
*pLen = SIMPLEPROFILE_CHAR1_LEN;
VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN );
case SIMPLEPROFILE_CHAR2_UUID:
*pLen = SIMPLEPROFILE_CHAR2_LEN;
VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR2_LEN );
case SIMPLEPROFILE_CHAR4_UUID:
*pLen = SIMPLEPROFILE_CHAR4_LEN;
VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN );
break;
case SIMPLEPROFILE_CHAR5_UUID:
*pLen = SIMPLEPROFILE_CHAR5_LEN;
VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN );
break;
default:
// Should never get here! (characteristics 3 and 4 do not have read permissions)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
// Make sure it's not a blob operation (no attributes in the profile are long)
if (offset > 0) {
return (ATT_ERR_ATTR_NOT_LONG);
}
}
else
{
// 128-bit UUID
*pLen = 0;
status = ATT_ERR_INVALID_HANDLE;
}
return ( status );
if (pAttr->type.len == ATT_BT_UUID_SIZE) {
// 16-bit UUID
uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch (uuid) {
// No need for "GATT_SERVICE_UUID" or "GATT_CLIENT_CHAR_CFG_UUID" cases;
// gattserverapp handles those reads
// characteristics 1 and 2 have read permissions
// characteritisc 3 does not have read permissions; therefore it is not
// included here
// characteristic 4 does not have read permissions, but because it
// can be sent as a notification, it is included here
case SIMPLEPROFILE_CHAR1_UUID:
*pLen = SIMPLEPROFILE_CHAR1_LEN;
VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR1_LEN);
break;
case SIMPLEPROFILE_CHAR2_UUID:
// *pLen = 1;
// pValue[0] = *pAttr->pValue;
*pLen = SIMPLEPROFILE_CHAR2_LEN;
VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR2_LEN);
break;
case SIMPLEPROFILE_CHAR4_UUID:
*pLen = SIMPLEPROFILE_CHAR4_LEN;
VOID memcpy(pValue, pAttr->pValue, SIMPLEPROFILE_CHAR4_LEN);
break;
// case SIMPLEPROFILE_CHAR5_UUID:
// *pLen = SIMPLEPROFILE_CHAR5_LEN;
// VOID memcpy( pValue, pAttr->pValue, SIMPLEPROFILE_CHAR5_LEN );
// break;
default:
// Should never get here! (characteristics 3 and 4 do not have read permissions)
*pLen = 0;
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
} else {
// 128-bit UUID
*pLen = 0;
status = ATT_ERR_INVALID_HANDLE;
}
return (status);
}
/*********************************************************************
@@ -681,83 +663,83 @@ static bStatus_t simpleProfile_ReadAttrCB(uint16_t connHandle,
*
* @return SUCCESS, blePending or Failure
*/
static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle,
gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len,
uint16_t offset, uint8_t method)
{
bStatus_t status = SUCCESS;
uint8 notifyApp = 0xFF;
static bStatus_t simpleProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr, uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method) {
bStatus_t status = SUCCESS;
uint8 notifyApp = 0xFF;
if ( pAttr->type.len == ATT_BT_UUID_SIZE )
{
// 16-bit UUID
uint16 uuid = BUILD_UINT16( pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch ( uuid )
{
case SIMPLEPROFILE_CHAR1_UUID:
case SIMPLEPROFILE_CHAR3_UUID:
if (pAttr->type.len == ATT_BT_UUID_SIZE) {
// 16-bit UUID
uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]);
switch (uuid) {
// Validate the value
// Make sure it's not a blob oper
/*
if ( offset == 0 )
{
if ( len != 1 )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Validate the value
// Make sure it's not a blob oper
if ( offset == 0 )
{
if ( len > SIMPLEPROFILE_CHAR3_LEN )
{
status = ATT_ERR_INVALID_VALUE_SIZE;
}
//Write the value
if ( status == SUCCESS )
{
uint8 *pCurValue = (uint8 *)pAttr->pValue;
*pCurValue = pValue[0];
if( pAttr->pValue == &simpleProfileChar1 )
{
notifyApp = SIMPLEPROFILE_CHAR1;
}
}
break;
*/
case SIMPLEPROFILE_CHAR3_UUID:
if (offset == 0) {
if (len > SIMPLEPROFILE_CHAR3_LEN) {
status = ATT_ERR_INVALID_VALUE_SIZE;
}
} else {
status = ATT_ERR_ATTR_NOT_LONG;
}
// Write the value
if (status == SUCCESS) {
// Copy pValue into the variable we point to from the attribute table.
memcpy(pAttr->pValue + offset, pValue, len);
memset(pAttr->pValue + len, 0, SIMPLEPROFILE_CHAR3_LEN - len);
if (pAttr->pValue == simpleProfileChar3) {
notifyApp = SIMPLEPROFILE_CHAR3;
}
}
break;
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_NOTIFY);
break;
default:
// Should never get here! (characteristics 2 and 4 do not have write permissions)
status = ATT_ERR_ATTR_NOT_FOUND;
break;
}
else
{
status = ATT_ERR_ATTR_NOT_LONG;
}
//Write the value
if ( status == SUCCESS )
{
uint8 *pCurValue = (uint8 *)pAttr->pValue;
*pCurValue = pValue[0];
// Copy pValue into the variable we point to from the attribute table.
memcpy(pAttr->pValue + offset, pValue, len);
memset(pAttr->pValue + len, 0, SIMPLEPROFILE_CHAR3_LEN - len);
if( pAttr->pValue == simpleProfileChar1 )
{
notifyApp = SIMPLEPROFILE_CHAR1;
}
else
{
notifyApp = SIMPLEPROFILE_CHAR3;
}
}
break;
case GATT_CLIENT_CHAR_CFG_UUID:
status = GATTServApp_ProcessCCCWriteReq( connHandle, pAttr, pValue, len,
offset, GATT_CLIENT_CFG_NOTIFY );
break;
default:
// Should never get here! (characteristics 2 and 4 do not have write permissions)
status = ATT_ERR_ATTR_NOT_FOUND;
break;
} else {
// 128-bit UUID
status = ATT_ERR_INVALID_HANDLE;
}
}
else
{
// 128-bit UUID
status = ATT_ERR_INVALID_HANDLE;
}
// If a characteristic value changed then callback function to notify application of change
if ( (notifyApp != 0xFF ) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange )
{
simpleProfile_AppCBs->pfnSimpleProfileChange( notifyApp );
}
// If a characteristic value changed then callback function to notify application of change
if ((notifyApp != 0xFF) && simpleProfile_AppCBs && simpleProfile_AppCBs->pfnSimpleProfileChange) {
simpleProfile_AppCBs->pfnSimpleProfileChange(notifyApp);
}
return ( status );
return (status);
}
/*********************************************************************
@@ -56,7 +56,7 @@ extern "C"
/*********************************************************************
* INCLUDES
*/
// #include "application_config/application_config.h"
/*********************************************************************
* CONSTANTS
*/
@@ -81,24 +81,12 @@ extern "C"
// Simple Keys Profile Services bit fields
#define SIMPLEPROFILE_SERVICE 0x00000001
#ifndef CUSTOM_GATT_LENGTH
// Length of Characteristic 5 in bytes
#define SIMPLEPROFILE_CHAR5_LEN 5
#define SIMPLEPROFILE_CHAR4_LEN 20
/*user insert*/
#define SIMPLEPROFILE_CHAR4_LEN 40
#define SIMPLEPROFILE_CHAR3_LEN 20
#define SIMPLEPROFILE_CHAR2_LEN 20
#define SIMPLEPROFILE_CHAR1_LEN 20
#else
/*user insert*/
#define SIMPLEPROFILE_CHAR5_LEN 5
#define SIMPLEPROFILE_CHAR4_LEN BLE_DAT_BUFF_SIZE
#define SIMPLEPROFILE_CHAR3_LEN BLE_INS_BUFF_SIZE
#define SIMPLEPROFILE_CHAR2_LEN BLE_CIS_BUFF_SIZE
#define SIMPLEPROFILE_CHAR1_LEN 20
#define BLE_CIS_BUFF_CHAR SIMPLEPROFILE_CHAR2
#define BLE_INS_BUFF_CHAR SIMPLEPROFILE_CHAR3
#define BLE_DAT_BUFF_CHAR SIMPLEPROFILE_CHAR4
#endif
/*********************************************************************
* TYPEDEFS
*/