Paparazzi UAS  v7.0_unstable
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 "modules/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;
38 static struct spi_transaction cc2500_spi_t;
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 modules/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
void cc2500WriteReg(uint8_t address, uint8_t data)
Definition: cc2500.c:206
static uint8_t rxSpiReadCommand(uint8_t command, uint8_t commandData)
Definition: cc2500.c:92
static void rxSpiWriteCommand(uint8_t command, uint8_t data)
Definition: cc2500.c:117
void cc2500ReadFifo(uint8_t *dpbuffer, uint8_t len)
Definition: cc2500.c:174
uint8_t cc2500ReadReg(uint8_t reg)
Definition: cc2500.c:199
void cc2500ReadRegisterMulti(uint8_t address, uint8_t *data, uint8_t length)
Definition: cc2500.c:188
void cc2500WriteRegisterMulti(uint8_t address, uint8_t *data, uint8_t length)
Definition: cc2500.c:193
void cc2500WriteFifo(uint8_t *dpbuffer, uint8_t len)
Definition: cc2500.c:180
static struct spi_transaction cc2500_spi_t
Definition: cc2500.c:38
#define delayMicroseconds(us)
Definition: cc2500.c:70
void cc2500Strobe(uint8_t address)
Definition: cc2500.c:204
static uint8_t cc2500_input_buf[64]
Definition: cc2500.c:39
#define NOP
Definition: cc2500.c:172
static struct spi_periph * cc2500_spi_p
Definition: cc2500.c:37
void cc2500_init(void)
Definition: cc2500.c:43
uint8_t cc2500Reset(void)
Definition: cc2500.c:228
void cc2500SetPower(uint8_t power)
Definition: cc2500.c:211
static void rxSpiWriteCommandMulti(uint8_t command, uint8_t *data, uint8_t length)
Definition: cc2500.c:99
static void rxSpiReadCommandMulti(uint8_t command, uint8_t commandData, uint8_t *retData, uint8_t length)
Definition: cc2500.c:73
static uint8_t cc2500_output_buf[64]
Definition: cc2500.c:40
static void cc2500_delayMicroseconds(uint32_t us)
Definition: cc2500.c:62
static void rxSpiWriteByte(uint8_t data)
Definition: cc2500.c:121
#define CC2500_SFTX
Definition: cc2500.h:162
#define CC2500_STX
Definition: cc2500.h:151
#define CC2500_READ_BURST
Definition: cc2500.h:137
#define CC2500_SRES
Definition: cc2500.h:140
#define CC2500_WRITE_BURST
Definition: cc2500.h:135
@ CC2500_3E_PATABLE
Definition: cc2500.h:128
@ CC2500_0E_FREQ1
Definition: cc2500.h:79
@ CC2500_3F_RXFIFO
Definition: cc2500.h:130
@ CC2500_3F_TXFIFO
Definition: cc2500.h:129
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:155
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:156
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:154
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:157
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:150
uint16_t input_length
number of data words to read
Definition: spi.h:151
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:159
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:149
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:153
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:158
uint16_t output_length
number of data words to write
Definition: spi.h:152
enum SPITransactionStatus status
Definition: spi.h:162
bool spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit SPI transaction.
Definition: spi_arch.c:533
@ SPICphaEdge1
CPHA = 0.
Definition: spi.h:74
@ SPITransSuccess
Definition: spi.h:99
@ SPITransDone
Definition: spi.h:101
@ SPICpolIdleLow
CPOL = 0.
Definition: spi.h:83
@ SPISelectUnselect
slave is selected before transaction and unselected after
Definition: spi.h:63
@ SPIMSBFirst
Definition: spi.h:112
@ SPIDiv32
Definition: spi.h:124
@ SPIDss8bit
Definition: spi.h:90
SPI peripheral structure.
Definition: spi.h:174
SPI transaction structure.
Definition: spi.h:148
Architecture independent SPI (Serial Peripheral Interface) API.
Architecture independent timing functions.
static float get_sys_time_float(void)
Get the time in seconds since startup.
Definition: sys_time.h:138
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98