cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 4

ellec_4046396
New Contributor

I am using a PSOC 4200.

I need to sample a single free running timer clocked at 1 megahertz from multiple digital input triggers.

PSOC does not seem to easily support multiple input capture signals on a single timer, so my solution is to create multiple timers running synchronously.

The attached graphic illustrates my proposed solution to this problem.

If I configure the timer counters without the start input, I am able to start them with calls like InputCapture_DG1_1_Timer_Start().

However, it takes 70 microseconds for the four InputCapture_NN_Timer_Start() routines to run, so they are not well synchronized.

That is why I added the start inputs to the TCPWM timers and connected them to the CaptureTimer_ReloadReg control register.

I have attempted to start the timers by calling CaptureTimer_ReloadReg_Write(0) and then CaptureTimer_ReloadReg_Write(1), when the start input is configured to

respond to rising edge signals, but the timers do not start. I am calling InputCapture_DG1_1_Timer_Start() prior to strobing CaptureTimer_ReloadReg so that InputCapture_DG1_1_Timer_Init() has been called prior to the strobe.

Does anyone have an idea why this is not working?

Any alternative suggestions?

capture.png

0 Likes
1 Solution
MotooTanaka
Esteemed Contributor

Hi,

I think that I encountered similar problem before, I gave up then, but tried again this morning.

It seems that we need to call TCPWM_x_Enable() after TCPWM_x_Init() to make the timer start.

I used CY8CKIT-044 for this and connected each Trigger_x to Capture_x with a jumper wire to test.

Schematic

001-schematic.JPG

TeraTerm log

000-TeraTerm-Log.JPG

main.c

=============================

#include "project.h"

#include "stdio.h"

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_UartPutString(str) ;

}

#define CAPTURE_NONE 0x00

#define CAPTURE_ALL  0x01

#define CAPTURE_1    0x02

#define CAPTURE_2    0x04

#define CAPTURE_3    0x08

#define CAPTURE_4    0x10

volatile int count[4] = { 0u } ;

CY_ISR(timer1_isr)

{

    TCPWM_1_ClearInterrupt(TCPWM_1_INTR_MASK_CC_MATCH) ;

    count[0] = TCPWM_1_ReadCapture() ;

    TCPWM_1_Stop() ;

}

CY_ISR(timer2_isr)

{

    TCPWM_2_ClearInterrupt(TCPWM_2_INTR_MASK_CC_MATCH) ;

    count[1] = TCPWM_2_ReadCapture() ;

    TCPWM_2_Stop() ;

}

CY_ISR(timer3_isr)

{

    TCPWM_3_ClearInterrupt(TCPWM_3_INTR_MASK_CC_MATCH) ;

    count[2] = TCPWM_3_ReadCapture() ;

    TCPWM_3_Stop() ;

}

CY_ISR(timer4_isr)

{

    TCPWM_4_ClearInterrupt(TCPWM_4_INTR_MASK_CC_MATCH) ;

    count[3] = TCPWM_4_ReadCapture() ;

    TCPWM_4_Stop() ;

}

void clear_timers(void)

{

    TCPWM_1_Init() ;

    TCPWM_2_Init() ;

    TCPWM_3_Init() ;

    TCPWM_4_Init() ;  

    TCPWM_1_WriteCounter(0) ;

    TCPWM_2_WriteCounter(0) ;

    TCPWM_3_WriteCounter(0) ;

    TCPWM_4_WriteCounter(0) ;  

  

    TCPWM_1_Enable() ;

    TCPWM_2_Enable() ;

    TCPWM_3_Enable() ;

    TCPWM_4_Enable() ;  

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_Start() ;

  

    CaptureOut_Write(CAPTURE_NONE) ;

    Control_Reg_Write(0) ;

  

    timer_int_1_ClearPending() ;

    timer_int_1_StartEx(timer1_isr) ;

    timer_int_2_ClearPending() ;

    timer_int_2_StartEx(timer2_isr) ;

    timer_int_3_ClearPending() ;

    timer_int_3_StartEx(timer3_isr) ;

    timer_int_4_ClearPending() ;

    timer_int_4_StartEx(timer4_isr) ;

  

    clear_timers() ;

}

void print_values(void)

{

    int i ;

    print("Captured: ") ;

    for (i = 0 ; i < 4 ; i++ ) {

        sprintf(str, "Timer %d: %d ", i+1, count) ;

        print(str) ;

    }

    print("\n") ;

}

void splash(void)

{

    sprintf(str, "Multi Capture Timer Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

  

    splash() ;

  

    print("Test 1 all at once\n") ;

    Control_Reg_Write(1) ;

    CyDelayUs(23) ;

    CaptureOut_Write(CAPTURE_ALL) ;

    print_values() ;

    CaptureOut_Write(CAPTURE_NONE) ;

    Control_Reg_Write(0) ;

  

    clear_timers() ;

  

    print("Test 2 different timings\n") ;

    Control_Reg_Write(1) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_1) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_2) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_3) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_4) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_NONE) ;

    print_values() ;

    for(;;)

    {

        /* Place your application code here. */

    }

}

=============================

moto

View solution in original post

2 Replies
MotooTanaka
Esteemed Contributor

Hi,

I think that I encountered similar problem before, I gave up then, but tried again this morning.

It seems that we need to call TCPWM_x_Enable() after TCPWM_x_Init() to make the timer start.

I used CY8CKIT-044 for this and connected each Trigger_x to Capture_x with a jumper wire to test.

Schematic

001-schematic.JPG

TeraTerm log

000-TeraTerm-Log.JPG

main.c

=============================

#include "project.h"

#include "stdio.h"

char str[128] ; /* print buffer */

void print(char *str)

{

    UART_UartPutString(str) ;

}

#define CAPTURE_NONE 0x00

#define CAPTURE_ALL  0x01

#define CAPTURE_1    0x02

#define CAPTURE_2    0x04

#define CAPTURE_3    0x08

#define CAPTURE_4    0x10

volatile int count[4] = { 0u } ;

CY_ISR(timer1_isr)

{

    TCPWM_1_ClearInterrupt(TCPWM_1_INTR_MASK_CC_MATCH) ;

    count[0] = TCPWM_1_ReadCapture() ;

    TCPWM_1_Stop() ;

}

CY_ISR(timer2_isr)

{

    TCPWM_2_ClearInterrupt(TCPWM_2_INTR_MASK_CC_MATCH) ;

    count[1] = TCPWM_2_ReadCapture() ;

    TCPWM_2_Stop() ;

}

CY_ISR(timer3_isr)

{

    TCPWM_3_ClearInterrupt(TCPWM_3_INTR_MASK_CC_MATCH) ;

    count[2] = TCPWM_3_ReadCapture() ;

    TCPWM_3_Stop() ;

}

CY_ISR(timer4_isr)

{

    TCPWM_4_ClearInterrupt(TCPWM_4_INTR_MASK_CC_MATCH) ;

    count[3] = TCPWM_4_ReadCapture() ;

    TCPWM_4_Stop() ;

}

void clear_timers(void)

{

    TCPWM_1_Init() ;

    TCPWM_2_Init() ;

    TCPWM_3_Init() ;

    TCPWM_4_Init() ;  

    TCPWM_1_WriteCounter(0) ;

    TCPWM_2_WriteCounter(0) ;

    TCPWM_3_WriteCounter(0) ;

    TCPWM_4_WriteCounter(0) ;  

  

    TCPWM_1_Enable() ;

    TCPWM_2_Enable() ;

    TCPWM_3_Enable() ;

    TCPWM_4_Enable() ;  

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_Start() ;

  

    CaptureOut_Write(CAPTURE_NONE) ;

    Control_Reg_Write(0) ;

  

    timer_int_1_ClearPending() ;

    timer_int_1_StartEx(timer1_isr) ;

    timer_int_2_ClearPending() ;

    timer_int_2_StartEx(timer2_isr) ;

    timer_int_3_ClearPending() ;

    timer_int_3_StartEx(timer3_isr) ;

    timer_int_4_ClearPending() ;

    timer_int_4_StartEx(timer4_isr) ;

  

    clear_timers() ;

}

void print_values(void)

{

    int i ;

    print("Captured: ") ;

    for (i = 0 ; i < 4 ; i++ ) {

        sprintf(str, "Timer %d: %d ", i+1, count) ;

        print(str) ;

    }

    print("\n") ;

}

void splash(void)

{

    sprintf(str, "Multi Capture Timer Test (%s %s)\n", __DATE__, __TIME__) ;

    print(str) ;

}

int main(void)

{

    init_hardware() ;

  

    splash() ;

  

    print("Test 1 all at once\n") ;

    Control_Reg_Write(1) ;

    CyDelayUs(23) ;

    CaptureOut_Write(CAPTURE_ALL) ;

    print_values() ;

    CaptureOut_Write(CAPTURE_NONE) ;

    Control_Reg_Write(0) ;

  

    clear_timers() ;

  

    print("Test 2 different timings\n") ;

    Control_Reg_Write(1) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_1) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_2) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_3) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_4) ;

    CyDelayUs(12) ;

    CaptureOut_Write(CAPTURE_NONE) ;

    print_values() ;

    for(;;)

    {

        /* Place your application code here. */

    }

}

=============================

moto

View solution in original post

ellec_4046396
New Contributor

Hello Motoo,

Thanks for your reply. It was helpful. I see that the generated source for Timer_Start() calls Timer_Enable(), so that was what I needed to do.

My code was calling Timer_Stop(). I naively assumed that after calling Timer_Stop() all that I needed to do was strobe the Start input signal, but nothing happened in that case.

If I call Timer_Stop, then call Timer_Start(which calls Timer_Enable), and then strobe the Start input signal, then the timer starts counting.

Thanks,

Elliot Leonard