diff --git a/examples/systick_irq/Makefile b/examples/systick_irq/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..c5d73486f1b7abb21cc6adad5054475e436f0eba --- /dev/null +++ b/examples/systick_irq/Makefile @@ -0,0 +1,41 @@ +TARGET:=systick_irq + +all : flash + +PREFIX:=riscv64-unknown-elf + +GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User + +CH32V003FUN:=../../ch32v003fun +MINICHLINK:=../../minichlink + +CFLAGS:= \ + -g -Os -flto -ffunction-sections \ + -static-libgcc -lgcc \ + -march=rv32ec \ + -mabi=ilp32e \ + -I/usr/include/newlib \ + -I$(CH32V003FUN) \ + -nostdlib \ + -I. -DSTDOUT_UART -Wall + +LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections + +SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c + +$(TARGET).elf : $(SYSTEM_C) $(TARGET).c + $(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS) + +$(TARGET).bin : $(TARGET).elf + $(PREFIX)-size $^ + $(PREFIX)-objdump -S $^ > $(TARGET).lst + $(PREFIX)-objdump -t $^ > $(TARGET).map + $(PREFIX)-objcopy -O binary $< $(TARGET).bin + $(PREFIX)-objcopy -O ihex $< $(TARGET).hex + +flash : $(TARGET).bin + $(MINICHLINK)/minichlink -w $< flash -b + +clean : + rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex + diff --git a/examples/systick_irq/systick.h b/examples/systick_irq/systick.h new file mode 100644 index 0000000000000000000000000000000000000000..e681d818f41432573f6f09283b05fcfb939ac016 --- /dev/null +++ b/examples/systick_irq/systick.h @@ -0,0 +1,80 @@ +/* + * 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; + +#if 0 + /* Set the tick interval to 1ms for normal op */ + SysTick->CMP = (SYSTEM_CORE_CLOCK/1000)-1; +#else + /* Set the tick interval to 100ms for debug */ + SysTick->CMP = (SYSTEM_CORE_CLOCK)-1; +#endif + + /* 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 + */ +void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); +//void SysTick_Handler(void) __attribute__((interrupt("interrupt"))); +void SysTick_Handler(void) +{ + /* clear IRQ */ + SysTick->SR &= ~SYSTICK_SR_CNTIF; + + /* update counter */ + systick_cnt++; + + printf("systick_cnt = 0x%08X\n\r", 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); +} + +#endif diff --git a/examples/systick_irq/systick_irq.c b/examples/systick_irq/systick_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..db9f4c4f7c3f3c490888468ab699b10d08261040 --- /dev/null +++ b/examples/systick_irq/systick_irq.c @@ -0,0 +1,82 @@ +/* + * 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"); + +#if 1 + // Debugging - does ISR run & inc counter? + // this section shows that IRQs during print will reset system, but during + // inf while() do not. + //while(1) + //for(int i=0;i<20;i++) + //{ + //printf("i = %d ", i); + printf("CNT = 0x%08X ", SysTick->CNT); + printf("systick_cnt = 0x%08X\n\r", systick_cnt); + //} + + // does cnt inc? + //uint32_t pcnt = systick_cnt; + while(1) + { + //if(pcnt != systick_cnt) + //{ + // printf("systick_cnt = %d\n\r", systick_cnt); + // pcnt = systick_cnt; + //} + } +#else + // Testing 1ms Systick + // 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); + + //printf("looping...\n\r"); + while(1) + { + GPIOD->BSHR = 1 | (1<<4); // Turn on GPIOs + GPIOC->BSHR = 1; + systick_delay_ms( 250 ); + GPIOD->BSHR = (1<<16) | (1<<(16+4)); // Turn off GPIODs + GPIOC->BSHR = (1<<16); + systick_delay_ms( 250 ); + printf( "Count: %lu\n\r", count++ ); + } +#endif +}