Paparazzi UAS  v5.2.2_stable-0-gd6b9f29
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures 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 "messages.h"
36 
37 /* Static functions used in the different statuses */
38 static bool_t cyrf6936_write_register(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data);
39 static bool_t cyrf6936_write_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data[], const uint8_t length);
40 static bool_t cyrf6936_read_register(struct Cyrf6936 *cyrf, const uint8_t addr);
41 static bool_t cyrf6936_read_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t length);
42 
46 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) {
47  /* Set spi_peripheral and the status */
48  cyrf->spi_p = spi_p;
49  cyrf->status = CYRF6936_UNINIT;
50  cyrf->has_irq = FALSE;
51 
52  /* Set the spi transaction */
53  cyrf->spi_t.cpol = SPICpolIdleLow;
54  cyrf->spi_t.cpha = SPICphaEdge1;
55  cyrf->spi_t.dss = SPIDss8bit;
56  cyrf->spi_t.bitorder = SPIMSBFirst;
57  cyrf->spi_t.cdiv = SPIDiv64;
58 
59  cyrf->spi_t.input_length = 0;
60  cyrf->spi_t.output_length = 0;
61  cyrf->spi_t.input_buf = cyrf->input_buf;
62  cyrf->spi_t.output_buf = cyrf->output_buf;
63  cyrf->spi_t.slave_idx = slave_idx;
65  cyrf->spi_t.status = SPITransDone;
66 
67  /* Reset the CYRF6936 chip (busy waiting) */
68  gpio_setup_output(rst_port, rst_pin);
69  gpio_set(rst_port, rst_pin);
70  sys_time_usleep(100);
71  gpio_clear(rst_port, rst_pin);
72  sys_time_usleep(100);
73 
74  /* Get the MFG ID */
76  cyrf->buffer_idx = 0;
78 }
79 
83 void cyrf6936_event(struct Cyrf6936 *cyrf) {
84  int i;
85  // Check if cyrf is initialized
86  if(cyrf->status == CYRF6936_UNINIT)
87  return;
88 
89  // Check if there is still a transaction in progress
90  if(cyrf->spi_t.status == SPITransPending || cyrf->spi_t.status == SPITransRunning)
91  return;
92 
93  /* Check the status of the cyrf */
94  switch (cyrf->status) {
95 
96  /* Getting the MFG id */
98  // When the last transaction isn't failed send the next
99  if(cyrf->spi_t.status != SPITransFailed)
100  cyrf->buffer_idx++;
101 
102  cyrf->spi_t.status = SPITransDone;
103 
104  // Switch for the different states
105  switch (cyrf->buffer_idx) {
106  case 0:
108  break;
109  case 1:
111  break;
112  case 2:
113  // Copy the MFG id
114  for(i = 0; i < 6; i++)
115  cyrf->mfg_id[i] = cyrf->input_buf[i+1];
116 
118  break;
119  default:
120  cyrf->status = CYRF6936_IDLE;
121  break;
122  }
123  break;
124 
125  /* Do a multi write */
126  case CYRF6936_MULTIWRITE:
127  // When the last transaction isn't failed send the next
128  if(cyrf->spi_t.status != SPITransFailed)
129  cyrf->buffer_idx++;
130 
131  cyrf->spi_t.status = SPITransDone;
132 
133  // When we are done writing
134  if(cyrf->buffer_idx == cyrf->buffer_length) {
135  cyrf->status = CYRF6936_IDLE;
136  break;
137  }
138 
139  // Write the next register from the buffer
141  ((uint8_t (*)[2])cyrf->buffer)[cyrf->buffer_idx][0],
142  ((uint8_t (*)[2])cyrf->buffer)[cyrf->buffer_idx][1]);
143  break;
144 
145  /* Do a write of the data code */
146  case CYRF6936_DATA_CODE:
147  break;
148 
149  /* Do a write of channel, sop, data and crc */
151  // When the last transaction isn't failed send the next
152  if(cyrf->spi_t.status != SPITransFailed)
153  cyrf->buffer_idx++;
154 
155  cyrf->spi_t.status = SPITransDone;
156 
157  // Switch for the different states
158  switch (cyrf->buffer_idx) {
159  case 0: // Write the CRC LSB
161  break;
162  case 1: // Write the CRC MSB
164  break;
165  case 2: // Write the SOP code
166  cyrf6936_write_block(cyrf, CYRF_SOP_CODE, &(cyrf->buffer[2]), 8);
167  break;
168  case 3: // Write the DATA code
169  cyrf6936_write_block(cyrf, CYRF_DATA_CODE, &(cyrf->buffer[10]), 16);
170  break;
171  case 4: // Write the Channel
172  cyrf6936_write_register(cyrf, CYRF_CHANNEL, cyrf->buffer[26]);
173  break;
174  default:
175  cyrf->status = CYRF6936_IDLE;
176  break;
177  }
178  break;
179 
180  /* Do a read of the receive irq status, receive status and the receive packet */
182  // When the last transaction isn't failed send the next
183  if(cyrf->spi_t.status != SPITransFailed)
184  cyrf->buffer_idx++;
185 
186  cyrf->spi_t.status = SPITransDone;
187 
188  // Switch for the different states
189  switch (cyrf->buffer_idx) {
190  case 0: // Read the receive IRQ status
192  break;
193  case 1: // Read the send IRQ status
194  cyrf->rx_irq_status = cyrf->input_buf[1];
196  break;
197  case 2: // Read the receive status
198  cyrf->tx_irq_status = cyrf->input_buf[1];
200  break;
201  case 3: // Set the packet length
202  cyrf->rx_status = cyrf->input_buf[1];
204  break;
205  case 4: // Read the receive packet
206  cyrf->rx_count = cyrf->input_buf[1];
208  break;
209  default:
210  // Copy the receive packet
211  for(i = 0; i < 16; i++)
212  cyrf->rx_packet[i] = cyrf->input_buf[i+1];
213 
214  cyrf->has_irq = TRUE;
215  cyrf->status = CYRF6936_IDLE;
216  break;
217  }
218  break;
219 
220  /* The CYRF6936 is busy sending a packet */
221  case CYRF6936_SEND:
222  // When the last transaction isn't failed send the next
223  if(cyrf->spi_t.status != SPITransFailed)
224  cyrf->buffer_idx++;
225 
226  cyrf->spi_t.status = SPITransDone;
227 
228  // Switch for the different states
229  switch (cyrf->buffer_idx) {
230  case 0: // Set the packet length
232  break;
233  case 1: // Clear the TX buffer
235  break;
236  case 2: // Write the send packet
237  cyrf6936_write_block(cyrf, CYRF_TX_BUFFER, &cyrf->buffer[1], 16);
238  break;
239  case 3: // Send the packet
241  break;
242  default:
243  cyrf->status = CYRF6936_IDLE;
244  break;
245  }
246  break;
247 
248  /* This should not happen */
249  default:
250  break;
251  }
252 }
253 
257 static bool_t cyrf6936_write_register(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data) {
258  return cyrf6936_write_block(cyrf, addr, &data, 1);
259 }
260 
264 static bool_t cyrf6936_write_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data[], const uint8_t length) {
265  uint8_t i;
266  /* Check if there is already a SPI transaction busy */
267  if(cyrf->spi_t.status != SPITransDone)
268  return FALSE;
269 
270  /* Set the buffer and commit the transaction */
271  cyrf->spi_t.output_length = length+1;
272  cyrf->spi_t.input_length = 0;
273  cyrf->output_buf[0] = addr | CYRF_DIR;
274 
275  // Copy the data
276  for(i = 0; i < length; i++)
277  cyrf->output_buf[i+1] = data[i];
278 
279  // Submit the transaction
280  return spi_submit(cyrf->spi_p, &(cyrf->spi_t));
281 }
282 
286 static bool_t cyrf6936_read_register(struct Cyrf6936 *cyrf, const uint8_t addr) {
287  return cyrf6936_read_block(cyrf, addr, 1);
288 }
289 
293 static bool_t cyrf6936_read_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t length) {
294  if(cyrf->spi_t.status != SPITransDone)
295  return FALSE;
296 
297  /* Set the buffer and commit the transaction */
298  cyrf->spi_t.output_length = 1;
299  cyrf->spi_t.input_length = length + 1;
300  cyrf->output_buf[0] = addr;
301 
302  // Submit the transaction
303  return spi_submit(cyrf->spi_p, &(cyrf->spi_t));
304 }
305 
309 bool_t cyrf6936_write(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data) {
310  const uint8_t data_multi[][2] = {
311  {addr, data}
312  };
313  return cyrf6936_multi_write(cyrf, data_multi, 1);
314 }
315 
319 bool_t cyrf6936_multi_write(struct Cyrf6936 *cyrf, const uint8_t data[][2], const uint8_t length) {
320  uint8_t i;
321  /* Check if the cyrf6936 isn't busy */
322  if(cyrf->status != CYRF6936_IDLE)
323  return FALSE;
324 
325  // Set the status
326  cyrf->status = CYRF6936_MULTIWRITE;
327 
328  /* Set the multi write */
329  cyrf->buffer_length = length;
330  cyrf->buffer_idx = 0;
331 
332  // Copy the buffer
333  for(i = 0; i< length; i++) {
334  cyrf->buffer[i*2] = data[i][0];
335  cyrf->buffer[i*2+1] = data[i][1];
336  }
337 
338  /* Write the first regiter */
339  if(length > 0)
340  cyrf6936_write_register(cyrf, data[0][0], data[0][1]);
341 
342  return TRUE;
343 }
344 
348 bool_t 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) {
349  uint8_t i;
350  /* Check if the cyrf6936 isn't busy */
351  if(cyrf->status != CYRF6936_IDLE)
352  return FALSE;
353 
354  // Set the status
356 
357  // Copy the CRC
358  cyrf->buffer[0] = crc_seed & 0xFF;
359  cyrf->buffer[1] = (crc_seed >> 8) & 0xFF;
360 
361  // Copy the SOP code
362  for(i = 0; i < 8; i++)
363  cyrf->buffer[i+2] = sop_code[i];
364 
365  // Copy the DATA code
366  for(i = 0; i < 16; i++)
367  cyrf->buffer[i+10] = data_code[i];
368 
369  // Copy the channel
370  cyrf->buffer[26] = chan;
371 
372  /* Try to write the CRC LSB */
373  cyrf->buffer_idx = 0;
375 
376  return TRUE;
377 }
378 
383  /* Check if the cyrf6936 isn't busy */
384  if(cyrf->status != CYRF6936_IDLE)
385  return FALSE;
386 
387  // Set the status
389 
390  /* Try to read the RX status */
391  cyrf->buffer_idx = 0;
393 
394  return TRUE;
395 }
396 
400 bool_t cyrf6936_send(struct Cyrf6936 *cyrf, const uint8_t data[], const uint8_t length) {
401  int i;
402 
403  /* Check if the cyrf6936 isn't busy */
404  if(cyrf->status != CYRF6936_IDLE)
405  return FALSE;
406 
407  // Set the status
408  cyrf->status = CYRF6936_SEND;
409 
410  // Copy the length and the data
411  cyrf->buffer[0] = length;
412  for(i = 0; i < length; i++)
413  cyrf->buffer[i+1] = data[i];
414 
415  /* Try to set the packet length */
416  cyrf->buffer_idx = 0;
418 
419  return TRUE;
420 }
Driver for the cyrf6936 2.4GHz radio chip.
bool_t cyrf6936_send(struct Cyrf6936 *cyrf, const uint8_t data[], const uint8_t length)
Send a packet with a certain length.
Definition: cyrf6936.c:400
bool_t cyrf6936_multi_write(struct Cyrf6936 *cyrf, const uint8_t data[][2], const uint8_t length)
Write to multiple registers one byte.
Definition: cyrf6936.c:319
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:152
unsigned short uint16_t
Definition: types.h:16
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:149
The chip is setting the channel, SOP code, DATA code and the CRC seed.
Definition: cyrf6936.h:42
uint8_t input_length
number of data words to read
Definition: spi.h:145
static bool_t cyrf6936_read_register(struct Cyrf6936 *cyrf, const uint8_t addr)
Read a byte from a register.
Definition: cyrf6936.c:286
uint8_t buffer_idx
The index of the buffer used for MULTIWRITE and used as sub-status for other statuses.
Definition: cyrf6936.h:57
The chip is idle and can be used.
Definition: cyrf6936.h:38
#define CYRF_TXC_IRQEN
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
Some architecture independent helper functions for GPIOs.
static void sys_time_usleep(uint32_t us)
Busy wait, in microseconds.
Definition: sys_time_arch.h:85
void gpio_set(uint32_t port, uint16_t pin)
Set a gpio output to high level.
uint8_t buffer_length
The length of the buffer used for MULTIWRITE.
Definition: cyrf6936.h:56
enum Cyrf6936Status status
The status of the CYRF6936 chip.
Definition: cyrf6936.h:51
uint8_t rx_packet[16]
The last received packet.
Definition: cyrf6936.h:65
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:143
#define CYRF_DIR
Bit for enabling writing.
Definition: cyrf6936_regs.h:78
uint8_t output_buf[17]
The output buffer for the SPI transaction.
Definition: cyrf6936.h:53
The chip is getting the receive irq status, receive status and the receive packet.
Definition: cyrf6936.h:43
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:148
bool_t has_irq
When the CYRF6936 is done reading the irq.
Definition: cyrf6936.h:59
void cyrf6936_event(struct Cyrf6936 *cyrf)
The on event call for the CYRF6936 chip.
Definition: cyrf6936.c:83
The chip is busy sending a packet.
Definition: cyrf6936.h:44
uint8_t rx_irq_status
The last receive interrupt status.
Definition: cyrf6936.h:62
#define FALSE
Definition: imu_chimu.h:141
enum SPITransactionStatus status
Definition: spi.h:156
Architecture independent SPI (Serial Peripheral Interface) API.
bool_t cyrf6936_write(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
Write to one register.
Definition: cyrf6936.c:309
bool_t 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:348
Definition: spi.h:84
The chip is writing multiple registers.
Definition: cyrf6936.h:40
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:153
bool_t spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit a spi transaction.
Definition: spi_arch.c:470
Architecture independent timing functions.
#define CYRF_TXE_IRQEN
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:151
unsigned long uint32_t
Definition: types.h:18
uint8_t tx_irq_status
The last send interrupt status.
Definition: cyrf6936.h:61
uint8_t output_length
number of data words to write
Definition: spi.h:146
struct spi_transaction spi_t
The SPI transaction used for the writing and reading of registers.
Definition: cyrf6936.h:50
CPOL = 0.
Definition: spi.h:77
struct spi_periph * spi_p
The SPI peripheral for the connection.
Definition: cyrf6936.h:49
static bool_t 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:264
void gpio_clear(uint32_t port, uint16_t pin)
Clear a gpio output to low level.
The chip is busy with getting the manufacturer ID.
Definition: cyrf6936.h:39
#define TRUE
Definition: imu_chimu.h:144
The chip isn't initialized.
Definition: cyrf6936.h:37
SPI peripheral structure.
Definition: spi.h:168
The chip is writing a data code.
Definition: cyrf6936.h:41
unsigned char uint8_t
Definition: types.h:14
static void gpio_setup_output(uint32_t port, uint32_t gpios)
Setup one or more pins of the given GPIO port as outputs.
Definition: gpio_arch.h:76
CPHA = 0.
Definition: spi.h:68
uint8_t rx_count
The length of the received packet.
Definition: cyrf6936.h:64
slave is selected before transaction and unselected after
Definition: spi.h:57
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:147
static bool_t cyrf6936_read_block(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t length)
Read multiple bytes from a register.
Definition: cyrf6936.c:293
uint8_t rx_status
The last receive status.
Definition: cyrf6936.h:63
#define CYRF_TX_CLR
Definition: spi.h:119
uint8_t buffer[CYRF6936_MAX_BUFFER]
The buffer used to write/read multiple registers.
Definition: cyrf6936.h:55
bool_t 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:382
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:144
uint8_t mfg_id[6]
The manufacturer id of the CYRF6936 chip.
Definition: cyrf6936.h:60
#define CYRF_TX_GO
uint8_t input_buf[17]
The input buffer for the SPI transaction.
Definition: cyrf6936.h:52
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:46
static bool_t cyrf6936_write_register(struct Cyrf6936 *cyrf, const uint8_t addr, const uint8_t data)
Write a byte to a register.
Definition: cyrf6936.c:257