I just wanted to let you know about radiobutton.
I have everything working now for the most part. I noticed on the music font there is 1 white pixel @ 0,0 that should not be there? I'm going to do some more digging... Building the Logic Analyzer has proven a bigger chore than thought since the tip on my iron is done. Now I must wait till Tuesday to get a new one.
I was recording a utube video, but the baby woke up. I'll try again during his next nap.
There's still some exploring to do as to the display issue. I want to port portions over to C so I can experiment with OTHER stuff. *no spoiler alert today *
Also on the to-do list is finish the chiptune player. I have the new transport, now to bind the controls and get a NICE font working instead of the debugging font. Also need to finish the transport buttons. I'm going to do the masking on the BMP so all I have to do is re-draw the button with the correct color bmp. Should be fairly simple and will be compatible with the ILI.
Gotta run! Thanks again for everything Doc!
*edit*
Could you post updated SD file system? I'm missing the HTML bmps. I think we could pull off 16x16 if we used a few cogs
Another edit, Got my latest demo ready. I need to show some people in the area. I squeezed chiptune player into the last little bit of space. 272 longs free!
Boards arrived today! Unfortunately I'm too busy to work on them ATM.
I've been watching the "other" post and you guys have done a lot of work! Keep up the good work!
So those boards work fine with the smaller ILI9325 displays and no hardware modifications. With your code mods you should be able to get the SSD1289 working - use the display socket on the right as that is the one with the SD card connected.
When the MCP23008 boards arrive we both will need to rewrite our code. I've been recycling most components off old boards by desoldering. Some components don't desolder very well (ie the ones with many pins) and I tend to abandon sockets, plugs and resistor SIL arrays.
If you are running out of space we can either move more things into objects and then have separate loadable programs like the standalone movie player, or we can move over to C. The move to C is a little daunting for me as a Basic/Spin programmer but I am starting to get a feel for what -> and :: and * mean. I'm hoping real soon we can have a design where we can get some other builders involved. The /CS thing on the SSD1289 has put things back a few weeks but I think we are back on track now.
Well, the dual-screen board is 99% built. I'm missing the input cap and need to fudge some of the other vreg caps. The 2- 470uf's are getting 100uf's. The 22uf tant will most likely be replaced with a 10uf EL, maybe 100 uf EL. Should work?
A revision note for the future, could you use polarized caps on the propeller chip? I usually use tants *a 4.7uf on the PLL side.
Those caps should be fine. If you are running from a wall wart you may not need an input cap - most wall warts I have pulled to bits have 4700uF inside them.
Re tants vs electrolytics, that could start a long debate! Suffice to say nothing is set in stone and you can solder in different caps if you want as long as the voltage rating is ok and the value is roughly the same.
Well, the dual-screen board is 99% built. I'm missing the input cap and need to fudge some of the other vreg caps. The 2- 470uf's are getting 100uf's. The 22uf tant will most likely be replaced with a 10uf EL, maybe 100 uf EL. Should work?
A revision note for the future, could you use polarized caps on the propeller chip? I usually use tants *a 4.7uf on the PLL side.
Well I suppose I had better go and read the data sheet! For the switchers http://pdf1.alldatasheet.com/datasheet-pdf/view/203238/NSC/LM2575T-5.0.html page 1 for the official values of 100uF on the input and 330uF on the output and scroll down to page 18 for a discussion of the capacitor types and values.
If you are using linear regulators (this board can have either) then check the data sheet for those.
Re the propeller caps - yes Sapieha is right, always use a tantalum.
Very good points! I don't want to start the discussion of what cap is better BUT.
Propeller chips ALWAYS get .1uf tant and 4.7uf tant on PLL side. *I'm out of 4.7s right now so using stock .1 tant for pll. Should be fine for standard clocked board.* I have also used ceramics in the past but don't recommend. EL's would be a no-no. The large caps are EL of course. The rest of the caps are ceramic, except for audio caps.
With my "standard" linear regulator design, I use .1 ceramic or tant on the input and output of vregs, right next to the regulator. Input cap will be from 100uf to 470uf. Output is usually a 100uf but I've used 10ufs before with no issues. The regulators I'm using look good with a wide range of caps.
The 22uf tant is the only one throwing me off. Suck a 10uf in and I'm preparing to pre-power test. Then smoke test!
*edit*
OOPS. I guess I loaded the .01uf audio caps with .1uf. I'm out of .01s? Will changing the resistor to 100 ohms hurt anything? Also, I still have no '08 so had to fudge in an '00 again.
I think You have write error --- Else You use bad capacitor with Propeller. .1uF shall always be Ceramic capacitor as it have better response to frequencies DECOUPLING capacitor shall answer for.
And all other decoupling capacitors on all IC's 0.1uF shall be Ceramic ones to.
4.7uF are to small -- it need's be at least 10uF
And You need have both ones on this side for all Frequencies --- If You will have stable PLL --- That not burn after some work time
Very good points! I don't want to start the discussion of what cap is better BUT.
Propeller chips ALWAYS get .1uf tant and 4.7uf tant on PLL side. *I'm out of 4.7s right now so using stock .1 tant for pll. Should be fine for standard clocked board.* I have also used ceramics in the past but don't recommend. EL's would be a no-no. The large caps are EL of course. The rest of the caps are ceramic, except for audio caps.
With my "standard" linear regulator design, I use .1 ceramic or tant on the input and output of vregs, right next to the regulator. Input cap will be from 100uf to 470uf. Output is usually a 100uf but I've used 10ufs before with no issues. The regulators I'm using look good with a wide range of caps.
The 22uf tant is the only one throwing me off. Suck a 10uf in and I'm preparing to pre-power test. Then smoke test!
Sapieha, thank you for those corrections. I had been using the tant layout I described but will use your recommendations from now on.
The board is built and just passed 1'st smoke test. Now to load the sockets and try again!
*edited*
I'm updating the dual screen driver and have a note:
PUB TouchXPercent
if ssd1289
result := 100 - (TouchValue & 255)
else
result := TouchValue & 255 ' decode xval 0-100%
X values are swapped. Could also be fixed when starting the D/A conversion?
ALSO!
[code]
ILIcmd($0001,$4B3F) ' set SS and SM bit 0001 0000 landscape
instead of
ILIcmd($0001,$6B3F) ' set SS and SM bit 0001 0000 landscape
Well I had the board working, now I get nothing... Well it wasn't exactly working, but it was close. Propfont was drawing wrong? FixGlitch no longer works? Scratching my head now!
I have revived the ORIGINAL board, this time with a more permanent voltage regulator fix. The reason for this is the original board is stable for the most part and I've been meaning to finish up work on the cache driver. I really like the first board, other than the problem with my display. I've started work on a logic analyzer that plugs in between the board and display. Should help with debugging.
Now the question that's eating at me, how will the SSD 1963 play with our boards? I've also been wondering about Ray's DVI graphics shield. How cool would it be to have one of the dual-screen boards with a 7" touchscreen and DVI out!
I'm still working on the cache driver for the original board. Seems to me locks need to be implemented on the bus so cache driver cog and display driver cog don't conflict. So anytime one of the propeller's cogs needs to access the bus, we need to lock the bus first:
*in asm*
lck_bus lockset lock_id wc
if_c jmp #lck_bus
and then unlock the bus when done
lockclr lock_id
There's also an optimization you might be interested in:
'-----------------------------------------------
' setups needed for burst read
'-----------------------------------------------
_frqa long $1000_0000
_ctra long 4<<26 | 19 ' NCO mode on P19
_phsa long $0000_0000 ' phsa offset for adjusting clock start
_frqb long 2 ' phsb accumulates twice per edge
_ctrb long $A<<26| 19 ' Edge Accumulate mode on P19
'----------------------------------------------------------------------------------------------------
mov frqa, _frqa ' setup NCO freq
mov frqb, _frqb ' setup EDGE freq
'
' rd_cache_line - read a cache line from external memory
'
' vmaddr is the external memory address to read
' hubaddr is the hub memory address to write
' line_size is the number of bytes to read
'
'----------------------------------------------------------------------------------------------------
rd_cache_line ' command T pasmramtohub
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
and dira,maskP16P31 ' set P0-P15 as inputs
andn outa,maskP16 ' memory /rd low
or outa,maskP19
mov phsa, _phsa ' init counters phsa
mov phsb, ptr ' save hub ptr to phsb
mov ctrb, _ctrb ' set ctr be mode
andn outa,maskP19 ' start counters
rdword data_16,phsb ' sync up only
mov ctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointer
mov data_16,ina ' get first data
wrword data_16,phsb ' move data to hub
djnz count,#ramtohub_loop
or outa,maskP19 ' stop clock
mov ctra, #0 ' stop counter
or outa,maskP16 ' memory /rd high
or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs
and dira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret ret
I realize the MPC board will require a re-write of the entire code, I'm just trying to get experience with GCC, SimpleIDE and the like. To be honest, I'm in completely over my head with the C and C++ but gotta start somewhere. I am quite happy with the cache driver numbers, although locking may impact them slightly.
Work on the chiptune player has begun again. I'm just pondering "skinning" the player. There are also some glaring bugs in the code. Hopefully I will be able to post a utube video soon.
Now the question that's eating at me, how will the SSD 1963 play with our boards? I've also been wondering about Ray's DVI graphics shield. How cool would it be to have one of the dual-screen boards with a 7" touchscreen and DVI out!
Yes - need to get the SSD1963 working properly. I had it working at one point with a stable picture and I should have saved that as a "restore point" as I can't replicate it again. I'm going to wait until the MCP23008 boards arrive.
The MCP23008 boards are on the way and that will take things backwards for a bit porting code over but I think it will be worth it as we will have independent control of the /cs lines.
Um, we have SSD1289's. I'd like to port over to the SSD 1963 as well. I was able to get the dual screen barely working, and then broke it. I will explore this later since getting C fully working is very important.
Ray's DVI graphics shield is built on the SSD1963, and the 5" and 7" displays I'm interested are as well. I'm hoping the issues we're having with the SSD1289 will not re-appear when transitioning to the 1963. I need to take a closer look at Ray's shield to determine if this will work the way I hope.
I was hoping to place my parts order today but once again life has interrupted. The kitty I had given away 5 years ago has come home! Sadly there is a growth on his neck that needs medical attention. So parts will need to wait until kitty is taken care of
Yes you are right I got the display numbers muddled.
I've been experimenting with moving most of the code into an "object". I think it makes it easier to understand. It isn't quite right yet eg the drawing of the icons is done within the object and ideally I'd like to draw them from a .ini file rather than from code.
Even better, somehow when we compile a program to a .bin or .exe file, create an icon to go with that program. Then the desktop can be rearranged to reflect working programs.
Jut to flat this line in the begin function of the object
Start_ILI9325(2) ' start the display 0 = ILI9325 single, 1 = SSD1289 single, 2 ILI9325 double, 3, SSD1289 double
@averagejoe, can you please PM me sometime with your new address so I can send you the next lot of parts and boards.
I'm in the process of writing some string routines.
In a roundabout way, I want to store the icon locations and list of programs in a text file on the sd card. To process that, it would be very helpful to be able to easily load text files into string arrays, and vice versa. And to manipulate those string arrays - search for file matches, strip off extensions etc.
Then I had another idea. Since we have an external ram chip, why not store all strings in external ram? That saves lots of hub space, and as an additional benefit, one does not have to try to conserve string space.
So - all strings are up to 128 bytes long. And they are in an array and you make that array as big as you like with a DIM command.
Not finished yet but I think this is a path towards a text editor as well.
' ************** string routines stored in external memory so can have arrays and large text files **********************
' to make things simpler, one array StringArray. any number of entries, each up to 128 characters
' pass the source and destination numbers
' TextArray(256) = 256 entries for text files etc
' first entry is destination, second entrie(s) are the source
' Commands are
' StringDimTextArray ' reserves memory 256*128, increments filenumber, adds filesize
' StringLoadFile(Name,S) ' read a .txt file off the SD card and stores in TextArray, new string entry is crlf
' StringSaveFile(Name,S,F) ' save .txt file from TextArray to SD card adding in crlf, Start to Finish
' StringClear(Dest) ' clear a string, pass string number
' StringAddChar(Dest,N) ' adds a character to a string at end
' StringSubChar(Dest) ' remove a character from the end
' StringCopy(Dest,Src) ' copy string from one location to another
' StringStore(Dest,Src) ' convert Prop string("mystring") to string stored in external memory
' StringLeft(Dest,Src,N) ' Basic Left$
' StringMid(Dest,Src,L,N) ' Basic Mid$
' StringRight ' Basic Right$
' StringInstr ' Basic Instr
' StringUcase(Dest,Src) ' Basic Ucase$
' StringLcase ' Basic Lcase$
' StringLen ' Length
' StringStr ' string representation of a number
' StringHex(Dest,N) ' number to hex string
' StringBin ' number to binary string
' StringVal ' value (add "&H" at beginning if a hex number, "&B" if a binary number)
' StringJoin(Dest,Src1,Src2) ' same as Basic + with strings
' StringDebug(n) ' print using the green propeller font string number n
' use these routines amongst others.
'integerToDecimal(number, length) '' 5 Stack Longs
'integerToHexadecimal(number, length) '' 5 Stack Longs
'integerToBinary(number, length) '' 5 Stack Longs
'decimalToInteger(characters) | sign '' 10 Stack Longs
'hexadecimalToInteger(characters) | sign '' 10 Stack Longs
'binaryToInteger(characters) | sign '' 10 Stack Longs
PUB StringTest ' test all the string routines
StringDim(10)
StringStore(5,string("Hello World"))
StringDebug(5)
'StringAddChar(5,"s")
'StringDebug(5)
'StringSubChar(5) ' remove one character from the right, useful for backspace etc
'StringDebug(5)
'StringCopy(7,5) ' copy
'StringDebug(7)
'StringLeft(7,7,5) ' source and destination the same or different
'StringDebug(7)
'StringMid(8,5,7,3) ' dest, source, starting byte, number of bytes. first byte is 1
'StringDebug(8)
'StringRight(3,5,4) ' dest, source, number of bytes
'StringDebug(3)
'Hex(StringInstr(5,2,"o"),2) ' find this character starting at 2
'StringBin(2,255) ' convert a number to binary
'StringDebug(2)
StringHex(4,100)
StringDebug(4)
repeat
PUB StringDim(n) ' reserve space for a string array, n= number of strings, 128 max bytes per string
Ramsize[Filenumber] := n << 7 ' * 128
StringAddress := NextLocation ' get the location of the string array
Filenumber += 1
PUB StringStore(StringN,Source) ' store a propeller string("test") to array number Dest
bytemove(@rambuffer, Source, (strsize(Source) + 1)) ' move to rambuffer array
StringToRam(StringN)
PUB StringDebug(StringN) ' print using the green propeller font
RamToString(StringN)
Text(@rambuffer) ' print it out
PUB StringClear(StringN)
bytefill(@rambuffer,0,128) ' only really need to do the first one but may help debugging to completely clear the string
StringToRam(StringN)
PUB StringAddChar(StringN,c) ' add c to the string
RamToString(StringN) ' get the string
byte[@rambuffer][strsize(@rambuffer)+1] := 0 ' add in the new zero (can't assume array is cleared)
byte[@rambuffer][strsize(@rambuffer)] := c
StringToRam(StringN) ' store back to ram
PUB StringSubChar(StringN) ' remove one character from the right same as strings.left(strings.len - 1)
RamToString(StringN)
byte[@rambuffer][strsize(@rambuffer)-1] :=0
StringToRam(StringN)
PUB StringCopy(Dest,Source) ' copy string from source to dest
RamToString(Source)
StringToRam(Dest)
PUB StringLeft(Dest,Source,n) ' Basic Left$
RamToString(Source)
byte[@rambuffer][n] := 0 ' move the terminator
StringToRam(Dest) ' move back to ram
PUB StringMid(Dest,Source,start,n) | i ' Basic Mid$
RamToString(Source)
repeat i from 0 to n-1
byte[@rambuffer][i] := byte[@rambuffer][i+start-1] ' possibly could use bytemove here
byte[@rambuffer][n] := 0 'add in the new zero terminator
StringToRam(Dest)
PUB StringRight(Dest,Source,n) | i,m
RamToString(Source)
m := strsize(@rambuffer) - n
repeat i from 0 to n ' Basic Right$. include the terminator
byte[@rambuffer][i] := byte[@rambuffer][i+m]
StringToRam(Dest)
PUB StringInstr(Source,Start,c) | i ' find c in the string starting at start
RamToString(Source)
result := 0 ' return 0 if not found
repeat i from (start-1) to strsize(@rambuffer)
if byte[@rambuffer][i] == c
result := i+1 ' 1 is first character
quit
PUB StringBin(Dest,n) ' convert n to a binary value at Dest
repeat result from 31 to 0
byte[@rambuffer][result] := ((n & 1) + "0")
n >>= 1
byte[@rambuffer][32] := 0 ' add zero terminator
StringToRam(Dest) ' store
PUB StringHex(Dest,n) ' number to hex, always 8 characters
repeat result from 7 to 0
byte[@rambuffer][result] := lookupz((n & $F): "0".."9", "A".."F")
n >>= 4
byte[@rambuffer][8] := 0 ' zero at end
StringToRam(Dest)
PRI StringToRam(StringN)
HubToRam(StringN<<7 + StringAddress,128)
PRI RamToString(StringN)
RamToHub(StringN<<7+StringAddress,128) ' moves to rambuffer array
' ***************** end string routines *************************
Great work Doc!
I've been studying Raymond's DVI board and trying to understand how to interface it with our boards. I think it would be nice to have DVI out as an option. Still stuck on datasheets and such.
The port of the chiptune player is riddled with bugs I'm working out. It's functional, but there are issues.
I've spent a few hours working on a C wrapper for low level spin functions. Work is slow due to my lack of C experience. Hopefully I will be able to pick up speed as I go.
Sending you a PM now!
@averagejoe, the MCP2008 boards have arrived - I'm just waiting on the parts so I can send you both together. I haven't soldered mine up yet as I've been completing a massive rewrite of the code so that now every icon on the screen runs a separate binary program.
Needed cunning things like a "warm boot" which is faster where we can store some parameters in the external ram as that stays static when the propeller is rebooted.
I'm also thinking of porting the desktop program to something that reads a file. Or at the very least has the .exe and the icons as the same filename! Need to store four things, exe filename, icon, x position and y position. I think an Excel .csv file might be the easiest.
Anyway, the desktop loader is called Desktop.spin and this is the code:
CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000
OBJ
tch: "Touch" ' touchscreen driver
PUB Main | wcboot ' warm or cold boot
wcboot := tch.Begin(2,true) ' display type 2 = dual ILI9325, true is desktop
if wcboot == false ' erase ram chip, checks if a cold or warm boot, sets some variables
tch.Clearscreen(tch.RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
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
else ' warm boot
tch.ManualValues ' coming from outside so reset ramsize and ramlocation values for 0 and 1
DrawDesktop ' quick redraw of desktop if a warm boot
tch.SelectSPIGroup ' selects this group and starts the cog
Touchscreen ' wait for input
PUB TouchScreen | yval, xval,pointer
repeat
yval := tch.TouchYPercent ' decode yval 0-100%
xval := tch.TouchXPercent ' decode xval 0-100%
if (xval <> 255) and (yval <> 255)
'tch.SelectMemGroup
'hex(xval,2) ' if display any debug messages need to restart the SPI cog as it has been stopped by the debug display
'hex(yval,2)
'repeat
pointer := (yval/20)*4+(xval/25) ' so can use a case statement 0-19
if pointer < 20
tch.SelectMemGroup
case pointer ' 0 to 19
0:
1:
2:
3:
4:
5:
6:
7:
8: tch.Chain(string("PHOTO.EXE"))
9: tch.Chain(string("CALC.EXE")) ' chain this precompiled program
10: tch.Chain(string("LOREM.EXE"))
11: tch.Chain(string("MOVIE.EXE")) 'chain this precompiled program
12: tch.Chain(string("KEYBOARD.EXE"))
13: tch.Chain(string("MUSIC.EXE"))
14: tch.Chain(string("WAVDEMO.EXE"))
15: tch.Chain(string("BUTTONS.EXE"))
16: tch.Chain(string("SYNTHDRC.EXE"))
17: tch.Chain(string("HTML.EXE"))
18:
19:
tch.SetOrientation(true)
tch.SelectMemGroup ' ready for mem out
DrawDesktop ' redraw the background
tch.SelectSPIGroup ' restart the spi driver
PUB LoadIcons ' load all the icons onto the screen. Possibly use a .ini text file for this
tch.SDBMPtoRam(string("mask.bmp")) ' file number 1
tch.MergeBackgroundIconRam(string("photos.bmp"),0,120) ' file number 2 and leaves filenumber as 2 ready for the next one
tch.MergeBackgroundIconRam(string("calc.bmp"),60,120) ' draw an icon onto the background
tch.MergeBackgroundIconRam(string("facebook.bmp"),120,120) ' draw an icon
tch.MergeBackgroundIconRam(string("videos.bmp"),180,120) ' draw an icon
tch.MergeBackgroundIconRam(string("notes.bmp"),0,180) ' draw an icon
tch.MergeBackgroundIconRam(string("music.bmp"),60,180) ' draw an icon
tch.MergeBackgroundIconRam(string("ipod.bmp"),120,180) ' draw an icon
tch.MergeBackgroundIconRam(string("prop.bmp"),180,180) ' prop icon for a GUI buttons, radio, checkboxes etc
tch.MergeBackgroundIconRam(string("itunes.bmp"),0,240) ' play some music
tch.MergeBackgroundIconRam(string("safari.bmp"),60,240) ' html (better GUI modelled on Opera rather than Windows)
DrawDesktop
PUB DrawDesktop
tch.DrawBMPRam(1,0,0) ' file number 1, location 0,0
PUB LoadDesktop ' first bmp file is not deleted wtih clearramdiskexcludedesktop
tch.SDBMPtoRam(string("balloon.bmp")) ' file number 1
and as an example, the photo viewer program
CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000
OBJ
tch: "Touch" ' touchscreen driver
PUB Main | touchtest ' debug value
tch.Begin(2,false) ' display type 2 = dual ILI9325, false means run a program not the desktop so don't load icons
PhotoAlbum
tch.SetWarmBoot ' clears screen, sets a warm boot and reboots
PUB PhotoAlbum | picturenumber
tch.Clearscreen(%00000000_00000000) ' clear the screen
tch.SetCursor(0,0)
tch.Text(string("Please wait 8s"))
tch.ClearRam
tch.SDBMPtoRam(string("slide1.bmp")) ' file 2
tch.SDBMPtoRam(string("slide2.bmp")) ' file 3
tch.SDBMPtoRam(string("slide3.bmp")) ' file 4
tch.SDBMPtoRam(string("slide4.bmp")) ' file 5
tch.SDBMPtoRam(string("slide5.bmp")) ' file 6
picturenumber := 2
repeat until picturenumber > 6
tch.DrawBMPRam(Picturenumber,0,0) ' draw the picture
result := tch.TouchSwishY ' swish left to right or up to down depending on orientation
if result > 0
picturenumber --
else
picturenumber ++
tch.Clearscreen(%00000000_00000000)
tch.pause1ms(1000) ' otherwise still touching the screen
The touch object has all sorts of useful things and I'm sure it will end up being changed and edited.
I think the important thing is that a typical program, eg the slide viewer above, is only using about half the hub ram. So for a program, and despite all the overheads of driving sd card, touchscreens, displays etc, there are still propeller pins free and half the memory free.
I'll see if I can get the desktop loading from a .csv file . Hmm - maybe even need an "edit" mode for the desktop so you can move icons around by dragging them with a finger?
Hi Doc,
I finished moving, cleaning, and all the various things that have occupied me for the past 2 weeks. I am by no means unpacked, but I've "found" all the things I need to get working again. With some luck, I'll be able to get the Ez-LCD301 working with the V1 board. It's my current "standard" board as it works for the most part. I've not been able to get the v2 board working yet, although it's fully built. Hopefully the v3 board will work with these dang ssd1289's! If not, I would still like to reference the OTHER ssd. Maybe those will work on all boards? $50 is out of my budget right now for such an experiment, since I still don't have the other 2 displays I ordered. Next week...
I was able to place a parts order that showed up today, okay well HALF showed up today. I have sockets, hc32's, hc08's as well as some other nice toys. I also ordered more SRAMs since having more than one board running at a time is a plus.. I need to talk to Steve about the board I sent him.
I could also use some advise about larger EEPROMs. I like the idea of having a larger eeprom that could hold "presets" or such.
Must run for now. Keep up the awesome work!
*edit*
After much thought, I have come up with the name
"DracBurger Touch"
Any thoughts?
Re names - no need for the Drac bit - I've already got a series of boards with Drac in the name so you can have the whole name.
I will get around to soldering the latest board soon. Meanwhile, I have managed to simplify the entire operating system right down to this little bit of code:
CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000
OBJ
tch: "Touch" ' touchscreen driver
PUB Main | wcboot ' warm or cold boot
wcboot := tch.Begin(2,true) ' display type 2 = dual ILI9325, true is desktop
if wcboot == false ' erase ram chip, checks if a cold or warm boot, sets some variables
tch.Clearscreen(tch.RGBtoWord(0,0,0)) ' clear screen to black - uses the display driver above
tch.SDBMPtoRam(string("desktop.bmp")) ' file number 1, a 240x320 file called desktop.bmp
DrawDesktop
LoadDesktopCSV
DrawIcons
else ' warm boot
tch.ManualValues ' coming from outside so reset ramsize and ramlocation values for 0 and 1
DrawDesktop ' quick redraw of desktop if a warm boot
LoadDesktopCSV
tch.SelectSPIGroup ' selects this group and starts the cog
Touchscreen ' wait for input
PUB TouchScreen | yval, xval,pointer
repeat
yval := tch.TouchYPercent ' decode yval 0-100%
xval := tch.TouchXPercent ' decode xval 0-100%
if (xval <> 255) and (yval <> 255)
pointer := (yval/20)*4+(xval/25) ' reduce to a value 0-19 so can read the correct string for the file name
if pointer < 20 ' there are spaces for 20 icons on the screen 4 wide 5 high
tch.SelectMemGroup
tch.StringJoin(85,pointer+60,81) ' filename plus .exe
tch.Chain(tch.stringrambuffer(85)) ' run this filename
PUB DrawDesktop
tch.DrawBMPRam(1,0,0) ' file number 1, location 0,0
PUB LoadDesktopCSV | n ' load the file desktop.csv (Excel csv file with icon locations)
tch.SDBMPtoRam(string("mask.bmp")) ' file 2, load this here - if load after the strings get a white line on the icons
tch.StringDim(85) ' file number 3 is all the strings
tch.StringStore(80,string("desktop.csv")) ' filename to load
tch.StringLoadfile(80,0) ' load from 0 to 19 (20 lines of text in a desktop.csv file)
repeat n from 0 to 19
CutupComma(n)
tch.StringStore(81,string(".exe")) ' store exe extension for later
tch.StringStore(82,string(".bmp")) ' store .bmp extension
tch.StringStore(83,string("blank")) ' store for later
' array 0-19 are raw string, 20-39 are x, 40-59 are y, 60-79 are filename with no extension or "blank"
PUB DrawIcons | n,x,y
repeat n from 60 to 79 ' draw the icons - mask alredy loaded in file 2 when loading desktop
if tch.StringCompare(n,83) == false ' is this entry "blank"?
tch.StringJoin(85,n,82) ' create filename.bmp
x := tch.StringVal(n-40) ' need to pre-evaluate these, can't put in the mergebackground routine
y := tch.StringVal(n-20)
tch.MergeBackgroundIconRam(tch.stringrambuffer(85),x,y,1,2,4) ' desktop file 1, mask file 2, icons in file 4
DrawDesktop
PUB CutupComma(Source) | c1,c2,len ' pass source 0-19, dest = 20-39 for first group, 40-59 for second group etc
c1 := tch.StringInstr(Source,1,",") ' first comma
c2 := tch.StringInstr(Source,c1+1,",") ' second comma
len := tch.StringLen(Source) ' length
tch.StringLeft(Source+20,Source,c1-1) ' first value
tch.StringMid(Source+40,Source,c1+1,c2-c1-1) ' second value
tch.StringRight(Source+60,Source,len-c2) ' third value = filename with no extension
It is now super simple. The background is a file called "desktop.bmp". All files that you run (eg calc.exe) have an associated file "calc.bmp" for the icon.
The locations of the icons and the files are stored in a standard .csv file made with Excel
For any program you want to run you write a new separate program. Use the "touch.spin" library with all sorts of useful routines. Last line in a .exe program is to call a warm boot which loads the desktop out of ram which means it is only about 1 second to chain programs or to go from a program back to the desktop operating system.
You can pass all sorts of things between chained programs as the external ram stays static.
There is a huge amount of string space now that strings are in external ram. All strings are fixed length 128 bytes (I've never been a great fan of variable length strings as every now and then you have to clean them up, eg MBASIC used to just freeze at random intervals every 10 mins or so). Who cares about how much space is wasted when strings are in external ram. 8192 strings of 128 bytes each if you want them.
re bigger eeprom, I am wondering if you can achieve the same effect by using the SD card?
Addit 20th June - working on porting over to the MCP23008 chip. Got pins going high and low. Need to rewrite all the code that talks to the display next.
'' Simple I2C MCP23008 demonstration J Moxham
'' output to pins (see MCP23016 objects in the Obex for input and other commmands)
'' Thanks to James Burrows and Michael Green
'' based on C code http://www.nutsvolts.com/index.php?/blog/post/adding_more_digital_i_o_to_your_16_bit_microcontroller_experiments_part_2_t
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
SCL = 28 ' pins never change
SDA = 29
PUB i2c_Demo
i2c_Initialize ' start the driver
i2c_writelocation($40,$0,$0) ' write to device $40 MCP23008, all pins are outputs
repeat
i2c_writelocation($40,$09,%11111110) ' device $40, address $09 is output - leds are active low
waitcnt((clkfreq/2)+cnt) ' small delay
i2c_writelocation($40,$09,%11111101) ' next led on
waitcnt((clkfreq/2)+cnt)
i2c_writelocation($40,$09,%11111011)
waitcnt((clkfreq/2)+cnt)
i2c_writelocation($40,$09,%11110111)
waitcnt((clkfreq/2)+cnt)
i2c_writelocation($40,$09,%11101111)
waitcnt((clkfreq/2)+cnt)
i2c_writelocation($40,$09,%11011111)
waitcnt((clkfreq/2)+cnt)
i2c_writelocation($40,$09,%10111111)
waitcnt((clkfreq/2)+cnt)
i2c_writelocation($40,$09,%01111111)
waitcnt((clkfreq/2)+cnt)
PUB i2c_Initialize ' An I2C device may be left in an
outa[SCL] := 1 ' reinitialized. Drive SCL high.
dira[SCL] := 1
dira[SDA] := 0 ' Set SDA as input
repeat 9
outa[SCL] := 0 ' Put out up to 9 clock pulses
outa[SCL] := 1
if ina[SDA] ' Repeat if SDA not driven high
quit ' by the EEPROM
PUB i2c_Start ' SDA goes HIGH to LOW with SCL HIGH
outa[SCL]~~ ' Initially drive SCL HIGH
dira[SCL]~~
outa[SDA]~~ ' Initially drive SDA HIGH
dira[SDA]~~
outa[SDA]~ ' Now drive SDA LOW
outa[SCL]~ ' Leave SCL LOW
PUB i2c_Stop ' SDA goes LOW to HIGH with SCL High
outa[SCL]~~ ' Drive SCL HIGH
outa[SDA]~~ ' then SDA HIGH
dira[SCL]~ ' Now let them float
dira[SDA]~ ' If pullups present, they'll stay HIGH
PUB i2c_Write(data) ': ackbit
'' Write i2c data. Data byte is output MSB first, SDA data line is valid
'' only while the SCL line is HIGH. Data is always 8 bits (+ ACK/NAK).
'' SDA is assumed LOW and SCL and SDA are both left in the LOW state.
'ackbit := 0 ' ack bit commented out as this chip always works
data <<= 24
repeat 8 ' Output data to SDA
outa[SDA] := (data <-= 1) & 1
outa[SCL]~~ ' Toggle SCL from LOW to HIGH to LOW
outa[SCL]~
dira[SDA]~ ' Set SDA to input for ACK/NAK
outa[SCL]~~
'ackbit := ina[SDA] ' Sample SDA when SCL is HIGH
outa[SCL]~
outa[SDA]~ ' Leave SDA driven LOW
dira[SDA]~~
PUB i2c_writeLocation(device_address, register, value)
i2c_start ' start the chip
i2c_write(device_address) ' write to this chip
i2c_write(register) ' write to this register
i2c_write(value) ' write value
i2c_stop ' stop the chip
I am considering ordering one of these displays, but how do I know of one that the propeller can run without too much trouble. Is this TFT running 320x480 going to be difficult?
But I am not sure - they might have changed the driver chip (again!). ILI9325 is the one that is the most reliable. Some other displays seem to require the /CS pin to be toggled when sending data. I'm in the middle of a massive rewrite - new code, new board, no display working at all, back to debugging things with a logic probe. I am hopeful I can get something working soon that is a more universal and where we can plug in a wide range of these displays and just change some code.
I've been using the 3.2" LCDs with the SSD1289 controller and they seem to be less forgiving than the ILI9325. During the beginning of my personal touchscreen journey, I was able to get the SSD 1289 working directly with the Prop. Screen refreshes were quite slow, but it seemed to work. Then came the V1 board which I am still using with my SSD1289. The ILI displays worked flawlessly, but the SSD has a glitch somewhere. Still can't pin it down exactly.
Now to answer your question:
In theory the propeller should be able to drive most of these display driver chips. SOME hardware implementations MAY have issues.
A bit more about your application and intended hardware would help clarify.
I am considering ordering one of these displays, but how do I know of one that the propeller can run without too much trouble. Is this TFT running 320x480 going to be difficult?
I note that display has a 'cloned connector' scheme, whilst this series
somehow missed that obvious answer. It really grates, on the bigger sizes, as you need a huge backing board, just to reach both connectors (or some strange double-crimped ribbon cable..)
On the plus side, I see ALL the display tech ones 3.5" and up, use the same SSD1963, and Rayman has that jumping thru hoops.
The smaller 4 all use the RAIO RA8872 LCD controller. Not sure how that goes with the Prop ?
The RA8872 looks quite capable, it has a simple font built in, and some graphics primitives, so should pair well with resource limited controllers.
The datasheet includes example code for an 8051, does not look too daunting.
Be interesting if anyone has that RA8872 working ?
Re displays, many of them come with example C driver code and I've found if you name the functions the same in Spin it makes it fairly easy to translate from C to Spin.
@average joe, I now have something working. Change one line of code to use the ILI9325 display or the SSD1289 display. Board takes both displays - just power down and swap them over. Now we have full control over all the pins it makes things easier. I put in the /cs low and then /cs high after every data write as that is what the SSD1289 needs and it seems to be ok with the ILI9325 so that makes this code backwards compatible.
Pictures of both size displays below. The two large ones probably could be another 0.1" closer.
Only working in spin at the moment so very slow. Will work on porting over to pasm now.
I have the boards for you at the moment but for some reason futurlec are taking a while with the parts. Do you want me to send the bare boards now we know this works?
Boards sent 36h ago - they will be winging their way to you now Just a thought - take a look at the picture on the right on post #417 - just note around the propeller chip where the resistor arrays go. I noticed when I soldered the board up that it was a bit unclear from the overlay which were the resistors and which were the pins for headers (if you want external headers/access to P0-P23).
I have done a massive rewrite of the code. Moved lots of "program specific" code out of the common "Touch.spin" object and into individual programs (eg you don't need the checkbox code if you are running the synth program).
One problem - this MCOP23008 code is slower as there are multiple changes between loading up the 161 chips and then sending to ram. One of the problems is the .bmp files - they start at the end and work to the beginning, but we want them in ram the other way round. So every line of the picture needs a new 161 address. Which means lots of 400khz messages to the I2C port. I'm trying to think of a way of flipping between the 161 and ram access in a quicker way. If only we had one more propeller pin!!
I am going to try recoding the 161 and I2C into pasm. I tried it yesterday but it didn't work (there are pasm I2C drivers in the obex) but it may not save much time anyway as the 400khz speed is fixed (?)
I've got one workaround in that the first load of the desktop program is slow, but doing a "warm boot" from a program like the calculator is super fast as it caches the desktop image in ram. Ram to the display is still fast because the .bmp file has already been turned into the right format for fast output to the display. So that is still 30ms.
Another thing - changing back and forth between the two displays I figured that if we add just one line of code in the desktop program
then the "S" or the "I" can be stored in external ram. That means that all the programs you run from icons eg the calculator, synth, can access the type of display from a static location in ram. So no other programs need worry about the display. I've been testing this and it works really well. Saves recompiling eg the calculator program each time you change the display.
Oh, a minor thing. The x axis is flipped on the SSD1289 display for the touchscreen. But no matter because all programs know which display it is, so that can stay internal to the Touch.Spin object and users don't need to worry about it. So a call to get the x and y position of a finger press is still 0-100% same for both displays.
It is very handy being able to swap displays. The larger ones almost are as big as the board and we have 480x320 of wonderful touchscreen to use. But the smaller ones have a much better image at oblique angles - almost oled or CRT in that the colors stay the same even when looking at the display very obliquely. So each have their uses.
re: MPC code, I see the 1.7Mhz mode listed on the datasheet, but it looks like 4.5 - 5.5v spec. Other than that, it seems the best way is to use RAW format?
re: Warm boot, EXCELLENT NEWS. I've had some ideas for "standalone" apps but no time to code.
re: boards, Thanks again! I will let you know when they arrive!
re: final stab at a name *it's all in the name* "TouchBurger x" where x is model?
@Bits, Please keep us updated of the display you choose. If you order something other than the ILI 9325 or SSD 1289 we may be able to spec you a board.
I must run and try to finish homework. Seems the first week and last week are the worst.
Standalone apps - yes I think that is the way to approach things. eg this is the dual display demo. All the complicated stuff is hidden away in the Touch object. A typical app has about half the hub ram free for code space. And data arrays and strings can be offloaded to the external ram, so there is plenty of space for coding.
CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000
OBJ
tch: "Touch" ' touchscreen driver
PUB Main
tch.BeginProgram
DualScreen
tch.SetWarmBoot ' clears screen, sets a warm boot and reboots
PUB DualScreen |xval, yval
tch.ClearRam
tch.SDBMPtoRam(string("KangL.bmp")) ' file 2
tch.DisplayLeft ' left picture
tch.DrawBMPRam(2,0,0) ' draw the picture
tch.SDBMPtoRam(string("KangR.bmp")) ' file 3
tch.DisplayRight ' right picture
tch.DrawBMPRam(3,0,0) ' draw the picture
tch.SelectSPIGroup ' talk to the spi touchscreen
repeat
yval := tch.TouchYPercent ' decode yval 0-100%
xval := tch.TouchXPercent ' decode xval 0-100%
if (xval <> 255) and (yval <> 255) ' valid keypress - touch the screen to exit
return
Comments
I have everything working now for the most part. I noticed on the music font there is 1 white pixel @ 0,0 that should not be there? I'm going to do some more digging... Building the Logic Analyzer has proven a bigger chore than thought since the tip on my iron is done. Now I must wait till Tuesday to get a new one.
I was recording a utube video, but the baby woke up. I'll try again during his next nap.
There's still some exploring to do as to the display issue. I want to port portions over to C so I can experiment with OTHER stuff. *no spoiler alert today *
Also on the to-do list is finish the chiptune player. I have the new transport, now to bind the controls and get a NICE font working instead of the debugging font. Also need to finish the transport buttons. I'm going to do the masking on the BMP so all I have to do is re-draw the button with the correct color bmp. Should be fairly simple and will be compatible with the ILI.
Gotta run! Thanks again for everything Doc!
*edit*
Could you post updated SD file system? I'm missing the HTML bmps. I think we could pull off 16x16 if we used a few cogs
Another edit, Got my latest demo ready. I need to show some people in the area. I squeezed chiptune player into the last little bit of space. 272 longs free!
I've been watching the "other" post and you guys have done a lot of work! Keep up the good work!
When the MCP23008 boards arrive we both will need to rewrite our code. I've been recycling most components off old boards by desoldering. Some components don't desolder very well (ie the ones with many pins) and I tend to abandon sockets, plugs and resistor SIL arrays.
If you are running out of space we can either move more things into objects and then have separate loadable programs like the standalone movie player, or we can move over to C. The move to C is a little daunting for me as a Basic/Spin programmer but I am starting to get a feel for what -> and :: and * mean. I'm hoping real soon we can have a design where we can get some other builders involved. The /CS thing on the SSD1289 has put things back a few weeks but I think we are back on track now.
A revision note for the future, could you use polarized caps on the propeller chip? I usually use tants *a 4.7uf on the PLL side.
Re tants vs electrolytics, that could start a long debate! Suffice to say nothing is set in stone and you can solder in different caps if you want as long as the voltage rating is ok and the value is roughly the same.
I will add some thing to DR_Acula's answer.
On V-Regs (OutSide-Regulated)--- If Data sheet specifies Tantalum --- Never change them to other type's.
On Propeller Crystal side Voltage pins ---- Use always Tantalums ---- As electrolytic ones gave to slow response time.
Well I suppose I had better go and read the data sheet! For the switchers http://pdf1.alldatasheet.com/datasheet-pdf/view/203238/NSC/LM2575T-5.0.html page 1 for the official values of 100uF on the input and 330uF on the output and scroll down to page 18 for a discussion of the capacitor types and values.
If you are using linear regulators (this board can have either) then check the data sheet for those.
Re the propeller caps - yes Sapieha is right, always use a tantalum.
Propeller chips ALWAYS get .1uf tant and 4.7uf tant on PLL side. *I'm out of 4.7s right now so using stock .1 tant for pll. Should be fine for standard clocked board.* I have also used ceramics in the past but don't recommend. EL's would be a no-no. The large caps are EL of course. The rest of the caps are ceramic, except for audio caps.
With my "standard" linear regulator design, I use .1 ceramic or tant on the input and output of vregs, right next to the regulator. Input cap will be from 100uf to 470uf. Output is usually a 100uf but I've used 10ufs before with no issues. The regulators I'm using look good with a wide range of caps.
The 22uf tant is the only one throwing me off. Suck a 10uf in and I'm preparing to pre-power test. Then smoke test!
*edit*
OOPS. I guess I loaded the .01uf audio caps with .1uf. I'm out of .01s? Will changing the resistor to 100 ohms hurt anything? Also, I still have no '08 so had to fudge in an '00 again.
I think You have write error --- Else You use bad capacitor with Propeller.
.1uF shall always be Ceramic capacitor as it have better response to frequencies DECOUPLING capacitor shall answer for.
And all other decoupling capacitors on all IC's 0.1uF shall be Ceramic ones to.
4.7uF are to small -- it need's be at least 10uF
And You need have both ones on this side for all Frequencies --- If You will have stable PLL --- That not burn after some work time
The board is built and just passed 1'st smoke test. Now to load the sockets and try again!
*edited*
I'm updating the dual screen driver and have a note:
X values are swapped. Could also be fixed when starting the D/A conversion?
ALSO!
[code]
ILIcmd($0001,$4B3F) ' set SS and SM bit 0001 0000 landscape
instead of
ILIcmd($0001,$6B3F) ' set SS and SM bit 0001 0000 landscape
Well I had the board working, now I get nothing... Well it wasn't exactly working, but it was close. Propfont was drawing wrong? FixGlitch no longer works? Scratching my head now!
Now the question that's eating at me, how will the SSD 1963 play with our boards? I've also been wondering about Ray's DVI graphics shield. How cool would it be to have one of the dual-screen boards with a 7" touchscreen and DVI out!
I'm still working on the cache driver for the original board. Seems to me locks need to be implemented on the bus so cache driver cog and display driver cog don't conflict. So anytime one of the propeller's cogs needs to access the bus, we need to lock the bus first:
*in asm* and then unlock the bus when done There's also an optimization you might be interested in:
I realize the MPC board will require a re-write of the entire code, I'm just trying to get experience with GCC, SimpleIDE and the like. To be honest, I'm in completely over my head with the C and C++ but gotta start somewhere. I am quite happy with the cache driver numbers, although locking may impact them slightly.
Work on the chiptune player has begun again. I'm just pondering "skinning" the player. There are also some glaring bugs in the code. Hopefully I will be able to post a utube video soon.
Yes - need to get the SSD1963 working properly. I had it working at one point with a stable picture and I should have saved that as a "restore point" as I can't replicate it again. I'm going to wait until the MCP23008 boards arrive.
The MCP23008 boards are on the way and that will take things backwards for a bit porting code over but I think it will be worth it as we will have independent control of the /cs lines.
Ray's DVI graphics shield is built on the SSD1963, and the 5" and 7" displays I'm interested are as well. I'm hoping the issues we're having with the SSD1289 will not re-appear when transitioning to the 1963. I need to take a closer look at Ray's shield to determine if this will work the way I hope.
I was hoping to place my parts order today but once again life has interrupted. The kitty I had given away 5 years ago has come home! Sadly there is a growth on his neck that needs medical attention. So parts will need to wait until kitty is taken care of
I've been experimenting with moving most of the code into an "object". I think it makes it easier to understand. It isn't quite right yet eg the drawing of the icons is done within the object and ideally I'd like to draw them from a .ini file rather than from code.
Even better, somehow when we compile a program to a .bin or .exe file, create an icon to go with that program. Then the desktop can be rearranged to reflect working programs.
Jut to flat this line in the begin function of the object
which sets the display type
I'm in the process of writing some string routines.
In a roundabout way, I want to store the icon locations and list of programs in a text file on the sd card. To process that, it would be very helpful to be able to easily load text files into string arrays, and vice versa. And to manipulate those string arrays - search for file matches, strip off extensions etc.
Then I had another idea. Since we have an external ram chip, why not store all strings in external ram? That saves lots of hub space, and as an additional benefit, one does not have to try to conserve string space.
So - all strings are up to 128 bytes long. And they are in an array and you make that array as big as you like with a DIM command.
Not finished yet but I think this is a path towards a text editor as well.
I've been studying Raymond's DVI board and trying to understand how to interface it with our boards. I think it would be nice to have DVI out as an option. Still stuck on datasheets and such.
The port of the chiptune player is riddled with bugs I'm working out. It's functional, but there are issues.
I've spent a few hours working on a C wrapper for low level spin functions. Work is slow due to my lack of C experience. Hopefully I will be able to pick up speed as I go.
Sending you a PM now!
Needed cunning things like a "warm boot" which is faster where we can store some parameters in the external ram as that stays static when the propeller is rebooted.
I'm also thinking of porting the desktop program to something that reads a file. Or at the very least has the .exe and the icons as the same filename! Need to store four things, exe filename, icon, x position and y position. I think an Excel .csv file might be the easiest.
Anyway, the desktop loader is called Desktop.spin and this is the code:
and as an example, the photo viewer program
The touch object has all sorts of useful things and I'm sure it will end up being changed and edited.
I think the important thing is that a typical program, eg the slide viewer above, is only using about half the hub ram. So for a program, and despite all the overheads of driving sd card, touchscreens, displays etc, there are still propeller pins free and half the memory free.
I'll see if I can get the desktop loading from a .csv file . Hmm - maybe even need an "edit" mode for the desktop so you can move icons around by dragging them with a finger?
Addit: I see the SSD1963 now comes in a 5" as well http://www.ebay.com.hk/itm/ws/eBayISAPI.dll?ViewItem&item=221044250453&ssPageName=ADME:B:FSEL:HK:1123
It would be very handy to have software that can handle a variety of screen sizes.
I finished moving, cleaning, and all the various things that have occupied me for the past 2 weeks. I am by no means unpacked, but I've "found" all the things I need to get working again. With some luck, I'll be able to get the Ez-LCD301 working with the V1 board. It's my current "standard" board as it works for the most part. I've not been able to get the v2 board working yet, although it's fully built. Hopefully the v3 board will work with these dang ssd1289's! If not, I would still like to reference the OTHER ssd. Maybe those will work on all boards? $50 is out of my budget right now for such an experiment, since I still don't have the other 2 displays I ordered. Next week...
I was able to place a parts order that showed up today, okay well HALF showed up today. I have sockets, hc32's, hc08's as well as some other nice toys. I also ordered more SRAMs since having more than one board running at a time is a plus.. I need to talk to Steve about the board I sent him.
I could also use some advise about larger EEPROMs. I like the idea of having a larger eeprom that could hold "presets" or such.
Must run for now. Keep up the awesome work!
*edit*
After much thought, I have come up with the name
"DracBurger Touch"
Any thoughts?
I will get around to soldering the latest board soon. Meanwhile, I have managed to simplify the entire operating system right down to this little bit of code:
It is now super simple. The background is a file called "desktop.bmp". All files that you run (eg calc.exe) have an associated file "calc.bmp" for the icon.
The locations of the icons and the files are stored in a standard .csv file made with Excel
And that is the entire operating system!
For any program you want to run you write a new separate program. Use the "touch.spin" library with all sorts of useful routines. Last line in a .exe program is to call a warm boot which loads the desktop out of ram which means it is only about 1 second to chain programs or to go from a program back to the desktop operating system.
You can pass all sorts of things between chained programs as the external ram stays static.
There is a huge amount of string space now that strings are in external ram. All strings are fixed length 128 bytes (I've never been a great fan of variable length strings as every now and then you have to clean them up, eg MBASIC used to just freeze at random intervals every 10 mins or so). Who cares about how much space is wasted when strings are in external ram. 8192 strings of 128 bytes each if you want them.
re bigger eeprom, I am wondering if you can achieve the same effect by using the SD card?
Addit 20th June - working on porting over to the MCP23008 chip. Got pins going high and low. Need to rewrite all the code that talks to the display next.
I've been using these http://www.ebay.com/itm/2-4-TFT-LCD-Module-Display-Touch-Panel-PCB-adapter-/190477028273?pt=LH_DefaultDomain_0&hash=item2c5950cbb1
But I am not sure - they might have changed the driver chip (again!). ILI9325 is the one that is the most reliable. Some other displays seem to require the /CS pin to be toggled when sending data. I'm in the middle of a massive rewrite - new code, new board, no display working at all, back to debugging things with a logic probe. I am hopeful I can get something working soon that is a more universal and where we can plug in a wide range of these displays and just change some code.
I've been using the 3.2" LCDs with the SSD1289 controller and they seem to be less forgiving than the ILI9325. During the beginning of my personal touchscreen journey, I was able to get the SSD 1289 working directly with the Prop. Screen refreshes were quite slow, but it seemed to work. Then came the V1 board which I am still using with my SSD1289. The ILI displays worked flawlessly, but the SSD has a glitch somewhere. Still can't pin it down exactly.
Now to answer your question:
In theory the propeller should be able to drive most of these display driver chips. SOME hardware implementations MAY have issues.
A bit more about your application and intended hardware would help clarify.
I note that display has a 'cloned connector' scheme, whilst this series
http://www.displaytech-us.com/integrated-tft-driver-boards
somehow missed that obvious answer. It really grates, on the bigger sizes, as you need a huge backing board, just to reach both connectors (or some strange double-crimped ribbon cable..)
On the plus side, I see ALL the display tech ones 3.5" and up, use the same SSD1963, and Rayman has that jumping thru hoops.
The smaller 4 all use the RAIO RA8872 LCD controller. Not sure how that goes with the Prop ?
The RA8872 looks quite capable, it has a simple font built in, and some graphics primitives, so should pair well with resource limited controllers.
The datasheet includes example code for an 8051, does not look too daunting.
Be interesting if anyone has that RA8872 working ?
@average joe, I now have something working. Change one line of code to use the ILI9325 display or the SSD1289 display. Board takes both displays - just power down and swap them over. Now we have full control over all the pins it makes things easier. I put in the /cs low and then /cs high after every data write as that is what the SSD1289 needs and it seems to be ok with the ILI9325 so that makes this code backwards compatible.
Pictures of both size displays below. The two large ones probably could be another 0.1" closer.
Only working in spin at the moment so very slow. Will work on porting over to pasm now.
I have the boards for you at the moment but for some reason futurlec are taking a while with the parts. Do you want me to send the bare boards now we know this works?
Very busy trying to catch up with schoolwork, hopefully next week I can post my progress!
Keep up the great work!
Boards sent 36h ago - they will be winging their way to you now Just a thought - take a look at the picture on the right on post #417 - just note around the propeller chip where the resistor arrays go. I noticed when I soldered the board up that it was a bit unclear from the overlay which were the resistors and which were the pins for headers (if you want external headers/access to P0-P23).
I have done a massive rewrite of the code. Moved lots of "program specific" code out of the common "Touch.spin" object and into individual programs (eg you don't need the checkbox code if you are running the synth program).
One problem - this MCOP23008 code is slower as there are multiple changes between loading up the 161 chips and then sending to ram. One of the problems is the .bmp files - they start at the end and work to the beginning, but we want them in ram the other way round. So every line of the picture needs a new 161 address. Which means lots of 400khz messages to the I2C port. I'm trying to think of a way of flipping between the 161 and ram access in a quicker way. If only we had one more propeller pin!!
I am going to try recoding the 161 and I2C into pasm. I tried it yesterday but it didn't work (there are pasm I2C drivers in the obex) but it may not save much time anyway as the 400khz speed is fixed (?)
I've got one workaround in that the first load of the desktop program is slow, but doing a "warm boot" from a program like the calculator is super fast as it caches the desktop image in ram. Ram to the display is still fast because the .bmp file has already been turned into the right format for fast output to the display. So that is still 30ms.
Another thing - changing back and forth between the two displays I figured that if we add just one line of code in the desktop program
then the "S" or the "I" can be stored in external ram. That means that all the programs you run from icons eg the calculator, synth, can access the type of display from a static location in ram. So no other programs need worry about the display. I've been testing this and it works really well. Saves recompiling eg the calculator program each time you change the display.
Oh, a minor thing. The x axis is flipped on the SSD1289 display for the touchscreen. But no matter because all programs know which display it is, so that can stay internal to the Touch.Spin object and users don't need to worry about it. So a call to get the x and y position of a finger press is still 0-100% same for both displays.
It is very handy being able to swap displays. The larger ones almost are as big as the board and we have 480x320 of wonderful touchscreen to use. But the smaller ones have a much better image at oblique angles - almost oled or CRT in that the colors stay the same even when looking at the display very obliquely. So each have their uses.
re: MPC code, I see the 1.7Mhz mode listed on the datasheet, but it looks like 4.5 - 5.5v spec. Other than that, it seems the best way is to use RAW format?
re: Warm boot, EXCELLENT NEWS. I've had some ideas for "standalone" apps but no time to code.
re: boards, Thanks again! I will let you know when they arrive!
re: final stab at a name *it's all in the name* "TouchBurger x" where x is model?
@Bits, Please keep us updated of the display you choose. If you order something other than the ILI 9325 or SSD 1289 we may be able to spec you a board.
I must run and try to finish homework. Seems the first week and last week are the worst.
Standalone apps - yes I think that is the way to approach things. eg this is the dual display demo. All the complicated stuff is hidden away in the Touch object. A typical app has about half the hub ram free for code space. And data arrays and strings can be offloaded to the external ram, so there is plenty of space for coding.