Shop Learn
Propeller GUI touchscreen and full color display - Page 6 — Parallax Forums

Propeller GUI touchscreen and full color display

13468924

Comments

  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-03-31 17:19
    Re regulators, don't worry about switching regs if you don't want to. Any reg will be fine. There are several places on the board you can bring in regulated voltages from another place if you want to.

    I got most of the components from futurlec, but they can take a couple of weeks to arrive and sometimes it is hard to find parts on their website that you know they sell.

    I found a mistake on the board. I'm using P16 for the clock and I need to use P19 or higher. I didn't read the spec sheet closely enough :( I thought the data was loaded when the load went from low to high, but it isn't - see below.
    These counters may be preset using the LOAD input. Presetting
    of all four flip-flops is synchronous to the rising edge
    of CLOCK. When LOAD is held LOW counting is disabled
    and the data on the A, B, C, and D inputs is loaded into the
    counter on the rising edge of CLOCK. If the load input is
    taken HIGH before the positive edge of CLOCK the count
    operation will be unaffected.

    So some tracks are going to need to be cut and moved. I think it will be a matter of driving all the clocks from P19 instead of P16, and then driving the memory /RD from P16 instead of P19. I'll need to think about where to put the changes on the board.

    addit - found a few more things on the board that are not quite right. Apart from swapping things above, I think the schematic is right though. Hmm - I might have to hold off posting any boards though. Maybe better to build this on a breadboard first?
  • average joeaverage joe Posts: 795
    edited 2012-03-31 22:34
    Sorry I didn't notice the load line error. I guess I should have looked over the schematic a bit closer. I'll take another, closer, look at the schematic tonight.
    I did decide to order regulators and all necessary components.
    I think it might be a good idea to breadboard first. I always start here if possible. Cutting a few traces is not a huge deal to me, but I will leave this up to you. I've been working on the old ili driver and almost done with ram to hub and hub to ram transfers. I need to get a jump start on homework for next week, but after this is done I will continue working.

    *edit*
    Okay, I've been working on the driver and hit an issue. I'm looking at the datasheet for my hc counters and see max clock 25MHZ @ 4.5V, 5MHZ @ 2v. *I'm going to slow it down for the LS, but will be going full HC - 3.3V compatible* So. How should I guestimate the timing cycle? Any advice? Just start slow and speed it up till it won't run?


    another edit
    I've been working on the ram read and write in ASM. None of this is tested, but I'm trying to get a framework. I think this should be close.
    DAT
    '                  First part tests ok
    '' +--------------------------------------------------------------------------+
    '' | Dracblade Ram Driver (with grateful acknowlegements to Cluso)            |
    '' +--------------------------------------------------------------------------+
                            org     0
    tbp2_start    ' setup the pointers to the hub command interface (saves execution time later
                                          '  +-- These instructions are overwritten as variables after start
    comptr                  mov     comptr, par     ' -|  hub pointer to command                
    hubptr                  mov     hubptr, par     '  |  hub pointer to hub address            
    ramptr                  add     hubptr, #4      '  |  hub pointer to ram address            
    lenptr                  mov     ramptr, par     '  |  hub pointer to length                 
    errptr                  add     ramptr, #8      '  |  hub pointer to error status           
    cmd                     mov     lenptr, par     '  |  command  I/R/W/G/P/Q                  
    hubaddr                 add     lenptr, #12     '  |  hub address                           
    ramaddr                 mov     errptr, par     '  |  ram address                           
    len                     add     errptr, #16     '  |  length                                
    err                     nop                     ' -+  error status returned (=0=false=good) 
    ' Initialise hardware tristates everything and read/write set the pins
    init                    mov     err, #0                  ' reset err=false=good
                            mov     dira,zero                ' tristate the pins
    done                    wrlong  err, errptr             ' status  =0=false=good, else error x
                            wrlong  zero, comptr            ' command =0 (done)
    ' wait for a command (pause short time to reduce power)
    pause
    '                        mov     ctr, delay      wz      ' if =0 no pause
    '              if_nz     add     ctr, cnt
    '              if_nz     waitcnt ctr, #0                 ' wait for a short time (reduces power)
                            rdlong  cmd, comptr     wz      ' command ?
                  if_z      jmp     #pause                  ' not yet
    'decode command    
    '                     
                            cmp     cmd, #"Z"       wz         ' Z moves command to the display from hub address, length times
                  if_z      jmp     #hubtodisplayCommand       ' command format "DoCmd(Z,hub_address, unused, length) 
                            cmp     cmd, #"Y"       wz         ' Y moves data to the display from hub address, length times
                  if_z      jmp     #hubtodisplayData          ' data format "DoCmd(Y, hub_address, unused, length)
    
    
                  
                           cmp     cmd, #"R"       wz      ' R = read block from external ram to hub
                 if_z      jmp     #rdblock
                           cmp     cmd, #"W"       wz      ' W = write block from hub to external ram
                 if_z      jmp     #wrblock
                           cmp     cmd, #"C"       wz      ' C moves a block of data from ram to the display
                 if_z      jmp     #extramtodisplay
    ' add new commands HERE  
    
    
    
    
    '                       cmp     cmd, #"A"       wz      ' A moves 256 bytes from hub to external ram
    '             if_z      jmp     #blockhubtoram
    '                       cmp     cmd, #"B"       wz      ' B moves 256 bytes from external ram to hub
    '             if_z      jmp     #blockramtohub
    '                       cmp     cmd, #"E"       wz      ' convert 3 byte .raw format to 2 byte .ili format - hub to hub
    '             if_z      jmp     #rawtoiliformat
    '                       cmp     cmd, #"F"       wz      ' draw a transparent icon, pass two locations in hub ram and len = number of pixels
    '             if_z      jmp     #drawicon
                
                            cmp     cmd, #"I"       wz      ' init
                  if_z      jmp     #init     
                            '            
                            mov     err, cmd                ' error = cmd (unknown command)
                            jmp     #done
                                         
    ram_open                rdlong  hubaddr, hubptr         ' get hub address
                            rdlong  ramaddr, ramptr         ' get ram address
                            rdlong  len, lenptr             ' get length
                            mov     err, #5                 ' err=5
    ram_open_ret            ret
    
    hubtodisplayData        ' send a block of data blocklen from hubaddr to the display (bypasses external ram)
                            call    #ram_open               ' gets hubaddr and len (ignores ramaddress)                        
                            call    #setRShigh              ' set pins for data output
    :hubdisploop            rdword  Display, hubaddr        ' copy word from hub, not needed ?
                            add     hubaddr,#2              ' add 2 to hub address changed for word alligned                        
                            call    #ilidisplayword         ' send these bytes to the display
                            djnz    len,#:hubdisploop       ' loop until done
                            jmp     #init                   ' set pins to tristate
                                                   
    hubtodisplayCommand     call    #ram_open               ' gets hubaddr and len (ignores ramaddress)
    :hubdisplayloop         call    #setRSlow                ' set pins for Command output
                            rdword  Display, hubaddr        ' copy word from hub
                            add     hubaddr,#2              ' add 2 to hub address changed for word alligned
                            call    #ilidisplayword         ' send these bytes to the display                         
                            djnz    len,#:data       ' loop until done
                            jmp     #init                   ' set pins to tristate                  
    :data                   call    #setRShigh
                            rdword  Display, hubaddr        ' copy word from hub
                            add     hubaddr,#2              ' add 2 to hub address changed for word alligned
                            call    #ilidisplayword         ' send these bytes to the display 
                            djnz    len,#:hubdisplayloop       ' loop until done
                            jmp     #init                   ' set pins to tristate
                            
    setRShigh               mov     outa, PinsInit
                            mov     dira, DirsEnabled      ' set rsHigh by tristate pin                  
    setRShigh_ret           ret 
    
    setRSlow                 mov   outa, PinsInit
                             mov   dira, DirsEnabled   wz           ' set rsHigh by tristate pin                             
                             muxnz dira, RSpin                      ' set rsLow by enabling pin
    setRslow_ret             ret
    
    ilidisplayword            ' pass data out, sends out to the display
                            add Display, p2dpins       wz                'this add presets the data for control pins and primes WZ flag for mux operation                      
                            mov outa, Display 'then make pins = data
                              muxz dira,EnablePin                          'make enable pin low                       
                              mov    timeout, #$f                        'set wait period
    :wait1                    djnz   timeout, :wait1                     'and wait  
                              muxnz dira, EnablePin                      'make enable pin high
    ilidisplayword_ret      ret
    '*********************************************************************************************************************************** 
    'tests ok
    
    '---------------------------------------------------------------------------------------------------------
    'Memory Access Functions
    rdblock                call    #ram_open               ' get variables from hub variables
                           call    #load_ram_add           ' load first address into counters
                           
    rdloop                 call    #read_memory_word             ' read word from address into data_8
                           wrword  data_8,hubaddr          ' write data_8 to hubaddr ie copy WORD to hub
                           add     hubaddr,#1              ' add 1 to hub address
                           add     ramaddr,#1              ' add 1 to ram address
                           call    #inc_ram_address        ' increment RAM address
                           djnz    len,#rdloop             ' loop until done
                           jmp     #init                   ' reinitialise
    
    
                            ' write block from hub to external ram
    wrblock                 call    #ram_open
                            call    #load_ram_add           ' load first address into counters
                            mov     dira, P2RPins
    
    wrloop                  rdword  data_8, hubaddr         ' copy word from hub
                            call    #write_memory_word      ' write word from data_8 to address
                            add     hubaddr,#1              ' add 1 to hub address
                            add     ramaddr,#1              ' add 1 to ram address
                            call    #inc_ram_address        ' increment RAM address 
                            djnz    len,#wrloop             ' loop until done
                            jmp     #init                   ' reinitialise
    
    load_ram_add       
                            mov  outa, RamLoadPins     wz   'preset pins and clear z flag. pins still tri-state
                            add  outa, ramaddr              'move rammaddress onto bus
                            mov dira, RamLoadDirs           'and enable all pins                       
                            'wait here if needed?
                            muxz  outa, EnablePin           ' make Enable Pin Low
                            'wait here if needed?
                            muxnz outa, EnablePin           ' make Enable Pin High
                            'wait?
                            mov   dira, zero                ' tri-state all pins
                            'wait here if needed?
    load_ram_add_ret       ret                                                  
    
    read_memory_word        mov   outa, R2PPins             ' preset pins for read
                            mov   dira, R2PDirs             ' enable pins
                            
                            add   timeout, RAMRDtimeout     'wait here if needed
    :wait                   djnz  timeout, #:wait
    
                            mov  data_8, ina
                            and  data_8, #$FF               ' extract 16 bits
    read_memory_word_ret   ret
    
                                                                                       
    
    write_memory_word       and   data_8, lowWordMask          ' ensure upper bytes=0
                            add   data_8, P2RPins              ' add to P2E initPins
                            mov   outa,   data_8         wz    ' send it out
                            muxz  outa,   Cadd1Pin             ' make 138 = RAMWR
                            muxz  outa,   EnablePin            ' make ram WR LOW
                            
                            add   timeout, RAMWRtimeout        'set wait
    :wait                   djnz  timeout, #:wait              'and wait
    
                            muxnz outa,   EnablePin            ' make ram WR HIGH 
                            muxz  outa,   Cadd1Pin             ' make 138 = COUNT
    write_memory_word_ret   ret
    
    inc_ram_address        add    zero, #0                     wz                   'prime z flag                 
                           muxnz  outa, EnablePin                                   'make Enable Pin LOW
                           
                           mov    timeout, countTimeout                             'set wait
    :wait                  djnz   timeout, #:wait                                   'and wait
    
                           muxz   outa, EnablePin                                   'make enable Pin High
                 'and wait again?          
    '                       mov    timeout, countTimeout                             'set wait
    ':wait                  djnz   timeout, #:wait                                   'and wait                       
                           
                           
    inc_ram_address_ret    ret            
    
    
    'extramtodisplay ' send a block of data blocklen from external memory ramaddress to the ILI9325 display
                           call    #ram_open               ' gets ramaddr and len (ignore hubaddr) 
                           call    #load_ram_add           ' loads ram address for transfer
                           mov      outa, R2DPins          ' preset pins for R2D transfer
                           mov      dira, R2DDirs          ' enable pins
                           'and wait if necessary?
    
                           add     zero, #0                     'prime z flag
                           
    ililoop                muxnz   outa, EnablePin          ' make enable pin LOW
    
                            mov     timeout, #$f                 ' set wait
    :wait1                  djnz    timeout, #:wait1            ' and wait
                                                        
                           muxz    outa, EnablePin          'make enable pin HIGH
                           
                           muxnz   outa, Cadd0Pin              ' set for ramcount
    
                           call    #inc_ram_address          ' and load next ram address
    
                           muxz    outa, Cadd0Pin              ' set for lcd_wr
                           
                            mov     timeout, #$f                 ' set wait
    :wait2                  djnz    timeout, #:wait2            ' and wait
    
                           djnz    len,#ililoop            ' loop until done
                           jmp     #init                   ' set pins to tristate
    
    RAMRDtimeout                    long $0000_00FF
    RAMWRtimeout                    long $0000_00FF                                                                                                 
    countTimeout                    long $0000_00FF
    
    
                                                                                                      
    lowWordMask                       long $0000_ffff
    
    
    
                                          'pin settings
    EnablePin                         long   %00000000_00000010_00000000_00000000
    RSPin                             long   %00000000_00000001_00000000_00000000
    
    
    LoadPin                           long   %00000010_00000000_00000000_00000000
    RamLoadPins                       long   %00001100_01000010_00000000_00000000
    RamLoadDirs                       long   %00001111_11100010_11111111_11111111
    
    R2PDirs                           long   %00001101_11100010_00000000_00000000
    P2RDirs                           long   %00001001_11100010_00000000_00000000
    
    P2RPins                           long   %00001110_01000010_00000000_00000000
    R2PPins                           long   %00000010_01000010_00000000_00000000
     
    R2DPins                           long   %00000000_01100011_00000000_00000000
    R2DDirs                           long   %00000101_11100011_00000000_00000000
    
    p2dpins                           long   %00001000_01100000_00000000_00000000      ' propToDisplay    enable pin low, but tristate, primed for lcd transfer                                               
    
    PinsInit                          long   %00001001_01100010_00000000_00000000      'pins Inital state, BUS = Prop -> RAM, Not RamRD, BusDisabled, enable pin high 
    DirsEnabled                       long   %00001001_11100000_11111111_11111111                                                                           ''                                          (R4Fh) (POR = 0000h)
    
    CAdd0Pin                          long   %00000000_00100000_00000000_00000000
    Cadd1Pin                          long   %00000000_01000000_00000000_00000000
    Cadd2Pin                          long   %00000000_10000000_00000000_00000000
    
    timeout                 res 1
    Display                 res 1
    
    fit                       
    
    I will keep updating this until it works, I just wanted to get a start so you could make suggestions. Also, here's the schematic
    1024 x 785 - 119K
  • average joeaverage joe Posts: 795
    edited 2012-04-01 21:51
    I flipped a quarter and it came up tails, so I started working on a new schematic. I updated to 19 bit address line, and your ram chips. I also added 2 - `374s to save 4 prop pins and add 12 GPOs. Un-buffered access to the 19 prop pins and 1 control pin are also provided. Two audio outs as well as midi I/O round out the connections. I also provided leds on p30 and p31 as you have. Should help debugging? There are a few errors I am aware of. Resistor values are incorrect for audio outs. I am still debating adding 5v reg. For those without midi devices, you can use the midi i/o for a ps2 keyboard? Or maybe even usb?

    I did not want to use the inverters, but couldn't think of an easier way. Let me know what you think!
    *edited*
    I found more issues. I forgot to remove a few resistors from the lcd lines. I am also thinking about adding a 4 pin jumper for midi I/O or PS2 port.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-02 03:46
    Looking good. Let me know how it goes on a breadboard. Are you still running the ram chips from 5V?

    I got routines working tonight to transfer data from hub to ram and ram to hub
    PUB HubToRam(RamAddress,Number) | i                     ' send data from hub to ram in a block
       Load161(RamAddress)                                  ' load all the 161 chips with the start value
       i := 0
       repeat Number
         OUTA &= %11111111_11111111_00000000_00000000       ' clear for output
         OUTA |= rambuffer[i]                               ' send out a word to P0-P15
         WR_Low                                             ' write to ram
         WR_High                                            ' toggle ram write
         Clock161_Low                                       ' toggle clock
         Clock161_High
         i += 1                                             ' increment i
    
    PUB RamToHub(RamAddress, Number) | i                    ' send data from ram to hub in a block     
       Load161(RamAddress)                                  ' load all the 161 chips with the start value
       i := 0
       DIRA &= %00001111_11111111_00000000_00000000         ' set P0-P15 as inputs
       repeat Number
         RD_Low                                             ' read pin low
         rambuffer[i] := INA                                ' get the data
         RD_High
         Clock161_Low                                       ' toggle clock
         Clock161_High
         i += 1                                             ' increment i
       DIRA |= %00000000_00000000_11111111_11111111         ' restore P0-P15 as outputs 
    

    So - move data from SD card to propeller, prop to external ram, external ram back to prop, and external ram to the display. This last one is where the fast refresh works with 30ms to do a screen. It is super simple in spin and so will easily translate over to pasm
    PUB RamToDisplay(RamAddress,Number)                     ' send n words to the display after sending a Draw command
       Load161(RamAddress)                                  ' load all the 161 chips with the start value
       ILI_RS_High                                          ' RS high for sending data
       RD_Low                                               ' memory read low
       DIRA &= %00001111_11111111_00000000_00000000         ' set P0-P15 as inputs so no data clash with propeller (prop ignores these pins)  
       repeat Number
         ILI_WR_Low                                         ' send out the data
         ILI_WR_High
         Clock161_Low                                       ' toggle clock
         Clock161_High
       RD_High                                              ' memory read high
       DIRA |= %00000000_00000000_11111111_11111111         ' restore P0-P15 as outputs 
    


    This little bit of code fills the screen from the ram with 76800 pixels (15% of the ram capacity)
      Draw(0,0,239,319)  ' dump out 76800 words to the display = a full screen
      RamToDisplay(0,76800)
    

    and the speed in spin is 5.5 seconds, which I think compares favorably with the previous speed around 9 seconds. This is going to be very fast in pasm.

    This 161 driver is brilliant!


    Full program:
    '' ILI9325 driver using the Touchblade161 design for faster ram to display transfers
    '' James Moxham 2012
    
    CON
    
    
      _clkmode      = xtal1 + pll16x                        ' use crystal x 16
      _xinfreq      = 5_000_000
    
      _1ms    = 1_000_000 /     1_000                         ' Divisor for 1 ms   
    
    ' pins
    ' P24 = audio out
    '  25,26,27   138 one of 8 decoded, active low
    ' 0=000 = SPI touchscreen input, keyboard, TV VGA enabled
    ' 1=001 = Load counter
    ' 2=010 = Memory transfer - P0-P15=bus, P19=161_clk, P17 = ILI_WR, P18=ILI_RS, P16= Ram_RD, P20=Ram_WR,P21-23 = SD card
    ' 3=011 = ILI Reset
    ' 4=100 = Digital output (8 bits to a 574 latch)
    ' 5=101 = spare
    ' 6=110 = spare
    ' 7=111 = startup (all above deselected)
    
    OBJ
    
    VAR
       long orientation
       long curx, cury
       long clkcycles     ' for the delay routine
       
    
       
    PUB Main
      curx :=0
      cury :=0
      PinsHigh
      start_ram                                             ' start the cog driver    
      MemoryTransferSelect                                  ' select 138 and set control pins
      Start_ILI9325                                         ' start the display
      HelloWorld                                            ' Bootup message
      rambuffer[0] :=$AA55                                  ' some random word values          
      rambuffer[1] :=$07FF
      rambuffer[2] := %00000111_11100000                    ' green pixels
      rambuffer[3] := %00000111_11100000
      rambuffer[4] := %11111000_00000000                    ' red pixels
      rambuffer[5] := %11111000_00000000
      rambuffer[6] := %11111000_00000000
      HubToRam(0,7)                                         ' ramaddress, number. Uses rambuffer (word array) up to 256
      rambuffer[1] := 0                                     ' clear the value for debugging
      RamToHub(0,7)                                        ' read data back
      
    
      MemoryTransferSelect                                  ' reselect 138 for display output for debugging
      hex(rambuffer[1],4)
    
      Draw(99,95,108,104)                                   ' draw a little black square
      repeat 100
        Pixel(0)
      
      Draw(100,100,106,100)                                 ' display pixels
      RamToDisplay(0,7)                                     ' dump out from ram to display
      repeat
    
    PUB RamToDisplay(RamAddress,Number)                     ' send n words to the display after sending a Draw command
       Load161(RamAddress)                                  ' load all the 161 chips with the start value
       ILI_RS_High                                          ' RS high for sending data
       RD_Low                                               ' memory read low
       DIRA &= %00001111_11111111_00000000_00000000         ' set P0-P15 as inputs so no data clash with propeller (prop ignores these pins)  
       repeat Number
         ILI_WR_Low                                         ' send out the data
         ILI_WR_High
         Clock161_Low                                       ' toggle clock
         Clock161_High
       RD_High                                              ' memory read high
       DIRA |= %00000000_00000000_11111111_11111111         ' restore P0-P15 as outputs  
    
    PUB HubToRam(RamAddress,Number) | i                     ' send data from hub to ram in a block
       Load161(RamAddress)                                  ' load all the 161 chips with the start value
       i := 0
       repeat Number
         OUTA &= %11111111_11111111_00000000_00000000       ' clear for output
         OUTA |= rambuffer[i]                               ' send out a word to P0-P15
         WR_Low                                             ' write to ram
         WR_High                                            ' toggle ram write
         Clock161_Low                                       ' toggle clock
         Clock161_High
         i += 1                                             ' increment i
    
    PUB RamToHub(RamAddress, Number) | i                    ' send data from ram to hub in a block     
       Load161(RamAddress)                                  ' load all the 161 chips with the start value
       i := 0
       DIRA &= %00001111_11111111_00000000_00000000         ' set P0-P15 as inputs
       repeat Number
         RD_Low                                             ' read pin low
         rambuffer[i] := INA                                ' get the data
         RD_High
         Clock161_Low                                       ' toggle clock
         Clock161_High
         i += 1                                             ' increment i
       DIRA |= %00000000_00000000_11111111_11111111         ' restore P0-P15 as outputs 
       
    
    PUB Load161(RamAddress)
       Select138(7)                                         ' deselect previous 138 value
       DIRA |= %00000000_00011111_11111111_11111111         ' P0-P18 enabled for output plus P19,P20
       OUTA &= %00001110_11111000_00000000_00000000         ' preserve previous values but set A0-18 low
       OUTA |= RamAddress                                   ' output address to the 161 chips
       Clock161_Low                                         ' clock low
       Select138(1)                                         ' 161 load low
       Clock161_High                                        ' load in value
       OUTA |= %00000000_11111111_00000000_00000000         ' set P16-P23 high prior to changing 138
       Select138(2)                                         ' 161 load high and back to mem transfer
     
    PUB Clock161_Low
       OUTA &= %11111111_11110111_11111111_11111111         ' P19 low
    PUB Clock161_High   
       OUTA |= %00000000_00001000_00000000_00000000         ' P19 high
    
    PUB WR_Low
       OUTA &= %11111111_11101111_11111111_11111111         ' P20 low
    PUB WR_High  
       OUTA |= %00000000_00010000_00000000_00000000         ' P20 high
    PUB RD_Low
       OUTA &= %11111111_11111110_11111111_11111111         ' P16 low
    PUB RD_High  
       OUTA |= %00000000_00000001_00000000_00000000         ' P16 high        
    
    PUB PinsHigh
       DIRA := %00001111_11111111_11111111_11111111         ' enable all pins as outputs
       OUTA := %00001110_11111111_11111111_11111111         ' all except P24 audio out are high  
    
    PUB MemoryTransferSelect
       Select138(2)                                         ' enable memory transfer group
       DIRA |= %00001110_11111111_11111111_11111111         ' Pins all as outputs
       OUTA |= %00000000_11111111_00000000_00000000         ' all control pins high                    
    
    PUB Select138(n) ' pass n=0 to 7
       n := n<<25                                           ' shift left so pins 25,26,27
       DIRA |= %00001110_00000000_00000000_00000000         ' enable these pins for output
       OUTA &= %11110001_11111111_11111111_11111111         ' mask 3 pins low
       OUTA |= n                                            ' send out
    
    PUB Clearscreen
      Draw(0,0,239,319)  ' clear the screen  - slow spin version
      repeat 76800
        Pixel($0000)     
    
    PUB HelloWorld  ' use propeller font in the rom for bootup messages when debugging sd cards
        Propfont_string(string("Hello World")) ' 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
        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 ILI_RS_Low
       OUTA &= %11111111_11111011_11111111_11111111         ' P18 low
    
    PRI ILI_RS_High   
       OUTA |= %00000000_00000100_00000000_00000000         ' P18 high
    
    PRI ILI_RD_Low                                          ' pulled high in hardware, not used  
    PRI ILI_RD_High                                           
    
    PRI ILI_WR_Low
       OUTA &= %11111111_11111101_11111111_11111111         ' p17 low
    
    PRI ILI_WR_High
       OUTA |= %00000000_00000010_00000000_00000000         ' p17 high
    
    PRI ILI_CS_Low                                          ' not used as setting 138 to %010 does this
    PRI ILI_CS_High   
    
    PRI ILI_RESET_Low                                       ' reset low
       Select138(3)                                         ' reset low
    
    PRI ILI_RESET_High
       Select138(2)                                         ' 138 back to memselect  
      
    
    DAT
    sdbuffer        byte    $0[512]  ' 512 byte buffer for sd card interface
    rambuffer       word    $0[256]
    
    '************************** Cog driver for the 16 bit ILI9325 screen *********************
    
    
    VAR
    
    ' communication params(5) between cog driver code - only "command" and "errx" are modified by the driver
       long  command, hubaddrs, ramaddrs, blocklen, errx, cog ' rendezvous between spin and assembly (can be used cog to cog)
    '        command  = R, W, H I,D etc =0 when operation completed by cog
    '        hubaddrs = hub address for data buffer
    '        ramaddrs = ram address for data ($0000 to $FFFF)
    '        blocklen = ram buffer length for data transfer
    '        errx     = returns =0 (false=good), else <>0 (true & error code)
    '        cog      = cog no of driver (set by spin start routine)
       
    PUB start_ram : err_
    ' Initialise the Drac Ram driver. No actual changes to ram as the read/write routines handle this
      command := "I"
      cog := 1 + cognew(@tbp2_start, @command)
      if cog == 0
        err_ := $FF                 ' error = no cog
      else
        repeat while command        ' driver cog sets =0 when done
        err_ := errx                ' driver cog sets =0 if no error, else xx = error code
    
    PUB stop_ram
       if cog
          cogstop(cog~ - 1)      
    
    PUB DoCmd(command_, hub_address, ram_address, block_length) : err_
    ' Do the command: R, W, N, F, H,I,D
      hubaddrs := hub_address       ' hub address start
      ramaddrs := ram_address       ' ram address start
      blocklen := block_length      ' block length
      command  := command_          ' must be last !!
    ' Wait for command to complete and get status
      repeat while command          ' driver cog sets =0 when done
      err_ := errx                  ' driver cog sets =0 if no error, else xx = error code
    
    
    DAT
    '' +--------------------------------------------------------------------------+
    '' | Dracblade Ram Driver (with grateful acknowlegements to Cluso)            |
    '' +--------------------------------------------------------------------------+
                            org     0
    tbp2_start    ' setup the pointers to the hub command interface (saves execution time later
                                          '  +-- These instructions are overwritten as variables after start
    comptr                  mov     comptr, par     ' -|  hub pointer to command                
    hubptr                  mov     hubptr, par     '  |  hub pointer to hub address            
    ramptr                  add     hubptr, #4      '  |  hub pointer to ram address            
    lenptr                  mov     ramptr, par     '  |  hub pointer to length                 
    errptr                  add     ramptr, #8      '  |  hub pointer to error status           
    cmd                     mov     lenptr, par     '  |  command  I/R/W/G/P/Q                  
    hubaddr                 add     lenptr, #12     '  |  hub address                           
    ramaddr                 mov     errptr, par     '  |  ram address                           
    len                     add     errptr, #16     '  |  length                                
    err                     nop                     ' -+  error status returned (=0=false=good) 
    
    
    ' Initialise hardware tristates everything and read/write set the pins
    init                    mov     err, #0                  ' reset err=false=good
                            mov     dira,zero                ' tristate the pins 
    
    done                    wrlong  err, errptr             ' status  =0=false=good, else error x
                            wrlong  zero, comptr            ' command =0 (done)
    pause
                            rdlong  cmd, comptr     wz      ' command ?
                  if_z      jmp     #pause                  ' not yet
    ' decode command
                            cmp     cmd,#"M"        wz                ' move a block from ram to the display
                  if_z      jmp     #moveblock
                            cmp     cmd, #"I"       wz      ' init
                  if_z      jmp     #init     
                            mov     err, cmd                ' error = cmd (unknown command)
                            jmp     #done
    
    '---------------------------------------------------------------------------------------------------------
    
    
    ram_open                rdlong  hubaddr, hubptr         ' get hub address
                            rdlong  ramaddr, ramptr         ' get ram address
                            rdlong  len, lenptr             ' get length
                            mov     err, #5                 ' err=5
    ram_open_ret            ret
    
    Moveblock               ' uses ramaddr and len
    '     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
                            mov     dira,direction          ' set P0-P23 as outputs 
                            call    #ram_open               ' get ramaddr and len
                            or      ramaddr,pin22              ' start with pin 22 high
    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
                            jmp     #init
    
    halt                    jmp     #halt                        
                                                  
    ' ************************ Variables ******************************
    delay                   long    80                                    ' waitcnt delay to reduce power (#80 = 1uS approx)
    Zero                    long    %00000000_00000000_00000000_00000000 ' for tristating all pins
    pin22                   long    %00000000_01000000_00000000_00000000
    direction               long    %00000000_11111111_11111111_11111111
                            fit     496      
    
  • average joeaverage joe Posts: 795
    edited 2012-04-02 08:29
    Wonderful! I am still running ram chips @5v. I am debating the switch to 3.3v, but looking at the timings I think 5v will be best. My new board will allow for either voltage with the change of a jumper. Please take a close look at the new schematic and let me know if you see any errors or room for improvement. I will be ordering a short run of boards as soon as I figure out how to do a large layout with the free version of eagle. I plan on sending you one when I get them done.


    Here's the schematics, and a basic idea for a layout. I am unable to layout a board because I am using eagle light. If you would do me a HUGE favor and throw a layout together, I will send you one when they're printed.
    1024 x 705 - 90K
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-02 16:07
    Can you repost that .jpg a bit bigger - I can see the chips but not the text that goes with them. (I added a .pdf 'printer' to my computer which you can then print to from any program. I think there are a number of these free pdf printers around. The pdf files can be zoomed better than a .jpg)

    Re getting boards made I wonder if 3.3V memory chips would be better as there would be an extra cost with the board space required for the resistors?
  • average joeaverage joe Posts: 795
    edited 2012-04-02 21:23
    The rar archive contains the schematic, png copy of the schematic as well as a basic idea for the layout. I will start printing as .pdf from now on, as per your advice.
    Concerning switching to 3.3v, I guess it's really a trade-off between speed and board footprint. I'm not sure how much space those resistors would add, nor how much more it would cost. I am also unsure what difference running @5v will do to clock speed. The 161's are rated @ 4.5 and 2 volts supply. Max frequency @2v is 6mhz, at 4.5v it's 30mhz. I'm wondering if this will help speed transfers from hub to ram and ram to hub. This will not improve ram to display writes, but should double working frequency? I would be interested to see what the max you're clocking your boards at. If it's close to the 30mhz side then I would say the switch to 3.3v would be ok. If it's under half I think the 5v would be best.

    If we can get the cost of a 3.3-5v board under $20 bucks, then it would be worth a short run to me.
    *edit*
    JP2 could be removed, and ext_out replaced with a single pin or this pin could be added to FPouts. This would save a bit of board space.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-03 01:16
    The rar archive contains the schematic, png copy of the schematic as well as a basic idea for the layout. I will start printing as .pdf from now on, as per your advice.

    Yes, sorry about that - not able to extract things from the work computer. I'll take a look when I get home.

    Thanks for the hints re the clock freq. Hopefully over the next few days I'll get a chance to push it all to pasm speeds. Start with some NOPs and then remove them one by one. The loop to move data from ram to display is only 4 pasm instructions plus one DJNZ so we shall see how fast it can go. I suspect the propogation of the overflow through the five 161 chips might be a limiting factor. Shouldn't matter though - 30ms vs 60ms for a screen refresh would not be noticable.

    I'd still hold re getting boards made. Still a few things to test out. My working board is becoming a mess of wire wrap links and drilled out vias but it is helping refine what the final working board is going to look like. I know with what we have that this is going to be quick. I think we can get it to 'ipad' speeds - touch the display and something happens instantly. Compared with my android pandapad, I can say we have already moved beyond 'android speed' for some things. (especially bootup time). All very exciting.
  • average joeaverage joe Posts: 795
    edited 2012-04-03 02:04
    I think the ram voltage is key with getting the hw as fast as possible. I agree that 30ms vs 60ms screen refresh is not perceivable, but doubling transfer speed to and from ram will be huge for me. Especially considering I will be using the 19 pins for quite a bit more than just transferring to screen and ram. My schematic allows reads from the screen, which I plan on using to dump a screen to Sd card. I also plan on being able to use p0-18 WHILE transferring from ram to display. I'm working on output expansion boards in the next few days. I'm planning several different modules, but the first to be completed will be * 2 - 4 x 40 LCD screens with 16 rotary encoders with push buttons, 16 leds and some buttons. *

    I apologize for being antsy to print boards, but I do not have enough room on the breadboards I have to put this together. Don't want to buy ANOTHER board, but just might. I'm ordering parts REAL soon, having larger ram will be nice.

    I totally agree that we are moving beyond android speeds. I switched back to my DUMB OLD hardware to work on Midi implementation, as well as put the finishing touches on my guitar switcher. I added mono audio out and midi i/o. Have not tested either because I'm trying to get the screen working again. I don't know what I did, but I messed something up.
  • average joeaverage joe Posts: 795
    edited 2012-04-03 05:18
    I found the problem a little while ago. The wire on the ribbon cable for pin2 had broke at the solder joint with the propRPM board. This is the second wire I've had to fix. That's what happens when you ghetto rig.
    So I was just looking over the datasheet for the 161's again. Found a neat little formula for cascaded counting.

    1/ (CP to TC prop. delay + TE to CP setup +TE to CP hold) = about max frequency

    So for my figuring from the datasheet, for 2v operation.
    1 / (185 + 50 + 0) = about 4MHZ
    This is a long way from 21MHZ spec'd @ 4.5V. I know we're not running @2v, but 3.3. Not sure how this scales across, but it will be interesting to see your results. Now back to making new code work on old hardware. *headache*

    *edited*

    I just flashed on an idea to save some board space for the PropERMidi board. Move the resistors for the lcd screen to a board that stands between the two. Not the most elegant solution, but a solution nonetheless.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-03 07:18
    Should be plenty fast enough.

    Re designs, I am working tonight on the SD driver and looking at the code out there, eg Kye's driver, it really does make things a lot simpler to devote 4 dedicated prop pins to the SD card. I had devoted P21-P23 with the /CS line decoded elsewhere but it will mean customising Kye's driver and I'd rather keep it as the standard version.

    So I'm going to steal P24 which is the audio output for /CS and then for audio, borrow P29 which is the eeprom data line.

    Schematic attached.

    I've got some spare breadboards - I'll post them to you tomorrow.
  • average joeaverage joe Posts: 795
    edited 2012-04-03 07:41
    Dedicated sd pins makes things easier by far. I was able to get fsrw going with minor adjustments. On my HW 3.4, I used a decoded /cs line and passed the address of the enable pin for this line. Then before doing an sd transfer, I set the address before calling. It works, but there are problems with this. I have thought about using locks to control access to the demux lines. This will use a few clock cycles, but should provide easy, safe sharing of the demux among cogs.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-03 16:12
    Yes 4 lines just for SD card makes things easier. I'm mulling over ways of running Catalina at the same time. Instead of using the 3 pins to decode a 138, use a MCP 23008 on the I2C bus, then take 3 of those pins and decode to a 138. That frees up 3 prop pins that could be used for external SPI memory (or even more cunning things like decoding a MCP23016 or two and feeding the data via I2C.) Terribly slow compared with parallel ram, but speed does not matter so much with C programs that use caching. I might post over on the Catalina thread about this.

    Also for audio, I might use some lower number pins rather than P29, and then use two pins and get stereo. Kye's original SD driver contained a wav player and it would be cool to have a music player as one of the touchscreen icons.

    In a general sense, once all the prop pins have been used to move pictures around from SD card to ram to the screen, that part can go to sleep and there are now a lot of free propeller pins for MIDI and other i/o.
  • average joeaverage joe Posts: 795
    edited 2012-04-06 15:28
    Hey Doc, how's the project coming? Just one quick question, what do you think about doing a left-shift every bus transaction? Would this waste too many clock cycles or do you think we could fit this in? I've been thinking about using the first 4 pins for Audio and Midi I/O.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-06 16:21
    Project slowly getting there. SD card working, touchscreen working. Display is working in Spin and now porting it over to pasm. I'm about half way through that at the moment.

    I'm not sure about left shifting. It isn't just the speed, it is also whether there are enough pins. The way I am doing things, once a picture has been sent to the screen, P0-P20 are free. In practice that would mean that if you want to play a song, you can't update the screen at the same time. But you can be polling for the screen being touched. There is a potential solution though - instead of decoding P25-P27 through a 138, use a MCP23008 on the I2C bus.

    Midi is a bit like RS232, right? In which case, outputs can be pins that you can enable when you need them. Inputs on the other hand need dedicated pins.

    So maybe we can free up P25-P27, use two for audio, one for Midi IN, and then intermittently enable another prop pin for midi OUT (ie you can only output if the screen is not being updated).
  • average joeaverage joe Posts: 795
    edited 2012-04-06 17:12
    Eh, it sounds like my idea may have taken me further from the solution. Two propeller chips are sounding better and better. One for the screen, one for the sound module. If this is the case, we could ditch midi and audio on the controller. That would free 4 pins, and chip to chip communication would be done through EEPROM pins? I don't want to mess with the programming pins, but they could be re-purposed for midi *or something else?* later. I still think I will need that `245 since I would very much like to use the 19 pins while transferring from ram to display. I have ALL SORTS of plans for these pins actually. :)

    Midi is quite a lot like 232. 7-bit asynchronous-serial, inverted, at 31.25k? I can't remember the number exactly. The spec also uses opto-isolators to combat ground loops. Not too big of a deal. The only reason my design requires CONSTANT midi in AND OUT is because I plan on doing Midi Time Code to Midi Clock conversion and vice versa. Not a feature I will be using all the time, but it will come in VERY handy when I do need it .
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-07 17:14
    Ok, now we have something working!

    Hit the reset button, it boots into a simple text display running from the propeller ROM to display "SD". If the SD card works, it loads a font and displays a message. And then it reads a picture off the SD card and displays it.

    Unzip the file and put the .ili picture and the .ifn font file on the SD card.

    There was a fair bit of recoding - everything changed from big-endian to little-endian. Lots of pasm code to rewrite.

    But the 161 concept is sound - it is (surprisingly) faster to have 5 external counter chips than it is to use the propeller's internal counters.

    The code to update the display from ram did not need any NOPs or delays. It is just 5 pasm instructions to send two bytes.
    ramtodisplay_loop       andn    outa,maskP17            ' ILI write low
                            or      outa,maskP17            ' ILI write high
                            andn    outa,maskP19            ' clock 161 low
                            or      outa,maskP19            ' clock 161 high
                            djnz    len,#ramtodisplay_loop
    

    76800 words = 153600 bytes, transferred in 30ms = 5.12 megabytes per second = 40.96 megabits per second.
  • average joeaverage joe Posts: 795
    edited 2012-04-07 20:18
    WOW! Lemme repeat. WOW. 40.96 megabits per second is very very nice. I'll do the math but this should work quite well. I received my parts today, but decided to wait till after the expo to play with this. There's too much to work on right now, and not enough time. I pulled everything out of the project box because the inside was looking quite gross. I'm stripping the inside to bare metal and will rattle can quickly. Then put everything back together with version 3.4.2 hardware *my old pin for pin hardware with midi and audio* with some slight adjustments. Also quite a bit of coding left. I will not be working on any "throw away" code *drivers for 3.4.2 have a couple bugs, nothing major.* I can't wait to get working on the 161 based board, and I am getting close to a proposed schematic.
    Keep up the great work!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-07 22:13
    I sent you a breadboard and some chips - should arrive next week. It is a large breadboard so you should be able to get all the project on one board.

    I think you started off with a spin version that took 9 seconds to refresh the screen. So we are just under 300x faster than that. I've very pleased that there were no problems with the overflow delays through the 161 chips. Your circuit is so simple but so clever!

    One nice thing about these fast screen refreshes - you can get on with other things like making music without having to worry about the screen so much.

    I need to think about icons. The previous code used .raw files with RGBA where A is a transparency layer. I takes longer to process on the fly. I am thinking that when you load an icon, take the background where it is going to go and store that in a file and combine it with the icon file so that when you re-display that icon it draws the background at the same time. So icon files are two bytes per pixel not four, and there is a separate transparency file. It means you can't move icons so easily, but generally they stay in the same place anyway. Should speed up icon refreshes about 100x so I think it is worth it.
  • pedwardpedward Posts: 1,591
    edited 2012-04-07 22:17
    Have a look at how Microsoft did icons for Windows. Basically instead of an Alpha layer, they did chroma keying -- a special color is designated as "transparent" and you avoid replacing the background where that color is.
  • average joeaverage joe Posts: 795
    edited 2012-04-07 22:43
    Thank you SO much! 300x is a HUGE improvement! To be honest, the credit goes to whoever came up with the idea of using a counter in the first place. The block transfer thingy you had on one of your pdf's made me think why not use 161's. Once again the idiot savant in me shines through! :D
    Transparency is very nice, I've had some issues because I have not programmed anything for that. I don't see moving icons as too big of a deal. As long as we can define a decent sized character and move that easily *remember the old faders? gotta finish that eventually!*
    G2G, Thank you SO SO SO much!
    Joe
    *edit*
    I've been thinking about a screen designer. There are many ways to go, but my initial efforts playing with the fader idea were slow and laborious. A bank of custom, system characters will be needed. This includes transport controls such as play, pause, stop, FF, and RW. I HAD example layouts in PF, but lost these due to stupidity. They were very slow to draw since they used multiple characters. This will work WAY better and be WAY faster :D
    Also, you need a name for your current board. Eurocard_Touchscreen_161 is too long :D I like "Euro-Touch++" I will examine it a few more times but it looks quite nice. Perfect for most Touch applications!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-04-08 05:45
    Playing around with images. Drawing a screen is so fast that it is ok to spend half a second doing a transfer from a standard file format. I took a picture off google images, ran it through paint shop pro, rotated it 90 degrees (not necessary if you reconfig the screen for landscape) resized it to 240x320 and saved it as a .raw file which is a standard RGB 3 bytes per pixel. Then convert with this little routine:
    PUB RawPicture | i' take a standard RGB .raw file and convert to two byte RRRRRGGGGGGBBBBB format and fill memory
        fat.openfile(string("synth.raw"),"R")                ' a .raw file 240 wide, 320 high
        i := 0
        repeat 600
          fat.readdata(@sdbuffer,384)                       ' 240x320=76800 bytes x3
          docmd("E",@sdbuffer,@rambuffer,128)               ' convert to 2 byte
          HubToRam(i,128)                                   ' send to external ram
          i += 128                                          ' increment external ram counter
        fat.closefile                                       ' close file
        DisplayPicture                                      ' display the picture
    

    Photo of this displaying "synth.raw"

    synth.jpg


    This is what we need for audio - but maybe sliders might be better than circular knobs? Easier to use with a touchscreen?
    1024 x 768 - 97K
  • average joeaverage joe Posts: 795
    edited 2012-04-08 06:38
    You know that is the one problem I have been mulling over. Even the faders are a bit difficult to control. Faster screens mean drag n drop faders will be possible now, but accurately setting during live performance might be difficult. I would like at least 1 rotary encoder and probably a minimum of 8 *since I've had 3 of my friends say they think 8 minimum. A stylus will be a big improvement too!
  • jazzedjazzed Posts: 11,803
    edited 2012-04-08 08:32
    Dr_Acula wrote: »
    I sent you a breadboard and some chips - should arrive next week. It is a large breadboard so you should be able to get all the project on one board. ...

    Is there a PCB available? If so I would like to have one for doing a software reference design for this type of hardware. I've been thinking about this 161 load and strobe idea a long time like used int NES cartridges, but have been too busy to act on it. It would be nice to use and support an existing hardware design before making my own.

    Thanks,
    --Steve
  • average joeaverage joe Posts: 795
    edited 2012-04-08 08:38
    Dr Acula should have the schematic just about perfected. I'm not sure how many mods are needed for the boards he printed but if they are as extensive as he suggested, we might need a re-print. I will be supporting his hardware since I will be using modified versions of his low-level code. I need to look at the printed boards vs new schematic before I give the nod this time. If I would have been really THINKING about using the board as opposed to just looking it over, I would have caught one mistake. I am sorry about that again! Hopefully another run of boards will be made soon. I'm sure a few people will be interested even if they decide to use them purely for the ram.
  • jazzedjazzed Posts: 11,803
    edited 2012-04-08 09:18
    I'm confused with the 74161 part of the schematic.

    Ripple Carry Out "RCO" transitions low to high when Q outputs go from X to $F.
    How can you guarantee that the next "nibble" counter is 0 while the first stage counter is $F?

    That is: if you load $0000E to 5 counters and strobe the clock once, you want to get $0000F. Then strobe again to get $00010.

    So the sequence you want is : load $0000E, strobe one gets $0000F, strobe two gets $00010.
    This seems to happen instead: load $0000E, strobe one gets $0001F, strobe two gets $00010.

    What really happens? Don't you need an inverter on the RCO for clocking the next stage?

    Thanks,
    --steve
  • jazzedjazzed Posts: 11,803
    edited 2012-04-08 09:28
    I'm sorry. I misunderstood the schematic. But isn't there a possibility that the propagation will cause trouble?
  • average joeaverage joe Posts: 795
    edited 2012-04-08 09:38
    It's ok, these chips can be a bit confusing. Pay close attention to the operation of load. That's what got Drac the first time. He was worried about propagation delays and the like when these things seem to work quite well. One more piece of advice, Dr Acula's very nice design keeps all chips at 3.3v. If you look at the datasheets, they are quite de-rated at 2 volts. I'm sure 3.3 is quite better, but 5v seems best for super-high speed operation. Plus 5v tolerant ram is less expensive than 3v. I plan on using 5v and some additional circuitry but need to actually try a few things before I commit. My thread has the most recent schematic I've written. It is not done and changes are small at this point. The inverter on the reset line is going away and getting replaced with an transistor - inverter. LCD wr/rd will be hooked up to Function Register. '374 http://forums.parallax.com/showthread.php?137999-LCD-touchscreen-A-development-thread
  • jazzedjazzed Posts: 11,803
    edited 2012-04-08 09:56
    The problem with using 5V parts is the "safe" resistor values cause RC slew rate problems and can degrade performance.

    The 74LV161 widely available in TSSOP and SO packages. That plus an extra $1 per SRAM beats analog uncertainty to me.
  • average joeaverage joe Posts: 795
    edited 2012-04-08 11:25
    See, this is what I'm worried about myself. That's why I'm going to try it after the expo. I'm stuck with thru-hole components for now. Adapters are not out of the question, but if that's the case I may just go completely SMD and have an excuse to upgrade my tools.
Sign In or Register to comment.