diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index dd02389..5abaed0 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -4,12 +4,14 @@ src/common.c src/system.c src/resets.c src/clock.c +src/irq.c src/sio.c src/gpio.c src/pio.c src/timer.c src/dma.c src/uart.c +src/usb.c ) set(TARGET driver) diff --git a/driver/inc/irq.h b/driver/inc/irq.h new file mode 100644 index 0000000..468f6b1 --- /dev/null +++ b/driver/inc/irq.h @@ -0,0 +1,74 @@ +#ifndef __HARDWARE_IRQ_H__ +#define __HARDWARE_IRQ_H__ + +#include "m0plus_reg.h" + +#define IRQ_PERI_BASE (16) +#define IRQ_NUM_BASE (0 - IRQ_PERI_BASE) + +#define RESET_IRQ (1 + IRQ_NUM_BASE) +#define NMI_IRQ (2 + IRQ_NUM_BASE) +#define HARDFAULT_IRQ (3 + IRQ_NUM_BASE) +#define SVCALL_IRQ (11 + IRQ_NUM_BASE) +#define PENDSV_IRQ (14 + IRQ_NUM_BASE) +#define SYSTICK_IRQ (15 + IRQ_NUM_BASE) + +#define TIMER_IRQ_0 (0) +#define TIMER_IRQ_1 (1) +#define TIMER_IRQ_2 (2) +#define TIMER_IRQ_3 (3) +#define PWM_IRQ_WRAP (4) +#define USBCTRL_IRQ (5) +#define XIP_IRQ (6) +#define PIO0_IRQ_0 (7) +#define PIO0_IRQ_1 (8) +#define PIO1_IRQ_0 (9) +#define PIO1_IRQ_1 (10) +#define DMA_IRQ_0 (11) +#define DMA_IRQ_1 (12) +#define IO_IRQ_BANK0 (13) +#define IO_IRQ_QSPI (14) +#define SIO_IRQ_PROC0 (15) +#define SIO_IRQ_PROC1 (16) +#define CLOCKS_IRQ (17) +#define SPI0_IRQ (18) +#define SPI1_IRQ (19) +#define UART0_IRQ (20) +#define UART1_IRQ (21) +#define ADC_IRQ_FIFO (22) +#define I2C0_IRQ (23) +#define I2C1_IRQ (24) +#define RTC_IRQ (25) +#define MAX_IRQ (26) + +#define IRQ_NUM_MAX (IRQ_PERI_BASE + MAX_IRQ) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*irq_handler_t)(void); + +static inline void irq_enable_global(void) +{ + __asm volatile ("cpsie i" : : : "memory"); +} + +static inline void irq_disable_global(void) +{ + __asm volatile ("cpsid i" : : : "memory"); +} + +void irq_init(void); +void irq_attach(int irq, irq_handler_t isr); +void irq_detach(int irq); +void irq_set_priority(int irq, uint8_t priority); +void irq_enable(int irq); +void irq_disable(int irq); +int irq_is_enabled(int irq); + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_IRQ_H__ */ diff --git a/driver/inc/reg/m0plus_reg.h b/driver/inc/reg/m0plus_reg.h new file mode 100644 index 0000000..3f023f4 --- /dev/null +++ b/driver/inc/reg/m0plus_reg.h @@ -0,0 +1,31 @@ +#ifndef __HARDWARE_M0PLUS_REG_H__ +#define __HARDWARE_M0PLUS_REG_H__ + +#include "reg.h" + +/* Nested Vectored Interrupt Controller(NVIC) */ +#define M0PLUS_NVIC_ISER_OFFSET 0x0000E100 +#define M0PLUS_NVIC_ICER_OFFSET 0x0000E180 +#define M0PLUS_NVIC_ISPR_OFFSET 0x0000E200 +#define M0PLUS_NVIC_ICPR_OFFSET 0x0000E280 +#define M0PLUS_NVIC_IPR0_OFFSET 0x0000E400 + +/* System Control Block(SCB) */ +#define M0PLUS_CPUID_OFFSET 0x0000ED00 +#define M0PLUS_ICSR_OFFSET 0x0000ED04 +#define M0PLUS_VTOR_OFFSET 0x0000ED08 +#define M0PLUS_AIRCR_OFFSET 0x0000ED0C +#define M0PLUS_SCR_OFFSET 0x0000ED10 +#define M0PLUS_CCR_OFFSET 0x0000ED14 +#define M0PLUS_SHPR2_OFFSET 0x0000ED1C +#define M0PLUS_SHPR3_OFFSET 0x0000ED20 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_M0PLUS_REG_H__ */ diff --git a/driver/inc/reg/resets_reg.h b/driver/inc/reg/resets_reg.h index 6354e80..fef3f38 100644 --- a/driver/inc/reg/resets_reg.h +++ b/driver/inc/reg/resets_reg.h @@ -9,7 +9,9 @@ typedef struct { io_rw_32 reset_done; } resets_hw_t; -#define resets_hw ((resets_hw_t *const)RESETS_BASE) +#define resets_hw ((resets_hw_t *const)RESETS_BASE) +#define resets_hw_set ((resets_hw_t *)hw_set_alias_untyped(resets_hw)) +#define resets_hw_clear ((resets_hw_t *)hw_clear_alias_untyped(resets_hw)) #ifdef __cplusplus extern "C" { diff --git a/driver/inc/reg/timer_reg.h b/driver/inc/reg/timer_reg.h index 0da853e..1c6669d 100644 --- a/driver/inc/reg/timer_reg.h +++ b/driver/inc/reg/timer_reg.h @@ -1,26 +1,31 @@ #ifndef __HARDWARE_TIMER_REG_H__ #define __HARDWARE_TIMER_REG_H__ -#define TIMER_TIMEHW_OFFSET (0x000) -#define TIMER_TIMELW_OFFSET (0x004) -#define TIMER_TIMEHR_OFFSET (0x008) -#define TIMER_TIMELR_OFFSET (0x00C) -#define TIMER_ALARM0_OFFSET (0x010) -#define TIMER_ALARM1_OFFSET (0x014) -#define TIMER_ALARM2_OFFSET (0x018) -#define TIMER_ALARM3_OFFSET (0x01C) -#define TIMER_ARMED_OFFSET (0x020) -#define TIMER_TIMERAWH_OFFSET (0x024) -#define TIMER_TIMERAWL_OFFSET (0x028) -#define TIMER_DBGPAUSE_OFFSET (0x02C) -#define TIMER_PAUSE_OFFSET (0x030) -#define TIMER_INTR_OFFSET (0x034) -#define TIMER_INTE_OFFSET (0x038) -#define TIMER_INTF_OFFSET (0x03C) -#define TIMER_INTS_OFFSET (0x040) +/* TIMER_PAUSE Register @0x030 */ +#define TIMER_PAUSE_BITS 0x00000001 -/* TIMER_PAUSE_OFFSET @0x030 */ -#define TIMER_PAUSE (1 << 0U) +#define NUM_TIMERS 4 + +typedef struct { + io_wo_32 timehw; + io_wo_32 timelw; + io_ro_32 timehr; + io_ro_32 timelr; + io_rw_32 alarm[NUM_TIMERS]; + io_rw_32 armed; + io_ro_32 timerawh; + io_ro_32 timerawl; + io_rw_32 dbgpause; + io_rw_32 pause; + io_rw_32 intr; + io_rw_32 inte; + io_rw_32 intf; + io_ro_32 ints; +} timer_hw_t; + +#define timer_hw ((timer_hw_t *const)TIMER_BASE) +#define timer_hw_set ((timer_hw_t *const)hw_set_alias_untyped(timer_hw)) +#define timer_hw_clear ((timer_hw_t *const)hw_clear_alias_untyped(timer_hw)) #ifdef __cplusplus extern "C" { diff --git a/driver/inc/reg/uart_reg.h b/driver/inc/reg/uart_reg.h index 60b0d50..47714d4 100644 --- a/driver/inc/reg/uart_reg.h +++ b/driver/inc/reg/uart_reg.h @@ -1,5 +1,5 @@ -#ifndef __UART_REG_H__ -#define __UART_REG_H__ +#ifndef __HARDWARE_UART_REG_H__ +#define __HARDWARE_UART_REG_H__ #define UART_UARTDR_OFFSET (0x000) #define UART_UARTRSR_OFFSET (0x004) @@ -156,4 +156,4 @@ extern "C" { } #endif -#endif /* __UART_REG_H__ */ +#endif /* __HARDWARE_UART_REG_H__ */ diff --git a/driver/inc/resets.h b/driver/inc/resets.h index f5979ef..63576a0 100644 --- a/driver/inc/resets.h +++ b/driver/inc/resets.h @@ -1,35 +1,34 @@ #ifndef __HARDWARE_RESET_H__ #define __HARDWARE_RESET_H__ -#include "reg.h" #include "resets_reg.h" -#define RESETS_RESET_ADC (1 << 0) -#define RESETS_RESET_BUSCTRL (1 << 1) -#define RESETS_RESET_DMA (1 << 2) -#define RESETS_RESET_I2C0 (1 << 3) -#define RESETS_RESET_I2C1 (1 << 4) -#define RESETS_RESET_IO_BANK0 (1 << 5) -#define RESETS_RESET_IO_QSPI (1 << 6) -#define RESETS_RESET_JTAG (1 << 7) -#define RESETS_RESET_PADS_BANK0 (1 << 8) -#define RESETS_RESET_PADS_QSPI (1 << 9) -#define RESETS_RESET_PIO0 (1 << 10) -#define RESETS_RESET_PIO1 (1 << 11) -#define RESETS_RESET_SYSPLL (1 << 12) -#define RESETS_RESET_USBPLL (1 << 13) -#define RESETS_RESET_PWM (1 << 14) -#define RESETS_RESET_RTC (1 << 15) -#define RESETS_RESET_SPI0 (1 << 16) -#define RESETS_RESET_SPI1 (1 << 17) -#define RESETS_RESET_SYSCFG (1 << 18) -#define RESETS_RESET_SYSINFO (1 << 19) -#define RESETS_RESET_TBMAN (1 << 20) -#define RESETS_RESET_TIMER (1 << 21) -#define RESETS_RESET_UART0 (1 << 22) -#define RESETS_RESET_UART1 (1 << 23) -#define RESETS_RESET_USBCTRL (1 << 24) -#define RESETS_RESET_ALL ((1 << 25) - 1) +#define RESETS_BLOCK_ADC (1 << 0) +#define RESETS_BLOCK_BUSCTRL (1 << 1) +#define RESETS_BLOCK_DMA (1 << 2) +#define RESETS_BLOCK_I2C0 (1 << 3) +#define RESETS_BLOCK_I2C1 (1 << 4) +#define RESETS_BLOCK_IO_BANK0 (1 << 5) +#define RESETS_BLOCK_IO_QSPI (1 << 6) +#define RESETS_BLOCK_JTAG (1 << 7) +#define RESETS_BLOCK_PADS_BANK0 (1 << 8) +#define RESETS_BLOCK_PADS_QSPI (1 << 9) +#define RESETS_BLOCK_PIO0 (1 << 10) +#define RESETS_BLOCK_PIO1 (1 << 11) +#define RESETS_BLOCK_SYSPLL (1 << 12) +#define RESETS_BLOCK_USBPLL (1 << 13) +#define RESETS_BLOCK_PWM (1 << 14) +#define RESETS_BLOCK_RTC (1 << 15) +#define RESETS_BLOCK_SPI0 (1 << 16) +#define RESETS_BLOCK_SPI1 (1 << 17) +#define RESETS_BLOCK_SYSCFG (1 << 18) +#define RESETS_BLOCK_SYSINFO (1 << 19) +#define RESETS_BLOCK_TBMAN (1 << 20) +#define RESETS_BLOCK_TIMER (1 << 21) +#define RESETS_BLOCK_UART0 (1 << 22) +#define RESETS_BLOCK_UART1 (1 << 23) +#define RESETS_BLOCK_USBCTRL (1 << 24) +#define RESETS_BLOCK_ALL ((1 << 25) - 1) #ifdef __cplusplus extern "C" { diff --git a/driver/inc/timer.h b/driver/inc/timer.h index 45347b6..2b8530f 100644 --- a/driver/inc/timer.h +++ b/driver/inc/timer.h @@ -4,10 +4,11 @@ #include "reg.h" #include "timer_reg.h" -#define TIMER_ALARM_0 (0) -#define TIMER_ALARM_1 (1) -#define TIMER_ALARM_2 (2) -#define TIMER_ALARM_3 (3) +#define TIMER_ALARM_0 (0) +#define TIMER_ALARM_1 (1) +#define TIMER_ALARM_2 (2) +#define TIMER_ALARM_3 (3) +#define TIMER_ALARM_MAX (4) #ifdef __cplusplus extern "C" { @@ -29,6 +30,13 @@ void timer_alarm_disarm_multi(uint32_t alarm_id_multi); int timer_alarm_is_armed(uint8_t alarm_id); uint32_t timer_alarm_is_armed_multi(uint32_t alarm_id_multi); +uint32_t timer_int_get_raw_status(void); +uint32_t timer_int_get_status(void); +void timer_int_enable(uint8_t alarm_id); +void timer_int_disable(uint8_t alarm_id); +void timer_int_force(uint8_t alarm_id); +void timer_int_clear(uint8_t alarm_id); + #ifdef __cplusplus } #endif diff --git a/driver/inc/uart.h b/driver/inc/uart.h index ada1748..88cc87f 100644 --- a/driver/inc/uart.h +++ b/driver/inc/uart.h @@ -1,5 +1,5 @@ -#ifndef __UART_H__ -#define __UART_H__ +#ifndef __HARDWARE_UART_H__ +#define __HARDWARE_UART_H__ #include "reg.h" #include "uart_reg.h" @@ -86,4 +86,4 @@ uint32_t uart_int_get_mask_status(uint8_t uart_id); } #endif -#endif /* __UART_H__ */ +#endif /* __HARDWARE_UART_H__ */ diff --git a/driver/src/clock.c b/driver/src/clock.c index c475fba..f6670fd 100644 --- a/driver/src/clock.c +++ b/driver/src/clock.c @@ -279,10 +279,10 @@ void clock_pll_init(uint8_t pll, uint8_t refdiv, uint8_t fbdiv, uint8_t postdiv1 uint32_t val; if (pll == CLOCK_PLL_SYSPLL) { - reset_unreset_blocks_wait(RESETS_RESET_SYSPLL); + reset_unreset_blocks_wait(RESETS_BLOCK_SYSPLL); addr = PLL_SYS_BASE; } else if (pll == CLOCK_PLL_USBPLL) { - reset_unreset_blocks_wait(RESETS_RESET_USBPLL); + reset_unreset_blocks_wait(RESETS_BLOCK_USBPLL); addr = PLL_USB_BASE; } else { return; @@ -311,10 +311,10 @@ void clock_pll_init(uint8_t pll, uint8_t refdiv, uint8_t fbdiv, uint8_t postdiv1 void clock_pll_deinit(uint8_t pll) { if (pll == CLOCK_PLL_SYSPLL) { - reset_unreset_blocks_wait(RESETS_RESET_SYSPLL); + reset_unreset_blocks_wait(RESETS_BLOCK_SYSPLL); putreg32(CLOCK_PLL_PWR_MASK, PLL_SYS_BASE + CLOCK_PLL_PWR_OFFSET); } else if (pll == CLOCK_PLL_USBPLL) { - reset_unreset_blocks_wait(RESETS_RESET_USBPLL); + reset_unreset_blocks_wait(RESETS_BLOCK_USBPLL); putreg32(CLOCK_PLL_PWR_MASK, PLL_USB_BASE + CLOCK_PLL_PWR_OFFSET); } } diff --git a/driver/src/irq.c b/driver/src/irq.c new file mode 100644 index 0000000..22682ce --- /dev/null +++ b/driver/src/irq.c @@ -0,0 +1,81 @@ +#include "irq.h" + +static irq_handler_t g_handler[IRQ_NUM_MAX] __attribute__((aligned(256))); + +static void irq_default_handler(void) +{ + while (1); +} + +void irq_init(void) +{ + int irq; + + __asm volatile ("cpsid i" : : : "memory"); + for (irq = 0; irq < IRQ_NUM_MAX; irq++) { + g_handler[irq] = (irq_handler_t)((uintptr_t)irq_default_handler | 1); + if (irq >= 0) { + *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ICER_OFFSET)) = 1u << irq; + *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ICPR_OFFSET)) = 1u << irq; + } + } + *((io_rw_32 *) (PPB_BASE + M0PLUS_VTOR_OFFSET)) = (io_rw_32)g_handler; + __asm volatile ("dsb 0xF":::"memory"); + __asm volatile ("cpsie i" : : : "memory"); +} + +void irq_attach(int irq, irq_handler_t isr) +{ + if (irq <= IRQ_NUM_BASE || irq >= IRQ_NUM_MAX) { + return; + } + g_handler[IRQ_PERI_BASE + irq] = (irq_handler_t)((uintptr_t)isr | 1); + __asm volatile ("dsb 0xF":::"memory"); +} + +void irq_detach(int irq) +{ + if (irq <= IRQ_NUM_BASE || irq >= IRQ_NUM_MAX) { + return; + } + if (irq >= 0) { + *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ICER_OFFSET)) = 1u << irq; + *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ICPR_OFFSET)) = 1u << irq; + } + g_handler[IRQ_PERI_BASE + irq] = (irq_handler_t)((uintptr_t)irq_default_handler | 1); + __asm volatile ("dsb 0xF":::"memory"); +} + +void irq_set_priority(int irq, uint8_t priority) +{ + if (irq >= 0) { + // note that only 32 bit writes are supported + io_rw_32 *p = (io_rw_32 *)((PPB_BASE + M0PLUS_NVIC_IPR0_OFFSET) + (irq & ~3u)); + *p = (*p & ~(0xffu << (8 * (irq & 3u)))) | (((uint32_t) priority) << (8 * (irq & 3u))); + } +} + +void irq_enable(int irq) +{ + if (irq >= 0) { + // Clear pending before enable + // (if IRQ is actually asserted, it will immediately re-pend) + *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ICPR_OFFSET)) = 1u << irq; + *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ISER_OFFSET)) = 1u << irq; + } +} + +void irq_disable(int irq) +{ + if (irq >= 0) { + *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ICER_OFFSET)) = 1u << irq; + } +} + +int irq_is_enabled(int irq) +{ + if (irq >= 0) { + return 0 != ((1u << irq) & *((io_rw_32 *) (PPB_BASE + M0PLUS_NVIC_ISER_OFFSET))); + } + return 0; +} diff --git a/driver/src/timer.c b/driver/src/timer.c index 0798234..63d1002 100644 --- a/driver/src/timer.c +++ b/driver/src/timer.c @@ -2,50 +2,42 @@ void timer_count_write(uint64_t count) { - putreg32((uint32_t)(count & 0xFFFFFFFF), TIMER_BASE + TIMER_TIMELW_OFFSET); - putreg32((uint32_t)((count >> 32) & 0xFFFFFFFF), TIMER_BASE + TIMER_TIMEHW_OFFSET); + timer_hw->timelw = count & 0xFFFFFFFF; + timer_hw->timehw = (count >> 32) & 0xFFFFFFFF; } uint64_t timer_count_read(void) { uint32_t high, low; - low = getreg32(TIMER_BASE + TIMER_TIMELR_OFFSET); - high = getreg32(TIMER_BASE + TIMER_TIMEHR_OFFSET); + low = timer_hw->timelr; + high = timer_hw->timehr; return (((uint64_t)high << 32) | ((uint64_t)low)); } uint32_t timer_count_l_read_raw(void) { - return getreg32(TIMER_BASE + TIMER_TIMERAWL_OFFSET); + return timer_hw->timerawl; } uint32_t timer_count_h_read_raw(void) { - return getreg32(TIMER_BASE + TIMER_TIMERAWH_OFFSET); + return timer_hw->timerawh; } void timer_start(void) { - uint32_t val; - - val = getreg32(TIMER_BASE + TIMER_PAUSE_OFFSET); - val &= ~TIMER_PAUSE; - putreg32(val, TIMER_BASE + TIMER_PAUSE_OFFSET); + timer_hw_clear->pause = TIMER_PAUSE_BITS; } void timer_stop(void) { - uint32_t val; - - val = getreg32(TIMER_BASE + TIMER_PAUSE_OFFSET); - val |= TIMER_PAUSE; - putreg32(val, TIMER_BASE + TIMER_PAUSE_OFFSET); + timer_hw_set->pause = TIMER_PAUSE_BITS; } int timer_is_stopped(void) { - if (getreg32(TIMER_BASE + TIMER_PAUSE_OFFSET) & TIMER_PAUSE) { + if (timer_hw->pause & TIMER_PAUSE_BITS) { return 1; } else { return 0; @@ -54,27 +46,39 @@ int timer_is_stopped(void) void timer_alarm_set(uint8_t alarm_id, uint32_t alarm_count) { - putreg32(alarm_count, TIMER_BASE + TIMER_ALARM0_OFFSET + (TIMER_ALARM1_OFFSET - TIMER_ALARM0_OFFSET) * alarm_id); + if (alarm_id >= TIMER_ALARM_MAX) { + return; + } + timer_hw->alarm[alarm_id] = alarm_count; } uint32_t timer_alarm_get(uint8_t alarm_id) { - return getreg32(TIMER_BASE + TIMER_ALARM0_OFFSET + (TIMER_ALARM1_OFFSET - TIMER_ALARM0_OFFSET) * alarm_id); + if (alarm_id >= TIMER_ALARM_MAX) { + return 0; + } + return timer_hw->alarm[alarm_id]; } void timer_alarm_disarm(uint8_t alarm_id) { - putreg32(1 << alarm_id, TIMER_BASE + TIMER_ARMED_OFFSET); + if (alarm_id >= TIMER_ALARM_MAX) { + return; + } + timer_hw_set->armed = 1u << alarm_id; } void timer_alarm_disarm_multi(uint32_t alarm_id_multi) { - putreg32(alarm_id_multi, TIMER_BASE + TIMER_ARMED_OFFSET); + timer_hw->armed = alarm_id_multi; } int timer_alarm_is_armed(uint8_t alarm_id) { - if (getreg32(TIMER_BASE + TIMER_ARMED_OFFSET) & (1 << alarm_id)) { + if (alarm_id >= TIMER_ALARM_MAX) { + return 0; + } + if (timer_hw->armed & (1u << alarm_id)) { return 1; } else { return 0; @@ -83,5 +87,35 @@ int timer_alarm_is_armed(uint8_t alarm_id) uint32_t timer_alarm_is_armed_multi(uint32_t alarm_id_multi) { - return (getreg32(TIMER_BASE + TIMER_ARMED_OFFSET) & alarm_id_multi); + return (timer_hw->armed & alarm_id_multi); +} + +uint32_t timer_int_get_raw_status(void) +{ + return timer_hw->intr; +} + +uint32_t timer_int_get_status(void) +{ + return timer_hw->ints; +} + +void timer_int_enable(uint8_t alarm_id) +{ + timer_hw_set->inte = 1u << alarm_id; +} + +void timer_int_disable(uint8_t alarm_id) +{ + timer_hw_clear->inte = 1u << alarm_id; +} + +void timer_int_force(uint8_t alarm_id) +{ + timer_hw_set->intf = 1u << alarm_id; +} + +void timer_int_clear(uint8_t alarm_id) +{ + timer_hw_clear->intr = 1u << alarm_id; } diff --git a/example/peripherals/timer/timer_interrupt/CMakeLists.txt b/example/peripherals/timer/timer_interrupt/CMakeLists.txt new file mode 100644 index 0000000..e07dfed --- /dev/null +++ b/example/peripherals/timer/timer_interrupt/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.10) + +include(proj.conf) + +project(${EXAMPLE_NAME} VERSION 0.1) +add_executable(${EXAMPLE_NAME}.elf main.c) + +add_subdirectory(${SDK_BASE_DIR} sdk) +target_link_libraries(${EXAMPLE_NAME}.elf sdk) diff --git a/example/peripherals/timer/timer_interrupt/Makefile b/example/peripherals/timer/timer_interrupt/Makefile new file mode 100644 index 0000000..df5330b --- /dev/null +++ b/example/peripherals/timer/timer_interrupt/Makefile @@ -0,0 +1,18 @@ +EXAMPLE_BASE_DIR ?= $(shell realpath .) +EXAMPLE_NAME := $(notdir $(patsubst %/,%,$(CURDIR))) +SDK_BASE_DIR ?= $(shell realpath ./../../../..) + +export SDK_BASE_DIR +export EXAMPLE_NAME +export EXAMPLE_BASE_DIR + +GCC_PATH := $(shell which arm-none-eabi-gcc) +CROSS_COMPILE := $(patsubst %gcc,%,$(GCC_PATH)) +ifeq ($(GCC_PATH),) +$(error arm-none-eabi-gcc not found in PATH. Please install the ARM toolchain.) +endif + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(SDK_BASE_DIR)/project.build diff --git a/example/peripherals/timer/timer_interrupt/main.c b/example/peripherals/timer/timer_interrupt/main.c new file mode 100644 index 0000000..ccfa627 --- /dev/null +++ b/example/peripherals/timer/timer_interrupt/main.c @@ -0,0 +1,51 @@ +#include "resets.h" +#include "clock.h" +#include "irq.h" +#include "gpio.h" +#include "uart.h" +#include "timer.h" +#include "stdio.h" +#include "RP2040.h" + +#define TIMER_ALARM_ID TIMER_ALARM_0 +#define TIMER_PERIOD_US (1000 * 1000) + +struct uart_cfg_s uart_cfg = { + .baudrate = 6 * 1000 * 1000, + .mode = UART_MODE_TX_RX, + .data_bits = UART_DATABITS_8, + .parity = UART_PARITY_NONE, + .stop_bits = UART_STOPBITS_1, + .fifo_enable = ENABLE, + .tx_fifo_level = UART_FIFO_LEVEL_1_2, + .rx_fifo_level = UART_FIFO_LEVEL_1_2, +}; + +void timer_alarm_0_isr(void) +{ + timer_int_clear(TIMER_ALARM_ID); + timer_alarm_set(TIMER_ALARM_ID, timer_alarm_get(TIMER_ALARM_ID) + TIMER_PERIOD_US); + printf("time low count = %ld\r\n", timer_count_l_read_raw()); +} + +int main(void) +{ + reset_unreset_blocks_wait(RESETS_BLOCK_IO_BANK0 | RESETS_BLOCK_PADS_BANK0 | RESETS_BLOCK_UART0 | RESETS_BLOCK_TIMER); + gpio_init_simple(0, GPIO_FUNC_UART, DISABLE, ENABLE); + __enable_irq(); + uart_init(UART_ID_0, &uart_cfg); + printf("timer interrupt example.\r\n"); + + irq_init(); + timer_count_write(0); + timer_alarm_set(TIMER_ALARM_ID, TIMER_PERIOD_US); + timer_int_enable(TIMER_ALARM_ID); + irq_attach(TIMER_IRQ_0, timer_alarm_0_isr); + irq_enable(TIMER_IRQ_0); + + while (1) { + + } + + return 0; +} diff --git a/example/peripherals/timer/timer_interrupt/proj.conf b/example/peripherals/timer/timer_interrupt/proj.conf new file mode 100644 index 0000000..7d2ef31 --- /dev/null +++ b/example/peripherals/timer/timer_interrupt/proj.conf @@ -0,0 +1 @@ +# set(CONFIG_COMPONENT1 1)