transleting code to make it faster
nicolad76
Posts: 164
Hi!!! Finally I have been able to write my first SPIN code ever. It is a driver for a module that drives a display.
My driver is entarely in SPIN code (I have never written ASM) soit is very slow....at 80 Mhz it sends out 60.000 byte in 7 seconds....I would say it is not enough considering that the module accepts 10MB/s.
I think the only way to get better performance is to rewrite, at least, the procedure sending the data to the module...here it comes the problem..I have a lot of questions
Let's start from the code I wrote...part of it...
CON
· _clkmode = xtal1 + pll16x
· _xinfreq = 5_000_000
· Input········ = %0·· '' define Input value
· Output······· = %1·· '' define Output value
·
· H_NRST······· = 10·· '' Pin for Reset (module reset)
· H_WUP········ = 11·· '' Pin for module wake-up
· H_CD········· = 12·· '' Command/Data selector
· H_DS········· = 13·· '' Device selector (module acquires data on falling edge of H_DS)
· H_RW········· = 14·· '' Read/Write selector pin
· H_ACK········ = 15·· '' Ack pin
·
· H_DMSB······· = 16·· '' MSB pin for data byte
· H_DLSB······· = 23·· '' LSB pin for data byte
· H_RW_Read····· = %1· '' when H_RW is HIGH MODULE is in reading mode (host write)
· H_RW_Write···· = %0· '' when H_RW id LOW· MODULE is in writing mode (host reads)
· H_CD_Data····· = %0· '' Host sends data
· H_CD_Command·· = %1· '' Host sends command
[noparse][[/noparse]...]
PUB Write (type, data)
· '' Set H_RW as LOW
·· DIRA[noparse][[/noparse]H_RW]:=Output
·· DIRA[noparse][[/noparse]H_CD]:=Output
·· DIRA[noparse][[/noparse]H_DS]:=Output
·· DIRA[noparse][[/noparse]H_ACK]:=Input
·· OUTA[noparse][[/noparse]H_DS]:= %1································ '' H_DS is data select
·· OUTA[noparse][[/noparse]H_RW]:= H_RW_Write
·· if (type==TYPE_Command)
······· OUTA[noparse][[/noparse]H_CD]:= H_CD_Command····
·· else
······· OUTA[noparse][[/noparse]H_CD]:= H_CD_Data
······
·······
·· '' SET Data
··
·· DIRA[noparse][[/noparse]H_DMSB..H_DLSB]:=%11111111
·· OUTA[noparse][[/noparse]H_DMSB..H_DLSB]:= data
··
·· OUTA[noparse][[/noparse]H_DS]:=%0·································· '' module gets data on
··················································· '' falling edge of H_DS
·· repeat while INA[noparse][[/noparse]H_ACK]==%00000001·············· '' wait for ack
··
·· OUTA[noparse][[/noparse]H_DS]:=%1·································· '' set H_DS HIGH
There is no much synch with the module in this function since code runs slowly enough for the module to ack correctly. (If I remove repeat while INA[noparse][[/noparse]H_ACK]==%00000001 it still works!!!).
Write function is called inside a loop and it sends 60000 byte (one vidoe·page size for the display).
I would like to turn that WRITE function into ASM hoping it gets faster.
Can you guys give me good advice on how to proceed?
I'll start with some question.
While Iin SPIN I can act on each single PIN at the time, can I do the same in ASM?
when I write, for example,·
·········································· move dira, $01
Am I setting pin1 for output...and the others for input???
and if I do
·········································· move dira, $01
·········································· move dira, $02
after the second·"move", pin1 is still output? I understand $02=%00000010 so·pin1=input and pin2=output...
is it correct?
Thanks for some help [noparse]:)[/noparse]
Nicola
My driver is entarely in SPIN code (I have never written ASM) soit is very slow....at 80 Mhz it sends out 60.000 byte in 7 seconds....I would say it is not enough considering that the module accepts 10MB/s.
I think the only way to get better performance is to rewrite, at least, the procedure sending the data to the module...here it comes the problem..I have a lot of questions
Let's start from the code I wrote...part of it...
CON
· _clkmode = xtal1 + pll16x
· _xinfreq = 5_000_000
· Input········ = %0·· '' define Input value
· Output······· = %1·· '' define Output value
·
· H_NRST······· = 10·· '' Pin for Reset (module reset)
· H_WUP········ = 11·· '' Pin for module wake-up
· H_CD········· = 12·· '' Command/Data selector
· H_DS········· = 13·· '' Device selector (module acquires data on falling edge of H_DS)
· H_RW········· = 14·· '' Read/Write selector pin
· H_ACK········ = 15·· '' Ack pin
·
· H_DMSB······· = 16·· '' MSB pin for data byte
· H_DLSB······· = 23·· '' LSB pin for data byte
· H_RW_Read····· = %1· '' when H_RW is HIGH MODULE is in reading mode (host write)
· H_RW_Write···· = %0· '' when H_RW id LOW· MODULE is in writing mode (host reads)
· H_CD_Data····· = %0· '' Host sends data
· H_CD_Command·· = %1· '' Host sends command
[noparse][[/noparse]...]
PUB Write (type, data)
· '' Set H_RW as LOW
·· DIRA[noparse][[/noparse]H_RW]:=Output
·· DIRA[noparse][[/noparse]H_CD]:=Output
·· DIRA[noparse][[/noparse]H_DS]:=Output
·· DIRA[noparse][[/noparse]H_ACK]:=Input
·· OUTA[noparse][[/noparse]H_DS]:= %1································ '' H_DS is data select
·· OUTA[noparse][[/noparse]H_RW]:= H_RW_Write
·· if (type==TYPE_Command)
······· OUTA[noparse][[/noparse]H_CD]:= H_CD_Command····
·· else
······· OUTA[noparse][[/noparse]H_CD]:= H_CD_Data
······
·······
·· '' SET Data
··
·· DIRA[noparse][[/noparse]H_DMSB..H_DLSB]:=%11111111
·· OUTA[noparse][[/noparse]H_DMSB..H_DLSB]:= data
··
·· OUTA[noparse][[/noparse]H_DS]:=%0·································· '' module gets data on
··················································· '' falling edge of H_DS
·· repeat while INA[noparse][[/noparse]H_ACK]==%00000001·············· '' wait for ack
··
·· OUTA[noparse][[/noparse]H_DS]:=%1·································· '' set H_DS HIGH
There is no much synch with the module in this function since code runs slowly enough for the module to ack correctly. (If I remove repeat while INA[noparse][[/noparse]H_ACK]==%00000001 it still works!!!).
Write function is called inside a loop and it sends 60000 byte (one vidoe·page size for the display).
I would like to turn that WRITE function into ASM hoping it gets faster.
Can you guys give me good advice on how to proceed?
I'll start with some question.
While Iin SPIN I can act on each single PIN at the time, can I do the same in ASM?
when I write, for example,·
·········································· move dira, $01
Am I setting pin1 for output...and the others for input???
and if I do
·········································· move dira, $01
·········································· move dira, $02
after the second·"move", pin1 is still output? I understand $02=%00000010 so·pin1=input and pin2=output...
is it correct?
Thanks for some help [noparse]:)[/noparse]
Nicola
Comments
DIRA[noparse][[/noparse]H_RW]:=Output
The equivalent PASM could be ...
Thanks!!!!!
Nicola
DAT
org 0
writeCMDASM
or DIRA,PinConfigOutput '' set H_RW, H_DS, H_CD as output
and DIRA,PinConfigAck '' set H_ACK as input
and DIRA,DataBitDirection '' Set DatBits [noparse][[/noparse]16..23] as output
or OUTA,PinValueStartH '' Set H_CD, H_DS HIGH
and OUTA,PinValueStartL '' Set H_RW low (write)
:loop
or OUTA, H_DS_HIGH ''set H_DS high
mov DataTemp,DataBitSampleData '' move sample data into DataTemp
rol DataTemp,#16 '' roll 16 on the left to move toward the data bit [noparse][[/noparse]16..23]
and OUTA, DataTemp '' set out put
and OUTA, H_DS_LOW '' and set H_DS low so that module reads
waitpeq 0, 15 '' wait ack
or OUTA, H_DS_HIGH '' set H_DS high
djnz count, #:loop '' loop
PinConfigOutput long %0000_0000_0000_0000_0111_0000_0000_0000
PinConfigAck long %1111_1111_1111_1111_0111_1111_1111_1111
PinValueStartH long %0000_0000_0000_0000_0011_0000_0000_0000
PinValueStartL long %1111_1111_1111_1111_1011_1111_1111_1111
DataBitDirection long %0000_0000_1111_1111_0000_0000_0000_0000
DataBitSampleData byte %1001_0011
DataTemp long $FFFFFFFF
H_DS_LOW long %1111_1111_1111_1111_1101_1111_1111_1111
H_DS_HIGH long %0000_0000_0000_0000_0010_0000_0000_0000
count long 60000
only very small answers or questions·to your code question, perhaps helpful (I do not understand your code completely):
Do you allready know the debugger for assembler pasd? http://forums.parallax.com/showpost.php?p=0
waitpeq 0, 15 '' wait ack············································································--- Ist there·no # needed?
mov DataTemp,DataBitSampleData '' move sample data into DataTemp·············· --- Do you want to use rdlong (later)??
rol DataTemp,#16 '' roll 16 on the left to move toward the data bit [noparse][[/noparse]16..23]
and OUTA, DataTemp '' set out put·····························································
Does this set only the right bits?
Best luck
Christof
I am going to download PASD...it seems cool....
My code could be really though since it is my forst attempt to write ASM so I still have ne "brain" fo rit [noparse]:)[/noparse]...probably I am missing some # here and there and timing is still an optional for me... I just wanted to push 60000 bytes (all the same patern) to the module just to learn...than I will modify to suit my application...
I'll ss what I can get using PASD
Thanks for the graet tip!!!
Graham
I just tried to save as many instructions as possible to make sure the "write routine" runs fast enough.
I went through deSilva's Bible so far and if you have any other great guide you can suggest, I would appreciate it.
I started using PASM and I could see that...yhep...I worte a lot of bad bad bad things [noparse]:)[/noparse]
THX!!!!