[update] update timer and add irq
This commit is contained in:
parent
5ad87c6515
commit
e408c7bca5
@ -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)
|
||||
|
||||
74
driver/inc/irq.h
Normal file
74
driver/inc/irq.h
Normal file
@ -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__ */
|
||||
31
driver/inc/reg/m0plus_reg.h
Normal file
31
driver/inc/reg/m0plus_reg.h
Normal file
@ -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__ */
|
||||
@ -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" {
|
||||
|
||||
@ -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" {
|
||||
|
||||
@ -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__ */
|
||||
|
||||
@ -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" {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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__ */
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
81
driver/src/irq.c
Normal file
81
driver/src/irq.c
Normal file
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
9
example/peripherals/timer/timer_interrupt/CMakeLists.txt
Normal file
9
example/peripherals/timer/timer_interrupt/CMakeLists.txt
Normal file
@ -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)
|
||||
18
example/peripherals/timer/timer_interrupt/Makefile
Normal file
18
example/peripherals/timer/timer_interrupt/Makefile
Normal file
@ -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
|
||||
51
example/peripherals/timer/timer_interrupt/main.c
Normal file
51
example/peripherals/timer/timer_interrupt/main.c
Normal file
@ -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;
|
||||
}
|
||||
1
example/peripherals/timer/timer_interrupt/proj.conf
Normal file
1
example/peripherals/timer/timer_interrupt/proj.conf
Normal file
@ -0,0 +1 @@
|
||||
# set(CONFIG_COMPONENT1 1)
|
||||
Loading…
Reference in New Issue
Block a user