Files
kunlun/driver/src/hw3/gp_timer.c
2024-09-28 14:24:04 +08:00

220 lines
5.6 KiB
C
Executable File

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_mem.h"
#include "os_task.h"
#include "irq.h"
#include "iot_gptmr.h"
#include "cpu.h"
#include "apb.h"
#include "gtmr_reg.h"
#include "hw_reg_api.h"
#include "gpio_mtx.h"
#include "cpu.h"
#define TIMER_NUM 4
typedef enum
{
TIMER0 = 0,
TIMER1,
TIMER2,
TIMER3,
TIMER_UNKNOW = 0XFF
}TIMER_ID;
void IRAM_ATTR gp_timer_reg_write(uint32_t reg, uint32_t data)
{
uint32_t cpu = cpu_get_mhartid();
if (0 == cpu) {
GTMR0_WRITE_REG(reg, data);
} else if (1 == cpu) {
GTMR1_WRITE_REG(reg, data);
} else if (2 == cpu) {
GTMR2_WRITE_REG(reg, data);
} else {
/* Do nothing. */
}
return;
}
uint32_t IRAM_ATTR gp_timer_reg_read(uint32_t reg)
{
uint32_t cpu = cpu_get_mhartid(), data = 0;
if (0 == cpu) {
data = GTMR0_READ_REG(reg);
} else if (1 == cpu) {
data = GTMR1_READ_REG(reg);
} else if (2 == cpu) {
data = GTMR2_READ_REG(reg);
} else {
/* Do nothing. */
}
return data;
}
void gp_timer_apb_enable()
{
uint32_t cpu = cpu_get_mhartid();
if (0 == cpu) {
apb_enable(APB_GTMR0);
} else if (1 == cpu) {
apb_enable(APB_GTMR1);
} else if (2 == cpu) {
apb_enable(APB_GTMR2);
} else {
/* Do nothing. */
}
return;
}
uint32_t IRAM_ATTR gp_timer_get_int_status(uint8_t id)
{
return gp_timer_reg_read(CFG_GTMR0_INT_STATUS_ADDR + (id * 0x14));
}
void IRAM_ATTR gp_timer_clear_int_status(uint8_t id)
{
gp_timer_reg_write(CFG_GTMR0_CLR_ADDR + (id * 0x14), 0x3);
}
void gp_timer_init()
{
uint8_t i = 0;
//enable gptimer;
gp_timer_apb_enable();
for (i = 0; i < TIMER_NUM; i++) {
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR + (i * 0x14), TMR0_TICK_SEL_MASK);
gp_timer_reg_write(CFG_GTMR0_CFG_ADDR + (i * 0x14), 0x0);
}
}
void gp_timer_set(uint8_t id, uint32_t val, uint8_t repeat)
{
uint32_t tmp;
if (id == TIMER_UNKNOW) {
return;
}
gp_timer_reg_write(CFG_GTMR0_CFG_ADDR + (id * 0x14), val);
tmp = gp_timer_reg_read(CFG_GTMR0_CTRL_CFG_ADDR + (id * 0x14));
if (repeat) {
REG_FIELD_SET(TMR0_MODE_CFG, tmp, 1);
} else {
REG_FIELD_SET(TMR0_MODE_CFG, tmp, 0);
}
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR + (id * 0x14), tmp);
}
void gp_timer_start(uint8_t id)
{
uint32_t tmp;
if (id == TIMER_UNKNOW) {
return;
}
gp_timer_reg_write(CFG_GTMR0_CLR_ADDR + (id * 0x14), 0x3);
tmp = gp_timer_reg_read(CFG_GTMR0_CTRL_CFG_ADDR + (id * 0x14));
REG_FIELD_SET(TMR0_ENA_CFG, tmp, 1);
REG_FIELD_SET(TMR0_INT_ENA, tmp, 1);
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR + (id * 0x14), tmp);
}
void IRAM_ATTR gp_timer_stop(uint8_t id)
{
uint32_t tmp;
if (id == TIMER_UNKNOW) {
return;
}
tmp = gp_timer_reg_read(CFG_GTMR0_CTRL_CFG_ADDR + (id * 0x14));
REG_FIELD_SET(TMR0_ENA_CFG, tmp, 0);
REG_FIELD_SET(TMR0_INT_ENA, tmp, 0);
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR + (id * 0x14), tmp);
}
void gp_timer_enable(uint8_t id, uint8_t mode, uint8_t us)
{
uint32_t tmp;
gp_timer_reg_write(CFG_GTMR0_CFG_ADDR, 0xffffffff);
gp_timer_reg_write(CFG_GTMR0_DIV_ADDR, 0x1);
tmp = gp_timer_reg_read(CFG_GTMR0_CTRL_CFG_ADDR);
REG_FIELD_SET(TMR0_TICK_SEL, tmp, 1); //1m tick sel
REG_FIELD_SET(TMR0_ENA_CFG, tmp, 1); // enable timer;
REG_FIELD_SET(TMR0_MODE_CFG, tmp, 1); //
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR, tmp);
}
uint32_t IRAM_ATTR gp_timer_get_current_val(uint8_t id)
{
return gp_timer_reg_read(CFG_GTMR0_VAL_ADDR + (id * 0x14));
}
void gp_timer_set_gpio_latch(uint8_t timer_id, uint8_t pad_id)
{
uint32_t tmp, sig_table[4] = {GPIO_MTX_GP_TMR_IN_0, GPIO_MTX_GP_TMR_IN_1,
GPIO_MTX_GP_TMR_IN_2, GPIO_MTX_GP_TMR_IN_3};
gpio_sig_info_t info = {1, {{IO_TYPE_IN, 0, 0, sig_table[timer_id], 0}}};
info.CFG[0].gpio = pad_id;
apb_enable(APB_GMTX);
gpio_module_pin_select(&info);
gpio_module_sig_select(&info, GPIO_MTX_MODE_MATRIX);
tmp = gp_timer_reg_read(CFG_GTMR0_CTRL_CFG_ADDR + (timer_id * 0x14));
/* [8:8] 0:raw input 1:invert input */
REG_FIELD_SET(TMR0_GPIO_INV_SEL, tmp, 0);
/* [7:7] 0:no debounce handle 1:have debounce handle */
REG_FIELD_SET(TMR0_GPIO_DEB_SEL, tmp, 1);
/* [6:6] 0:negedge 1:posedge */
REG_FIELD_SET(TMR0_GPIO_EDGE_SEL, tmp, 0);
/* [10:9] 0:edge trig 1:level trig 2:rsv 3:no trig */
REG_FIELD_SET(TMR0_GPIO_TRIG_SEL, tmp, 1);
gp_timer_reg_write(CFG_GTMR0_CTRL_CFG_ADDR + (timer_id * 0x14), tmp);
}
uint32_t gp_timer_get_vector(void)
{
uint32_t cpu = cpu_get_mhartid();
if (0 == cpu) {
return HAL_VECTOR_GPTMR0;
} else if (1 == cpu) {
return HAL_VECTOR_GPTMR1;
} else {
return HAL_VECTOR_GPTMR2;
}
}