best way to delay microseconds?

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

cross mob
duno_297731
Level 3
Level 3
10 sign-ins 10 replies posted 10 questions asked

so, I tried using the CyDelayUs() function, but it sucks (always delays something like 6us+whatever you pass the function). 

   

 

   

does anyone have a recommendation for delaying from single microseconds up to hundreds of micro seconds?  anything longer than hundreds of microseconds does not need to be that precise, but I want something that when I intend 3us delay, that I actually get 3us ±0.5us.  also, something that is robust enough to handle a change in core clock speed without needing to be re-coded for the new clock frequency.  is there anything like that in a library? 

   

 

   

should I just make a loop of nops?  if I make a loop of nops, how can I sample what my current cpu speed is, so I can adjust the loop to maintain accuracy? 

   

 

   

I'm curious for the CY8CKIT-042 dev board, but I also just bought a CY8CKIT-059 and would like a solution for both. 

0 Likes
6 Replies
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Are you trying to delay something that is for HW ? If so use a timer, run at 2 Mhz, attach an

   

ISR to it when it rolls over. Or attach HW to the terminal count = no latency caused by ISR

   

approach. Timer period of course becomes delay. Accuracy controlled by device specs, or if

   

you use xtal by it.

   

 

   

Regards, Dana.

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted
        Did you try CyDelayCycles(100)? It basically counts system ticks, but the time will change with bus clock.   
0 Likes
duno_297731
Level 3
Level 3
10 sign-ins 10 replies posted 10 questions asked

so, I did some more measurements, here is what I found:

   

1.  CyDelayCycles always delays about 0.3us, then single cycle delays add up (so CyDelayCycles(1) will actually delay about 15 cycles and CyDelayCycles(2) will delay 16 cycles), which is annoying but usable.

   

2.  mysignal_Write(1) takes about 1.4us, about 75 clocks with my setup.  I think this is where my problems are coming from, I assumed I could switch a pin from high to low faster than 75 clock cycles, that's a really long time when microseconds matter.

   

3.  CyDelayUs() always has about 1us delay, so CyDelayUs(1) actually delays about 2us, which is also really annoying.

   

so, in the short term, I should be able to use CyDelayCycles and stay accurate to .5us like I need.  in the long term, maybe I have to write my own functions for delays since whoever wrote the built-in ones failed really hard. 

   

also, it will suck if I have to abandon the mysignal_Write() functions because they're slow as hell.  I will have to figure out how to do direct pin assignments.  you'd think the _Write() wrapper would optimize out most of it's inefficiency, but I guess either the code or the compiler is just poorly implemented.

   

also, does anyone know how to test my clock speed from the code so I can make accurate delay functions?

0 Likes
lock attach
Attachments are accessible only for community members.
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Faster pin toggling discussed here -

   

 

   

http://www.cypress.com/?rID=93401     AN86439 - PSoC® 4 - Using GPIO Pins

   

 

   

Regards, Dana.

0 Likes
duno_297731
Level 3
Level 3
10 sign-ins 10 replies posted 10 questions asked

here is what I believe will resolve the pin switching time problems:  

   

To set, reset, and read the pin using direct register writes, the following macros are provided in PSoC Creator:

   

CY_SYS_PINS_SET_PIN(portDR, pin) 
Sets the output value for the pin to logic high
portDR is the address of the port data register
pin is the pin number (0 to 7)

   

CY_SYS_PINS_CLEAR_PIN(portDR, pin) 
Clears the output value for the pin to logic low
portDR is the address of the port data register
pin is the pin number (0 to 7)

   

CY_SYS_PINS_READ_PIN(portPS, pin) 
Reads the pin value
portPS is the address of the port status register
pin is the pin number (0 to 7)

   

 

   

 

   

 

   

again, does anyone know if it's possible to read what the clock dividers are set to so I can know my own clock speed?

   

 

   

also,  does CY_SYS_PINS work for both PSoC4 and 5?

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted
        psoc4_guy, On PSoC5 toggning a pin takes 5 CPU cycles (2 up, 3 down). https://vimeo.com/65092394 PSoC4 was discussed here: http://www.cypress.com/forum/psoc-4-architecture/psoc-4-study-pin-toggle-max-speed-comparison-severa... odissey1   
0 Likes