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

Committer:
manitou
Date:
Thu Nov 05 18:40:14 2015 +0000
Revision:
0:f9aaa2c9c4a4
k64f fast SPI proof of concept

Who changed what in which revision?

UserRevisionLine numberNew contents of line
manitou 0:f9aaa2c9c4a4 1 // k64f fast SPI from teensy 3.1 SDfat lib SPI
manitou 0:f9aaa2c9c4a4 2 #include "mbed.h"
manitou 0:f9aaa2c9c4a4 3
manitou 0:f9aaa2c9c4a4 4 #define PRREG(z) printf(#z" 0x%x\n",z)
manitou 0:f9aaa2c9c4a4 5 Timer tmr;
manitou 0:f9aaa2c9c4a4 6 DigitalOut CSpin(D10);
manitou 0:f9aaa2c9c4a4 7 SPI spi(D11,D12,D13); // mosi, miso, sclk
manitou 0:f9aaa2c9c4a4 8
manitou 0:f9aaa2c9c4a4 9 #define SPI_BUFF_SIZE 1024
manitou 0:f9aaa2c9c4a4 10 uint8_t rx_buffer[SPI_BUFF_SIZE];
manitou 0:f9aaa2c9c4a4 11 uint8_t tx_buffer[SPI_BUFF_SIZE];
manitou 0:f9aaa2c9c4a4 12
manitou 0:f9aaa2c9c4a4 13 void spiperf(int mhz) {
manitou 0:f9aaa2c9c4a4 14 int i, us;
manitou 0:f9aaa2c9c4a4 15
manitou 0:f9aaa2c9c4a4 16 spi.frequency(mhz*1000000);
manitou 0:f9aaa2c9c4a4 17 CSpin=0;
manitou 0:f9aaa2c9c4a4 18 us = tmr.read_us();
manitou 0:f9aaa2c9c4a4 19 for(i=0;i<SPI_BUFF_SIZE;i++) spi.write(tx_buffer[i]);
manitou 0:f9aaa2c9c4a4 20 us = tmr.read_us()-us;
manitou 0:f9aaa2c9c4a4 21 CSpin=1;
manitou 0:f9aaa2c9c4a4 22 printf("spi %d mhz %d us %.2f mbs %0x\n",mhz,us,8.*SPI_BUFF_SIZE/us,SPI0_CTAR0);
manitou 0:f9aaa2c9c4a4 23 }
manitou 0:f9aaa2c9c4a4 24
manitou 0:f9aaa2c9c4a4 25
manitou 0:f9aaa2c9c4a4 26 #define SPI_INITIAL_FIFO_DEPTH 3
manitou 0:f9aaa2c9c4a4 27
manitou 0:f9aaa2c9c4a4 28 static void spiInit() {
manitou 0:f9aaa2c9c4a4 29 uint32_t ctar, ctar0, ctar1;
manitou 0:f9aaa2c9c4a4 30
manitou 0:f9aaa2c9c4a4 31 ctar = 0xb8000000; // 30 mhz
manitou 0:f9aaa2c9c4a4 32 ctar = 0x38000100; //15
manitou 0:f9aaa2c9c4a4 33 ctar = 0xb8020202; // 4
manitou 0:f9aaa2c9c4a4 34 ctar = 0x38000101; // 8
manitou 0:f9aaa2c9c4a4 35 ctar = 0x38020302; // 2
manitou 0:f9aaa2c9c4a4 36
manitou 0:f9aaa2c9c4a4 37 // CTAR0 - 8 bit transfer
manitou 0:f9aaa2c9c4a4 38 ctar0 = ctar | BF_SPI_CTARn_FMSZ(7);
manitou 0:f9aaa2c9c4a4 39 // CTAR1 - 16 bit transfer
manitou 0:f9aaa2c9c4a4 40 ctar1 = ctar | BF_SPI_CTARn_FMSZ(15);
manitou 0:f9aaa2c9c4a4 41
manitou 0:f9aaa2c9c4a4 42 if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1 ) {
manitou 0:f9aaa2c9c4a4 43 SPI0_MCR = BM_SPI_MCR_MSTR | BM_SPI_MCR_MDIS | BM_SPI_MCR_HALT;
manitou 0:f9aaa2c9c4a4 44 SPI0_CTAR0 = ctar0;
manitou 0:f9aaa2c9c4a4 45 SPI0_CTAR1 = ctar1;
manitou 0:f9aaa2c9c4a4 46 }
manitou 0:f9aaa2c9c4a4 47 SPI0_MCR = BM_SPI_MCR_MSTR;
manitou 0:f9aaa2c9c4a4 48 }
manitou 0:f9aaa2c9c4a4 49
manitou 0:f9aaa2c9c4a4 50 /** SPI send a byte */
manitou 0:f9aaa2c9c4a4 51 static void spiSend(uint8_t b) {
manitou 0:f9aaa2c9c4a4 52 SPI0_MCR |= BM_SPI_MCR_CLR_RXF;
manitou 0:f9aaa2c9c4a4 53 SPI0_SR = BM_SPI_SR_TCF;
manitou 0:f9aaa2c9c4a4 54 SPI0_PUSHR = b;
manitou 0:f9aaa2c9c4a4 55 while (!(SPI0_SR & BM_SPI_SR_TCF)) {}
manitou 0:f9aaa2c9c4a4 56 }
manitou 0:f9aaa2c9c4a4 57
manitou 0:f9aaa2c9c4a4 58 /** SPI send multiple bytes */
manitou 0:f9aaa2c9c4a4 59 static void spiSend(const uint8_t* output, size_t len) {
manitou 0:f9aaa2c9c4a4 60 // clear any data in RX FIFO
manitou 0:f9aaa2c9c4a4 61 SPI0_MCR = BM_SPI_MCR_MSTR | BM_SPI_MCR_CLR_RXF;
manitou 0:f9aaa2c9c4a4 62 // use 16 bit frame to avoid TD delay between frames
manitou 0:f9aaa2c9c4a4 63 // send one byte if len is odd
manitou 0:f9aaa2c9c4a4 64 if (len & 1) {
manitou 0:f9aaa2c9c4a4 65 spiSend(*output++);
manitou 0:f9aaa2c9c4a4 66 len--;
manitou 0:f9aaa2c9c4a4 67 }
manitou 0:f9aaa2c9c4a4 68 // initial number of words to push into TX FIFO
manitou 0:f9aaa2c9c4a4 69 int nf = len/2 < SPI_INITIAL_FIFO_DEPTH ? len/2 : SPI_INITIAL_FIFO_DEPTH;
manitou 0:f9aaa2c9c4a4 70 // limit for pushing data into TX fifo
manitou 0:f9aaa2c9c4a4 71 const uint8_t* limit = output + len;
manitou 0:f9aaa2c9c4a4 72 for (int i = 0; i < nf; i++) {
manitou 0:f9aaa2c9c4a4 73 uint16_t w = (*output++) << 8;
manitou 0:f9aaa2c9c4a4 74 w |= *output++;
manitou 0:f9aaa2c9c4a4 75 SPI0_PUSHR = BM_SPI_PUSHR_CONT | BF_SPI_PUSHR_CTAS(1) | w;
manitou 0:f9aaa2c9c4a4 76 }
manitou 0:f9aaa2c9c4a4 77 // write data to TX FIFO
manitou 0:f9aaa2c9c4a4 78 while (output < limit) {
manitou 0:f9aaa2c9c4a4 79 uint16_t w = *output++ << 8;
manitou 0:f9aaa2c9c4a4 80 w |= *output++;
manitou 0:f9aaa2c9c4a4 81 while (!(SPI0_SR & BM_SPI_SR_RXCTR)) {}
manitou 0:f9aaa2c9c4a4 82 SPI0_PUSHR = BM_SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w;
manitou 0:f9aaa2c9c4a4 83 SPI0_POPR;
manitou 0:f9aaa2c9c4a4 84 }
manitou 0:f9aaa2c9c4a4 85 // wait for data to be sent
manitou 0:f9aaa2c9c4a4 86 while (nf) {
manitou 0:f9aaa2c9c4a4 87 while (!(SPI0_SR & BM_SPI_SR_RXCTR)) {}
manitou 0:f9aaa2c9c4a4 88 SPI0_POPR;
manitou 0:f9aaa2c9c4a4 89 nf--;
manitou 0:f9aaa2c9c4a4 90 }
manitou 0:f9aaa2c9c4a4 91 }
manitou 0:f9aaa2c9c4a4 92
manitou 0:f9aaa2c9c4a4 93 int main() {
manitou 0:f9aaa2c9c4a4 94 uint32_t us, i;
manitou 0:f9aaa2c9c4a4 95
manitou 0:f9aaa2c9c4a4 96 printf("SystemCoreClock %d %s %s\n",SystemCoreClock,__TIME__,__DATE__);
manitou 0:f9aaa2c9c4a4 97 tmr.start();
manitou 0:f9aaa2c9c4a4 98 CSpin =1;
manitou 0:f9aaa2c9c4a4 99 for(i=0;i<SPI_BUFF_SIZE;i++) tx_buffer[i]=i;
manitou 0:f9aaa2c9c4a4 100 PRREG(SPI0_MCR);
manitou 0:f9aaa2c9c4a4 101 PRREG(SPI0_SR);
manitou 0:f9aaa2c9c4a4 102 PRREG(SPI0_CTAR0);
manitou 0:f9aaa2c9c4a4 103 PRREG(SPI0_CTAR1);
manitou 0:f9aaa2c9c4a4 104 spiperf(1);
manitou 0:f9aaa2c9c4a4 105 spiperf(2);
manitou 0:f9aaa2c9c4a4 106 spiperf(4);
manitou 0:f9aaa2c9c4a4 107 spiperf(8);
manitou 0:f9aaa2c9c4a4 108 spiperf(15);
manitou 0:f9aaa2c9c4a4 109 spiperf(30);
manitou 0:f9aaa2c9c4a4 110
manitou 0:f9aaa2c9c4a4 111 spiInit();
manitou 0:f9aaa2c9c4a4 112 CSpin = 0;
manitou 0:f9aaa2c9c4a4 113 us = tmr.read_us();
manitou 0:f9aaa2c9c4a4 114 spiSend(tx_buffer,SPI_BUFF_SIZE);
manitou 0:f9aaa2c9c4a4 115 us = tmr.read_us()-us;
manitou 0:f9aaa2c9c4a4 116 CSpin=1;
manitou 0:f9aaa2c9c4a4 117 printf("fastspi %d us %.2f mbs %0x\n",us,8.*SPI_BUFF_SIZE/us,SPI0_CTAR0);
manitou 0:f9aaa2c9c4a4 118 }