RadioHead
RHGenericSPI.h
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.9 2020/01/05 07:02:23 mikem Exp $
6
7#ifndef RHGenericSPI_h
8#define RHGenericSPI_h
9
10#include <RadioHead.h>
11
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 implemented:
27/// - begin()
28/// - end()
29/// - transfer()
31{
32public:
33
34 /// \brief Defines constants for different SPI modes
35 ///
36 /// Defines constants for different SPI modes
37 /// that can be passed to the constructor or setMode()
38 /// We need to define these in a device and platform independent way, because the
39 /// SPI implementation is different on each platform.
40 typedef enum
41 {
42 DataMode0 = 0, ///< SPI Mode 0: CPOL = 0, CPHA = 0
43 DataMode1, ///< SPI Mode 1: CPOL = 0, CPHA = 1
44 DataMode2, ///< SPI Mode 2: CPOL = 1, CPHA = 0
45 DataMode3, ///< SPI Mode 3: CPOL = 1, CPHA = 1
46 } DataMode;
47
48 /// \brief Defines constants for different SPI bus frequencies
49 ///
50 /// Defines constants for different SPI bus frequencies
51 /// that can be passed to setFrequency().
52 /// The frequency you get may not be exactly the one according to the name.
53 /// We need to define these in a device and platform independent way, because the
54 /// SPI implementation is different on each platform.
55 typedef enum
56 {
57 Frequency1MHz = 0, ///< SPI bus frequency close to 1MHz
58 Frequency2MHz, ///< SPI bus frequency close to 2MHz
59 Frequency4MHz, ///< SPI bus frequency close to 4MHz
60 Frequency8MHz, ///< SPI bus frequency close to 8MHz
61 Frequency16MHz ///< SPI bus frequency close to 16MHz
63
64 /// \brief Defines constants for different SPI endianness
65 ///
66 /// Defines constants for different SPI endianness
67 /// that can be passed to setBitOrder()
68 /// We need to define these in a device and platform independent way, because the
69 /// SPI implementation is different on each platform.
70 typedef enum
71 {
72 BitOrderMSBFirst = 0, ///< SPI MSB first
73 BitOrderLSBFirst, ///< SPI LSB first
74 } BitOrder;
75
76 /// Constructor
77 /// Creates an instance of an abstract SPI interface.
78 /// Do not use this contructor directly: you must instead use on of the concrete subclasses provided
79 /// such as RHHardwareSPI or RHSoftwareSPI
80 /// \param[in] frequency One of RHGenericSPI::Frequency to select the SPI bus frequency. The frequency
81 /// is mapped to the closest available bus frequency on the platform.
82 /// \param[in] bitOrder Select the SPI bus bit order, one of RHGenericSPI::BitOrderMSBFirst or
83 /// RHGenericSPI::BitOrderLSBFirst.
84 /// \param[in] dataMode Selects the SPI bus data mode. One of RHGenericSPI::DataMode
86
87 /// Transfer a single octet to and from the SPI interface
88 /// \param[in] data The octet to send
89 /// \return The octet read from SPI while the data octet was sent
90 virtual uint8_t transfer(uint8_t data) = 0;
91
92#if (RH_PLATFORM == RH_PLATFORM_MONGOOSE_OS)
93 /// Transfer up to 2 bytes on the SPI interface
94 /// \param[in] byte0 The first byte to be sent on the SPI interface
95 /// \param[in] byte1 The second byte to be sent on the SPI interface
96 /// \return The second byte clocked in as the second byte is sent.
97 virtual uint8_t transfer2B(uint8_t byte0, uint8_t byte1) = 0;
98
99 /// Read a number of bytes on the SPI interface from an NRF device
100 /// \param[in] reg The NRF device register to read
101 /// \param[out] dest The buffer to hold the bytes read
102 /// \param[in] len The number of bytes to read
103 /// \return The NRF status byte
104 virtual uint8_t spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len) = 0;
105
106 /// Wrte a number of bytes on the SPI interface to an NRF device
107 /// \param[in] reg The NRF device register to read
108 /// \param[out] src The buffer to hold the bytes write
109 /// \param[in] len The number of bytes to write
110 /// \return The NRF status byte
111 virtual uint8_t spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len) = 0;
112
113#endif
114
115 /// SPI Configuration methods
116 /// Enable SPI interrupts (if supported)
117 /// This can be used in an SPI slave to indicate when an SPI message has been received
118 virtual void attachInterrupt() {};
119
120 /// Disable SPI interrupts (if supported)
121 /// This can be used to diable the SPI interrupt in slaves where that is supported.
122 virtual void detachInterrupt() {};
123
124 /// Initialise the SPI library.
125 /// Call this after configuring and before using the SPI library
126 virtual void begin() = 0;
127
128 /// Disables the SPI bus (leaving pin modes unchanged).
129 /// Call this after you have finished using the SPI interface
130 virtual void end() = 0;
131
132 /// Sets the bit order the SPI interface will use
133 /// Sets the order of the bits shifted out of and into the SPI bus, either
134 /// LSBFIRST (least-significant bit first) or MSBFIRST (most-significant bit first).
135 /// \param[in] bitOrder Bit order to be used: one of RHGenericSPI::BitOrder
136 virtual void setBitOrder(BitOrder bitOrder);
137
138 /// Sets the SPI data mode: that is, clock polarity and phase.
139 /// See the Wikipedia article on SPI for details.
140 /// \param[in] dataMode The mode to use: one of RHGenericSPI::DataMode
141 virtual void setDataMode(DataMode dataMode);
142
143 /// Sets the SPI clock divider relative to the system clock.
144 /// On AVR based boards, the dividers available are 2, 4, 8, 16, 32, 64 or 128.
145 /// The default setting is SPI_CLOCK_DIV4, which sets the SPI clock to one-quarter
146 /// the frequency of the system clock (4 Mhz for the boards at 16 MHz).
147 /// \param[in] frequency The data rate to use: one of RHGenericSPI::Frequency
148 virtual void setFrequency(Frequency frequency);
149
150 /// Signal the start of an SPI transaction that must not be interrupted by other SPI actions
151 /// In subclasses that support transactions this will ensure that other SPI transactions
152 /// are blocked until this one is completed by endTransaction().
153 /// Base does nothing
154 /// Might be overridden in subclass
155 virtual void beginTransaction(){}
156
157 /// Signal the end of an SPI transaction
158 /// Base does nothing
159 /// Might be overridden in subclass
160 virtual void endTransaction(){}
161
162 /// Specify the interrupt number of the interrupt that will use SPI transactions
163 /// Tells the SPI support software that SPI transactions will occur with the interrupt
164 /// handler assocated with interruptNumber
165 /// Base does nothing
166 /// Might be overridden in subclass
167 /// \param[in] interruptNumber The number of the interrupt
168 virtual void usingInterrupt(uint8_t interruptNumber){
169 (void)interruptNumber;
170 }
171
172protected:
173
174 /// The configure SPI Bus frequency, one of RHGenericSPI::Frequency
175 Frequency _frequency; // Bus frequency, one of RHGenericSPI::Frequency
176
177 /// Bit order, one of RHGenericSPI::BitOrder
179
180 /// SPI bus mode, one of RHGenericSPI::DataMode
182};
183#endif
Base class for SPI interfaces.
Definition: RHGenericSPI.h:31
virtual void end()=0
Frequency _frequency
The configure SPI Bus frequency, one of RHGenericSPI::Frequency.
Definition: RHGenericSPI.h:175
DataMode _dataMode
SPI bus mode, one of RHGenericSPI::DataMode.
Definition: RHGenericSPI.h:181
virtual uint8_t transfer(uint8_t data)=0
DataMode
Defines constants for different SPI modes.
Definition: RHGenericSPI.h:41
@ DataMode0
SPI Mode 0: CPOL = 0, CPHA = 0.
Definition: RHGenericSPI.h:42
@ DataMode2
SPI Mode 2: CPOL = 1, CPHA = 0.
Definition: RHGenericSPI.h:44
@ DataMode3
SPI Mode 3: CPOL = 1, CPHA = 1.
Definition: RHGenericSPI.h:45
@ DataMode1
SPI Mode 1: CPOL = 0, CPHA = 1.
Definition: RHGenericSPI.h:43
virtual void usingInterrupt(uint8_t interruptNumber)
Definition: RHGenericSPI.h:168
BitOrder
Defines constants for different SPI endianness.
Definition: RHGenericSPI.h:71
@ BitOrderMSBFirst
SPI MSB first.
Definition: RHGenericSPI.h:72
@ BitOrderLSBFirst
SPI LSB first.
Definition: RHGenericSPI.h:73
virtual void setBitOrder(BitOrder bitOrder)
Definition: RHGenericSPI.cpp:17
RHGenericSPI(Frequency frequency=Frequency1MHz, BitOrder bitOrder=BitOrderMSBFirst, DataMode dataMode=DataMode0)
Definition: RHGenericSPI.cpp:9
virtual void setDataMode(DataMode dataMode)
Definition: RHGenericSPI.cpp:22
virtual void endTransaction()
Definition: RHGenericSPI.h:160
virtual void setFrequency(Frequency frequency)
Definition: RHGenericSPI.cpp:27
BitOrder _bitOrder
Bit order, one of RHGenericSPI::BitOrder.
Definition: RHGenericSPI.h:178
virtual void begin()=0
virtual void attachInterrupt()
Definition: RHGenericSPI.h:118
virtual void beginTransaction()
Definition: RHGenericSPI.h:155
Frequency
Defines constants for different SPI bus frequencies.
Definition: RHGenericSPI.h:56
@ Frequency8MHz
SPI bus frequency close to 8MHz.
Definition: RHGenericSPI.h:60
@ Frequency2MHz
SPI bus frequency close to 2MHz.
Definition: RHGenericSPI.h:58
@ Frequency1MHz
SPI bus frequency close to 1MHz.
Definition: RHGenericSPI.h:57
@ Frequency16MHz
SPI bus frequency close to 16MHz.
Definition: RHGenericSPI.h:61
@ Frequency4MHz
SPI bus frequency close to 4MHz.
Definition: RHGenericSPI.h:59
virtual void detachInterrupt()
Definition: RHGenericSPI.h:122