pasm driving me crazy.
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:
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:
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
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
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▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
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,
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]:=$3Fthis 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 496Timing 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.
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?
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,
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.
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
Okay, good luck then with your project.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Post Edited (Paul Baker) : 1/24/2009 8:38:50 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, uOLED-IOC, eProto for SunSPOT, BitScope
www.tdswieter.com