sdk: examples: add timer
Signed-off-by: liangkangnan <liangkangnan@163.com>pull/4/head
parent
64041b4d2b
commit
c4fe45ffaf
|
@ -22,7 +22,7 @@ C_SRCS += $(BSP_DIR)/lib/utils.c
|
|||
C_SRCS += $(BSP_DIR)/lib/xprintf.c
|
||||
C_SRCS += $(BSP_DIR)/lib/uart.c
|
||||
C_SRCS += $(BSP_DIR)/lib/sim_ctrl.c
|
||||
C_SRCS += $(BSP_DIR)/lib/machine_timer.c
|
||||
C_SRCS += $(BSP_DIR)/lib/timer.c
|
||||
C_SRCS += $(BSP_DIR)/lib/gpio.c
|
||||
C_SRCS += $(BSP_DIR)/lib/rvic.c
|
||||
|
||||
|
|
|
@ -1,11 +1,56 @@
|
|||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
// Generated register defines for timer
|
||||
|
||||
#define TIMER0_BASE (0x40000000)
|
||||
#define TIMER0_CTRL (TIMER0_BASE + (0x00))
|
||||
#define TIMER0_COUNT (TIMER0_BASE + (0x04))
|
||||
#define TIMER0_VALUE (TIMER0_BASE + (0x08))
|
||||
// Copyright information found in source file:
|
||||
// Copyright lowRISC contributors.
|
||||
|
||||
#define TIMER0_REG(addr) (*((volatile uint32_t *)addr))
|
||||
// Licensing information found in source file:
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef _TIMER_REG_DEFS_
|
||||
#define _TIMER_REG_DEFS_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Register width
|
||||
#define TIMER_PARAM_REG_WIDTH 32
|
||||
|
||||
#define TIMER0_BASE_ADDR (0x40000000)
|
||||
#define TIMER0_REG(offset) (*((volatile uint32_t *)(TIMER0_BASE_ADDR + offset)))
|
||||
|
||||
// Timer control register
|
||||
#define TIMER_CTRL_REG_OFFSET 0x0
|
||||
#define TIMER_CTRL_REG_RESVAL 0x0
|
||||
#define TIMER_CTRL_EN_BIT 0
|
||||
#define TIMER_CTRL_INT_EN_BIT 1
|
||||
#define TIMER_CTRL_INT_PENDING_BIT 2
|
||||
#define TIMER_CTRL_MODE_BIT 3
|
||||
#define TIMER_CTRL_CLK_DIV_MASK 0xffffff
|
||||
#define TIMER_CTRL_CLK_DIV_OFFSET 8
|
||||
#define TIMER_CTRL_CLK_DIV_FIELD \
|
||||
((bitfield_field32_t) { .mask = TIMER_CTRL_CLK_DIV_MASK, .index = TIMER_CTRL_CLK_DIV_OFFSET })
|
||||
|
||||
// Timer expired value register
|
||||
#define TIMER_VALUE_REG_OFFSET 0x4
|
||||
#define TIMER_VALUE_REG_RESVAL 0x0
|
||||
|
||||
// Timer current count register
|
||||
#define TIMER_COUNT_REG_OFFSET 0x8
|
||||
#define TIMER_COUNT_REG_RESVAL 0x0
|
||||
|
||||
void timer0_start(uint8_t en);
|
||||
void timer0_set_value(uint32_t val);
|
||||
void timer0_set_int_enable(uint8_t en);
|
||||
void timer0_clear_int_pending();
|
||||
uint8_t timer0_get_int_pending();
|
||||
uint32_t timer0_get_current_count();
|
||||
void timer0_set_mode_auto_reload();
|
||||
void timer0_set_mode_ontshot();
|
||||
void timer0_set_div(uint32_t div);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // _TIMER_REG_DEFS_
|
||||
// End generated register defines for timer
|
|
@ -0,0 +1,59 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "../include/timer.h"
|
||||
|
||||
|
||||
void timer0_start(uint8_t en)
|
||||
{
|
||||
if (en)
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) |= 1 << TIMER_CTRL_EN_BIT;
|
||||
else
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) &= ~(1 << TIMER_CTRL_EN_BIT);
|
||||
}
|
||||
|
||||
void timer0_set_value(uint32_t val)
|
||||
{
|
||||
TIMER0_REG(TIMER_VALUE_REG_OFFSET) = val;
|
||||
}
|
||||
|
||||
void timer0_set_int_enable(uint8_t en)
|
||||
{
|
||||
if (en)
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) |= 1 << TIMER_CTRL_INT_EN_BIT;
|
||||
else
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) &= ~(1 << TIMER_CTRL_INT_EN_BIT);
|
||||
}
|
||||
|
||||
void timer0_clear_int_pending()
|
||||
{
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) |= 1 << TIMER_CTRL_INT_PENDING_BIT;
|
||||
}
|
||||
|
||||
uint8_t timer0_get_int_pending()
|
||||
{
|
||||
if (TIMER0_REG(TIMER_CTRL_REG_OFFSET) & (1 << TIMER_CTRL_INT_PENDING_BIT))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t timer0_get_current_count()
|
||||
{
|
||||
return TIMER0_REG(TIMER_COUNT_REG_OFFSET);
|
||||
}
|
||||
|
||||
void timer0_set_mode_auto_reload()
|
||||
{
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) |= 1 << TIMER_CTRL_MODE_BIT;
|
||||
}
|
||||
|
||||
void timer0_set_mode_ontshot()
|
||||
{
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) &= ~(1 << TIMER_CTRL_MODE_BIT);
|
||||
}
|
||||
|
||||
void timer0_set_div(uint32_t div)
|
||||
{
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) &= ~(TIMER_CTRL_CLK_DIV_MASK << TIMER_CTRL_CLK_DIV_OFFSET);
|
||||
TIMER0_REG(TIMER_CTRL_REG_OFFSET) |= div << TIMER_CTRL_CLK_DIV_OFFSET;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.bin
|
||||
*.dump
|
||||
*.mem
|
||||
timer
|
|
@ -0,0 +1,20 @@
|
|||
RISCV_ARCH := rv32im
|
||||
RISCV_ABI := ilp32
|
||||
RISCV_MCMODEL := medlow
|
||||
|
||||
|
||||
TARGET = timer
|
||||
|
||||
|
||||
#CFLAGS += -DSIMULATION
|
||||
#CFLAGS += -Os
|
||||
#ASM_SRCS +=
|
||||
#LDFLAGS +=
|
||||
#INCLUDES += -I.
|
||||
|
||||
C_SRCS := \
|
||||
main.c \
|
||||
|
||||
|
||||
BSP_DIR = ../../bsp
|
||||
include ../../bsp/bsp.mk
|
|
@ -0,0 +1 @@
|
|||
机器定时器(中断)例程。
|
|
@ -0,0 +1,62 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "../../bsp/include/timer.h"
|
||||
#include "../../bsp/include/utils.h"
|
||||
#include "../../bsp/include/rvic.h"
|
||||
#include "../../bsp/include/gpio.h"
|
||||
|
||||
static volatile uint32_t count;
|
||||
|
||||
int main()
|
||||
{
|
||||
count = 0;
|
||||
|
||||
#ifdef SIMULATION
|
||||
timer0_set_div(50);
|
||||
timer0_set_value(100); // 100us period
|
||||
timer0_clear_int_pending();
|
||||
timer0_set_int_enable(1);
|
||||
timer0_set_mode_auto_reload();
|
||||
global_irq_enable();
|
||||
rvic_irq_enable(0);
|
||||
timer0_start(1);
|
||||
|
||||
while (1) {
|
||||
if (count == 3) {
|
||||
timer0_start(0);
|
||||
// TODO: do something
|
||||
set_test_pass();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
timer0_set_div(25);
|
||||
timer0_set_value(10000); // 10ms period
|
||||
timer0_clear_int_pending();
|
||||
timer0_set_int_enable(1);
|
||||
timer0_set_mode_auto_reload();
|
||||
global_irq_enable();
|
||||
rvic_irq_enable(0);
|
||||
timer0_start(1);
|
||||
|
||||
gpio_output_enable(GPIO0);
|
||||
|
||||
while (1) {
|
||||
// 500ms
|
||||
if (count == 50) {
|
||||
count = 0;
|
||||
gpio_data_toggle(GPIO0); // toggle led
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void timer_irq_handler()
|
||||
{
|
||||
count++;
|
||||
|
||||
timer0_clear_int_pending();
|
||||
rvic_clear_irq_pending(0);
|
||||
}
|
Loading…
Reference in New Issue