Shop OBEX P1 Docs P2 Docs Learn Events
How to pass an array to a cog ? — Parallax Forums

How to pass an array to a cog ?

BTXBTX Posts: 674
edited 2007-01-07 19:47 in Propeller 1
Hi all.
This thing is getting me crazy (again).eyes.gif
I have some, like this code..
{B.spin}
 
VAR
   Long Cog
 
PUB Start(direc) : Success  
   Stop
   Success :=  (Cog := cognew(@test_it, direc) + 1)
 
PUB Stop
  if Cog
    cogstop(Cog~ - 1)
 
PUB Run(direc)    
    return
 

 
 
DAT
test_it       mov       t1,par                           
              rdlong    t2,t1          wz
        if_z  jmp       #test_it
 
              mov       t3,#16
m_loop        add       t1,#4           ' I want to get here x[noparse][[/noparse]0], x[noparse][[/noparse]1], x[noparse][[/noparse]2],....x[noparse][[/noparse]16] address
              rdlong    t2,t1            
'              ....do something with t2
              djnz      t3,#m_loop
              
              wrlong    zero,par 
              jmp       #test_it
                            
'------------------------------------------------------------------------------------------------------------------------------
zero    long  0                       'constant
t1      res   1
t2      res   1
t3      res   1


I call it from spin method like:· B.start(@x) where x is:·· long· x[noparse][[/noparse]16] having first the value x[noparse][[/noparse]0]:=0
so the asm rutine loops at the "test_it" flag.· (This lets me start the asm cog only once, and leaving it running in a conditional endless loop)
Then I call B.Run(@x) previously charging x from 0 to 16 with non zero values. The asm routine respons fine, this leave the "test_it" loop and begins from· mov t3,#16.
THE PROBLEM IS: If I erase the line "add t1,#4" the routine works fine for the first value of x[noparse][[/noparse]0], if I leave the code like I wrote above, it seems that the x[noparse][[/noparse]1] value never is getting (like if it's not the correctly address).
In my final target I'll catch 512 values of x, so it is not possible for me, to get all values at start, after get out of the "test_it" loop like conventional way, as when you pass more than one parameter to the asm rutine.

I'll apreciate so much your help.

Regards.
Alberto.



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Envio editado por (BTX) : 1/6/2007 9:13:52 PM GMT

Comments

  • SSteveSSteve Posts: 808
    edited 2007-01-06 20:53
    I'm not 100% from your explanation what you're trying to do, but I see some things that look like they might be problems.

    After m_loop is finished, you're setting x[noparse][[/noparse]0] to zero and then jumping back to the beginning of m_loop. It looks to me like you should be jumping to test_it.

    B.run doesn't do anything. Did you leave some code out?

    If you are modifying an array outside of the assembly routine, you'll need to use a semaphore so that the assembly routine won't start acting on the array before you are finished modifying it.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows

    links:
    My band's website
    Our album on the iTunes Music Store
  • BTXBTX Posts: 674
    edited 2007-01-06 21:33
    OK thanks so much Steve.
    I've just "edit" and correct the code, like you said it must jump to the test_it, but this was only an error when I post the question.
    exactly what I have is a code in spin (we'll call A.spin it) that have an array of 512 data, from x[noparse][[/noparse]0] to x[noparse][[/noparse]511].
    In it code I call first B.start(@x) to 'start' a new cog (running in asm) with a value of zero for x[noparse][[/noparse]0], then I call B.Run(@x) with a value of x[noparse][[/noparse]0] <> 0
    B.Run doesn't do anythig... my purpose is give in that moment a new value for x[noparse][[/noparse]0], and so the test_it loop will end, and the second part of the asm rutine begins.

    Perhaps it is not the best procedure todo it, but it works fine !! I've test it with differents examples using LED semaphores.
    The real problem for me, is not that part of the code, when I did that the first value for x[noparse][[/noparse]0]<>o came perfect. but when the m_loop go to the second pass and add's #4 to the x address it fails, it give me an x value that is not what I give it in the A.spin, and so on with the x, x etc.
    It seem like the address of X was lost, after the first past for the m_loop....
    My target is to process the 512 values in asm very very fast (nothing of spin code after asm lunch) I did it some like this but with a portion of spin code in B.spin actualizing the x[noparse]/noparse variable, and it works fine...but I give form A.spin only the first address "understand me" then that spin code in B did a repeat incrementing the "i" value in x and the asm rutine did all right, but a bit slowly for my application, I get only 15 mSec to process all 512 bytes...I need until 5 mSec or less.

    Hope to be clear with my English...sorry.. and thanks so much for your help.
    Regards.
    Alberto.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


  • SSteveSSteve Posts: 808
    edited 2007-01-06 22:48
    BTX said...
    I call it from spin method like: B.start(@x) where x is: long x[noparse][[/noparse]16] having first the value x[noparse][[/noparse]0]:=0

    ...

    m_loop add t1,#4 ' I want to get here x[noparse][[/noparse]0], x, x,....x[noparse][[/noparse]16] address

    If you want to access x[noparse][[/noparse]16], you'll need to define the array as "long x[noparse][[/noparse]17]".
    BTX said...
    mov       t3,#16
    m_loop        add       t1,#4           ' I want to get here x[noparse][[/noparse]0], x, x,....x[noparse][[/noparse]16] address
                  rdlong    t2,t1
    


    If you increment t1 before the first time through the loop, the first array element you'll address is x[noparse][[/noparse] 1], not x[noparse][[/noparse]0].
    BTX said...
    Then I call B.Run(@x) previously charging x from 0 to 16 with non zero values

    There is no reason to call B.Run(@x). The assembler loop is constantly looking at x[noparse][[/noparse]0] anyway. As soon as it is changed in your other code, m_loop will start. So you must make sure that x[noparse][[/noparse]0] is the last array value that's changed. If you change it first, m_loop will start processing the array before you've given values to the rest of its elements.

    I've written a test program with a corrected version of your B.spin code. (My propeller is currently wired to a seven-segment display so I used that for displaying the array.)

    I hope this is helpful. Let me know if I can clarify anything.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows

    links:
    My band's website
    Our album on the iTunes Music Store
  • BTXBTX Posts: 674
    edited 2007-01-07 01:10
    OK Steve.
    You're really be a big help for me this time.
    I'm learning a lot while working...so it's very important...

    I'm not using x[noparse][[/noparse]17] instead x[noparse][[/noparse]16] long array, because I trust in the asm rutine will be waiting until I start it with B.Run(@x), and controll it giving a zero value for the x[noparse][[/noparse]0] when I want to maintain it in the endless loop, and x[noparse][[/noparse]0] <> 0 when I want to start the rest of the code....BUT...·that is MY one ERROR, like you said I could verify that Run method is NOT necessary in my A.spin.
    So when I begin to assign values <>0 to x[noparse]/noparse array it begins automatically doing the job, I must think a bit, because it could be a colateral effect in my final application. Perhaps could be usefull for me to launch the asm rutine in some other way after I get all x[noparse]/noparse array charged with data.

    In the other hand, I don't understand this in your code:
      repeat inx from 15 to 0                               'put values in array
        x[noparse][[/noparse]inx] := inx + 5                                   ' x[noparse][[/noparse]0] must be set last!!
      
      repeat
      until x[noparse][[/noparse]0] == 0                                       'wait for assembly routine to finish
    
    

    ·When ? [noparse][[/noparse]inx] will be zero ?? last value will be 5.... how ends the last repeat ?

    I fact you are correcting me a lot, but the problem that cause my first question was a mix of many things, one of them,·is the chip that I'm controlling with the propeller,·I don't see before·that perhaps I have a incorrect delay between commands to the chip.
    I was quiet, because it say that all inputs are form DC to· 30 Mhz, but could be something that I miss in the way, I must put a delay between the asm code to get it work correctly, the first problem seems to be a bad address of my variables but it were not. It was solved with· the delay, and now, like you said, I can see that the asm code begins automatically without call Run method ...so my head is going to explode after all day in it....

    For your reference I'm controlling a TLC5940 (Texas Instrument), it is a 16 channel PWM LED driver, I must put 32 of them in cascade to get a final 16x32 module of a big sign board. Is has 16 modules in total. Each channel has until 4096 grayscale (12 Bits).
    I could use 512 words instead longs, but it is in the first trying, and I·like to get the things working·slowly... I began to controll it·entirely in Spin·, but like I need to refresh the display about 30 times, or more per seccond,·once I get it working, I continue to get the necessary speed, so I went to asm to get controll.
    For you knowledge,·I need to charge all 512 "longs" of data , then show it (latch), and so on, at the rate that I mencioned above.·At this time if you're thinking, it's one per channel R,G,B.
    So I will use a Propeller with 3 cogs identicall. one for each one of the colors. And get with another cog the 512x3 "lomgs" of data, so my memory will receive too, all data, by ?????? not determined yet.

    Oh...my wife is calling me, for dinner...

    Regards.
    Alberto.

    EDIT:· I'll post the final code when it were finished, for people that want to play with LED signs.





    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Envio editado por (BTX) : 1/7/2007 3:03:14 AM GMT
  • SSteveSSteve Posts: 808
    edited 2007-01-07 06:48
    BTX said...
    In the other hand, I don't understand this in your code:

      repeat inx from 15 to 0                               'put values in array
        x[noparse][[/noparse]inx] := inx + 5                                   ' x[noparse][[/noparse]0] must be set last!!
    
      repeat
      until x[noparse][[/noparse]0] == 0                                       'wait for assembly routine to finish
     
    
    


    When ? [noparse][[/noparse]inx] will be zero ?? last value will be 5.... how ends the last repeat ?
    That is the key to understanding parallel processing. Since we've already called B.Start, there is a cog constantly processing the array, no matter what other cogs are doing. The first first Repeat loop fills the array with values. The "B" object I wrote sets x[noparse][[/noparse]0] to zero when it's finished, so the second Repeat loop ends when the assembler loop is finished processing the array. Now that you've explained your application in more detail, it sounds like you aren't processing the array a single time, so my example might not be perfectly applicable, but it does access an array correctly.
    BTX said...
    Perhaps could be usefull for me to launch the asm rutine in some other way after I get all x[noparse]/noparse array charged with data.
    If you need to periodically stop processing the array you could use LOCKNEW/LOCKCLR/LOCKSET. If you simply need to wait until the array is initially charged before you start using the data, you could wait and call B.Start after the array is fully charged.

    This sounds like an interesting project. I hope you'll share some photos when it's finished.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows

    links:
    My band's website
    Our album on the iTunes Music Store
  • BTXBTX Posts: 674
    edited 2007-01-07 17:26
    Thanks Steve so much !!
    Now I understand your example...
    Steve said...
    you could wait and call B.Start after the array is fully charged.

    Steve, if I do that, I lost a lot of time between each frame, remember I need about 30fps, so I think that, maintain the cog started and controll the start- stop the data to the TLC , with the x[noparse][[/noparse]0] value could be faster.

    I'll controll my data by the following.:

    1- x[noparse][[/noparse]0]:=0···· ' I maintain the cog in the endless loop.
    2- Start the asm cog.
    3- Charge data in array
    4- x[noparse][[/noparse]0]:= 1··· ' asm cog leave the endless loop, and begins to send data to TLC.
    5=x[noparse][[/noparse]0]:=0···· ' this inmediatly of the before line, when the charge data is finished after 512 "longs" the asm rutine will stay at the endless loop again, waiting for a new array of data.

    The data will be:
    ·x[noparse][[/noparse]0]:= unused data, only for start-stop.
    ·x[noparse][[/noparse]1] through x[noparse][[/noparse]512] display data longs.
    The total array lenght is 513 longs each color, next step is to contoll all with one cog per color. R[noparse]/noparse, G[noparse]/noparse, B[noparse]/noparse arrays.

    I tried an example to check the speed, and it seems that I'm sending about 240 fps.

    I wil upload picts ..of course, but the final project will take many months. In next week I'll put some code (I hope to get some free time to do it), I'm travelling Sao Paulo on thursday.

    Regards.
    Alberto.



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • SSteveSSteve Posts: 808
    edited 2007-01-07 19:47
    It looks like you've got a plan. Good luck with the project.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows

    links:
    My band's website
    Our album on the iTunes Music Store
Sign In or Register to comment.