Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
cyrf6936.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013 Freek van Tienen <freek.v.tienen@gmail.com>
3 *
4 * This file is part of paparazzi.
5 *
6 * paparazzi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * paparazzi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with paparazzi; see the file COPYING. If not, write to
18 * the Free Software Foundation, 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
27#include "cyrf6936.h"
28#include "mcu_periph/spi.h"
29#include "mcu_periph/gpio.h"
30#include "mcu_periph/sys_time.h"
32
33#include "mcu_periph/uart.h"
34#include "pprzlink/messages.h"
36
37/* Static functions used in the different statuses */
38static bool cyrf6936_write_register(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data);
39static bool cyrf6936_write_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data[],
40 const uint8_t length);
41static bool cyrf6936_read_register(struct Cyrf6936 *cyrf, const uint8_t addr);
42static bool cyrf6936_read_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t length);
43
47void cyrf6936_init(struct Cyrf6936 *cyrf, struct spi_periph *spi_p, const uint8_t slave_idx, const uint32_t rst_port,
48 const uint16_t rst_pin)
49{
50 /* Set spi_peripheral and the status */
51 cyrf->spi_p = spi_p;
53 cyrf->has_irq = false;
54
55 /* Set the spi transaction */
56 cyrf->spi_t.cpol = SPICpolIdleLow;
57 cyrf->spi_t.cpha = SPICphaEdge1;
58 cyrf->spi_t.dss = SPIDss8bit;
59 cyrf->spi_t.bitorder = SPIMSBFirst;
60 cyrf->spi_t.cdiv = SPIDiv64;
61
62 cyrf->spi_t.input_length = 0;
63 cyrf->spi_t.output_length = 0;
64 cyrf->spi_t.input_buf = cyrf->input_buf;
65 cyrf->spi_t.output_buf = cyrf->output_buf;
66 cyrf->spi_t.slave_idx = slave_idx;
67 cyrf->spi_t.select = SPISelectUnselect;
68 cyrf->spi_t.status = SPITransDone;
69
70 /* Reset the CYRF6936 chip (busy waiting) */
73 sys_time_usleep(100);
75 sys_time_usleep(100);
76
77 /* Get the MFG ID */
78 cyrf->status = CYRF6936_GET_MFG_ID;
79 cyrf->buffer_idx = 0;
81}
82
87{
88 int i;
89 // Check if cyrf is initialized
90 if (cyrf->status == CYRF6936_UNINIT) {
91 return;
92 }
93
94 // Check if there is still a transaction in progress
95 if (cyrf->spi_t.status == SPITransPending || cyrf->spi_t.status == SPITransRunning) {
96 return;
97 }
98
99 /* Check the status of the cyrf */
100 switch (cyrf->status) {
101
102 /* Getting the MFG id */
104 // When the last transaction isn't failed send the next
105 if (cyrf->spi_t.status != SPITransFailed) {
106 cyrf->buffer_idx++;
107 }
108
109 cyrf->spi_t.status = SPITransDone;
110
111 // Switch for the different states
112 switch (cyrf->buffer_idx) {
113 case 0:
115 break;
116 case 1:
118 break;
119 case 2:
120 // Copy the MFG id
121 for (i = 0; i < 6; i++) {
122 cyrf->mfg_id[i] = cyrf->input_buf[i + 1];
123 }
124
126 break;
127 default:
128 cyrf->status = CYRF6936_IDLE;
129 break;
130 }
131 break;
132
133 /* Do a multi write */
135 // When the last transaction isn't failed send the next
136 if (cyrf->spi_t.status != SPITransFailed) {
137 cyrf->buffer_idx++;
138 }
139
140 cyrf->spi_t.status = SPITransDone;
141
142 // When we are done writing
143 if (cyrf->buffer_idx == cyrf->buffer_length) {
144 cyrf->status = CYRF6936_IDLE;
145 break;
146 }
147
148 // Write the next register from the buffer
150 ((uint8_t ( *)[2])cyrf->buffer)[cyrf->buffer_idx][0],
151 ((uint8_t ( *)[2])cyrf->buffer)[cyrf->buffer_idx][1]);
152 break;
153
154 /* Do a write of the data code */
156 break;
157
158 /* Do a write of channel, sop, data and crc */
160 // When the last transaction isn't failed send the next
161 if (cyrf->spi_t.status != SPITransFailed) {
162 cyrf->buffer_idx++;
163 }
164
165 cyrf->spi_t.status = SPITransDone;
166
167 // Switch for the different states
168 switch (cyrf->buffer_idx) {
169 case 0: // Write the CRC LSB
171 break;
172 case 1: // Write the CRC MSB
174 break;
175 case 2: // Write the SOP code
176 cyrf6936_write_block(cyrf, CYRF_SOP_CODE, &(cyrf->buffer[2]), 8);
177 break;
178 case 3: // Write the DATA code
179 cyrf6936_write_block(cyrf, CYRF_DATA_CODE, &(cyrf->buffer[10]), 16);
180 break;
181 case 4: // Write the Channel
183 break;
184 default:
185 cyrf->status = CYRF6936_IDLE;
186 break;
187 }
188 break;
189
190 /* Do a read of the receive irq status, receive status and the receive packet */
192 // When the last transaction isn't failed send the next
193 if (cyrf->spi_t.status != SPITransFailed) {
194 cyrf->buffer_idx++;
195 }
196
197 cyrf->spi_t.status = SPITransDone;
198
199 // Switch for the different states
200 switch (cyrf->buffer_idx) {
201 case 0: // Read the receive IRQ status
203 break;
204 case 1: // Read the send IRQ status
205 cyrf->rx_irq_status = cyrf->input_buf[1];
207 break;
208 case 2: // Read the receive status
209 cyrf->tx_irq_status = cyrf->input_buf[1];
211 break;
212 case 3: // Set the packet length
213 cyrf->rx_status = cyrf->input_buf[1];
215 break;
216 case 4: // Read the receive packet
217 cyrf->rx_count = cyrf->input_buf[1];
219 break;
220 default:
221 // Copy the receive packet
222 for (i = 0; i < 16; i++) {
223 cyrf->rx_packet[i] = cyrf->input_buf[i + 1];
224 }
225
226 cyrf->has_irq = true;
227 cyrf->status = CYRF6936_IDLE;
228 break;
229 }
230 break;
231
232 /* The CYRF6936 is busy sending a packet */
233 case CYRF6936_SEND:
234 // When the last transaction isn't failed send the next
235 if (cyrf->spi_t.status != SPITransFailed) {
236 cyrf->buffer_idx++;
237 }
238
239 cyrf->spi_t.status = SPITransDone;
240
241 // Switch for the different states
242 switch (cyrf->buffer_idx) {
243 case 0: // Set the packet length
245 break;
246 case 1: // Clear the TX buffer
248 break;
249 case 2: // Write the send packet
250 cyrf6936_write_block(cyrf, CYRF_TX_BUFFER, &cyrf->buffer[1], 16);
251 break;
252 case 3: // Send the packet
254 break;
255 default:
256 cyrf->status = CYRF6936_IDLE;
257 break;
258 }
259 break;
260
261 /* This should not happen */
262 default:
263 break;
264 }
265}
266
270static bool cyrf6936_write_register(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
271{
272 return cyrf6936_write_block(cyrf, addr, &data, 1);
273}
274
278static bool cyrf6936_write_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data[],
279 const uint8_t length)
280{
281 uint8_t i;
282 /* Check if there is already a SPI transaction busy */
283 if (cyrf->spi_t.status != SPITransDone) {
284 return false;
285 }
286
287 /* Set the buffer and commit the transaction */
288 cyrf->spi_t.output_length = length + 1;
289 cyrf->spi_t.input_length = 0;
290 cyrf->output_buf[0] = addr | CYRF_DIR;
291
292 // Copy the data
293 for (i = 0; i < length; i++) {
294 cyrf->output_buf[i + 1] = data[i];
295 }
296
297 // Submit the transaction
298 return spi_submit(cyrf->spi_p, &(cyrf->spi_t));
299}
300
304static bool cyrf6936_read_register(struct Cyrf6936 *cyrf, const uint8_t addr)
305{
306 return cyrf6936_read_block(cyrf, addr, 1);
307}
308
312static bool cyrf6936_read_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t length)
313{
314 if (cyrf->spi_t.status != SPITransDone) {
315 return false;
316 }
317
318 /* Set the buffer and commit the transaction */
319 cyrf->spi_t.output_length = 1;
320 cyrf->spi_t.input_length = length + 1;
321 cyrf->output_buf[0] = addr;
322
323 // Submit the transaction
324 return spi_submit(cyrf->spi_p, &(cyrf->spi_t));
325}
326
330bool cyrf6936_write(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
331{
332 const uint8_t data_multi[][2] = {
333 {addr, data}
334 };
336}
337
341bool cyrf6936_multi_write(struct Cyrf6936 *cyrf, const uint8_t data[][2], const uint8_t length)
342{
343 uint8_t i;
344 /* Check if the cyrf6936 isn't busy */
345 if (cyrf->status != CYRF6936_IDLE) {
346 return false;
347 }
348
349 // Set the status
350 cyrf->status = CYRF6936_MULTIWRITE;
351
352 /* Set the multi write */
353 cyrf->buffer_length = length;
354 cyrf->buffer_idx = 0;
355
356 // Copy the buffer
357 for (i = 0; i < length; i++) {
358 cyrf->buffer[i * 2] = data[i][0];
359 cyrf->buffer[i * 2 + 1] = data[i][1];
360 }
361
362 /* Write the first regiter */
363 if (length > 0) {
364 cyrf6936_write_register(cyrf, data[0][0], data[0][1]);
365 }
366
367 return true;
368}
369
374 const uint8_t data_code[], const uint16_t crc_seed)
375{
376 uint8_t i;
377 /* Check if the cyrf6936 isn't busy */
378 if (cyrf->status != CYRF6936_IDLE) {
379 return false;
380 }
381
382 // Set the status
384
385 // Copy the CRC
386 cyrf->buffer[0] = crc_seed & 0xFF;
387 cyrf->buffer[1] = (crc_seed >> 8) & 0xFF;
388
389 // Copy the SOP code
390 for (i = 0; i < 8; i++) {
391 cyrf->buffer[i + 2] = sop_code[i];
392 }
393
394 // Copy the DATA code
395 for (i = 0; i < 16; i++) {
396 cyrf->buffer[i + 10] = data_code[i];
397 }
398
399 // Copy the channel
400 cyrf->buffer[26] = chan;
401
402 /* Try to write the CRC LSB */
403 cyrf->buffer_idx = 0;
405
406 return true;
407}
408
413{
414 /* Check if the cyrf6936 isn't busy */
415 if (cyrf->status != CYRF6936_IDLE) {
416 return false;
417 }
418
419 // Set the status
421
422 /* Try to read the RX status */
423 cyrf->buffer_idx = 0;
425
426 return true;
427}
428
432bool cyrf6936_send(struct Cyrf6936 *cyrf, const uint8_t data[], const uint8_t length)
433{
434 int i;
435
436 /* Check if the cyrf6936 isn't busy */
437 if (cyrf->status != CYRF6936_IDLE) {
438 return false;
439 }
440
441 // Set the status
442 cyrf->status = CYRF6936_SEND;
443
444 // Copy the length and the data
445 cyrf->buffer[0] = length;
446 for (i = 0; i < length; i++) {
447 cyrf->buffer[i + 1] = data[i];
448 }
449
450 /* Try to set the packet length */
451 cyrf->buffer_idx = 0;
453
454 return true;
455}
void gpio_setup_output(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as outputs.
Definition gpio_arch.c:33
static void gpio_set(ioportid_t port, uint16_t pin)
Set a gpio output to high level.
Definition gpio_arch.h:104
static void gpio_clear(ioportid_t port, uint16_t pin)
Clear a gpio output to low level.
Definition gpio_arch.h:114
void sys_time_usleep(uint32_t us)
sys_time_usleep(uint32_t us)
void cyrf6936_event(struct Cyrf6936 *cyrf)
The on event call for the CYRF6936 chip.
Definition cyrf6936.c:86
void cyrf6936_init(struct Cyrf6936 *cyrf, struct spi_periph *spi_p, const uint8_t slave_idx, const uint32_t rst_port, const uint16_t rst_pin)
Initializing the cyrf chip.
Definition cyrf6936.c:47
bool cyrf6936_multi_write(struct Cyrf6936 *cyrf, const uint8_t data[][2], const uint8_t length)
Write to multiple registers one byte.
Definition cyrf6936.c:341
bool cyrf6936_write_chan_sop_data_crc(struct Cyrf6936 *cyrf, const uint8_t chan, const uint8_t sop_code[], const uint8_t data_code[], const uint16_t crc_seed)
Set the channel, SOP code, DATA code and the CRC seed.
Definition cyrf6936.c:373
bool cyrf6936_write(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
Write to one register.
Definition cyrf6936.c:330
static bool cyrf6936_write_register(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
Write a byte to a register.
Definition cyrf6936.c:270
bool cyrf6936_read_rx_irq_status_packet(struct Cyrf6936 *cyrf)
Read the RX IRQ status register, the rx status register and the rx packet.
Definition cyrf6936.c:412
bool cyrf6936_send(struct Cyrf6936 *cyrf, const uint8_t data[], const uint8_t length)
Send a packet with a certain length.
Definition cyrf6936.c:432
static bool cyrf6936_read_register(struct Cyrf6936 *cyrf, const uint8_t addr)
Read a byte from a register.
Definition cyrf6936.c:304
static bool cyrf6936_write_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data[], const uint8_t length)
Write multiple bytes to a register.
Definition cyrf6936.c:278
static bool cyrf6936_read_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t length)
Read multiple bytes from a register.
Definition cyrf6936.c:312
Driver for the cyrf6936 2.4GHz radio chip.
@ CYRF6936_DATA_CODE
The chip is writing a data code.
Definition cyrf6936.h:41
@ CYRF6936_IDLE
The chip is idle and can be used.
Definition cyrf6936.h:38
@ CYRF6936_GET_MFG_ID
The chip is busy with getting the manufacturer ID.
Definition cyrf6936.h:39
@ CYRF6936_MULTIWRITE
The chip is writing multiple registers.
Definition cyrf6936.h:40
@ CYRF6936_RX_IRQ_STATUS_PACKET
The chip is getting the receive irq status, receive status and the receive packet.
Definition cyrf6936.h:43
@ CYRF6936_UNINIT
The chip isn't initialized.
Definition cyrf6936.h:37
@ CYRF6936_SEND
The chip is busy sending a packet.
Definition cyrf6936.h:44
@ CYRF6936_CHAN_SOP_DATA_CRC
The chip is setting the channel, SOP code, DATA code and the CRC seed.
Definition cyrf6936.h:42
#define CYRF_TXE_IRQEN
#define CYRF_TX_CLR
@ CYRF_CHANNEL
@ CYRF_SOP_CODE
@ CYRF_MFG_ID
@ CYRF_RX_COUNT
@ CYRF_CRC_SEED_LSB
@ CYRF_TX_LENGTH
@ CYRF_TX_CTRL
@ CYRF_CRC_SEED_MSB
@ CYRF_RX_IRQ_STATUS
@ CYRF_RX_STATUS
@ CYRF_DATA_CODE
@ CYRF_TX_BUFFER
@ CYRF_TX_IRQ_STATUS
@ CYRF_RX_BUFFER
#define CYRF_DIR
Bit for enabling writing.
#define CYRF_TX_GO
#define CYRF_TXC_IRQEN
Some architecture independent helper functions for GPIOs.
enum SPIStatus status
internal state of the peripheral
Definition spi.h:180
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
@ SPITransFailed
Definition spi.h:100
@ SPITransRunning
Definition spi.h:98
@ SPITransPending
Definition spi.h:97
@ 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
@ SPIDiv64
Definition spi.h:125
@ SPIDss8bit
Definition spi.h:90
SPI peripheral structure.
Definition spi.h:174
uint16_t foo
Definition main_demo5.c:58
Generic interface for radio control modules.
Architecture independent SPI (Serial Peripheral Interface) API.
Architecture independent timing functions.
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.