Dr. Acula you are amazing, first CPM, now a touchscreen GUI. What's next, a KDE desktop ?
Wait up a minute, CP/M on the Prop was me!
Dr A is amazing, and his work and encouragement (Not forgetting Cluso and a cast of thousands) pushed CP/M on the Prop much further than I would ever have imagined.
Heater is correct. And his avatar is "Zicog". Plus he invented Zog who is bigger than all of us!
I've coded a simple demo program. 40x15 white on blue screen using the propeller font. One font. No graphics. Font is stored in hub, so no external ram needed. Useful for debugging as you need something simple to display the debugging information.
Dr. A, I believe you have gotten the SD Card on the board to work. I have replaced the resistors with wire links and they seem ok. I know what the 4 data lines to the propeller are, but what are the power pins on the LCD board?
I noticed the Gadget Gangster board that has the LCD shows two resistors for the backlight. One can be tied to P6 or the other to VDD but the resistors values are not shown in the schematic. What values are required? Thanks.
Can you post a schematic? I'm not sure about 2 resistors, I thought there was only 1. I'm using 220R for the backlight because that is a fairly generic value for running a led at reasonable brightness from 5V.
Also, just for posterity, this is the code to print text using the propeller's internal font. Useful for debugging an SD card as the SD card needs to work in order to display a font that is stored on the SD card. Now (slowly) you can at least print some debug messages without needing the SD card.
PUB Propfont ' use propeller font in the rom for bootup messages when debugging sd cards
curx := 0 ' set cursor to top left of screen (common variable)
cury := 0
Propfont_string(string("Loading SD")) ' string to send
Propfont_string(string("Loading Font"))
PUB Propfont_string(stringptr) 'print at curx,cury
repeat strsize(stringptr)
ILI9325.draw(curx,cury,curx+15,cury+31) ' location to start drawing
Propfont_out(byte[stringptr++])
curx +=16
curx := 0
cury += 32 ' new line at end of string
PUB Propfont_out(ascii) | address,pixels
address := $8000 + (ascii >> 1) << 7 ' get rom address
repeat 32 ' 32 rows per character, split in two parts
pixels := long[address] ' get rom font data
pixels := pixels >> (ascii & 1) ' shift for odd characters
repeat 16 ' 16 columns
if pixels & 1
ILI9325.pixel(%00000111_11100000) ' foreground color RRRRRGGG_GGGBBBBB
else
ILI9325.pixel(%00000000_00000000) ' background color
pixels := pixels >> 2 ' alternate pixels interleaved so shift 2
address += 4 'increment address by 4 bytes
Edit: I just found the parts list and it looks like they use a 47 ohm resistor and you use only one. The resistor is tied to P6 or VDD depending on where you solder it. I'm making a DIY board with the platform using 16 bit input and having the Back light jumpered to either the Propeller or VDD
Hi All! The sd doesn't seem to work I gave it power and hooked it up properly and the sd is the right kind and formatted correctly, but still nothing. I'm using this code:
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
DO = 0
CLK = 1
DI = 2
CS = 3
var
long mount
OBJ
sd : "fsrw"
pst : "SimpleDebug"
PUB Main
pst.Start(115_200)
pst.str(string(13,"sup",13))
waitcnt(clkfreq*2 + cnt)
mount := \sd.mount_explicit(0, 1, 2, 3)
if mount < 0
pst.dec(mount)
pst.str(string(13,"Failed to mount",13))
abort
pst.str(string(13,"Cool...Cool",13))
sd.unmount
Mabye the code is part of the problem. All help is appreciated.
Edit: I just found the parts list and it looks like they use a 47 ohm resistor and you use only one. The resistor is tied to P6 or VDD depending on where you solder it. I'm making a DIY board with the platform using 16 bit input and having the Back light jumpered to either the Propeller or VDD
Cool. It looks like one prop pin is being used to turn the backlight on and off. That would work but it does use a precious prop pin. I'd just tie it to 5V with the appropriate resistor.
@Tyler, I've not used fsrw but others may chime in. I presume you have 10k pullups on those pins?
Cool. It looks like one prop pin is being used to turn the backlight on and off. That would work but it does use a precious prop pin. I'd just tie it to 5V with the appropriate resistor.
@Tyler, I've not used fsrw but others may chime in. I presume you have 10k pullups on those pins?
Yes i am using 10k pullups. Thanks i'll try another sd object.
Have added xmodem for file transfers. This adds a serial port and reuses the propeller download port for transferring data. Xmodem transfers from a terminal program (eg hyperterminal) are a little tedious opening and closing programs, but they work very well from an IDE, eg an IDE that compiles/dowloads/runs C programs.
We can do similar things for Spin as there are command line spin compilers. Design your icon in such a program, design your desktop layout, save this as an .ini file, then transfer the file with xmodem. Programs are compiled binary files sitting on an SD card. In Kyedos, such programs have an .exe extension, and to find out what programs are available you type "DIR *.EXE" and then look at the list eg MYPROG.EXE and then type "MYPROG" and it reboots the propeller chip and runs that program.
On a touchscreen it is a bit different - you would associate the file with an icon, define where the icon is on the screen, and then when you touch that part of the screen it reboots the propeller and runs that program.
@Cluso, I'm still confused by that other thread discussion about intercog communications with registries. To my simple way of thinking, it all works fine with cogs, but half a typical object is also Spin, and you can't load the spin bit in and out independently. So unless your program is pure PASM (like Juergen's CP/M emulation), I can't see how a registry helps much.
What does work though is to have an operating system which can load other programs. Don't try to leave cogs running between programs - just load them in again. The time penalty is only minimal. And you can share common code by using common objects. So yes it is a little inefficient as you reboot and load up a cog with exactly the same code you had before, but the advantage is that there is no complexity with trying to understand the concept of registries. The .exe program is self contained. It also makes testing easier - test out the .exe program with F10 downloads and when it is ready, do an F8 and save to the SD card directly by typing the path and name into the save box on F8. Name as .exe
So you can write an .exe for a TV display, and one for VGA, and one for the ILI touchscreen. Each is self contained. Each probably has many objects in common (eg SD driver). But there are no #ifdefs needed. Ideally, try to make it such that changing one object, like a display object, is all you need to do (ie, use the common methods like .hex, .out, .decimal).
Just to demonstrate, I replaced the movie player code with this line of code. Touch the movie icon and this runs:
42: result := \fat.bootpartition(string("MOVIE.EXE")) ' reboot and run this program (42 is the code for this icon's position)
and that reboots the propeller and runs movie.exe. Time to reboot and run is about 1 second. The screen need not blank during this time if you don't want it to. The program reboots the propeller at the end which returns to the main program.
The movie player program is fairly short as it does not need the touch part of the touchscreen, nor keyboard, nor serial port etc etc. It uses the same display object code as the main operating system.
The aim now is to automate the icon placement and program association.
'' Movie player for the touchscreen
'' James Moxham 2011
CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000
_SD_DO = 12
_SD_CLK = 13
_SD_DI = 14
_SD_CS = 15
_SD_WP = -1 ' -1 ifnot installed.
_SD_CD = -1 ' -1 ifnot installed.
_RTC_DAT = -1 ' -1 ifnot installed. For kye's sd driver
_RTC_CLK = -1 ' -1 ifnot installed.
OBJ
fat: "SD3.01_FATEngine.spin" ' thanks to Kye
ILI9325: "ILI9325_Dracblade" ' J Moxham
VAR
word ScreenWidth ' either 240 in portrait or 320 in landscape
word ScreenHeight ' 320 in portrait or 240 in landscape
byte Orientation ' true for portrait, false for landscape
PUB Main
ILI9325.start_ram ' start the external ram driver in a cog
ILI9325.start_ILI9325 ' start the ILI9325 display
SetOrientation(true) ' in portrait (true) or landscape mode (false)
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
Movie
reboot
PUB Movie ' maybe need to speed up the draw routine as this is in spin
clearscreen(0)
fat.openfile(string("taz.ilm"),"R") ' also can skip alt frames, and maybe make the sd buffer bigger
repeat 338 ' number of frames
ILI9325.draw(60,115,179,204) ' this can be sped up as this is in spin
repeat 9 ' 120*90*2 / 480
fat.readdata(@sdbuffer,2400) ' read data into hub
ILI9325.docmd("D",@sdbuffer,0,2400) ' send data out to the display (could possibly do some in parallel, though the ILI display may be faster than the sd card)
fat.closefile
PUB Clearscreen(color)
bytefill(@sdbuffer,color,512)
ILI9325.draw(0,0,screenwidth,screenheight) ' set up the area of the screen to draw in
repeat 300
ILI9325.docmd("D",@sdbuffer,0,512) ' move bytes from ram out to the display
PUB SetOrientation(e) ' change orientation true = portrait. Changes global variable 'orientation' and also screen width and height
orientation := e
ILI9325.ChangeOrientation(orientation)
if orientation
screenwidth :=239
screenheight :=319
else
screenwidth :=319
screenheight :=239
DAT
sdbuffer byte $0[2400] '2400 byte buffer for sd card interface
Very beginnings of the new board design - see photo. Propeller, 2 ram chips, 4 latches and 3 HC245 buffers.
Optimised for transferring data from ram to the display, for fast updates of fonts etc. The Spin version is at least 4x faster than previous versions and in Spin the code to move one pixel comes down to just 4 lines of code.
repeat nwords
OUTA := address ' address is not latched - this is where the speed is
OUTA &= %11111111_10111111_11111111_11111111 ' ILI write low
OUTA |= %00000000_01000000_00000000_00000000 ' ILI write high
address++ ' increment address
Things like moving from the propeller to the ram are a little slower, but fonts only need to be loaded into ram once. Board is not fully populated - has room for a real time clock and some digital and analog I/O and stereo sound and a keyboard. The SD socket is not going to be needed as while this board was being made, other clever people on the forum got the display's SD card working by removing three resistors on the back of the display.
Once this is ported over to pasm it should really fly!
The board has two 512k ram chips in parallel so it works with words rather than bytes.
Got to go to work - I'll post a schematic shortly. Code is below
'' ILI9325 driver using the Touchblade2 design for faster ram to display transfers
'' James Moxham 2011
CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000
_1ms = 1_000_000 / 1_000 ' Divisor for 1 ms
OBJ
VAR
long IC9Status
long orientation
long curx, cury
long clkcycles ' for the delay routine
PUB Main |a,b
curx :=0
cury :=0
DIRA := %00000000_11111111_11111111_11111111 ' enable these pins for output
OUTA := %00000000_11111111_00000000_00000000 ' sets ILI write high and ILIBus is disconnected
Mem_Rd_High ' so no data clashes
ILI_Bus_Dir_Low ' direction = prop to display
ILI_Bus_Connect ' connect the bus so can talk to the display
Start_ILI9325
'Draw(0,0,239,319) ' clear the screen
'repeat 76800
' Pixel($0000)
' Hex(100,4) ' test printing a hex digit
Propfont
bytefill(@sdbuffer,$FF,512)
PropToRam(20000,256)
'RamToProp(0,2) ' read the data back from ram to the sdbuffer array
'hex(sdbuffer[0],2) ' should read E5
a :=0 ' pixel
b :=0 ' ram address counter
repeat 76800 ' fills with all colors
sdbuffer[0] := a & $FF
sdbuffer[1] := a >> 8
PropToRam(b,1)
b++
a++
' need to put some pixels in ram at various places
Draw(0,0,239,319)
RamToDisplay(0,76800) ' start at address send n words
'PropFont
'bytefill(@sdbuffer,0,512)
'b :=0
'repeat 5
' RamToProp(b,1) ' not reading back the correct values
' hex(sdbuffer[0],2)
' hex(sdbuffer[1],2)
' b++
Propfont_string(string("Finished"))
repeat ' repeat forever
PUB Propfont ' use propeller font in the rom for bootup messages when debugging sd cards
Propfont_string(string("Wait 20s")) ' string to send
PUB Propfont_string(stringptr) 'print at curx,cury
repeat strsize(stringptr)
Propfont_out(byte[stringptr++])
crlf
PUB crlf
curx := 0
cury += 32 ' new line at end of string
if cury >319 ' bottom of screen so new screen
curx:=0
cury:=0
PUB Propfont_out(ascii) | address,pixels
Draw(curx,cury,curx+15,cury+31) ' location to start drawing
address := $8000 + (ascii >> 1) << 7 ' get rom address
repeat 32 ' 32 rows per character, split in two parts
pixels := long[address] ' get rom font data
pixels := pixels >> (ascii & 1) ' shift for odd characters
repeat 16 ' 16 columns
if pixels & 1
Pixel(%00000111_11100000) ' foreground color RRRRRGGG_GGGBBBBB
else
Pixel(%00000000_00000000) ' background color
pixels := pixels >> 2 ' alternate pixels interleaved so shift 2
address += 4
curx +=16
if curx >239 ' new line
crlf
PUB Start_ILI9325 ' pass orientation true = portrait, false = landscape
ILI_Reset_High
pause1ms(5)
ILI_Reset_Low
pause1ms(5)
ILI_Reset_High
ILI_CS_High
ILI_RD_High
ILI_WR_High
pause1ms(5)
ILI_CS_Low
' ************* 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 ChangeOrientation(n) ' pass true = portrait or false = landscape, changes global variable orientation in this object
orientation := n
if orientation
ILIcmd($0001,$0100) ' set SS and SM bit 0001 0100 portrait
ILIcmd($0003,$1030) ' set GRAM write direction and BGR=1. $0003 $1030
else
ILIcmd($0001,$0000) ' set SS and SM bit 0001 0000 landscape
ILIcmd($0003,$1038) ' landscape $1028 = original but 1038 is correct - not mirror image
PUB Draw(x1, y1, x2, y2) ' sets the pixel to x1,y1 and then fills the next (x2-x1)*(y2-y1) pixels
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
ILIcmd($0050,x1)
ILIcmd($0052,y1)
ILIcmd($0051,x2)
ILIcmd($0053,y2)
ILIcmd($0020,x1)
ILIcmd($0021,y1)
Lcd_Write_Com($0022)
PUB Pixel(pixelcolor) ' send out a pixel, high byte then low byte
Lcd_Write_Data(pixelcolor)
PUB pause1ms(period)
'' Pause execution for period (in units of 1 ms).
clkcycles := ((clkfreq / _1ms * period) - 4296) #> 381 ' Calculate 1 ms time unit
waitcnt(clkcycles + cnt) ' Wait for designated time
PUB hex(value, digits)
'' Print a hexadecimal number
propfont_out("O")
propfont_out("x")
value <<= (8 - digits) << 2
repeat digits
propfont_out(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
crlf
PRI ILIcmd(c,d) ' instruction in one method
Lcd_Write_Com(c) ' send out a word
Lcd_Write_Data(d)
PRI Lcd_Write_Com(ILIlong)
ILI_RS_low
LCD_Writ_Bus(ILIlong)
PRI Lcd_Write_Data(ILIlong)
ILI_RS_High
LCD_Writ_Bus(ILIlong)
PRI LCD_Writ_Bus(ILILong)
'ILILong &= %00000000_00000000_11111111_11111111 ' mask to a word. Not needed if care taken always to send a word value
OUTA &= %11111111_11111111_00000000_00000000 ' set P0-P15 to zero ready to OR
OUTA |= ILILong ' merge with the word to output
ILI_WR_Low ' send out the data
ILI_WR_High
PRI IC9Latch ' uses IC9status common variable (only use one byte of this)
DIRA:=%00000000_11111111_11111111_11111111 ' enable these pins for output
IC9status &= %00000000_00000000_00000000_11111111 ' mask off byte
OUTA &= %11111111_11111111_11111111_00000000 ' mask P0-P7 low
OUTA |= IC9status ' combine with the data byte
OUTA &= %11111111_11010111_11111111_11111111 ' set latch to Y2 = 010
OUTA |= %00000000_00111000_00000000_00000000 ' 138 to output Y7 which is deselected
PRI ILI_RS_Low
IC9status &= %11111111_11111111_11111111_11111110 ' ILI RS pin low
IC9Latch
PRI ILI_RS_High
IC9status |= %00000000_00000000_00000000_00000001 ' ILI RS pin high
IC9Latch
PRI ILI_RD_Low
IC9status &= %11111111_11111111_11111111_11111101 ' ILI RD pin low
IC9Latch
PRI ILI_RD_High
IC9status |= %00000000_00000000_00000000_00000010 ' ILI RD pin high
IC9Latch
PRI ILI_WR_Low
OUTA &= %11111111_10111111_11111111_11111111 ' ILI write low
PRI ILI_WR_High
OUTA |= %00000000_01000000_00000000_00000000 ' ILI write high
PRI ILI_CS_Low
IC9status &= %11111111_11111111_11111111_11111011 ' ILI CS pin low
IC9Latch
PRI ILI_CS_High
IC9status |= %00000000_00000000_00000000_00000100 ' ILI CS pin high
IC9Latch
PRI ILI_RESET_Low
IC9status &= %11111111_11111111_11111111_11110111 ' ILI RESET pin low
IC9Latch
PRI ILI_RESET_High
IC9status |= %00000000_00000000_00000000_00001000 ' ILI RESET pin high
IC9Latch
PRI ILI_Bus_Dir_Low
IC9status &= %11111111_11111111_11111111_11101111 ' data from propeller to ILI bus
IC9Latch
PRI ILI_Bus_Dir_High
IC9status |= %00000000_00000000_00000000_00010000 ' data from ILI bus to propeller
IC9Latch
PRI ILI_Bus_Connect
OUTA &= %11111111_01111111_11111111_11111111 ' P23 low connect the ILI bus to the propeller
PRI ILI_Bus_Disconnect
OUTA |= %00000000_10000000_00000000_00000000 ' set P23 high
PRI Mem_Rd_Low
IC9status &= %11111111_11111111_11111111_11011111 ' mem read low
IC9Latch
PRI Mem_Rd_High
IC9status |= %00000000_00000000_00000000_00100000 ' mem read high
IC9Latch
PRI PropToRam(address,nwords)|c,d ' data is at sdbuffer, length up to 256 words (ie 512 byte full buffer, pass 256)
c :=0
d := 0
ILI_Bus_Dir_Low ' for writing to ram B to A on the 245
'ILI_Bus_Connect ' no need as bit 23 in address is set low in the next line
Address &= %00000000_00000111_11111111_11111111 ' mask off A0=A18
Address |= %00000000_01001000_00000000_00000000 ' 138 Y1 = 00xxx00000000 and nn000000 = ILI write and 245 bus isolate
repeat nwords
OUTA := address ' send out
OUTA |= %00000000_00111000_00000000_00000000 ' latch in the address
d := sdbuffer[c] | sdbuffer[c+1] << 8 ' build the data word LSB first
d |= %00000000_01000000_00000000_00000000 ' or in Y0 for write and P22 and P23
OUTA := d ' put the word on the propeller pins P0-P15 and write
OUTA |= %00000000_01111000_00000000_00000000 ' Y7 default write high
c +=2 ' increment counter
address +=1 ' address only goes up by 1 as writing out words at a time
'
PRI RamToProp(address,nwords) |c,d ' move data from ram to sdbuffer array
c :=0
d := 0
' data is coming out of the ram chips so need to toggle the 245 buffer.
ILI_Bus_Disconnect ' disconnect the buffer first P23 high
ILI_Bus_Dir_High ' data from the ram to the propeller
Mem_Rd_low ' for reading data
Address &= %00000000_00000111_11111111_11111111 ' mask off A0=A18
Address |= %00000000_11001000_00000000_00000000 ' 138 Y1 = 10xxx000 and nn000000 = ILI write and 245 bus isolate
repeat nwords
DIRA := %00000000_11111111_11111111_11111111 ' enable these pins for output
OUTA := Address ' put on the propeller pins
OUTA |= %00000000_00111000_00000000_00000000 ' latch in the address
DIRA := %00000000_11111111_00000000_00000000 ' P0-P15 are now inputs
ILI_Bus_Connect ' connect the bus P23 low, read the data
d := INA & %00000000_00000000_11111111_11111111 ' read data from ram and mask as a word
ILI_Bus_Disconnect ' disconnect the P23 high bus
sdbuffer[c] := d & $FF ' mask LSB
sdbuffer[c+1] := d >> 8 ' mask MSB
c +=2
address +=1
'finish up
DIRA := %00000000_11111111_11111111_11111111 ' enable these pins for output
Mem_Rd_High ' memory read high
ILI_Bus_Dir_Low ' restore the default direction to the display
ILI_Bus_Connect ' restore the connection
PRI RamToDisplay(address,nwords) ' send nwords to the display from ram address
ILI_Bus_Disconnect ' P23 high so isolated from the propeller. Dir does not matter
Mem_Rd_Low ' low for this entire routine as reading
ILI_RS_High ' see pixel routine
Address &= %00000000_00000111_11111111_11111111 ' mask off A0=A18
Address |= %00000000_11001000_00000000_00000000 ' 138 Y1 = 10xxx000 and nn000000 = ILI write and 245 bus isolate
repeat nwords
OUTA := address ' address is not latched - this is where the speed is
OUTA &= %11111111_10111111_11111111_11111111 ' ILI write low
OUTA |= %00000000_01000000_00000000_00000000 ' ILI write high
address++ ' increment address
' finish up
Mem_Rd_High ' memory read high
ILI_Bus_Dir_Low ' restore the default direction to the display
ILI_Bus_Connect ' restore the connection
DAT
sdbuffer byte $0[512] ' 512 byte buffer for sd card interface
Blink and you will miss it. The Text is still in Spin - it is the redraw of the screen that is fast. I timed a loop 100x and it is 3seconds so that is 30milliseconds to refresh the screen. A bit faster than the 9 seconds in Spin! This circuit has been optimised for speed sending data from the ram directly to the display. The final pasm loop per pixel comes down to this:
Moveblock_loop mov outa,ramaddr ' send out the address value
andn outa,pin22 ' set pin 22 low
or outa,pin22 ' set pin 22 high
add ramaddr,#1 ' increment ram address
djnz len,#moveblock_loop
Now to go back and work on optimising other things. At the moment SD transfers are too slow as it is sending data to ram in pieces. So need to have the SD card on some dedicated propeller pins.
So in general terms, need fast transfer from SD to ram, and fast transfer from ram to the display.
At the moment I have two boards and they are each optimised to do one of these. Need to combine these into one board now.
Scroll test. Dump out the entire memory (filled with random data and some black lines) and scroll up 10 lines each screen. Refresh is 30x a second so this should make for a very responsive text scroll when moving a finger on the touchscreen. Plus animated GIFs will be very smooth.
Thanks! I really appreciate that eagle file. If I can think of any more parts, I will let you know.
I have not been able to get the sd card working. I have tried everything I can think of. Pullup resistors, bypass caps. I'm beginning to believe the 3 cards I have are incompatible?
@DR. A
I FINALLY got the sd card working. After the frustration of wiring the breakout board, then adding bypass caps AND RESISTORS.... to realize that the card is incorrectly formatted. SO, FSRW is working on both the breakout and the screen. I haven't done much other than run the speed test a few times. I've been busy with other things, *more about that in a moment.*
RE. the ram chip.
I missed my chance to buy a couple of those chips. Yesterday my wife got her package from Parallax, containing the 1 continuous rotation servo I THOUGH we'd need *along with a refresher kit and new wheeeles!* to revive my old 02 era boe bot. To my dismay, when I FINALLY tested the old servo for the first time in a few years it was dead. SO... after ordering another servo *like I should have done in the first place,* my wife has told me no more ordering parts... I have several OLD 150 - 180 ns sram's, 2 - 8k x8 : 9 - 2k x8. I did score a 62256 ( 32k x8). My old srams seem like more work than they'd be worth. I need to find another 32k, if those would even work.
For single guys that are contemplating marriage, please take heed of this young mans demise. Be sure to include a clause within your prenuptial agreement that allows you to order parts for your electronic projects, irregardless of any financial crisis or disapproval from your future spouse
Comments
-Phil
Wait up a minute, CP/M on the Prop was me!
Dr A is amazing, and his work and encouragement (Not forgetting Cluso and a cast of thousands) pushed CP/M on the Prop much further than I would ever have imagined.
Heater is correct. And his avatar is "Zicog". Plus he invented Zog who is bigger than all of us!
I've coded a simple demo program. 40x15 white on blue screen using the propeller font. One font. No graphics. Font is stored in hub, so no external ram needed. Useful for debugging as you need something simple to display the debugging information.
Thanks,
Tyler
Gnd is pin 1, and pin 2 is 5V. That plus the 4 SD pins is the minimum you need to get the SD card working.
Correct, but this board has an onboard 3V3 regulator. So you have to give it 5V.
Also, just for posterity, this is the code to print text using the propeller's internal font. Useful for debugging an SD card as the SD card needs to work in order to display a font that is stored on the SD card. Now (slowly) you can at least print some debug messages without needing the SD card.
Edit: I just found the parts list and it looks like they use a 47 ohm resistor and you use only one. The resistor is tied to P6 or VDD depending on where you solder it. I'm making a DIY board with the platform using 16 bit input and having the Back light jumpered to either the Propeller or VDD
Mabye the code is part of the problem. All help is appreciated.
Thanks,
Tyler
Cool. It looks like one prop pin is being used to turn the backlight on and off. That would work but it does use a precious prop pin. I'd just tie it to 5V with the appropriate resistor.
@Tyler, I've not used fsrw but others may chime in. I presume you have 10k pullups on those pins?
BTW you might like to add a few second delay after the pst.start call to give yourself time to get pst running on the pc.
Yes i am using 10k pullups. Thanks i'll try another sd object.
Have added xmodem for file transfers. This adds a serial port and reuses the propeller download port for transferring data. Xmodem transfers from a terminal program (eg hyperterminal) are a little tedious opening and closing programs, but they work very well from an IDE, eg an IDE that compiles/dowloads/runs C programs.
We can do similar things for Spin as there are command line spin compilers. Design your icon in such a program, design your desktop layout, save this as an .ini file, then transfer the file with xmodem. Programs are compiled binary files sitting on an SD card. In Kyedos, such programs have an .exe extension, and to find out what programs are available you type "DIR *.EXE" and then look at the list eg MYPROG.EXE and then type "MYPROG" and it reboots the propeller chip and runs that program.
On a touchscreen it is a bit different - you would associate the file with an icon, define where the icon is on the screen, and then when you touch that part of the screen it reboots the propeller and runs that program.
xmodem transfer in action
What does work though is to have an operating system which can load other programs. Don't try to leave cogs running between programs - just load them in again. The time penalty is only minimal. And you can share common code by using common objects. So yes it is a little inefficient as you reboot and load up a cog with exactly the same code you had before, but the advantage is that there is no complexity with trying to understand the concept of registries. The .exe program is self contained. It also makes testing easier - test out the .exe program with F10 downloads and when it is ready, do an F8 and save to the SD card directly by typing the path and name into the save box on F8. Name as .exe
So you can write an .exe for a TV display, and one for VGA, and one for the ILI touchscreen. Each is self contained. Each probably has many objects in common (eg SD driver). But there are no #ifdefs needed. Ideally, try to make it such that changing one object, like a display object, is all you need to do (ie, use the common methods like .hex, .out, .decimal).
Just to demonstrate, I replaced the movie player code with this line of code. Touch the movie icon and this runs:
and that reboots the propeller and runs movie.exe. Time to reboot and run is about 1 second. The screen need not blank during this time if you don't want it to. The program reboots the propeller at the end which returns to the main program.
The movie player program is fairly short as it does not need the touch part of the touchscreen, nor keyboard, nor serial port etc etc. It uses the same display object code as the main operating system.
The aim now is to automate the icon placement and program association.
Optimised for transferring data from ram to the display, for fast updates of fonts etc. The Spin version is at least 4x faster than previous versions and in Spin the code to move one pixel comes down to just 4 lines of code.
Things like moving from the propeller to the ram are a little slower, but fonts only need to be loaded into ram once. Board is not fully populated - has room for a real time clock and some digital and analog I/O and stereo sound and a keyboard. The SD socket is not going to be needed as while this board was being made, other clever people on the forum got the display's SD card working by removing three resistors on the back of the display.
Once this is ported over to pasm it should really fly!
The board has two 512k ram chips in parallel so it works with words rather than bytes.
Got to go to work - I'll post a schematic shortly. Code is below
[video=youtube_share;cu8HJPWWDDw]
Blink and you will miss it. The Text is still in Spin - it is the redraw of the screen that is fast. I timed a loop 100x and it is 3seconds so that is 30milliseconds to refresh the screen. A bit faster than the 9 seconds in Spin! This circuit has been optimised for speed sending data from the ram directly to the display. The final pasm loop per pixel comes down to this:
Now to go back and work on optimising other things. At the moment SD transfers are too slow as it is sending data to ram in pieces. So need to have the SD card on some dedicated propeller pins.
So in general terms, need fast transfer from SD to ram, and fast transfer from ram to the display.
At the moment I have two boards and they are each optimised to do one of these. Need to combine these into one board now.
[video=youtube_share;WDnrjIzFUnI]
Also re your PM, attached is the eagle library file for the 512k ram chip. I have some other parts as well if you want them.
I have not been able to get the sd card working. I have tried everything I can think of. Pullup resistors, bypass caps. I'm beginning to believe the 3 cards I have are incompatible?
I FINALLY got the sd card working. After the frustration of wiring the breakout board, then adding bypass caps AND RESISTORS.... to realize that the card is incorrectly formatted. SO, FSRW is working on both the breakout and the screen. I haven't done much other than run the speed test a few times. I've been busy with other things, *more about that in a moment.*
RE. the ram chip.
I missed my chance to buy a couple of those chips. Yesterday my wife got her package from Parallax, containing the 1 continuous rotation servo I THOUGH we'd need *along with a refresher kit and new wheeeles!* to revive my old 02 era boe bot. To my dismay, when I FINALLY tested the old servo for the first time in a few years it was dead. SO... after ordering another servo *like I should have done in the first place,* my wife has told me no more ordering parts... I have several OLD 150 - 180 ns sram's, 2 - 8k x8 : 9 - 2k x8. I did score a 62256 ( 32k x8). My old srams seem like more work than they'd be worth. I need to find another 32k, if those would even work.
For single guys that are contemplating marriage, please take heed of this young mans demise. Be sure to include a clause within your prenuptial agreement that allows you to order parts for your electronic projects, irregardless of any financial crisis or disapproval from your future spouse
Bruce