Advertisement
Guest User

Untitled

a guest
Jan 17th, 2014
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.69 KB | None | 0 0
  1. //Lifted from the MK20DX portion of SdFat
  2. // https://code.google.com/p/beta-lib/downloads/list
  3.  
  4.  
  5. ///definitions
  6. #define SPI_USE_8BIT_FRAME 0
  7. // Limit initial fifo to three entries to avoid fifo overrun
  8. #define SPI_INITIAL_FIFO_DEPTH 3
  9. // define some symbols that are not in mk20dx128.h
  10. #ifndef SPI_SR_RXCTR
  11. #define SPI_SR_RXCTR 0XF0
  12. #endif  // SPI_SR_RXCTR
  13. #ifndef SPI_PUSHR_CONT
  14. #define SPI_PUSHR_CONT 0X80000000
  15. #endif   // SPI_PUSHR_CONT
  16. #ifndef SPI_PUSHR_CTAS
  17. #define SPI_PUSHR_CTAS(n) (((n) & 7) << 28)
  18. #endif  // SPI_PUSHR_CTAS
  19. ///
  20.  
  21.  
  22. ///in setup
  23.  SIM_SCGC6 |= SIM_SCGC6_SPI0;
  24.  spiInit(0);
  25. ///
  26.  
  27. static void spiInit(uint8_t spiRate) {
  28.   // spiRate = 0 or 1 : 24 or 12 Mbit/sec
  29.   // spiRate = 2 or 3 : 12 or 6 Mbit/sec
  30.   // spiRate = 4 or 5 : 6 or 3 Mbit/sec
  31.   // spiRate = 6 or 7 : 3 or 1.5 Mbit/sec
  32.   // spiRate = 8 or 9 : 1.5 or 0.75 Mbit/sec
  33.   // spiRate = 10 or 11 : 250 kbit/sec
  34.   // spiRate = 12 or more : 125 kbit/sec
  35.   uint32_t ctar, ctar0, ctar1;
  36.   switch (spiRate/2) {
  37.     case 0: ctar = SPI_CTAR_DBR | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); break;
  38.     case 1: ctar = SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); break;
  39.     case 2: ctar = SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); break;
  40.     case 3: ctar = SPI_CTAR_BR(2) | SPI_CTAR_CSSCK(2); break;
  41.     case 4: ctar = SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(3); break;
  42. #if F_BUS == 48000000
  43.     case 5: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5); break;
  44.     default: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
  45. #elif F_BUS == 24000000
  46.     case 5: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4); break;
  47.     default: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5);
  48. #else
  49. #error "MK20DX128 bus frequency must be 48 or 24 MHz"
  50. #endif
  51.   }
  52.  
  53.   // CTAR0 - 8 bit transfer
  54.   ctar0 = ctar | SPI_CTAR_FMSZ(7);
  55.   // CTAR1 - 16 bit transfer
  56.   ctar1 = ctar | SPI_CTAR_FMSZ(15);
  57.  
  58.   if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1 ) {
  59.     SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT;
  60.     SPI0_CTAR0 = ctar0;
  61.     SPI0_CTAR1 = ctar1;
  62.   }
  63.   SPI0_MCR = SPI_MCR_MSTR;
  64.   CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  65.   CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
  66.   CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  67. }
  68.  
  69.  
  70. static void spiSend(const uint8_t* output, size_t len) {
  71.   // clear any data in RX FIFO
  72.   SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF;
  73. #if SPI_USE_8BIT_FRAME
  74.   // initial number of bytes to push into TX FIFO
  75.   int nf = len < SPI_INITIAL_FIFO_DEPTH ? len : SPI_INITIAL_FIFO_DEPTH;
  76.   // limit for pushing data into TX fifo
  77.   const uint8_t* limit = output + len;
  78.   for (int i = 0; i < nf; i++) {
  79.     SPI0_PUSHR = *output++;
  80.   }
  81.   // write data to TX FIFO
  82.   while (output < limit) {
  83.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  84.     SPI0_PUSHR = *output++;
  85.     SPI0_POPR;
  86.   }
  87.   // wait for data to be sent
  88.   while (nf) {
  89.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  90.     SPI0_POPR;
  91.     nf--;
  92.   }
  93. #else  // SPI_USE_8BIT_FRAME
  94.   // use 16 bit frame to avoid TD delay between frames
  95.   // send one byte if len is odd
  96.   if (len & 1) {
  97.     spiSend(*output++);
  98.     len--;
  99.   }
  100.   // initial number of words to push into TX FIFO
  101.   int nf = len/2 < SPI_INITIAL_FIFO_DEPTH ? len/2 : SPI_INITIAL_FIFO_DEPTH;
  102.   // limit for pushing data into TX fifo
  103.   const uint8_t* limit = output + len;
  104.   for (int i = 0; i < nf; i++) {
  105.     uint16_t w = (*output++) << 8;
  106.     w |= *output++;
  107.     SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w;
  108.   }
  109.   // write data to TX FIFO
  110.   while (output < limit) {
  111.     uint16_t w = *output++ << 8;
  112.     w |= *output++;
  113.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  114.     SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w;
  115.     SPI0_POPR;
  116.   }
  117.   // wait for data to be sent
  118.   while (nf) {
  119.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  120.     SPI0_POPR;
  121.     nf--;
  122.   }
  123.   #endif  // SPI_USE_8BIT_FRAME
  124. }
  125.  
  126. static uint8_t spiRec(uint8_t* buf, size_t len) {
  127.   // clear any data in RX FIFO
  128.   SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF;
  129. #if SPI_USE_8BIT_FRAME
  130.   // initial number of bytes to push into TX FIFO
  131.   int nf = len < SPI_INITIAL_FIFO_DEPTH ? len : SPI_INITIAL_FIFO_DEPTH;
  132.   for (int i = 0; i < nf; i++) {
  133.     SPI0_PUSHR = 0XFF;
  134.   }
  135.   // limit for pushing dummy data into TX FIFO
  136.   uint8_t* limit = buf + len - nf;
  137.   while (buf < limit) {
  138.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  139.     SPI0_PUSHR = 0XFF;
  140.     *buf++ = SPI0_POPR;
  141.   }
  142.   // limit for rest of RX data
  143.   limit += nf;
  144.   while (buf < limit) {
  145.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  146.     *buf++ = SPI0_POPR;
  147.   }
  148. #else  // SPI_USE_8BIT_FRAME
  149.   // use 16 bit frame to avoid TD delay between frames
  150.   // get one byte if len is odd
  151.   if (len & 1) {
  152.     *buf++ = spiRec();
  153.     len--;
  154.   }
  155.   // initial number of words to push into TX FIFO
  156.   int nf = len/2 < SPI_INITIAL_FIFO_DEPTH ? len/2 : SPI_INITIAL_FIFO_DEPTH;
  157.   for (int i = 0; i < nf; i++) {
  158.     SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF;
  159.   }
  160.   uint8_t* limit = buf + len - 2*nf;
  161.   while (buf < limit) {
  162.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  163.     SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF;
  164.     uint16_t w = SPI0_POPR;
  165.     *buf++ = w >> 8;
  166.     *buf++ = w & 0XFF;
  167.   }
  168.   // limit for rest of RX data
  169.   limit += 2*nf;
  170.   while (buf < limit) {
  171.     while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  172.     uint16_t w = SPI0_POPR;
  173.     *buf++ = w >> 8;
  174.     *buf++ = w & 0XFF;
  175.   }
  176. #endif  // SPI_USE_8BIT_FRAME
  177.   return 0;
  178. }
  179.  
  180. static void spiSend(uint8_t b) {
  181.   SPI0_MCR |= SPI_MCR_CLR_RXF;
  182.   SPI0_SR = SPI_SR_TCF;
  183.   SPI0_PUSHR = b;
  184.   while (!(SPI0_SR & SPI_SR_TCF)) {}
  185. }
  186.  
  187. static  uint8_t spiRec() {
  188.   SPI0_MCR |= SPI_MCR_CLR_RXF;
  189.   SPI0_SR = SPI_SR_TCF;
  190.   SPI0_PUSHR = 0xFF;
  191.   while (!(SPI0_SR & SPI_SR_TCF)) {}
  192.   return SPI0_POPR;
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement