This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我复用mcu timer[4:9]做捕捉器,对MCU_TIMER_IO[0:9]分时捕捉。 启动捕捉时,首先切换TIMER IO, 后使能定时器捕捉。 一段时间后,关闭timer捕捉,读取数值。
但发现,尽管输入信号无变化,每次启动一次捕捉,总有1到2个数据采集到。
这是什么原因,正确的操作流程应该是怎样的,要注意哪些操作?
我复用mcu timer[4:9]做捕捉器,对MCU_TIMER_IO[0:9]分时捕捉。 启动捕捉时,首先切换TIMER IO, 后使能定时器捕捉。
您好,这里的捕捉器是什么意义?这些定时器是怎么使用的?
这里的捕捉器,就是AUTOSAR的ICU,输入捕捉单元。
目前使用mcu_timer[4:9],以timerIO为纲复用这些定时器。
Icu_StartTimestamp时,从空闲的mcu_timer列表中,分配一个给启动的IO;
Icu_StopTimestamp时,停止硬件后,把对应的mcu_timer回收到空闲列表。
sdk: ti-processor-sdk-rtos-j721e-evm-08_00_00_12
os: freertos
SDK示例: mcusw/mcuss_demos/profiling/can
您好,您使用哪些 ICU (ECAP) 进行捕获? ICU 驱动程序目前支持 3 个 ECAP 模块。 您的输入看起来比 ICU 多,这就是为什么您将不同的定时器模块多路复用到 ICU 的原因?
目前使用mcu_timer[4:9],以timerIO为纲复用这些定时器。
Icu_StartTimestamp时,从空闲的mcu_timer列表中,分配一个给启动的IO;
Icu_StopTimestamp时,停止硬件后,把对应的mcu_timer回收到空闲列表。
在该示例中,您提到在定时器未运行时,您看到 1-2 个数据捕获。 代码是怎样的?
当您启动 ICM_StartTimestamp() 时,使用 "tiperIO" 将其中一个计时器分配给 ECAP 模块,您能详细说下这个硬件是什么吗?
此外您能否分享下您的参考代码,以便我们更好地了解 ICU 驱动程序的用法?
的确,原生ECAP只有三路,而我们需要12路。MCU这边暂时做10路。这10路完全用mcu_timer硬件捕捉。根ECAP没有关系。
源码如下:
#define MULTIPLEX_ICU_TIMERS
#define MCU_TIMER0_BASE (0x40400000UL)
#define ICU_BASE_TIMER0 (0x02400000UL)
#define ICU_BASE_TIMER1 (0x02410000UL)
#define ICU_BASE_TIMER2 (0x02420000UL)
#define ICU_BASE_TIMER3 (0x02430000UL)
#define ICU_BASE_TIMER4 (0x02440000UL)
#define ICU_BASE_TIMER5 (0x02450000UL)
#define ICU_BASE_TIMER6 (0x02460000UL)
#define ICU_BASE_TIMER7 (0x02470000UL)
#define ICU_BASE_TIMER8 (0x02480000UL)
#define ICU_BASE_TIMER9 (0x02490000UL)
#define ICU_BASE_TIMER10 (0x024A0000UL)
#define ICU_BASE_TIMER11 (0x024B0000UL)
#define ICU_BASE_TIMER12 (0x024C0000UL)
#define ICU_BASE_TIMER13 (0x024D0000UL)
#define ICU_BASE_TIMER14 (0x024E0000UL)
#define ICU_BASE_TIMER15 (0x024F0000UL)
#define ICU_BASE_TIMER16 (0x02500000UL)
#define ICU_BASE_TIMER17 (0x02510000UL)
#define ICU_BASE_TIMER18 (0x02520000UL)
#define ICU_BASE_TIMER19 (0x02530000UL)
#define ICU_BASE_MCU_TIMER0 (0x40400000UL)
#define ICU_BASE_MCU_TIMER1 (0x40410000UL)
#define ICU_BASE_MCU_TIMER2 (0x40420000UL)
#define ICU_BASE_MCU_TIMER3 (0x40430000UL)
#define ICU_BASE_MCU_TIMER4 (0x40440000UL)
#define ICU_BASE_MCU_TIMER5 (0x40450000UL)
#define ICU_BASE_MCU_TIMER6 (0x40460000UL)
#define ICU_BASE_MCU_TIMER7 (0x40470000UL)
#define ICU_BASE_MCU_TIMER8 (0x40480000UL)
#define ICU_BASE_MCU_TIMER9 (0x40490000UL)
#define MCU_TIMER0_INTR_PEND_0 (38U)
#define MCU_TIMER1_INTR_PEND_0 (39U)
#define MCU_TIMER2_INTR_PEND_0 (40U)
#define MCU_TIMER3_INTR_PEND_0 (41U)
#define MCU_TIMER4_INTR_PEND_0 (108U)
#define MCU_TIMER5_INTR_PEND_0 (109U)
#define MCU_TIMER6_INTR_PEND_0 (110U)
#define MCU_TIMER7_INTR_PEND_0 (111U)
#define MCU_TIMER8_INTR_PEND_0 (112U)
#define MCU_TIMER9_INTR_PEND_0 (113U)
#define TIMER0_INTR_PEND_0 (256UL)
#define TIMER1_INTR_PEND_0 (257UL)
#define TIMER2_INTR_PEND_0 (258UL)
#define TIMER3_INTR_PEND_0 (259UL)
#define TIMER4_INTR_PEND_0 (260UL)
#define TIMER5_INTR_PEND_0 (261UL)
#define TIMER6_INTR_PEND_0 (262UL)
#define TIMER7_INTR_PEND_0 (263UL)
#define TIMER8_INTR_PEND_0 (264UL)
#define TIMER9_INTR_PEND_0 (265UL)
#define TIMER10_INTR_PEND_0 (266UL)
#define TIMER11_INTR_PEND_0 (267UL)
#define TIMER12_INTR_PEND_0 (268UL)
#define TIMER13_INTR_PEND_0 (269UL)
#define TIMER14_INTR_PEND_0 (270UL)
#define TIMER15_INTR_PEND_0 (271UL)
#define TIMER16_INTR_PEND_0 (272UL)
#define TIMER17_INTR_PEND_0 (273UL)
#define TIMER18_INTR_PEND_0 (274UL)
#define TIMER19_INTR_PEND_0 (275UL)
#ifdef MULTIPLEX_ICU_TIMERS
#define FIRST_ICU_TMR_IDX (4U) /* MCU timer[0:3] used as GPT by RTOS. And here, mcu_timer[4:9] is for ICU */
#define LAST_ICU_TMR_IDX (9U) /* mcu_timer[4:9] for ICU */
#define NVLDIF (0xFFU)
#define COUNT_OF_ICU_TMR (((LAST_ICU_TMR_IDX)+1)-(FIRST_ICU_TMR_IDX))
#define COUNT_OF_ICU_IO (sizeof(IcuTmrInfo)/sizeof(IcuTmrInfo[0]))
#define isIcuTmrUsed(Tmr) ((COUNT_OF_ICU_IO) > LnkIO[Tmr])
#define isIoAssigned(nIO) ((COUNT_OF_ICU_TMR) > LnkTmr[nIO])
#endif
typedef struct{
uint32 baseAddress;
uint32 ClockRegister;
uint32 PadConfigRegister;
uint32 PadConfigVal;
uint32 TimerControllRegster;
uint32 TimerIoControllRegister;
uint32 MmrVal;
uint32 Vector;
}tIcuePinmuxInfo;
static const tIcuePinmuxInfo IcuTmrInfo[] = {
[0] = {
.baseAddress = ICU_BASE_MCU_TIMER0,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER0_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG21),
.PadConfigVal = 0x00050002UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER0_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO0_CTRL),
.MmrVal = 0x0UL,
.Vector = MCU_TIMER0_INTR_PEND_0,
},
[1] = {
.baseAddress = ICU_BASE_MCU_TIMER1,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER1_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG55),
.PadConfigVal = 0x00050004UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER1_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO1_CTRL),
.MmrVal = 0x1UL,
.Vector = MCU_TIMER1_INTR_PEND_0,
},
[2] = {
.baseAddress = ICU_BASE_MCU_TIMER2,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER2_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG24),
.PadConfigVal = 0x00050001UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER2_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO2_CTRL),
.MmrVal = 0x2UL,
.Vector = MCU_TIMER2_INTR_PEND_0,
},
[3] = {
.baseAddress = ICU_BASE_MCU_TIMER3,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER3_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG25),
.PadConfigVal = 0x00050001UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER3_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO3_CTRL),
.MmrVal = 0x3UL,
.Vector = MCU_TIMER3_INTR_PEND_0,
},
[4] = {
.baseAddress = ICU_BASE_MCU_TIMER4,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER4_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG30),
.PadConfigVal = 0x00050001UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER4_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO4_CTRL),
.MmrVal = 0x4UL,
.Vector = MCU_TIMER4_INTR_PEND_0,
},
[5] = {
.baseAddress = ICU_BASE_MCU_TIMER5,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER5_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG31),
.PadConfigVal = 0x00050001UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER5_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO5_CTRL),
.MmrVal = 0x5UL,
.Vector = MCU_TIMER5_INTR_PEND_0,
},
[6] = {
.baseAddress = ICU_BASE_MCU_TIMER6,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER6_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG52),
.PadConfigVal = 0x00050004UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER6_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO6_CTRL),
.MmrVal = 0x6UL,
.Vector = MCU_TIMER6_INTR_PEND_0,
},
[7] = {
.baseAddress = ICU_BASE_MCU_TIMER7,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER7_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG53),
.PadConfigVal = 0x00050004UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER7_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO7_CTRL),
.MmrVal = 0x7UL,
.Vector = MCU_TIMER7_INTR_PEND_0,
},
[8] = {
.baseAddress = ICU_BASE_MCU_TIMER8,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER8_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG60),
.PadConfigVal = 0x00050004UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER8_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO8_CTRL),
.MmrVal = 0x8UL,
.Vector = MCU_TIMER8_INTR_PEND_0,
},
[9] = {
.baseAddress = ICU_BASE_MCU_TIMER9,
.ClockRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER9_CLKSEL),
.PadConfigRegister = (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG61),
.PadConfigVal = 0x00050004UL,
.TimerControllRegster = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER9_CTRL),
.TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO9_CTRL),
.MmrVal = 0x9UL,
.Vector = MCU_TIMER9_INTR_PEND_0,
},
/*
[10] = {
.baseAddress = ICU_BASE_TIMER0,
.ClockRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER0_CLKSEL),
.PadConfigRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_PADCONFIG154),
.PadConfigVal = 0x00050003UL,
.TimerControllRegster = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER0_CTRL),
.TimerIoControllRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMERIO0_CTRL),
.MmrVal = 0x4UL,
.Vector = TIMER0_INTR_PEND_0,
},
[11] = {
.baseAddress = ICU_BASE_TIMER1,
.ClockRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER1_CLKSEL),
.PadConfigRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_PADCONFIG155),
.PadConfigVal = 0x00050003UL,
.TimerControllRegster = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER1_CTRL),
.TimerIoControllRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMERIO1_CTRL),
.MmrVal = 0x5UL,
.MmrVal = TIMER1_INTR_PEND_0,
},
*/
};
#ifdef MULTIPLEX_ICU_TIMERS
static uint8 LnkIO[COUNT_OF_ICU_TMR] = {NVLDIF}; /* Recored IO index */
static uint8 LnkTmr[COUNT_OF_ICU_IO];
#endif
extern void AppUtils_Printf (uint32 type,const char *pcString, ...);
extern FUNC(void, ICU_CODE) IcuE_ISR(Icu_ChannelType Channel, uint32 Value);
static inline int32_t IcuE_timerWaitForWrite(uint32_t reg, uint32_t baseAddr)
{
int32_t retVal = CSL_PASS;
volatile uint32_t exit_count = (uint32_t) 0U;
uint32_t step_size = (uint32_t) 1U;
if (0U != HW_RD_FIELD32(baseAddr + TIMER_TSICR, TIMER_TSICR_POSTED))
{
while ((uint32_t) 0U != (reg & TIMERWritePostedStatusGet(baseAddr)))
{
exit_count += step_size;
/* Do nothing - Busy wait,
* quit the loop if posted transations are not complete
* by one full cycle of counting
* This check and break prevents getting stuck in the loop
*/
if (exit_count == 0U)
{
retVal = CSL_ETIMEOUT;
break;
}
}
}
return (retVal);
}
static void ICUHW_Isr(uint32 Module)
{
uint32 baseAddr;
uint32 status;
//AppUtils_Printf(2, "isr%d\n", Module);
if((sizeof(IcuTmrInfo)/sizeof(IcuTmrInfo[0])) > Module)
{
// SchM_Enter_Icu_ICU_EXCLUSIVE_AREA_0();
baseAddr = IcuTmrInfo[Module].baseAddress;
status = TIMERIntStatusGet(baseAddr);
#ifdef MULTIPLEX_ICU_TIMERS
if((FIRST_ICU_TMR_IDX) <= Module && (LAST_ICU_TMR_IDX) >= Module)
{
Module = LnkIO[Module - (FIRST_ICU_TMR_IDX)];
#endif
/* Wait until event detected? */
/* Read timer capture value */
if(0 != (TIMER_INT_TCAR_IT_FLAG & status))
{
IcuE_ISR(Module, HW_RD_REG32(baseAddr + TIMER_TCAR1));
}
if(0 != (TIMER_INT_OVF_IT_FLAG & status))
{
}
if(0!= (TIMER_INT_MAT_IT_FLAG & status))
{
}
/* Clear capture interrupt request. */
TIMERIntStatusClear(baseAddr, TIMER_INT_TCAR_IT_FLAG|TIMER_INT_OVF_IT_FLAG|TIMER_INT_MAT_IT_FLAG);
#ifdef MULTIPLEX_ICU_TIMERS
}
#endif
// SchM_Exit_Icu_ICU_EXCLUSIVE_AREA_0();
}
}
void ICUHW_init(uint32 nModule, Icu_ChannelConfigType* cfg)
{
uint32 baseAddr;
int32_t regVal;
OsalRegisterIntrParams_t intrPrms;
HwiP_Handle hwiHandle;
uint32 tmp32;
tIcuePinmuxInfo *HwInfo;
if ((sizeof(IcuTmrInfo)/sizeof(IcuTmrInfo[0])) > nModule)
{
HwInfo = (tIcuePinmuxInfo*)(&(IcuTmrInfo[nModule]));
baseAddr = HwInfo->baseAddress;
#ifdef MULTIPLEX_ICU_TIMERS
LnkTmr[nModule] = NVLDIF;
if(FIRST_ICU_TMR_IDX <= nModule)
{
LnkIO[nModule-FIRST_ICU_TMR_IDX] = NVLDIF;
#endif
/* Execute software reset. TIMER_TIOCP_CFG[0] SOFTRESET 0x1 */
/* Wait until reset release? TIMER_TIOCP_CFG[0] SOFTRESET 0x0 */
TIMERReset(baseAddr);
/* Configure idle mode. TIMER_ TIOCP_CFG[3-2] IDLEMODE 0x- */
TIMERIdleModeConfigure(baseAddr, TIMER_SMART_IDLE);
/* Enable wake-up interrupt events. TIMER_IRQWAKEEN[2-0] 0x- */
/* Select posted mode. TIMER_TSICR[2] POSTED 0x- */
/* ע\B2\E1\D6жϺ\AF\CA\FD */
Osal_RegisterInterrupt_initParams(&intrPrms);
intrPrms.corepacConfig.arg = nModule;
intrPrms.corepacConfig.isrRoutine = &ICUHW_Isr;
intrPrms.corepacConfig.priority = 2U;
intrPrms.corepacConfig.corepacEventNum = 0U; /* NOT USED ? */
intrPrms.corepacConfig.intVecNum = HwInfo->Vector;
(void)Osal_RegisterInterrupt(&intrPrms, &hwiHandle);
HW_WR_REG32(HwInfo->ClockRegister, 0x2UL/* CLK_12M_RC SPRUIL1B P1506 */); /* Select clock */
HW_WR_REG32(baseAddr + TIMER_TIOCP_CFG, 0xAUL);
/* Initialize capture mode. See Section 12.10.3.5.2.3.2. */
/* Select autoreload mode. TIMER_TCLR[1] AR 0x- */
regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);
if(CSL_PASS == regVal)
{
regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);
regVal |= (TIMER_TCLR_AR_MASK);
HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);
}
/* Set prescale timer value. TIMER_TCLR[4-2] PTV 0x- */
tmp32 = cfg->prescaler;
if(8 <= tmp32) {tmp32 = 7;}
else if(0 < tmp32) {tmp32--;}
regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);
if(CSL_PASS == regVal)
{
regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);
regVal &= (~(TIMER_TCLR_PTV_MASK));
regVal |= (tmp32 << (TIMER_TCLR_PTV_SHIFT));
HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);
}
/* Enable prescaler. TIMER_TCLR[5] PRE 0x1 */
regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);
if(CSL_PASS == regVal)
{
regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);
regVal |= (TIMER_TCLR_PRE_MASK);
HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);
}
/* Select TIMER[19-0] or MCU_TIMER[9-0] TIMER_TCLR[14] GPO_CFG 0x1 */
/* Capture input at device pins */
/* TIMER_IO[7-0] for TIMER[19-0] or at pins */
/* MCU_TIMER_IO[9-0] for MCU_TIMER[9-0]. */
regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);
if(CSL_PASS == regVal)
{
regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);
regVal |= (TIMER_TCLR_GPO_CFG_MASK);
HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);
}
/* Binding IO */
#ifndef MULTIPLEX_ICU_TIMERS
HW_WR_REG32(HwInfo->TimerControllRegster, HwInfo->MmrVal);
HW_WR_REG32(HwInfo->TimerIoControllRegister, HwInfo->MmrVal);
#endif
/* Select single or second event capture. TIMER_TCLR[13] CAPT_MODE 0x- */
regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);
if(CSL_PASS == regVal)
{
regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);
regVal &= (~(TIMER_TCLR_CAPT_MODE_MASK));
HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);
}
/* Select transition capture mode. TIMER_TCLR[9-8] TCM 0x- */
if(ICU_RISING_EDGE == cfg->defaultStartEdge)
{
tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X1) << (TIMER_TCLR_TCM_SHIFT));
}
else if(ICU_FALLING_EDGE == cfg->defaultStartEdge)
{
tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X2) << (TIMER_TCLR_TCM_SHIFT));
}
else
{
tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X3) << (TIMER_TCLR_TCM_SHIFT));
}
regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);
if(CSL_PASS == regVal)
{
regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);
regVal &= (~(TIMER_TCLR_TCM_MASK));
regVal |= tmp32;
HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);
}
/* Enable capture interrupt. TIMER_IRQSTATUS_SET[2] TCAR_EN_FLAG 0x1 */
//TIMERIntEnable(baseAddr, TIMER_INT_TCAR_EN_FLAG/*|TIMER_INT_OVF_EN_FLAG*/);
/* Start the timer. TIMER_TCLR[0] ST 0x1 */
//TIMEREnable(baseAddr);
/* Detect event. See Section 12.10.3.5.2.3.3. */
#ifdef MULTIPLEX_ICU_TIMERS
}
#endif
/* PAD work as timer IO */
HW_WR_REG32(HwInfo->PadConfigRegister, HwInfo->PadConfigVal);
}
}
void ICUHW_deinit(uint32 nModule)
{
if(COUNT_OF_ICU_IO > nModule)
{
TIMERReset(IcuTmrInfo[nModule].baseAddress);
}
}
#ifdef MULTIPLEX_ICU_TIMERS
/******************************************************************************
* \BA\AF\CA\FD\C3\FB\B3ƣ\BAICUHW_assignTimer
*------------------------------------------------------------------------------
* \BA\AF\CA\FD\B9\A6\C4ܣ\BAIf the module has be assigned a timer, return the timer index, oth-
* erwise assigned a timer to it
* \CA\E4\C8\EB\B2\CE\CA\FD\A3\BAnModule--Hardware module
* \B7\B5\BB\D8ֵ \A3\BArelative timer index. The value 0xFFu means assignment filed.
* \B1\B8 ע\A3\BA
******************************************************************************/
static uint8 ICUHW_assignTimer(uint32 nModule)
{
uint8 i = 0xFFu;
tIcuePinmuxInfo *HwInfo;
if(COUNT_OF_ICU_IO > nModule)
{
if(isIoAssigned(nModule)) /* \B7\D6\C5\E4Ӳ\BC\FE */
{
i = LnkTmr[nModule];
}
else
{
for(i=0; i<(COUNT_OF_ICU_TMR); i++)
{
if(!isIcuTmrUsed(i))
{
LnkIO[i] = nModule; /* Timer link to witch IO */
LnkTmr[nModule] = i; /* Assigne timer */
HwInfo = (tIcuePinmuxInfo*)&IcuTmrInfo[i + FIRST_ICU_TMR_IDX];
HW_WR_REG32(HwInfo->TimerControllRegster, nModule);
HW_WR_REG32(HwInfo->TimerIoControllRegister, nModule);
break;
}
}
if(COUNT_OF_ICU_TMR <= i) /* \CE\C9\D3\C3Ӳ\BC\FE\A3\AC\B7\D6\C5\E4ʧ\B0ܣ\ACֱ\BD\D3\CD˳\F6 */
{
i = 0xFF;
AppUtils_Printf(2, " f\n");
}
}
}
return (i);
}
static void ICUHW_reclaimTimer(uint32 nModule)
{
if(COUNT_OF_ICU_IO > nModule)
{
if(isIoAssigned(nModule))
{
LnkIO[LnkTmr[nModule]] = NVLDIF;
LnkTmr[nModule] = NVLDIF;
}
}
}
#endif
void IcuhW_SetActivationCondition( Icu_ChannelType nModule, Icu_ActivationType Activation )
{
uint32 tmp32;
int32_t regVal;
uint32 baseAddr;
if (COUNT_OF_ICU_IO > nModule)
{
#ifdef MULTIPLEX_ICU_TIMERS
tmp32 = ICUHW_assignTimer(nModule);
if(COUNT_OF_ICU_TMR > tmp32)
{
nModule = (Icu_ChannelType)(tmp32 + (FIRST_ICU_TMR_IDX));
#endif
baseAddr = IcuTmrInfo[nModule].baseAddress;
/* Select transition capture mode. TIMER_TCLR[9-8] TCM 0x- */
if(ICU_RISING_EDGE == Activation)
{
tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X1) << (TIMER_TCLR_TCM_SHIFT));
}
else if(ICU_FALLING_EDGE == Activation)
{
tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X2) << (TIMER_TCLR_TCM_SHIFT));
}
else
{
tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X3) << (TIMER_TCLR_TCM_SHIFT));
}
regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);
if(CSL_PASS == regVal)
{
regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);
regVal &= (~(TIMER_TCLR_TCM_MASK));
regVal |= tmp32;
HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);
}
#ifdef MULTIPLEX_ICU_TIMERS
}
#endif
}
}
void ICUHW_startModule(Icu_ChannelType nModule)
{
uint32 baseAddr;
if(COUNT_OF_ICU_IO > nModule)
{
#ifdef MULTIPLEX_ICU_TIMERS
uint8 i;
tIcuePinmuxInfo *HwInfo;
AppUtils_Printf(2, ">%d", nModule);
i = ICUHW_assignTimer(nModule);
if(COUNT_OF_ICU_TMR > i)
{
nModule = i + FIRST_ICU_TMR_IDX;
#endif
baseAddr = IcuTmrInfo[nModule].baseAddress;
HW_WR_REG32(baseAddr+TIMER_IRQSTATUS_RAW, 0UL);
HW_WR_REG32(baseAddr+TIMER_IRQSTATUS, 7UL);
/* Enable capture interrupt. TIMER_IRQSTATUS_SET[2] TCAR_EN_FLAG 0x1 */
TIMERIntEnable(baseAddr, TIMER_INT_TCAR_EN_FLAG/*|TIMER_INT_OVF_EN_FLAG*/);
/* Start the timer. TIMER_TCLR[0] ST 0x1 */
TIMEREnable(baseAddr);
#ifdef MULTIPLEX_ICU_TIMERS
}
#endif
}
}
void ICUHW_stopModule(Icu_ChannelType nModule)
{
uint32 baseAddr;
if(COUNT_OF_ICU_IO > nModule)
{
#ifdef MULTIPLEX_ICU_TIMERS
//AppUtils_Printf(2, "<%d", nModule);
if(isIoAssigned(nModule))
{
nModule = LnkTmr[nModule] + (FIRST_ICU_TMR_IDX);
#endif
baseAddr = IcuTmrInfo[nModule].baseAddress;
TIMERIntDisable(baseAddr, TIMER_INT_TCAR_EN_FLAG);
TIMERDisable(baseAddr);
#ifdef MULTIPLEX_ICU_TIMERS
ICUHW_reclaimTimer(nModule);
}
#endif
}
}
您好,您能否试下用示波器或者其他仪器以查看 ICU 是否正在读取任何内容?或者更简单的测试,看下在断开 ICU 与任何这些外设的连接时,是否仍有读数? 这样我们可以确定 ICU 本身不会进行随机读数。
目前使用mcu_timer[4:9]六个,mcu_timer_io[0:9]十个。十个输入口都能捕捉,但频率低于550hz才能捕捉到双边沿,否则只捕捉到周期。不链接信号时,io[0:5]不会干扰,io[6:9]总捕捉到一个数值。优先级调整过到0,效果不明显。示波器跟踪过信号,硬件能保证10khz占空比1%的信号输入,到tda4管脚信号有完整的高和低电平。已对上面代码做排查调整,算法不变。
您好,有一点需要说明,我们不支持 MCAL/AUTOSAR 的 ICU 驱动器用于计时器输入捕获。 请问您是在哪里获得这个驱动程序的? 我们的 MCAL 驱动程序支持 ECAP,您是否使用定时器自己制作了 MCAL 驱动程序?
好的感谢您提供的信息,现在您这边和工程师是同步的了。您能否重新总结一下关于您在使用计时器时的问题?
有可能是硬件中的配置问题? 还是说您使用 TI 提供的软件?