CommunityGD32Cores / gd32-pio-projects

PlatformIO test projects for the new GD32 platform and arduino core
42 stars 10 forks source link

Best approach to get an ADC to serial example working on a board/chip like F1x0? #3

Closed crosswick closed 2 years ago

crosswick commented 2 years ago

Hi - I see that in terms of ADC examples, there's currently only two for the F30x range.

When I simply open the polling one of those and add my F1x0 board to the platform.ini and the include, I get a bunch of errors, amongst which:

src/main.c:64:22: error: 'GPIO_MODE_AF_PP' undeclared (first use in this function); did you mean 'GPIO_MODE_AF'?
   64 |     gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
      |                      ^~~~~~~~~~~~~~~
      |                      GPIO_MODE_AF
src/main.c:64:22: note: each undeclared identifier is reported only once for each function it appears in
src/main.c:65:22: error: 'GPIO_MODE_IN_FLOATING' undeclared (first use in this function); did you mean 'GPIO_MODE_ANALOG'?
   65 |     gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
      |                      ^~~~~~~~~~~~~~~~~~~~~
      |                      GPIO_MODE_ANALOG
src/main.c: In function 'rcu_config':
src/main.c:102:29: error: 'RCU_ADC0' undeclared (first use in this function); did you mean 'RCU_ADC'?

Do the APIs for these chips indeed differ in this way? I'd be happy to learn the best approach here, thanks in advance.

maxgerhardt commented 2 years ago

Yeah using the different API styles for analog reads can be done, the code will just get a but messy with it. I'll expand the examples.

maxgerhardt commented 2 years ago

If your goal is to have one clean project with code only targeting the F1x0, you should be taking the code from the official SPL example that's always in the SPL firmware folders: https://github.com/CommunityGD32Cores/gigadevice-firmware-and-docs/blob/main/GD32F1x0/GD32F1x0_Firmware_Library_V3.3.2/Examples/ADC/ADC0_software_trigger_regular_channel_polling/main.c

Most of the SPL project here are based on these projects, and slightly modified to work in a few more configurations.

crosswick commented 2 years ago

Ah great, thank you, that will certainly do for now for me.

crosswick commented 2 years ago

So far I'm copying over code from that to the SPL USART example, and am finding this error:

image

Perhaps this is something unique introduced in the 3.3.2 firmware, and not yet supported somehow?

maxgerhardt commented 2 years ago

Oops yes, the SPL repo currently works with the older firmware package version 3.1.0, not 3.3.2 (https://github.com/CommunityGD32Cores/gd32-pio-spl-package/blob/main/gd32/cmsis/variants/gd32f1x0/gd32f1x0.h#L6-L13). You should be using the suggested ADC_EXTTRIG_REGULAR_SWRCST there for the older version.

crosswick commented 2 years ago

Alright - then it still is not working somehow; it seems to lock up on the adc_channel_sample function call here:

 //int i = 0;
    while (1)
    {
        adc_value[0] = adc_channel_sample(ADC_CHANNEL_1);
        printf("Hello World\n");
        //printf("GPIOA1 is seeing a value of: %u\n", adc_value[0]);
        //printf("a usart transmit test example! iteration %d\n", i++);
        delay_1ms(500);
    }

Because this doesn't output anything over serial... when I comment out that adc_value line it does output the HelloWorlds

crosswick commented 2 years ago

I think there might be some more dependencies? The 'ADC software trigger regular channel polling' example did not exist yet in 3.1.0...

I might better use a different 3.1.0 example or wait a bit for your expanded examples.

maxgerhardt commented 2 years ago

The closest reference example is https://github.com/CommunityGD32Cores/gigadevice-firmware-and-docs/blob/main/GD32F1x0/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/main.c for V_TEMP and it does the adc_config() a bit differently, especially with adc_external_trigger_config(ADC_INSERTED_CHANNEL,ENABLE); and adc_inserted_channel_config(0,ADC_CHANNEL_16,ADC_SAMPLETIME_239POINT5); for the trigger configuration.

I'll update the SPL package to 3.3.1 quickly so that these issues are resolved, no point in staying on the older version.

maxgerhardt commented 2 years ago

Please open a CLI and execute pio platform update gd32, then try the project https://github.com/CommunityGD32Cores/gd32-pio-projects/tree/main/gd32-spl-adc-polling-gd32f1x0

crosswick commented 2 years ago

Will do, afk now

crosswick commented 2 years ago

I'm getting misformatted usart messages:

<␀␜�␎␀␇�␞�␇ �X␃�␜␀␏�␀��<@␆�␀� �␜�␎u␇␅␝ �8�<�␜␇�␜B␏�␃�␁�␜Ȱ�␜��8@␏��␀�<␀␏␀␇�␞�␀␃␆�:�␝�␕0␌␀␞�␀␃␃�␃�␝�J␆���␃�8@��␁ ��␝�<␀␇�

maxgerhardt commented 2 years ago

Oh, I forgot to se monitor_speed = 115200 at the top.

Fixed in https://github.com/CommunityGD32Cores/gd32-pio-projects/commit/84ea6ce6016bb0daf7cb57d0b811c81f070ff52a

crosswick commented 2 years ago

Yes that did the trick. Not that it's super important for my current application, but: I am seeing a reported value of 2.11V when I input 2V according to my bench power supply

maxgerhardt commented 2 years ago

When you replace ADC_SAMPLETIME_7POINT5 with ADC_SAMPLETIME_239POINT5 in the code, does it get more accurate? What does the connection to the analog-power rails VDDA and VSSA look like? It should have some decoupling / filtering going on like this in the hardware.

Also the value will fluctuate if VDDA is not exactly the expected 3.300000V.

crosswick commented 2 years ago

Looks like it was down to the 3.2V from my USB-USART dongle. When I power the board via USB the value is much closer to 2V, namely 1.98V

maxgerhardt commented 2 years ago

The microcontroller (every gd32 chip basically) has the capability to measure a V_REFINT internal reference voltage (1.2V per user manual page 239) and with that one can get the actual supply voltage and correct the ADC count -> voltage conversion adc_value[i] * 3.3f / 4095.f with respect to the statically-assumed 3.3V value there. There is example code for reading VREFINT (and VTEMP and VBAT) at https://github.com/CommunityGD32Cores/gigadevice-firmware-and-docs/blob/main/GD32F1x0/GD32F1x0_Firmware_Library_v3.1.0/Examples/ADC/Temperature_Vref_Vbat/main.c, that plus a bit of math will make the measurements much more correct -- not implented in the example for simplicity though.

crosswick commented 2 years ago

Good to know! As far as I'm concerned this issue is now resolved, thanks again for your swift assistance