| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- /*
- * 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: ftacho.c
- * Date: 2022-02-10 14:53:42
- * LastEditTime: 2022-05-20 09:08:52
- * Description: This files is for
- *
- * Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- */
- /***************************** Include Files *********************************/
- #include <string.h>
- #include "fassert.h"
- #include "fkernel.h"
- #include "fsleep.h"
- #include "ftimer_tacho_hw.h"
- #include "ftimer_tacho.h"
- #include "fparameters.h"
- /************************** Function Prototypes ******************************/
- /**
- * @name: FTachoInit
- * @msg: 初始化Tacho,并且使能计数器和tachometer
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {FTimerTachoConfig} *config_p 驱动配置数据结构
- */
- FError FTachoInit(FTimerTachoCtrl *instance_p, const FTimerTachoConfig *config_p)
- {
- FASSERT(instance_p && config_p);
- u32 reg_val = 0;
- if (instance_p->isready == FT_COMPONENT_IS_READY)
- {
- FTIMER_INFO("device is already initialized.!!!\r\n");
- return FTIMER_TACHO_ERR_IS_READ;
- }
- /* set work mode */
- if (FTIMER_WORK_MODE_TACHO == config_p->work_mode)
- {
- reg_val |= FTIMER_REG_TACHO_MODE_TACHO;
- reg_val |= FTACHO_REG_CAP_IN_ENABLE;
- /* plus num of rpm calculate period */
- FTIMER_CMPL_WRITE(instance_p, config_p->plus_num);
- }
- else if (FTIMER_WORK_MODE_CAPTURE == config_p->work_mode)
- {
- reg_val |= FTIMER_REG_TACHO_MODE_CAPTURE;
- reg_val |= FTIMER_REG_TACHO_CAPTURE_ENABLE;
- /* set capture cnt to assert capture intr */
- reg_val |= FTIMER_REG_TACHO_CAPTURE_CNT_MASK & (config_p->captue_cnt << FTIMER_REG_TACHO_CAPTURE_CNT_SHIFT);
- reg_val |= FTIMER_REG_ENABLE;
- }
- else
- {
- FTACHO_ERROR("not support work_mode.");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- /* set timer bits */
- 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
- {
- FTACHO_ERROR("invalid input 32/64bits.");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- /* set edge mode */
- if (FTACHO_FALLING_EDGE == config_p->edge_mode)
- {
- reg_val &= ~FTACHO_REG_MODE_MASK;
- reg_val |= FTACHO_REG_MODE_FALLING_EDGE;
- }
- else if (FTACHO_RISING_EDGE == config_p->edge_mode)
- {
- reg_val &= ~FTACHO_REG_MODE_MASK;
- reg_val |= FTACHO_REG_MODE_RISING_EDGE;
- }
- else if (FTACHO_DOUBLE_EDGE == config_p->edge_mode)
- {
- reg_val &= ~FTACHO_REG_MODE_MASK;
- reg_val |= FTACHO_REG_MODE_DOUBLE_EDGE;
- }
- else
- {
- FTACHO_ERROR("invalid input edge.");
- return FTIMER_TACHO_ERR_INVAL_PARM;
- }
- /* set jitter level */
- reg_val |= FTACHO_REG_ANTI_JITTER_MASK &
- (config_p->jitter_level << FTACHO_REG_ANTI_JITTER_SHIFT);
- //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;
- }
- /**
- * @name: FTachoGetFanRPM
- * @msg: 获取风扇的转速值
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {u32} *rpm 将获取到的数值写入到此地址
- */
- FError FTachoGetFanRPM(FTimerTachoCtrl *instance_p, u32 *rpm)
- {
- u32 loop_cnt;
- u32 raw_dat;
- FASSERT(instance_p);
- if (instance_p->isready != FT_COMPONENT_IS_READY || instance_p->config.work_mode != FTIMER_WORK_MODE_TACHO)
- {
- FTIMER_ERROR("device is not already or not work on TACHO_MODE!!!");
- return FTIMER_TACHO_ERR_NOT_READY;
- }
- u32 cnt_num = FTIMER_CMPL_READ(instance_p);
- for (loop_cnt = 0;; loop_cnt++)
- {
- raw_dat = FTACHO_RESU_READ(instance_p);
- /* wait for tacho result */
- if (raw_dat & FTACHO_REG_RESU_ISVALID)
- {
- break;
- }
- if (loop_cnt < 300)
- {
- fsleep_millisec(20); //20ms
- }
- else
- {
- return FTIMER_TACHO_ERR_ABORT;
- }
- }
- raw_dat &= FTACHO_REG_RESU_MASK;
- if (0 == raw_dat)
- {
- *rpm = 0;
- }
- else
- {
- /* calculate rpm */
- /* (60(second) * freq * tacho) / (2 * (cmp_l + 1)) cmp_l */
- *rpm = (TIMER_CLK_FREQ_HZ * 60 * raw_dat) / (2 * (cnt_num + 1));
- }
- return FTIMER_TACHO_SUCCESS;
- }
- /**
- * @name: FTachoGetCaptureCnt
- * @msg: 获取capture模式下,tacho输入脉冲的个数
- * @return {u32}返回获取到的数值
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- u32 FTachoGetCaptureCnt(FTimerTachoCtrl *instance_p)
- {
- u32 cap_cnt = FTIMER_TACHO_SUCCESS;
- FASSERT(instance_p);
- if (instance_p->isready != FT_COMPONENT_IS_READY || instance_p->config.work_mode != FTIMER_WORK_MODE_CAPTURE)
- {
- FTIMER_ERROR("device is not already or not work on CAPTURE_MODE!!!");
- return FTIMER_TACHO_ERR_NOT_READY;
- }
- /* read cap cnt */
- cap_cnt = FTIMER_CNTL_READ(instance_p);
- return cap_cnt;
- }
- /**
- * @name: FTimerSwithMode
- * @msg: 切换定时器模式和tachometer-capture模式
- * @return {FError} 驱动初始化的错误码信息,FTIMER_TACHO_SUCCESS 表示初始化成功,其它返回值表示初始化失败
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {FTimerTachoConfig} *pNewConfig 新的驱动配置数据结构
- */
- FError FTimerSwithMode(FTimerTachoCtrl *instance_p, FTimerTachoConfig *pNewConfig)
- {
- FASSERT(instance_p && pNewConfig);
- u32 ret = FTIMER_TACHO_SUCCESS;
- if (instance_p->config.work_mode == pNewConfig->work_mode)
- {
- return FTIMER_TACHO_SUCCESS;
- }
- /* disable and clear timer */
- u32 reg_val = FTIMER_CTRL_READ(instance_p);
- reg_val &= (~FTIMER_REG_ENABLE);
- reg_val |= FTIMER_REG_CNT_CLR;
- FTIMER_CTRL_WRITE(instance_p, reg_val);
- if (FTIMER_WORK_MODE_TIMER == pNewConfig->work_mode)
- {
- ret = FTimerInit(instance_p, pNewConfig);
- }
- else
- {
- ret = FTachoInit(instance_p, pNewConfig);
- }
- return ret;
- }
- /**
- * @name: FTachoSetCntPeriod
- * @msg: 配置 tach计数周期 = pulse_num
- * @return {void}
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {u32}计数ticks
- */
- void FTachoSetCntPeriod(FTimerTachoCtrl *instance_p, u32 ticks)
- {
- FTIMER_CMPL_WRITE(instance_p, ticks);
- }
- /**
- * @name: FTachoSetOverLimit
- * @msg: 预设tacho的最大值
- * @return {void}
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {u32}上限值
- */
- void FTachoSetOverLimit(FTimerTachoCtrl *instance_p, u32 overLim)
- {
- FTACHO_OVER_WRITE(instance_p, overLim);
- }
- /**
- * @name: FTachoSetUnderLimit
- * @msg: 预设tacho的最小值
- * @return {void}
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- * @param {u32}下限值
- */
- void FTachoSetUnderLimit(FTimerTachoCtrl *instance_p, u32 underLim)
- {
- FTACHO_UNDER_WRITE(instance_p, underLim);
- }
- /**
- * @name: FTachoDeInit
- * @msg: 去初始化,寄存器复位,结构体参数置0
- * @return {void}
- * @param {FTimerTachoCtrl} *instance_p 驱动控制数据结构
- */
- void FTachoDeInit(FTimerTachoCtrl *instance_p)
- {
- FASSERT(instance_p);
- /* reset reg*/
- FTimerSoftwareReset(instance_p);
- instance_p->isready = 0;
- memset(instance_p, 0, sizeof(*instance_p));
- return;
- }
|