Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
cc2500.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Tom van Dijk <tomvand@users.noreply.github.com>
3  *
4  * This code is based on the betaflight cc2500 and FrskyX implementation.
5  * https://github.com/betaflight/betaflight
6  *
7  * This file is part of paparazzi.
8  *
9  * paparazzi is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2, or (at your option)
12  * any later version.
13  *
14  * paparazzi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with paparazzi; see the file COPYING. If not, write to
21  * the Free Software Foundation, 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24 
25 #include "subsystems/datalink/downlink.h" // TODO remove before PR
26 
27 #include "cc2500.h"
28 
29 #include "generated/modules.h"
30 #include "mcu_periph/sys_time.h"
31 #include "mcu_periph/spi.h"
32 
33 #include <assert.h>
34 
35 #define USE_RX_CC2500
36 
37 static struct spi_periph *cc2500_spi_p;
41 
42 
43 void cc2500_init(void) {
44  /* Set spi peripheral */
45  cc2500_spi_p = &(CC2500_SPI_DEV);
46  /* Set the spi transaction */
56  cc2500_spi_t.cdiv = SPIDiv32; // Found experimentally
58  cc2500_spi_t.slave_idx = CC2500_SPI_SLAVE_IDX;
59 }
60 
61 
63  float start = get_sys_time_float();
64  while(get_sys_time_float() < start + (us / 1.0e6)) ;
65 }
66 // Fix naming conflict with subsystems/radio_control/cc2500_frsky delayMicroseconds
67 #ifdef delayMicroseconds
68 #undef delayMicroseconds
69 #endif
70 #define delayMicroseconds(us) cc2500_delayMicroseconds(us)
71 
72 
73 static void rxSpiReadCommandMulti(uint8_t command, uint8_t commandData, uint8_t *retData, uint8_t length) {
74  // Check that the SPI transaction is not busy
75  assert(cc2500_spi_t.status == SPITransDone);
76  // Set up the transaction
77  cc2500_spi_t.output_length = 2; // command + commandData
78  cc2500_spi_t.input_length = length + 1; // STATUS BYTE + RETURN DATA
79  cc2500_spi_t.output_buf[0] = command;
80  cc2500_spi_t.output_buf[1] = commandData;
81  // Submit the transaction
83  // Spin until transaction is completed
84  while(cc2500_spi_t.status != SPITransSuccess) ; // TODO not ideal in event function...
86  // Copy the input buffer
87  for (uint8_t i = 0; i < length; ++i) {
88  retData[i] = cc2500_spi_t.input_buf[i + 1]; // Skips status byte, betaflight code does not work when this byte is included.
89  }
90 }
91 
92 static uint8_t rxSpiReadCommand(uint8_t command, uint8_t commandData) {
93  uint8_t retData; // DATA
94  rxSpiReadCommandMulti(command, commandData, &retData, 1);
95  return retData;
96 }
97 
98 
99 static void rxSpiWriteCommandMulti(uint8_t command, uint8_t *data, uint8_t length) {
100  // Check that the SPI transaction is not busy
101  assert(cc2500_spi_t.status == SPITransDone);
102  // Set up the transaction
103  cc2500_spi_t.output_length = length + 1; // command + data[length]
105  cc2500_spi_t.output_buf[0] = command;
106  // Copy the data to the output buffer
107  for (uint8_t i = 0; i < length; ++i) {
108  cc2500_spi_t.output_buf[i + 1] = data[i];
109  }
110  // Submit the transaction
112  // Spin until transaction is completed
113  while(cc2500_spi_t.status != SPITransSuccess) ; // TODO not ideal in event function...
115 }
116 
117 static void rxSpiWriteCommand(uint8_t command, uint8_t data) {
118  rxSpiWriteCommandMulti(command, &data, 1);
119 }
120 
121 static void rxSpiWriteByte(uint8_t data) {
122  rxSpiWriteCommandMulti(data, NULL, 0);
123 }
124 
125 
126 
127 // betaflight/src/main/drivers/rx/rx_cc2500.c @ 0a16f4d on Oct 1, 2018
128 
129 /*
130  * This file is part of Cleanflight and Betaflight.
131  *
132  * Cleanflight and Betaflight are free software. You can redistribute
133  * this software and/or modify this software under the terms of the
134  * GNU General Public License as published by the Free Software
135  * Foundation, either version 3 of the License, or (at your option)
136  * any later version.
137  *
138  * Cleanflight and Betaflight are distributed in the hope that they
139  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
140  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
141  * See the GNU General Public License for more details.
142  *
143  * You should have received a copy of the GNU General Public License
144  * along with this software.
145  *
146  * If not, see <http://www.gnu.org/licenses/>.
147  */
148 
149 /*
150 * CC2500 SPI drivers
151 */
152 #include <stdbool.h>
153 #include <stdint.h>
154 #include <stdlib.h>
155 
156 //#include "platform.h"
157 
158 #ifdef USE_RX_CC2500
159 
160 //#include "build/build_config.h"
161 //
162 //#include "pg/rx.h"
163 //#include "pg/rx_spi.h"
164 //
165 //#include "drivers/io.h"
166 //#include "drivers/rx/rx_spi.h"
167 //#include "drivers/system.h"
168 //#include "drivers/time.h"
169 
170 //#include "rx_cc2500.h"
171 
172 #define NOP 0xFF
173 
174 void cc2500ReadFifo(uint8_t *dpbuffer, uint8_t len)
175 {
177 // DOWNLINK_SEND_CC2500_PACKET(DefaultChannel, DefaultDevice,len, dpbuffer);
178 }
179 
180 void cc2500WriteFifo(uint8_t *dpbuffer, uint8_t len)
181 {
182  cc2500Strobe(CC2500_SFTX); // 0x3B SFTX
184  dpbuffer, len);
185  cc2500Strobe(CC2500_STX); // 0x35
186 }
187 
188 void cc2500ReadRegisterMulti(uint8_t address, uint8_t *data, uint8_t length)
189 {
190  rxSpiReadCommandMulti(address, NOP, data, length);
191 }
192 
194  uint8_t length)
195 {
196  rxSpiWriteCommandMulti(address, data, length);
197 }
198 
200 {
201  return rxSpiReadCommand(reg | 0x80, NOP);
202 }
203 
204 void cc2500Strobe(uint8_t address) { rxSpiWriteByte(address); }
205 
206 void cc2500WriteReg(uint8_t address, uint8_t data)
207 {
208  rxSpiWriteCommand(address, data);
209 }
210 
212 {
213  const uint8_t patable[8] = {
214  0xC5, // -12dbm
215  0x97, // -10dbm
216  0x6E, // -8dbm
217  0x7F, // -6dbm
218  0xA9, // -4dbm
219  0xBB, // -2dbm
220  0xFE, // 0dbm
221  0xFF // 1.5dbm
222  };
223  if (power > 7)
224  power = 7;
225  cc2500WriteReg(CC2500_3E_PATABLE, patable[power]);
226 }
227 
229 {
231  delayMicroseconds(1000); // 1000us
232  // CC2500_SetTxRxMode(TXRX_OFF);
233  // RX_EN_off;//off tx
234  // TX_EN_off;//off rx
235  return cc2500ReadReg(CC2500_0E_FREQ1) == 0xC4; // check if reset
236 }
237 #endif
spi_transaction::cdiv
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:159
spi_transaction::cpol
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:155
cc2500_spi_p
static struct spi_periph * cc2500_spi_p
Definition: cc2500.c:37
cc2500_init
void cc2500_init(void)
Definition: cc2500.c:43
cc2500_input_buf
static uint8_t cc2500_input_buf[64]
Definition: cc2500.c:39
spi_transaction::output_length
uint16_t output_length
number of data words to write
Definition: spi.h:152
get_sys_time_float
static float get_sys_time_float(void)
Get the time in seconds since startup.
Definition: sys_time.h:129
spi.h
spi_transaction
SPI transaction structure.
Definition: spi.h:148
rxSpiWriteCommandMulti
static void rxSpiWriteCommandMulti(uint8_t command, uint8_t *data, uint8_t length)
Definition: cc2500.c:99
uint32_t
unsigned long uint32_t
Definition: types.h:18
CC2500_0E_FREQ1
@ CC2500_0E_FREQ1
Definition: cc2500.h:79
SPISelectUnselect
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition: spi.h:63
SPITransSuccess
@ SPITransSuccess
Definition: spi.h:99
spi_transaction::bitorder
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:158
CC2500_SRES
#define CC2500_SRES
Definition: cc2500.h:140
cc2500Reset
uint8_t cc2500Reset(void)
Definition: cc2500.c:228
spi_transaction::output_buf
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:150
cc2500ReadRegisterMulti
void cc2500ReadRegisterMulti(uint8_t address, uint8_t *data, uint8_t length)
Definition: cc2500.c:188
spi_periph
SPI peripheral structure.
Definition: spi.h:174
spi_transaction::select
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:154
SPICphaEdge1
@ SPICphaEdge1
CPHA = 0.
Definition: spi.h:74
cc2500ReadReg
uint8_t cc2500ReadReg(uint8_t reg)
Definition: cc2500.c:199
rxSpiWriteCommand
static void rxSpiWriteCommand(uint8_t command, uint8_t data)
Definition: cc2500.c:117
SPIMSBFirst
@ SPIMSBFirst
Definition: spi.h:112
SPICpolIdleLow
@ SPICpolIdleLow
CPOL = 0.
Definition: spi.h:83
CC2500_SFTX
#define CC2500_SFTX
Definition: cc2500.h:162
cc2500_delayMicroseconds
static void cc2500_delayMicroseconds(uint32_t us)
Definition: cc2500.c:62
spi_transaction::cpha
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:156
spi_submit
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition: spi_arch.c:511
sys_time.h
Architecture independent timing functions.
uint8_t
unsigned char uint8_t
Definition: types.h:14
cc2500WriteFifo
void cc2500WriteFifo(uint8_t *dpbuffer, uint8_t len)
Definition: cc2500.c:180
rxSpiWriteByte
static void rxSpiWriteByte(uint8_t data)
Definition: cc2500.c:121
cc2500Strobe
void cc2500Strobe(uint8_t address)
Definition: cc2500.c:204
SPIDss8bit
@ SPIDss8bit
Definition: spi.h:90
SPIDiv32
@ SPIDiv32
Definition: spi.h:124
CC2500_READ_BURST
#define CC2500_READ_BURST
Definition: cc2500.h:137
delayMicroseconds
#define delayMicroseconds(us)
Definition: cc2500.c:70
spi_transaction::input_length
uint16_t input_length
number of data words to read
Definition: spi.h:151
cc2500SetPower
void cc2500SetPower(uint8_t power)
Definition: cc2500.c:211
spi_transaction::dss
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:157
spi_transaction::slave_idx
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:153
cc2500_output_buf
static uint8_t cc2500_output_buf[64]
Definition: cc2500.c:40
CC2500_WRITE_BURST
#define CC2500_WRITE_BURST
Definition: cc2500.h:135
rxSpiReadCommand
static uint8_t rxSpiReadCommand(uint8_t command, uint8_t commandData)
Definition: cc2500.c:92
SPITransDone
@ SPITransDone
Definition: spi.h:101
CC2500_3E_PATABLE
@ CC2500_3E_PATABLE
Definition: cc2500.h:128
spi_transaction::input_buf
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:149
cc2500WriteRegisterMulti
void cc2500WriteRegisterMulti(uint8_t address, uint8_t *data, uint8_t length)
Definition: cc2500.c:193
CC2500_STX
#define CC2500_STX
Definition: cc2500.h:151
cc2500WriteReg
void cc2500WriteReg(uint8_t address, uint8_t data)
Definition: cc2500.c:206
cc2500ReadFifo
void cc2500ReadFifo(uint8_t *dpbuffer, uint8_t len)
Definition: cc2500.c:174
cc2500_spi_t
static struct spi_transaction cc2500_spi_t
Definition: cc2500.c:38
CC2500_3F_TXFIFO
@ CC2500_3F_TXFIFO
Definition: cc2500.h:129
NOP
#define NOP
Definition: cc2500.c:172
CC2500_3F_RXFIFO
@ CC2500_3F_RXFIFO
Definition: cc2500.h:130
rxSpiReadCommandMulti
static void rxSpiReadCommandMulti(uint8_t command, uint8_t commandData, uint8_t *retData, uint8_t length)
Definition: cc2500.c:73
spi_transaction::status
enum SPITransactionStatus status
Definition: spi.h:162
cc2500.h