From cb2ca239f06152304819bc0fc535e552394d32bb Mon Sep 17 00:00:00 2001 From: soypat Date: Mon, 15 Jan 2024 21:25:22 -0300 Subject: [PATCH] rename EraseBlocks to EraseSectors --- sd/blockdevice.go | 39 ++++++++++++++++++++++++++++----------- sd/card.go | 37 +++++++++++++++---------------------- sd/rustref.go | 2 +- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/sd/blockdevice.go b/sd/blockdevice.go index 7311f16..f3c6d3a 100644 --- a/sd/blockdevice.go +++ b/sd/blockdevice.go @@ -13,13 +13,19 @@ var ( var _ Card = (*SPICard)(nil) type Card interface { + // WriteBlocks writes the given data to the card, starting at the given block index. + // The data must be a multiple of the block size. WriteBlocks(data []byte, startBlockIdx int64) error + // ReadBlocks reads the given number of blocks from the card, starting at the given block index. + // The dst buffer must be a multiple of the block size. ReadBlocks(dst []byte, startBlockIdx int64) error - EraseBlocks(start, len int64) error + // EraseBlocks erases + EraseSectors(startBlockIdx, numBlocks int64) error } -func NewBlockDevice(card Card, blockSize int, numBlocks, eraseBlockSize int64) (*BlockDevice, error) { - if card == nil || blockSize <= 0 || eraseBlockSize <= 0 || numBlocks <= 0 { +// NewBlockDevice creates a new BlockDevice from a Card. +func NewBlockDevice(card Card, blockSize int, numBlocks, eraseBlockSizeInBytes int64) (*BlockDevice, error) { + if card == nil || blockSize <= 0 || eraseBlockSizeInBytes <= 0 || numBlocks <= 0 { return nil, errors.New("invalid argument(s)") } tz := bits.TrailingZeros(uint(blockSize)) @@ -27,16 +33,17 @@ func NewBlockDevice(card Card, blockSize int, numBlocks, eraseBlockSize int64) ( return nil, errors.New("blockSize must be a power of 2") } bd := &BlockDevice{ - card: card, - blockbuf: make([]byte, blockSize), - blockshift: tz, - blockmask: (1 << tz) - 1, - numblocks: numBlocks, + card: card, + blockbuf: make([]byte, blockSize), + blockshift: tz, + blockmask: (1 << tz) - 1, + numblocks: int64(numBlocks), + eraseBlockSize: eraseBlockSizeInBytes, } return bd, nil } -// BlockDevice implements tinyfs.BlockDevice interface. +// BlockDevice implements tinyfs.BlockDevice interface for an [sd.Card] type. type BlockDevice struct { card Card blockbuf []byte @@ -54,6 +61,7 @@ func (bd *BlockDevice) divideBlockSize(n int64) int64 { return n >> bd.blockshift } +// ReadAt implements [io.ReadAt] interface for an SD card. func (bd *BlockDevice) ReadAt(p []byte, off int64) (n int, err error) { if off < 0 { return 0, errNegativeOffset @@ -94,6 +102,7 @@ func (bd *BlockDevice) ReadAt(p []byte, off int64) (n int, err error) { return n, nil } +// WriteAt implements [io.WriterAt] interface for an SD card. func (bd *BlockDevice) WriteAt(p []byte, off int64) (n int, err error) { if off < 0 { return 0, errNegativeOffset @@ -140,14 +149,22 @@ func (bd *BlockDevice) WriteAt(p []byte, off int64) (n int, err error) { return n, nil } +// Size returns the number of bytes in this block device. func (bd *BlockDevice) Size() int64 { return int64(len(bd.blockbuf)) * bd.numblocks } -func (bd *BlockDevice) EraseBlocks(start, len int64) error { - return bd.card.EraseBlocks(start, len) +// EraseBlocks erases the given number of blocks. An implementation may +// transparently coalesce ranges of blocks into larger bundles if the chip +// supports this. The start and len parameters are in block numbers, use +// EraseBlockSize to map addresses to blocks. +func (bd *BlockDevice) EraseBlocks(startEraseBlockIdx, len int64) error { + return bd.card.EraseSectors(startEraseBlockIdx, len) } +// EraseBlockSize returns the smallest erasable area on this particular chip +// in bytes. This is used for the block size in EraseBlocks. +// It must be a power of two, and may be as small as 1. A typical size is 4096. func (bd *BlockDevice) EraseBlockSize() int64 { return bd.eraseBlockSize } diff --git a/sd/card.go b/sd/card.go index 0002889..1929227 100644 --- a/sd/card.go +++ b/sd/card.go @@ -13,10 +13,6 @@ var ( errBadCSDCID = errors.New("sd:bad CSD/CID in CRC or always1") errNoSDCard = errors.New("sd:no card") errCardNotSupported = errors.New("sd:card not supported") - errCmd8 = errors.New("sd:cmd8") - errCmdOCR = errors.New("sd:cmd_ocr") - errCmdBlkLen = errors.New("sd:cmd_blklen") - errAcmdAppCond = errors.New("sd:acmd_appOrCond") errWaitStartBlock = errors.New("sd:did not find start block token") errNeedBlockLenMultiple = errors.New("sd:need blocksize multiple for I/O") errWrite = errors.New("sd:write") @@ -25,28 +21,27 @@ var ( errBusyTimeout = errors.New("sd:busy card timeout") errOOB = errors.New("sd:oob block access") errNoblocks = errors.New("sd:no readable blocks") - errCmdGeneric = errors.New("sd:command error") ) -type digitalPinout func(b bool) +type digitalPinout = func(b bool) type SPICard struct { - bus drivers.SPI - cs digitalPinout - bufcmd [6]byte - kind CardKind - cid CID - csd CSD - lastCRC uint16 + bus drivers.SPI + cs digitalPinout + + timers [2]timer + numblocks int64 + timeout time.Duration + wait time.Duration + // Card Identification Register. + cid CID + // Card Specific Register. + csd CSD + bufcmd [6]byte + kind CardKind // shift to calculate blocksize, taken from CSD. blockshift uint8 - timers [2]timer - numblocks int64 - timeout time.Duration - wait time.Duration - // relative card address. - rca uint32 - lastr1 r1 + lastCRC uint16 } func NewSPICard(spi drivers.SPI, cs digitalPinout) *SPICard { @@ -93,8 +88,6 @@ func (d *SPICard) CSD() CSD { return d.csd } func (d *SPICard) yield() { time.Sleep(d.wait) } -var timeoutTimer [2]timer - type timer struct { deadline time.Time } diff --git a/sd/rustref.go b/sd/rustref.go index 5cf7bb5..f295441 100644 --- a/sd/rustref.go +++ b/sd/rustref.go @@ -189,7 +189,7 @@ func (d *SPICard) ReadBlocks(dst []byte, startBlockIdx int64) error { panic("unreachable numblocks<=0") } -func (d *SPICard) EraseBlocks(startBlock, endBlock int64) error { +func (d *SPICard) EraseSectors(startSector, numberSectors int64) error { return errors.New("sd:erase not implemented") }