diff --git a/drivers/bl702_driver/hal_drv/inc/hal_clock.h b/drivers/bl702_driver/hal_drv/inc/hal_clock.h index d75923ee..33376621 100644 --- a/drivers/bl702_driver/hal_drv/inc/hal_clock.h +++ b/drivers/bl702_driver/hal_drv/inc/hal_clock.h @@ -66,6 +66,8 @@ enum peripheral_clock_type { PERIPHERAL_CLOCK_I2S, PERIPHERAL_CLOCK_PWM, PERIPHERAL_CLOCK_CAM, + PERIPHERAL_CLOCK_TIMER0, + PERIPHERAL_CLOCK_TIMER1, }; void system_clock_init(void); diff --git a/drivers/bl702_driver/hal_drv/inc/hal_timer.h b/drivers/bl702_driver/hal_drv/inc/hal_timer.h index d0f3f319..bf64a8fb 100644 --- a/drivers/bl702_driver/hal_drv/inc/hal_timer.h +++ b/drivers/bl702_driver/hal_drv/inc/hal_timer.h @@ -26,22 +26,40 @@ #include "drv_device.h" #include "bl702_config.h" -#define DEVICE_OFLAG_INT 0x01 -#define DEVICE_OFLAG_POLL 0x02 -#define DEVICE_CTRL_TIMER_CH_START 0x80 -#define DEVICE_CTRL_TIMER_CH_STOP 0x81 -#define DEVICE_CTRL_GET_MATCH_STATUS 0x82 - enum timer_index_type { -#ifdef BSP_USING_TIMER_CH0 - TIMER_CH0_INDEX, +#ifdef BSP_USING_TIMER0 + TIMER0_INDEX, #endif -#ifdef BSP_USING_TIMER_CH1 - TIMER_CH1_INDEX, +#ifdef BSP_USING_TIMER1 + TIMER1_INDEX, #endif TIMER_MAX_INDEX }; +enum timer_preload_trigger_type { + TIMER_PRELOAD_TRIGGER_NONE, + TIMER_PRELOAD_TRIGGER_COMP0, + TIMER_PRELOAD_TRIGGER_COMP1, + TIMER_PRELOAD_TRIGGER_COMP2, +}; + +enum timer_cnt_mode_type { + TIMER_CNT_PRELOAD, + TIMER_CNT_FREERUN, +}; + +enum timer_compare_id_type { + TIMER_COMPARE_ID_0, + TIMER_COMPARE_ID_1, + TIMER_COMPARE_ID_2, +}; + +enum timer_it_type { + TIMER_COMP0_IT = 1 << 0, + TIMER_COMP1_IT = 1 << 1, + TIMER_COMP2_IT = 1 << 2, +}; + enum timer_event_type { TIMER_EVENT_COMP0, TIMER_EVENT_COMP1, @@ -49,44 +67,20 @@ enum timer_event_type { TIMER_EVENT_UNKNOWN }; -enum timer_it_type { - TIMER_COMP0_IT = 1 << 0, - TIMER_COMP1_IT = 1 << 1, - TIMER_COMP2_IT = 1 << 2, - TIMER_ALL_IT = 1 << 3 -}; -typedef enum { - TIMER_CLK_FCLK, - TIMER_CLK_32K, - TIMER_CLK_1K, - TIMER_CLK_XTAL, -} timer_clk_src_t; - -typedef enum { - TIMER_PL_TRIG_NONE, - TIMER_PL_TRIG_COMP0, - TIMER_PL_TRIG_COMP1, - TIMER_PL_TRIG_COMP2, -} timer_pl_trig_t; - -typedef enum { - TIMER_CNT_PRELOAD, - TIMER_CNT_FREERUN, -} timer_cnt_mode; - -typedef struct -{ +typedef struct timer_timeout_cfg { + enum timer_compare_id_type timeout_id; uint32_t timeout_val; - uint32_t comp_it; -} timer_user_cfg_t; +} timer_timeout_cfg_t; typedef struct timer_device { struct device parent; uint8_t id; - uint8_t ch; - uint8_t clk_div; - timer_cnt_mode cnt_mode; - timer_pl_trig_t pl_trig_src; + enum timer_cnt_mode_type cnt_mode; + enum timer_preload_trigger_type trigger; + uint32_t reload; + uint32_t timeout1; + uint32_t timeout2; + uint32_t timeout3; } timer_device_t; #define TIMER_DEV(dev) ((timer_device_t *)dev) diff --git a/drivers/bl702_driver/hal_drv/src/hal_clock.c b/drivers/bl702_driver/hal_drv/src/hal_clock.c index 73ed5e54..461f9676 100644 --- a/drivers/bl702_driver/hal_drv/src/hal_clock.c +++ b/drivers/bl702_driver/hal_drv/src/hal_clock.c @@ -23,6 +23,7 @@ #include "bl702_glb.h" #include "bl702_pwm.h" +#include "bl702_timer.h" #include "hal_clock.h" #include "hal_mtimer.h" @@ -31,6 +32,28 @@ static uint32_t mtimer_get_clk_src_div(void) return ((SystemCoreClockGet() / (GLB_Get_BCLK_Div() + 1)) / 1000 / 1000 - 1); } +static void peripheral_clock_gate_all() +{ + uint32_t tmpVal; + tmpVal = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG1); + tmpVal &= (~(1 << BL_AHB_SLAVE1_DMA)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_EMAC)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_UART0)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_UART1)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_SPI)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_I2C)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_PWM)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_TMR)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_IRR)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_QDEC)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_KYS)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_I2S)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_USB)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_CAM)); + tmpVal &= (~(1 << BL_AHB_SLAVE1_MJPEG)); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG1, tmpVal); +} + void system_clock_init(void) { /*select root clock*/ @@ -45,10 +68,23 @@ void system_clock_init(void) } void peripheral_clock_init(void) { + peripheral_clock_gate_all(); #if defined(BSP_USING_UART0) || defined(BSP_USING_UART1) #if BSP_UART_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_PLL_96M +#if defined(BSP_USING_UART0) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_UART0); +#endif +#if defined(BSP_USING_UART1) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_UART1); +#endif GLB_Set_UART_CLK(ENABLE, HBN_UART_CLK_96M, BSP_UART_CLOCK_DIV); #elif BSP_UART_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_FCLK +#if defined(BSP_USING_UART0) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_UART0); +#endif +#if defined(BSP_USING_UART1) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_UART1); +#endif GLB_Set_UART_CLK(ENABLE, HBN_UART_CLK_FCLK, BSP_UART_CLOCK_DIV); #else #error "please select correct uart clock source" @@ -57,6 +93,7 @@ void peripheral_clock_init(void) #if defined(BSP_USING_I2C0) #if BSP_I2C_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_BCLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_I2C); GLB_Set_I2C_CLK(ENABLE, BSP_I2C_CLOCK_DIV); #else #error "please select correct i2c clock source" @@ -65,12 +102,91 @@ void peripheral_clock_init(void) #if defined(BSP_USING_SPI0) #if BSP_SPI_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_BCLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_SPI); GLB_Set_SPI_CLK(ENABLE, BSP_SPI_CLOCK_DIV); #else #error "please select correct spi clock source" #endif #endif +#if defined(BSP_USING_TIMER0) +#if BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_FCLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_TMR); + /* Configure timer clock source */ + uint32_t tmp = BL_RD_REG(TIMER_BASE, TIMER_TCCR); + tmp = BL_SET_REG_BITS_VAL(tmp, TIMER_CS_1, TIMER_CLKSRC_FCLK); + BL_WR_REG(TIMER_BASE, TIMER_TCCR, tmp); + + /* Configure timer clock division */ + tmp = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + tmp = BL_SET_REG_BITS_VAL(tmp, TIMER_TCDR2, BSP_TIMER0_CLOCK_DIV); + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmp); +#elif BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_XCLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_TMR); + /* Configure timer clock source */ + uint32_t tmp = BL_RD_REG(TIMER_BASE, TIMER_TCCR); + tmp = BL_SET_REG_BITS_VAL(tmp, TIMER_CS_1, TIMER_CLKSRC_XTAL); + BL_WR_REG(TIMER_BASE, TIMER_TCCR, tmp); + + /* Configure timer clock division */ + tmp = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + tmp = BL_SET_REG_BITS_VAL(tmp, TIMER_TCDR2, BSP_TIMER0_CLOCK_DIV); + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmp); +#elif BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_32K_CLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_TMR); + /* Configure timer clock source */ + uint32_t tmp = BL_RD_REG(TIMER_BASE, TIMER_TCCR); + tmp = BL_SET_REG_BITS_VAL(tmp, TIMER_CS_1, TIMER_CLKSRC_32K); + BL_WR_REG(TIMER_BASE, TIMER_TCCR, tmp); + + /* Configure timer clock division */ + tmp = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + tmp = BL_SET_REG_BITS_VAL(tmp, TIMER_TCDR2, BSP_TIMER0_CLOCK_DIV); + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmp); +#else +#error "please select correct timer0 clock source" +#endif +#endif + +#if defined(BSP_USING_TIMER1) +#if BSP_TIMER1_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_FCLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_TMR); + /* Configure timer clock source */ + uint32_t tmp1 = BL_RD_REG(TIMER_BASE, TIMER_TCCR); + tmp1 = BL_SET_REG_BITS_VAL(tmp1, TIMER_CS_2, TIMER_CLKSRC_FCLK); + BL_WR_REG(TIMER_BASE, TIMER_TCCR, tmp1); + + /* Configure timer clock division */ + tmp1 = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + tmp1 = BL_SET_REG_BITS_VAL(tmp1, TIMER_TCDR3, BSP_TIMER1_CLOCK_DIV); + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmp1); +#elif BSP_TIMER1_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_XCLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_TMR); + /* Configure timer clock source */ + uint32_t tmp1 = BL_RD_REG(TIMER_BASE, TIMER_TCCR); + tmp1 = BL_SET_REG_BITS_VAL(tmp1, TIMER_CS_2, TIMER_CLKSRC_XTAL); + BL_WR_REG(TIMER_BASE, TIMER_TCCR, tmp1); + + /* Configure timer clock division */ + tmp1 = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + tmp1 = BL_SET_REG_BITS_VAL(tmp1, TIMER_TCDR3, BSP_TIMER1_CLOCK_DIV); + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmp1); +#elif BSP_TIMER1_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_32K_CLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_TMR); + /* Configure timer clock source */ + uint32_t tmp1 = BL_RD_REG(TIMER_BASE, TIMER_TCCR); + tmp1 = BL_SET_REG_BITS_VAL(tmp1, TIMER_CS_2, TIMER_CLKSRC_32K); + BL_WR_REG(TIMER_BASE, TIMER_TCCR, tmp1); + + /* Configure timer clock division */ + tmp1 = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + tmp1 = BL_SET_REG_BITS_VAL(tmp, TIMER_TCDR3, BSP_TIMER1_CLOCK_DIV); + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmp1); +#else +#error "please select correct timer1 clock source" +#endif +#endif + #if defined(BSP_USING_PWM_CH0) || defined(BSP_USING_PWM_CH1) || defined(BSP_USING_PWM_CH2) || defined(BSP_USING_PWM_CH3) || defined(BSP_USING_PWM_CH4) || defined(BSP_USING_PWM_CH5) /* Disable clock gate */ GLB_AHB_Slave1_Clock_Gate(DISABLE, BL_AHB_SLAVE1_PWM); @@ -143,10 +259,12 @@ void peripheral_clock_init(void) #endif #if defined(BSP_USING_IR) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_IRR); GLB_Set_IR_CLK(ENABLE, 0, BSP_IR_CLOCK_DIV); #endif #if defined(BSP_USING_I2S0) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_I2S); GLB_Set_I2S_CLK(ENABLE, GLB_I2S_OUT_REF_CLK_NONE); #endif @@ -172,9 +290,11 @@ void peripheral_clock_init(void) #if defined(BSP_USING_CAM) #if BSP_CAM_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_PLL_96M + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_CAM); GLB_Set_CAM_CLK(ENABLE, GLB_CAM_CLK_DLL96M, BSP_CAM_CLOCK_DIV); GLB_SWAP_EMAC_CAM_Pin(GLB_EMAC_CAM_PIN_CAM); #elif BSP_CAM_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_XCLK + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_CAM); GLB_Set_CAM_CLK(ENABLE, GLB_CAM_CLK_XCLK, BSP_CAM_CLOCK_DIV); GLB_SWAP_EMAC_CAM_Pin(GLB_EMAC_CAM_PIN_CAM); #else @@ -184,8 +304,20 @@ void peripheral_clock_init(void) #if defined(BSP_USING_QDEC0) || defined(BSP_USING_QDEC1) || defined(BSP_USING_QDEC2) || defined(BSP_USING_KEYSCAN) #if BSP_QDEC_KEYSCAN_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_32K_CLK +#ifdef BSP_USING_KEYSCAN + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_KYS); +#endif +#if defined(BSP_USING_QDEC0) || defined(BSP_USING_QDEC1) || defined(BSP_USING_QDEC2) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_QDEC); +#endif GLB_Set_QDEC_CLK(GLB_QDEC_CLK_F32K, BSP_QDEC_KEYSCAN_CLOCK_DIV); #elif BSP_QDEC_KEYSCAN_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_XCLK +#if defined(BSP_USING_KEYSCAN) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_KYS); +#endif +#if defined(BSP_USING_QDEC0) || defined(BSP_USING_QDEC1) || defined(BSP_USING_QDEC2) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_QDEC); +#endif GLB_Set_QDEC_CLK(GLB_QDEC_CLK_XCLK, BSP_QDEC_KEYSCAN_CLOCK_DIV); #else #error "please select correct qdec or keyscan clock source" @@ -193,6 +325,7 @@ void peripheral_clock_init(void) #endif #if defined(BSP_USING_USB) + GLB_AHB_Slave1_Clock_Gate(0, BL_AHB_SLAVE1_USB); GLB_Set_USB_CLK(1); #endif } @@ -291,7 +424,36 @@ uint32_t peripheral_clock_get(enum peripheral_clock_type type) return system_clock_get(SYSTEM_CLOCK_AUPLL) / div; #endif #endif - + case PERIPHERAL_CLOCK_TIMER0: +#if BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_FCLK + tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + div = BL_GET_REG_BITS_VAL(tmpVal, TIMER_TCDR2); + return system_clock_get(SYSTEM_CLOCK_FCLK) / (div + 1); +#elif BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_XCLK + tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + div = BL_GET_REG_BITS_VAL(tmpVal, TIMER_TCDR2); + return system_clock_get(SYSTEM_CLOCK_XCLK) / (div + 1); +#elif BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_32K_CLK + tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + div = BL_GET_REG_BITS_VAL(tmpVal, TIMER_TCDR2); + return system_clock_get(SYSTEM_CLOCK_32K_CLK) / (div + 1); +#endif + break; + case PERIPHERAL_CLOCK_TIMER1: +#if BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_FCLK + tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + div = BL_GET_REG_BITS_VAL(tmpVal, TIMER_TCDR3); + return system_clock_get(SYSTEM_CLOCK_FCLK) / (div + 1); +#elif BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_XCLK + tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + div = BL_GET_REG_BITS_VAL(tmpVal, TIMER_TCDR3); + return system_clock_get(SYSTEM_CLOCK_XCLK) / (div + 1); +#elif BSP_TIMER0_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_32K_CLK + tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + div = BL_GET_REG_BITS_VAL(tmpVal, TIMER_TCDR3); + return system_clock_get(SYSTEM_CLOCK_32K_CLK) / (div + 1); +#endif + break; case PERIPHERAL_CLOCK_PWM: #if defined(BSP_USING_PWM_CH0) || defined(BSP_USING_PWM_CH1) || defined(BSP_USING_PWM_CH2) || defined(BSP_USING_PWM_CH3) || defined(BSP_USING_PWM_CH4) || defined(BSP_USING_PWM_CH5) #if BSP_PWM_CLOCK_SOURCE == ROOT_CLOCK_SOURCE_32K_CLK diff --git a/drivers/bl702_driver/hal_drv/src/hal_timer.c b/drivers/bl702_driver/hal_drv/src/hal_timer.c index 34b5fe14..d2c86e99 100644 --- a/drivers/bl702_driver/hal_drv/src/hal_timer.c +++ b/drivers/bl702_driver/hal_drv/src/hal_timer.c @@ -24,19 +24,21 @@ #include "timer_config.h" #include "bl702_glb.h" #include "bl702_timer.h" +#include "hal_clock.h" -#define TIMER_MAX_VALUE (0xFFFFFFFF) -#define TIMER_CLK_DIV (0) - -void TIMER_CH0_IRQ(void); -void TIMER_CH1_IRQ(void); +#ifdef BSP_USING_TIMER0 +void TIMER0_IRQ(void); +#endif +#ifdef BSP_USING_TIMER1 +void TIMER1_IRQ(void); +#endif static timer_device_t timerx_device[TIMER_MAX_INDEX] = { -#ifdef BSP_USING_TIMER_CH0 - TIMER_CH0_CONFIG, +#ifdef BSP_USING_TIMER0 + TIMER0_CONFIG, #endif -#ifdef BSP_USING_TIMER_CH1 - TIMER_CH1_CONFIG, +#ifdef BSP_USING_TIMER1 + TIMER1_CONFIG, #endif }; @@ -50,48 +52,117 @@ static timer_device_t timerx_device[TIMER_MAX_INDEX] = { int timer_open(struct device *dev, uint16_t oflag) { timer_device_t *timer_device = (timer_device_t *)dev; - TIMER_CFG_Type timer_cfg = { 0 }; - timer_cfg.timerCh = timer_device->ch; - timer_cfg.clkSrc = TIMER_CLK_SRC; - timer_cfg.plTrigSrc = timer_device->pl_trig_src; - timer_cfg.countMode = timer_device->cnt_mode; - timer_cfg.clockDivision = TIMER_CLK_DIV; - timer_cfg.matchVal0 = TIMER_MAX_VALUE; - timer_cfg.matchVal1 = TIMER_MAX_VALUE; - timer_cfg.matchVal2 = TIMER_MAX_VALUE; - timer_cfg.preLoadVal = TIMER_MAX_VALUE; + uint32_t tmpval; + uint64_t compare_count1; + uint64_t compare_count2; + uint64_t compare_count3; /* Disable all interrupt */ - TIMER_IntMask(timer_device->ch, TIMER_INT_ALL, MASK); + TIMER_IntMask(timer_device->id, TIMER_INT_ALL, MASK); /* Disable timer before config */ - TIMER_Disable(timer_device->ch); + TIMER_Disable(timer_device->id); - /* Timer init with default configuration */ - TIMER_Init(&timer_cfg); + /* Configure timer count mode: preload or free run */ + tmpval = BL_RD_WORD(TIMER_BASE + TIMER_TCMR_OFFSET); + tmpval &= (~(1 << (timer_device->id + 1))); + tmpval |= (timer_device->cnt_mode << (timer_device->id + 1)); + BL_WR_WORD(TIMER_BASE + TIMER_TCMR_OFFSET, tmpval); + + /* Configure timer preload trigger source */ + BL_WR_WORD(TIMER_BASE + TIMER_TPLCR2_OFFSET + 4 * timer_device->id, timer_device->trigger); + + if (timer_device->cnt_mode == TIMER_CNT_PRELOAD) { + BL_WR_WORD(TIMER_BASE + TIMER_TPLVR2_OFFSET + 4 * timer_device->id, timer_device->reload); + + if (timer_device->id == TIMER_CH0) { + compare_count1 = timer_device->timeout1 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / (1000 * 1000)) + timer_device->reload; + compare_count2 = timer_device->timeout2 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / (1000 * 1000)) + timer_device->reload; + compare_count3 = timer_device->timeout3 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / (1000 * 1000)) + timer_device->reload; + + } else { + compare_count1 = timer_device->timeout1 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / (1000 * 1000)) + timer_device->reload; + compare_count2 = timer_device->timeout2 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / (1000 * 1000)) + timer_device->reload; + compare_count3 = timer_device->timeout3 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / (1000 * 1000)) + timer_device->reload; + } + + /* Configure match compare values */ + if (compare_count1 > 1) { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_0, compare_count1 - 2); + } else { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_0, compare_count1); + } + + if (compare_count2 > 1) { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_1, compare_count2 - 2); + } else { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_1, timer_device->timeout2); + } + + if (compare_count3 > 1) { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_2, compare_count3 - 2); + } else { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_2, timer_device->timeout3); + } + } else { + if (timer_device->id == TIMER_CH0) { + compare_count1 = timer_device->timeout1 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / (1000 * 1000)); + compare_count2 = timer_device->timeout2 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / (1000 * 1000)); + compare_count3 = timer_device->timeout3 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / (1000 * 1000)); + + } else { + compare_count1 = timer_device->timeout1 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / (1000 * 1000)); + compare_count2 = timer_device->timeout2 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / (1000 * 1000)); + compare_count3 = timer_device->timeout3 * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / (1000 * 1000)); + } + /* Configure match compare values */ + if (compare_count1 > 1) { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_0, compare_count1 - 2); + } else { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_0, compare_count1); + } + + if (compare_count2 > 1) { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_1, compare_count2 - 2); + } else { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_1, compare_count2); + } + + if (compare_count3 > 1) { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_2, compare_count3 - 2); + } else { + TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_2, compare_count3); + } + } /* Clear interrupt status*/ - TIMER_ClearIntStatus(timer_device->ch, TIMER_COMP_ID_0); - TIMER_ClearIntStatus(timer_device->ch, TIMER_COMP_ID_1); - TIMER_ClearIntStatus(timer_device->ch, TIMER_COMP_ID_2); + TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_0); + TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_1); + TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_2); -#ifdef BSP_USING_TIMER_CH0 + if (oflag & DEVICE_OFLAG_STREAM_TX) { + /* Enable timer match interrupt */ + /* Note: if not enable match interrupt, TIMER_GetMatchStatus will not work + and status bit will not set */ + TIMER_IntMask(timer_device->id, TIMER_INT_COMP_0, UNMASK); + TIMER_IntMask(timer_device->id, TIMER_INT_COMP_1, UNMASK); + TIMER_IntMask(timer_device->id, TIMER_INT_COMP_2, UNMASK); + } - if (oflag == DEVICE_OFLAG_INT) - if (timer_device->ch == TIMER_CH0) { - Interrupt_Handler_Register(TIMER_CH0_IRQn, TIMER_CH0_IRQ); + if (oflag & DEVICE_OFLAG_INT_TX) { +#ifdef BSP_USING_TIMER0 + if (timer_device->id == TIMER_CH0) { + Interrupt_Handler_Register(TIMER_CH0_IRQn, TIMER0_IRQ); } - #endif -#ifdef BSP_USING_TIMER_CH1 - - if (oflag == DEVICE_OFLAG_INT) - if (timer_device->ch == TIMER_CH1) { - Interrupt_Handler_Register(TIMER_CH1_IRQn, TIMER_CH1_IRQ); +#ifdef BSP_USING_TIMER1 + if (timer_device->id == TIMER_CH1) { + Interrupt_Handler_Register(TIMER_CH1_IRQn, TIMER1_IRQ); } - #endif - + } + /* Enable timer */ + TIMER_Enable(timer_device->id); return 0; } @@ -104,7 +175,7 @@ int timer_open(struct device *dev, uint16_t oflag) int timer_close(struct device *dev) { timer_device_t *timer_device = (timer_device_t *)(dev); - TIMER_Disable(timer_device->ch); + TIMER_Disable(timer_device->id); return 0; } @@ -122,10 +193,19 @@ int timer_control(struct device *dev, int cmd, void *args) switch (cmd) { case DEVICE_CTRL_SET_INT /* constant-expression */: { - if (timer_device->ch == TIMER_CH0) { + uint32_t offset = __builtin_ctz((uint32_t)args); + + while (offset < 3) { + if ((uint32_t)args & (1 << offset)) { + TIMER_IntMask(timer_device->id, offset, UNMASK); + } + offset++; + } + + if (timer_device->id == TIMER_CH0) { NVIC_ClearPendingIRQ(TIMER_CH0_IRQn); NVIC_EnableIRQ(TIMER_CH0_IRQn); - } else if (timer_device->ch == TIMER_CH1) { + } else if (timer_device->id == TIMER_CH1) { NVIC_ClearPendingIRQ(TIMER_CH1_IRQn); NVIC_EnableIRQ(TIMER_CH1_IRQn); } @@ -134,100 +214,47 @@ int timer_control(struct device *dev, int cmd, void *args) } case DEVICE_CTRL_CLR_INT /* constant-expression */: { - timer_user_cfg_t *timer_user_cfg = ((timer_user_cfg_t *)(args)); - uint32_t offset = __builtin_ctz((uint32_t)timer_user_cfg->comp_it); + uint32_t offset = __builtin_ctz((uint32_t)args); - if (timer_device->ch == TIMER_CH0) { - NVIC_DisableIRQ(TIMER_CH0_IRQn); - } else if (timer_device->ch == TIMER_CH1) { - NVIC_DisableIRQ(TIMER_CH1_IRQn); - } - - while ((0 <= offset) && (offset < 4)) { - if ((uint32_t)timer_user_cfg->comp_it & (1 << offset)) { - TIMER_SetCompValue(timer_device->ch, offset, TIMER_MAX_VALUE); - TIMER_IntMask(timer_device->ch, offset, MASK); + while (offset < 3) { + if ((uint32_t)args & (1 << offset)) { + TIMER_IntMask(timer_device->id, offset, MASK); } - offset++; } - + if (timer_device->id == TIMER_CH0) { + NVIC_DisableIRQ(TIMER_CH0_IRQn); + } else if (timer_device->id == TIMER_CH1) { + NVIC_DisableIRQ(TIMER_CH1_IRQn); + } break; } - case DEVICE_CTRL_GET_INT /* constant-expression */: - /* code */ - break; - + case DEVICE_CTRL_GET_INT /* constant-expression */: { + uint32_t offset = __builtin_ctz((uint32_t)args); + uint32_t intstatus = TIMER_GetMatchStatus(timer_device->id, offset); + /* Clear interrupt status*/ + TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_0); + TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_1); + TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_2); + return intstatus; + } case DEVICE_CTRL_CONFIG /* constant-expression */: /* code */ break; case DEVICE_CTRL_RESUME /* constant-expression */: { /* Enable timer */ - TIMER_Enable(timer_device->ch); + TIMER_Enable(timer_device->id); break; } case DEVICE_CTRL_SUSPEND /* constant-expression */: { - TIMER_Disable(timer_device->ch); + TIMER_Disable(timer_device->id); break; } - - case DEVICE_CTRL_TIMER_CH_START: { - timer_user_cfg_t *timer_user_cfg = ((timer_user_cfg_t *)(args)); - - uint32_t offset = __builtin_ctz((uint32_t)timer_user_cfg->comp_it); - uint32_t timeout = (timer_user_cfg->timeout_val * 144); - TIMER_SetPreloadValue(timer_device->ch, 0); - - while ((0 <= offset) && (offset < 4)) { - if ((uint32_t)timer_user_cfg->comp_it & (1 << offset)) { - TIMER_SetCompValue(timer_device->ch, offset, timeout); - TIMER_IntMask(timer_device->ch, offset, UNMASK); - } - - offset++; - } - - /* Enable timer */ - TIMER_Enable(timer_device->ch); - break; - } - - case DEVICE_CTRL_TIMER_CH_STOP: { - timer_user_cfg_t *timer_user_cfg = ((timer_user_cfg_t *)(args)); - uint32_t offset = __builtin_ctz((uint32_t)timer_user_cfg->comp_it); - - if (timer_device->ch == TIMER_CH0) { - NVIC_DisableIRQ(TIMER_CH0_IRQn); - } else if (timer_device->ch == TIMER_CH1) { - NVIC_DisableIRQ(TIMER_CH1_IRQn); - } - - while ((0 <= offset) && (offset < 4)) { - if ((uint32_t)timer_user_cfg->comp_it & (1 << offset)) { - TIMER_SetCompValue(timer_device->ch, offset, TIMER_MAX_VALUE); - TIMER_IntMask(timer_device->ch, offset, MASK); - } - - offset++; - } - - TIMER_Disable(timer_device->ch); - break; - } - case DEVICE_CTRL_GET_CONFIG: - return TIMER_GetCounterValue(timer_device->ch); - break; - - case DEVICE_CTRL_GET_MATCH_STATUS: { - uint32_t tmpval = (uint32_t)args; - return TIMER_GetMatchStatus(timer_device->ch, tmpval); - break; - } - + return TIMER_GetCounterValue(timer_device->id); default: break; } @@ -237,6 +264,25 @@ int timer_control(struct device *dev, int cmd, void *args) int timer_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size) { + timer_device_t *timer_device = (timer_device_t *)dev; + timer_timeout_cfg_t *timeout_cfg = (timer_timeout_cfg_t *)buffer; + uint64_t compare_count; + + if (size % sizeof(timer_timeout_cfg_t)) { + return -1; + } + /* Disable timer before config */ + TIMER_Disable(timer_device->id); + + for (uint32_t i = 0; i < size / sizeof(timer_timeout_cfg_t); i++) { + if (timer_device->id == TIMER_CH0) { + compare_count = timeout_cfg->timeout_val * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0) / (1000 * 1000)); + } else { + compare_count = timeout_cfg->timeout_val * (peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1) / (1000 * 1000)); + } + TIMER_SetCompValue(timer_device->id, timeout_cfg->timeout_id, compare_count - 2); + } + TIMER_Enable(timer_device->id); return 0; } int timer_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size) @@ -245,15 +291,12 @@ int timer_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size) } /** - * @brief timer register + * @brief * * @param index * @param name - * @param flag - * @param timer_user_cfg * @return int */ - int timer_register(enum timer_index_type index, const char *name) { struct device *dev; @@ -267,7 +310,7 @@ int timer_register(enum timer_index_type index, const char *name) dev->open = timer_open; dev->close = timer_close; dev->control = timer_control; - // dev->write = NULL; + dev->write = timer_write; // dev->read = NULL; dev->status = DEVICE_UNREGISTER; @@ -283,53 +326,53 @@ void timer_isr(timer_device_t *handle) uint32_t tmpVal = 0; uint32_t tmpAddr = 0; - intId = BL_RD_WORD(TIMER_BASE + TIMER_TMSR2_OFFSET + 4 * handle->ch); - tmpAddr = TIMER_BASE + TIMER_TICR2_OFFSET + 4 * handle->ch; - tmpVal = BL_RD_WORD(tmpAddr); - if (!handle->parent.callback) { return; } + intId = BL_RD_WORD(TIMER_BASE + TIMER_TMSR2_OFFSET + 4 * handle->id); + tmpAddr = TIMER_BASE + TIMER_TICR2_OFFSET + 4 * handle->id; + tmpVal = BL_RD_WORD(tmpAddr); + /* Comparator 0 match interrupt */ if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_0)) { - BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_0)); handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP0); + BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_0)); } /* Comparator 1 match interrupt */ if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_1)) { - BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_1)); handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP1); + BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_1)); } /* Comparator 2 match interrupt */ if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_2)) { - BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_2)); handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP2); + BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_2)); } } -#ifdef BSP_USING_TIMER_CH0 +#ifdef BSP_USING_TIMER0 /** * @brief * */ -void TIMER_CH0_IRQ(void) +void TIMER0_IRQ(void) { - timer_isr(&timerx_device[TIMER_CH0_INDEX]); + timer_isr(&timerx_device[TIMER0_INDEX]); } #endif -#ifdef BSP_USING_TIMER_CH1 +#ifdef BSP_USING_TIMER1 /** * @brief * */ -void TIMER_CH1_IRQ(void) +void TIMER1_IRQ(void) { - timer_isr(&timerx_device[TIMER_CH1_INDEX]); + timer_isr(&timerx_device[TIMER1_INDEX]); } #endif