PSoC 5LP SysTick changes frequency

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
StKr_1203736
Level 3
Level 3
First like received 10 replies posted 10 sign-ins

I am writing a complex application with PSoC Creator 4.4. The target MCU is CY8C5868AXI-LP035.

Operation is SysTick timer based, counting off a number of ticks to schedule 'tasks'. The number of ticks is always odd, and most are prime, with the intent being to minimize the number of 'task' running in any 1mS tick.

I have code in place to identify any code that runs longer than expected. The longest 'task' is less than 25mS.

SysTick clearly runs at 1000Hz. I added a hardware marker to my SysTick code so I can measure the execution rate with an oscillocope.

After some (indeterminate, but usually small) number of minutes, the SysTick rate changes from 1000Hz to 255Hz, and stays there. There is nothing in my code that should change any of the clocks.

Text coming out of the UART changes from normal to garbage. It normally runs at 115200Hz, so there is no quarter speed baud rate to test with.

I have traced text down to writing to the UART Tx register, and it looks correct.

I even added code to look at the SysTick values, and up to the point where the clock changes, they look good:

uint32 SysTickReload = CySysTickGetReload();

uint32 SysTickValue = CySysTickGetValue();

sprintf(tstr, " SysTickReload %lu SysTickValue %lu", SysTickReload, SysTickValue);
uart_put_line(tstr);

After the clock changes, I have to use the debugger to look at the numbers. They remain the same as before. For some reason, CySysTickGetValue never goes below 9000d. CySysTickGetReload remains 12000.

Does anyone have any thoughts here?

0 Likes
1 Solution

StKr,

There is a circuit called Phase-Frequency Detector (PFD), which can be useful to monitor if the input frequency falls below (or above) the set point. The signal train on the Pin_1 or Pin_06 shall appear only when F_inp > F_ref or Finp < F_ref accordingly. Otherwise it is zero.

This way it doesn't need to be monitored at 5Hz intervals - as soon the frequency drops below the reference clock (or stops) it shall rise the interrupt isr_1. The Status register should be set to a Sticky mode, so that  only  the first edge will be serviced, and the rest of the train is ignored (until the Status register is reset) 

SRFF_01a_PFD.png

View solution in original post

14 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

StKr,

Are you willing to share your project (or a minimized version of it) so that we can reproduce your results?

I've used the SysTick resource at the normal 1ms tick timing MANY times.   I can't say I've ever had it change the base frequency on me.

Having said that, the normal source clock for the SysTick resource is the BUS_CLK.   If you change the BUS_CLK in mid-operation, you will get a change in the SysTick period.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
lock attach
Attachments are accessible only for community members.
StKr_1203736
Level 3
Level 3
First like received 10 replies posted 10 sign-ins

Hi - Thank you for the response. I don't know if I can share the project; it is very hardware dependent, anyway, and will not progress very far unless certain signals are present.

I do not do ANYTHING with any of the clocks at runtime.

One other data point - There are two interrupts generated by input signals. One seems to work OK; the signal is low rate (<10Hz). The interrupts for the other one (65Hz)stop shortly before this clock change occurs (shortly == seconds) even though the signal is still present and has not changed.

Both of these interrupts are serviced selectively. The interrupts are enabled ONCE every 207mS, and they are disabled after an edge and interrupt are detected, so the MCU is not being flooded with interrupts. The two interrupts have nearly identical but separate code.

0 Likes

StKr,

I'll look at your code modules in the morning.

Hi - Thank you for the response. I don't know if I can share the project; it is very hardware dependent, anyway, and will not progress very far unless certain signals are present.


I appreciate your comment.

One debugging trick I use on difficult root cause identification is to selective turn off parts of the project resources.  If turning off a resource from processing makes the problem go away, then you look for the interconnection relationship between the SysTick resource ISR and this resource.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
lock attach
Attachments are accessible only for community members.

StKr,

1.  just a note that interrupt semaphore flags should be marked as volatile to avoid optimization issues, for example:

//BOOL fgKeepalive_Interrupt_Flag = FALSE;

static volatile uint8 fgKeepalive_Interrupt_Flag = FALSE;  

 

2. Other thought: the SysTick is specific and unique resource. It can be useful e.g. for system debugging and profiling. If you need it only to generate a 1ms interrupt, it would be more straightforward to use 1khz clock and standard interrupt. 

 

3. Do you use DMA in the project? (If improperly configured it may override memory) 

 

4. For 1ms periodic intervals there is tested SysTimers component by Mark Hastings, which uses SysTick. The datasheet is attached

0 Likes
lock attach
Attachments are accessible only for community members.
StKr_1203736
Level 3
Level 3
First like received 10 replies posted 10 sign-ins

Thank you for the comments. You are absolutely correct about using volatile; I don't know why I did not think of it.

The project does not use DMA at all.

I have updated the SampleSource archive to include my timer code. I don't have a SysTimer object in the TopDesign, although perhaps I should. I will look into it. I will also try using a 1KHz clock + interrupt.

I will also look at completely disabling some of the interrupt-related code, to see if that actually makes a difference.

Thanks!

Steve

0 Likes
StKr_1203736
Level 3
Level 3
First like received 10 replies posted 10 sign-ins

I am unable to find the SysTimers component anywhere. Hints, anyone?

Steve

0 Likes

StKr,

Actually, the link to SysTimers was provided above. I checked it yesterday. It seems that the Infineon search engine  is not working on some forum threads. I have notified the moderator.  

SysTimers v3.0 by Mark Hastings 

0 Likes

StKr,

I looked at the files; they reminded me the work I did in my previous life some 25 years ago (HV separation, etc.). Anyway, the timer_interface.c looks very similar to the code of SysTimers, so I would definitely check it out, as it was written by the Cypress employee and went through revisions.

 

I noticed that the array of 6 fans was monitored for speed and here you may find useful this recent component which was designed exactly for that purpose:

Tach24: 24-channel Tachometer component 

 

If you drive the 6 fans using independent  PWM sources, you may find this QuadPWM component useful. It can produce 4 PWM outputs with individual duty cycles out of a single UDB block:

8-bit Quad PWM Component by Rodolfo Gondim Lossio 

 

 

     

0 Likes

Hi - Thank you for the suggestions. The fans are all driven with a single PWM. They are measured separately to monitor for failures of dust clogging. The tach signals all go through an external MUX, because I am just about out of pins.

0 Likes
StKr_1203736
Level 3
Level 3
First like received 10 replies posted 10 sign-ins

The link gets me to documentation, but I cannot find the component. There is nothing in my component window that matches 'syst' or 'tick'.

I changed my 1mS clock to run off a '1KHz' clock and generate an (approximately) 1mS interrupt. The resulting interrupt is 1.28KHz, which is workable. The visible parts of system operation (LEDs) look about right, even though the timing is off by 25%.

But this has no effect on whatever generates the UART baud rate, and it eventually changes so that the UART output is garbage. The system behaves as if a 1:4 divider has been activated on the 12MHz BUS_CLK, because the PWM generated 25KHz control frequency for my fans is now about 6.38KHz.

One other note: In general, a few seconds before this uncontrolled clock change, one of my edge-detection interrupts stops working. The signal is still present, and the setup() and checkresult() routines are called, so the interrupt is enabled, but the interrupt itself is no longer called.

Is it possible that something is producing the same effect as calling one of these?

void CyMasterClk_SetSource(uint8 source) ;
void CyMasterClk_SetDivider(uint8 divider) ;
void CyBusClk_SetDivider(uint16 divider) ;

0 Likes
lock attach
Attachments are accessible only for community members.

SysTimers component library and demos are attached. After installation into Project->Dependencies->User dependencies... it will show up in the Community page:

SysTimers_Component catalog_A.png

The system clock BUS_CLK of 12MHz seems excessively low - I believe that your application is not a low-power type. I would use 48MHz or 24MHz to avoid any timing issues. The accuracy of the 3MHz IMO is typically 3%, so the 1kHz clock should be within +/-30Hz, not 300Hz. I suspect that you used ILO oscillator for 1 kHz output, or set selection to "Auto". The ILO is not accurate and its frequency can be easily 50% off. 

I have concerns about the UART Rx code that you have. I suggest to disable UART to see if that has any effect. What type of UART you are using and at what baud rate?

I am not aware of any standard components which would try to affect the BUS_CLK frequency, as such attempt may have adverse effect on the entire application. However, I had my own created to deliberately overclock PSoC5 to 110MHz. 

 

0 Likes
StKr_1203736
Level 3
Level 3
First like received 10 replies posted 10 sign-ins

Thank you for all the Systimers code and documentation. As noted above, I changed the source of my 1Khz clock (really just for testing purposes) and found that it remains stable, although not very accurate.

I added appropriate #ifdefs in my code, so I could easily rebuild it with some functionality missing. What I found is that everything works OK.. until I apply a signal to the last edge detection input. It is a 66KHz signal, but it is mostly a hardware pass-through. The MCU needs to monitor its presence to blink a LED at 1Hz. It is monitored at 5Hz (207mS) and the rest of the time, the interrupt is disabled.

I am pretty certain that this input has been exposed to overvoltages (possibly 20V or more!) because of some confusion over 1X/10X scope probes used to measure it. To make things worse, the pulse generator that I was using to drive it is 'spikey', producing overvoltages on the edges. These overvoltages or spikes appear to be the cause of my clock problems. No signal == no problem.

I swapped around signal sources, so that I could use a very clean signal generator for this input. The expected interrupt was generated briefly (maybe for a minute?) and then no more. But the clocks did not change, and the UART output is still fine.

It is possible that something is damaged on this input, and it simply behaves weirdly. If I can apply a valid signal, and it does not break the system, then I am good going forward. I don't have any additional boards to test with; my only other PCB has other problems.

This has driven home for me the need for ESD and overvoltage protection on all inputs!

At this point, 12MHz seems to be adequate for the BUS_CLK. I cannot simply change it, because of all the places it is used. The system is based on each task having a timer running off a 1mS tick. Each task measures its own duration and compares it to previously observed execution times, so I can tell if something runs much too long.

Steve

0 Likes

Steve,

I understand that external inputs/outputs can be subjected to harsh ESD and other transients.

By design virtually ALL GPIOs have some ESD protection.  They tend to be two signal diodes from the GPIO to VDD and VSS.  Any voltage 0.6V above VDD or 0.6V below VSS will attempt to be suppressed.  The absolute maximum current to prevent damage is 100mA.

Many times an in-line series resistor to limit the max current in the case of a transient may be enough.

If you want additional protection, the GPIO pins listed as SIO pins have extra transient/over-voltage protection.  On the PSoC5LP these are the pins on Port 12.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

StKr,

There is a circuit called Phase-Frequency Detector (PFD), which can be useful to monitor if the input frequency falls below (or above) the set point. The signal train on the Pin_1 or Pin_06 shall appear only when F_inp > F_ref or Finp < F_ref accordingly. Otherwise it is zero.

This way it doesn't need to be monitored at 5Hz intervals - as soon the frequency drops below the reference clock (or stops) it shall rise the interrupt isr_1. The Status register should be set to a Sticky mode, so that  only  the first edge will be serviced, and the rest of the train is ignored (until the Status register is reset) 

SRFF_01a_PFD.png