Shop OBEX P1 Docs P2 Docs Learn Events
Propeller Assembly for beginners - Page 19 — Parallax Forums

Propeller Assembly for beginners

1161719212229

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2012-01-17 16:07
    Post #535
    Harprit wrote: »
    Dat           org 0 
    C_og1        
    loop1         mov mem, par
                  wrlong one, mem
                  jmp #loop1
    
    C_og2        
    loop2         mov mem, par
                  add mem, #4
                  wrlong two, mem
                  jmp #loop2
    
    one  long 1
    two  long 2
    
    mem res 1
    
    1. What's the (cog) address of labels C_og1 and loop1?
    2. What's the (cog) address of labels C_og2 and loop2?
    3. What's are the (cog) addresses of labels one, two and mem?
    (all in the context of the listed DAT block)

    Once we established that I have some more questions.
  • ericballericball Posts: 774
    edited 2012-01-18 06:35
    Assuming there is no other code, the answers should be:
    1. C_og1 and loop1 are both 0 (org 0)
    2. C_og2 and loop2 are both 3
    3. one, two and mem are 7, 8 and 9 respectively.
  • HarpritHarprit Posts: 539
    edited 2012-01-18 07:15
    @K:

    By cog address do you mean which cog they are running in (or have been instructed to run in)?.

    @Ericball

    I did not understand your post completely.
    Please expand.
    It is important for me to understand this thread in detail.

    @jazzed

    I made the changes you suggested and it does indeed work now. Thanks
    Now to understand exactly what is going on! And why.

    H
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-18 17:02
    Harprit wrote: »
    By cog address do you mean which cog they are running in (or have been instructed to run in)?
    Nope, I mean exactly what Eric so conveniently answered for you. If you have a loop in assembler the jump has to go somewhere. Normally we hide numeric values behind label names. Now, if we look at this one level down we get this picture:
    DAT             org     0               ' cog address
    C_og1        
    loop1           mov     9, $1F0         ' $000
                    wrlong  7, 9            ' $001
                    jmp     #0              ' $002
    
    C_og2        
    loop2           mov     9, $1F0         ' $003
                    add     9, #4           ' $004
                    wrlong  8, 9            ' $005
                    jmp     #3              ' $006
    
    one             long    1               ' $007
    two             long    2               ' $008
    
    mem             res     1               ' $009
    
    DAT
    
    This is what you'd actually see when you disassemble the binary file. After cognew(@C_og1, address) has finished the first 10 registers in the cog will look like this (location 9 will be more or less random depending on what your SPIN code looks like).

    Is this OK so far? Can you see how the first loop works?
  • ericballericball Posts: 774
    edited 2012-01-19 07:10
    Sorry about the brevity to my response, but I tend to only answer the question.

    I haven't read the whole thread, but I think I know where kuroneko is going with this.
    DAT             org     0               ' cog address
    C_og1        
    loop1           mov     9, $1F0         ' $000 move the contents of register $1F0 (aka PAR, i.e. the second parameter in the SPIN cognew statement) to register 9
                    wrlong  7, 9            ' $001 write the contents of register 7 to the HUB address pointed to by the contents of register 9
                    jmp     #0              ' $002 move the immediate value 0 to the program counter, execution continues with the instruction in register 0
    
    C_og2        
    loop2           mov     9, $1F0         ' $003 move the contents of register $1F0 (aka PAR, i.e. the second parameter in the SPIN cognew statement) to register 9
                    add     9, #4           ' $004 add the immediate value 4 to the contents of register 9 
                    wrlong  8, 9            ' $005 write the contents of register 8 to the HUB address pointed to by the contents of register 9
                    jmp     #3              ' $006 move the immediate value 3 to the program counter, execution continues with the instruction in register 3
    
    one             long    1               ' $007 the contents of register 7 is the value 1
    two             long    2               ' $008 the contents of register 8 is the value 2
    
    mem             res     1               ' $009 the contents of register 9 is undefined as no data is stored in HUB RAM for this register
    
    
    So if you did a cognew(@C_og1, @variable) the value of variable would be continuously overwritten with the value 1 after ~8K clock cycles. However, if you tried to cognew(@C_og2, @variable) the value of variable would be overwritten with an unknown value only once after ~8K clock cycles. This is because the C_og2 instruction would be loaded into register 0, not register 3 and would look like:
    DAT             org     0               ' cog address
    C_og2        
    loop2           mov     9, $1F0         ' $000 move the contents of register $1F0 (aka PAR, i.e. the second parameter in the SPIN cognew statement) to register 9
                    add     9, #4           ' $001 add the immediate value 4 to the contents of register 9 
                    wrlong  8, 9            ' $002 write the contents of register 8 to the HUB address pointed to by the contents of register 9
                    jmp     #3              ' $003 move the immediate value 6 to the program counter, execution continues with the instruction in register 3
    
    one             long    1               ' $004 the contents of register 4 is the value 1
    two             long    2               ' $005 the contents of register 5 is the value 2
    
    mem             res     1               ' $006 the contents of register 6 is undefined as no data is stored in HUB RAM for this register
    
  • HarpritHarprit Posts: 539
    edited 2012-01-19 09:50
    @ericball

    Very interesting indeed. The point of interest (getting it right) seems to have been made by "jazzed" by pointing out that we need another DAT statement to end what is contained in Cog1 before starting Cog2. That aside, I appreciate your taking the time to spell it all out for me so that I can hopefully pass the information on the beginners without messing it up.

    An interesting aside to this is that I did not appreciate what kureneko was trying to get across to me and you saw it right away. I do not even understand the jargon at this time!! One more indication that beginners need to really start in the beginning and there seems to be no indicator, as far as I can see, as to where the beginning needs to be. Maybe I can help in that direction.

    Thanks again I appreciated it.
    H
  • HarpritHarprit Posts: 539
    edited 2012-01-19 11:36
    I am finding that a long declared as a PASM program constant at the bottom of the program can have its value changed by the program.
    So it is not a constant forever the same as constants that are declared under CON.
    Is this true and is it a proper use of a variable.
    Or is just one way to declare a variable.
    H
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2012-01-19 13:33
    They are not constants but initialized variables. It it quite normal as you will see in many objects.

    You can also change their values before launching the associated assembly cog if I remember rightly which can be useful and avoids having to send set-up parameters via par.

    Graham
  • Heater.Heater. Posts: 21,230
    edited 2012-01-19 14:18
    A long in DAT is not any kind of constant. It is initialized with what ever value you put in your code but can be changed by Spin or PASM after. But beware that long may be loaded into COG with your PASM in which case that same LONG you wrote has a dual existance, in the COG or COGs and the original place it occupied in HUB.
    No you do not need to start a new DAT section to have more than one COGs PASM in an object.
  • jazzedjazzed Posts: 11,803
    edited 2012-01-19 15:24
    Heater. wrote: »
    No you do not need to start a new DAT section to have more than one COGs PASM in an object.
    That's true. An ORG 0 in a current DAT section will reset address references.
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-19 15:58
    @ericball: Thanks for seeing this through. Let's hope it helps :)
  • HarpritHarprit Posts: 539
    edited 2012-01-21 12:17
    HELP:

    Well I don't have the fat lady singing yet as regards the use of PAR.

    I cannot figure out a simple rule that tells me when the variables being pointed to by PAR will be cleared or not.
    What does one have to do or not do to preserve the variables across all cogs
    And what does one have to do the clear them either on purpose or by mistake.

    I can make it work but I am not sure I am doing it right. And things get messed up inadvertently.
    i.e. I still don't have the confidence to tell beginners what to do or not do.

    H
  • ericballericball Posts: 774
    edited 2012-01-21 13:08
    PAR is typically a pointer to a long in HUB RAM (which may be the first long in an array or list of longs). Note: due to how coginit (PASM) works, only bits 2-15 of PAR are valid; the other bits are zero; therefore PAR cannot point to a byte or word. It's also a read-only register.

    Because HUB RAM is shared by all cogs, any cog can make updates. Changing the long pointed to by PAR is done via WRLOG register, PAR (where register contains the desired value).
  • Heater.Heater. Posts: 21,230
    edited 2012-01-21 15:32
    I don't meant be flipant but I guess the simple as to when variables pointed to by PAR are cleared or not is:
    If you clear them they are cleared. If you don't they are not.
    I think you should answere kureneko's little quiz questions in pozt #542 before proceeding as we are suspecting a confusion over the use of DAT and/or ORG and/or RES here.
  • jazzedjazzed Posts: 11,803
    edited 2012-01-21 16:10
    Maybe you should consider having a conference call with Parallax Tech Support ?
    Harprit wrote: »
    HELP:

    Well I don't have the fat lady singing yet as regards the use of PAR.

    I cannot figure out a simple rule that tells me when the variables being pointed to by PAR will be cleared or not.
    What does one have to do or not do to preserve the variables across all cogs
    And what does one have to do the clear them either on purpose or by mistake.

    I can make it work but I am not sure I am doing it right. And things get messed up inadvertently.
    i.e. I still don't have the confidence to tell beginners what to do or not do.

    H
  • HarpritHarprit Posts: 539
    edited 2012-01-21 17:58
    @heater

    Ericball answered the question in # 542. Iresponded by mading the corrections and posted to jazzed that everything wored fine for the simp[le programs that I was running. I dont think I am doing thingsany different now!!

    ======

    Well I do think I am getting a handle on things so its not totally blind on my part.

    Here is what I have going

    Program 1
    Reads a potentiometer stores it at Par pointer 1st position. Variable passed is @P_Val
    Performs a division and stores the result in PAR pointer +16 the 5th long location
    One routine displays the data, One stores it via PAR pointers.
    Everything works fine I can read the data and it is what I want where I want it to be.
    Running the program shows everything just right on the PST
    No problems.

    Program 2
    Calls the all of the program in program 1 and everything is fine
    Running the program shows everything just right on the PST
    No problems.

    Next I call just the part of the program that stored the variables in program 1
    I get zeroes.

    All routines that refer to the data use @V_Pal as the passed variable

    Here are the listings you can comment routines out as you see fit.
    {{
    022 PASM Read4Pots.spin
    Program to read 4 pots
    Repeats the program GOOD 006 PASM ReadPot 4 times
    Installs in separate cog.
    Reads resistances to 12 bits appears in POT_RES global variable
    15 Dec 2011
    By Harprit Sandhu
    }}
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      bits=12
      pots=8
      
    VAR
      long P_Val[7]
      long  pot_sub
      long  clear
      
    OBJ                                                            
      fds : "FullDuplexSerial"
      
    PUB Main (address)                  'P_VAL is a local variable here
    fds.start(31,30,0,115200)            'start console at 115200 for debug output
    read_Pots(@P_Val)
    dira[0..2]~~
      repeat                            'endless loop
        pot_sub:=0                      'reset id of pot to be printed
        fds.tx($1)                      'home to 0,0
        repeat pots                     'loop to display data
          fds.bin(P_val[pot_sub], bits) 'print to the PST in binary                                 
          repeat 2                      'two spaces                                                          
            fds.tx(" ")                 'space to erase old data overflow        
          fds.dec(P_val[pot_sub])       'print value as decimal value     
          repeat 2                      'two spaces
            fds.tx(" ")                 'space to erase old data overflow        
          fds.dec(pot_sub*4)            'print value as decimal value     
          repeat 3                      'three spaces
            fds.tx(" ")                 'space to erase old data overflow
          fds.tx($d)                    'new line
          pot_sub:=(pot_sub)+1          'increment display counter
        waitcnt(clkfreq/60+cnt)         'flicker free wait
        clear:=clear+1                  'increment counter. This routine clears up screen
        if clear>10                     'decision point     by erasing extra lines of bot
          fds.tx(16)                    'clear screen       of PST display every 10 loops
          clear:=0                      'reset counter
    
    PUB Read_Pots(address)
    cognew(@Read_P, address)
    
    '----------------------------------end of first Cog------------------------------------------
    DAT           org 0                              'sets the starting point in Cog
    Read_P        mov      dira,      set_dira     'sets direction of the prop pi
                  mov       pots_read, #1           'number of pots to read [also change data]
                  mov       bits_read, #12          'bit resolution of 3208 IC, can be less
                  mov       mem,       par          'get address of mem for PAR
                  mov       mem1, mem
                  mov       pot_id,    #0           'first pot read is pot 0
                   
    Next_pot      or        outa ,   chs_Bit        'makes Chip select high
                  andn      outa,    chs_Bit        'makes chip select low 
                  andn      outa ,   clk_bit        'ANDN it with the Clock Bit to make low
                  or        outa ,   din_Bit        'makes the Din high
                  call      #Tog_clk                'toggle clock line hi-low to read data
                  or        outa ,   din_Bit        'makes the Din high 
                  call      #Tog_Clk                'toggle clock line hi-low to read data
                  
                  mov       temp2,     pot_id       'we will read three bits from this pot
                  call      #get_third_bit          'get bit
           if_nz  jmp       #its_one                'jump to set it as needed
                  jmp       #its_zero               'jump to set it as needed
    its_one       call      #Set_next_bit1          'setting bit subroutine call
                  jmp       #continue1              'go to next bit
    its_zero      call      #Set_next_bit0          'setting bit subroutine call
    continue1     call      #get_second_bit         'get bit
           if_nz  jmp       #its_one1               'jump to set it as needed
                  jmp       #its_zero1              'jump to set it as needed
    its_one1      call      #Set_next_bit1          'setting bit subroutine call
                  jmp       #continue2              'go to next bit
    its_zero1     call      #Set_next_bit0          'setting bit subroutine call
    continue2     call      #get_first_bit          'get bit
           if_nz  jmp       #its_one2               'jump to set it as needed
                  jmp       #its_zero2              'jump to set it as needed
    its_one2      call      #Set_next_bit1          'setting bit subroutine call
                  jmp       #continue3              'go to next bit
    its_zero2     call      #Set_next_bit0          'setting bit subroutine call
    
    continue3     andn      outa ,   din_Bit        'makes Din low              
                  call      #Tog_Clk                'toggle clock line hi-low to read data
                  call      #Tog_Clk                'toggle clock line hi-low to read data                        
                  mov       Data_read,  #0          'clear register we will read data into             
                  mov       bit_count, bits_read    'counter for number of bits we will read
    read_bit      mov       temp,     ina           'read in what is in all the input lines
                  andn      temp,     mask26 wz     'mask off except Dout line. Set Z flag    
                  shl       Data_read,  #1          'shift register left 1 bit for next bit
            if_nz add       Data_read,  #1          'if value + add 1 to data register    
                  call      #Tog_Clk                'toggle clock get next bit ready in Dout
                  sub       bit_count, #1 wz        'decr the "bits read" counter. Set Z flag
            if_nz jmp       #read_bit               'go up do it again if counter not yet 0 
                  wrlong    Data_read,  mem  wz       'write it in PAR to share it as P.Val
            if_z  jmp #next_pot
                  call #get_beat
    skip          add       mem1,#16
                  wrlong    data_read, mem1 
                  add       mem,  #4                'add 4 to hub address for next long
                  mov       mem1, mem
                  add       pot_id, #1              'so we can look at next pot
                  mov       temp2, pot_id           'recall what pot we are reading
                  sub       temp2, pots_Read   wz   'check if it is how many we want to read
          if_nz   jmp       #Next_pot               'if it is not 0 go up and read next pot
                  jmp       #Read_P                 'go back beginning and do all pots again
                 
    'subroutines used
    Set_next_bit0  andn     outa ,    din_Bit       'makes Din low in 000 for line
                  call      #Tog_Clk                'toggle clock line hi-low to read data              
    Set_next_bit0_ret       ret                     'return from this subroutine
    
    Set_next_bit1 or        outa ,    din_Bit       'makes Din high in 000 for line
                  call      #Tog_Clk                'toggle clock line hi-low to read data              
    Set_next_bit1_ret       ret                     'return from this subroutine
    
    Tog_Clk       nop                                'nop to settle signals
                  or        outa,      clk_bit      'make clock bit high
                  nop                                'nop to settle signals
                  andn      outa,      clk_bit      'make clock bit low
                  nop                                'nop to settle signals
    Tog_Clk_ret   ret                               'return from this subroutine         
    
    Get_first_bit  mov      temp2,     pot_id       'get current pot number
                   andn     temp2,     mask0 wz     'get last bit
    Get_first_bit_ret       ret                     'return
    
    Get_second_bit mov      temp2,     pot_id       'get current pot number
                   shr      temp2,     #1           'shift right 1 bit to get second bit
                   andn     temp2,     mask0 wz     'return   
    Get_second_bit_ret      ret                
    
    Get_third_bit  mov      temp2,     pot_id       'get current pot number
                   shr      temp2,     #2           'shift right 2 bits to get third bit
                   andn     temp2,     mask0 wz     'return 
    Get_third_bit_ret        ret
    
    Get_beat       mov   temp3,  data_read
                   shl  temp3, #3
                   mov  total, clkf
                   mov  beat, #0
    do_again       sub  total, temp3  wc
                   add  beat,  #1
            if_nc  jmp  #do_again
                   sub  beat,  #1
                   mov   data_read, beat
    Get_beat_ret  ret                              
     
    Set_dira      long      001011_00000000_00000000_00000111   'Set dira register                                 
    Chs_Bit       long      000001_00000000_00000000_00000000   'Chip select bit     24
    Din_Bit       long      000010_00000000_00000000_00000000   'Data in bit         25
    Dout_Bit      long      000100_00000000_00000000_00000000   'Data out bit        26
    Clk_Bit       long      001000_00000000_00000000_00000000   'Clock bit           27
    mask26        long      111011_11111111_11111111_11111111   'Mask to read Dout bit
    mask0         long      111111_11111111_11111111_11111110   'Mask to  read 0  bit                                                                                          
    clkf  long  80_000_000
    
    beat res 1
    mem            res      1       'Par location
    mem1 res 1
    temp           res      1       'temporary storage variable, misc
    temp2          res      1       'temporary storage variable, misc
    temp3 res 1
    bit_count      res      1       'temporary storage variable, read bit counter
    Data_Read      res      1       'temporary storage variable, data being read 
    pot_id         res      1       'current pot id number
    pots_read      res      1       'total number of pots to be read.
    bits_Read      res      1       'resolution of data read, 12 bits max
    total res 1
    
    
    {
    OSC for metronome
    Read pot and display on PST through 022 PASM Rea4PotsX
    And sets up basic count oscillator
    }
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      'bits=32
    VAR
      long P_Val[7]
    
    obj
      RP : "ReadPots"    'reads pots
      
    PUB Main                           
      dira[0..2]~~
      RP.main(@P_val)
      'RP.read_Pots(@P_val)
      Oscillate (@P_val)                                                                         
      
    PUB Oscillate (address)                        
      cognew(@Oscil, address)
     
    DAT           org       0                                                           
    Oscil         mov       dira,      set_dira       'sets direction of the prop pins
    loop          mov       mem,       par            'get par address
                  add       mem,       #16
                  rdlong    Pot,       mem
                                   
                  mov       delay,     cnt            'read in CNT
                  add       delay,     50             'add to skip over counter fill
                  andn      outa,      bit_1          'bits low
                  waitcnt   delay,     pot            'pause
                  
                  mov       delay,     cnt            'read in CNT
                  add       delay,     50             'add to skip over counter fill
                  or        outa,      bit_1          'bits high
                  waitcnt   delay,     pot            'pause
                  
                  jmp       #loop                     'loop back
    
    Set_dira      long      001011_00000000_00000000_00000111   'Set dira register  
    bit_1         long      000000_00000000_00000000_00000001   'output bit
          
    pot res 1
    mem           res       1          'memory location for PAR variable
    delay         res       1          'delay constant for CNT
    
    

    Harprit.
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-21 18:22
    Harprit wrote: »
    Next I call just the part of the program that stored the variables in program 1 I get zeroes.
    By that I assume you mean program 2 does this? If not please elaborate.
    PUB Main                           
      dira[0..2]~~
      RP.read_Pots(@P_val)
      Oscillate (@P_val)                                                                         
    
    What does get zeroes actually mean (you don't have PST output in this case AFAICS)? It would also help if you used a technique (to attach code) which doesn't destroy binary constants.
  • Heater.Heater. Posts: 21,230
    edited 2012-01-22 05:26
    What goes on here?
    That code in post #557 does not even compile.
    There are binary constants with out %
    There are two _clkmode and _xinfreq which at least BST does not like.
  • HarpritHarprit Posts: 539
    edited 2012-01-22 05:54
    Sorry, its two programs.
    Each will compile
    H
  • kuronekokuroneko Posts: 3,623
    edited 2012-01-22 06:07
    Harprit wrote: »
    Each will compile
    No they don't. It would make it easier (and faster) for us to help you if you'd actually answer questions posed to you. Otherwise people will stop responding.
  • HarpritHarprit Posts: 539
    edited 2012-01-22 09:31
    @kuroneko

    My sincerest apologies. I try to answer all questions unless someone else does or they other wise get discussed.
    Or if I think they are tangential to a beginner's interests at this time.
    I copied the programs from code that I was running so they should have compiled.
    The % indicators were stripped by the discussion software.
    I was unaware that it does that.
    No one has ever mentioned it before to my knowledge.
    As regards #558 I am not getting any output on the PST but if I put in 0s for the variables, I get the same output on the O'scope as if I had read 0s

    @Jazzed
    I will call Tech support on Monday and report the results

    @Heater
    I store the variables, I never clear them and then later I cannot read them. Something is happening that is causing them to be cleared and I cannot
    figure out what it is. Till I know I cannot proceed with the book because this affects everything about my understanding of what is going on and how I explain it.
    I've been at it for two weeks!!


    @All
    Lets try again with less code in the examples. I stripped almost everything that I could think of as unnecessary.

    My code had the % binary designators in it but they were stripped by the discussion forum.
    I do not know the reason.
    I have eliminated them and shortened the code many times over to show just the essence of the problem I am having
    The following code in the first program has two routines in it.
    This program should be saved as "ReadPots2" when you save it. It will be called in a later program.
    The first routine lets you look at the 12 LS bits on 8 registers, as longs, pointed to by PAR on the Parallax Serial Terminal
    {{
    Name this program"ReadPots2"
    }}
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      bits=12
      pots=8
      
    VAR
      long P_Val[7]
      long  pot_sub
      long  clear
      
    OBJ                                                            
      fds : "FullDuplexSerial"
      
    PUB Main                            'P_VAL is a local variable here
    fds.start(31,30,0,115200)            'start console at 115200 for debug output
    read_Pots(@P_Val)
    show
    
    PUB Show
    dira[0..2]~~
      repeat                            'endless loop
        pot_sub:=0                      'reset id of pot to be printed
        fds.tx($1)                      'home to 0,0
        repeat pots                     'loop to display data
          fds.bin(P_val[pot_sub], bits) 'print to the PST in binary                                 
          repeat 2                      'two spaces                                                          
            fds.tx(" ")                 'space to erase old data overflow        
          fds.dec(P_val[pot_sub])       'print value as decimal value     
          repeat 2                      'two spaces
            fds.tx(" ")                 'space to erase old data overflow        
          fds.dec(pot_sub*4)            'print value as decimal value     
          repeat 3                      'three spaces
            fds.tx(" ")                 'space to erase old data overflow
          fds.tx($d)                    'new line
          pot_sub:=(pot_sub)+1          'increment display counter
        waitcnt(clkfreq/60+cnt)         'flicker free wait
        clear:=clear+1                  'increment counter. This routine clears up screen
        if clear>10                     'decision point     by erasing extra lines of bot
          fds.tx(16)                    'clear screen       of PST display every 10 loops
          clear:=0                      'reset counter
    
    PUB Read_Pots(address)
    cognew(@Read_P, address)
    
    
    DAT           org 0                              'sets the starting point in Cog
    Read_P        mov      dira,      set_dira     'sets direction of the prop pi
                  mov       mem,       par          'get address of mem for PAR
                  wrlong    data1,     mem
                  mov       mem1,      mem
                  add       mem1,      #16
                  wrlong    data2,     mem1
                  jmp  #Read_P
     
    Set_dira      long      7   'Set dira register                                 
    
    data1         long      2000
    data2         long      500
    
    mem           res       1       'Par location
    mem1          res       1
    

    The second routine in the first program stores 2000 at the first PAR location and 500 at the fifth PAR location as longs

    ===================================================================

    The second program reads the fifth PAR locations and uses it as a delay to turn bit 1 on the propeller on and off so I can look at it with a scope.
    It does not
    It should also allow you to look at the 8 PAR longs but it does not. The PST remains blank
    I am at a complete loss as to why this is happening. And I know its something stupid on my part.
    {
    Name this [U]program[/U] "Oscillator" it calls "ReadPots2" as a OBJ
    }
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      bits=12
      pots=8
    
    VAR
      long P_Val[7]
    
    obj
      RP : "ReadPots2"   'reads pots
     fds : "FullDuplexSerial"
        
    PUB Main                                                                          
      dira[0..2]~~     
      fds.start(31,30,0,115200)            'start console at 115200 for debug output 
      RP.read_Pots(@P_val)
      RP.show
      Oscillate (@P_val)                                                                         
      
    PUB Oscillate (address)                        
      cognew(@Oscil, address)
     
    DAT           org       0                                                           
    Oscil         mov       dira,      set_dira       'sets direction of the prop pins
    loop          mov       mem,       par            'get par address
                  add       mem,       #16
                  rdlong    Pot,       mem
                                   
                  mov       delay,     cnt            'read in CNT
                  add       delay,     #50             'add to skip over counter fill
                  andn      outa,      bit_1          'bits low
                  waitcnt   delay,     pot            'pause
                  
                  mov       delay,     cnt            'read in CNT
                  add       delay,     #50             'add to skip over counter fill
                  or        outa,      bit_1          'bits high
                  waitcnt   delay,     pot            'pause
                  
                  jmp       #loop                     'loop back
    
    Set_dira      long      7   'Set dira register  
    bit_1         long      1   'output bit
          
    pot           res       1          'read variable
    mem           res       1          'memory location for PAR variable
    delay         res       1          'delay variable usage
    
    

    The way I understand things, this should all work but it does not.
    I am at a loss to understand why.

    H
  • jazzedjazzed Posts: 11,803
    edited 2012-01-22 09:59
    I see some potential problems in your code.
    1. Your Show "pot_sub" variable increments forever, which means your output will probably be bogus after a few loops.
    2. You add the contents of register 50 to your delay in DAT Oscil. What is in 50? Did you mean to use the value #50?
    3. Of course Oscillate is never called since Show repeats forever.
    I believe Kuroneko is asking you questions to inspire you to solve your own problems.
    New knowledge can be cemented by thinking about such questions and answers.
    Seems like he's trying to teach you how to fish.

    A conference call may allow you to quickly resolve some software barriers in maybe a few minutes -vs- a few days.
  • HarpritHarprit Posts: 539
    edited 2012-01-22 10:28
    @Jazzed

    The repeat that Pot_sub is is in, repeats pot times, so it get reset after reaching 7. It starts at 0.
    The 50 is indeed mistake. Its should be #50. But I fixed that and it still does not work.

    MAIN call three public methods each of which loops on its own. If Oscillate did not execute, nor would show
    But show does execute because you can see the display of the PST which is called in show

    Then I made the oscillator software a part of the ReadPots program. At the tail end.
    Now the display show garbage numbers for the first and 5th longs in PAR but the
    oscillation starts to work but it is insensitive to data changes in the 5th variable.

    Very strange. I am as confused as I have ever been.

    H
  • HarpritHarprit Posts: 539
    edited 2012-01-22 10:36
    @Jazzed

    You are right about the loop in show.
    It has to be called after the other methods start.

    H
  • jazzedjazzed Posts: 11,803
    edited 2012-01-22 10:39
    Harprit wrote: »
    @Jazzed

    The repeat that Pot_sub is is in, repeats pot times, so it get reset after reaching 7. It starts at 0.

    OK. :)
  • HarpritHarprit Posts: 539
    edited 2012-01-22 10:54
    I have a suspicion
    Is it possible the encountering a DAT resets everything in the world of PAR

    H
  • jazzedjazzed Posts: 11,803
    edited 2012-01-22 11:07
    Harprit wrote: »
    I have a suspicion
    Is it possible the encountering a DAT resets everything in the world of PAR

    H
    Only with cognew would the value of PAR change. PAR is read-only and at a fixed COG address.

    The contents of the long variable pointed to by PAR can change of course, but not by the DAT statement.
  • HarpritHarprit Posts: 539
    edited 2012-01-22 11:08
    This is really driving me up the wall.
    I'm going to re write the whole metronome object as one PASM routine with PASM subroutines to see what happens.
    So I can examine variable my way.

    H
  • HarpritHarprit Posts: 539
    edited 2012-01-22 12:36
    @jazzed:

    Re #568 it means that you can write to PAR only with the last Cog you open. EVER. You cannot open a cog after the writes.
    But...You read from other cogs in loops so that you re read the data after it was written later in the game.
    Since this is not the case with my code, I need to recode

    Am I right?
    H
  • jazzedjazzed Posts: 11,803
    edited 2012-01-22 12:52
    Harprit wrote: »
    @jazzed:

    Re #568 it means that you can write to PAR only with the last Cog you open. EVER. You cannot open a cog after the writes.
    But...You read from other cogs in loops so that you re read the data after it was written later in the game.
    Since this is not the case with my code, I need to recode

    Am I right?
    H

    There is a PAR register for every COG, so there is no interdependence between opening COG1 and COG2 (unless the value PAR passed for both cognew is the same).

    I mean only that when you use cognew(@somecode, @somelong) the value of PAR is set to the address of somelong. Alternatively, cognew(@somecode, someaddr) will set PAR to the value of someaddr with the 2 lower bits cleared. That is the only way to set the value of PAR for a COG. If you write to PAR from inside the COG code, it is not changing PAR. Once PAR is set using cognew, it will not change.

    You can change the data of the variable passed to PAR with no problem and read the data in the COG with rdlong, etc.... You just can't change PAR.
Sign In or Register to comment.