/* * CH224K USB PD Voltage Selector * MCU: CH32V003F4P6 (WCH RISC-V) * * Cycles through 5V → 9V → 12V → 15V → 20V on each button press. * Drives CH224K CFG1/CFG2/CFG3 pins to set the requested PD voltage * and lights the corresponding indicator LED. * * Pin mapping (from schematic): * PD2 → CFG1 (CH224K pin 9) * PD3 → CFG2 (CH224K pin 2) * PD4 → CFG3 (CH224K pin 3) * PC0 → LED1 (5V indicator) * PC1 → LED3 (9V indicator) * PC2 → LED4 (12V indicator) * PC3 → LED5 (15V indicator) * PC4 → LED6 (20V indicator) * PC6 → SW3 (push button, 10k pull-down via R2, press = HIGH) * LED2 is hardware-driven by CH224K PG (power-good, open-drain active-low) * * LED1/3/4/5/6 are ACTIVE-HIGH: anodes on PC0-PC4, cathodes share * R12 (1k) to GND. Pin HIGH = LED on. * * CH224K level-configuration truth table (datasheet §5.2.2): * CFG1 CFG2 CFG3 │ Voltage * ───────────────────────────── * 1 - - │ 5 V * 0 0 0 │ 9 V * 0 0 1 │ 12 V * 0 1 1 │ 15 V * 0 1 0 │ 20 V */ #include "debug.h" /* ---------- CFG pins (Port D) ---------- */ #define CFG1_PIN GPIO_Pin_2 /* PD2 */ #define CFG2_PIN GPIO_Pin_3 /* PD3 */ #define CFG3_PIN GPIO_Pin_4 /* PD4 */ #define CFG_ALL (CFG1_PIN | CFG2_PIN | CFG3_PIN) /* ---------- LED pins (Port C, active-HIGH) ---------- */ #define LED_5V GPIO_Pin_0 /* PC0 – LED1 */ #define LED_9V GPIO_Pin_1 /* PC1 – LED3 */ #define LED_12V GPIO_Pin_2 /* PC2 – LED4 */ #define LED_15V GPIO_Pin_3 /* PC3 – LED5 */ #define LED_20V GPIO_Pin_4 /* PC4 – LED6 */ #define LED_ALL (LED_5V | LED_9V | LED_12V | LED_15V | LED_20V) /* ---------- Button pin (Port C) ---------- */ #define BTN_PIN GPIO_Pin_6 /* PC6 – SW3 */ /* Lookup tables indexed by mode (0-4 → 5V,9V,12V,15V,20V) */ static const uint8_t cfg1_table[] = { 1, 0, 0, 0, 0 }; static const uint8_t cfg2_table[] = { 0, 0, 0, 1, 1 }; static const uint8_t cfg3_table[] = { 0, 0, 1, 1, 0 }; static const uint16_t led_table[] = { LED_5V, LED_9V, LED_12V, LED_15V, LED_20V }; volatile uint8_t modeIndex = 0; /* 0=5V … 4=20V */ static uint8_t btn_prev = 0; /* ---------------------------------------------------------- */ void GPIO_Config(void) { GPIO_InitTypeDef gpio = {0}; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE); /* PC0-PC4: push-pull outputs (LEDs) */ gpio.GPIO_Pin = LED_ALL; gpio.GPIO_Mode = GPIO_Mode_Out_PP; gpio.GPIO_Speed = GPIO_Speed_30MHz; GPIO_Init(GPIOC, &gpio); /* PC6: floating input (button – external 10k pull-down via R2) */ gpio.GPIO_Pin = BTN_PIN; gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOC, &gpio); /* PD2-PD4: push-pull outputs (CH224K CFG1/CFG2/CFG3) */ gpio.GPIO_Pin = CFG_ALL; gpio.GPIO_Mode = GPIO_Mode_Out_PP; gpio.GPIO_Speed = GPIO_Speed_30MHz; GPIO_Init(GPIOD, &gpio); /* LEDs off at start (active-high: LOW = off) */ GPIO_ResetBits(GPIOC, LED_ALL); } /* Drive CFG1/CFG2/CFG3 to the CH224K */ static void setCFG(uint8_t c1, uint8_t c2, uint8_t c3) { if (c1) GPIO_SetBits(GPIOD, CFG1_PIN); else GPIO_ResetBits(GPIOD, CFG1_PIN); if (c2) GPIO_SetBits(GPIOD, CFG2_PIN); else GPIO_ResetBits(GPIOD, CFG2_PIN); if (c3) GPIO_SetBits(GPIOD, CFG3_PIN); else GPIO_ResetBits(GPIOD, CFG3_PIN); } /* Apply current mode: update CFG pins and light matching LED */ void applyMode(void) { /* All LEDs off */ GPIO_ResetBits(GPIOC, LED_ALL); /* Set CH224K configuration */ setCFG(cfg1_table[modeIndex], cfg2_table[modeIndex], cfg3_table[modeIndex]); /* Light the corresponding LED (active-high: HIGH = on) */ GPIO_SetBits(GPIOC, led_table[modeIndex]); } /* Poll button with debounce, advance mode on rising edge */ void readButton(void) { uint8_t btn_now = GPIO_ReadInputDataBit(GPIOC, BTN_PIN); if (btn_now == Bit_SET && btn_prev == Bit_RESET) { Delay_Ms(20); /* debounce */ if (GPIO_ReadInputDataBit(GPIOC, BTN_PIN) == Bit_SET) { modeIndex++; if (modeIndex >= 5) modeIndex = 0; applyMode(); } } btn_prev = btn_now; } /* ---------------------------------------------------------- */ int main(void) { SystemCoreClockUpdate(); Delay_Init(); GPIO_Config(); /* Boot into 5V – the safest default */ modeIndex = 0; applyMode(); while (1) { readButton(); } }