Paparazzi UAS  v5.0.5_stable-7-g4b8bbb7
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
lisa_stm_gps_passthrough_main.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 The Paparazzi Team
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  */
22 
23 #include "mcu.h"
24 #include "mcu_periph/sys_time.h"
25 #include "lisa/lisa_overo_link.h"
26 #include "lisa/lisa_spistream.h"
27 #include "generated/airframe.h"
28 #include "mcu_periph/uart.h"
29 #include "led.h"
30 
31 static inline void main_init(void);
32 static inline void main_periodic(void);
33 static inline void main_event(void);
34 static inline void uart_transfer_event(void);
35 
36 static inline void on_spistream_msg_received(uint8_t msg_id, uint8_t * data, uint16_t num_bytes);
37 static inline void on_spistream_msg_sent(uint8_t msg_id);
38 
39 static inline void on_overo_link_msg_received(void);
40 static inline void on_overo_link_lost(void);
41 static inline void on_overo_link_crc_failed(void);
42 
43 #ifdef SPISTREAM_DEBUG
44 static inline void uart_debug_transfer_event(void);
45 static inline void uart_debug_transfer_init(void);
46 #endif
47 
48 struct __attribute__ ((packed)) spistream_uart_msg {
51 };
52 
53 // TODO
54 // Use 3 static instances of this struct in uart_transfer_event
55 // instead of a myriad of repetitive static vars:
56 struct uart_state {
63 };
64 
68 #ifdef SPISTREAM_DEBUG
69 static struct spistream_uart_msg spistream_debug_msg;
70 #endif
71 
72 // The number of current, unfinished spistream transfers.
73 // Incremented after sending an spistream message, decremented
74 // in spistream TX completion handler (here: on_spistream_msg_sent).
76 
77 int main(void) {
78 
79  main_init();
80 
81  while (1) {
83  main_periodic();
84  }
85  main_event();
86  }
87 
88  return 0;
89 }
90 
91 static inline void main_init(void) {
92 
93  mcu_init();
96 
97  uart1_init();
98  uart2_init();
99  uart3_init();
100 
104 
105 #ifdef SPISTREAM_DEBUG
106  uart_debug_transfer_init();
107 #endif
108 
111 
112 }
113 
119 static inline void on_spistream_msg_received(uint8_t msg_id,
120  uint8_t * data,
121  uint16_t num_bytes)
122 {
123  spistream_send_msg(data, num_bytes, SPISTREAM_NO_WAIT);
124 }
125 
126 static inline void on_spistream_msg_sent(uint8_t msg_id) {
129  }
130 }
131 
132 static inline void main_periodic(void)
133 {
135 
136  RunOnceEvery(1, {
137  LED_PERIODIC();
138  });
139 }
140 
151 static inline void on_overo_link_msg_received(void)
152 {
155 }
156 
157 static inline void on_overo_link_lost(void) {
158 }
159 
160 static inline void on_overo_link_crc_failed(void) {
161 }
162 
163 static inline void main_event(void)
164 {
166 
167 #ifdef SPISTREAM_DEBUG
168  uart_debug_transfer_event();
169 #else
171 #endif
172 }
173 
174 #ifdef SPISTREAM_DEBUG
175 static inline void uart_debug_transfer_init(void) {
176  uint16_t idx;
177  for(idx = 1; idx < 700; idx++) {
178  spistream_debug_msg.uart_data[idx] = idx % 40;
179  }
180 }
181 #endif
182 
190 #ifdef SPISTREAM_DEBUG
191 static inline void uart_debug_transfer_event(void) {
192  static uint16_t len = 0;
193  static uint16_t timeout = 1;
194 
195  if(timeout-- == 0) {
196  timeout = 8000;
198  {
199  LED_OFF(6);
200  len++;
201  if(len > 700) { len = 500; }
202 
203  spistream_debug_msg.uart_id = 1;
204  if(spistream_send_msg((uint8_t *)&spistream_debug_msg,
205  len+1-20,
206  SPISTREAM_WAIT_FOR_READ)) { // +1 for UART id byte
208  }
209  spistream_debug_msg.uart_id = 2;
210  if(spistream_send_msg((uint8_t *)&spistream_debug_msg,
211  len+1,
212  SPISTREAM_WAIT_FOR_READ)) { // +1 for UART id byte
214  }
215  spistream_debug_msg.uart_id = 3;
216  if(spistream_send_msg((uint8_t *)&spistream_debug_msg,
217  len+1+20,
218  SPISTREAM_WAIT_FOR_READ)) { // +1 for UART id byte
220  }
221  }
222  else {
223  LED_ON(6);
224  }
225  }
226 }
227 #endif
228 
229 static inline void uart_transfer_event(void) {
230 
231  static uint16_t uart1_num_rx_bytes = 0;
232  static uint16_t uart2_num_rx_bytes = 0;
233  static uint16_t uart3_num_rx_bytes = 0;
234  static uint32_t timeout_trig = 2;
235  static uint32_t timeout_uart1 = 0;
236  static uint32_t timeout_uart2 = 0;
237  static uint32_t timeout_uart3 = 0;
238  static uint8_t uart1_sent = 0;
239  static uint8_t uart2_sent = 0;
240  static uint8_t uart3_sent = 0;
241  static uint8_t uart1_has_data = 0;
242  static uint8_t uart2_has_data = 0;
243  static uint8_t uart3_has_data = 0;
244  static uint8_t trigger_send = 0;
245 
246  static uint8_t uart1_enabled = 1;
247  static uint8_t uart2_enabled = 1;
248  static uint8_t uart3_enabled = 1;
249 
250  // We cache data availability, so it doesn't change between checks:
251  uart1_has_data = uart_char_available(&uart1);
252  uart2_has_data = uart_char_available(&uart2);
253  uart3_has_data = uart_char_available(&uart3);
254 
255  // Fill stage: Read data from UARTs into buffers, or increment
256  // their timeouts if no data is available:
257  if(!uart1_sent && uart1_has_data) {
258  spistream_uart1_msg.uart_data[uart1_num_rx_bytes] = uart_getch(&uart1);
259  timeout_uart1 = 0;
260  if(uart1_num_rx_bytes < SPISTREAM_MAX_MESSAGE_LENGTH)
261  { uart1_num_rx_bytes++; }
262  } else { if(timeout_uart1 < timeout_trig) { timeout_uart1++; } }
263 
264  if(!uart2_sent && uart2_has_data) {
265  spistream_uart2_msg.uart_data[uart2_num_rx_bytes] = uart_getch(&uart2);
266  timeout_uart2 = 0;
267  if(uart2_num_rx_bytes < SPISTREAM_MAX_MESSAGE_LENGTH)
268  { uart2_num_rx_bytes++; }
269  } else { if(timeout_uart2 < timeout_trig) { timeout_uart2++; } }
270 
271  if(!uart3_sent && uart3_has_data) {
272  spistream_uart3_msg.uart_data[uart3_num_rx_bytes] = uart_getch(&uart3);
273  timeout_uart3 = 0;
274  if(uart3_num_rx_bytes < SPISTREAM_MAX_MESSAGE_LENGTH)
275  { uart3_num_rx_bytes++; }
276  } else { if(timeout_uart3 < timeout_trig) { timeout_uart3++; } }
277 
278  trigger_send = ((!uart1_enabled ||
279  (timeout_uart1 >= timeout_trig)) &&
280  (!uart2_enabled ||
281  (timeout_uart2 >= timeout_trig)) &&
282  (!uart3_enabled ||
283  (timeout_uart3 >= timeout_trig)));
284 
285  // Send stage: If all UART timeouts reach the timeout
286  // trigger value and have accumulated data to send
287  if(trigger_send) {
288 
289  // If there was no new data on any UART for some time
290  // and there is data in every rx buffer:
291 
293  {
294  // Warning LED: Could not finish all transactions
295  // from last call.
296  LED_ON(6);
297  }
298  else
299  {
300  LED_OFF(6);
301 
302  uart1_sent = !uart1_enabled; // If we set uartX_sent to 1 here, it
303  uart2_sent = !uart2_enabled; // is just ignored for every read poll
304  uart3_sent = !uart3_enabled; // as it seems to have been read already.
305 
306  if(!uart1_sent && uart1_num_rx_bytes > 0) {
308  uart1_num_rx_bytes+1, // +1 for UART id
310  uart1_sent = 1;
312  }
313  }
314 
315  if(!uart2_sent && uart1_num_rx_bytes > 0) {
317  uart1_num_rx_bytes+1, // +1 for UART id
319  uart2_sent = 1;
321  }
322  }
323 
324  if(!uart3_sent && uart3_num_rx_bytes > 0) {
326  uart3_num_rx_bytes+1, // +1 for UART id
328  uart3_sent = 1;
330  }
331  }
332 
333  // Transaction completed, reset state.
334  // Note: Only reset when all uart buffers have been transmitted,
335  // otherwise the timeout would start from the beginning and the
336  // loop phase shifts (aka "you're in the deep").
337  uart1_num_rx_bytes = 0;
338  uart2_num_rx_bytes = 0;
339  uart3_num_rx_bytes = 0;
340  timeout_uart1 = 0;
341  timeout_uart2 = 0;
342  timeout_uart3 = 0;
343  uart1_sent = 0;
344  uart2_sent = 0;
345  uart3_sent = 0;
346  }
347  }
348 }
unsigned short uint16_t
Definition: types.h:16
static struct spistream_uart_msg spistream_uart3_msg
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
void mcu_init(void)
Microcontroller peripherals initialization.
Definition: mcu.c:61
uint8_t uart_getch(struct uart_periph *p)
Definition: uart.c:71
#define SPISTREAM_MAX_MESSAGE_LENGTH
Definition: lisa_spistream.h:7
static bool_t uart_char_available(struct uart_periph *p)
Definition: uart.h:83
static void main_event(void)
static uint8_t spistream_send_msg(uint8_t *data, uint16_t num_bytes, enum spistream_flag)
Used from userland: Send num_bytes bytes from buffer over spistream.
#define LED_ON(i)
Definition: led_hw.h:28
uint8_t uart_data[SPISTREAM_MAX_MESSAGE_LENGTH]
static void on_overo_link_lost(void)
static void on_overo_link_crc_failed(void)
static void uart_transfer_event(void)
spistream stress test: Send big (500-700 bytes) messages with different message lengths for every cha...
struct spistream_uart_msg * msg
static struct spistream_uart_msg spistream_uart2_msg
Architecture independent timing functions.
static struct spistream_uart_msg spistream_uart1_msg
unsigned long uint32_t
Definition: types.h:18
static uint8_t spistream_wait_for_num_transfers
static void main_init(void)
int sys_time_register_timer(float duration, sys_time_cb cb)
Register a new system timer.
Definition: sys_time.c:37
static bool_t sys_time_check_and_ack_timer(tid_t id)
Check if timer has elapsed.
Definition: sys_time.h:111
#define LED_PERIODIC()
Definition: led_hw.h:8
Arch independent mcu ( Micro Controller Unit ) utilities.
unsigned char uint8_t
Definition: types.h:14
static void on_overo_link_msg_received(void)
Every SPI transfer contains exactly two packages of type AutopilotMessagePTStream, one for each direction (up: STM->Overo, down: Overo->STM).
int main(void)
static void spistream_init(spistream_message_rx_handler_t message_rx_handler, spistream_message_tx_handler_t message_tx_handler)
#define PERIODIC_FREQUENCY
Definition: imu_aspirin2.c:54
#define LED_OFF(i)
Definition: led_hw.h:29
arch independent LED (Light Emitting Diodes) API
static void on_spistream_msg_received(uint8_t msg_id, uint8_t *data, uint16_t num_bytes)
Handler for commands (messages from Overo->STM).
static void spistream_read_pkg(struct AutopilotMessagePTStream *pkg_in)
Read a single package into internal RX buffer.
static void spistream_write_pkg(struct AutopilotMessagePTStream *pkg_out)
Fill given SPI package with next package from TX buffer.
static void on_spistream_msg_sent(uint8_t msg_id)
static void main_periodic(void)