Shop OBEX P1 Docs P2 Docs Learn Events
CTRA help — Parallax Forums

CTRA help

It's been a while since I got to understand the parameters of CTRA - now the understanding has faded a bit.
Can anyone help me how to set up a CTRA to give a single pulse to an output pin, duration from10uS up to 4mS?

Erlend

Comments

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-11-15 21:07
    NCO mode, retard phase by the desired number of clock ticks, wait for the pulse to finish:
    PUB pulseOut(myPin, duration_us)
      dira[mypin]~~
      ctra := (%00100 << 26) + mypin
      frqa := 1
      phsa := -duration_us * (clkfreq/1000000)
      waitpeq(0, |<mypin, 0)   ' let it finish
      ctra := 0   ' stop the counter
    
  • Thanks, but I was hoping there was some way it could be done without holding up my main code - like waitpeq would do. I would like to have my code go on doing stuff, and when the uS's have expired the pin goes low. I was thinking that since the counter can do pwm by it self, it should be able to do a singel pulse too.

    Erlend
  • AribaAriba Posts: 2,690
    Erlend

    The pin goes low anyway, you don't need to stop the counter immediatley. But after about 27 seconds it will go high again, so you need to stop the counter, or trigger another pulse before that amount of time.

    Andy
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-11-15 23:07
    What Andy said.

    1100000000111111110000000011111111
    ^_________*
    

    Phase is retarded to just enough, the point marked ^, to give you your microseconds high pulse. Once phase advances to the point where it goes low again, it takes 26.8435456 seconds before it advances to the point marked * where it goes high again. Can your program stop it during that time? Or, if the program needs to regenerate the pulse at intervals less than 26.8435456 seconds, all it has to do is retard the phase again to point ^.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-11-16 05:00
    Within your main loop you could check the pin being driven by the counter; if the counter is enabled and the pin is low, the pulse is done.
    if ((ctra) and (ina[PULSE_PIN] == 0))
      ctra := 0
    
    This removes the blocking code, but introduces a slight pad to deal with the counter.
  • JonnyMac wrote: »
    Within your main loop you could check the pin being driven by the counter; if the counter is enabled and the pin is low, the pulse is done.
    if ((ctra) and (ina[PULSE_PIN] == 0))
      ctra := 0
    
    This removes the blocking code, but introduces a slight pad to deal with the counter.
    Yes, I can do this, I can fit it into some of the other routines without any penalty.
    (I am working on a driver for the NRF24L01+ tranceiver module, and the radio should not be continously active for more than 4mS)

    Erlend
  • Yes, I can do this, I can fit it into some of the other routines without any penalty.

    Okay, then, just remove the last two lines from Dr. Allen's pulseOut() method and you're good to go.
  • JonnyMac wrote: »
    Yes, I can do this, I can fit it into some of the other routines without any penalty.

    Okay, then, just remove the last two lines from Dr. Allen's pulseOut() method and you're good to go.
    Thanks, I did this:
    PRI PulseOut(Pin, duration)         
                                        
      CTRA := (%00100 << 26) + Pin      
      FRQA := 1                         
      PHSA := -duration                 
                                        
                                        
    PRI PulseStop(Pin)                  
                                        
       IF ((CTRA) AND (INA[Pin] == 0))  
         CTRA := 0                      
    

    Erlend
  • JonnyMacJonnyMac Posts: 9,105
    edited 2015-11-16 17:06
    That's fine -- just remember that the way you've coded PulseOut() the duration is specified in system ticks. I would tend to use names like this
    pub pulse_out(pin, ticks)
    
      ctra := (%00100 << 26) | pin
      frqa := 1
      ctra := -ticks
    
    Using constants in my standard header I could do things like this:
    pulse_out(0, 20 * US_001)
    
    pulse_out(0, 10 * MS_001)
    
  • I have long since adopted your approach (learnt from you) by having this as my standard template:
    CON
    
              _clkmode = xtal1 + pll16x
              _xinfreq = 5_000_000                                          ' use 5MHz crystal
            
              clk_freq = (_clkmode >> 6) * _xinfreq                         ' system freq as a constant
              mSec     = clk_freq / 1_000                                   ' ticks in 1ms
              uSec     = clk_freq / 1_000_000                               ' ticks in 1us
    

    Erlend
  • And I "liberated" that header from another forum member -- the forums are a great resource!
  • Erlend wrote: »
    It's been a while since I got to understand the parameters of CTRA - now the understanding has faded a bit.
    Can anyone help me how to set up a CTRA to give a single pulse to an output pin, duration from10uS up to 4mS?

    Erlend

    That looks like the minimum and maximum time to hold the CE pin high on the nrf24L01 in TX mode.
    (I'm working on a SPI method with little success at the moment.)
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-11-16 23:49
    I'd made a diagram to help show an intern how the cog counters work. Cog_Counter_Scheme.png
    It is easier to understand it as circular, as a clock face. Phase phsx advances from 0 around the circle from zero to 2^32-1.
    In the first half, from zero to posx the value of the most significant bit is msb=0, then from negx to 2^32-1, msb=1. The frequency variable frqx is simply how much is added to the phase at each tick of the system clock, and it can be either a positive or a negative value. A carry is generated each time the advancing or retarding phase crosses the top boundary. Either the msb or the carry can be associated with an output pin, NCO or DUTY mode respectively.

    In generating a pulse, you've set phsa just a tad back into the blue area, which sets the pin associated with the msb to a high level. With frqa:=1, the phase advances one unit per tick, and when it advances into the yellow area, the msb and the associated pin go low. The pulse it generates is very accurate, to 12.5ns. Subsequently, the phase advances through the yellow area with the msb low for just shy of 27 seconds before it returns high again at the transition from posx to negx.
    601 x 668 - 56K
  • @Tracy Allen
    Simply brilliant!

    Erlend
  • ErlendErlend Posts: 612
    edited 2015-11-17 08:19
    lardom wrote: »

    That looks like the minimum and maximum time to hold the CE pin high on the nrf24L01 in TX mode.
    (I'm working on a SPI method with little success at the moment.)

    Exactly!
    For some reason I've got hooked on writing protocols. I know they are mostly already there in OBEX ang GitHub, at least low level implementations, but to really get to understand how they work, and how the various chips work, I like to implement the protocols from scratch. I've just completed I2C and drivers for a few chips, and now I have done SPI and a chip & application level driver for nRF24L01+. I am at present debugging this. My SPI works fine when I loop back MOSI to MISO, but when communicating with the chip, the reply bits are shifted 1 bit left, so there must be some hickup in the repeat loop. Good fun.
    If you want, I can share the code, but it is probably full of bugs still.

    Erlend
  • What are you guys doing with the nrf24L01? I thought about ordering a few for a possible customer (of EFX-TEK) project.
  • ErlendErlend Posts: 612
    edited 2015-11-18 07:08
    My project is possibly not very mainstream; I am going to have two fast-acting and very sensitive temperature sensors + propeller + nRF24L01 fixed to each far end of the wing of my paraglider, and they will communicate to a propellor with a display as well as audio, located in front of me, the audio routed to headphones in my helmet. When the air temperature increases on one side - even a minute amount - that signals that there is a thermal in that direction. I am thinking I will use a rising tone in my earphone at that same side to tell me to turn in that direction to catch the termal. This is not so straightforward as it sounds. To avoid the sound going haywire in general change of air temperature some filtering algorithms are needed - therefore the propeller. To spend a propeller at each wingtip just to read I2C temperature sensor and SPI tranceiver may sound a bit over the top, but it has the benefit of being hardware I am familiar with.
    Either it becomes an interesting flop, or I become a master in the sky.

    Erlend
  • Wow, that's a cool app! You'll have to share some video once deployed. I used to fly old-school canvas gliders as a boy. As I grew up in the desert, we would simply watch for hawks and vultures riding the thermals and then go fly with them.
  • Desert, yeah, strong thermals! Here in the sub-arctic though the thermals are often marginal. There will not be a video until summer, when the pg-season begins.

    Erlend
Sign In or Register to comment.