Shop OBEX P1 Docs P2 Docs Learn Events
pasm driving me crazy. — Parallax Forums

pasm driving me crazy.

mctriviamctrivia Posts: 3,772
edited 2009-01-31 01:45 in Propeller 1
it has taken me a bit to get back into the grove of thinking in assembly but I am pretty sure I got all my # in the right place and all my other silly errors fixed.

I have built a 60x14 led grid and programed it in spin successfully using:
PUB spinDisplay
  dira[noparse][[/noparse]25..16]~~
  repeat
    repeat ubVb from 0 to 13
      outa[noparse][[/noparse]25..22]:=ubVb
      Multi:=1<<ubVb
      repeat ubVa from 0 to 59
        if Long[noparse][[/noparse]@ulDisplay][noparse][[/noparse]ubVa]&Multi
          outa[noparse][[/noparse]21..16]:=ubVa
        else
          outa[noparse][[/noparse]21..16]:=$3F 




and get an output like this
100101001010101010101001...
010101010101001010101010...
101010100101000101001010...
...
(ulDisplay contains random on off states)

this is to slow and causes it to blink. I switched to PASM with:
DAT
              org       0
               
              'dira:=$03FF0000(4 cycles)
Display       mov       dira,PINSDIR            'Set pins to output

              'set X pointer to last column+1(8 cycles)
:main         mov       ulX,#60                 'set to last column+1
              mov       ptrToX,ptrToDisplay     'set ptr to point to x value in ulDisplay

              'move X pointer one column left(8 cycles)
:outer        sub       ulX,#1                  'set to previous column
              sub       ptrToX,#1               'set ptr to point to x value in ulDisplay

              'read column X fromDisplay(4 cycles)
              rdlong    ulColumn,ptrToX         'Read column
              
              'set Y pointer to last row+1(8 cycles)
              mov       ulY,#14                 'Set to last row+1
              mov       ulMask,MASKSTART        'set to %1 0000000 0000000

              'move Y pointer one row up(8 cycles)
:inner        sub       ulY,#1                  'set to above pixel
              shr       ulMask,#1               'shift mask bit to match requested pixel

              'See if pixel is on(16 if off,12 if on)
              mov       temp,ulColumn           'Copy ulColumn so data can be re used
              and       temp,ulMask             'Clear all bits but bit for this pixel
              tjnz      temp,#:turnon           'if pixel is on move to on routine

              'Turn LED off(20 cycles) 
              nop                               '/  wait time to  \
              nop                               '|match on routine|
              nop                               '\     timing     /
              mov       outa,LEDOFF             'turn led off
              jmp       #:continue              'ketch back up to routine

              'Turn LED on(24 cycles)
:turnon       mov       temp,ulY                'Copy current Y value
              shl       temp,#6                 'Shift Y to upper half of 10 bit address
              or        temp,ulX                'Add current X value
              shl       temp,#16                'Shift to match output pins
              mov       outa,temp               'turn led on
              nop                               'wait time to match off routine timing

              'do next led in column or keep on to match 48 cycle loop(4 if not done)
:continue     tjnz      ulY,#:inner             'if not all leds in column done do inner over again      
              mov       temp,#2                 'setup to run through wait loop twice
:wait         sub       temp,#1                 'subtract loop counter
              nop                               'waist 4 cycles
              tjnz      temp,#:wait             'check if gone through apropriate number of times
              mov       outa,LEDOFF             'finally it has been 48 cycles turn led off
              
              'do next column or start over
              tjnz      ulX,#:outer             'if display not done do column to left
              jmp       #:main                  'display done start over
                          

                  

'Locale Time Value
ulX           long      0
ulY           long      0
ulColumn      long      0
ulMask        long      0

ptrToDisplay  long      0
ptrToX        long      0
temp          long      0 

'constants                        
LEDOFF        long      $003F0000
PINSDIR       long      $03FF0000
MASKSTART     long      $4000
              fit       496    



I changed the scan order to go backwards and for speed reasons. now my output is

11110000111100001111000011110000000000001111....
00001111000000001111000000001111000011110000...
00000000111111110000111111111111000000001111...
...
(ulDisplay is still random but output show every block of 4 horizontally being identical)

pretty sure my error has something to do with me reading the values in ulDisplay wrong witch is in hub ram

Comments

  • AleAle Posts: 2,363
    edited 2009-01-22 08:37
    mctrivia:

    The only think I can see is that you are reading the display buffer backwards. I just modified your code (marked with **) a bit, dropped tjnzs and used djnz instead, it decrements and jumps if not zero,so the sub counter,#1 is not needed. That does not change the functionality.
    As I see it outputs 0x003f0000 is not bit is set and the corresponding y and x coords in the right position if the bit is set.

    CON
    
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    PUB start
    
      cognew(@Display, 0) ' led driver
    
    DAT
            org
    
    'dira:=$03FF0000(4 cycles)
    Display       mov       dira,PINSDIR            'Set pins to output
    
                  'set X pointer to last column+1(8 cycles)
    :main         mov       ulX,#60                 'set to last column+1
                  mov       ptrToX,ptrToDisplay     'set ptr to point to x value in ulDisplay
    
                  'move X pointer one column left(8 cycles)
    :outer        '**sub       ulX,#1                  'set to previous column
                  '**sub       ptrToX,#1               'set ptr to point to x value in ulDisplay
    
                  'read column X fromDisplay(4 cycles)
                  rdlong    ulColumn,ptrToX         'Read column
    
                  'set Y pointer to last row+1(8 cycles)
                  mov       ulY,#14                 'Set to last row+1
                  mov       ulMask,MASKSTART        'set to %1 0000000 0000000
    
                  'move Y pointer one row up(8 cycles)
    :inner        '**sub       ulY,#1                  'set to above pixel
                  shr       ulMask,#1               'shift mask bit to match requested pixel
    
                  'See if pixel is on(16 if off,12 if on)
                  mov       temp,ulColumn           'Copy ulColumn so data can be re used
                  and       temp,ulMask   wz '**    'Clear all bits but bit for this pixel
            if_nz jmp       #:turnon           'if pixel is on move to on routine
    
                  'Turn LED off(20 cycles)
                  nop                               '/  wait time to  \
                  nop                               '|match on routine|
                  nop                               '\     timing     /
                  mov       outa,LEDOFF             'turn led off
                  jmp       #:continue              'ketch back up to routine
    
                  'Turn LED on(24 cycles)
    :turnon       mov       temp,ulY                'Copy current Y value
                  shl       temp,#6                 'Shift Y to upper half of 10 bit address
                  or        temp,ulX                'Add current X value
                  shl       temp,#16                'Shift to match output pins
                  mov       outa,temp               'turn led on
                  nop                               'wait time to match off routine timing
    
                  'do next led in column or keep on to match 48 cycle loop(4 if not done)
    :continue     djnz      ulY,#:inner  '**           'if not all leds in column done do inner over again
                  mov       temp,#2                 'setup to run through wait loop twice
    :wait         nop       '**                        'waist 4 cycles
                  nop
                  djnz      temp,#:wait             'check if gone through apropriate number of times
                  mov       outa,LEDOFF             'finally it has been 48 cycles turn led off
    
                  'do next column or start over
                  add       ptrToX,#1               'set ptr to point to x value in ulDisplay
                  djnz      ulX,#:outer             'if display not done do column to left
                  jmp       #:main                  'display done start over
    
    
    
    
    'Locale Time Value
    ulX           long      0
    ulY           long      0
    ulColumn      long      0
    ulMask        long      0
    
    ptrToDisplay  long      @DisplayData+16
    ptrToX        long      0
    temp          long      0
    
    'constants
    LEDOFF        long      $003F0000
    PINSDIR       long      $03FF0000
    MASKSTART     long      $4000
    
    
    DisplayData   long      14546346,23562356,235613561,1356135635,325613561,135135613
                  long      562356253,32562356,23562356,1352357,36824687,24682468
    
    
    
    
  • heaterheater Posts: 3,370
    edited 2009-01-22 12:17
    "pasm driving me crazy" - Yeah it will do that. But don't worry, when you are as crazy as the rest of us here everything will go just fine [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • KyeKye Posts: 2,200
    edited 2009-01-22 15:17
    Hey, I'll do you a favor.

    If you post exactly what you want to do with ALL details and such I'll build the driver for you in asm.

    What i'll need is the:

    timing info

    output pins

    what I'm outputing

    how the display buffer should work

    how you want the driver to work

    etc.

    I'm not really sure exactly what you're doing at all with a giant LED display, and how your connecting to in. Please provide all the information I need and I'll write the driver for you. I'm not going to do any research however, so please provide me with all the details.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-23 03:41
    the display is a grid of pixels driven by 10 io lines. pins 22 to 25 designate the y access. 0 being top 13 being the bottom. pins 16 to 21 designate the x access 0 being the left 59 being the right. if a valid address is put on those 10 io lines then the pixel will light up. if an invalid address like $003F0000(x=64,y=15) is sent then no pixels light up.

    I have a block of 60 longs in hub ram that designates what should be displayed. the first long is for x=0 second is for x=1 ect. the lest significant bit of each long is the state of row y=0, the second least significant is the state of row y=1, ect

    The following spin code works but because it scans at less the 60hz the leds do not look solid they blink
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    
    Dat
    ulDisplay long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    
    Var
      long  stack2[noparse][[/noparse]200]  
      word  Multi
      byte  ubVa,ubVb
      byte  ubA,ubB
    OBJ
      oRR: "RealRandom"  
    
    PUB start
      cognew(spinDisplay,@stack2)      
      
      'put some moving random pixels in ulDisplay to test functionality
      oRR.start
      repeat
        ubA:=(oRR.random&$3F)<#59
        ubB:=(oRR.random&$0F)<#13
        Long[noparse][[/noparse]@ulDisplay][noparse][[/noparse]ubA]^=(1<<ubB) 
    
    PUB spinDisplay
      dira[noparse][[/noparse]25..16]~~
      repeat
        repeat ubVb from 0 to 13
          outa[noparse][[/noparse]25..22]:=ubVb
          Multi:=1<<ubVb
          repeat ubVa from 0 to 59
            if Long[noparse][[/noparse]@ulDisplay][noparse][[/noparse]ubVa]&Multi
              outa[noparse][[/noparse]21..16]:=ubVa
            else
              outa[noparse][[/noparse]21..16]:=$3F 
    
    



    this is my code so far did not implement Ale recomendation because it would scan from x=60 to 1 and y=14 to 1 instead of x=59 to 0 and y=13 to 0

    CON
    
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    
    Dat
    ulDisplay long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    
    Var
      byte  ubA
      byte  ubB 
    
    OBJ
      oRR: "RealRandom"  
    
    PUB start
      ptrToDisplay := @ulDisplay+60
      cognew(@Display,0)      
    
      oRR.start
      repeat
        ubA:=(oRR.random&$3F)<#59
        ubB:=(oRR.random&$0F)<#13
        Long[noparse][[/noparse]@ulDisplay][noparse][[/noparse]ubA]^=(1<<ubB) 
    
    DAT
                  org       0
                   
                  'dira:=$03FF0000(4 cycles)
    Display       mov       dira,PINSDIR            'Set pins to output
    
                  'set X pointer to last column+1(8 cycles)
    :main         mov       ulX,#60                 'set to last column+1
                  mov       ptrToX,ptrToDisplay     'set ptr to point to x value in ulDisplay
    
                  'move X pointer one column left(8 cycles)
    :outer        sub       ulX,#1                  'set to previous column
                  sub       ptrToX,#1               'set ptr to point to x value in ulDisplay
    
                  'read column X fromDisplay(4 cycles)
                  rdlong    ulColumn,ptrToX         'Read column
                  
                  'set Y pointer to last row+1(8 cycles)
                  mov       ulY,#14                 'Set to last row+1
                  mov       ulMask,MASKSTART        'set to %1 0000000 0000000
    
                  'move Y pointer one row up(8 cycles)
    :inner        sub       ulY,#1                  'set to above pixel
                  shr       ulMask,#1               'shift mask bit to match requested pixel
    
                  'See if pixel is on(16 if off,12 if on)
                  mov       temp,ulColumn           'Copy ulColumn so data can be re used
                  and       temp,ulMask             'Clear all bits but bit for this pixel
                  tjnz      temp,#:turnon           'if pixel is on move to on routine
    
                  'Turn LED off(20 cycles) 
                  nop                               '/  wait time to  \
                  nop                               '|match on routine|
                  nop                               '\     timing     /
                  mov       outa,LEDOFF             'turn led off
                  jmp       #:continue              'ketch back up to routine
    
                  'Turn LED on(24 cycles)
    :turnon       mov       temp,ulY                'Copy current Y value
                  shl       temp,#6                 'Shift Y to upper half of 10 bit address
                  or        temp,ulX                'Add current X value
                  shl       temp,#16                'Shift to match output pins
                  mov       outa,temp               'turn led on
                  nop                               'wait time to match off routine timing
    
                  'do next led in column or keep on to match 48 cycle loop(4 if not done)
    :continue     tjnz      ulY,#:inner             'if not all leds in column done do inner over again      
                  mov       temp,#2                 'setup to run through wait loop twice
    :wait         sub       temp,#1                 'subtract loop counter
                  nop                               'waist 4 cycles
                  tjnz      temp,#:wait             'check if gone through apropriate number of times
                  mov       outa,LEDOFF             'finally it has been 48 cycles turn led off
                  
                  'do next column or start over
                  tjnz      ulX,#:outer             'if display not done do column to left
                  jmp       #:main                  'display done start over
                              
    
                      
    
    'Locale Time Value
    ulX           long      0
    ulY           long      0
    ulColumn      long      0
    ulMask        long      0
    
    ptrToDisplay  long      0
    ptrToX        long      0
    temp          long      0 
    
    'constants                        
    LEDOFF        long      $003F0000
    PINSDIR       long      $03FF0000
    MASKSTART     long      $4000
                  fit       496    
    
    



    Timing is not critical. The on time for each lead must be the same so they all look the same brightness. The time taken to scan the entire display must be the same iregardless of percentage of on leds to make screen brightness constant. Actual speed not so important as long as it scans the entire screen at least 60 times/sec to keep they eye from seeing the blink.
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-23 04:56
    just did a test. placed 1,2,3,4,5,6,... in display.

    should get

    01010101010101..
    00110011001100..
    00001111000011..
    00000000111111..

    but instead i get

    000011110000111100001111...
    000000001111111100000000...
    000000000000000011111111...
    000000000000000000000000...

    any idea why it is running the inner loop 4 times with same x value?
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-23 04:58
    sorry i ment outer loop
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-23 05:13
    i figured it out. cog memory may be longs but hub memory is bytes. need to advance initial pointer by 60*4 not just 60 and subtract 4 from pointer each time.
  • KyeKye Posts: 2,200
    edited 2009-01-23 05:24
    Okay,

    So...this is what I understand.

    4 I/O lines for the yAxis

    6 I/O lines for the xAxis

    60 Hz refreshrate

    When a valid address is given on the I/O lines the pixle at that address should light up.


    Now, how do these pixles stay lit? I mean I'm not telling the device to hold the data, do they stay lit up for a second or such? I don't quite understand the display.


    I'll make the driver by making a loop that simply cycles through all x combinationa nd then y combinations and check to see if they should be on or off. BUT!!! how do I turn a pixle on??? I do not understand how the display works. Simply passing putting an address on the I/O lines is all well and good but what happens when the address changes??? Does the pixles then turn off again??? If so the display will never work.

    Please provide details on this. A display makes no sense if it only has addressing. There needs to be some way to hold the LED state until I wish to turn it off again.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-23 05:40
    well i figured out my problem so I have it working now.

    There is no need to have an led stay lit. if you blink an led on and off faster then 60 times per second the human eye will see it as always on even though it is off most of the time. at any given time only 1 of the 840LEDs are actually lit but because each led that should apear on gets lit more then 60 times a second you see lots of leds on.
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-01-23 11:13
    Kye said...

    Now, how do these pixles stay lit?

    Persistence of vision.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, uOLED-IOC, eProto for SunSPOT, BitScope
    www.tdswieter.com
  • KyeKye Posts: 2,200
    edited 2009-01-23 15:01
    Heh, I didn't think it was that type of a display...

    Okay, good luck then with your project.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Paul BakerPaul Baker Posts: 6,351
    edited 2009-01-24 06:53
    Tim isn't talking about those displays that move, he's talking about the fact that the human eye integrates photons detected on a time frame of 1/60th to 1/30th of a second. As long as the LED is illuminated during a portion of that time the eye perceives the LED to illuminated during the entire time frame. It does not matter if the photons came in a burst or evenly distributed over the time what matters is the number of photons in the interval, and this number corresponds with perceived intensity. This is why you see different illumination intensities when you drive an LED with a PWM signal of varying duty cycles, it affects the total number of photons emitted over the integration interval.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker


    Post Edited (Paul Baker) : 1/24/2009 8:38:50 AM GMT
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-24 07:55
    right. this is a standard pixel grid
    1200 x 948 - 397K
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-01-28 09:35
    Yikes - lot of wires there on the prototype board!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, uOLED-IOC, eProto for SunSPOT, BitScope
    www.tdswieter.com
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-31 01:45
    yes there are. I will be making a pcb soon to replace them all. just trying to figure out if i need transistors to increase the brightness
Sign In or Register to comment.