SCTimer Falling Edge Event Not Consistently Firing

cancel
Showing results for 
Search instead for 
Did you mean: 

SCTimer Falling Edge Event Not Consistently Firing

618 Views
use
Contributor II

I am currently attempting to use the SCTimer on the LPC54606 to measure pulse widths. The state registers are configured so that when a rising edge occurs, the state moves to 1. When in state 1, a falling edge event is allowed. This event lowers the state back to 0 and triggers an interrupt where I grab the counter data and reset it. This seems to work about 80% of the time but it is occasionally missing the falling edge and so the state remains in state 1. Even with slow pulses (0.5 ms on, 0.5 ms off) it is missing edges and the event doesn't fire. Has anybody else experienced this?

Thanks

Labels (1)
4 Replies

240 Views
timcarney
Contributor II

I believe I have seen similar behavior. My issue has been reported here: https://community.nxp.com/message/1062204 

0 Kudos

240 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

Hi,

Thank you for your interest in NXP Semiconductor products and 
the opportunity to serve you.
I was wondering if you can share the demo code which can replicate the phenomenon.

Have a great day,
TIC

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!

0 Kudos

240 Views
use
Contributor II

I am using the high counter for the edge detection counter and the low (currently unused) for PWM generation.

sctimer_event_callback_t sctimer_callback_table = { SCT_Detection_Callback };

void PulseDetection_Init(void)
{

   sctimer_config_t sctimerInfo;

   SCTIMER_GetDefaultConfig(&sctimerInfo);
   sctimerInfo.enableCounterUnify = FALSE;
   SCTIMER_Init(SCT0, &sctimerInfo);

   INPUTMUX->SCT0_INMUX[2] = 0x2; //GPIO0_2

   uint32_t risingEdge_Event;
   uint32_t fallingEdge_Event;
   //Create an event for rising edge //kSCTIMER_InputLowEvent kSCTIMER_InputFallEvent
   SCTIMER_CreateAndScheduleEvent(SCT0,kSCTIMER_InputRiseEvent,0,2,kSCTIMER_Counter_H,&risingEdge_Event);
   SCTIMER_CreateAndScheduleEvent(SCT0,kSCTIMER_InputFallEvent,0,2,kSCTIMER_Counter_H,&fallingEdge_Event);

   //Start counter when Rising Edge occurs
   SCTIMER_SetupCounterStartAction(SCT0,kSCTIMER_Counter_H,risingEdge_Event);
   SCTIMER_SetupNextStateAction(SCT0,1,risingEdge_Event); //not working as expected

   //HALT counter when falling edge occurs
   SCTIMER_SetupCounterHaltAction(SCT0,kSCTIMER_Counter_H,fallingEdge_Event);

   //Set callback for interrupt
   SCTIMER_SetCallback(SCT0, sctimer_callback_table, fallingEdge_Event);

   SCTIMER_EnableInterrupts(SCT0,1<<fallingEdge_Event);
   NVIC_SetPriority(SCT0_IRQn, IRQ_PRIORITY_CTIMER);

   SCT0->EVENT[risingEdge_Event].CTRL |= 0x0000C010; //set state to 1 after this event occurs and HEVENT to 1
   SCT0->EVENT[fallingEdge_Event].CTRL |= 0x00004010; //set state to 0 after this event occurs

   NVIC_EnableIRQ(SCT0_IRQn);

   //SCTIMER_StartTimer(SCT0,kSCTIMER_Counter_H);

   SCT0->EVENT[risingEdge_Event].STATE = 0x00000001; //enable rising egde in state 0
   SCT0->EVENT[fallingEdge_Event].STATE = 0x00000002; //enable falling edge in state 1

   uint32_t CTRL_Enable_Event = SCT0->CTRL;

   CTRL_Enable_Event &= (~(SCT_CTRL_HALT_H_MASK) ); //clear halt H bit
   CTRL_Enable_Event |= SCT_CTRL_STOP_H_MASK; //set stop H bit

   SCT0->CTRL = CTRL_Enable_Event; //Write both changes at once

   SCT0->CTRL |= (1<<19);//clear counter
}

void SCT_Detection_Callback(void)
{

   widths[count++] = (SCT0->COUNT) >> 16; //add width value to array

   SCT0->CTRL |= (1<<19);//clear counter

   uint32_t CTRL_Enable_Event = SCT0->CTRL;
   CTRL_Enable_Event &= (~(SCT_CTRL_HALT_H_MASK) ); //clear halt H bit
   CTRL_Enable_Event |= SCT_CTRL_STOP_H_MASK; //set stop H bit
   SCT0->CTRL = CTRL_Enable_Event; //Write both changes at once
}

0 Kudos

240 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

Hi use,

In my honest, your coding style will make some troubles for you in future and it takes me some time to figure it out.

And I've simplified your code which is illustrated below, please giving it a try.

/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "fsl_debug_console.h"
#include "board.h"
#include "fsl_sctimer.h"

#include "pin_mux.h"
#include "fsl_inputmux.h"
#include <stdbool.h>
/*******************************************************************************
 * Definitions
 ******************************************************************************/

#define BUS_CLK_FREQ CLOCK_GetFreq(kCLOCK_BusClk)


/*******************************************************************************
 * Prototypes
 ******************************************************************************/
sctimer_event_callback_t sctimer_callback_table={SCT_Detection_Callback};


uint32_t widths;

void SCT_Detection_Callback(void)
{

  widths = SCT0->COUNT;

   SCT0->CTRL |= (1<<19);//clear counter

   uint32_t CTRL_Enable_Event = SCT0->CTRL;
   CTRL_Enable_Event &= (~(SCT_CTRL_HALT_H_MASK) ); //clear halt H bit
   CTRL_Enable_Event |= SCT_CTRL_STOP_H_MASK; //set stop H bit
   SCT0->CTRL = CTRL_Enable_Event; //Write both changes at once
}





/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Main function
 */
int main(void)
{
    sctimer_config_t sctimerInfo;

    uint32_t stateNumber;
    uint32_t eventNumberInput, eventNumberInputPlus;
    uint32_t sctimerClock;

    /* Board pin, clock, debug console init */
    CLOCK_EnableClock(kCLOCK_Gpio0);
    CLOCK_EnableClock(kCLOCK_Gpio3);
    /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

    /* configure the input mux for the sct timer input1 from external pin*/
    INPUTMUX_Init(INPUTMUX);
    INPUTMUX_AttachSignal(INPUTMUX, 1U, kINPUTMUX_SctGpi6ToSct0);

    BOARD_InitPins();
    BOARD_BootClockFROHF48M();
    BOARD_InitDebugConsole();

    sctimerClock = BUS_CLK_FREQ;

    /* Print a note to terminal */
    PRINTF("\r\nSCTimer example\r\n");

    /* Default configuration operates the counter in 32-bit mode */
    SCTIMER_GetDefaultConfig(&sctimerInfo);

    /* Initialize SCTimer module */
    SCTIMER_Init(SCT0, &sctimerInfo);

    stateNumber = SCTIMER_GetCurrentState(SCT0);

    /* Schedule an event to look for a rising edge on input 1 in this state */
    if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_InputRiseEvent, 0, kSCTIMER_Input_1, kSCTIMER_Counter_L,
                                       &eventNumberInput) == kStatus_Fail)
    {
        return -1;
    }

    /* Transition to next state when a rising edge is detected on input 1 */
    SCTIMER_SetupNextStateAction(SCT0, stateNumber + 1, eventNumberInput);

    /* Go to next state; State 1 */
    SCTIMER_IncreaseState(SCT0);

    /* Schedule an event to look for a rising edge on input 1 in this state */
    if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_InputFallEvent, 0, kSCTIMER_Input_1, kSCTIMER_Counter_L,
                                       &eventNumberInputPlus) == kStatus_Fail)
    {
        return -1;
    }

    /* Transition to next state when a rising edge is detected on input 1 */
    SCTIMER_SetupNextStateAction(SCT0, stateNumber - 2, eventNumberInputPlus);

    //HALT counter when falling edge occurs
     SCTIMER_SetupCounterHaltAction(SCT0,kSCTIMER_Counter_L,eventNumberInputPlus);

     SCTIMER_SetCallback(SCT0, sctimer_callback_table, eventNumberInputPlus);

     SCTIMER_EnableInterrupts(SCT0,1<<eventNumberInputPlus);


     NVIC_EnableIRQ(SCT0_IRQn);


    /* Start the timer, use counter L as we are operating counter in 32-bit mode */
    SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_L);


    while (1)
    {
    }
}

TIC

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!

 

0 Kudos