sdk: examples: add timer

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/4/head
liangkangnan 2021-08-10 09:54:20 +08:00
parent 64041b4d2b
commit c4fe45ffaf
7 changed files with 207 additions and 12 deletions

View File

@ -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

View File

@ -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

59
sdk/bsp/lib/timer.c Normal file
View File

@ -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;
}

8
sdk/examples/timer/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Object files
*.o
*.ko
*.obj
*.bin
*.dump
*.mem
timer

View File

@ -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

View File

@ -0,0 +1 @@
机器定时器(中断)例程。

62
sdk/examples/timer/main.c Normal file
View File

@ -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);
}