diff --git a/examples/systick_irq/README.md b/examples/systick_irq/README.md index 26e561ef98affb57cc7e1b2b8c752c089c86b81e..9ca11cb3c225054e2fe688168274efd48eff9adf 100644 --- a/examples/systick_irq/README.md +++ b/examples/systick_irq/README.md @@ -4,11 +4,11 @@ interrupts for timing. Many bare-metal and RTOS based embedded applications will use the Systick IRQ for timing, periodic housekeeping and task arbitration so knowing how to set that up is useful. -Note that this example is *NOT* compatible with the Delay_*() functions that are -part of the ch32v003fun library - those functions use the Systick counter for -doing busy-wait delays and assume that the CNT register rolls over at 32-bit -maximum. Do not use the built-in Delay_Ms() and related functions when using -Systick for IRQs. +This code is compatible with the busywait delay functions in the ch32v003fun +library because it allows the Systick CNT register to keep running over its full +32-bit range. It does not set the STRE bit in the CTRL register so the counter +does not reset when the CMP register matches. In order to do this, the CMP register +is advanced at every IRQ. Note also the use of the `__attribute__((interrupt))` syntax in declaring the IRQ handler. Some of the IRQ examples from the WCH HAL library have slightly diff --git a/examples/systick_irq_millis/Makefile b/examples/systick_irq_millis/Makefile deleted file mode 100644 index 641fc4cd43b6b16d9107b38143bb71cc0001d478..0000000000000000000000000000000000000000 --- a/examples/systick_irq_millis/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -all : flash - -TARGET:=systick_irq_millis - -CFLAGS+=-DSTDOUT_UART - -include ../../ch32v003fun/ch32v003fun.mk - -flash : cv_flash -clean : cv_clean - diff --git a/examples/systick_irq_millis/README.md b/examples/systick_irq_millis/README.md deleted file mode 100644 index f9d469a8e1efcd6bea087d822b0133785116b694..0000000000000000000000000000000000000000 --- a/examples/systick_irq_millis/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Systick IRQ demonstration -This example shows how to set up the built-in Systick IRQ to generate periodic -interrupts for timing. Many bare-metal and RTOS based embedded applications will -use the Systick IRQ for timing, periodic housekeeping and task arbitration so -knowing how to set that up is useful. - -Systick.h now also contains an arduino-like millis() function to return the -current time. -The example has been adapted to use this millis() function for a lock-free program. -Here, you compare the difference of current time and the last time a task was -executed against a desired interval. If enough time has passed, run the next -step. - -The benefit of this dance is that the CPU doesn't spend 250ms (12,000,000 -cycles!) drooling onto the carpet. -Other important tasks (reading buttons, DDoSing your grandma) can run until it's time. - -Of course a real RTos would be much more powerful. - -Note that this example is *NOT* compatible with the Delay_Ms() function that's -part of the ch32v003fun library - that function uses the Systick counter for -doing busy-wait delays and will interfere with its use in generating predictable -IRQs. Do not use the built-in Delay_Ms() and related functions when using Systick -for IRQs. - -Note also the use of the `__attribute__((interrupt))` syntax in declaring the -IRQ handler. Some of the IRQ examples from the WCH HAL library have slightly -different syntax to make use of a fast IRQ mode but which is not compatible with -generic RISC-V GCC so that feature is not used here. - -# Use -Connect LEDs (with proper current limit resistors) to GPIO pins C0, D0, D4 and -a 3.3V logic level serial terminal to PD5. The LEDs will flash and an incrementing -count will be printed to the serial port at rates that are controlled by the -Systick IRQ. diff --git a/examples/systick_irq_millis/systick.h b/examples/systick_irq_millis/systick.h deleted file mode 100644 index 1f3700e660fecb4821dfd9528404fc0c36118618..0000000000000000000000000000000000000000 --- a/examples/systick_irq_millis/systick.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Single-File-Header for using SysTick with millisecond interrupts - * 03-25-2023 E. Brombaugh - */ - -#ifndef _SYSTICK_H -#define _SYSTICK_H - -#include <stdint.h> - -/* some bit definitions for systick regs */ -#define SYSTICK_SR_CNTIF (1<<0) -#define SYSTICK_CTLR_STE (1<<0) -#define SYSTICK_CTLR_STIE (1<<1) -#define SYSTICK_CTLR_STCLK (1<<2) -#define SYSTICK_CTLR_STRE (1<<3) -#define SYSTICK_CTLR_SWIE (1<<31) - -volatile uint32_t systick_cnt; - -/* - * Start up the SysTick IRQ - */ -void systick_init(void) -{ - /* enable the SysTick IRQ */ - NVIC_EnableIRQ(SysTicK_IRQn); - - /* Clear any existing IRQ */ - SysTick->SR &= ~SYSTICK_SR_CNTIF; - - /* Set the tick interval to 1ms for normal op */ - SysTick->CMP = (SYSTEM_CORE_CLOCK/1000)-1; - - /* Start at zero */ - SysTick->CNT = 0; - systick_cnt = 0; - - /* Enable SysTick counter, IRQ, HCLK/1, auto reload */ - SysTick->CTLR = SYSTICK_CTLR_STE | SYSTICK_CTLR_STIE | - SYSTICK_CTLR_STCLK | SYSTICK_CTLR_STRE; -} - -#if 1 -/* - * SysTick ISR just counts ticks - * note - the __attribute__((interrupt)) syntax is crucial! - */ -void SysTick_Handler(void) __attribute__((interrupt)); -void SysTick_Handler(void) -{ - /* clear IRQ */ - SysTick->SR &= 0; - - /* update counter */ - systick_cnt++; -} -#endif - -/* - * Millisecond delay routine - */ -void systick_delay_ms(uint32_t milliseconds) -{ - /* compute end time */ - uint32_t etime = systick_cnt + milliseconds; - - /* wait for current time == end time */ - while(systick_cnt != etime); -} - -uint32_t millis() { - return systick_cnt; -} -#endif diff --git a/examples/systick_irq_millis/systick_irq_millis.c b/examples/systick_irq_millis/systick_irq_millis.c deleted file mode 100644 index b306cf6ff2cdeb3df15c5b6a7c27750dc07171b8..0000000000000000000000000000000000000000 --- a/examples/systick_irq_millis/systick_irq_millis.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Example for using SysTick with IRQs - * 03-25-2023 E. Brombaugh - */ - -// Could be defined here, or in the processor defines. -#define SYSTEM_CORE_CLOCK 48000000 -#define APB_CLOCK SYSTEM_CORE_CLOCK - -#include "ch32v003fun.h" -#include <stdio.h> -#include "systick.h" - -int main() -{ - uint32_t count = 0; - - SystemInit48HSI(); - - // start serial @ default 115200bps - SetupUART( UART_BRR ); - printf("\r\r\n\nsystick_irq example\n\r"); - - printf("SysTick_Handler = 0x%08X\n\r", SysTick_Handler); - - // init systick @ 1ms rate - printf("initializing systick..."); - systick_init(); - printf("done.\n\r"); - - // Enable GPIOs - RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC; - - // 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 C0 Push-Pull - GPIOC->CFGLR &= ~(0xf<<(4*0)); - GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*0); - - const uint16_t led_i = 250; - uint32_t led_t_last; - uint8_t led_progstep = 0; - - printf("looping...\n\r"); - while(1) - { - if (millis() - led_t_last >= led_i) { - switch (led_progstep) { - case 0: - GPIOD->BSHR = 1 | (1<<4); // Turn on GPIOs - break; - case 1: - GPIOC->BSHR = 1; - break; - case 2: - GPIOD->BSHR = (1<<16) | (1<<(16+4)); // Turn off GPIODs - break; - case 3: - GPIOC->BSHR = (1<<16); - printf( "Count: %lu\n\r", count++ ); - break; - } - led_progstep++; - led_t_last = millis(); - if (led_progstep > 3) { - led_progstep = 0; - } - } - } -}