WCH CH32V307VCT6 programarla con WCHISP desde GNU/Linux

Compré ésta MCU(microcontrolador) desde Aliexpress

https://es.aliexpress.com/item/1005007639944954.html?spm=a2g0o.order_list.order_list_main.5.69cd194dFMl64l&gatewayAdapt=glo2esp

Tengo el esquemático y su hoja de datos (Datasheet), tuve que hacer un pequeño programa para probar el encendidode los LED1 y LED2 desde la IDE de MounRiver Studio. Ha funcionado bien, salvo que hubo que hacer unos arreglos para que funcionara. El código fue generado por la IA ChatGPT.

Adjuntaré el código del parpadeo al final de la nota.

MCU CH32V307

Descargas:

PCB:
https://blog.maximi89.cl/ch32v307vc-size-m/

Esquemático:
https://blog.maximi89.cl/yd-ch32v307vct6-sch/

Hoja de datos:

https://blog.maximi89.cl/ch32v307ds0/

Para compilar el código desde el ELF al BIN:

riscv64-unknown-elf-objcopy -O binary CH32V307VCT6Pro2.elf CH32V307VCT6Pro2.bin && ~/Programacion/wchisp/target/release/wchisp flash CH32V307VCT6Pro2.bin

Básicamente, deben posicionarse en la carpeta en donde tienen su proyecto, para que al momento de que la aplicación lo convierta, te genere el archivo que necesitas, osea el “.bin”. Luego, wchisp intentará pasar el archivo CH32V307VCT6Pro2.bin a tu MCU, recuerda que debes tenerlo en modo ISP (presionar BOOT0 + RESET para entrar en modo ISP), osea que aparecerá al hacer en consola “lsusb”, listado como:

Bus 005 Device 006: ID 4348:55e0 WinChipHead

Al pasar exitosamente tu código al MCU, quedará simplemente como esto:


maximi89@maximi89-X870-EAGLE-WIFI7:~/mounriver-studio-projects/CH32V307VCT6Pro2/obj$ riscv64-unknown-elf-objcopy -O binary CH32V307VCT6Pro2.elf CH32V307VCT6Pro2.bin && ~/Programacion/wchisp/target/release/wchisp flash CH32V307VCT6Pro2.bin
09:03:32 [INFO] Opening USB device #0
09:03:32 [INFO] Chip: CH32V307VCT6[0x7017] (Code Flash: 256KiB)
09:03:32 [INFO] Chip UID: 61-E3-BE-AA-54-50-AA-AA
09:03:32 [INFO] BTVER(bootloader ver): 02.90
09:03:32 [INFO] Code Flash protected: false
09:03:32 [INFO] Current config registers: a55a9f6000ff00ffffffffff0002090061e3be7b545073af
RDPR_USER: 0x609F5AA5
[7:0] RDPR 0xA5 (0b10100101)
- Unprotected [16:16] IWDG_SW 0x1 (0b1) - IWDG enabled by the software, and disabled by hardware
[17:17] STOP_RST 0x1 (0b1)
- Disable [18:18] STANDBY_RST 0x1 (0b1) - Disable, entering standby-mode without RST
[23:22] SRAM_CODE_MODE 0x2 (0b10)
- CODE-256KB + RAM-64KB DATA: 0xFF00FF00 [7:0] DATA0 0x0 (0b0) [23:16] DATA1 0x0 (0b0) WRP: 0xFFFFFFFF - Unprotected
09:03:32 [INFO] Read CH32V307VCT6Pro2.bin as Binary format
09:03:32 [INFO] Firmware size: 8192
09:03:32 [INFO] Erasing…
09:03:32 [INFO] Erased 9 code flash sectors
09:03:33 [INFO] Erase done
09:03:33 [INFO] Writing to code flash…
██████████████████████████████████████████████████████████████████████ 8192/819209:03:33 [INFO] Code flash 8192 bytes written
09:03:34 [INFO] Verifying…
██████████████████████████████████████████████████████████████████████ 8192/819209:03:34 [INFO] Verify OK
09:03:34 [INFO] Now reset device and skip any communication errors
09:03:34 [INFO] Device reset

Código:

#include “ch32v30x.h”
#include “ch32v30x_gpio.h”
#include “ch32v30x_rcc.h”
#include “ch32v30x_misc.h”
#include <stdio.h> // Para printf
#include “debug.h”
#define LED1_PORT GPIOA
#define LED1_PIN GPIO_Pin_15
#define LED2_PORT GPIOB
#define LED2_PIN GPIO_Pin_4
/*********************************************************************
* @fn LED_Init
*
* @brief Inicializa LED1 y LED2 en modo salida push-pull
*
* @return none
*/
void LED_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = LED1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED1_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LED2_PIN;
GPIO_Init(LED2_PORT, &GPIO_InitStructure);
}
/*********************************************************************
* @fn main
*
* @brief Main program.
*
* @return none
*/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SystemCoreClockUpdate(); // actualiza variable SystemCoreClock
Delay_Init();
USART_Printf_Init(115200); // USART1 TX en PA9
LED_Init(); // inicializa los LEDS
printf(“SystemClk:%d\r\n”, SystemCoreClock);
printf(“ChipID:%08x\r\n”, DBGMCU_GetCHIPID());
printf(“LED blink and UART example\r\n”);
while(1)
{
GPIO_SetBits(LED1_PORT, LED1_PIN); // LED1 ON
GPIO_ResetBits(LED2_PORT, LED2_PIN); // LED2 OFF
printf(“LED1 ON, LED2 OFF\r\n”);
Delay_Ms(500);
GPIO_ResetBits(LED1_PORT, LED1_PIN); // LED1 OFF
GPIO_SetBits(LED2_PORT, LED2_PIN); // LED2 ON
printf(“LED1 OFF, LED2 ON\r\n”);
Delay_Ms(500);
}
}