PDA

View Full Version : pasm driving me crazy.



mctrivia
01-22-2009, 02:49 PM
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[25..16]~~
repeat
repeat ubVb from 0 to 13
outa[25..22]:=ubVb
Multi:=1<<ubVb
repeat ubVa from 0 to 59
if Long[@ulDisplay][ubVa]&Multi
outa[21..16]:=ubVa
else
outa[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

Ale
01-22-2009, 04:37 PM
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,1 35135613
long 562356253,32562356,23562356,1352357,36824687,24682 468

heater
01-22-2009, 08:17 PM
"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 :)

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.

Kye
01-22-2009, 11:17 PM
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,

mctrivia
01-23-2009, 11:41 AM
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[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[@ulDisplay][ubA]^=(1<<ubB)

PUB spinDisplay
dira[25..16]~~
repeat
repeat ubVb from 0 to 13
outa[25..22]:=ubVb
Multi:=1<<ubVb
repeat ubVa from 0 to 59
if Long[@ulDisplay][ubVa]&Multi
outa[21..16]:=ubVa
else
outa[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[@ulDisplay][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.

mctrivia
01-23-2009, 12:56 PM
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?

mctrivia
01-23-2009, 12:58 PM
sorry i ment outer loop

mctrivia
01-23-2009, 01:13 PM
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.

Kye
01-23-2009, 01:24 PM
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,

mctrivia
01-23-2009, 01:40 PM
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. Swieter
01-23-2009, 07:13 PM
Kye said...

Now, how do these pixles stay lit?



Persistence of vision.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com (http://www.brilldea.com) - Prop Blade, LED Painter, RGB LEDs, uOLED-IOC, eProto for SunSPOT, BitScope
www.tdswieter.com (http://www.tdswieter.com)

Kye
01-23-2009, 11:01 PM
Heh, I didn't think it was that type of a display...

Okay, good luck then with your project.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,

Paul Baker
01-24-2009, 02:53 PM
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 (mailto:pbaker@parallax.com)


Post Edited (Paul Baker) : 1/24/2009 8:38:50 AM GMT

mctrivia
01-24-2009, 03:55 PM
right. this is a standard pixel grid

Timothy D. Swieter
01-28-2009, 05:35 PM
Yikes - lot of wires there on the prototype board!

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com (http://www.brilldea.com) - Prop Blade, LED Painter, RGB LEDs, uOLED-IOC, eProto for SunSPOT, BitScope
www.tdswieter.com (http://www.tdswieter.com)

mctrivia
01-31-2009, 09:45 AM
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