Exemplo n.º 1
0
/** read CID or CSR register */
uint8_t Sd2Card::readRegister(uint8_t cmd, void* buf) {
  uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
  if (cardCommand(cmd, 0)) {
    error(SD_CARD_ERROR_READ_REG);
    goto fail;
  }
  if (!waitStartBlock()) goto fail;
  // transfer data
  for (uint16_t i = 0; i < 16; i++) dst[i] = spiRec();
  spiRec();  // get first crc byte
  spiRec();  // get second crc byte
  chipSelectHigh();
  return true;

 fail:
  chipSelectHigh();
  return false;
}
Exemplo n.º 2
0
/**
 * Read part of a 512 byte block from an SD card.
 *
 * \param[in] block Logical block to be read.
 * \param[in] offset Number of bytes to skip at start of block
 * \param[out] dst Pointer to the location that will receive the data.
 * \param[in] count Number of bytes to read
 * \return The value one, true, is returned for success and
 * the value zero, false, is returned for failure.
 */
uint8_t Sd2Card::readData(uint32_t block,
        uint16_t offset, uint16_t count, uint8_t* dst) {
  uint16_t n;
  if (count == 0) return true;
  if ((count + offset) > 512) {
    goto fail;
  }
  if (!inBlock_ || block != block_ || offset < offset_) {
    block_ = block;
    // use address if not SDHC card
    if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
    if (cardCommand(CMD17, block)) {
      error(SD_CARD_ERROR_CMD17);
      goto fail;
    }
    if (!waitStartBlock()) {
      goto fail;
    }
    offset_ = 0;
    inBlock_ = 1;
  }


  // skip data before offset
  for (;offset_ < offset; offset_++) {
    spiRec();
  }
  // transfer data
  for (uint16_t i = 0; i < count; i++) {
    dst[i] = spiRec();
  }

  offset_ += count;
  if (!partialBlockRead_ || offset_ >= 512) {
    // read rest of data, checksum and set chip select high
    readEnd();
  }
  return true;

 fail:
  chipSelectHigh();
  return false;
}
Exemplo n.º 3
0
/**
 * Read a 512 byte block from an SD card device.
 *
 * \param[in] block Logical block to be read.
 * \param[out] dst Pointer to the location that will receive the data.

 * \return The value one, true, is returned for success and
 * the value zero, false, is returned for failure.
 */
int Sd2Card::readBlock(uint32_t block, uint8_t* dst) {
	//return readData(block, 0, 512, dst);
	unsigned int *idst;
	int i;


	if (!inBlock_ || block != block_) {
		block_ = block;
		// use address if not SDHC card
		if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
		if (cardCommand(CMD17, block)) {
			error(SD_CARD_ERROR_CMD17);
			goto fail;
		}
		if (!waitStartBlock()) {
			goto fail;
		}
		offset_ = 0;
		inBlock_ = 1;
	}
		/* Do fast readout */

	idst = (unsigned int*)dst;
	for (i=128;i!=0;i--) {
		*idst++=spiRec32(wishboneSlot_);
		// USPIDATA=0xff;
		// USPIDATA=0xff;
		// USPIDATA=0xff;
		// USPIDATA=0xff;
		//*idst++=USPIDATA;
	}
	chipSelectHigh();
	inBlock_ = 0;
	return true;

fail:
	chipSelectHigh();
	return false;
}
Exemplo n.º 4
0
/**
    Read part of a 512 byte block from an SD card.

    \param[in] block Logical block to be read.
    \param[in] offset Number of bytes to skip at start of block
    \param[out] dst Pointer to the location that will receive the data.
    \param[in] count Number of bytes to read
    \return The value one, true, is returned for success and
    the value zero, false, is returned for failure.
*/
uint8_t Sd2Card::readData(uint32_t block, uint16_t offset, uint16_t count, uint8_t* dst)
{
//    uint16_t n;
    if (count == 0)
    {
        return true;
    }
    if ((count + offset) > 512)
    {
        goto fail;
    }
    if (!inBlock_ || block != block_ || offset < offset_)
    {
        block_ = block;
        // use address if not SDHC card
        if (type() != SD_CARD_TYPE_SDHC)
        {
            block <<= 9;
        }
        if (cardCommand(CMD17, block))
        {
            error(SD_CARD_ERROR_CMD17);
            goto fail;
        }
        if (!waitStartBlock())
        {
            goto fail;
        }
        offset_ = 0;
        inBlock_ = 1;
    }

#ifdef OPTIMIZE_HARDWARE_SPI
    // start first spi transfer
    SPDR = 0XFF;

    // skip data before offset
    for (; offset_ < offset; offset_++)
    {
        while (!(SPSR & (1 << SPIF)));
        SPDR = 0XFF;
    }
    // transfer data
    n = count - 1;
    for (uint16_t i = 0; i < n; i++)
    {
        while (!(SPSR & (1 << SPIF)));
        dst[i] = SPDR;
        SPDR = 0XFF;
    }
    // wait for last byte
    while (!(SPSR & (1 << SPIF)));
    dst[n] = SPDR;

#else  // OPTIMIZE_HARDWARE_SPI

    // skip data before offset
    for (; offset_ < offset; offset_++)
    {
        spiRec();
    }
    // transfer data
    for (uint16_t i = 0; i < count; i++)
    {
        dst[i] = spiRec();
    }
#endif  // OPTIMIZE_HARDWARE_SPI

    offset_ += count;
    if (!partialBlockRead_ || offset_ >= 512)
    {
        // read rest of data, checksum and set chip select high
        readEnd();
    }
    return true;

fail:
    chipSelectHigh();
    return false;
}
/**
 * Read part of a 512 byte block from an SD card.
 *
 * \param[in] block Logical block to be read.
 * \param[in] offset Number of bytes to skip at start of block
 * \param[out] dst Pointer to the location that will receive the data.
 * \param[in] count Number of bytes to read
 * \return The value one, true, is returned for success and
 * the value zero, false, is returned for failure.
 */
uint8_t Sd2Card::readData(uint32_t block,
        uint16_t offset, uint16_t count, uint8_t* dst) {
  //uint16_t n;
  if (count == 0) return true;
  if ((count + offset) > 512) {
    goto fail;
  }
  if (!inBlock_ || block != block_ || offset < offset_) {
    block_ = block;
    // use address if not SDHC card
    if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
    if (cardCommand(CMD17, block)) {
      error(SD_CARD_ERROR_CMD17);
	  Serial.println("Error: CMD17");
      goto fail;
    }
    if (!waitStartBlock()) {
      goto fail;
    }
    offset_ = 0;
    inBlock_ = 1;
  }

#ifdef SPI_DMA
    // skip data before offset
    if(offset_ < offset){
        dma_setup_transfer(DMA1,
				DMA_CH3,
				&SPI1->regs->DR,
				DMA_SIZE_8BITS,
				ack,
				DMA_SIZE_8BITS,
                           (/*DMA_MINC_MODE | DMA_CIRC_MODE  |*/ DMA_FROM_MEM | DMA_TRNS_CMPLT | DMA_TRNS_ERR));
        dma_attach_interrupt(DMA1, DMA_CH3, DMAEvent);
        dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH);
        dma_set_num_transfers(DMA1, DMA_CH3, offset - offset_);

        dmaActive = true;
        dma_enable(DMA1, DMA_CH3);

        while(dmaActive) delayMicroseconds(1);
        dma_disable(DMA1, DMA_CH3);
    }
    offset_ = offset;

    // transfer data
    dma_setup_transfer(DMA1, DMA_CH2, &SPI1->regs->DR, DMA_SIZE_8BITS, dst, DMA_SIZE_8BITS,
                       (DMA_MINC_MODE | DMA_TRNS_CMPLT | DMA_TRNS_ERR));
    dma_attach_interrupt(DMA1, DMA_CH2, DMAEvent);
    dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS, ack, DMA_SIZE_8BITS,
                       (/*DMA_MINC_MODE | DMA_CIRC_MODE |*/ DMA_FROM_MEM));
    dma_set_priority(DMA1, DMA_CH2, DMA_PRIORITY_VERY_HIGH);
    dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH);
    dma_set_num_transfers(DMA1, DMA_CH2, count);
    dma_set_num_transfers(DMA1, DMA_CH3, count);

    dmaActive = true;
    dma_enable(DMA1, DMA_CH3);
    dma_enable(DMA1, DMA_CH2);

    while(dmaActive) delayMicroseconds(1);
    dma_disable(DMA1, DMA_CH3);
    dma_disable(DMA1, DMA_CH2);

    offset_ += count;
    if (!partialBlockRead_ || offset_ >= SPI_BUFF_SIZE) {
        readEnd();
    }

#else
  // skip data before offset
  for (;offset_ < offset; offset_++) {
    spiRec();
  }
  // transfer data
  for (uint16_t i = 0; i < count; i++) {
    dst[i] = spiRec();
  }
  offset_ += count;
  if (!partialBlockRead_ || offset_ >= 512) {
    // read rest of data, checksum and set chip select high
    readEnd();
  }
#endif

  return true;

 fail:
  chipSelectHigh();
  Serial.println("Error: Sd2Card::readData()");
  return false;
}