Shop OBEX P1 Docs P2 Docs Learn Events
Pseudo Timer Interrupt — Parallax Forums

Pseudo Timer Interrupt

StephenMooreStephenMoore Posts: 188
edited 2012-09-24 18:48 in Propeller 1
I am trying to do some real time machine motion control and am trying to use two separate background timers. Does anyone have an idea for trapping timer timeouts. The following program fails since in DUTY mode the carry bit is only high for one clock cycle. I would like to do a bunch of math and motor control while the timer is running and stop when it runs out.
CON


  _CLKMODE = XTAL1 + PLL16X
  _XINFREQ = 5_000_000


   myPin = 1
  
VAR


  long  myStack[10], timerValue
  byte cog, flag
               
OBJ
  pst    :"Parallax Serial Terminal"
   
PUB Main


  pst.Start(115200)
  cog := cognew(testTimer(myPin, @timerValue), @myStack)  
  waitcnt(clkfreq * 2 + cnt)
  
  repeat
    
    pst.str(string($0D, "Enter timeout value: "))
    timerValue := pst.DecIn
    repeat while (timerValue <> 0)
         'Do a bunch of motor control here


PUB testTimer(Pin, timerAddr)  | timer


   timer := 0
   flag  := 0
   
   repeat
      if timer <> long[timerAddr]
       timer := long[timerAddr]  
       
       frqa := 1
       phsa := $FFFF_FFFF - timerValue   
       ctra := 111 << 26 + Pin      'Start timer in DUTY cycle mode


        repeat while (flag == 0)
         flag := ina[Pin]           'Trap timer timeout here
       long[timerAddr] := 0
   
   

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-09-23 21:46
    I can't find any dira assignment in your program which means that even if you could spot the DUTY pulse from SPIN you wouldn't see it in the first place (counte-to-pin connection is missing). That said, why don't you simply start a LOGIC ALWAYS counter and monitor it for a negative/positive phsx transition? This has the same effect, doesn't use a pin and is more likely to work in SPIN. Catching a DUTY pulse is even challenging in PASM. HTH

    So you'd monitor the phsx value until it's negative and then wait for it to become positive again.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-09-23 22:29
    Thanks. I also thought about using NCO mode but I was trying to utilize the full 32 bit timer range. I'll give your suggestions a try.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-09-23 22:43
    Have you tried just setting up a simple task in a cog to maintain timeouts etc? I've done this in the past where I have multiple software timers that countdown to zero every millisecond and the main program only has to load the "timer" and poll when it's ready to check for a timeout.

    In my Tachyon Forth I have stepper motors running and I need to have multiple timeouts and so I use a similar scheme which is built-in to the kernel, I just say "#2000 5 TIMEOUT" to set timer 5 for a 2 second timeout and then use "5 TIMEOUT?" to test that timer. Of course this timer task can do a lot more but this feature alone is very useful.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-09-24 06:04
    Mr Jakacki:

    That is what I am trying to do. I actually need two timers. One for overall motion move and one that times out at regular intervals for doing numerical integration for overall rotations. I will try to set up a cog with this feature and post it. It won't be ultra precise but if I look at PHSA or PHSB register values I should be able to get within a few hundred clock cycles.

    Regards,

    sm
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2012-09-24 07:31
    There is the WAITCNT instruction both in Spin and in PASM. Your background timer function would use this to maintain accurate timing despite the variation in the execution time of your timer code. If you need some sample code I'm sure I've got some in Spin and PASM that will maintain multiple timers easily.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-09-24 18:48
    I modified things a little bit and it sort of works.

    The idea is the timer cog will control pulse output on ctra (and encoder pulse counting on ctrb eventually). The main program controls time of execution.

    I am not sure I am allocating cog stack space properly in the Timer object...
    VAR
    
    
      long  timerStack[60]
      byte  cog[3]
                   
      
    PUB Start(timer, pin, freqAddr)
    
    
      
      if (timer < 1 or timer > numTimers)
        return 0 
      
      cog[timer-1] := cognew(timerFreq(pin, freqAddr), @timerStack[(timer-1) * 20])   ' start a new cog with stack space of 20 indexed for each timer 
        
      return cog[timer-1] 
    
Sign In or Register to comment.