mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-18 13:43:58 +00:00
remove some of API
This commit is contained in:
+27
-9
@@ -4,7 +4,6 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
"math"
|
||||||
"runtime"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
@@ -43,13 +42,29 @@ type SPICard struct {
|
|||||||
timers [2]timer
|
timers [2]timer
|
||||||
numblocks int64
|
numblocks int64
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
wait time.Duration
|
||||||
// relative card address.
|
// relative card address.
|
||||||
rca uint32
|
rca uint32
|
||||||
lastr1 r1
|
lastr1 r1
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSPICard(spi drivers.SPI, cs digitalPinout) *SPICard {
|
func NewSPICard(spi drivers.SPI, cs digitalPinout) *SPICard {
|
||||||
return &SPICard{bus: spi, cs: cs, timeout: 300 * time.Millisecond}
|
const defaultTimeout = 300 * time.Millisecond
|
||||||
|
s := &SPICard{
|
||||||
|
bus: spi,
|
||||||
|
cs: cs,
|
||||||
|
}
|
||||||
|
s.setTimeout(defaultTimeout)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// setTimeout sets the timeout for all operations and the wait time between each yield during busy spins.
|
||||||
|
func (c *SPICard) setTimeout(timeout time.Duration) {
|
||||||
|
if timeout <= 0 {
|
||||||
|
panic("timeout must be positive")
|
||||||
|
}
|
||||||
|
c.timeout = timeout
|
||||||
|
c.wait = timeout / 512
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *SPICard) csEnable(b bool) { c.cs(!b) }
|
func (c *SPICard) csEnable(b bool) { c.cs(!b) }
|
||||||
@@ -61,7 +76,7 @@ func (c *SPICard) LastR1() r1 { return c.lastr1 }
|
|||||||
// Init initializes the SD card. This routine should be performed with a SPI clock
|
// Init initializes the SD card. This routine should be performed with a SPI clock
|
||||||
// speed of around 100..400kHz. One may increase the clock speed after initialization.
|
// speed of around 100..400kHz. One may increase the clock speed after initialization.
|
||||||
func (d *SPICard) Init() error {
|
func (d *SPICard) Init() error {
|
||||||
dummy := d.buf[:]
|
dummy := d.buf[:512]
|
||||||
for i := range dummy {
|
for i := range dummy {
|
||||||
dummy[i] = 0xFF
|
dummy[i] = 0xFF
|
||||||
}
|
}
|
||||||
@@ -343,8 +358,8 @@ func (d *SPICard) appCmd(cmd appcommand, arg uint32) (response1, error) {
|
|||||||
return d.cmd(command(cmd), arg, 0xFF)
|
return d.cmd(command(cmd), arg, 0xFF)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *SPICard) cmdEnsure0Status(cmd command, arg uint32, crc byte) error {
|
func (d *SPICard) cmdEnsure0Status(cmd command, arg uint32, precalcCRC byte) error {
|
||||||
status, err := d.cmd(cmd, arg, crc)
|
status, err := d.cmd(cmd, arg, precalcCRC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -354,7 +369,7 @@ func (d *SPICard) cmdEnsure0Status(cmd command, arg uint32, crc byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *SPICard) cmd(cmd command, arg uint32, precalculatedCRC byte) (response1, error) {
|
func (d *SPICard) cmd(cmd command, arg uint32, precalcCRC byte) (response1, error) {
|
||||||
const transmitterBit = 1 << 6
|
const transmitterBit = 1 << 6
|
||||||
if cmd >= transmitterBit {
|
if cmd >= transmitterBit {
|
||||||
panic("invalid SD command")
|
panic("invalid SD command")
|
||||||
@@ -374,8 +389,8 @@ func (d *SPICard) cmd(cmd command, arg uint32, precalculatedCRC byte) (response1
|
|||||||
|
|
||||||
buf[0] = transmitterBit | byte(cmd)
|
buf[0] = transmitterBit | byte(cmd)
|
||||||
binary.BigEndian.PutUint32(buf[1:5], arg)
|
binary.BigEndian.PutUint32(buf[1:5], arg)
|
||||||
if precalculatedCRC != 0 {
|
if precalcCRC != 0 {
|
||||||
buf[5] = precalculatedCRC
|
buf[5] = precalcCRC
|
||||||
} else {
|
} else {
|
||||||
// CRC and end bit which is always 1.
|
// CRC and end bit which is always 1.
|
||||||
buf[5] = crc7noshift(buf[:5]) | 1
|
buf[5] = crc7noshift(buf[:5]) | 1
|
||||||
@@ -399,7 +414,7 @@ func (d *SPICard) cmd(cmd command, arg uint32, precalculatedCRC byte) (response1
|
|||||||
} else if tm.expired() {
|
} else if tm.expired() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
runtime.Gosched()
|
d.yield()
|
||||||
}
|
}
|
||||||
|
|
||||||
d.csEnable(false)
|
d.csEnable(false)
|
||||||
@@ -407,6 +422,8 @@ func (d *SPICard) cmd(cmd command, arg uint32, precalculatedCRC byte) (response1
|
|||||||
return 0xFF, errCmdGeneric
|
return 0xFF, errCmdGeneric
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *SPICard) yield() { time.Sleep(d.wait) }
|
||||||
|
|
||||||
func (d *SPICard) waitNotBusy(timeout time.Duration) error {
|
func (d *SPICard) waitNotBusy(timeout time.Duration) error {
|
||||||
if _, ok := d.waitToken(timeout, 0xff); ok {
|
if _, ok := d.waitToken(timeout, 0xff); ok {
|
||||||
return nil
|
return nil
|
||||||
@@ -437,6 +454,7 @@ func (d *SPICard) waitToken(timeout time.Duration, tok byte) (byte, bool) {
|
|||||||
} else if tm.expired() {
|
} else if tm.expired() {
|
||||||
return received, false
|
return received, false
|
||||||
}
|
}
|
||||||
|
d.yield()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-3
@@ -60,17 +60,17 @@ func TestCRC7(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmdTests := []struct {
|
cmdTests := []struct {
|
||||||
cmd byte
|
cmd command
|
||||||
arg uint32
|
arg uint32
|
||||||
wantCRC uint8
|
wantCRC uint8
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
cmd: CMD0_GO_IDLE_STATE,
|
cmd: cmdGoIdleState,
|
||||||
arg: 0,
|
arg: 0,
|
||||||
wantCRC: 0x95,
|
wantCRC: 0x95,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cmd: CMD8_SEND_IF_COND,
|
cmd: cmdSendIfCond,
|
||||||
arg: 0x1AA,
|
arg: 0x1AA,
|
||||||
wantCRC: 0x87,
|
wantCRC: 0x87,
|
||||||
},
|
},
|
||||||
@@ -84,3 +84,12 @@ func TestCRC7(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func putCmd(dst []byte, cmd command, arg uint32) {
|
||||||
|
dst[0] = byte(cmd) | (1 << 6)
|
||||||
|
dst[1] = byte(arg >> 24)
|
||||||
|
dst[2] = byte(arg >> 16)
|
||||||
|
dst[3] = byte(arg >> 8)
|
||||||
|
dst[4] = byte(arg)
|
||||||
|
dst[5] = crc7noshift(dst[:5]) | 1 // Stop bit added.
|
||||||
|
}
|
||||||
|
|||||||
+14
-8
@@ -88,14 +88,17 @@ type CSD struct {
|
|||||||
data [16]byte
|
data [16]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CSDv1 is the Card Specific Data register for V1 devices. See [CSD] for more info.
|
||||||
type CSDv1 struct {
|
type CSDv1 struct {
|
||||||
CSD
|
CSD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CSDv2 is the Card Specific Data register for V2 devices. See [CSD] for more info.
|
||||||
type CSDv2 struct {
|
type CSDv2 struct {
|
||||||
CSD
|
CSD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeCSD decodes the CSD from a 16-byte slice.
|
||||||
func DecodeCSD(b []byte) (CSD, error) {
|
func DecodeCSD(b []byte) (CSD, error) {
|
||||||
if len(b) < 16 {
|
if len(b) < 16 {
|
||||||
return CSD{}, io.ErrShortBuffer
|
return CSD{}, io.ErrShortBuffer
|
||||||
@@ -108,18 +111,22 @@ func DecodeCSD(b []byte) (CSD, error) {
|
|||||||
return csd, nil
|
return csd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CSDStructure returns the version of the CSD structure.
|
// csdStructure returns the version of the CSD structure.
|
||||||
func (c *CSD) CSDStructure() uint8 { return c.data[0] >> 6 }
|
func (c *CSD) csdStructure() uint8 { return c.data[0] >> 6 }
|
||||||
|
|
||||||
|
// Version returns the version of the CSD structure. Effectively returns 1+CSDStructure.
|
||||||
|
func (c *CSD) Version() uint8 { return 1 + c.csdStructure() }
|
||||||
|
|
||||||
|
// MustV1 returns the CSD as a CSDv1. Panics if the CSD is not version 1.0.
|
||||||
func (c CSD) MustV1() CSDv1 {
|
func (c CSD) MustV1() CSDv1 {
|
||||||
if c.CSDStructure() != 0 {
|
if c.csdStructure() != 0 {
|
||||||
panic("CSD is not version 1.0")
|
panic("CSD is not version 1.0")
|
||||||
}
|
}
|
||||||
return CSDv1{CSD: c}
|
return CSDv1{CSD: c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c CSD) MustV2() CSDv2 {
|
func (c CSD) MustV2() CSDv2 {
|
||||||
if c.CSDStructure() != 1 {
|
if c.csdStructure() != 1 {
|
||||||
panic("CSD is not version 2.0")
|
panic("CSD is not version 2.0")
|
||||||
}
|
}
|
||||||
return CSDv2{CSD: c}
|
return CSDv2{CSD: c}
|
||||||
@@ -215,7 +222,7 @@ func (c *CSD) IsCopy() bool { return c.data[14]&(1<<6) != 0 }
|
|||||||
func (c *CSD) FileFormatGroup() bool { return c.data[14]&(1<<7) != 0 }
|
func (c *CSD) FileFormatGroup() bool { return c.data[14]&(1<<7) != 0 }
|
||||||
|
|
||||||
func (c *CSD) DeviceCapacity() (size uint64) {
|
func (c *CSD) DeviceCapacity() (size uint64) {
|
||||||
switch c.CSDStructure() {
|
switch c.csdStructure() {
|
||||||
case 0:
|
case 0:
|
||||||
v1 := c.MustV1()
|
v1 := c.MustV1()
|
||||||
size = uint64(v1.DeviceCapacity())
|
size = uint64(v1.DeviceCapacity())
|
||||||
@@ -283,7 +290,7 @@ func (c *CSDv1) VddWriteCurrent() (min, max uint8) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CSD) String() string {
|
func (c *CSD) String() string {
|
||||||
version := c.CSDStructure() + 1
|
version := c.csdStructure() + 1
|
||||||
if version > 2 {
|
if version > 2 {
|
||||||
return "<unsupported CSD version>"
|
return "<unsupported CSD version>"
|
||||||
}
|
}
|
||||||
@@ -298,7 +305,7 @@ func (c *CSDv1) String() string { return c.CSD.String() }
|
|||||||
func (c *CSDv2) String() string { return c.CSD.String() }
|
func (c *CSDv2) String() string { return c.CSD.String() }
|
||||||
|
|
||||||
func (c *CSD) appendf(b []byte, delim byte) []byte {
|
func (c *CSD) appendf(b []byte, delim byte) []byte {
|
||||||
b = appendnum(b, "Version", uint64(c.CSDStructure()+1), delim)
|
b = appendnum(b, "Version", uint64(c.Version()), delim)
|
||||||
b = appendnum(b, "Capacity(bytes)", c.DeviceCapacity(), delim)
|
b = appendnum(b, "Capacity(bytes)", c.DeviceCapacity(), delim)
|
||||||
b = appendnum(b, "TimeAccess_ns", uint64(c.TAAC().AccessTime()), delim)
|
b = appendnum(b, "TimeAccess_ns", uint64(c.TAAC().AccessTime()), delim)
|
||||||
b = appendnum(b, "NSAC", uint64(c.NSAC()), delim)
|
b = appendnum(b, "NSAC", uint64(c.NSAC()), delim)
|
||||||
@@ -466,7 +473,6 @@ func b2u8(b bool) uint8 {
|
|||||||
// CRC16 computes the CRC16 checksum for a given payload using the CRC-16-CCITT polynomial.
|
// CRC16 computes the CRC16 checksum for a given payload using the CRC-16-CCITT polynomial.
|
||||||
func CRC16(buf []byte) (crc uint16) {
|
func CRC16(buf []byte) (crc uint16) {
|
||||||
const poly uint16 = 0x1021 // Generator polynomial G(x) = x^16 + x^12 + x^5 + 1
|
const poly uint16 = 0x1021 // Generator polynomial G(x) = x^16 + x^12 + x^5 + 1
|
||||||
|
|
||||||
for _, b := range buf {
|
for _, b := range buf {
|
||||||
crc ^= (uint16(b) << 8) // Shift byte into MSB of crc
|
crc ^= (uint16(b) << 8) // Shift byte into MSB of crc
|
||||||
for i := 0; i < 8; i++ { // Process each bit
|
for i := 0; i < 8; i++ { // Process each bit
|
||||||
|
|||||||
Reference in New Issue
Block a user