Shop OBEX P1 Docs P2 Docs Learn Events
Weird asm issue — Parallax Forums

Weird asm issue

BTXBTX Posts: 674
edited 2009-04-20 00:52 in Propeller 1
HI.
This get me crazy.

              rdlong    data,Data_Address                         ' Read one long
              movs      dataR1,data                                  ' take 4 bytes in differents variables for that long
              shr       data,#8
              movs      dataG1,data
              shr       data,#8
              movs      dataB1,data
              shr       data,#8
              movs      dataR2,data

              add       Data_Address,#4                            'Read the next address word 

              rdword    data2,Data_Address                      'take 2 bytes  in differents variables for that word   
              movs      dataG2,data2
              shr       data2,#8
              movs      dataB2,data2

              add       Data_Address,#2         ' This is UNRECOGNIZED why ??      ' Add  two to read the next long             
              '
              ' here some process
              '
              rdlong    data,Data_Address                         
              movs      dataR1,data



At the end of the code I've in the dataR1 variable the value of dataG1 variable, so seems to be that the last add for address is unrecognized. Why ??

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Regards.

Alberto.

Comments

  • KyeKye Posts: 2,200
    edited 2009-04-18 23:13
    Where are you reading the data from???

    If its from a var section then you cannot assume the compilier put everything in the order you defined it in unless its in an array.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • BTXBTX Posts: 674
    edited 2009-04-18 23:25
    Hi Kye
    My data come from a spin code & it is an array, I pass the data through par register
    This is:
    var
    '
       long cog
       
    PUB Start(Adrr) : Success  
    
       Stop
       Success :=  (Cog := cognew(@Process, Adrr) + 1) ' 
    
    PUB Stop
    {{Stop toggling process, if any.}}
    
      if Cog
        cogstop(Cog~ - 1)
    
    dat
            org
    Process
                  mov       t2,outs                           ' P0,1,2,3,4,5 as outs( )
                  mov       dira,t2
    
                  mov       t3,OE          wz                 '          OE Pin          
                  muxz      outa,t3                           '          Set OE Pin LOW
    
    
                  mov       t1,par                            ' Get the dir
                  mov       Data_Address,t1                   ' 
    
    '------------------------------------------------------------------------------------------------------------------------------
                  rdlong    data,Data_Address                         ' 
                  movs      dataR1,data
                  shr       data,#8
                  movs      dataG1,data
                  shr       data,#8
                  movs      dataB1,data
                  shr       data,#8
                  movs      dataR2,data
                  add       Data_Address,#4                             ' 
                  rdlong    data,Data_Address                         ' 
                  movs      dataG2,data
                  shr       data,#8
                  movs      dataB2,data
    
                  add       Data_Address,#2                             ' Here is the problem
    
                  rdlong    data,Data_Address                         ' 
                  movs      dataR1,data
    
    



    Is it clear now ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Regards.

    Alberto.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-04-19 00:00
    Alberto,

    A rdlong requires an address on a long boundary. After adding two to the address, this condition no longer holds, and the address that's used is truncated to a multiple of four, which was the value extant before adding two. Also, make sure that the address passed to PAR is on a long boundary, too, since the last two bits of PAR are always zero.

    Finally, when you use a movs, nine bits get written, not eight. So, in your program, the lsb of the next higher byte in your long value will get written as the msb of the source field.

    -Phil

    Post Edited (Phil Pilgrim (PhiPi)) : 4/19/2009 12:07:00 AM GMT
  • BTXBTX Posts: 674
    edited 2009-04-19 00:17
    Hi Phil. Thanks for your answer.
    I'm not sure if I understood what you mean, but so, How to get six bytes of data ??? faster.
    I've critical speed for this code, I used six rdbyte before, incrementing the address in one by one, and it works fine, but, due the speed limitation of the code, I thinked to use one read with a long, and one with a word to get the six bytes, (only two rdxxxx instructions instead six rdbyte).
    Do you understand what I mean ?

    movs instructions seems not to give me problems, since I use only six bits of each variable.

    I passed the address to PAR register from spin, from a byte variable, is that bad ??

    byte Data_address[noparse][[/noparse]384]
    Then I call the asm with:
    driver.start(@Data_address)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Regards.

    Alberto.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-04-19 00:22
    Last things first:
    BTX said...
    I passed the address to PAR register from spin, from a byte variable, is that bad ??
    It can be, if the byte variable is not long-aligned. (But if it's your only variable, it will be. The rule is this: longs are allocated first, in order of appearance, then words, then bytes.)

    If you only need to read two bytes after the first rdlong, increment the address by four, then do a rdword.

    -Phil
  • BTXBTX Posts: 674
    edited 2009-04-19 00:46
    Correct Phil.
    That's what I did before, but, after those two reads (one rlong and one rdword) my code loops and read again, so when I add the next "add" instrucion for the next cycle, appears my problem. Like I need to add two instead four to get the sixth byte.
    Something like this:


    mov       t1,par                            '
                  mov       Data_Address,t1                   ' 
    
                  mov       t4,#64                            ' 
    loop64        ' 
    '------------------------------------------------------------------------------------------------------------------------------
                  rdlong    data,Data_Address                         ' 
                  movs      dataR1,data
                  shr       data,#8
                  movs      dataG1,data
                  shr       data,#8
                  movs      dataB1,data
                  shr       data,#8
                  movs      dataR2,data
    
                  add       Data_Address,#4                             ' 
                  
                  rdword    data,Data_Address                         ' 
                  movs      dataG2,data
                  shr       data,#8
                  movs      dataB2,data
    
                  add       Data_Address,#2                             '  PROBLEM
    '------------------------------------------------------------------------------------------------------------------------------
                  '*************************************************************************
                  ' Here some process with the six bytes 
                  '*************************************************************************
    
                  djnz      t4,#loop64                   ' Lupeo hasta que t4 sea cero.
    
    



    This obviously wont work, but I need to add 2 instead 4 for the next loop in PROBLEM comment, if not, in the next loop I lose two bytes of data.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Regards.

    Alberto.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-04-19 00:56
    You could unroll your loop a bit:

    rdlong
    add 4
    movs R1,G1,B1,R2
    rdlong
    add 4
    movs G2,B2
    CALL process
    movs R1,G1
    rdlong
    add 4
    movs B1,R2,G2,B2
    CALL process
    loop

    Or, you could just use rdwords.

    -Phil
  • BTXBTX Posts: 674
    edited 2009-04-19 01:12
    Thank so much Phill. Good idea.
    I'll try that, and then I'll post the news.

    I'm also very worried, because what I'm trying to do is PWM by software, I saw a PIC working doing this, without problems, and I can see now that my prop is getting out of speed to do the same, although using more cogs for that, I'll plain to post the full code then, I've just comment it in English.
    The PIC I saw is a PIC18F97J60 and also he is reading UDP by ethernet, and doing the PWM by software plus sending the data by SPI to some led module of 256 RGB pixeles, I can't believe this, but I saw it.

    Now I can't get the PWM working fine and fast with my prop, I should think that is my fault programming the prop.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Regards.

    Alberto.
  • WNedWNed Posts: 157
    edited 2009-04-19 02:30
    Here's a link to a PWM object in the Object Exchange: http://obex.parallax.com/objects/216/
    Looking at the code may give you some ideas, or maybe it will do what you want.

    Ned

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "They may have computers, and other weapons of mass destruction." - Janet Reno
  • BTXBTX Posts: 674
    edited 2009-04-19 03:22
    Hi Ned.
    Thanks so much for your suggest, but it is not what I'm trying to do.

    I've tried what Phil suggest for solution the last problem and work (not at all), although the poor thing is that I've continue having a very slow response.
    I need to speed up my code too much, although I though that is not possible, so maybe I need a new idea of how to do my task.

    What I'm trying to do is: (I hope explain it more clear).

    I've a led screen module that is 16*8 RGB pixeles, that module have only one clk input, latch input, and OE input. Plus two R inputs, two G inputs, and two B inputs, some of them for the upper side of the module, and some for the down side of the module,
    So you need to charge the data for the 128 pixeles at once. Up and down sides, that is 6 bits clk them and latch.
    But also, to get the things more complicated, the module has not PWM incorporate inside (Leds are controlled like on-off), so you need to charge the data in the module and simulate a PWM of that data in real time.
    How to do that ??, this is the big question.
    I did two loops, one 255 counting for PWM (256 gray scale), and one loop more of 64 counting for charge the data inside the last one. This data is obtained comparing the original data to perform a 6bit special data for the module, Depending the original data value and comparing it with the 255 counter value, you choose the bit in on state or in of state.
    Difficult to understand no ??
    Here's a link of somebody trying to do the same as me, with the same led module, without luck too. (Like his language is English, maybe he explain better than me )

    www.electro-tech-online.com/micro-controllers/84793-want-learn-about-pwm-spi-type-rgb-led-display.html

    Although I saw it working with a PIC (I commented before).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Regards.

    Alberto.
  • BTXBTX Posts: 674
    edited 2009-04-19 05:07
    Here is my actual working code.
    It is controlling the upper side of one module, and the speed is poor.
    Later I need to controll two full modules, upper and down part of each.
    Obviously my method is not usefull.
    Any ideas ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Regards.

    Alberto.
  • BTXBTX Posts: 674
    edited 2009-04-20 00:52
    Hi.
    Here is my final code working fine...
    It controlls a couple of DI-P20F1 module for LED screens made by Dicolor or sAbsen (China).
    The modules have 16x8 RGB pixeles each. And the poor is that the led controllers inside their boards, don't have PWM control.

    This code takes 768 bytes of rgb data enough for two modules, realize a pwm with that data, and send it to the modules.
    Although it is working fine, I wasted SIX cogs for this task (What seems to be too much) plus the spin cog.
    The code is so critical, that you can't add any intruction into the loop64 loop, also, it is optimized for sincronizing all cogs for a correct task.

    IF SOMEBODY can change my idea of how to do it, could be great, I'm not a good programmer, and after too much work and efforce, it is all the best I get.
    Although when you see the code at first look, you could think that is pretty easy, if you look very close, you'll find two nested loops, of 255 and 128 what do the task to waste many clock cycles and consecuently a low final speed.

    Could be great if any of the "big heads" in this forum, could give me a reasonable idea, of how to do it in a better & efficient way.
    Don't be surprise if this broke your head. smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Regards.

    Alberto.
Sign In or Register to comment.