implement Card interface

This commit is contained in:
soypat
2024-01-15 21:11:49 -03:00
parent e6907db19e
commit c5ff13ad23
3 changed files with 35 additions and 21 deletions
+16 -13
View File
@@ -9,20 +9,22 @@ var (
errNegativeOffset = errors.New("sd: negative offset") errNegativeOffset = errors.New("sd: negative offset")
) )
// Compile time guarantee of interface implementation.
var _ Card = (*SPICard)(nil)
type Card interface { type Card interface {
WriteBlocks(data []byte, startBlockIdx int64) error WriteBlocks(data []byte, startBlockIdx int64) error
ReadBlocks(dst []byte, startBlockIdx int64) error ReadBlocks(dst []byte, startBlockIdx int64) error
EraseBlockSize() int64
EraseBlocks(start, len int64) error EraseBlocks(start, len int64) error
} }
func NewBlockDevice(card Card, blockSize int, numBlocks int64) *BlockDevice { func NewBlockDevice(card Card, blockSize int, numBlocks, eraseBlockSize int64) (*BlockDevice, error) {
if card == nil || blockSize <= 0 { if card == nil || blockSize <= 0 || eraseBlockSize <= 0 || numBlocks <= 0 {
panic("invalid arguments") return nil, errors.New("invalid argument(s)")
} }
tz := bits.TrailingZeros(uint(blockSize)) tz := bits.TrailingZeros(uint(blockSize))
if blockSize>>tz != 1 { if blockSize>>tz != 1 {
panic("blockSize must be a power of 2") return nil, errors.New("blockSize must be a power of 2")
} }
bd := &BlockDevice{ bd := &BlockDevice{
card: card, card: card,
@@ -31,20 +33,21 @@ func NewBlockDevice(card Card, blockSize int, numBlocks int64) *BlockDevice {
blockmask: (1 << tz) - 1, blockmask: (1 << tz) - 1,
numblocks: numBlocks, numblocks: numBlocks,
} }
return bd return bd, nil
} }
// BlockDevice implements tinyfs.BlockDevice interface. // BlockDevice implements tinyfs.BlockDevice interface.
type BlockDevice struct { type BlockDevice struct {
card Card card Card
blockbuf []byte blockbuf []byte
blockshift int blockshift int
blockmask int64 blockmask int64
numblocks int64 numblocks int64
eraseBlockSize int64
} }
func (bd *BlockDevice) moduloBlockSize(n int64) int64 { func (bd *BlockDevice) moduloBlockSize(n int64) int64 {
return n &^ bd.blockmask return n & bd.blockmask
} }
func (bd *BlockDevice) divideBlockSize(n int64) int64 { func (bd *BlockDevice) divideBlockSize(n int64) int64 {
@@ -146,5 +149,5 @@ func (bd *BlockDevice) EraseBlocks(start, len int64) error {
} }
func (bd *BlockDevice) EraseBlockSize() int64 { func (bd *BlockDevice) EraseBlockSize() int64 {
return bd.card.EraseBlockSize() return bd.eraseBlockSize
} }
-2
View File
@@ -34,8 +34,6 @@ type SPICard struct {
bus drivers.SPI bus drivers.SPI
cs digitalPinout cs digitalPinout
bufcmd [6]byte bufcmd [6]byte
buf [512]byte
bufTok [1]byte
kind CardKind kind CardKind
cid CID cid CID
csd CSD csd CSD
+19 -6
View File
@@ -189,6 +189,10 @@ func (d *SPICard) ReadBlocks(dst []byte, startBlockIdx int64) error {
panic("unreachable numblocks<=0") panic("unreachable numblocks<=0")
} }
func (d *SPICard) EraseBlocks(startBlock, endBlock int64) error {
return errors.New("sd:erase not implemented")
}
// WriteBlocks writes to sdcard from a buffer multiple of 512 bytes from src starting at block `startBlockIdx`. // WriteBlocks writes to sdcard from a buffer multiple of 512 bytes from src starting at block `startBlockIdx`.
func (d *SPICard) WriteBlocks(data []byte, startBlockIdx int64) error { func (d *SPICard) WriteBlocks(data []byte, startBlockIdx int64) error {
numblocks, err := d.checkBounds(startBlockIdx, len(data)) numblocks, err := d.checkBounds(startBlockIdx, len(data))
@@ -274,20 +278,26 @@ func (d *SPICard) checkBounds(startBlockIdx int64, datalen int) (numblocks int,
return numblocks, nil return numblocks, nil
} }
func (d *SPICard) read_cid() (csd CID, err error) { func (d *SPICard) read_cid() (cid CID, err error) {
err = d.cmd_read(cmdSendCID, 0, d.buf[:16]) // CMD10. err = d.cmd_read(cmdSendCID, 0, d.cid.data[:16]) // CMD10.
if err != nil { if err != nil {
return csd, err return cid, err
} }
return DecodeCID(d.buf[:16]) if !d.cid.IsValid() {
return cid, errBadCSDCID
}
return d.cid, nil
} }
func (d *SPICard) read_csd() (csd CSD, err error) { func (d *SPICard) read_csd() (csd CSD, err error) {
err = d.cmd_read(cmdSendCSD, 0, d.buf[:16]) // CMD9. err = d.cmd_read(cmdSendCSD, 0, d.csd.data[:16]) // CMD9.
if err != nil { if err != nil {
return csd, err return csd, err
} }
return DecodeCSD(d.buf[:16]) if !d.csd.IsValid() {
return csd, errBadCSDCID
}
return d.csd, nil
} }
func (d *SPICard) cmd_read(cmd command, args uint32, buf []byte) error { func (d *SPICard) cmd_read(cmd command, args uint32, buf []byte) error {
@@ -322,6 +332,9 @@ func (d *SPICard) card_command(cmd command, args uint32) (uint8, error) {
buf[5] = crc7noshift(buf[:5]) | 1 // CRC and end bit which is always 1. buf[5] = crc7noshift(buf[:5]) | 1 // CRC and end bit which is always 1.
err = d.bus.Tx(buf, nil) err = d.bus.Tx(buf, nil)
if err != nil {
return 0, err
}
if cmd == cmdStopTransmission { if cmd == cmdStopTransmission {
d.receive() // skip stuff byte for stop read. d.receive() // skip stuff byte for stop read.
} }