mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-09-02 12:59:01 +00:00
rename commands
This commit is contained in:
+53
-51
@@ -71,7 +71,7 @@ func (d *SPICard) Init() error {
|
|||||||
tm := d.timers[0].setTimeout(2 * time.Second)
|
tm := d.timers[0].setTimeout(2 * time.Second)
|
||||||
for !tm.expired() {
|
for !tm.expired() {
|
||||||
// Wait up to 2 seconds to be the same as the Arduino
|
// Wait up to 2 seconds to be the same as the Arduino
|
||||||
result, err := d.cmd(CMD0_GO_IDLE_STATE, 0, 0x95)
|
result, err := d.cmd(cmdGoIdleState, 0, 0x95)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -85,39 +85,38 @@ func (d *SPICard) Init() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CMD8: determine card version
|
// CMD8: determine card version
|
||||||
r1, err := d.cmd(CMD8_SEND_IF_COND, 0x01AA, 0x87)
|
r1, err := d.cmd(cmdSendIfCond, 0x01AA, 0x87)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if r1.IllegalCmdError() {
|
if r1.IllegalCmdError() {
|
||||||
d.kind = TypeSD1
|
d.kind = TypeSD1
|
||||||
return errCardNotSupported
|
return errCardNotSupported
|
||||||
} else {
|
|
||||||
// r7 response
|
|
||||||
status := byte(0)
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
var err error
|
|
||||||
status, err = d.bus.Transfer(0xFF)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (status & 0x0F) != 0x01 {
|
|
||||||
return makeResponseError(response1(status))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 3; i < 4; i++ {
|
|
||||||
var err error
|
|
||||||
status, err = d.bus.Transfer(0xFF)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if status != 0xAA {
|
|
||||||
return makeResponseError(response1(status))
|
|
||||||
}
|
|
||||||
d.kind = TypeSD2
|
|
||||||
}
|
}
|
||||||
|
// r7 response
|
||||||
|
status := byte(0)
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
var err error
|
||||||
|
status, err = d.bus.Transfer(0xFF)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status & 0x0F) != 0x01 {
|
||||||
|
return makeResponseError(response1(status))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 3; i < 4; i++ {
|
||||||
|
var err error
|
||||||
|
status, err = d.bus.Transfer(0xFF)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if status != 0xAA {
|
||||||
|
return makeResponseError(response1(status))
|
||||||
|
}
|
||||||
|
d.kind = TypeSD2
|
||||||
|
|
||||||
// initialize card and send host supports SDHC if SD2
|
// initialize card and send host supports SDHC if SD2
|
||||||
arg := uint32(0)
|
arg := uint32(0)
|
||||||
@@ -129,7 +128,7 @@ func (d *SPICard) Init() error {
|
|||||||
ok = false
|
ok = false
|
||||||
tm = tm.setTimeout(2 * time.Second)
|
tm = tm.setTimeout(2 * time.Second)
|
||||||
for !tm.expired() {
|
for !tm.expired() {
|
||||||
r1, err = d.appCmd(ACMD41_SD_APP_OP_COND, arg)
|
r1, err = d.appCmd(acmdSD_APP_OP_COND, arg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -143,7 +142,7 @@ func (d *SPICard) Init() error {
|
|||||||
|
|
||||||
// if SD2 read OCR register to check for SDHC card
|
// if SD2 read OCR register to check for SDHC card
|
||||||
if d.kind == TypeSD2 {
|
if d.kind == TypeSD2 {
|
||||||
err := d.cmdEnsure0Status(CMD58_READ_OCR, 0, 0xFF)
|
err := d.cmdEnsure0Status(cmdReadOCR, 0, 0xFF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -160,7 +159,7 @@ func (d *SPICard) Init() error {
|
|||||||
d.bus.Transfer(0xFF)
|
d.bus.Transfer(0xFF)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = d.cmdEnsure0Status(CMD16_SET_BLOCKLEN, 0x0200, 0xff)
|
err = d.cmdEnsure0Status(cmdSetBlocklen, 0x0200, 0xff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -200,7 +199,8 @@ func (d *SPICard) ReadBlock(block int64, dst []byte) error {
|
|||||||
if d.kind != TypeSDHC {
|
if d.kind != TypeSDHC {
|
||||||
block <<= 9
|
block <<= 9
|
||||||
}
|
}
|
||||||
err := d.cmdEnsure0Status(CMD17_READ_SINGLE_BLOCK, uint32(block), 0xFF)
|
|
||||||
|
err := d.cmdEnsure0Status(cmdReadSingleBlock, uint32(block), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -234,7 +234,7 @@ func (d *SPICard) WriteBlock(block int64, src []byte) error {
|
|||||||
if d.kind != TypeSDHC {
|
if d.kind != TypeSDHC {
|
||||||
block <<= 9
|
block <<= 9
|
||||||
}
|
}
|
||||||
err := d.cmdEnsure0Status(CMD24_WRITE_BLOCK, uint32(block), 0xFF)
|
err := d.cmdEnsure0Status(cmdWriteBlock, uint32(block), 0xFF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -278,7 +278,7 @@ func (d *SPICard) CSD() CSD { return d.csd }
|
|||||||
|
|
||||||
func (d *SPICard) readCID() (CID, error) {
|
func (d *SPICard) readCID() (CID, error) {
|
||||||
buf := d.buf[len(d.buf)-16:]
|
buf := d.buf[len(d.buf)-16:]
|
||||||
if err := d.readRegister(CMD10_SEND_CID, buf); err != nil {
|
if err := d.readRegister(cmdSendCID, buf); err != nil {
|
||||||
return CID{}, err
|
return CID{}, err
|
||||||
}
|
}
|
||||||
return DecodeCID(buf)
|
return DecodeCID(buf)
|
||||||
@@ -286,13 +286,13 @@ func (d *SPICard) readCID() (CID, error) {
|
|||||||
|
|
||||||
func (d *SPICard) readCSD() (CSD, error) {
|
func (d *SPICard) readCSD() (CSD, error) {
|
||||||
buf := d.buf[len(d.buf)-16:]
|
buf := d.buf[len(d.buf)-16:]
|
||||||
if err := d.readRegister(CMD9_SEND_CSD, buf); err != nil {
|
if err := d.readRegister(cmdSendCSD, buf); err != nil {
|
||||||
return CSD{}, err
|
return CSD{}, err
|
||||||
}
|
}
|
||||||
return DecodeCSD(buf)
|
return DecodeCSD(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *SPICard) readRegister(cmd uint8, dst []byte) error {
|
func (d *SPICard) readRegister(cmd command, dst []byte) error {
|
||||||
err := d.cmdEnsure0Status(cmd, 0, 0xFF)
|
err := d.cmdEnsure0Status(cmd, 0, 0xFF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -315,15 +315,15 @@ func (d *SPICard) readRegister(cmd uint8, dst []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *SPICard) appCmd(cmd byte, arg uint32) (response1, error) {
|
func (d *SPICard) appCmd(cmd appcommand, arg uint32) (response1, error) {
|
||||||
status, err := d.cmd(CMD55_APP_CMD, 0, 0xFF)
|
status, err := d.cmd(cmdAppCmd, 0, 0xFF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status, err
|
return status, err
|
||||||
}
|
}
|
||||||
return d.cmd(cmd, arg, 0xFF)
|
return d.cmd(command(cmd), arg, 0xFF)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *SPICard) cmdEnsure0Status(cmd byte, arg uint32, crc byte) error {
|
func (d *SPICard) cmdEnsure0Status(cmd command, arg uint32, crc byte) error {
|
||||||
status, err := d.cmd(cmd, arg, crc)
|
status, err := d.cmd(cmd, arg, crc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -334,17 +334,10 @@ func (d *SPICard) cmdEnsure0Status(cmd byte, arg uint32, crc byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func putCmd(dst []byte, cmd byte, arg uint32) {
|
func (d *SPICard) cmd(cmd command, arg uint32, precalculatedCRC byte) (response1, error) {
|
||||||
if len(dst) < 6 {
|
if cmd >= 1<<6 {
|
||||||
panic("bad buflength")
|
panic("invalid SD command")
|
||||||
}
|
}
|
||||||
dst[0] = 0x40 | cmd
|
|
||||||
binary.BigEndian.PutUint32(dst[1:5], arg)
|
|
||||||
dst[5] = CRC7(dst[:5])<<1 | 1 // CRC and stop bit.
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0100000000000000000000000000000000000000
|
|
||||||
func (d *SPICard) cmd(cmd byte, arg uint32, crc byte) (response1, error) {
|
|
||||||
d.csEnable(true)
|
d.csEnable(true)
|
||||||
|
|
||||||
if cmd != 12 {
|
if cmd != 12 {
|
||||||
@@ -353,8 +346,17 @@ func (d *SPICard) cmd(cmd byte, arg uint32, crc byte) (response1, error) {
|
|||||||
|
|
||||||
// create and send the command
|
// create and send the command
|
||||||
buf := d.bufcmd[:6]
|
buf := d.bufcmd[:6]
|
||||||
putCmd(buf, cmd, arg)
|
// Start bit is always zero; transmitter bit is one since we are Host.
|
||||||
buf[5] = crc
|
const transmitterBit = 1 << 6
|
||||||
|
buf[0] = transmitterBit | byte(cmd)
|
||||||
|
binary.BigEndian.PutUint32(buf[1:5], arg)
|
||||||
|
if precalculatedCRC != 0 {
|
||||||
|
buf[5] = precalculatedCRC
|
||||||
|
} else {
|
||||||
|
// CRC and end bit which is always 1.
|
||||||
|
buf[5] = crc7noshift(buf[:5]) | 1
|
||||||
|
}
|
||||||
|
|
||||||
err := d.bus.Tx(buf, nil)
|
err := d.bus.Tx(buf, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|||||||
+60
-49
@@ -347,55 +347,62 @@ func upToNull(buf []byte) []byte {
|
|||||||
return buf[:nullIdx]
|
return buf[:nullIdx]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
command byte
|
||||||
|
appcommand byte
|
||||||
|
)
|
||||||
|
|
||||||
|
// SD commands and application commands.
|
||||||
const (
|
const (
|
||||||
CMD0_GO_IDLE_STATE = 0
|
cmdGoIdleState command = 0
|
||||||
CMD1_SEND_OP_CND = 1
|
cmdSendOpCnd command = 1
|
||||||
CMD2_ALL_SEND_CID = 2
|
cmdAllSendCID command = 2
|
||||||
CMD3_SEND_RELATIVE_ADDR = 3
|
cmdSendRelativeAddr command = 3
|
||||||
CMD4_SET_DSR = 4
|
cmdSetDSR command = 4
|
||||||
CMD6_SWITCH_FUNC = 6
|
cmdSwitchFunc command = 6
|
||||||
CMD7_SELECT_DESELECT_CARD = 7
|
cmdSelectDeselectCard command = 7
|
||||||
CMD8_SEND_IF_COND = 8
|
cmdSendIfCond command = 8
|
||||||
CMD9_SEND_CSD = 9
|
cmdSendCSD command = 9
|
||||||
CMD10_SEND_CID = 10
|
cmdSendCID command = 10
|
||||||
CMD12_STOP_TRANSMISSION = 12
|
cmdStopTransmission command = 12
|
||||||
CMD13_SEND_STATUS = 13
|
cmdSendStatus command = 13
|
||||||
CMD15_GO_INACTIVE_STATE = 15
|
cmdGoInactiveState command = 15
|
||||||
CMD16_SET_BLOCKLEN = 16
|
cmdSetBlocklen command = 16
|
||||||
CMD17_READ_SINGLE_BLOCK = 17
|
cmdReadSingleBlock command = 17
|
||||||
CMD18_READ_MULTIPLE_BLOCK = 18
|
cmdReadMultipleBlock command = 18
|
||||||
CMD24_WRITE_BLOCK = 24
|
cmdWriteBlock command = 24
|
||||||
CMD25_WRITE_MULTIPLE_BLOCK = 25
|
cmdWriteMultipleBlock command = 25
|
||||||
CMD27_PROGRAM_CSD = 27
|
cmdProgramCSD command = 27
|
||||||
CMD28_SET_WRITE_PROT = 28
|
cmdSetWriteProt command = 28
|
||||||
CMD29_CLR_WRITE_PROT = 29
|
cmdClrWriteProt command = 29
|
||||||
CMD30_SEND_WRITE_PROT = 30
|
cmdSendWriteProt command = 30
|
||||||
CMD32_ERASE_WR_BLK_START_ADDR = 32
|
cmdEraseWrBlkStartAddr command = 32
|
||||||
CMD33_ERASE_WR_BLK_END_ADDR = 33
|
cmdEraseWrBlkEndAddr command = 33
|
||||||
CMD38_ERASE = 38
|
cmdErase command = 38
|
||||||
CMD42_LOCK_UNLOCK = 42
|
cmdLockUnlock command = 42
|
||||||
CMD55_APP_CMD = 55
|
cmdAppCmd command = 55
|
||||||
CMD56_GEN_CMD = 56
|
cmdGenCmd command = 56
|
||||||
CMD58_READ_OCR = 58
|
cmdReadOCR command = 58
|
||||||
CMD59_CRC_ON_OFF = 59
|
cmdCRCOnOff command = 59
|
||||||
ACMD6_SET_BUS_WIDTH = 6
|
|
||||||
ACMD13_SD_STATUS = 13
|
acmdSET_BUS_WIDTH appcommand = 6
|
||||||
ACMD22_SEND_NUM_WR_BLOCKS = 22
|
acmdSD_STATUS appcommand = 13
|
||||||
ACMD23_SET_WR_BLK_ERASE_COUNT = 23
|
acmdSEND_NUM_WR_BLOCKS appcommand = 22
|
||||||
ACMD41_SD_APP_OP_COND = 41
|
acmdSET_WR_BLK_ERASE_COUNT appcommand = 23
|
||||||
ACMD42_SET_CLR_CARD_DETECT = 42
|
acmdSD_APP_OP_COND appcommand = 41
|
||||||
ACMD51_SEND_SCR = 51
|
acmdSET_CLR_CARD_DETECT appcommand = 42
|
||||||
ACMD18_SECURE_READ_MULTI_BLOCK = 18
|
acmdSEND_SCR appcommand = 51
|
||||||
ACMD25_SECURE_WRITE_MULTI_BLOCK = 25
|
acmdSECURE_READ_MULTI_BLOCK appcommand = 18
|
||||||
ACMD26_SECURE_WRITE_MKB = 26
|
acmdSECURE_WRITE_MULTI_BLOCK appcommand = 25
|
||||||
ACMD38_SECURE_ERASE = 38
|
acmdSECURE_WRITE_MKB appcommand = 26
|
||||||
ACMD43_GET_MKB = 43
|
acmdSECURE_ERASE appcommand = 38
|
||||||
ACMD44_GET_MID = 44
|
acmdGET_MKB appcommand = 43
|
||||||
ACMD45_SET_CER_RN1 = 45
|
acmdGET_MID appcommand = 44
|
||||||
ACMD46_SET_CER_RN2 = 46
|
acmdSET_CER_RN1 appcommand = 45
|
||||||
ACMD47_SET_CER_RES2 = 47
|
acmdSET_CER_RN2 appcommand = 46
|
||||||
ACMD48_SET_CER_RES1 = 48
|
acmdSET_CER_RES2 appcommand = 47
|
||||||
ACMD49_CHANGE_SECURE_AREA = 49
|
acmdSET_CER_RES1 appcommand = 48
|
||||||
|
acmdCHANGE_SECURE_AREA appcommand = 49
|
||||||
)
|
)
|
||||||
|
|
||||||
// CSD enum types.
|
// CSD enum types.
|
||||||
@@ -497,10 +504,14 @@ func CRC16(buf []byte) (crc uint16) {
|
|||||||
|
|
||||||
// CRC7 computes the CRC7 checksum for a given payload using the polynomial x^7 + x^3 + 1.
|
// CRC7 computes the CRC7 checksum for a given payload using the polynomial x^7 + x^3 + 1.
|
||||||
func CRC7(data []byte) (crc uint8) {
|
func CRC7(data []byte) (crc uint8) {
|
||||||
|
return crc7noshift(data) >> 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func crc7noshift(data []byte) (crc uint8) {
|
||||||
for _, b := range data {
|
for _, b := range data {
|
||||||
crc = crc7_table[crc^b]
|
crc = crc7_table[crc^b]
|
||||||
}
|
}
|
||||||
return crc >> 1
|
return crc
|
||||||
}
|
}
|
||||||
|
|
||||||
var crc7_table = [256]byte{
|
var crc7_table = [256]byte{
|
||||||
|
|||||||
Reference in New Issue
Block a user