mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-20 06:28:59 +00:00
implement Card interface
This commit is contained in:
+16
-13
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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.
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user