Author Topic: [SOLVED] CH32V003F4P6-R0-1v1: can't seem to use PA1/PA2 as GPIO  (Read 1038 times)

0 Members and 1 Guest are viewing this topic.

Offline salfterTopic starter

  • Contributor
  • Posts: 25
  • Country: us
    • My Blog
[SOLVED] CH32V003F4P6-R0-1v1: can't seem to use PA1/PA2 as GPIO
« on: November 18, 2023, 05:45:23 am »
I have a project in which I'm looking to replace an ATTINY85 with a CH32V003J4M6.  It'll use three buttons to control a PWM output: increase duty cycle, decrease duty cycle, toggle on/off.

I have some chips on order, but in the meantime I have an eval board with a CH32V003F4P6 on it.  Its capabilities are a superset of what I'm eventually targeting, so I can get to work wrapping my head around the different libraries that are available and figure out which one works best.  So far, I'm gravitating toward the ch32v003fun library, as it seems simple enough to do what I need it to do.  I've already run several of the examples: blink, GPIO, tim1_pwm, and probably some others.  I/O on the J4M6 is limited, so I'd like to be able to use PA1 and PA2 if necessary (I'll be running it without a crystal). 

As it happens, while the CH32V003F4P6-R0-1v1 eval board does have a crystal on it, it's not actually connected by default.  If I'm reading the schematic right, R4 and R5 need to be populated with jumpers to use the crystal.  Every attempt at using PA1 and PA2 for output, though, has failed.

Here's the ch32v003fun blink program, tweaked to hopefully toggle PA1 and PA2 along with some PC* and PD* pins:

Code: [Select]
#include "ch32v003fun.h"
#include <stdio.h>

int main()
{
SystemInit();

// enable GPIO on A1 and A2
AFIO->PCFR1 &= ~GPIO_Remap_PA1_2;

// Enable GPIOs
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA;

// GPIO A1 Push-Pull
GPIOA->CFGLR &= ~(0xf<<(4*1));
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*1);

// GPIO A2 Push-Pull
GPIOA->CFGLR &= ~(0xf<<(4*2));
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*2);

// GPIO D0 Push-Pull
GPIOD->CFGLR &= ~(0xf<<(4*0));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);

// GPIO D4 Push-Pull
GPIOD->CFGLR &= ~(0xf<<(4*4));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);

// GPIO D6 Push-Pull
GPIOD->CFGLR &= ~(0xf<<(4*6));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*6);

// GPIO C0 Push-Pull
GPIOC->CFGLR &= ~(0xf<<(4*0));
GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);

while(1)
{
GPIOD->BSHR = (1<<0) | (1<<4) | (1<<6); // Turn on GPIOs
GPIOC->BSHR = (1<<0);
GPIOA->BSHR=(1<<1) | (1<<2);
Delay_Ms( 250 );
GPIOD->BSHR = (1<<16) | (1<<(16+4)) | (1<<(16+6)); // Turn off GPIOs
GPIOC->BSHR = (1<<16);
GPIOA->BSHR=(1<<(16+1)) | (1<<(16+2));
Delay_Ms( 250 );
}
}

I hoped that the line that clears the GPIO_Remap_PA1_2 bit in AFIO->PCFR1 would ensure that PA1 and PA2 were set up as GPIO pins instead of clock pins, and then the rest was a bit of cut-and-paste after reading the reference and figuring out what was happening.   When I connect an LED to PA1 or PA2, though, I still get nothing.  I must be doing something wrong, but I'll be damned if I can figure it out.  What am I missing?
« Last Edit: November 27, 2023, 04:59:50 pm by salfter »
 

Offline wek

  • Frequent Contributor
  • **
  • Posts: 495
  • Country: sk
Re: CH32V003F4P6-R0-1v1: can't seem to use PA1/PA2 as GPIO
« Reply #1 on: November 18, 2023, 06:41:59 am »
AFIO needs a clock to be enabled in RCC?

JW
 

Offline HwAoRrDk

  • Super Contributor
  • ***
  • Posts: 1478
  • Country: gb
Re: CH32V003F4P6-R0-1v1: can't seem to use PA1/PA2 as GPIO
« Reply #2 on: November 18, 2023, 03:19:33 pm »
Yeah, if you want to configure anything for AFIO, you need to enable its clock first.
 

Offline jnk0le

  • Contributor
  • Posts: 41
  • Country: pl
Re: CH32V003F4P6-R0-1v1: can't seem to use PA1/PA2 as GPIO
« Reply #3 on: November 18, 2023, 03:44:55 pm »
As it happens, while the CH32V003F4P6-R0-1v1 eval board does have a crystal on it, it's not actually connected by default.  If I'm reading the schematic right, R4 and R5 need to be populated with jumpers to use the crystal.  Every attempt at using PA1 and PA2 for output, though, has failed.

It's the other way. R4,R5 needs to be populated to connect headers to the PA1,PA2.
 

Offline salfterTopic starter

  • Contributor
  • Posts: 25
  • Country: us
    • My Blog
Re: CH32V003F4P6-R0-1v1: can't seem to use PA1/PA2 as GPIO
« Reply #4 on: November 21, 2023, 09:22:54 pm »
As it happens, while the CH32V003F4P6-R0-1v1 eval board does have a crystal on it, it's not actually connected by default.  If I'm reading the schematic right, R4 and R5 need to be populated with jumpers to use the crystal.  Every attempt at using PA1 and PA2 for output, though, has failed.

It's the other way. R4,R5 needs to be populated to connect headers to the PA1,PA2.

Oops...looks like I read the schematic incorrectly:

1934391-0

I had tried adding some additional initialization code as suggested earlier, but to no effect.  I'll need to try again after whacking the jumpers in.

Update: (27 Nov 11) Got it working...no tweaking of AFIO registers was necessary, just a couple of jumpers across R4 and R5 and a tweak to the second line of code:

Code: [Select]
#include "ch32v003fun.h"
#include <stdio.h>

int main()
{
SystemInit();

// Enable GPIOs
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA;

// GPIO A1 Push-Pull
GPIOA->CFGLR &= ~(0xf<<(4*1));
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*1);

// GPIO A2 Push-Pull
GPIOA->CFGLR &= ~(0xf<<(4*2));
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*2);

// GPIO D0 Push-Pull
GPIOD->CFGLR &= ~(0xf<<(4*0));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);

// GPIO D4 Push-Pull
GPIOD->CFGLR &= ~(0xf<<(4*4));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);

// GPIO D6 Push-Pull
GPIOD->CFGLR &= ~(0xf<<(4*6));
GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*6);

// GPIO C0 Push-Pull
GPIOC->CFGLR &= ~(0xf<<(4*0));
GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);

while(1)
{
GPIOD->BSHR = (1<<0) | (1<<4) | (1<<6); // Turn on GPIOs
GPIOC->BSHR = (1<<0);
GPIOA->BSHR=(1<<1) | (1<<2);
Delay_Ms( 250 );
GPIOD->BSHR = (1<<16) | (1<<(16+4)) | (1<<(16+6)); // Turn off GPIOs
GPIOC->BSHR = (1<<16);
GPIOA->BSHR=(1<<(16+1)) | (1<<(16+2));
Delay_Ms( 250 );
}
}
« Last Edit: November 27, 2023, 04:59:19 pm by salfter »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf