| name | ch57x-dev-skill |
| description | AI Skill for CH57x BLE microcontroller firmware development. Used when users need to create, modify, or debug CH57x embedded projects, including BLE peripheral/central/mesh applications, peripheral driver configuration, IAP/OTA updates, and power management. Supports CH573, CH571 and other chips in the CH57x family. Trigger words: "CH573", "CH571", "CH57x", "WCH", "沁恒", "BLE", "蓝牙", "RISC-V", "MounRiver", "OTA", "IAP" |
| tags | ["embedded","BLE","bluetooth","RISC-V","WCH","CH57x","CH573","CH571","microcontroller","firmware"] |
| license | MIT |
| compatibility | Build requires MounRiver Studio IDE; target is CH57x RISC-V BLE SoC family |
| metadata | {"author":"Community","version":"1.2.0"} |
ch57x-dev-skill
AI Skill for CH57x BLE microcontroller firmware development. Provides scenario-driven recipes, complete API reference, configuration guides, and common pitfalls. Supports the CH57x chip family including CH573, CH571.
Core Principles
- Never guess APIs — Check
resources/ first; no matching doc = does not exist
- Verify header inclusion — Peripheral drivers need
CH57x_*.h; BLE needs CH57xBLE_LIB.h + HAL.h
- BLE initialization order matters — Always: SetSysClock → CH57X_BLEInit → HAL_Init → GAPRole_Init → App_Init → Main_Circulation
- config.h controls BLE stack — Memory, buffers, TX power, connection limits, sleep behavior all configured here
- Interrupt handlers must use
.highcode section — Place in RAM for fast execution: __attribute__((section(".highcode")))
- Flash writes need safe access —
FLASH_ROM_WRITE/FLASH_ROM_ERASE handle this internally; EEPROM ops do too
- IAP applications start at 0x1000 — Bootloader occupies 0x0000-0x0FFF; application linker script must offset
- TMOS is the BLE event loop — All BLE processing happens in
TMOS_SystemProcess() inside Main_Circulation()
When to Use
Applicable:
- Creating new CH57x firmware projects (BLE or non-BLE)
- Implementing BLE peripheral, central, broadcaster, observer, or mesh roles
- Configuring peripheral drivers (GPIO, UART, SPI, ADC, Timer, PWM, USB)
- Implementing IAP bootloader or BLE OTA firmware updates
- Power management and sleep mode configuration
- Flash/EEPROM data storage
Not applicable:
- General C programming questions unrelated to CH57x/WCH chips
- Other WCH chip families (CH569, CH582, CH32V, etc.) — different register maps
- PCB design or hardware schematics
Scenario Quick Reference (Recipes)
When user intent matches a scenario below, read the corresponding recipe first — it contains the complete call chain, step-by-step instructions, common errors, and code examples.
Project Setup
| recipe | scenario |
|---|
recipes/new_project.md | Create a new CH57x project from scratch with proper project structure |
BLE Applications
| recipe | scenario |
|---|
recipes/ble_peripheral.md | BLE peripheral (slave) — advertising, GATT services, notifications |
recipes/ble_central.md | BLE central (master) — scanning, connecting, service discovery, R/W |
recipes/ble_broadcaster_observer.md | Broadcaster / Observer — beacon, scanning without connection |
recipes/ble_hid.md | BLE HID device — keyboard, mouse, consumer control, touch |
recipes/ble_profiles.md | Standard profiles — HeartRate, CyclingSensor, RunningSensor, SpeedTest |
recipes/ble_multi_role.md | Multi-role / multi-connection — CentPeri, MultiCentral, MultiCentPeri |
recipes/ble_mesh.md | BLE Mesh — Alibaba light model, provisioning, vendor model |
recipes/ble_uart_bridge.md | BLE UART transparent bridge — bidirectional BLE-UART data |
recipes/ble_rf_dtm.md | RF test — DTM, non-standard RF PHY, frequency hopping |
recipes/ble_lwns_mesh.md | LWNS networking — broadcast, unicast, mesh, IoCHub |
recipes/ble_usb_combo.md | BLE + USB combo — BLE-to-USB serial bridge, WCHMcuIAP tool |
Peripheral Drivers
| recipe | scenario |
|---|
recipes/uart_comm.md | UART communication — init, send, receive, interrupt-driven |
recipes/gpio_control.md | GPIO — input, output, interrupt, pull-up/down |
recipes/adc_reading.md | ADC — external channel, temperature, battery, touch key |
recipes/timer_pwm.md | Timer and PWM — periodic interrupt, PWM output, capture |
recipes/spi_comm.md | SPI — master/slave, FIFO, DMA transfer |
recipes/flash_storage.md | Flash/EEPROM — read, write, erase, data storage |
System Features
| recipe | scenario |
|---|
recipes/power_management.md | Sleep modes — Idle, Halt, Sleep, Shutdown, GPIO/RTC wakeup |
recipes/iap_ota.md | IAP bootloader and BLE OTA — dual-image update system |
recipes/usb_device.md | USB device — CDC serial, HID, vendor-defined |
recipes/usb_host.md | USB host — device enumeration, AOA, U-disk filesystem |
Peripheral Pin Mapping
CH57x series has GPIOA (24 pins) and GPIOB (24 pins). Common peripheral pin assignments:
| Peripheral | Pin | Function |
|---|
| UART0 | PA4 (TX), PA5 (RX) | Default UART0 pins |
| UART1 | PA9 (TX), PA8 (RX) | Default UART1 pins (also debug UART) |
| UART2 | PA20 (TX), PA21 (RX) | Default UART2 pins |
| UART3 | PA13 (TX), PA12 (RX) | Default UART3 pins |
| SPI0 | PA12 (SCK), PA13 (MOSI), PA14 (MISO), PA15 (CS) | Default SPI0 pins |
| ADC_CH0 | PA4 | Analog input channel 0 |
| ADC_CH1 | PA5 | Analog input channel 1 |
| ADC_CH2 | PA12 | Analog input channel 2 |
| ADC_CH3 | PA13 | Analog input channel 3 |
| PWM4 | PA12 | PWM output channel 4 |
| PWM5 | PA13 | PWM output channel 5 |
| USB | PA11 (D-), PA12 (D+) | USB device/host |
Pin mux is configured via GPIOA_ModeCfg() before peripheral initialization. Check CH57x datasheet for alternate function assignments.
BLE Role State Machine
Peripheral States
GAPROLE_INIT → GAPROLE_STARTED → GAPROLE_ADVERTISING ↔ GAPROLE_CONNECTED
↓
GAPROLE_WAITING (disconnected)
Central States
GAPROLE_INIT → GAPROLE_STARTED → GAPROLE_STARTED (scanning) → GAPROLE_CONNECTED
Key Callback Signatures
typedef void (*gapRolesStateNotify_t)(gapRole_States_t newState, gapRoleEvent_t *pEvent);
typedef void (*pfnGapCentralRoleEventCB_t)(gapCentralRoleEvent_t *pEvent);
typedef uint8_t (*pfnGATTReadAttrCB_t)(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen);
typedef uint8_t (*pfnGATTWriteAttrCB_t)(uint16_t connHandle, gattAttribute_t *pAttr,
uint8_t *pValue, uint16_t len, uint16_t offset);
Critical Pitfalls (Must Read)
These are the most common errors. Violating any of these will produce non-working firmware.
1. BLE Init Order Must Be Exact
HAL_Init();
CH57X_BLEInit();
SetSysClock(CLK_SOURCE_PLL_60MHz);
CH57X_BLEInit();
HAL_Init();
GAPRole_PeripheralInit();
Peripheral_Init();
Main_Circulation();
2. Main_Circulation Never Returns
int main(void) {
init_all();
}
int main(void) {
init_all();
Main_Circulation();
}
3. config.h BLE_MEMHEAP_SIZE Must Be Large Enough
#define BLE_MEMHEAP_SIZE (1024*2)
#define BLE_MEMHEAP_SIZE (1024*6)
4. ATT_MTU = BLE_BUFF_MAX_LEN - 4
#define BLE_BUFF_MAX_LEN 23
#define BLE_BUFF_MAX_LEN 27
#define BLE_BUFF_MAX_LEN 251
5. GATT Service Registration Order
MyCustomService_AddService(GATT_ALL_SERVICES);
GGS_AddService(GATT_ALL_SERVICES);
GGS_AddService(GATT_ALL_SERVICES);
GATTServApp_AddService(GATT_ALL_SERVICES);
DevInfo_AddService();
MyCustomService_AddService(GATT_ALL_SERVICES);
6. Interrupt Handler Must Use .highcode Section
void UART1_IRQHandler(void) {
}
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void UART1_IRQHandler(void) {
}
7. GPIO Mode Must Be Set Before Peripheral Use
UART1_DefInit();
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
8. Flash Write Erases Entire Sector
FLASH_ROM_WRITE(addr, &single_byte, 1);
uint8_t buf[256];
FLASH_ROM_READ(sector_addr, buf, 256);
buf[offset] = new_value;
FLASH_ROM_ERASE(sector_addr, 256);
FLASH_ROM_WRITE(sector_addr, buf, 256);
9. IAP App Must Have Different Linker Script
10. BLE Notification Requires Connection Handle
GATT_Notification(0xFFFF, ¬i, FALSE);
static uint16_t connHandle;
connHandle = pEvent->linkCmpl.connectionHandle;
GATT_Notification(connHandle, ¬i, FALSE);
11. TMOS Event Must Return Unhandled Bits
uint16_t ProcessEvent(uint8_t task_id, uint16_t events) {
if (events & MY_EVT) {
handle_my_evt();
return 0;
}
return 0;
}
uint16_t ProcessEvent(uint8_t task_id, uint16_t events) {
if (events & MY_EVT) {
handle_my_evt();
return (events ^ MY_EVT);
}
return 0;
}
12. BLE ConnectNumber Encoding
cfg.PeripheralNumber = 1;
cfg.CentralNumber = 3;
cfg.ConnectNumber = (PERIPHERAL_MAX_CONNECTION & 3) | (CENTRAL_MAX_CONNECTION << 2);
Execution Workflow
| Step | Name | Description |
|---|
| 1 | Plan | Understand requirements, identify BLE role (if any), peripherals needed |
| 2 | Recipe | Check if a matching recipe exists in recipes/; if yes, follow its call chain |
| 3 | Query | For APIs not covered by recipes, query resources/ using quick reference docs |
| 4 | Validate | Verify all API signatures, header includes, pin assignments, config.h values |
| 5 | Confirm | Present implementation plan to user: includes, pin config, init sequence, main loop |
| 6 | Execute | New project: copy the closest example from resources/EXAM/ to the working directory, then modify. Existing project: edit files in place. |
| 7 | Check | Verify: init order, GPIO config before peripheral use, interrupt handler sections |
| 8 | Flash | Build with MounRiver Studio, flash via WCH-LinkE or USB ISP |
| 9 | Debug | Verify via UART debug output (UART1 @ 115200), check BLE with nRF Connect |
Step 6 Detail — Project Creation Strategy
When the target directory has no existing project (first-time creation):
-
Select the closest example from resources/EXAM/ based on user requirements:
- BLE peripheral →
resources/EXAM/BLE/Peripheral/
- BLE central →
resources/EXAM/BLE/Central/
- BLE HID →
resources/EXAM/BLE/HID_Keyboard/ (or HID_Mouse, HID_Consumer, HID_Touch)
- BLE Mesh →
resources/EXAM/BLE/MESH/adv_ali_light/ (or other mesh variant)
- BLE multi-role →
resources/EXAM/BLE/CentPeri/ or MultiCentPeri/
- BLE OTA/IAP →
resources/EXAM/BLE/BackupUpgrade_OTA/ or OnlyUpdateApp_Peripheral/
- UART →
resources/EXAM/UART1/
- SPI →
resources/EXAM/SPI0/
- ADC →
resources/EXAM/ADC/
- Timer/PWM →
resources/EXAM/TMR/ or resources/EXAM/PWMX/
- Flash →
resources/EXAM/FLASH/
- USB device →
resources/EXAM/USB/Device/COM/ (or HID, Vendor)
- USB host →
resources/EXAM/USB/Host/HostEnum/
- Power management →
resources/EXAM/PM/
-
Copy the entire example directory to the user's project directory, preserving the full structure (including APP/, Profile/, linked SRC/, etc.)
-
Modify the copied code to match user requirements — rename files, adjust config.h, change GATT services, update pin assignments, etc. This is faster and more reliable than writing from scratch.
-
Explain what was copied and why, so the user understands the starting point.
When the target directory already contains a project:
Edit existing files in place. Do not overwrite unless explicitly asked.
Failure Strategies
| Situation | Action |
|---|
| API does not exist in resources | Stop immediately, inform user |
| BLE stack config unsure | Default to BLE_MEMHEAP_SIZE=(1024*6), BLE_BUFF_MAX_LEN=27 |
| Pin conflict detected | Check CH57x datasheet for alternate functions, suggest reassignment |
| IAP memory overlap | Verify bootloader at 0x0000, app at 0x1000, no overlap |
| MESH not working | Check provisioning state, verify mesh library linked |
References
- Scenario recipes →
recipes/ directory
- Peripheral API quick ref →
resources/peripheral_api.md
- BLE API quick ref →
resources/ble_api.md
- Configuration options →
resources/config_reference.md
- Memory layout →
resources/memory_layout.md
- HAL reference →
resources/hal_reference.md
- Common pitfalls →
resources/pitfalls.md
- Example project index →
resources/example_list.md
- Example projects →
resources/EXAM/ (all peripheral and BLE examples)
- BLE development guide →
resources/EXAM/BLE/沁恒低功耗蓝牙软件开发参考手册.pdf