Add OSD_STATE_GROUP_ELEMENTS state to osdUpdate() and optimise DMA vs polled MAX7456...
[betaflight.git] / src / main / rx / rx_spi.c
blob68f6a21f1b81fa683639e8474e71f2055d4e77b6
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #ifdef USE_RX_SPI
28 #include "build/build_config.h"
30 #include "common/utils.h"
32 #include "config/feature.h"
34 #include "drivers/io.h"
35 #include "drivers/rx/rx_spi.h"
36 #include "drivers/rx/rx_nrf24l01.h"
38 #include "config/config.h"
40 #include "pg/rx_spi.h"
42 #include "rx/rx_spi.h"
43 #include "rx/cc2500_frsky_common.h"
44 #include "rx/cc2500_redpine.h"
45 #include "rx/nrf24_cx10.h"
46 #include "rx/nrf24_syma.h"
47 #include "rx/nrf24_v202.h"
48 #include "rx/nrf24_h8_3d.h"
49 #include "rx/nrf24_inav.h"
50 #include "rx/nrf24_kn.h"
51 #include "rx/a7105_flysky.h"
52 #include "rx/cc2500_sfhss.h"
53 #include "rx/cyrf6936_spektrum.h"
54 #include "rx/expresslrs.h"
56 uint16_t rxSpiRcData[MAX_SUPPORTED_RC_CHANNEL_COUNT];
57 STATIC_UNIT_TESTED uint8_t rxSpiPayload[RX_SPI_MAX_PAYLOAD_SIZE];
58 STATIC_UNIT_TESTED uint8_t rxSpiNewPacketAvailable; // set true when a new packet is received
60 static void nullProtocolStop(void) {}
62 typedef bool (*protocolInitFnPtr)(const rxSpiConfig_t *rxSpiConfig, rxRuntimeState_t *rxRuntimeState, rxSpiExtiConfig_t *extiConfig);
63 typedef rx_spi_received_e (*protocolDataReceivedFnPtr)(uint8_t *payload);
64 typedef rx_spi_received_e (*protocolProcessFrameFnPtr)(uint8_t *payload);
65 typedef void (*protocolSetRcDataFromPayloadFnPtr)(uint16_t *rcData, const uint8_t *payload);
66 typedef void (*protocolStopFnPtr)(void);
68 static protocolInitFnPtr protocolInit;
69 static protocolDataReceivedFnPtr protocolDataReceived;
70 static protocolProcessFrameFnPtr protocolProcessFrame;
71 static protocolSetRcDataFromPayloadFnPtr protocolSetRcDataFromPayload;
72 static protocolStopFnPtr protocolStop = nullProtocolStop;
74 STATIC_UNIT_TESTED float rxSpiReadRawRC(const rxRuntimeState_t *rxRuntimeState, uint8_t channel)
76 STATIC_ASSERT(NRF24L01_MAX_PAYLOAD_SIZE <= RX_SPI_MAX_PAYLOAD_SIZE, NRF24L01_MAX_PAYLOAD_SIZE_larger_than_RX_SPI_MAX_PAYLOAD_SIZE);
78 if (channel >= rxRuntimeState->channelCount) {
79 return 0;
81 if (rxSpiNewPacketAvailable) {
82 protocolSetRcDataFromPayload(rxSpiRcData, rxSpiPayload);
83 rxSpiNewPacketAvailable = false;
85 return rxSpiRcData[channel];
88 STATIC_UNIT_TESTED bool rxSpiSetProtocol(rx_spi_protocol_e protocol)
90 switch (protocol) {
91 #ifdef USE_RX_V202
92 case RX_SPI_NRF24_V202_250K:
93 case RX_SPI_NRF24_V202_1M:
94 protocolInit = v202Nrf24Init;
95 protocolDataReceived = v202Nrf24DataReceived;
96 protocolSetRcDataFromPayload = v202Nrf24SetRcDataFromPayload;
97 break;
98 #endif
99 #ifdef USE_RX_SYMA
100 case RX_SPI_NRF24_SYMA_X:
101 case RX_SPI_NRF24_SYMA_X5C:
102 protocolInit = symaNrf24Init;
103 protocolDataReceived = symaNrf24DataReceived;
104 protocolSetRcDataFromPayload = symaNrf24SetRcDataFromPayload;
105 break;
106 #endif
107 #ifdef USE_RX_CX10
108 case RX_SPI_NRF24_CX10:
109 case RX_SPI_NRF24_CX10A:
110 protocolInit = cx10Nrf24Init;
111 protocolDataReceived = cx10Nrf24DataReceived;
112 protocolSetRcDataFromPayload = cx10Nrf24SetRcDataFromPayload;
113 break;
114 #endif
115 #ifdef USE_RX_H8_3D
116 case RX_SPI_NRF24_H8_3D:
117 protocolInit = h8_3dNrf24Init;
118 protocolDataReceived = h8_3dNrf24DataReceived;
119 protocolSetRcDataFromPayload = h8_3dNrf24SetRcDataFromPayload;
120 break;
121 #endif
122 #ifdef USE_RX_KN
123 case RX_SPI_NRF24_KN:
124 protocolInit = knNrf24Init;
125 protocolDataReceived = knNrf24DataReceived;
126 protocolSetRcDataFromPayload = knNrf24SetRcDataFromPayload;
127 break;
128 #endif
129 #ifdef USE_RX_INAV
130 case RX_SPI_NRF24_INAV:
131 protocolInit = inavNrf24Init;
132 protocolDataReceived = inavNrf24DataReceived;
133 protocolSetRcDataFromPayload = inavNrf24SetRcDataFromPayload;
134 break;
135 #endif
136 #if defined(USE_RX_FRSKY_SPI)
137 #if defined(USE_RX_FRSKY_SPI_D)
138 case RX_SPI_FRSKY_D:
139 #endif
140 #if defined(USE_RX_FRSKY_SPI_X)
141 case RX_SPI_FRSKY_X:
142 case RX_SPI_FRSKY_X_LBT:
143 case RX_SPI_FRSKY_X_V2:
144 case RX_SPI_FRSKY_X_LBT_V2:
145 protocolInit = frSkySpiInit;
146 protocolDataReceived = frSkySpiDataReceived;
147 protocolSetRcDataFromPayload = frSkySpiSetRcData;
148 protocolProcessFrame = frSkySpiProcessFrame;
149 break;
150 #endif
151 #if defined(USE_RX_REDPINE_SPI)
152 case RX_SPI_REDPINE:
153 protocolInit = redpineSpiInit;
154 protocolDataReceived = redpineSpiDataReceived;
155 protocolSetRcDataFromPayload = redpineSetRcData;
156 break;
157 #endif
159 #endif // USE_RX_FRSKY_SPI
160 #ifdef USE_RX_FLYSKY
161 case RX_SPI_A7105_FLYSKY:
162 case RX_SPI_A7105_FLYSKY_2A:
163 protocolInit = flySkyInit;
164 protocolDataReceived = flySkyDataReceived;
165 protocolSetRcDataFromPayload = flySkySetRcDataFromPayload;
166 break;
167 #endif
168 #ifdef USE_RX_SFHSS_SPI
169 case RX_SPI_SFHSS:
170 protocolInit = sfhssSpiInit;
171 protocolDataReceived = sfhssSpiDataReceived;
172 protocolSetRcDataFromPayload = sfhssSpiSetRcData;
173 break;
174 #endif
175 #ifdef USE_RX_SPEKTRUM
176 case RX_SPI_CYRF6936_DSM:
177 protocolInit = spektrumSpiInit;
178 protocolDataReceived = spektrumSpiDataReceived;
179 protocolSetRcDataFromPayload = spektrumSpiSetRcDataFromPayload;
180 break;
181 #endif
182 #ifdef USE_RX_EXPRESSLRS
183 case RX_SPI_EXPRESSLRS:
184 protocolInit = expressLrsSpiInit;
185 protocolDataReceived = expressLrsDataReceived;
186 protocolSetRcDataFromPayload = expressLrsSetRcDataFromPayload;
187 protocolStop = expressLrsStop;
188 break;
189 #endif
190 default:
191 return false;
194 return true;
198 * Returns true if the RX has received new data.
199 * Called from updateRx in rx.c, updateRx called from taskUpdateRxCheck.
200 * If taskUpdateRxCheck returns true, then taskUpdateRxMain will shortly be called.
202 static uint8_t rxSpiFrameStatus(rxRuntimeState_t *rxRuntimeState)
204 UNUSED(rxRuntimeState);
206 uint8_t status = RX_FRAME_PENDING;
208 rx_spi_received_e result = protocolDataReceived(rxSpiPayload);
210 if (result & RX_SPI_RECEIVED_DATA) {
211 rxSpiNewPacketAvailable = true;
212 status = RX_FRAME_COMPLETE;
215 if (result & RX_SPI_ROCESSING_REQUIRED) {
216 status |= RX_FRAME_PROCESSING_REQUIRED;
219 return status;
222 static bool rxSpiProcessFrame(const rxRuntimeState_t *rxRuntimeState)
224 UNUSED(rxRuntimeState);
226 if (protocolProcessFrame) {
227 rx_spi_received_e result = protocolProcessFrame(rxSpiPayload);
229 if (result & RX_SPI_RECEIVED_DATA) {
230 rxSpiNewPacketAvailable = true;
233 if (result & RX_SPI_ROCESSING_REQUIRED) {
234 return false;
238 return true;
242 * Set and initialize the RX protocol
244 bool rxSpiInit(const rxSpiConfig_t *rxSpiConfig, rxRuntimeState_t *rxRuntimeState)
246 bool ret = false;
248 if (!rxSpiDeviceInit(rxSpiConfig)) {
249 return false;
252 if (!rxSpiSetProtocol(rxSpiConfig->rx_spi_protocol)) {
253 return false;
256 rxSpiExtiConfig_t extiConfig = {
257 .ioConfig = IOCFG_IN_FLOATING,
258 .trigger = BETAFLIGHT_EXTI_TRIGGER_RISING,
261 ret = protocolInit(rxSpiConfig, rxRuntimeState, &extiConfig);
263 if (rxSpiExtiConfigured()) {
264 rxSpiExtiInit(extiConfig.ioConfig, extiConfig.trigger);
266 rxRuntimeState->rcFrameTimeUsFn = rxSpiGetLastExtiTimeUs;
269 rxSpiNewPacketAvailable = false;
270 rxRuntimeState->rxRefreshRate = 20000;
272 rxRuntimeState->rcReadRawFn = rxSpiReadRawRC;
273 rxRuntimeState->rcFrameStatusFn = rxSpiFrameStatus;
274 rxRuntimeState->rcProcessFrameFn = rxSpiProcessFrame;
276 return ret;
279 void rxSpiStop(void)
281 protocolStop();
284 #endif