spinix-hive/pfth/safe_spi.spin

107 lines
3.5 KiB
Plaintext

'******************************************************************************
' Copyright (c) 2011, 2012, Dave Hein
' See end of file for terms of use.
'******************************************************************************
{{
SPI interface routines for SD & SDHC & MMC cards
Jonathan "lonesock" Dummer
version 0.3.0 2009 July 19
Using multiblock SPI mode exclusively.
This is the "SAFE" version...uses
* 1 instruction per bit writes
* 2 instructions per bit reads
For the fsrw project:
fsrw.sf.net
}}
OBJ
sys : "sysdefs"
CON
' Rendezvoud locations
pSPI_engine_cog = sys#SPI_engine_cog
pSPI_command = sys#SPI_command
pSPI_block_index = sys#SPI_block_index
pSPI_buffer_address = sys#SPI_buffer_address
' Error codes
ERR_BLOCK_NOT_LONG_ALIGNED = -4
ERR_SPI_ENGINE_NOT_RUNNING = -999
PUB readblock( block_index, buffer_address )
if long[pSPI_engine_cog] == 0
abort ERR_SPI_ENGINE_NOT_RUNNING
if (buffer_address & 3)
abort ERR_BLOCK_NOT_LONG_ALIGNED
long[pSPI_block_index] := block_index
long[pSPI_buffer_address] := buffer_address
long[pSPI_command] := "r"
repeat while long[pSPI_command] == "r"
if long[pSPI_command] < 0
abort long[pSPI_command]
PUB writeblock( block_index, buffer_address )
if long[pSPI_engine_cog] == 0
abort ERR_SPI_ENGINE_NOT_RUNNING
if (buffer_address & 3)
abort ERR_BLOCK_NOT_LONG_ALIGNED
long[pSPI_block_index] := block_index
long[pSPI_buffer_address] := buffer_address
long[pSPI_command] := "w"
repeat while long[pSPI_command] == "w"
if long[pSPI_command] < 0
abort long[pSPI_command]
PUB get_seconds
if long[pSPI_engine_cog] == 0
abort ERR_SPI_ENGINE_NOT_RUNNING
long[pSPI_command] := "t"
repeat while long[pSPI_command] == "t"
' seconds are in SPI_block_index, remainder is in SPI_buffer_address
return long[pSPI_block_index]
PUB get_milliseconds : ms
if long[pSPI_engine_cog] == 0
abort ERR_SPI_ENGINE_NOT_RUNNING
long[pSPI_command] := "t"
repeat while long[pSPI_command] == "t"
' seconds are in SPI_block_index, remainder is in SPI_buffer_address
ms := long[pSPI_block_index] * 1000
ms += long[pSPI_buffer_address] * 1000 / clkfreq
PUB release
{{
I do not want to abort if the cog is not
running, as this is called from stop, which
is called from start/ [8^)
}}
if long[pSPI_engine_cog]
long[pSPI_command] := "z"
repeat while long[pSPI_command] == "z"
'' 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.
}}