Ram Test for C3
RossH
Posts: 5,694
Hi,
Can someone with a C3 please try the enclosed binary and see if it works? - it's a simple RAM test for testing Catalina's 64kb SPI SRAM access code.
The program uses the serial port, and can be loaded by any suitable means (including the Parallax Propeller Tool or Catalina Payload).
When run, it prints Start? and waits for a y (this gives you time to start a serial terminal emulator). The first test is a trivial test which can be repeated by pressing y again. Or press n to go to the more complex test (which usually prints nothing).
If everything works ok, you should see something like:
Ross.
Can someone with a C3 please try the enclosed binary and see if it works? - it's a simple RAM test for testing Catalina's 64kb SPI SRAM access code.
The program uses the serial port, and can be loaded by any suitable means (including the Parallax Propeller Tool or Catalina Payload).
When run, it prints Start? and waits for a y (this gives you time to start a serial terminal emulator). The first test is a trivial test which can be repeated by pressing y again. Or press n to go to the more complex test (which usually prints nothing).
If everything works ok, you should see something like:
START?y A 00000000 00000000 DEADBEEF A 00000004 00000004 DEADBEEF A 00000008 00000008 DEADBEEF A 0000000C 0000000C DEADBEEF A 00000010 00000010 DEADBEEF A 00000014 00000014 DEADBEEF A 00000018 00000018 DEADBEEF A 0000001C 0000001C DEADBEEF A 00000020 00000020 DEADBEEF A 00000024 00000024 DEADBEEF A 00000028 00000028 DEADBEEF A 0000002C 0000002C DEADBEEF A 00000030 00000030 DEADBEEF A 00000034 00000034 DEADBEEF A 00000038 00000038 DEADBEEF A 0000003C 0000003C DEADBEEF AGAIN?n DONE AGAIN?Here is my XMM RAM access logic, in case anyone wants to check it:
'------------------------- C3 SPI XMM Support Routines -------------------------
'
' XMM_Activate : Activate the XMM bus.
'
XMM_Activate
muxc XMM_Flags,#1 ' save C flag
muxnz XMM_Flags,#2 ' save Z flag
andn dira,MASK ' set I/O pins as inputs while initializing
andn outa,MASK ' set all I/O pins zero ...
or outa,CS_BOTH ' ... except CS_CLR and CL_CLK
or dira,DIRN ' set pin directions
mov XMM_Addr,BIT15 ' select ...
call #XMM_BankSelect ' ... SPI SRAM bank 1
mov outx,#%0000_0001 ' set ...
call #XMM_OutByte ' ... selected SPI SRAM ...
mov outx,#%0100_0000 ' ... to sequential ...
call #XMM_OutByte ' ... mode
mov XMM_Addr,#0 ' select ...
call #XMM_BankSelect ' ... SPI SRAM bank 0
mov outx,#%0000_0001 ' set ...
call #XMM_OutByte ' ... selected SPI SRAM ...
mov outx,#%0100_0000 ' ... to sequential ...
call #XMM_OutByte ' ... mode
shr XMM_Flags,#1 wz,wc ' restore C & Z flags, fall through to ...
'
'XMM_Tristate : Give up the XMM bus. Call this to allow other cogs to use microSD etc.
' To activate XMM again, call XMM_Activate.
'
XMM_Tristate
andn outa,CS_CLR ' Reset SPI channel ...
or outa,CS_CLR ' ... to deselect SPI SRAMs
XMM_Activate_ret
XMM_Tristate_ret
ret
'
#ifdef NEED_XMM_READLONG
'
' XMM_ReadLong : Read long from XMM at address in XMM_Addr into the destination register
' set up in XMM_Dest. XMM_Activate should be called at least once before
' this routine is used.
' On entry:
' XMM_Addr : address to read (up to 16 bits)
' XMM_Dst : destination of this instruction set to destination register
' On exit:
' Destination register contains long read from XMM.
'
'
' XMM_ReadMult : Read multiple bytes in source register to XMM at address XMM_Addr.
' XMM_Activate should be called at least once before this routine is used.
' On entry:
' XMM_Addr : address to read (up to 16 bits)
' XMM_Dst : destination of this instruction set to destination register
' XMM_Len : number of bytes to read (usually 1, 2 or 4)
' On exit:
' Destination register contains bytes read from XMM.
'
XMM_ReadLong
mov XMM_Len,#4 ' read 4 bytes
XMM_ReadMult
muxc XMM_Flags,#1 ' save C flag
muxnz XMM_Flags,#2 ' save Z flag
mov outx,#%0000_0011 ' Set Command ...
call #XMM_SetCmdAddr ' ... and Address (and lower CS)
add XMM_Addr,XMM_Len ' update XMM_Addr
mov XMM_Temp,#0
:ReadLoop
call #XMM_InByte ' read next byte from SPI
and outx,#$FF
or XMM_Temp,outx
ror XMM_Temp,#8
djnz XMM_Len,#:ReadLoop ' repeat while XMM_len <> 0
XMM_Dst mov 0-0,XMM_Temp ' save the result
andn outa,CS_CLR ' reset SPI Channel ...
or outa,CS_CLR ' ... to terminate read
shr XMM_Flags,#1 wz,wc ' restore C & Z flags
XMM_ReadLong_ret
XMM_ReadMult_ret
ret
'
#endif
'
#ifdef NEED_XMM_WRITELONG
'
' XMM_WriteLong : Write long in source register to XMM at address XMM_Addr.
' On entry:
' XMM_Addr : (32-bit) address to write (up to 16 bits)
' XMM_Src : source of this instruction set to source register
' On exit:
' XMM_Addr incremented by 4.
'
'
' XMM_WriteMult : Write multiple bytes in source register to XMM at address XMM_Addr.
' XMM_Activate should be called at least once before this routine is used.
' On entry:
' XMM_Addr : address to write (up to 16 bits)
' XMM_Src : source of this instruction set to source register
' XMM_Len : number of bytes to write (usually 1, 2 or 4)
' On exit:
' XMM_Addr incremented by 4.
'
XMM_WriteLong
mov XMM_Len,#4 ' write 4 bytes
XMM_WriteMult
muxc XMM_Flags,#1 ' save C flag
muxnz XMM_Flags,#2 ' save Z flag
mov outx,#%0000_0010 ' Set Command ...
call #XMM_SetCmdAddr ' ... and Address (and lower CS)
add XMM_Addr,XMM_Len ' update XMM_Addr
XMM_Src mov XMM_Temp,0-0 ' save the value to write
:WriteLoop
mov outx,XMM_Temp
and outx,#$FF
call #XMM_OutByte ' write a byte to SPI
ror XMM_Temp,#8 ' shift next byte down to prepare
djnz XMM_Len,#:WriteLoop ' repeat while XMM_len <> 0
andn outa,CS_CLR ' reset SPI Channel ...
or outa,CS_CLR ' ... to terminate read
shr XMM_Flags,#1 wz,wc ' restore C & Z flags
XMM_WriteLong_ret
XMM_WriteMult_ret
ret
'
#endif
'
#ifdef NEED_XMM_WRITEPAGE
'
' XMM_WritePage : Write bytes from Hub RAM to XMM RAM
' On entry:
' XMM_Addr (32-bit): destination address in sram, 16-bits used
' Hub_Addr (32-bit): source address in main memory, 16-bits used
' XMM_Len (32-bit): number of bytes to write.
'
XMM_WritePage
muxc XMM_Flags,#1 ' save C flag
muxnz XMM_Flags,#2 ' save Z flag
mov outx,#%0000_0010 ' Set Command ...
call #XMM_SetCmdAddr ' ... and Address (and lower CS)
:WriteLoop
rdbyte outx,Hub_Addr ' get byte from source (Hub)
call #XMM_OutByte ' write byte to SPI
add Hub_Addr,#1 ' inc source address
add XMM_Addr,#1 ' inc dest address
djnz XMM_Len,#:WriteLoop ' repeat while XMM_len <> 0
andn outa,CS_CLR ' reset SPI Channel ...
or outa,CS_CLR ' ... to terminate read
shr XMM_Flags,#1 wz,wc ' restore C & Z flags
XMM_WritePage_ret
ret
'
#endif
'
#ifdef NEED_XMM_READPAGE
'
' XMM_ReadPage : Read bytes from XMM RAM to Hub RAM.
' On Entry:
' XMM_Addr (32-bit): source address in sram, 16-bits used
' Hub_Addr (32-bit): destination address in main memory, 16-bits used
' XMM_Len (32-bit): number of bytes to read.
'
XMM_ReadPage
muxc XMM_Flags,#1 ' save C flag
muxnz XMM_Flags,#2 ' save Z flag
mov outx,#%0000_0011 ' Set Command ...
call #XMM_SetCmdAddr ' ... and Address (and lower CS)
:ReadLoop
call #XMM_InByte ' read byte from SPI
wrbyte outx,Hub_Addr ' write byte to destination (Hub)
add Hub_Addr,#1 ' inc dest address
add XMM_Addr,#1 ' inc src address
djnz XMM_Len,#:ReadLoop ' repeat while XMM_len <> 0
andn outa,CS_CLR ' reset SPI Channel ...
or outa,CS_CLR ' ... to terminate read
shr XMM_Flags,#1 wz,wc ' restore C & Z flags
XMM_ReadPage_ret
ret
'
#endif
'
'XMM_SetCmdAddr : Set XMM command and address (and lower CS). XMM_Activate should be called
' at least once before this routine is used.
'On Entry:
' outx : Command (2 for read, 3 for write)
' XMM_Addr : address to set (up to 16 bits)
'On Exit:
' XMM_Addr : preserved
' C & Z flags destroyed!
'
XMM_SetCmdAddr
call #XMM_BankSelect ' select the SPI SRAM bank
mov XMM_Test,#8 ' command is 8 bits
rol outx,#24 ' put first bit in MSB
:CmdLoop
rol outx,#1 wc
muxc outa,IBIT
or outa,CLCK
andn outa,CLCK
djnz XMM_Test,#:CmdLoop
mov XMM_Test,#16 ' 16 address bits
rol XMM_Addr,#16 ' put first address bit in MSB
:AddrLoop
rol XMM_Addr,#1 wc
muxc outa,IBIT
or outa,CLCK
andn outa,CLCK
djnz XMM_Test,#:AddrLoop
XMM_SetCmdAddr_ret
ret
'
' XMM_OutByte - send a byte to the SPI RAM
' On entry: byte in outx (lower 8 bits)
' On exit: C flag destroyed!
'
XMM_OutByte
mov XMM_Test,#8 ' 8 bits
rol outx,#24 ' put first bit in MSB
:OutLoop
rol outx,#1 wc
muxc outa,IBIT
or outa,CLCK
andn outa,CLCK
djnz XMM_Test,#:OutLoop
XMM_OutByte_ret
ret
'
' XMM_InByte - receive a byte from SPI RAM
' On exit: outx shifted left 8 bits, new byte in lower 8 bits
' On exit: Z flag destroyed!
'
XMM_InByte
mov XMM_Test,#8 ' 8 bits
:InLoop
test OBIT,ina wz
shl outx,#1
muxnz outx,#1
or outa,CLCK
andn outa,CLCK
djnz XMM_Test,#:InLoop
XMM_InByte_ret
ret
'
' XMM_BankSelect - select appropriate SPI SRAM bank based on address
' On entry: XMM_Addr bit 15 determines SRAM bank to select (0 or 1)
' On exit: Z flag destroyed!
'
XMM_BankSelect
andn outa,CS_CLR ' Reset SPI Channel ...
or outa,CS_CLR ' ... to deselect SPI SRAMs
andn outa,CS_CLK ' toggle SPI Select Clock ...
or outa,CS_CLK ' ... to select first SRAM (bank 0)
test XMM_Addr,BIT15 wz ' if bit 15 set ...
if_nz andn outa,CS_CLK ' ... toggle SPI Select Clock ...
if_nz or outa,CS_CLK ' ... to select second SRAM (bank 1)
XMM_BankSelect_ret
ret
'
' XMM variables
'
outx long $0
'
XMM_Flags long $0
XMM_Len long $0
XMM_Temp long $0
XMM_Test long $0
XMM_Addr long $0
HUB_Addr long $0
'
'
' C3 Hardware Access:
'
MASK long (|<Common#SPI_CS_CLK) | (|<Common#SPI_CS_CLR) | (|<Common#SPI_CLK) | (|<Common#SPI_SI) | (|<Common#SPI_SO)
DIRN long (|<Common#SPI_CS_CLK) | (|<Common#SPI_CS_CLR) | (|<Common#SPI_CLK) | (|<Common#SPI_SI)
CS_CLK long (|<Common#SPI_CS_CLK)
CS_CLR long (|<Common#SPI_CS_CLR)
CS_BOTH long (|<Common#SPI_CS_CLK) | (|<Common#SPI_CS_CLR)
OBIT long (|<Common#SPI_SO)
IBIT long (|<Common#SPI_SI)
CLCK long (|<Common#SPI_CLK)
BIT15 long $8000
'
'---------------------- End of C3 SPI XMM Support Routines ---------------------
Thanks,Ross.

Comments
I tried this on my prototype C3 and unfortunately it doesn't seem to work. Here is some of the transcript from my serial terminal (bst). I deleted a lot of blank lines to save space.
I've also attached the cache driver I use with ZOG on the C3. It has the same interface as jazzed's SDRAM cache driver.
Thanks,
David
Andre'
No, I haven't ordered a C3 yet - Parallax's shipping costs doubles the price of the board, so I thought I'd wait until I could investigate alternative methods of acquiring one.
Hi David,
Thanks, I'll check my code (and compare it with yours) and re-post an amended version.
Ross.
Aha! For a start, it seems I had my CLR and INC pins for selecting the SPI channel the wrong way round! If you get a chance, try the attached executable. But don't worry too much - my own C3 should arrive in a few days, so I'll fix it then.
Ross.
Looks much better this time. I think it's working. Congratulations!
Thanks! Yes, that's working. This means I can now execute C programs out of the 64Kb of SPI SRAM on the C3 (albeit a bit slowly!). Adding in the FLASH support should be easy. I'll do that over the next week or so, so by the time my C3 arrives, Catalina should be fully functional.
I'll also have a look at using your caching driver. It will be interesting to see the performance difference.
Ross.
One alternative is to enter the order with whatever shipping method you want and put in the notes "Please use the cheapest USPS method and credit me the difference charged by the on-line order system". - Ken
It will be faster even though the backstore choices (some SPI device) are slow. Of course the same interface is also used by the SDRAM cache driver which makes things interesting. The performance is different of course between SPI RAM and SDRAM. I'm looking into to doing a C3 8MB SDRAM add on module which at first glance seems possible..
Hi Ken. The UPS cost quoted by your online ordering system was US$65, so I opted for USPS instead (~US$38 from memory). I still thought was a bit steep considering USPS themselves only charge US$13 (I checked) - but I paid it, and as far as I know the order has been processed - certainly it has already been debited from my credit card.
Happy to get a credit if you can figure out a cheaper way to post it.
Ross.
Hi David,
The code I posted above is all that is required (the error was in the pin definitions, not in that code). This is the actual code I include in the XMM kernel. Of course, this is a pretty brain-dead implementation for a serial interface - it is cribbed from my parallel SRAM code. For serial SRAM it will be at least 10 times slower - but I expect a cache will speed things up quite a bit. Of course, the overhead of interacting with the cache (which will be in another cog) will slow it back down again, but you should still see better performance (at the cost of a cog).
I will also have to add a new option to the C3 target to tell it to put read/write segments in the SPI SRAM and read-only segments in the SPI FLASH, but that's fairly simple.
Ross.
Now THAT would be nice!
Ross.
Hi Ross,
Looks like the US Postal Service changed the link for 1st class international. Our IT manager is working on getting the correct link. We are dealing with the US post office, so it could take a bit to get this fixed. For now, customers can put a note in the comments section of the order to ship 1st class international, or call our sales department and place an order.
Sorry for the trouble and we hope to have this fixed soon.
Jim Carey
Parallax Sales