Shop OBEX P1 Docs P2 Docs Learn Events
Propeller GUI touchscreen and full color display - Page 18 — Parallax Forums

Propeller GUI touchscreen and full color display

1151618202124

Comments

  • average joeaverage joe Posts: 795
    edited 2012-08-19 00:57
    Okay, burst read working. I have not stuffed it into the touch.spin but I'll try to get that done soon.
    needed to set up Pcounters for burst read, done on init
            mov     frqa, _frqa         ' setup NCO freq
            mov     frqb, _frqb         ' setup EDGE freq
    
    
    the "overhead"
    get_values              mov     ptr,   hubaddr          ' get hub address
                            mov     count, line_size        ' get ram address                        
                            'shr     count, #1                ' shift data to word alligned from byte
     
                            'shr    vmaddr, #1                ' shift data to word alligned from byte
                                                  
                            mov     dirb,latchvalue         ' make copy of latchvalue here for restore
                            or      outa,maskP16P20         ' set control pins high
                            or      dira,maskP16P20         ' set control pins P16-P20 as outputs   
    get_values_ret          ret
    
    set373                  or      outa,maskP22            ' pin 22 high 
                            or      dira,#%1_11111111       ' enable pins 0-7 and 8 as outputs
                            and     outa,maskP0P8low        ' P0-P8 low
                            or      outa,latchvalue         ' send out the data 
                            or      outa,maskP8             ' P8 high, clocks out data
                            andn    outa,maskP22            ' pin 22 low
    set373_ret              ret       
    
    
    set161                  mov     latchvalue,#%11111110   ' group 1, displays all off
                            call    #set373                 ' send out to the latch
                            and     outa,maskP0P20low       '%11111111_11100000_00000000_00000000   
                            or      dira,maskP0P20          '%00000000_00011111_11111111_11111111
                            or      outa,vmaddr             ' send out ramaddr
                            or      outa,maskP20            ' clock high
                            or      outa,maskP19            ' load high
    
                            or      outa,maskP16P20 ' set control pins high
                            
                            mov     latchvalue,#%11111101   ' group 2, displays all off
                            call    #set373                 ' send out to the latch
                            
    
    set161_ret              ret
    
    and the transfers
    ' command S
    pasmhubtoram            call    #get_values             ' get hubaddr,ramaddr,len and set control pins
                            call    #set161
                                                                                                                                                     
    hubtoram_loop           and     outa,maskP16P31         '%11111111_11111111_00000000_00000000       ' clear for output                   
                            rdword  data_16,ptr             ' get the word from hub
                            and     data_16,maskP0P15       ' mask to a word only
                            or      outa,data_16            ' send out the byte to P0-P15
                            andn    outa,maskP17            ' set mem write low
                            add     ptr,#2                  ' increment by 2 bytes = 1 word. Put this here for small delay while writes
                            or      outa,maskP17            ' mem write high
                            andn    outa,maskP20            ' clock 161 low
                            or      outa,maskP20            ' clock 161 high
                            djnz    count,#hubtoram_loop    ' loop this many times
    
                            mov    latchvalue, dirb         ' restore latch value
                            call   #set373
                            and    dira,    maskP0P20low     ' tristates all the common pins, leaves P22 as is though
    
    '                       jmp     #done                   ' tristate pins and listen for commands
    
    ' command S
    wr_cache_line_ret       ret           
    
    
    '-----------------------------------------------
    ' setups needed for burst read
    '-----------------------------------------------
    _frqa                   long    $1000_0000
    _ctra                   long    4<<26 | 20      ' NCO mode on P20
    _phsa                   long    $0000_0000      ' phsa offset for adjusting clock start
    
    _frqb                   long    2               ' phsb accumulates twice per edge
    _ctrb                   long    $A<<26| 20      ' Edge Accumulate mode on P20
    
    '----------------------------------------------------------------------------------------------------
    '
    ' 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    #get_values             ' get hubaddr,ramaddr,len and set control pins
                            call    #set161
    
                            
                            and     dira,maskP16P31         '%11111111_11111111_00000000_00000000 inputs
                            andn    outa,maskP16            ' memory /rd low
    
                            'insert bus read here
                             or      outa,maskP20           ' get clock line?
                             
    
                            mov     phsa, _phsa             ' init counters phsa
                            mov     phsb, ptr               ' save hub ptr to phsb
                            mov     ctrb, _ctrb             ' set ctr be mode
                            andn    outa,maskP20            ' 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,maskP20            ' 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,    maskP0P20low     ' tristates all the common pins, leaves P22 as is though
    
    
    rd_cache_line_ret       ret
    
    ' variables
    pasm_n                  long    0                                    ' general purpose value
    data_16                 long    0                                    ' general purpose value
    latchvalue              long    %00000000_00000000_00000000_00000000  ' current 373 value  
    
    ' constants
    'Zero                    long    %00000000_00000000_00000000_00000000 ' used in several places
    maskP0P2low             long    %11111111_11111111_11111111_11111000 ' P0-P2 low
    maskP0P20               long    %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20    
    maskP0P18low            long    %11111111_11111000_00000000_00000000 ' P0-P18 low
    maskP16                 long    %00000000_00000001_00000000_00000000 ' pin 16
    maskP17                 long    %00000000_00000010_00000000_00000000 ' pin 17
    maskP18                 long    %00000000_00000100_00000000_00000000 ' pin 18
    maskP19                 long    %00000000_00001000_00000000_00000000 ' pin 19
    maskP20                 long    %00000000_00010000_00000000_00000000 ' pin 20
    maskP22                 long    %00000000_01000000_00000000_00000000 ' pin 22
    maskP16P31              long    %11111111_11111111_00000000_00000000 ' pin 16 to pin 31
    maskP0P15               long    %00000000_00000000_11111111_11111111 ' for masking words
    maskP16P20              long    %00000000_00011111_00000000_00000000
    maskP0P20low            long    %11111111_11100000_00000000_00000000 ' for returning all group pins HiZ
    maskP16P17P20           long    %00000000_00010011_00000000_00000000
    maskP0P8low             long    %11111111_11111111_11111110_00000000  ' P0-P7 low
    maskP8                  long    %00000000_00000000_00000001_00000000  ' pin 8
    
    It's FAST!
  • average joeaverage joe Posts: 795
    edited 2012-08-22 03:35
    I needed a break from the cache driver, so I decided to see how fast I could get transfers to run... Using the counters for burst read was not too hard thanks to Jazzed.
    'setups for burst read
    '-----------------------------------------------
    ' setups needed for burst read
    '-----------------------------------------------
    rd_phsa                  long    $0000_0000      ' phsa offset for adjusting clock start
    rd_frqa                  long    $1000_0000
    rd_ctra                  long    4<<26 | 20      ' NCO mode on P20
    
    rd_frqb                   long    2               ' phsb accumulates twice per edge
    rd_ctrb                   long    $A<<26| 20      ' Edge Accumulate mode on P20
    
    
    pasmramtohub            call    #get_values             ' get hubaddr,ramaddr,len and set control pins
                            call    #set161
                            or      outa,maskP16P20         ' set control pins high
                            mov     latchvalue,#%11111101    ' group 2, displays all off
                            call    #set373                 ' send out to the latch
                         
                            and     dira,maskP16P31         '%11111111_11111111_00000000_00000000 inputs
                            andn    outa,maskP16            ' memory /rd low
    
                            'insert burst read here
                             or      outa,maskP20           ' get clock line?
                            mov     phsa, rd_phsa             ' init counters phsa
                            mov     phsb, hubaddr           ' save hub ptr to phsb
                            'ctrb setup for burst read
                            mov     frqb, rd_frqb         ' setup EDGE freq
                            mov     ctrb, rd_ctrb             ' set ctr be mode
                            'ctra setup for burst read
                            mov     frqa, rd_frqa         ' setup NCO freq
                            
                            andn    outa,maskP20            ' start counters
    
                            rdword  data_16,phsb            ' sync up only                  1-2
                            mov     ctra, rd_ctra             ' enable address counter clk   3              1
                            
    ramtohub_loop           ' 10MB/s read loop uses phsb for hub pointer
                            mov     data_16,ina             ' get first data               4              2
                            wrword  data_16,phsb            ' move data to hub            1-2            3-4
                            djnz    len,#ramtohub_loop                                '    3              5
    
                            or      outa,maskP20            ' stop clock
                            mov     ctra, #0                ' stop counter
    
                            or      outa,maskP16            ' memory /rd high
                            jmp #done
    
    

    Then I wanted to see if I could tune the hub to display, as it was taking 3 hub-slots to complete...
    ' command V
    pasmhubtodisplay        call    #get_values             ' get hubaddr,ramaddr,len and set control pins high
                            andn    outa,maskP19            ' CS low
                            or      dira,maskP0P15          '%00000000_00000000_11111111_11111111   
        
    hubtodisplay_loop       and     outa,maskP16P31         '%11111111_11111111_00000000_00000000       ' clear for output                   
                            rdword  data_16,hubaddr         ' get the word from hub
                            'and     data_16,maskP0P15       ' mask to a word only
                            or      outa,data_16            ' send out the byte to P0-P15
                            andn    outa,maskP18            ' ILI write low
                            or      outa,maskP18            ' ILI write high
                            add     hubaddr,#2              ' one word
                            djnz    len,#hubtodisplay_loop
                            or      outa,maskP19            ' CS high
                            jmp     #done
    
    
    Then I tried to get hub to ram running the burst... and failed. and failed. and failed...

    So I moved on to the ram to display... Not much to trim really, just 5 instructions. Well it took forever but I got it down to 2.
    '-----------------------------------------------
    ' setups needed for burst read to display
    '-----------------------------------------------
    ds_phsa                  long    $0000_0000      ' phsa offset for adjusting clock start
    ds_frqa                  long    $2000_0000
    ds_ctra                  long    4<<26 | 20      ' NCO mode on P20
    
    ds_phsb                  long    $0000_0000      ' phsb offset for adjusting clock start
    ds_frqb                   long   $2000_0000      ' phsb accumulates twice per edge
    ds_ctrb                   long   4<<26 | 18      ' NCO mode on P18 
                                                    
    fastpasmramtodisplay    call    #get_values             ' get hubaddr,ramaddr,len (only uses len) and set control pins
                            sub     len, #2
                            call    #set161
                            or      outa,maskP16P20         ' set control pins high
                            mov     latchvalue, dirb
                            call    #set373
                            and     dira,maskP16P31         ' %11111111_11111111_00000000_00000000 so prop pins 0-15 HiZ
                            andn    outa,maskP19            ' CS low
                            andn    outa,maskP16            ' ram /rd low
                'ctra setup for burst read
                            mov     phsa, ds_phsa             ' init counters phsa        P20
                            mov     phsb, ds_phsb             ' init         to phsb   P18
                            mov     frqa, ds_frqa             ' setup NCO freq             P20
                            mov     frqb, ds_frqb             ' setup NCO freq        P18
                            andn    outa,maskP20              ' start counters             P20
                            andn    outa,maskP18              ' start counters         P18
                                                                                                    '   P20   Count                 P18  Write
                            mov     ctrb, ds_ctrb             ' enable display clk           P18         0                           2   4   6   8
                            mov     ctra, ds_ctra             ' enable address counter clk   P20         2  4  6  8                  10  12  14  0
                            
    fastramtodisplay_loop   'andn    outa,maskP18            ' ILI write low                                                      
                            'or      outa,maskP18            ' ILI write high
                            'andn    outa,maskP20            ' clock 161 low
                            'or      outa,maskP20            ' clock 161 high
                            nop                                  '                                       10  12  14   0               2   4   6  8
                            djnz    len,#fastramtodisplay_loop   '                                       2    4   6   8               10  12  14 0
                                                                                                      '  10  12  14   0               2   4  6   8
                            mov     ctrb, #0                ' stop counter                               2    4   6   8               10  12  14 0
                            mov     ctra, #0                ' stop counter
                            
                            or      outa,maskP20            ' stop clock
                            or      outa,maskP18            ' stop clock
                                         
                            or      outa,maskP16            ' mem /rd high
                            or      outa,maskP19            ' CS high 
                            jmp     #done
    

    One slight problem, seems it doesn't quite work right? I am able to draw backgrounds, but everything else draws garbage? I need to think through it a bit, but if I can get the counter code to work, it will be as fast as the display can draw! Now that I have it partially working, I will take a look at hub to ram. It might help me figure out what I'm doing wrong.

    Now, just for my sanity in case I screw something up
    DAT
    '' +-----------------------------------------------------------------------------------------------+
    '' | Touchblade 161 Ram Driver (with grateful acknowlegements to Cluso Jazzed and Average Joe)     |
    '' +-----------------------------------------------------------------------------------------------+
                            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) 
                            
    init                      'set up latches here
                            or      outa,maskP22            ' pin 22 high 
                            or      dira,maskP22            ' and now set as an output
                            mov     dirb, #%11111111        'set latch All hi
                            
    ' Initialise hardware tristates everything and read/write set the pins
    
    done                    mov      err, #0                ' reset err=false=good
                            mov     latchvalue, dirb        ' restore latch value
                            call    #set373
                            and     dira,maskP0P20low       ' tristates all the common pins, leaves P22 as is though
                            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, #"S"       wz      ' hub to ram              ''S
                  if_z      jmp     #pasmhubtoram                                     
                            cmp     cmd, #"T"       wz      ' ram to hub              ''T
                  if_z      jmp     #pasmramtohub
                            cmp     cmd, #"U"       wz      ' ram to display          ''U
                  if_z      jmp     #pasmramtodisplay                                 
                            cmp     cmd, #"V"       wz      ' hub to display          ''V
                  if_z      jmp     #pasmhubtodisplay           
                            cmp     cmd, #"E"       wz      ' convert 3 byte .raw format to 2 byte .ili format - hub to hub                      ''E
                  if_z      jmp     #rawtoiliformat
                            cmp     cmd, #"F"       wz      ' convert 3 byte .bmp format BGR to 2 byte ili format (same as E but order reversed) ''F
                  if_z      jmp     #bmptoiliformat              
                            cmp     cmd, #"X"       wz      ' merge icon and background based on a mask                                          ''X
                  if_z      jmp     #mergeicons
                            cmp     cmd, #"Z"       wz      ' set the 161 counters                                                               ''Z
                  if_z      jmp     #extset161
                            cmp     cmd, #"M"        wz     ' pass current latch value to pasm                                                   ''M
                  if_z      jmp     #latch373value
                            cmp     cmd, #"I"       wz      ' init                                                                               ''I
                  if_z      jmp     #init
    
                            cmp     cmd, #"W"       wz      ' fast RAM to display, doesn't work right?                                           ''I
                  if_z      jmp     #init
                                                                                                            
                            mov     err, cmd                ' error = cmd (unknown command)
                            jmp     #done
                            
    ' ----------------- common routines -------------------------------------
    
    get_values              rdlong  hubaddr, hubptr         ' get hub address
                            rdlong  ramaddr, ramptr         ' get ram address
                            rdlong  len, lenptr             ' get length
                            mov     err, #5                 ' err=5
                            mov     dirb,latchvalue         ' make copy of latchvalue here for restore
                            or      outa,maskP16P20         ' set control pins high
                            or      dira,maskP16P20         ' set control pins P16-P20 as outputs   
    get_values_ret          ret
    
    
    set373                  or      outa,maskP22            ' pin 22 high 
                            or      dira,#%1_11111111       ' enable pins 0-7 and 8 as outputs
                            and     outa,maskP0P8low        ' P0-P8 low
                            or      outa,latchvalue         ' send out the data 
                            or      outa,maskP8             ' P8 high, clocks out data
                            andn    outa,maskP22            ' pin 22 low
    set373_ret              ret       
    
    
    set161                  mov     latchvalue,#%11111110   ' group 1, displays all off
                            call    #set373                 ' send out to the latch
                            and     outa,maskP0P20low       '%11111111_11100000_00000000_00000000   
                            or      dira,maskP0P20          '%00000000_00011111_11111111_11111111
                            or      outa,ramaddr            ' send out ramaddr
                            or      outa,maskP20            ' clock high
                            or      outa,maskP19            ' load high
    set161_ret              ret
                            
    
    '' *** command Z **********
    'changes the latch so displays won't work unless resend the spin value for the latch
    extset161               call    #get_values             ' gets ramaddr = the 161 value to set
                            mov     dirb, latchvalue
                            call    #set161
                            jmp     #done                   ' tristates pins etc     
    
                            
    ' *** command M - pass current latch value and send out
    latch373value           call    #get_values
                            mov     dirb,hubaddr
                            jmp     #done
    ' variables
    pasm_n                  long    0                                    ' general purpose value
    data_16                 long    0                                    ' general purpose value
    ililow                  long    0                                    ' low data byte 
    ilihigh                 long    0                                    ' high data byte 
    red                     long    0                                    ' red, green blue variables
    green                   long    0
    blue                    long    0
    
    ' constants
    Zero                    long    %00000000_00000000_00000000_00000000 ' used in several places
    'maskP0P2low            long    %11111111_11111111_11111111_11111000 ' P0-P2 low
    maskP0P20               long    %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20    
    maskP0P18low            long    %11111111_11111000_00000000_00000000 ' P0-P18 low
    maskP16                 long    %00000000_00000001_00000000_00000000 ' pin 16
    maskP17                 long    %00000000_00000010_00000000_00000000 ' pin 17
    maskP18                 long    %00000000_00000100_00000000_00000000 ' pin 18
    maskP19                 long    %00000000_00001000_00000000_00000000 ' pin 19
    maskP20                 long    %00000000_00010000_00000000_00000000 ' pin 20
    maskP22                 long    %00000000_01000000_00000000_00000000 ' pin 22
    maskP16P31              long    %11111111_11111111_00000000_00000000 ' pin 16 to pin 31
    maskP0P15               long    %00000000_00000000_11111111_11111111 ' for masking words
    maskP16P20              long    %00000000_00011111_00000000_00000000
    maskP0P20low            long    %11111111_11100000_00000000_00000000 ' for returning all group pins HiZ
    maskP0P8low             long    %11111111_11111111_11111111_00000000  ' P0-P7 low
    maskP8                  long    %00000000_00000000_00000001_00000000  ' pin 8
    latchvalue              long    %00000000_00000000_00000000_00000000  ' current 373 value
    
    
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-22 05:03
    Wow, pushing things to the limit there. I'm a bit lost with the cache driver - I need to step back and understand it at a more fundamental level. Can you do it with a simple pasm call? I see code inserted here and there, maybe we can simply add a cache driver to this pasm driver and put some common routines into their own subroutines? I don't know how much space there is left in that cog but it would be really nifty if the cache driver used the same cog as you don't even need locks then.

    Once the boards arrive, are you going to solder one up just to double check it works? If you do, take some photos along the way as that could be useful for a writeup of how to build the board.

    The expansion boards are on the way, will be maybe another couple of weeks to get to you.

    I'm playing around with some crazy stuff trying to translate vb.net into spin. (and then with ersmith's routine, spin into C).

    Rather than work with objects, which spin is not very good at, I'm thinking more in terms of a single database. You put data in and then you request it out again. So a description of a screen like a synthesizer or a button is a list of information.
            'Button1
            '
            Me.Button1.Location = New System.Drawing.Point(68, 37)
            Me.Button1.Name = "Button1"
            Me.Button1.Size = New System.Drawing.Size(84, 30)
            Me.Button1.TabIndex = 0
            Me.Button1.Text = "Button1"
            Me.Button1.UseVisualStyleBackColor = True
            '
            'TextBox1
            '
            Me.TextBox1.Location = New System.Drawing.Point(59, 123)
            Me.TextBox1.Name = "TextBox1"
            Me.TextBox1.Size = New System.Drawing.Size(118, 20)
            Me.TextBox1.TabIndex = 1
    

    With a few minor changes, you can send that straight into a database as strings. Maybe lose the "new system.drawing.size" and just store the numbers. Storing strings is easy with the touch.spin object.

    Then do a sort on the entire database. Either pre compilation or in code, it does not matter. Then request data out of the database, eg an object name, then the size of the object and that gives you areas of the screen that respond when you touch them.

    So two essential things here are a sort algorithm (ideally a quicksort, but since this is only done once, ye olde inefficient bubble sort will do). Then a binary search algorithm to extract the data. So I have this silly little bit of code
    PUB Main | touchtest  ' debug value
      tch.BeginProgram
      Bubblesort(1,6)                                   ' sort the list
      tch.stringstore(0,string("Elephant"))                  ' search for this
      touchtest := BinarySearch(1,6)                    ' do a binary search
      tch.text(string("Found answer"))
      tch.hex(touchtest,2) ' zero if no match
    
    PUB BubbleSort(start,finish) | i,swap
       tch.stringdim(10)                  ' uses string0 as a temp store
       tch.stringstore(1,string("Bee"))
       tch.stringstore(2,string("Cow"))
       tch.stringstore(3,string("Dog"))
       tch.stringstore(4,string("Aardvark"))
       tch.stringstore(5,string("Elephant"))
       tch.stringstore(6,string("Giraffe"))
       repeat
         swap := false
         repeat i from start to (finish-1)
           if tch.stringcompare(i,i+1) >0
             tch.stringcopy(0,i)                            ' swap
             tch.stringcopy(i,i+1)
             tch.stringcopy(i+1,0)
             swap := true
       until swap == false                                  ' repeat until no swaps happened
       repeat i from start to finish                       ' print out the answers in alphabetical order
         tch.stringdebug(i)
    
    PUB BinarySearch(start,finish) | imid, imin, imax,compare      ' http://en.wikipedia.org/wiki/Binary_search_algorithm
       imin := start   
       imax := finish                                      ' string(0) is the key to search
       compare := -1                                        ' if not found returns zero
       repeat while (imax => imin)                          ' repeat until found
         imid := (imin + imax) >> 1                         ' (imin+imax)/2
         compare := tch.stringcompare(0,imid)
         if compare > 0                                     ' search the upper half
           imin := imid + 1
         if compare < 0                                     ' search the lower half
           imax := imid - 1
         if compare == 0
           result := imid
           imax := 0                                        ' ends the routine
    

    And I think we can pull data in and out of that database without having to worry about getting mixed string/number objects working in spin. A database working in just strings, and only in external memory is a very nice thing as you don't have to worry about conserving memory any more. Store all the descriptions of the screen objects long hand like vb.net does and you can always go and extract data later. Plus it demonstrates some of the string routines (thanks Kye!).
  • tritoniumtritonium Posts: 539
    edited 2012-08-22 14:23
    Guys
    I have been following this thread since post 1 and as a result purchased a 3.2" board from egochina and have had hours of 'fun'.
    I was thinking along the lines of using counters and ram and then off you went and did it, but I didn't!
    First of all I must come clean and admit that I am using an arduino at the moment which means that at a clock of 16 Mhz and ONLY a single processor my computing resources are small in comparison to the mighty prop. (I have a cameleon on the shelf but to my shame its only been used in arduino mode - I also have a raspberry pi in the same place - I just dont have the time to invest in learning new architectures while I am able to play with interesting periferals like this touch screen).
    Because of my shortage of pins I have had to use spi and a couple of 574's used as shift registers to provide the 16 data pins, so where you are getting 30 frames a second I get 1/2. But thats ok because for my needs thats PLENTY fast enough, and I am able to display bitmaps recalculated for the 5-6-5 screen colour format, and fonts - I have used the DOS font 8 bit by 16, ie 16 bytes per character, and saved as an array, and by having global backgroung forground colours use these when reading the on/off bits that make up the character as I write/overwrite the display .
    Now to my question - it regards the relatively trivial task of reading the touch screen position. My code works, and if I hadn't read your post that when the screen is not touched the reading gives co-ordinates off screen, and therefore using the interrupt pin is not required, I wouldn't be bothering you now.
    Well I dont get the same results and it is a REAL PAIN; I get a no touch reading of somewhere in the middle of the screen!
    So I wonder if you could share the code/method you use to read the touch position.
    I use 8 bit mode; so I set CS low, and (for x axis) send 0x93 (0xD3 for 'Y' axis) and ignore the return byte, then I send 0x00 and use the returned byte as my result. I know that I am wasting the lsbit but I still get results of 1 - 110 on both X and Y axis. This I do 32 times for each axis and average the result (>>5).
    I have not put a pullup resistor on the int pin (since I'm not using it) and maybe doing this gives a no touch bias to offscreen - I dont know, I havent had the energy to try.
    Perhaps you are doing it differently; I would really like to know.
    If you could summarise the way you have connected yours and the mode and algorythm you use I would be grateful.
    By the way - just as a matter of interest - The arduino is 5v and the display is 3 volt - and all I do is put a 22K resistor in series in the data and control lines and so far the screen hasn't complained - I guess the protection diodes in the display are doing their stuff.
    In My opinion threads like this are like gold and are required daily reading.
    Thanks
    Dave
  • average joeaverage joe Posts: 795
    edited 2012-08-22 19:04
    Hi Dave,
    Not much time but hopefully this will help.
    PRI TouchX
          SPI.SHIFTOUT(Touch_DataIn, Touch_Clock, 5, 8 , %1101_0000)  ' reads x from  500 to 3700  (off < 500 )
          result := SPI.SHIFTIN(Touch_DataOut,Touch_Clock,2, 12)
    
    PRI TouchY      
          SPI.SHIFTOUT(Touch_DataIn, Touch_Clock, 5, 8 , %1001_0000)  ' reads y from 400 to 3800 (off > 3800 ) 
          result := SPI.SHIFTIN(Touch_DataOut,Touch_Clock,2, 12)  
    

    The shiftout is Data, Clock MSBFIRST, 8bits. The shiftin is Data, Clock, MSBPost, 12bits..
    I'll be around later to try and clarify
    Joe

    *edit*
    I've had some more time to re-read the post and I'm not entirely sure of your communication algorithm. I will see if I can track down the C code for the touchscreen.
    The INT pin is not needed and left unconnected on our board.
    Now in my experience, *and this may or may not apply toward your issue* if there is "gunk" on the display it can register a false touch. There is also the issue of the first read from the touchscreen returning incorrectly occasionally. To me it sounds as if the 8bit SPI mode may or may not be an issue.

    Now, we are sending "D0" for touchX and "90" for touchY. The ADS7843 touchscreen controller datasheet is here : http://www.ti.com/lit/ds/symlink/ads7843.pdf
    No time to double check right now but RTFM may help!

    If you have the display, then you may be interested in our board. It's VERY nice and quite a bit faster than 30fps. A full screen draw from RAM file is well under 30ms. Calculating ACTUAL fps depends on the number of FILES drawn from ram * Size of draw, plus spin overhead to setup the draw, ect. I will be taking video soon, but all I can say is Propeller+161addressed SRAM is "The Way To Go!" Well worth the $55 for components.
    BTW: If you are interested in JUST the board, I would send you one if you pay shipping. Also able to arrange Full/Partial kits. PM for details :)
  • average joeaverage joe Posts: 795
    edited 2012-08-22 21:41
    James,
    Re Cache driver: I'm still trying to figure things out, need to take a break for a couple days. It should be quite possible to integrate the cache driver with the PASM driver. There should be plenty of room in the cog, it's just a matter of getting things to work properly. My cache driver passed the cache tests, but failed running "hello world" from SimpleIDE. Like I said, need a short break. I'll resume work next week.

    Production boards arrived today. I plan on soldering one up and taking photos/video when I do.. Sadly I'm quite short on bypass caps, so I need to get the 2 kits together and see if I have enough to build the new board. It will be close, that's for sure. If I don't, I can de-solder a few from previous boards. *Waiting for my new heat-gun to arrive to bulk de-solder previous boards.*

    Very, Very interesting stuff you've been working on. I think it should make some things a snap. WAY cool!

    I've been concerned with getting the PASM driver perfected, and as fast as possible. We're to the point where it shouldn't need changing any time soon. This is proving to be a bit of a challenge since I've never DIRECTLY programmed for the propeller counters. I'm getting it though and learning quite a bit, so that's good. The one thing that's boggling me is the FASTRamToDisplay... I have not really "played" with it too much so it's probably simple. The one thing I've observed is this: When running my simple splash screen test, I can draw the background *first file* but when drawing textT *don't know where yet* it garbles the display and gets stuck in the R2D loop? I'll play with this later, hopefully more information can solve the problem.
    This is the working/old transfer
    pasmramtodisplay        call    #get_values             ' get hubaddr,ramaddr,len (only uses len) and set control pins
                            call    #set161
                            or      outa,maskP16P20         ' set control pins high
                            mov     latchvalue, dirb
                            call    #set373
    
                            andn    outa,maskP19            ' CS low
                            and     dira,maskP16P31         ' %11111111_11111111_00000000_00000000 so prop pins 0-15 HiZ
                            andn    outa,maskP16            ' ram /rd low
    
    ramtodisplay_loop       andn    outa,maskP18            ' ILI write low
                            or      outa,maskP18            ' ILI write high
                            andn    outa,maskP20            ' clock 161 low
                            or      outa,maskP20            ' clock 161 high
                            djnz    len,#ramtodisplay_loop
                            or      outa,maskP16            ' mem /rd high
                            or      outa,maskP19            ' CS high 
                            jmp     #done
    
    The new transfer starts the same but adds
                            sub     len, #2
    
    To make up for the 2 extra transfers, one at the beginning of the loop when turning counters on, and one at the end when turning them off.
    THEN set the counters up:
    ds_phsa                  long    $0000_0000      ' phsa offset for adjusting clock start
    ds_frqa                  long    $2000_0000      '10Mhz
    ds_ctra                  long    4<<26 | 20      ' NCO mode on P20
    
    ds_phsb                  long    $0000_0000      ' phsb offset for adjusting clock start
    ds_frqb                   long   $2000_0000      ' 10Mhz
    ds_ctrb                   long   4<<26 | 18      ' NCO mode on P18 
    
                'ctra setup for burst read
                            mov     phsa, ds_phsa             ' init counters phsa        P20
                            mov     phsb, ds_phsb             ' init         to phsb   P18
                            mov     frqa, ds_frqa             ' setup NCO freq             P20
                            mov     frqb, ds_frqb             ' setup NCO freq        P18
                            andn    outa,maskP20              ' start counters             P20
                            andn    outa,maskP18              ' start counters         P18
                                                                                                    '   P20   Count                 P18  Write
                            mov     ctrb, ds_ctrb             ' enable display clk           P18              0                               2   4   6   8
                            mov     ctra, ds_ctra             ' enable address counter clk   P20         2  4  6  8                  10  12  14  0
    
    And the actual transfer loop:
    fastramtodisplay_loop           nop                           '                                       10  12  14   0               2   4   6  8
                            djnz    len,#fastramtodisplay_loop   '                                       2    4   6   8               10  12  14 0
    
    
    Then shut it down
                            mov     ctrb, #0                ' stop counter                               2    4   6   8               10  12  14 0
                            mov     ctra, #0                ' stop counter
                            
                            or      outa,maskP20            ' stop clock
                            or      outa,maskP18            ' stop clock
                                         
                            or      outa,maskP16            ' mem /rd high
                            or      outa,maskP19            ' CS high 
                            jmp     #done
    
    
    The numbers on the side are the counter accumulation. This helped me figure out what was going on in the counters. I think it should work properly, but as I said it fails drawing text. I'll try drawing elements with it to determine more and let you know what I figure out!

    *aedit*
    After some more testing, fastR2D works in all cases of DrawBMPToRam, now to figure out why TextT doesn't work right?

    *more edit!*
    Seems fast draws now work correctly? Still need to debug. Speaking of bugs, I found one in the photo app, need to add code below after checking touchscreen to keep 2 < picturenumber < 7
         if result > 0
           if picturenumber > 2
             picturenumber --
           else
             picturenumber := 6
         else
           picturenumber ++
    

    I'm also missing several bmps for the signal generator as well as all files for HTML.
  • tritoniumtritonium Posts: 539
    edited 2012-08-23 02:59
    Hi average joe
    Thanks for your help, especially seeing how busy you must be with your project, and please do not go to any trouble searching out any more info for me, but if you have 5 minutes you might find some of my findings interesting.
    Oh I've read the data sheet over and over and there is also a 'tips' pdf.
    I see you send 0x90 or 0xD0 as an 8 bit command then read 12 bits in for a result.
    This means you are in a mode where the touch chip powers down while CS is high and the int pin is activated even though you don't use it - I've elected to keep mine powered up all the time - that together with my using 8 bit mode gives the different command byte.
    You are doing what the C51 code in the supplied (downloaded from sellers site) info' files does. (and why not)
    I was thinking that an eight bit result would be plenty big enough for my purposes and when using the 'built in' avr spi hardware, 8 bits at a time is all it will do. Of course I could read two bytes (16 bits) and shift and adjust as required but seemed a bit over the top for my needs.
    I send 0x9B or 0xDB as an 8 bit command then read 8 bits in for a result. (in my first post I mistyped 3 for B).
    Did you know you can interleave these commands and read data? This allows you to get a 12 bit result every 16 bits?
    This is only relevent if you want to achieve maximum speed.
    example on one axis
    send- 10010000 00000000 10010000 00000000 10010000 00000000...........etc
    recv- ???????? ?BA98765 43210??? ?BA98765 43210??? ?BA98765...........etc
    The data sheet suggests doing multiple reads and averaging the result (as one method) or keep reading until you get a number of reads all the same.

    Also, if I read the data sheet correctly, the data you get from the first clock of the twelve you send to receive a result is invalid! I suppose you should actually send 13 and lose the first? Of course this would mean you get a much bigger result (double) - I hope this makes some sense because really I'm thinking aloud - I might be rambling.....
    AHA - and maybe that is why you get the result you do!!
    PERHAPS for some reason when the screen is not touched that first bit is set and gives a large answer??? I dont know I must do some tests. It certainly doesn't in 8 bit mode.
    Since you are satisfied with the way its works for you this is all just mental musing.
    Anyway - thanks
    Happy hunting
    Dave
  • tritoniumtritonium Posts: 539
    edited 2012-08-24 11:38
    Hi again
    Well I've done some more testing this time sending 0x98 and 0xD8, still using 8 bit mode but with PD1 & PD0 =00 which puts it in 'power down and PENIRQ enabled mode'.(but not using the penirq pin). IT WORKS - with nothing touching the panel I get X=127 and Y=0 reliably! So thats a result! I can move on and do some button pushing:smile:.
    It seems in portrait mode the touch pad regards the x axis as the vertical axis numbering from 1 at the bottom to 120 at the top and the Y as the horizontal numbering 1 to the left up to 120 at the right. It seems you have asked the display for the x value but assign it to y etc and I will do the same.
    Regarding 12 /13 clocks I have been looking at your data sheet (Fig5 page 8) and zooming in to the clock/data signals it really looks as if the first clock after the command returns invalid data - try counting back from the positive clock in the middle of the lsb of the result and you get 13! - so perhaps you are losing the lsbit and in fact the result can give you twice the resolution!
    When you get time have a look.
    And thanks because without that chance remark about not needing penirq I would have wasted a precoius I/O pin.
    Dave
  • average joeaverage joe Posts: 795
    edited 2012-08-25 02:27
    Hi Dave,
    Interesting observations! As far as the 12/13 clock, you are probably right. It may explain some of the results I've witnessed. I'm also unsure of the x/y at this time, maybe Dr.A could shed some light on this. Perhaps I will investigate this further after I solve some other issues. Glad to hear you have things working though!

    I've spent the majority of my time working on the PASM portion and I'm stumped. I have been able to get fastR2D and fastR2H working but H2R is kickin my butt. Hopefully the guru's can help so I will start another thread in regards to this. My previous code may be faulty so I'm posting my recent efforts.
    '--------------------------------------------------------------------------
    ' setups needed for burst write to display  Thanks to Jazzed (Steve Denson)
    '--------------------------------------------------------------------------
    ds_ctra                  long    4<<26 | 20      ' NCO mode on P20         
    ds_frq                   long    $2000_0000      ' phsb accumulates twice per edge
    ds_ctrb                  long    4<<26 | 18      ' NCO mode on P18 
                                                    
    fastpasmramtodisplay    call    #get_values             ' get hubaddr,ramaddr,len (only uses len) and set control pins
                            sub     len, #2 
                            add     ramaddr, #1   
                            call    #set161
                            or      outa,maskP16P20         ' set control pins high
                            mov     latchvalue, dirb
                            call    #set373
                            and     dira,maskP16P31         ' %11111111_11111111_00000000_00000000 so prop pins 0-15 HiZ
                            andn    outa,maskP19            ' CS low
                            andn    outa,maskP16            ' ram /rd low
                'ctra setup for burst read
                            mov     phsa, #0                  ' init counters phsa        P20
                            mov     phsb, #0                  ' init         to phsb   P18
                            mov     frqa, ds_frq              ' setup NCO freq             P20
                            mov     frqb, ds_frq              ' setup NCO freq        P18
                            andn    outa,maskP20              ' start counters             P20
                            andn    outa,maskP18              ' start counters         P18
                                                                                                    '   P20   Count                 P18  Write
                            mov     ctrb, ds_ctrb             ' enable display clk           P18         
                            mov     ctra, ds_ctra             ' enable address counter clk   P20         0                           2   4   6   8
                            
    fastramtodisplay_loop   nop                                  '                                       2    4   6   8               10  12  14 0  2   4   6  8 
                            djnz    len,#fastramtodisplay_loop   '                                       10  12  14   0               2   4   6  8
                                                                                                       ' 2    4   6   8               10  12  14 0
                            or      outa,maskP18                 ' stop clock
                                                                                                                                   
                            mov     ctrb, #0                ' stop counter                               10  12  14   0               
                            mov     ctra, #0                ' stop counter                               2    4   6   8               10  12  14 0
                                                       
                            or      outa,maskP20            ' stop clock                                 2    4   6   8
                            
                            or      outa,maskP19            ' CS high
                            or      outa,maskP16            ' mem /rd high
    
                            jmp     #done
    
    
    and
    '-----------------------------------------------------------------------
    ' setups needed for burst read from ram  Thanks to Jazzed (Steve Denson)
    '-----------------------------------------------------------------------
    rd_frqa                  long     $1000_0000
    rd_ctra                  long     4<<26 | 20     ' NCO mode on P20
    rd_ctrb                  long     $A<<26| 20      ' Edge Accumulate mode on P20
    
    
    fastpasmramtohub        call    #get_values             ' get hubaddr,ramaddr,len and set control pins
                            call    #set161
                            or      outa,maskP16P20         ' set control pins high
                            mov     latchvalue,#%11111101   ' group 2, displays all off
                            call    #set373                 ' send out to the latch
                               
                            and     dira,maskP16P31         ' %11111111_11111111_00000000_00000000 inputs
                            andn    outa,maskP16            ' memory /rd low
    
                            mov     phsa, #0                ' init counters phsa
                            mov     frqa, rd_frqa           ' setup NCO freq
                           
                            mov     phsb, hubaddr           ' save hub ptr to phsb
                            mov     frqb, #2                ' setup EDGE freq
                            'ctra setup for burst read
                            
                            or      outa,maskP20            ' get clock line?
                            andn    outa,maskP20            ' start counters
    
                            mov     ctrb, rd_ctrb           ' set ctr be mode
                               
                            rdword  data_16,phsb            ' sync up only                  
                            mov     ctra, rd_ctra           ' enable address counter clk                    
                            
    fastramtohub_loop           ' 10MB/s read loop uses phsb for hub pointer
                            mov     data_16,ina             ' get first data                   1 2 3 4 
                            wrword  data_16,phsb            ' move data to hub                 5 6 7 8 9 A B C
                            djnz    len,#fastramtohub_loop                                '    D E F 0
    
                            or      outa,maskP20            ' stop clock
                            
                            mov      ctra, #0               ' stop counter
                            mov      ctrb, #0               ' stop counter
    
                            or      outa,maskP16            ' memory /rd high
    
                            jmp #done
    
    
  • average joeaverage joe Posts: 795
    edited 2012-08-25 05:07
    James, I think I have it! I believe this is the final "tuned" PASM driver. Just replace current code with code below. It's MUCH faster. and seems to work flawless. Please let me know if you find any bugs!
    DAT
    '' +-------------------------------------------------------------------------------------------------------+
    '' | Touchblade 161 Ram Driver (with grateful acknowlegements to Cluso, Jazzed, Kuroneko, and Average Joe) |
    '' +-------------------------------------------------------------------------------------------------------+
                            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) 
                            
    init                      'set up latches here
                            or      outa,maskP22            ' pin 22 high 
                            or      dira,maskP22            ' and now set as an output
                            mov     dirb, #%11111111        'set latch All hi
                            
    ' Initialise hardware tristates everything and read/write set the pins
    
    done                    mov      err, #0                ' reset err=false=good
                            mov     latchvalue, dirb        ' restore latch value
                            call    #set373
                            and     dira,maskP0P20low       ' tristates all the common pins, leaves P22 as is though
                            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, #"S"       wz      ' hub to ram              ''S
                  if_z      jmp     #fastpasmhubtoram                                 
                            cmp     cmd, #"T"       wz      ' ram to hub              ''T
                  if_z      jmp     #fastpasmramtohub
                            cmp     cmd, #"U"       wz      ' ram to display          ''U
                  if_z      jmp     #fastpasmramtodisplay                                     
                            cmp     cmd, #"V"       wz      ' hub to display          ''V
                  if_z      jmp     #pasmhubtodisplay           
                            cmp     cmd, #"E"       wz      ' convert 3 byte .raw format to 2 byte .ili format - hub to hub                      ''E
                  if_z      jmp     #rawtoiliformat
                            cmp     cmd, #"F"       wz      ' convert 3 byte .bmp format BGR to 2 byte ili format (same as E but order reversed) ''F
                  if_z      jmp     #bmptoiliformat              
                            cmp     cmd, #"X"       wz      ' merge icon and background based on a mask                                          ''X
                  if_z      jmp     #mergeicons
                            cmp     cmd, #"Z"       wz      ' set the 161 counters                                                               ''Z
                  if_z      jmp     #extset161
                            cmp     cmd, #"M"        wz     ' pass current latch value to pasm                                                   ''M
                  if_z      jmp     #latch373value
                            cmp     cmd, #"I"       wz      ' init                                                                               ''I
                  if_z      jmp     #init
                                                                                                            
                            mov     err, cmd                ' error = cmd (unknown command)
                            jmp     #done
                            
    ' ----------------- common routines -------------------------------------
    
    get_values              rdlong  hubaddr, hubptr         ' get hub address
                            rdlong  ramaddr, ramptr         ' get ram address
                            rdlong  len, lenptr             ' get length
                            mov     err, #5                 ' err=5
                            mov     dirb,latchvalue         ' make copy of latchvalue here for restore
                            or      outa,maskP16P20         ' set control pins high
                            or      dira,maskP16P20         ' set control pins P16-P20 as outputs   
    get_values_ret          ret
    
    
    set373                  or      outa,maskP22            ' pin 22 high 
                            or      dira,#%1_11111111       ' enable pins 0-7 and 8 as outputs
                            and     outa,maskP0P8low        ' P0-P8 low
                            or      outa,latchvalue         ' send out the data 
                            or      outa,maskP8             ' P8 high, clocks out data
                            andn    outa,maskP22            ' pin 22 low
    set373_ret              ret       
    
    
    set161                  mov     latchvalue,#%11111110   ' group 1, displays all off
                            call    #set373                 ' send out to the latch
                            and     outa,maskP0P20low       '%11111111_11100000_00000000_00000000   
                            or      dira,maskP0P20          '%00000000_00011111_11111111_11111111
                            or      outa,ramaddr            ' send out ramaddr
                            or      outa,maskP20            ' clock high
                            or      outa,maskP19            ' load high
    set161_ret              ret
    
    
    ' command T                                  
    fastpasmramtohub        call    #get_values                                     ' get hubaddr,ramaddr,len and set control pins
                            call    #set161                                         '
                            or      outa,maskP16P20                                 ' set control pins high
                            mov     latchvalue,#%11111101                           ' group 2, displays all off
                            call    #set373                                         ' send out to the latch
                            and     dira,maskP16P31                                 ' %11111111_11111111_00000000_00000000 inputs
                            andn    outa,maskP16                                    ' memory /rd low
                                                    'ctr setup for burst read
                            mov     phsa, #0                                        ' init counters phsa
                            mov     frqa, rd_frqa                                   ' setup NCO freq
                            mov     phsb, hubaddr                                   ' save hub ptr to phsb
                            mov     frqb, #2                                        ' setup EDGE freq
                            andn    outa,maskP20                                    ' start counters
                            mov     ctrb, rd_ctrb                                   ' set ctr be mode
                               
                            rdword  data_16,phsb                                    ' sync up only
                            mov     ctra, _ctra                                     ' enable address counter clk
                                                    ' 10MB/s read loop uses phsb for hub pointer
    fastramtohub_loop       mov     data_16,ina                                     ' get first data                     
                            wrword  data_16,phsb                                    ' move data to hub
                            djnz    len,#fastramtohub_loop                                
    
                            or      outa,maskP20                                    ' stop clock
                            mov     ctra, #0                                        ' stop counter
                            mov     ctrb, #0                                        ' stop counter
                            or      outa,maskP16                                    ' memory /rd high
    
                            jmp #done
    ' command U                                                
    fastpasmramtodisplay    call    #get_values                                     ' get hubaddr,ramaddr,len (only uses len) and set control pins
                            sub     len, #2                                         ' offset 1 extra clock at start and 1 at end
                            add     ramaddr, #1                                     ' ???not sure???
                            call    #set161                                         ' Set start address
                            or      outa,maskP16P20                                 ' set control pins high
                            mov     latchvalue, dirb                                ' restore latchvalue saved at get_values
                            call    #set373                                         ' and set
                            and     dira,maskP16P31                                 ' %11111111_11111111_00000000_00000000 so prop pins 0-15 HiZ
                            andn    outa,maskP19                                    ' CS low
                            andn    outa,maskP16                                    ' ram /rd low
                                                    'ctr setup for burst read
                            mov     phsa, #0                                        ' init counters phsa P20
                            mov     phsb, #0                                        ' init counters phsb P18
                            mov     frqa, ds_frq                                    ' setup NCO freq P20
                            mov     frqb, ds_frq                                    ' setup NCO freq P18
                            andn    outa,maskP20                                    ' start counters P20
                            andn    outa,maskP18                                    ' start counters P18                                                                                 
                            mov     ctrb, ds_ctrb                                   ' enable display clk P18
                            mov     ctra, _ctra                                     ' enable address counter clk P20
                                                    ' 20MB/s read loop uses ctra for address clock and ctrb for display clock
    fastramtodisplay_loop   nop                                                     ' idle               
                            djnz    len,#fastramtodisplay_loop                      '                             
                            or      outa,maskP18                                    ' stop clock
                            mov     ctrb, #0                                        ' stop counter                                    
                            mov     ctra, #0                                        ' stop counter       
                            or      outa,maskP20                                    ' stop clock            
                            or      outa,maskP19                                    ' CS high
                            or      outa,maskP16                                    ' mem /rd high
    
                            jmp     #done
                            
    
    ' command S
    fastpasmhubtoram        call    #get_values                                     ' get hubaddr,ramaddr,len and set control pins
                            sub     ramaddr,#1                                      '??????
                            call    #set161
                            or      outa,maskP16P20                                 ' set control pins high
                            mov     latchvalue,#%11111101                           ' group 2, displays all off
                            call    #set373                                         ' send out to the latch
                                                    'ctr setup for burst read
                            mov     phsa, wr_phsa                                   ' init counters phsa
                            mov     frqa, wr_frqa                                   ' setup NCO freq
                            andn    outa,maskP20                                    ' start counters
                            rdword  data_16,hubaddr                                 ' sync up only
                            mov     ctra, _ctra                                     ' enable address counter clk                                                              
                                                    ' 5MB/s write loop uses ctra for address clock                                         
    fasthubtoram_loop       and     outa,maskP16P31                                 '%11111111_11111111_00000000_00000000 clear for output                                          
                            rdword  data_16,hubaddr                                 ' get the word from hub                                                 
                            or      outa,data_16                                    ' send out the byte to P0-P15                                           
                            andn    outa,maskP17                                    ' set mem write low                                                     
                            add     hubaddr,#2                                      ' increment by 2 bytes = 1 word. Put this here for small delay while writes 
                            or      outa,maskP17                                    ' mem write high                                                        
                            djnz    len,#fasthubtoram_loop                          ' loop this many times                                                  
                                                                                                                                                          
                            or      outa,maskP20                                    ' stop clock                                                                                                                                 ' 
                            mov     ctra, #0                                        ' stop counter                                                                                                                              
                            jmp     #done                                           ' tristate pins and listen for commands
                            
    ' command V
    pasmhubtodisplay        call    #get_values                                     ' get hubaddr,ramaddr,len and set control pins high
                            andn    outa,maskP19                                    ' CS low
                            or      dira,maskP0P15                                  '%00000000_00000000_11111111_11111111
        
    hubtodisplay_loop       and     outa,maskP16P31                                 ' %11111111_11111111_00000000_00000000 ' clear for output
                            rdword  data_16,hubaddr                                 ' get the word from hub
                            or      outa,data_16                                    ' send out the byte to P0-P15
                            andn    outa,maskP18                                    ' ILI write low
                            or      outa,maskP18                                    ' ILI write high
                            add     hubaddr,#2                                      ' one word
                            djnz    len,#hubtodisplay_loop
                            or      outa,maskP19                                    ' CS high
                            jmp     #done
    
    'command E
    RawtoILIformat          ' takes a .raw 3 byte RRRRRRRR GGGGGGGG BBBBBBBB and converts to 2 byte RRRRRGGG GGGBBBBB
                            ' pass hubaddr, ramaddr and len
                            ' hubaddr is source location, len is number of pixels
                            ' ramaddr is destination in hub (messy naming) and length is 2/3 of blocklength
                            call    #get_values ' gets hubaddress, ramaddress and len (ignores ramaddress)
    rawloop
                            rdbyte red,hubaddr
                            add hubaddr,#1
                            rdbyte green,hubaddr
                            add hubaddr,#1
                            rdbyte blue,hubaddr
                            add hubaddr,#1
                            call #rgbtoili
                            wrbyte ililow,ramaddr
                            add ramaddr,#1
                            wrbyte ilihigh,ramaddr
                            add ramaddr,#1
                            djnz    len,#rawloop            ' loop until done 
                            jmp     #done                   ' set pins to tristate
    
    RGBtoILI                ' pass red,green, blue, returns ililow and ilihigh
                            shr     red,#3                  ' 000RRRRR 
                            shl     red,#3                  ' RRRRR000 
                            shr     green,#2                ' 00GGGGGG
                            mov     ilihigh,green           ' ilihigh = 00GGGGGG
                            shr     ilihigh,#3              ' ilihigh = 00000GGG
                            or      ilihigh,red             ' ilihigh = RRRRRGGG
                            and     green,#%00000111        ' 00000GGG
                            shl     green,#5                ' GGG00000
                            mov     ililow,green            ' ililow = GGG00000
                            shr     blue,#3                 ' blue = 000BBBBB
                            or      ililow,blue             ' ililow = GGGBBBBB
    RGBtoILI_ret            ret
    
    BMPtoILIformat          ' takes a .bmp 3 byte BBBBBBBB GGGGGGGG RRRRRRRR and converts to 2 byte RRRRRGGG GGGBBBBB
                            ' same as E above but BGR instead of RGB
                            ' pass hubaddr, ramaddr and len
                            ' hubaddr is source location, len is number of pixels
                            ' ramaddr is destination in hub (messy naming) and length is 2/3 of blocklength
                            call    #get_values ' gets hubaddress, ramaddress and len (ignores ramaddress)
    bmploop
                            rdbyte blue,hubaddr
                            add hubaddr,#1
                            rdbyte green,hubaddr
                            add hubaddr,#1
                            rdbyte red,hubaddr
                            add hubaddr,#1
                            call #rgbtoili
                            wrbyte ililow,ramaddr
                            add ramaddr,#1
                            wrbyte ilihigh,ramaddr
                            add ramaddr,#1
                            djnz    len,#bmploop            ' loop until done
                            jmp     #done                   ' set pins to tristate
    ' **** command X *********************
    
    MergeIcons              call    #get_values ' gets hubaddress, ramaddress,len which are used here as background,icon,mask
                            mov     pasm_n,#59               ' do a single row
    mergeiconsloop          rdbyte  ililow,len                 ' reuse ililow, so this is rdword mask,maskcounter
                            and     ililow,#%11111             ' mask off low 5 bits and use just the blue as this is a grayscale bitmap
                            rdword  red,hubaddr              ' reuse red, so actually this is rdword background,backgroundcounter                        
                            cmp     ililow,#%10000   wc       ' compare if >128 (ie mid level gray)
                  if_c      jmp     #mergeskip
                            rdword  green,ramaddr            ' reuse green, so this is rdword iconpixel, iconpixelcounter 
                            wrword  green,hubaddr            ' if replace, then move icon pixel to the background     
    mergeskip               add     hubaddr,#2
                            add     ramaddr,#2
                            add     len,#2
                            djnz    pasm_n,#mergeiconsloop            ' loop until done 
                            jmp     #done                   'set pins to tristate 
    
    '' *** command Z **********
    'changes the latch so displays won't work unless resend the spin value for the latch
    extset161               call    #get_values             ' gets ramaddr = the 161 value to set
                            mov     dirb, latchvalue
                            call    #set161
                            jmp     #done                   ' tristates pins etc     
    
                            
    ' *** command M - pass current latch value and send out
    latch373value           call    #get_values
                            mov     dirb,hubaddr
                            jmp     #done
    
    
    stop                   jmp     #stop                  ' for debugging
    
    'delaynop                nop
    '                        nop
    '                        nop
    '                        nop
    'delaynop_ret            ret
    
    
    ' variables
    pasm_n                  long    0                                    ' general purpose value
    data_16                 long    0                                    ' general purpose value
    ililow                  long    0                                    ' low data byte 
    ilihigh                 long    0                                    ' high data byte 
    red                     long    0                                    ' red, green blue variables
    green                   long    0
    blue                    long    0
    
    ' constants
    Zero                    long    %00000000_00000000_00000000_00000000 ' used in several places
    'maskP0P2low            long    %11111111_11111111_11111111_11111000 ' P0-P2 low
    maskP0P20               long    %00000000_00011111_11111111_11111111 ' P0-P18 enabled for output plus P19,P20    
    maskP0P18low            long    %11111111_11111000_00000000_00000000 ' P0-P18 low
    maskP16                 long    %00000000_00000001_00000000_00000000 ' pin 16
    maskP17                 long    %00000000_00000010_00000000_00000000 ' pin 17
    maskP18                 long    %00000000_00000100_00000000_00000000 ' pin 18
    maskP19                 long    %00000000_00001000_00000000_00000000 ' pin 19
    maskP20                 long    %00000000_00010000_00000000_00000000 ' pin 20
    maskP22                 long    %00000000_01000000_00000000_00000000 ' pin 22
    maskP16P31              long    %11111111_11111111_00000000_00000000 ' pin 16 to pin 31
    maskP0P15               long    %00000000_00000000_11111111_11111111 ' for masking words
    maskP16P20              long    %00000000_00011111_00000000_00000000
    maskP0P20low            long    %11111111_11100000_00000000_00000000 ' for returning all group pins HiZ
    maskP0P8low             long    %11111111_11111111_11111111_00000000  ' P0-P7 low
    maskP8                  long    %00000000_00000000_00000001_00000000  ' pin 8
    latchvalue              long    %00000000_00000000_00000000_00000000  ' current 373 value
    
    '--------------------------------------------------------------------------
    ' setups needed for burst read/write  Thanks to Jazzed (Steve Denson)
    '--------------------------------------------------------------------------
    _ctra                    long     4<<26 | 20     ' NCO mode on P20
    
    ds_frq                   long    $2000_0000      ' 10 MHZ
    ds_ctrb                  long    4<<26 | 18      ' NCO mode on P18 
    
    rd_frqa                  long     $1000_0000     ' 5 MHZ
    rd_ctrb                  long     $A<<26| 20     ' Edge Accumulate mode on P20
    
    wr_phsa                  long    $8800_0000       ' phsa offset for adjusting clock start
    wr_frqa                  long    $0800_0000       ' 2.5 MHZ                          
    
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-25 05:36
    Sounds interesting. Why does it end up faster?

    Ok, we have both been writing code for the last week and now we need to reunify the code.

    Attached is my current package of .spin files. In particular, I modified the stringcompare routine so that it returns 0 if equal, and negative or positive values if the strings are more or less than each other. I needed that for a bubblesort routine. But it broke the desktop.spin program (that displays the icons). There might be some other tweaks to the touch.spin program, but it will all be the spin part, not the pasm part. So you have been working on the pasm so hopefully it is not to hard to re-merge things.

    Can you take a look at my code and double check it runs on your board, then let me know if I just drop your pasm bit into the code?

    I'm not sure about the touch variables you have been discussing. A lot of it was trial and error with swapping x and y with the orientation. I'm still not sure of the best solution. I have a vague idea about a board with a little mercury/ball bearing tilt sensor and you tilt the board and it changes the orientation. If you did that, you want x and y to swap. Or do you? All the icons get rotated 90 degrees too. Or would you ever use such a tilt sensor?

    You have found some other bugs - can you list them wrt that aug25 zip?

    In an ideal world hopefully the touch.spin program becomes fairly stable and then who cares if you/we alter other apps, but we obviously need to work very closely on that common .spin program. And the desktop.spin as well.

    BTW were you missing some .bmp files?
  • average joeaverage joe Posts: 795
    edited 2012-08-25 06:12
    The speed increases are due to using counters to generate the clocks, as well as hubaddr for burst read. This reduces the loops by 1 hub cycle per rep. Also tweaked hub2display for a "tight" timing cycle. There is a bit more overhead but since most transfers are more than one word, it turns out faster. Removing the "maskToWord" from hub2display allows it to complete in 2 hub slots *32 clocks* instead of 3. Hub2ram is reduced by 2 instructions, allowing it to complete in 2 hub slots as well. Ram2Hub is reduced by several clock cycles to fit into 1 hub slot instead of *I think it was* 2. Ram2Display is the fastest since there is no hub slots used so it completes in 8 clock cycles! See loops below
    fastramtohub_loop       mov     data_16,ina                                     ' get first data                     
                            wrword  data_16,phsb                                    ' move data to hub, phsb is ptr to hub address
                            djnz    len,#fastramtohub_loop                                
    
    fastramtodisplay_loop   nop                                                     ' idle               
                            djnz    len,#fastramtodisplay_loop                      '                             
    
    fasthubtoram_loop       and     outa,maskP16P31                                 '%11111111_11111111_00000000_00000000 clear for output                                          
                            rdword  data_16,hubaddr                                 ' get the word from hub                                                 
                            or      outa,data_16                                    ' send out the byte to P0-P15                                           
                            andn    outa,maskP17                                    ' set mem write low                                                     
                            add     hubaddr,#2                                      ' increment by 2 bytes = 1 word. Put this here for small delay while writes 
                            or      outa,maskP17                                    ' mem write high                                                        
                            djnz    len,#fasthubtoram_loop                          ' loop this many times                                                  
    
    
    Boy those counters are handy!

    Hopefully the PASM will "just work." I'll double check your latest code in a bit, as well as test the updated PASM in it.

    Re: tilt sensor. This could be interesting but I see some inherent issues with it. First, I believe we would need 2 files for background images *or any image with one axis resolution over 240px.* Also, in my experience with my Android, I just find it annoying. Better to provide an option to change orientation through user interaction IMO.

    Re: x/y. I'm not sure of the best way of handling this either. I will keep thinking about this too.

    I think the "bugs" I mentioned were more "user error" than anything else. If I find any I will let you know.
    The BMPs I was missing are the ones for HTML and Signal Generator.


    *edit*
    Just found out the PASM is not compatible. I'll figure out why and get back to you.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-25 06:31
    You are onto something clever with those counters. Ok, take my code, drop in the one line that changes the display settings in the desktop.spin program and hopefully you can copy and paste the new pasm.

    Oh darn, I remember I did change the pasm. I stuck the
                            call    #get_values      ' get hubaddr,ramaddr,len and set control pins   
    
    at the beginning as I noticed that it was called by every routine anyway. Sorry. I might have changed other bits too. Might have been one of those intense alcohol/caffeine fueled coding sessions. Why are those the most productive??!

    re missing .bmp files, hopefully it prints the missing filename on the screen - can you give me the names of the missing files?

    We both probably need to have version numbers of these files and spend more time documenting changes than making changes. Not quite the way I tend to code but with collaborative efforts I guess that is the only solution...
  • average joeaverage joe Posts: 795
    edited 2012-08-25 06:38
    I figured out the problem with the new PASM. It has to do with setting the latch value. I need to think about the best way to handle the latch value. To me, it seems best left to the program running to keep track of *?and possibly store in SRAM when swapping programs?* My only issue with the "A/O" is *I THINK* it requires more work to set the latch value. *2 PASM calls in some cases* That plus starting a new program will wipe the latch value anyway. I could be wrong though.

    *edit*
    OKAY, digging deeper and it's going to require quite a bit of modification one way or another. I've made some hefty changes to the PASM driver, and that requires changes to the SPIN portion. This could get complicated....
  • average joeaverage joe Posts: 795
    edited 2012-08-25 20:58
    Spent time working on the Touch.spin and I have things working. Lots of changes here, I tried to note most of them. I will elaborate a bit.
    First and least important, these commands were changed to reduce number of jumps *by 1*
    PUB HubToRam(RamAddress,Number)                         ' send pixels from rambuffer hub to ram
        CogCmd("S",@rambuffer,RamAddress,Number)
    
    PUB RamToHub(RamAddress,Number)                         ' send pixels from ram to hub at rambuffer
       CogCmd("T",@rambuffer,Ramaddress, number)
    
    PUB RamToDisplay(RamAddress,Number)                     ' send pixels from ram to display
       CogCmd("U",0,Ramaddress,Number)                               ' pasm alternative to code below, much faster 
    
    Also, removed
      'Latch_AllHighStart                                    ' all Latch pins high and enables pin 22,                              ''done by cog init
    
    Since this is now done by cogInit.
    Then, changed all Spin code containing DIRAs to clear bit23 *p22* since P22 is only controlled by cog.
    PUB SelectMemGroup                                      ' select group 1 for memory transfer
       spi.stop                                             ' and stop any other cogs here too if needed
       LatchGroup2
       DIRA |= %00000000_01011111_11111111_11111111         ' enable these pins for output                                          ''P22 controlled by cog
       OUTA |= %00000000_00011111_00000000_00000000         ' set /rd /wr /disp wr and 161 clock high
    
       
    PUB SelectSPIGroup
       LatchGroup3                                            ' select group 2 for spi transfers
       DIRA &= %11111111_10111111_11111111_11000000   ' so no clashes with the cog using P0-P2 set these as inputs and P3-P5        ''P22 controlled by cog
       TouchStart                                     ' start the touchscreen cog
    
    Then changed SpinRamToDisplay, this is where things get interesting.
    PRI SpinRamToHub(hubaddress,ramaddress,number)          ' move data from ram to hub
       CogCmd("T",hubaddress,ramaddress,number)             ' pasm block move   
    
    not
    PRI SpinRamToDisplay(ramaddress,number)                 ' ramaddress, number of words (pixels), display = 1 or 2
       Load161(ramaddress)                                  ' load the 161 counters
       LatchGroup2                                          ' group 2 is block data transfers
       DisplayEnable                                        ' latch output one or both displays
       CogCmd("U",0,0,number)                               ' pasm alternative to code below, much faster
    
    The reductions here are pushing the ramaddress into the CogCmd. Group changes auto by cog. Display enable is not needed since cog backs up/ restores latch value automatically. Set and forget until changing display.
    Changes to CogCmd are fairly simple, remove bit 23 *p22* from DIR command, and restore outa BEFORE dira:
    ..
      DIRA &= %11111111_10100000_00000000_00000000 ' tristate all common pins that cog can change so no conflicts
    ..
    ..
      outa := b
      dira := a                     ' restore dira and outa                                                 ''restore dirb last
    
    Now the big changes... The PASM driver,...First off, at end of loops, jump to "done", not "init," init is used to enable P22 and set latch all high. Also, get_values saves current latch value into dirb for restore @ done, or ramToDisplay. Not needed for hubToDisplay since latch value never changes. Changing latches is done to dirb instead of latchvalue, then jump to done which updates the contents of the latch from dirb.
    init                      'set up latches here                                                          ''only call init on start, all loops return to done  JH
                            or      outa,maskP22            ' pin 22 high 
                            or      dira,maskP22            ' and now set P22 as an output
                            mov     dirb, #%11111111        ' set latch All hi
                            
    ' Initialise hardware tristates everything and read/write set the pins
    
    done                    mov      err, #0                ' reset err=false=good
                            mov     latchvalue, dirb        ' restore latch value
                            call    #set373                 ' and update latch
                            and     dira,maskP0P20low       ' tristates all the common pins, leaves P22 as is though
                            wrlong  err, errptr             ' status  =0=false=good, else error x
                            wrlong  zero, comptr            ' command =0 (done)
    
    get_values              rdlong  hubaddr, hubptr         ' get hub address
                            rdlong  ramaddr, ramptr         ' get ram address
                            rdlong  len, lenptr             ' get length
                            mov     err, #5                 ' err=5
                            mov     dirb,latchvalue         ' make copy of latchvalue here for restore                              ''All changes to latch value applied to dirb
                            or      outa,maskP16P20         ' set control pins high
                            or      dira,maskP16P20         ' set control pins P16-P20 as outputs   
    get_values_ret          ret
    
    set373                  or      outa,maskP22            ' pin 22 high 
                            'or      dira,maskP22            ' and now set as an output                                             'P22 always controlled by cog              
                            or      dira,#%1_11111111       ' enable pins 0-7 and 8 as outputs
                            'andn    outa,maskP8             ' P8 low 
                            and     outa,maskP0P8low        ' P0-P8 low                                                             ''P8 is made low at the same time as P0-P7
                            or      outa,latchvalue         ' send out the data 
                            or      outa,maskP8             ' P8 high, clocks out data
                            'andn    outa,maskP8             ' P8 low                                                               ''P8 low not needed
                            andn    outa,maskP22            ' pin 22 low
    set373_ret              ret
    
    set161                  mov     latchvalue,#%11111110    ' group 1, displays all off
                            call    #set373                 ' send out to the latch
                            and     outa,maskP0P20low       '%11111111_11100000_00000000_00000000   
                            or      dira,maskP0P20          '%00000000_00011111_11111111_11111111
                            or      outa,ramaddr            ' send out ramaddr
                            or      outa,maskP20            ' P20 clock high
                            or      outa,maskP19            ' p19 load high
                            'andn    outa,maskP20            ' clock low                                                            ''Not needed since 
                            'andn    outa,maskP19            ' load low
                            'or      outa,maskP20            ' clock high
                            'or      outa,maskP19            ' load high
                            or      outa,maskP16P20         ' P16-P20 high in case the next thing is a group change and P16/P17 are low and hence upset the ram chip
    set161_ret              ret
    
    ' *** command O - logical OR hubaddr with latchvalue and send out (set desired bits) ***       
    latch373_OR             or      dirb,hubaddr                                                   ''Makes changes to dirb
                            'call    #set373                                                       '' Changes retored on call to done
                            jmp     #done
    
    ' *** command A - logical AND hubaddr with latchvalue and send out (clear desired bits) ***
    latch373_AND            and     dirb,hubaddr                                                   ''Makes changes to dirb 
                            'call    #set373                                                        '' Changes retored on call to done 
                            jmp     #done                     
    
    
    This covers most of the changes. I removed some instructions here and there since they were not needed.


    *edit*
    I've been attempting to test the driver and there's something interesting going on. I can't quite put my finger on it yet, but it seems "BeginProgram" does not work? If I change to BeginDesktop("S"), everything seems to work. I've also missed a few optimizations unifying the driver so it's a bit slower than my previous version. *About 1/2 second for photo app.* Not sure what exactly is going on with BeginProgram...

    *more edit*
    RGBtoWord(255,255,255) causes program to crash?
  • Mark_TMark_T Posts: 1,981
    edited 2012-08-29 02:27
    Bargain 320x240 touchscreen modules: ILI9325 TFT LCD controller and ADS7843 compatible touch screen controller as well as a SD card socket: http://www.ebay.co.uk/itm/2-4-TFT-LCD-Module-Display-Touch-Panel-PCB-adapter-akt-/180868037704?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item2a1c933c48

    The ILI9325 is well supported I believe, and at that price (£10 in UK money, not sure what the $ cost is) I'm ordering a couple. Pin out not clear but it looks like it might have 2 latch chips to drive 16bit interface from 8 data lines? Seems to need 5V (backlight?) but IO is 3V3.
  • average joeaverage joe Posts: 795
    edited 2012-08-29 15:22
    Interesting! I have not seen these exact display modules. The ILI9325 seems to be a nice display and have a better viewing angle than the SSD1289s I'm using. Not sure about the latch chips but you are probably correct. At a cost of about $13, they are similarly priced with the ILI9325 Dr.A is using. The I/Os are 3v3 and backlight will be 5v. They will likely require 5v supply for display as the modules we use have 3v3 regulators on them. I'm assuming the modules you referenced are the same.

    A word of caution. You CAN connect the propeller chip directly to the display. Display draws will be SLOW if not using the external memory. I started out using my display connected directly to the propeller. Performance is less than ideal with full display draws taking several seconds.

    I've been very busy this week, as I have family in town. The production board is ALMOST completely built and I should have the video done next week. As a side note, I just sold a fully assembled Touchburger!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-08-29 23:37
    Good to read all the news here.

    I've been playing around with writing Pacman for this display using tile driver code. I'm also experimenting with a programming technique where you write and debug more quickly using a GUI on the PC and try to use routines with similar names so translating over to spin is quicker and easier. So, this is the propeller code, with a very strange alphanumeric description of the layout. It is a convenient way to work because it is easy to edit. Nothing is moving yet - this is just drawing the display. However, that byte array also is a useful descriptor for the code, as the pacman can use the ascii letters to work out where walls are, and the ghosts can work out where pacman is.
    CON
      _clkmode      = xtal1 + pll16x                        ' use crystal x 16
      _xinfreq      = 5_000_000
       
    OBJ
      tch:           "Touch"                                 ' touchscreen driver
    
    PUB Main | touchtest  ' debug value
      tch.BeginProgram
      Pacman
      repeat  
      tch.SetWarmBoot                                           ' clears screen, sets a warm boot and reboots
    
    PUB Pacman | address
        tch.Clearscreen(%00000000_00000000)                 ' so something happens immediately
        tch.ClearRam
        tch.SDBMPtoRam(string("pactiles.bmp"))                ' file 2. File is a .bmp image but each 6x6 tile is continous for fast output
        tch.SDBMPtoRam(string("pacbut.bmp"))                ' file 3 - control buttons
        tch.DrawBMPRam(3,70,215)                               ' draw the control buttons
    
        PacText(string("PACMAN"),0,300)
        DrawMaze
    
    PUB DrawTile(n,x,y) ' draw tile n in location x,y
        tch.draw(x,y,x+5,y+5)
        tch.ramtodisplay(tch.getramlocation(2)+$36+(n*36),36) ' $36 is the bitmap header offset, 36 is number of pixels to draw
    
    PUB PacText(stringptr,x,y) ' the tiles also include text but only capitals. Happens to be stored at position 65 up (though numbers are not in the ascii position)
      repeat strsize(stringptr)
        DrawTile(byte[stringptr++],x,y)
        x += 6
    
    PUB DrawMaze | x,y,address,c
       repeat y from 0 to 30
         repeat x from 0 to 39
           c := byte[@maze][40*y+x]
           case c
             32..120:address := 143 + c                     ' walls of the maze 
             126: address := 16                             ' ~ is small food
             125: address := 20                             ' } is large food
             121: address := 32 * 14 + 24                   ' y is part of pacman
             122: address := 32 * 14 + 25                   ' part of pacman
             123: address := 32 * 15 + 24                   ' part of pacman  
             124: address := 32 * 15 + 25                   ' part of pacman  
             
           drawtile(address,x*6,y*6)
    
    DAT
      Maze byte "BKKKKKKKKKKKKKKKKKKlkKKKKKKKKKKKKKKKKKKA"
           byte "D~~~~~~~~~~~~~~~~~~ZY~~~~~~~~~~~~~~~~~~C"
           byte "D~XPPPPPW~XPPPPPPW~ZY~XPPPPPPW~XPPPPPW~C"
           byte "D}ZwwwwwY~ZwwwwwwY~ZY~ZwwwwwwY~ZwwwwwY}C"
           byte "D~\VVVVV[~\VVVVVV[~\[~\VVVVVV[~\VVVVV[~C"
           byte "D~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~C"
           byte "D~XPPPPPW~XW~XPPPPPPPPPPPPW~XW~XPPPPPW~C"
           byte "D~\VVVVV[~ZY~\VVVVVWXVVVVV[~ZY~\VVVVV[~C"
           byte "D~~~~~~~~~ZY~~~~~~~ZY~~~~~~~ZY~~~~~~~~~C"
           byte "HPPPPPPPW~ZePPPPPW~ZY~XPPPPPfY~XPPPPPPPG"
           byte "nwwwwwwwY~ZcVVVVV[~\[~\VVVVVdY~Zwwwwwwwm"
           byte "nwwwwwwwY~ZY~~~~~~~~~~~~~~~~ZY~Zwwwwwwwm"
           byte "VVVVVVVV[~\[~^MMMMb??aMMMM]~\[~\VVVVVVVV"
           byte "~~~~~~~~~~~~~C!",34,"w'(w-.w34wD~~~~~~~~~~~~~"
           byte "PPPPPPPPW~XW~C#$w)*w/0w56wD~XW~XPPPPPPPP"
           byte "DwwwwwwwY~ZY~C%&w+,w12w78wD~ZY~ZwwwwwwwC"
           byte "DwyzwwwwY~ZY~`KKKKKKKKKKKK_~ZY~ZwwwwwwwC"
           byte "Dw{|wwwwY~ZY~~~~~~~~~~~~~~~~ZY~ZwwwwwwwC"
           byte "DwwwwwwwY~ZY~XPPPPPPPPPPPPW~ZY~ZwwwwwwwC"
           byte "JVVVVVVV[~\[~\VVVVVWXVVVVV[~\[~\VVVVVVVI"
           byte "D~~~~~~~~~~~~~~~~~~ZY~~~~~~~~~~~~~~~~~~C"
           byte "D~XPPPW~XPPPPPPPPW~ZY~XPPPPPPPPW~XPPPW~C"
           byte "D~\VVWY~\VVVVVVVV[~\[~\VVVVVVVV[~ZXVV[~C"
           byte "D}~~~ZY~~~~~~~~~~~~~~~~~~~~~~~~~~ZY~~~}C"
           byte "HPPW~ZY~XW~XPPPPPPPPPPPPPPPPW~XW~ZY~XPPG"
           byte "JVV[~\[~ZY~\VVVVVVVWXVVVVVVV[~ZY~\[~\VVI"
           byte "D~~~~~~~ZY~~~~~~~~~ZY~~~~~~~~~ZY~~~~~~~C"
           byte "D~XPPPPPfePPPPPPPW~ZY~XPPPPPPPfePPPPPW~C"
           byte "D~\VVVVVVVVVVVVVV[~\[~\VVVVVVVVVVVVVV[~C"
           byte "D~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~C"
           byte "FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMME"
    

    So this started life as vb.net code and was/is being debugged in vb.net
    Public Class Form1
    
        Dim Pixelarray(192 * 144) As Color ' array with all the tiles, each 6x6
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            CreateArray()
            MazeLayout()
        End Sub
        Private Sub CreateArray()
            Dim MyBitmap As New System.Drawing.Bitmap(PictureBox1.BackgroundImage) 'image from picture box
            Dim i, x, y, sizex, sizey, tilex, tiley, startx, starty, finx, finy, width, height As Integer
            Dim Mycolor As Color
            sizex = 192
            sizey = 144
            width = 6
            height = 6
            i = 0
            For tiley = 0 To (sizey / width) - 1
                For tilex = 0 To (sizex / height) - 1
                    startx = tilex * width
                    finx = tilex * width + (width - 1)
                    starty = tiley * height
                    finy = tiley * height + (height - 1)
                    For y = starty To finy
                        For x = startx To finx
                            Mycolor = MyBitmap.GetPixel(x, y) ' get the color
                            Pixelarray(i) = Mycolor
                            i += 1
                        Next
                    Next
                Next
            Next
        End Sub
    
        Sub DrawTile(ByVal tileN As Integer, ByVal startx As Integer, ByVal starty As Integer)
            Dim address As Integer
            Dim finx, finy, screenwidth, x, y As Integer
            Dim MyBitmap As New System.Drawing.Bitmap(PictureBox3.BackgroundImage)
            address = tileN * 36
            finx = startx + 5
            finy = starty + 5
            screenwidth = 240
            For y = starty To finy
                For x = startx To finx
                    MyBitmap.SetPixel(x, y, Pixelarray(address))
                    address += 1
                Next
            Next
    
            PictureBox3.BackgroundImage = MyBitmap
        End Sub
        Private Sub MazeLayout()
            ' describe the maze in letters with A starting at the first maze symbol on the tile map
            ' B=top left, A=top right, C= right side, D=left side, E=bottom right, F=bottom left
            ' K= top double, M=bottom double
            ' f = food
            ' 40 wide, 53 high
            Dim Maze(53) As String
            Dim x, y, address, c As Integer
            Maze(0) = "BKKKKKKKKKKKKKKKKKKlkKKKKKKKKKKKKKKKKKKA"
            Maze(1) = "D~~~~~~~~~~~~~~~~~~ZY~~~~~~~~~~~~~~~~~~C"
            Maze(2) = "D~XPPPPPW~XPPPPPPW~ZY~XPPPPPPW~XPPPPPW~C"
            Maze(3) = "D}ZwwwwwY~ZwwwwwwY~ZY~ZwwwwwwY~ZwwwwwY}C"
            Maze(4) = "D~\VVVVV[~\VVVVVV[~\[~\VVVVVV[~\VVVVV[~C"
            Maze(5) = "D~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~C"
            Maze(6) = "D~XPPPPPW~XW~XPPPPPPPPPPPPW~XW~XPPPPPW~C"
            Maze(7) = "D~\VVVVV[~ZY~\VVVVVWXVVVVV[~ZY~\VVVVV[~C"
            Maze(8) = "D~~~~~~~~~ZY~~~~~~~ZY~~~~~~~ZY~~~~~~~~~C"
            Maze(9) = "HPPPPPPPW~ZePPPPPW~ZY~XPPPPPfY~XPPPPPPPG"
            Maze(10) = "nwwwwwwwY~ZcVVVVV[~\[~\VVVVVdY~Zwwwwwwwm"
            Maze(11) = "nwwwwwwwY~ZY~~~~~~~~~~~~~~~~ZY~Zwwwwwwwm"
            Maze(12) = "VVVVVVVV[~\[~^MMMMb??aMMMM]~\[~\VVVVVVVV"
            Maze(13) = "~~~~~~~~~~~~~C!" + Strings.Chr(34) + "w'(w-.w34wD~~~~~~~~~~~~~"
            Maze(14) = "PPPPPPPPW~XW~C#$w)*w/0w56wD~XW~XPPPPPPPP"
            Maze(15) = "DwwwwwwwY~ZY~C%&w+,w12w78wD~ZY~ZwwwwwwwC"
            Maze(16) = "DwyzwwwwY~ZY~`KKKKKKKKKKKK_~ZY~ZwwwwwwwC"
            Maze(17) = "Dw{|wwwwY~ZY~~~~~~~~~~~~~~~~ZY~ZwwwwwwwC"
            Maze(18) = "DwwwwwwwY~ZY~XPPPPPPPPPPPPW~ZY~ZwwwwwwwC"
            Maze(19) = "JVVVVVVV[~\[~\VVVVVWXVVVVV[~\[~\VVVVVVVI"
            Maze(20) = "D~~~~~~~~~~~~~~~~~~ZY~~~~~~~~~~~~~~~~~~C"
            Maze(21) = "D~XPPPW~XPPPPPPPPW~ZY~XPPPPPPPPW~XPPPW~C"
            Maze(22) = "D~\VVWY~\VVVVVVVV[~\[~\VVVVVVVV[~ZXVV[~C"
            Maze(23) = "D}~~~ZY~~~~~~~~~~~~~~~~~~~~~~~~~~ZY~~~}C"
            Maze(24) = "HPPW~ZY~XW~XPPPPPPPPPPPPPPPPW~XW~ZY~XPPG"
            Maze(25) = "JVV[~\[~ZY~\VVVVVVVWXVVVVVVV[~ZY~\[~\VVI"
            Maze(26) = "D~~~~~~~ZY~~~~~~~~~ZY~~~~~~~~~ZY~~~~~~~C"
            Maze(27) = "D~XPPPPPfePPPPPPPW~ZY~XPPPPPPPfePPPPPW~C"
            Maze(28) = "D~\VVVVVVVVVVVVVV[~\[~\VVVVVVVVVVVVVV[~C"
            Maze(29) = "D~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~C"
            Maze(30) = "FMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMME"
            For y = 0 To 30
                For x = 0 To 39
                    c = Strings.Asc(Strings.Mid(Maze(y), x + 1, 1))
                    If c > 32 And c < 121 Then
                        address = 208 + c - 65
                    End If
                    If c = 126 Then ' ~ = small food 
                        address = 16
                    End If
                    If c = 125 Then
                        address = 20 ' } is large food
                    End If
                    If c = 121 Then ' y is part of pacman
                        address = 32 * 14 + 24
                    End If
                    If c = 122 Then ' z is part of pacman
                        address = 32 * 14 + 25
                    End If
                    If c = 123 Then ' { is part of pacman
                        address = 32 * 15 + 24
                    End If
                    If c = 124 Then ' | is part of pacman
                        address = 32 * 15 + 25
                    End If
                    DrawTile(address, x * 6, y * 6)
                Next
            Next
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim MyBitmap As New System.Drawing.Bitmap(PictureBox2.BackgroundImage) ' for export
            Dim address As Integer = 0
            For y = 0 To 143
                For x = 0 To 191
                    MyBitmap.SetPixel(x, y, Pixelarray(address))
                    address += 1
                Next
            Next
            PictureBox2.BackgroundImage = MyBitmap
            PictureBox2.BackgroundImage.Save("c:\Pactiles.bmp", System.Drawing.Imaging.ImageFormat.Bmp)
        End Sub
    End Class
    

    The pictures all exist as tiles, and for simplicity the tiles are all 6x6 pixels. So some things like ghosts end up needing 4 tiles. We will also be needing a transparency layer down the track. Take the tile data and work out how all the little curves and straight lines go together. Lots of fun!

    For both vb.net and Spin, it is more convenient to convert a two dimensional array to a one dimensional array. That way, tiles can be sent to the display with a single call to a pasm routine, which is less than a microsecond to send out a tile. Hence the rather strange "smeared" bitmap which the spin version uses.

    Next step is to start coding the rules for movement. Then pull in the .wav files (many available on the internet for pacman) and the controls.
    640 x 613 - 88K
    455 x 331 - 66K
  • average joeaverage joe Posts: 795
    edited 2012-08-31 03:09
    Very nice work! I completed building the first board and it passed initial testing. I have found something puzzling. When both displays are installed, the desktop will not boot properly. Either display by itself works fine, so I suspect a weak power supply. I'm also wondering if it could be due to 100k resistor networks. Still need to investigate the exact cause. I'll keep you up to date.
    Keep up the excellent work and thanks again!
    Joe

    *edit*
    Voltage rails look good and I'm not seeing any transients on the /reset line either. I'm confused as to what the issue is. Need to scavenge some 10k resistor networks from previous boards. Resistor networks *as well as 4 sets of regulators* are on their way from futurlec.

    *aedit*
    Replaced RN1 and RN6 with 10k. Still rebooting randomly. Really starting to make me wonder.

    *more edit*
    OKAY, I figured it out! I guess wall-wart selection is more important than I thought. Seems the 12v .9a I have been using doesn't have the amps to push 2 displays? *14.3v out* Tried a 5v 2.5a and it works, although 5v is 4.3 and 3.3v is 3.17-3.23. I'll test some more warts and see what I find!


    *final edit*
    Power supply issues confirmed. I suspect the buck regs are allowing a very quick voltage drop I'm not able to see on my slow meters. None of the wall-warts I've tried have the guts to push this board. Pulled the rack-mount out and it's supply runs the board just fine @7.5v with a peak observable draw of 175ma?*The supply is fused @750ma. I've tried 6-9v warts from 900ma to 2100ma and the only ones that "work" are "switching" 5v warts. One rated 2.5a, the other rated 2a. They boot and run programs, but I've had the occasional random reboot. I'm guessing the recommended wall-wart should be 6-9v 2A?
  • average joeaverage joe Posts: 795
    edited 2012-09-02 14:36
    Well I've tried a bunch of different stuff and still can't get the dual-display to run stable. Seems to be random rebooting during SD mount.
    I tried soldering a .1uf ceramic and 10 uf to the sd card pins. Tried many wall warts. I even tried swapping a 5v linear regulator. I'm really starting to wonder what is going on.

    Curious what you're using to power the boards?

    *edit*
    I just got a VERY interesting result when I removed the MAX chip. It looks like the 3v3 rail is sagging, during sd mount. This is (somehow) causing the MAX to pull a reset. Need to investigate further, but at least I'm getting somewhere...

    *aedit*

    Okay, removing the MAX2323 solved the "reset bug." As I stated, my meters are too "slow" to really "see" the spike. It seems to be the 3v3, not 5 as I had though. Propplug works just fine *if not better than the MAX3232* so this is a bonus.
    After re-installing the 5v buck reg, I tested several wall-warts and they work fine with both displays installed. Not recommending the 5v "switching" supplies as the rails are too weak, seeing 4.37-4.4v and 3.21v.

    Tested "working" warts have 4.85v and 3.25-3.27 respectively.
    Radioshack 9v 800ma. CAT 273-1770
    Panasonic 12v 0.9A Model BAD7001 *my MAIN wart, from NICAD charger.*
    Cannon 8.4v 2.0A Model CA-570 *nice and lightweight, voltages seem stable?*

    More testing soon!
    The whole time I've been wondering the EXACT details of my reset bug. Need to dig through the data-sheets for the SIPEX SP3232ECP. Removing this chip restored stability *even the rackmount PSU started to bug*
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-09-02 16:15
    I think an SD mount can surge up to 200mA. Still well under the switching reg limit of 1A. My wallwart is 9V 1A and open circuit runs around 13V.

    I was going to suggest some bigger caps eg 4700uF on each of the 3V and 5V supplies. It is strange that the display on the 5V supply is upsetting something on the 3V supply.

    I've pulled apart my wallwart and it has a 4700uF cap inside. It is possible that different wall warts have smaller caps inside, so maybe worth putting 4700uF across the input instead of the 470uF?
  • average joeaverage joe Posts: 795
    edited 2012-09-02 16:38
    I'm a bit puzzled because after all the testing, removing the SP chip "solved" the issue. I must think about this a bit more, and will experiment a bit. The Panasonic *which is close to your specs* has a large cap, I'd guess 4700-10,000uf can't tell exactly since it's ??wrapped in heat-shrink tubing?? and I'm not interested in cutting it off ATM. A bit of a puzzle, I will try adding more caps to the supply.

    It's curious I have this issue and you do not. Perhaps the SP3232 is sensitive in a way the MAX is not? I'm fairly certain the issue involves a "saggy rail," although I'm not happy with 3.25 and 4.85 nominal voltages. IMO should be 3.31v and 5.02v to 3.28v and 4.97v. I've tried a number of warts and none could handle SD mount. I can "see" sag on my meters, but can't estimate "ACTUAL" sag. I'm going to look into the sound-card -scope programs. No substitue for good test equipment, but might help track the issue. The GB "GDT-11" is about as worthless as they come, and my analog meter is not much help either.

    *edit*
    Well I must have something messed up since Lorem is showing up with a "1" or "3" at the beginning?
    *aedit*
    About Lorem... It was indicating an error in my driver. I was aware that things were not working correctly and have solved this. Seems I tried optimizing TOO far and broke Set161... The correct version is
    set161                  mov     latchvalue,#%11111110    ' group 1, displays all off
                            call    #set373                 ' send out to the latch
                            and     outa,maskP0P20low       '%11111111_11100000_00000000_00000000   
                            or      dira,maskP0P20          '%00000000_00011111_11111111_11111111
                            or      outa,ramaddr            ' send out ramaddr
                            or      outa,maskP20            ' P20 clock high
                            or      outa,maskP19            ' p19 load high
                            andn    outa,maskP20            ' clock low                                                            
                            andn     outa,maskP19            ' load low
                            'or      outa,maskP20            ' clock high                                                          ''Not needed since    
                            'or      outa,maskP19            ' load high
                            or      outa,maskP16P20         ' P16-P20 high in case the next thing is a group change and P16/P17 are low and hence upset the ram chip
    set161_ret              ret
    
    
    I went back and re-compiled everything, updated SD and some things work. I think buttons has a glitch, not sure what yet. There's a few other things. Need to check your tile driver. I hope I didn't break that..
  • average joeaverage joe Posts: 795
    edited 2012-09-03 00:57
    Once again, all bugs were on my end... I believe the PASM driver is ALMOST done. There's a bit of room left in the cog, and I've been thinking about what to do with it.

    #1. More code. I have an idea that might speed things up a fraction of a MS... Moving all display commands to cog. Fill rambuffer with commands as longs, hi-word command, low-word data. Call PASM driver, which outputs command, data... until reaching command #22, *write gddr*

    I've also been thinking about Ram2display and Hub2display. Before calling these commands, we must be in group2, with RS high, and the display(s) selected. Seems best to me if we only be concerned about having the proper display selected and everything else is automatic. This way if we're in group3 and the display is touched, just select the proper display and update. Then return to caller will be in group3, *or 4* just like you left.

    #2. I've also been thinking about "stuffing" SPI into cog-driver. This will obviously not work for the cache driver, but could save a cog? Stuffing FATe is not a possibility.

    The idea is to improve performance, increase flexibility, and not break anything in the process. I'm still not 100% sure the driver is correct. I still can't account for all of the instructions in the burst-transfers. The propeller's counters and our external 161 counters are dynamite together. Making it work properly is not so easy. I tried to import one portion at a time, checking against the other 2 for reference. The set161 bug might have a "ripple" effect, or that's what I'm afraid of. I'll revive the OTHER post on this issue as maybe one of the guru's can guide me in the right direction.

    I'm still wrapping my head around the reset bug. I'll build a few more boards and see if I can find a difference. I still need to document the linear regulator mod. More photos and video will always help. The last build session was in low light and came out with a bit of video-noise. The outside portion was full of glare. A few good clips, but need more footage. I'm attaching the "fixed" touch.spin. Notice change in revision#.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-09-03 01:32
    Have you found the reset bug yet?

    There is much we can do with putting code into cogs - we haven't even started with that but hopefully with more builders others will be able to contribute.

    One thing for instance is the Spin "draw" routine that sets up where to draw a picture x,y,sizex,sizey eg - for a 36 pixel tile like in pacman, the time to do the "draw" may well be taking longer than the actual outputting of the bytes.

    In one sense I kind of like the idea of handing over code to other builders with 2/3 of the hub free, with most cogs free and with pasm drivers still with spare space. There were some instances a few years back with the 8080 and Z80 drivers where some of the object code came with "one long free".

    I haven't had a chance to do any coding for the last few days but hopefully later this week.
  • average joeaverage joe Posts: 795
    edited 2012-09-03 02:12
    I've been thinking about "draw" a bit too. There are many ways of streamlining the draw setup, and I'm not sure of the best way yet. I've been thinking a separate command for displaycmd, in PASM. This would help a bit, I'm sure. Maybe slipping the draw into the first write would be most efficient. Either way, I think it's best to get command transfers working in PASM first.

    Re: free hub memory... I've been thinking about this A LOT. Things like the display initialization code could be stored on the SD card to save space. Then there's the problem of what happens when something goes wrong with the SD... Not easy to diagnose. May not be worth the trouble. Other things could be done and, if worse came to worse, builders could remove unused PUBs in touch.spin. Dynamic loading could also save some memory. For instance, if ALL programs expect to be called from desktop, no need for all the initializations in the PROGRAM's touch.spin

    The last thing is, thinking about expanding the desktop app. It would be interesting to be able to "add" a program to the desktop without manually editing cvs... Say open keyboard, enter command string and desktop edits CVS? Maybe change name of background file? A file browser/selection would be handy... Many things to do! Many possibilities!

    I CERTAINLY want to leave builders enough room to do "useful" stuff. I don't want to "force" them to use the SRAM... And I don't think it will be necessary. A few longs in PASM will be worth the savings in SPIN, in speed and program size, IMO. Draw is the first to "go under the knife" just not sure the best way to implement the command buffer. I'm thinking of allocating 5 longs JUST BEFORE rambuffer to store draw cmds... X,Y,SizeX,SizeY, AND gddrwr... Or maybe 2 calls to PASM driver is better? I'll start writing for seperate calls since it will be the easiest to debug. I have a basic idea, now just need to flesh it out!

    Oh and no, reset bug is still "buggin" me. Only 1 board built ATM and MAX circuit was removed. Must save this for another day since it's not "top of stack." The 3 sold boards will be using propPlugs for programming *I think* Still not happy with the Supply rails being as low as they are... Or am I just paranoid??
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-09-03 02:24
    Lots of great ideas there.

    Not much goes wrong with the SD but Kye's code allows you to print debug error messages to the screen and the code for that is there for things like not finding a .bmp file.

    Re adding things to the .csv, well that would be an app that we need to write. Take the keyboard app and display the .csv file in it and then allow the user to scroll up and down and insert text. The text buffer is small so plenty of room in hub to fit that, which makes coding easier.

    Re the low supply rails, I'm measuring values a little higher and I did once put all my multimeters on a rail and they all disagreed but 0.1 to 0.3V.

    I see on facebook you got your other half to do all the soldering. Wish my wife would learn to solder!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-09-03 02:24
    Lots of great ideas there.

    Not much goes wrong with the SD but Kye's code allows you to print debug error messages to the screen and the code for that is there for things like not finding a .bmp file.

    Re adding things to the .csv, well that would be an app that we need to write. Take the keyboard app and display the .csv file in it and then allow the user to scroll up and down and insert text. The text buffer is small so plenty of room in hub to fit that, which makes coding easier.

    Re the low supply rails, I'm measuring values a little higher and I did once put all my multimeters on a rail and they all disagreed but 0.1 to 0.3V.

    I see on facebook you got your other half to do all the soldering. Wish my wife would learn to solder!
  • average joeaverage joe Posts: 795
    edited 2012-09-03 16:43
    I've been thinking about things a bit, and have come up with some ideas...

    RE: sd debugging. My thought is pushing the display setups to the SD could save quite a bit of space. This means the sd card needs to mount before the display can be initialized. Perhaps we could have more than 1 version of touch.spin? One contains display inits and all code touch.spin currently has. Desktop will be compiled with this version. A "slim" version could be built for user programs that pulls all display inits from SD card. Or something like that, still need to think on it.

    The idea I stated about editing the CVS is one "function" of a larger "desktop settings" program I'm thinking about. Still need to think of all the things necessary to make this work.

    I have done some work on display commands in PASM. I started with draw which seems to work. Still need to experiment but the basics *for verification*
    PUB Draw(x1, y1, x2, y2)   |   drcmd[7]                  ' sets the pixel to x1,y1 and then fills the next (x2-x1)*(y2-y1) pixels
    '    DisplayEnable                                       ' enable one or both displays       already in cog!
    '    SelectMemGroup                                      ' select memory group               already in cog!
        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
          
        if displaymode == "I"                            ' ILI9325 display
          drcmd[0] := ($0050_0000 + x1)
          drcmd[1] := ($0052_0000 + y1)
          drcmd[2] := ($0051_0000 + x2)
          drcmd[3] := ($0053_0000 + y2)
          drcmd[4] := ($0020_0000 + x1)
          drcmd[5] := ($0021_0000 + y1)
          drcmd[6] := ($0022_0000)
          
        if displaymode == "S"                           ' SSD1289 display
          drcmd[0] := ($0044_0000 + ((x2<<8)+x1))
          drcmd[1] := ($0045_0000 + y1)
          drcmd[2] := ($0046_0000 + y2)
          drcmd[3] := ($004e_0000 + x1)
          drcmd[4] := ($004f_0000 + y1)
          drcmd[5] := ($0022_0000)
    
        CogCmd("W", @drcmd, 0,0)
    
    ..
                            cmp     cmd, #"W"       wz      ' hub to display command, terminated with gddrwr
                  if_z      jmp     #pasm_disp_cmd           
    ..
    ..
    
    pasm_disp_cmd           or      dira,maskP0P15                                  '%00000000_00000000_11111111_11111111
                                                            'prepare for command, display(s) selected, /rs low, group2
    :loop                   and     latchvalue, #%0111_0000                         'isolate display and reset
                            or      latchvalue, #%0000_1101                         'group2, /rs low
                            call    #set373                                          'and set
                                                            ' and send command to display
                            andn    outa,maskP19                                    ' CS low
                            and     outa,maskP16P31                                 '%11111111_11111111_00000000_00000000       ' clear for output                   
    
                            rdlong   data_32,hubaddr                                'read command/data from hub
                            mov      pasm_n, data_32                                'copy to pasm_n
                            shr      pasm_n, #16                                    'isolate command
                            
                            or      outa,pasm_n                                    ' send out the word to P0-P15
                            andn    outa,maskP18                                    ' ILI write low
                            or      outa,maskP18                                    ' ILI write high
                            or      outa,maskP19                                    ' CS high
                                                            'prepare for data, display(s) selectd, /rs high, group2
                            and     latchvalue, #%0111_0000                         'isolate display and reset
                            or      latchvalue, #%1000_1101                         'group2, /rs high
                            call    #set373                                          'and set
                                                            'and check if wrGDDR was last command
                            cmp     pasm_n, #$22   wz                              ' is gddwr cmd?
            if_z            jmp     #done                                           ' then finish, otherwise continue
                                                            'if not, continue sending data
                            andn    outa,maskP19                                    ' CS low
                            and     outa,maskP16P31                                 '%11111111_11111111_00000000_00000000       ' clear for output                   
    
                            and     data_32,maskP0P15                               ' mask off data word
                            
                            or      outa,data_32                                    ' send out the word to P0-P15
                            andn    outa,maskP18                                    ' ILI write low
                            or      outa,maskP18                                    ' ILI write high
                            add     hubaddr,#4                                      ' one word
                            or      outa,maskP19                                    ' CS high
    
                            jmp     #:loop                                          'continue until wrGDDR cmd
    
    pasm_disp_cmd_ret       ret           
    
    
    This could be optimized a bit and in several ways. I'm thinking of optimizing for speed first...
    Still need to work on cache driver. I'll try that later tonight.

    I am VERY lucky my better half takes an interest in my hobbies. She soldered together a few of the early boards to help keep things moving. *None of this would be possible without her love and support*

    *edit*
    I've come up with an idea but wanted to bounce the details off of you. What I've been thinking about is trying to cut as much SPIN as possible. Also simplify the draw command so, instead of the above draw
    PUB Draw(x1, y1, x2, y2)   |   drcmd[7]                  ' sets the pixel to x1,y1 and then fills the next (x2-x1)*(y2-y1) pixels
    '    DisplayEnable                                       ' enable one or both displays       already in cog!
    '    SelectMemGroup                                      ' select memory group               already in cog!
        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
       
        CogCmd("W", @x1, 0,0)
    
    And have the cog setup the proper draw commands. This would require a command to configure the selected display? Or could we do this on INIT?
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-09-03 21:17
    Re passing multiple parameters to the display cog, one answer could be to use the existing three arrays we have - eg sdbuffer or rambuffer. Then just pass the location of the array in, say, hubaddress and the command letter, and a cog routine can send it out. How much pasm space do we have left in that cog?

    Thinking in a generic sense, what you could do is put a whole series of commands in that array and send them out. You could have a simple language for that, maybe it is a bit inefficient but if you have one long and 8 bits are for the data and one bit defines whether it is a command or data, and another bit could define if it is the end of sequence. Then you could store all the startup sequence as a series of longs. And that could be stored as a file on the SD card like you say, and save a pile of hub ram code space.

    I've been pondering cache drivers in C. The fundamental problem holding this all back is that both C++ and C89 don't suit this board, because the cache driver and the code both may want to share access to external memory at the same time. I'm not sure how to explain it fully on the C threads - it is our hardware so I think we have to solve it. So - store the program on the SD card and you can't use the SD card. Store it in ram and the code can't use ram. I have an idea that you run Kye's SD driver through the Spin2C program and run it but it is not that simple.

    Fundamentally, I'd like to have the C program in external ram rather than on the SD card because it is faster. I see two solutions - one uses two cogs - one running the C cache driver and one running our touchscreen driver. Between those you have a lock and control is handed back and forth between those cogs. An alternative is three cogs where one is the master cog (either running spin or pasm) which handles which cog has control of the system.

    It is complicated thinking about the code needed to do a large block transfer from SD out to external ram. Such a block transfer is going to need the C code running in order for the SD code to be running. But if the C code is running, the user does not have access to the ram to do the data transfer. You end up sending the data in 512 byte chunks through hub with multiple resetting of the 161 counters rather than one smooth transfer. And yet Spin can do that transfer in one go. At the deep down fundamental level, XMM C still can't seem to replicate what Spin can do. Maybe it can - I just need to think about it some more. I think the problem is that C that fits just in hub will work, but C is bigger than Spin for given equivalent code so a realistic program won't fit in hub. So you are stuck with putting the C program in some form of external storage and that creates all the problems. Perhaps the answer is to allocate a much bigger SD buffer in hub - maybe 8k or something, and then transfer everything in 8k chunks, thus decreasing the number of swaps back and forth between the display driver and the cache driver.

    I guess I have bailed out and gone back to coding everything in Spin. Solve the simple problems first. Certainly putting the draw routine in pasm will speed up pacman and other tile programs, and putting the init code on the SD card as a file will save hub space.
  • average joeaverage joe Posts: 795
    edited 2012-09-03 21:55
    I have been pondering the cache driver quite a bit, and I think the answer is a one cog solution. Cache driver and ram driver in one cog. There should still be room to do this, and it seems all that will be needed is to re-code all the spin in C with appropriate wrappers. I think there is a way to use the existing Spin, but I'm still trying to understand that a bit more.

    I should be able to have the "basic" cache driver soon. My previous attempt was foiled due to poor coding of MY touch.spin. I'm fairly sure this is fixed. The only program that highlighted the bug was Lorem. Now things run properly and BeginProgram works again. Sorry about that.

    I still need to optimize touch.spin a bit more. I see quite a bit of room for improvement. I would very much like to pass draw commands as an address to a an array of 4 long, x1,x2,y1,y2 and have the cog do the rest... Quite possible, but may take a bit of self-modifying code... Not my strongest suit but it will help improve my skills. I feel the driver may be headed in 2 paths in the future. The one path mentioned previously, where the driver does not include display inits, should be named differently for reference. The other path is best for initial development of programs, containing debug code and display inits. From my point of view, most programs should be expected to run from the desktop. The desktop inits the display so there should be no need for that code in the driver... EXCEPT for initial development where program will most likely be run from unknown state. Not my favorite solution but seems better than using conditional compiles and BST. We don't need to worry about this quite yet, just something to think about.

    There's quite a bit to think about, all quite possible... Just several levels of difficulty. Oh, there's 227 longs left in the RAM cog. I'll keep you updated!
    PS. please test VER 0.0.8.6, I think it's okay but need a second set of eyes. The cache driver test did not show bug in old code, but when trying to run Hello.c failed. Hopefully I'll have better luck tonight.
Sign In or Register to comment.