3 Commits
Author SHA1 Message Date
hulk 8872b5ae57 fix(i2c): sync robust hardware transactions 2026-09-15 19:16:53 +08:00
hulk dccce6967c fix(vscode): match HDMI hardware-reset tasks 2026-09-15 18:32:10 +08:00
hulk 142b0133d9 feat(vscode): add connect-under-reset tasks 2026-09-15 18:23:12 +08:00
4 changed files with 594 additions and 1039 deletions
+3 -3
View File
@@ -52,7 +52,7 @@
"args": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
"-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",
"problemMatcher": [],
@@ -77,7 +77,7 @@
"args": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
"-f", "${env:GD32_OPENOCD_SCRIPTS}/${config:gd32.openocd.targetConfig}",
"-c", "init; reset; exit"
"-c", "init; adapter deassert srst; sleep 200; reset; exit"
],
"group": "build",
"problemMatcher": [],
@@ -102,7 +102,7 @@
"args": [
"-s", "${env:GD32_OPENOCD_SCRIPTS}",
"-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",
"problemMatcher": [],
+69 -10
View File
@@ -25,6 +25,11 @@
#define I2C_RECOVERY_CLOCKS 9U /* Clock pulses for bus recovery */
#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 */
#define I2C_OK 1
#define I2C_FAIL 0
@@ -91,29 +96,33 @@ void i2c_scan(void);
#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] 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[out] none
\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]);
/*!
\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] reg_addr: register address
\param[in] reg_addr: 8-bit register address
\param[out] data: pointer to 2-byte data buffer
\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);
/* 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] 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] length: number of bytes to write (1-255)
\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);
/*!
\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] reg_addr: register address (16-bit, high byte first)
\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);
/* 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) */
/*!
\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);
#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
\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
*/
const char* i2c_get_status_string(i2c_result_t status);
#endif
#endif //I2C_H
+20 -4
View File
@@ -299,13 +299,29 @@ OpenOCD 的 cfg 文件由工程自己的 `.vscode/settings.json` 指定,环境
cfg 必须可以直接启动完整会话,包含调试器 interface 和目标芯片配置;只有 `target/gd32e23x.cfg` 这种 target-only 文件不能单独启动调试会话。
例如 CMSIS-DAP 的 wrapper cfg 可以写成:
例如 CMSIS-DAP 的 wrapper cfg 可以写成(使用下述硬件复位任务时,还需追加后面的 RST 配置):
```tcl
source [find interface/cmsis-dap.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
@@ -375,10 +391,10 @@ cmake --build Build/Release
### 烧录
通过 VSCode 任务栏运行 `Flash MCU` 任务,或命令行:
通过 VSCode 任务栏运行 `Flash MCU` 任务,或使用同样的硬件复位时序从命令行烧录:
```bash
openocd -f interface/cmsis-dap.cfg -f target/gd32e23x.cfg -c "program Build/Debug/Application.elf verify reset exit"
```powershell
& "$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"
```
### 产物
+429 -949
View File
File diff suppressed because it is too large Load Diff