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.

LAUNCHXL-F28377S: Synchronize all eCaps with SWSYNC

Part Number: LAUNCHXL-F28377S

Hello everyone,

I'm trying to measure time differences for some input signals. Therefore I want to use the eCap Peripherals from the F28377S. After reading through several threads in the forum I cannot find the problem with my application.

I configure all ecaps as followed:

void eCaps_init(void)
{
    gpioInit();
    EALLOW;

    SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP1, SYSCTL_SYNC_IN_SRC_EPWM10SYNCOUT);
    SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP4, SYSCTL_SYNC_IN_SRC_ECAP1SYNCOUT);

    for(unsigned i = 0; i < DIM(ecap_bases); ++i)
    {
        singleEcapInit(ecap_bases[i]);
    }

    irqInit();
    EDIS;
}
static void singleEcapInit(uint32_t base)
{
    ECAP_disableInterrupt(base, ALL_ECAP_EVENTS);
    ECAP_clearInterrupt(base, ALL_ECAP_EVENTS);

    ECAP_stopCounter(base);
    ECAP_disableTimeStampCapture(base);

    ECAP_setPhaseShiftCount(base, 0u);
    ECAP_enableLoadCounter(base);
    ECAP_setSyncOutMode(base, ECAP_SYNC_OUT_SYNCI);

    ECAP_setCaptureMode(base, ECAP_CONTINUOUS_CAPTURE_MODE, ECAP_EVENT_4);

    ECAP_setEventPolarity(base, ECAP_EVENT_1, ECAP_EVNT_FALLING_EDGE);
    ECAP_setEventPolarity(base, ECAP_EVENT_2, ECAP_EVNT_RISING_EDGE);
    ECAP_setEventPolarity(base, ECAP_EVENT_3, ECAP_EVNT_FALLING_EDGE);
    ECAP_setEventPolarity(base, ECAP_EVENT_4, ECAP_EVNT_RISING_EDGE);

    ECAP_disableCounterResetOnEvent(base, ECAP_EVENT_1);
    ECAP_disableCounterResetOnEvent(base, ECAP_EVENT_2);
    ECAP_disableCounterResetOnEvent(base, ECAP_EVENT_3);
    ECAP_disableCounterResetOnEvent(base, ECAP_EVENT_4);

    ECAP_enableCaptureMode(base);
    ECAP_enableTimeStampCapture(base);
    ECAP_enableInterrupt(base, USED_ECAP_IRQS);

    ECAP_startCounter(base);
}

The counters are running as expected but when I want to synchronize the eCaps by setting ECap1Regs.ECCTL2.SWSYNC only eCap 1 resets.

If I do the same with ECap2Regs.ECCTL2.SWSYNC only eCap2 resets (and not eCap3) -> As I can reset eCap2, I suppose SYNCI_EN is OK and the failure is that the signal from eCap1 doesn't popule as configured within SYNCO_SEL?
From the Technical_Reference_Manual for SWSYNC: Writing a one forces a TSCTR shadow load of current module and any modules down-stream providing the SYNCO_SEL bits are 0, 0.

I have following Configuration for all eCaps (as seen in Registers view within CCS):

CTRPHS    0x00000000    Counter Phase Offset Value Register [Memory Mapped]
ECCTL1    0x0111    Capture Control Register 1 [Memory Mapped]
ECCTL2    0x0036    Capture Control Register 2 [Memory Mapped]
ECEINT    0x003E    Capture Interrupt Enable Register [Memory Mapped]

For synchronization I suppose following bits are the most interresting ones (also taken from debug view):

SYNCO_SEL    00    Sync-out mode
SYNCI_EN    1    Counter sync-in select

I get the interrupts as I want them to with anything else. Only synchronization fails.

Is there anything else I have to look out in order to use SYNC_OUT as I intend to?

  • Hi Alexander,

    You can follow the sequence below to synchronize all 6 eCAPs, to capture the time stamp.

    ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/

    ECap2Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap2Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/

    ECap3Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap3Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/

    ECap4Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap4Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/

    ECap5Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap5Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/

    ECap6Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap6Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/

    EALLOW;
    SyncSocRegs.SYNCSELECT.bit.ECAP4SYNCIN = 4U;
    EDIS;

    /* Synchronize all ECAPs */
    EALLOW;
    ECap1Regs.ECCTL2.SWSYNC = 1U;
    EDIS;

    Regards,
    Nirav
  • Thanks for you reply.

    I tried something like the following (I extracted code for string manipulation and waiting):

    InitECapture(ECap1Regs);
    InitECapture(ECap2Regs);
    
    ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/
    
    ECap2Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/
    ECap2Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/
    
    EALLOW;
    SyncSocRegs.SYNCSELECT.bit.ECAP4SYNCIN = 4U;
    EDIS;
    
    while(1)
    {
        EALLOW;
        ECap1Regs.ECCTL2.bit.SWSYNC = 1U;
        EDIS;
    
        const uint32_t ecap1tsctr = ECap1Regs.TSCTR;
        const uint32_t ecap2tsctr = ECap2Regs.TSCTR;
        
        printf("ECAP1: %X", ecap1tsctr);
        printf("ECAP2: %X", ecap2tsctr);
        
        delay();
    }
    

    And receive the following:

    ECAP1: 1
    ECAP2: 32A
    ECAP1: 1
    ECAP2: 2987C45
    ECAP1: 1
    ECAP2: 53DA2C6
    ECAP1: 1
    ECAP2: 7E2C949
    ECAP1: 1
    ...

    ECAP1 resets as I want it to, but ECAP2 won't reset :(

  • Hi Alexander,

    Can you send me your complete code (along with all the initialization functions used prior)? I can try it on my end to see what is going on. 

    Regards,

    Nirav

  • This is my main.cpp:


    #include "F28x_Project.h" static void InitECapture(volatile ECAP_REGS & ecap); static void output_init(void); static char * u32_to_hex(uint32_t dat, char * pOut); static void output_puts(const char * pData); void main(void) { InitSysCtrl(); InitGpio(); EALLOW; GpioCtrlRegs.GPADIR.bit.GPIO12 = 1; EDIS; output_init(); // turn off LED GpioDataRegs.GPADAT.bit.GPIO12 = 1; InitECap1Gpio(14); GPIO_SetupPinOptions(14, GPIO_INPUT, GPIO_ASYNC); InitECap2Gpio(15); GPIO_SetupPinOptions(15, GPIO_INPUT, GPIO_ASYNC); InitECapture(ECap1Regs); InitECapture(ECap2Regs); ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/ ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/ ECap2Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/ ECap2Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/ ECap3Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/ ECap3Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/ ECap4Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/ ECap4Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/ ECap5Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/ ECap5Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/ ECap6Regs.ECCTL2.bit.SYNCI_EN = 1; /* Enable sync in*/ ECap6Regs.ECCTL2.bit.SYNCO_SEL = 0; /* Pass through*/ EALLOW; SyncSocRegs.SYNCSELECT.bit.ECAP4SYNCIN = 4U; EDIS; char output[100]; while(1) { EALLOW; ECap1Regs.ECCTL2.bit.SWSYNC = 1U; EDIS; const uint32_t ecap1tsctr = ECap1Regs.TSCTR; const uint32_t ecap2tsctr = ECap2Regs.TSCTR; output_puts("ECAP1: "); char * p = u32_to_hex(ecap1tsctr, output); *p = '\0'; output_puts(output); output_puts("\n"); output_puts("ECAP2: "); p = u32_to_hex(ecap2tsctr, output); *p = '\0'; output_puts(output); output_puts("\n"); // Turn on LED GpioDataRegs.GPADAT.bit.GPIO12 = 0; // Delay for a bit. for(uint32_t delay = 0; delay < 2000000; delay++){} // Turn off LED GpioDataRegs.GPADAT.bit.GPIO12 = 1; // Delay for a bit. for(uint32_t delay = 0; delay < 2000000; delay++){} } } // // InitECapture - Initialize ECAP1 configurations static void InitECapture(volatile ECAP_REGS & ecap) { ecap.ECEINT.all = 0x0000; // Disable all capture __interrupts ecap.ECCLR.all = 0xFFFF; // Clear all CAP __interrupt flags ecap.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads ecap.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped // // Configure peripheral registers ecap.ECCTL2.bit.CONT_ONESHT = 0; // One-shot ecap.ECCTL2.bit.STOP_WRAP = 3; // Stop at 4 events ecap.ECCTL1.bit.CAP1POL = 1; // Falling edge ecap.ECCTL1.bit.CAP2POL = 0; // Rising edge ecap.ECCTL1.bit.CAP3POL = 1; // Falling edge ecap.ECCTL1.bit.CAP4POL = 0; // Rising edge ecap.ECCTL1.bit.CTRRST1 = 0; // Difference operation ecap.ECCTL1.bit.CTRRST2 = 0; // Difference operation ecap.ECCTL1.bit.CTRRST3 = 0; // Difference operation ecap.ECCTL1.bit.CTRRST4 = 0; // Difference operation ecap.ECCTL2.bit.SYNCI_EN = 1; // Enable sync in ecap.ECCTL2.bit.SYNCO_SEL = 0; // Pass through ecap.ECCTL1.bit.CAPLDEN = 1; // Enable capture units ecap.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter ecap.ECCTL2.bit.REARM = 1; // arm one-shot ecap.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads } static char * u32_to_hex(uint32_t dat, char * pOut) { static const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; bool isWritten = false; uint32_t cur_nibble = dat >> (32 - 4); if(cur_nibble) { *pOut = nibble_to_hex[cur_nibble]; ++pOut; isWritten = true; } for(int i = (32 - 8); i >= 0; i -= 4) { cur_nibble = (dat >> i) & 0xf; if(cur_nibble || isWritten) { *pOut = nibble_to_hex[cur_nibble]; ++pOut; isWritten = true; } } /* If we have nothing written yet, we write a 0 */ if(!isWritten) { *pOut = '0'; ++pOut; } return pOut; } static void output_init(void) { GPIO_SetupPinMux(84, GPIO_MUX_CPU1, 5); GPIO_SetupPinOptions(84, GPIO_INPUT, GPIO_PUSHPULL); GPIO_SetupPinMux(85, GPIO_MUX_CPU1, 5); GPIO_SetupPinOptions(85, GPIO_OUTPUT, GPIO_ASYNC); /* Initialize the SCI FIFO */ SciaRegs.SCIFFTX.all = 0xE040; SciaRegs.SCIFFRX.all = 0x2044; SciaRegs.SCIFFCT.all = 0x0; SciaRegs.SCICCR.all = 0x0007; // 1 stop bit, No loopback // No parity,8 char bits, // async mode, idle-line protocol SciaRegs.SCICTL1.all = 0x0003; // enable TX, RX, internal SCICLK, // Disable RX ERR, SLEEP, TXWAKE SciaRegs.SCICTL2.all = 0x0003; SciaRegs.SCICTL2.bit.TXINTENA = 0; SciaRegs.SCICTL2.bit.RXBKINTENA = 1; // 9600 baud SciaRegs.SCIHBAUD.all = 0x0002; SciaRegs.SCILBAUD.all = 0x008B; SciaRegs.SCICCR.bit.LOOPBKENA = 0; // Disable loop back SciaRegs.SCICTL1.all = 0x0023; // Relinquish SCI from Reset } static void output_puts(const char * pData) { while(*pData) { while(SciaRegs.SCIFFTX.bit.TXFFST != 0){} SciaRegs.SCITXBUF.all = *pData; ++pData; } }
  • The synchronization propagates from eCap1 to eCap2 as soon as I change InputXbarRegs.INPUT5SELECT to some unused Pin i pull down. Even if SyncSocRegs.SYNCSELECT.bit.ECAP1SYNCIN is set to 0 (PWM1 Sync Output).

    What surprises me most with this is that eCap1 resets as expected but doesn't propagate the Sync signal to eCap2...