📄 etpu_qd.c
字号:
/*******************************************************************************
* FILE NAME: etpu_qd.c COPYRIGHT (c) Freescale Semiconductor 2005
* All Rights Reserved
* DESCRIPTION:
* This file contains the eTPU Quadrature Decoder (QD) API.
*===============================================================================
* REV AUTHOR DATE DESCRIPTION OF CHANGE
* --- ----------- ---------- ---------------------
* 0.1 A. Butok 23/Feb/04 Initial version.
* 0.2 M. Princ 16/Nov/04 Automatic switch between 3 modes:
* slow-normal-fast. Commutations removed.
* 2.0 M. Brejl 22/Mar/05 New QD API state flow:
* M. Princ init -> (disable -> align -> enable).
*******************************************************************************/
#include "etpu_util.h" /* Utility routines for working with the eTPU */
#include "etpu_qd.h" /* eTPU QD API */
extern uint32_t fs_etpu_data_ram_start;
extern uint32_t fs_etpu_data_ram_ext;
/*******************************************************************************
*FUNCTION : fs_etpu_qd_init
*PURPOSE : To initialize an eTPU channels to implement QD.
*INPUTS NOTES : This function has 19 parameters:
* channel_primary - This is the Primary channel number (Phase A).
* The Secondary channel (Phase B) is alwayes a channel
* one higner.
* 0-31 for ETPU_A and 64-95 for ETPU_B.
* channel_home - If a Home signal is processed, this is the Home
* channel number.
* 0-31 for ETPU_A and 64-95 for ETPU_B.
* channel_index - If an Index signal is processed, this is the Index
* channel number.
* 0-31 for ETPU_A and 64-95 for ETPU_B.
* signals - This parameter determines which QD signals are used.
* This parameter should be assigned a value of:
* FS_ETPU_QD_PRIM_SEC
* FS_ETPU_QD_PRIM_SEC_INDEX
* FS_ETPU_QD_PRIM_SEC_HOME
* FS_ETPU_QD_PRIM_SEC_INDEX_HOME.
* priority - This is the priority to assign to the QD function.
* This parameter should be assigned a value of:
* FS_ETPU_PRIORITY_HIGH or
* FS_ETPU_PRIORITY_MIDDLE or
* FS_ETPU_PRIORITY_LOW or
* FS_ETPU_PRIORITY_DISABLED.
* configuration - This is the configuration of channels.
* This parameter should be assigned a value of:
* FS_ETPU_QD_CONFIGURATION_0 or
* FS_ETPU_QD_CONFIGURATION_1.
* timer - This is the timer to use as a reference for the QD
* signals.
* This parameter should be assigned to a value of:
* FS_ETPU_TCR1 or
* FS_ETPU_TCR2.
* pc_max - Maximum value of Position Counter.
* This parameter is optional and can be set to zero;
* then the automatic Position Counter reset is not
* performed.
* slow_normal_threshold - This is the threshold for automatic switching from
* slow mode to normal mode, in [rpm].
* normal_slow_threshold - This is the threshold for automatic switching from
* normal mode to slow mode, in [rpm].
* normal_fast_threshold - This is the threshold for automatic switching from
* normal mode to fast mode, in [rpm].
* fast_normal_threshold - This is the threshold for automatic switching from
* fast mode to normal mode, in [rpm].
* (When all thresholds are set to zero QD function
* runs in slow mode only.)
* window_ratio1 - This is the ratio which applies when scheduling
* the window beginning (in normal and fast mode).
* This parameter determines how much time prior the
* expected next QD edge the window opens.
* This is a fractional value in format (9.15)
* (0x00800000 corresponds to 1.0)
* and should be assigned a value between
* 0.5 (0x00400000) and 0.9 (0x00733333).
* window_ratio2 - This is the ratio which applies when scheduling
* the window ending (in normal and fast mode).
* This parameter determines how much time after the
* expected next QD edge the window opens.
* This is a fractional value in format (9.15)
* (0x00800000 corresponds to 1.0)
* and should be assigned a value between
* 1.1 (0x008CCCCC) and 1.5 (0x00C00000).
* home_transition - This parameter selects a type of Home signal
* transition to detect.
* This parameter should be assigned a value of:
* FS_ETPU_QD_HOME_TRANS_LOW_HIGH,
* FS_ETPU_QD_HOME_TRANS_HIGH_LOW or
* FS_ETPU_QD_HOME_TRANS_ANY.
* This parameter is ignored if Home channel is not
* used.
* index_pulse - This parameter selects a type of Index signal pulse
* to detect.
* This parameter should be assigned to a value of:
* FS_ETPU_QD_INDEX_PULSE_POSITIVE or
* FS_ETPU_QD_INDEX_PULSE_NEGATIVE.
* This parameter is ignored if Index channel is not
* used.
* index_pc_reset - This parameter selects an action to perform on Index
* signal detection.
* This parameter should be assigned to a value of:
* FS_ETPU_QD_INDEX_PC_NO_RESET or
* FS_ETPU_QD_INDEX_PC_RESET.
* This parameter is ignored if Index channel is not
* used.
* etpu_tcr_freq - This is the frequency of TCR module used by QD
* channels, in [Hz].
* qd_pc_per_rev - This is the number of QD Position Counter increments
* per revolution.
*
* RETURNS NOTES: Error codes which can be returned are: FS_ETPU_ERROR_VALUE,
* FS_ETPU_ERROR_MALLOC
******************************************************************************/
int32_t fs_etpu_qd_init( uint8_t channel_primary,
uint8_t channel_home,
uint8_t channel_index,
uint8_t signals,
uint8_t priority,
uint8_t configuration,
uint8_t timer,
uint24_t pc_max,
uint24_t slow_normal_threshold,
uint24_t normal_slow_threshold,
uint24_t normal_fast_threshold,
uint24_t fast_normal_threshold,
fract24_t window_ratio1,
fract24_t window_ratio2,
uint8_t home_transition,
uint8_t index_pulse,
uint8_t index_pc_reset,
uint32_t etpu_tcr_freq,
uint24_t pc_per_rev)
{
uint32_t * pba;
uint8_t options = 0;
/****************************************
* Parameters bounds check.
***************************************/
#ifdef FS_ETPU_MC_PARAM_CHECK
if(((channel_primary>31)&&(channel_primary<64))||(channel_primary>95)||
(configuration>FS_ETPU_QD_CONFIGURATION_1)||
(timer>FS_ETPU_TCR2)||
((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_HOME))&&
(((channel_home>31)&&(channel_home<64))||
(channel_home>95)||(home_transition>FS_ETPU_QD_HOME_TRANS_ANY))||
((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_INDEX))&&
(((channel_index>31)&&(channel_index<64))||
(channel_index>95)||(index_pulse>FS_ETPU_QD_INDEX_PULSE_NEGATIVE)||
(index_pc_reset>FS_ETPU_QD_INDEX_PC_RESET)))
{
return(FS_ETPU_ERROR_VALUE);
}
#endif
/****************************************
* PRAM allocation.
***************************************/
if ((pba=fs_etpu_malloc(FS_ETPU_QD_NUM_PARMS))== 0)
{
return(FS_ETPU_ERROR_MALLOC);
}
/****************************************
* Write channel configuration registers
* and FM (function mode) bits.
***************************************/
/* PRIMARY CHANNEL */
eTPU->CHAN[channel_primary].CR.R = (FS_ETPU_QD_TABLE_SELECT << 24) +
(FS_ETPU_QD_FUNCTION_NUMBER << 16) +
(((uint32_t)pba - fs_etpu_data_ram_start) >> 3);
eTPU->CHAN[channel_primary].SCR.R = (uint32_t)((timer << 1) +
FS_ETPU_QD_FM_CHANNEL_PRIMARY);
/* SECONDARY CHANNEL */
eTPU->CHAN[channel_primary+1].CR.R = eTPU->CHAN[channel_primary].CR.R;
eTPU->CHAN[channel_primary+1].SCR.R = (uint32_t)((timer << 1) +
FS_ETPU_QD_FM_CHANNEL_SECONDARY);
/* HOME CHANNEL */
if((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_HOME))
{
eTPU->CHAN[channel_home].CR.R = (FS_ETPU_QD_HOME_TABLE_SELECT << 24) +
(FS_ETPU_QD_HOME_FUNCTION_NUMBER << 16) +
(((uint32_t)pba - fs_etpu_data_ram_start) >> 3);
eTPU->CHAN[channel_home].SCR.R = home_transition;
}
/* INDEX CHANNEL */
if((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_INDEX))
{
eTPU->CHAN[channel_index].CR.R = (FS_ETPU_QD_INDEX_TABLE_SELECT << 24) +
(FS_ETPU_QD_INDEX_FUNCTION_NUMBER << 16)+
(((uint32_t)pba - fs_etpu_data_ram_start) >> 3);
eTPU->CHAN[channel_index].SCR.R = (uint32_t)index_pc_reset + index_pulse;
}
/****************************************
* Write parameters.
***************************************/
if (pc_max>0)
options = FS_ETPU_QD_PC_MAX_ENABLED;
if (pc_per_rev > 0)
{
if (slow_normal_threshold > 0)
slow_normal_threshold = (uint24_t)(((30*etpu_tcr_freq)/
(pc_per_rev*slow_normal_threshold))<<2);
if (normal_slow_threshold > 0)
normal_slow_threshold = (uint24_t)(((30*etpu_tcr_freq)/
(pc_per_rev*normal_slow_threshold))<<2);
if (normal_fast_threshold > 0)
normal_fast_threshold = (uint24_t)(((30*etpu_tcr_freq)/
(pc_per_rev*normal_fast_threshold))<<2);
if (fast_normal_threshold > 0)
fast_normal_threshold = (uint24_t)(((30*etpu_tcr_freq)/
(pc_per_rev*fast_normal_threshold))<<2);
}
*(pba + ((FS_ETPU_QD_PC_OFFSET - 1)>>2)) = 0;
*(pba + ((FS_ETPU_QD_RC_OFFSET - 1)>>2)) = 0;
*(pba + ((FS_ETPU_QD_PERIOD_OFFSET - 1)>>2)) = 0;
*(pba + ((FS_ETPU_QD_PCMAX_OFFSET - 1)>>2)) = pc_max;
*(pba + ((FS_ETPU_QD_PCINTERRUPT1_OFFSET - 1)>>2)) = 0;
*(pba + ((FS_ETPU_QD_PCINTERRUPT2_OFFSET - 1)>>2)) = 0;
*(pba + ((FS_ETPU_QD_SLOW_NORMAL_THR_OFFSET - 1)>>2))= slow_normal_threshold;
*(pba + ((FS_ETPU_QD_NORMAL_SLOW_THR_OFFSET - 1)>>2))= normal_slow_threshold;
*(pba + ((FS_ETPU_QD_NORMAL_FAST_THR_OFFSET - 1)>>2))= normal_fast_threshold;
*(pba + ((FS_ETPU_QD_FAST_NORMAL_THR_OFFSET - 1)>>2))= fast_normal_threshold;
*(pba + ((FS_ETPU_QD_LAST_LEADING_EDGE_OFFSET - 1)>>2)) = 0;
*(pba + ((FS_ETPU_QD_LAST_EDGE_OFFSET - 1)>>2)) = 0;
*(pba + ((FS_ETPU_QD_PC_SC_OFFSET - 1)>>2)) = 0;
*((uint8_t*)pba + FS_ETPU_QD_DIRECTION_OFFSET) = 0;
*((uint8_t*)pba + FS_ETPU_QD_PINS_OFFSET) = (uint8_t)(configuration << 2);
*((uint8_t*)pba + FS_ETPU_QD_OPTIONS_OFFSET) = options;
*(pba + ((FS_ETPU_QD_RATIO1_OFFSET - 1)>>2)) = (uint32_t)window_ratio1;
*(pba + ((FS_ETPU_QD_RATIO2_OFFSET - 1)>>2)) = (uint32_t)window_ratio2 -
0x00800000;
/****************************************
* Write HSR.
***************************************/
eTPU->CHAN[channel_primary].HSRR.R = FS_ETPU_QD_INIT;
eTPU->CHAN[channel_primary+1].HSRR.R = FS_ETPU_QD_INIT;
if((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_HOME))
eTPU->CHAN[channel_home].HSRR.R = FS_ETPU_QD_HOME_INIT;
if((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_INDEX))
eTPU->CHAN[channel_index].HSRR.R = FS_ETPU_QD_INDEX_INIT;
/****************************************
* Set channel priorities and enable.
***************************************/
fs_etpu_enable(channel_primary, priority);
fs_etpu_enable((uint8_t)(channel_primary+1), priority);
if((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_HOME))
fs_etpu_enable(channel_home, priority);
if((signals==FS_ETPU_QD_PRIM_SEC_INDEX_HOME)||
(signals==FS_ETPU_QD_PRIM_SEC_INDEX))
fs_etpu_enable(channel_index, priority);
return(0);
}
/*******************************************************************************
* FUNCTION : fs_etpu_qd_disable
* PURPOSE : To disable an eTPU Quadrature Decoder channels.
* INPUTS NOTES : This function has 4 parameters:
*
* channel_primary - This is the Primary channel number (Phase A).
* 0-31 for ETPU_A and 64-95 for ETPU_B.
* channel_home - If a Home signal is processed, this is the Home channel
* number.
* 0-31 for ETPU_A and 64-95 for ETPU_B.
* channel_index - If an Index signal is processed, this is the Index channel
* number.
* 0-31 for ETPU_A and 64-95 for ETPU_B.
* signals - This parameter determines which QD signals are used.
* This parameter should be assigned a value of:
* FS_ETPU_QD_PRIM_SEC
* FS_ETPU_QD_PRIM_SEC_INDEX
* FS_ETPU_QD_PRIM_SEC_HOME
* FS_ETPU_QD_PRIM_SEC_INDEX_HOME.
* RETURNS NOTES: Error code which can be returned is: FS_ETPU_ERROR_VALUE
*******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -