Well, I've given up on the new board for now. I only have 1 display and the other board works, sort of. So, I'll be stepping back to that board as soon as I re-design the power supply fix.
The cache driver is a bit tricky. My idea is to lock the COMMON resources before accessing that resource.. I see 2 different resources, the SD card AND the SRAM. Use 1 lock or 2?
spi_flash_cache.spin seems to use the locks in a special way?
lock_set_handler
mov lock_id, vmaddr
mov lck_spi, lock_set
mov nlk_spi, lock_clr
jmp #waitcmd
lock_set
lockset lock_id wc
lock_clr
lockclr lock_id
lock_id long 0 ' lock id for optional bus interlock
From what I can tell, this copies in the lock set and clear instructions into their "placeholders" in this code
miss movd mtest, line
movd mst, line
lck_spi test $, #0 wc ' lock no-op: clear the carry bit
if_c jmp #lck_spi
mov dira, spidir ' set the pins back so we can use them
mtest test 0-0, dirty_mask wz
if_z jmp #:rd ' current page is clean, just read new page
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #BWRITE ' write current page
:rd mov vmaddr, vmpage
shl vmaddr, offset_width
call #BREAD ' read new page
mov dira, #0 ' release the pins for other SPI clients
nlk_spi nop
mst mov 0-0, vmpage
miss_ret ret
I get the basic idea, but still not sure how to compensate for this:
lck_spi test $, #0 wc ' lock no-op: clear the carry bit
I'm also unsure how to pass in the lock id with a start-up parameter? Or is this unnecessary? I will work up some code for review and comments.
I guess a better question is this: What is an extended function in spi_flash_cache? How is it called? I started working on a patch and this is what I have so far::
{
Skeleton JCACHE external RAM driver
Copyright (c) 2011 by David Betz
Based on code by Steve Denson (jazzed)
Copyright (c) 2010 by John Steven Denson
Inspired by VMCOG - virtual memory server for the Propeller
Copyright (c) February 3, 2010 by William Henning
For the EuroTouch 161 By James Moxham and Joe Heinz
Basic port by Joe Heinz, Optimizations by Steve Denson
Copyright (c) 2012 by John Steven Denson and Joe Heinz
TERMS OF USE: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
}
CON
' default cache dimensions
DEFAULT_INDEX_WIDTH = 6
DEFAULT_OFFSET_WIDTH = 7
' cache line tag flags
EMPTY_BIT = 30
DIRTY_BIT = 31
PUB image
return @init_vm
DAT
org $0
' initialization structure offsets
' $0: pointer to a two word mailbox
' $4: pointer to where to store the cache lines in hub ram
' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH)
' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH)
' note that $4 must be at least 2^(index_width+offset_width) bytes in size
' the cache line mask is returned in $0
init_vm mov t1, par ' get the address of the initialization structure
rdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bit
mov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on return
add pvmaddr, #4
add t1, #4
rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cache
add t1, #4
rdlong t2, t1 wz
if_nz mov index_width, t2 ' override the index_width default value
add t1, #4
rdlong t2, t1 wz
if_nz mov offset_width, t2 ' override the offset_width default value
mov index_count, #1
shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1
mov line_size, #1
shl line_size, offset_width
mov t1, line_size
sub t1, #1
wrlong t1, par
shr line_size, #1 ' divide lenght by two for word-byte after response - jsd
mov frqa, _frqa ' setup NCO freq
mov frqb, _frqb ' setup EDGE freq
' put external memory initialization here
jmp #vmflush
fillme long 0[128-fillme] ' first 128 cog locations are used for a direct mapped cache table
fit 128
' initialize the cache lines
vmflush movd :flush, #0
mov t1, index_count
:flush mov 0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wz
if_z jmp #:wait
shr vmline, offset_width wc ' carry is now one for read and zero for write
mov set_dirty_bit, #0 ' make mask to set dirty bit on writes
muxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line index
and line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache line
wrlong hubaddr, pvmaddr ' return the address of the cache line
movs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0 ' get the cache line tag
and vmcurrent, tag_mask
cmp vmcurrent, vmline wz ' z set means there was a cache hit
if_nz call #miss ' handle a cache miss
:st or 0-0, set_dirty_bit ' set the dirty bit on writes
jmp #waitcmd ' wait for a new command
' line is the cache line index
' vmcurrent is current cache line
' vmline is new cache line
' hubaddr is the address of the cache line
miss movd mtest, line
movd mst, line
lck_bus test $, #0 wc ' lock no-op: clear the carry bit
if_c jmp #lck_bus
mtest test 0-0, dirty_mask wz
if_z jmp #:rd ' current cache line is clean, just read new one
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
nlk_bus nop
mst mov 0-0, vmline
miss_ret ret
' pointers to mailbox entries
pvmcmd long 0 ' on call this is the virtual address and read/write bit
pvmaddr long 0 ' on return this is the address of the cache line containing the virtual address
cacheptr long 0 ' address in hub ram where cache lines are stored
vmline long 0 ' cache line containing the virtual address
vmcurrent long 0 ' current selected cache line (same as vmline on a cache hit)
line long 0 ' current cache line index
set_dirty_bit long 0 ' DIRTY_BIT set on writes, clear on reads
zero long 0 ' zero constant
dstinc long 1<<9 ' increment for the destination field of an instruction
t1 long 0 ' temporary variable
t2 long 0 ' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long 0
index_count long 0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long 0 ' line size in bytes
empty_mask long (1<<EMPTY_BIT)
dirty_mask long (1<<DIRTY_BIT)
' input parameters to rd_cache_line and wr_cache_line
vmaddr long 0 ' external address
hubaddr long 0 ' hub memory address
' temporaries used by rd_cache_line and wr_cache_line
ptr long 0
count long 0 ' copy line size from shifted line size
'get_values rdlong hubaddr, hubptr ' get hub address
' rdlong ramaddr, ramptr ' get ram address
' rdlong len, lenptr ' get length
' mov err, #5 ' err=5
'get_values_ret ret
'init 'mov err, #0 ' reset err=false=good
'mov dira,zero ' tristate the pins with the cog dira
' and dira,maskP0P20P22 ' tristates all the common pins
'done 'wrlong err, errptr ' status =0=false=good, else error x
'wrlong zero, comptr ' command =0 (done)
lock_set_handler
mov lock_id, vmaddr
mov lck_bus, lock_set
mov nlk_bus, lock_clr
jmp #waitcmd
lock_set
lockset lock_id wc
lock_clr
lockclr lock_id
' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 or dira,maskP22 ' pin 22 is an output
andn outa,maskP22 ' set P22low so Y0-Y7 are all high
or dira,maskP0P20 ' pins P0-P20 are outputs
and outa,maskP0P2low ' set these 3 pins low
or outa,pasm_n ' set the 137 pins
or outa,maskP22 ' pin 22 high
set137_ret ret ' return
load161pasm ' uses vmaddr
mov count, line_size ' make a copy of line_size AND.
mov ptr, hubaddr ' hubaddr = hub page address
'or outa,maskP0P20 ' set P0-P20 high - unnecessary - jsd
lock lockset lock_id wc
or dira,maskP0P20 ' output pins 0-20
mov pasm_n,#0 ' group 0
call #set137 ' set the 137 output
and outa,maskP0P18low ' pins 0-18 set low
shr vmaddr, #1 ' schematic connects SRAM A0 to A0, not A1 - jsd
or outa,vmaddr ' output addres to 161 chips
andn outa,maskP19P20 ' clock and load low
or outa,maskP19 ' clock high
or outa,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high
or outa,maskP16P20
mov pasm_n,#1 ' back to group 1 for memory transfer
call #set137 ' as next routine will always be group 1
or dira,maskP16P20 ' output pins 16-20
or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
'-----------------------------------------------
' setups needed for burst read
'-----------------------------------------------
_frqa long $1000_0000
_ctra long 4<<26 | 19 ' NCO mode on P19
_phsa long $0000_0000 ' phsa offset for adjusting clock start
_frqb long 2 ' phsb accumulates twice per edge
_ctrb long $A<<26| 19 ' Edge Accumulate mode on P19
'----------------------------------------------------------------------------------------------------
'
' rd_cache_line - read a cache line from external memory
'
' vmaddr is the external memory address to read
' hubaddr is the hub memory address to write
' line_size is the number of bytes to read
'
'----------------------------------------------------------------------------------------------------
rd_cache_line
' command T
pasmramtohub
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
and dira,maskP16P31 ' set P0-P15 as inputs
andn outa,maskP16 ' memory /rd low
or outa,maskP19
mov phsa, _phsa ' init counters phsa
mov phsb, ptr ' save hub ptr to phsb
mov ctrb, _ctrb ' set ctr be mode
andn outa,maskP19 ' start counters
rdword data_16,phsb ' sync up only
mov ctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointer
mov data_16,ina ' get first data
wrword data_16,phsb ' move data to hub
djnz count,#ramtohub_loop
or outa,maskP19 ' stop clock
mov ctra, #0 ' stop counter
or outa,maskP16 ' memory /rd high
or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs
and dira,maskP0P20P22 ' tristates all the common pins
rd_unlock lockclr lock_id
rd_cache_line_ret ret
'----------------------------------------------------------------------------------------------------
'
' wr_cache_line - write a cache line to external memory
'
' vmaddr is the external memory address to write
' hubaddr is the hub memory address to read
' line_size is the number of bytes to write
'
'----------------------------------------------------------------------------------------------------
wr_cache_line
' command S
pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
or dira,maskP0P15 ' set prop pins 0-15 as outputs
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,maskP19 ' clock 161 low
or outa,maskP19 ' clock 161 high
djnz count,#hubtoram_loop ' loop this many times
and dira,maskP0P20P22 ' tristates all the common pins
wr_unlock lockclr lock_id
wr_cache_line_ret ret
lock_id long 0 ' lock id for optional bus interlock
pasm_n long 0 ' general purpose value
data_16 long 0 ' general purpose value
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
maskP19P20 long %00000000_00011000_00000000_00000000 ' pin 19/20
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
maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ
fit 496
I don't think this is even close. First, this defaults not to use the lock
miss movd mtest, line
movd mst, line
lck_bus test $, #0 wc ' lock no-op: clear the carry bit
if_c jmp #lck_bus
mtest test 0-0, dirty_mask wz
if_z jmp #:rd ' current cache line is clean, just read new one
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
nlk_bus nop
mst mov 0-0, vmline
miss_ret ret
Which patches the lock set and clear commands into the no:ops? This is done at the end of the dispatch section of the extend command? I'm not sure how to replicate?
Please ignore SD lock comment since I realized the only time the cache will use the SD is on boot loading SD content to SRAM. The "program" will not be running, so no need to lock SD. UNLESS using SDxmmC? *Not sure I want to at this point?*
If you guys could point me in the direction of FIXING this I would appreciate it. I will look at the OTHER cache drivers to see how they differ.
Thanks guys...
Oh, btw.. what's going on with the board? I could use a logic analyzer on the LCD pins if someone has the time. If not I understand!
I guess a better question is this: What is an extended function in spi_flash_cache? How is it called? I started working on a patch and this is what I have so far::
{
Skeleton JCACHE external RAM driver
Copyright (c) 2011 by David Betz
Based on code by Steve Denson (jazzed)
Copyright (c) 2010 by John Steven Denson
Inspired by VMCOG - virtual memory server for the Propeller
Copyright (c) February 3, 2010 by William Henning
For the EuroTouch 161 By James Moxham and Joe Heinz
Basic port by Joe Heinz, Optimizations by Steve Denson
Copyright (c) 2012 by John Steven Denson and Joe Heinz
TERMS OF USE: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
}
CON
' default cache dimensions
DEFAULT_INDEX_WIDTH = 6
DEFAULT_OFFSET_WIDTH = 7
' cache line tag flags
EMPTY_BIT = 30
DIRTY_BIT = 31
PUB image
return @init_vm
DAT
org $0
' initialization structure offsets
' $0: pointer to a two word mailbox
' $4: pointer to where to store the cache lines in hub ram
' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH)
' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH)
' note that $4 must be at least 2^(index_width+offset_width) bytes in size
' the cache line mask is returned in $0
init_vm mov t1, par ' get the address of the initialization structure
rdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bit
mov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on return
add pvmaddr, #4
add t1, #4
rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cache
add t1, #4
rdlong t2, t1 wz
if_nz mov index_width, t2 ' override the index_width default value
add t1, #4
rdlong t2, t1 wz
if_nz mov offset_width, t2 ' override the offset_width default value
mov index_count, #1
shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1
mov line_size, #1
shl line_size, offset_width
mov t1, line_size
sub t1, #1
wrlong t1, par
shr line_size, #1 ' divide lenght by two for word-byte after response - jsd
mov frqa, _frqa ' setup NCO freq
mov frqb, _frqb ' setup EDGE freq
' put external memory initialization here
jmp #vmflush
fillme long 0[128-fillme] ' first 128 cog locations are used for a direct mapped cache table
fit 128
' initialize the cache lines
vmflush movd :flush, #0
mov t1, index_count
:flush mov 0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wz
if_z jmp #:wait
shr vmline, offset_width wc ' carry is now one for read and zero for write
mov set_dirty_bit, #0 ' make mask to set dirty bit on writes
muxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line index
and line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache line
wrlong hubaddr, pvmaddr ' return the address of the cache line
movs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0 ' get the cache line tag
and vmcurrent, tag_mask
cmp vmcurrent, vmline wz ' z set means there was a cache hit
if_nz call #miss ' handle a cache miss
:st or 0-0, set_dirty_bit ' set the dirty bit on writes
jmp #waitcmd ' wait for a new command
' line is the cache line index
' vmcurrent is current cache line
' vmline is new cache line
' hubaddr is the address of the cache line
miss movd mtest, line
movd mst, line
lck_bus test $, #0 wc ' lock no-op: clear the carry bit
if_c jmp #lck_bus
mtest test 0-0, dirty_mask wz
if_z jmp #:rd ' current cache line is clean, just read new one
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
nlk_bus nop
mst mov 0-0, vmline
miss_ret ret
' pointers to mailbox entries
pvmcmd long 0 ' on call this is the virtual address and read/write bit
pvmaddr long 0 ' on return this is the address of the cache line containing the virtual address
cacheptr long 0 ' address in hub ram where cache lines are stored
vmline long 0 ' cache line containing the virtual address
vmcurrent long 0 ' current selected cache line (same as vmline on a cache hit)
line long 0 ' current cache line index
set_dirty_bit long 0 ' DIRTY_BIT set on writes, clear on reads
zero long 0 ' zero constant
dstinc long 1<<9 ' increment for the destination field of an instruction
t1 long 0 ' temporary variable
t2 long 0 ' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long 0
index_count long 0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long 0 ' line size in bytes
empty_mask long (1<<EMPTY_BIT)
dirty_mask long (1<<DIRTY_BIT)
' input parameters to rd_cache_line and wr_cache_line
vmaddr long 0 ' external address
hubaddr long 0 ' hub memory address
' temporaries used by rd_cache_line and wr_cache_line
ptr long 0
count long 0 ' copy line size from shifted line size
'get_values rdlong hubaddr, hubptr ' get hub address
' rdlong ramaddr, ramptr ' get ram address
' rdlong len, lenptr ' get length
' mov err, #5 ' err=5
'get_values_ret ret
'init 'mov err, #0 ' reset err=false=good
'mov dira,zero ' tristate the pins with the cog dira
' and dira,maskP0P20P22 ' tristates all the common pins
'done 'wrlong err, errptr ' status =0=false=good, else error x
'wrlong zero, comptr ' command =0 (done)
lock_set_handler
mov lock_id, vmaddr
mov lck_bus, lock_set
mov nlk_bus, lock_clr
jmp #waitcmd
lock_set
lockset lock_id wc
lock_clr
lockclr lock_id
' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 or dira,maskP22 ' pin 22 is an output
andn outa,maskP22 ' set P22low so Y0-Y7 are all high
or dira,maskP0P20 ' pins P0-P20 are outputs
and outa,maskP0P2low ' set these 3 pins low
or outa,pasm_n ' set the 137 pins
or outa,maskP22 ' pin 22 high
set137_ret ret ' return
load161pasm ' uses vmaddr
mov count, line_size ' make a copy of line_size AND.
mov ptr, hubaddr ' hubaddr = hub page address
'or outa,maskP0P20 ' set P0-P20 high - unnecessary - jsd
lock lockset lock_id wc
or dira,maskP0P20 ' output pins 0-20
mov pasm_n,#0 ' group 0
call #set137 ' set the 137 output
and outa,maskP0P18low ' pins 0-18 set low
shr vmaddr, #1 ' schematic connects SRAM A0 to A0, not A1 - jsd
or outa,vmaddr ' output addres to 161 chips
andn outa,maskP19P20 ' clock and load low
or outa,maskP19 ' clock high
or outa,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high
or outa,maskP16P20
mov pasm_n,#1 ' back to group 1 for memory transfer
call #set137 ' as next routine will always be group 1
or dira,maskP16P20 ' output pins 16-20
or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
'-----------------------------------------------
' setups needed for burst read
'-----------------------------------------------
_frqa long $1000_0000
_ctra long 4<<26 | 19 ' NCO mode on P19
_phsa long $0000_0000 ' phsa offset for adjusting clock start
_frqb long 2 ' phsb accumulates twice per edge
_ctrb long $A<<26| 19 ' Edge Accumulate mode on P19
'----------------------------------------------------------------------------------------------------
'
' rd_cache_line - read a cache line from external memory
'
' vmaddr is the external memory address to read
' hubaddr is the hub memory address to write
' line_size is the number of bytes to read
'
'----------------------------------------------------------------------------------------------------
rd_cache_line
' command T
pasmramtohub
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
and dira,maskP16P31 ' set P0-P15 as inputs
andn outa,maskP16 ' memory /rd low
or outa,maskP19
mov phsa, _phsa ' init counters phsa
mov phsb, ptr ' save hub ptr to phsb
mov ctrb, _ctrb ' set ctr be mode
andn outa,maskP19 ' start counters
rdword data_16,phsb ' sync up only
mov ctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointer
mov data_16,ina ' get first data
wrword data_16,phsb ' move data to hub
djnz count,#ramtohub_loop
or outa,maskP19 ' stop clock
mov ctra, #0 ' stop counter
or outa,maskP16 ' memory /rd high
or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs
and dira,maskP0P20P22 ' tristates all the common pins
rd_unlock lockclr lock_id
rd_cache_line_ret ret
'----------------------------------------------------------------------------------------------------
'
' wr_cache_line - write a cache line to external memory
'
' vmaddr is the external memory address to write
' hubaddr is the hub memory address to read
' line_size is the number of bytes to write
'
'----------------------------------------------------------------------------------------------------
wr_cache_line
' command S
pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
or dira,maskP0P15 ' set prop pins 0-15 as outputs
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,maskP19 ' clock 161 low
or outa,maskP19 ' clock 161 high
djnz count,#hubtoram_loop ' loop this many times
and dira,maskP0P20P22 ' tristates all the common pins
wr_unlock lockclr lock_id
wr_cache_line_ret ret
lock_id long 0 ' lock id for optional bus interlock
pasm_n long 0 ' general purpose value
data_16 long 0 ' general purpose value
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
maskP19P20 long %00000000_00011000_00000000_00000000 ' pin 19/20
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
maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ
fit 496
I don't think this is even close. First, this defaults not to use the lock
miss movd mtest, line
movd mst, line
lck_bus test $, #0 wc ' lock no-op: clear the carry bit
if_c jmp #lck_bus
mtest test 0-0, dirty_mask wz
if_z jmp #:rd ' current cache line is clean, just read new one
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
nlk_bus nop
mst mov 0-0, vmline
miss_ret ret
Which patches the lock set and clear commands into the no:ops? This is done at the end of the dispatch section of the extend command? I'm not sure how to replicate?
Please ignore SD lock comment since I realized the only time the cache will use the SD is on boot loading SD content to SRAM. The "program" will not be running, so no need to lock SD. UNLESS using SDxmmC? *Not sure I want to at this point?*
If you guys could point me in the direction of FIXING this I would appreciate it. I will look at the OTHER cache drivers to see how they differ.
Thanks guys...
Oh, btw.. what's going on with the board? I could use a logic analyzer on the LCD pins if someone has the time. If not I understand!
]
We use function #7 to set the lock and since that is currently the highest function code used by the driver the code was placed directly after the lock table to save one long which would normally be just a jmp to the start of the handler. That's clever coding by Ted.
Okay, I think I'm with you on the structure. I'm still unsure about how to modify the CURRENT cache driver to support locking. Seems like I need to add extended functionality?
extend mov vmaddr, vmpage
shr vmaddr, #8
shr vmpage, #2
and vmpage, #7
add vmpage, #dispatch
mov dira, spidir ' set the pins back so we can use them
jmp vmpage
dispatch
jmp #waitcmd
jmp #erase_4k_block_handler
jmp #write_data_handler
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
' jmp #lock_set_handler - This is the next instruction - no need to waste a long
Is called from the beginning of the command loop:
' start the command loop
waitcmd mov dira, #0 ' release the pins for other SPI clients
wrlong zero, pvmcmd
:wait rdlong vmpage, pvmcmd wz
if_z jmp #:wait
test vmpage, #int#EXTEND_MASK wz ' test for an extended command
if_z jmp #extend
would become
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wz
if_z jmp #:wait
test vmpage, #int#EXTEND_MASK wz ' test for an extended command
if_z jmp #extend
This extended command section sounds like the way to implement ADDITIONAL functions?
Now function 7 sets the lock, and is called ???? automatically I hope?
I also noticed the SPI cache has
int: "cache_interface"
I found this in load161. Got rid of it.
lock lockset lock_id wc
OKAY... Getting close:
{
Skeleton JCACHE external RAM driver
Copyright (c) 2011 by David Betz
Based on code by Steve Denson (jazzed)
Copyright (c) 2010 by John Steven Denson
Inspired by VMCOG - virtual memory server for the Propeller
Copyright (c) February 3, 2010 by William Henning
For the EuroTouch 161 By James Moxham and Joe Heinz
Basic port by Joe Heinz, Optimizations by Steve Denson
Copyright (c) 2012 by John Steven Denson and Joe Heinz
TERMS OF USE: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
}
CON
' default cache dimensions
DEFAULT_INDEX_WIDTH = 6
DEFAULT_OFFSET_WIDTH = 7
' cache line tag flags
EMPTY_BIT = 30
DIRTY_BIT = 31
OBJ
int: "cache_interface"
PUB image
return @init_vm
DAT
org $0
' initialization structure offsets
' $0: pointer to a two word mailbox
' $4: pointer to where to store the cache lines in hub ram
' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH)
' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH)
' note that $4 must be at least 2^(index_width+offset_width) bytes in size
' the cache line mask is returned in $0
init_vm mov t1, par ' get the address of the initialization structure
rdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bit
mov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on return
add pvmaddr, #4
add t1, #4
rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cache
add t1, #4
rdlong t2, t1 wz
if_nz mov index_width, t2 ' override the index_width default value
add t1, #4
rdlong t2, t1 wz
if_nz mov offset_width, t2 ' override the offset_width default value
mov index_count, #1
shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1
mov line_size, #1
shl line_size, offset_width
mov t1, line_size
sub t1, #1
wrlong t1, par
shr line_size, #1 ' divide lenght by two for word-byte after response - jsd
mov frqa, _frqa ' setup NCO freq
mov frqb, _frqb ' setup EDGE freq
' put external memory initialization here
jmp #vmflush
fillme long 0[128-fillme] ' first 128 cog locations are used for a direct mapped cache table
fit 128
' initialize the cache lines
vmflush movd :flush, #0
mov t1, index_count
:flush mov 0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wz
if_z jmp #:wait
test vmline, #int#EXTEND_MASK wz ' test for an extended command added JPH 6-5-12
if_z jmp #extend ' added JPH 6-5-12
shr vmline, offset_width wc ' carry is now one for read and zero for write
mov set_dirty_bit, #0 ' make mask to set dirty bit on writes
muxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line index
and line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache line
wrlong hubaddr, pvmaddr ' return the address of the cache line
movs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0 ' get the cache line tag
and vmcurrent, tag_mask
cmp vmcurrent, vmline wz ' z set means there was a cache hit
if_nz call #miss ' handle a cache miss
:st or 0-0, set_dirty_bit ' set the dirty bit on writes
jmp #waitcmd ' wait for a new command
' line is the cache line index
' vmcurrent is current cache line
' vmline is new cache line
' hubaddr is the address of the cache line
miss movd mtest, line 'modified names to match SPI_Flash_Cache JPH 6-5-12
movd mst, line 'modified names to match SPI_Flash_Cache JPH 6-5-12
lck_bus test $, #0 wc ' lock no-op: clear the carry bit JPH 6-5-12
if_c jmp #lck_bus ' added for locking JPH 6-5-12
mtest test 0-0, dirty_mask wz 'modified names to match SPI_Flash_Cache JPH 6-5-12
if_z jmp #:rd ' current cache line is clean, just read new one
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
nlk_bus nop ' added for locking JPH 6-5-12
mst mov 0-0, vmline 'modified names to match SPI_Flash_Cache JPH 6-5-12
miss_ret ret
'Extended function set? JPH 6-5-12
extend mov vmaddr, vmline
shr vmaddr, #8
shr vmline, #2
and vmline, #7
add vmline, #dispatch
' mov dira, spidir ' not needed since pins should be tri-state by now?
jmp vmline
dispatch
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
' jmp #lock_set_handler - This is the next instruction - no need to waste a long
lock_set_handler
mov lock_id, vmaddr
mov lck_bus, lock_set
mov nlk_bus, lock_clr
jmp #waitcmd
lock_set
lockset lock_id wc
lock_clr
lockclr lock_id
lock_id long 0 ' lock id for optional bus interlock
'Insert extended function stubs here???
' pointers to mailbox entries
pvmcmd long 0 ' on call this is the virtual address and read/write bit
pvmaddr long 0 ' on return this is the address of the cache line containing the virtual address
cacheptr long 0 ' address in hub ram where cache lines are stored
vmline long 0 ' cache line containing the virtual address
vmcurrent long 0 ' current selected cache line (same as vmline on a cache hit)
line long 0 ' current cache line index
set_dirty_bit long 0 ' DIRTY_BIT set on writes, clear on reads
zero long 0 ' zero constant
dstinc long 1<<9 ' increment for the destination field of an instruction
t1 long 0 ' temporary variable
t2 long 0 ' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long 0
index_count long 0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long 0 ' line size in bytes
empty_mask long (1<<EMPTY_BIT)
dirty_mask long (1<<DIRTY_BIT)
' input parameters to rd_cache_line and wr_cache_line
vmaddr long 0 ' external address
hubaddr long 0 ' hub memory address
' temporaries used by rd_cache_line and wr_cache_line
ptr long 0
count long 0 ' copy line size from shifted line size
'get_values rdlong hubaddr, hubptr ' get hub address
' rdlong ramaddr, ramptr ' get ram address
' rdlong len, lenptr ' get length
' mov err, #5 ' err=5
'get_values_ret ret
'init 'mov err, #0 ' reset err=false=good
'mov dira,zero ' tristate the pins with the cog dira
' and dira,maskP0P20P22 ' tristates all the common pins
'done 'wrlong err, errptr ' status =0=false=good, else error x
'wrlong zero, comptr ' command =0 (done)
' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 or dira,maskP22 ' pin 22 is an output
andn outa,maskP22 ' set P22low so Y0-Y7 are all high
or dira,maskP0P20 ' pins P0-P20 are outputs
and outa,maskP0P2low ' set these 3 pins low
or outa,pasm_n ' set the 137 pins
or outa,maskP22 ' pin 22 high
set137_ret ret ' return
load161pasm ' uses vmaddr
mov count, line_size ' make a copy of line_size AND.
mov ptr, hubaddr ' hubaddr = hub page address
'or outa,maskP0P20 ' set P0-P20 high - unnecessary - jsd
or dira,maskP0P20 ' output pins 0-20
mov pasm_n,#0 ' group 0
call #set137 ' set the 137 output
and outa,maskP0P18low ' pins 0-18 set low
shr vmaddr, #1 ' schematic connects SRAM A0 to A0, not A1 - jsd
or outa,vmaddr ' output addres to 161 chips
andn outa,maskP19P20 ' clock and load low
or outa,maskP19 ' clock high
or outa,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high
or outa,maskP16P20
mov pasm_n,#1 ' back to group 1 for memory transfer
call #set137 ' as next routine will always be group 1
or dira,maskP16P20 ' output pins 16-20
or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
'-----------------------------------------------
' setups needed for burst read
'-----------------------------------------------
_frqa long $1000_0000
_ctra long 4<<26 | 19 ' NCO mode on P19
_phsa long $0000_0000 ' phsa offset for adjusting clock start
_frqb long 2 ' phsb accumulates twice per edge
_ctrb long $A<<26| 19 ' Edge Accumulate mode on P19
'----------------------------------------------------------------------------------------------------
'
' rd_cache_line - read a cache line from external memory
'
' vmaddr is the external memory address to read
' hubaddr is the hub memory address to write
' line_size is the number of bytes to read
'
'----------------------------------------------------------------------------------------------------
rd_cache_line ' command T pasmramtohub
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
and dira,maskP16P31 ' set P0-P15 as inputs
andn outa,maskP16 ' memory /rd low
or outa,maskP19
mov phsa, _phsa ' init counters phsa
mov phsb, ptr ' save hub ptr to phsb
mov ctrb, _ctrb ' set ctr be mode
andn outa,maskP19 ' start counters
rdword data_16,phsb ' sync up only
mov ctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointer
mov data_16,ina ' get first data
wrword data_16,phsb ' move data to hub
djnz count,#ramtohub_loop
or outa,maskP19 ' stop clock
mov ctra, #0 ' stop counter
or outa,maskP16 ' memory /rd high
or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs
and dira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret ret
'----------------------------------------------------------------------------------------------------
'
' wr_cache_line - write a cache line to external memory
'
' vmaddr is the external memory address to write
' hubaddr is the hub memory address to read
' line_size is the number of bytes to write
'
'----------------------------------------------------------------------------------------------------
wr_cache_line ' command S pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
or dira,maskP0P15 ' set prop pins 0-15 as outputs
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,maskP19 ' clock 161 low
or outa,maskP19 ' clock 161 high
djnz count,#hubtoram_loop ' loop this many times
and dira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret ret
pasm_n long 0 ' general purpose value
data_16 long 0 ' general purpose value
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
maskP19P20 long %00000000_00011000_00000000_00000000 ' pin 19/20
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
maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ
fit 496
I think it's close now? Ready for comments/ Sorry about the repetitive edits but don't want to "CLOG" the thread
Ok, well we have a finalized board design for the ILI chip. I just got an email saying the latest board is on the way which will run both displays. We must be getting close to a hardware that is stable now. So... if this new board works with both your 3.2" and my 2.4" displays, and with dual displays so we can do 480x320, then maybe we can say the hardware is working. And if that is so, well I ordered 10 boards, so maybe we can start sending out some boards and maybe the brilliant boffins here on the GCC thread can try out a board? Happy here to send a few out to those keen to help debug things. I see so many brilliant things here that are just on the verge of being implemented!
Okay guys, sorry about the false starts. I think I've got the revisions necessary, but I don't know how to test? I've done the "standard" cache driver tests and it passes with flying colors. Here's the FULL file, and I will post the section I changed so you don't need to dig.
{
Skeleton JCACHE external RAM driver
Copyright (c) 2011 by David Betz
Based on code by Steve Denson (jazzed)
Copyright (c) 2010 by John Steven Denson
Inspired by VMCOG - virtual memory server for the Propeller
Copyright (c) February 3, 2010 by William Henning
For the EuroTouch 161 By James Moxham and Joe Heinz
Basic port by Joe Heinz, Optimizations by Steve Denson
Copyright (c) 2012 by John Steven Denson and Joe Heinz
TERMS OF USE: MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
}
CON
' default cache dimensions
DEFAULT_INDEX_WIDTH = 6
DEFAULT_OFFSET_WIDTH = 7
' cache line tag flags
EMPTY_BIT = 30
DIRTY_BIT = 31
OBJ
int: "cache_interface_joemod"
PUB image
return @init_vm
DAT
org $0
' initialization structure offsets
' $0: pointer to a two word mailbox
' $4: pointer to where to store the cache lines in hub ram
' $8: number of bits in the cache line index if non-zero (default is DEFAULT_INDEX_WIDTH)
' $a: number of bits in the cache line offset if non-zero (default is DEFAULT_OFFSET_WIDTH)
' note that $4 must be at least 2^(index_width+offset_width) bytes in size
' the cache line mask is returned in $0
init_vm mov t1, par ' get the address of the initialization structure
rdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bit
mov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on return
add pvmaddr, #4
add t1, #4
rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cache
add t1, #4
rdlong t2, t1 wz
if_nz mov index_width, t2 ' override the index_width default value
add t1, #4
rdlong t2, t1 wz
if_nz mov offset_width, t2 ' override the offset_width default value
mov index_count, #1
shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1
mov line_size, #1
shl line_size, offset_width
mov t1, line_size
sub t1, #1
wrlong t1, par
shr line_size, #1 ' divide lenght by two for word-byte after response - jsd
mov frqa, _frqa ' setup NCO freq
mov frqb, _frqb ' setup EDGE freq
' put external memory initialization here
jmp #vmflush
fillme long 0[128-fillme] ' first 128 cog locations are used for a direct mapped cache table
fit 128
' initialize the cache lines
vmflush movd :flush, #0
mov t1, index_count
:flush mov 0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wz
if_z jmp #:wait
test vmline, #int#EXTEND_MASK wz ' test for an extended command added JPH 6-5-12
if_z jmp #extend ' added JPH 6-5-12
shr vmline, offset_width wc ' carry is now one for read and zero for write
mov set_dirty_bit, #0 ' make mask to set dirty bit on writes
muxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line index
and line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache line
wrlong hubaddr, pvmaddr ' return the address of the cache line
movs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0 ' get the cache line tag
and vmcurrent, tag_mask
cmp vmcurrent, vmline wz ' z set means there was a cache hit
if_nz call #miss ' handle a cache miss
:st or 0-0, set_dirty_bit ' set the dirty bit on writes
jmp #waitcmd ' wait for a new command
' line is the cache line index
' vmcurrent is current cache line
' vmline is new cache line
' hubaddr is the address of the cache line
miss movd mtest, line 'modified names to match SPI_Flash_Cache JPH 6-5-12
movd mst, line 'modified names to match SPI_Flash_Cache JPH 6-5-12
lck_bus test $, #0 wc ' lock no-op: clear the carry bit JPH 6-5-12
if_c jmp #lck_bus ' added for locking JPH 6-5-12
mtest test 0-0, dirty_mask wz 'modified names to match SPI_Flash_Cache JPH 6-5-12
if_z jmp #:rd ' current cache line is clean, just read new one
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
nlk_bus nop ' added for locking JPH 6-5-12
mst mov 0-0, vmline 'modified names to match SPI_Flash_Cache JPH 6-5-12
miss_ret ret
'Extended function set? JPH 6-5-12
extend mov vmaddr, vmline
shr vmaddr, #8
shr vmline, #2
and vmline, #7
add vmline, #dispatch
' mov dira, spidir ' not needed since pins should be tri-state by now?
jmp vmline
dispatch
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
' jmp #lock_set_handler - This is the next instruction - no need to waste a long
lock_set_handler
mov lock_id, vmaddr
mov lck_bus, lock_set
mov nlk_bus, lock_clr
jmp #waitcmd
lock_set
lockset lock_id wc
lock_clr
lockclr lock_id
lock_id long 0 ' lock id for optional bus interlock
'Insert extended function stubs here???
' pointers to mailbox entries
pvmcmd long 0 ' on call this is the virtual address and read/write bit
pvmaddr long 0 ' on return this is the address of the cache line containing the virtual address
cacheptr long 0 ' address in hub ram where cache lines are stored
vmline long 0 ' cache line containing the virtual address
vmcurrent long 0 ' current selected cache line (same as vmline on a cache hit)
line long 0 ' current cache line index
set_dirty_bit long 0 ' DIRTY_BIT set on writes, clear on reads
zero long 0 ' zero constant
dstinc long 1<<9 ' increment for the destination field of an instruction
t1 long 0 ' temporary variable
t2 long 0 ' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long 0
index_count long 0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long 0 ' line size in bytes
empty_mask long (1<<EMPTY_BIT)
dirty_mask long (1<<DIRTY_BIT)
' input parameters to rd_cache_line and wr_cache_line
vmaddr long 0 ' external address
hubaddr long 0 ' hub memory address
' temporaries used by rd_cache_line and wr_cache_line
ptr long 0
count long 0 ' copy line size from shifted line size
'get_values rdlong hubaddr, hubptr ' get hub address
' rdlong ramaddr, ramptr ' get ram address
' rdlong len, lenptr ' get length
' mov err, #5 ' err=5
'get_values_ret ret
'init 'mov err, #0 ' reset err=false=good
'mov dira,zero ' tristate the pins with the cog dira
' and dira,maskP0P20P22 ' tristates all the common pins
'done 'wrlong err, errptr ' status =0=false=good, else error x
'wrlong zero, comptr ' command =0 (done)
' Pass pasm_n = 0- 7 come to this with P0-P20 and P22 tristated and returns them as this too
set137 or dira,maskP22 ' pin 22 is an output
andn outa,maskP22 ' set P22low so Y0-Y7 are all high
or dira,maskP0P20 ' pins P0-P20 are outputs
and outa,maskP0P2low ' set these 3 pins low
or outa,pasm_n ' set the 137 pins
or outa,maskP22 ' pin 22 high
set137_ret ret ' return
load161pasm ' uses vmaddr
mov count, line_size ' make a copy of line_size AND.
mov ptr, hubaddr ' hubaddr = hub page address
'or outa,maskP0P20 ' set P0-P20 high - unnecessary - jsd
or dira,maskP0P20 ' output pins 0-20
mov pasm_n,#0 ' group 0
call #set137 ' set the 137 output
and outa,maskP0P18low ' pins 0-18 set low
shr vmaddr, #1 ' schematic connects SRAM A0 to A0, not A1 - jsd
or outa,vmaddr ' output addres to 161 chips
andn outa,maskP19P20 ' clock and load low
or outa,maskP19 ' clock high
or outa,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer or dira,maskP16P20 ' so /wr and other pins definitely high
or outa,maskP16P20
mov pasm_n,#1 ' back to group 1 for memory transfer
call #set137 ' as next routine will always be group 1
or dira,maskP16P20 ' output pins 16-20
or outa,maskP16P20 ' set P16-P20 high (P0-P15 set as inputs or outputs in the calling routine)
memorytransfer_ret ret
'-----------------------------------------------
' setups needed for burst read
'-----------------------------------------------
_frqa long $1000_0000
_ctra long 4<<26 | 19 ' NCO mode on P19
_phsa long $0000_0000 ' phsa offset for adjusting clock start
_frqb long 2 ' phsb accumulates twice per edge
_ctrb long $A<<26| 19 ' Edge Accumulate mode on P19
'----------------------------------------------------------------------------------------------------
'
' rd_cache_line - read a cache line from external memory
'
' vmaddr is the external memory address to read
' hubaddr is the hub memory address to write
' line_size is the number of bytes to read
'
'----------------------------------------------------------------------------------------------------
rd_cache_line ' command T pasmramtohub
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
and dira,maskP16P31 ' set P0-P15 as inputs
andn outa,maskP16 ' memory /rd low
or outa,maskP19
mov phsa, _phsa ' init counters phsa
mov phsb, ptr ' save hub ptr to phsb
mov ctrb, _ctrb ' set ctr be mode
andn outa,maskP19 ' start counters
rdword data_16,phsb ' sync up only
mov ctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointer
mov data_16,ina ' get first data
wrword data_16,phsb ' move data to hub
djnz count,#ramtohub_loop
or outa,maskP19 ' stop clock
mov ctra, #0 ' stop counter
or outa,maskP16 ' memory /rd high
or dira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs
and dira,maskP0P20P22 ' tristates all the common pins
rd_cache_line_ret ret
'----------------------------------------------------------------------------------------------------
'
' wr_cache_line - write a cache line to external memory
'
' vmaddr is the external memory address to write
' hubaddr is the hub memory address to read
' line_size is the number of bytes to write
'
'----------------------------------------------------------------------------------------------------
wr_cache_line ' command S pasmhubtoram
call #load161pasm ' load the 161 counters with ramaddr
call #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high
or dira,maskP0P15 ' set prop pins 0-15 as outputs
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,maskP19 ' clock 161 low
or outa,maskP19 ' clock 161 high
djnz count,#hubtoram_loop ' loop this many times
and dira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret ret
pasm_n long 0 ' general purpose value
data_16 long 0 ' general purpose value
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
maskP19P20 long %00000000_00011000_00000000_00000000 ' pin 19/20
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
maskP0P20P22 long %11111111_10100000_00000000_00000000 ' for returning all group pins HiZ
fit 496
These are the changed section.
' initialize the cache lines
vmflush movd :flush, #0
mov t1, index_count
:flush mov 0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wz
if_z jmp #:wait
test vmline, #int#EXTEND_MASK wz ' test for an extended command added JPH 6-5-12
if_z jmp #extend ' added JPH 6-5-12
shr vmline, offset_width wc ' carry is now one for read and zero for write
mov set_dirty_bit, #0 ' make mask to set dirty bit on writes
muxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line index
and line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache line
wrlong hubaddr, pvmaddr ' return the address of the cache line
movs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0 ' get the cache line tag
and vmcurrent, tag_mask
cmp vmcurrent, vmline wz ' z set means there was a cache hit
if_nz call #miss ' handle a cache miss
:st or 0-0, set_dirty_bit ' set the dirty bit on writes
jmp #waitcmd ' wait for a new command
' line is the cache line index
' vmcurrent is current cache line
' vmline is new cache line
' hubaddr is the address of the cache line
miss movd mtest, line 'modified names to match SPI_Flash_Cache JPH 6-5-12
movd mst, line 'modified names to match SPI_Flash_Cache JPH 6-5-12
lck_bus test $, #0 wc ' lock no-op: clear the carry bit JPH 6-5-12
if_c jmp #lck_bus ' added for locking JPH 6-5-12
mtest test 0-0, dirty_mask wz 'modified names to match SPI_Flash_Cache JPH 6-5-12
if_z jmp #:rd ' current cache line is clean, just read new one
mov vmaddr, vmcurrent
shl vmaddr, offset_width
call #wr_cache_line ' write current cache line
:rd mov vmaddr, vmline
shl vmaddr, offset_width
call #rd_cache_line ' read new cache line
nlk_bus nop ' added for locking JPH 6-5-12
mst mov 0-0, vmline 'modified names to match SPI_Flash_Cache JPH 6-5-12
miss_ret ret
'Extended function set? JPH 6-5-12
extend mov vmaddr, vmline
shr vmaddr, #8
shr vmline, #2
and vmline, #7
add vmline, #dispatch
' mov dira, spidir ' not needed since pins should be tri-state by now?
jmp vmline
dispatch
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
jmp #waitcmd
' jmp #lock_set_handler - This is the next instruction - no need to waste a long
lock_set_handler
mov lock_id, vmaddr
mov lck_bus, lock_set
mov nlk_bus, lock_clr
jmp #waitcmd
lock_set
lockset lock_id wc
lock_clr
lockclr lock_id
lock_id long 0 ' lock id for optional bus interlock
'Insert extended function stubs here???
Where to go from here? How to test the locking mech? How to implement read-write byte-word?
*edit*
I take it the locking mechanism is working since dryPerS dropped to 1348 for XMMC. Need more testing, but I THINK I'm about ready to start porting existing spin to c!
I'm getting deeper and deeper. I hope you guys aren't sick of me yet!
One final thought. I've mentioned using other libraries, now I've found something I'm interested in and don't know WHERE to start!
http://tse3.sourceforge.net/
This project seems to contain quite a few functions I've been looking for, but I have no idea where to start. Any good wiki's or other helpful C++ docs you guys could point me to?
Unfortunately, Ted (denominator) wrote the code for the locks so I haven't actually used it. I'm not sure if he checks the forums anymore but maybe he'll reply to your question. I think the idea is that the cache driver doesn't use locks initially but a program wishing to share pins with the cache driver can pass it a lock through the set_lock_handler driver function to tell it to start using that lock when it has to access the shared pins.
Comments
The cache driver is a bit tricky. My idea is to lock the COMMON resources before accessing that resource.. I see 2 different resources, the SD card AND the SRAM. Use 1 lock or 2?
spi_flash_cache.spin seems to use the locks in a special way?
From what I can tell, this copies in the lock set and clear instructions into their "placeholders" in this code I get the basic idea, but still not sure how to compensate for this:
I'm also unsure how to pass in the lock id with a start-up parameter? Or is this unnecessary? I will work up some code for review and comments.
Please ignore SD lock comment since I realized the only time the cache will use the SD is on boot loading SD content to SRAM. The "program" will not be running, so no need to lock SD. UNLESS using SDxmmC? *Not sure I want to at this point?*
If you guys could point me in the direction of FIXING this I would appreciate it. I will look at the OTHER cache drivers to see how they differ.
Thanks guys...
Oh, btw.. what's going on with the board? I could use a logic analyzer on the LCD pins if someone has the time. If not I understand!
We use function #7 to set the lock and since that is currently the highest function code used by the driver the code was placed directly after the lock table to save one long which would normally be just a jmp to the start of the handler. That's clever coding by Ted.
Now function 7 sets the lock, and is called ???? automatically I hope?
I also noticed the SPI cache has
I found this in load161. Got rid of it.
OKAY... Getting close:
I think it's close now? Ready for comments/ Sorry about the repetitive edits but don't want to "CLOG" the thread
Now is function 7 always called on boot?
No, no, we don't want that!
Ok, well we have a finalized board design for the ILI chip. I just got an email saying the latest board is on the way which will run both displays. We must be getting close to a hardware that is stable now. So... if this new board works with both your 3.2" and my 2.4" displays, and with dual displays so we can do 480x320, then maybe we can say the hardware is working. And if that is so, well I ordered 10 boards, so maybe we can start sending out some boards and maybe the brilliant boffins here on the GCC thread can try out a board? Happy here to send a few out to those keen to help debug things. I see so many brilliant things here that are just on the verge of being implemented!
These are the changed section. Where to go from here? How to test the locking mech? How to implement read-write byte-word?
*edit*
I take it the locking mechanism is working since dryPerS dropped to 1348 for XMMC. Need more testing, but I THINK I'm about ready to start porting existing spin to c!
I'm getting deeper and deeper. I hope you guys aren't sick of me yet!
One final thought. I've mentioned using other libraries, now I've found something I'm interested in and don't know WHERE to start!
http://tse3.sourceforge.net/
This project seems to contain quite a few functions I've been looking for, but I have no idea where to start. Any good wiki's or other helpful C++ docs you guys could point me to?
http://code.google.com/p/propgcc/issues/detail?id=44