| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- /*
- * Copyright : (C) 2022 Phytium Information Technology, Inc.
- * All Rights Reserved.
- *
- * This program is OPEN SOURCE software: you can redistribute it and/or modify it
- * under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
- * either version 1.0 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the Phytium Public License for more details.
- *
- *
- * FilePath: ftimer.c
- * Date: 2022-02-10 14:53:42
- * LastEditTime: 2022-02-18 09:09:49
- * Description: This files is for
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- */
- /***************************** Include Files *********************************/
- #include <string.h>
- #include "fassert.h"
- #include "ftimer_tacho_hw.h"
- #include "ftimer_tacho.h"
- /************************** Function Prototypes ******************************/
- /**
- * @name: FTimerSoftwareReset
- * @msg: 将控制器复位
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- FError FTimerSoftwareReset(FTimerTachoCtrl *instance_p)
- {
- FASSERT(instance_p);
- if (instance_p->isready != FT_COMPONENT_IS_READY)
- {
- FTIMER_ERROR("device is not already!!!");
- return FTIMER_TACHO_ERR_NOT_READY;
- }
- u32 reg_val = FTIMER_CTRL_READ(instance_p);
- u32 Timeout = 0;
- reg_val |= FTIMER_REG_TACHO_RESET;
- FTIMER_CTRL_WRITE(instance_p, reg_val);
- do
- {
- reg_val = FTIMER_CTRL_READ(instance_p);
- Timeout++;
- }
- while ((reg_val & FTIMER_REG_TACHO_RESET) && (Timeout < FTIMER_TIMEOUT));
- if (Timeout >= FTIMER_TIMEOUT)
- {
- FTIMER_ERROR("Software Reset Failed!!!");
- return FTIMER_TACHO_ERR_FAILED;
- }
- return FTIMER_TACHO_SUCCESS;
- }
- /**
- * @name: FTimerStart
- * @msg: 启动timer_tacho外设,根据不同的功能,开启使能位
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- FError FTimerStart(FTimerTachoCtrl *instance_p)
- {
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- u32 reg_val;
- reg_val = FTIMER_CTRL_READ(instance_p);
- if (FTIMER_WORK_MODE_TIMER == instance_p->config.work_mode)
- {
- reg_val |= FTIMER_REG_ENABLE;
- }
- else
- {
- /* for tacho mode and capture mode */
- reg_val |= FTIMER_REG_ENABLE | FTACHO_REG_CAP_IN_ENABLE;
- }
- FTIMER_CTRL_WRITE(instance_p, reg_val);
- return FTIMER_TACHO_SUCCESS;
- }
- /**
- * @name: FTimerStop
- * @msg: 停止timer外设,根据不同的功能,关闭使能位,计数值停止并冻结
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- FError FTimerStop(FTimerTachoCtrl *instance_p)
- {
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- u32 reg_val = FTIMER_CTRL_READ(instance_p);
- if (FTIMER_WORK_MODE_TIMER == instance_p->config.work_mode)
- {
- reg_val &= (~FTIMER_REG_ENABLE);
- }
- else
- {
- /* for tacho mode and capture mode */
- reg_val &= (~FTIMER_REG_ENABLE) & (~FTACHO_REG_CAP_IN_ENABLE);
- }
- FTIMER_CTRL_WRITE(instance_p, reg_val);
- return FTIMER_TACHO_SUCCESS;
- }
- /**
- * @name: TimerSwithBits
- * @msg: 计数器32/64切换
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- static FError TimerSwithBits(FTimerTachoCtrl *instance_p)
- {
- u32 reg_val;
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- reg_val = FTIMER_CTRL_READ(instance_p);
- if (FTIMER_32_BITS == instance_p->config.timer_bits)
- {
- reg_val &= (~FTIMER_REG_CNT_SERIES_64BIT);
- }
- else if (FTIMER_64_BITS == instance_p->config.timer_bits)
- {
- reg_val |= FTIMER_REG_CNT_SERIES_64BIT;
- }
- else
- {
- FTIMER_ERROR("invalid input");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- FTIMER_CTRL_WRITE(instance_p, reg_val);
- return FTIMER_TACHO_SUCCESS;
- }
- /**
- * @name: TimerForceLoad
- * @msg: 强制更新位置位
- * @return {void} 无
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- static void TimerForceLoad(FTimerTachoCtrl *instance_p)
- {
- u32 reg_val;
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- reg_val = FTIMER_CTRL_READ(instance_p);
- reg_val |= FTIMER_REG_TACHO_FORCE_LOAD;
- FTIMER_CTRL_WRITE(instance_p, reg_val);
- return;
- }
- /**
- * @name: FTimerSetPeriod32
- * @msg: 设置32位计数模式下,计数器的compare的值,达到此值,如果开启中断,则开启中断
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {u32}NewCmpL
- */
- FError FTimerSetPeriod32(FTimerTachoCtrl *instance_p, u32 new_cmp_l)
- {
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- if (FTIMER_64_BITS == instance_p->config.timer_bits)
- {
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- /* update cmp val */
- FTIMER_CMPL_WRITE(instance_p, new_cmp_l);
- return FTIMER_TACHO_SUCCESS;
- }
- /**
- * @name: FTimerSetPeriod64
- * @msg: 设置64位计数模式下,计数器的compare的值,达到此值,如果开启中断,则开启中断
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {u64}ticks
- */
- FError FTimerSetPeriod64(FTimerTachoCtrl *instance_p, u64 ticks)
- {
- u32 low_cmp;
- u32 up_cmp;
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- if (FTIMER_32_BITS == instance_p->config.timer_bits)
- {
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- low_cmp = (u32)(GENMASK_ULL(31, 0) & ticks);
- up_cmp = (u32)((GENMASK_ULL(63, 32) & ticks) >> 32);
- /* MUST write low 32 bit first !!! */
- FTIMER_CMPL_WRITE(instance_p, low_cmp);
- FTIMER_CMPU_WRITE(instance_p, up_cmp);
- return FTIMER_TACHO_SUCCESS;
- }
- /**
- * @name: FTimerSetStartVal
- * @msg: 设置计数器初始值
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {u32} cnt
- */
- inline FError FTimerSetStartVal(FTimerTachoCtrl *instance_p, u32 cnt)
- {
- u32 ret = FTIMER_TACHO_SUCCESS;
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- ret = TimerSwithBits(instance_p);
- if (FTIMER_TACHO_SUCCESS != ret)
- {
- return ret;
- }
- FTIMER_STAR_WRITE(instance_p, cnt);
- /* set force_load=1,invalid previous cmp val,
- otherwise the previous cmp val still work */
- TimerForceLoad(instance_p);
- FTIMER_INFO("set start val 0x%x", FTIMER_STAR_READ(instance_p));
- return ret;
- }
- /**
- * @name: FTimerGetCurCnt32
- * @msg: 32位模式下,获取计数器当前计数值
- * @return {u32}返回当前计数器的值
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- u32 FTimerGetCurCnt32(FTimerTachoCtrl *instance_p)
- {
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- return FTIMER_CNTL_READ(instance_p);
- }
- /**
- * @name: FTimerGetCurCnt64
- * @msg: 64位模式下,获取计数器当前计数值
- * @return {u64}返回当前计数器的值
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- inline u64 FTimerGetCurCnt64(FTimerTachoCtrl *instance_p)
- {
- u64 cnt = 0;
- FASSERT(instance_p);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- /* must read lower 32 bits first */
- cnt |= (u64)FTIMER_CNTL_READ(instance_p);
- cnt |= (u64)(((u64)FTIMER_CNTU_READ(instance_p)) << 32);
- return cnt;
- }
- /**
- * @name: FTimerInit
- * @msg: 完成TimerTacho驱动实例的初始化,使之在就绪状态
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {FTimerTachoConfig} *config_p 驱动配置数据结构
- */
- FError FTimerInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p)
- {
- FASSERT(instance_p && config_p);
- u32 reg_val = 0;
- u32 Ret = FTIMER_TACHO_SUCCESS;
- if ((FTIMER_ONCE_CMP == config_p->cmp_type) &&
- (FTIMER_FREE_RUN != config_p->timer_mode))
- {
- FTIMER_ERROR("time mode shall be free-run when use once timer!!");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- if (instance_p->isready == FT_COMPONENT_IS_READY)
- {
- FTIMER_INFO("device is already initialized.!!!\r\n");
- return FTIMER_TACHO_ERR_IS_READ;
- }
- if (FTIMER_WORK_MODE_TIMER == config_p->work_mode)
- {
- reg_val |= FTIMER_REG_TACHO_MODE_TIMER;
- }
- else
- {
- FTIMER_ERROR("not support");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- if (FTIMER_FREE_RUN == config_p->timer_mode)
- {
- reg_val &= (~FTIMER_REG_CNT_RESTART);
- }
- else if (FTIMER_RESTART == config_p->timer_mode)
- {
- reg_val |= FTIMER_REG_CNT_RESTART;
- }
- else
- {
- FTIMER_ERROR("invalid input");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- if (FTIMER_32_BITS == config_p->timer_bits)
- {
- reg_val &= (~FTIMER_REG_CNT_SERIES_64BIT);
- }
- else if (FTIMER_64_BITS == config_p->timer_bits)
- {
- reg_val |= FTIMER_REG_CNT_SERIES_64BIT;
- }
- else
- {
- FTIMER_ERROR("invalid input");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- if (FTIMER_ONCE_CMP == config_p->cmp_type)
- {
- reg_val |= FTIMER_REG_MODE_ONCE;
- }
- else if (FTIMER_CYC_CMP == config_p->cmp_type)
- {
- reg_val &= (~FTIMER_REG_MODE_ONCE);
- }
- else
- {
- FTIMER_ERROR("invalid input");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- if (TRUE == config_p->force_load)
- {
- reg_val |= FTIMER_REG_TACHO_FORCE_LOAD;
- }
- if (TRUE == config_p->clear_cnt)
- {
- reg_val |= FTIMER_REG_CNT_CLR;
- }
- /*use input config*/
- if (config_p != &instance_p->config)
- {
- instance_p->config = *config_p;
- }
- FTIMER_CTRL_WRITE(instance_p, reg_val);
- instance_p->isready = FT_COMPONENT_IS_READY;
- return FTIMER_TACHO_SUCCESS;
- }
- void FTimerDeInit(FTimerTachoCtrl *instance_p)
- {
- FASSERT(instance_p);
- /* stop timer first */
- FTimerStop(instance_p);
- /* reset reg*/
- FTimerSoftwareReset(instance_p);
- instance_p->isready = 0;
- memset(instance_p, 0, sizeof(*instance_p));
- return;
- }
- /**
- * @name: FTimeSettingDump
- * @msg: 打印寄存器信息
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- FError FTimeSettingDump(const FTimerTachoCtrl *instance_p)
- {
- FASSERT(instance_p);
- u32 CtrlReg = FTIMER_CTRL_READ(instance_p);
- boolean is64Bit = ((CtrlReg & FTIMER_REG_CNT_SERIES_64BIT) != 0);
- FASSERT(FT_COMPONENT_IS_READY == instance_p->isready);
- printf("ctrl: \r\n");
- printf("===%d-bit timer\r\n", is64Bit ? 64 : 32);
- printf("===timer enabled: %d\r\n", (CtrlReg & FTIMER_REG_ENABLE) ? 1 : 0);
- printf("===timer mode: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_MODE_TIMER) ? 1 : 0);
- printf("===once timer: %d\r\n", (CtrlReg & FTIMER_REG_MODE_ONCE) ? 1 : 0);
- printf("===restart mode: %d\r\n", (CtrlReg & FTIMER_REG_CNT_RESTART) ? 1 : 0);
- printf("===in reset: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_RESET) ? 1 : 0);
- printf("===force load: %d\r\n", (CtrlReg & FTIMER_REG_TACHO_FORCE_LOAD) ? 1 : 0);
- printf("===clear cnt: %d\r\n", (CtrlReg & FTIMER_REG_CNT_CLR) ? 1 : 0);
- printf("start cnt: 0x%08x\r\n", FTIMER_STAR_READ(instance_p));
- if (is64Bit)
- {
- printf("cmp low: 0x%08x", FTIMER_CMPL_READ(instance_p));
- printf("high: 0x%08x\r\n", FTIMER_CMPU_READ(instance_p));
- printf("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p));
- printf("high: 0x%08x\r\n", FTIMER_CNTU_READ(instance_p));
- }
- else
- {
- printf("cmp low: 0x%08x\r\n", FTIMER_CMPL_READ(instance_p));
- printf("cur cnt: low: 0x%08x", FTIMER_CNTL_READ(instance_p));
- }
- printf("intr mask: 0x%08x\r\n", FTIMER_INTR_M_READ(instance_p));
- printf("intr status: 0x%08x\r\n", FTIMER_INTR_S_READ(instance_p));
- return FTIMER_TACHO_SUCCESS;
- }
|