LPC824 events triggering immediately on timer start?

cancel
Showing results for 
Search instead for 
Did you mean: 

LPC824 events triggering immediately on timer start?

Jump to solution
1,258 Views
jamesward0001
Contributor II

Hi, I'm new to using the SCTimer module but I've got three events set up, one on a rising edge event, one on a falling edge event and one on a match event only.  However if i set them all up to capture the value and then print them out, i get values of 1,2 and 3, i.e. each event is triggering as soon as it can after the timer is started.  Any ideas on what might cause thi?  I'm using the sctimer drivers included in the LPC824 SDK.  

Here's my timer setup code:

sctimer_config_t sctimerInfo;

uint32_t riseEvent;
uint32_t fallEvent;
uint32_t timeoutEvent;

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

//sctimerClock = CLOCK_GetFreq(kCLOCK_MainClk);
sctimerClock = CLOCK_GetFreq(kCLOCK_Irc);


SCTIMER_GetDefaultConfig(&sctimerInfo);

uint32_t timeoutMillis = MSEC_TO_COUNT(5000u,sctimerClock);

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

/*create events for pin rise, fall and timeout conditions*/
SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_InputRiseEvent, 0u, ASICREPLY_PIN, kSCTIMER_Counter_L, &riseEvent); //creates event on data input pin L->H transition
SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_InputFallEvent, 0u, ASICREPLY_PIN, kSCTIMER_Counter_L, &fallEvent); //creates event on data input pin transition

SCTIMER_CreateAndScheduleEvent(SCT0, kSCTIMER_MatchEventOnly, timeoutMillis, 0, kSCTIMER_Counter_L, &timeoutEvent);


/*setup capture actions on pin rise and fall*/
SCTIMER_SetupCaptureAction(SCT0, kSCTIMER_Counter_L, &riseCaptureReg, riseEvent); //captures input on pin rise transition event
SCTIMER_SetupCaptureAction(SCT0, kSCTIMER_Counter_L, &fallCaptureReg, fallEvent); //captures input on pin fall transition event

SCTIMER_SetupCaptureAction(SCT0, kSCTIMER_Counter_L, &timeoutCaptureReg, timeoutEvent);

/*setup counter reset on timeout or falling edge*/
SCTIMER_SetupCounterLimitAction(SCT0,kSCTIMER_Counter_L,fallEvent);
SCTIMER_SetupCounterLimitAction(SCT0,kSCTIMER_Counter_L,timeoutEvent);

/*setup halt on timeout*/
SCTIMER_SetupCounterHaltAction(SCT0,kSCTIMER_Counter_L, timeoutEvent);

pinMode(INHIBIT_PIN2,0);

SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_L);

Hope this is just me being silly cause I haven't used the module before.

Thanks in advance,

James

Labels (1)
1 Solution
853 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hi James,

You're right, it looks like the SCTIMER_CreateAndScheduleEvent API is limited to use the Counter_H or Counter_L.

Update the register SCT0->SCTMATCH and the SCT0->SCTMATCHREL with the correct counter value after the API and it should work.

Let me know if this helps you.

Best Regards,

Alexis Andalon

View solution in original post

11 Replies
853 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hi James,

For more information about the SCTIMER please check the SCTimer/PWM cookbook that can be found in the following link under the application note section: LPC82X | NXP.

Best Regards,

Alexis Andalon

853 Views
jamesward0001
Contributor II

Hi,

Thanks for the reply but I've already trawled through the examples and I can't find any major differences between what I'm doing and what the examples are doing (I've especially looked at the 16 bit and rc5 timer examples).  Is there any extra configuration that if set up incorrectly could cause this kind of instant triggering behaviour?

0 Kudos
853 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Dear James,

Checking your code I see there's some events that are contradictory. For example, in the timeout event there's the Halt, the Limit and the Capture event. So there's the doubt which event will be done first.

As far as I see, you need to capture the value of the counter in the Rise Edge and the Fall Edge but there's any function to set the output state in your code, you need to change the state of the pin to let the events trigger. You could use the functions SCTIMER_SetupOutputSetAction and SCTIMER_SetupOutputClearAction.

I will suggest to check the SCTIMER_SetupPwm function to see how the events works.

I hope this helps you.

Best Regards,

Alexis Andalon

853 Views
jamesward0001
Contributor II

Dear Alexis,

I had identified the event ordering issue but I thought I'd try it and see what the result was then change the code afterwards to fit.  Would the solution be to create separate events for each action so they always fall one after another?  That actually would make a lot of sense.  

I don't need to set outputs and I don't think the setupPwm would be very relevant as I'm not trying to generate a signal, I'm trying to capture and decode an FSK signal on the monitored pin.  Also, the main issue I'm having is that the events are all triggering as soon as possible after starting the timer (captured values for the 3 events are 1, 2 and 3 clock cycles) which I can't see a cause for in the setup I've got?  Anyway, thank you so much for the help.  

Kind Regards,

James Ward

0 Kudos
853 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hi James,

 

Yes,I think you need to set one event for each one of the events, only remember you have up to 8 events.

 

First I will suggest to schedule the events independently and check if the pin configurations are done correctly.

 

Best Regards,

Alexis Andalon

0 Kudos
853 Views
jamesward0001
Contributor II

Hi, you're absolutely right, my pin config was wrong.  I hadn't routed the SCT MUX correctly.  I also found out that the MCUxpresso config tools application has a tool in it for setting up timers which is much easier than doing it manually so I'd really like to use it but it appears to be missing a capture option in the list of possible actions?  

0 Kudos
853 Views
jamesward0001
Contributor II

So i used the tool to just set up a timer andthe pin transitions i needed (plus configging the input mux correctly this time) an I'm getting the same behaviour as before, all events trigger instantly on timer start.  Here's my revised timer setup.

void SCTimer_1_init(void) {
sctimerClock = CLOCK_GetFreq(kCLOCK_MainClk);
uint32_t timeoutClocks = MSEC_TO_COUNT(100u,sctimerClock);


SCTIMER_Init(SCTIMER_1_PERIPHERAL, &SCTimer_1_initConfig);

/* Initialization of state 0 */
SCTIMER_CreateAndScheduleEvent(SCTIMER_1_PERIPHERAL, kSCTIMER_InputRiseEvent, 0, kSCTIMER_Input_0, kSCTIMER_Counter_L, &SCTimer_1_event[0]);
SCTIMER_SetupCaptureAction(SCTIMER_1_PERIPHERAL,kSCTIMER_Counter_L,&riseCaptureReg, &SCTimer_1_event[0]);

SCTIMER_CreateAndScheduleEvent(SCTIMER_1_PERIPHERAL, kSCTIMER_InputFallEvent, 0, kSCTIMER_Input_0, kSCTIMER_Counter_L, &SCTimer_1_event[1]);
SCTIMER_SetupCaptureAction(SCTIMER_1_PERIPHERAL,kSCTIMER_Counter_L,&fallCaptureReg, &SCTimer_1_event[1]);

SCTIMER_CreateAndScheduleEvent(SCTIMER_1_PERIPHERAL, kSCTIMER_InputFallEvent, timeoutClocks, kSCTIMER_Input_0, kSCTIMER_Counter_L, &SCTimer_1_event[2]);
SCTIMER_SetupCounterLimitAction(SCTIMER_1_PERIPHERAL, kSCTIMER_Counter_L, SCTimer_1_event[2]);

SCTIMER_CreateAndScheduleEvent(SCTIMER_1_PERIPHERAL, kSCTIMER_MatchEventOnly, timeoutClocks, kSCTIMER_Out_0, kSCTIMER_Counter_L, &SCTimer_1_event[3]);

SCTIMER_SetupCounterLimitAction(SCTIMER_1_PERIPHERAL, kSCTIMER_Counter_L, SCTimer_1_event[3]);
SCTIMER_SetupCounterHaltAction(SCTIMER_1_PERIPHERAL, kSCTIMER_Counter_L, SCTimer_1_event[3]);


//SCTIMER_StartTimer(SCTIMER_1_PERIPHERAL, kSCTIMER_Counter_L);
}

After you call startTimer, the two captures trigger and both store 0, the timer then resets and halts.  If i init the capture regs to values other than zero they are changed back to zero by the timer action and if i remove the halt action, the halt bit in the control register remains 1 (so the timer is at least trying to run).  

0 Kudos
853 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hi James,

Could you let me know which is the value calculated in the timeoutClocks? The counter use 16 bits so maybe you need to use all the counter. Using the single counter you can count up to 2 ms if its using the max core clock.

So I will suggest to use the unified counter mode.

Best Regards,

Alexis Andalon

0 Kudos
853 Views
jamesward0001
Contributor II

Hiya, the value calculated in timeoutClocks is 1200000, however this should be fine as i'm already using the 32 bit unified counter as I also identified that as a possible issue.  I decided to try and see if any of the timer funcs are working at all so i set up a pwm signal output and nothing else.  Worked perfectly, so the sctimer clock and everything must be running correctly.  So i then decided to try and emulate that using a match event (toggle output and limit on match), this also worked perfectly... on values lower than 65535.  as soon as i go above that it fails.  the pwm behaves the same.  It seems that the counter Is not unified like it's supposed to be even though the config file definitely has enableCounterUnify set to true.  going to hunt through your sdk files to see if I can figure out where it's going wrong.

EDIT: didn't manage to see anything wrong in the SDK but if i grab the value from the match register after setting up the event, the value overflows back to zero even though the match register is an array of 32 bit values.  very puzzling.

EDIT II: figured it out.  in fsl_sctimer.c you treat match conditions for the unified counter and just counter_L  the same, but as part of that you do a logical and of the match value with 0xFFFFu i.e. limiting it to 16 bit which then shafts the unified counter match value.  surprised no-one else has picked up on this yet.  The fix is to separate the two situations and treat them appropriately.

0 Kudos
854 Views
Alexis_A
NXP TechSupport
NXP TechSupport

Hi James,

You're right, it looks like the SCTIMER_CreateAndScheduleEvent API is limited to use the Counter_H or Counter_L.

Update the register SCT0->SCTMATCH and the SCT0->SCTMATCHREL with the correct counter value after the API and it should work.

Let me know if this helps you.

Best Regards,

Alexis Andalon

853 Views
jamesward0001
Contributor II

yeah sorted it before i saw your message,

replacing:

if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L))
{
base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
}

with:

if (base->CONFIG & SCT_CONFIG_UNIFY_MASK)
{
base->SCTMATCH[s_currentMatch] = (uint32_t)matchValue;
base->SCTMATCHREL[s_currentMatch] = (uint32_t)matchValue;
}
else if(whichCounter == kSCTIMER_Counter_L){
base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue);
base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue);
}

fixes it right up.  Thanks for your help anyway! :smileyhappy:  If you could push that fix to the official sdk it would be cool.

0 Kudos