[SOLVED] CH32V003F4P6-R0-1v1: can't seem to use PA1/PA2 as GPIO - Page 1
Forum section: electronics / general

author: salfter
author_rank: Contributor
timestamp: November 18, 2023, 05:45:23 am
content: 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:#include "ch32v003fun.h"#include <stdio.h>int main(){SystemInit();// enable GPIO on A1 and A2AFIO->PCFR1 &= ~GPIO_Remap_PA1_2;// Enable GPIOsRCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA;// GPIO A1 Push-PullGPIOA->CFGLR &= ~(0xf<<(4*1));GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*1);// GPIO A2 Push-PullGPIOA->CFGLR &= ~(0xf<<(4*2));GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*2);// GPIO D0 Push-PullGPIOD->CFGLR &= ~(0xf<<(4*0));GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);// GPIO D4 Push-PullGPIOD->CFGLR &= ~(0xf<<(4*4));GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);// GPIO D6 Push-PullGPIOD->CFGLR &= ~(0xf<<(4*6));GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*6);// GPIO C0 Push-PullGPIOC->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 GPIOsGPIOC->BSHR = (1<<0);GPIOA->BSHR=(1<<1) | (1<<2);Delay_Ms( 250 );GPIOD->BSHR = (1<<16) | (1<<(16+4)) | (1<<(16+6)); // Turn off GPIOsGPIOC->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?

author: wek
author_rank: Frequent Contributor
timestamp: November 18, 2023, 06:41:59 am
content: AFIO needs a clock to be enabled in RCC?JW

author: HwAoRrDk
author_rank: Super Contributor
timestamp: November 18, 2023, 03:19:33 pm
content: Yeah, if you want to configure anything for AFIO, you need to enable its clock first.

author: jnk0le
author_rank: Regular Contributor
timestamp: November 18, 2023, 03:44:55 pm
content: Quote from: salfter on November 18, 2023, 05:45:23 amIt's the other way. R4,R5 needs to be populated to connect headers to the PA1,PA2.

author: salfter
author_rank: Contributor
timestamp: November 21, 2023, 09:22:54 pm
content: Quote from: jnk0le on November 18, 2023, 03:44:55 pmOops...looks like I read the schematic incorrectly: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:#include "ch32v003fun.h"#include <stdio.h>int main(){SystemInit();// Enable GPIOsRCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA;// GPIO A1 Push-PullGPIOA->CFGLR &= ~(0xf<<(4*1));GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*1);// GPIO A2 Push-PullGPIOA->CFGLR &= ~(0xf<<(4*2));GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*2);// GPIO D0 Push-PullGPIOD->CFGLR &= ~(0xf<<(4*0));GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0);// GPIO D4 Push-PullGPIOD->CFGLR &= ~(0xf<<(4*4));GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);// GPIO D6 Push-PullGPIOD->CFGLR &= ~(0xf<<(4*6));GPIOD->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*6);// GPIO C0 Push-PullGPIOC->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 GPIOsGPIOC->BSHR = (1<<0);GPIOA->BSHR=(1<<1) | (1<<2);Delay_Ms( 250 );GPIOD->BSHR = (1<<16) | (1<<(16+4)) | (1<<(16+6)); // Turn off GPIOsGPIOC->BSHR = (1<<16);GPIOA->BSHR=(1<<(16+1)) | (1<<(16+2));Delay_Ms( 250 );}}