- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would like to use a TCPWM Counter in mode Capture to measure the time difference between two pulses (edges). However, I would like to omit the substraction of CC0_BUFF minus CC0 to calculate the number of clocks.
How do I implement a hardware auto-reload (of zero in my case) of the count register on every capture event (after the count value has been transfered into the register CC0)?
Solved! Go to Solution.
- Labels:
-
Automotive Traveo_II
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I think I found a solution myself by using the Trigger Multiplexer 4:
// Trigger Mux Configuration
// Innerhalb des Multiplexers 4: verbinde Mpx-Ausgang Nr. 0 mit Mpx-Eingang Nr. 17
PERI_TR_GR4->unTR_CTL[0].stcField.u8TR_SEL = 17; // 17 bedeutet TCPWM_16_TR_OUT00
// #############################################################################
// 1. Set the Control Register
TCPWMx_GRPx_CNTx_CAPTURE->unCTRL.stcField = sent_capture_control;
// 2. Set the Period Register
TCPWMx_GRPx_CNTx_CAPTURE->unPERIOD.u32Register = 0xFFFFul;
// 3. Set the Counter Register
TCPWMx_GRPx_CNTx_CAPTURE->unCOUNTER.u32Register = 0ul;
// 4. Set the TR_IN_SEL0 register for select input trigger;
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_SEL0.stcField.u8CAPTURE0_SEL = 2; // 2 = HSIOM, PortPin
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_SEL0.stcField.u8RELOAD_SEL = 5; // 5 = MUX4 TR_ALL_CNT_IN[0]
// 5. Set the TR_IN_EDGE_SEL register to capture the edge of the input trigger
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_EDGE_SEL.stcField.u2CAPTURE0_EDGE = 1; // 1 = Falling Edge
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_EDGE_SEL.stcField.u2RELOAD_EDGE = 1; // 1 = Falling Edge
// 6. SET the CC0 Register
TCPWMx_GRPx_CNTx_CAPTURE->unCC0.stcField.u32CC = 0ul;
// 7. Set the CC0_BUF register; CC0_BUFF
TCPWMx_GRPx_CNTx_CAPTURE->unCC0_BUFF.stcField.u32CC = 0ul;
// 8. Set the TR_OUT_SEL register;
TCPWMx_GRPx_CNTx_CAPTURE->unTR_OUT_SEL.stcField.u3OUT0 = 3; // 3 = Compare Match0 Event
TCPWMx_GRPx_CNTx_CAPTURE->unTR_OUT_SEL.stcField.u3OUT1 = 7; // 7 = disabled
// #############################################################################
Cy_Tcpwm_Counter_SetCC0_IntrMask(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_Counter_SetCC1_IntrMask(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_Counter_Enable(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_TriggerStart(TCPWMx_GRPx_CNTx_CAPTURE);
It works BUT:
Looping the TCPWM Capture Event output signal through the Trigger Multiplexer back into the Trigger-Input of the TCPWM takes 2 timer ticks in my case. The measured time duration is always 2 ticks to small. After adding this systematic error to the captured values this setup worked for my purposes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi AS_36,
I use the CYT2B75CADES on the CYTVII-B-E-1M-SK Starter Kit. In the meantime I understand that I have to employ the Peripheral Device Interconnect System aka Trigger MUX.
I copied the timer initialization from one of your AppNotes and it runs just fine. On every falling edge of the input signal the timer is captured and the program branches into the respective service routine.
However the "Auto Reload" functionality does not work yet. I tried to implement this with part printed below in bold.
cy_stc_tcpwm_counter_config_t const sent_capture_config = {
.period = 0xFFFFul,
.clockPrescaler = CY_TCPWM_COUNTER_PRESCALER_DIVBY_2,
.runMode = CY_TCPWM_COUNTER_CONTINUOUS,
.countDirection = CY_TCPWM_COUNTER_COUNT_UP,
.debug_pause = true,
.CompareOrCapture = CY_TCPWM_COUNTER_MODE_CAPTURE,
.compare0 = 0uL,
.compare0_buff = 0uL,
.compare1 = 0uL,
.compare1_buff = 0uL,
.enableCompare0Swap = false,
.enableCompare1Swap = false,
.interruptSources = CY_TCPWM_INT_ON_CC,
.capture0InputMode = CY_TCPWM_INPUT_FALLING_EDGE,
.capture0Input = CY_TCPWM_INPUT_TRIG0,
.reloadInputMode = 3uL,
.reloadInput = 0uL,
.startInputMode = 3uL,
.startInput = 0uL,
.stopInputMode = 3uL,
.stopInput = 0uL,
.capture1InputMode = CY_TCPWM_INPUT_FALLING_EDGE,
.capture1Input = CY_TCPWM_INPUT0,
.countInputMode = 3uL,
.countInput = 1uL,
.trigger1 = CY_TCPWM_COUNTER_CC0_MATCH,
.trigger2 = CY_TCPWM_COUNTER_CC0_MATCH
};
/* Assign a programmable divider for TCPWM0_GRPx_CNTx_COUNTER */
Cy_SysClk_PeriphAssignDivider(PCLK_TCPWMx_CLOCKSx_CAPTURE, CY_SYSCLK_DIV_16_BIT, TCPWMx_PERI_CLK_DIVIDER_NO);
/* Sets the 16-bit divider */
Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_16_BIT, TCPWMx_PERI_CLK_DIVIDER_NO, (divNum - 1ul));
/* Enable the divider */
Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_16_BIT, TCPWMx_PERI_CLK_DIVIDER_NO);
/* Interrupt setting for Capture */
Cy_SysInt_InitIRQ(&irq_cfg);
Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, capture_isr_handler);
/* Set the Interrupt Priority & Enable the Interrupt */
NVIC_SetPriority(irq_cfg.intIdx, 3ul);
NVIC_EnableIRQ(irq_cfg.intIdx);
/* Peripheral Connect (Trigger Multiplexer) for Auto Reload */
Cy_TrigMux_Connect(TRIG_IN_MUX_4_TCPWM_16_TR_OUT00,
TRIG_OUT_MUX_4_TCPWM_ALL_CNT_TR_IN0,
0 /*invert*/,
TRIGGER_TYPE_EDGE,
0 /*dbg_frz_en*/);
/*Trigger Capture Timer by SW*/
Cy_TrigMux_SwTrigger(TRIG_OUT_MUX_4_TCPWM_ALL_CNT_TR_IN0,
TRIGGER_TYPE_EDGE, 1 /*output*/);
/* Initialize PCLK_TCPWM0_CLOCKSx_CAPTURE as Capture Mode & Enable */
Cy_Tcpwm_Counter_Init(TCPWMx_GRPx_CNTx_CAPTURE, &sent_capture_config);
Cy_Tcpwm_Counter_SetCC0_IntrMask(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_Counter_SetCC1_IntrMask(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_Counter_Enable(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_TriggerStart(TCPWMx_GRPx_CNTx_CAPTURE);
Thank you for your support,
Best regards
Ralf
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I think I found a solution myself by using the Trigger Multiplexer 4:
// Trigger Mux Configuration
// Innerhalb des Multiplexers 4: verbinde Mpx-Ausgang Nr. 0 mit Mpx-Eingang Nr. 17
PERI_TR_GR4->unTR_CTL[0].stcField.u8TR_SEL = 17; // 17 bedeutet TCPWM_16_TR_OUT00
// #############################################################################
// 1. Set the Control Register
TCPWMx_GRPx_CNTx_CAPTURE->unCTRL.stcField = sent_capture_control;
// 2. Set the Period Register
TCPWMx_GRPx_CNTx_CAPTURE->unPERIOD.u32Register = 0xFFFFul;
// 3. Set the Counter Register
TCPWMx_GRPx_CNTx_CAPTURE->unCOUNTER.u32Register = 0ul;
// 4. Set the TR_IN_SEL0 register for select input trigger;
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_SEL0.stcField.u8CAPTURE0_SEL = 2; // 2 = HSIOM, PortPin
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_SEL0.stcField.u8RELOAD_SEL = 5; // 5 = MUX4 TR_ALL_CNT_IN[0]
// 5. Set the TR_IN_EDGE_SEL register to capture the edge of the input trigger
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_EDGE_SEL.stcField.u2CAPTURE0_EDGE = 1; // 1 = Falling Edge
TCPWMx_GRPx_CNTx_CAPTURE->unTR_IN_EDGE_SEL.stcField.u2RELOAD_EDGE = 1; // 1 = Falling Edge
// 6. SET the CC0 Register
TCPWMx_GRPx_CNTx_CAPTURE->unCC0.stcField.u32CC = 0ul;
// 7. Set the CC0_BUF register; CC0_BUFF
TCPWMx_GRPx_CNTx_CAPTURE->unCC0_BUFF.stcField.u32CC = 0ul;
// 8. Set the TR_OUT_SEL register;
TCPWMx_GRPx_CNTx_CAPTURE->unTR_OUT_SEL.stcField.u3OUT0 = 3; // 3 = Compare Match0 Event
TCPWMx_GRPx_CNTx_CAPTURE->unTR_OUT_SEL.stcField.u3OUT1 = 7; // 7 = disabled
// #############################################################################
Cy_Tcpwm_Counter_SetCC0_IntrMask(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_Counter_SetCC1_IntrMask(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_Counter_Enable(TCPWMx_GRPx_CNTx_CAPTURE);
Cy_Tcpwm_TriggerStart(TCPWMx_GRPx_CNTx_CAPTURE);
It works BUT:
Looping the TCPWM Capture Event output signal through the Trigger Multiplexer back into the Trigger-Input of the TCPWM takes 2 timer ticks in my case. The measured time duration is always 2 ticks to small. After adding this systematic error to the captured values this setup worked for my purposes.