Open Witawat opened 11 months ago
I2C master is working. The AT24C02 eeprom example gives a demonstration. I tested that example with a bare EEPROM chip and it worked. Note however that error handling often results in a lockup. I've experimented to improve this. To get I2C scanning working some modifications are needed. It mainly involves resetting the I2C when there is no device at the specific address. (Have something working for myself, but not ready to publish a PR yet)
@maxint-rd can you please share your I2C scan?
Hello @0x0fe Eventually I modified /libraries/Wire/src/utility/twi.c to get the regular I2C scanning to work. Here you can find a scanning example: https://playground.arduino.cc/Main/I2cScanner/
For this fix I got inspiration from this example: https://github.com/mockthebear/easy-ch32v003/tree/main/examples/i2c_scanner
As stated before, my modifications are not ready for a PR yet. but perhaps they are useful as is. The main changes were:
These are the changes (line numbers were changed in the process, so for reference only):
:50
#define I2C_TIMEOUT_TICK 10 // shorter timeout to facilitate I2C scanning
:276 / :290 / :304
if((GetTick()-tickstart) > I2C_TIMEOUT_TICK)
{
// To allow I2C scanning, when a start condition times out the bus needs to be released
if(sendstop)
I2C_GenerateSTOP(obj->handle.Instance, ENABLE);
return I2C_TIMEOUT;
}
:314
if(size) // Support for I2C scanning: allow only sending the address (without actual data)
{
while(size)
{
if( I2C_GetFlagStatus(obj->handle.Instance, I2C_FLAG_TXE) != RESET )
{
I2C_SendData(obj->handle.Instance, *data++);
size--;
}
}
tickstart = GetTick();
while(!I2C_CheckEvent(obj->handle.Instance, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
if((GetTick()-tickstart) > I2C_TIMEOUT_TICK)
{
return I2C_TIMEOUT;
}
}
} // if(size)
:428
while(I2C_GetFlagStatus( obj->handle.Instance, I2C_FLAG_RXNE ) == RESET)
{
// at occasion the CH32 would just hang while reading the response. Still unknown why. but adding a timeout may prevent this
if((GetTick()-tickstart) > I2C_TIMEOUT_TICK)
{
I2C_GenerateSTOP( obj->handle.Instance, ENABLE );
return I2C_TIMEOUT;
}
}
@maxint-rd thank you, i will make the changes on my side (i use ch32x035 though)
Allright, unfortunately I have no CH32x035 to test with. I only bought a bunch of the CH32V003 and try to make the most of them. For one project I use I2C scanning to detect a slave device and then use I2C to read values to display them on an I2C-driven LCD. It works for me. Good luck with your project...
it should be alright, for some reason they disabled the I2C on their HAL for CH32X035, but i wil ltest soon, at least it compiles.
Perhaps you need to set a configuration option somewhere in a header file. They did something similar with SPI on the CH32v003. I also needed to change the configuration of the clock selection to be able to run bare chips without external crystal.
@maxint-rd yes, for those interested the option to re-enable the I2C in the HAL is here : https://github.com/openwch/arduino_core_ch32/blob/f14a216b441e03907d2c0c9afab03e3985ab6852/variants/CH32X035/CH32X035G8U/variant_CH32X035G8U.h#L19
@maxint-rd do you mind to share your twi.c file? seems like it has changed quite a bit since and i cannot quite match your diffs.
@TianpeiLee Since the pinmux is somewhat limited on CH32V and CH32X series, i suggest that you add a soft i2c and soft uart (at least TX) implementation directly in the core or as libraries so that users can still use alternative pins for uart output and i2c bus. For I2C this library can be used as is, i have tested it on CH32V003 and it works fine. https://github.com/yasir-shahzad/SoftI2C/blob/master/src/SoftI2C.cpp
@maxint-rd do you mind to share your twi.c file? seems like it has changed quite a bit since and i cannot quite match your diffs.
Hello @0x0fe ,
Attached is my current version: twi.zip I zipped the twi.c file to be able to attach it to this post. Note that this is my version, based on a version found in an earlier release of the WCH Arduino core. It may have been modified in the meanwhile. I marked most of my changes with a comment containing the tag "MMOLE:", but you may need to compare it to an earlier release to locate all changes. It works for me, but I can't guarantee it works for you...
@maxint-rd Can you open a PR with your changes to the Two-wire-library? Other people seem to be running into I2C issues too regarding I2C scanning, locking up after the first non-responding I2C address. Unfortunately the twi.zip
you linked above just gives me a "Request has expired" error message.
@maxint-rd I think there is two topics, re-enabling hardware I2C, with proper mux handling so that at least the two available ports can be used, and extending twi with soft i2c, so that any pin can be used, i tested both hardware I2C ports and soft I2C, on x035, everything works fine, so it is just a matter of updating the core now, unfortunately there is no ressources allocated on this core at wch, maybe if peoples submit PR they will eventually be merged.
@maxgerhardt - what do you mean by that error message? I just tried the link in the post above and it properly lets me download the zip containing my twi.c file. (BTW. A few posts higher I posted the changes I made to fix I2C scanning for my CH32V003).
I still need to install the latest core and then redo my changes. I would like to then post a PR. even though WCH hasn't really merge many of them in the past, I did see the occasional copying of suggested changes. Since I only have the CH32V003 I cannot test the others before proposing global changes.
@0x0fe - you're right. From what I've read the x035 seems to have some other issues as well, including batches without I2C altogether. I've also noticed a lack of allocated resources. That's a bit unfortunate since the CH32 is a nice family of chips that could be a good addition to the Arduino ecosystem. Without sufficient support I'm afraid many potential users may get disappointed and turn away...
@maxint-rd Can you open a PR with your changes to the Two-wire-library? Other people seem to be running into I2C issues too regarding I2C scanning, locking up after the first non-responding I2C address. Unfortunately the
twi.zip
you linked above just gives me a "Request has expired" error message.
@maxgerhardt - I saw some people asking for it on the Platformio forum. Since I don't use Platformio, I won't respond there. I recently shared my changes in a fork with a branch. All work in progress, so use at your own risk. No production quality code either, but it works for me...
I'm having some progress on getting I2C slave functions working on my CH32V003 as well. Hope to share that too (sometime...) When I do I'll probably use a shorter timeout, resulting in faster scanning too. Edit: I published something that seems to work. Those who dare can try the Wire library in this branch . I added basic examples for an I2C scanner and for a simple blinking slave. Work in progress - USE AT YOUR OWN RISK - No guarantees or support! -
Edit2: Tested ADC a bit and the regular Arduino function analogRead() seems to work.
Need SPI,I2C_Master, Easy ADC on CH32V003