Shop OBEX P1 Docs P2 Docs Learn Events
Help with array of addresses — Parallax Forums

Help with array of addresses

mynet43mynet43 Posts: 644
edited 2013-08-02 08:51 in Propeller 1
I'm using an array of addresses to produce data driven code.

I ran across something I don't understand.

I have eight strings defined in my DAT block. To access these in the code, I've defined an array of addresses to these strings.

When I access these addresses using an index, such as "calib_string_top", I find that the address pointed to in the array is wrong.

In order to make it work right, I have to add 16 to each of the addresses in the array. Once I do this, the code works fine.

Can someone please help me understand why I have to add 16 to the addresses in the array.

Thank you for your help.

Jim

Here's a sample of the code I'm using:
CON
  ' *****NHD standard display 4x20 character LCD***** '
  
  ' CRYSTAL SETUP 80MHz
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
  
  ' DATA PINS FOR DISPLAY
  D0    = 8
  D1    = 9
  D2    = 10
  D3    = 11
  D4    = 12
  D5    = 13
  D6    = 14
  D7    = 15
  
  ' CONTROL PINS FOR DISPLAY
  RS    = 16
  RW    = 17
  EN    = 18                    

  ' POWER FOR PROCESSOR
  LATCH = 22                    ' supply for power to screen and LED
  PWR   = 23

  ' OUTPUT FROM 16 TO 4 ENCODER
  A0    = 24
  A1    = 25
  A2    = 26
  A3    = 27

  ' PARAMETERS
  screen_timeout = 1            ' time after switch is off before screen turns off
  debug          = 1            ' debug on = display on serial terminal
  connected      = 1            ' 1 if connected to main board, 0 if using debug terminal = eliminates waiting for ack 
  action_timeout = 20           ' time before action failed to finish
  
VAR

  byte  ack_back[64]            ' buffer for ack when coming back from light board 
  byte  light_flag              ' light is on or off
  byte  pwr_flag                ' power is on or off
  byte  calib_mode              ' calib mode status flag
  byte  clear_flag              ' clear screen flag
  long  gs_index                ' index used for getstr
  
OBJ

DAT

  Version     byte  "1.0", 0
  ack         byte  "ack", 0     ' look for 'ack' from main control board
  nak         byte  "nak", 0     ' if nak, command failed to send
  fin         byte  "fin", 0     ' action has finished  

  entr        byte  "I"         ' enter
  cal         byte  "J"         ' calibration
  ext_cal     byte  "K"
  ret_cal     byte  "L"
  center_cal  byte  "M"
  STOP        byte  "S"         ' light stopped moving. also means no switch was pressed
   
' KEYS FOR BUTTON FLAGS
  pwr_btn     long  0
  lgt_btn     long  1
  ret_btn     long  2
  ext_btn     long  3
  cal_btn     long  4
  entr_btn    long  5

' DISPLAY INITIALIZATION
  init_cmd    long  %0011_0000, %0011_0000, %0011_0000, %0011_1000, %0000_1000, %0000_0001, %0000_0110, %0000_1100, %1000_0000, 0

' DEBOUNCE FLAGS FOR BUTTONS
  btn_flags   long  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  
' CALIBRATION DATA
  calib_data  long  0, 0, 0, 0
  calib_send  long  @ext_cal, @ret_cal, 0, @center_cal

  calib_steps long  4   ' number of steps in the calibration process
  calib_string_top  long @calib1_top + 16, @calib2_top + 16, @calib3_top + 16, @calib4_top + 16
  calib_string_bot  long @calib1_bot + 16, @calib2_bot + 16, @calib3_bot + 16, @calib4_bot + 16

  calib1_top  byte  "Extend light", 0
  calib1_bot  byte  "to 120 degrees", 0

  calib2_top  byte  "Retract light", 0
  calib2_bot  byte  "to 0 degrees", 0

  calib3_top  byte  "Extend light", 0
  calib3_bot  byte  "to 90 degrees", 0

  calib4_top  byte  "Rotate light", 0
  calib4_bot  byte  "To center", 0

PUB calib_start | i

  calib_mode := 1               ' tell main board you're calibrating 
  clear(0)

  repeat i from 0 to calib_steps - 1
    stringdraw(2, 0, calib_string_top[i])
    stringdraw(3, 0, calib_string_bot[i])
    stringdraw(4, 0, string("Enter when done."))

  ' wait while user calibrates
    repeat until btn_flags[entr_btn]  ' wait for button press
      check_switches

    repeat until not btn_flags[entr_btn] ' wait for button release
      check_switches

    if i <> 2                   ' don't care about third step data
      send_usb_data(calib_send[i])
      
  calib_mode := 0               ' set back to manual mode before leaving calibration
  
PRI check_switches | input, i
  input~                        ' initialize input low
  input := ina[A0..A3]          ' number of the pressed button
  return input                  ' return hex number displaying which button was pressed

PRI clear(line)                 ' clear line on display screen

PRI send_usb_data(d) | jdata, temp    ' send data to usb

PRI stringdraw(line, offset, text) | cmd
  case line                     ' pick correct line, starting address for each line                                   
    1:  cmd := $80              ' line 1
    2:  cmd := $C0              ' line 2
    3:  cmd := $94              ' line 3
    4:  cmd := $D4              ' line 4

  cmd += offset                 ' add offset to get true starting position 
  writecmd(cmd)                 
  writedata(text)               ' display text   
  
PRI writecmd(cmd)               ' send out a command by toggling EN signal
  outa[RS]~                     ' RS low for command    
  outa[D7..D0] := cmd
  !outa[EN]
  waitcnt(clkfreq/1000 + cnt)
  !outa[EN]
  outa[RS]~~
                  
PRI writedata(data) | jdata     ' send data by toggling EN signal
  outa[RS]~~
  repeat while (jdata := byte[data++]) <> 0  
    outa[D7..D0] := jdata       
    !outa[EN]
    waitcnt(clkfreq/1000 + cnt)
    !outa[EN]

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2013-08-02 07:59
    Is PropTool a 2nd stage compiler?, e.g. can a variables address be referred to before it have been reached by the complier.
    As that is done below.

    calib_string_top long @calib1_top + 16, @calib2_top + 16, @calib3_top + 16, @calib4_top + 16
    calib_string_bot long @calib1_bot + 16, @calib2_bot + 16, @calib3_bot + 16, @calib4_bot + 16
    calib1_top byte "Extend light", 0
  • AribaAriba Posts: 2,690
    edited 2013-08-02 08:36
    A @ in a DAT section gives the relative address to the start-address of the object in hubmemory. For the top object the offset is 16 but for sub-objects you can not know where the compiler places them in hubmemory.

    But there is a special operator: @@ which adds the object offset. See Propeller Manual page 173 (the example is exactly what you do).

    Andy
  • mynet43mynet43 Posts: 644
    edited 2013-08-02 08:51
    Thanks for the quick replies.

    Perfect explanation Andy. Now I fully understand it.

    Jim
Sign In or Register to comment.