From add4bb778cf04f1a0892236b2374c59b288c5510 Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 4 Nov 2019 10:19:56 -0500 Subject: [PATCH] Work on SDCard --- g2core/device/sd_card/diskio.cpp | 176 ++++++++++++++++--------------- g2core/device/sd_card/sd_card.h | 62 +++++++---- 2 files changed, 136 insertions(+), 102 deletions(-) diff --git a/g2core/device/sd_card/diskio.cpp b/g2core/device/sd_card/diskio.cpp index 39144c0a..91032b4c 100644 --- a/g2core/device/sd_card/diskio.cpp +++ b/g2core/device/sd_card/diskio.cpp @@ -32,22 +32,22 @@ int rcvr_datablock ( /* 1:OK, 0:Failed */ UINT btr /* Byte count (must be even number) */ ) { - volatile INT token; + volatile INT token; uint32_t start = Motate::SysTickTimer.getValue(); - do { /* Wait for data packet in timeout of 100ms */ - token = sd_card.read(SPIMessage::DeassertAfter); - } while ((token != 0xFE) && Motate::SysTickTimer.getValue()-start < 100); - if(token != 0xFE) { + do { /* Wait for data packet in timeout of 100ms */ + token = sd_card.read(SPIMessage::DeassertAfter); + } while ((token != 0xFE) && Motate::SysTickTimer.getValue()-start < 100); + if(token != 0xFE) { return 0; /* If not valid data token, return with error */ } sd_card.read((uint8_t*)buff, btr); - sd_card.read(SPIMessage::RemainAsserted); /* Discard CRC */ - sd_card.read(SPIMessage::RemainAsserted); + sd_card.read(SPIMessage::RemainAsserted); /* Discard CRC */ + sd_card.read(SPIMessage::RemainAsserted); - return 1; /* Return with success */ + return 1; /* Return with success */ } @@ -80,11 +80,11 @@ int xmit_datablock ( /* 1:OK, 0:Failed */ return 0; } - return 1; + return 1; } #endif -alignas(4) uint8_t data[6]; +alignas(4) uint8_t data[12]; /*-----------------------------------------------------------------------*/ /* Send a command packet to MMC */ @@ -109,7 +109,11 @@ uint8_t send_cmd ( /* Returns command response (bit7==1:Send failed)*/ // wait until card is ready to receive command Motate::Timeout timeout; timeout.set(1000); - while ((sd_card.read(SPIMessage::DeassertAfter) != 0xFF) && !timeout.isPast()) {}; + data[8] = 0x00; + while ((data[8] != 0xFF) && !timeout.isPast()) { + data[0] = 0xFF; + sd_card.readWrite(data, data + 8, 1, SPIMessage::DeassertAfter); + }; // choose the command CRC uint8_t n = 0x01; /* Dummy CRC + Stop */ @@ -127,14 +131,18 @@ uint8_t send_cmd ( /* Returns command response (bit7==1:Send failed)*/ sd_card.write(data, 6, SPIMessage::RemainAsserted); // receive response - if (cmd == CMD12) sd_card.read(SPIMessage::RemainAsserted); /* Skip a stuff byte when stop reading */ - uint8_t tries = 0xFF; /* Wait for a valid response in timeout of 10 attempts */ - do - res = sd_card.read(SPIMessage::RemainAsserted); - while ((res & 0x80) && --tries); // 7th bit is low in all valid responses + if (cmd == CMD12) { + sd_card.read(SPIMessage::RemainAsserted); /* Skip a stuff byte when stop reading */ + } - if (ocr) + uint8_t tries = 10; /* Wait for a valid response in timeout of 10 attempts */ + do { + res = sd_card.read(SPIMessage::RemainAsserted); + } while ((res & 0x80) && --tries); // 7th bit is low in all valid responses + + if (ocr) { sd_card.read(ocr, 4); + } return res; /* Return with the response value */ } @@ -159,32 +167,32 @@ DSTATUS disk_initialize ( BYTE drv /* Physical drive number (0) */ ) { - BYTE ty, cmd, ocr[4]; + BYTE ty, cmd, ocr[4]; - if (drv) return STA_NOINIT; /* Supports only single drive */ - if (disk_status(drv) & STA_NODISK) return Stat; /* No card in the socket */ + if (drv) return STA_NOINIT; /* Supports only single drive */ + if (disk_status(drv) & STA_NODISK) return Stat; /* No card in the socket */ // initialization has to be performed at a slower speed sd_card.setOptions(SD_INIT_SPEED); - sd_card.setSDMode(); /* 80 dummy clocks */ + sd_card.setSDMode(); /* 80 dummy clocks */ - ty = 0; + ty = 0; if (send_cmd_until_specific_response(CMD0, 0, 1)) { /* Enter Idle state */ - if (send_cmd(CMD8, 0x1AA, &ocr[0]) == 1) { /* SDv2? */ - if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ + if (send_cmd(CMD8, 0x1AA, &ocr[0]) == 1) { /* SDv2? */ + if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ if (send_cmd_until_specific_response(ACMD41, 1UL << 30, 0, nullptr, 1000)) { /* Wait for leaving idle state (ACMD41 with HCS bit) */ if (send_cmd_until_specific_response(CMD58, 0, 0, &ocr[0])) { ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 */ } } - } - } else { /* SDv1 or MMCv3 */ - if (send_cmd(ACMD41, 0) <= 1) { - ty = CT_SD1; cmd = ACMD41; /* SDv1 */ - } else { - ty = CT_MMC; cmd = CMD1; /* MMCv3 */ - } + } + } else { /* SDv1 or MMCv3 */ + if (send_cmd(ACMD41, 0) <= 1) { + ty = CT_SD1; cmd = ACMD41; /* SDv1 */ + } else { + ty = CT_MMC; cmd = CMD1; /* MMCv3 */ + } bool success = false; if (send_cmd_until_specific_response(cmd, 0, 0, nullptr, 1000)) { /* Wait for leaving idle state */ if (send_cmd(CMD16, 512) == 0) /* Set R/W block length to 512 */ @@ -192,17 +200,17 @@ DSTATUS disk_initialize ( } if (!success) ty = 0; - } - } - CardType = ty; + } + } + CardType = ty; - if (ty) { /* Initialization succeeded */ - Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ - } + if (ty) { /* Initialization succeeded */ + Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ + } sd_card.setOptions(SD_ACTIVE_SPEED); - return Stat; + return Stat; } @@ -211,7 +219,7 @@ DSTATUS disk_initialize ( /*-----------------------------------------------------------------------*/ DSTATUS disk_status ( - BYTE drv /* Physical drive number to identify the drive */ + BYTE drv /* Physical drive number to identify the drive */ ) { if (drv != SD0) return STA_NOINIT; @@ -233,29 +241,29 @@ DSTATUS disk_status ( /*-----------------------------------------------------------------------*/ DRESULT disk_read ( - BYTE drv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Sector address in LBA */ - UINT count /* Number of sectors to read */ + BYTE drv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Sector address in LBA */ + UINT count /* Number of sectors to read */ ) { - if (drv || !count) return RES_PARERR; + if (drv || !count) return RES_PARERR; if (disk_status(drv) & (STA_NODISK | STA_NOINIT)) return RES_NOTRDY; - if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ BYTE cmd; - cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ + cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ - if (send_cmd_until_specific_response(cmd, sector, 0)) { - do { - if (!rcvr_datablock(buff, 512)) break; - buff += 512; - } while (--count); - if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ - } + if (send_cmd_until_specific_response(cmd, sector, 0)) { + do { + if (!rcvr_datablock(buff, 512)) break; + buff += 512; + } while (--count); + if (cmd == CMD18) send_cmd(CMD12, 0); /* STOP_TRANSMISSION */ + } - return count ? RES_ERROR : RES_OK; + return count ? RES_ERROR : RES_OK; } @@ -266,37 +274,37 @@ DRESULT disk_read ( #if _USE_WRITE DRESULT disk_write ( - BYTE drv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Sector address in LBA */ - UINT count /* Number of sectors to write */ + BYTE drv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector address in LBA */ + UINT count /* Number of sectors to write */ ) { if (drv || !count) return RES_PARERR; if (disk_status(drv) & (STA_NODISK | STA_NOINIT)) return RES_NOTRDY; - if (Stat & STA_PROTECT) return RES_WRPRT; + if (Stat & STA_PROTECT) return RES_WRPRT; - if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ - if (count == 1) { /* Single block write */ + if (count == 1) { /* Single block write */ if (send_cmd_until_specific_response(CMD24, sector, 0) - && xmit_datablock(buff, 0xFE)) - count = 0; - } - else { /* Multiple block write */ - if (CardType & CT_SDC) send_cmd(ACMD23, count); - if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ - do { - if (!xmit_datablock(buff, 0xFC)) break; - buff += 512; - } while (--count); - if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */ - count = 1; - } - } + && xmit_datablock(buff, 0xFE)) + count = 0; + } + else { /* Multiple block write */ + if (CardType & CT_SDC) send_cmd(ACMD23, count); + if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ + do { + if (!xmit_datablock(buff, 0xFC)) break; + buff += 512; + } while (--count); + if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */ + count = 1; + } + } - return count ? RES_ERROR : RES_OK; + return count ? RES_ERROR : RES_OK; } #endif @@ -312,16 +320,16 @@ DRESULT disk_ioctl ( void *buff /* Buffer to send/receive control data */ ) { - DRESULT res; - BYTE n, csd[16], *ptr = (BYTE*)buff; - DWORD cs; + DRESULT res; + BYTE n, csd[16], *ptr = (BYTE*)buff; + DWORD cs; - if (drv) return RES_PARERR; + if (drv) return RES_PARERR; if (disk_status(drv) & (STA_NODISK | STA_NOINIT)) return RES_NOTRDY; - res = RES_ERROR; - switch (ctrl) { + res = RES_ERROR; + switch (ctrl) { case CTRL_SYNC : /* Make sure that no pending write process */ res = RES_OK; break; @@ -395,10 +403,10 @@ DRESULT disk_ioctl ( default: res = RES_PARERR; - } + } // deselect(); - return res; + return res; } #endif diff --git a/g2core/device/sd_card/sd_card.h b/g2core/device/sd_card/sd_card.h index 7aa37b37..a971bad8 100644 --- a/g2core/device/sd_card/sd_card.h +++ b/g2core/device/sd_card/sd_card.h @@ -43,10 +43,10 @@ struct SDCard final { template SDCard(SPIBus_t &spi_bus, chipSelect_t &chip_select) : _device{spi_bus.getDevice(chip_select, // pass it the chip select - 100000, SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit, - 400, // min_between_chip_select_delay_ns - 400, // cs_to_sck_delay_ns - 80 // between_word_delay_ns + 400000, SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit, + 0, // min_between_chip_select_delay_ns + 0, // cs_to_sck_delay_ns + 0 // between_word_delay_ns )}, _chip_select{chip_select} { init(); }; @@ -58,8 +58,7 @@ struct SDCard final { SDCard(const SDCard &) = delete; // Toss out buffer - uint8_t _scribble_buffer[SCRIBBLE_BUF_MAX]; - uint8_t _out_buffer[512]; + alignas(4) uint8_t _scribble_buffer[SCRIBBLE_BUF_MAX]; bool _spi_write = false; bool _spi_read = false; @@ -67,6 +66,7 @@ struct SDCard final { uint16_t _num_bytes = 0; uint8_t *_spi_data; + uint8_t *_spi_read_data; void _startNextReadWrite() { @@ -76,7 +76,7 @@ struct SDCard final { // We write before we read -- so we don't lose what we set in the registers when writing if (_spi_write) { _spi_write = false; - _message.setup(_spi_data, nullptr, _num_bytes, _deassert_chip_select, SPIMessage::EndTransaction); + _message.setup(_spi_data, _spi_read_data, _num_bytes, _deassert_chip_select, SPIMessage::EndTransaction); } else if (_spi_read) { _spi_read = false; @@ -94,6 +94,11 @@ struct SDCard final { void init() { _message.message_done_callback = [&] { this->messageDoneCallback(); }; + const auto miso_mode = _device._spi_bus->misoPin.getMode(); + _device._spi_bus->misoPin.setMode(Motate::kOutput); + _device._spi_bus->misoPin.clear(); + _device._spi_bus->misoPin.setMode(miso_mode); + // Establish default values _spi_write = false; _spi_read = false; @@ -105,24 +110,27 @@ struct SDCard final { } void setSDMode() { - // _device._spi_bus->misoPin.setOptions(Motate::kPullUp); + // _device._spi_bus->misoPin.setOptions(Motate::kOutput); for (size_t i = 100000; i--;) { /* code */ } - const auto cs_mode = _chip_select.getMode(); - _chip_select.setMode(Motate::kOutput); - _chip_select.set(); + // const auto cs_mode = _chip_select.getMode(); + // _chip_select.setMode(Motate::kOutput); + // _chip_select.set(); // _device._spi_bus->misoPin.setMode(Motate::kOutput); // _device._spi_bus->misoPin.set(); alignas(4) uint8_t tossme[12]; - this->read(tossme, 10); /* 80 dummy clocks */ + tossme[0] = 0xff; + uint8_t i = 10; + while (i--) { this->write(tossme, 1); /* 80 dummy clocks */ } - _chip_select.setMode(cs_mode); - // _device._spi_bus->misoPin.setOptions(Motate::kNormal); + // _chip_select.setMode(cs_mode); }; - void setOptions(const uint32_t baud, const uint16_t options = (SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit), uint32_t min_between_chip_select_delay_ns = 400, uint32_t cs_to_sck_delay_ns = 400, uint32_t between_word_delay_ns = 80) { + void setOptions(const uint32_t baud, const uint16_t options = (SPIDeviceMode::kSPIMode0 | SPIDeviceMode::kSPI8Bit), + uint32_t min_between_chip_select_delay_ns = 0, uint32_t cs_to_sck_delay_ns = 0, + uint32_t between_word_delay_ns = 0) { _device.setOptions(baud, options, min_between_chip_select_delay_ns, cs_to_sck_delay_ns, between_word_delay_ns); } @@ -134,11 +142,29 @@ struct SDCard final { _startNextReadWrite(); }; - void read(uint8_t *data, const uint16_t num_bytes, const bool deassert_chip_select = SPIMessage::DeassertAfter) { + void read(uint8_t *data, const uint16_t num_bytes, const bool deassert_chip_select = SPIMessage::RemainAsserted) { // Configure multi byte read _spi_read = true; _spi_data = data; + _spi_read_data = nullptr; + _deassert_chip_select = deassert_chip_select; + _num_bytes = num_bytes; + + // Set up read + _startNextReadWrite(); + + while (_transmitting) { + ; + } + }; + + void readWrite(uint8_t *data, uint8_t *read, const uint16_t num_bytes, const bool deassert_chip_select = SPIMessage::DeassertAfter) { + + // Configure multi byte read + _spi_write = true; + _spi_data = data; + _spi_read_data = read; _deassert_chip_select = deassert_chip_select; _num_bytes = num_bytes; @@ -151,7 +177,6 @@ struct SDCard final { }; uint8_t read(const bool deassert_chip_select = SPIMessage::DeassertAfter) { - // Configure and set up single byte read read(_scribble_buffer, 1, deassert_chip_select); return _scribble_buffer[0]; @@ -162,6 +187,7 @@ struct SDCard final { // Configure multi byte write _spi_write = true; _spi_data = data; + _spi_read_data = nullptr; _deassert_chip_select = deassert_chip_select; _num_bytes = num_bytes; @@ -173,7 +199,7 @@ struct SDCard final { } }; - void write(uint8_t data, const bool deassert_chip_select = SPIMessage::DeassertAfter) { + void write(uint8_t data, const bool deassert_chip_select = SPIMessage::RemainAsserted) { _scribble_buffer[0] = data; // Configure and set up single byte write write(_scribble_buffer, 1, deassert_chip_select);