SCTimer/PWM for Controlling a AC Fan Motor??

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SCTimer/PWM for Controlling a AC Fan Motor??

3,662 Views
leo838
Contributor II

Hello All,

I have a project that controls an AC fan motor via a triac. It senses the zero crossing & then after a delay triggers the triac to supply power to the ac motor. The speed of the fan is determined by the delay (which changes depending on user input) in switching on the triac. It is similar to attached the circuit.

I had been using interrupts & an LPC1768 for this project but am now switching to an '812. After investing it looks like the SCTimer/PWM is a suitable, but complicated in setup & control. Could anyone with experience tell me should I stick with an interrupt driven setup or is the SCTimer/PWM suitable? Once it's setup correctly it seems like it offloads alot of potential overhead.

Many thanks,

Leo

0 Kudos
16 Replies

3,311 Views
leo838
Contributor II

Thanks for the suggestion but I need accurate timing from an input going low & so I need to start the counter from zero from that event.

0 Kudos

3,311 Views
leo838
Contributor II

Jeremy,

Thanks for the reply.

Yes, your correct, the reason I was getting the 5ms delay was the the counter reaching all ones. My post previous to this outlines the reason the counter was not cleared.

I've attached the last version of my project for reference. The quickest I could achieve the stop, clear & restart scheme of the counter was approx 1ms, if you can see any quicker way I be grateful if you could share!

0 Kudos

3,311 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

Thanks for your clarification.
Maybe you can try to create another event to detect the voltage level of kSCTIMER_Out_0 became 0 when the event 2 arises, after detecting it, triggering the counter resume.

In my opinion, it should be quicker than the interrupt handler function.

Have a great day,
TIC

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,311 Views
leo838
Contributor II

It looks like I've found the issue.

I was attempting to stop the counter & trigger an interrupt routine based on the same event. It appears that the counter was still running when the ISR attempted to clear it, hence it failed. Moving the call to the ISR into the following state solved the issue.

However based on the new code the minimum delay I was able to achieve using the stop, clear & restart scheme of the counter was approx 1ms, unsuitable for my application. I cannot see a way to achieve this any quicker. Also occasionally the clearing of the counter was missed & a long delay occurred.

I can definitely see the usefulness of the SCT but unfortunately it seems inappropriate for my application.

0 Kudos

3,311 Views
leo838
Contributor II

Jeremy,

Thanks for the reply.

I've  changed to a 824 & have got a working project running now.

However I've found that I need to stop & restart the counter to achieve consistent timings. Using this technique however it looks like the minimum time I can get from starting the timer, it reaching a limit & triggering the event (setting an output high in state 1) is approx 5ms. I don't see anything in the manual mentioning delays between starting the counter & it running so its difficult to understand the delay. Ideally I'd like to achieve a minimum delay of 500uSec. I attach the project & the main file below.

/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * Modified --
 * Input P0_24
 * Output P0_15
 *
 * State 0 -> rising edges detected on input -> counter L started -> advance to state 1
 * State 1 -> Counter L reaches limit value -> output set high -> advance to state 2
 * State 2- > Falling edge on input -> output set low & counter stopped -> set state to 0
 */

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

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

#define SCTIMER_CLK_FREQ CLOCK_GetFreq(kCLOCK_Irc)
#define DEMO_FIRST_SCTIMER_OUT kSCTIMER_Out_2
#define DEMO_SECOND_SCTIMER_OUT kSCTIMER_Out_4

#define INPUTSYNC0      (0U)
#define INPUTSYNC1      (1U)
#define INPUTSYNC2      (2U)
#define INPUTSYNC3      (3U)

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Main function
 */
int main(void)
{
    sctimer_config_t sctimerInfo;
    uint32_t riseEvent, eventCounterL, fallEvent, riseEvent2; // Modified
    uint32_t stateNumber; // Modified
    uint32_t sctimerClock;
    uint32_t matchValueL;

    /* Board pin, clock, debug console init */
    /* Enable clock of uart0. */
    CLOCK_EnableClock(kCLOCK_Uart0);
    /* Ser DIV of uart0. */
    CLOCK_SetClkDivider(kCLOCK_DivUsartClk, 1U);

    /* configure the input mux for the sct timer input0 from external pin*/
    INPUTMUX_Init(INPUTMUX);
    INPUTMUX_AttachSignal(INPUTMUX, 0U, kINPUTMUX_SctPin0ToSct0);

    BOARD_InitPins();
    BOARD_BootClockIRC12M();
    BOARD_InitDebugConsole();

    /* Enable clock of sct. */
    CLOCK_EnableClock(kCLOCK_Sct);

    sctimerClock = SCTIMER_CLK_FREQ;

    /* Print a note to terminal */
    PRINTF("\r\nAC Fan Controller using an LPC824 & SCT\r\n");

    SCTIMER_GetDefaultConfig(&sctimerInfo);
/* Add judgment for change clock source*/
#if defined(SCTIMER_NEED_CHANGE_CLOCK_SOURCE)
    sctimerInfo.clockMode   = DEMO_CLOCK_MODE;
    sctimerInfo.clockSelect = DEMO_CLOCK_SEL;
#endif

    /* Switch to 16-bit mode */
    sctimerInfo.enableCounterUnify = false;

    /* Calculate prescaler and match value for Counter L for 100ms interval */
    //matchValueL            = MSEC_TO_COUNT(7U, sctimerClock);
    // Looking for 0.5ms or 500uSec resolution
    // From 0 to approx 10ms
    matchValueL            = USEC_TO_COUNT(1000U, sctimerClock);
    sctimerInfo.prescale_l = matchValueL / 65536;
    matchValueL            = matchValueL / (sctimerInfo.prescale_l + 1) - 1;

    // Switch off synchronization for inputs to speed up TODO: Necessary??
    //sctimerInfo.inputsync = (1 << INPUTSYNC0);

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

    stateNumber = SCTIMER_GetCurrentState(SCT0);

    // Interrupt callback for SCT //////////////////////////////////////////////////////////////
    /* The interrupt callback function is used to update the PWM dutycycle */
    void SCTIMER_COUNTER_HANDLER()
    {
        // Clear Counter_L so it starts from known value each time for event
        SCT0->CTRL |=  (1 << SCT_CTRL_CLRCTR_L_SHIFT);
        //GPIO_PortToggle(GPIO, 0U, 1U << 13U);
    }

    // STATE 0 /////////////////////////////////////////////////////////////////////////////////

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

    // Set output in this state TODO DEBUG
       //SCTIMER_SetupOutputToggleAction(SCT0, kSCTIMER_Out_1, riseEvent);

       // Restart counter for (next) timer event
       SCTIMER_SetupCounterStartAction(SCT0, kSCTIMER_Counter_L,riseEvent);

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

       // Goto next state
       SCTIMER_IncreaseState(SCT0);

       // STATE 1 /////////////////////////////////////////////////////////////////////////////////

       // event 1
       // Schedule a single match event for Counter L
       if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, matchValueL, 0, kSCTIMER_Counter_L,
                                          &eventCounterL) == kStatus_Fail)
       {
           return -1;
       }

       // Set output in this state
       SCTIMER_SetupOutputSetAction(SCT0, kSCTIMER_Out_0, eventCounterL);

       // Transition to next state when counter expires
       SCTIMER_SetupNextStateAction(SCT0, stateNumber + 2, eventCounterL);

       // Stop counter to enable it to be cleared in interrupt handler
    SCTIMER_SetupCounterStopAction(SCT0,kSCTIMER_Counter_L,eventCounterL);

       // Enable interrupt for this event
    SCTIMER_EnableInterrupts(SCT0,(1 << eventCounterL));

       /* Receive notification when event is triggered */
       SCTIMER_SetCallback(SCT0, SCTIMER_COUNTER_HANDLER, eventCounterL);

       // Goto next state
       SCTIMER_IncreaseState(SCT0);

       // STATE 2 /////////////////////////////////////////////////////////////////////////////////

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

       // Clear output in this state
       SCTIMER_SetupOutputClearAction(SCT0, kSCTIMER_Out_0, fallEvent);

       // Transition to next state when event occurs in this state, i.e. loop back to initial state
       SCTIMER_SetupNextStateAction(SCT0, stateNumber, fallEvent);

       // STATE 3 /////////////////////////////////////////////////////////////////////////////////
       // Use this state when full power is required
       // SCT will be stuck in this state until software intervention

       // event 3
       /* Schedule an event to look for a rising edge on input 0 in this state */
       if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_InputRiseEvent, 0u, kSCTIMER_Input_0, kSCTIMER_Counter_L,
                                                  &riseEvent2) == kStatus_Fail)

       // Set output in this state
       SCTIMER_SetupOutputSetAction(SCT0, kSCTIMER_Out_0, riseEvent2);

       // No automatic transition to next event..

       ///////////////////////////////////////////////////////////////////////////////////////////

       /* Enable at the NVIC */
       EnableIRQ(SCT0_IRQn);

       /* Start the L counter */
    SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_L);

    /* Force the counter to be placed into memory. */
    volatile static int i = 0 ;

    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {
        i++ ;
//      char strdat[19] = "               ";
//      sprintf(strdat,"\n\r\n\r\n\r%i",SCT0->SCTCAP[riseTimeReg]);
//
//      char strdat2[15] = "               ";
//      sprintf(strdat2,"\n\r%i",SCT0->SCTCAP[fallTimeReg]);
//
//      USART_WriteBlocking(USART0, strdat,19);
//      USART_WriteBlocking(USART0, strdat2,15);

        for(int i=0; i < 5000000; i++);

        PRINTF(".");

        __asm volatile ("nop");
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos

3,311 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,

Sorry for reply late.
Regarding the statement: 'it looks like the minimum time I can get from starting the timer, it reaching a limit & triggering the event (setting an output high in state 1) is approx 5ms.', I think you misunderstand the limit event. When without other event configurations, counting up to all ones or counting down to zero is always equivalent to a limit event occurring. So the 'delay' between the starting the timer and reaching a limit & triggering the event seems like a 'timeout' period actually.
I was wondering if you can share the new code and introduce the testing process, as I'm not very clear with your current question.

Have a great day,
TIC

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,311 Views
leo838
Contributor II

Hello all,

I've hit a wall & could use some assistance. Using the code below I can successfully get an output to go high after the rising edge (state 0) & timer (state 1) have occurred. However the output never gets set low (state 2). If I remove the timer element (state 1) & edit the code the output correctly transitions to follow the input.

Can anyone see what I'm doing wrong? Is it something to do with the timer triggering while the SCT is in other states? Do I need to stop or halt the timer in other states to stop it interfering?

Thanks for looking..

/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2017 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * Modified -- P0_13 now as input to counter to start it,
 *
 * State 0 -> rising edges detected on input -> counter L started -> advance to state 1
 * State 1 -> Counter L reaches limit value -> output set high -> advance to state 2
 * State 2- > Falling edge on input -> output set low & counter reset -> set state to 0
 */

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

#include "pin_mux.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/

#define SCTIMER_CLK_FREQ CLOCK_GetFreq(kCLOCK_Irc)
#define DEMO_FIRST_SCTIMER_OUT kSCTIMER_Out_2
#define DEMO_SECOND_SCTIMER_OUT kSCTIMER_Out_3

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Main function
 */
int main(void)
{
    sctimer_config_t sctimerInfo;
    uint32_t riseEvent, fallEvent; // Modified
    uint32_t stateNumber; // Modified
    uint32_t eventCounterL;
    uint32_t sctimerClock;
    uint32_t matchValueL;

    /* Board pin, clock, debug console init */
    /* Enable clock of uart0. */
    CLOCK_EnableClock(kCLOCK_Uart0);
    /* Ser DIV of uart0. */
    CLOCK_SetClkDivider(kCLOCK_DivUsartClk, 1U);

    BOARD_InitPins();
    BOARD_BootClockIRC12M();
    BOARD_InitDebugConsole();
    /* Enable clock of sct. */
    CLOCK_EnableClock(kCLOCK_Sct);

    sctimerClock = SCTIMER_CLK_FREQ;

    /* Print a note to terminal */
 //   PRINTF("\r\nSCTimer example to use it in 16-bit mode\r\n");
 //   PRINTF("\r\nThe example shows both 16-bit counters running and toggling an output periodically  ");

    SCTIMER_GetDefaultConfig(&sctimerInfo);
/* Add judgment for change clock source*/
#if defined(SCTIMER_NEED_CHANGE_CLOCK_SOURCE)
    sctimerInfo.clockMode   = DEMO_CLOCK_MODE;
    sctimerInfo.clockSelect = DEMO_CLOCK_SEL;
#endif

    /* Switch to 16-bit mode */
    sctimerInfo.enableCounterUnify = false;

    /* Calculate prescaler and match value for Counter L for 10ms */
    matchValueL            = MSEC_TO_COUNT(100U, sctimerClock);
    sctimerInfo.prescale_l = matchValueL / 65536;
    matchValueL            = matchValueL / (sctimerInfo.prescale_l + 1) - 1;

    // Switch off synchronization for inputs to speed up TODO: Necessary??
  //  sctimerInfo.inputsync = 0x0U;

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

    stateNumber = SCTIMER_GetCurrentState(SCT0);
    // STATE 0 /////////////////////////////////////////////////////////////////////////////////

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

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

 // Goto next state
 SCTIMER_IncreaseState(SCT0);

 // STATE 1 /////////////////////////////////////////////////////////////////////////////////

 // event 1
 /* Schedule a single match event for Counter L */
 if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, matchValueL, 0, kSCTIMER_Counter_L,
            &eventCounterL) == kStatus_Fail)
 {
  return -1;
 }

 // Set output in this state
 SCTIMER_SetupOutputSetAction(SCT0, kSCTIMER_Out_0, eventCounterL);

 /* Reset Counter L when Counter L event occurs TODO: Should counter be reset?? */
 //SCTIMER_SetupCounterLimitAction(SCT0, kSCTIMER_Counter_L, eventCounterL);

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

 // Goto next state
 SCTIMER_IncreaseState(SCT0);

 // STATE 2 /////////////////////////////////////////////////////////////////////////////////

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

 // Clear output when event occurs in this state
 SCTIMER_SetupOutputClearAction(SCT0, kSCTIMER_Out_0, fallEvent);

 // Transition to next state when event occurs in this state, i.e. loop back to initial state
 SCTIMER_SetupNextStateAction(SCT0, 0u, fallEvent);

 ///////////////////////////////////////////////////////////////////////////////////////////


 /* Start the L counter */
 SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_L);

 while (1)
 {

  __asm("NOP"); /* delay */

 }
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

& pin_mux.c

/***********************************************************************************************************************
 * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
 * will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
 **********************************************************************************************************************/

/* clang-format off */
/*
 * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Pins v6.0
processor: LPC812
package_id: LPC812M101JDH20
mcu_data: ksdk2_0
processor_version: 6.0.2
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
 */
/* clang-format on */

#include "fsl_common.h"
#include "fsl_swm.h"
#include "pin_mux.h"

/* FUNCTION ************************************************************************************************************
 *
 * Function Name : BOARD_InitBootPins
 * Description   : Calls initialization functions.
 *
 * END ****************************************************************************************************************/
void BOARD_InitBootPins(void)
{
    BOARD_InitPins();
}

/* clang-format off */
/*
 * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitPins:
- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'}
- pin_list:
  - {pin_num: '18', peripheral: USART0, signal: TXD, pin_signal: PIO0_6/VDDCMP}
  - {pin_num: '12', peripheral: USART0, signal: RXD, pin_signal: PIO0_1/ACMP_I2/CLKIN}
  - {pin_num: '3', peripheral: SCT0, signal: 'IN, 1', pin_signal: PIO0_12, mode: pullDown}
  - {pin_num: '2', peripheral: SCT0, signal: 'OUT, 0', pin_signal: PIO0_13, mode: pullDown}
  - {pin_num: '20', peripheral: SCT0, signal: 'OUT, 1', pin_signal: PIO0_14, mode: pullDown}
  - {pin_num: '11', peripheral: SCT0, signal: 'OUT, 2', pin_signal: PIO0_15, mode: pullDown}
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
 */
/* clang-format on */

/* FUNCTION ************************************************************************************************************
 *
 * Function Name : BOARD_InitPins
 * Description   : Configures pin routing and optionally pin electrical features.
 *
 * END ****************************************************************************************************************/
/* Function assigned for the Cortex-M0P */
void BOARD_InitPins(void)
{
    /* Enables clock for switch matrix.: Enable. */
    CLOCK_EnableClock(kCLOCK_Swm);

    IOCON->PIO[2] = ((IOCON->PIO[2] &
                      /* Mask bits to zero which are setting */
                      (~(IOCON_PIO_MODE_MASK)))

                     /* Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-down. Pull-down
                      * resistor enabled. */
                     | IOCON_PIO_MODE(PIO0_12_MODE_PULL_DOWN));

    IOCON->PIO[1] = ((IOCON->PIO[1] &
                      /* Mask bits to zero which are setting */
                      (~(IOCON_PIO_MODE_MASK)))

                     /* Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-down. Pull-down
                      * resistor enabled. */
                     | IOCON_PIO_MODE(PIO0_13_MODE_PULL_DOWN));

    IOCON->PIO[18] = ((IOCON->PIO[18] &
                       /* Mask bits to zero which are setting */
                       (~(IOCON_PIO_MODE_MASK)))

                      /* Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-down. Pull-down
                       * resistor enabled. */
                      | IOCON_PIO_MODE(PIO0_14_MODE_PULL_DOWN));

    IOCON->PIO[10] = ((IOCON->PIO[10] &
                       /* Mask bits to zero which are setting */
                       (~(IOCON_PIO_MODE_MASK)))

                      /* Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-down. Pull-down
                       * resistor enabled. */
                      | IOCON_PIO_MODE(PIO0_15_MODE_PULL_DOWN));

    /* USART0_TXD connect to P0_6 */
    SWM_SetMovablePinSelect(SWM0, kSWM_USART0_TXD, kSWM_PortPin_P0_6);

    /* USART0_RXD connect to P0_1 */
    SWM_SetMovablePinSelect(SWM0, kSWM_USART0_RXD, kSWM_PortPin_P0_1);

    /* SCT_PIN1 connect to P0_12 */
    SWM_SetMovablePinSelect(SWM0, kSWM_CTIN_1, kSWM_PortPin_P0_12);

    /* SCT_OUT0 connect to P0_13 */
    SWM_SetMovablePinSelect(SWM0, kSWM_CTOUT_0, kSWM_PortPin_P0_13);

    /* SCT_OUT1 connect to P0_14 */
    SWM_SetMovablePinSelect(SWM0, kSWM_CTOUT_1, kSWM_PortPin_P0_14);

    /* SCT_OUT2 connect to P0_15 */
    SWM_SetMovablePinSelect(SWM0, kSWM_CTOUT_2, kSWM_PortPin_P0_15);

    /* Disable clock for switch matrix. */
    CLOCK_DisableClock(kCLOCK_Swm);
}
/***********************************************************************************************************************
 * EOF
 **********************************************************************************************************************/
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos

3,311 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

Thanks for your reply.
After having a reviewing of the code, I've not found any of the wrongs in the codes. So I'd like to suggest you take advantage of step in step debug feature to observe the values of the set of SCTimer's registers to locate the issue.

Have a great day,
TIC

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,311 Views
leo838
Contributor II

Thanks for the reply.

In state 1 I’m using the L counter to achieve a delay. The other two states using input edge transitions as events. After using the L counter in state 1 should I stop the counter?

Regards,

0 Kudos

3,309 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

Thanks for your reply.
According to the description of your scheme, I don't think it should stop the counter after using the L counter in state 1.

Have a great day,
TIC

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,309 Views
leo838
Contributor II

Jeremy,

Thanks for the reply. I've spent hours looking at the code & trying to debug but without any success. I've verified that it increments to state 2 & gets stuck there, the event (number 3) in state 2 is never triggered. I've tried numerous ways to trigger & verified the inputs show a level change but no action occurs in this event.

I had thought I'd discovered the reason as a possible bug in the file fsl_sctimer.c. At line 516 the following code appears:

  /* Enable the event in the current state */
    base->EVENT[s_currentEvent].STATE = (1U << s_currentState);

Once s_currentState increases beyond 2 this fails to set anything (only bit 0 & 1 can be set) but this has no impact on my code. Perhaps I'm missing something.

I can only suspect another possible bug or I've damaged my board (an Xpresso board) during debugging. I've attached the project, if you had a moment to see if it runs on a similar board I'd be much appreciated.

Regards,

0 Kudos

3,308 Views
leo838
Contributor II

Well the penny finally dropped! The part I'm using (812) only has 2 states for it's SCT, others have more. Interestingly the manual mentions numerous times the max possible number of events but not states. The SDK software checks for exceedance in events but not states. I found the table below in the SCT cookbook, included for reference by others.

As an aside is it possible for the L & H counter to use the same input & output or must they be separate?

pastedImage_1.png

0 Kudos

3,308 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,

Thanks for your reply and I'm glad to hear that you found out the issue.
Regarding another question, is it possible for the L & H counter to use the same input & output or must they be separated?
-- Yes, the L & H counter share the same clock source.

Have a great day,
TIC

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,310 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
1) Could anyone with experience tell me should I stick with an interrupt driven setup or is the SCTimer/PWM suitable?
-- According to your description, I consider the SCTimer is suited to the application, I've attached an application note which will guide to you how to utilize the SCTimer module.

Have a great day,
TIC

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

3,310 Views
leo838
Contributor II

Many thanks, I'll take a look!

0 Kudos

3,310 Views
leo838
Contributor II

Ive had a look at this but difficult to get my head around. What I'd like to do:

  1. Use an input pin to capture a rising edge from an optocoupler -> this starts a timer
  2. When this timer expires it sets an output high
  3. After a predefined time (eg. 5ms) another event sets the output low
  4. the process continues..

so far I have something like:

 /* SCT_PIN2 connect to P0_13 */
    SWM_SetMovablePinSelect(SWM0, kSWM_CTIN_2, kSWM_PortPin_P0_13);

    /* SCT_OUT3 connect to P0_12 */
    SWM_SetMovablePinSelect(SWM0, kSWM_CTOUT_3, kSWM_PortPin_P0_12);

/* Schedule a capture event  to start timer on rising edge of input pin*/
    if (SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_InputRiseEvent, matchValueL, output_pin_here, kSCTIMER_Counter_L,&eventCounterL) == kStatus_Fail)
    {
        return -1;
    }

I've obviously a long way to go... any pointers??

0 Kudos