Shop OBEX P1 Docs P2 Docs Learn Events
Program won't run from EEPROM but will from RAM — Parallax Forums

Program won't run from EEPROM but will from RAM

StephenMooreStephenMoore Posts: 188
edited 2012-08-23 21:28 in Propeller 1
Hi,

I am using FullDuplexSerial4portPlus_0v3 and can not get the program to run when loaded from eeprom. It works fine when I reload from RAM. I can not seem to find the problem. Has anyone experienced this before?
CON
    
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    
      
      DIRECTION = 0
      PULSE     = 1   
      ENABLE    = 2 
    
      ENCODER   = 1
      
    
      MINSPEED   = 20
      MAXSPEED   = 4500
    
      MINACCEL   = 1
      MAXACCEL   = 20
    
    
      stepsPerRev     = 200
    
      
      numMOTORS       = 2
      motorArraySIZE  = 9
      
    'motor array elements  
      arrayPOSITION   = 0
      arrayWORLD      = 1
      arrayOFFSET     = 2
      arraySPEED      = 3
      arrayACCEL      = 4
      arrayPULSE      = 5
      arrayENCODER    = 6
      arrayFREQ       = 7
      arrayTARGET     = 8
      
  
  
VAR
        long          motor, position, world, offset, speed, accel, pulsePin, encoderPin, freq
        long          directionPin, disablePin           
       
        long          motorData[numMOTORS * motorArraySIZE]    ' Motor registers loaded into motor object.
        byte          char[4]
        
OBJ
   stepper  : "stepper_clocks"
   cmd      : "FullDuplexSerial4portPlus_0v3"
  
PUB  main  | index, curSpeed, xPos, yPos
    cmd.Init
    cmd.AddPort(0,31,30,-1,-1,0,0,115200)
    cmd.Start
    
    waitcnt(clkfreq/2 + cnt)
    cmd.rxflush(0)
    dira[5..0]~~
   
    ' initialize HUB memory with motor data
   
    repeat motor from 1 to numMOTORS
      index := motor - 1      
      motorData[index * motorArraySIZE + arrayPOSITION ] := 0
      motorData[index * motorArraySIZE + arrayWORLD]     := 0
      motorData[index * motorArraySIZE + arrayOFFSET]    := 0
      motorData[index * motorArraySIZE + arraySPEED]     := MINSPEED
      motorData[index * motorArraySIZE + arrayACCEL]     := MINACCEL 
      motorData[index * motorArraySIZE + arrayPULSE]     := PULSE   + (index * 3)  ' 3 pins need to be contiguous (direction, pulse, disable)
      motorData[index * motorArraySIZE + arrayENCODER]   := ENCODER + (index * 3)' only one encoder pin is used
      motorData[index * motorArraySIZE + arrayFREQ]      := 1               ' 1 puts stepper in hold at cogstart only
      motorData[index * motorArraySIZE + arrayTARGET]    := 0               ' set initil position target equal to zero
      
      stepper.start(motor, @motorData)    ' set up 1 cog  for each motor with 2 counters (ctra & ctrb); cog ctra: APIN = PULSE; cog ctrb: APIN = ENCODER 
   

  
    waitcnt(clkfreq/2 + cnt)  
              
    freq := 60 * clkfreq / 200 / 2  / MINSPEED   ' ctr freq = clkfreq (pulses per sec) / steps per revolution / 10 microsteps per step / pulses per microstep / revs per sec
    repeat motor from 1 to numMOTORS
     stepper.set_period(motor, freq, freq)  ' set the period for ctra module (motor pulse rate)
    waitcnt(clkfreq/2 + cnt)     

   repeat motor from 1 to numMOTORS
    offMotor(motor)
    forwardMotor(motor)
    homeMotor(motor)
    waitcnt(clkfreq/2 + cnt)    
'===============================Motor Commands===================================
'
'                               s = motor set speed
'                               i = motor move incremental
'                               a = motor set acceleration
'                               o = motor on
'                               k = motor off
'                               b = motor backward
'                               f = motor forward
'                               h = hold motor
'                               r = release motor                              
'                               s, p and a commands ask for values 
repeat
 
  char[0] := cmd.rx(0)
  char[1] := cmd.rx(0)
  cmd.tx(0,$0D)
   
  motor :=  char[1] - $30
     
  case char[0]
  
    "s":
     cmd.Str(0, String("Current speed: "))
     curSpeed := motorData[(motor-1) * motorArraySIZE + arraySPEED ]            
     cmd.dec(0, curSpeed)
     cmd.tx(0, $0D)
     cmd.Str(0, String("New speed (20 < rpm < 4500): "))
     speed := getVal  
     if IsOn(motor) == 1
        rampSpeed(motor, curSpeed, Speed)
     else 
        setSpeed(motor, Speed)            
     
    "i":
     cmd.Str(0, String("Current position:  "))      
     cmd.dec(0, getPosition(motor))
     cmd.tx(0, $0D)       
     cmd.str(0, string("Incremental steps: "))
     position := getVal
     positionMotor(motor, position)
     cmd.Str(0, String("Final position:    "))      
     cmd.dec(0, getPosition(motor))
     cmd.tx(0, $0D)
        
   "a":
    cmd.Str(0, String("Current acceleration: "))
    accel := motorData[(motor-1) * motorArraySIZE + arrayACCEL]
    cmd.dec(0, accel)                                        
    cmd.Str(0, String($0D, "New acceleration: "))    
    accel := getVal
    setAccel(motor, accel)
        
   "o": 
    onMotor(motor)
 
   "k":
    offMotor(motor)
   "b":
    reverseMotor(motor)
       
   "f":
    forwardMotor(motor)
        
   "h":
    homeMotor(motor)
       
   "r":                        
    releaseMotor(motor)
            
   "z":    
    zeroMotor(motor)
          
   "g":
    getPosition(motor)
    
   "m":
   
     cmd.Str(0, String("Current position: X= "))      
     cmd.dec(0, getPosition(1))
     cmd.Str(0, String(" Y = "))
     cmd.dec(0, getPosition(2)) 
     cmd.tx(0, $0D)
     cmd.Str(0, String("Delta X: ")) 
     xPos := getVal
     cmd.Str(0, String("Delta Y: "))
     yPos := getVal
     moveXY(xPos, yPos)
     
     cmd.Str(0, String("Final position: X= "))      
     cmd.dec(0, getPosition(1))
     cmd.Str(0, String(" Y = "))
     cmd.dec(0, getPosition(2)) 
     cmd.tx(0, $0D) 
          
'////////////////// Motion Programs ////////////////////////
PRI getVal: num | digit, sign
 num := 0
 sign := 1 
 repeat while (digit := cmd.rx(0)) <>  $0D
   if digit == "-"
     sign := -1
     next
   else    
     if digit < $30 or digit > $39
        num := 0
        quit
   num := (num * 10 + (digit - $30))
 num := sign * num
  
PRI rampSpeed(motorNum, beginSpeed, endSpeed) | ramp, rampDelay
  
 accel := motorData[(motorNum-1) * motorArraySIZE + arrayACCEL]
 repeat ramp from beginSpeed to endSpeed  step accel
   setSpeed(motorNum, ramp)                                                              
   
PRI setSpeed(motorNum, newSpeed)
  newSpeed #>= MINSPEED
  newSpeed <#= MAXSPEED
  motorData[(motor-1) * motorArraySIZE + arraySPEED] := newSpeed
  freq := 60 * clkfreq / 200 / 2  / newSpeed   ' ctr freq = clkfreq (pulses per sec) / steps per revolution / 10 microsteps per step / pulses per microstep / revs per sec
  stepper.set_period(motor, freq, freq)
     
PRI setAccel(motorNum, newAccel)
  newAccel #>= MINACCEL
  newAccel <#= MAXACCEL
  motorData[(motorNum-1) * motorArraySIZE + arrayACCEL]  := newAccel
PRI holdMotor(motorNum) 
  disablePin := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1
  stepper.set_period(motorNum, 0, 0)
  outa[disablePin]~~          
     
PRI releaseMotor(motorNum)
  disablePin   := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1
  outa[disablePin]~
        
PRI onMotor(motorNum) | curSpeed  
  curSpeed    := motorData[(motorNum-1) * motorArraySIZE + arraySPEED]
  setSpeed(motorNum, MINSPEED)  
  disablePin  := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1  
  outa[disablePin]~~ 
  rampSpeed(motorNum, MINSPEED , curSpeed)
    
PRI offMotor(motorNum) | curSpeed 
  curSpeed    := motorData[(motorNum-1) * motorArraySIZE + arraySPEED]
  disablePin  := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1
  rampSpeed(motorNum, curSpeed, MINSPEED)
  outa[disablePin]~
  setSpeed(motorNum, curSpeed)
  outa[disablePin]~
  
PRI isOn(motorNum) 
    
  disablePin  := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1 
  return ina[disablePin]
    
PRI reverseMotor(motorNum)  | curSpeed 
  
  disablePin   := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1 
  directionPin := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] - 1
  curSpeed        := motorData[(motorNum-1) * motorArraySIZE + arraySPEED]
     
 if  IsOn(motorNum) == 0
   outa[directionPin]~~
              
 else 
  rampSpeed(motorNum, curSpeed, MINSPEED)     
  outa[direction]~~
  rampSpeed(motorNum, MINSPEED, curSpeed)
  
      
PRI forwardMotor(motorNum)  | curSpeed 
 disablePin   := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1 
 directionPin := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] - 1
 curSpeed     := motorData[(motorNum-1) * motorArraySIZE + arraySPEED]
      
 if IsOn(motorNum) == 0
   outa[directionPin]~
              
 else 
  rampSpeed(motorNum, curSpeed, MINSPEED)     
  outa[directionPin]~
  rampSpeed(motorNum, MINSPEED, curSpeed)
PRI getPosition(motorNum) 
  
  position    := motorData[(motorNum-1) * motorArraySIZE + arrayPOSITION]
  world       := motorData[(motorNum-1) * motorArraySIZE + arrayWORLD] 
  offset      := motorData[(motorNum-1) * motorArraySIZE + arrayOFFSET]      
  return world - offset
     
PRI zeroMotor(motorNum) | worldPtr, offsetPtr
   worldPtr  := @motorData[(motorNum-1) * motorArraySIZE + arrayWORLD] 
   offsetPtr := @motorData[(motorNum-1) * motorArraySIZE + arrayOFFSET]    
   long[offsetPtr] := long[worldPtr]
     
PRI homeMotor(motorNum) | worldPtr, offsetPtr
   worldPtr  := @motorData[(motorNum-1) * motorArraySIZE + arrayWORLD] 
   offsetPtr := @motorData[(motorNum-1) * motorArraySIZE + arrayOFFSET]   
   long[offsetPtr] := long[worldPtr] := 0    
  
PRI positionMotor(motorNum, newPos) | posPtr, curSpeed, curAccel
  disablePin   := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] + 1 
  directionPin := motorData[(motorNum-1) * motorArraySIZE + arrayPULSE] - 1
  curSpeed     := motorData[(motorNum-1) * motorArraySIZE + arraySPEED]
  curAccel     := motorData[(motorNum-1) * motorArraySIZE + arrayACCEL]
  posPtr       := @motorData[(motorNum-1) * motorArraySIZE+ arrayPOSITION]
  if newPos < 0
   reverseMotor(motorNum)
   newPos := -newPos
  else
   forwardMotor(motorNum)
    
  if newPos < 2000
   setSpeed(motorNum, MINSPEED)
  setAccel(motorNum, MINACCEL)
  onMotor(motorNum)
   
  repeat while long[posPtr] < (newPos - 2000)
   
  setAccel(motorNum, MAXACCEL)
  rampSpeed(motorNum, speed, MINSPEED)
   
  repeat while long[posPtr] < newPos
 
  offMotor(motorNum)
  setSpeed(motorNum, curSpeed)
  setAccel(motornum, curAccel)
  
PRI moveXY(x1, y1) | posXptr, posYptr, motor1, motor2, curSpeed1, curSpeed2, accel1, accel2
  motor1 := 1
  motor2 := 2
  
  posXptr       := @motorData[(motor1-1) * motorArraySIZE+ arrayPOSITION]
  posYptr       := @motorData[(motor2-1) * motorArraySIZE+ arrayPOSITION]
    
     if x1 < 0
       reverseMotor(motor1)
       x1 := -x1
     else
       forwardMotor(motor1)
       
     if y1 < 0
       reverseMotor(motor2)
       y1 := -y1
     else
       forwardMotor(motor2)
        
  
  onMotor(motor1)
  onMotor    (motor2)
    
      repeat
    
        if long[posXptr] > (x1 - 2000)
            curSpeed1     := motorData[(motor1-1) * motorArraySIZE + arraySPEED]
            rampSpeed(motor1, curSpeed1, MINSPEED)
        if  long[posYptr] < (y1 - 2000)
            curSpeed2     := motorData[(motor2-1) * motorArraySIZE + arraySPEED]
            rampSpeed(motor1, curSpeed2, MINSPEED)     
      
        if long[posXptr] > x1
         offMotor(motor1)
        
        if long[posYptr] > y1 
          offMotor(motor2)
          
        if (isOn(motor1) == 0) AND (isOn(motor2) == 0)
          quit 
          
   setSpeed(motor1, curSpeed1)
setSpeed(motor2, curSpeed2)

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-08-23 20:52
    It doesn't make any sense for a program to behave differently when loaded from EEPROM into RAM for execution vs. loaded from a PC (via serial) into RAM for execution. The only situations where that happens are when a program directly reads and/or writes to EEPROM explicitly.

    Exactly what behavior are you seeing? Perhaps the program is affected by a power cycle and you're not power cycling when you download the program into RAM to run, but you might be power cycling when you download and run the program from EEPROM.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-08-23 21:01
    Hi Mr. Green,

    I am using SimpleIDE to load programs. If I load to to EEPROM the program will not execute. When I load to RAM it runs. Is this just normal behavior?
  • kuronekokuroneko Posts: 3,623
    edited 2012-08-23 21:10
    What happens when you power cycle after the program has been written to EEPROM? There is the small chance that SimpleIDE uses ProgramShutdown instead of ProgramRun when it uploads the binary.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-08-23 21:16
    Seems to run OK if I manually cycle the power on the board.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-08-23 21:21
    According to the SimpleIDE loader documentation, it uses the Prop's ROM loader for everything but XMMC programs (extended memory model C) which you're not using. The ROM loader is the same that the Propeller Tool uses and, when you download to EEPROM, it automatically runs the program (ProgramRun). If it's not doing that, I'm not sure what would be going on. Do you have access to a Windows PC where you could try your program with the Propeller Tool?

    I've not had problems with SimpleIDE on a Mac.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-08-23 21:28
    Runs when loaded to EEPROM from Propeller Tool v1.3.2.

    The funny thing is I do not recall this behavior from SimpleIDE in the past. I presumed I had somehow implemented a memory usage scheme that became problematic with the enhanced SerialDriver4port object.
Sign In or Register to comment.