/** SPI receive multiple bytes */ uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { Spi* pSpi = SPI0; int rtn = 0; #if USE_SAM3X_DMAC // clear overrun error uint32_t s = pSpi->SPI_SR; spiDmaRX(buf, n); spiDmaTX(0, n); uint32_t m = millis(); while (!dmac_channel_transfer_done(SPI_DMAC_RX_CH)) { if ((millis() - m) > SAM3X_DMA_TIMEOUT) { dmac_channel_disable(SPI_DMAC_RX_CH); dmac_channel_disable(SPI_DMAC_TX_CH); rtn = 2; break; } } if (pSpi->SPI_SR & SPI_SR_OVRES) { rtn |= 1; } #else // USE_SAM3X_DMAC for (size_t i = 0; i < n; i++) { pSpi->SPI_TDR = 0XFF; while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} buf[i] = pSpi->SPI_RDR; } #endif // USE_SAM3X_DMAC return rtn; }
/** SPI receive multiple bytes */ uint8_t spiRec(uint8_t* buf, size_t len) { Spi* pSpi = SPI0; int rtn = 0; #if USE_SAM3X_DMAC // clear overrun error uint32_t s = pSpi->SPI_SR; spiDmaRX(buf, len); spiDmaTX(0, len); uint32_t m = millis(); while (!dmac_channel_transfer_done(SPI_DMAC_RX_CH)) { if ((millis() - m) > SAM3X_DMA_TIMEOUT) { dmac_channel_disable(SPI_DMAC_RX_CH); dmac_channel_disable(SPI_DMAC_TX_CH); rtn = 2; break; } } if (pSpi->SPI_SR & SPI_SR_OVRES) rtn |= 1; #else // USE_SAM3X_DMAC for (size_t i = 0; i < len; i++) { pSpi->SPI_TDR = 0XFF; while ((pSpi->SPI_SR & SPI_SR_RDRF) == 0) {} buf[i] = pSpi->SPI_RDR; } #endif // USE_SAM3X_DMAC if (bitOrder == LSBFIRST) { for (register int i=0; i<len; i++) { buf[i] = __REV(__RBIT(buf[i])); } } return rtn; }