k64f fast SPI using SDfat SPI FIFO logic from teensy 3.1 SDfat lib. with SPI clock at 30mhz, standard SPI yields 3.7 mbs, fast SPI 27.3mbs https://github.com/manitou48/DUEZoo/blob/master/SPIperf.txt
k64f fast SPI using SDfat SPI FIFO logic from teensy 3.1 SDfat lib. with SPI clock at 30mhz, standard SPI yields 3.7 mbs, fast SPI 27.3mbs
https://github.com/manitou48/DUEZoo/blob/master/SPIperf.txt
Diff: main.cpp
- Revision:
- 0:f9aaa2c9c4a4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Nov 05 18:40:14 2015 +0000 @@ -0,0 +1,118 @@ +// k64f fast SPI from teensy 3.1 SDfat lib SPI +#include "mbed.h" + +#define PRREG(z) printf(#z" 0x%x\n",z) +Timer tmr; +DigitalOut CSpin(D10); +SPI spi(D11,D12,D13); // mosi, miso, sclk + +#define SPI_BUFF_SIZE 1024 +uint8_t rx_buffer[SPI_BUFF_SIZE]; +uint8_t tx_buffer[SPI_BUFF_SIZE]; + +void spiperf(int mhz) { + int i, us; + + spi.frequency(mhz*1000000); + CSpin=0; + us = tmr.read_us(); + for(i=0;i<SPI_BUFF_SIZE;i++) spi.write(tx_buffer[i]); + us = tmr.read_us()-us; + CSpin=1; + printf("spi %d mhz %d us %.2f mbs %0x\n",mhz,us,8.*SPI_BUFF_SIZE/us,SPI0_CTAR0); +} + + +#define SPI_INITIAL_FIFO_DEPTH 3 + +static void spiInit() { + uint32_t ctar, ctar0, ctar1; + + ctar = 0xb8000000; // 30 mhz + ctar = 0x38000100; //15 + ctar = 0xb8020202; // 4 + ctar = 0x38000101; // 8 + ctar = 0x38020302; // 2 + + // CTAR0 - 8 bit transfer + ctar0 = ctar | BF_SPI_CTARn_FMSZ(7); + // CTAR1 - 16 bit transfer + ctar1 = ctar | BF_SPI_CTARn_FMSZ(15); + + if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1 ) { + SPI0_MCR = BM_SPI_MCR_MSTR | BM_SPI_MCR_MDIS | BM_SPI_MCR_HALT; + SPI0_CTAR0 = ctar0; + SPI0_CTAR1 = ctar1; + } + SPI0_MCR = BM_SPI_MCR_MSTR; +} + +/** SPI send a byte */ +static void spiSend(uint8_t b) { + SPI0_MCR |= BM_SPI_MCR_CLR_RXF; + SPI0_SR = BM_SPI_SR_TCF; + SPI0_PUSHR = b; + while (!(SPI0_SR & BM_SPI_SR_TCF)) {} +} + +/** SPI send multiple bytes */ +static void spiSend(const uint8_t* output, size_t len) { + // clear any data in RX FIFO + SPI0_MCR = BM_SPI_MCR_MSTR | BM_SPI_MCR_CLR_RXF; + // use 16 bit frame to avoid TD delay between frames + // send one byte if len is odd + if (len & 1) { + spiSend(*output++); + len--; + } + // initial number of words to push into TX FIFO + int nf = len/2 < SPI_INITIAL_FIFO_DEPTH ? len/2 : SPI_INITIAL_FIFO_DEPTH; + // limit for pushing data into TX fifo + const uint8_t* limit = output + len; + for (int i = 0; i < nf; i++) { + uint16_t w = (*output++) << 8; + w |= *output++; + SPI0_PUSHR = BM_SPI_PUSHR_CONT | BF_SPI_PUSHR_CTAS(1) | w; + } + // write data to TX FIFO + while (output < limit) { + uint16_t w = *output++ << 8; + w |= *output++; + while (!(SPI0_SR & BM_SPI_SR_RXCTR)) {} + SPI0_PUSHR = BM_SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w; + SPI0_POPR; + } + // wait for data to be sent + while (nf) { + while (!(SPI0_SR & BM_SPI_SR_RXCTR)) {} + SPI0_POPR; + nf--; + } +} + +int main() { + uint32_t us, i; + + printf("SystemCoreClock %d %s %s\n",SystemCoreClock,__TIME__,__DATE__); + tmr.start(); + CSpin =1; + for(i=0;i<SPI_BUFF_SIZE;i++) tx_buffer[i]=i; + PRREG(SPI0_MCR); + PRREG(SPI0_SR); + PRREG(SPI0_CTAR0); + PRREG(SPI0_CTAR1); + spiperf(1); + spiperf(2); + spiperf(4); + spiperf(8); + spiperf(15); + spiperf(30); + + spiInit(); + CSpin = 0; + us = tmr.read_us(); + spiSend(tx_buffer,SPI_BUFF_SIZE); + us = tmr.read_us()-us; + CSpin=1; + printf("fastspi %d us %.2f mbs %0x\n",us,8.*SPI_BUFF_SIZE/us,SPI0_CTAR0); +} \ No newline at end of file