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/>.
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"
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
) {
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
)
79 case RX_SPI_NRF24_V202_250K
:
80 case RX_SPI_NRF24_V202_1M
:
81 protocolInit
= v202Nrf24Init
;
82 protocolDataReceived
= v202Nrf24DataReceived
;
83 protocolSetRcDataFromPayload
= v202Nrf24SetRcDataFromPayload
;
87 case RX_SPI_NRF24_SYMA_X
:
88 case RX_SPI_NRF24_SYMA_X5C
:
89 protocolInit
= symaNrf24Init
;
90 protocolDataReceived
= symaNrf24DataReceived
;
91 protocolSetRcDataFromPayload
= symaNrf24SetRcDataFromPayload
;
95 case RX_SPI_NRF24_CX10
:
96 case RX_SPI_NRF24_CX10A
:
97 protocolInit
= cx10Nrf24Init
;
98 protocolDataReceived
= cx10Nrf24DataReceived
;
99 protocolSetRcDataFromPayload
= cx10Nrf24SetRcDataFromPayload
;
103 case RX_SPI_NRF24_H8_3D
:
104 protocolInit
= h8_3dNrf24Init
;
105 protocolDataReceived
= h8_3dNrf24DataReceived
;
106 protocolSetRcDataFromPayload
= h8_3dNrf24SetRcDataFromPayload
;
110 case RX_SPI_NRF24_KN
:
111 protocolInit
= knNrf24Init
;
112 protocolDataReceived
= knNrf24DataReceived
;
113 protocolSetRcDataFromPayload
= knNrf24SetRcDataFromPayload
;
117 case RX_SPI_NRF24_INAV
:
118 protocolInit
= inavNrf24Init
;
119 protocolDataReceived
= inavNrf24DataReceived
;
120 protocolSetRcDataFromPayload
= inavNrf24SetRcDataFromPayload
;
123 #if defined(USE_RX_FRSKY_SPI)
124 #if defined(USE_RX_FRSKY_SPI_D)
127 #if defined(USE_RX_FRSKY_SPI_X)
130 protocolInit
= frSkySpiInit
;
131 protocolDataReceived
= frSkySpiDataReceived
;
132 protocolSetRcDataFromPayload
= frSkySpiSetRcData
;
135 #endif // USE_RX_FRSKY_SPI
137 case RX_SPI_A7105_FLYSKY
:
138 case RX_SPI_A7105_FLYSKY_2A
:
139 protocolInit
= flySkyInit
;
140 protocolDataReceived
= flySkyDataReceived
;
141 protocolSetRcDataFromPayload
= flySkySetRcDataFromPayload
;
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
)
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
;