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
main.cpp
- Committer:
- manitou
- Date:
- 2015-11-05
- Revision:
- 0:f9aaa2c9c4a4
File content as of revision 0:f9aaa2c9c4a4:
// 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); }