🤖

CH32V003J4M6マイコンとch32v003funを使ってみる

2023/10/15に公開

前回Platformio+RTOS環境でch32v203向けのプログラム環境を確認しました。

今回はch32v003について開発環境の確認してみます。ch32v003はRTOSサポートしてないので、直接レジスタを設定するOSレスな開発になります。その場合、ch32v003funというGithubリポジトリで開発環境とサンプルが一番揃っている感じなので、使い方を試してみました。

利用するマイコンは、8ピンのCH32V003J4M6です。ほかにWCH-LinkEが必要になります。

Github
https://github.com/cnlohr/ch32v003fun

開発環境のインストール

Win環境はいろいろ試してみようと思いましたが断念。WSLであればビルドはできるけど、USBに接続してアップロードするところについて、ツールを使わないと接続できない不便さで却下。結局Ubuntu22.04稼働するPCで作業しています。(ラズパイとかでも良いので、Ubuntu環境で作業できると捗ると思います。)

Install方法は以下を参考
https://github.com/cnlohr/ch32v003fun/wiki/Installation

自分の環境だと依存関係の問題が発生してました。

> sudo apt-get install build-essential libnewlib-dev gcc-riscv64-unknown-elf libusb-1.0-0-dev libudev-dev
:
以下のパッケージには満たせない依存関係があります:
 libudev-dev : 依存: libudev1 (= 249.11-0ubuntu3.7) しかし、249.11-0ubuntu3.9 はインストールされようとしています
E: 問題を解決することができません。壊れた変更禁止パッケージがあります。

libudev-dev249.11-0ubuntu3.9に対応した新しいパッケージがリポジトリになさそうです。sources.listには以下の2つのリポジトリが指定されています。

deb http://jp.archive.ubuntu.com/ubuntu/ jammy main restricted
deb http://jp.archive.ubuntu.com/ubuntu/ jammy-security main restricted

いずれ上記リポジトリに反映されると思いますが、とりあえずもう一つ以下のリポジトリを追加したら。依存関係パスしてインストールできました。

deb http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted universe multiverse
> sudo apt update
> sudo apt-get install build-essential libnewlib-dev gcc-riscv64-unknown-elf libusb-1.0-0-dev libudev-dev

WCH-LinkEのセットアップ

モジュールのアップロードやデバッグでWCH-LinkEが必要になります。

https://akizukidenshi.com/catalog/g/gM-18065/

WCH-LinkUtilityを使って1回だけRISC-Vモードに変更する必要がありますが割愛。
注意点として

  • 必ず最新版のツールをDLして使う。
  • 1回はファームウェアのアップデートしないといけないと思う。失敗するとゴミになるらしい。。(もう1個購入してファームウェアを書き換えることはできる)

UbuntuでWCH-LinkE使う場合、ひょっとするとパーミッションがなくて使えない可能性がある。毎回chmodでパーミッション変更はメンドクサイので以下手順で自動化してます。

WCH-LinkEをPCに刺したら、lsusbでIDを確認する。

> lsusb
Bus 003 Device 005: ID 1a86:8010 QinHeng Electronics WCH-Link

上記デバイスが接続されたら、plugdevグループのパーミッションを指定する。

cd /etc/udev/rules.d
sudo vi 10-wch-linke.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="1a86", ATTR{idProduct}=="8010", MODE="0666", GROUP="plugdev"

plugdevグループに開発ユーザを追加。マシン再起動。

sudo gpasswd -a $USER plugdev
sudo chmod a+r /etc/udev/rules.d/10-wch-linke.rules

sudo reboot

CH32V003J4M6でBlinkサンプル

CH32V003のリファレンスマニュアル
https://www.wch-ic.com/downloads/CH32V003RM_PDF.html

ch32v003-01.png
ch32v003-02.png

サンプルのexamples/blinkを最小限まで減らしたコードです。5番ピンのPC1を出力にしてLEDを光らせてみる。

Makefile

all : flash

TARGET:=blink

include ../../ch32v003fun/ch32v003fun.mk

flash : cv_flash
clean : cv_clean

blink.c

#include "ch32v003fun.h"
#include <stdio.h>

int main()
{
	SystemInit();

	// Enable GPIOs GPIOC
	RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;

  // 0000000011110000を反転してクリア
	GPIOC->CFGLR &= ~(0xf<<(4*1)); 
  // 10MHz, Output Push Pull
	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*1); 
	
	while(1)
	{
		// Turn on PC1
		GPIOC->BSHR = (1<<1);
		Delay_Ms( 250 );

		// Turn off PC1
		GPIOC->BSHR = (1<<(16+1));
		Delay_Ms( 250 );
	}
}

基本的にch32v003funはレジスタを直接設定しながら開発するスタイルで、隠蔽化されてないです。GPIOの設定とON/OFFする方法をリファレンス見ながら確認してみます。

まずSystemInit()を最初に1回だけコールしています。お約束コードです。

#include "ch32v003fun.h"
#include <stdio.h>

int main()
{
	SystemInit();
  :
}

3.3.5.2 AHB Bus Peripheral Clock (HCLK)
AHB、APB1、APB2のバスでグループ化されていて、GPIOCはAPB2にカテゴリ化されているっぽい。このAPB2を有効化します。デフォルトでは、省エネのため無効化されていているみたいです。

// Enable GPIOs GPIOC
RCC->APB2PCENR |= RCC_APB2Periph_GPIOC;

7.3.1.1 Port Configuration Register Low (GPIOx_CFGLR) (x=A/C/D)
PC1のGPIO設定

// 0000000011110000を反転してクリア
GPIOC->CFGLR &= ~(0xf<<(4*1));
// 10MHz, Output Push Pull
GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*1);

リファレンスを見ると、クロックの設定とモードを指定する必要がある。

7.3.1.4 Port Reset/Set Register (GPIOx_BSHR) (x=A/C/D)
GPIOピンのON/OFF設定

// Turn on PC1
GPIOC->BSHR = (1<<1);

// Turn off PC1
GPIOC->BSHR = (1<<(16+1));

上位16ビットがOFF、下位16ビットがONと読み取れる。

ビルド&アップロード

ch32v003funmakeするとコンパイルとアップロードをまとめてやってくれる仕組みですので、ハードウェア側のセットアップをあらかじめしておきます。(してなくてもコンパイルまではできると思いますが)

このあたりは、Makefileのカスタマイズとかすると、自分好みにできるとは思いますが、まだ理解が追い付いてないです。

CH32V003J4M6 回路
VSS WCH-LinkEのGND
VDD WCH-LinkEの3V3, GND間に1uFのコンデンサ
PC1 10kΩ=>LED=>GND
SWIO WCH-LinkEのSWDIO
なし WCH-LinkEのSWCLK

> make
riscv64-unknown-elf-gcc -o blink.elf ../../ch32v003fun/ch32v003fun.c blink.c -g -Os -flto -ffunction-sections -static-libgcc -march=rv32ec -mabi=ilp32e -I/usr/include/newlib -I../../ch32v003fun/../extralibs -I../../ch32v003fun -nostdlib -I. -Wall  -T ../../ch32v003fun/ch32v003fun.ld -Wl,--gc-sections -L../../ch32v003fun/../misc -lgcc
riscv64-unknown-elf-size blink.elf
   text    data     bss     dec     hex filename
    460       0       0     460     1cc blink.elf
riscv64-unknown-elf-objdump -S blink.elf > blink.lst
riscv64-unknown-elf-objdump -t blink.elf > blink.map
riscv64-unknown-elf-objcopy -O binary blink.elf blink.bin
riscv64-unknown-elf-objcopy -O ihex blink.elf blink.hex
make -C ../../ch32v003fun/../minichlink all
make[1]: Entering directory '/home/ubuntu/work/ch32v003fun/minichlink'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/ubuntu/work/ch32v003fun/minichlink'
../../ch32v003fun/../minichlink/minichlink -w blink.bin flash -b
Found WCH Link
WCH Programmer is LinkE version 2.10
Chip Type: 003
Setup success
Flash Storage: 16 kB
Part UUID    : ab-d0-ab-cd-13-f8-bc-5b
PFlags       : ff-ff-ff-ff
Part Type (B): 07-13-bb-91
Read protection: disabled
Interface Setup
Image written.

一連の操作が成功して、Lチカできました。

PlatformIO経由だとCH32V200系、CH32V300系のサンプルは割とあるのですが、003系は少ないのとRTOS使えないのでレジストリ操作に終始するマイコン開発になる感じがします。その場合は、このch32v003funの開発環境を使うのが便利だと思います。

ch32v003funと関連あるほかのリポジトリ

ch32v003funとCH32V003を使ってUSBデバイスを開発しているリポジトリ。USB接続デバイス作成するときはここ参考にすると良いかもしれない。
https://github.com/cnlohr/rv003usb/

次回は、ADC読み取り、CH32V003内蔵のオペアンプを使うプログラム?を作成する予定です。

Discussion