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 long0' 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 $, #0wc' lock no-op: clear the carry bitif_cjmp #lck_spi
movdira, spidir ' set the pins back so we can use them
mtest test0-0, dirty_mask wzif_zjmp #:rd ' current page is clean, just read new pagemov vmaddr, vmcurrent
shl vmaddr, offset_width
call #BWRITE ' write current page
:rd mov vmaddr, vmpage
shl vmaddr, offset_width
call #BREAD ' read new pagemovdira, #0' release the pins for other SPI clients
nlk_spi nop
mst mov0-0, vmpage
miss_ret ret
I get the basic idea, but still not sure how to compensate for this:
lck_spi test $, #0wc' 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 = 31PUBimagereturn @init_vm
DATorg$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 structurerdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bitmov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on returnadd pvmaddr, #4add t1, #4rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cacheadd t1, #4rdlong t2, t1 wzif_nzmov index_width, t2 ' override the index_width default valueadd t1, #4rdlong t2, t1 wzif_nzmov offset_width, t2 ' override the offset_width default valuemov index_count, #1shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1mov line_size, #1shl line_size, offset_width
mov t1, line_size
sub t1, #1wrlong t1, parshr line_size, #1' divide lenght by two for word-byte after response - jsdmovfrqa, _frqa ' setup NCO freqmovfrqb, _frqb ' setup EDGE freq' put external memory initialization herejmp #vmflush
fillme long0[128-fillme] ' first 128 cog locations are used for a direct mapped cache tablefit128' initialize the cache lines
vmflush movd :flush, #0mov t1, index_count
:flush mov0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
shr vmline, offset_width wc' carry is now one for read and zero for writemov set_dirty_bit, #0' make mask to set dirty bit on writesmuxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line indexand line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache linewrlong hubaddr, pvmaddr ' return the address of the cache linemovs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0' get the cache line tagand vmcurrent, tag_mask
cmp vmcurrent, vmline wz' z set means there was a cache hitif_nzcall #miss ' handle a cache miss
:st or0-0, set_dirty_bit ' set the dirty bit on writesjmp #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 $, #0wc' lock no-op: clear the carry bitif_cjmp #lck_bus
mtest test0-0, dirty_mask wzif_zjmp #:rd ' current cache line is clean, just read new onemov 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 mov0-0, vmline
miss_ret ret' pointers to mailbox entries
pvmcmd long0' on call this is the virtual address and read/write bit
pvmaddr long0' on return this is the address of the cache line containing the virtual address
cacheptr long0' address in hub ram where cache lines are stored
vmline long0' cache line containing the virtual address
vmcurrent long0' current selected cache line (same as vmline on a cache hit)
line long0' current cache line index
set_dirty_bit long0' DIRTY_BIT set on writes, clear on reads
zero long0' zero constant
dstinc long1<<9' increment for the destination field of an instruction
t1 long0' temporary variable
t2 long0' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long0
index_count long0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long0' 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 long0' external address
hubaddr long0' hub memory address' temporaries used by rd_cache_line and wr_cache_line
ptr long0
count long0' 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 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrmov 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 wcordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set lowshr vmaddr, #1' schematic connects SRAM A0 to A0, not A1 - jsdorouta,vmaddr ' output addres to 161 chipsandnouta,maskP19P20 ' clock and load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,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 long4<<26 | 19' NCO mode on P19
_phsa long$0000_0000' phsa offset for adjusting clock start
_frqb long2' 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 ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high anddira,maskP16P31 ' set P0-P15 as inputsandnouta,maskP16 ' memory /rd loworouta,maskP19
movphsa, _phsa ' init counters phsamovphsb, ptr ' save hub ptr to phsbmovctrb, _ctrb ' set ctr be modeandnouta,maskP19 ' start countersrdword data_16,phsb' sync up onlymovctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointermov data_16,ina' get first datawrword data_16,phsb' move data to hubdjnz count,#ramtohub_loop
orouta,maskP19 ' stop clockmovctra, #0' stop counterorouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,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 ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highordira,maskP0P15 ' set prop pins 0-15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,ptr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd ptr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz count,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_unlock lockclr lock_id
wr_cache_line_ret ret
lock_id long0' lock id for optional bus interlock
pasm_n long0' general purpose value
data_16 long0' 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 HiZfit496
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 $, #0wc' lock no-op: clear the carry bitif_cjmp #lck_bus
mtest test0-0, dirty_mask wzif_zjmp #:rd ' current cache line is clean, just read new onemov 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 mov0-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 = 31PUBimagereturn @init_vm
DATorg$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 structurerdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bitmov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on returnadd pvmaddr, #4add t1, #4rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cacheadd t1, #4rdlong t2, t1 wzif_nzmov index_width, t2 ' override the index_width default valueadd t1, #4rdlong t2, t1 wzif_nzmov offset_width, t2 ' override the offset_width default valuemov index_count, #1shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1mov line_size, #1shl line_size, offset_width
mov t1, line_size
sub t1, #1wrlong t1, parshr line_size, #1' divide lenght by two for word-byte after response - jsdmovfrqa, _frqa ' setup NCO freqmovfrqb, _frqb ' setup EDGE freq' put external memory initialization herejmp #vmflush
fillme long0[128-fillme] ' first 128 cog locations are used for a direct mapped cache tablefit128' initialize the cache lines
vmflush movd :flush, #0mov t1, index_count
:flush mov0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
shr vmline, offset_width wc' carry is now one for read and zero for writemov set_dirty_bit, #0' make mask to set dirty bit on writesmuxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line indexand line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache linewrlong hubaddr, pvmaddr ' return the address of the cache linemovs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0' get the cache line tagand vmcurrent, tag_mask
cmp vmcurrent, vmline wz' z set means there was a cache hitif_nzcall #miss ' handle a cache miss
:st or0-0, set_dirty_bit ' set the dirty bit on writesjmp #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 $, #0wc' lock no-op: clear the carry bitif_cjmp #lck_bus
mtest test0-0, dirty_mask wzif_zjmp #:rd ' current cache line is clean, just read new onemov 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 mov0-0, vmline
miss_ret ret' pointers to mailbox entries
pvmcmd long0' on call this is the virtual address and read/write bit
pvmaddr long0' on return this is the address of the cache line containing the virtual address
cacheptr long0' address in hub ram where cache lines are stored
vmline long0' cache line containing the virtual address
vmcurrent long0' current selected cache line (same as vmline on a cache hit)
line long0' current cache line index
set_dirty_bit long0' DIRTY_BIT set on writes, clear on reads
zero long0' zero constant
dstinc long1<<9' increment for the destination field of an instruction
t1 long0' temporary variable
t2 long0' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long0
index_count long0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long0' 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 long0' external address
hubaddr long0' hub memory address' temporaries used by rd_cache_line and wr_cache_line
ptr long0
count long0' 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 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrmov 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 wcordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set lowshr vmaddr, #1' schematic connects SRAM A0 to A0, not A1 - jsdorouta,vmaddr ' output addres to 161 chipsandnouta,maskP19P20 ' clock and load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,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 long4<<26 | 19' NCO mode on P19
_phsa long$0000_0000' phsa offset for adjusting clock start
_frqb long2' 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 ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high anddira,maskP16P31 ' set P0-P15 as inputsandnouta,maskP16 ' memory /rd loworouta,maskP19
movphsa, _phsa ' init counters phsamovphsb, ptr ' save hub ptr to phsbmovctrb, _ctrb ' set ctr be modeandnouta,maskP19 ' start countersrdword data_16,phsb' sync up onlymovctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointermov data_16,ina' get first datawrword data_16,phsb' move data to hubdjnz count,#ramtohub_loop
orouta,maskP19 ' stop clockmovctra, #0' stop counterorouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,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 ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highordira,maskP0P15 ' set prop pins 0-15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,ptr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd ptr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz count,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_unlock lockclr lock_id
wr_cache_line_ret ret
lock_id long0' lock id for optional bus interlock
pasm_n long0' general purpose value
data_16 long0' 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 HiZfit496
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 $, #0wc' lock no-op: clear the carry bitif_cjmp #lck_bus
mtest test0-0, dirty_mask wzif_zjmp #:rd ' current cache line is clean, just read new onemov 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 mov0-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, #8shr vmpage, #2and vmpage, #7add vmpage, #dispatch
movdira, spidir ' set the pins back so we can use themjmp 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 movdira, #0' release the pins for other SPI clientswrlong zero, pvmcmd
:wait rdlong vmpage, pvmcmd wzif_zjmp #:wait
test vmpage, #int#EXTEND_MASK wz' test for an extended commandif_zjmp #extend
would become
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
test vmpage, #int#EXTEND_MASK wz' test for an extended commandif_zjmp #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 = 31OBJ
int: "cache_interface"PUBimagereturn @init_vm
DATorg$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 structurerdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bitmov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on returnadd pvmaddr, #4add t1, #4rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cacheadd t1, #4rdlong t2, t1 wzif_nzmov index_width, t2 ' override the index_width default valueadd t1, #4rdlong t2, t1 wzif_nzmov offset_width, t2 ' override the offset_width default valuemov index_count, #1shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1mov line_size, #1shl line_size, offset_width
mov t1, line_size
sub t1, #1wrlong t1, parshr line_size, #1' divide lenght by two for word-byte after response - jsdmovfrqa, _frqa ' setup NCO freqmovfrqb, _frqb ' setup EDGE freq' put external memory initialization herejmp #vmflush
fillme long0[128-fillme] ' first 128 cog locations are used for a direct mapped cache tablefit128' initialize the cache lines
vmflush movd :flush, #0mov t1, index_count
:flush mov0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
test vmline, #int#EXTEND_MASK wz' test for an extended command added JPH 6-5-12if_zjmp #extend ' added JPH 6-5-12shr vmline, offset_width wc' carry is now one for read and zero for writemov set_dirty_bit, #0' make mask to set dirty bit on writesmuxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line indexand line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache linewrlong hubaddr, pvmaddr ' return the address of the cache linemovs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0' get the cache line tagand vmcurrent, tag_mask
cmp vmcurrent, vmline wz' z set means there was a cache hitif_nzcall #miss ' handle a cache miss
:st or0-0, set_dirty_bit ' set the dirty bit on writesjmp #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 $, #0wc' lock no-op: clear the carry bit JPH 6-5-12 if_cjmp #lck_bus ' added for locking JPH 6-5-12
mtest test0-0, dirty_mask wz'modified names to match SPI_Flash_Cache JPH 6-5-12 if_zjmp #:rd ' current cache line is clean, just read new onemov 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 mov0-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, #8shr vmline, #2and vmline, #7add 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 long0' lock id for optional bus interlock'Insert extended function stubs here???' pointers to mailbox entries
pvmcmd long0' on call this is the virtual address and read/write bit
pvmaddr long0' on return this is the address of the cache line containing the virtual address
cacheptr long0' address in hub ram where cache lines are stored
vmline long0' cache line containing the virtual address
vmcurrent long0' current selected cache line (same as vmline on a cache hit)
line long0' current cache line index
set_dirty_bit long0' DIRTY_BIT set on writes, clear on reads
zero long0' zero constant
dstinc long1<<9' increment for the destination field of an instruction
t1 long0' temporary variable
t2 long0' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long0
index_count long0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long0' 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 long0' external address
hubaddr long0' hub memory address' temporaries used by rd_cache_line and wr_cache_line
ptr long0
count long0' 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 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrmov 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 - jsdordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set lowshr vmaddr, #1' schematic connects SRAM A0 to A0, not A1 - jsdorouta,vmaddr ' output addres to 161 chipsandnouta,maskP19P20 ' clock and load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,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 long4<<26 | 19' NCO mode on P19
_phsa long$0000_0000' phsa offset for adjusting clock start
_frqb long2' 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 pasmramtohubcall #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high anddira,maskP16P31 ' set P0-P15 as inputsandnouta,maskP16 ' memory /rd loworouta,maskP19
movphsa, _phsa ' init counters phsamovphsb, ptr ' save hub ptr to phsbmovctrb, _ctrb ' set ctr be modeandnouta,maskP19 ' start countersrdword data_16,phsb' sync up onlymovctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointermov data_16,ina' get first datawrword data_16,phsb' move data to hubdjnz count,#ramtohub_loop
orouta,maskP19 ' stop clockmovctra, #0' stop counterorouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputsanddira,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 ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highordira,maskP0P15 ' set prop pins 0-15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,ptr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd ptr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz count,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret ret
pasm_n long0' general purpose value
data_16 long0' 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 HiZfit496
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 = 31OBJ
int: "cache_interface_joemod"PUBimagereturn @init_vm
DATorg$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 structurerdlong pvmcmd, t1 ' pvmcmd is a pointer to the virtual address and read/write bitmov pvmaddr, pvmcmd ' pvmaddr is a pointer into the cache line on returnadd pvmaddr, #4add t1, #4rdlong cacheptr, t1 ' cacheptr is the base address in hub ram of the cacheadd t1, #4rdlong t2, t1 wzif_nzmov index_width, t2 ' override the index_width default valueadd t1, #4rdlong t2, t1 wzif_nzmov offset_width, t2 ' override the offset_width default valuemov index_count, #1shl index_count, index_width
mov index_mask, index_count
sub index_mask, #1mov line_size, #1shl line_size, offset_width
mov t1, line_size
sub t1, #1wrlong t1, parshr line_size, #1' divide lenght by two for word-byte after response - jsdmovfrqa, _frqa ' setup NCO freqmovfrqb, _frqb ' setup EDGE freq' put external memory initialization herejmp #vmflush
fillme long0[128-fillme] ' first 128 cog locations are used for a direct mapped cache tablefit128' initialize the cache lines
vmflush movd :flush, #0mov t1, index_count
:flush mov0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
test vmline, #int#EXTEND_MASK wz' test for an extended command added JPH 6-5-12if_zjmp #extend ' added JPH 6-5-12shr vmline, offset_width wc' carry is now one for read and zero for writemov set_dirty_bit, #0' make mask to set dirty bit on writesmuxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line indexand line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache linewrlong hubaddr, pvmaddr ' return the address of the cache linemovs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0' get the cache line tagand vmcurrent, tag_mask
cmp vmcurrent, vmline wz' z set means there was a cache hitif_nzcall #miss ' handle a cache miss
:st or0-0, set_dirty_bit ' set the dirty bit on writesjmp #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 $, #0wc' lock no-op: clear the carry bit JPH 6-5-12 if_cjmp #lck_bus ' added for locking JPH 6-5-12
mtest test0-0, dirty_mask wz'modified names to match SPI_Flash_Cache JPH 6-5-12 if_zjmp #:rd ' current cache line is clean, just read new onemov 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 mov0-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, #8shr vmline, #2and vmline, #7add 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 long0' lock id for optional bus interlock'Insert extended function stubs here???' pointers to mailbox entries
pvmcmd long0' on call this is the virtual address and read/write bit
pvmaddr long0' on return this is the address of the cache line containing the virtual address
cacheptr long0' address in hub ram where cache lines are stored
vmline long0' cache line containing the virtual address
vmcurrent long0' current selected cache line (same as vmline on a cache hit)
line long0' current cache line index
set_dirty_bit long0' DIRTY_BIT set on writes, clear on reads
zero long0' zero constant
dstinc long1<<9' increment for the destination field of an instruction
t1 long0' temporary variable
t2 long0' temporary variable
tag_mask long !(1<<DIRTY_BIT) ' includes EMPTY_BIT
index_width long DEFAULT_INDEX_WIDTH
index_mask long0
index_count long0
offset_width long DEFAULT_OFFSET_WIDTH
line_size long0' 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 long0' external address
hubaddr long0' hub memory address' temporaries used by rd_cache_line and wr_cache_line
ptr long0
count long0' 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 ordira,maskP22 ' pin 22 is an outputandnouta,maskP22 ' set P22low so Y0-Y7 are all highordira,maskP0P20 ' pins P0-P20 are outputsandouta,maskP0P2low ' set these 3 pins loworouta,pasm_n ' set the 137 pinsorouta,maskP22 ' pin 22 high
set137_ret ret' return
load161pasm ' uses vmaddrmov 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 - jsdordira,maskP0P20 ' output pins 0-20mov pasm_n,#0' group 0call #set137 ' set the 137 outputandouta,maskP0P18low ' pins 0-18 set lowshr vmaddr, #1' schematic connects SRAM A0 to A0, not A1 - jsdorouta,vmaddr ' output addres to 161 chipsandnouta,maskP19P20 ' clock and load loworouta,maskP19 ' clock highorouta,maskP20 ' load high
load161pasm_ret ret
stop jmp #stop ' for debugging
memorytransfer ordira,maskP16P20 ' so /wr and other pins definitely highorouta,maskP16P20
mov pasm_n,#1' back to group 1 for memory transfercall #set137 ' as next routine will always be group 1ordira,maskP16P20 ' output pins 16-20orouta,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 long4<<26 | 19' NCO mode on P19
_phsa long$0000_0000' phsa offset for adjusting clock start
_frqb long2' 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 pasmramtohubcall #load161pasm ' load the 161 counters with ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 high anddira,maskP16P31 ' set P0-P15 as inputsandnouta,maskP16 ' memory /rd loworouta,maskP19
movphsa, _phsa ' init counters phsamovphsb, ptr ' save hub ptr to phsbmovctrb, _ctrb ' set ctr be modeandnouta,maskP19 ' start countersrdword data_16,phsb' sync up onlymovctra, _ctra ' enable address counter clk
ramtohub_loop ' 10MB/s read loop uses phsb for hub pointermov data_16,ina' get first datawrword data_16,phsb' move data to hubdjnz count,#ramtohub_loop
orouta,maskP19 ' stop clockmovctra, #0' stop counterorouta,maskP16 ' memory /rd high ordira,maskP0P15 ' %00000000_00000000_11111111_11111111 restore P0-P15as outputs anddira,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 ramaddrcall #memorytransfer ' set to group 1, enable P16-P20 as outputs and set P16-P20 highordira,maskP0P15 ' set prop pins 0-15 as outputs
hubtoram_loop andouta,maskP16P31 '%11111111_11111111_00000000_00000000 ' clear for output rdword data_16,ptr ' get the word from huband data_16,maskP0P15 ' mask to a word onlyorouta,data_16 ' send out the byte to P0-P15andnouta,maskP17 ' set mem write lowadd ptr,#2' increment by 2 bytes = 1 word. Put this here for small delay while writesorouta,maskP17 ' mem write highandnouta,maskP19 ' clock 161 loworouta,maskP19 ' clock 161 highdjnz count,#hubtoram_loop ' loop this many timesanddira,maskP0P20P22 ' tristates all the common pins
wr_cache_line_ret ret
pasm_n long0' general purpose value
data_16 long0' 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 HiZfit496
These are the changed section.
' initialize the cache lines
vmflush movd :flush, #0mov t1, index_count
:flush mov0-0, empty_mask
add :flush, dstinc
djnz t1, #:flush
' start the command loop
waitcmd wrlong zero, pvmcmd
:wait rdlong vmline, pvmcmd wzif_zjmp #:wait
test vmline, #int#EXTEND_MASK wz' test for an extended command added JPH 6-5-12if_zjmp #extend ' added JPH 6-5-12shr vmline, offset_width wc' carry is now one for read and zero for writemov set_dirty_bit, #0' make mask to set dirty bit on writesmuxnc set_dirty_bit, dirty_mask
mov line, vmline ' get the cache line indexand line, index_mask
mov hubaddr, line
shl hubaddr, offset_width
add hubaddr, cacheptr ' get the address of the cache linewrlong hubaddr, pvmaddr ' return the address of the cache linemovs :ld, line
movd :st, line
:ld mov vmcurrent, 0-0' get the cache line tagand vmcurrent, tag_mask
cmp vmcurrent, vmline wz' z set means there was a cache hitif_nzcall #miss ' handle a cache miss
:st or0-0, set_dirty_bit ' set the dirty bit on writesjmp #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 $, #0wc' lock no-op: clear the carry bit JPH 6-5-12 if_cjmp #lck_bus ' added for locking JPH 6-5-12
mtest test0-0, dirty_mask wz'modified names to match SPI_Flash_Cache JPH 6-5-12 if_zjmp #:rd ' current cache line is clean, just read new onemov 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 mov0-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, #8shr vmline, #2and vmline, #7add 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 long0' 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?
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.
{ 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 lockmiss 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
This does nothing new until you call :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
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.
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.
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 becomewaitcmd 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
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!
{ 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?
http://code.google.com/p/propgcc/issues/detail?id=44