PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
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.

167 lines
4.4KB

  1. // RHHardwareSPI1.h
  2. // Author: Mike McCauley (mikem@airspayce.com)
  3. // Copyright (C) 2011 Mike McCauley
  4. // Contributed by Joanna Rutkowska
  5. // $Id: RHHardwareSPI1.cpp,v 1.16 2016/07/07 00:02:53 mikem Exp mikem $
  6. // This is a copy of the standard SPI node, that is hopefully setup to work on those processors
  7. // who have SPI1. Currently I only have it setup for Teensy 3.5/3.6 and LC
  8. #if defined(__arm__) && defined(TEENSYDUINO) && (defined(KINETISL) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1052__)|| defined(__IMXRT1062__))
  9. #include <RHHardwareSPI1.h>
  10. // Declare a single default instance of the hardware SPI interface class
  11. RHHardwareSPI1 hardware_spi1;
  12. #ifdef RH_HAVE_HARDWARE_SPI
  13. RHHardwareSPI1::RHHardwareSPI1(Frequency frequency, BitOrder bitOrder, DataMode dataMode)
  14. :
  15. RHGenericSPI(frequency, bitOrder, dataMode)
  16. {
  17. }
  18. uint8_t RHHardwareSPI1::transfer(uint8_t data)
  19. {
  20. return SPI1.transfer(data);
  21. }
  22. void RHHardwareSPI1::attachInterrupt()
  23. {
  24. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO)
  25. SPI1.attachInterrupt();
  26. #endif
  27. }
  28. void RHHardwareSPI1::detachInterrupt()
  29. {
  30. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO)
  31. SPI1.detachInterrupt();
  32. #endif
  33. }
  34. void RHHardwareSPI1::begin()
  35. {
  36. // Sigh: there are no common symbols for some of these SPI options across all platforms
  37. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) || (RH_PLATFORM == RH_PLATFORM_UNO32) || (RH_PLATFORM == RH_PLATFORM_CHIPKIT_CORE)
  38. uint8_t dataMode;
  39. if (_dataMode == DataMode0)
  40. dataMode = SPI_MODE0;
  41. else if (_dataMode == DataMode1)
  42. dataMode = SPI_MODE1;
  43. else if (_dataMode == DataMode2)
  44. dataMode = SPI_MODE2;
  45. else if (_dataMode == DataMode3)
  46. dataMode = SPI_MODE3;
  47. else
  48. dataMode = SPI_MODE0;
  49. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined(__arm__) && defined(CORE_TEENSY)
  50. // Temporary work-around due to problem where avr_emulation.h does not work properly for the setDataMode() cal
  51. SPCR &= ~SPI_MODE_MASK;
  52. #else
  53. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined (__arm__) && defined(ARDUINO_ARCH_SAMD)
  54. // Zero requires begin() before anything else :-)
  55. SPI1.begin();
  56. #endif
  57. SPI1.setDataMode(dataMode);
  58. #endif
  59. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined(SPI_HAS_TRANSACTION)
  60. uint32_t frequency32;
  61. if (_frequency == Frequency16MHz) {
  62. frequency32 = 16000000;
  63. } else if (_frequency == Frequency8MHz) {
  64. frequency32 = 8000000;
  65. } else if (_frequency == Frequency4MHz) {
  66. frequency32 = 4000000;
  67. } else if (_frequency == Frequency2MHz) {
  68. frequency32 = 2000000;
  69. } else {
  70. frequency32 = 1000000;
  71. }
  72. _settings = SPISettings(frequency32,
  73. (_bitOrder == BitOrderLSBFirst) ? LSBFIRST : MSBFIRST,
  74. dataMode);
  75. #endif
  76. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined (__arm__) && (defined(ARDUINO_SAM_DUE) || defined(ARDUINO_ARCH_SAMD))
  77. // Arduino Due in 1.5.5 has its own BitOrder :-(
  78. // So too does Arduino Zero
  79. ::BitOrder bitOrder;
  80. #else
  81. uint8_t bitOrder;
  82. #endif
  83. if (_bitOrder == BitOrderLSBFirst)
  84. bitOrder = LSBFIRST;
  85. else
  86. bitOrder = MSBFIRST;
  87. SPI1.setBitOrder(bitOrder);
  88. uint8_t divider;
  89. switch (_frequency)
  90. {
  91. case Frequency1MHz:
  92. default:
  93. #if F_CPU == 8000000
  94. divider = SPI_CLOCK_DIV8;
  95. #else
  96. divider = SPI_CLOCK_DIV16;
  97. #endif
  98. break;
  99. case Frequency2MHz:
  100. #if F_CPU == 8000000
  101. divider = SPI_CLOCK_DIV4;
  102. #else
  103. divider = SPI_CLOCK_DIV8;
  104. #endif
  105. break;
  106. case Frequency4MHz:
  107. #if F_CPU == 8000000
  108. divider = SPI_CLOCK_DIV2;
  109. #else
  110. divider = SPI_CLOCK_DIV4;
  111. #endif
  112. break;
  113. case Frequency8MHz:
  114. divider = SPI_CLOCK_DIV2; // 4MHz on an 8MHz Arduino
  115. break;
  116. case Frequency16MHz:
  117. divider = SPI_CLOCK_DIV2; // Not really 16MHz, only 8MHz. 4MHz on an 8MHz Arduino
  118. break;
  119. }
  120. SPI1.setClockDivider(divider);
  121. SPI1.begin();
  122. // Teensy requires it to be set _after_ begin()
  123. SPI1.setClockDivider(divider);
  124. #else
  125. #warning RHHardwareSPI does not support this platform yet. Consider adding it and contributing a patch.
  126. #endif
  127. }
  128. void RHHardwareSPI1::end()
  129. {
  130. return SPI1.end();
  131. }
  132. // If our platform is arduino and we support transactions then lets use the begin/end transaction
  133. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO) && defined(SPI_HAS_TRANSACTION)
  134. void RHHardwareSPI1::beginTransaction()
  135. {
  136. SPI1.beginTransaction(_settings);
  137. }
  138. void RHHardwareSPI1::endTransaction()
  139. {
  140. SPI1.endTransaction();
  141. }
  142. #endif
  143. #endif
  144. #endif