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

Dependencies:   mbed

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

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