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.

RHGenericSPI.h 6.1KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // RHGenericSPI.h
  2. // Author: Mike McCauley (mikem@airspayce.com)
  3. // Copyright (C) 2011 Mike McCauley
  4. // Contributed by Joanna Rutkowska
  5. // $Id: RHGenericSPI.h,v 1.7 2014/04/14 08:37:11 mikem Exp $
  6. #ifndef RHGenericSPI_h
  7. #define RHGenericSPI_h
  8. #include <RadioHead.h>
  9. #if (RH_PLATFORM == RH_PLATFORM_ARDUINO)
  10. #include <SPI.h> // for SPI_HAS_TRANSACTION and SPISettings
  11. #endif
  12. /////////////////////////////////////////////////////////////////////
  13. /// \class RHGenericSPI RHGenericSPI.h <RHGenericSPI.h>
  14. /// \brief Base class for SPI interfaces
  15. ///
  16. /// This generic abstract class is used to encapsulate hardware or software SPI interfaces for
  17. /// a variety of platforms.
  18. /// The intention is so that driver classes can be configured to use hardware or software SPI
  19. /// without changing the main code.
  20. ///
  21. /// You must provide a subclass of this class to driver constructors that require SPI.
  22. /// A concrete subclass that encapsualates the standard Arduino hardware SPI and a bit-banged
  23. /// software implementation is included.
  24. ///
  25. /// Do not directly use this class: it must be subclassed and the following abstract functions at least
  26. /// must be implmented:
  27. /// - begin()
  28. /// - end()
  29. /// - transfer()
  30. class RHGenericSPI
  31. {
  32. public:
  33. /// \brief Defines constants for different SPI modes
  34. ///
  35. /// Defines constants for different SPI modes
  36. /// that can be passed to the constructor or setMode()
  37. /// We need to define these in a device and platform independent way, because the
  38. /// SPI implementation is different on each platform.
  39. typedef enum
  40. {
  41. DataMode0 = 0, ///< SPI Mode 0: CPOL = 0, CPHA = 0
  42. DataMode1, ///< SPI Mode 1: CPOL = 0, CPHA = 1
  43. DataMode2, ///< SPI Mode 2: CPOL = 1, CPHA = 0
  44. DataMode3, ///< SPI Mode 3: CPOL = 1, CPHA = 1
  45. } DataMode;
  46. /// \brief Defines constants for different SPI bus frequencies
  47. ///
  48. /// Defines constants for different SPI bus frequencies
  49. /// that can be passed to setFrequency().
  50. /// The frequency you get may not be exactly the one according to the name.
  51. /// We need to define these in a device and platform independent way, because the
  52. /// SPI implementation is different on each platform.
  53. typedef enum
  54. {
  55. Frequency1MHz = 0, ///< SPI bus frequency close to 1MHz
  56. Frequency2MHz, ///< SPI bus frequency close to 2MHz
  57. Frequency4MHz, ///< SPI bus frequency close to 4MHz
  58. Frequency8MHz, ///< SPI bus frequency close to 8MHz
  59. Frequency16MHz ///< SPI bus frequency close to 16MHz
  60. } Frequency;
  61. /// \brief Defines constants for different SPI endianness
  62. ///
  63. /// Defines constants for different SPI endianness
  64. /// that can be passed to setBitOrder()
  65. /// We need to define these in a device and platform independent way, because the
  66. /// SPI implementation is different on each platform.
  67. typedef enum
  68. {
  69. BitOrderMSBFirst = 0, ///< SPI MSB first
  70. BitOrderLSBFirst, ///< SPI LSB first
  71. } BitOrder;
  72. /// Constructor
  73. /// Creates an instance of an abstract SPI interface.
  74. /// Do not use this contructor directly: you must instead use on of the concrete subclasses provided
  75. /// such as RHHardwareSPI or RHSoftwareSPI
  76. /// \param[in] frequency One of RHGenericSPI::Frequency to select the SPI bus frequency. The frequency
  77. /// is mapped to the closest available bus frequency on the platform.
  78. /// \param[in] bitOrder Select the SPI bus bit order, one of RHGenericSPI::BitOrderMSBFirst or
  79. /// RHGenericSPI::BitOrderLSBFirst.
  80. /// \param[in] dataMode Selects the SPI bus data mode. One of RHGenericSPI::DataMode
  81. RHGenericSPI(Frequency frequency = Frequency1MHz, BitOrder bitOrder = BitOrderMSBFirst, DataMode dataMode = DataMode0);
  82. /// Transfer a single octet to and from the SPI interface
  83. /// \param[in] data The octet to send
  84. /// \return The octet read from SPI while the data octet was sent
  85. virtual uint8_t transfer(uint8_t data) = 0;
  86. /// SPI Configuration methods
  87. /// Enable SPI interrupts (if supported)
  88. /// This can be used in an SPI slave to indicate when an SPI message has been received
  89. virtual void attachInterrupt() {};
  90. /// Disable SPI interrupts (if supported)
  91. /// This can be used to diable the SPI interrupt in slaves where that is supported.
  92. virtual void detachInterrupt() {};
  93. /// Initialise the SPI library.
  94. /// Call this after configuring and before using the SPI library
  95. virtual void begin() = 0;
  96. /// Disables the SPI bus (leaving pin modes unchanged).
  97. /// Call this after you have finished using the SPI interface
  98. virtual void end() = 0;
  99. /// Sets the bit order the SPI interface will use
  100. /// Sets the order of the bits shifted out of and into the SPI bus, either
  101. /// LSBFIRST (least-significant bit first) or MSBFIRST (most-significant bit first).
  102. /// \param[in] bitOrder Bit order to be used: one of RHGenericSPI::BitOrder
  103. virtual void setBitOrder(BitOrder bitOrder);
  104. /// Sets the SPI data mode: that is, clock polarity and phase.
  105. /// See the Wikipedia article on SPI for details.
  106. /// \param[in] dataMode The mode to use: one of RHGenericSPI::DataMode
  107. virtual void setDataMode(DataMode dataMode);
  108. /// Sets the SPI clock divider relative to the system clock.
  109. /// On AVR based boards, the dividers available are 2, 4, 8, 16, 32, 64 or 128.
  110. /// The default setting is SPI_CLOCK_DIV4, which sets the SPI clock to one-quarter
  111. /// the frequency of the system clock (4 Mhz for the boards at 16 MHz).
  112. /// \param[in] frequency The data rate to use: one of RHGenericSPI::Frequency
  113. virtual void setFrequency(Frequency frequency);
  114. // Try to add SPI Transaction support
  115. // Note: Maybe add some way to set SPISettings?
  116. virtual void beginTransaction() {};
  117. virtual void endTransaction() {};
  118. protected:
  119. /// The configure SPI Bus frequency, one of RHGenericSPI::Frequency
  120. Frequency _frequency; // Bus frequency, one of RHGenericSPI::Frequency
  121. /// Bit order, one of RHGenericSPI::BitOrder
  122. BitOrder _bitOrder;
  123. /// SPI bus mode, one of RHGenericSPI::DataMode
  124. DataMode _dataMode;
  125. };
  126. #endif