118 Commits

Author SHA1 Message Date
Neucrack
4d31122a39 Merge pull request #142 from dimitre/invalid
invalid
2024-06-15 16:16:19 +08:00
Dimitre
2bae74b0c0 invalid 2024-06-14 14:29:16 -03:00
Neucrack
1e63c0d678 Merge pull request #140 from dimitre/flip
[suggestion] : having a flip function with horizontal and vertical
2024-06-13 11:00:20 +08:00
Dimitre
377cb291e7 flip 2024-06-12 16:02:30 -03:00
Neucrack
0c9ca167b7 Merge pull request #132 from alirezainallo/bugFix/UARTClass
BugFix/serial1-3
2024-06-07 01:17:34 +08:00
Neucrack
6d2de50937 Merge pull request #139 from dimitre/patch-1
422
2024-06-07 01:16:28 +08:00
Dimitre
8aaca6ea3a 422 2024-06-06 11:24:08 -03:00
Neucrack
7fd025bcd4 Merge pull request #137 from dimitre/polarity
Poliraty -> Polarity
2024-06-05 10:43:54 +08:00
Neucrack
032eb52ac9 Merge pull request #135 from dimitre/rotaion
rotaion -> rotation keyword
2024-06-05 10:43:29 +08:00
Dimitre
f18df03229 polarity 2024-06-04 14:49:31 -03:00
Dimitre
d4a7042c82 rotaion -> rotation keyword 2024-06-03 23:43:52 -03:00
Neucrack
fb781728b9 Merge pull request #134 from dimitre/typo
sensro -> sensor
2024-06-03 15:34:06 +08:00
Dimitre
ca9c0a900a sensro -> sensor 2024-06-03 00:29:41 -03:00
alirezainallo
c2f8db6a9f Fix Rx/Tx define number 2023-08-02 16:39:04 +03:30
alirezainallo
22ab4ecfe7 bypass gpio map for serial1-3 2023-08-02 16:38:38 +03:30
Neucrack
aa6543538c fix readme index url error 2021-11-29 18:08:27 +08:00
Neucrack
b9c5f43fea Merge pull request #96 from mikljohansson/fix_memleak_warning
Fixed memory leak warning
2021-05-31 10:09:32 +08:00
Neucrack
e9532200e9 Merge pull request #99 from UT2UH/master
Missing devices added
2021-05-31 10:06:45 +08:00
Neucrack
50cb129b02 Merge pull request #110 from mikljohansson/add-binocular-camera-support
Add binocular camera support
2021-05-31 10:02:52 +08:00
Neucrack
f54b3f19ab Merge pull request #111 from mikljohansson/fixed-uart-write-return-value
Fixed some bugs in the Serial implementations
2021-05-31 10:00:08 +08:00
Neucrack
03b7995e0c Merge pull request #116 from per1234/optimal-library-name
Use optimal bundled library names
2021-05-31 09:55:22 +08:00
per1234
86acd72c3d Use optimal bundled library names
When multiple libraries contain files matching an #include directive in the program, the Arduino build system must pick
one to use for compilation. Multiple factors are used in order to make an intelligent determination of which library is
best.

In order to enhance this determination, the closeness of match between the library.properties name value and the
filename in the #include directive is being added as one of those factors. This new factor is referred to as
"Library Name Priority".

Unfortunately, this change can result in platform bundled libraries which had previously been correctly correctly chosen
no longer being given priority over their equivalent standalone libraries, which may be incompatible or not optimized
for the platform's boards.

This priority inversion only occurs when all the following conditions are true:

- There is a standalone library installed which provides a header filename collision.
- The platform bundled library is architecture optimized (e.g., architectures=esp32).
- The standalone library is architecture compatible (architectures=*).
- The standalone library has equal "Folder Name Priority".
- The standalone library has better "Library Name Priority" (e.g., name=SD vs name=SD(ESP32) for a library with primary
  header file SD.h.

The fix is to simply give the platform bundled library a perfect "Library Name Priority".

Some platform bundled libraries were given a modified name as a workaround to a bug in the Arduino IDE's Library Manager
which caused Library Manager to always show the library as updatable under specific circumstances. That bug was fixed in
Arduino IDE 1.8.6, ~3 years ago.
2021-05-30 13:11:35 -07:00
Mikael Johansson
f95f8e70c9 Disable debug output by default from GC0328 camera driver. Fixed GC0328 camera driver mirror/flip functionality 2021-03-13 11:13:26 +01:00
Mikael Johansson
4f4d43094b Fixed return value handling of UARTClass::write and Print::write 2021-03-13 11:00:50 +01:00
Mikael Johansson
a346d8cab1 Added support for binocular camera 2021-02-21 15:59:13 +01:00
Mikael Johansson
ca5e26d4e9 Fixed typo in Sipeed_GC0328::setRotation method name 2021-02-21 15:59:13 +01:00
vamoosebbf
abba977741 Merge pull request #103 from vamoosebbf/master
[libraries] add gc0328 support
2021-01-10 10:26:24 +08:00
vamoosebbf
ae99df0800 [libraries] add gc0328 support 2021-01-07 13:47:59 +08:00
UT2UH
ea172fc074 Merge branch 'NewBoards' 2020-11-11 13:31:04 +02:00
UT2UH
2fe52b570e min max macros and Wire fixes 2020-11-11 13:29:58 +02:00
UT2UH
403e61d90a Update README.md 2020-11-02 21:12:39 +02:00
UT2UH
1376ced183 New boards added 2020-11-02 21:05:00 +02:00
Mikael Johansson
505f888835 Fixed memory leak warning 2020-10-22 21:57:07 +02:00
UT2UH
a256706b7f Merge pull request #1 from sipeed/master
Merge to upsatream update
2020-10-18 11:46:26 +03:00
Neucrack
dead5bc98d Merge pull request #95 from mikljohansson/fix_twowire_compat
Fixed TwoWire implementation to be more Arduino compatible
2020-10-14 11:41:44 +08:00
Mikael Johansson
78f7bb18c5 Flush buffers on every I2C transaction, in case the user hasn't consumed all bytes
F
2020-10-11 15:24:14 +02:00
Mikael Johansson
763c23d13c Refacted TwoWire::begin() to reduce duplicated code with TwoWire::setClock() 2020-10-11 14:59:18 +02:00
Mikael Johansson
7c7ec509ac Return number of received bytes from TwoWire::requestFrom(), like Arduino documentation specifies
Nl
2020-10-11 12:12:37 +02:00
Mikael Johansson
9b077cb470 Set default I2C frequency to 400kHz, same as Arduino boards use 2020-10-10 16:48:49 +02:00
Mikael Johansson
359f7a89f2 Fixed return value bug in TwoWire::write 2020-10-10 16:48:14 +02:00
Bits
bb42e208a7 Merge pull request #66 from epozzobon/master
Fixed receiving the NUL '\x00' character on Serial
2019-11-20 21:35:18 +08:00
Enrico Pozzobon
0cfbfacc40 Fixed receiving the NUL '\x00' character on Serial 2019-11-17 03:07:46 +01:00
Bits
d4a0f06d05 Merge pull request #61 from ioxgd/master
Add IOXGD4 board
2019-10-30 09:20:57 +08:00
Max
2c08ea95bb Add IOXGD4 board 2019-10-25 11:41:07 +07:00
Bits
d42af6a0a2 Merge pull request #60 from sabas1080/master
Fix Typo Rotation in Sipeed_OV2640
2019-10-19 09:11:30 +08:00
Sabas
4fb76511f6 fix typo rotation 2019-10-18 13:52:31 -05:00
Sabas
64fe55b858 fix typo rotation 2019-10-18 13:51:50 -05:00
bigbits
85c0d7d24e release new version 2019-10-12 09:27:11 +08:00
Bits
31fa216fd0 Merge pull request #58 from vanvuongngo/patch-1
prettier drawline.ino example
2019-10-11 12:10:23 +08:00
Van Vuong Ngo
4dd21db55e prettier 2019-10-11 06:07:55 +02:00
Bits
6f7873a49c Merge pull request #57 from vanvuongngo/patch-1
outputs values as formatted strings
2019-10-10 11:40:56 +08:00
Van Vuong Ngo
4f5585a0dd outputs values as formatted strings 2019-10-10 05:31:11 +02:00
Bits
485cf192ba Merge pull request #55 from richardclli/fix-compile-error
Added quotes in library path to fix sketch compile error
2019-09-30 18:52:14 +08:00
Richard Li
2570fd3b5a Added quotes in library path to fix sketch compile error when Windows username has space. 2019-09-30 11:10:20 +08:00
Bits
3ffdbe9768 Merge pull request #41 from majenkotech/master
Fix module path for non-windows OS
2019-09-13 12:04:09 +08:00
Bits
d19982e248 Merge pull request #43 from sajattack/patch-1
Fix Issue #33
2019-09-13 12:03:47 +08:00
Bits
a8a5e39e9e Merge pull request #39 from iZhangHui/master
fix issue #38
2019-09-13 12:03:25 +08:00
Bits
4fad772219 Merge pull request #45 from lamloei/patch-2
Create pins_arduino.h
2019-08-07 11:44:56 +08:00
Bits
546dc5e894 Merge pull request #44 from lamloei/patch-1
Update boards.txt
2019-08-07 11:44:43 +08:00
lamloei
5d85ca78a3 Create pins_arduino.h
ADD LamLoei AIoT DaaN
2019-08-04 00:34:05 +07:00
lamloei
a241ae41a7 Update boards.txt
ADD LamLoei AIoT DaaN Board
2019-08-04 00:31:46 +07:00
Paul
1eb49c57da Fix Issue #33 2019-08-02 17:13:33 -04:00
Majenko Technologies
db7a98b893 Fix module path for non-windows OS
`/` is the universal path separator. `\` is specific to Windows. Other OSes don't understand `\`
2019-07-31 23:22:13 +01:00
Henry Zhang
9b2f110f0b fix bug of SD init failed 2019-07-31 11:19:25 +08:00
Henry Zhang
99ab059752 Keep Maixduino board backward compatibility 2019-07-31 11:18:28 +08:00
Bits
7d66935095 Maixduino board can use tx led to run blink #36 2019-07-30 13:12:44 +08:00
Bigbits
18164baf25 Modify version to 0.3.10 2019-07-23 09:06:01 +08:00
Bigbits
656abee8aa M platform.txt 2019-07-17 15:07:48 +08:00
Bigbits
240bb27d0b Fix sdcard bug #26 2019-07-17 10:27:36 +08:00
Bigbits
b47d512182 Update Lvgl to v6.0 2019-07-15 18:43:08 +08:00
Bigbits
ba0fd67e4e add lv_maixduino 2019-07-15 17:20:38 +08:00
Bigbits
98756e8832 rm lv_arduino 2019-07-15 17:19:06 +08:00
Bigbits
e75526f51f Add mit-mic board 2019-07-15 16:14:59 +08:00
Bigbits
363b2bade7 add microsecond into Ticker lib #23 2019-07-11 15:47:50 +08:00
Bigbits
b6da4a0466 modify sdk. 2019-07-11 15:29:11 +08:00
Bits
25d62719d4 Modify maixduino board burn_tool name. 2019-07-05 21:52:49 +08:00
Bigbits
8cb90d021c modify version to v0.3.9 2019-06-13 12:38:10 +08:00
Bigbits
850d1ce215 add maixduino onboard key0. 2019-06-13 10:57:58 +08:00
Bigbits
2a83d6d993 add maixduino board. 2019-06-12 23:10:57 +08:00
Bigbits
314c2782cf fix windows special user name bug. 2019-06-11 16:52:25 +08:00
Bigbits
b44939c693 fix bug #15 2019-06-07 23:17:08 +08:00
Bigbits
f3a7b1e487 fix folder name 2019-05-15 20:02:26 +08:00
Bigbits
503b51beb5 remove debug info 2019-05-15 14:17:06 +08:00
Bigbits
4a56110cc8 add speech recognition english examples. 2019-05-15 14:16:15 +08:00
Bigbits
4c78275e85 Merge branch 'master' of github.com:sipeed/Maixduino 2019-05-15 13:00:55 +08:00
Bigbits
8552b652c3 add speech recognition lib 2019-05-15 13:00:35 +08:00
Neucrack
ace1967aec update sdk 2019-05-14 17:32:07 +08:00
Bigbits
6d6add4a05 fix a bug 2019-05-08 20:21:13 +08:00
Bigbits
483981d747 add camera setInvert 2019-05-07 22:01:52 +08:00
Bigbits
6bb5916212 add enum for analog output pin. 2019-05-04 19:49:09 +08:00
Bigbits
0f0dd7f92a Add boards. 2019-05-04 19:33:01 +08:00
Bigbits
ff02b8ea83 add serial.printf() function. 2019-05-04 17:43:19 +08:00
Bits
e3609f4be6 Merge pull request #5 from wuhanstudio/upstream-vscode-bug
[fix] vscode undefined error
2019-04-28 14:52:53 +08:00
Wu Han
616ae387af [fix] vscode menu error 2019-04-28 14:14:18 +07:00
Wu Han
20dfb8c1c9 [fix] vscode undefined error 2019-04-28 13:53:59 +07:00
Bigbits
c74b948b53 add open-ec super speed support. 2019-04-26 20:18:50 +08:00
Bigbits
93fbb08ad6 add c flags 2019-04-26 15:45:44 +08:00
Bigbits
3debc75348 Modify package name. 2019-04-25 07:51:00 +08:00
Bigbits
c07ca972f3 Fix include path for PlatformIO. 2019-04-25 06:51:20 +08:00
Bigbits
8a3ae10f1c Use the usual variants folders. 2019-04-24 20:31:21 +08:00
Bits
b53e72fe8e Add OSX upload cmd #3 2019-04-20 20:07:31 +08:00
Bigbits
d6e171190c Add package.json 2019-04-19 17:42:54 +08:00
Bigbits
827797bdb2 Specifying a PID will cause errors on other Arduino boards. 2019-04-16 12:08:05 +08:00
Bigbits
6116e6b348 Fix interrupts bug. 2019-04-13 17:54:13 +08:00
Bigbits
fd93da2c00 Fix io bug. 2019-04-12 20:36:57 +08:00
Bigbits
0c42ce6f28 fix a bug 2019-04-12 19:31:59 +08:00
Bigbits
63d00b0ea5 Modify the Serial1.begin baudrate. #2 2019-04-12 16:58:02 +08:00
Bigbits
23062f3df7 Specify the include file 2019-04-07 17:43:20 +08:00
Bigbits
dfed93ad27 Add lvgl support 2019-04-07 17:37:51 +08:00
Bigbits
7dc6ee2366 Some fix 2019-04-07 17:18:07 +08:00
Bigbits
170fb03039 Add Ticker lib (Hardware Timer) 2019-04-07 14:48:39 +08:00
Bigbits
e13913f802 Add TouchScreen Library 2019-04-05 22:49:54 +08:00
Neucrack
57abaf8159 add bin export 2019-04-04 11:49:32 +08:00
Neucrack
a9749d24ce remove kflash color syntax for linux... 2019-04-03 16:59:14 +08:00
Neucrack
c5023445b4 add install doc link 2019-04-03 15:20:50 +08:00
Neucrack
afc08d3dd1 replace k-flash with kflash.py on windows 2019-04-03 14:51:07 +08:00
Neucrack
38671731ce update readme 2019-04-02 18:55:12 +08:00
Neucrack
806c7dc762 add license 2019-04-02 18:53:06 +08:00
107 changed files with 10154 additions and 267 deletions

6
.gitmodules vendored
View File

@@ -7,3 +7,9 @@
[submodule "libraries/WiFiEsp"]
path = libraries/WiFiEsp
url = https://github.com/btx000/WiFiEsp
[submodule "libraries/lv_arduino"]
path = libraries/lv_arduino
url = https://github.com/btx000/lv_arduino.git
[submodule "libraries/lv_maixduino"]
path = libraries/lv_maixduino
url = https://github.com/littlevgl/lv_maixduino.git

28
LICENSE.md Normal file
View File

@@ -0,0 +1,28 @@
License
======
All the source code in this repository is released under LGPL or Apache v2.0 license even more.
All the sources created/modified by the repository owner are released under Apache v2.0 license and contains the following copyright notice:
Copyright 2019 Sipeed Co.,Ltd.
Most of the source files contains license and copyright notice, please check the individual files for more information.
Also check the license information in individual components directories.
```
Copyright 2019 Sipeed Co.,Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

120
README.md
View File

@@ -1,43 +1,77 @@
# Arduino Core for Kendryte K210
## Windows
### 1.首选项添加下列地址 然后打开开发版管理器下载开发包
>https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_k210/package_k210_index.json
### 2.安装好之后添加工具链目录到PATH环境变量
>C:\Users\\**(username)**\AppData\Local\Arduino15\packages\Kenduino\tools\riscv64-unknown-elf-gcc\8.2.0\bin
### 3.安装[.Net core runtime](https://download.visualstudio.microsoft.com/download/pr/3f05ee2d-5372-43d6-9562-be86632a53d4/1361281426efa7ff206289adb0411f55/dotnet-runtime-3.0.0-preview3-27503-5-win-x64.exe)
### 4.开发板选择Sipeed M1 Board 编程器选 k-flash
### 5.连接开发板选对应的串口号
### 6.编写程序 编译 上传 完成
----
## Ubuntu
### 1.首选项添加下列地址 然后打开开发版管理器下载开发包
>https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_k210/package_k210_index.json
### 2.需要解决usb串口访问权限
>sudo usermode -a -G dialout **(username)**
### 3.安装pyserial
>pip3 install pyserial
### 4.开发板选择Sipeed M1 Board 编程器选 k-flash
### 5.连接开发板选对应的串口号
### 6.编写程序 编译 上传 完成
----
## Windows
### 1.Add the following address to the **Preferences** and open the **Boards Manager** to download the development kit.
>https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_k210/package_k210_index.json
### 2.Add the toolchain directory to the PATH environment variable after installation.
>C:\Users\\**(username)**\AppData\Local\Arduino15\packages\Kenduino\tools\riscv64-unknown-elf-gcc\8.2.0\bin
### 3.Install [.Net core runtime](https://download.visualstudio.microsoft.com/download/pr/3f05ee2d-5372-43d6-9562-be86632a53d4/1361281426efa7ff206289adb0411f55/dotnet-runtime-3.0.0-preview3-27503-5-win-x64.exe)
### 4.Board selects Sipeed M1 Board & Programmer to choose k-flash.
### 5.Connect the development board and then choose the serial port.
### 6.Now you can write the Arduino code and upload it to the k210 board.
----
## Ubuntu
### 1.Add the following address to the **Preferences** and open the **Boards Manager** to download the development kit.
>https://bigbits.oss-cn-qingdao.aliyuncs.com/Arduino_for_k210/package_k210_index.json
### 2.Enter the following command in the terminal to solve the problem of usb serial port access rights.
>sudo usermode -a -G dialout **(username)**
### 3.Install pyserial
>pip3 install pyserial
### 4.Board selects Sipeed M1 Board & Programmer to choose k-flash.
### 5.Connect the development board and then choose the serial port.
### 6.Now you can write the Arduino code and upload it to the k210 board.
----
Maixduino
========
# Arduino Core for K210 based devices
## Supported devices
### Sipeed Maix series
- [Amigo](https://dl.sipeed.com/MAIX/HDK/Sipeed-Amigo)
- [Cube](https://dl.sipeed.com/MAIX/HDK/Sipeed-Maix-Cube)
- [Go](https://dl.sipeed.com/MAIX/HDK/Sipeed-Maix-GO)
- [Maixduino](https://dl.sipeed.com/MAIX/HDK/Sipeed-Maixduino)
- [Dock](https://dl.sipeed.com/MAIX/HDK/Sipeed-Maix-Dock)
- [BiT](https://dl.sipeed.com/MAIX/HDK/Sipeed-Maix-Bit)
- [Nano](https://dl.sipeed.com/MAIX/HDK/Sipeed-Maix-Nano)
### M5Stack
* [M5StickV](https://m5stack.com/products/stickv)
* [M5UnitV](https://m5stack.com/collections/m5-unit/products/unitv-ai-camera)
### Various custom boards
* [LAMLOEI AOIT DAAN](https://github.com/lamloei/AIoTDaaN/tree/master/hardware/20190505-R2/AIoTDaaN_R2/pdf)
* [IOXGD4](https://github.com/ioxgd/IOXGD-hardware/tree/master/IOXGD4/pdf)
## Docs
Docs: [wiki.sipeed.com](https://wiki.sipeed.com/soft/maixduino/zh/index.html)
## Install
Refer install doc: [Install](https://maixduino.sipeed.com/en/get_started/install.html)
## Installing
### From Board Manager
1. [Download and install the Arduino IDE](https://www.arduino.cc/en/Main/Software) (at least version v1.9.8)
2. Start the Arduino IDE
3. Go into Preferences
4. Add ```https://dl.sipeed.com/MAIX/Maixduino/package_Maixduino_k210_index.json``` as an "Additional Board Manager URL"
5. Open the Boards Manager from the Tools -> Board menu and install "Maixduino(K210)"
6. Select your K210 board from the Tools -> Board menu
### From git
1. Follow steps from Board Manager section above
2. ```cd <SKETCHBOOK>```, where ```<SKETCHBOOK>``` is your Arduino Sketch folder:
* OS X: ```~/Documents/Arduino```
* Linux: ```~/Arduino```
* Windows: ```~/Documents/Arduino```
3. Create a folder named ```hardware```, if it does not exist, and change directories to it
4. Clone this repo: ```git clone https://github.com/Sipeed/Maixduino Maixduino/k210```
5. Restart the Arduino IDE
### Firmware flashing
The firmware of the K210 devices is updated with a Python-based [kflash](https://github.com/sipeed/kflash.py) cross-platform tool.
Follow ```kflash``` github page on installation instruction.
###### Change board settings in Tools section on the top of Arduino IDE
1. Board: The same as your dev board
2. Burn Toolfirmware: leave default, for Maix Go Kit - ```open-ec```
3. Burn Baudrate: Decrease it if download fails
4. Port: Serial port, e.g. ```/dev/ttyUSB0```
5. Programmer: ```k-flash```
## Credits
This core is based on and compatible with the [Sipeed Maixduino Core](https://github.com/sipeed/Maixduino)

View File

@@ -1,47 +1,278 @@
menu.clksrc = CPU Clock Frequency
menu.burn_tool_firmware = Burn Tool Firmware
menu.burn_baudrate = Burn Baud Rate
menu.toolsloc = Tool Install Location
menu.clksrc=CPU Clock Frequency
menu.burn_tool_firmware=Burn Tool Firmware
menu.burn_baudrate=Burn Baud Rate
menu.toolsloc=Tool Install Location
##################################################
############# Sipeed Maix Amigo ###############
amigo.name=Sipeed Maix Amigo
## Toolchain
amigo.menu.toolsloc.default=Default
amigo.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
amigo.menu.clksrc.400=400MHz CPU Clock Frequency
amigo.menu.clksrc.500=500MHz CPU Clock Frequency
amigo.menu.clksrc.600=600MHz CPU Clock Frequency
amigo.menu.clksrc.400.build.f_cpu=400000000L
amigo.menu.clksrc.500.build.f_cpu=500000000L
amigo.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
amigo.menu.burn_baudrate.2000000=2 Mbps
amigo.menu.burn_baudrate.4500000=4.5 Mbps (Must open-ec!)
amigo.menu.burn_baudrate.1500000=1.5 Mbps
amigo.menu.burn_baudrate.1000000=1 Mbps
amigo.menu.burn_baudrate.2000000.build.burn_baudrate=2000000
amigo.menu.burn_baudrate.4500000.build.burn_baudrate=4500000
amigo.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
amigo.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
amigo.menu.burn_tool_firmware.amigo=open-ec
amigo.menu.burn_tool_firmware.amigo.build.burn_tool_firmware=goE
## Core settings
amigo.build.variant=sipeed_maix_amigo
amigo.build.core=arduino
## This sets a define for use in the compiled code.
amigo.build.board=MAIX_AMIGO
## This selects the tool from "programmers.txt"
amigo.program.tool=kflash
amigo.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
amigo.upload.maximum_size=8388608
amigo.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# Sipeed Maix Cube ###############
cube.name=Sipeed Maix Cube
## Toolchain
cube.menu.toolsloc.default=Default
cube.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
cube.menu.clksrc.400=400MHz CPU Clock Frequency
cube.menu.clksrc.500=500MHz CPU Clock Frequency
cube.menu.clksrc.600=600MHz CPU Clock Frequency
cube.menu.clksrc.400.build.f_cpu=400000000L
cube.menu.clksrc.500.build.f_cpu=500000000L
cube.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
cube.menu.burn_baudrate.1500000=1.5 Mbps
cube.menu.burn_baudrate.1000000=1 Mbps
cube.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
cube.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
cube.menu.burn_tool_firmware.cube=open-ec
cube.menu.burn_tool_firmware.cube.build.burn_tool_firmware=goE
## Point to the file for ./variants/<variant>/pins_arduino.h
cube.build.variant=sipeed_maix_cube
## "The 'core' file directory for this board, in ./cores
cube.build.core=arduino
## This sets a define for use in the compiled code.
cube.build.board=MAIX_CUBE
cube.build.sdata.size=512
## This selects the tool from "programmers.txt"
cube.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
cube.upload.maximum_size=8388608
cube.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
####################################################
############### Sipeed Maix Go Board ###############
go.name=Sipeed Maix Go
## Toolchain
go.menu.toolsloc.default=Default
go.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
go.menu.clksrc.400=400MHz CPU Clock Frequency
go.menu.clksrc.500=500MHz CPU Clock Frequency
go.menu.clksrc.600=600MHz CPU Clock Frequency
go.menu.clksrc.400.build.f_cpu=400000000L
go.menu.clksrc.500.build.f_cpu=500000000L
go.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
go.menu.burn_baudrate.2000000=2 Mbps
go.menu.burn_baudrate.4500000=4.5 Mbps (Must open-ec!)
go.menu.burn_baudrate.1500000=1.5 Mbps
go.menu.burn_baudrate.1000000=1 Mbps
go.menu.burn_baudrate.2000000.build.burn_baudrate=2000000
go.menu.burn_baudrate.4500000.build.burn_baudrate=4500000
go.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
go.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
go.menu.burn_tool_firmware.goE=open-ec
go.menu.burn_tool_firmware.goD=CMSIS-DAP
go.menu.burn_tool_firmware.goE.build.burn_tool_firmware=goE
go.menu.burn_tool_firmware.goD.build.burn_tool_firmware=goD
## Core settings
## Point to the file for ./variants/<variant>/pins_arduino.h
go.build.variant=sipeed_maix_go
## "The 'core' file directory for this board, in ./cores
go.build.core=arduino
## This sets a define for use in the compiled code.
go.build.board=MAIX_GO
## This selects the tool from "programmers.txt"
go.program.tool=kflash
go.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
go.upload.maximum_size=8388608
go.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# Sipeed Maixduino Board ###############
mduino.name=Sipeed Maixduino
## Toolchain
mduino.menu.toolsloc.default=Default
mduino.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
mduino.menu.clksrc.400=400MHz CPU Clock Frequency
mduino.menu.clksrc.500=500MHz CPU Clock Frequency
mduino.menu.clksrc.600=600MHz CPU Clock Frequency
mduino.menu.clksrc.400.build.f_cpu=400000000L
mduino.menu.clksrc.500.build.f_cpu=500000000L
mduino.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
mduino.menu.burn_baudrate.1500000=1.5 Mbps
mduino.menu.burn_baudrate.1000000=1 Mbps
mduino.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
mduino.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
mduino.menu.burn_tool_firmware.mduino=Default
mduino.menu.burn_tool_firmware.mduino.build.burn_tool_firmware=maixduino
## Point to the file for ./variants/<variant>/pins_arduino.h
mduino.build.variant=sipeed_maixduino
## "The 'core' file directory for this board, in ./cores
mduino.build.core=arduino
## This sets a define for use in the compiled code.
mduino.build.board=MAIX_DUINO
mduino.build.sdata.size=512
## This selects the tool from "programmers.txt"
mduino.program.tool=kflash
mduino.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
mduino.upload.maximum_size=8388608
mduino.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# Sipeed M1W Dock Board ###############
m1w.name=Sipeed Maix Dock M1W
## Toolchain
m1w.menu.toolsloc.default=Default
m1w.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
m1w.menu.clksrc.400=400MHz CPU Clock Frequency
m1w.menu.clksrc.500=500MHz CPU Clock Frequency
m1w.menu.clksrc.600=600MHz CPU Clock Frequency
m1w.menu.clksrc.400.build.f_cpu=400000000L
m1w.menu.clksrc.500.build.f_cpu=500000000L
m1w.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
m1w.menu.burn_baudrate.2000000=2 Mbps
m1w.menu.burn_baudrate.1500000=1.5 Mbps
m1w.menu.burn_baudrate.1000000=1 Mbps
m1w.menu.burn_baudrate.2000000.build.burn_baudrate=2000000
m1w.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
m1w.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
m1w.menu.burn_tool_firmware.dan=Default
m1w.menu.burn_tool_firmware.dan.build.burn_tool_firmware=dan
## Point to the file for ./variants/<variant>/pins_arduino.h
m1w.build.variant=sipeed_maix_one_w_dock
## "The 'core' file directory for this board, in ./cores
m1w.build.core=arduino
## This sets a define for use in the compiled code.
m1w.build.board=MAIX_DOCK_M1W
m1w.build.sdata.size=512
## This selects the tool from "programmers.txt"
m1w.program.tool=kflash
m1w.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
m1w.upload.maximum_size=8388608
m1w.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# Sipeed M1 Dock Board ###############
m1.name = Sipeed "Maix One Dock"/"Maix Bit" Board
m1.vid.0=0x1A86
m1.pid.0=0x7523
m1.name=Sipeed Maix Dock M1
## Toolchain
m1.menu.toolsloc.default=Default
m1.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
m1.menu.clksrc.400 = 400MHz CPU Clock Frequency
m1.menu.clksrc.500 = 500MHz CPU Clock Frequency
m1.menu.clksrc.600 = 600MHz CPU Clock Frequency
m1.menu.clksrc.400.build.f_cpu = 400000000L
m1.menu.clksrc.500.build.f_cpu = 500000000L
m1.menu.clksrc.600.build.f_cpu = 600000000L
m1.menu.clksrc.400=400MHz CPU Clock Frequency
m1.menu.clksrc.500=500MHz CPU Clock Frequency
m1.menu.clksrc.600=600MHz CPU Clock Frequency
m1.menu.clksrc.400.build.f_cpu=400000000L
m1.menu.clksrc.500.build.f_cpu=500000000L
m1.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
m1.menu.burn_baudrate.2000000 = 2 Mbps
m1.menu.burn_baudrate.1500000 = 1.5 Mbps
m1.menu.burn_baudrate.1000000 = 1 Mbps
m1.menu.burn_baudrate.2000000.build.burn_baudrate = 2000000
m1.menu.burn_baudrate.1500000.build.burn_baudrate = 1500000
m1.menu.burn_baudrate.1000000.build.burn_baudrate = 1000000
m1.menu.burn_baudrate.2000000=2 Mbps
m1.menu.burn_baudrate.1500000=1.5 Mbps
m1.menu.burn_baudrate.1000000=1 Mbps
m1.menu.burn_baudrate.2000000.build.burn_baudrate=2000000
m1.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
m1.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
m1.menu.burn_tool_firmware.dan = Default
m1.menu.burn_tool_firmware.dan.build.burn_tool_firmware = dan
m1.menu.burn_tool_firmware.dan=Default
m1.menu.burn_tool_firmware.dan.build.burn_tool_firmware=dan
## Point to the file for ./variants/<variant>/pins_arduino.h
m1.build.variant=standard
m1.build.variant=sipeed_maix_one_dock
## "The 'core' file directory for this board, in ./cores
m1.build.core=arduino
## This sets a define for use in the compiled code.
m1.build.board = BOARD_SIPEED_MAIX_ONE_DOCK
m1.build.board=MAIX_DOCK_M1
m1.build.sdata.size=512
## This selects the tool from "programmers.txt"
@@ -50,57 +281,281 @@ m1.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
m1.upload.maximum_size=8388608
m1.build.ldscript={runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld
m1.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# Sipeed Maix Bit Board ###############
####################################################
############### Sipeed Maix Go Board ###############
go.name = Sipeed Maix Go Board
go.vid.0=0x0403
go.pid.0=0x6010
bit.name=Sipeed Maix Bit
## Toolchain
go.menu.toolsloc.default=Default
go.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
bit.menu.toolsloc.default=Default
bit.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
go.menu.clksrc.400 = 400MHz CPU Clock Frequency
go.menu.clksrc.500 = 500MHz CPU Clock Frequency
go.menu.clksrc.600 = 600MHz CPU Clock Frequency
go.menu.clksrc.400.build.f_cpu = 400000000L
go.menu.clksrc.500.build.f_cpu = 500000000L
go.menu.clksrc.600.build.f_cpu = 600000000L
bit.menu.clksrc.400=400MHz CPU Clock Frequency
bit.menu.clksrc.500=500MHz CPU Clock Frequency
bit.menu.clksrc.600=600MHz CPU Clock Frequency
bit.menu.clksrc.400.build.f_cpu=400000000L
bit.menu.clksrc.500.build.f_cpu=500000000L
bit.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
go.menu.burn_baudrate.2000000 = 2 Mbps
go.menu.burn_baudrate.1500000 = 1.5 Mbps
go.menu.burn_baudrate.1000000 = 1 Mbps
go.menu.burn_baudrate.2000000.build.burn_baudrate = 2000000
go.menu.burn_baudrate.1500000.build.burn_baudrate = 1500000
go.menu.burn_baudrate.1000000.build.burn_baudrate = 1000000
bit.menu.burn_baudrate.2000000=2 Mbps
bit.menu.burn_baudrate.1500000=1.5 Mbps
bit.menu.burn_baudrate.1000000=1 Mbps
bit.menu.burn_baudrate.2000000.build.burn_baudrate=2000000
bit.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
bit.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
go.menu.burn_tool_firmware.goE = open-ec
go.menu.burn_tool_firmware.goD = CMSIS-DAP
go.menu.burn_tool_firmware.goE.build.burn_tool_firmware = goE
go.menu.burn_tool_firmware.goD.build.burn_tool_firmware = goD
bit.menu.burn_tool_firmware.dan=Default
bit.menu.burn_tool_firmware.dan.build.burn_tool_firmware=dan
## Core settings
go.build.variant= standard
go.build.core = arduino
## Point to the file for ./variants/<variant>/pins_arduino.h
bit.build.variant=sipeed_maix_bit
## "The 'core' file directory for this board, in ./cores
bit.build.core=arduino
## This sets a define for use in the compiled code.
go.build.board = BOARD_SIPEED_MAIX_GO
bit.build.board=MAIX_BIT
bit.build.sdata.size=512
## This selects the tool from "programmers.txt"
go.program.tool = kflash
go.upload.tool = kflash
bit.program.tool=kflash
bit.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
go.upload.maximum_size=8388608
go.build.ldscript={runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld
bit.upload.maximum_size=8388608
bit.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# Sipeed Maix Bit with Mic Board ###############
bitm.name=Sipeed Maix Bit-Mic
## Toolchain
bitm.menu.toolsloc.default=Default
bitm.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
bitm.menu.clksrc.400=400MHz CPU Clock Frequency
bitm.menu.clksrc.500=500MHz CPU Clock Frequency
bitm.menu.clksrc.600=600MHz CPU Clock Frequency
bitm.menu.clksrc.400.build.f_cpu=400000000L
bitm.menu.clksrc.500.build.f_cpu=500000000L
bitm.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
bitm.menu.burn_baudrate.1500000=1.5 Mbps
bitm.menu.burn_baudrate.1000000=1 Mbps
bitm.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
bitm.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
bitm.menu.burn_tool_firmware.bitm=Default
bitm.menu.burn_tool_firmware.bitm.build.burn_tool_firmware=bit-mic
## Point to the file for ./variants/<variant>/pins_arduino.h
bitm.build.variant=sipeed_maix_bit_mic
## "The 'core' file directory for this board, in ./cores
bitm.build.core=arduino
## This sets a define for use in the compiled code.
bitm.build.board=MAIX_BIT_M
bitm.build.sdata.size=512
## This selects the tool from "programmers.txt"
bitm.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
bitm.upload.maximum_size=8388608
bitm.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# M5Stack M5StickV Stick ###############
stickv.name=M5Stack M5StickV Stick
## Toolchain
stickv.menu.toolsloc.default=Default
stickv.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
stickv.menu.clksrc.400=400MHz CPU Clock Frequency
stickv.menu.clksrc.500=500MHz CPU Clock Frequency
stickv.menu.clksrc.600=600MHz CPU Clock Frequency
stickv.menu.clksrc.400.build.f_cpu=400000000L
stickv.menu.clksrc.500.build.f_cpu=500000000L
stickv.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
stickv.menu.burn_baudrate.1500000=1.5 Mbps
stickv.menu.burn_baudrate.1000000=1 Mbps
stickv.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
stickv.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
stickv.menu.burn_tool_firmware.stick1=CH340
stickv.menu.burn_tool_firmware.stick1.build.burn_tool_firmware=bit-mic
## Point to the file for ./variants/<variant>/pins_arduino.h
stickv.build.variant=m5stack_m5stick_v
## "The 'core' file directory for this board, in ./cores
stickv.build.core=arduino
## This sets a define for use in the compiled code.
stickv.build.board=M5STICK_V
stickv.build.sdata.size=512
## This selects the tool from "programmers.txt"
stickv.program.tool=kflash
stickv.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
stickv.upload.maximum_size=8388608
stickv.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# M5Stack M5UnitV Camera ###############
unitv.name=M5Stack M5UnitV Camera
## Toolchain
unitv.menu.toolsloc.default=Default
unitv.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
unitv.menu.clksrc.400=400MHz CPU Clock Frequency
unitv.menu.clksrc.500=500MHz CPU Clock Frequency
unitv.menu.clksrc.600=600MHz CPU Clock Frequency
unitv.menu.clksrc.400.build.f_cpu=400000000L
unitv.menu.clksrc.500.build.f_cpu=500000000L
unitv.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
unitv.menu.burn_baudrate.1500000=1.5 Mbps
unitv.menu.burn_baudrate.1000000=1 Mbps
unitv.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
unitv.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
unitv.menu.burn_tool_firmware.unit1=CH340
unitv.menu.burn_tool_firmware.unit1.build.burn_tool_firmware=bit-mic
## Point to the file for ./variants/<variant>/pins_arduino.h
unitv.build.variant=m5stack_m5unit_v
## "The 'core' file directory for this board, in ./cores
unitv.build.core=arduino
## This sets a define for use in the compiled code.
unitv.build.board=M5UNIT_V
unitv.build.sdata.size=512
## This selects the tool from "programmers.txt"
unitv.program.tool=kflash
unitv.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
unitv.upload.maximum_size=8388608
unitv.build.ldscript="{runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld"
##################################################
############# LamLoei AIoT DaaN Board ###############
aiotdaan.name=LamLoei AIoT DaaN
## Toolchain
aiotdaan.menu.toolsloc.default=Default
aiotdaan.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
aiotdaan.menu.clksrc.400=400MHz CPU Clock Frequency
aiotdaan.menu.clksrc.500=500MHz CPU Clock Frequency
aiotdaan.menu.clksrc.600=600MHz CPU Clock Frequency
aiotdaan.menu.clksrc.400.build.f_cpu=400000000L
aiotdaan.menu.clksrc.500.build.f_cpu=500000000L
aiotdaan.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
aiotdaan.menu.burn_baudrate.2000000=2 Mbps
aiotdaan.menu.burn_baudrate.1500000=1.5 Mbps
aiotdaan.menu.burn_baudrate.1000000=1 Mbps
aiotdaan.menu.burn_baudrate.2000000.build.burn_baudrate=2000000
aiotdaan.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
aiotdaan.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
aiotdaan.menu.burn_tool_firmware.dan=Default
aiotdaan.menu.burn_tool_firmware.dan.build.burn_tool_firmware=dan
## Point to the file for ./variants/<variant>/pins_arduino.h
aiotdaan.build.variant=lamloei_aiot_daan
## "The 'core' file directory for this board, in ./cores
aiotdaan.build.core=arduino
## This sets a define for use in the compiled code.
aiotdaan.build.board=MAIX_DOCK_M1
aiotdaan.build.sdata.size=512
## This selects the tool from "programmers.txt"
aiotdaan.program.tool=kflash
aiotdaan.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
aiotdaan.upload.maximum_size=8388608
aiotdaan.build.ldscript={runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld
##################################################
############# IOXGD4 ###############
ioxgd4.name=IOXGD4
## Toolchain
ioxgd4.menu.toolsloc.default=Default
ioxgd4.menu.toolsloc.default.compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
## CPU Clock
ioxgd4.menu.clksrc.400=400MHz CPU Clock Frequency
ioxgd4.menu.clksrc.500=500MHz CPU Clock Frequency
ioxgd4.menu.clksrc.600=600MHz CPU Clock Frequency
ioxgd4.menu.clksrc.400.build.f_cpu=400000000L
ioxgd4.menu.clksrc.500.build.f_cpu=500000000L
ioxgd4.menu.clksrc.600.build.f_cpu=600000000L
## Burn baud rate
ioxgd4.menu.burn_baudrate.2000000=2 Mbps
ioxgd4.menu.burn_baudrate.1500000=1.5 Mbps
ioxgd4.menu.burn_baudrate.1000000=1 Mbps
ioxgd4.menu.burn_baudrate.2000000.build.burn_baudrate=2000000
ioxgd4.menu.burn_baudrate.1500000.build.burn_baudrate=1500000
ioxgd4.menu.burn_baudrate.1000000.build.burn_baudrate=1000000
## Burn tool firmware
ioxgd4.menu.burn_tool_firmware.dan=Default
ioxgd4.menu.burn_tool_firmware.dan.build.burn_tool_firmware=dan
## Point to the file for ./variants/<variant>/pins_arduino.h
ioxgd4.build.variant=ioxgd4
## "The 'core' file directory for this board, in ./cores
ioxgd4.build.core=arduino
## This sets a define for use in the compiled code.
ioxgd4.build.board=MAIX_DOCK_M1
ioxgd4.build.sdata.size=512
## This selects the tool from "programmers.txt"
ioxgd4.program.tool=kflash
ioxgd4.upload.tool=kflash
## Limit is the 16MB Flash. Assume half is used for something else.
ioxgd4.upload.maximum_size=8388608
ioxgd4.build.ldscript={runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lds/kendryte.ld

View File

@@ -29,6 +29,7 @@ class HardwareSerial : public Stream
virtual void begin(uint32_t) {};
virtual void end() {};
virtual int available(void) = 0;
virtual int availableForWrite(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;

View File

@@ -28,13 +28,42 @@
#include "Print.h"
// Public Methods //////////////////////////////////////////////////////////////
size_t Print::printf(const char *format, ...)
{
char loc_buf[64];
char * temp = loc_buf;
va_list arg;
va_list copy;
va_start(arg, format);
va_copy(copy, arg);
size_t len = vsnprintf(NULL, 0, format, arg);
va_end(copy);
if(len >= sizeof(loc_buf)){
temp = new char[len+1];
if(temp == NULL) {
return 0;
}
}
len = vsnprintf(temp, len+1, format, arg);
size_t ret = write((uint8_t*)temp, len);
va_end(arg);
if(len >= sizeof(loc_buf)){
delete[] temp;
}
return ret;
}
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--) {
n += write(*buffer++);
size_t ret = write(*buffer++);
if (ret == 0) {
// Write of last byte didn't complete, abort additional processing
break;
}
n += ret;
}
return n;
}

View File

@@ -25,6 +25,9 @@ extern "C"{
#endif // __cplusplus
#include <inttypes.h>
#include <stdio.h> // for size_t
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
@@ -61,6 +64,7 @@ class Print
return write((const uint8_t *)buffer, size);
}
size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3)));
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);

View File

@@ -6,7 +6,7 @@ extern pwm_fpio_set_t pwm_pins[VARIANT_NUM_PWM];
void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
{
int8_t _pin = k210FpioSet(pin);
int8_t _pin = k210FpioSet(MD_PIN_MAP(pin));
if(_pin >= 0){
if (duration > 0) {
pwm_set_frequency(pwm_pins[_pin].device, pwm_pins[_pin].channel,(double)frequency,0.5);
@@ -24,7 +24,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
void noTone(uint8_t pin)
{
int8_t _pin = k210FpioSet(pin);
int8_t _pin = k210FpioSet(MD_PIN_MAP(pin));
if(_pin >= 0){
pwm_set_enable(pwm_pins[_pin].device, pwm_pins[_pin].channel,0);
}

View File

@@ -21,7 +21,7 @@
#include <string.h>
#include "UARTClass.h"
#include "pins_arduino.h"
#include "Arduino.h"
#include "uarths.h"
#include "fpioa.h"
#include "sysctl.h"
@@ -63,11 +63,17 @@ UARTClass::UARTClass(uart_device_number_t device_select)
}
}
void
UARTClass::begin(uint32_t dwBaudRate)
{
begin(dwBaudRate, RX1, TX1);
}
void
UARTClass::begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx)
{
fpioa_set_function((int)_rx, this->_rxfunc);
fpioa_set_function((int)_tx, this->_txfunc);
fpioa_set_function(_rx, this->_rxfunc);
fpioa_set_function(_tx, this->_txfunc);
uart_init(this->_uart);
uart_configure(this->_uart, dwBaudRate, UART_BITWIDTH_8BIT, UART_STOP_1, UART_PARITY_NONE);
this->_buff = new RingBuffer();
@@ -107,6 +113,7 @@ UARTClass::read(void)
while(this->_buff->available()){
return this->_buff->read_char();
}
return -1;
}
void
@@ -121,7 +128,7 @@ UARTClass::write(const uint8_t c)
while (uart[this->_uart]->LSR & (1u << 5))
continue;
uart[this->_uart]->THR = c;
return 0;
return 1;
}
static int
@@ -140,11 +147,17 @@ UARTHSClass::UARTHSClass()
}
void
UARTHSClass::begin(uint32_t dwBaudRate)
{
begin(dwBaudRate, RX0, TX0);
}
void
UARTHSClass::begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx)
{
fpioa_set_function((int)_rx, FUNC_UARTHS_RX);
fpioa_set_function((int)_tx, FUNC_UARTHS_TX);
fpioa_set_function((int)MD_PIN_MAP(_rx), FUNC_UARTHS_RX);
fpioa_set_function((int)MD_PIN_MAP(_tx), FUNC_UARTHS_TX);
uarths_init();
uarths_config(dwBaudRate, UARTHS_STOP_1);
this->_buff = new RingBuffer();
@@ -164,8 +177,11 @@ UARTHSClass::end()
size_t
UARTHSClass::write(const uint8_t uc_data)
{
uarths_putchar(uc_data);
return (1);
if (uarths_putchar(uc_data) == uc_data) {
return 1;
}
return 0;
}
static int
@@ -173,9 +189,9 @@ uarths_rec_callback(void *ctx)
{
int data;
auto &driver = *reinterpret_cast<UARTHSClass *>(ctx);
data = uarths_getc();
if(data != 0){
data = uarths_getchar();
if(data != EOF){
driver._buff->store_char((char)data);
}
return 0;
}
}

View File

@@ -27,12 +27,15 @@
#include "pins_arduino.h"
#include "RingBuffer.h"
class UARTClass : public HardwareSerial
{
public:
UARTClass();
UARTClass(uart_device_number_t device_select);
void begin(uint32_t dwBaudRate, uint8_t _rx = 6, uint8_t _tx = 7);
void begin(uint32_t dwBaudRate);
void begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx);
void end(void);
int available(void);
int availableForWrite(void);
@@ -57,7 +60,8 @@ class UARTHSClass : public UARTClass
{
public:
UARTHSClass();
void begin(uint32_t dwBaudRate, uint8_t _rx = 4, uint8_t _tx = 5);
void begin(uint32_t dwBaudRate);
void begin(uint32_t dwBaudRate, uint8_t _rx, uint8_t _tx);
void end(void);
size_t write(const uint8_t c);
using Print::write;

View File

@@ -3,11 +3,13 @@
#include "wiring_constants.h"
#include "plic.h"
void attachInterrupt(uint8_t intnum, voidFuncPtr callback, uint8_t mode)
void attachInterrupt(uint8_t intnum, voidFuncPtr user_callback, uint8_t mode)
{
plic_irq_callback_t _callback = (plic_irq_callback_t)callback;
int gpionum = getGpio(intnum);
int gpionum = get_gpio(MD_PIN_MAP(intnum));
if(gpionum >= 0){
fpioa_function_t function = FUNC_GPIOHS0 + gpionum;
fpioa_set_function(intnum, function);
gpiohs_set_drive_mode(gpionum, GPIO_DM_INPUT_PULL_UP);
switch(mode){
case LOW :
gpiohs_set_pin_edge((uint8_t)gpionum, GPIO_PE_LOW);
@@ -25,15 +27,22 @@ void attachInterrupt(uint8_t intnum, voidFuncPtr callback, uint8_t mode)
gpiohs_set_pin_edge((uint8_t)gpionum, GPIO_PE_RISING);
break;
}
gpiohs_irq_register((uint8_t)gpionum, 10, _callback, NULL);
gpiohs_irq_register((uint8_t)gpionum, 10, gpiohs_callback, user_callback);
sysctl_enable_irq();
}
}
void detachInterrupt(uint8_t intnum)
{
int gpionum = getGpio(intnum);
int gpionum = get_gpio(MD_PIN_MAP(intnum));
if(gpionum >= 0){
gpiohs_irq_unregister((uint8_t)gpionum);
}
}
int gpiohs_callback(void *ctx)
{
voidFuncPtr user_callback = ctx;
user_callback();
return 0;
}

View File

@@ -35,7 +35,7 @@ extern "C"{
#define DEFAULT 1
#define EXTERNAL 0
#define digitalPinToInterrupt(Pin) Pin;
#define digitalPinToInterrupt(Pin) Pin
typedef void (*voidFuncPtr)(void);
/*
* \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs. Use digitalPinToInterrupt(pin) to get the correct intnum.
@@ -49,6 +49,8 @@ void attachInterrupt(uint8_t intnum, voidFuncPtr callback, uint8_t mode);
*/
void detachInterrupt(uint8_t intnum);
int gpiohs_callback(void *ctx);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@@ -1,5 +1,5 @@
#include "SPI.h"
#include "../../../libraries/SPI/src/SPI.h"
#include "stdio.h"
#include "utils.h"

View File

@@ -52,7 +52,7 @@ void analogOutputInit(void)
void analogWrite(uint8_t ucPin, uint32_t ulValue )
{
int8_t _pin = k210FpioSet(ucPin);
int8_t _pin = k210FpioSet(MD_PIN_MAP(ucPin));
double _duty;
if(_pin >= 0){
_duty = dValueToDuty(ulValue);
@@ -96,6 +96,13 @@ int8_t getPwmPin(void)
return -1;
}
uint32_t analogRead( uint32_t ulPin )
{
#if (defined(BOARD_SIPEED_MAIX_GO) || defined(BOARD_SIPEED_MAIX_ONE_DOCK) )
return 0;
#endif
}
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@@ -65,11 +65,11 @@ enum BitOrder {
#endif // abs
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
#endif // min
#ifndef max
#define max(a,b) ((a)>(b)?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))
#endif // max
#define abs(x) ((x)>0?(x):-(x))

View File

@@ -13,56 +13,45 @@
extern "C"{
#endif // __cplusplus
static int8_t _fpio_to_gpio_table[48]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
void pinMode(uint8_t dwPin, uint8_t dwMode){
int gpionum = getGpio(dwPin);
int gpionum = get_gpio(MD_PIN_MAP(dwPin));
if(gpionum >= 0){
fpioa_function_t function = FUNC_GPIOHS0 + gpionum;
fpioa_set_function(dwPin, function);
fpioa_set_function(MD_PIN_MAP(dwPin), function);
gpiohs_set_drive_mode((uint8_t)gpionum, (gpio_drive_mode_t)dwMode);
gpiohs_set_pin((uint8_t)gpionum, GPIO_PV_LOW);
}
return ;
}
void digitalWrite(uint8_t dwPin, uint8_t dwVal){
int gpionum = getGpio_s(dwPin);
if(gpionum >= 0){
gpiohs_set_pin((uint8_t)gpionum, (gpio_pin_value_t)dwVal);
int8_t gpio_pin = _fpio_to_gpio_table[MD_PIN_MAP(dwPin)];
if( gpio_pin >= 0){
gpiohs_set_pin((uint8_t)gpio_pin, (gpio_pin_value_t)dwVal);
}
return ;
}
int digitalRead(uint8_t dwPin){
int gpionum = getGpio_s(dwPin);
if(gpionum >= 0){
return (int)gpiohs_get_pin((uint8_t)gpionum);
int8_t gpio_pin = _fpio_to_gpio_table[MD_PIN_MAP(dwPin)];
if(gpio_pin >= 0){
return (int)gpiohs_get_pin((uint8_t)gpio_pin);
}
return -1;
}
int getGpio(uint8_t fpioPin) //分配一个gpio给fpio 输入 fpio 返回 gpiohs号
int get_gpio(uint8_t fpio_pin)
{
fpioa_function_t function = fpioa_get_function_buy_io(fpioPin);
if(function <= FUNC_GPIOHS31 && function >= FUNC_GPIOHS0 )
{
return (int)(function - FUNC_GPIOHS0);
if(_fpio_to_gpio_table[fpio_pin] >= 0){
return (int)_fpio_to_gpio_table[fpio_pin];
}else{
return find_unused_gpiohs_io();
_fpio_to_gpio_table[fpio_pin] = (int8_t)find_unused_gpiohs_io();
return (int)_fpio_to_gpio_table[fpio_pin];
}
}
int getGpio_s(uint8_t fpioPin)
{
fpioa_function_t function = fpioa_get_function_buy_io(fpioPin);
if(function <= FUNC_GPIOHS31 && function >= FUNC_GPIOHS0 )
{
return (int)(function - FUNC_GPIOHS0);
}else{
return -1;
}
}
fpioa_function_t fpioa_get_function_buy_io(uint8_t fpioPin)
fpioa_function_t fpioa_get_function_by_io(uint8_t fpioPin)
{
return (fpioa_function_t)fpioa->io[fpioPin].ch_sel ;
}
@@ -80,6 +69,11 @@ int find_unused_gpiohs_io(void) //返回一个未使用的gpio ,失败返回-1
return -1;
}
int read_fpio_to_gpio_table(int number)
{
return _fpio_to_gpio_table[number];
}
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@@ -53,10 +53,10 @@ extern void digitalWrite( uint8_t dwPin, uint8_t dwVal ) ;
*/
extern int digitalRead( uint8_t dwPin ) ;
int getGpio(uint8_t fpioPin) ;
int getGpio_s(uint8_t fpioPin) ;
fpioa_function_t fpioa_get_function_buy_io(uint8_t fpioPin) ;
int get_gpio(uint8_t fpio_pin) ;
fpioa_function_t fpioa_get_function_by_io(uint8_t fpioPin) ;
int find_unused_gpiohs_io(void) ;
int read_fpio_to_gpio_table(int number);
#ifdef __cplusplus
} // extern "C"

115
libraries/AXP173/AXP173.cpp Normal file
View File

@@ -0,0 +1,115 @@
#include "AXP173.h"
AXP173::AXP173()
{
}
void AXP173::begin(bool isInited)
{
if(!isInited){
Wire.begin((uint8_t) SDA, (uint8_t) SCL, 400000);
}
#if defined (ARDUINO_MAIX_AMIGO)
Write1Byte(0x27, 0x20); //LDO4 - 0.8V (default 0x48 1.8V)
Write1Byte(0x28, 0x0C); //LDO2/3 - LDO2 1.8V / LDO3 3.0V
#else //ARDUINO_MAIX_CUBE
Write1Byte(0x46, 0xFF); //Clear interupts
Write1Byte(0x33, 0xC1); //Set Bat Charging Voltage to 4V2, Current to 190mA
Write1Byte(0x10, (Read8bit(0x10) & 0xFC)); //EXTEN & DC-DC2 control
#endif
}
void AXP173::Write1Byte( uint8_t Addr , uint8_t Data )
{
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.write(Data);
Wire.endTransmission();
}
uint8_t AXP173::Read8bit( uint8_t Addr )
{
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 1);
return Wire.read();
}
uint16_t AXP173::Read12Bit( uint8_t Addr)
{
uint16_t Data = 0;
uint8_t buf[2];
ReadBuff(Addr,2,buf);
Data = ((buf[0] << 4) + buf[1]);
return Data;
}
uint16_t AXP173::Read13Bit( uint8_t Addr)
{
uint16_t Data = 0;
uint8_t buf[2];
ReadBuff(Addr,2,buf);
Data = ((buf[0] << 5) + buf[1]);
return Data;
}
uint16_t AXP173::Read16bit( uint8_t Addr )
{
uint16_t ReData = 0;
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 2);
for( int i = 0 ; i < 2 ; i++ )
{
ReData <<= 8;
ReData |= Wire.read();
}
return ReData;
}
uint32_t AXP173::Read24bit( uint8_t Addr )
{
uint32_t ReData = 0;
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 3);
for( int i = 0 ; i < 3 ; i++ )
{
ReData <<= 8;
ReData |= Wire.read();
}
return ReData;
}
uint32_t AXP173::Read32bit( uint8_t Addr )
{
uint32_t ReData = 0;
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 4);
for( int i = 0 ; i < 4 ; i++ )
{
ReData <<= 8;
ReData |= Wire.read();
}
return ReData;
}
void AXP173::ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff )
{
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, (int)Size);
for (int i = 0; i < Size; i++)
{
*( Buff + i ) = Wire.read();
}
}

53
libraries/AXP173/AXP173.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef __AXP173_H__
#define __AXP173_H__
#include <Wire.h>
#include <Arduino.h>
#define SLEEP_MSEC(us) (((uint64_t)us) * 1000L)
#define SLEEP_SEC(us) (((uint64_t)us) * 1000000L)
#define SLEEP_MIN(us) (((uint64_t)us) * 60L * 1000000L)
#define SLEEP_HR(us) (((uint64_t)us) * 60L * 60L * 1000000L)
#define AXP_ADDR 0X34
#define CURRENT_100MA (0b0000)
#define CURRENT_190MA (0b0001)
#define CURRENT_280MA (0b0010)
#define CURRENT_360MA (0b0011)
#define CURRENT_450MA (0b0100)
#define CURRENT_550MA (0b0101)
#define CURRENT_630MA (0b0110)
#define CURRENT_700MA (0b0111)
class AXP173 {
public:
AXP173();
/**
* DCDC1: 3V3 Main rail. When not set the stick shuts down
* DCDC2: 0V9 K210 VCore
* DCDC3: 1V8 Use unknown
* LDO1: Don't set GPIO1 as LDO
* LDO2: 2V8 Display backlight
* LDO3: 1V5 Display Control
* GPIO0: LDO1 LCD_BL
* EXTEN:
*/
void begin(bool isInited = false);
public:
private:
void Write1Byte( uint8_t Addr , uint8_t Data );
uint8_t Read8bit( uint8_t Addr );
uint16_t Read12Bit( uint8_t Addr);
uint16_t Read13Bit( uint8_t Addr);
uint16_t Read16bit( uint8_t Addr );
uint32_t Read24bit( uint8_t Addr );
uint32_t Read32bit( uint8_t Addr );
void ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff );
};
#endif

428
libraries/AXP192/AXP192.cpp Normal file
View File

@@ -0,0 +1,428 @@
#include "AXP192.h"
AXP192::AXP192()
{
}
void AXP192::begin(bool isInited)
{
if(!isInited){
Wire.begin((uint8_t) SDA, (uint8_t) SCL, 400000);
}
Write1Byte(0x46, 0xFF); //Clear interupts
Write1Byte(0x23, 0x08); //Set DC-DC2 (VCore) to 0V9
Write1Byte(0x33, 0xC0); //Set Bat Charging Voltage to 4V2, Current to 100mA
Write1Byte(0x36, 0x0C); //Set 128ms power on, 4s power off
Write1Byte(0x91, 0xF0); //Set GPIO0 (TFT_BL) (from 0x70 (min)) to 3V3 (max)
Write1Byte(0x90, 0x02); //Set GPIO0 to LDO mode
Write1Byte(0x28, 0xF0); //VDD2.8V net: LDO2 3.3V, VDD 1.5V net: LDO3 1.8V
Write1Byte(0x27, 0x2C); //VDD1.8V net: DC-DC3 1.8V
Write1Byte(0x12, 0xFF); //Enble all LDO/DC_DC and EXTEN
Write1Byte(0x23, 0x08); //VDD 0.9v net: DC-DC2 0.9V
Write1Byte(0x32, 0x46); //Enable bat detection
Write1Byte(0x39, 0xFC); //Disable Temp Protection (Sensor doesn't exist!)
Write1Byte(0x31, (Read8bit(0x31) & 0xf8) | (1 << 2)); // Set Power off voltage 3V0
fpioa_set_function(INTL_INT, (fpioa_function_t)(FUNC_GPIOHS0 + 26));
gpiohs_set_drive_mode(26, GPIO_DM_OUTPUT);
gpiohs_set_pin(26, GPIO_PV_HIGH); //Disable VBUS As Input, BAT->5V Boost->VBUS->Charing Cycle
msleep(20);
}
void AXP192::Write1Byte( uint8_t Addr , uint8_t Data )
{
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.write(Data);
Wire.endTransmission();
}
uint8_t AXP192::Read8bit( uint8_t Addr )
{
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 1);
return Wire.read();
}
uint16_t AXP192::Read12Bit( uint8_t Addr)
{
uint16_t Data = 0;
uint8_t buf[2];
ReadBuff(Addr,2,buf);
Data = ((buf[0] << 4) + buf[1]);
return Data;
}
uint16_t AXP192::Read13Bit( uint8_t Addr)
{
uint16_t Data = 0;
uint8_t buf[2];
ReadBuff(Addr,2,buf);
Data = ((buf[0] << 5) + buf[1]);
return Data;
}
uint16_t AXP192::Read16bit( uint8_t Addr )
{
uint16_t ReData = 0;
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 2);
for( int i = 0 ; i < 2 ; i++ )
{
ReData <<= 8;
ReData |= Wire.read();
}
return ReData;
}
uint32_t AXP192::Read24bit( uint8_t Addr )
{
uint32_t ReData = 0;
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 3);
for( int i = 0 ; i < 3 ; i++ )
{
ReData <<= 8;
ReData |= Wire.read();
}
return ReData;
}
uint32_t AXP192::Read32bit( uint8_t Addr )
{
uint32_t ReData = 0;
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 4);
for( int i = 0 ; i < 4 ; i++ )
{
ReData <<= 8;
ReData |= Wire.read();
}
return ReData;
}
void AXP192::ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff )
{
Wire.beginTransmission(AXP_ADDR);
Wire.write(Addr);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, (int)Size);
for (int i = 0; i < Size; i++)
{
*( Buff + i ) = Wire.read();
}
}
void AXP192::ScreenBreath(uint8_t brightness)
{
if (brightness > 12)
{
brightness = 12;
}
uint8_t buf = Read8bit( 0x28 );
Write1Byte( 0x28 , ((buf & 0x0f) | (brightness << 4)) );
}
// Return True = Battery Exist
bool AXP192::GetBatState()
{
if( Read8bit(0x01) | 0x20 )
return true;
else
return false;
}
// Input Power Status
uint8_t AXP192::GetInputPowerStatus()
{
return Read8bit(0x00);
}
// Battery Charging Status
uint8_t AXP192::GetBatteryChargingStatus()
{
return Read8bit(0x01);
}
//---------coulombcounter_from_here---------
//enable: void EnableCoulombcounter(void);
//disable: void DisableCOulombcounter(void);
//stop: void StopCoulombcounter(void);
//clear: void ClearCoulombcounter(void);
//get charge data: uint32_t GetCoulombchargeData(void);
//get discharge data: uint32_t GetCoulombdischargeData(void);
//get coulomb val affter calculation: float GetCoulombData(void);
//------------------------------------------
void AXP192::EnableCoulombcounter(void)
{
Write1Byte( 0xB8 , 0x80 );
}
void AXP192::DisableCoulombcounter(void)
{
Write1Byte( 0xB8 , 0x00 );
}
void AXP192::StopCoulombcounter(void)
{
Write1Byte( 0xB8 , 0xC0 );
}
void AXP192::ClearCoulombcounter(void)
{
Write1Byte( 0xB8, Read8bit(0xB8) | 0x20); // Only set the Clear Flag
}
uint32_t AXP192::GetCoulombchargeData(void)
{
return Read32bit(0xB0);
}
uint32_t AXP192::GetCoulombdischargeData(void)
{
return Read32bit(0xB4);
}
float AXP192::GetCoulombData(void)
{
uint32_t coin = GetCoulombchargeData();
uint32_t coout = GetCoulombdischargeData();
uint32_t valueDifferent = 0;
bool bIsNegative = false;
if (coin > coout)
{ // Expected, in always more then out
valueDifferent = coin - coout;
}
else
{ // Warning: Out is more than In, the battery is not started at 0%
// just Flip the output sign later
bIsNegative = true;
valueDifferent = coout - coin;
}
//c = 65536 * current_LSB * (coin - coout) / 3600 / ADC rate
//Adc rate can be read from 84H, change this variable if you change the ADC reate
float ccc = (65536 * 0.5 * valueDifferent) / 3600.0 / 200.0; // Note the ADC has defaulted to be 200 Hz
if( bIsNegative )
ccc = 0.0 - ccc; // Flip it back to negative
return ccc;
}
//----------coulomb_end_at_here----------
uint8_t AXP192::GetWarningLeve(void)
{
Wire.beginTransmission(AXP_ADDR);
Wire.write(0x47);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 1);
uint8_t buf = Wire.read();
return (buf & 0x01);
}
void AXP192::SetSleep(void)
{
Write1Byte(0x31 , Read8bit(0x31) | ( 1 << 3)); // Turn on short press to wake up
Write1Byte(0x90 , Read8bit(0x90) | 0x07); // GPIO1 floating
Write1Byte(0x82, 0x00); // Disable ADCs
Write1Byte(0x12, Read8bit(0x12) & 0xA1); // Disable all outputs but DCDC1
}
// Return 0 = not press, 0x01 = long press(1.5s), 0x02 = short press
uint8_t AXP192::GetBtnPress()
{
uint8_t state = Read8bit(0x46); // IRQ 3 status.
if(state)
{
Write1Byte( 0x46 , 0x03 ); // Write 1 back to clear IRQ
}
return state;
}
// Low Volt Level 1, when APS Volt Output < 3.4496 V
// Low Volt Level 2, when APS Volt Output < 3.3992 V, then this flag is SET (0x01)
// Flag will reset once battery volt is charged above Low Volt Level 1
// Note: now AXP192 have the Shutdown Voltage of 3.0V (B100) Def in REG 31H
uint8_t AXP192::GetWarningLevel(void)
{
return Read8bit(0x47) & 0x01;
}
float AXP192::GetBatVoltage()
{
float ADCLSB = 1.1 / 1000.0;
uint16_t ReData = Read12Bit( 0x78 );
return ReData * ADCLSB;
}
float AXP192::GetBatCurrent()
{
float ADCLSB = 0.5;
uint16_t CurrentIn = Read13Bit( 0x7A );
uint16_t CurrentOut = Read13Bit( 0x7C );
return ( CurrentIn - CurrentOut ) * ADCLSB;
}
float AXP192::GetVinVoltage()
{
float ADCLSB = 1.7 / 1000.0;
uint16_t ReData = Read12Bit( 0x56 );
return ReData * ADCLSB;
}
float AXP192::GetVinCurrent()
{
float ADCLSB = 0.625;
uint16_t ReData = Read12Bit( 0x58 );
return ReData * ADCLSB;
}
float AXP192::GetVBusVoltage()
{
float ADCLSB = 1.7 / 1000.0;
uint16_t ReData = Read12Bit( 0x5A );
return ReData * ADCLSB;
}
float AXP192::GetVBusCurrent()
{
float ADCLSB = 0.375;
uint16_t ReData = Read12Bit( 0x5C );
return ReData * ADCLSB;
}
float AXP192::GetTempInAXP192()
{
float ADCLSB = 0.1;
const float OFFSET_DEG_C = -144.7;
uint16_t ReData = Read12Bit( 0x5E );
return OFFSET_DEG_C + ReData * ADCLSB;
}
float AXP192::GetBatPower()
{
float VoltageLSB = 1.1;
float CurrentLCS = 0.5;
uint32_t ReData = Read24bit( 0x70 );
return VoltageLSB * CurrentLCS * ReData/ 1000.0;
}
float AXP192::GetBatChargeCurrent()
{
float ADCLSB = 0.5;
uint16_t ReData = Read13Bit( 0x7A );
return ReData * ADCLSB;
}
float AXP192::GetAPSVoltage()
{
float ADCLSB = 1.4 / 1000.0;
uint16_t ReData = Read12Bit( 0x7E );
return ReData * ADCLSB;
}
float AXP192::GetBatCoulombInput()
{
uint32_t ReData = Read32bit( 0xB0 );
return ReData * 65536 * 0.5 / 3600 /25.0;
}
float AXP192::GetBatCoulombOut()
{
uint32_t ReData = Read32bit( 0xB4 );
return ReData * 65536 * 0.5 / 3600 /25.0;
}
// Can turn LCD Backlight OFF for power saving
void AXP192::SetLDO2( bool State )
{
uint8_t buf = Read8bit(0x12);
if( State == true )
{
buf = (1<<2) | buf;
}
else
{
buf = ~(1<<2) & buf;
}
Write1Byte( 0x12 , buf );
}
void AXP192::SetLDO3(bool State)
{
uint8_t buf = Read8bit(0x12);
if( State == true )
{
buf = (1<<3) | buf;
}
else
{
buf = ~(1<<3) & buf;
}
Write1Byte( 0x12 , buf );
}
// Not recommend to set charge current > 100mA, since Battery is only 80mAh.
// more then 1C charge-rate may shorten battery life-span.
void AXP192::SetChargeCurrent(uint8_t current)
{
uint8_t buf = Read8bit(0x33);
buf = (buf & 0xf0) | (current & 0x07);
Write1Byte(0x33, buf);
}
// Cut all power, except for LDO1 (RTC)
void AXP192::PowerOff()
{
Write1Byte(0x32, Read8bit(0x32) | 0x80); // MSB for Power Off
}
void AXP192::SetAdcState(bool state)
{
Write1Byte(0x82, state ? 0xff : 0x00); // Enable / Disable all ADCs
}
// AXP192 have a 6 byte storage, when the power is still valid, the data will not be lost
void AXP192::Read6BytesStorage( uint8_t *bufPtr )
{
// Address from 0x06 - 0x0B
Wire.beginTransmission(AXP_ADDR);
Wire.write(0x06);
Wire.endTransmission();
Wire.requestFrom(AXP_ADDR, 6);
for( int i = 0; i < 6; ++i )
{
bufPtr[i] = Wire.read();
}
}
// AXP192 have a 6 byte storage, when the power is still valid, the data will not be lost
void AXP192::Write6BytesStorage( uint8_t *bufPtr )
{
// Address from 0x06 - 0x0B
Wire.beginTransmission(AXP_ADDR);
Wire.write(0x06);
Wire.write(bufPtr[0]);
Wire.write(0x07);
Wire.write(bufPtr[1]);
Wire.write(0x08);
Wire.write(bufPtr[2]);
Wire.write(0x09);
Wire.write(bufPtr[3]);
Wire.write(0x0A);
Wire.write(bufPtr[4]);
Wire.write(0x0B);
Wire.write(bufPtr[5]);
Wire.endTransmission();
}

94
libraries/AXP192/AXP192.h Normal file
View File

@@ -0,0 +1,94 @@
#ifndef __AXP192_H__
#define __AXP192_H__
#include <Wire.h>
#include <Arduino.h>
#define SLEEP_MSEC(us) (((uint64_t)us) * 1000L)
#define SLEEP_SEC(us) (((uint64_t)us) * 1000000L)
#define SLEEP_MIN(us) (((uint64_t)us) * 60L * 1000000L)
#define SLEEP_HR(us) (((uint64_t)us) * 60L * 60L * 1000000L)
#define AXP_ADDR 0X34
#define CURRENT_100MA (0b0000)
#define CURRENT_190MA (0b0001)
#define CURRENT_280MA (0b0010)
#define CURRENT_360MA (0b0011)
#define CURRENT_450MA (0b0100)
#define CURRENT_550MA (0b0101)
#define CURRENT_630MA (0b0110)
#define CURRENT_700MA (0b0111)
class AXP192 {
public:
AXP192();
/**
* DCDC1: 3V3 Main rail. When not set the stick shuts down
* DCDC2: 0V9 K210 VCore
* DCDC3: 1V8 Use unknown
* LDO1: Don't set GPIO1 as LDO
* LDO2: 2V8 Display backlight
* LDO3: 1V5 Display Control
* GPIO0: LDO1 LCD_BL
* EXTEN:
*/
void begin(bool isInited = false);
void ScreenBreath(uint8_t brightness);
bool GetBatState();
uint8_t GetInputPowerStatus();
uint8_t GetBatteryChargingStatus();
void EnableCoulombcounter(void);
void DisableCoulombcounter(void);
void StopCoulombcounter(void);
void ClearCoulombcounter(void);
uint32_t GetCoulombchargeData(void); // Raw Data for Charge
uint32_t GetCoulombdischargeData(void); // Raw Data for Discharge
float GetCoulombData(void); // total in - total out and calc
uint8_t GetBtnPress(void);
void SetSleep(void);
uint8_t GetWarningLeve(void);
public:
// void SetChargeVoltage( uint8_t );
void SetChargeCurrent( uint8_t );
float GetBatVoltage();
float GetBatCurrent();
float GetVinVoltage();
float GetVinCurrent();
float GetVBusVoltage();
float GetVBusCurrent();
float GetTempInAXP192();
float GetBatPower();
float GetBatChargeCurrent();
float GetAPSVoltage();
float GetBatCoulombInput();
float GetBatCoulombOut();
uint8_t GetWarningLevel(void);
void SetLDO2( bool State ); // Can turn LCD Backlight OFF for power saving
void SetLDO3( bool State );
void SetAdcState(bool State);
// -- Power Off
void PowerOff();
// Power Maintained Storage
void Read6BytesStorage( uint8_t *bufPtr );
void Write6BytesStorage( uint8_t *bufPtr );
private:
void Write1Byte( uint8_t Addr , uint8_t Data );
uint8_t Read8bit( uint8_t Addr );
uint16_t Read12Bit( uint8_t Addr);
uint16_t Read13Bit( uint8_t Addr);
uint16_t Read16bit( uint8_t Addr );
uint32_t Read24bit( uint8_t Addr );
uint32_t Read32bit( uint8_t Addr );
void ReadBuff( uint8_t Addr , uint8_t Size , uint8_t *Buff );
};
#endif

View File

@@ -19,7 +19,7 @@ id KEYWORD2
snapshot KEYWORD2
getRGB565 KEYWORD2
getRGB888 KEYWORD2
setRotaion KEYWORD2
setRotation KEYWORD2
setInver KEYWORD2
width KEYWORD2
height KEYWORD2

View File

@@ -5,7 +5,7 @@
#include <stdbool.h>
typedef enum {
PIXFORMAT_INVLAID = 0,
PIXFORMAT_INVALID = 0,
PIXFORMAT_BAYER, // RAW
PIXFORMAT_RGB565, // RGB565
PIXFORMAT_YUV422, // YUV422
@@ -76,8 +76,9 @@ public:
* e.g. two RED pixel: {0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}
*/
virtual uint8_t* getRGB888(){ return nullptr; };
virtual void setRotaion(uint8_t rotation) = 0;
virtual void setRotation(uint8_t rotation) = 0;
virtual void setInvert(bool invert) = 0;
virtual void flip(bool horiz, bool vert);
virtual int width(){ return _width; }

View File

@@ -1,27 +1,39 @@
#include <MSA300.h>
#include <Wire.h>
// This is the length of the string that will be created
// included minus and decimal point
const signed char formattedStringLength = 11;
// The number of digits after the deimal point to print
const unsigned char numVarsAfterDecimal = 6;
acc_t data;
MSA300 msa;
void setup() {
// put your setup code here, to run once:
static char outstr[formattedStringLength];
char * formatValue(float value)
{
dtostrf(value, formattedStringLength, numVarsAfterDecimal, outstr);
return outstr;
}
void setup()
{
Serial.begin(9600);
Wire.begin();
msa.begin();
}
void loop() {
// put your main code here, to run repeatedly:
void loop()
{
data = msa.getAcceleration();
Serial.print("Xa:");
Serial.print(data.x);
Serial.print("Ya:");
Serial.print(data.y);
Serial.print("Za:");
Serial.println(data.z);
Serial.printf("Xa:%s ", formatValue(data.x));
Serial.printf("Ya:%s ", formatValue(data.y));
Serial.printf("Za:%s", formatValue(data.z));
Serial.println();
delay(100);
}

View File

@@ -0,0 +1,20 @@
#include "Maix_Speech_Recognition.h"
SpeechRecognizer rec;
void setup()
{
rec.begin();
Serial.begin(115200);
Serial.println("start rec...");
if( rec.record(0, 0) == 0) //keyword_num, model_num
{
rec.print_model(0, 0);
}
else
Serial.println("rec failed");
}
void loop()
{
}

View File

@@ -0,0 +1,71 @@
#include "Maix_Speech_Recognition.h"
#include "voice_model.h"
SpeechRecognizer rec;
void setup()
{
pinMode(LED_RED, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
rec.begin();
Serial.begin(115200);
Serial.println("init model...");
rec.addVoiceModel(0, 0, red_0, fram_num_red_0);
rec.addVoiceModel(0, 1, red_1, fram_num_red_1);
rec.addVoiceModel(0, 2, red_2, fram_num_red_2);
rec.addVoiceModel(0, 3, red_3, fram_num_red_3);
rec.addVoiceModel(1, 0, green_0, fram_num_green_0);
rec.addVoiceModel(1, 1, green_1, fram_num_green_1);
rec.addVoiceModel(1, 2, green_2, fram_num_green_2);
rec.addVoiceModel(1, 3, green_3, fram_num_green_3);
rec.addVoiceModel(2, 0, blue_0, fram_num_blue_0);
rec.addVoiceModel(2, 1, blue_1, fram_num_blue_1);
rec.addVoiceModel(2, 2, blue_2, fram_num_blue_2);
rec.addVoiceModel(2, 3, blue_3, fram_num_blue_3);
rec.addVoiceModel(3, 0, turnoff_0, fram_num_turnoff_0);
rec.addVoiceModel(3, 1, turnoff_1, fram_num_turnoff_1);
rec.addVoiceModel(3, 2, turnoff_2, fram_num_turnoff_2);
rec.addVoiceModel(3, 3, turnoff_3, fram_num_turnoff_3);
Serial.println("init model ok!");
}
void loop()
{
int res;
res = rec.recognize();
Serial.printf("res : %d ", res);
if (res > 0){
switch (res)
{
case 1:
digitalWrite(LED_RED, LOW); //power on red led
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_BLUE, HIGH);
Serial.println("rec : red ");
break;
case 2:
digitalWrite(LED_GREEN, LOW); //power on green led
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_BLUE, HIGH);
Serial.println("rec : green ");
break;
case 3:
digitalWrite(LED_BLUE, LOW); //power on blue led
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, HIGH);
Serial.println("rec : blue ");
break;
case 4:
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_BLUE, HIGH); //power off all leds
Serial.println("rec : turnoff ");
default:
break;
}
}else
{
Serial.println("recognize failed.");
}
delay(1000);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
#include "Maix_Speech_Recognition.h"
#include "voice_model.h"
SpeechRecognizer rec;
void setup()
{
pinMode(LED_RED, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
rec.begin();
Serial.begin(115200);
Serial.println("init model...");
rec.addVoiceModel(0, 0, hongse_0, fram_num_hongse_0); //36
rec.addVoiceModel(0, 1, hongse_1, fram_num_hongse_1); //20
rec.addVoiceModel(0, 2, hongse_2, fram_num_hongse_2); //23
rec.addVoiceModel(0, 3, hongse_3, fram_num_hongse_3); //21
rec.addVoiceModel(1, 0, lvse_0, fram_num_lvse_0); //20
rec.addVoiceModel(1, 1, lvse_1, fram_num_lvse_1); //37
rec.addVoiceModel(1, 2, lvse_2, fram_num_lvse_2); //19
rec.addVoiceModel(1, 3, lvse_3, fram_num_lvse_3); //26
rec.addVoiceModel(2, 0, lanse_0, fram_num_lanse_0); //19
rec.addVoiceModel(2, 1, lanse_1, fram_num_lanse_1); //21
rec.addVoiceModel(2, 2, lanse_2, fram_num_lanse_2); //28
rec.addVoiceModel(2, 3, lanse_3, fram_num_lanse_3); //22
rec.addVoiceModel(3, 0, guandeng_0, fram_num_guandeng_0); //26
rec.addVoiceModel(3, 1, guandeng_1, fram_num_guandeng_1); //29
rec.addVoiceModel(3, 2, guandeng_2, fram_num_guandeng_2); //33
rec.addVoiceModel(3, 3, guandeng_3, fram_num_guandeng_3); //29
Serial.println("init model ok!");
}
void loop()
{
int res;
res = rec.recognize();
Serial.printf("res : %d ", res);
if (res > 0){
switch (res)
{
case 1:
digitalWrite(LED_RED, LOW); //power on red led
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_BLUE, HIGH);
Serial.println("rec : hongse ");
break;
case 2:
digitalWrite(LED_GREEN, LOW); //power on green led
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_BLUE, HIGH);
Serial.println("rec : lvse ");
break;
case 3:
digitalWrite(LED_BLUE, LOW); //power on blue led
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, HIGH);
Serial.println("rec : lanse ");
break;
case 4:
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_BLUE, HIGH); //power off all leds
Serial.println("rec : guandeng ");
default:
break;
}
}else
{
Serial.println("recognize failed.");
}
delay(1000);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
name=Maix_Speech_Recognition
version=1.0
author=BigBits
maintainer=BigBits<bigbits@hackx.cc>
sentence=Maix Boards Speech Recognition Lib
paragraph=Maix Boards Speech Recognition Lib
category=Uncategorized
url=
architectures=k210

View File

@@ -0,0 +1,383 @@
#include "Maix_Speech_Recognition.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sysctl.h"
#include "plic.h"
#include "uarths.h"
#include "util/g_def.h"
#include "i2s.h"
#include "fpioa.h"
#include "util/VAD.h"
#include "util/MFCC.h"
#include "util/DTW.h"
#include "util/flash.h"
#include "util/ADC.h"
#define USART1_printf Serial.printf
uint16_t VcBuf[atap_len];
atap_tag atap_arg;
valid_tag valid_voice[max_vc_con];
v_ftr_tag ftr;
v_ftr_tag ftr_temp;
v_ftr_tag ftr_mdl_temp[10];
v_ftr_tag *pftr_mdl_temp[10];
#define save_ok 0
#define VAD_fail 1
#define MFCC_fail 2
#define Flash_fail 3
#define FFT_N 512
uint16_t rx_buf[FRAME_LEN];
uint32_t g_rx_dma_buf[FRAME_LEN * 2];
uint64_t fft_out_data[FFT_N / 2];
volatile uint32_t g_index;
volatile uint8_t uart_rec_flag;
volatile uint32_t receive_char;
volatile uint8_t i2s_rec_flag;
volatile uint8_t i2s_start_flag = 0;
int i2s_dma_irq(void *ctx)
{
uint32_t i;
if(i2s_start_flag)
{
int16_t s_tmp;
if(g_index)
{
i2s_receive_data_dma(I2S_DEVICE_0, &g_rx_dma_buf[g_index], frame_mov * 2, DMAC_CHANNEL3);
g_index = 0;
for(i = 0; i < frame_mov; i++)
{
s_tmp = (int16_t)(g_rx_dma_buf[2 * i] & 0xffff); //g_rx_dma_buf[2 * i + 1] Low left
rx_buf[i] = s_tmp + 32768;
}
i2s_rec_flag = 1;
}
else
{
i2s_receive_data_dma(I2S_DEVICE_0, &g_rx_dma_buf[0], frame_mov * 2, DMAC_CHANNEL3);
g_index = frame_mov * 2;
for(i = frame_mov; i < frame_mov * 2; i++)
{
s_tmp = (int16_t)(g_rx_dma_buf[2 * i] & 0xffff);//g_rx_dma_buf[2 * i + 1] Low left
rx_buf[i] = s_tmp + 32768;
}
i2s_rec_flag = 2;
}
}
else
{
i2s_receive_data_dma(I2S_DEVICE_0, &g_rx_dma_buf[0], frame_mov * 2, DMAC_CHANNEL3);
g_index = frame_mov * 2;
}
return 0;
}
SpeechRecognizer::SpeechRecognizer(){
}
SpeechRecognizer::~SpeechRecognizer(){
}
int
SpeechRecognizer::begin()
{
//io_mux_init
fpioa_set_function(20, FUNC_I2S0_IN_D0);
fpioa_set_function(18, FUNC_I2S0_SCLK);
fpioa_set_function(19, FUNC_I2S0_WS);
//i2s init
i2s_init(I2S_DEVICE_0, I2S_RECEIVER, 0x3);
i2s_rx_channel_config(I2S_DEVICE_0, I2S_CHANNEL_0,
RESOLUTION_16_BIT, SCLK_CYCLES_32,
TRIGGER_LEVEL_4, STANDARD_MODE);
i2s_set_sample_rate(I2S_DEVICE_0, 8000);
dmac_init();
dmac_set_irq(DMAC_CHANNEL3, i2s_dma_irq, NULL, 3);
i2s_receive_data_dma(I2S_DEVICE_0, &g_rx_dma_buf[0], frame_mov * 2, DMAC_CHANNEL3);
/* Enable the machine interrupt */
sysctl_enable_irq();
return 0;
}
int
SpeechRecognizer::record(uint8_t keyword_num, uint8_t model_num)
{
if (keyword_num > 10) return -1;
if (model_num > 4) return -2;
comm = keyword_num;
uint8_t prc_count = model_num;
uint32_t addr = 0;
g_index = 0;
i2s_rec_flag = 0;
i2s_start_flag = 1;
addr = ftr_start_addr + comm * size_per_comm + prc_count * size_per_ftr;
if (save_mdl(VcBuf, addr) == save_ok) {
return 0;
}else{
return -3;
}
}
int
SpeechRecognizer::recognize()
{
u8 res;
u32 dis;
g_index = 0;
i2s_rec_flag = 0;
i2s_start_flag = 1;
res = spch_recg(VcBuf, &dis);
if(dis != dis_err)
return res;
else
return -1;
}
int
SpeechRecognizer::addVoiceModel(uint8_t keyword_num, uint8_t model_num, const int16_t *voice_model, uint16_t frame_num)
{
ftr_save[keyword_num * 4 + model_num].save_sign = save_mask;
ftr_save[keyword_num * 4 + model_num].frm_num = frame_num;
for (int i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[keyword_num * 4 + model_num].mfcc_dat[i] = voice_model[i];
return 0;
}
int
SpeechRecognizer::print_model(uint8_t keyword_num, uint8_t model_num)
{
Serial.printf("frm_num=%d\n", ftr_save[keyword_num*4 + model_num].frm_num);
for (int i = 0; i < (vv_frm_max * mfcc_num); i++) {
if (((i + 1) % 35) == 0)
Serial.printf("%d,\n", ftr_save[keyword_num*4 + model_num].mfcc_dat[i]);
else
Serial.printf("%d, ", ftr_save[keyword_num*4 + model_num].mfcc_dat[i]);
}
Serial.printf("\nprint model ok!\n");
return 0;
}
uint8_t SpeechRecognizer::save_mdl(uint16_t *v_dat, uint32_t addr)
{
u16 i, num;
u16 frame_index;
get_noise1:
frame_index = 0;
num = atap_len / frame_mov;
//wait for finish
while (1) {
while (i2s_rec_flag == 0)
continue;
if (i2s_rec_flag == 1) {
for (i = 0; i < frame_mov; i++)
v_dat[frame_mov * frame_index + i] = rx_buf[i];
} else {
for (i = 0; i < frame_mov; i++)
v_dat[frame_mov * frame_index + i] = rx_buf[i + frame_mov];
}
i2s_rec_flag = 0;
frame_index++;
if (frame_index >= num)
break;
}
// for(i = 0; i < atap_len; i++)
// Serial.printf("noise: %d\n", v_dat[i]);
noise_atap(v_dat, atap_len, &atap_arg);
if (atap_arg.s_thl > 10000) {
Serial.printf("get noise again...\n");
goto get_noise1;
}
Serial.printf("speeking...\n");
//wait for finish
while (i2s_rec_flag == 0)
continue;
if (i2s_rec_flag == 1) {
for (i = 0; i < frame_mov; i++)
v_dat[i + frame_mov] = rx_buf[i];
} else {
for (i = 0; i < frame_mov; i++)
v_dat[i + frame_mov] = rx_buf[i + frame_mov];
}
i2s_rec_flag = 0;
while (1) {
while (i2s_rec_flag == 0)
continue;
if (i2s_rec_flag == 1) {
for (i = 0; i < frame_mov; i++) {
v_dat[i] = v_dat[i + frame_mov];
v_dat[i + frame_mov] = rx_buf[i];
}
} else {
for (i = 0; i < frame_mov; i++) {
v_dat[i] = v_dat[i + frame_mov];
v_dat[i + frame_mov] = rx_buf[i + frame_mov];
}
}
i2s_rec_flag = 0;
if (VAD2(v_dat, valid_voice, &atap_arg) == 1)
break;
if (receive_char == 's')
return MFCC_fail;
}
// if (valid_voice[0].end == ((void *)0)) {
// Serial.printf("VAD_fail\n");
// return VAD_fail;
// }
get_mfcc(&(valid_voice[0]), &ftr, &atap_arg);
if (ftr.frm_num == 0) {
//Serial.printf("MFCC_fail\n");
return MFCC_fail;
}
// ftr.word_num = valid_voice[0].word_num;
return save_ftr_mdl(&ftr, addr);
// ftr_mdl_temp[addr] = ftr;
// return save_ok;
}
uint8_t SpeechRecognizer::spch_recg(uint16_t *v_dat, uint32_t *mtch_dis)
{
u16 i;
u32 ftr_addr;
u32 min_dis;
u16 min_comm;
u32 cur_dis;
v_ftr_tag *ftr_mdl;
u16 num;
u16 frame_index;
uint32_t cycle0, cycle1;
get_noise2:
frame_index = 0;
num = atap_len / frame_mov;
//wait for finish
i2s_rec_flag = 0;
while (1) {
while (i2s_rec_flag == 0)
continue;
if (i2s_rec_flag == 1) {
for (i = 0; i < frame_mov; i++)
v_dat[frame_mov * frame_index + i] = rx_buf[i];
} else {
for (i = 0; i < frame_mov; i++)
v_dat[frame_mov * frame_index + i] = rx_buf[i + frame_mov];
}
i2s_rec_flag = 0;
frame_index++;
if (frame_index >= num)
break;
}
noise_atap(v_dat, atap_len, &atap_arg);
if (atap_arg.s_thl > 10000) {
Serial.printf("get noise again...\n");
goto get_noise2;
}
Serial.printf("speeking...\n");
//wait for finish
while (i2s_rec_flag == 0)
continue;
if (i2s_rec_flag == 1) {
for (i = 0; i < frame_mov; i++)
v_dat[i + frame_mov] = rx_buf[i];
} else {
for (i = 0; i < frame_mov; i++)
v_dat[i + frame_mov] = rx_buf[i + frame_mov];
}
i2s_rec_flag = 0;
while (1) {
while (i2s_rec_flag == 0)
continue;
if (i2s_rec_flag == 1) {
for (i = 0; i < frame_mov; i++) {
v_dat[i] = v_dat[i + frame_mov];
v_dat[i + frame_mov] = rx_buf[i];
}
} else {
for (i = 0; i < frame_mov; i++) {
v_dat[i] = v_dat[i + frame_mov];
v_dat[i + frame_mov] = rx_buf[i + frame_mov];
}
}
i2s_rec_flag = 0;
if (VAD2(v_dat, valid_voice, &atap_arg) == 1)
break;
if (receive_char == 's') {
*mtch_dis = dis_err;
Serial.printf("send 'c' to start\n");
return 0;
}
}
Serial.printf("vad ok\n");
// if (valid_voice[0].end == ((void *)0)) {
// *mtch_dis=dis_err;
// USART1_printf("VAD fail ");
// return (void *)0;
// }
get_mfcc(&(valid_voice[0]), &ftr, &atap_arg);
if (ftr.frm_num == 0) {
*mtch_dis = dis_err;
Serial.printf("MFCC fail ");
return 0;
}
// for (i = 0; i < ftr.frm_num * mfcc_num; i++) {
// if (i % 12 == 0)
// Serial.printf("\n");
// Serial.printf("%d ", ftr.mfcc_dat[i]);
// }
// ftr.word_num = valid_voice[0].word_num;
Serial.printf("mfcc ok\n");
i = 0;
min_comm = 0;
min_dis = dis_max;
cycle0 = read_csr(mcycle);
for (ftr_addr = ftr_start_addr; ftr_addr < ftr_end_addr; ftr_addr += size_per_ftr) {
// ftr_mdl=(v_ftr_tag*)ftr_addr;
ftr_mdl = (v_ftr_tag *)(&ftr_save[ftr_addr / size_per_ftr]);
cur_dis = ((ftr_mdl->save_sign) == save_mask) ? dtw(ftr_mdl, &ftr) : dis_err;
if ((ftr_mdl->save_sign) == save_mask) {
Serial.printf("no. %d, frm_num = %d, save_mask=%d", i + 1, ftr_mdl->frm_num, ftr_mdl->save_sign);
Serial.printf("cur_dis=%d\n", cur_dis);
}
if (cur_dis < min_dis) {
min_dis = cur_dis;
min_comm = i + 1;
}
i++;
}
cycle1 = read_csr(mcycle) - cycle0;
Serial.printf("[INFO] recg cycle = 0x%08x\n", cycle1);
if (min_comm % 4)
min_comm = min_comm / ftr_per_comm + 1;
else
min_comm = min_comm / ftr_per_comm;
//USART1_printf("recg end ");
*mtch_dis = min_dis;
return (u8)min_comm;//(commstr[min_comm].str);
}

View File

@@ -0,0 +1,43 @@
#ifndef __MAIX_SPEECH_RECOGNITION_H
#define __MAIX_SPEECH_RECOGNITION_H
#include "Arduino.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sysctl.h"
#include "plic.h"
#include "uarths.h"
#include "util/g_def.h"
#include "i2s.h"
#include "util/VAD.h"
#include "util/MFCC.h"
#include "util/DTW.h"
#include "util/flash.h"
#include "util/ADC.h"
class SpeechRecognizer{
public:
SpeechRecognizer();
~SpeechRecognizer();
int begin(); //初始化i2s
int record(uint8_t keyword_num, uint8_t model_num); //记录关键词
int recognize(); //识别,返回关键词号
int addVoiceModel(uint8_t keyword_num, uint8_t model_num, const int16_t *voice_model, uint16_t frame_num);
int print_model(uint8_t keyword_num, uint8_t model_num);
private:
uint8_t save_mdl(uint16_t *v_dat, uint32_t addr);
uint8_t spch_recg(uint16_t *v_dat, uint32_t *mtch_dis);
private:
uint8_t comm; //关键词号
};
#endif

View File

@@ -0,0 +1,22 @@
#ifndef _ADC_H
#define _ADC_H
#define fs 8000 //ADC采样率 Hz 8000
#define voice_len 3000 //录音时间长度 单位ms
#define VcBuf_Len ((fs/1000)*voice_len) //语音缓存区长度 单位点数 每个采样点16位
#define atap_len_t 300 //背景噪音自适应时间长度 ms
#define atap_len ((fs/1000)*atap_len_t) //背景噪音自适应长度
#ifdef __cplusplus
extern "C" {
#endif
void ADC_DMA_Init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,434 @@
/******* DTW.C ********/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "g_def.h"
#include "ADC.h"
#include "VAD.h"
#include "MFCC.h"
#include "DTW.h"
/*
* DTW算法 通过局部优化的方法实现加权距离总和最小
时间规整函数:
C={c(1),c(2),…,c(N)}
N为路径长度c(n)=(i(n),j(n))表示第n个匹配点是有参考模板的
第i(n)个特征矢量与待测模板的第j(n)个特征矢量构成的匹配点对,两
者之间的距离d(x(i(n)),y(j(n)))称为匹配距离。
时间规整函数满足一下约束:
1.单调性,规整函数单调增加。
2.起点终点约束,起点对起点,终点对终点。
3.连续性,不允许跳过任何一点。
4.最大规整量不超过某一极限值。|i(n)-j(n)|<M,M为窗宽。规整
函数所处的区域位于平行四边形内。局部路径约束用于限制当第n步
为(i(n),j(n))时,前几步存在几种可能的路径。
DTW步骤
1.初始化。令i(0)=j(0)=0,i(N)=in_frm_num,j(N)=mdl_frm_num.
确定一个平行四边形,有两个位于(0,0)和(in_frm_num,mdl_frm_num)的顶点,相邻斜边斜
率分别是2和1/2.规整函数不可超出此平行四边形。
2.递推求累计距离。
若输入特征与特征模板的帧数差别过大,直接将匹配距离设为最大
frm_in_num<(frm_mdl_num/2)||frm_in_num>(frm_mdl_num*2)
*/
int64_t avr_in[mfcc_num];
int64_t avr_mdl[mfcc_num];
int64_t standard_in[mfcc_num];
int64_t standard_mdl[mfcc_num];
int dtw_data[vv_frm_max*vv_frm_max];
struct pointOritation//节点方向用来回溯每个W点
{
int frontI, frontJ;
};
int g[vv_frm_max][vv_frm_max];
struct pointOritation pOritation[vv_frm_max][vv_frm_max];//用来存放
void gArray(int *p, int n, int m, int *g, struct pointOritation *pr)
{
int i = 0, j = 0;
*g = (*p) * 2;//起始点(最左上角的点)
for (i = 1; i < m; i++) {//最上面一横
*(g + i) = *(g + i - 1) + *(p + i);
(pr + i)->frontI = 0;
(pr + i)->frontJ = i - 1;
}
for (i = 1; i < n; i++) {//最左边的一竖
*(g+i*m+0) = *(g+(i-1)*m+0)+(*(p+i*m+0));
(pr+i*m+0)->frontI = i-1;
(pr+i*m+0)->frontJ = 0;
}
//计算剩余网格的G值
for (i = 1; i < n; i++) {
for (j = 1; j < m; j++) {
int left, up, incline;
left = *(g + i*m+j-1) + *(p + i * m + j);
up = *(g + (i - 1) * m + j) + *(p + i * m + j);
incline = *(g + (i - 1) * m + j - 1) + (*(p + i * m + j)) * 2;
//从左、上、斜三个方向选出最小的
int min = left;
*(g + i * m + j) = min;
(pr + i * m + j)->frontI = i;
(pr + i * m + j)->frontJ = j - 1;
if (min > up) {
min = up;
*(g + i * m + j) = min;
(pr + i * m + j)->frontI = i - 1;
(pr + i * m + j)->frontJ = j;
}
if (min > incline) {
min = incline;
*(g + i * m + j) = min;
(pr + i * m + j)->frontI = i - 1;
(pr + i * m + j)->frontJ = j - 1;
}
}
}
#if 0
//输出G数组
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
printf("%d, ", *(g+i*m+j));
printf("\n");
}
//输出方向数组
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
printf("(%d,%d), ", (pr+i*m+j)->frontI, (pr+i*m+j)->frontJ);
printf("\n");
}
#endif
}
int printPath(struct pointOritation *po, int n, int m, int *g)
{
//从最后一个点向前输出路径节点
int i = n-1, j = m - 1;
int step = 0;
while (1) {
int ii = (po + i * m + j)->frontI, jj = (po + i * m + j)->frontJ;
if (i == 0 && j == 0)
break;
// printf("(%d,%d):%d\n",i,j,*(g+i*m+j));
i = ii;
j = jj;
step++;
}
// printf("distance1 = %d\n", *(g+(n-1)*m + m -1) / step);
return step;
//printf("distance = %d\n", *(g+(n-1)*m + m -1) / step);
}
/*
* 获取两个特征矢量之间的距离
参数
frm_ftr1 特征矢量1
frm_ftr2 特征矢量2
返回值
dis 矢量距离
*/
u32 get_dis(s16 *frm_ftr1, s16 *frm_ftr2)
{
u8 i;
#if 0
#if 1
u32 dis;
s32 dif; //两矢量相同维度上的差值
dis = 0;
for (i = 0; i < mfcc_num; i++) {
//USART1_printf("dis=%d ",dis);
dif = frm_ftr1[i]-frm_ftr2[i];
dis += (dif*dif);
}
//USART1_printf("dis=%d ",dis);
dis = sqrtf(dis);
//USART1_printf("%d\r\n",dis);
return dis;
#else
u32 dis;
s32 dif;
s32 avr;
dis = 0;
for (i = 0; i < mfcc_num; i++) {
//USART1_printf("dis=%d ",dis);
avr = (frm_ftr1[i]+frm_ftr2[i]) / 2;
dif = sqrtf((frm_ftr1[i] - avr) * (frm_ftr1[i] - avr) + (frm_ftr2[i] - avr) * (frm_ftr2[i] - avr));
dif = (frm_ftr1[i]-frm_ftr2[i]) * 100 / dif;
dis += (dif*dif);
}
//USART1_printf("dis=%d ",dis);
dis = sqrtf(dis);
//USART1_printf("%d\r\n",dis);
return dis;
#endif
#else
#if 1
int64_t dif = 0;
int64_t dif_a = 0;
int64_t dif_b = 0;
int32_t dif_r = 0;
for (i = 0; i < mfcc_num; i++) {
dif += (frm_ftr1[i]*frm_ftr2[i]);
dif_a += (frm_ftr1[i] * frm_ftr1[i]);
dif_b += (frm_ftr2[i] * frm_ftr2[i]);
}
dif_r = 1000 - (dif * 1000 / sqrt(dif_a * dif_b));
return dif_r;
#else
int64_t dif = 0;
int64_t dif_a = 0;
int64_t dif_b = 0;
int32_t dif_r = 0;
for (i = 0; i < mfcc_num; i++) {
dif += ((frm_ftr1[i] - avr_mdl[i]) * (frm_ftr2[i] - avr_in[i]));
dif_a += ((frm_ftr1[i] - avr_mdl[i]) * (frm_ftr1[i] - avr_mdl[i]));
dif_b += ((frm_ftr2[i] - avr_in[i]) * (frm_ftr2[i] - avr_in[i]));
}
dif_r = 1000 - (dif * 1000 / (sqrt(dif_a * dif_b)));
return dif_r;
#endif
#endif
}
//平行四边形两外两顶点 X坐标值
static u16 X1; //上边交点
static u16 X2; //下边交点
static int in_frm_num; //输入特征帧数
static int mdl_frm_num;//特征模板帧数
#define ins 0
#define outs 1
/*
* 范围控制
*/
u8 dtw_limit(u16 x, u16 y)
{
if (x < X1) {
if (y >= ((2*x)+2))
return outs;
} else {
if ((2*y+in_frm_num-2*mdl_frm_num) >= (x+4))
return outs;
}
if (x < X2) {
if ((2*y+2) <= x)
return outs;
} else {
if ((y+4) <= (2*x+mdl_frm_num-2*in_frm_num))
return outs;
}
return ins;
}
/*
* DTW 动态时间规整
参数
ftr_in :输入特征值
ftr_mdl :特征模版
返回值
dis :累计匹配距离
*/
u32 dtw(v_ftr_tag *ftr_in, v_ftr_tag *frt_mdl)
{
u32 dis;
// u16 x, y;
u16 step;
s16 *in;
s16 *mdl;
// u32 d_right_up, right, right_up; //up,
// u32 min;
int i, j;
in_frm_num = ftr_in->frm_num;
mdl_frm_num = frt_mdl->frm_num;
if ((in_frm_num > (mdl_frm_num*3)) || ((3*in_frm_num) < mdl_frm_num)) {
//USART1_printf("in_frm_num=%d mdl_frm_num=%d\r\n", in_frm_num,mdl_frm_num);
return dis_err;
} else {
// 计算约束平行四边形顶点值
X1 = (2*mdl_frm_num-in_frm_num)/3;
X2 = (4*in_frm_num-2*mdl_frm_num)/3;
in = ftr_in->mfcc_dat;
mdl = frt_mdl->mfcc_dat;
#if 0
for (j = 0; j < mfcc_num; j++) {
avr_in[j] = 0;
avr_mdl[j] = 0;
}
for (j = 0; j < mfcc_num; j++)
for (i = 0; i < in_frm_num; i++)
avr_in[j] += in[mfcc_num * i + j];
for (j = 0; j < mfcc_num; j++)
avr_in[j] = avr_in[j] / in_frm_num;
//
for (j = 0; j < mfcc_num; j++)
for (i = 0; i < mdl_frm_num; i++)
avr_mdl[j] += mdl[mfcc_num * i + j];
for (j = 0; j < mfcc_num; j++)
avr_mdl[j] = avr_mdl[j] / mdl_frm_num;
dis = get_dis(in, mdl);
x = 1;
y = 1;
step = 1;
#endif
#if 0
for (i = 0; i < in_frm_num; i++) {
for (j = 0; j < mdl_frm_num; j++) {
printf("%d,", get_dis(mdl, in));
mdl += mfcc_num;
}
mdl = frt_mdl->mfcc_dat;
in += mfcc_num;
printf("\n");
}
in = ftr_in->mfcc_dat;
mdl = frt_mdl->mfcc_dat;
#endif
for (i = 0; i < in_frm_num; i++) {
for (j = 0; j < mdl_frm_num; j++) {
//dtw_data[i][j] = get_dis(in + (i * mfcc_num), mdl + (j * mfcc_num));
//dtw_data[i][j] = get_dis(in, mdl);
*(dtw_data+i*mdl_frm_num+j) = get_dis(in, mdl);
// printf("%d,", dtw_data[i*mdl_frm_num+j]);
mdl += mfcc_num;
}
//printf("\n");
mdl = frt_mdl->mfcc_dat;
in += mfcc_num;
}
gArray(dtw_data, in_frm_num, mdl_frm_num, *g, *pOritation);
step = printPath(*pOritation, in_frm_num, mdl_frm_num, *g);
//printf("step=%d\r\n",step);
dis = *((int *)g+(in_frm_num-1)*mdl_frm_num + mdl_frm_num - 1);
// printf("dis=%d step=%d dis/step=%d\r\n",dis,step,dis/step);
}
return (dis/step); //步长归一化
}
void get_mean(s16 *frm_ftr1, s16 *frm_ftr2, s16 *mean)
{
u8 i;
for (i = 0; i < mfcc_num; i++) {
mean[i] = (frm_ftr1[i]+frm_ftr2[i])/2;
// printf("x=%d y=%d ", frm_ftr1[i], frm_ftr2[i]);
// printf("mean=%d\r\n", mean[i]);
}
}
/*
* 从两特征矢量获取特征模板
参数
ftr_in1 :输入特征值
ftr_in2 :输入特征值
ftr_mdl :特征模版
返回值
dis :累计匹配距离
*/
u32 get_mdl(v_ftr_tag *ftr_in1, v_ftr_tag *ftr_in2, v_ftr_tag *ftr_mdl)
{
u32 dis;
u16 x, y;
u16 step;
s16 *in1;
s16 *in2;
s16 *mdl;
u32 right, right_up, d_right_up;//up,
u32 min;
in_frm_num = ftr_in1->frm_num;
mdl_frm_num = ftr_in2->frm_num;
if ((in_frm_num > (mdl_frm_num*2)) || ((2*in_frm_num) < mdl_frm_num)) {
printf("in_frm_num= %d, mdl_frm_num= %d\n", in_frm_num, mdl_frm_num);
return dis_err;
} else {
// 计算约束平行四边形顶点值
X1 = (2*mdl_frm_num-in_frm_num)/3;
X2 = (4*in_frm_num-2*mdl_frm_num)/3;
in1 = ftr_in1->mfcc_dat;
in2 = ftr_in2->mfcc_dat;
mdl = ftr_mdl->mfcc_dat;
dis = get_dis(in1, in2);
get_mean(in1, in2, mdl);
x = 1;
y = 1;
step = 1;
do {
//up = (dtw_limit(x, y+1) == ins)?get_dis(in2+mfcc_num, in1):dis_err;
d_right_up = (dtw_limit(x+1, y+2) == ins)?get_dis(in2+mfcc_num+mfcc_num, in1+mfcc_num):dis_err;
right = (dtw_limit(x+1, y) == ins)?get_dis(in2, in1+mfcc_num):dis_err;
right_up = (dtw_limit(x+1, y+1) == ins)?get_dis(in2+mfcc_num, in1+mfcc_num):dis_err;
min = right_up;
if (min > right)
min = right;
if (min > d_right_up)
min = d_right_up;
dis += min;
if (min == right_up) {
in1 += mfcc_num;
x++;
in2 += mfcc_num;
y++;
} else if (min == d_right_up) {
//in2 += mfcc_num;
//y++;
in2 = in2 + mfcc_num + mfcc_num;
y += 2;
in1 += mfcc_num;
x++;
} else {
in1 += mfcc_num;
x++;
}
step++;
mdl += mfcc_num;
get_mean(in1, in2, mdl);
// printf("x=%d y=%d\r\n", x, y);
} while ((x < in_frm_num) && (y < mdl_frm_num));
printf("step=%d\r\n", step);
ftr_mdl->frm_num = step;
}
return (dis/step); //步长归一化
}

View File

@@ -0,0 +1,20 @@
#ifndef _DTW_H
#define _DTW_H
#include "g_def.h"
#define dis_err 0xFFFFFFFF
#define dis_max 0xFFFFFFFF
#ifdef __cplusplus
extern "C" {
#endif
u32 dtw(v_ftr_tag *ftr_in, v_ftr_tag *frt_mdl);
u32 get_mdl(v_ftr_tag *ftr_in1, v_ftr_tag *ftr_in2, v_ftr_tag *ftr_mdl);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,37 @@
#include <stdio.h>
#include "FIR.h"
const double Gains[39] = {
-0.01152483856464, -0.0225638929287, -0.002300804134165, 0.01259363093284,
-0.0003113695305127, -0.01591961043518, 0.005297252625722, 0.01846679452201,
-0.01074864266549, -0.02187510941784, 0.0192688121099, 0.02485021814652,
-0.03198920030056, -0.02754770718169, 0.05351978821001, 0.0296026126381,
-0.09977798297944, -0.03089664322888, 0.3161729116138, 0.5313543998522,
0.3161729116138, -0.03089664322888, -0.09977798297944, 0.0296026126381,
0.05351978821001, -0.02754770718169, -0.03198920030056, 0.02485021814652,
0.0192688121099, -0.02187510941784, -0.01074864266549, 0.01846679452201,
0.005297252625722, -0.01591961043518, -0.0003113695305127, 0.01259363093284,
-0.002300804134165, -0.0225638929287, -0.01152483856464
};
#define ORDER 38 //阶数
double Buffer[ORDER + 1]; //采样历史数据
double Fir(double Input)
{
double Output = 0.0; //数据输出
int Index; //下标索引
//采样数据移位
for (Index = ORDER; Index > 0; Index--)
Buffer[Index] = Buffer[Index-1];
Buffer[0] = Input;
//计算输出
for (Index = 0; Index < ORDER+1; Index++)
Output += Gains[Index]*Buffer[Index];
return Output;
}

View File

@@ -0,0 +1,15 @@
#ifndef _FIR_H_
#define _FIR_H_
#ifdef __cplusplus
extern "C" {
#endif
double Fir(double Input);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,273 @@
/******* MFCC.C *******/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "g_def.h"
#include <math.h>
#include "ADC.h"
#include "VAD.h"
#include "MFCC.h"
#include "MFCC_Arg.h"
#include <float.h>
#include "sysctl.h"
#include "dmac.h"
#include "fft.h"
#include "FIR.h"
void cr4_fft_1024_stm32(void *pssOUT, void *pssIN, u16 Nbin);
void normalize(s16 *mfcc_p, u16 frm_num);
u32 fft_out[mfcc_fft_point];
s16 fft_in[mfcc_fft_point];
extern uint64_t fft_out_data[512 / 2];
extern void fft_dma_init(void);
extern volatile fft_t *const fft;
void fft_input_intdata(int16_t *data, uint8_t point)
{
uint16_t point_num = 0;
uint16_t i;
fft_data_t input_data;
if (point == 0)
point_num = 512;
else if (point == 1)
point_num = 256;
else if (point == 2)
point_num = 128;
else if (point == 3)
point_num = 64;
point_num = point_num / 2; // one time send two data
for (i = 0; i < point_num; i++) {
input_data.R1 = data[2 * i];
input_data.I1 = 0;
input_data.R2 = data[2 * i + 1];
input_data.I2 = 0;
fft->fft_input_fifo.fft_input_fifo = *(uint64_t *)&input_data;
}
}
void fft_sync_data(int16_t *data, uint8_t point, fft_data_t *fft_data)
{
uint16_t point_num = 0;
uint16_t i;
if (point == 0)
point_num = 512;
else if (point == 1)
point_num = 256;
else if (point == 2)
point_num = 128;
else if (point == 3)
point_num = 64;
point_num = point_num / 2; // one time send two data
for (i = 0; i < point_num; i++) {
(fft_data + i)->R1 = data[2 * i];
(fft_data + i)->I1 = 0;
(fft_data + i)->R2 = data[2 * i + 1];
(fft_data + i)->I2 = 0;
}
}
/*
* cr4_fft_1024_stm32输入参数是有符号数
*
* cr4_fft_1024_stm32输入参数包括实数和虚数
但语音数据只包括实数部分 虚数用0填充
fft点数超出输入数据长度时 超过部分用0填充
cr4_fft_1024_stm32输出数据包括实数和虚数
应该取其绝对值 即平方和的根
*/
u32 *mfcc_fft(s16 *dat_buf, u16 buf_len)
{
u16 i;
s32 real, imag;
fft_data_t output_data;
if (buf_len > mfcc_fft_point)
return (void *)0;
for (i = 0; i < buf_len; i++) {
fft_in[i] = *(dat_buf+i);//虚部高位 实部低位
}
for (; i < mfcc_fft_point; i++)
fft_in[i] = 0;//超出部分用0填充
fft_data_t fft_in_buf[512];
memset(fft_in_buf, 0 , sizeof(fft_in_buf));
fft_sync_data(fft_in, FFT_512, fft_in_buf);
fft_complex_uint16_dma(DMAC_CHANNEL0, DMAC_CHANNEL1, 0x1ff, FFT_DIR_FORWARD, (uint64_t *)fft_in_buf, 512, fft_out_data);
for (i = 0; i < frq_max / 2; i++) {
output_data = *(fft_data_t *)&fft_out_data[i];
imag = (s16)output_data.I1;
real = (s16)output_data.R1;
real = real*real+imag*imag;
fft_out[2 * i] = sqrtf((float)real)*10;
imag = (s16)output_data.I2;
real = (s16)output_data.R2;
real = real*real+imag*imag;
fft_out[2 * i + 1] = sqrtf((float)real)*10;
}
return fft_out;
}
/* MFCCMel频率倒谱系数
*
参数:
valid 有效语音段起点终点
返回值:
v_ftr MFCC值帧数
Mel=2595*lg(1+f/700)
1000Hz以下按线性刻度 1000Hz以上按对数刻度
三角型滤波器中心频率 在Mel频率刻度上等间距排列
预加重:6dB/倍频程 一阶高通滤波器 H(z)=1-uz^(-1) y(n)=x(n)-ux(n-1) u=0.94~0.97
MFCC 步骤:
1.对语音信号预加重、分帧、加汉明窗处理,然后进行短时傅里叶变换,得出频谱
2.取频谱平方得能量谱。并用24个Mel带通滤波器进行滤波输出Mel功率谱
3.对每个滤波器的输出值取对数得到相应频带的对数功率谱。然后对24个对数功率进行
反离散余弦变换得到12个MFCC系数
*/
void get_mfcc(valid_tag *valid, v_ftr_tag *v_ftr, atap_tag *atap_arg)
{
u16 *vc_dat;
u16 h, i;
u32 *frq_spct; //频谱
s16 vc_temp[FRAME_LEN]; //语音暂存区
s32 temp;
u32 pow_spct[tri_num]; //三角滤波器输出对数功率谱
u16 frm_con;
s16 *mfcc_p;
s8 *dct_p;
s32 mid;
u16 v_frm_num;
//USART1_printf("start=%d end=%d",(u32)(valid->start),(u32)(valid->end));
v_frm_num = (((u32)(valid->end)-(u32)(valid->start))/2-FRAME_LEN)/(FRAME_LEN-frame_mov)+1;
if (v_frm_num > vv_frm_max) {
printf("frm_num=%d ", v_frm_num);
v_ftr->frm_num = 0;
} else {
mid = (s32)atap_arg->mid_val;
mfcc_p = v_ftr->mfcc_dat;
frm_con = 0;
//low pass filter
// for (vc_dat = (u16 *)(valid->start); vc_dat <= ((u16 *)(valid->end-FRAME_LEN)); vc_dat += 1) {
// *vc_dat = (u16)(Fir(*vc_dat));
// }
for (vc_dat = (u16 *)(valid->start); vc_dat <= ((u16 *)(valid->end-FRAME_LEN)); vc_dat += (FRAME_LEN-frame_mov)) {
for (i = 0; i < FRAME_LEN; i++) {
//预加重
// printf("vc_dat[%d]=%d ",i,((s32)(*(vc_dat+i))-mid));
temp = ((s32)(*(vc_dat+i))-mid) - hp_ratio(((s32)(*(vc_dat+i-1))-mid));
// printf("vc_hp[%d]=%d ",i,temp);
//加汉明窗 并放大10倍
vc_temp[i] = (s16)(temp*hamm[i]/(hamm_top/10));
// printf("vc_hm[%d]=%d\r\n",i,vc_temp[i]);
}
frq_spct = mfcc_fft(vc_temp, FRAME_LEN);
for (i = 0; i < frq_max; i++) {
//printf("frq_spct[%d]=%d ",i,frq_spct[i]);
frq_spct[i] *= frq_spct[i];//能量谱
//printf("E_spct[%d]=%d\r\n",i,frq_spct[i]);
}
//加三角滤波器
pow_spct[0] = 0;
for (i = 0; i < tri_cen[1]; i++)
pow_spct[0] += (frq_spct[i]*tri_even[i]/(tri_top/10));
for (h = 2; h < tri_num; h += 2) {
pow_spct[h] = 0;
for (i = tri_cen[h-1]; i < tri_cen[h+1]; i++)
pow_spct[h] += (frq_spct[i]*tri_even[i]/(tri_top/10));
}
for (h = 1; h < (tri_num-2); h += 2) {
pow_spct[h] = 0;
for (i = tri_cen[h-1]; i < tri_cen[h+1]; i++)
pow_spct[h] += (frq_spct[i]*tri_odd[i]/(tri_top/10));
}
pow_spct[tri_num-1] = 0;
for (i = tri_cen[tri_num-2]; i < (mfcc_fft_point/2); i++)
pow_spct[tri_num-1] += (frq_spct[i]*tri_odd[i]/(tri_top/10));
//三角滤波器输出取对数
for (h = 0; h < tri_num; h++) {
//USART1_printf("pow_spct[%d]=%d ",h,pow_spct[h]);
pow_spct[h] = (u32)(log(pow_spct[h])*100);//取对数后 乘100 提升数据有效位数
//USART1_printf("%d\r\n",pow_spct[h]);
}
//反离散余弦变换
dct_p = (s8 *)dct_arg;
for (h = 0; h < mfcc_num; h++) {
mfcc_p[h] = 0;
for (i = 0; i < tri_num; i++)
mfcc_p[h] += (((s32)pow_spct[i])*((s32)dct_p[i])/100);
//printf("%d,",mfcc_p[h]);
dct_p += tri_num;
}
//USART1_printf("\r\n");
mfcc_p += mfcc_num;
frm_con++;
}
mfcc_p = v_ftr->mfcc_dat;
normalize(mfcc_p, frm_con);
v_ftr->frm_num = frm_con;
}
}
s16 avg(s16 *mfcc_p, u16 frm_num)
{
int i, j;
double sum = 0.0f;
printf("frm_num = %d, mfcc_num = %d\n", frm_num, mfcc_num);
for (i = 0; i < frm_num; i++)
for (j = 0; j < mfcc_num; j++) {
sum += mfcc_p[i * mfcc_num + j];
// printf("[%d, %d]%f %f ", i, j, sum, mfcc_p[i * mfcc_num + j]);
}
return (s16)(sum / (frm_num * mfcc_num));
}
s16 stdev(s16 *mfcc_p, s16 avg1, u16 frm_num)
{
int i, j;
double sum = 0.0f;
for (i = 0; i < frm_num; i++)
for (j = 0; j < mfcc_num; j++)
sum += (mfcc_p[i * mfcc_num + j] - avg1) * (mfcc_p[i * mfcc_num + j] - avg1);
return (s16)(sqrt(sum / (frm_num * mfcc_num)));
}
void normalize(s16 *mfcc_p, u16 frm_num)
{
int i, j;
s16 avg1 = avg(mfcc_p, frm_num);
s16 stdev1 = stdev(mfcc_p, avg1, frm_num);
printf("avg1 = %d, stdev1 = %d\n", avg1, stdev1);
for (i = 0; i < frm_num; i++)
for (j = 0; j < mfcc_num; j++)
mfcc_p[i * mfcc_num + j] = (mfcc_p[i * mfcc_num + j] - avg1) * 100 / stdev1;
}

View File

@@ -0,0 +1,39 @@
#ifndef _MFCC_H
#define _MFCC_H
#include "VAD.h"
#include "g_def.h"
#define hp_ratio(x) (x*95/100)//预加重系数 0.95
#define mfcc_fft_point 512 //FFT点数
#define frq_max (mfcc_fft_point/2) //最大频率
#define hamm_top 10000 //汉明窗最大值
#define tri_top 1000 //三角滤波器顶点值
#define tri_num 24 //三角滤波器个数
//#define tri_num 17 //三角滤波器个数
#define mfcc_num 12 //MFCC阶数
#define vv_tim_max 2200 //单段有效语音最长时间 ms
#define vv_frm_max ((vv_tim_max-frame_time)/(frame_time-frame_mov_t)+1) //单段有效语音最长帧数
#ifdef __cplusplus
extern "C" {
#endif
//#pragma pack(4)
typedef struct {
u16 save_sign; //存储标记 用于判断flash中特征模板是否有效
u16 frm_num; //帧数
// u8 word_num;
s16 mfcc_dat[vv_frm_max*mfcc_num]; //MFCC转换结果
// float mfcc_dat[vv_frm_max*mfcc_num];
} v_ftr_tag; //语音特征结构体
//#pragma pack()
void get_mfcc(valid_tag *valid, v_ftr_tag *v_ftr, atap_tag *atap_arg);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,135 @@
#ifndef MFCC_Arg
#define MFCC_Arg
#include "g_def.h"
//汉明窗 窗长160
const u16 hamm[] = {
800, 804, 814, 832, 857, 889, 929, 975, 1028, 1088, 1155, 1228, 1308, 1394, 1486, 1585, 1689, 1800, 1915, 2037,
2163, 2295, 2432, 2573, 2718, 2868, 3022, 3179, 3340, 3504, 3671, 3841, 4013, 4187, 4364, 4542, 4721, 4901, 5082,
5264, 5445, 5627, 5808, 5989, 6169, 6348, 6525, 6700, 6873, 7044, 7213, 7378, 7541, 7700, 7856, 8007, 8155, 8298,
8437, 8571, 8701, 8825, 8943, 9056, 9164, 9265, 9361, 9450, 9533, 9610, 9680, 9743, 9799, 9849, 9892, 9927, 9956,
9978, 9992, 9999, 9999, 9992, 9978, 9956, 9927, 9892, 9849, 9799, 9743, 9680, 9610, 9533, 9450, 9361, 9265, 9164,
9056, 8943, 8825, 8701, 8571, 8437, 8298, 8155, 8007, 7856, 7700, 7541, 7378, 7213, 7044, 6873, 6700, 6525, 6348,
6169, 5989, 5808, 5627, 5445, 5264, 5082, 4901, 4721, 4542, 4364, 4187, 4013, 3841, 3671, 3504, 3340, 3179, 3022,
2868, 2718, 2573, 2432, 2295, 2163, 2037, 1915, 1800, 1689, 1585, 1486, 1394, 1308, 1228, 1155, 1088, 1028, 975,
929, 889, 857, 832, 814, 804, 800
};
#if 0 //1024 point fft
//三角滤波器中心频率点
const u16 tri_cen[] = {
11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 134, 152, 171, 191, 214, 237, 263, 291, 321, 354, 389, 427, 468
};
//奇数三角滤波器首尾相连的折线
const u16 tri_odd[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545,
455, 364, 273, 182, 91, 0, 91, 182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455,
364, 273, 182, 91, 0, 91, 182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364,
273, 182, 91, 0, 91, 182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273,
182, 91, 0, 91, 182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273, 182,
91, 0, 77, 154, 231, 308, 385, 462, 538, 615, 692, 769, 846, 923, 1000, 944, 889, 833, 778, 722, 667, 611, 556,
500, 444, 389, 333, 278, 222, 167, 111, 56, 0, 53, 105, 158, 211, 263, 316, 368, 421, 474, 526, 579, 632, 684,
737, 789, 842, 895, 947, 1000, 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200,
150, 100, 50, 0, 43, 87, 130, 174, 217, 261, 304, 348, 391, 435, 478, 522, 565, 609, 652, 696, 739, 783, 826,
870, 913, 957, 1000, 957, 913, 870, 826, 783, 739, 696, 652, 609, 565, 522, 478, 435, 391, 348, 304, 261, 217,
174, 130, 87, 43, 0, 38, 77, 115, 154, 192, 231, 269, 308, 346, 385, 423, 462, 500, 538, 577, 615, 654, 692,
731, 769, 808, 846, 885, 923, 962, 1000, 964, 929, 893, 857, 821, 786, 750, 714, 679, 643, 607, 571, 536, 500,
464, 429, 393, 357, 321, 286, 250, 214, 179, 143, 107, 71, 36, 0, 33, 67, 100, 133, 167, 200, 233, 267, 300,
333, 367, 400, 433, 467, 500, 533, 567, 600, 633, 667, 700, 733, 767, 800, 833, 867, 900, 933, 967, 1000, 970,
939, 909, 879, 848, 818, 788, 758, 727, 697, 667, 636, 606, 576, 545, 515, 485, 455, 424, 394, 364, 333, 303,
273, 242, 212, 182, 152, 121, 91, 61, 30, 0, 29, 57, 86, 114, 143, 171, 200, 229, 257, 286, 314, 343, 371, 400,
429, 457, 486, 514, 543, 571, 600, 629, 657, 686, 714, 743, 771, 800, 829, 857, 886, 914, 943, 971, 1000, 974,
947, 921, 895, 868, 842, 816, 789, 763, 737, 711, 684, 658, 632, 605, 579, 553, 526, 500, 474, 447, 421, 395,
368, 342, 316, 289, 263, 237, 211, 184, 158, 132, 105, 79, 53, 26, 0, 24, 49, 73, 98, 122, 146, 171, 195, 220,
244, 268, 293, 317, 341, 366, 390, 415, 439, 463, 488, 512, 537, 561, 585, 610, 634, 659, 683, 707, 732, 756,
780, 805, 829, 854, 878, 902, 927, 951, 976, 1000, 977, 955, 932, 909, 886, 864, 841, 818, 795, 773, 750, 727,
705, 682, 659, 636, 614, 591, 568, 545, 523, 500, 477, 455, 432, 409, 386, 364, 341, 318, 295, 273, 250, 227,
205, 182, 159, 136, 114, 91, 68, 45, 23, 0
};
//偶数三角滤波器首尾相连的折线
const u16 tri_even[] = {
91, 182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273, 182, 91, 0, 91,
182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273, 182, 91, 0, 91, 182,
273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273, 182, 91, 0, 91, 182, 273,
364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273, 182, 91, 0, 91, 182, 273, 364,
455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273, 182, 91, 0, 91, 182, 273, 364, 455,
545, 636, 727, 818, 909, 1000, 923, 846, 769, 692, 615, 538, 462, 385, 308, 231, 154, 77, 0, 56, 111, 167, 222,
278, 333, 389, 444, 500, 556, 611, 667, 722, 778, 833, 889, 944, 1000, 947, 895, 842, 789, 737, 684, 632, 579,
526, 474, 421, 368, 316, 263, 211, 158, 105, 53, 0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600,
650, 700, 750, 800, 850, 900, 950, 1000, 957, 913, 870, 826, 783, 739, 696, 652, 609, 565, 522, 478, 435, 391,
348, 304, 261, 217, 174, 130, 87, 43, 0, 43, 87, 130, 174, 217, 261, 304, 348, 391, 435, 478, 522, 565, 609, 652,
696, 739, 783, 826, 870, 913, 957, 1000, 962, 923, 885, 846, 808, 769, 731, 692, 654, 615, 577, 538, 500, 462,
423, 385, 346, 308, 269, 231, 192, 154, 115, 77, 38, 0, 36, 71, 107, 143, 179, 214, 250, 286, 321, 357, 393, 429,
464, 500, 536, 571, 607, 643, 679, 714, 750, 786, 821, 857, 893, 929, 964, 1000, 967, 933, 900, 867, 833, 800, 767,
733, 700, 667, 633, 600, 567, 533, 500, 467, 433, 400, 367, 333, 300, 267, 233, 200, 167, 133, 100, 67, 33, 0, 30,
61, 91, 121, 152, 182, 212, 242, 273, 303, 333, 364, 394, 424, 455, 485, 515, 545, 576, 606, 636, 667, 697, 727,
758, 788, 818, 848, 879, 909, 939, 970, 1000, 971, 943, 914, 886, 857, 829, 800, 771, 743, 714, 686, 657, 629, 600,
571, 543, 514, 486, 457, 429, 400, 371, 343, 314, 286, 257, 229, 200, 171, 143, 114, 86, 57, 29, 0, 26, 53, 79,
105, 132, 158, 184, 211, 237, 263, 289, 316, 342, 368, 395, 421, 447, 474, 500, 526, 553, 579, 605, 632, 658, 684,
711, 737, 763, 789, 816, 842, 868, 895, 921, 947, 974, 1000, 976, 951, 927, 902, 878, 854, 829, 805, 780, 756, 732,
707, 683, 659, 634, 610, 585, 561, 537, 512, 488, 463, 439, 415, 390, 366, 341, 317, 293, 268, 244, 220, 195, 171,
146, 122, 98, 73, 49, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif
#if 1 //512 point fft
//三角滤波器中心频率点
const u16 tri_cen[] = {
4, 7, 12, 16, 21, 26, 32, 38, 44, 51, 59, 67, 76, 85, 96, 107, 119, 132, 146, 161, 177, 195, 213, 234
};
//奇数三角滤波器首尾相连的折线
const u16 tri_odd[] = {
0, 0, 0, 0, 333, 667, 1000, 800, 600, 400, 200, 0, 250, 500, 750, 1000, 800, 600, 400, 200, 0, 200, 400, 600, 800, 1000, 833, 667, 500, 333,
167, 0, 167, 333, 500, 667, 833, 1000, 833, 667, 500, 333, 167, 0, 143, 286, 429, 571, 714, 857, 1000, 875, 750, 625, 500, 375, 250, 125, 0,
125, 250, 375, 500, 625, 750, 875, 1000, 889, 778, 667, 556, 444, 333, 222, 111, 0, 111, 222, 333, 444, 556, 667, 778, 889, 1000, 909, 818,
727, 636, 545, 455, 364, 273, 182, 91, 0, 91, 182, 273, 364, 455, 545, 636, 727, 818, 909, 1000, 917, 833, 750, 667, 583, 500, 417, 333, 250,
167, 83, 0, 77, 154, 231, 308, 385, 462, 538, 615, 692, 769, 846, 923, 1000, 929, 857, 786, 714, 643, 571, 500, 429, 357, 286, 214, 143, 71, 0,
67, 133, 200, 267, 333, 400, 467, 533, 600, 667, 733, 800, 867, 933, 1000, 938, 875, 813, 750, 688, 625, 563, 500, 438, 375, 313, 250, 188,
125, 63, 0, 56, 111, 167, 222, 278, 333, 389, 444, 500, 556, 611, 667, 722, 778, 833, 889, 944, 1000, 944, 889, 833, 778, 722, 667, 611, 556,
500, 444, 389, 333, 278, 222, 167, 111, 56, 0, 48, 95, 143, 190, 238, 286, 333, 381, 429, 476, 524, 571, 619, 667, 714, 762, 810, 857, 905, 952,
1000, 955, 909, 864, 818, 773, 727, 682, 636, 591, 545, 500, 455, 409, 364, 318, 273, 227, 182, 136, 91, 45, 0
};
//偶数三角滤波器首尾相连的折线
const u16 tri_even[] = {
250, 500, 750, 1000, 667, 334, 0, 200, 400, 600, 800, 1000, 750, 500, 250, 0, 200, 400, 600, 800, 1000, 800, 600, 400, 200, 0, 167, 333, 500,
667, 833, 1000, 833, 667, 500, 333, 167, 0, 167, 333, 500, 667, 833, 1000, 857, 714, 571, 429, 286, 143, 0, 125, 250, 375, 500, 625, 750, 875,
1000, 875, 750, 625, 500, 375, 250, 125, 0, 111, 222, 333, 444, 556, 667, 778, 889, 1000, 889, 778, 667, 556, 444, 333, 222, 111, 0, 91, 182,
273, 364, 455, 545, 636, 727, 818, 909, 1000, 909, 818, 727, 636, 545, 455, 364, 273, 182, 91, 0, 83, 167, 250, 333, 417, 500, 583, 667, 750,
833, 917, 1000, 923, 846, 769, 692, 615, 538, 462, 385, 308, 231, 154, 77, 0, 71, 143, 214, 286, 357, 429, 500, 571, 643, 714, 786, 857, 929,
1000, 933, 867, 800, 733, 667, 600, 533, 467, 400, 333, 267, 200, 133, 67, 0, 63, 125, 188, 250, 313, 375, 438, 500, 563, 625, 688, 750, 813,
875, 938, 1000, 944, 889, 833, 778, 722, 667, 611, 556, 500, 444, 389, 333, 278, 222, 167, 111, 56, 0, 56, 111, 167, 222, 278, 333, 389, 444,
500, 556, 611, 667, 722, 778, 833, 889, 944, 1000, 952, 905, 857, 810, 762, 714, 667, 619, 571, 524, 476, 429, 381, 333, 286, 238, 190, 143,
95, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif
// 反离散余弦变换 余弦表 24*12
const s8 dct_arg[] = {
100, 98, 95, 90, 83, 75, 66, 56, 44, 32, 20, 7, -7, -20, -32, -44, -56, -66, -75, -83, -90, -95, -98, -100,
99, 92, 79, 61, 38, 13, -13, -38, -61, -79, -92, -99, -99, -92, -79, -61, -38, -13, 13, 38, 61, 79, 92, 99,
98, 83, 56, 20, -20, -56, -83, -98, -98, -83, -56, -20, 20, 56, 83, 98, 98, 83, 56, 20, -20, -56, -83, -98,
97, 71, 26, -26, -71, -97, -97, -71, -26, 26, 71, 97, 97, 71, 26, -26, -71, -97, -97, -71, -26, 26, 71, 97,
95, 56, -7, -66, -98, -90, -44, 20, 75, 100, 83, 32, -32, -83, -100, -75, -20, 44, 90, 98, 66, 7, -56, -95,
92, 38, -38, -92, -92, -38, 38, 92, 92, 38, -38, -92, -92, -38, 38, 92, 92, 38, -38, -92, -92, -38, 38, 92,
90, 20, -66, -100, -56, 32, 95, 83, 7, -75, -98, -44, 44, 98, 75, -7, -83, -95, -32, 56, 100, 66, -20, -90,
87, 0, -87, -87, 0, 87, 87, 0, -87, -87, 0, 87, 87, 0, -87, -87, 0, 87, 87, 0, -87, -87, 0, 87,
83, -20, -98, -56, 56, 98, 20, -83, -83, 20, 98, 56, -56, -98, -20, 83, 83, -20, -98, -56, 56, 98, 20, -83,
79, -38, -99, -13, 92, 61, -61, -92, 13, 99, 38, -79, -79, 38, 99, 13, -92, -61, 61, 92, -13, -99, -38, 79,
75, -56, -90, 32, 98, -7, -100, -20, 95, 44, -83, -66, 66, 83, -44, -95, 20, 100, 7, -98, -32, 90, 56, -75,
71, -71, -71, 71, 71, -71, -71, 71, 71, -71, -71, 71, 71, -71, -71, 71, 71, -71, -71, 71, 71, -71, -71, 71,
};
#endif

View File

@@ -0,0 +1,333 @@
/******** VAD.C *******/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "g_def.h"
#include "ADC.h"
#include "VAD.h"
#define n_thl_ratio 1 //噪声门限系数 n_thl=n_max_mean*n_thl_ratio
#define s_thl_ratio(x) (x*30/10) //短时幅度判决门限系数 s_thl=sum_mean*s_thl_ratio
#define z_thl_ratio(x) (x*2/160) //短时过零率 判决门限系数 常数
#define atap_frm_t 30 //背景噪音自适应时间帧长度 ms
#define atap_frm_len ((fs/1000)*atap_frm_t) //背景噪音自适应帧长度
u16 vad_data[VcBuf_Len];
u32 frm_n;
/* 求取自适应参数
* noise :噪声起始点
n_len :噪声长度
atap ;自适应参数
*/
void noise_atap(const u16 *noise, u16 n_len, atap_tag *atap)
{
u32 h, i;
u32 n_max;
u32 max_sum;//每一帧噪声最大值 累加取平均 求噪声阈值
u32 n_sum; //所有数值之和 求平均值 确定零(中)值
u32 mid; //中值
u32 abs; //绝对值
u32 abs_sum;//绝对值和
u32 frm_num;
if ((n_len%atap_frm_len) != 0) //参数检查
return;
frm_num = n_len/atap_frm_len;
n_sum = 0;
max_sum = 0;
for (i = 0; i < n_len; i++)
n_sum += *(noise+i);
mid = n_sum/i;
abs_sum = 0;
for (i = 0; i < n_len; i += atap_frm_len) {
n_max = 0;
for (h = 0; h < atap_frm_len; h++) {
abs = (*(noise+i+h) > mid)?(*(noise+i+h)-mid):(mid-*(noise+i+h));
if (abs > n_max) ////取每帧最大绝对值
n_max = abs;
abs_sum += abs;
}
max_sum += n_max;
//USART1_printf("n_max=%d ", n_max);
//USART1_printf("max_sum=%d\r\n", max_sum);
}
abs_sum /= (n_len/FRAME_LEN);
max_sum /= frm_num;
atap->mid_val = mid;
atap->n_thl = max_sum*n_thl_ratio;
atap->s_thl = s_thl_ratio(abs_sum);
atap->z_thl = z_thl_ratio(FRAME_LEN)/n_thl_ratio;
printf("VAD sum=%d ", atap->s_thl);
printf("VAD zero=%d\n", atap->z_thl);
}
#define v_durmin_t 200 //有效语音最短时间门限 ms
#define v_durmin_f v_durmin_t/(frame_time-frame_mov_t) //有效语音最短帧数
#define s_durmax_t 210 //无声段最长时间门限 ms
#define s_durmax_f s_durmax_t/(frame_time-frame_mov_t)//无声段最长帧数
/*******
* VAD (Voice activity detection) 语音活动检测
检测出一段声音中的有效语音 起始点和长度 最多3段语音
短时幅度 短时过零率求取:
短时幅度直接累加
短时过零率改进为过门限率,设置正负两个绝对值相等的门限。
构成门限带,穿过门限带计作过零
端点判决:
1.判断语音起始点,要求能够滤除突发性噪声
突发性噪声可以引起短时能量或过零率的数值很高,但是往往不能维持足够长的时间,
如门窗的开关,物体的碰撞等引起的噪声,这些都可以通过设定最短时间门限来判别。
超过两门限之一或全部,并且持续时间超过有效语音最短时间门限,
返回最开始超过门限的时间点,将其标记为有效语音起始点。
2.判断语音结束点,要求不能丢弃连词中间短暂的有可能被噪声淹没的“寂静段”
同时低于两门限,并且持续时间超过无声最长时间门限,
返回最开始低于门限的时间点,将其标记为有效语音结束点。
*********/
void VAD(const u16 *vc, u16 buf_len, valid_tag *valid_voice, atap_tag *atap_arg)
{
u8 last_sig = 0; // 上次跃出门限带的状态 1:门限带以下2:门限带以上
u8 cur_stus = 0; // 当前语音段状态 0无声段 1前端过渡段 2语音段 3后端过渡段
u16 front_duration = 0;//前端过渡段超过门限值持续帧数
u16 back_duration = 0;//后端过渡段低于门限值持续帧数
u32 h, i;
u32 frm_sum; // 短时绝对值和
u32 frm_zero; // 短时过零(门限)率
u32 a_thl; // 上门限值
u32 b_thl; // 下门限值
u8 valid_con = 0;//语音段计数 最大max_vc_con
u32 frm_con = 0; //帧计数
a_thl = atap_arg->mid_val+atap_arg->n_thl;
b_thl = atap_arg->mid_val-atap_arg->n_thl;
for (i = 0; i < max_vc_con; i++) {
((valid_tag *)(valid_voice+i))->start = (void *)0;
((valid_tag *)(valid_voice+i))->end = (void *)0;
}
for (i = 0; i < (buf_len-FRAME_LEN); i += (FRAME_LEN-frame_mov)) {
frm_con++;
frm_sum = 0;
for (h = 0; h < FRAME_LEN; h++)//短时绝对值和
frm_sum += (*(vc+i+h) > (atap_arg->mid_val))?(*(vc+i+h)-(atap_arg->mid_val)):((atap_arg->mid_val)-*(vc+i+h));
frm_zero = 0;
for (h = 0; h < (FRAME_LEN-1); h++) {//短时过门限率
if (*(vc+i+h) >= a_thl) //大于上门限值
last_sig = 2;
else if (*(vc+i+h) < b_thl) //小于下门限值
last_sig = 1;
if (*(vc+i+h+1) >= a_thl) {
if (last_sig == 1)
frm_zero++;
} else if (*(vc+i+h+1) < b_thl) {
if (last_sig == 2)
frm_zero++;
}
}
//USART1_printf("frm_con=%d ",frm_con);
//USART1_printf("frm_sum=%d ",frm_sum);
//USART1_printf("frm_zero=%d\r\n",frm_zero);
if ((frm_sum > (atap_arg->s_thl)) || (frm_zero > (atap_arg->z_thl))) {
//至少有一个参数超过其门限值
// if(frm_sum>(atap_arg->s_thl))
// printf("frm_sum ok\n");
// else
// printf("frm_zero ok\n");
if (cur_stus == 0) {//如果当前是无声段
cur_stus = 1; //进入前端过渡段
front_duration = 1; //前端过渡段持续帧数置1 第一帧
} else if (cur_stus == 1) {//当前是前端过渡段
front_duration++;
if (front_duration >= v_durmin_f) { //前端过渡段帧数超过最短有效语音帧数
cur_stus = 2; //进入语音段
((valid_tag *)(valid_voice+valid_con))->start = (u16 *)vc+i-((v_durmin_f-1)*(FRAME_LEN-frame_mov));//记录起始帧位置
front_duration = 0; //前端过渡段持续帧数置0
}
} else if (cur_stus == 3) { //如果当前是后端过渡段 两参数都回升到门限值以上
back_duration = 0;
cur_stus = 2; //记为语音段
}
} else {//两参数都在门限值以下
// printf("frm not ok\n");
if (cur_stus == 2) {//当前是语音段
cur_stus = 3;//设为后端过渡段
back_duration = 1; //前端过渡段持续帧数置1 第一帧
} else if (cur_stus == 3) {//当前是后端过渡段
back_duration++;
if (back_duration >= s_durmax_f) { //后端过渡段帧数超过最长无声帧数
cur_stus = 0; //进入无声段
((valid_tag *)(valid_voice+valid_con))->end = (u16 *)vc+i-(s_durmax_f*(FRAME_LEN-frame_mov))+FRAME_LEN;//记录结束帧位置
valid_con++;
if (valid_con == max_vc_con)
return;
back_duration = 0;
}
} else if (cur_stus == 1) {//当前是前端过渡段 两参数都回落到门限值以下
//持续时间低于语音最短时间门限 视为短时噪声
front_duration = 0;
cur_stus = 0; //记为无声段
}
}
}
}
u8 VAD2(const u16 *vc, valid_tag *valid_voice, atap_tag *atap_arg)
{
u8 last_sig = 0; // 上次跃出门限带的状态 1:门限带以下2:门限带以上
static u8 cur_stus; // 当前语音段状态 0无声段 1前端过渡段 2语音段 3后端过渡段
static u16 front_duration;//前端过渡段超过门限值持续帧数
static u16 back_duration;//后端过渡段低于门限值持续帧数
static u8 word_num_tmp;
u32 h, i;
u32 frm_sum; // 短时绝对值和
u32 frm_zero; // 短时过零(门限)率
u32 a_thl; // 上门限值
u32 b_thl; // 下门限值
a_thl = atap_arg->mid_val+atap_arg->n_thl;
b_thl = atap_arg->mid_val-atap_arg->n_thl;
frm_sum = 0;
for (h = 0; h < FRAME_LEN; h++)//短时绝对值和
frm_sum += (*(vc+h) > (atap_arg->mid_val))?(*(vc+h)-(atap_arg->mid_val)):((atap_arg->mid_val)-*(vc+h));
frm_zero = 0;
for (h = 0; h < (FRAME_LEN-1); h++) {//短时过门限率
if (*(vc+h) >= a_thl) //大于上门限值
last_sig = 2;
else if (*(vc+h) < b_thl) //小于下门限值
last_sig = 1;
if (*(vc+h+1) >= a_thl) {
if (last_sig == 1)
frm_zero++;
} else if (*(vc+h+1) < b_thl) {
if (last_sig == 2)
frm_zero++;
}
}
// printf("frm_sum=%d\n",frm_sum);
// printf("frm_zero=%d ",frm_zero);
if (FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n > VcBuf_Len - (FRAME_LEN - frame_mov)) {//over frame length
cur_stus = 0; //进入无声段
frm_n = 0;
printf("I am here\n");
return 0;
}
if ((frm_sum > (atap_arg->s_thl)) || (frm_zero > (atap_arg->z_thl))) {
//至少有一个参数超过其门限值
if (frm_sum > (atap_arg->s_thl))
printf("frm_sum ok\n");
else
printf("frm_zero ok\n");
if (cur_stus == 0) {//如果当前是无声段
cur_stus = 1; //进入前端过渡段
front_duration = 1; //前端过渡段持续帧数置1 第一帧
frm_n = 0;
word_num_tmp = 1;
for (i = 0; i < FRAME_LEN; i++) //copy the valid data
vad_data[i] = vc[i];
} else if (cur_stus == 1) { //当前是前端过渡段
front_duration++;
if (front_duration >= v_durmin_f) {//前端过渡段帧数超过最短有效语音帧数
cur_stus = 2; //进入语音段
front_duration = 0; //前端过渡段持续帧数置0
valid_voice[0].start = (u16 *)vad_data;
}
for (i = 0; i < FRAME_LEN - frame_mov; i++)//copy the valid data
vad_data[FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n + i] = vc[i + frame_mov];
frm_n++;
if (FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n > VcBuf_Len + frame_mov - FRAME_LEN) {
cur_stus = 0; //进入无声段
valid_voice[0].end = (u16 *)vad_data + VcBuf_Len;//记录结束帧位置
// valid_voice[0].word_num = word_num_tmp;
return 1;
}
} else if (cur_stus == 3) { //如果当前是后端过渡段 两参数都回升到门限值以上
if (back_duration > 5)
word_num_tmp++;
// printf("back_duration = %d\n", back_duration);
back_duration = 0;
cur_stus = 2; //记为语音段
for (i = 0; i < FRAME_LEN - frame_mov; i++)//copy the valid data
vad_data[FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n + i] = vc[i + frame_mov];
frm_n++;
if (FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n > VcBuf_Len + frame_mov - FRAME_LEN) {
cur_stus = 0; //进入无声段
valid_voice[0].end = (u16 *)vad_data + VcBuf_Len;//记录结束帧位置
// valid_voice[0].word_num = word_num_tmp;
return 1;
}
} else if (cur_stus == 2) {
for (i = 0; i < FRAME_LEN - frame_mov; i++)//copy the valid data
vad_data[FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n + i] = vc[i + frame_mov];
frm_n++;
if (FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n > VcBuf_Len + frame_mov - FRAME_LEN) {
cur_stus = 0; //进入无声段
valid_voice[0].end = (u16 *)vad_data + VcBuf_Len;//记录结束帧位置
// valid_voice[0].word_num = word_num_tmp;
return 1;
}
}
} else {//两参数都在门限值以下
// printf("frm error\n");
if (cur_stus == 2) {//当前是语音段
cur_stus = 3;//设为后端过渡段
back_duration = 1; //前端过渡段持续帧数置1 第一帧
#if 0
for (i = 0; i < FRAME_LEN - frame_mov; i++)//copy the valid data
vad_data[FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n + i] = vc[i + frame_mov];
frm_n++;
if (FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n > VcBuf_Len + frame_mov - FRAME_LEN) {
cur_stus = 0; //进入无声段
valid_voice[0].end = (u16 *)vad_data + VcBuf_Len;//记录结束帧位置
// valid_voice[0].word_num = word_num_tmp;
return 1;
}
#endif
} else if (cur_stus == 3) {//当前是后端过渡段
back_duration++;
#if 0
for (i = 0; i < FRAME_LEN - frame_mov; i++)//copy the valid data
vad_data[FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n + i] = vc[i + frame_mov];
frm_n++;
if (FRAME_LEN + (FRAME_LEN-frame_mov) * frm_n > VcBuf_Len + frame_mov - FRAME_LEN) {
cur_stus = 0; //进入无声段
valid_voice[0].end = (u16 *)vad_data + VcBuf_Len;//记录结束帧位置
// valid_voice[0].word_num = word_num_tmp;
return 1;
}
#endif
if (back_duration >= s_durmax_f) {//后端过渡段帧数超过最长无声帧数
cur_stus = 0; //进入无声段
back_duration = 0;
frm_n = frm_n - s_durmax_f;
valid_voice[0].end = (u16 *)vad_data+frm_n*(FRAME_LEN-frame_mov)+FRAME_LEN;//记录结束帧位置
// valid_voice[0].word_num = word_num_tmp;
return 1;
}
} else if (cur_stus == 1) {//当前是前端过渡段 两参数都回落到门限值以下
//持续时间低于语音最短时间门限 视为短时噪声
front_duration = 0;
cur_stus = 0; //记为无声段
frm_n = 0;
}
}
return 0;
}

View File

@@ -0,0 +1,42 @@
#ifndef _VAD_H
#define _VAD_H
#include "g_def.h"
#define max_vc_con 3 //VAD最多检测的语音段数
#define frame_time 20 // 每帧时间长度 单位ms
#define frame_mov_t 10 // 帧移
#define FRAME_LEN (frame_time*fs/1000) // 帧长
#define frame_mov (frame_mov_t *fs/1000) // 帧移,相邻帧交叠部分
#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(1)
typedef struct {
u32 mid_val; //语音段中值 相当于有符号的0值 用于短时过零率计算
u16 n_thl; //噪声阈值,用于短时过零率计算
u16 z_thl; //短时过零率阈值,超过此阈值,视为进入过渡段。
u32 s_thl; //短时累加和阈值,超过此阈值,视为进入过渡段。
} atap_tag; //自适应参数
#pragma pack()
//#pragma pack(4)
typedef struct {
u16 *start; //起始点
u16 *end; //结束点
// u8 word_num;
} valid_tag; //有效语音段
//#pragma pack()
void noise_atap(const u16 *noise, u16 n_len, atap_tag *atap);
void VAD(const u16 *vc, u16 buf_len, valid_tag *valid_voice, atap_tag *atap_arg);
u8 VAD2(const u16 *vc, valid_tag *valid_voice, atap_tag *atap_arg);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,105 @@
/* 适用于STM32F103VE
* 全部falsh 512KB 256页 每页2KB
每个语音特征模板占用4KB 采用冗余模板 每个语音指令4个特征模板
初步设计设定20个语音指令 共占用320KB
flash最后320KB用于存储语音特征模板
编译器需设置 以免存储区被代码占用
烧写程序时也不能擦除存储区 选擦除需要的页
*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "g_def.h"
#include "flash.h"
#include "uarths.h"
#include "MFCC.h"
//#include "voice_modle.h"
v_ftr_tag ftr_save[20 * 4];
u8 save_ftr_mdl(v_ftr_tag *ftr, u32 addr)
{
// u32 ftr_size;
addr = addr / size_per_ftr;
if (addr > 40) {
printf("flash addr error");
return Flash_Fail;
}
ftr->save_sign = save_mask;
ftr_save[addr] = *ftr;
// ftr_size=2*mfcc_num*ftr->frm_num;
return Flash_Success;
}
#if 0
void init_voice_mdl(void)
{
uint16_t i, j, comm;
for (comm = 0; comm < 4; comm++) {
for (j = 0; j < 4; j++) {
ftr_save[comm*4+j].save_sign = save_mask;
ftr_save[comm*4+j].frm_num = mdl_fram_num[comm*4+j];
// ftr_save[comm*4+j].word_num = 2;
}
}
//
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[0].mfcc_dat[i] = start1[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[1].mfcc_dat[i] = start2[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[2].mfcc_dat[i] = start3[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[3].mfcc_dat[i] = start4[i];
//
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[4].mfcc_dat[i] = pause1[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[5].mfcc_dat[i] = pause2[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[6].mfcc_dat[i] = pause3[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[7].mfcc_dat[i] = pause4[i];
//
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[8].mfcc_dat[i] = cancle1[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[9].mfcc_dat[i] = cancle2[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[10].mfcc_dat[i] = cancle3[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[11].mfcc_dat[i] = cancle4[i];
//
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[12].mfcc_dat[i] = confirm1[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[13].mfcc_dat[i] = confirm2[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[14].mfcc_dat[i] = confirm3[i];
for (i = 0; i < (vv_frm_max * mfcc_num); i++)
ftr_save[15].mfcc_dat[i] = confirm4[i];
}
#endif

View File

@@ -0,0 +1,39 @@
#ifndef __FLASH_H
#define __FLASH_H
#include "g_def.h"
#include "MFCC.h"
#define FLASH_PAGE_SIZE 2048
#define Flash_Fail 3
#define Flash_Success 0
#define save_mask 12345
#define size_per_ftr (4*1024)
#define page_per_ftr (size_per_ftr/FLASH_PAGE_SIZE)
#define ftr_per_comm 4
#define size_per_comm (ftr_per_comm*size_per_ftr)
#define comm_num 10
#define ftr_total_size (size_per_comm*comm_num)
//#define ftr_end_addr 0x8080000
#define ftr_end_addr (size_per_ftr * ftr_per_comm * comm_num)
#define ftr_start_addr 0 //(ftr_end_addr-ftr_total_size)
#ifdef __cplusplus
extern "C" {
#endif
u8 save_ftr_mdl(v_ftr_tag *ftr, u32 addr);
//void init_voice_mdl(void);
extern v_ftr_tag ftr_save[20 * 4];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,13 @@
#ifndef _G_DEF_H_
#define _G_DEF_H_
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
#endif

View File

@@ -0,0 +1,44 @@
#include <Sipeed_ST7789.h>
#include "touchscreen.h"
SPIClass spi_(SPI0); // MUST be SPI0 for Maix series on board LCD
Sipeed_ST7789 lcd(320, 240, spi_);
TouchScreen touchscreen;
int key = KEY0;
int touchscreen_status = 0;
int touchscreen_x = 0;
int touchscreen_y = 0;
int status_last = TOUCH_NONE;
int x_last = 0;
int y_last = 0;
bool draw = false;
void setup()
{
pinMode(key, INPUT);
lcd.begin(15000000, COLOR_RED);
touchscreen.begin();
touchscreen.calibrate(320, 240);
}
void loop()
{
touchscreen.read();
touchscreen_status = touchscreen.getStatus();
touchscreen_x = touchscreen.getX();
touchscreen_y = touchscreen.getY();
if (draw) {
lcd.writeLine(x_last,y_last,touchscreen_x,touchscreen_y,COLOR_WHITE);
}
if (status_last != touchscreen_status) {
draw = (touchscreen_status == TOUCH_BEGIN || touchscreen_status == TOUCH_MOVE);
status_last = touchscreen_status;
}
x_last = touchscreen_x;
y_last = touchscreen_y;
if (digitalRead(key) == LOW) {
lcd.fillScreen(COLOR_BLACK);
}
}

View File

@@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map For Wire
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
read KEYWORD2
getStatus KEYWORD2
getX KEYWORD2
getY KEYWORD2
calibrate KEYWORD2
is_init KEYWORD2
end KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View File

@@ -0,0 +1,10 @@
name=Touchscreen
version=1.0
author=BigBits
maintainer=BigBits<bigbits@bigbits.com>
sentence=NS2009 Touchscreen driver
paragraph=NS2009 Touchscreen driver
category=Display
url=
architectures=k210
includes=touchscreen.h

View File

@@ -0,0 +1,74 @@
/*
* libc/filter/mean.c
*/
#include <math.h>
#include <stddef.h>
#include <mean.h>
#include "stdlib.h"
#define touchscreen_malloc(p) malloc(p)
#define touchscreen_free(p) free(p)
struct mean_filter_t *mean_alloc(int length)
{
struct mean_filter_t *filter;
int i;
if (length <= 0)
return NULL;
filter = touchscreen_malloc(sizeof(struct mean_filter_t));
if (!filter)
return NULL;
filter->buffer = touchscreen_malloc(sizeof(int) * length);
if (!filter->buffer)
{
touchscreen_free(filter);
return NULL;
}
for (i = 0; i < length; i++)
filter->buffer[i] = 0;
filter->length = length;
filter->index = 0;
filter->count = 0;
filter->sum = 0;
return filter;
}
void mean_free(struct mean_filter_t *filter)
{
if (filter)
{
if (filter->buffer)
touchscreen_free(filter->buffer);
touchscreen_free(filter);
}
}
int mean_update(struct mean_filter_t *filter, int value)
{
filter->sum -= filter->buffer[filter->index];
filter->sum += value;
filter->buffer[filter->index] = value;
filter->index = (filter->index + 1) % filter->length;
if (filter->count < filter->length)
filter->count++;
return filter->sum / filter->count;
}
void mean_clear(struct mean_filter_t *filter)
{
int i;
if (filter)
{
for (i = 0; i < filter->length; i++)
filter->buffer[i] = 0;
filter->index = 0;
filter->count = 0;
filter->sum = 0;
}
}

View File

@@ -0,0 +1,27 @@
#ifndef __MEAN_H__
#define __MEAN_H__
#ifdef __cplusplus
extern "C"
{
#endif
struct mean_filter_t
{
int *buffer;
int length;
int index;
int count;
int sum;
};
struct mean_filter_t *mean_alloc(int length);
void mean_free(struct mean_filter_t *filter);
int mean_update(struct mean_filter_t *filter, int value);
void mean_clear(struct mean_filter_t *filter);
#ifdef __cplusplus
}
#endif
#endif /* __MEAN_H__ */

View File

@@ -0,0 +1,138 @@
/*
* libc/filter/median.c
*/
#include <math.h>
#include <stddef.h>
#include <median.h>
#include "stdlib.h"
#define touchscreen_malloc(p) malloc(p)
#define touchscreen_free(p) free(p)
struct median_filter_t *median_alloc(int length)
{
struct median_filter_t *filter;
if (length <= 0)
return NULL;
filter = touchscreen_malloc(sizeof(struct median_filter_t));
if (!filter)
return NULL;
filter->buffer = touchscreen_malloc(sizeof(int) * length);
filter->index = touchscreen_malloc(sizeof(int) * length);
if (!filter->buffer || !filter->index)
{
if (filter->buffer)
touchscreen_free(filter->buffer);
if (filter->index)
touchscreen_free(filter->index);
touchscreen_free(filter);
return NULL;
}
filter->length = length;
filter->position = 0;
filter->count = 0;
return filter;
}
void median_free(struct median_filter_t *filter)
{
if (filter)
{
if (filter->buffer)
touchscreen_free(filter->buffer);
if (filter->index)
touchscreen_free(filter->index);
touchscreen_free(filter);
}
}
int median_update(struct median_filter_t *filter, int value)
{
int pos = filter->position;
int cnt = filter->count;
int *idx;
int cidx;
int oidx;
int oval;
int result;
if (cnt > 0)
{
if (cnt == filter->length)
{
oidx = 0;
while (filter->index[oidx] != pos)
++oidx;
oval = filter->buffer[pos];
}
else
{
filter->index[pos] = pos;
oidx = pos;
oval = INT_MAX;
}
filter->buffer[pos] = value;
idx = &filter->index[oidx];
if (oval < value)
{
while (++oidx != cnt)
{
cidx = *(++idx);
if (filter->buffer[cidx] < value)
{
*idx = *(idx - 1);
*(idx - 1) = cidx;
}
else
{
break;
}
}
}
else if (oval > value)
{
while (oidx-- != 0)
{
cidx = *(--idx);
if (filter->buffer[cidx] > value)
{
*idx = *(idx + 1);
*(idx + 1) = cidx;
}
else
{
break;
}
}
}
result = filter->buffer[filter->index[cnt / 2]];
}
else
{
filter->buffer[0] = value;
filter->index[0] = 0;
filter->position = 0;
filter->count = 0;
result = value;
}
pos++;
filter->position = (pos == filter->length) ? 0 : pos;
if (cnt < filter->length)
filter->count++;
return result;
}
void median_clear(struct median_filter_t *filter)
{
if (filter)
{
filter->position = 0;
filter->count = 0;
}
}

View File

@@ -0,0 +1,30 @@
#ifndef __MEDIAN_H__
#define __MEDIAN_H__
#ifdef __cplusplus
extern "C"
{
#endif
#define INT_MIN (-1 - 0x7fffffff)
#define INT_MAX 0x7fffffff
struct median_filter_t
{
int *buffer;
int *index;
int length;
int position;
int count;
};
struct median_filter_t *median_alloc(int length);
void median_free(struct median_filter_t *filter);
int median_update(struct median_filter_t *filter, int value);
void median_clear(struct median_filter_t *filter);
#ifdef __cplusplus
}
#endif
#endif /* __MEDIAN_H__ */

View File

@@ -0,0 +1,174 @@
#include "ns2009.h"
#include <string.h>
#include <stdlib.h>
#include <tsfilter.h>
#include <stdio.h>
#include "fpioa.h"
#include "sleep.h"
#include <math.h>
#include "stdlib.h"
#define touchscreen_malloc(p) malloc(p)
#define touchscreen_free(p) free(p)
static uint8_t ns2009_read(uint8_t cmd, int *val)
{
uint8_t ret, buf[2];
ret = ns2009_hal_i2c_recv(&cmd, 1, buf, 2);
if (ret != 0)
return 0;
if (val)
*val = (buf[0] << 4) | (buf[1] >> 4);
return 1;
}
static void push_event_begin(struct ts_ns2009_event_t *ts_event, int x, int y)
{
ts_event->type = TOUCH_BEGIN;
ts_event->x = x;
ts_event->y = y;
}
static void push_event_move(struct ts_ns2009_event_t *ts_event, int x, int y)
{
ts_event->type = TOUCH_MOVE;
ts_event->x = x;
ts_event->y = y;
}
static void push_event_end(struct ts_ns2009_event_t *ts_event, int x, int y)
{
ts_event->type = TOUCH_END;
ts_event->x = x;
ts_event->y = y;
}
static void push_event_none(struct ts_ns2009_event_t *ts_event)
{
ts_event->type = TOUCH_NONE;
ts_event->x = 0;
ts_event->y = 0;
}
int ts_ns2009_poll(struct ts_ns2009_pdata_t *ts_ns2009_pdata)
{
int x = 0, y = 0, z1 = 0;
if (ns2009_read(NS2009_LOW_POWER_READ_Z1, &z1))
{
if ((z1 > 70) && (z1 < 2000))
{
ns2009_read(NS2009_LOW_POWER_READ_X, &x);
ns2009_read(NS2009_LOW_POWER_READ_Y, &y);
tsfilter_update(ts_ns2009_pdata->filter, &x, &y);
if (!ts_ns2009_pdata->press)
{
push_event_begin(ts_ns2009_pdata->event, x, y);
ts_ns2009_pdata->press = 1;
}
else
{
if ((ts_ns2009_pdata->x != x) || (ts_ns2009_pdata->y != y))
{
push_event_move(ts_ns2009_pdata->event, x, y);
}
}
ts_ns2009_pdata->x = x;
ts_ns2009_pdata->y = y;
}
else
{
if (ts_ns2009_pdata->press)
{
tsfilter_clear(ts_ns2009_pdata->filter);
push_event_end(ts_ns2009_pdata->event, ts_ns2009_pdata->x, ts_ns2009_pdata->y);
ts_ns2009_pdata->press = 0;
}
}
}
else
{
push_event_none(ts_ns2009_pdata->event);
}
return 1;
}
int ts_ns2009_set_calibration(struct ts_ns2009_pdata_t *ts_ns2009_pdata, int cmd, void *arg)
{
int cal[7];
if (cmd == NS2009_IOCTL_SET_CALBRATION)
{
if (!arg)
return -1;
memcpy(cal, arg, sizeof(int) * 7);
tsfilter_setcal(ts_ns2009_pdata->filter, cal);
return 0;
}
return -1;
}
// "ts-ns2009@0" : {
// "i2c-bus" : "i2c-v3s.0",
// "slave-address" : 72,
// "median-filter-length" : 5,
// "mean-filter-length" : 5,
// "calibration" : [ 14052, 21, -2411064, -67, 8461, -1219628, 65536 ],
// "poll-interval-ms" : 10
// },
//[-4278, -68, 16701858, -8, -5930, 21990146, 65536]
//{65, 5853, -1083592, -4292, -15, 16450115, 65536};
struct ts_ns2009_pdata_t *ts_ns2009_probe(int* cal, int* err)
{
struct ts_ns2009_pdata_t *ts_ns2009_pdata;
*err = 0;
if (!ns2009_read(NS2009_LOW_POWER_READ_Z1, NULL))
{
*err = 5; // EIO
return NULL;
}
ts_ns2009_pdata = touchscreen_malloc(sizeof(struct ts_ns2009_pdata_t));
if (!ts_ns2009_pdata)
{
*err = 12; //ENOMEM
return NULL;
}
ts_ns2009_pdata->filter = tsfilter_alloc(5, 5);
tsfilter_setcal(ts_ns2009_pdata->filter, cal);
//
ts_ns2009_pdata->x = 0;
ts_ns2009_pdata->y = 0;
ts_ns2009_pdata->press = 0;
//
ts_ns2009_pdata->event = touchscreen_malloc(sizeof(struct ts_ns2009_event_t));
ts_ns2009_pdata->event->x = 0;
ts_ns2009_pdata->event->y = 0;
ts_ns2009_pdata->event->type = TOUCH_NONE;
return ts_ns2009_pdata;
}
void ts_ns2009_remove(struct ts_ns2009_pdata_t *ts_ns2009_pdata)
{
if (ts_ns2009_pdata->filter)
{
tsfilter_free(ts_ns2009_pdata->filter);
ts_ns2009_pdata->filter = NULL;
}
if (ts_ns2009_pdata->event)
{
touchscreen_free(ts_ns2009_pdata->event);
ts_ns2009_pdata->filter = NULL;
}
if (ts_ns2009_pdata)
{
touchscreen_free(ts_ns2009_pdata);
ts_ns2009_pdata->filter = NULL;
}
}

View File

@@ -0,0 +1,56 @@
#ifndef __NS2009_H
#define __NS2009_H
#include <stdio.h>
/* clang-format off */
#define NS2009_SLV_ADDR 0x48
#define NS2009_IOCTL_SET_CALBRATION 0x1
/* clang-format on */
#ifdef __cplusplus
extern "C"{
#endif // __cplusplus
enum
{
NS2009_LOW_POWER_READ_X = 0xc0,
NS2009_LOW_POWER_READ_Y = 0xd0,
NS2009_LOW_POWER_READ_Z1 = 0xe0,
NS2009_LOW_POWER_READ_Z2 = 0xf0,
};
enum event_type
{
TOUCH_NONE = 0,
TOUCH_BEGIN,
TOUCH_MOVE,
TOUCH_END
};
struct ts_ns2009_event_t
{
enum event_type type;
int x, y;
} __attribute__((aligned(8)));
struct ts_ns2009_pdata_t
{
struct tsfilter_t *filter;
struct ts_ns2009_event_t *event;
int x, y;
int press;
} __attribute__((aligned(8)));
int ts_ns2009_poll(struct ts_ns2009_pdata_t *ts_ns2009_pdata);
int ts_ns2009_set_calibration(struct ts_ns2009_pdata_t *ts_ns2009_pdata, int cmd, void *arg);
struct ts_ns2009_pdata_t *ts_ns2009_probe(int* cal, int* err);
void ts_ns2009_remove(struct ts_ns2009_pdata_t *ts_ns2009_pdata);
int ns2009_hal_i2c_recv(const uint8_t *send_buf, size_t send_buf_len, uint8_t *receive_buf,
size_t receive_buf_len);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif

View File

@@ -0,0 +1,117 @@
#include "touchscreen.h"
#include "Wire.h"
extern "C"
{
#include "tscal.h"
}
TouchScreen::TouchScreen()
{
}
TouchScreen::~TouchScreen()
{
}
int
TouchScreen::begin()
{
int err;
Wire.begin();
ts_ns2009_pdata = ts_ns2009_probe(calibration, &err); //calibration
if (ts_ns2009_pdata == NULL || err!=0)
return err;
_is_init = true;
return 0;
}
bool
TouchScreen::is_init()
{
return _is_init;
}
int
TouchScreen::read()
{
ts_ns2009_poll(ts_ns2009_pdata);
_x = 0;
_y = 0;
switch (ts_ns2009_pdata->event->type)
{
case TOUCH_BEGIN:
_x = ts_ns2009_pdata->event->x;
_y = ts_ns2009_pdata->event->y;
_status = TOUCHSCREEN_STATUS_PRESS;
break;
case TOUCH_MOVE:
_x = ts_ns2009_pdata->event->x;
_y = ts_ns2009_pdata->event->y;
_status = TOUCHSCREEN_STATUS_MOVE;
break;
case TOUCH_END:
_x= ts_ns2009_pdata->event->x;
_y= ts_ns2009_pdata->event->y;
_status = TOUCHSCREEN_STATUS_RELEASE;
break;
default:
break;
}
return 0;
}
int
TouchScreen::getStatus()
{
return _status;
}
int
TouchScreen::getX()
{
return _x;
}
int
TouchScreen::getY()
{
return _y;
}
int
TouchScreen::end()
{
ts_ns2009_remove(ts_ns2009_pdata);
_is_init = false;
return 0;
}
int
TouchScreen::calibrate(int w, int h)
{
return do_tscal(ts_ns2009_pdata, w, h, calibration);
}
//////////////HAL//////////////
int ns2009_hal_i2c_recv(const uint8_t *send_buf, size_t send_buf_len, uint8_t *receive_buf,
size_t receive_buf_len)
{
Wire.beginTransmission(NS2009_SLV_ADDR);
Wire.write(send_buf,send_buf_len);
Wire.endTransmission();
Wire.requestFrom(NS2009_SLV_ADDR,receive_buf_len);
while(Wire.available()){
*receive_buf++ = Wire.read();
}
return 0;
}

View File

@@ -0,0 +1,64 @@
#ifndef __TOUCHSCREEN_H_
#define __TOUCHSCREEN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "stdbool.h"
typedef enum{
TOUCHSCREEN_STATUS_IDLE =0,
TOUCHSCREEN_STATUS_RELEASE,
TOUCHSCREEN_STATUS_PRESS,
TOUCHSCREEN_STATUS_MOVE
} touchscreen_type_t;
#ifdef __cplusplus
}//extern "C"
#endif
#include "Wire.h"
#include "ns2009.h"
#define CALIBRATION_SIZE 7
#ifdef __cplusplus
class TouchScreen{
public :
TouchScreen();
~TouchScreen();
int begin();
int read();
int getStatus();
int getX();
int getY();
int calibrate(int w = 320, int h = 240);
bool is_init();
int end();
private:
int calibration[CALIBRATION_SIZE] = {
-6,
-5941,
22203576,
4232,
-8,
-700369,
65536
};
bool _is_init = false ;
ts_ns2009_pdata_t *ts_ns2009_pdata;
int _status = TOUCHSCREEN_STATUS_IDLE;
int _x = 0;
int _y = 0;
};
#endif
#include "stdlib.h"
#define touchscreen_malloc(p) malloc(p)
#define touchscreen_free(p) free(p)
#endif

View File

@@ -0,0 +1,235 @@
#include "ns2009.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "lcd.h"
#include "tscal.h"
#include "sleep.h"
static int perform_calibration(struct tscal_t *cal)
{
float n, x, y, x2, y2, xy, z, zx, zy;
float det, a, b, c, e, f, i;
float scaling = 65536.0;
int j;
n = x = y = x2 = y2 = xy = 0;
for (j = 0; j < 5; j++)
{
n += 1.0;
x += (float)cal->x[j];
y += (float)cal->y[j];
x2 += (float)(cal->x[j] * cal->x[j]);
y2 += (float)(cal->y[j] * cal->y[j]);
xy += (float)(cal->x[j] * cal->y[j]);
}
det = n * (x2 * y2 - xy * xy) + x * (xy * y - x * y2) + y * (x * xy - y * x2);
if (det < 0.1 && det > -0.1)
return 0;
a = (x2 * y2 - xy * xy) / det;
b = (xy * y - x * y2) / det;
c = (x * xy - y * x2) / det;
e = (n * y2 - y * y) / det;
f = (x * y - n * xy) / det;
i = (n * x2 - x * x) / det;
z = zx = zy = 0;
for (j = 0; j < 5; j++)
{
z += (float)cal->xfb[j];
zx += (float)(cal->xfb[j] * cal->x[j]);
zy += (float)(cal->xfb[j] * cal->y[j]);
}
cal->a[0] = (int)((b * z + e * zx + f * zy) * (scaling));
cal->a[1] = (int)((c * z + f * zx + i * zy) * (scaling));
cal->a[2] = (int)((a * z + b * zx + c * zy) * (scaling));
z = zx = zy = 0;
for (j = 0; j < 5; j++)
{
z += (float)cal->yfb[j];
zx += (float)(cal->yfb[j] * cal->x[j]);
zy += (float)(cal->yfb[j] * cal->y[j]);
}
cal->a[3] = (int)((b * z + e * zx + f * zy) * (scaling));
cal->a[4] = (int)((c * z + f * zx + i * zy) * (scaling));
cal->a[5] = (int)((a * z + b * zx + c * zy) * (scaling));
cal->a[6] = (int)scaling;
return 1;
}
//画线
//x1,y1:起点坐标
//x2,y2:终点坐标
void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
uint16_t t;
int xerr = 0, yerr = 0, delta_x, delta_y, distance;
int incx, incy, uRow, uCol;
delta_x = x2 - x1; //计算坐标增量
delta_y = y2 - y1;
uRow = x1;
uCol = y1;
if (delta_x > 0)
incx = 1; //设置单步方向
else if (delta_x == 0)
incx = 0; //垂直线
else
{
incx = -1;
delta_x = -delta_x;
}
if (delta_y > 0)
incy = 1;
else if (delta_y == 0)
incy = 0; //水平线
else
{
incy = -1;
delta_y = -delta_y;
}
if (delta_x > delta_y)
distance = delta_x; //选取基本增量坐标轴
else
distance = delta_y;
for (t = 0; t <= distance + 1; t++) //画线输出
{
lcd_draw_point(uRow, uCol, color); //画点
xerr += delta_x;
yerr += delta_y;
if (xerr > distance)
{
xerr -= distance;
uRow += incx;
}
if (yerr > distance)
{
yerr -= distance;
uCol += incy;
}
}
}
//在指定位置画一个指定大小的圆
//(x,y):中心点
//r :半径
void lcd_draw_circle(uint16_t x0, uint16_t y0, uint8_t r, uint16_t color)
{
int a, b;
int di;
a = 0;
b = r;
di = 3 - (r << 1); //判断下个点位置的标志
while (a <= b)
{
lcd_draw_point(x0 + a, y0 - b, color); //5
lcd_draw_point(x0 + b, y0 - a, color); //0
lcd_draw_point(x0 + b, y0 + a, color); //4
lcd_draw_point(x0 + a, y0 + b, color); //6
lcd_draw_point(x0 - a, y0 + b, color); //1
lcd_draw_point(x0 - b, y0 + a, color);
lcd_draw_point(x0 - a, y0 - b, color); //2
lcd_draw_point(x0 - b, y0 - a, color); //7
a++;
//使用Bresenham算法画圆
if (di < 0)
di += 4 * a + 6;
else
{
di += 10 + 4 * (a - b);
b--;
}
}
}
static void lcd_draw_cross(int x, int y, uint16_t color)
{
lcd_draw_line(x - 12, y, x + 13, y, color); //横线
lcd_draw_line(x, y - 12, x, y + 13, color); //竖线
lcd_draw_point(x + 1, y + 1, color);
lcd_draw_point(x - 1, y + 1, color);
lcd_draw_point(x + 1, y - 1, color);
lcd_draw_point(x - 1, y - 1, color);
lcd_draw_circle(x, y, 6, color); //画中心圈
}
static void cairo_draw_string(int x, int y, const char *title)
{
lcd_draw_string(x, y, title, WHITE);
}
int do_tscal(struct ts_ns2009_pdata_t *ts_ns2009_pdata, int width, int height, int* c)
{
struct tscal_t cal;
lcd_ctl_t lcd_ctl;
// char buffer[256];
int index;
c[0] = 1;
c[1] = 0;
c[2] = 0;
c[3] = 0;
c[4] = 1;
c[5] = 0;
c[6] = 1;
ts_ns2009_set_calibration(ts_ns2009_pdata, NS2009_IOCTL_SET_CALBRATION, c);
cal.xfb[0] = 50;
cal.yfb[0] = 50;
cal.xfb[1] = width - 50;
cal.yfb[1] = 50;
cal.xfb[2] = width - 50;
cal.yfb[2] = height - 50;
cal.xfb[3] = 50;
cal.yfb[3] = height - 50;
cal.xfb[4] = width / 2;
cal.yfb[4] = height / 2;
index = 0;
lcd_clear(BLACK);
lcd_draw_cross(cal.xfb[index], cal.yfb[index], RED);
while (1)
{
ts_ns2009_poll(ts_ns2009_pdata);
if (ts_ns2009_pdata->event->type == TOUCH_END)
{
cal.x[index] = ts_ns2009_pdata->event->x;
cal.y[index] = ts_ns2009_pdata->event->y;
if (++index >= 5)
{
if (perform_calibration(&cal))
{
ts_ns2009_set_calibration(ts_ns2009_pdata, NS2009_IOCTL_SET_CALBRATION, &cal.a[0]);
// sprintf(buffer, "[%d,%d,%d,%d,%d,%d,%d]", cal.a[0], cal.a[1], cal.a[2], cal.a[3], cal.a[4], cal.a[5], cal.a[6]);
}
else
{
// sprintf(buffer, "%s", "calibration failed");
}
lcd_clear(BLACK);
// cairo_draw_string(0, height / 2, buffer);
memcpy(c, cal.a, 7*sizeof(int));
ts_ns2009_pdata->event->type = TOUCH_NONE;
break;
}
lcd_clear(BLACK);
lcd_draw_cross(cal.xfb[index], cal.yfb[index], RED);
}
ts_ns2009_pdata->event->type = TOUCH_NONE;
}
return 0;
}

View File

@@ -0,0 +1,15 @@
#ifndef __TSCAL_H
#define __TSCAL_H
#include <stdio.h>
struct tscal_t
{
int x[5], xfb[5];
int y[5], yfb[5];
int a[7];
};
int do_tscal(struct ts_ns2009_pdata_t *ts_ns2009_pdata, int w, int h, int* cal_ret);
#endif

View File

@@ -0,0 +1,98 @@
#include <stddef.h>
#include <tsfilter.h>
#include "stdlib.h"
#define touchscreen_malloc(p) malloc(p)
#define touchscreen_free(p) free(p)
struct tsfilter_t *tsfilter_alloc(int ml, int nl)
{
struct tsfilter_t *filter;
if (ml <= 0 || nl <= 0)
return NULL;
filter = touchscreen_malloc(sizeof(struct tsfilter_t));
if (!filter)
return NULL;
filter->mx = median_alloc(ml);
filter->my = median_alloc(ml);
filter->nx = mean_alloc(nl);
filter->ny = mean_alloc(nl);
filter->cal[0] = 1;
filter->cal[1] = 0;
filter->cal[2] = 0;
filter->cal[3] = 0;
filter->cal[4] = 1;
filter->cal[5] = 0;
filter->cal[6] = 1;
if (!filter->mx || !filter->my || !filter->nx || !filter->ny)
{
if (filter->mx)
median_free(filter->mx);
if (filter->my)
median_free(filter->my);
if (filter->nx)
mean_free(filter->nx);
if (filter->ny)
mean_free(filter->ny);
}
return filter;
}
void tsfilter_free(struct tsfilter_t *filter)
{
if (filter)
{
if (filter->mx)
median_free(filter->mx);
if (filter->my)
median_free(filter->my);
if (filter->nx)
mean_free(filter->nx);
if (filter->ny)
mean_free(filter->ny);
touchscreen_free(filter);
}
}
void tsfilter_setcal(struct tsfilter_t *filter, int *cal)
{
if (filter)
{
filter->cal[0] = cal[0];
filter->cal[1] = cal[1];
filter->cal[2] = cal[2];
filter->cal[3] = cal[3];
filter->cal[4] = cal[4];
filter->cal[5] = cal[5];
filter->cal[6] = cal[6];
}
}
void tsfilter_update(struct tsfilter_t *filter, int *x, int *y)
{
int tx, ty;
tx = median_update(filter->mx, *x);
ty = median_update(filter->my, *y);
tx = mean_update(filter->nx, tx);
ty = mean_update(filter->ny, ty);
*x = (filter->cal[2] + filter->cal[0] * tx + filter->cal[1] * ty) / filter->cal[6];
*y = (filter->cal[5] + filter->cal[3] * tx + filter->cal[4] * ty) / filter->cal[6];
}
void tsfilter_clear(struct tsfilter_t *filter)
{
if (filter)
{
if (filter->mx)
median_clear(filter->mx);
if (filter->my)
median_clear(filter->my);
if (filter->nx)
mean_clear(filter->nx);
if (filter->ny)
mean_clear(filter->ny);
}
}

View File

@@ -0,0 +1,29 @@
#ifndef __TSFILTER_H__
#define __TSFILTER_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <median.h>
#include <mean.h>
struct tsfilter_t
{
struct median_filter_t *mx, *my;
struct mean_filter_t *nx, *ny;
int cal[7];
} __attribute__((aligned(8)));
struct tsfilter_t *tsfilter_alloc(int ml, int nl);
void tsfilter_free(struct tsfilter_t *filter);
void tsfilter_setcal(struct tsfilter_t *filter, int *cal);
void tsfilter_update(struct tsfilter_t *filter, int *x, int *y);
void tsfilter_clear(struct tsfilter_t *filter);
#ifdef __cplusplus
}
#endif
#endif /* __TSFILTER_H__ */

View File

@@ -1,4 +1,4 @@
name=SD(k210)
name=SD
version=1.2.4
author=Arduino, SparkFun, Neucrack
maintainer=Sipeed <support@sipeed.com>

View File

@@ -20,6 +20,9 @@
#define USE_SPI_LIB
#include <Arduino.h>
#include "Sd2Card.h"
#include "fpioa.h"
#include "gpio.h"
#include "wiring_digital.h"
//------------------------------------------------------------------------------
#ifndef SOFTWARE_SPI
#ifdef USE_SPI_LIB
@@ -251,6 +254,7 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
// set pin modes
pinMode(chipSelectPin_, OUTPUT);
digitalWrite(chipSelectPin_, HIGH);
#ifndef USE_SPI_LIB
pinMode(SPI_MISO_PIN, INPUT);
pinMode(SPI_MOSI_PIN, OUTPUT);

View File

@@ -0,0 +1,26 @@
#include <Sipeed_GC0328.h>
#include <Sipeed_ST7789.h>
SPIClass spi_(SPI0); // MUST be SPI0 for Maix series on board LCD
Sipeed_ST7789 lcd(320, 240, spi_);
Sipeed_GC0328 camera(FRAMESIZE_QVGA, PIXFORMAT_RGB565, &Wire);
void setup()
{
Serial.begin(115200);
lcd.begin(15000000, COLOR_RED);
if(!camera.begin())
Serial.printf("camera init fail\n");
else
Serial.printf("camera init success\n");
camera.run(true);
}
void loop()
{
uint8_t*img = camera.snapshot();
if(img == nullptr || img==0)
Serial.printf("snap fail\r\n");
else
lcd.drawImage(0, 0, camera.width(), camera.height(), (uint16_t*)img);
}

View File

@@ -0,0 +1,35 @@
#include <Sipeed_GC0328.h>
#include <Sipeed_ST7789.h>
SPIClass spi_(SPI0); // MUST be SPI0 for Maix series on board LCD
Sipeed_ST7789 lcd(320, 240, spi_);
Sipeed_GC0328 camera(FRAMESIZE_QVGA, PIXFORMAT_RGB565, &Wire);
// Use left camera if true, right camera when true
bool leftCamera = true;
void setup()
{
Serial.begin(115200);
lcd.begin(15000000, COLOR_RED);
// Start camera in binocular mode
if(!camera.begin(true))
Serial.printf("camera init fail\n");
else
Serial.printf("camera init success\n");
camera.run(true);
}
void loop()
{
// Switch left/right cameras
camera.shutdown(leftCamera);
leftCamera = !leftCamera;
uint8_t*img = camera.snapshot();
if(img == nullptr || img==0)
Serial.printf("snap fail\r\n");
else
lcd.drawImage(0, 0, camera.width(), camera.height(), (uint16_t*)img);
}

View File

@@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
reset KEYWORD2
setPixFormat KEYWORD2
setFrameSize KEYWORD2
run KEYWORD2
id KEYWORD2
snapshot KEYWORD2
setRotation KEYWORD2
setInvert KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@@ -0,0 +1,9 @@
name=Sipeed_GC0328
version=1.0
author=vamoosebbf
maintainer=vamoosebbf<vamoosebbf@Sipeed.com>
sentence=Camera Sipeed_GC0328 driver
paragraph=Camera Sipeed_GC0328 driver
category=Sensors
url=
architectures=k210

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
#ifndef __SIPEED_GC0328_H
#define __SIPEED_GC0328_H
#include "Camera.h"
#include "Wire.h"
#define GC0328_ID (0x9d)
#define GC0328_ADDR (0x21)
typedef enum {
GAINCEILING_2X,
GAINCEILING_4X,
GAINCEILING_8X,
GAINCEILING_16X,
GAINCEILING_32X,
GAINCEILING_64X,
GAINCEILING_128X,
} gainceiling_t;
typedef enum {
FRAMERATE_2FPS =0x9F,
FRAMERATE_8FPS =0x87,
FRAMERATE_15FPS=0x83,
FRAMERATE_30FPS=0x81,
FRAMERATE_60FPS=0x80,
} framerate_t;
class Sipeed_GC0328 : public Camera{
public:
Sipeed_GC0328(framesize_t frameSize = FRAMESIZE_QVGA, pixformat_t pixFormat = PIXFORMAT_RGB565, TwoWire *i2c = &Wire);
Sipeed_GC0328(uint16_t width, uint16_t height, pixformat_t pixFormat = PIXFORMAT_RGB565, TwoWire *i2c = &Wire);
~Sipeed_GC0328();
virtual bool begin();
bool begin(bool binocular);
virtual void end();
bool reset(bool binocular = false);
void debug(bool enable);
bool setPixFormat(pixformat_t pixFormat);
bool setFrameSize(framesize_t frameSize);
virtual bool run(bool run);
virtual int id();
/**
* @return pixels
* If pixels format is RGB565: return RGB565 pixels with every uint16_t one pixel, e.g. RED: 0xF800
*/
virtual uint8_t* snapshot();
virtual uint16_t* getRGB565(){ return (uint16_t*)_dataBuffer; };
virtual uint8_t* getRGB888(){ return _aiBuffer; };
virtual void setRotation(uint8_t rotation);
virtual void setInvert(bool invert);
virtual void shutdown(bool enable);
void setFlip(bool flip);
private:
uint8_t* _dataBuffer; // put RGB565 data
uint8_t* _aiBuffer; // put RGB888 data
uint8_t _resetPolarity; // reset polarity flag
uint8_t _pwdnPolarity; // PWDN polarity flag
uint8_t _slaveAddr; // camera address
uint8_t _id;
uint32_t _freq;
TwoWire *_i2c; // replace sccb
bool _vflip;
bool _hmirror;
bool _debug;
int dvpInit(uint32_t freq = 14000000);
int dvpInitIrq();
int cambus_scan();
int cambus_read_id(uint8_t addr,uint16_t *manuf_id, uint16_t *device_id);
int cambus_scan_gc0328(void);
int cambus_readb(uint8_t slv_addr, uint8_t reg_addr, uint8_t *reg_data);
int cambus_writeb(uint8_t slv_addr, uint8_t reg_addr, uint8_t reg_data);
int sensor_gc_detect();
int gc0328_reset();
int gc0328_read_reg(uint8_t reg_addr);
int gc0328_write_reg(uint8_t reg_addr, uint8_t reg_data);
int gc0328_set_pixformat(pixformat_t pixformat);
int gc0328_set_framesize(framesize_t framesize);
int gc0328_set_framerate(framerate_t framerate);
int gc0328_set_contrast(int level);
int gc0328_set_brightness(int level);
int gc0328_set_saturation(int level);
int gc0328_set_gainceiling( gainceiling_t gainceiling);
int gc0328_set_quality(int qs);
int gc0328_set_colorbar(int enable);
int gc0328_set_auto_gain(int enable, float gain_db, float gain_db_ceiling);
int gc0328_get_gain_db(float *gain_db);
int gc0328_set_auto_exposure(int enable, int exposure_us);
int gc0328_get_exposure_us(int *exposure_us);
int gc0328_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db);
int gc0328_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db);
int gc0328_set_hmirror(int enable);
int gc0328_set_vflip(int enable);
int sensor_snapshot( );
int reverse_u32pixel(uint32_t* addr,uint32_t length);
};
#endif

View File

@@ -1,6 +1,5 @@
#include <Sipeed_OV2640.h>
#include <Sipeed_ST7789.h>
#include <stdio.h>
SPIClass spi_(SPI0); // MUST be SPI0 for Maix series on board LCD
Sipeed_ST7789 lcd(320, 240, spi_);
@@ -10,11 +9,12 @@ Sipeed_OV2640 camera(FRAMESIZE_QVGA, PIXFORMAT_RGB565);
void setup()
{
Serial.begin(115200);
lcd.begin(15000000, COLOR_RED);
if(!camera.begin())
printf("camera init fail\n");
Serial.printf("camera init fail\n");
else
printf("camera init success\n");
Serial.printf("camera init success\n");
camera.run(true);
}
@@ -22,7 +22,7 @@ void loop()
{
uint8_t*img = camera.snapshot();
if(img == nullptr || img==0)
printf("snap fail\n");
Serial.printf("snap fail\n");
else
lcd.drawImage(0, 0, camera.width(), camera.height(), (uint16_t*)img);
}

View File

@@ -18,7 +18,7 @@ setFrameSize KEYWORD2
run KEYWORD2
id KEYWORD2
snapshot KEYWORD2
setRotaion KEYWORD2
setRotation KEYWORD2
setInvert KEYWORD2
#######################################

View File

@@ -599,7 +599,7 @@ static const uint8_t saturation_regs[NUM_SATURATION_LEVELS + 1][5] = {
Sipeed_OV2640::Sipeed_OV2640( framesize_t frameSize, pixformat_t pixFormat)
:Camera(frameSize, pixFormat),
_dataBuffer(NULL), _aiBuffer(NULL),
_resetPoliraty(ACTIVE_HIGH), _pwdnPoliraty(ACTIVE_HIGH),
_resetPolarity(ACTIVE_HIGH), _pwdnPolarity(ACTIVE_HIGH),
_slaveAddr(0x00),
_id(0)
{
@@ -611,7 +611,7 @@ _id(0)
Sipeed_OV2640::Sipeed_OV2640(uint16_t width, uint16_t height, pixformat_t pixFormat)
:Camera(width, height, pixFormat),
_dataBuffer(NULL), _aiBuffer(NULL),
_resetPoliraty(ACTIVE_HIGH), _pwdnPoliraty(ACTIVE_HIGH),
_resetPolarity(ACTIVE_HIGH), _pwdnPolarity(ACTIVE_HIGH),
_slaveAddr(0x00),
_id(0)
{
@@ -721,21 +721,24 @@ uint8_t* Sipeed_OV2640::snapshot()
return _dataBuffer;
}
void Sipeed_OV2640::setRotaion(uint8_t rotation)
void Sipeed_OV2640::setRotation(uint8_t rotation)
{
//FIXME
}
void Sipeed_OV2640::setInvert(bool invert)
{
//FIXME
ov2640_set_hmirror(!invert);
//ov2640_set_vflip(1);
return;
}
int Sipeed_OV2640::dvpInit(uint32_t freq)
{
// just support RGB565 and YUV442 on k210
// just support RGB565 and YUV422 on k210
configASSERT(_pixFormat==PIXFORMAT_RGB565 || _pixFormat==PIXFORMAT_YUV422);
_freq = freq;
@@ -775,7 +778,7 @@ int Sipeed_OV2640::dvpInit(uint32_t freq)
if(0 == sensor_ov_detect()){//find ov sensor
// printf("find ov sensor\n");
}
else if(0 == sensro_gc_detect()){//find gc0328 sensor
else if(0 == sensor_gc_detect()){//find gc0328 sensor
// printf("find gc3028\n");
}
@@ -874,7 +877,7 @@ int Sipeed_OV2640::sensor_ov_detect()
if (_slaveAddr == 0) {
/* Sensor has been held in reset,
so the reset line is active low */
_resetPoliraty = ACTIVE_LOW;
_resetPolarity = ACTIVE_LOW;
/* Pull the sensor out of the reset state,systick_sleep() */
DCMI_RESET_HIGH();
@@ -883,14 +886,14 @@ int Sipeed_OV2640::sensor_ov_detect()
/* Probe again to set the slave addr */
_slaveAddr = cambus_scan();
if (_slaveAddr == 0) {
_pwdnPoliraty = ACTIVE_LOW;
_pwdnPolarity = ACTIVE_LOW;
DCMI_PWDN_HIGH();
msleep(10);
_slaveAddr = cambus_scan();
if (_slaveAddr == 0) {
_resetPoliraty = ACTIVE_HIGH;
_resetPolarity = ACTIVE_HIGH;
DCMI_RESET_LOW();
msleep(10);
@@ -944,7 +947,7 @@ int Sipeed_OV2640::sensor_ov_detect()
return 0;
}
int Sipeed_OV2640::sensro_gc_detect()
int Sipeed_OV2640::sensor_gc_detect()
{
DCMI_PWDN_HIGH();//enable gc0328 要恢复 normal 工作模式,需将 PWDN pin 接入低电平即可,同时写入初始化寄存器即可
DCMI_RESET_LOW();//reset gc3028
@@ -1485,6 +1488,38 @@ int Sipeed_OV2640::ov2640_set_vflip(int enable)
return ret;
}
int Sipeed_OV2640::ov2640_set_flip(bool horiz, bool vert)
{
uint8_t reg;
int ret = cambus_readb(_slaveAddr, BANK_SEL, &reg);
ret |= cambus_writeb(_slaveAddr, BANK_SEL, reg | BANK_SEL_SENSOR);
ret |= cambus_readb(_slaveAddr, REG04, &reg);
if (horiz) {
reg |= REG04_HFLIP_IMG;
reg |= REG04_HREF_EN;
}
else {
reg &= ~REG04_HFLIP_IMG;
reg &= ~REG04_HREF_EN;
}
if (vert) {
reg |= REG04_VFLIP_IMG;
reg |= REG04_VREF_EN;
}
else {
reg &= ~REG04_VFLIP_IMG;
reg &= ~REG04_VREF_EN;
}
ret |= cambus_writeb(_slaveAddr, REG04, reg);
return ret;
}
int Sipeed_OV2640::reverse_u32pixel(uint32_t* addr,uint32_t length)
{
if(NULL == addr)
@@ -1519,3 +1554,6 @@ int Sipeed_OV2640::sensor_snapshot( )
return 0;
}
int Sipeed_OV2640::flip( bool horiz, bool vert ) {
return ov2640_set_flip(horiz, vert);
}

View File

@@ -54,14 +54,16 @@ public:
virtual uint8_t* snapshot();
virtual uint16_t* getRGB565(){ return (uint16_t*)_dataBuffer; };
virtual uint8_t* getRGB888(){ return _aiBuffer; };
virtual void setRotaion(uint8_t rotation);
virtual void setRotation(uint8_t rotation);
virtual void setInvert(bool invert);
void flip(bool horiz, bool vert);
private:
uint8_t* _dataBuffer; // put RGB565 data
uint8_t* _aiBuffer; // put RGB888 data
uint8_t _resetPoliraty; // reset poliraty flag
uint8_t _pwdnPoliraty; // PWDN poliraty flag
uint8_t _resetPolarity; // reset polarity flag
uint8_t _pwdnPolarity; // PWDN polarity flag
uint8_t _slaveAddr; // camera address
uint8_t _id;
uint32_t _freq;
@@ -80,7 +82,7 @@ private:
int cambus_writew2(uint8_t slv_addr, uint16_t reg_addr, uint16_t reg_data);
int sensor_ov_detect();
int sensro_gc_detect();
int sensor_gc_detect();
int ov2640_reset();
int ov2640_read_reg(uint8_t reg_addr);
@@ -103,6 +105,8 @@ private:
int ov2640_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db);
int ov2640_set_hmirror(int enable);
int ov2640_set_vflip(int enable);
int ov2640_set_flip(bool horiz, bool vert);
int sensor_snapshot( );
int reverse_u32pixel(uint32_t* addr,uint32_t length);

View File

@@ -0,0 +1,26 @@
#include <Arduino.h>
#include <Ticker.h>
// attach a LED to GPIO 21
#define LED_PIN 13
Ticker tickerSetHigh(TIMER1);
Ticker tickerSetLow(TIMER2);
void setPin(int state) {
digitalWrite(LED_PIN, state);
}
void setup() {
pinMode(LED_PIN, OUTPUT);
// every 25 ms, call setPin(0)
tickerSetLow.attach_ms(25, setPin, 0);
// every 26 ms, call setPin(1)
tickerSetHigh.attach_ms(26, setPin, 1);
}
void loop() {
}

View File

@@ -0,0 +1,42 @@
#include <Arduino.h>
#include <Ticker.h>
// attach a LED to pPIO 13
#define LED_PIN 13
Ticker blinker(TIMER0);
Ticker toggler(TIMER1);
Ticker changer(TIMER2);
float blinkerPace = 0.1; //seconds
const float togglePeriod = 5; //seconds
void change() {
blinkerPace = 0.5;
}
void blink() {
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}
void toggle() {
static bool isBlinking = false;
if (isBlinking) {
blinker.detach();
isBlinking = false;
}
else {
blinker.attach(blinkerPace, blink);
isBlinking = true;
}
digitalWrite(LED_PIN, LOW); //make sure LED on on after toggling (pin LOW = led ON)
}
void setup() {
pinMode(LED_PIN, OUTPUT);
toggler.attach(togglePeriod, toggle);
changer.once(30, change);
}
void loop() {
}

View File

@@ -0,0 +1,24 @@
#######################################
# Datatypes (KEYWORD1)
#######################################
Ticker KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
attach KEYWORD2
attach_ms KEYWORD2
attach_us KEYWORD2
once KEYWORD2
once_ms KEYWORD2
once_us KEYWORD2
detach KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
TIMER0 LITERAL1
TIMER1 LITERAL1
TIMER2 LITERAL1

View File

@@ -0,0 +1,9 @@
name=Ticker
version=1.0
author=BigBits
maintainer=BigBits <bigbits@bigbits.cc>
sentence=Allows to call functions with a given interval.
paragraph=Allows to call functions with a given interval.
category=Timing
url=
architectures=k210

View File

@@ -0,0 +1,51 @@
#include "Ticker.h"
#include "sysctl.h"
static int timer_callback(void* ctx);
Ticker::Ticker(timer_id_t id)
:timer_id(id)
{
timer_init(timer_device_number_t(timer_id));
}
Ticker::~Ticker()
{
detach();
}
void
Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, size_t arg)
{
user_callback = callback;
_arg = arg;
timer_set_interval(timer_device_number_t(timer_id), TIMER_CHANNEL_0, milliseconds * 1000000);
timer_irq_register(timer_device_number_t(timer_id), TIMER_CHANNEL_0, !repeat, 4, timer_callback, this);
timer_set_enable(timer_device_number_t(timer_id), TIMER_CHANNEL_0, 1);
sysctl_enable_irq();
}
void
Ticker::_attach_us(uint32_t microseconds, bool repeat, callback_with_arg_t callback, size_t arg)
{
user_callback = callback;
_arg = arg;
timer_set_interval(timer_device_number_t(timer_id), TIMER_CHANNEL_0, microseconds * 1000);
timer_irq_register(timer_device_number_t(timer_id), TIMER_CHANNEL_0, !repeat, 4, timer_callback, this);
timer_set_enable(timer_device_number_t(timer_id), TIMER_CHANNEL_0, 1);
sysctl_enable_irq();
}
void
Ticker::detach()
{
timer_irq_unregister(timer_device_number_t(timer_id), TIMER_CHANNEL_0);
timer_set_enable(timer_device_number_t(timer_id), TIMER_CHANNEL_0, 0);
}
static int timer_callback(void* ctx)
{
auto &driver = *reinterpret_cast<Ticker *>(ctx);
driver.user_callback((void *)driver._arg);
return 0;
}

View File

@@ -0,0 +1,118 @@
#ifndef TICKER_H
#define TICKER_H
#include "utils.h"
#include "timer.h"
#include "stdio.h"
#include "stdint.h"
typedef enum{
TIMER0 = 0,
TIMER1,
TIMER2,
TIMER_MAX
}timer_id_t;
class Ticker
{
public:
Ticker(timer_id_t id = TIMER2);
~Ticker();
typedef void (*callback_t)(void);
typedef void (*callback_with_arg_t)(void*);
void attach(float seconds, callback_t callback)
{
_attach_ms(seconds * 1000, true, reinterpret_cast<callback_with_arg_t>(callback), 0);
}
void attach_ms(uint32_t milliseconds, callback_t callback)
{
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), 0);
}
void attach_us(uint32_t microseconds, callback_t callback)
{
_attach_us(microseconds, true, reinterpret_cast<callback_with_arg_t>(callback), 0);
}
template<typename TArg>
void attach(float seconds, void (*callback)(TArg), TArg arg)
{
configASSERT(sizeof(TArg) <= sizeof(size_t));
size_t arg32 = (size_t)arg;
_attach_ms(seconds * 1000, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
template<typename TArg>
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
{
configASSERT(sizeof(TArg) <= sizeof(size_t));
size_t arg32 = (size_t)arg;
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
template<typename TArg>
void attach_us(uint32_t microseconds, void (*callback)(TArg), TArg arg)
{
configASSERT(sizeof(TArg) <= sizeof(size_t));
size_t arg32 = (size_t)arg;
_attach_us(microseconds, true, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
void once(float seconds, callback_t callback)
{
_attach_ms(seconds * 1000, false, reinterpret_cast<callback_with_arg_t>(callback), 0);
}
void once_ms(uint32_t milliseconds, callback_t callback)
{
_attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), 0);
}
void once_us(uint32_t microseconds, callback_t callback)
{
_attach_us(microseconds, false, reinterpret_cast<callback_with_arg_t>(callback), 0);
}
template<typename TArg>
void once(float seconds, void (*callback)(TArg), TArg arg)
{
configASSERT(sizeof(TArg) <= sizeof(size_t));
size_t arg32 = (size_t)(arg);
_attach_ms(seconds * 1000, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
template<typename TArg>
void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
{
configASSERT(sizeof(TArg) <= sizeof(size_t));
size_t arg32 = (size_t)(arg);
_attach_ms(milliseconds, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
template<typename TArg>
void once_us(uint32_t microseconds, void (*callback)(TArg), TArg arg)
{
configASSERT(sizeof(TArg) <= sizeof(size_t));
size_t arg32 = (size_t)(arg);
_attach_us(microseconds, false, reinterpret_cast<callback_with_arg_t>(callback), arg32);
}
void detach();
bool active();
callback_with_arg_t user_callback = NULL;
size_t _arg;
protected:
void _attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, size_t arg);
void _attach_us(uint32_t microseconds, bool repeat, callback_with_arg_t callback, size_t arg);
private:
timer_id_t timer_id;
}__attribute__((packed));
#endif

View File

@@ -9,6 +9,9 @@ static int maix_i2c_slave_irq(void *userdata);
TwoWire::TwoWire(i2c_device_number_t i2c_device)
{
i2c_tx_buff = 0;
i2c_rx_buff = 0;
_i2c_num = i2c_device;
switch(i2c_device)
{
@@ -38,44 +41,27 @@ TwoWire::~TwoWire()
void
TwoWire::begin(uint8_t sda, uint8_t scl, uint32_t frequency)
{
i2c_clk = frequency;
fpioa_set_function(sda, sda_func);
fpioa_set_function(scl, scl_func);
volatile i2c_t *i2c_adapter = i2c[_i2c_num];
uint8_t speed_mode = I2C_CON_SPEED_STANDARD;
//i2c_clk_init
sysctl_clock_enable((sysctl_clock_t)(SYSCTL_CLOCK_I2C0 + _i2c_num));
sysctl_clock_set_threshold((sysctl_threshold_t)(SYSCTL_THRESHOLD_I2C0 + _i2c_num), 3);
uint32_t v_i2c_freq = sysctl_clock_get_freq((sysctl_clock_t)(SYSCTL_CLOCK_I2C0 + _i2c_num));
uint16_t v_period_clk_cnt = floor( (v_i2c_freq*1.0 / i2c_clk / 2) + 0.5 );
if(v_period_clk_cnt <= 6)
v_period_clk_cnt = 6;
if(v_period_clk_cnt >= 65525)//65535-10
v_period_clk_cnt = 65525;
if((i2c_clk>100000) && (i2c_clk<=1000000))
speed_mode = I2C_CON_SPEED_FAST;
else
speed_mode = I2C_CON_SPEED_HIGH;
volatile i2c_t *i2c_adapter = i2c[_i2c_num];
i2c_adapter->enable = 0;
i2c_adapter->con = I2C_CON_MASTER_MODE | I2C_CON_SLAVE_DISABLE | I2C_CON_RESTART_EN |
(address_width == 10 ? I2C_CON_10BITADDR_SLAVE : 0) | I2C_CON_SPEED(speed_mode);
i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(v_period_clk_cnt);
i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(v_period_clk_cnt);
i2c_adapter->intr_mask = 0;
i2c_adapter->dma_cr = 0x3;
i2c_adapter->dma_rdlr = 0;
i2c_adapter->dma_tdlr = 4;
i2c_adapter->enable = I2C_ENABLE_ENABLE;
is_master_mode = true;
delete i2c_tx_buff;
delete i2c_rx_buff;
i2c_tx_buff = new RingBuffer();
i2c_rx_buff = new RingBuffer();
setClock(frequency);
}
void
@@ -83,12 +69,11 @@ TwoWire::begin(uint16_t slave_address, uint8_t sda, uint8_t scl)
{
fpioa_set_function(sda, sda_func);
fpioa_set_function(scl, scl_func);
volatile i2c_t *i2c_adapter = i2c[_i2c_num];
sysctl_clock_enable((sysctl_clock_t)(SYSCTL_CLOCK_I2C0 + _i2c_num));
sysctl_clock_set_threshold((sysctl_threshold_t)(SYSCTL_THRESHOLD_I2C0 + _i2c_num), 3);
volatile i2c_t *i2c_adapter = i2c[_i2c_num];
i2c_adapter->enable = 0;
i2c_adapter->con = I2C_CON_SPEED(1) | I2C_CON_STOP_DET_IFADDRESSED;
i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(37);
@@ -98,17 +83,20 @@ TwoWire::begin(uint16_t slave_address, uint8_t sda, uint8_t scl)
i2c_adapter->tx_tl = I2C_TX_TL_VALUE(0);
i2c_adapter->intr_mask = I2C_INTR_MASK_RX_FULL | I2C_INTR_MASK_START_DET | I2C_INTR_MASK_STOP_DET | I2C_INTR_MASK_RD_REQ;
is_master_mode = false;
plic_set_priority((plic_irq_t)(IRQN_I2C0_INTERRUPT + _i2c_num), 1);
plic_irq_register((plic_irq_t)(IRQN_I2C0_INTERRUPT + _i2c_num), maix_i2c_slave_irq, this);
plic_irq_enable((plic_irq_t)(IRQN_I2C0_INTERRUPT + _i2c_num));
i2c_adapter->enable = I2C_ENABLE_ENABLE;
is_master_mode = false;
delete i2c_tx_buff;
delete i2c_rx_buff;
i2c_tx_buff = new RingBuffer();
i2c_rx_buff = new RingBuffer();
}
i2c_adapter->enable = I2C_ENABLE_ENABLE;
}
void
TwoWire::setTimeOut(uint16_t timeOutMillis)
{
@@ -145,7 +133,6 @@ TwoWire::setClock(uint32_t frequency)
i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(v_period_clk_cnt);
i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(v_period_clk_cnt);
i2c_adapter->enable = I2C_ENABLE_ENABLE;
}
uint32_t
@@ -236,6 +223,9 @@ TwoWire::readTransmission(uint16_t address, uint8_t* receive_buf, size_t receive
void
TwoWire::beginTransmission(uint16_t address)
{
// Clear buffers when new transation/packet starts
flush();
transmitting = 1;
txAddress = address;
}
@@ -263,24 +253,28 @@ TwoWire::endTransmission(bool sendStop) //结束时从rxbuff发送数据
uint8_t
TwoWire::requestFrom(uint16_t address, uint8_t size, bool sendStop) //请求数据存入rxbuff供read读
{
// Clear buffers when new transation/packet starts
flush();
int state,index = 0;
uint8_t rx_data[RING_BUFFER_SIZE];
state = readTransmission(address, rx_data, size, sendStop);
if(0 == state){
while(size)
while(index < size)
{
i2c_rx_buff->store_char(rx_data[index++]);
size--;
}
return size;
}
return state;
return 0;
}
size_t
TwoWire::write(uint8_t data) //写到txbuff
{
if(transmitting) {
if(transmitting && !i2c_tx_buff->isFull()) {
i2c_tx_buff->store_char(data);
return 1;
}
return 0;
}
@@ -288,7 +282,7 @@ TwoWire::write(uint8_t data) //写到txbuff
size_t
TwoWire::write(const uint8_t *data, int quantity)
{
for(size_t i = 0; i < quantity; ++i) {
for(size_t i = 0; i < quantity; i++) {
if(!write(data[i])) {
return i;
}

View File

@@ -24,7 +24,7 @@ public:
TwoWire(i2c_device_number_t i2c_device);
~TwoWire();
void begin(uint8_t sda = SDA, uint8_t scl = SCL, uint32_t frequency = 500000);
void begin(uint8_t sda = SDA, uint8_t scl = SCL, uint32_t frequency = 400000);
void begin(uint16_t slave_address, uint8_t sda = SDA, uint8_t scl = SCL);
void setClock(uint32_t frequency);

6
package.json Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "framework-maixduino",
"description": "Arduino Wiring-based Framework (K210 Core)",
"version": "0.3.11",
"url": "https://github.com/sipeed/Maixduino"
}

View File

@@ -1,9 +1,9 @@
name = Maixduino
version = 0.2.3
name=Maixduino
version=0.3.11
# arch
arch = k210
arch_for_c_cpp = K210
arch=k210
arch_for_c_cpp=K210
# Compile variables
compiler.path={runtime.tools.riscv64-unknown-elf-gcc.path}/bin/
@@ -15,19 +15,18 @@ compiler.objcopy.cmd=riscv64-unknown-elf-objcopy
compiler.elf2hex.cmd=riscv64-unknown-elf-objcopy
compiler.size.cmd=riscv64-unknown-elf-size
compiler.clib.path={runtime.tools.riscv64-unknown-elf-gcc.path}/include
compiler.sdk.path={runtime.platform.path}/cores/arduino/kendryte-standalone-sdk/lib
compiler.lib_hal_inc.path={runtime.platform.path}/cores/arduino/hal/include
compiler.cores.path={runtime.platform.path}/cores/arduino/
compiler.preproc.flags=-I{build.system.path}/include -I{compiler.cores.path} -I{compiler.lib_hal_inc.path} -I{compiler.sdk.path}/bsp/include -I{compiler.sdk.path}/drivers/include -I{compiler.sdk.path}/utils/include -I{compiler.sdk.path}/freertos/conf -I{compiler.sdk.path}/freertos/include -I{compiler.sdk.path}/freertos/portable -I{compiler.clib.path}
compiler.preproc.flags="-I{build.system.path}/include" "-I{compiler.cores.path}" "-I{compiler.cores.path}/avr" "-I{compiler.lib_hal_inc.path}" "-I{compiler.sdk.path}/bsp/include" "-I{compiler.sdk.path}/drivers/include" "-I{compiler.sdk.path}/utils/include" "-I{compiler.sdk.path}/freertos/conf" "-I{compiler.sdk.path}/freertos/include" "-I{compiler.sdk.path}/freertos/portable"
compiler.both.flags=-mcmodel=medany -mabi=lp64f -march=rv64imafc -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fno-zero-initialized-in-bss -Os -ggdb -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wextra -Werror=frame-larger-than=65536 -Wno-unused-parameter -Wno-sign-compare -Wno-error=missing-braces -Wno-error=return-type -Wno-error=pointer-sign -Wno-missing-braces -Wno-strict-aliasing -Wno-implicit-fallthrough -Wno-missing-field-initializers -Wno-int-to-pointer-cast -Wno-error=comment -Wno-error=logical-not-parentheses -Wno-error=duplicate-decl-specifier -Wno-error=parentheses -lpthread
compiler.both.flags=-mcmodel=medany -mabi=lp64f -march=rv64imafc -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fno-zero-initialized-in-bss -Os -ggdb -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wextra -Werror=frame-larger-than=65536 -Wno-unused-parameter -Wno-sign-compare -Wno-error=missing-braces -Wno-error=return-type -Wno-error=pointer-sign -Wno-missing-braces -Wno-strict-aliasing -Wno-implicit-fallthrough -Wno-missing-field-initializers -Wno-int-to-pointer-cast -Wno-error=comment -Wno-error=logical-not-parentheses -Wno-error=duplicate-decl-specifier -Wno-error=parentheses -Wno-error=narrowing -Wno-error=unused-value
compiler.debug.flags=-DCONFIG_LOG_ENABLE -DCONFIG_LOG_LEVEL=LOG_INFO -DDEBUG=1 -D__riscv64
compiler.c.flags=-c {compiler.debug.flags} {compiler.both.flags} {compiler.preproc.flags} -std=gnu11 -Wno-pointer-to-int-cast -Wno-old-style-declaration -g -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=unused-const-variable
compiler.cpp.flags=-c {compiler.debug.flags} {compiler.both.flags} -I{runtime.platform.path}/libraries/SPI/src {compiler.preproc.flags} -std=gnu++17 -g -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=unused-const-variable
compiler.cpp.flags=-c {compiler.debug.flags} {compiler.both.flags} "-I{runtime.platform.path}/libraries/SPI/src" {compiler.preproc.flags} -std=gnu++17 -g -Wno-error=unused-variable -Wno-error=unused-function -Wno-error=unused-const-variable
compiler.ld.flags=-mcmodel=medany -mabi=lp64f -march=rv64imafc -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fno-zero-initialized-in-bss -Os -ggdb -nostartfiles -static -Wl,--gc-sections -Wl,-static -Wl,--whole-archive -Wl,--no-whole-archive -Wl,-EL -Wl,--no-relax -T {build.ldscript}
@@ -84,14 +83,18 @@ recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -B "{build.path}/{build.project_name}.elf"
recipe.size.regex=\s*[0-9]+\s+[0-9]+\s+[0-9]+\s+([0-9]+).*
## Save hex
recipe.output.tmp_file={build.project_name}.bin
recipe.output.save_file={build.project_name}.{build.variant}.bin
# Uploader tools
# -------------------
tools.kflash.path={runtime.tools.kflash.path}/
tools.kflash.cmd=python3 {runtime.tools.kflash.path}/kflash.py
tools.kflash.cmd.windows={runtime.tools.kflash.path}/k-flash
tools.kflash.cmd.windows={runtime.tools.kflash.path}/kflash_py
tools.kflash.cmd.macosx=/usr/local/bin/python3 {runtime.tools.kflash.path}/kflash.py
tools.kflash.program.pattern={cmd} -n -p {serial.port} -b {build.burn_baudrate} -B {build.burn_tool_firmware} {build.path}/{build.project_name}.bin
tools.kflash.program.pattern.windows="{cmd}" -d {serial.port} -b {build.burn_baudrate} {build.path}/{build.project_name}.bin
tools.kflash.program.pattern.windows="{cmd}" -n -p {serial.port} -b {build.burn_baudrate} -B {build.burn_tool_firmware} {build.path}/{build.project_name}.bin

View File

@@ -0,0 +1,91 @@
#ifndef _VARIANT_IOXGD4
#define _VARIANT_IOXGD4
#include <stdint.h>
#define RISCV
#include "platform.h"
#include "Arduino.h"
#include "pwm.h"
#ifdef __cplusplus
#include "UARTClass.h"
extern class UARTHSClass Serial;
extern class UARTClass Serial1;
extern class UARTClass Serial2;
extern class UARTClass Serial3;
#endif
/* BOARD PIN DEFINE */
/* LEDs */
#define PIN_LED_GREEN 13
#define PIN_LED_BLUE 12
#define PIN_LED_RED 14
#define PIN_LED 13
#define LED_BUILTIN 13
#define LED_GREEN 13
#define LED_BLUE 12
#define LED_RED 14
/* KEY */
#define KEY0 16
/* MIC ARRAY */
#define MIC_BCK 18
#define MIC_WS 19
#define MIC_DAT3 20
#define MIC_DAT2 21
#define MIC_DAT1 22
#define MIC_DAT0 23
#define MIC_LED_DAT 24
/* SPI0 */
#define SPI0_CS1 25
#define SPI0_MISO 26
#define SPI0_SCLK 27
#define SPI0_MOSI 28
#define SPI0_CS0 29
/* I2S */
#define MIC0_WS 30
#define MIC0_DATA 31
#define MIC0_BCK 32
#define I2S_WS 33
#define I2S_DA 34
#define I2S_BCK 35
/* LCD */
#define LCD_CS 36
#define LCD_RST 37
#define LCD_DC 38
#define LCD_WR 39
#define RX0 4
#define TX0 5
#define RX1 7
#define TX1 6
#define SDA 33
#define SCL 32
#define MD_PIN_MAP(fpio) (fpio)
#define ORG_PIN_MAP(org_pin) (org_pin)
static const uint8_t SS = SPI0_CS0 ;
static const uint8_t MOSI = SPI0_MOSI;
static const uint8_t MISO = SPI0_MISO;
static const uint8_t SCK = SPI0_SCLK;
typedef struct _pwm_fpio_set_t{
pwm_channel_number_t channel;
pwm_device_number_t device;
uint8_t inuse;
}pwm_fpio_set_t;
#define VARIANT_NUM_GPIOHS (32)
#define VARIANT_NUM_GPIO ( 8)
#define VARIANT_NUM_PWM (12)
#define VARIANT_NUM_I2C ( 3)
#define VARIANT_NUM_SPI ( 3)
#define VARIANT_NUM_UART ( 3)
#endif

View File

@@ -1,5 +1,5 @@
#ifndef _VARIANT_BOARD_SIPEED_MAIX_GO
#define _VARIANT_BOARD_SIPEED_MAIX_GO
#ifndef _VARIANT_LAMLOEI_AIOT_DAAN
#define _VARIANT_LAMLOEI_AIOT_DAAN
#include <stdint.h>
@@ -65,6 +65,9 @@ extern class UARTClass Serial3;
#define SDA 31
#define SCL 30
#define MD_PIN_MAP(fpio) (fpio)
#define ORG_PIN_MAP(org_pin) (org_pin)
static const uint8_t SS = SPI0_CS0 ;
static const uint8_t MOSI = SPI0_MOSI;
static const uint8_t MISO = SPI0_MISO;

View File

@@ -0,0 +1,93 @@
#ifndef _VARIANT_M5STACK_M5STICK_V
#define _VARIANT_M5STACK_M5STICK_V
#include <stdint.h>
#define RISCV
#include "platform.h"
#include "Arduino.h"
#include "pwm.h"
#ifdef __cplusplus
#include "UARTClass.h"
extern class UARTHSClass Serial;
extern class UARTClass Serial1;
extern class UARTClass Serial2;
extern class UARTClass Serial3;
#endif
/* BOARD PIN DEFINE */
/* UART */
#define RX0 4
#define TX0 5
/* LEDs */
#define PIN_LED_RED 6
#define PIN_LED_WHITE 7
#define PIN_LED_BLUE 8
#define PIN_LED_GREEN 9
#define PIN_LED 9
#define LED_RED 6
#define LED_WHITE 7
#define LED_BLUE 8
#define LED_GREEN 9
#define LED_BUILTIN 9
/* MIC ARRAY */
#define MIC_WS 10
#define MIC_DAT3 12
#define MIC_BCK 13
/* SPK MAX98357 */
#define I2S_SD 11
#define I2S_LRCLK 14
#define I2S_BCLK 15
#define I2S_DIN 17
/* LCD ST7789 135x240 */
#define LCD_SDA 18
#define LCD_SCL 19
#define LCD_DC 20
#define LCD_RST 21
#define LCD_CS 22
/* AXP192 INT PIN */
#define INTL_INT 23
/* INTL I2C - AXP192, MPU6886 */
#define SCL 28
#define SDA 29
/* SPI0 */
#define SPI0_SCLK 30
#define SPI0_MISO 31
#define SPI0_CS0 32
#define SPI0_MOSI 33
/* GROVE */
#define RX1 34
#define TX1 35
#define EXTL_SCL 34
#define EXTL_SDA 35
/* BUTTONS */
#define BTN_A 36
#define BTN_B 37
#define KEY0 36
#define KEY1 37
#define MD_PIN_MAP(fpio) (fpio)
#define ORG_PIN_MAP(org_pin) (org_pin)
static const uint8_t SS = SPI0_CS0 ;
static const uint8_t MOSI = SPI0_MOSI;
static const uint8_t MISO = SPI0_MISO;
static const uint8_t SCK = SPI0_SCLK;
typedef struct _pwm_fpio_set_t{
pwm_channel_number_t channel;
pwm_device_number_t device;
uint8_t inuse;
} pwm_fpio_set_t;
#define VARIANT_NUM_GPIOHS (32)
#define VARIANT_NUM_GPIO ( 8)
#define VARIANT_NUM_PWM (12)
#define VARIANT_NUM_I2C ( 3)
#define VARIANT_NUM_SPI ( 3)
#define VARIANT_NUM_UART ( 3)
#endif

View File

@@ -0,0 +1,78 @@
#ifndef _VARIANT_M5STACK_M5UNIT_V
#define _VARIANT_M5STACK_M5UNIT_V
#include <stdint.h>
#define RISCV
#include "platform.h"
#include "Arduino.h"
#include "pwm.h"
#ifdef __cplusplus
#include "UARTClass.h"
extern class UARTHSClass Serial;
extern class UARTClass Serial1;
extern class UARTClass Serial2;
extern class UARTClass Serial3;
#endif
/* BOARD PIN DEFINE */
/* UART */
#define RX0 4
#define TX0 5
/* WS2812 LEDs */
#define PIN_LED_RGB 8
/* MIC ARRAY */
#define MIC_WS 10
#define MIC_DAT3 12
#define MIC_BCK 13
/* SPK MAX98357 */
#define SPK_LRCLK 14
#define SPK_BCLK 15
#define SPK_DIN 17
#define SPK_SD 25
/* BUTTONS */
#define BTN_A 18
#define BTN_B 19
#define KEY0 18
#define KEY1 19
/* AXP192 INT PIN */
#define AXP_INT 23
/* INTL I2C */
#define SCL 28
#define SDA 29
/* SPI0 */
#define SPI0_SCLK 30
#define SPI0_MISO 31
#define SPI0_CS0 32
#define SPI0_MOSI 33
/* EXTL I2C */
#define EXTL_SCL 34
#define EXTL_SDA 35
#define MD_PIN_MAP(fpio) (fpio)
#define ORG_PIN_MAP(org_pin) (org_pin)
static const uint8_t SS = SPI0_CS0 ;
static const uint8_t MOSI = SPI0_MOSI;
static const uint8_t MISO = SPI0_MISO;
static const uint8_t SCK = SPI0_SCLK;
typedef struct _pwm_fpio_set_t{
pwm_channel_number_t channel;
pwm_device_number_t device;
uint8_t inuse;
}pwm_fpio_set_t;
#define VARIANT_NUM_GPIOHS (32)
#define VARIANT_NUM_GPIO ( 8)
#define VARIANT_NUM_PWM (12)
#define VARIANT_NUM_I2C ( 3)
#define VARIANT_NUM_SPI ( 3)
#define VARIANT_NUM_UART ( 3)
#endif

View File

@@ -0,0 +1,96 @@
#ifndef _VARIANT_SIPEED_MAIX_AMIGO
#define _VARIANT_SIPEED_MAIX_AMIGO
#include <stdint.h>
#define RISCV
#include "platform.h"
#include "Arduino.h"
#include "pwm.h"
#ifdef __cplusplus
#include "UARTClass.h"
extern class UARTHSClass Serial;
extern class UARTClass Serial1;
extern class UARTClass Serial2;
extern class UARTClass Serial3;
#endif
/* BOARD PIN DEFINE */
/* UARTHS CH552T */
#define RX0 4
#define TX0 5
/* UART Grove */
#define RX1 9 //Grove
#define TX1 7 //Grove
/* 8P Connector */
// #define PB0 8 //8P-12
// #define PB1 12 //8P-3
/* SPI0 */
#define SPI0_MISO 6 //8P-11
#define SPI0_MOSI 10 //8P-2
#define SPI0_SCLK 11 //8P-1
#define SPI0_CS0 26 //TF
/* KEYs */
#define KEY2 20 //Grove
#define KEY1 23 //Grove
/* LEDs */
#define PIN_LED_RED 14
#define PIN_LED_GREEN 15
#define PIN_LED_BLUE 17
#define PIN_LED 15
#define LED_RED 14
#define LED_GREEN 15
#define LED_BLUE 17
#define LED_BUILTIN 15
/* UART3 */
#define TX2 22 //8P-4
#define RX2 25 //8P-5
/* I2C1 - AXP173, MSA301, TOUCH */
#define SCL 24
#define SDA 27
/* USB_SBU */
#define USB_DP 28 //8P-8
#define USB_DM 29 //8P-9
/* I2S AUDIO CODEC ES8374 */
#define I2S2_MCLK 13
#define I2S2_WS 18
#define I2S2_SCLK 21
#define I2S2_DOUT 34
#define I2S2_DIN 35
/* Flash LED */
#define WLED_EN 32
/* TouchScreen */
#define CAP_TOUCH_IRQ 33
/* LCD */
#define LCD_TEN 19
#define LCD_CS 36
#define LCD_RST 37
#define LCD_DC 38
#define LCD_WR 39
#define MD_PIN_MAP(fpio) (fpio)
#define ORG_PIN_MAP(org_pin) (org_pin)
static const uint8_t SS = SPI0_CS0 ;
static const uint8_t MOSI = SPI0_MOSI;
static const uint8_t MISO = SPI0_MISO;
static const uint8_t SCK = SPI0_SCLK;
typedef struct _pwm_fpio_set_t{
pwm_channel_number_t channel;
pwm_device_number_t device;
uint8_t inuse;
} pwm_fpio_set_t;
#define VARIANT_NUM_GPIOHS (32)
#define VARIANT_NUM_GPIO ( 8)
#define VARIANT_NUM_PWM (12)
#define VARIANT_NUM_I2C ( 3)
#define VARIANT_NUM_SPI ( 3)
#define VARIANT_NUM_UART ( 3)
#endif

View File

@@ -0,0 +1,96 @@
#ifndef _VARIANT_SIPEED_MAIX_BIT
#define _VARIANT_SIPEED_MAIX_BIT
#include <stdint.h>
#define RISCV
#include "platform.h"
#include "Arduino.h"
#include "pwm.h"
#ifdef __cplusplus
#include "UARTClass.h"
extern class UARTHSClass Serial;
extern class UARTClass Serial1;
extern class UARTClass Serial2;
extern class UARTClass Serial3;
#endif
/* BOARD PIN DEFINE */
/* UARTHS */
#define RX0 4
#define TX0 5
/* UART */
#define RX1 6
#define TX1 7
// #define IO_8 8
// #define IO_9 9
// #define IO_10 10
/* LEDs */
#define PIN_LED_GREEN 12
#define PIN_LED_RED 13
#define PIN_LED_BLUE 14
#define PIN_LED 12
#define LED_RED 13
#define LED_GREEN 12
#define LED_BLUE 14
#define LED_BUILTIN 12
// #define IO_15 15
// #define IO_17 17
/* I2S MIC */
#define MIC_BCK 18
#define MIC_WS 19
#define MIC_DAT3 20
// #define IO_21 21
// #define IO_22 22
// #define IO_23 23
// #define IO_24 24
// #define IO_25 25
/* SPI0 */
#define SPI0_MISO 26
#define SPI0_SCLK 27
#define SPI0_MOSI 28
#define SPI0_CS0 29
// #define SCL 30
// #define SDA 31
// #define IO_30 30
// #define IO_31 31
// #define IO_32 32
// #define IO_33 33
// #define IO_34 34
// #define IO_35 35
/* LCD */
#define LCD_CS 36
#define LCD_RST 37
#define LCD_DC 38
#define LCD_WR 39
#define MD_PIN_MAP(fpio) (fpio)
#define ORG_PIN_MAP(org_pin) (org_pin)
static const uint8_t SS = SPI0_CS0 ;
static const uint8_t MOSI = SPI0_MOSI;
static const uint8_t MISO = SPI0_MISO;
static const uint8_t SCK = SPI0_SCLK;
typedef struct _pwm_fpio_set_t{
pwm_channel_number_t channel;
pwm_device_number_t device;
uint8_t inuse;
} pwm_fpio_set_t;
#define VARIANT_NUM_GPIOHS (32)
#define VARIANT_NUM_GPIO ( 8)
#define VARIANT_NUM_PWM (12)
#define VARIANT_NUM_I2C ( 3)
#define VARIANT_NUM_SPI ( 3)
#define VARIANT_NUM_UART ( 3)
#endif

Some files were not shown because too many files have changed in this diff Show More