TCPWM, Auto Reload on Capture Event

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
JJack
Level 5
Level 5
Associated Partner - Distributor Rutronik
5 questions asked 25 likes received 100 sign-ins

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)?

0 Likes
1 Solution
JJack
Level 5
Level 5
Associated Partner - Distributor Rutronik
5 questions asked 25 likes received 100 sign-ins

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.

View solution in original post

0 Likes
3 Replies
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi @JJack 

Please provide the part number of the device you are using.

Regards.

0 Likes
JJack
Level 5
Level 5
Associated Partner - Distributor Rutronik
5 questions asked 25 likes received 100 sign-ins

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

0 Likes
JJack
Level 5
Level 5
Associated Partner - Distributor Rutronik
5 questions asked 25 likes received 100 sign-ins

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.

0 Likes