Help with assembly language OUTA bit order
mynet43
Posts: 644
I have a display screen routine that works fine in spin. I'm trying to convert parts of it to assembly language to increase the speed.
Part of the current code looks something like this:
This all works, and clears the screen to the selected color. But it's not fast enough.
My question has only to do with the outa[D15..D0] command used in WriteCmd and WriteData. Note that D15 is defined as pin 8 and D0 as pin 23, so the display pin order are opposite the propeller pin order.
The outa[D15..D0] automatically puts the bits in the right order needed by the display.
My question is: how do I do this outa[D15..D0] in assembly language, and still keep the bits in the right order? In other words, how do I code WriteCmd and WriteData in assembly language? I think I've got the rest of it figured out.
Thank you for your help.
Jim
Part of the current code looks something like this:
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 HorizontalMax = 800 VerticalMax = 480 HorizontalPulseWidth = 1 HorizontalFrontPorch = 45 HorizontalBackPorch = 210 VerticalPulseWidth = 1 VerticalFrontPorch = 10 VerticalBackPorch = 34 ' PIN ASSIGNMENT PWM = 6 RST = 7 D15 = 8 D0 = 23 RD_ = 24 WR_ = 25 RS = 26 CS = 27 DAT SoftReset long $01 ' Software reset DispOn long $29 ' Turn display on ColumnCmd long $2A ' Column start PageCmd long $2B ' Page start MemStart long $2C ' Set to start at beginning of memory PixelFormat long $3A ' Set Pixel Format SetPanelMode long $B0 ' Set Panel Mode and Resolution SetHPeriod long $B4 ' Horizontal Period SetVPeriod long $B6 ' Vertical Period PWM_Conf long $BE ' Configuration for PWM PLLStart long $E0 ' Start PLL SetPLLMN long $E2 ' Set M and N values SetPCLK long $E6 ' Set PCLK DataInterface long $F0 ' Set Pixel Data Interface PRI ClearScreen | counter, x, y SetArea(0, 0, HorizontalMax-1, VerticalMax-1) WriteCmd(MemStart) ' Start at beginning of memory outa[CS]~ repeat y from 0 to VerticalMax-1 ' Go down repeat x from 0 to HorizontalMax-1 ' Go across WriteData(BackgroundColor) outa[CS]~~ PRI WriteCmd(cmd) outa[RS]~ outa[D15..D0] := cmd outa[CS]~ outa[WR_]~ outa[WR_]~~ outa[CS]~~ PRI WriteData(data) outa[RS]~~ outa[D15..D0] := data outa[WR_]~ outa[WR_]~~
This all works, and clears the screen to the selected color. But it's not fast enough.
My question has only to do with the outa[D15..D0] command used in WriteCmd and WriteData. Note that D15 is defined as pin 8 and D0 as pin 23, so the display pin order are opposite the propeller pin order.
The outa[D15..D0] automatically puts the bits in the right order needed by the display.
My question is: how do I do this outa[D15..D0] in assembly language, and still keep the bits in the right order? In other words, how do I code WriteCmd and WriteData in assembly language? I think I've got the rest of it figured out.
Thank you for your help.
Jim
Comments
Yes, it's really a 16 bit bus. The commands are 8-bit commands. The color data are sent as 16-bit RGB. (5-red, 6-green, 5-blue). It works fine. The display is a 7" touchscreen I got off eBay with a resolution of 800 x 480. It uses the SSD1963 driver chip. Right now I'm running from a prop proto board. I finally got the driver code working. I need to speed it up.
Now if I can just get my head around that bit order.
I seem to be getting conflicting answers. Some say the bits are in the right order, some say they need to be reversed.
I'll read them all over again carefully and see if I can pull it off.
Thanks everyone for the great support!
Jim
Thanks for the info on the rev command. I've never used it and the description isn't too easy to understand.
What you said all makes sense. I think I'll try it this way.
Thanks!
Jim
You pack the cmd byte and data into a long that is put into par -- a non-zero value causes the code to take off.
Thanks for the code, I appreciate it.
I've been doing the same thing at the same time.
I'll compare what I have with yours to see if I can catch some errors or do it better than I am now.
I'll post mine when I finish.
Thanks again,
Jim
Here's an update of where I'm at now. I'm trying to write a driver for a 7" touchscreen that uses the SSD1963 control chip. So far it works great in spin, but slow. I'm having trouble getting the assembly language routines to work.
I received some great code from JonnyMac and Mike Green. The assembly code I was writing was quite similar to JonnyMac's, so I added a couple of changes he provided and the reverse command code from Mike.
Right now I'm focusing on the _Write_Data routine in the assembly language section. I've stared at it for a long time and it appears identical in function to the spin code for the same function. But it doesn't work.
I've added debug code, to be able to print out values from the assembly language routines. I've displayed the parameter data passed, the masks used, etc. I've even tried adding time delays between the assembly instructions to make it slower, like spin. All the debug data looks right that I get from the assembly routines.
I've written the main program so it's easy to switch from the spin code to assembly code that does the same function. When I run the program in spin only mode, it works perfectly and clears the screen to many different colors.
When I switch to using the assembly language _Write_Data routine, and leave everything else in spin, it runs fine, but it doesn't display any color on the screen.
It's frustrating because it's very fast in the assembly routines, but it doesn't quite work.
I've attached the source file for the code I'm testing.
Would someone please take a look at the code to see if you can spot my mistakes in the _Write_Data implementation in the assembly code? See lines 132 and 133 in the spin code. All I have to do is switch these and one works, the other doesn't. They're supposed to be identical functions.
Thank you for your help and support.
Jim