You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 line
4.3KB

  1. /*
  2. * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
  3. * SPI Master library for arduino.
  4. *
  5. * This file is free software; you can redistribute it and/or modify
  6. * it under the terms of either the GNU General Public License version 2
  7. * or the GNU Lesser General Public License version 2.1, both as
  8. * published by the Free Software Foundation.
  9. */
  10. #include "SPI.h"
  11. #include "pins_arduino.h"
  12. SPIClass SPI;
  13. uint8_t SPIClass::interruptMode = 0;
  14. uint8_t SPIClass::interruptMask = 0;
  15. uint8_t SPIClass::interruptSave = 0;
  16. void SPIClass::begin()
  17. {
  18. #if defined(__AVR__)
  19. // Set SS to high so a connected chip will be "deselected" by default
  20. digitalWrite(SS, HIGH);
  21. // When the SS pin is set as OUTPUT, it can be used as
  22. // a general purpose output port (it doesn't influence
  23. // SPI operations).
  24. pinMode(SS, OUTPUT);
  25. // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  26. // automatically switches to Slave, so the data direction of
  27. // the SS pin MUST be kept as OUTPUT.
  28. SPCR |= _BV(MSTR);
  29. SPCR |= _BV(SPE);
  30. // Set direction register for SCK and MOSI pin.
  31. // MISO pin automatically overrides to INPUT.
  32. // By doing this AFTER enabling SPI, we avoid accidentally
  33. // clocking in a single bit since the lines go directly
  34. // from "input" to SPI control.
  35. // http://code.google.com/p/arduino/issues/detail?id=888
  36. pinMode(SCK, OUTPUT);
  37. pinMode(MOSI, OUTPUT);
  38. #elif defined(__arm__) && defined(TEENSYDUINO)
  39. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  40. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  41. SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  42. SPI0_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  43. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  44. SPCR.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  45. #endif
  46. }
  47. void SPIClass::end() {
  48. #if defined(__AVR__)
  49. SPCR &= ~_BV(SPE);
  50. #elif defined(__arm__) && defined(TEENSYDUINO)
  51. SPCR.disable_pins();
  52. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  53. #endif
  54. }
  55. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  56. {
  57. uint8_t mask;
  58. if (interruptMode > 1) return;
  59. noInterrupts();
  60. switch (interruptNumber) {
  61. #ifdef SPI_INT0_MASK
  62. case 0: mask = SPI_INT0_MASK; break;
  63. #endif
  64. #ifdef SPI_INT1_MASK
  65. case 1: mask = SPI_INT1_MASK; break;
  66. #endif
  67. #ifdef SPI_INT2_MASK
  68. case 2: mask = SPI_INT2_MASK; break;
  69. #endif
  70. #ifdef SPI_INT3_MASK
  71. case 3: mask = SPI_INT3_MASK; break;
  72. #endif
  73. #ifdef SPI_INT4_MASK
  74. case 4: mask = SPI_INT4_MASK; break;
  75. #endif
  76. #ifdef SPI_INT5_MASK
  77. case 5: mask = SPI_INT5_MASK; break;
  78. #endif
  79. #ifdef SPI_INT6_MASK
  80. case 6: mask = SPI_INT6_MASK; break;
  81. #endif
  82. #ifdef SPI_INT7_MASK
  83. case 7: mask = SPI_INT7_MASK; break;
  84. #endif
  85. default:
  86. interruptMode = 2;
  87. interrupts();
  88. return;
  89. }
  90. interruptMode = 1;
  91. interruptMask |= mask;
  92. interrupts();
  93. }
  94. #if defined(__arm__) && defined(TEENSYDUINO)
  95. const uint16_t SPISettings::ctar_div_table[23] = {
  96. 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40,
  97. 56, 64, 96, 128, 192, 256, 384, 512, 640, 768
  98. };
  99. const uint32_t SPISettings::ctar_clock_table[23] = {
  100. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  101. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  102. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  103. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  104. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  105. SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  106. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  107. SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  108. SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  109. SPI_CTAR_PBR(2) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(0),
  110. SPI_CTAR_PBR(1) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  111. SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(3),
  112. SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  113. SPI_CTAR_PBR(3) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  114. SPI_CTAR_PBR(0) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  115. SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  116. SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  117. SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  118. SPI_CTAR_PBR(0) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  119. SPI_CTAR_PBR(1) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  120. SPI_CTAR_PBR(0) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7),
  121. SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  122. SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7)
  123. };
  124. #endif