That code came from some C code and is copied pretty much directly. I have no idea how it all works. So what that function does is start up the display in portrait mode and at least then you can get a debug message on the screen.
There are other routines which change from portrait to landscape (and which took a lot of experimenting to get right because the demo code didn't work for that).
So you shouldn't need to change that startup code at all.
I still have a bit of experimenting to do because I'm a bit confused as to what exactly is going on with my display. The different controllers have different register assignments and bit assignments.. I wanted to pick up an ILI for debugging but keep putting it off. Everything should work, once I get the LCD registers fixed. TBH I've only spent an hour playing around with it so far. Had to get the ever present school work done. As a note, if the PropPlug is installed and connected to the pc with no supply to the board, there is a WEAK 3.3 leak. MEANING, the 3.3v supply LED will glow slightly. I was just preparing to get coding/ I'll update this post until I get it working! Oh, here's some Pictures!
I'm using the SSD1289, not an ILI actually. It's the 3.2" so I would guess you have the 2.4" BTW, my wife is soldering the second board!
*edit*
The one thing that would come in handy is to be able to read from the display. Then the program can get the "Screen ID" and automatically choose the correct register layout. The script could be written once and then be re-usable. I've been hard-translating across and it's a bit difficult. I HAD the settings somewhere, now if I could only find them. Currently I get a black screen, I HAD it partially working, now it does nothing. SOOO confused.
Thanks for the C code, I will go through the datasheet for the controller and comment this code. I need to check against what I HAD working? Right now I've completely broken screen writes. It will take some time to figure out exactly what is going on.
Post 301 has the initialization code at the bottom of the CON section for my display. Editing post now.
OK, here's what I've got so far for the initialization:
Still nothing on the display.. I'm going to play with things a bit more and if I still can't get it to work? I'll double check hardware?
*edit again*
OOOOK.. SO. P2 to shorted to GND... It was the regulator screw on back of board shorting p2 trace.. I FINALLY found that puppy, so I will correct and try again!
After I solved the issue with the regulator screw, I have the screen partially working!!!!!! Here's my INIT changes. Seems landscape is still broken, but more on that in a sec.
PUB Draw(x1, y1, x2, y2) | HORIZONTALRAMADDRESSPOS ' sets the pixel to x1,y1 and then fills the next (x2-x1)*(y2-y1) pixels
SelectMemGroup ' set 137 to correct value
ifnot orientation ' landscape mode so swap x and y
result :=x1 ' swap x1 and y1
x1 := y1
y1 := result
result := x2 ' swap x2 and y2
x2 :=y2
y2 := result
'_____________ILI__________________________________________________________
'ILIcmd($0050,x1)
'ILIcmd($0052,y1)
'ILIcmd($0051,x2)
'ILIcmd($0053,y2)
'ILIcmd($0020,x1)
'ILIcmd($0021,y1)
'___________FOR SSD1289__________________________________________________
HORIZONTALRAMADDRESSPOS := x1 + (x2 << 8)
ILIcmd(REG_HORIZONTALRAMADDRESSPOS,HORIZONTALRAMADDRESSPOS)
ILIcmd(REG_VERTICALRAMADDRESSSTART,y1)
ILIcmd(REG_VERTICALRAMADDRESSEND,y2)
ILIcmd(REG_SETGDDRxADDRESSCOUNTER,x1)
ILIcmd(REG_SETGDDRyADDRESSCOUNTER,y1)
Lcd_Write_Com($0022)
The part that I THINK is broken is the LCD orientation method:
if orientation
' for origin top left and portrait mode
ILIcmd($0001,$2B3F) ' $0001,$0100 set SS and SM bit 0001 0100 portrait
ILIcmd($0011,$6070) ' $0003,$1030 set GRAM write direction and BGR=1. $0003 $1030
else
' for origin top right and landscape mode
ILIcmd($0001,$6B3F) ' set SS and SM bit 0001 0000 landscape
ILIcmd($0011,$6838) ' landscape $1028 = original but 1038 is correct - not mirror image
What works so far:
PUB Main | touchtest ' debug value
'term.start( 31, 30, 0, 115200 ) ' for debugging
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
reboot
fat.mountPartition(0) ' mount the sd card
ClearRamdisk ' clear ram disk for pictures not on the desktop
LoadDesktop ' a image 240x320 for the desktop. Load first as there is a ramclear routine that does not delete the first entry
DrawDesktop
deadend
'Broken here
LoadIcons ' load the mask and icons onto the screen
ILISetcursor(0,0) ' cursor for debugging to 0,0
SelectSPIGroup ' selects this group and starts the cog
Touchscreen ' wait for input
Loading icons causes the screen to "freak out" Need to play around a bit more but it's WAY past my bedtime. Maybe in the morning I will script up a quick test picture for full-screen landscape. I think that's the big issue. Not too sure really, seems like a register gets changed incorrectly. A picture is worth a thousand words, so here's to saving space!
*edit* uploading 5 minutes of wierdness to youtube right now and I'll link when done...all I can say is wow, that was strange ;(
The icons are doing a few things - reading back from ram the background pixels, comparing using a mask bitmap, and then sending back new pixels. So lots of things have to work there, but on the other hand it tests lots of things.
I think you have cracked the hard part though.
Do you have a picture editor? I'm using an ancient 1996 version of paint shop pro but it does everything I need. Try grabbing a picture from the internet, resample/resize to 240x320, save as a .bmp file and see if you can change the desktop.
Then save a 320x240 picture and see if that will display landscape.
BTW what time are you going to bed? It is almost my bedtime and you are 9 hours ahead of me. Was this an all-nighter?
This was definitely an all-nighter, and it was WAY worth it. It's 4:45 right now and I'm playing with the calculator. I was looking for references on screen. Seems the touch x input is backwards? There's a lot to debug, I think the screen writes are glitching somewhere. I will go through and slow things down until I find the culprit. It's weird because it works, every once and a while. *After several attempts, it appears if you power-off for a bit and then power on it works on first boot, but not reset?* tinysynth NEVER works. Text works, Calc works, pictures usually crashes. Movie is non existent? checkboxes usually works?? very interesting results, not sure what it means. I will Tripple-tripple check wiring but I think with the screw fixed...
Tried to get the ftp server fixed but no luck. Tried to determine why screen freak is occurring but still no clue. To me it looks like what happens when the LCD write timings are wrong. I'm not sure though since I tried slowing the pasm driver down with no luck. An interesting artifact of testing, when trying to get pixels writing properly, I had to slow things down see code
If I decrease the pause by even 1, it stops working. I THINK it draws all pixels at one location?
*edit*
More puzzling results. Seems like it sometimes loads the mask and fails. Sometimes it loads Photos and fails. Sometimes it loads the Mask and Photos then fails. If I turn off all the icon loads, things seem to work except tiny synth?
Maybe go back a step and test whether you can read and write data from the ram reliably? Try sending data to the ram, then reading it back. Use the propeller internal font and the hex() command for debugging. That was how I found the strange bug caused by me accidentally cutting one of the ram address lines.
Spent some time trying to figure out the RIGHT way to test the ram and what I have so far is
PUB TestRAM | i,n,c
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(string("RAM test"))
Propfont_string(string("Filling RAM"))
Propfont_string(string("May take a few"))
repeat c from 0 to 255
repeat i from 0 to 255
word[@rambuffer][i] := i + ($100*C)
'hex(i,4)
HubToRam(c*255,255)
pause1ms(1000)
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ILISetCursor(0,0)
Propfont_string(string("Read back Ram"))
repeat c from 0 to 255
RAMToHub (c*255,255)
repeat i from 0 to 255
ifnot word[@rambuffer][i] == i + ($100*C)
propfont_string(string("Errors found"))
propfont_string(string("Expected"))
hex(i + ($100*C),4)
propfont_string(string("Received"))
hex(word[@rambuffer][i],4)
pause1ms(100_000)
ILISetCursor(0,0)
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
'errors at
Propfont_string(String("Ramtest done"))
It's currently running, hopefully it should tell me something. Not sure if I'm headed in the right direction.
First error, expected $00FF, received $0000
Next error, expected $01FF, received $0000
and so on?
OOOK. SO... Got the RamTest to pass. Here's the working code!
PUB TestRAM | i,n,c
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(string("RAM test"))
Propfont_string(string("Filling RAM"))
Propfont_string(string("May take a few"))
repeat c from 0 to 255
repeat i from 0 to 255
word[@rambuffer][i] := i + ($100*C)
HubToRam(c*256,256)
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ILISetCursor(0,0)
Propfont_string(string("Read back Ram"))
repeat c from 0 to 255
RAMToHub (c*256,256)
repeat i from 0 to 255
ifnot word[@rambuffer][i] == i + ($100*C)
propfont_string(string("Errors found"))
propfont_string(string("Expected"))
hex(i + ($100*C),4)
propfont_string(string("Received"))
hex(word[@rambuffer][i],4)
pause1ms(100_000)
ILISetCursor(0,0)
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(String("Ramtest done"))
I will check this out a few times. Not sure what to do now?
Trying to write above 256 writes to the screen?
The latest ram test? I think it checks thoroughly? Any thoughts?
PUB TestRAM | i,n,c
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(string("RAM test"))
Propfont_string(string("Filling RAM"))
Propfont_string(string("May take a few"))
'pause1ms(1_0)
Repeat n from 0 to 8
repeat c from 0 to 255
repeat i from 0 to 255
word[@rambuffer][i] := (i + ($100*C)) '- 255
HubToRam((c*256)+n,256)
'pause1ms(10_00)
Propfont_string(string("Done!"))
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ILISetCursor(0,0)
Propfont_string(string("Read back Ram"))
hex(n,1)
pause1ms(5)
repeat c from 0 to 255
RAMToHub ((c*256)+n,256)
repeat i from 0 to 255
ifnot word[@rambuffer][i] == (i + ($100*C)) '- 255
propfont_string(string("Errors found"))
propfont_string(string("Expected"))
hex(i + ($100*C),4) '- 255
propfont_string(string("Received"))
hex(word[@rambuffer][i],4)
pause1ms(100_000)
ILISetCursor(0,0)
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(String("Ramtest done"))
PUB Main | touchtest ' debug value
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
reboot
fat.mountPartition(0) ' mount the sd card
SDToDisplay(string("cat.bmp"))
repeat
So that will test sd to hub, then hub to ramdisk, then ramdisk out to the display.
How about this which tests hub to display, bypassing the external ram. That will test your pixel timings. It should produce a blank textbox on a gray background.
PUB Main | touchtest ' debug value
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
reboot
fat.mountPartition(0) ' mount the sd card
clearscreen(RGBtoWord(212,208,200)) ' background color determined from paintshop
Textboxclear(10,200,120,215) ' clear a text box. height = fontheight+1?
repeat
Ok, bypassing ram seems to work? I've been poking around and still don't get it. Seems LoadBMP is the problem
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i ' load and display a bitmap file
' http://en.wikipedia.org/wiki/BMP_file_format scroll down about 1/3 of the way for the header formats
' get the width, height
' store these as 2 longs at the beginning of the ram file
' the bitmap format starts at the last row and works up so need to reverse the order
' on the ram store a 0x36 byte header - the bitmap header but put in the filename at location 0
' this becomes a rudimentary file system that can be searched to find pictures
propfont_out(".") ' for debugging display something while load in pictures
pause1ms(5_000)
propfont_string(fat.openfile(stringptr,"R"))
'fat.openfile(stringptr,"R")
pause1ms(5_000)
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
w := width * 3 ' this number of bytes per row, and round up to nearest 4 bytes et 327 goes to 328 The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
w +=3 ' add 3 and
w &= %11111111_11111111_11111111_11111100 ' round down
repeat i from 0 to 11 ' add the file name at the beginning of the header
sdbuffer[i] := byte[stringptr][i]
docmd("S",@sdbuffer,RamDiskPointer,$36) ' store header to ram
i := $36 + RamDiskPointer + ((height - 1) * width) ' start + header and on the last row and work back
repeat height
fat.readdata(@sdbuffer,w) ' read in the first row
docmd("F",@sdbuffer,@rambuffer,width)
HubToRam(i,width) ' send to ram
i -= width ' subtract the width, move up the picture
fat.closefile
RamDiskPointer += $36 + (width * height) ' increment the ramdiskpointer for next picture
RamDiskFiles += 1 ' increment number of entries in the ram disk
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i ' load and display a bitmap file
' http://en.wikipedia.org/wiki/BMP_file_format scroll down about 1/3 of the way for the header formats
' get the width, height
' store these as 2 longs at the beginning of the ram file
' the bitmap format starts at the last row and works up so need to reverse the order
' on the ram store a 0x36 byte header - the bitmap header but put in the filename at location 0
' this becomes a rudimentary file system that can be searched to find pictures
'propfont_out(".") ' for debugging display something while load in pictures
'pause1ms(5_000)
'propfont_string(fat.openfile(stringptr,"R"))
fat.openfile(stringptr,"R")
'pause1ms(5_000)
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
w := width * 3 ' this number of bytes per row, and round up to nearest 4 bytes et 327 goes to 328 The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
w +=3 ' add 3 and
w &= %11111111_11111111_11111111_11111100 ' round down
repeat i from 0 to 11 ' add the file name at the beginning of the header
sdbuffer[i] := byte[stringptr][i]
docmd("S",@sdbuffer,RamDiskPointer,$36) ' store header to ram
i := $36 + RamDiskPointer + ((height - 1) * width) ' start + header and on the last row and work back
repeat height
fat.readdata(@sdbuffer,w) ' read in the first row
docmd("F",@sdbuffer,@rambuffer,width)
HubToRam(i,width) ' send to ram !!!!This is where screen freak occurs!
DEADEND
i -= width ' subtract the width, move up the picture
fat.closefile
RamDiskPointer += $36 + (width * height) ' increment the ramdiskpointer for next picture
RamDiskFiles += 1 ' increment number of entries in the ram disk
HubToRam command seems to be the problem. I will play with this more.
Ok, the screen would glitch if you didn't read the correct size of the bitmap file. Then it would try to read something completely different, possibly even a huge number which would cycle through all the ram.
so - can we read the bitmap information correctly?
Try this main loop
PUB Main | touchtest ' debug value
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
reboot
fat.mountPartition(0) ' mount the sd card
ClearRamdisk ' clear ram disk for pictures not on the desktop
SDToDisplay(string("cat.bmp")) ' draw a portrait picture
repeat
and in the loadbmptoramdisk try this
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i ' load and display a bitmap file
' http://en.wikipedia.org/wiki/BMP_file_format scroll down about 1/3 of the way for the header formats
' get the width, height
' store these as 2 longs at the beginning of the ram file
' the bitmap format starts at the last row and works up so need to reverse the order
' on the ram store a 0x36 byte header - the bitmap header but put in the filename at location 0
' this becomes a rudimentary file system that can be searched to find pictures
'propfont_out(".") ' for debugging display something while load in pictures
fat.openfile(stringptr,"R")
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
hex(width,8)
hex(height,8)
repeat
you should get 0x000000F0 as the width and 0x00000140 as the height
If that works see if this prints the filename "cat.bmp"
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i ' load and display a bitmap file
' http://en.wikipedia.org/wiki/BMP_file_format scroll down about 1/3 of the way for the header formats
' get the width, height
' store these as 2 longs at the beginning of the ram file
' the bitmap format starts at the last row and works up so need to reverse the order
' on the ram store a 0x36 byte header - the bitmap header but put in the filename at location 0
' this becomes a rudimentary file system that can be searched to find pictures
'propfont_out(".") ' for debugging display something while load in pictures
fat.openfile(stringptr,"R")
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
w := width * 3 ' this number of bytes per row, and round up to nearest 4 bytes et 327 goes to 328 The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
w +=3 ' add 3 and
w &= %11111111_11111111_11111111_11111100 ' round down
repeat i from 0 to 11 ' add the file name at the beginning of the header
sdbuffer[i] := byte[stringptr][i]
docmd("S",@sdbuffer,RamDiskPointer,$36) ' store header to ram
propfont_string(@sdbuffer)
repeat
and just to double check
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i ' load and display a bitmap file
' http://en.wikipedia.org/wiki/BMP_file_format scroll down about 1/3 of the way for the header formats
' get the width, height
' store these as 2 longs at the beginning of the ram file
' the bitmap format starts at the last row and works up so need to reverse the order
' on the ram store a 0x36 byte header - the bitmap header but put in the filename at location 0
' this becomes a rudimentary file system that can be searched to find pictures
'propfont_out(".") ' for debugging display something while load in pictures
fat.openfile(stringptr,"R")
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
w := width * 3 ' this number of bytes per row, and round up to nearest 4 bytes et 327 goes to 328 The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
w +=3 ' add 3 and
w &= %11111111_11111111_11111111_11111100 ' round down
repeat i from 0 to 11 ' add the file name at the beginning of the header
sdbuffer[i] := byte[stringptr][i]
docmd("S",@sdbuffer,RamDiskPointer,$36) ' store header to ram
i := $36 + RamDiskPointer + ((height - 1) * width) ' start + header and on the last row and work back
hex(i,8)
repeat
If that works, let's see if the data comes back out of the ram
PUB Main | touchtest ' debug value
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
reboot
fat.mountPartition(0) ' mount the sd card
ClearRamdisk ' clear ram disk for pictures not on the desktop
SDToDisplay(string("cat.bmp")) ' draw a portrait picture
and then see if you get back 0xF0 and 0x140
PUB DrawBMP(stringptr,x,y) | rampointer,width,height ' pass the name and the x and y location, searches for this file and if found, displays it
rampointer := FindBMP(stringptr) ' find the file in the list
if rampointer <> -1 ' if a match then draw
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
hex(width,8)
hex(height,8)
repeat
Crashes at
LoadBMPtoRamdisk : HubToRam(i,width)
Need to step through the ASM driver and find where the issue is.
*edited*
I've been playing around and it keeps jumping. I got this working: a few waits seem to help, although things seem to move around? I have quadruple checked the board and I THINK everything is wired okay? Checked ohms across every socket pin and gnd, +3.3v, +5, adjacent, all other socket pins? This is VERY STRANGE! I'm sure it's something simple. *I need to get my wife to finish soldering the 2nd board to build for testing purposes!*
PUB SdToDisplayTEST | touchtest ' debug value
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
reboot
fat.mountPartition(0) ' mount the sd card
SDToDisplay(string("cat.bmp"))
deadend
PUB SDToDisplay(stringptr) ' bitmap from SD to display
Clearscreen(0)
ClearRamDiskExcludeDesktop
LoadBMPtoRamdisk(stringptr)
DrawBMP(stringptr,0,0)
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i ' load and display a bitmap file
' http://en.wikipedia.org/wiki/BMP_file_format scroll down about 1/3 of the way for the header formats
' get the width, height
' store these as 2 longs at the beginning of the ram file
' the bitmap format starts at the last row and works up so need to reverse the order
' on the ram store a 0x36 byte header - the bitmap header but put in the filename at location 0
' this becomes a rudimentary file system that can be searched to find pictures
propfont_out(".") ' for debugging display something while load in pictures
pause1ms(5_000)
propfont_string(fat.openfile(stringptr,"R"))
'fat.openfile(stringptr,"R")
pause1ms(5_000)
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
w := width * 3 ' this number of bytes per row, and round up to nearest 4 bytes et 327 goes to 328 The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
w +=3 ' add 3 and
w &= %11111111_11111111_11111111_11111100 ' round down
repeat i from 0 to 11 ' add the file name at the beginning of the header
sdbuffer[i] := byte[stringptr][i]
docmd("S",@sdbuffer,RamDiskPointer,$36) ' store header to ram
i := $36 + RamDiskPointer + ((height - 1) * width) ' start + header and on the last row and work back
repeat height
fat.readdata(@sdbuffer,w) ' read in the first row
docmd("F",@sdbuffer,@rambuffer,width)
pause1ms(5) 'fixed a glitch?
HubToRam(i,width) ' send to ram
i -= width ' subtract the width, move up the picture
fat.closefile
RamDiskPointer += $36 + (width * height) ' increment the ramdiskpointer for next picture
RamDiskFiles += 1 ' increment number of entries in the ram disk
PUB DrawBMP(stringptr,x,y) | rampointer,width,height ' pass the name and the x and y location, searches for this file and if found, displays it
rampointer := FindBMP(stringptr) ' find the file in the list
if rampointer <> -1 ' if a match then draw
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
Draw(x,y,x+width-1,y+height-1) ' set up the area to draw
'pause1ms(50_000)
RamToDisplay(RamPointer + $36,width*height) ' skip the header and display
result := (width <<16) | (height & $0000FFFF) ' return the width and height combined into a long
Strangely enough, if I comment out all the mask icons, I can get the photo viewer running, and calculator. I think a BETTER ram test needs to be written. What I came up with is pretty crude and probably doesn't catch the error?
*edit*
So, I gotta take a break. Here's what I've been able to figure out so far
PUB Main | touchtest, Error ' debug value
'term.start( 31, 30, 0, 115200 ) ' for debugging
'deadend
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
'testram ''inserted testram JH
Propfont_string(string("Loading SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
reboot
fat.mountPartition(0) ' mount the sd card
pause1ms(5_000)
'-----Test section. Insert testing here
'-----Tested good
' bypassRam
'TestRAM
'SdToDisplayTEST2
'SdToDisplayTEST
'Buttons
'ClearRamdisk ' clear ram disk for pictures not on the desktop
'LoadDesktop ' a image 240x320 for the desktop. Load first as there is a ramclear routine that does not delete the first entry
'DrawDesktop
'LoremPortLand
'-----Tesed bad
'Keyboard
'LoadIcons ' load the mask and icons onto the screen
''
'-----End Test Section
deadend
'ILISetcursor(0,0) ' cursor for debugging to 0,0
'SelectSPIGroup ' selects this group and starts the cog
'Touchscreen ' wait for input
PUB bypassRam | touchtest ' debug value
' start_ram ' start the external ram / display driver in a cog
' Change161(0) ' reset all the 161 counters to zero
' SelectMemGroup ' select group1
' Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
' Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
' pause1ms(1_000)
' SetOrientation(true ) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
' Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
' ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
' reboot
' fat.mountPartition(0) ' mount the sd card
'
' clearscreen(RGBtoWord(212,208,200)) ' background color determined from paintshop
Textboxclear(10,200,120,215) ' clear a text box. height = fontheight+1?
deadend
PUB SdToDisplayTEST2 | touchtest ' debug value
' start_ram ' start the external ram / display driver in a cog
' Change161(0) ' reset all the 161 counters to zero
' SelectMemGroup ' select group1
' Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
' SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
' Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
' Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
' ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
' reboot
' fat.mountPartition(0) ' mount the sd card
ClearRamdisk ' clear ram disk for pictures not on the desktop
SDToDisplay(string("cat.bmp")) ' draw a portrait picture
deadend
'
PUB SdToDisplayTEST | touchtest ' debug value
' start_ram ' start the external ram / display driver in a cog
' Change161(0) ' reset all the 161 counters to zero
' SelectMemGroup ' select group1
'Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
'Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
' SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
' Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
' ifnot( fat.FATEngineStart(_SD_DO, _SD_CLK, _SD_DI, _SD_CS, _SD_WP, _SD_CD, _RTC_DAT, _RTC_CLK, -1))
' reboot
' fat.mountPartition(0) ' mount the sd card
SDToDisplay(string("cat.bmp"))
deadend
PUB TestRAM | i,n,c,yval,xval
' start_ram ' start the external ram / display driver in a cog
' Change161(0) ' reset all the 161 counters to zero
' SelectMemGroup ' select group1
' Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
' SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
' Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(string("RAM test"))
Propfont_string(string("Filling RAM"))
Propfont_string(string("May take a few"))
'pause1ms(1_0)
Repeat n from 1 to 8
repeat c from 0 to 255
repeat i from 0 to 255
word[@rambuffer][i] := (i + ($100*C)) '- 255
HubToRam((c*256)*n,256)
'pause1ms(10_00)
Propfont_string(string("Done!"))
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
ILISetCursor(0,0)
Propfont_string(string("Read back Ram"))
hex(n,1)
'pause1ms(5)
repeat c from 0 to 255
RAMToHub ((c*256)*n,256)
repeat i from 0 to 255
ifnot word[@rambuffer][i] == (i + ($100*C)) '- 255
propfont_string(string("Errors found"))
propfont_string(string("Expected"))
hex(i + ($100*C),4) '- 255
propfont_string(string("Received"))
hex(word[@rambuffer][i],4)
'pause1ms(100_000)
TSWAIT
ILISetCursor(0,0)
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(String("Ramtest done"))
'pub testpixel
'draw(0,0,239,319)
' pause1ms(26_844)
'repeat 76800
' pixel(0)
'pause1ms(26_844)
'deadend
PUB Deadend
repeat
waitcnt(cnt)
PUB TSWAIT |yval, xval
SelectSPIGroup ' talk to the spi touchscreen
repeat
yval := TouchYPercent ' decode yval 0-100%
xval := TouchXPercent ' decode xval 0-100%
if (xval <> 255) and (yval <> 255) ' valid keypress
return
This is hard if you have a different display. On the other hand... checking the people who sold me the last display it appears they have changed the driver chip to the one you are using so I'm going to get some new displays.
If things are not working in pasm, there is a break line
stop jmp #stop ' for debugging
and many times I've added that to code and then gone through with the logic probe to check pins are what they are supposed to be.
Just remember to remove the break afterwards!
Today I sent off the dual display board to be made. Has all the corrections we have been doing plus a few headers for things like the group select and some latch outputs and P0-P15.
I've got some ideas using the dual display eg the synth could be run in two cogs at the same time and then you could send the output of one to the right speaker and the output of the other to the left speaker and play with two hands at the same time. A rudimentary polyphonic synth!
Or you could use one of the more sophisticated synth objects and there is room for more slider controls.
I agree that it is difficult to diagnose with different screens. If you are moving to the SSD1289, this might help a bit. I will be stepping through the PASM and if I can't figure it out I think I have a diagnostic route figured out. What I will probably end up doing is using the display /RD to check LCD registers after error occurs. This should give me some idea what's going on. It will be a few days before I can dig back in. I am excited about the dual screen board since this will make realizing a grovebox much easier. I'm thinking something like this : http://en.wikipedia.org/wiki/Roland_MC-909
*edited*
So, as a side note... If using a ribbon cable to connect screens, you need to put the pin-header on the BOTTOM of the board?
It is strange that you can send things out to the screen like the textbox, but you can't send pictures. That suggests that going through the ram is the problem. But reading back the ram is ok.
Well there is one last bit of code that could explain this behaviour and it is the routine that sends from ram to the display
PUB RamToDisplay(RamAddress,Number) ' send pixels from ram to display
docmd("U",0,RamAddress,Number)
which calls this pasm
' command U
pasmramtodisplay call #get_values ' get hubaddr,ramaddr,len
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
call #businput ' set prop pins 0-15 as inputs so doesn't interfere with the transfer
or outa,maskP18 ' ILI_RS high
andn outa,maskP16 ' memory /rd low
ramtodisplay_loop andn outa,maskP20 ' ILI write low
or outa,maskP20 ' ILI write high
andn outa,maskP19 ' clock 161 low
or outa,maskP19 ' clock 161 high
djnz len,#ramtodisplay_loop
or outa,maskP16 ' memory /rd high
or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs
jmp #init
Also I added a little routine so that when you open a file for reading and it is not there, it displays an error message. Useful as the number of files on the card increases. I also ported it over to Kye's latest SD code. I don't think that is your problem though so no need to change your code if you don't want to yet.
Maybe take that pasm code above and stick some halts through the code and test the pins?
The dual screen has the screens side by side with only short components under the screens. So in one sense you can have a 480x320 display.
Ok, I'm starting over with your new attachment. My wife finished her board *and it looks better than mine* and both have tested the same. I realized the code had become swiss cheese. Now writing to ram is broken? Hopefully the fresh code will help!
Just tried compiling: "Missing SD-MMC_FATEngine.spin"
I'll hunt that down and keep plugging!
*edit* Hmmm, I found something.
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
This order loads, the original crashes at propfont out?
Now runs until load desktop.
*edit again*
Nope, not quite? Started slowing things down and stepping through. Loading mask fails at HUBtoRAM.
The tricky thing is the error keeps moving. It seems to happen in one place, and then it creeps in somewhere else? I'm really confused right now. I'm sure it's something simple.
Right now I'm back to the RAM. Seems problem is in LOAD BMP:
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i
propfont_out("1") ' for debugging display something while load in pictures
pause1ms(50)
fat.openfile(stringptr,"R")
propfont_out("2") ' for debugging display something while load in pictures
pause1ms(50)
OpenFileRead(stringptr)
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
w := width * 3 ' this number of bytes per row, and round up to nearest 4 bytes et 327 goes to 328 The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
w +=3 ' add 3 and
w &= %11111111_11111111_11111111_11111100 ' round down
repeat i from 0 to 11 ' add the file name at the beginning of the header
sdbuffer[i] := byte[stringptr][i]
docmd("S",@sdbuffer,RamDiskPointer,$36) ' store header to ram
i := $36 + RamDiskPointer + ((height - 1) * width) ' start + header and on the last row and work back
propfont_out("3") ' for debugging display something while load in pictures
pause1ms(5_000)
repeat height
fat.readdata(@sdbuffer,w) ' read in the first row
docmd("F",@sdbuffer,@rambuffer,width)
HubToRam(i,width) ' send to ram
i -= width ' subtract the width, move up the picture
pause1ms(5_0)
propfont_out("4") ' for debugging display something while load in pictures
pause1ms(5_0)
fat.closefile
propfont_out("5") ' for debugging display something while load in pictures
pause1ms(5_0)
RamDiskPointer += $36 + (width * height) ' increment the ramdiskpointer for next picture
RamDiskFiles += 1 ' increment number of entries in the ram disk
propfont_out("6") ' for debugging display something while load in pictures
pause1ms(5_0)
*more edit*
I keep taking one step forward, and 2 steps back. Changing the timeouts changes the operation, moves the bug, etc. Seems the screen is writing when the ram is transferring. Need to think more about this. Seems swapping from group 0-1 is the problem. Maybe the extra NAND?!!
HINT HINT. It's GOTTA BE screen write timing or something. I must play around with some registers!!! I have a CRUDE work-around... Re-init the screen after drawing everything?
PUB Main | touchtest ' debug value
start_ram ' start the external ram / display driver in a cog
Change161(0) ' reset all the 161 counters to zero
SelectMemGroup ' select group1
Start_ILI9325 ' start the display. Don't clear screen as this uses ram commands and these might not be working yet
pause1ms(5000)
SetOrientation(true) ' in portrait (true) or landscape mode (false), must be before clearscreen otherwise don't know screensize
Clearscreen(RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
Propfont_string(string("SD")) ' string to send, uses internal prop font so can see something if the SD fails to mount
fat.fatEngineStart( _dopin, _clkpin, _dipin, _cspin, _wppin, _cdpin, _rtcres1, _rtcres2, _rtcres3)
fat.mountPartition(0) ' mount the sd card
ClearRamdisk ' clear ram disk for pictures not on the desktop
LoadDesktop ' a image 240x320 for the desktop. Load first as there is a ramclear routine that does not delete the first entry
DrawDesktop
LoadIcons ' load the mask and icons onto the screen
ILISetcursor(0,0) ' cursor for debugging to 0,0
SsdInit
SelectSPIGroup ' selects this group and starts the cog
Touchscreen ' wait for input
con Debugtimer = 25
PUB LoadBMPtoRamdisk(stringptr) | width,height,w,i ' load and display a bitmap file
' http://en.wikipedia.org/wiki/BMP_file_format scroll down about 1/3 of the way for the header formats
' get the width, height
' store these as 2 longs at the beginning of the ram file
' the bitmap format starts at the last row and works up so need to reverse the order
' on the ram store a 0x36 byte header - the bitmap header but put in the filename at location 0
' this becomes a rudimentary file system that can be searched to find pictures
propfont_out("1") ' for debugging display something while load in pictures
pause1ms(Debugtimer)
fat.openfile(stringptr,"R")
pause1ms(Debugtimer)
propfont_out("2") ' for debugging display something while load in pictures
pause1ms(Debugtimer)
OpenFileRead(stringptr)
fat.readdata(@sdbuffer,$36) ' get the header 0x36 hex bytes
width := sdbuffer[$12] + sdbuffer[$13] << 8 ' only read in two bytes as never will be >64k wide or high
height := sdbuffer[$16] + sdbuffer[$17] << 8
w := width * 3 ' this number of bytes per row, and round up to nearest 4 bytes et 327 goes to 328 The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
w +=3 ' add 3 and
w &= %11111111_11111111_11111111_11111100 ' round down
repeat i from 0 to 11 ' add the file name at the beginning of the header
sdbuffer[i] := byte[stringptr][i]
docmd("S",@sdbuffer,RamDiskPointer,$36) ' store header to ram
i := $36 + RamDiskPointer + ((height - 1) * width) ' start + header and on the last row and work back
pause1ms(Debugtimer)
propfont_out("3") ' for debugging display something while load in pictures
pause1ms(Debugtimer)
repeat height
fat.readdata(@sdbuffer,w) ' read in the first row
docmd("F",@sdbuffer,@rambuffer,width)
HubToRam(i,width) ' send to ram
i -= width ' subtract the width, move up the picture
pause1ms(Debugtimer)
propfont_out("4") ' for debugging display something while load in pictures
pause1ms(Debugtimer)
fat.closefile
pause1ms(Debugtimer)
propfont_out("5") ' for debugging display something while load in pictures
pause1ms(Debugtimer)
RamDiskPointer += $36 + (width * height) ' increment the ramdiskpointer for next picture
RamDiskFiles += 1 ' increment number of entries in the ram disk
pause1ms(Debugtimer)
propfont_out("6") ' for debugging display something while load in pictures
crlf
pause1ms(Debugtimer)
PUB ChangeOrientation(n) ' pass true = portrait or false = landscape, changes global variable orientation in this object
' command $0001
'8.2.4. Driver Output Control (R01h)
'R/W RS D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
'W 1 0 0 0 0 0 SM 0 SS 0 0 0 0 0 0 0 0
'SS: Select the shift direction of outputs from the source driver.
'When SS = 0, the shift direction of outputs is from S1 to S720
'When SS = 1, the shift direction of outputs is from S720 to S1.
'In addition to the shift direction, the settings for both SS and BGR bits are required to change the
'assignment of R, G, B dots to the source driver pins.
'To assign R, G, B dots to the source driver pins from S1 to S720, set SS = 0.
'To assign R, G, B dots to the source driver pins from S720 to S1, set SS = 1.
' command $0003
'R/W RS D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
'W 1 TRI DFM 0 BGR 0 0 HWM 0 ORG 0 I/D1 I/D0 AM 0 0 0
' When AM = 0, the address is updated in horizontal writing direction.
'When AM = 1, the address is updated in vertical writing direction.
'I/D[1:0] Control the address counter (AC) to automatically increase or decrease by 1 when update one pixel
' display data.
SelectMemGroup ' 137 and appropriate pins
orientation := n
'_________Start ILI_______________________
' if orientation
' ' for origin top left and portrait mode
' ILIcmd($0001,%00000001_00000000) ' $0001,$0100 set SS and SM bit 0001 0100 portrait
' ILIcmd($0003,%00010000_00110000) ' $0003,$1030 set GRAM write direction and BGR=1. $0003 $1030
' else
' ' for origin top right and landscape mode
' ILIcmd($0001,%00000000_00000000) ' set SS and SM bit 0001 0000 landscape
' ILIcmd($0003,%00010000_00111000) ' landscape $1028 = original but 1038 is correct - not mirror image
'________END ILI_____________________
'________Start SSD___________________
if orientation
' for origin top left and portrait mode
ILIcmd($0001,$2B3F) ' $0001,$0100 set SS and SM bit 0001 0100 portrait
ILIcmd($0011,$6070) ' $0003,$1030 set GRAM write direction and BGR=1. $0003 $1030
else
' for origin top right and landscape mode
ILIcmd($0001,$6B3F) ' set SS and SM bit 0001 0000 landscape
ILIcmd($0011,$6838) ' landscape $1028 = original but 1038 is correct - not mirror image
'_________END SSD____________________
PUB Start_ILI9325 ' pass orientation true = portrait, false = landscape
ILI_Reset_High
pause1ms(5)
ILI_Reset_Low
pause1ms(5)
ILI_Reset_High ' returns in group 2, ie CS is high
Change137(2) ' replaces ILI_CS high - select another group
ILI_RD_High
ILI_WR_High
pause1ms(5)
'ILI_CS_Low
SelectMemGroup ' enables correct pins for output and sets CS low
'IliInit
SsdInit
PRI SsdInit
ILIcmd($0000,$0001) 'Turn Oscillator on POR-$0000
pause1ms(1)
ILIcmd($0003,$A8A4) 'Power control (1) POR-$6664
pause1ms(1)
ILIcmd($000C,$0000) 'Power control (2) POR- ?
pause1ms(1)
ILIcmd($000D,$080C) 'Power control (3) POR-$0009
pause1ms(1)
ILIcmd($000E,$2B00) 'Power control (4) POR-$3200
pause1ms(1)
ILIcmd($001E,$00B0) 'Power control (5) POR-$0029
pause1ms(1)
ILIcmd($0001,$6B3F) 'Driver output control, *landscape?? $6B3F* POR-$433F
pause1ms(1)
ILIcmd($0002,$0600) 'LCD drive AC control POR-$0400
pause1ms(1)
ILIcmd($0010,$0000) 'Sleep Mode sleep mode off POR-$0001
pause1ms(1)
ILIcmd($0011,$6070) 'Entry Mode, *landscape? $4030* POR-$6830
pause1ms(1)
ILIcmd($0005,$0000) 'Compare Register (1) POR-$0000
pause1ms(1)
ILIcmd($0006,$0000) 'Compare Register (2) POR-$0000
pause1ms(1)
ILIcmd($0016,$EF1C) 'Horizontal Porch POR-$EFC1
pause1ms(1)
ILIcmd($0017,$0003) 'Vertical Porch POR-$0003
pause1ms(1)
ILIcmd($0007,$0033) 'Display Control POR-$0000
pause1ms(1)
ILIcmd($000B,$D308) 'Frame cycle Control POR-$D308
pause1ms(1)
ILIcmd($000F,$0000) 'Gate Scan start position POR-$0000
' pause1ms(1)
'ILIcmd($0041,$0000) 'Vertical Scroll Control (1) POR-$0000
' pause1ms(1)
'ILIcmd($0042,$0000) 'Vertical Scroll Control (2) POR-$0000
' pause1ms(1)
'ILIcmd($0048,$0000) 'First Window Start POR-$0000
' pause1ms(1)
'ILIcmd($0049,$013F) 'First Window End POR-$013F
' pause1ms(1)
'ILIcmd($004A,$0000) 'Second Window Start POR-$0000
' pause1ms(1)
'ILIcmd($004B,$0000) 'Second Window End POR-$013F
' pause1ms(1)
'ILIcmd($0044,$EF00) 'Horizontal Ram Address Postion POR-$EF00
' pause1ms(1)
'ILIcmd($0045,$0000) 'Vertical Ram Address Start POR-$0000
' pause1ms(1)
'ILIcmd($0046,$013F) 'Vertical Ram Address End POR-$013F
' pause1ms(1)
'ILIcmd($0030,$0707) 'gamma 1 POR-$
' pause1ms(1)
'ILIcmd($0031,$0204) 'gamma 2 POR-$
' pause1ms(1)
'ILIcmd($0032,$0204) 'gamma 3 POR-$
' pause1ms(1)
'ILIcmd($0033,$0502) 'gamma 4 POR-$
' pause1ms(1)
'ILIcmd($0034,$0507) 'gamma 5 POR-$
' pause1ms(1)
'ILIcmd($0035,$0204) 'gamma 6 POR-$
' pause1ms(1)
'ILIcmd($0036,$0204) 'gamma 7 POR-$
' pause1ms(1)
'ILIcmd($0037,$0502) 'gamma 8 POR-$
' pause1ms(1)
'ILIcmd($003A,$0302) 'gamma 9 POR-$
' pause1ms(1)
'ILIcmd($003B,$0302) 'gamma 10 POR-$
' pause1ms(1)
'ILIcmd($0023,$0000) 'RAM write data mask (1) POR-$0000
' pause1ms(1)
'ILIcmd($0024,$0000) 'RAM write data mask (2) POR-$0000
' pause1ms(1)
'ILIcmd($0025,$8000) 'not in datasheet?
' pause1ms(1)
'ILIcmd($004f,0) 'RAM Y address counter POR-$0000
' pause1ms(1)
'ILIcmd($004e,0) 'RAM X address counter POR-$0000
' pause1ms(1)
ChangeOrientation(false) ' default to portrait
'----------------SSD1289 END----------------------------------------------------------------------
PRI IliInit
' ************* Start Initial Sequence **********
ILIcmd($00E5,$78F0) ' set SRAM internal timing
ILIcmd($0001,$0100) ' set SS and SM bit 0001 0100 portrait
ILIcmd($0002,$0700) ' set 1 line inversion
ILIcmd($0003,$1030) ' set GRAM write direction and BGR=1. $0003 $1030
ILIcmd($0004,$0000) ' Resize register
ILIcmd($0008,$0207) ' set the back porch and front porch
ILIcmd($0009,$0000) ' set non-display area refresh cycle ISC[3:0]
ILIcmd($000A,$0000) ' FMARK function
ILIcmd($000C,$0000) ' RGB interface setting
ILIcmd($000D,$0000) ' Frame marker Position
ILIcmd($000F,$0000) ' RGB interface polarity
' *************Power On sequence ****************//
ILIcmd($0010,$0000) ' SAP, BT[3:0], AP, DSTB, SLP, STB
ILIcmd($0011,$0007) ' DC1[2:0], DC0[2:0], VC[2:0]
ILIcmd($0012,$0000) ' VREG1OUT voltage
ILIcmd($0013,$0000) ' VDV[4:0] for VCOM amplitude
ILIcmd($0007,$0001)
pause1ms(50) ' Dis-charge capacitor power voltage
ILIcmd($0010,$1090) ' 1490//SAP, BT[3:0], AP, DSTB, SLP, STB
ILIcmd($0011,$0227) ' DC1[2:0], DC0[2:0], VC[2:0]
pause1ms(50) ' delay
ILIcmd($0012,$001F) ' 001C// Internal reference voltage= Vci;
pause1ms(50) ' delay
ILIcmd($0013,$1500) ' $1000//1400 Set VDV[4:0] for VCOM amplitude 1A00
ILIcmd($0029,$0027) ' $0012 //001a Set VCM[5:0] for VCOMH //$0025 0034
ILIcmd($002B,$000D) ' Set Frame Rate 000C
pause1ms(50) ' delay
ILIcmd($0020,$0000) ' GRAM horizontal Address
ILIcmd($0021,$0000) ' GRAM Vertical Address
' ----------- Adjust the Gamma Curve ----------//
ILIcmd($0030,$0000)
ILIcmd($0031,$0707)
ILIcmd($0032,$0307)
ILIcmd($0035,$0200)
ILIcmd($0036,$0008)
ILIcmd($0037,$0004)
ILIcmd($0038,$0000)
ILIcmd($0039,$0707)
ILIcmd($003C,$0002)
ILIcmd($003D,$1D04)
' ------------------ Set GRAM area ---------------//
ILIcmd($0050,$0000) ' Horizontal GRAM Start Address
ILIcmd($0051,$00EF) ' Horizontal GRAM End Address
ILIcmd($0052,$0000) ' Vertical GRAM Start Address
ILIcmd($0053,$013F) ' Vertical GRAM Start Address
ILIcmd($0060,$A700) ' Gate Scan Line
ILIcmd($0061,$0001) ' NDL,VLE, REV
ILIcmd($006A,$0000) ' set scrolling line
' -------------- Partial Display Control ---------/
ILIcmd($0080,$0000)
ILIcmd($0081,$0000)
ILIcmd($0082,$0000)
ILIcmd($0083,$0000)
ILIcmd($0084,$0000)
ILIcmd($0085,$0000)
' //-------------- Panel Control -------------------//
ILIcmd($0090,$0010)
ILIcmd($0092,$0600)
ILIcmd($0007,$0133) ' 262K color and display ON
ChangeOrientation(true) ' default to portrait
PUB Draw(x1, y1, x2, y2)|HORIZONTALRAMADDRESSPOS ' sets the pixel to x1,y1 and then fills the next (x2-x1)*(y2-y1) pixels
SelectMemGroup ' set 137 to correct value
ifnot orientation ' landscape mode so swap x and y
result :=x1 ' swap x1 and y1
x1 := y1
y1 := result
result := x2 ' swap x2 and y2
x2 :=y2
y2 := result
HORIZONTALRAMADDRESSPOS := x1 + (x2 << 8)
ILIcmd(REG_HORIZONTALRAMADDRESSPOS,HORIZONTALRAMADDRESSPOS)
ILIcmd(REG_VERTICALRAMADDRESSSTART,y1)
ILIcmd(REG_VERTICALRAMADDRESSEND,y2)
ILIcmd(REG_SETGDDRxADDRESSCOUNTER,x1)
ILIcmd(REG_SETGDDRyADDRESSCOUNTER,y1)
Lcd_Write_Com($0022)
'ILIcmd($0050,x1)
'ILIcmd($0052,y1)
'ILIcmd($0051,x2)
'ILIcmd($0053,y2)
'ILIcmd($0020,x1)
'ILIcmd($0021,y1)
'Lcd_Write_Com($0022)
Everything else is stock. NOTE. My screen has swapped TOUCH-X
Comments
That code came from some C code and is copied pretty much directly. I have no idea how it all works. So what that function does is start up the display in portrait mode and at least then you can get a debug message on the screen.
There are other routines which change from portrait to landscape (and which took a lot of experimenting to get right because the demo code didn't work for that).
So you shouldn't need to change that startup code at all.
*edit*
The one thing that would come in handy is to be able to read from the display. Then the program can get the "Screen ID" and automatically choose the correct register layout. The script could be written once and then be re-usable. I've been hard-translating across and it's a bit difficult. I HAD the settings somewhere, now if I could only find them. Currently I get a black screen, I HAD it partially working, now it does nothing. SOOO confused.
and this is some uncommented code in C for your display (hex opcodes fortunately)
Are they the same?
Do you have some commented code?
Post 301 has the initialization code at the bottom of the CON section for my display. Editing post now.
OK, here's what I've got so far for the initialization: Still nothing on the display.. I'm going to play with things a bit more and if I still can't get it to work? I'll double check hardware?
*edit again*
OOOOK.. SO. P2 to shorted to GND... It was the regulator screw on back of board shorting p2 trace.. I FINALLY found that puppy, so I will correct and try again!
*edit* uploading 5 minutes of wierdness to youtube right now and I'll link when done...all I can say is wow, that was strange ;(
The icons are doing a few things - reading back from ram the background pixels, comparing using a mask bitmap, and then sending back new pixels. So lots of things have to work there, but on the other hand it tests lots of things.
I think you have cracked the hard part though.
Do you have a picture editor? I'm using an ancient 1996 version of paint shop pro but it does everything I need. Try grabbing a picture from the internet, resample/resize to 240x320, save as a .bmp file and see if you can change the desktop.
Then save a 320x240 picture and see if that will display landscape.
BTW what time are you going to bed? It is almost my bedtime and you are 9 hours ahead of me. Was this an all-nighter?
Ok, movie won't work because the file is 15mb so don't worry about that.
All the other things sound like they have to be related. Not sure what it all means though.
*edit*
More puzzling results. Seems like it sometimes loads the mask and fails. Sometimes it loads Photos and fails. Sometimes it loads the Mask and Photos then fails. If I turn off all the icon loads, things seem to work except tiny synth?
First error, expected $00FF, received $0000
Next error, expected $01FF, received $0000
and so on?
Trying to write above 256 writes to the screen?
I'll think of some more tests. brb
So that will test sd to hub, then hub to ramdisk, then ramdisk out to the display.
But you have problems sending just one pixel?
HubToRam command seems to be the problem. I will play with this more.
Ok, the screen would glitch if you didn't read the correct size of the bitmap file. Then it would try to read something completely different, possibly even a huge number which would cycle through all the ram.
so - can we read the bitmap information correctly?
Try this main loop
and in the loadbmptoramdisk try this
you should get 0x000000F0 as the width and 0x00000140 as the height
and just to double check
should be 0x0003F77C
*edited*
Tried everything and it all looks right?
and then see if you get back 0xF0 and 0x140
LoadBMPtoRamdisk : HubToRam(i,width)
Need to step through the ASM driver and find where the issue is.
*edited*
I've been playing around and it keeps jumping. I got this working: a few waits seem to help, although things seem to move around? I have quadruple checked the board and I THINK everything is wired okay? Checked ohms across every socket pin and gnd, +3.3v, +5, adjacent, all other socket pins? This is VERY STRANGE! I'm sure it's something simple. *I need to get my wife to finish soldering the 2nd board to build for testing purposes!* Strangely enough, if I comment out all the mask icons, I can get the photo viewer running, and calculator. I think a BETTER ram test needs to be written. What I came up with is pretty crude and probably doesn't catch the error?
*edit*
So, I gotta take a break. Here's what I've been able to figure out so far
If things are not working in pasm, there is a break line
and many times I've added that to code and then gone through with the logic probe to check pins are what they are supposed to be.
Just remember to remove the break afterwards!
Today I sent off the dual display board to be made. Has all the corrections we have been doing plus a few headers for things like the group select and some latch outputs and P0-P15.
I've got some ideas using the dual display eg the synth could be run in two cogs at the same time and then you could send the output of one to the right speaker and the output of the other to the left speaker and play with two hands at the same time. A rudimentary polyphonic synth!
Or you could use one of the more sophisticated synth objects and there is room for more slider controls.
*edited*
So, as a side note... If using a ribbon cable to connect screens, you need to put the pin-header on the BOTTOM of the board?
Well there is one last bit of code that could explain this behaviour and it is the routine that sends from ram to the display
which calls this pasm
Also I added a little routine so that when you open a file for reading and it is not there, it displays an error message. Useful as the number of files on the card increases. I also ported it over to Kye's latest SD code. I don't think that is your problem though so no need to change your code if you don't want to yet.
Maybe take that pasm code above and stick some halts through the code and test the pins?
The dual screen has the screens side by side with only short components under the screens. So in one sense you can have a 480x320 display.
Just tried compiling: "Missing SD-MMC_FATEngine.spin"
I'll hunt that down and keep plugging!
*edit* Hmmm, I found something. This order loads, the original crashes at propfont out?
Now runs until load desktop.
*edit again*
Nope, not quite? Started slowing things down and stepping through. Loading mask fails at HUBtoRAM.
The tricky thing is the error keeps moving. It seems to happen in one place, and then it creeps in somewhere else? I'm really confused right now. I'm sure it's something simple.
Right now I'm back to the RAM. Seems problem is in LOAD BMP: *more edit*
I keep taking one step forward, and 2 steps back. Changing the timeouts changes the operation, moves the bug, etc. Seems the screen is writing when the ram is transferring. Need to think more about this. Seems swapping from group 0-1 is the problem. Maybe the extra NAND?!!
HINT HINT. It's GOTTA BE screen write timing or something. I must play around with some registers!!! I have a CRUDE work-around... Re-init the screen after drawing everything?
Everything else is stock. NOTE. My screen has swapped TOUCH-X