openwch / arduino_core_ch32

Core library for CH32duino
269 stars 52 forks source link

analogRead() on CH32V003A4M6 only returns 0 #94

Open beehphy opened 6 months ago

beehphy commented 6 months ago

I am using the CH32V00x configuration when compiling. Programming goes fine. Log:

Info : WCH-LinkE  mode:RV version 2.12 
Info : wlink_init ok
Info : clock speed 6000 kHz
Info : [wch_riscv.cpu.0] datacount=2 progbufsize=8
Info : [wch_riscv.cpu.0] Examined RISC-V core; found 1 harts
Info : [wch_riscv.cpu.0]  XLEN=32, misa=0x40800014
[wch_riscv.cpu.0] Target successfully examined.
Info : starting gdb server for wch_riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections
** Programming Started **
Info : device id = 0xc7a4abcd
Info : flash size = 16kbytes
** Programming Finished **
** Verify Started **
** Verified OK **

I have attempted many line configurations analogRead(PIN_A0) analogRead(PA2) analogRead(A0) All return 0

This package variant should work, yes? The V003-EVT uses F4P6 but that code should still work on A4M6 as long as I use pins that are exposed right? I tested Serial outputs and digitalWrite() working just fine, but no analog reads.

Arduino Studio 2.3.2 Boards Mgr Rev 1.0.4 WCH-Link hw:1v3

maxint-rd commented 6 months ago

I have used ADC on the CH32V003J4M6 (the SOP8 package). I first had to make sure ADC was enabled in .../variants/CH32V00x/CH32V004F4/variant_CH32V003F4.h: #define ADC_MODULE_ENABLED // no difference in flash usage`

After that I had no trouble using the regular ADC channels. However to read PADC_VREF to be able to calculate VCC, I had to implement a workaround in analogInputToPinName() in pins_arduino.cpp. (vRef is about 1.2V: "VREFINT Internal reference voltage TA = -40℃~85℃ Min:1.17 Typ:1.2 Max:1.23 V").

Have you checked to see that ADC is enabled?

beehphy commented 6 months ago

Thank you, that was definitely the fix. I guess I assumed all peripherals would be enabled by default. Or I didn't contemplate they would have #define to enable them.

Why wouldn't the ADC be enabled by default? Power management? code size? Is there compelling reason to toggle these on and off with each build?

maxint-rd commented 6 months ago

Been there, done that... In my case it was enabling SPI. Most of us made that assumption. In Arduino land we're not used to make configurations that way. I prefer to set my options in the IDE.

Reason might be both. Some of these defines definitely affect code size. For some it doesn't matter. I use the CH32V003 which is limited to 16kB programming flash that can fill up quickly. Multiple times I had to select which features I needed most and dump the rest.

After finding out that my chips without crystal ran at incorrect speed, I also needed to change a header file. For my own projects I added such option to the IDE. Someone else posted the same change as PR. I still want to make a change that puts all peripheral options in the IDE.

Finally be aware that this Arduino core isn't very mature yet. Other people and myself proposed several changes to make the core more usefull (eg. implement Serial.available(), i2c-slave mode, ADC vRef/VCC, Eeprom emulation, etc). Some suggestions are submitted as PR, some others can be found reading through the issues. I think the CH32 family could be a great addition to the Arduino world, if only it would get a bit more TLC...

beehphy commented 6 months ago

There do seem to be some issues here. Not all the channels are plumbed correctly. Signal source: 0.1Hz 0-5V Sine

With this code installed:

#define ANALOG_PIN PIN_A0
void setup() {
  Serial.begin(115200);  //setup debug
}

void loop() {
  Serial.print(" >\n< ");
  Serial.print(analogRead(ANALOG_PIN));
  delay(250);
}

When deployed to the CH32X035 this is the result: image

When deployed to the CH32V003 this is the result: image

So A0 is broken. A1 is also broken.

If I set #define ANALOG_PIN PIN_A2 and change signal then I get a good result: image

maxint-rd commented 6 months ago

In my project I use the CH32V003J4M6 (the SOP8 package). I checked my code and saw that it uses A2 as pin name. I also saw it calls pinMode() in setup(): pinMode(MY_ADC_INPUT, INPUT); // CH32 extension INPUT_ANALOG gives same results as INPUT

Since your A4M6 has OSCO and OSCI on the same pins as A0 and A1, I assume you're using the internal oscillator. Have you also tried to call pinMode() to see if it makes a difference?