Created
August 26, 2024 15:59
-
-
Save xsrf/95522c0329f2a52c0f8900f439051f74 to your computer and use it in GitHub Desktop.
CH32V003 TIM1 ISR Debug LEDs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "ch32v003fun.h" | |
| #include <stdio.h> | |
| // LEDs on A1 and A2 (to GND) | |
| #define LED_PORT GPIOA | |
| #define LED_PIN1 1 | |
| #define LED_PIN2 2 | |
| void TIM1_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); | |
| void TIM1_UP_IRQHandler(void) { | |
| if (TIM1->INTFR & TIM_UIF) { | |
| LED_PORT->BSHR = 1<<(LED_PIN2+16); // LED2 OFF | |
| } | |
| if (TIM1->INTFR & ~TIM_UIF) { // TIM_UIF is 0x01 so this is true for every IF that's not 0x01 | |
| LED_PORT->BSHR = 1<<(LED_PIN1+16); // LED1 OFF | |
| } | |
| TIM1->INTFR = 0; | |
| } | |
| int main() | |
| { | |
| SystemInit(); | |
| RCC->APB2PCENR |= RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_TIM1 | RCC_APB2Periph_AFIO; | |
| LED_PORT->CFGLR &= ~(0xf<<(4*LED_PIN1)); | |
| LED_PORT->CFGLR &= ~(0xf<<(4*LED_PIN2)); | |
| LED_PORT->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*LED_PIN1); | |
| LED_PORT->CFGLR |= (GPIO_Speed_50MHz | GPIO_CNF_OUT_PP)<<(4*LED_PIN2); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED1 ON | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED2 ON | |
| Delay_Ms(100); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+16); // Set LED1 ON | |
| LED_PORT->BSHR = 1<<(LED_PIN2+16); // Set LED2 ON | |
| Delay_Ms(100); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED1 ON | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED2 ON | |
| // LED1/2 (100ms steps): 10.. (see below) | |
| // Reset TIM1 to init all regs | |
| RCC->APB2PRSTR |= RCC_APB2Periph_TIM1; | |
| RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1; | |
| TIM1->PSC = 48000-1; // 1kHz | |
| TIM1->ATRLR = 500-1; // 500ms | |
| // Timer CNT resets to 0 regardless of TIM_ARPE set or not | |
| TIM1->CTLR1 |= TIM_OPM; // | TIM_ARPE; // One-Pulse-Mode + Auto-Reload | |
| TIM1->DMAINTENR |= TIM_UIE; | |
| TIM1->SWEVGR |= TIM_UG; // REQUIRED to set the PSC correctly!!! | |
| TIM1->INTFR &= ~TIM_UIF; // Clears the Interrupt Flag set by TIM_UG before so it won't fire immediately! | |
| TIM1->CTLR1 |= TIM_CEN; | |
| NVIC_EnableIRQ(TIM1_UP_IRQn); // TIM1-Interrupt im NVIC aktivieren | |
| // By now LED1 is turned off because the Interrupt Handler is called immediately | |
| // LED2 is still untouched | |
| while(0) { | |
| ; | |
| } // Result: LED1 off after 500ms, LED2 off after 1s; OK | |
| // LED1 (100ms steps): ..000000000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| while(0) { | |
| Delay_Ms(10); | |
| } // Result: LED1 off after 500ms, LED2 off after 1s; OK | |
| // LED1 (100ms steps): ..000000000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| while(0) { | |
| Delay_Ms(99); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED_PIN1 HIGH | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED_PIN2 HIGH | |
| } // Result: LED1 blinks off for 100ms; Both turn off after 1s; They never turn on again; ERR | |
| // LED1 (100ms steps): ..011110000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| while(0) { | |
| Delay_Ms(100); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED_PIN1 HIGH | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED_PIN2 HIGH | |
| } // Result within ~16s after cold start: LED1 blinks off for 100ms; Both turn off after 1s; They never turn on again; ERR | |
| // LED1 (100ms steps): ..011110000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| // Result after ~16s: LED1 blinks off for 100ms then both STAY ON forever; OK | |
| // LED1 (100ms steps): ..011111111111111..1 | |
| // LED2 (100ms steps): ..111111111111111..1 | |
| while(0) { | |
| Delay_Ms(105); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED_PIN1 HIGH | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED_PIN2 HIGH | |
| } // Result (<16s): LED1 blinks off for 100ms; Both turn off after 1s; They never turn on again; ERR | |
| // LED1 (100ms steps): ..011110000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| // Result (>16s): LED1 blinks off for 100ms then both STAY ON forever; OK | |
| // LED1 (100ms steps): ..011111111111111..1 | |
| // LED2 (100ms steps): ..111111111111111..1 | |
| while(0) { | |
| Delay_Ms(400); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED_PIN1 HIGH | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED_PIN2 HIGH | |
| } // Result: LED1 blinks 100ms ON before both turn off after 1s; They never tun on again; ERR | |
| // LED1 (100ms steps): ..000010000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| while(0) { | |
| Delay_Ms(600); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED_PIN1 HIGH | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED_PIN2 HIGH | |
| } // Result within 16s: Result: LED1 off after 500ms, LED2 off after 1s; They never turn on again! ERR | |
| // LED1 (100ms steps): ..000000000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| // Result after 16s cold start: | |
| // LED1 (100ms steps): ..000001111111111..1 | |
| // LED2 (100ms steps): ..111111111111111..1 | |
| while(1) { | |
| Delay_Ms(1000); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+0); // Set LED_PIN1 HIGH | |
| LED_PORT->BSHR = 1<<(LED_PIN2+0); // Set LED_PIN2 HIGH | |
| Delay_Ms(1000); | |
| LED_PORT->BSHR = 1<<(LED_PIN1+16); // Set LED_PIN1 LOW | |
| LED_PORT->BSHR = 1<<(LED_PIN2+16); // Set LED_PIN2 LOW | |
| } // Result within ~16s: Result: LED1 off after 500ms, LED2 off after 1s; They never turn on again! ERR | |
| // LED1 (100ms steps): ..000000000000000..0 | |
| // LED2 (100ms steps): ..111110000000000..0 | |
| // Result after ~16s cold start: LED1 is turned ON after 500ms (+init above) even though it should still be in the 1s delay! | |
| // LED1 (100ms steps): ..00000111111111100000000001111111111000.. | |
| // LED2 (100ms steps): ..11111111111111100000000001111111111000.. | |
| /* | |
| The Chip is connected just with 5V, GND and SWD and a 0.1uF decoubling on 5V/GND. | |
| "cold boot" means I shorted 5V to GND (obviously with supply disconnected). | |
| Without "cold boot" the chip keeps some values like SysTick even after reset via minichlink/upload or just disconnecting 5V, | |
| probably because of current supplied by SWD and the cap. | |
| */ | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment