/**************************************************************************** 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; } }