Skip to content

Add support for WCH CH32V series I2C controller#87922

Merged
kartben merged 5 commits intozephyrproject-rtos:mainfrom
andrei-edward-popa:wch_i2c
Apr 17, 2025
Merged

Add support for WCH CH32V series I2C controller#87922
kartben merged 5 commits intozephyrproject-rtos:mainfrom
andrei-edward-popa:wch_i2c

Conversation

@andrei-edward-popa
Copy link
Copy Markdown
Contributor

This PR adds a new I2C driver for the WCH CH32V series microcontrollers.
The driver implements standard I2C master functionality using the
hardware peripheral available on CH32V003 and similar WCH MCUs.

Features:

  • Supports standard (100 kHz) and fast mode (400 kHz) speeds.
  • Implements interrupt-driven transfers for efficient communication.

Tested on:

  • ch32v003evt
  • ch32v003f4p6_dev_board

@VynDragon
Copy link
Copy Markdown
Contributor

Thank you! I will take a look at this later and check it works with the other SoCs.

@VynDragon
Copy link
Copy Markdown
Contributor

So how did you actually test this? CH32V203 didnt work, i tried CH32V003 and found out neither bme280 or display (ssd1315) sample fit...

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

andrei-edward-popa commented Apr 1, 2025

So how did you actually test this? CH32V203 didnt work, i tried CH32V003 and found out neither bme280 or display (ssd1315) sample fit...

Hi @VynDragon! I created some samples that fits into ch32v003 like i2c scan and drivers for lcd 1602 and ds3231 here: https://github.com/andrei-edward-popa/zephyr/tree/wch_examples/samples/boards/wch. Can you try one of those? Also, a driver for mpu6050 is there, but I didn't test it because the chip hasn't arrived yet.

@miggazElquez
Copy link
Copy Markdown
Contributor

I tested it on the ch32v303 and it works fine. I didn't test the interrupts.

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

andrei-edward-popa commented Apr 1, 2025

I tested it on the ch32v303 and it works fine. I didn't test the interrupts.

Hi @miggazElquez! Thank you for checking it on ch32v303. If you do more tests and find some issues let me know.

@VynDragon
Copy link
Copy Markdown
Contributor

VynDragon commented Apr 1, 2025

I must be doing something wrong, i see no activity at all on the bus on either 203 or 003.

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

andrei-edward-popa commented Apr 1, 2025

I must be doing something wrong, i see no activity at all on the bus on either 203 or 003.

I guess you are using ch32v003evt, I didn't create the pinctrl.dtsi and enabled the i2c in dts for it, only for ch32v003f4p6_dev_board. Did you do it for ch32v003evt? If yes, did you enable gpioc?

@VynDragon
Copy link
Copy Markdown
Contributor

VynDragon commented Apr 1, 2025

Yea, Scratch the ch32v003 part, just got it working (hadnt fogotten anythinbg, not sure whjat was going on). with the example code, back to 203.

@VynDragon
Copy link
Copy Markdown
Contributor

Okay so still no activity with the display sample, but the scan sample shows activity on the bus (that looks like toggling pins and off though), but doesn't find anything.

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

Okay so still no activity with the display sample, but the scan sample shows activity on the bus (that looks like toggling pins and off though), but doesn't find anything.

Can you tell me what board are you using? I want to order one also.

@VynDragon
Copy link
Copy Markdown
Contributor

my dts overlay for the example code is:

#include <dt-bindings/pinctrl/ch32v20x_30x-pinctrl.h>
#include <zephyr/dt-bindings/i2c/i2c.h>

&pinctrl {
	i2c1_default: i2c1_default {
		group1 {
			pinmux = <I2C1_SDA_PB7_0>, <I2C1_SCL_PB6_0>;
			bias-pull-up;
			drive-open-drain;
			output-high;
			slew-rate = "max-speed-10mhz";
		};
	};
};


/ {
	aliases {
		i2c-0 = &i2c1;
	};
};

&i2c1 {
	status = "okay";

	pinctrl-0 = <&i2c1_default>;
	pinctrl-names = "default";
	clock-frequency = <I2C_BITRATE_STANDARD>;
};

i have added this:

		i2c1: i2c@40005400 {
			compatible = "wch,i2c";
			#address-cells = <1>;
			#size-cells = <0>;
			reg = <0x40005400 0x400>;
			clocks = <&rcc CH32V20X_V30X_CLOCK_I2C1>;
			interrupt-parent = <&pfic>;
			interrupts = <33>,<34>;
		};

to soc dts,
GPIOB (i2c1 on 20x) is already enabled, and i have checked the GPIO config is supposed to be correct.

@VynDragon
Copy link
Copy Markdown
Contributor

VynDragon commented Apr 1, 2025

Can you tell me what board are you using? I want to order one also.

Weactstudio ch32v203 blue pill plus (#87490), i'd do CH32V208RBT6 (gbu6/linkw doesnt have i2c1 pads, only i2c2 which i expect to not work due to not handling pinmux without remappings) on a breakout too but i didnt feel like plugging the 10 wires it needs for power (and if it works on 203 it works on 208)

@VynDragon
Copy link
Copy Markdown
Contributor

I tested it on the ch32v303 and it works fine. I didn't test the interrupts.

Did you actually test functionality or just build? 203 and 303 should be similar enough that if it works for you it should work for me.

Anyway bus looks like that:

image
image (all identical like this)

@VynDragon
Copy link
Copy Markdown
Contributor

VynDragon commented Apr 1, 2025

Figured my error, I read the wrong column for Interrupt numberm it works! (33 34 should be 47 48)

Edit: Display is still a no-go though, I have to ask drivers through i2c should work.

@VynDragon
Copy link
Copy Markdown
Contributor

Do not worry about going fast, PRs usually take a very long time to be merged

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

Do not worry about going fast, PRs usually take a very long time to be merged

Nono, I don't want to merge it fast, I want to make it work for all SoCs 😊

@andrei-edward-popa andrei-edward-popa force-pushed the wch_i2c branch 2 times, most recently from 308e4b6 to d45484b Compare April 16, 2025 18:21
@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

@VynDragon Hi, I get the board with CH32V203 and indeed the I2C was not working on it. I found the problem and I solved it. I tested on CH32V003 and CH32V203 with 3 I2C devices and on CH32V203 with an additional one, the ssd1306 display and it works. Can you check it?

@VynDragon
Copy link
Copy Markdown
Contributor

Yes it works 👍

Copy link
Copy Markdown
Contributor

@VynDragon VynDragon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works and I dont see any issue.

Comment thread drivers/i2c/i2c_wch.c
@VynDragon
Copy link
Copy Markdown
Contributor

I wanted to try with a different display, pulled SSD1363 out of the stack and it's having load address misaligned issue, currently debugging this to see if which driver / bit is having the issue (could be that a buffer needs to be aligned).

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

I wanted to try with a different display, pulled SSD1363 out of the stack and it's having load address misaligned issue, currently debugging this to see if which driver / bit is having the issue (could be that a buffer needs to be aligned).

Okay, let me know if it is something related to the driver.

@VynDragon
Copy link
Copy Markdown
Contributor

It fails in multithreading start, not too sure what it is unhappy about, but multithreading cannot be disabled due to the semaphore in this code. I will try a different display (a less 'heavy' one) and see if the issue happens still.

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

It fails in multithreading start, not too sure what it is unhappy about, but multithreading cannot be disabled due to the semaphore in this code. I will try a different display (a less 'heavy' one) and see if the issue happens still.

Can you increase the stack size of the main thread and isr? For CH32V203 it can be much bigger.

@VynDragon
Copy link
Copy Markdown
Contributor

VynDragon commented Apr 16, 2025

I tried a different display (one that wasnt hitting as close to ram limits, driver arch is still almost the same, part of my serie of oled drivers) and it's fine.
Found the issue, entirely my fault, broke the driver on my last push with a bad copy-paste 🤦
image
I2c driver is all good 👍 (this specific display browns out ch32v203's power supply instead now :) )

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

I tried a different display (one that wasnt hitting as close to ram limits, driver arch is still almost the same, part of my serie of oled drivers) and it's fine.
Found the issue, entirely my fault, broke the driver on my last push with a bad copy-paste 🤦
image
I2c driver is all good 👍 (this specific display browns out ch32v203's power supply instead now :) )

I see, I'm glad that the I2C driver is working fine now on all SoCs 😊

@VynDragon
Copy link
Copy Markdown
Contributor

VynDragon commented Apr 16, 2025

So i was testing with BME280 for reads and turns out it's not good for testing anymore, they changed it to use async API and it has no checks for whether i2c supports the async mode... Which resulted in another unexplainable crash...

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

andrei-edward-popa commented Apr 16, 2025

So i was testing with BME280 for reads and turns out it's not good for testing anymore, they changed it to use async API and it has no checks for whether i2c supports the async mode... Which resulted in another unexplainable crash...

Oh, I see :( For reads I tested with ds3231 (RTC) and mpu6050 (accelerometer + gyro + temp) and it works on both SoCs that I have. I tested 1 byte read, 2 bytes read and >=3 bytes read to see if the stop condition is generated ok for "corner cases" like 1 byte and 2 bytes (in manual they said that some things must be done if we want to receive only 1 or 2 bytes) and it works on all of this cases.

@VynDragon
Copy link
Copy Markdown
Contributor

VynDragon commented Apr 16, 2025

It's all good, after spending some time on it and asking around, it turned out to be a ch32v203 stack issue (like nzmichael warned about actually...), and the possible async issue isnt present either (apparently it should?).

The fix was to remove the stack size kconfigs in Kconfig.defconfig of ch32v203.

And yes BME280 reads work perfectly.

Comment thread drivers/i2c/i2c_wch.c
added i2c bindings for wch platforms

Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com>
added i2c node for ch32v003

Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com>
enabled i2c for ch32v003evt
added default i2c pins for ch32v003evt
added i2c as supported

Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com>
enabled i2c for ch32v003f4p6_dev_board
added default i2c pins for ch32v003f4p6_dev_board
added i2c as supported

Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com>
added i2c driver for wch platforms

Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com>
@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

It's all good, after spending some time on it and asking around, it turned out to be a ch32v203 stack issue (like nzmichael warned about actually...), and the possible async issue isnt present either (apparently it should?).

The fix was to remove the stack size kconfigs in Kconfig.defconfig of ch32v203.

And yes BME280 reads work perfectly.

That's great to know. Thank you for all of your testing, I'm very glad that the driver works now. :)

Copy link
Copy Markdown
Contributor

@VynDragon VynDragon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not push rebase at the same time as changes, it makes it impossible to tell easily what changed.

@andrei-edward-popa
Copy link
Copy Markdown
Contributor Author

Do not push rebase at the same time as changes, it makes it impossible to tell easily what changed.

Okay, good to know, thank you for all! 😊

@kartben kartben merged commit e4c2cec into zephyrproject-rtos:main Apr 17, 2025
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: I2C area: RISCV RISCV Architecture (32-bit & 64-bit) platform: WinChipHead WCH

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants