Template
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8872b5ae57 | ||
|
|
dccce6967c | ||
|
|
142b0133d9 | ||
|
|
5feae37831 |
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
"gd32.openocd.targetConfig": "target/openocd_gdlink_gd32e23x.cfg",
|
"gd32.openocd.targetConfig": "target/openocd_gdlink_gd32e23x.cfg",
|
||||||
"gd32.openocd.massEraseCommand": "gd32e23x mass_erase 0",
|
"gd32.openocd.massEraseCommand": "gd32e23x mass_erase 0",
|
||||||
"gd32.jlink.device": "GD32E230F8",
|
"gd32.jlink.device": "GD32E230F8",
|
||||||
"gd32.jlink.interface": "SWD",
|
"gd32.jlink.interface": "swd",
|
||||||
"gd32.jlink.speed": "4000",
|
"gd32.jlink.speed": "4000",
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.h": "c",
|
"*.h": "c",
|
||||||
|
|||||||
Vendored
+3
-3
@@ -52,7 +52,7 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
|
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
|
||||||
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
|
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
|
||||||
"-c", "init; reset halt; flash write_image erase ${command:cmake.launchTargetFilename}; reset; exit"
|
"-c", "init; adapter deassert srst; sleep 200; catch {reset halt}; reset halt; flash write_image erase ${command:cmake.launchTargetFilename}; reset; exit"
|
||||||
],
|
],
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
|
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
|
||||||
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
|
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
|
||||||
"-c", "init; reset; exit"
|
"-c", "init; adapter deassert srst; sleep 200; reset; exit"
|
||||||
],
|
],
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
|
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
|
||||||
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
|
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
|
||||||
"-c", "init; reset halt; ${config:gd32.openocd.massEraseCommand}; exit"
|
"-c", "init; adapter deassert srst; sleep 200; catch {reset halt}; reset halt; ${config:gd32.openocd.massEraseCommand}; exit"
|
||||||
],
|
],
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
|
|||||||
@@ -25,6 +25,11 @@
|
|||||||
#define I2C_RECOVERY_CLOCKS 9U /* Clock pulses for bus recovery */
|
#define I2C_RECOVERY_CLOCKS 9U /* Clock pulses for bus recovery */
|
||||||
#define I2C_MASTER_ADDRESS 0x00U /* Master address (not used) */
|
#define I2C_MASTER_ADDRESS 0x00U /* Master address (not used) */
|
||||||
|
|
||||||
|
/* Optional delay between the sub-address write phase and repeated START. */
|
||||||
|
#ifndef I2C_READ_RESTART_DELAY_MS
|
||||||
|
#define I2C_READ_RESTART_DELAY_MS 0U
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Legacy compatibility */
|
/* Legacy compatibility */
|
||||||
#define I2C_OK 1
|
#define I2C_OK 1
|
||||||
#define I2C_FAIL 0
|
#define I2C_FAIL 0
|
||||||
@@ -91,29 +96,33 @@ void i2c_scan(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief write 16-bit data to I2C device
|
\brief write two data bytes using an 8-bit register address
|
||||||
\param[in] slave_addr: 7-bit slave address
|
\param[in] slave_addr: 7-bit slave address
|
||||||
\param[in] reg_addr: register address (16-bit, high byte first)
|
\param[in] reg_addr: 8-bit register address
|
||||||
\param[in] data: pointer to 2-byte data array
|
\param[in] data: pointer to 2-byte data array
|
||||||
\param[out] none
|
\param[out] none
|
||||||
\retval i2c_result_t
|
\retval i2c_result_t
|
||||||
|
\note legacy compatibility wrapper; "16bits" describes data length,
|
||||||
|
not register-address width
|
||||||
*/
|
*/
|
||||||
i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
|
i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief read 16-bit data from I2C device
|
\brief read two data bytes using an 8-bit register address
|
||||||
\param[in] slave_addr: 7-bit slave address
|
\param[in] slave_addr: 7-bit slave address
|
||||||
\param[in] reg_addr: register address
|
\param[in] reg_addr: 8-bit register address
|
||||||
\param[out] data: pointer to 2-byte data buffer
|
\param[out] data: pointer to 2-byte data buffer
|
||||||
\retval i2c_result_t
|
\retval i2c_result_t
|
||||||
|
\note legacy compatibility wrapper; "16bits" describes data length,
|
||||||
|
not register-address width
|
||||||
*/
|
*/
|
||||||
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
||||||
|
|
||||||
/* Generic read/write functions with configurable length */
|
/* Legacy generic APIs: register address is sent as two bytes, MSB first. */
|
||||||
/*!
|
/*!
|
||||||
\brief write data to I2C device with configurable length
|
\brief write data using a 16-bit register address
|
||||||
\param[in] slave_addr: slave device address (7-bit)
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
\param[in] reg_addr: register address
|
\param[in] reg_addr: 16-bit register address (MSB first on the bus)
|
||||||
\param[in] data: pointer to data buffer
|
\param[in] data: pointer to data buffer
|
||||||
\param[in] length: number of bytes to write (1-255)
|
\param[in] length: number of bytes to write (1-255)
|
||||||
\param[out] none
|
\param[out] none
|
||||||
@@ -122,7 +131,7 @@ i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data
|
|||||||
i2c_result_t i2c_write(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length);
|
i2c_result_t i2c_write(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief read data from I2C device with configurable length
|
\brief read data using a 16-bit register address
|
||||||
\param[in] slave_addr: slave device address (7-bit)
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
\param[in] reg_addr: register address (16-bit, high byte first)
|
\param[in] reg_addr: register address (16-bit, high byte first)
|
||||||
\param[out] data: pointer to data buffer
|
\param[out] data: pointer to data buffer
|
||||||
@@ -131,6 +140,51 @@ i2c_result_t i2c_write(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uin
|
|||||||
*/
|
*/
|
||||||
i2c_result_t i2c_read(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length);
|
i2c_result_t i2c_read(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
|
/* Explicit register-address-width APIs. */
|
||||||
|
/*!
|
||||||
|
\brief write data using an 8-bit register address
|
||||||
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
|
\param[in] reg_addr: 8-bit register address
|
||||||
|
\param[in] data: pointer to data buffer
|
||||||
|
\param[in] length: number of bytes to write (1-255)
|
||||||
|
\retval i2c_result_t: operation result
|
||||||
|
*/
|
||||||
|
i2c_result_t i2c_write_reg8(uint8_t slave_addr, uint8_t reg_addr,
|
||||||
|
const uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief read data using an 8-bit register address
|
||||||
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
|
\param[in] reg_addr: 8-bit register address
|
||||||
|
\param[out] data: pointer to data buffer
|
||||||
|
\param[in] length: number of bytes to read (1-255)
|
||||||
|
\retval i2c_result_t: operation result
|
||||||
|
*/
|
||||||
|
i2c_result_t i2c_read_reg8(uint8_t slave_addr, uint8_t reg_addr,
|
||||||
|
uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief write data using a 16-bit register address
|
||||||
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
|
\param[in] reg_addr: 16-bit register address (MSB first on the bus)
|
||||||
|
\param[in] data: pointer to data buffer
|
||||||
|
\param[in] length: number of bytes to write (1-255)
|
||||||
|
\retval i2c_result_t: operation result
|
||||||
|
*/
|
||||||
|
i2c_result_t i2c_write_reg16(uint8_t slave_addr, uint16_t reg_addr,
|
||||||
|
const uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief read data using a 16-bit register address
|
||||||
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
|
\param[in] reg_addr: 16-bit register address (MSB first on the bus)
|
||||||
|
\param[out] data: pointer to data buffer
|
||||||
|
\param[in] length: number of bytes to read (1-255)
|
||||||
|
\retval i2c_result_t: operation result
|
||||||
|
*/
|
||||||
|
i2c_result_t i2c_read_reg16(uint8_t slave_addr, uint16_t reg_addr,
|
||||||
|
uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
/* Pure read response without sub-address phase (for commands that already sent read request parameters) */
|
/* Pure read response without sub-address phase (for commands that already sent read request parameters) */
|
||||||
/*!
|
/*!
|
||||||
\brief read data from I2C device without register/sub-address phase
|
\brief read data from I2C device without register/sub-address phase
|
||||||
@@ -141,7 +195,13 @@ i2c_result_t i2c_read(uint8_t slave_addr, uint16_t reg_addr, uint8_t *data, uint
|
|||||||
*/
|
*/
|
||||||
i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length);
|
i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length);
|
||||||
|
|
||||||
#if DEBUG_VERBOSE == CFG_ENABLE
|
/*!
|
||||||
|
\brief probe one 7-bit address (ACK only, no data phase)
|
||||||
|
\param[in] slave_addr: slave device address (7-bit)
|
||||||
|
\retval bool: true when the address was acknowledged
|
||||||
|
*/
|
||||||
|
bool i2c_probe_ack(uint8_t slave_addr);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief get status string for debugging
|
\brief get status string for debugging
|
||||||
\param[in] status: i2c_result_t value
|
\param[in] status: i2c_result_t value
|
||||||
@@ -149,6 +209,5 @@ i2c_result_t i2c_read_raw(uint8_t slave_addr, uint8_t *data, uint8_t length);
|
|||||||
\retval const char* status string
|
\retval const char* status string
|
||||||
*/
|
*/
|
||||||
const char* i2c_get_status_string(i2c_result_t status);
|
const char* i2c_get_status_string(i2c_result_t status);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //I2C_H
|
#endif //I2C_H
|
||||||
|
|||||||
@@ -71,9 +71,8 @@
|
|||||||
|
|
||||||
| 分支 | 用途 |
|
| 分支 | 用途 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| `template_pc` | **主模板**(推荐),用于桌面端 VSCode 开发 |
|
| `main` | **主模板**(推荐),用于桌面端 VSCode 开发 |
|
||||||
| `template_xl` | 小琅适配版 |
|
| `codex/*` | 功能开发和合并前验证分支 |
|
||||||
| `main` | 早期版本,不推荐使用 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -286,7 +285,7 @@ FLASH (rx) : ORIGIN = 0x08002000, LENGTH = 8K
|
|||||||
- **版本**:xpack-arm-none-eabi-gcc-11.3.1-1.1
|
- **版本**:xpack-arm-none-eabi-gcc-11.3.1-1.1
|
||||||
- **安装位置**:每台电脑本机任意目录,工具包不放入工程仓库
|
- **安装位置**:每台电脑本机任意目录,工具包不放入工程仓库
|
||||||
- **官方下载地址**:https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases
|
- **官方下载地址**:https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases
|
||||||
- **活动变量**:`GD32_GCC_BIN`,值为工具链的 `bin` 目录(也接受工具链根目录)
|
- **活动变量**:`GD32_GCC_BIN`,值为工具链的 `bin` 目录
|
||||||
|
|
||||||
### 2. OpenOCD(调试/烧录)
|
### 2. OpenOCD(调试/烧录)
|
||||||
|
|
||||||
@@ -300,13 +299,29 @@ OpenOCD 的 cfg 文件由工程自己的 `.vscode/settings.json` 指定,环境
|
|||||||
|
|
||||||
cfg 必须可以直接启动完整会话,包含调试器 interface 和目标芯片配置;只有 `target/gd32e23x.cfg` 这种 target-only 文件不能单独启动调试会话。
|
cfg 必须可以直接启动完整会话,包含调试器 interface 和目标芯片配置;只有 `target/gd32e23x.cfg` 这种 target-only 文件不能单独启动调试会话。
|
||||||
|
|
||||||
例如 CMSIS-DAP 的 wrapper cfg 可以写成:
|
例如 CMSIS-DAP 的 wrapper cfg 可以写成(使用下述硬件复位任务时,还需追加后面的 RST 配置):
|
||||||
|
|
||||||
```tcl
|
```tcl
|
||||||
source [find interface/cmsis-dap.cfg]
|
source [find interface/cmsis-dap.cfg]
|
||||||
source [find target/gd32e23x.cfg]
|
source [find target/gd32e23x.cfg]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
模板的 `Flash MCU`、`Reset MCU` 和 `Mass Erase MCU` 任务默认使用 RST 硬件复位:OpenOCD
|
||||||
|
连接时保持复位,连接后松开 RST,并等待 200 ms 后执行烧录、复位或擦除操作。每台开发机需要满足以下条件:
|
||||||
|
|
||||||
|
- 调试器的 RST 线连接到 MCU 的 NRST。
|
||||||
|
- `gd32.openocd.targetConfig` 指定的 cfg 包含以下配置:
|
||||||
|
|
||||||
|
```tcl
|
||||||
|
adapter srst delay 100
|
||||||
|
reset_config srst_only srst_nogate connect_assert_srst
|
||||||
|
```
|
||||||
|
|
||||||
|
- 若固件会复用 SWD 引脚,松开复位后应保留至少 2 秒的调试挂接窗口。
|
||||||
|
|
||||||
|
cfg 位于 `GD32_OPENOCD_SCRIPTS` 指向的工具目录中,不随工程仓库分发;更换电脑或 OpenOCD
|
||||||
|
版本后需要再次确认上述配置。未连接 RST 线的硬件应改用软复位配置。
|
||||||
|
|
||||||
每台开发电脑配置一次用户环境变量(路径按本机实际位置填写):
|
每台开发电脑配置一次用户环境变量(路径按本机实际位置填写):
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -346,12 +361,12 @@ cmake --preset Debug -DTOOLCHAIN_DIRECTORY="C:/toolchain/gcc-arm-none-eabi/bin"
|
|||||||
|
|
||||||
| 变量名 | 值 | 用途 |
|
| 变量名 | 值 | 用途 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `GD32_GCC_BIN` | 活动 ARM GCC 的 `bin` 目录(或工具链根目录) | CMake 编译、GDB 调试、binutils |
|
| `GD32_GCC_BIN` | 活动 ARM GCC 的 `bin` 目录 | CMake 编译、GDB 调试、binutils |
|
||||||
| `GD32_OPENOCD_BIN` | 包含 `openocd.exe` 的 `bin` 目录 | OpenOCD 任务/调试 |
|
| `GD32_OPENOCD_BIN` | 包含 `openocd.exe` 的 `bin` 目录 | OpenOCD 任务/调试 |
|
||||||
| `GD32_OPENOCD_SCRIPTS` | OpenOCD `scripts` 根目录 | `-s` 脚本搜索路径 |
|
| `GD32_OPENOCD_SCRIPTS` | OpenOCD `scripts` 根目录 | `-s` 脚本搜索路径 |
|
||||||
|
|
||||||
- **可选的环境变量**:为不同 GCC 版本分别建立 `GD32_GCC_XPACK11_BIN`、`GD32_GCC_GNU12_BIN` 等变量,需要切换时手动把选中的路径写入 `GD32_GCC_BIN`。`GD32_GCC_ENV_VAR` 仅在需要让 CMake 使用另一个 `GD32_*` 变量名时设置。
|
- **可选的环境变量**:为不同 GCC 版本分别建立 `GD32_GCC_XPACK11_BIN`、`GD32_GCC_GNU12_BIN` 等变量,需要切换时手动把选中的路径写入 `GD32_GCC_BIN`。`GD32_GCC_ENV_VAR` 仅在需要让 CMake 使用另一个 `GD32_*` 变量名时设置。
|
||||||
- ARM GCC 必须是 `arm-none-eabi` 交叉工具链,变量指向工具链根目录或 `bin` 目录;`gcc`、`g++`、`gdb`、`ar`、`as`、`ld`、`objcopy`、`objdump`、`size`、`ranlib` 必须齐全。
|
- ARM GCC 必须是 `arm-none-eabi` 交叉工具链;`GD32_GCC_BIN` 及其它 `GD32_*_BIN` 变量必须指向 `bin` 目录,以同时支持 CMake 和 VSCode 调试。仅通过 CMake 的 `TOOLCHAIN_DIRECTORY` 参数配置时,可以传工具链根目录或 `bin` 目录。`gcc`、`g++`、`gdb`、`ar`、`as`、`ld`、`objcopy`、`objdump`、`size`、`ranlib` 必须齐全。
|
||||||
- 当前工程已验证 xPack GCC 11.3.1 和 GNU Arm GCC 12.3.1;链接脚本使用 GCC 11+ 支持的 `READONLY` 语法。更换更新版本仍需在目标板上验证编译、链接和调试。
|
- 当前工程已验证 xPack GCC 11.3.1 和 GNU Arm GCC 12.3.1;链接脚本使用 GCC 11+ 支持的 `READONLY` 语法。更换更新版本仍需在目标板上验证编译、链接和调试。
|
||||||
- OpenOCD 需要同时提供 `GD32_OPENOCD_BIN`、`GD32_OPENOCD_SCRIPTS`;任务会在 bin 目录下使用固定文件名 `openocd.exe`,每个工程在 `.vscode/settings.json` 中设置相对 `scripts` 根目录的 `gd32.openocd.targetConfig`,不依赖全局 `OPENOCD_SCRIPTS`。
|
- OpenOCD 需要同时提供 `GD32_OPENOCD_BIN`、`GD32_OPENOCD_SCRIPTS`;任务会在 bin 目录下使用固定文件名 `openocd.exe`,每个工程在 `.vscode/settings.json` 中设置相对 `scripts` 根目录的 `gd32.openocd.targetConfig`,不依赖全局 `OPENOCD_SCRIPTS`。
|
||||||
- CMake ≥ 3.20、Ninja、VSCode CMake Tools,以及 cortex-debug(使用 OpenOCD 调试时)必须已安装;J-Link 任务另需 `JLink.exe` 在 PATH 中。
|
- CMake ≥ 3.20、Ninja、VSCode CMake Tools,以及 cortex-debug(使用 OpenOCD 调试时)必须已安装;J-Link 任务另需 `JLink.exe` 在 PATH 中。
|
||||||
@@ -376,10 +391,10 @@ cmake --build Build/Release
|
|||||||
|
|
||||||
### 烧录
|
### 烧录
|
||||||
|
|
||||||
通过 VSCode 任务栏运行 `Flash MCU` 任务,或命令行:
|
通过 VSCode 任务栏运行 `Flash MCU` 任务,或使用同样的硬件复位时序从命令行烧录:
|
||||||
|
|
||||||
```bash
|
```powershell
|
||||||
openocd -f interface/cmsis-dap.cfg -f target/gd32e23x.cfg -c "program Build/Debug/Application.elf verify reset exit"
|
& "$env:GD32_OPENOCD_BIN\openocd.exe" -s "$env:GD32_OPENOCD_SCRIPTS" -f "target/openocd_gdlink_gd32e23x.cfg" -c "init; adapter deassert srst; sleep 200; catch {reset halt}; reset halt; flash write_image erase Build/Debug/Application/Application.elf; reset; exit"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 产物
|
### 产物
|
||||||
|
|||||||
Reference in New Issue
Block a user