Exemplo n.º 1
0
//-----------------------------------------------------------------------------
bool SdioCard::readData(uint8_t *dst) {
  DBG_IRQSTAT();
  uint32_t *p32 = reinterpret_cast<uint32_t*>(dst);

  if (!(SDHC_PRSSTAT & SDHC_PRSSTAT_RTA)) {
    SDHC_PROCTL &= ~SDHC_PROCTL_SABGREQ;
    if ((SDHC_BLKATTR & 0XFFFF0000) == 0X10000) {
    // Don't stop at block gap if last block.  Allows auto CMD12.
      SDHC_PROCTL |= SDHC_PROCTL_CREQ;
    } else {
      noInterrupts();
      SDHC_PROCTL |= SDHC_PROCTL_CREQ;
      SDHC_PROCTL |= SDHC_PROCTL_SABGREQ;
      interrupts();
    }
  }
  if (waitTimeout(isBusyFifoRead)) {
    return sdError(SD_CARD_ERROR_READ_FIFO);
  }
  for (uint32_t iw = 0 ; iw < 512/(4*FIFO_WML); iw++) {
    while (0 == (SDHC_PRSSTAT & SDHC_PRSSTAT_BREN)) {
    }
    for (uint32_t i = 0; i < FIFO_WML; i++) {
      p32[i] = SDHC_DATPORT;
    }
    p32 += FIFO_WML;
  }
  if (waitTimeout(isBusyTransferComplete)) {
    return sdError(SD_CARD_ERROR_READ_TIMEOUT);
  }
  m_irqstat = SDHC_IRQSTAT;
  SDHC_IRQSTAT = m_irqstat;
  return (m_irqstat & SDHC_IRQSTAT_TC) && !(m_irqstat & SDHC_IRQSTAT_ERROR);
}
Exemplo n.º 2
0
//-----------------------------------------------------------------------------
bool SdioCard::writeData(const uint8_t* src) {
  DBG_IRQSTAT();
  const uint32_t* p32 = reinterpret_cast<const uint32_t*>(src);

  if (!(SDHC_PRSSTAT & SDHC_PRSSTAT_WTA)) {
    SDHC_PROCTL &= ~SDHC_PROCTL_SABGREQ;
    // Don't stop at block gap if last block.  Allows auto CMD12.
    if ((SDHC_BLKATTR & 0XFFFF0000) == 0X10000) {
      SDHC_PROCTL |= SDHC_PROCTL_CREQ;
    } else {
      SDHC_PROCTL |= SDHC_PROCTL_CREQ;
      SDHC_PROCTL |= SDHC_PROCTL_SABGREQ;
    }
  }
  if (waitTimeout(isBusyFifoWrite)) {
    return sdError(SD_CARD_ERROR_WRITE_FIFO);
  }
  for (uint32_t iw = 0 ; iw < 512/(4*FIFO_WML); iw++) {
    while (0 == (SDHC_PRSSTAT & SDHC_PRSSTAT_BWEN)) {
    }
    for (uint32_t i = 0; i < FIFO_WML; i++) {
      SDHC_DATPORT = p32[i];
    }
    p32 += FIFO_WML;
  }
  if (waitTimeout(isBusyTransferComplete)) {
    return sdError(SD_CARD_ERROR_WRITE_TIMEOUT);
  }
  m_irqstat = SDHC_IRQSTAT;
  SDHC_IRQSTAT = m_irqstat;
  return (m_irqstat & SDHC_IRQSTAT_TC) && !(m_irqstat & SDHC_IRQSTAT_ERROR);
}
Exemplo n.º 3
0
//-----------------------------------------------------------------------------
bool SdioCard::erase(uint32_t firstBlock, uint32_t lastBlock) {
  // check for single block erase
  if (!m_csd.v1.erase_blk_en) {
    // erase size mask
    uint8_t m = (m_csd.v1.sector_size_high << 1) | m_csd.v1.sector_size_low;
    if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) {
      // error card can't erase specified area
      return sdError(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
    }
  }
  if (!m_highCapacity) {
    firstBlock <<= 9;
    lastBlock <<= 9;
  }
  if (!cardCommand(CMD32_XFERTYP, firstBlock)) {
    return sdError(SD_CARD_ERROR_CMD32);
  }
  if (!cardCommand(CMD33_XFERTYP, lastBlock)) {
     return sdError(SD_CARD_ERROR_CMD33);
  }
  if (!cardCommand(CMD38_XFERTYP, 0)) {
    return sdError(SD_CARD_ERROR_CMD38);
  }
  if (waitTimeout(isBusyCMD13)) {
    return sdError(SD_CARD_ERROR_ERASE_TIMEOUT);
  }
  return true;
}
Exemplo n.º 4
0
//------------------------------------------------------------------------------
// zero FAT and root dir area on SD
void clearFatDir(uint32_t bgn, uint32_t count) {
  clearCache(false);
  if (!card.writeStart(bgn, count)) {
    sdError("Clear FAT/DIR writeStart failed");
  }
  for (uint32_t i = 0; i < count; i++) {
    if ((i & 0XFF) == 0) cout << '.';
    if (!card.writeData(cache.data)) {
      sdError("Clear FAT/DIR writeData failed");
    }
  }
  if (!card.writeStop()) {
    sdError("Clear FAT/DIR writeStop failed");
  }
  cout << endl;
}
Exemplo n.º 5
0
//-----------------------------------------------------------------------------
static bool rdWrBlocks(uint32_t xfertyp,
                       uint32_t lba, uint8_t* buf, size_t n) {
  if ((3 & (uint32_t)buf) || n == 0) {
    return sdError(SD_CARD_ERROR_DMA);
  }
  if (yieldTimeout(isBusyCMD13)) {
    return sdError(SD_CARD_ERROR_CMD13);
  }
  enableDmaIrs();
  SDHC_DSADDR  = (uint32_t)buf;
  SDHC_CMDARG = m_highCapacity ? lba : 512*lba;
  SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(n) | SDHC_BLKATTR_BLKSIZE(512);
  SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK;
  SDHC_XFERTYP = xfertyp;

  return waitDmaStatus();
}
Exemplo n.º 6
0
bool staticDataAdd(StaticData *self, StaticDataId id, void *object) {

    if (self->locked) {
        sdError(self, "StaticData has been locked and cannot be modified anymore.");
        return false;
    }

    StaticDataKey key;
    staticDataGenKey(self, id, key);

    if (zhash_insert(self->hashtable, key, object) != 0) {
        sdError(self, "Cannot insert the object '%s'", key);
        return false;
    }

    return true;
}
Exemplo n.º 7
0
//-----------------------------------------------------------------------------
static bool cardCMD6(uint32_t arg, uint8_t* status) {
  // CMD6 returns 64 bytes.
  if (waitTimeout(isBusyCMD13)) {
    return sdError(SD_CARD_ERROR_CMD13);
  }
  enableDmaIrs();
  SDHC_DSADDR  = (uint32_t)status;
  SDHC_CMDARG = arg;
  SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(64);
  SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK;
  SDHC_XFERTYP = CMD6_XFERTYP;

  if (!waitDmaStatus()) {
    return sdError(SD_CARD_ERROR_CMD6);
  }
  return true;
}
Exemplo n.º 8
0
//-----------------------------------------------------------------------------
// SDHC will do Auto CMD12 after count blocks.
bool SdioCard::readStart(uint32_t lba, uint32_t count) {
  DBG_IRQSTAT();
  if (count > 0XFFFF) {
    return sdError(SD_CARD_ERROR_READ_START);
  }
  if (yieldTimeout(isBusyCMD13)) {
    return sdError(SD_CARD_ERROR_CMD13);
  }
  if (count > 1) {
    SDHC_PROCTL |= SDHC_PROCTL_SABGREQ;
  }
  SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(count) | SDHC_BLKATTR_BLKSIZE(512);
  if (!cardCommand(CMD18_PGM_XFERTYP, m_highCapacity ? lba : 512*lba)) {
    return sdError(SD_CARD_ERROR_CMD18);
  }
  return true;
}
Exemplo n.º 9
0
//-----------------------------------------------------------------------------
bool SdioCard::readBlock(uint32_t lba, uint8_t* buf) {
  uint8_t aligned[512];

  uint8_t* ptr = (uint32_t)buf & 3 ? aligned : buf;

  if (!rdWrBlocks(CMD17_DMA_XFERTYP, lba, ptr, 1)) {
    return sdError(SD_CARD_ERROR_CMD18);
  }
  if (ptr != buf) {
    memcpy(buf, aligned, 512);
  }
  return true;
}
Exemplo n.º 10
0
//-----------------------------------------------------------------------------
static bool transferStop() {
  DBG_IRQSTAT();

  if (!cardCommand(CMD12_XFERTYP, 0)) {
    return sdError(SD_CARD_ERROR_CMD12);
  }
  if (yieldTimeout(isBusyCMD13)) {
    return sdError(SD_CARD_ERROR_CMD13);
  }
  // Save registers before reset DAT lines.
  uint32_t irqsststen = SDHC_IRQSTATEN;
  uint32_t proctl = SDHC_PROCTL & ~SDHC_PROCTL_SABGREQ;

  // Do reset to clear CDIHB.  Should be a better way!
  SDHC_SYSCTL |= SDHC_SYSCTL_RSTD;

  // Restore registers.
  SDHC_IRQSTATEN = irqsststen;
  SDHC_PROCTL = proctl;

  return true;
}
Exemplo n.º 11
0
//-----------------------------------------------------------------------------
bool SdioCard::readBlocks(uint32_t lba, uint8_t* buf, size_t n) {
  if ((uint32_t)buf & 3) {
    for (size_t i = 0; i < n; i++, lba++, buf += 512) {
      if (!readBlock(lba, buf)) {
        return false;  // readBlock will set errorCode.
      }
    }
    return true;
  }
  if (!rdWrBlocks(CMD18_DMA_XFERTYP, lba, buf, n)) {
    return sdError(SD_CARD_ERROR_CMD18);
  }
  return true;
}
Exemplo n.º 12
0
bool staticDataInit(StaticData *self, char *name) {

    memset(self, 0, sizeof(StaticData));

    self->locked = false;
    self->name = strdup(name);

    if (!(self->hashtable = zhash_new())) {
        sdError(self, "Cannot allocate a new hashtable.");
        return false;
    }

    return true;
}
Exemplo n.º 13
0
bool staticDataGet(StaticData *self, StaticDataId id, void *_out, bool emitError) {

    void **out = _out;

    if (!self->locked) {
        sdError(self, "StaticData should have been locked before querying it.");
        return false;
    }

    StaticDataKey key;
    staticDataGenKey(self, id, key);

    void *object = NULL;
    if (!(object = zhash_lookup(self->hashtable, key))) {
        if (emitError) {
            sdError(self, "Cannot find the static data for object '%s'", key);
        }
        return false;
    }

    *out = object;
    return true;
}
Exemplo n.º 14
0
//-----------------------------------------------------------------------------
bool SdioCard::writeBlock(uint32_t lba, const uint8_t* buf) {
  uint8_t *ptr;
  uint8_t aligned[512];
  if (3 & (uint32_t)buf) {
    ptr = aligned;
    memcpy(aligned, buf, 512);
  } else {
    ptr = const_cast<uint8_t*>(buf);
  }
  if (!rdWrBlocks(CMD24_DMA_XFERTYP, lba, ptr, 1)) {
    return sdError(SD_CARD_ERROR_CMD24);
  }
  return true;
}
Exemplo n.º 15
0
//-----------------------------------------------------------------------------
bool SdioCard::writeBlocks(uint32_t lba, const uint8_t* buf, size_t n) {
  uint8_t* ptr = const_cast<uint8_t*>(buf);
  if (3 & (uint32_t)ptr) {
    for (size_t i = 0; i < n; i++, lba++, ptr += 512) {
      if (!writeBlock(lba, ptr)) {
        return false;  // writeBlock will set errorCode.
      }
    }
    return true;
  }
  if (!rdWrBlocks(CMD25_DMA_XFERTYP, lba, ptr, n)) {
    return sdError(SD_CARD_ERROR_CMD25);
  }
  return true;
}
Exemplo n.º 16
0
//------------------------------------------------------------------------------
// format and write the Master Boot Record
void writeMbr() {
  clearCache(true);
  part_t* p = cache.mbr.part;
  p->boot = 0;
  uint16_t c = lbnToCylinder(relSector);
  if (c > 1023) sdError("MBR CHS");
  p->beginCylinderHigh = c >> 8;
  p->beginCylinderLow = c & 0XFF;
  p->beginHead = lbnToHead(relSector);
  p->beginSector = lbnToSector(relSector);
  p->type = partType;
  uint32_t endLbn = relSector + partSize - 1;
  c = lbnToCylinder(endLbn);
  if (c <= 1023) {
    p->endCylinderHigh = c >> 8;
    p->endCylinderLow = c & 0XFF;
    p->endHead = lbnToHead(endLbn);
    p->endSector = lbnToSector(endLbn);
  } else {
Exemplo n.º 17
0
//------------------------------------------------------------------------------
// initialize appropriate sizes for SD capacity
void initSizes() {
  if (cardCapacityMB <= 6) {
    sdError("Card is too small.");
  } else if (cardCapacityMB <= 16) {
    sectorsPerCluster = 2;
  } else if (cardCapacityMB <= 32) {
    sectorsPerCluster = 4;
  } else if (cardCapacityMB <= 64) {
    sectorsPerCluster = 8;
  } else if (cardCapacityMB <= 128) {
    sectorsPerCluster = 16;
  } else if (cardCapacityMB <= 1024) {
    sectorsPerCluster = 32;
  } else if (cardCapacityMB <= 32768) {
    sectorsPerCluster = 64;
  } else {
    // SDXC cards
    sectorsPerCluster = 128;
  }

  cout << pstr("Blocks/Cluster: ") << int(sectorsPerCluster) << endl;
  // set fake disk geometry
  sectorsPerTrack = cardCapacityMB <= 256 ? 32 : 63;

  if (cardCapacityMB <= 16) {
    numberOfHeads = 2;
  } else if (cardCapacityMB <= 32) {
    numberOfHeads = 4;
  } else if (cardCapacityMB <= 128) {
    numberOfHeads = 8;
  } else if (cardCapacityMB <= 504) {
    numberOfHeads = 16;
  } else if (cardCapacityMB <= 1008) {
    numberOfHeads = 32;
  } else if (cardCapacityMB <= 2016) {
    numberOfHeads = 64;
  } else if (cardCapacityMB <= 4032) {
    numberOfHeads = 128;
  } else {
    numberOfHeads = 255;
  }
}
Exemplo n.º 18
0
//-----------------------------------------------------------------------------
bool SdioCard::writeStart(uint32_t lba) {
  // K66/K65 Errata - SDHC: Does not support Infinite Block Transfer Mode.
  return sdError(SD_CARD_ERROR_FUNCTION_NOT_SUPPORTED);
}
Exemplo n.º 19
0
//=============================================================================
bool SdioCard::begin() {
  uint32_t kHzSdClk;
  uint32_t arg;
  m_initDone = false;
  m_errorCode = SD_CARD_ERROR_NONE;
  m_highCapacity = false;
  m_version2 = false;

  // initialize controller.
  initSDHC();

  if (!cardCommand(CMD0_XFERTYP, 0)) {
    return sdError(SD_CARD_ERROR_CMD0);
  }
  // Try several times for case of reset delay.
  for (uint32_t i = 0; i < CMD8_RETRIES; i++) {
    if (cardCommand(CMD8_XFERTYP, 0X1AA)) {
      if (SDHC_CMDRSP0 != 0X1AA) {
        return sdError(SD_CARD_ERROR_CMD8);
      }
      m_version2 = true;
      break;
    }
  }
  arg = m_version2 ? 0X40300000 : 0x00300000;
  uint32_t m = micros();
  do {
    if (!cardAcmd(0, ACMD41_XFERTYP, arg) ||
       ((micros() - m) > BUSY_TIMEOUT_MICROS)) {
      return sdError(SD_CARD_ERROR_ACMD41);
    }
  } while ((SDHC_CMDRSP0 & 0x80000000) == 0);

  m_ocr = SDHC_CMDRSP0;
  if (SDHC_CMDRSP0 & 0x40000000) {
    // Is high capacity.
    m_highCapacity = true;
  }
  if (!cardCommand(CMD2_XFERTYP, 0)) {
    return sdError(SD_CARD_ERROR_CMD2);
  }
  if (!cardCommand(CMD3_XFERTYP, 0)) {
    return sdError(SD_CARD_ERROR_CMD3);
  }
  m_rca = SDHC_CMDRSP0 & 0xFFFF0000;

  if (!readReg16(CMD9_XFERTYP, &m_csd)) {
    return sdError(SD_CARD_ERROR_CMD9);
  }
  if (!readReg16(CMD10_XFERTYP, &m_cid)) {
    return sdError(SD_CARD_ERROR_CMD10);
  }
  if (!cardCommand(CMD7_XFERTYP, m_rca)) {
    return sdError(SD_CARD_ERROR_CMD7);
  }
  // Set card to bus width four.
  if (!cardAcmd(m_rca, ACMD6_XFERTYP, 2)) {
    return sdError(SD_CARD_ERROR_ACMD6);
  }
  // Set SDHC to bus width four.
  SDHC_PROCTL &= ~SDHC_PROCTL_DTW_MASK;
  SDHC_PROCTL |= SDHC_PROCTL_DTW(SDHC_PROCTL_DTW_4BIT);

  SDHC_WML = SDHC_WML_RDWML(FIFO_WML) | SDHC_WML_WRWML(FIFO_WML);

  // Determine if High Speed mode is supported and set frequency.
  uint8_t status[64];
  if (cardCMD6(0X00FFFFFF, status) && (2 & status[13]) &&
      cardCMD6(0X80FFFFF1, status) && (status[16] & 0XF) == 1) {
    kHzSdClk = 50000;
  } else {
    kHzSdClk = 25000;
  }
  // disable GPIO
  enableGPIO(false);

  // Set the SDHC SCK frequency.
  setSdclk(kHzSdClk);

  // enable GPIO
  enableGPIO(true);
  m_initDone = true;
  return true;
}