If RSSI Channel is set to Disabled when using S.Bus then generate RSS… (#5090)
[betaflight.git] / src / main / rx / rx_spi.c
blob33c1990a242be3ad52148900ffb5e8037bb4f59d
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stdbool.h>
19 #include <stdint.h>
21 #include <platform.h>
23 #ifdef USE_RX_SPI
25 #include "build/build_config.h"
27 #include "common/utils.h"
29 #include "config/feature.h"
31 #include "drivers/rx/rx_spi.h"
32 #include "drivers/rx/rx_nrf24l01.h"
34 #include "fc/config.h"
36 #include "rx/rx.h"
37 #include "rx/rx_spi.h"
38 #include "rx/cc2500_frsky_common.h"
39 #include "rx/nrf24_cx10.h"
40 #include "rx/nrf24_syma.h"
41 #include "rx/nrf24_v202.h"
42 #include "rx/nrf24_h8_3d.h"
43 #include "rx/nrf24_inav.h"
44 #include "rx/nrf24_kn.h"
45 #include "rx/flysky.h"
48 uint16_t rxSpiRcData[MAX_SUPPORTED_RC_CHANNEL_COUNT];
49 STATIC_UNIT_TESTED uint8_t rxSpiPayload[RX_SPI_MAX_PAYLOAD_SIZE];
50 STATIC_UNIT_TESTED uint8_t rxSpiNewPacketAvailable; // set true when a new packet is received
52 typedef bool (*protocolInitFnPtr)(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig);
53 typedef rx_spi_received_e (*protocolDataReceivedFnPtr)(uint8_t *payload);
54 typedef void (*protocolSetRcDataFromPayloadFnPtr)(uint16_t *rcData, const uint8_t *payload);
56 static protocolInitFnPtr protocolInit;
57 static protocolDataReceivedFnPtr protocolDataReceived;
58 static protocolSetRcDataFromPayloadFnPtr protocolSetRcDataFromPayload;
60 STATIC_UNIT_TESTED uint16_t rxSpiReadRawRC(const rxRuntimeConfig_t *rxRuntimeConfig, uint8_t channel)
62 BUILD_BUG_ON(NRF24L01_MAX_PAYLOAD_SIZE > RX_SPI_MAX_PAYLOAD_SIZE);
64 if (channel >= rxRuntimeConfig->channelCount) {
65 return 0;
67 if (rxSpiNewPacketAvailable) {
68 protocolSetRcDataFromPayload(rxSpiRcData, rxSpiPayload);
69 rxSpiNewPacketAvailable = false;
71 return rxSpiRcData[channel];
74 STATIC_UNIT_TESTED bool rxSpiSetProtocol(rx_spi_protocol_e protocol)
76 switch (protocol) {
77 default:
78 #ifdef USE_RX_V202
79 case RX_SPI_NRF24_V202_250K:
80 case RX_SPI_NRF24_V202_1M:
81 protocolInit = v202Nrf24Init;
82 protocolDataReceived = v202Nrf24DataReceived;
83 protocolSetRcDataFromPayload = v202Nrf24SetRcDataFromPayload;
84 break;
85 #endif
86 #ifdef USE_RX_SYMA
87 case RX_SPI_NRF24_SYMA_X:
88 case RX_SPI_NRF24_SYMA_X5C:
89 protocolInit = symaNrf24Init;
90 protocolDataReceived = symaNrf24DataReceived;
91 protocolSetRcDataFromPayload = symaNrf24SetRcDataFromPayload;
92 break;
93 #endif
94 #ifdef USE_RX_CX10
95 case RX_SPI_NRF24_CX10:
96 case RX_SPI_NRF24_CX10A:
97 protocolInit = cx10Nrf24Init;
98 protocolDataReceived = cx10Nrf24DataReceived;
99 protocolSetRcDataFromPayload = cx10Nrf24SetRcDataFromPayload;
100 break;
101 #endif
102 #ifdef USE_RX_H8_3D
103 case RX_SPI_NRF24_H8_3D:
104 protocolInit = h8_3dNrf24Init;
105 protocolDataReceived = h8_3dNrf24DataReceived;
106 protocolSetRcDataFromPayload = h8_3dNrf24SetRcDataFromPayload;
107 break;
108 #endif
109 #ifdef USE_RX_KN
110 case RX_SPI_NRF24_KN:
111 protocolInit = knNrf24Init;
112 protocolDataReceived = knNrf24DataReceived;
113 protocolSetRcDataFromPayload = knNrf24SetRcDataFromPayload;
114 break;
115 #endif
116 #ifdef USE_RX_INAV
117 case RX_SPI_NRF24_INAV:
118 protocolInit = inavNrf24Init;
119 protocolDataReceived = inavNrf24DataReceived;
120 protocolSetRcDataFromPayload = inavNrf24SetRcDataFromPayload;
121 break;
122 #endif
123 #if defined(USE_RX_FRSKY_SPI)
124 #if defined(USE_RX_FRSKY_SPI_D)
125 case RX_SPI_FRSKY_D:
126 #endif
127 #if defined(USE_RX_FRSKY_SPI_X)
128 case RX_SPI_FRSKY_X:
129 #endif
130 protocolInit = frSkySpiInit;
131 protocolDataReceived = frSkySpiDataReceived;
132 protocolSetRcDataFromPayload = frSkySpiSetRcData;
134 break;
135 #endif // USE_RX_FRSKY_SPI
136 #ifdef USE_RX_FLYSKY
137 case RX_SPI_A7105_FLYSKY:
138 case RX_SPI_A7105_FLYSKY_2A:
139 protocolInit = flySkyInit;
140 protocolDataReceived = flySkyDataReceived;
141 protocolSetRcDataFromPayload = flySkySetRcDataFromPayload;
142 break;
143 #endif
145 return true;
149 * Returns true if the RX has received new data.
150 * Called from updateRx in rx.c, updateRx called from taskUpdateRxCheck.
151 * If taskUpdateRxCheck returns true, then taskUpdateRxMain will shortly be called.
153 static uint8_t rxSpiFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
155 UNUSED(rxRuntimeConfig);
157 if (protocolDataReceived(rxSpiPayload) == RX_SPI_RECEIVED_DATA) {
158 rxSpiNewPacketAvailable = true;
159 return RX_FRAME_COMPLETE;
161 return RX_FRAME_PENDING;
165 * Set and initialize the RX protocol
167 bool rxSpiInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig)
169 bool ret = false;
171 const rx_spi_type_e spiType = feature(FEATURE_SOFTSPI) ? RX_SPI_SOFTSPI : RX_SPI_HARDSPI;
172 rxSpiDeviceInit(spiType);
173 if (rxSpiSetProtocol(rxConfig->rx_spi_protocol)) {
174 ret = protocolInit(rxConfig, rxRuntimeConfig);
176 rxSpiNewPacketAvailable = false;
177 rxRuntimeConfig->rxRefreshRate = 20000;
179 rxRuntimeConfig->rcReadRawFn = rxSpiReadRawRC;
180 rxRuntimeConfig->rcFrameStatusFn = rxSpiFrameStatus;
182 return ret;
184 #endif