6 Replies Latest reply on Aug 18, 2017 1:48 PM by dude.notmyname

    best way to delay microseconds?

    dude.notmyname

      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. 

        • 1. Re: best way to delay microseconds?
          user_14586677

          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.

          • 2. Re: best way to delay microseconds?
            user_342122993
                    Did you try CyDelayCycles(100)? It basically counts system ticks, but the time will change with bus clock.   
            • 3. Re: best way to delay microseconds?
              dude.notmyname

              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?

              • 4. Re: best way to delay microseconds?
                user_14586677

                Faster pin toggling discussed here -

                   

                 

                   

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

                   

                 

                   

                Regards, Dana.

                • 5. Re: best way to delay microseconds?
                  dude.notmyname

                  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?