Shop OBEX P1 Docs P2 Docs Learn Events
PASM to spin — Parallax Forums

PASM to spin

UltraLazerUltraLazer Posts: 30
edited 2009-12-05 23:40 in Propeller 1
Is there a good way to send a long from a PASM cog back to a spin cog.

I am using a
COGINIT (SEQ_cog,@Step000,@SEQ)

to lunch my PASM cog so par is pointing at the beginning of a
SEQ long 0,0,0,0,0,0....

in DAT...

I have a changing variable (long) in my PASM that I want to
wrlong

to update the value in hub ram 1 x per loop of the pasm.

should I reserve space in DAT for the value to be shared? or declare it in spin?

can I "reuse" the par register later in the pasm, now that the cog has been initialized to the sequence?

Comments

  • Graham StablerGraham Stabler Posts: 2,510
    edited 2009-12-05 00:12
    You can declare seq in the VAR section then access it using par as you say:

    mov   p,par      'make a copy of par
    wrlong   data,p  'write to hub
    add   p,#4     'address of next long
    wrlong   data,p  'write to next position
    
    



    par will just stay as par I am not sure what you mean by resuse
  • JonnyMacJonnyMac Posts: 9,208
    edited 2009-12-05 00:18
    When you start a PASM cog you can only pass one parameter (usually an address, as you're doing with Step000) -- this goes across in par. If you're dealing with more than one address in the hub then your PASM code needs to understand the relationship to the address passed in par.

    Let's say you have three longs; you really should put them into contiguous locations and then pass the address of the first with coginit. In your PASM code you can start off like this:

    dat
    
                            org     0
    
    asm                     mov     val1pntr, par
                            mov     val2pntr, val1pntr
                            add     val2pntr, #4
                            mov     val3pntr, val2pntr
                            add     val3pntr, #4
    


    This a simple way to handle it; there are some crafty programmer here that have come up with other solutions that are very clever -- I tend to stick with simple (keeps my brain from melting).
  • UltraLazerUltraLazer Posts: 30
    edited 2009-12-05 21:26
    Thanks for the tips guys, although I think my question was unclear. Sorry Im a PASM newb.

    I am actually experimenting with Ray Tracy's, Mother of all LED sequencers (M.O.A.L.S.?)(http://obex.parallax.com/objects/240/)

    I have a spin cog that reads a sequence from an eeprom, writes it to some predefined long array space called "SEQ" in DAT and launches the M.O.A.L.S. SEQ_Cog.


    This works well, and looks Something like this:

    Pub start
        
        i2c.ToRam(@SEQ,@SEQ[noparse][[/noparse]SEQ_num]+3,tmp_MV_Address) 
        COGINIT (SEQ_cog,@Step000,@SEQ) 
    
    
    
    DAT
            org     0
    {   Step000 initialize   }
    Step000 or      DIRA, ledmask           ' Set output lines in the direction register
                mov     Time, delay             ' Setup arbitrary initial $01312D00
                add     Time, cnt               
    
    { Step010 setup the first sequence }
    :Step010
            mov     P0,par                  ' Get data patterns starting address 
            mov     P1,P0                   ' Setup working pointer
            
            rdlong Reps,P1                  ' Get Repetition count
            add     P1,#4                   ' Advance pointer to sequence timing
            rdlong  Dly,P1                  ' Get sequence timing
    
    { Step020 set working pointer to start of sequence }
    :Step020
            mov     P2,P1                    'P1 points to sequence timing
            add     P2,#4                    'P2 now points to element count
    
    { Step030 get element count }
    :Step030
            rdlong  Ectr,P2               ' Get element count
            
    { Step040 get next pattern element }
    :Step040
            add     P2,#4                 ' Advance pointer to next element
            
            rdlong T1,P2          ' Get the pattern
            'wrlong T1,SEQ <--- this does not work; AREA IN QUESTION - As far as I can tell I need write value of T1 to the hub about here
    
    { Step050 turn on leds }
    :Step050
            xor     T1,#0                  ' For the Demo Board 03ff0000 (ledmask) for the PropRPM
         
            mov     outa,T1
    
          ...  jmp     #:Step020 .........and so on.....
    
            cogid ID
            cogstop ID         
                    
            FIT $1F0
    
    SEQ long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
           long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
           long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
           long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
           long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
           long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
           long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    
    



    I am hoping to get the M.O.A.L.S. to update a long in hub ram with its current element as it chunks through the SEQ data.
    the par I was referring to is the one already used in the sequencer to set the data patterns adress. I was wondering if I have to reference the address of the shared SEQ data in order to write a long to the hub? my head hurts.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2009-12-05 21:39
    In your top level program you could declare two longs: one holds the address of the DAT table with the sequence data (this will be passed in par, the next is the variable that holds the current step your sequencer is running. Like this:

    var
    
      long  seqstart
      long  seqstep
    



    Your top-level code would write the address (@) of the data table to seqstart before calling coginit:

    pub main
    
      seqstart := @seq
      coginit(@moas, @seqstart)
    



    The MOAS code needs to capture the value par and add four to it to know the address of seqstep -- this is the address you will write back to that tells the top level code what step MOAS is presently running. Make sense? I would do something like this at the top of MOAS:

    dat
    
                            org     0
    
    moas                    mov     startpntr, par
                            mov     steppntr, startpntr
                            add     steppntr, #4
    



    Remember... you can only pass one parameter when using coginit with an assembly cog. This is why the order of your variables is important; the cog needs to match the spin code that launches it. Now that know where the step address is held in the hub you can write the step back with wrlong (to steppntr).

    Post Edited (JonnyMac) : 12/5/2009 9:52:52 PM GMT
  • UltraLazerUltraLazer Posts: 30
    edited 2009-12-05 22:12
    seqstart := @seq etc work well thanks!, but the PASM bit seems to crash the SEQuencer...
    
    Step000 or      DIRA, ledmask           ' Set output lines in the direction register
            mov     Time, delay             ' Setup arbitrary initial $01312D00
            add     Time, cnt               
    
            mov    startpntr, par                 <--- 
            mov    steppntr, startpntr   <--- this seems to crash the sequncer
            add    steppntr, #4                   <--- 
            
    { Step010 setup the first sequence }
    :Step010
            mov     P0,par                  ' Get data patterns starting address
            mov     P1,P0                   ' Setup working pointer
            
            rdlong Reps,P1                  ' Get Repetition count
            add     P1,#4                   ' Advance pointer to sequence timing
            rdlong  Dly,P1 
    
    .....
    wrlong T1,steppntr   'T1 holds current SEQ value
    ...
    steppntr res  1
    startpntr res 1
    
    
    



    The first 3 values (0,1,2) in the SEQ data are required for reps, timing and # of elements. Is this an issue with the suggested fix?
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-12-05 23:40
    What Jonny did not tell you is that you have to read the SEQ address from HUB RAM then.

    { Step010 setup the first sequence }
    :Step010
    mov P0,par ' Get data patterns starting address

    needs to be changed to
    { Step010 setup the first sequence }
    :Step010
    rdlong P0,startpntr ' Get data patterns starting address




    Ehmmm ... and currently the sequencer does not wait. My expectation is that this will be changed, as you want to see the sequence?! But·at the moment·your SPIN code will miss a lot of data.

    Post Edited (MagIO2) : 12/5/2009 11:48:20 PM GMT
Sign In or Register to comment.