Compare commits

..

64 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
43 changed files with 11112 additions and 3085 deletions
-55
View File
@@ -1,55 +0,0 @@
#Generated from Visual Studio settings
---
BasedOnStyle: webkit
BraceWrapping:
BeforeCatch: true
BeforeElse: true
AfterClass: true
AfterFunction: true
AfterControlStatement: true
AfterEnum: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
ColumnLimit: 0
BreakBeforeBraces: Custom
NamespaceIndentation: All
TabWidth: 4
IndentCaseLabels: true
AlignAfterOpenBracket: Align
PointerAlignment: Right
AlignOperands: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortLoopsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: false
BreakAfterJavaFieldAnnotations: true
AlignConsecutiveAssignments: true
AlignTrailingComments: true
BreakConstructorInitializers: AfterColon
AlignConsecutiveMacros:
Enabled: true
AcrossEmptyLines: true
AcrossComments: true
AlignArrayOfStructures: Right
AlignConsecutiveAssignments:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: true
PadOperators: true
AlignConsecutiveBitFields:
Enabled: true
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: true
PadOperators: true
AlignEscapedNewlines: Right
BinPackArguments: false
BinPackParameters: false
...
+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.
@@ -15,16 +15,16 @@ extern "C" {
* +------------------------+----------------------+-------------------------+----------------+----------------------+----------------------+----------+
* | model name | hw upper board | hw lower board | product number | device name | data server lib name | UI |
* +------------------------+----------------------+-------------------------+----------------+----------------------+----------------------+----------+
* | DEF_ELITE_EDC_1_4 | Elite1.4-re Jun.2019 | Elite1.4-re Jun. 2019 | 0, 2, 1, 5 | "Elite-EDC" | Elite_EDC_1.4 | null |
* | DEF_ELITE_EDC_1_5 | Elite1.5 Dec. 2019 | Elite1.5 Dec. 2019 | 0, 2, 1, 6 | "Elite-EDC" | Elite_EDC_1.5 | EliteEDC |
* | DEF_ELITE_EDC_1_5_RE | Elite1.5 Dec. 2019 | Elite1.5-re Jan. 2021 | 0, 2, 1, 7 | "Elite-EDC" | Elite_EDC_1.5re | EliteEDC |
* | DEF_ELITE_EDC_1_5_R2 | Elite1.5 Dec. 2019 | Elite1.5-r2 May. 2022 | 0, 2, 1, 8 | "Elite-EDC" | Elite_EDC_1.5r2 | EliteEDC |
* | DEF_ELITE_BAT_1_0 | Elite2.0 Feb. 2022 | 0, 3, 1, 0 | "Elite-BAT" | Elite_BAT_1.0 | EliteEDC |
* | DEF_ELITE_EIS_1_0 | Elite1.5 Dec. 2019 | Elite EIS1.0 Aug. 2020 | 0, 4, 1, 0 | "Elite-EIS" | Elite_EIS_1.0 | EliteEIS |
* | DEF_ELITE_EIS_1_1 | Elite1.5 Dec. 2019 | Elite EIS1.1 Feb. 2022 | 0, 4, 1, 1 | "Elite-EIS" | Elite_EIS_1.1 | EliteEIS |
* | DEF_ELITE_EIS_MINI_1_0 | EIS MINI May. 2022 | 0, 4, 1, 2 | "Elite-EIS-MINI" | Elite_EIS_MINI_1.0 | EliteEIS |
* | DEF_ELITE_TRIG_0_1 | Elite TRIG01 Jan. 2021 | 0, 5, 1, 0 | "Elite-TRIG" | Elite_TRIG_0.1 | null |
* | DEF_ELITE_MEGAFLY_0_1 | Elite1.5 Dec. 2019 | Elite Megafly Sep. 2020 | 0, 6, 1, 0 | "Elite-MEGAFLY" | Elite_MEGAFLY_0.1 | null |
* | 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
@@ -32,102 +32,102 @@ extern "C" {
*/
#define DEF_ELITE_EDC_1_4 0
#define DEF_ELITE_EDC_1_5 1
#define DEF_ELITE_EDC_1_5_RE 2
#define DEF_ELITE_EDC_1_5_R2 3
#define DEF_ELITE_BAT_1_0 4
#define DEF_ELITE_EIS_1_0 5
#define DEF_ELITE_EIS_1_1 6
#define DEF_ELITE_EIS_MINI_1_0 7
#define DEF_ELITE_TRIG_0_1 8
#define DEF_ELITE_MEGAFLY_0_1 9
#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_TRIG_0_1
#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_1_4)
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_14)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_1_5)
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_1_5_RE)
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15RE)
#include "boards_config/pin_def_edc15re.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_1_5_R2)
#elif (DEF_ELITE_MODEL == DEF_ELITE_EDC_15R2)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_1_0)
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_10)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_1_1)
#elif (DEF_ELITE_MODEL == DEF_ELITE_EIS_11)
#include "boards_config/pin_def_eis11.h"
#elif (DEF_ELITE_MODEL == DEF_ELITE_BAT_1_0)
#elif (DEF_ELITE_MODEL == DEF_ELITE_BAT_10)
#error "code no support" // need fix
#elif (DEF_ELITE_MODEL == DEF_ELITE_MEGAFLY_0_1)
#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
#elif (DEF_ELITE_MODEL == DEF_ELITE_TRIG_0_1)
#include "boards_config/pin_def_trig01.h"
#else
#error "no this model"
#endif
// model information
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_1_4)
#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_1_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_1_5_RE)
#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_1_5_R2)
#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_1_0)
#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_1_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_1_1)
#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_1_0)
#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_0_1)
#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_0_1)
#elif (DEF_ELITE_MODEL == DEF_ELITE_MEGAFLY_01)
#define DEVICE_NAME "Elite-MEGAFLY"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 6
@@ -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
@@ -1,93 +0,0 @@
#ifndef PIN_DEF_TRIG01_H
#define PIN_DEF_TRIG01_H
#ifdef __cplusplus
extern "C"
{
#endif
/*
* +------------------------------+
* | CC2650moda |
* +-------------+----------------+
* | TRIG_0 | DIO_0 |
* | MISO | DIO_1 |
* | TRIG_1 | DIO_2 | re: short TRIG_1 & LOAD2
* | D0 | DIO_3 |
* | D1 | DIO_4 |
* | D2/JTAG_TDO | DIO_5/JTAG_TDO |
* | D3/JTAG_TDI | DIO_6/JTAG_TDI |
* | D4 | DIO_7 |
* | D5 | DIO_8 |
* | D6 | DIO_9 |
* | D7 | DIO_10 |
* | LOAD0 | DIO_11 |
* | LOAD1 | DIO_12 |
* | FLT | DIO_13 |
* | SHUT_DOWN | DIO_14 |
* +-------------+----------------+
*/
#define CC2650_TRIG_0 DIO0
#define CC2650_MISO DIO1
#define CC2650_TRIG_1 DIO2
#define CC2650_D0 DIO3
#define CC2650_D1 DIO4
#define CC2650_D2 DIO5
#define CC2650_D3 DIO6
#define CC2650_D4 DIO7
#define CC2650_D5 DIO8
#define CC2650_D6 DIO9
#define CC2650_D7 DIO10
#define CC2650_LOAD0 DIO11
#define CC2650_LOAD1 DIO12
#define CC2650_FLT DIO13
#define CC2650_SHUT_DOWN DIO14
#define CC2650_LOAD2 CC2650_TRIG_1
#define E_PIN_LED_SCLK_A CC2650_LOAD0, CC2650_D0
#define E_PIN_LED_MOSI_A CC2650_LOAD0, CC2650_D1
#define E_PIN_SCLK CC2650_LOAD0, CC2650_D2
#define E_PIN_MOSI CC2650_LOAD0, CC2650_D3
#define E_PIN_TW_SCKI_0 CC2650_LOAD0, CC2650_D4
#define E_PIN_TW_SCKI_1 CC2650_LOAD0, CC2650_D5
#define E_PIN_TW_SCKI_2 CC2650_LOAD0, CC2650_D6
#define E_PIN_TW_SCKI_3 CC2650_LOAD0, CC2650_D7
#define E_PIN_BAT_CHAR CC2650_LOAD1, CC2650_D0
#define E_PIN_BAT_OK CC2650_LOAD1, CC2650_D1
#define E_PIN_3V_PULL_UP_DOWN_0 CC2650_LOAD1, CC2650_D2
#define E_PIN_3V_PULL_UP_DOWN_1 CC2650_LOAD1, CC2650_D3
#define E_PIN_OFF CC2650_LOAD1, CC2650_D4
#define E_PIN_5V_OUT_EN_0 CC2650_LOAD1, CC2650_D5
#define E_PIN_5V_enable CC2650_LOAD1, CC2650_D6
#define E_PIN_5V_OUT_EN_1 CC2650_LOAD1, CC2650_D7
#define E_PIN_DO_MOS_0 CC2650_LOAD2, CC2650_D0
#define E_PIN_DO_MOS_1 CC2650_LOAD2, CC2650_D1
#define E_PIN_AO_MOS_0 CC2650_LOAD2, CC2650_D2
#define E_PIN_AO_MOS_1 CC2650_LOAD2, CC2650_D3
#define E_PIN_AO_MOS_2 CC2650_LOAD2, CC2650_D4
#define E_PIN_AO_MOS_3 CC2650_LOAD2, CC2650_D5
#define E_PIN_D0_PR_0 CC2650_LOAD2, CC2650_D6
#define E_PIN_D0_PR_1 CC2650_LOAD2, CC2650_D7
/* SPI Board */
#define Board_SPI0_MISO PIN_UNASSIGNED
#define Board_SPI0_MOSI CC2650_D1 // load0 need to activate
#define Board_SPI0_CLK CC2650_D0 // load0 need to activate
#define Board_SPI0_CS PIN_UNASSIGNED
#define Board_SPI1_MISO CC2650_MISO
#define Board_SPI1_MOSI CC2650_D3 // load0 need to activate
#define Board_SPI1_CLK CC2650_D2 // load0 need to activate
#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_TRIG01_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;
}
@@ -1,11 +1,14 @@
#include <Board.h>
#include <ti/drivers/SPI.h>
#include "board.h"
#include "driver/spi_ctrl.h"
#define CC2650_SPI_BITRATE_MAX 6e6 // Full-duplex maximum speed = 6M
#define CC2650_SPI_BITRATE_MAX 6e6 //Full-duplex maximum speed = 6M
static SPI_Handle handle0 = NULL;
static SPI_Handle handle1 = NULL;
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
@@ -30,82 +33,91 @@ static SPI_FrameFormat _get_spi_mode(uint8_t pol, uint8_t pha)
}
/**
* spi_open -
* 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 spi already open,
* 3 on unsupported bit rate, 4 on unsupported polarity and phase,
* while (1); on failure
* note: Before using PIN_open() and SPI_open(), make sure that the pins are
* 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_Params para;
SPI_Handle* h;
SPI_Params* para;
uint8_t spi_module;
if (spi_n >= 2)
return 1;
if ((spi_n == SPI0 && handle0) || (spi_n == SPI1 && handle1))
if (b_rate > CC2650_SPI_BITRATE_MAX)
return 2;
if (b_rate > CC2650_SPI_BITRATE_MAX)
if (pol > 1 || pha > 1)
return 3;
if (pol > 1 || pha > 1)
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);
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 (spi_n == SPI0) {
handle0 = SPI_open(Board_SPI0, &para);
if (handle0 == NULL) {
while (1);
}
} else {
handle1 = SPI_open(Board_SPI1, &para);
if (handle1 == NULL) {
while (1);
}
}
if (*h == NULL)
return 5;
return 0;
}
/**
* spi_close -
* 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 \
* 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 && !handle0) || (spi_n == SPI1 && !handle1))
if (spi_n == SPI0)
h = &SpiHandle0;
else
h = &SpiHandle1;
if (*h == NULL)
return 2;
if (spi_n == SPI0) {
SPI_close(handle0);
handle0 = NULL;
} else {
SPI_close(handle1);
handle1 = NULL;
}
SPI_close(*h);
*h = NULL;
return 0;
}
/**
* spi_write -
* spi_close -
* @spi_n: which SPI
* @*rxBuf: rxbuf
* @*txBuf: txbuf
@@ -115,29 +127,47 @@ 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)
{
bool transferOK;
uint8_t ret;
SPI_Handle* h;
SPI_Transaction spi_tran;
if (spi_n >= 2)
return 1;
if ((spi_n == SPI0 && !handle0) || (spi_n == SPI1 && !handle1))
if (spi_n == SPI0)
h = &SpiHandle0;
else
h = &SpiHandle1;
if (*h == NULL)
return 2;
spi_tran.count = len;
spi_tran.txBuf = txBuf;
spi_tran.rxBuf = rxBuf;
spi_tran.count = len;
spi_tran.txBuf = txBuf;
spi_tran.arg = NULL;
spi_tran.rxBuf = NULL;
ret = SPI_transfer(*h, &spi_tran) ? 0 : 3;
if (spi_n == SPI0) {
transferOK = SPI_transfer(handle0, &spi_tran);
} else {
transferOK = SPI_transfer(handle1, &spi_tran);
}
if (!transferOK) {
// Error in SPI or transfer already in progress.
return 3;
}
return 0;
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;
}
*/
@@ -1,13 +1,40 @@
#ifndef __TIMERS_H
#define __TIMERS_H
#ifndef TIMERS_H
#define TIMERS_H
#ifdef __cplusplus
extern "C" {
#endif
void elite_gptimer_open(void);
//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
#endif // TIMERS_H
@@ -1,72 +1,90 @@
/*
* Copyright (c) 2015-2016, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Board.h>
#include <ti/drivers/timer/GPTimerCC26XX.h>
#include <xdc/runtime/Types.h>
#include <ti/sysbios/BIOS.h>
#include "board.h"
#include "driver/timers.h"
#include "service/app_ser.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 __timerCallback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask)
{
// interrupt callback code goes here. Minimize processing in interrupt.
elite_100us_task();
static void elite_gptimer_callback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {
elite_gptimer_task();
return;
}
void elite_gptimer_open(void)
void elite_gptimer_open()
{
GPTimerCC26XX_Handle hTimer;
GPTimerCC26XX_Params params;
GPTimerCC26XX_Params_init(&params);
params.width = GPT_CONFIG_16BIT;
params.mode = GPT_MODE_PERIODIC_UP;
params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
hTimer = GPTimerCC26XX_open(Board_GPTIMER0A, &params);
if (hTimer == NULL) {
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
GPTimerCC26XX_Value loadVal = CLOCK_FREQ; //0.1ms
GPTimerCC26XX_setLoadValue(hTimer, loadVal);
GPTimerCC26XX_registerInterrupt(hTimer, __timerCallback, GPT_INT_TIMEOUT);
GPTimerCC26XX_start(hTimer);
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;
}
@@ -21,7 +21,7 @@ extern "C" {
#include "driver/spi_ctrl.h"
#define DEF_LED_TANDEN_N 8
#define DEF_LED_TANDEN_N 12
#ifdef DEF_LED_TANDEN_N
#define LED_TANDEM_N DEF_LED_TANDEN_N
@@ -78,6 +78,12 @@ struct led_color_t {
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);
@@ -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
@@ -1,9 +1,15 @@
#ifndef VERSION_DATE
#define VERSION_DATE
#define VERSION_DATE_YEAR 24
#define VERSION_DATE_MONTH 1
#define VERSION_DATE_DAY 8
#define VERSION_DATE_HOUR 17
#define VERSION_DATE_MINUTE 41
#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
@@ -132,7 +132,7 @@ PIN_Handle radCtrlHandle;
extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
//extern Display_Handle dispHandle;
// extern Display_Handle dispHandle;
/*******************************************************************************
* @fn Main
@@ -247,47 +247,49 @@ int main()
*/
void AssertHandler(uint8 assertCause, uint8 assertSubcause)
{
/*
// Open the display if the app has not already done so
// if ( !dispHandle )
// {
// dispHandle = Display_open(Display_Type_LCD, NULL);
// }
if ( !dispHandle )
{
dispHandle = Display_open(Display_Type_LCD, NULL);
}
// Display_print0(dispHandle, 0, 0, ">>>STACK ASSERT");
Display_print0(dispHandle, 0, 0, ">>>STACK ASSERT");
// // check the assert cause
// switch (assertCause)
// {
// case HAL_ASSERT_CAUSE_OUT_OF_MEMORY:
// Display_print0(dispHandle, 0, 0, "***ERROR***");
// Display_print0(dispHandle, 2, 0, ">> OUT OF MEMORY!");
// break;
// check the assert cause
switch (assertCause)
{
case HAL_ASSERT_CAUSE_OUT_OF_MEMORY:
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> OUT OF MEMORY!");
break;
// case HAL_ASSERT_CAUSE_INTERNAL_ERROR:
// // check the subcause
// if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR)
// {
// Display_print0(dispHandle, 0, 0, "***ERROR***");
// Display_print0(dispHandle, 2, 0, ">> INTERNAL FW ERROR!");
// }
// else
// {
// Display_print0(dispHandle, 0, 0, "***ERROR***");
// Display_print0(dispHandle, 2, 0, ">> INTERNAL ERROR!");
// }
// break;
case HAL_ASSERT_CAUSE_INTERNAL_ERROR:
// check the subcause
if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR)
{
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> INTERNAL FW ERROR!");
}
else
{
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> INTERNAL ERROR!");
}
break;
// case HAL_ASSERT_CAUSE_ICALL_ABORT:
// Display_print0(dispHandle, 0, 0, "***ERROR***");
// Display_print0(dispHandle, 2, 0, ">> ICALL ABORT!");
// HAL_ASSERT_SPINLOCK;
// break;
case HAL_ASSERT_CAUSE_ICALL_ABORT:
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> ICALL ABORT!");
HAL_ASSERT_SPINLOCK;
break;
// default:
// Display_print0(dispHandle, 0, 0, "***ERROR***");
// Display_print0(dispHandle, 2, 0, ">> DEFAULT SPINLOCK!");
// HAL_ASSERT_SPINLOCK;
// }
default:
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> DEFAULT SPINLOCK!");
HAL_ASSERT_SPINLOCK;
}
*/
return;
}
@@ -1,149 +0,0 @@
#include <stdint.h>
#include <string.h>
#include "module/led_APA_102.h"
#define LED_FRAME_RSVD 0x07 // 0x11100000 || bright
#define LED_SERIES_D_START 0x00000000
#define LED_SERIES_D_END 0xFFFFFFFF
struct led_frame_t {
uint8_t bright: 5,
rsvd: 3;
struct led_color_t color;
};
struct led_series_data_t {
uint32_t f_start;
struct led_frame_t f_led[LED_TANDEM_N];
uint32_t f_end;
};
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_complete(struct led_series_data_t *sd)
{
for (int i = LED_NB_1; i < LED_NB_MAX; i++)
sd->f_led[i].rsvd = LED_FRAME_RSVD;
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)
{
static struct led_series_data_t led_series_data_g = {0};
struct led_series_data_t *sd = &led_series_data_g;
/*
* led_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 (led_nb < LED_NB_MAX) {
memcpy(&sd->f_led[led_nb], led_f, sizeof(struct led_frame_t));
} else if (led_nb == LED_NB_MAX) {
for (enum led_series_nb_e i = LED_NB_1; i < LED_NB_MAX; i++) {
memcpy(&sd->f_led[i], led_f, sizeof(struct led_frame_t));
}
}
__led_complete(sd);
spi_open(SPI0, SPI_RATE_1M, SPI_POL0, SPI_PHA1); //SPI 1M: LED
led_cs(1);
spi_write(SPI0, NULL, (uint8_t *)sd, sizeof(struct led_series_data_t));
led_cs(0);
spi_close(SPI0);
return 0;
}
int led_color_set(enum led_series_nb_e led_nb, enum led_bright_e bright, enum led_color_e color)
{
struct led_frame_t led_f = {0};
if (led_nb > LED_NB_MAX)
return -1;
if (bright > LED_BR_MAX)
return -2;
if (color >= LED_CLR_MAX)
return -3;
led_f.bright = bright;
led_f.color = led_color_list_g[color];
__led_color_set(led_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)
{
struct led_frame_t led_f = {0};
if (led_nb > LED_NB_MAX)
return -1;
if (bright > LED_BR_MAX)
return -2;
led_f.bright = bright;
memcpy(&led_f.color, &color, sizeof(struct led_color_t));
__led_color_set(led_nb, &led_f);
return 0;
}
int led_rainbow(enum led_bright_e bright)
{
if (bright > LED_BR_MAX)
return -1;
for(enum led_series_nb_e i=LED_NB_1; i<LED_NB_MAX; i++)
led_color_set(i, bright, (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);
*/
@@ -1,33 +0,0 @@
# $python .\simplelink\ble_sdk_2_02_02_25\src\examples\simple_peripheral\cc26xx\app\python\update_elite_version.py
import datetime
import os
print(datetime.datetime.now())
# print(datetime.datetime.now().year)
# print(datetime.datetime.now().month)
# print(datetime.datetime.now().day)
# print(datetime.datetime.now().hour)
# print(datetime.datetime.now().minute)
# print(datetime.datetime.now().strftime("%H:%M:%S"))
y = datetime.datetime.now().year % 100
m = datetime.datetime.now().month
d = datetime.datetime.now().day
hour = datetime.datetime.now().hour
minute = datetime.datetime.now().minute
path = os.getcwd()
path += '/simplelink/ble_sdk_2_02_02_25/src/examples/simple_peripheral/cc26xx/app/headstage/Elite_version.h'
print('save:', path)
with open(path, 'w') as f:
f.write('#ifndef VERSION_DATE' + '\n')
f.write('#define VERSION_DATE' + '\n\n')
f.write('#define VERSION_DATE_YEAR ' + str(y) + '\n')
f.write('#define VERSION_DATE_MONTH ' + str(m) + '\n')
f.write('#define VERSION_DATE_DAY ' + str(d) + '\n')
f.write('#define VERSION_DATE_HOUR ' + str(hour) + '\n')
f.write('#define VERSION_DATE_MINUTE ' + str(minute) + '\n')
f.write('#endif' + '\n')
@@ -1,274 +0,0 @@
#ifndef APP_SER_H
#define APP_SER_H
#ifdef __cplusplus
extern "C" {
#endif
struct elite_instru_t
{
uint8_t memoryboard_id;
uint8_t elite_mode;
// time relation
uint32_t vscan_rate;
uint32_t notify_rate;
/** TRIG output channel **/
bool tri_d0_as_5v_en;
bool tri_d1_as_5v_en;
/** trigger mode enable **/
bool trig0_en;
bool trig1_en;
uint8_t trig0_edge;
uint8_t trig1_edge;
// about a0~a3
uint16_t Trig_CurCon[4];
};
#include "Elite_version.h"
#include "driver/timers.h"
#include "driver/spi_ctrl.h"
#include "module/led_APA_102.h"
#include "service/mode_all_output_ctrl.h"
// LED
#define LED_BT_WAIT 0x01
#define LED_NO_EVENT 0x02
#define LED_WORKING 0x04
static uint8_t led_status = LED_NO_EVENT;
static void update_led(uint8_t led);
/**
* Trigger channel initialize
*/
#define PIN_PR0 0
#define PIN_D0_SW 1
#define PIN_A0 2
#define PIN_A2 3
#define PIN_A3 4
#define PIN_A1 5
#define PIN_D1_SW 6
#define PIN_PR1 7
#define PIN_D0_5V 8
#define PIN_D1_5V 9
#define PIN_OUT_CH_MAX 10
bool chan_en[PIN_OUT_CH_MAX]; // [pr0_en, d0_mos_en, a0_en, a2_en, a3_en,
// a1_en, d1_mos_en, pr1_en, d0_5v_en, d1_5v_en]
/** TRIG01 trigger edge type **/
#define TRIG_POSEDGE 0x00
#define TRIG_NEGEDGE 0x01
#define TRIG_BOTHEDGE 0x02
#define TRIG_DIS 0x03
// 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_STI 0xC0
#define VIS_INT 0x60
#define VIS_DEVICE_SHINY 0x10
#define VIS_SHINY_DIS 0x20
//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
// Elite TRIG01 ADC command
#define CMD_DOUT_5V_IMON_0 0xC5
#define CMD_DOUT_5V_IMON_1 0xD5
#define Aout_CH_0 0x00
#define Aout_CH_1 0x01
#define Aout_CH_2 0x02
#define Aout_CH_3 0x03
#define LATCH_BUFF_SIZE 8 // define latch
// CIS (control instruction)
#define CIS_VERSION 0x40
#define CIS_VOLT 0x10
#define CIS_TEMPERATURE 0x80
/* TRIG01 define */
#define TRIG_PR 0x00
#define TRIG_MOS_DOUT 0x01
#define TRIG_MOS_AOUT 0x02
#define TRIG_5V_OUT 0x03
#define TRIG_input 0x04
// #define TRIG_CHAN_COUNT 10 // channel count of TRIG01
// gptimer
struct gptimer_t
{
uint32_t gpt_now;
uint32_t gpt_last;
uint8_t gpt_delta;
};
/* member of mode */
struct wm_aout_ctx_t
{
int32_t _Vset;
int32_t _Curset0;
int32_t _Curset1;
int32_t _Curset2;
int32_t _Curset3;
};
/* member of mode */
#define CH_PR0 0
#define CH_D0 1
#define CH_A0 2
#define CH_A2 3
#define CH_A3 4
#define CH_A1 5
#define CH_D1 6
#define CH_PR1 7
/**
* Latch initialize
*/
struct _LH
{
bool LATCH0[LATCH_BUFF_SIZE];
bool LATCH1[LATCH_BUFF_SIZE];
bool LATCH2[LATCH_BUFF_SIZE];
};
// RIS (real instruction)
enum all_mode_e
{
MODE_ANALOG_CURRENT_CTRL = 0x0E, // 0x0E
MODE_ALL_OUTPUT_CTRL = 0x0F, // 0x0F
DEV_TEST = 0xFF, // 0xFF,
SET_SAMPLE_RATE = 0xE0, // 0xE0,
SET_EN_CHAN = 0x81, // 0x81,
SET_PARA = 0xE2, // 0xE2,
SET_TRIG_EN = 0x41 // 0x41,
};
enum dev_para_e
{
VERSION_DEV_TEST = 0x01,
BAT_DEV_TEST = 0x02,
TEMP_DEV_TEST = 0x03,
LED_DEV_TEST = 0x04,
AOUT_DEV_TEST = 0x05,
DOUT_DEV_TEST = 0x06,
PR_DEV_TEST = 0x07,
OUT_5VEN_DEV_TEST = 0x08,
SET_EN_CHAN_DEV_TEST = 0x0F,
VIS_DEV_TRIG_EN = 0x09,
Init_DEV_Trig_flag = 0x0A
};
enum set_para_e
{
AOUT_CURRENT = 0x02,
};
struct _LH LH = { 0 };
struct elite_instru_t instru = { 0 };
struct gptimer_t gpt = {0};
static int32_t notify_ch1 = 0;
static int32_t notify_ch2 = 0;
static int32_t notify_ch3 = 0;
static int32_t notify_ch4 = 0;
static int32_t notify_ch5 = 0;
static int32_t notify_ch6 = 0;
static uint16_t NotifyVoltBat = 2000; //0x07d0
static uint16_t NotifyTemperature = 200; //0x00c8
static uint16_t NotifyCycleNumber = 0;
static bool trig0_event_wait = false;
static bool trig1_event_wait = false;
static bool dual_trig_mode = false;
static bool single_trig_mode = false;
static void *workMode_p = NULL;
/* Trigger Flag */
static bool trig_PeriodicEvent = false;
static bool TRIG_TrigEnable = false;
static bool Trig_receive = false;
static bool trig0_event = false;
static bool trig1_event = false;
static bool FLT_event = false;
static bool PeriodicEvent = false;
static bool mode_init;
static bool finishMode = false;
PIN_Handle PinHandle;
static PIN_State PinStatus;
const PIN_Config Elite_pin[] = {
CC2650_LOAD0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
CC2650_LOAD1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
CC2650_LOAD2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
CC2650_SHUT_DOWN | PIN_INPUT_EN | PIN_PULLDOWN, // to sense switch
CC2650_TRIG_0 | PIN_INPUT_EN | PIN_PULLDOWN,
CC2650_FLT | PIN_INPUT_EN | PIN_PULLDOWN,
// CC2650_TRIG_1 | PIN_INPUT_EN | PIN_PULLDOWN,
PIN_TERMINATE
};
void elite_100us_task(void);
static void InitEliteInstruction(void);
static void set_channel_led(bool *chan_en);
static void elite_reset();
static void SendNotify();
static void FlushNotify();
static void key_manage(uint32_t delta_time);
static uint8_t pin_button_get(void);
static bool power_on(uint32_t delta_time);
static void GPT_timerIncrement();
static uint16_t Aout_decode(uint16_t input_code);
static void set_Aoutput(uint8_t GPIO_channel, uint16_t input_code);
static void TW1508reset();
static void curr_out();
static void aout_Curscan(void);
static uint16_t Usercode_Correction_to_Aout(uint8_t aout_chan, uint16_t usercode);
static void device_init();
static void send_device_info();
static void set_para(uint8_t elite_mode, uint16_t parameter, int32_t value);
static void chg_aout_para(uint16_t parameter, int32_t value);
static void trig_event_flush();
static void trig_callback(PIN_Handle handle, PIN_Id pinId);
static void trig_sense();
static void trig_en_check();
static void InitTrigChan();
static void PIN_trig_edge_set(uint8_t trig0_edge, uint8_t trig1_edge);
static void GPIO_SPI_transfer(uint32_t *GPIO_CLK_CH, uint16_t spi_GPIO_txbuf);
static void led_cs(uint8_t signal);
static void disable_trig_output();
static void PIN15_setOutputValue_refresh();
static void PIN15_setOutputValue(uint32_t latch_num, uint32_t pin_num, bool highlow);
static void update_latch_status(uint32_t latch_num, uint32_t elite_pin, bool highlow);
static void remove_elite_pin();
static void add_elite_pin();
static int wm_deinit(void);
static void *wm_get(void);
static void receive_instruction(uint8 *recv_instru);
static void elite_task(void);
#ifdef __cplusplus
}
#endif
#endif // APP_SER_H
@@ -1,15 +0,0 @@
#ifndef __MODE_ALL_OUTPUT_CTRL_H
#define __MODE_ALL_OUTPUT_CTRL_H
#ifdef __cplusplus
extern "C" {
#endif
void all_output_ctrl_mode_vsan(uint32_t delta_t);
int all_output_ctrl_mode_create(void);
void handle_all_output_mode_instru(uint8_t *recv_instru, struct elite_instru_t *instruction);
#ifdef __cplusplus
}
#endif
#endif
@@ -1,294 +0,0 @@
#include <stdint.h>
#include "service/mode_all_output_ctrl.h"
struct ch_all_out_ctrl_ctx_t
{
// user setting
uint8_t used: 1,
v_early: 1,
v_mid: 4,
v_late: 1,
v_rsvd: 1;
uint32_t t_early;
uint32_t t_mid[4];
uint32_t t_late;
uint16_t cycle;
// automatic setting
uint32_t t_part[4];
uint32_t t_period;
uint8_t init: 1,
t_early_period: 1,
t_mid_period: 1,
t_late_period: 1,
rsvd: 4;
uint32_t v_scan_rate;
};
struct mode_all_out_ctrl_ctx_t
{
struct ch_all_out_ctrl_ctx_t channel[8];
};
void __all_output_ctrl_mode_ch_vsan(struct ch_all_out_ctrl_ctx_t *channel, uint32_t delta_t, uint8_t ch)
{
uint32_t m;
if (!channel->used)
return;
if (channel->init) {
channel->v_scan_rate = 0;
channel->init = false;
}
channel->v_scan_rate += delta_t;
if (channel->t_early_period) {
if (ch==CH_D0 && instru.tri_d0_as_5v_en==1) {
if(channel->v_early) {
chan_en[CH_D0] = 0;
chan_en[8] = 0;
} else {
chan_en[CH_D0] = 0;
chan_en[8] = 1;
}
} else if (ch==CH_D1 && instru.tri_d1_as_5v_en==1) {
if(channel->v_early) {
chan_en[CH_D1] = 0;
chan_en[9] = 0;
} else {
chan_en[CH_D1] = 0;
chan_en[9] = 1;
}
} else {
chan_en[ch] = channel->v_early;
}
if (channel->v_scan_rate >= channel->t_early) {
channel->v_scan_rate -= channel->t_early; //To get right time
channel->t_early_period = false;
channel->t_mid_period = true;
channel->v_scan_rate = 0;
}
return;
}
if (channel->t_mid_period) {
if (channel->v_scan_rate >= channel->t_period) {
channel->v_scan_rate -= channel->t_period; //To get right time
channel->cycle--;
if (channel->cycle == 0) {
channel->t_mid_period = false;
channel->t_late_period = true;
channel->v_scan_rate = 0;
return;
}
}
m = channel->v_scan_rate ? (channel->v_scan_rate % channel->t_period) : 0;
for(int i=0; i<4; i++) {
if (m < channel->t_part[i]) {
if (ch == CH_D0 && instru.tri_d0_as_5v_en==1) {
if(channel->v_mid & (1 << i)) {
chan_en[CH_D0] = 0;
chan_en[8] = 0;
} else {
chan_en[CH_D0] = 0;
chan_en[8] = 1;
}
} else if (ch == CH_D1 && instru.tri_d1_as_5v_en==1) {
if(channel->v_mid & (1 << i)) {
chan_en[CH_D1] = 0;
chan_en[9] = 0;
} else {
chan_en[CH_D1] = 0;
chan_en[9] = 1;
}
} else {
chan_en[ch] = channel->v_mid & (1 << i);
}
return;
}
}
return;
}
if (channel->t_late_period) {
if (ch==CH_D0 && instru.tri_d0_as_5v_en==1) {
if(channel->v_late) {
chan_en[CH_D0] = 0;
chan_en[8] = 0;
} else {
chan_en[CH_D0] = 0;
chan_en[8] = 1;
}
} else if (ch==CH_D1 && instru.tri_d1_as_5v_en==1) {
if(channel->v_late) {
chan_en[CH_D1] = 0;
chan_en[9] = 0;
} else {
chan_en[CH_D1] = 0;
chan_en[9] = 1;
}
} else {
chan_en[ch] = channel->v_late;
}
if (channel->v_scan_rate >= channel->t_late) {
channel->v_scan_rate -= channel->t_late; //To get right time
channel->used = false;
if (ch==CH_D0 && instru.tri_d0_as_5v_en==1) { //ending
chan_en[CH_D0] = 0;
chan_en[8] = 1;
} else if (ch==CH_D1 && instru.tri_d1_as_5v_en==1) {
chan_en[CH_D1] = 0;
chan_en[9] = 1;
} else {
chan_en[ch] = 0;
}
}
return;
}
}
void all_output_ctrl_mode_vsan(uint32_t delta_t)
{
struct mode_all_out_ctrl_ctx_t *mode = (struct mode_all_out_ctrl_ctx_t *)wm_get();
struct ch_all_out_ctrl_ctx_t *ch;
for(int i=CH_PR0; i<=CH_PR1; i++) {
ch = &mode->channel[i];
__all_output_ctrl_mode_ch_vsan(ch, delta_t, i);
}
if (mode->channel[CH_PR0].used == false &&
mode->channel[CH_D0].used == false &&
mode->channel[CH_A0].used == false &&
mode->channel[CH_A2].used == false &&
mode->channel[CH_A3].used == false &&
mode->channel[CH_A1].used == false &&
mode->channel[CH_D1].used == false &&
mode->channel[CH_PR1].used == false)
PeriodicEvent = false;
return;
}
int all_output_ctrl_mode_create(void)
{
struct mode_all_out_ctrl_ctx_t *p;
void **wm = &workMode_p;
if (*wm)
return -1;
p = malloc(sizeof(struct mode_all_out_ctrl_ctx_t));
if (!p)
return -2;
struct ch_all_out_ctrl_ctx_t *ch;
for (int i=CH_D0; i<=CH_D1; i++) {
ch = &p->channel[i];
ch->used = false;
}
*wm = p;
return 0;
}
void __all_output_ctrl_mode_channel_init(uint8_t *ins)
{
struct mode_all_out_ctrl_ctx_t *mode = (struct mode_all_out_ctrl_ctx_t *)wm_get();
struct ch_all_out_ctrl_ctx_t *ch;
uint8_t channel = ins[3];
uint8_t para_sequence = ins[4];
ch = &mode->channel[channel];
if (para_sequence == 1) {
ch->used = (ins[5] & 1<<0);
ch->v_early = (ins[5] & 1<<1) >> 1;
ch->v_late = (ins[5] & 1<<2) >> 2;
ch->v_mid = ins[6]; // |rsvd|v3|v2|v1|v0|
ch->cycle = (uint16_t)ins[7] << 8 | (uint16_t)ins[8];
ch->t_early = (uint32_t)ins[9] << 24 | (uint32_t)ins[10] << 16 | (uint32_t)ins[11] << 8 | (uint32_t)ins[12]; // 1ms->0.1ms
ch->t_early *=10;
ch->t_late = (uint32_t)ins[13] << 24 | (uint32_t)ins[14] << 16 | (uint32_t)ins[15] << 8 | (uint32_t)ins[16];
ch->t_late *=10;
} else if (para_sequence == 2) {
ch->t_mid[0] = (uint32_t)ins[5] << 24 | (uint32_t)ins[6] << 16 | (uint32_t)ins[7] << 8 | (uint32_t)ins[8];
ch->t_mid[0] *= 10;
ch->t_mid[1] = (uint32_t)ins[9] << 24 | (uint32_t)ins[10] << 16 | (uint32_t)ins[11] << 8 | (uint32_t)ins[12];
ch->t_mid[1] *= 10;
} else if (para_sequence == 3) {
ch->t_mid[2] = (uint32_t)ins[5] << 24 | (uint32_t)ins[6] << 16 | (uint32_t)ins[7] << 8 | (uint32_t)ins[8];
ch->t_mid[2] *= 10;
ch->t_mid[3] = (uint32_t)ins[9] << 24 | (uint32_t)ins[10] << 16 | (uint32_t)ins[11] << 8 | (uint32_t)ins[12];
ch->t_mid[3] *= 10;
ch->t_period = 0;
for (int i=0; i<4; i++) {
ch->t_period += ch->t_mid[i];
ch->t_part[i] = ch->t_period;
}
if (ch->used == true)
ch->init = true;
else
ch->init = false;
ch->t_early_period = true;
ch->t_mid_period = false;
ch->t_late_period = false;
} else if (para_sequence == 4) {
if (channel==CH_D0) {
instru.tri_d0_as_5v_en = ins[5];
} else if (channel==CH_D1) {
instru.tri_d1_as_5v_en = ins[5];
} else if (channel==CH_A0) {
instru.Trig_CurCon[0] = (uint16_t)ins[5] << 8 | (uint16_t)ins[6]; //5000=20mA
} else if (channel==CH_A1) {
instru.Trig_CurCon[1] = (uint16_t)ins[5] << 8 | (uint16_t)ins[6];
} else if (channel==CH_A2) {
instru.Trig_CurCon[2] = (uint16_t)ins[5] << 8 | (uint16_t)ins[6];
} else if (channel==CH_A3) {
instru.Trig_CurCon[3] = (uint16_t)ins[5] << 8 | (uint16_t)ins[6];
}
}
}
void handle_all_output_mode_instru(uint8_t *recv_instru, struct elite_instru_t *instruction)
{
uint8_t *ins = recv_instru;
uint8_t ch = ins[3];
switch (ch) {
case 0xFF:
instru.elite_mode = MODE_ALL_OUTPUT_CTRL;
all_output_ctrl_mode_create();
break;
case CH_PR0:
case CH_PR1:
case CH_D0:
case CH_D1:
case CH_A0:
case CH_A1:
case CH_A2:
case CH_A3:
__all_output_ctrl_mode_channel_init(ins);
break;
}
instruction->notify_rate = 5000;
}
@@ -297,7 +297,7 @@ 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_performPeriodicTask(void);
static void SimpleBLEPeripheral_performPeriodicTask(void);
// static void SimpleBLEPeripheral_clockHandler(UArg arg);
static void SimpleBLEPeripheral_sendAttRsp(void);
@@ -571,10 +571,120 @@ static void SimpleBLEPeripheral_init(void)
*/
}
/*elite code*/
#include "service/app_ser.h"
// 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
*
@@ -586,9 +696,11 @@ static void SimpleBLEPeripheral_init(void)
*/
static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
{
uint8_t key= 0;
bool elite_on = false;
batteryADC_flag = false;
uint32_t check_key_time = 0;
static bool open_6994 = false;
uint16_t counter6994 = 0;
// Initialize application
SimpleBLEPeripheral_init();
@@ -599,7 +711,7 @@ static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
if (events & SBP_PERIODIC_EVT) {
events &= ~SBP_PERIODIC_EVT;
GPT_timerIncrement();
elite_on = power_on(gpt.gpt_delta);
elite_on = power_on(GPT.cnt_gpt_delta);
}
if (elite_on)
break;
@@ -656,44 +768,43 @@ static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1)
}
}
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;
GPT_timerIncrement();
check_key_time = check_key_time + gpt.gpt_delta;
/* routinely check the button status*/
if (check_key_time >= 200) {
key_manage(200);
check_key_time = 0;
}
if (!open_6994) {
static uint16_t cnt = 0;
if (cnt < 50000) //5000ms
cnt++;
else {
PIN15_setOutputValue(E_PIN_OFF, 0); // on=0, off=1, turn on 6994
open_6994 = true;
}
}
if (!PeriodicEvent) { // if there is no periodic event
if (TRIG_TrigEnable)
{
trig_sense();
if (trig_PeriodicEvent)
{
trig_PeriodicEvent = false;
PeriodicEvent = true;
mode_init = true;
}
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
elite_task();
SimpleBLEPeripheral_performPeriodicTask();
}
}
@@ -887,23 +998,6 @@ static void SimpleBLEPeripheral_freeAttRsp(uint8_t status)
}
}
#define BLE_INS_BUFF_CHAR SIMPLEPROFILE_CHAR3
#define BLE_INS_BUFF_SIZE SIMPLEPROFILE_CHAR3_LEN
static void elite_instru_handle(uint8_t characteristic)
{
uint8_t ins_buf[BLE_INS_BUFF_SIZE] = {0};
switch (characteristic)
{
case BLE_INS_BUFF_CHAR:
SimpleProfile_GetParameter(BLE_INS_BUFF_CHAR, ins_buf);
receive_instruction(ins_buf);
break;
default:
break;
}
}
/*********************************************************************
* @fn SimpleBLEPeripheral_processAppMsg
*
@@ -921,7 +1015,7 @@ static void SimpleBLEPeripheral_processAppMsg(sbpEvt_t *pMsg) {
case SBP_CHAR_CHANGE_EVT:
// SimpleBLEPeripheral_processCharValueChangeEvt(pMsg->hdr.state);
elite_instru_handle(pMsg->hdr.state);
ZM_instruction_update_handle(pMsg->hdr.state);
break;
default:
@@ -1069,12 +1163,12 @@ static void SimpleBLEPeripheral_processStateChangeEvt(gaprole_States_t newState)
case GAPROLE_WAITING:
SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
update_led(LED_BT_WAIT);
ModeLED(BT_WAIT);
break;
case GAPROLE_WAITING_AFTER_TIMEOUT:
SimpleBLEPeripheral_freeAttRsp(bleNotConnected);
update_led(LED_BT_WAIT);
ModeLED(BT_WAIT);
#ifdef PLUS_BROADCASTER
// Reset flag for next connection.
@@ -1161,10 +1255,11 @@ static void SimpleBLEPeripheral_processCharValueChangeEvt(uint8_t paramID)
*
* @return None.
*/
/*
static void SimpleBLEPeripheral_performPeriodicTask(void)
{
elite_task();
/*
#ifndef FEATURE_OAD_ONCHIP
uint8_t valueToCopy;
@@ -1179,9 +1274,9 @@ static void SimpleBLEPeripheral_performPeriodicTask(void)
&valueToCopy);
}
#endif //!FEATURE_OAD_ONCHIP
}
*/
}
#ifdef FEATURE_OAD
/*********************************************************************
@@ -1267,14 +1362,15 @@ static void SimpleBLEPeripheral_enqueueMsg(uint8_t event, uint8_t state)
Util_enqueueMsg(appMsgQueue, semaphore, (uint8*)pMsg);
}
}
/*******************************************************************************************/
//clock
/*********************************************************************
*********************************************************************/
#include "driver/timers_c.h"
#include "hardware/led_APA_102_c.h"
#include "driver/spi_ctrl_c.h"
#include "module/led_APA_102_c.h"
#include "service/app_ser_c.h"
#include "service/mode_all_output_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"