Paparazzi UAS  v4.0.4_stable-3-gf39211a
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
spektrum_arch.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2010 Eric Parsonage <eric@eparsonage.com>
5  *
6  * This file is part of paparazzi.
7  *
8  * paparazzi is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * paparazzi is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with paparazzi; see the file COPYING. If not, write to
20  * the Free Software Foundation, 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
24 #include <stdint.h>
25 #include <stm32/gpio.h>
26 #include <stm32/rcc.h>
27 #include <stm32/tim.h>
28 #include <stm32/misc.h>
29 #include <stm32/usart.h>
31 #include "subsystems/radio_control/spektrum_arch.h"
32 #include "mcu_periph/uart.h"
33 #include "pprz_baudrate.h"
34 
35 
36 
37 #define SPEKTRUM_CHANNELS_PER_FRAME 7
38 #define MAX_SPEKTRUM_FRAMES 2
39 #define MAX_SPEKTRUM_CHANNELS 16
40 
41 #define MAX_DELAY INT16_MAX
42 /* the frequency of the delay timer */
43 #define DELAY_TIM_FREQUENCY 1000000
44 /* Number of low pulses sent to satellite receivers */
45 #define MASTER_RECEIVER_PULSES 5
46 #define SLAVE_RECEIVER_PULSES 6
47 
48 /* The line that is pulled low at power up to initiate the bind process */
49 #define BIND_PIN GPIO_Pin_3
50 #define BIND_PIN_PORT GPIOC
51 #define BIND_PIN_PERIPH RCC_APB2Periph_GPIOC
52 
53 #define TIM_FREQ_1000000 1000000
54 #define TIM_TICS_FOR_100us 100
55 #define MIN_FRAME_SPACE 70 // 7ms
56 #define MAX_BYTE_SPACE 3 // .3ms
57 
58 /*
59  * in the makefile we set RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT to be Uartx
60  * but in uart_hw.c the initialisation functions are
61  * defined as uartx these macros give us the glue
62  * that allows static calls at compile time
63  */
64 
65 #define __PrimaryUart(dev, _x) dev##_x
66 #define _PrimaryUart(dev, _x) __PrimaryUart(dev, _x)
67 #define PrimaryUart(_x) _PrimaryUart(RADIO_CONTROL_SPEKTRUM_PRIMARY_PORT, _x)
68 
69 #define __SecondaryUart(dev, _x) dev##_x
70 #define _SecondaryUart(dev, _x) __SecondaryUart(dev, _x)
71 #define SecondaryUart(_x) _SecondaryUart(RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT, _x)
72 
84 };
85 
87 
89 #ifdef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
90 #pragma message "Using secondary spektrum receiver."
91 SpektrumStateType SecondarySpektrumState = {1,0,0,0,0,0,0,0,0};
92 #else
93 #pragma message "NOT using secondary spektrum receiver."
94 #endif
95 
97 /* the order of the channels on a spektrum is always as follows :
98  *
99  * Throttle 0
100  * Aileron 1
101  * Elevator 2
102  * Rudder 3
103  * Gear 4
104  * Flap/Aux1 5
105  * Aux2 6
106  * Aux3 7
107  * Aux4 8
108  * Aux5 9
109  * Aux6 10
110  * Aux7 11
111  */
112 
113 /* reverse some channels to suit Paparazzi conventions */
114 /* the maximum number of channels a Spektrum can transmit is 12 */
116 
117 /* Parser state variables */
120 /* initialise the uarts used by the parser */
121 void SpektrumUartInit(void);
122 /* initialise the timer used by the parser to ensure sync */
123 void SpektrumTimerInit(void);
124 /* sets a GPIO pin as output for debugging */
125 void DebugInit(void);
126 void tim6_irq_handler(void);
127 /* wait busy loop, microseconds */
128 static void DelayUs( uint16_t uSecs );
129 /* wait busy loop, milliseconds */
130 static void DelayMs( uint16_t mSecs );
131 /* setup timer 1 for busy wait delays */
132 static void SpektrumDelayInit( void );
133 
134 
135  /*****************************************************************************
136  *
137  * Initialise the timer an uarts used by the Spektrum receiver subsystem
138  *
139  *****************************************************************************/
142  // DebugInit();
144 }
145 
146 /*****************************************************************************
147  * The bind function means that the satellite receivers believe they are
148  * connected to a 9 channel JR-R921 24 receiver thus during the bind process
149  * they try to get the transmitter to transmit at the highest resolution that
150  * it can manage. The data is contained in 16 byte packets transmitted at
151  * 115200 baud. Depending on the transmitter either 1 or 2 frames are required
152  * to contain the data for all channels. These frames are either 11ms or 22ms
153  * apart.
154  *
155  * The format of each frame for the main receiver is as follows
156  *
157  * byte1: frame loss data
158  * byte2: transmitter information
159  * byte3: and byte4: channel data
160  * byte5: and byte6: channel data
161  * byte7: and byte8: channel data
162  * byte9: and byte10: channel data
163  * byte11: and byte12: channel data
164  * byte13: and byte14: channel data
165  * byte15: and byte16: channel data
166  *
167  *
168  * The format of each frame for the secondary receiver is as follows
169  *
170  * byte1: frame loss data
171  * byte2: frame loss data
172  * byte3: and byte4: channel data
173  * byte5: and byte6: channel data
174  * byte7: and byte8: channel data
175  * byte9: and byte10: channel data
176  * byte11: and byte12: channel data
177  * byte13: and byte14: channel data
178  * byte15: and byte16: channel data
179  *
180  * The frame loss data bytes starts out containing 0 as long as the
181  * transmitter is switched on before the receivers. It then increments
182  * whenever frames are dropped.
183  *
184  * Three values for the transmitter information byte have been seen thus far
185  *
186  * 0x01 From a Spektrum DX7eu which transmits a single frame containing all
187  * channel data every 22ms with 10bit resolution.
188  *
189  * 0x02 From a Spektrum DM9 module which transmits two frames to carry the
190  * data for all channels 11ms apart with 10bit resolution.
191  *
192  * 0x12 From a Spektrum DX7se which transmits two frames to carry the
193  * data for all channels 11ms apart with 11bit resolution.
194  *
195  * 0x12 From a JR X9503 which transmits two frames to carry the
196  * data for all channels 11ms apart with 11bit resolution.
197  *
198  * 0x01 From a Spektrum DX7 which transmits a single frame containing all
199  * channel data every 22ms with 10bit resolution.
200  *
201  * 0x12 From a JR DSX12 which transmits two frames to carry the
202  * data for all channels 11ms apart with 11bit resolution.
203  *
204  * 0x1 From a Spektru DX5e which transmits a single frame containing all
205  * channel data every 22ms with 10bit resolution.
206  *
207  * 0x01 From a Spektrum DX6i which transmits a single frame containing all
208  * channel data every 22ms with 10bit resolution.
209  *
210  * Currently the assumption is that the data has the form :
211  *
212  * [0 0 0 R 0 0 N1 N0]
213  *
214  * where :
215  *
216  * 0 means a '0' bit
217  * R: 0 for 10 bit resolution 1 for 11 bit resolution channel data
218  * N1 to N0 is the number of frames required to receive all channel
219  * data.
220  *
221  * Channels can have either 10bit or 11bit resolution. Data from a tranmitter
222  * with 10 bit resolution has the form:
223  *
224  * [F 0 C3 C2 C1 C0 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0]
225  *
226  * Data from a tranmitter with 11 bit resolution has the form
227  *
228  * [F C3 C2 C1 C0 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0]
229  *
230  * where :
231  *
232  * 0 means a '0' bit
233  * F: Normally 0 but set to 1 for the first channel of the 2nd frame if a
234  * second frame is transmitted.
235  *
236  * C3 to C0 is the channel number, 4 bit, matching the numbers allocated in
237  * the transmitter.
238  *
239  * D9 to D0 is the channel data (10 bit) 0xaa..0x200..0x356 for
240  * 100% transmitter-travel
241  *
242  *
243  * D10 to D0 is the channel data (11 bit) 0x154..0x400..0x6AC for
244  * 100% transmitter-travel
245  *****************************************************************************/
246 
247  /*****************************************************************************
248  *
249  * Spektrum Parser captures frame data by using time between frames to sync on
250  *
251  *****************************************************************************/
252 
253 #define SpektrumParser(_c, _SpektrumState, _receiver) { \
254  \
255  uint16_t ChannelData; \
256  uint8_t TimedOut; \
257  static uint8_t TmpEncType = 0; /* 0 = 10bit, 1 = 11 bit */ \
258  static uint8_t TmpExpFrames = 0; /* # of frames for channel data */ \
259  \
260  TimedOut = (!_SpektrumState.SpektrumTimer) ? 1 : 0; \
261  \
262  /* If we have just started the resync process or */ \
263  /* if we have recieved a character before our */ \
264  /* 7ms wait has finished */ \
265  if ((_SpektrumState.ReSync == 1) || \
266  ((_SpektrumState.Sync == 0) && (!TimedOut))) { \
267  \
268  _SpektrumState.ReSync = 0; \
269  _SpektrumState.SpektrumTimer = MIN_FRAME_SPACE; \
270  _SpektrumState.Sync = 0; \
271  _SpektrumState.ChannelCnt = 0; \
272  _SpektrumState.FrameCnt = 0; \
273  _SpektrumState.SecondFrame = 0; \
274  return; \
275  } \
276  \
277  /* the first byte of a new frame. It was received */ \
278  /* more than 7ms after the last received byte. */ \
279  /* It represents the number of lost frames so far.*/ \
280  if (_SpektrumState.Sync == 0) { \
281  _SpektrumState.LostFrameCnt = _c; \
282  if(_receiver) /* secondary receiver */ \
283  _SpektrumState.LostFrameCnt = _SpektrumState.LostFrameCnt << 8; \
284  _SpektrumState.Sync = 1; \
285  _SpektrumState.SpektrumTimer = MAX_BYTE_SPACE; \
286  return; \
287  } \
288  \
289  /* all other bytes should be recieved within */ \
290  /* MAX_BYTE_SPACE time of the last byte received */ \
291  /* otherwise something went wrong resynchronise */ \
292  if(TimedOut) { \
293  _SpektrumState.ReSync = 1; \
294  /* next frame not expected sooner than 7ms */ \
295  _SpektrumState.SpektrumTimer = MIN_FRAME_SPACE; \
296  return; \
297  } \
298  \
299  /* second character determines resolution and frame rate for main */ \
300  /* receiver or low byte of LostFrameCount for secondary receiver */ \
301  if(_SpektrumState.Sync == 1) { \
302  if(_receiver) { \
303  _SpektrumState.LostFrameCnt +=_c; \
304  TmpExpFrames = ExpectedFrames; \
305  } else { \
306  /* TODO: collect more data. I suspect that there is a low res */\
307  /* protocol that is still 10 bit but without using the full range. */\
308  TmpEncType =(_c & 0x10)>>4; /* 0 = 10bit, 1 = 11 bit */\
309  TmpExpFrames = _c & 0x03; /* 1 = 1 frame contains all channels */\
310  /* 2 = 2 channel data in 2 frames */\
311  } \
312  _SpektrumState.Sync = 2; \
313  _SpektrumState.SpektrumTimer = MAX_BYTE_SPACE; \
314  return; \
315  } \
316  \
317  /* high byte of channel data if this is the first byte */ \
318  /* of channel data and the most significant bit is set */ \
319  /* then this is the second frame of channel data. */ \
320  if(_SpektrumState.Sync == 2) { \
321  _SpektrumState.HighByte = _c; \
322  if (_SpektrumState.ChannelCnt == 0) { \
323  _SpektrumState.SecondFrame = (_SpektrumState.HighByte & 0x80) ? 1 : 0; \
324  } \
325  _SpektrumState.Sync = 3; \
326  _SpektrumState.SpektrumTimer = MAX_BYTE_SPACE; \
327  return; \
328  } \
329  \
330  /* low byte of channel data */ \
331  if(_SpektrumState.Sync == 3) { \
332  _SpektrumState.Sync = 2; \
333  _SpektrumState.SpektrumTimer = MAX_BYTE_SPACE; \
334  /* we overwrite the buffer now so rc data is not available now */ \
335  _SpektrumState.RcAvailable = 0; \
336  ChannelData = ((uint16_t)_SpektrumState.HighByte << 8) | _c; \
337  _SpektrumState.values[_SpektrumState.ChannelCnt \
338  + (_SpektrumState.SecondFrame * 7)] = ChannelData; \
339  _SpektrumState.ChannelCnt ++; \
340  } \
341  \
342  /* If we have a whole frame */ \
343  if(_SpektrumState.ChannelCnt >= SPEKTRUM_CHANNELS_PER_FRAME) { \
344  /* how many frames did we expect ? */ \
345  ++_SpektrumState.FrameCnt; \
346  if (_SpektrumState.FrameCnt == TmpExpFrames) \
347  { \
348  /* set the rc_available_flag */ \
349  _SpektrumState.RcAvailable = 1; \
350  _SpektrumState.FrameCnt = 0; \
351  } \
352  if(!_receiver) { /* main receiver */ \
353  EncodingType = TmpEncType; /* only update on a good */ \
354  ExpectedFrames = TmpExpFrames; /* main receiver frame */ \
355  } \
356  _SpektrumState.Sync = 0; \
357  _SpektrumState.ChannelCnt = 0; \
358  _SpektrumState.SecondFrame = 0; \
359  _SpektrumState.SpektrumTimer = MIN_FRAME_SPACE; \
360  } \
361 } \
362 
363 /*****************************************************************************
364  *
365  * RadioControlEventImp decodes channel data stored by uart irq handlers
366  * and calls callback funtion
367  *
368  *****************************************************************************/
369 
370 void RadioControlEventImp(void (*frame_handler)(void)) {
372  uint8_t ChannelNum;
373  uint16_t ChannelData;
374  uint8_t MaxChannelNum = 0;
375 
376 #ifdef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
377  /* If we have two receivers and at least one of them has new data */
378  uint8_t BestReceiver;
379  if ((PrimarySpektrumState.RcAvailable) ||
380  (SecondarySpektrumState.RcAvailable)) {
381  /* if both receivers have new data select the one */
382  /* that has had the least number of frames lost */
383  if ((PrimarySpektrumState.RcAvailable) &&
384  (SecondarySpektrumState.RcAvailable)) {
385  BestReceiver = (PrimarySpektrumState.LostFrameCnt
386  <= SecondarySpektrumState.LostFrameCnt) ? 0 : 1;
387  } else {
388  /* if only one of the receivers have new data use it */
389  BestReceiver = (PrimarySpektrumState.RcAvailable) ? 0 : 1;
390  }
391  /* clear the data ready flags */
392  PrimarySpektrumState.RcAvailable = 0;
393  SecondarySpektrumState.RcAvailable = 0;
394 
395 #else
396  /* if we have one receiver and it has new data */
397  if(PrimarySpektrumState.RcAvailable) {
398  PrimarySpektrumState.RcAvailable = 0;
399 #endif
400  ChannelCnt = 0;
401  /* for every piece of channel data we have received */
402  for(int i = 0; (i < SPEKTRUM_CHANNELS_PER_FRAME * ExpectedFrames); i++) {
403 #ifndef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
404  ChannelData = PrimarySpektrumState.values[i];
405 #else
406  ChannelData = (!BestReceiver) ? PrimarySpektrumState.values[i] :
407  SecondarySpektrumState.values[i];
408 #endif
409  /* find out the channel number and its value by */
410  /* using the EncodingType which is only received */
411  /* from the main receiver */
412  switch(EncodingType) {
413  case(0) : /* 10 bit */
414  ChannelNum = (ChannelData >> 10) & 0x0f;
415  /* don't bother decoding unused channels */
416  if (ChannelNum < RADIO_CONTROL_NB_CHANNEL) {
417  SpektrumBuf[ChannelNum] = ChannelData & 0x3ff;
418  SpektrumBuf[ChannelNum] -= 0x200;
419  SpektrumBuf[ChannelNum] *= MAX_PPRZ/0x156;
420  ChannelCnt++;
421  }
422  break;
423 
424  case(1) : /* 11 bit */
425  ChannelNum = (ChannelData >> 11) & 0x0f;
426  /* don't bother decoding unused channels */
427  if (ChannelNum < RADIO_CONTROL_NB_CHANNEL) {
428  SpektrumBuf[ChannelNum] = ChannelData & 0x7ff;
429  SpektrumBuf[ChannelNum] -= 0x400;
430  SpektrumBuf[ChannelNum] *= MAX_PPRZ/0x2AC;
431  ChannelCnt++;
432  }
433  break;
434 
435  default : ChannelNum = 0x0F; break; /* never going to get here */
436  }
437  /* store the value of the highest valid channel */
438  if ((ChannelNum != 0x0F) && (ChannelNum > MaxChannelNum))
439  MaxChannelNum = ChannelNum;
440 
441  }
442 
443  /* if we have a valid frame the pass it to the frame handler */
444  if (ChannelCnt >= (MaxChannelNum + 1)) {
445  radio_control.frame_cpt++;
446  radio_control.time_since_last_frame = 0;
447  radio_control.status = RC_OK;
448  for (int i = 0; i < (MaxChannelNum + 1); i++) {
449  radio_control.values[i] = SpektrumBuf[i];
450  if (i == RADIO_THROTTLE ) {
451  radio_control.values[i] += MAX_PPRZ;
452  radio_control.values[i] /= 2;
453  }
454  radio_control.values[i] *= SpektrumSigns[i];
455  }
456  (*frame_handler)();
457  }
458  }
459 }
460 
461 
462 /*****************************************************************************
463  *
464  * Initialise TIM6 to fire an interrupt every 100 microseconds to provide
465  * timebase for SpektrumParser
466  *
467  *****************************************************************************/
468 void SpektrumTimerInit( void ) {
469 
470  /* enable TIM6 clock */
471  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
472 
473  /* TIM6 configuration */
474  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
475  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
476  /* 100 microseconds ie 0.1 millisecond */
477  TIM_TimeBaseStructure.TIM_Period = TIM_TICS_FOR_100us-1;
478  TIM_TimeBaseStructure.TIM_Prescaler = ((AHB_CLK / TIM_FREQ_1000000) - 1);
479  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
480  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down;
481  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
482 
483  /* Enable TIM6 interrupts */
484  NVIC_InitTypeDef NVIC_InitStructure;
485 
486  /* Enable and configure TIM6 IRQ channel */
487  NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
488  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
489  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
490  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
491  NVIC_Init(&NVIC_InitStructure);
492 
493  /* Enable TIM6 Update interrupt */
494  TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
495  TIM_ClearFlag(TIM6, TIM_FLAG_Update);
496 
497  /* TIM6 enable counter */
498  TIM_Cmd(TIM6, ENABLE);
499 }
500 
501 /*****************************************************************************
502  *
503  * TIM6 interrupt request handler updates times used by SpektrumParser
504  *
505  *****************************************************************************/
506 void tim6_irq_handler( void ) {
507 
508  TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
509 
510  if (PrimarySpektrumState.SpektrumTimer)
511  --PrimarySpektrumState.SpektrumTimer;
512 #ifdef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
513  if (SecondarySpektrumState.SpektrumTimer)
514  --SecondarySpektrumState.SpektrumTimer;
515 #endif
516 }
517 
518 /*****************************************************************************
519  *
520  * Initialise the uarts for the spektrum satellite receivers
521  *
522  *****************************************************************************/
523 void SpektrumUartInit(void) {
524  /* init RCC */
525  PrimaryUart(_remap);
526  PrimaryUart(_clk)(PrimaryUart(_UartPeriph), ENABLE);;
527  //RCC_APB1PeriphClockCmd(PrimaryUart(_UartPeriph), ENABLE);
528 
529  /* Enable USART interrupts */
530  NVIC_InitTypeDef nvic;
531  nvic.NVIC_IRQChannel = PrimaryUart(_IRQn);
532  nvic.NVIC_IRQChannelPreemptionPriority = 2;
533  nvic.NVIC_IRQChannelSubPriority = 1;
534  nvic.NVIC_IRQChannelCmd = ENABLE;
535  NVIC_Init(&nvic);
536  /* Init GPIOS */
537  GPIO_InitTypeDef GPIO_InitStructure;
538  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
539  /* Primary UART Rx pin as floating input */
540  GPIO_InitStructure.GPIO_Pin = PrimaryUart(_RxPin);
541  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
542  GPIO_Init(PrimaryUart(_RxPort), &GPIO_InitStructure);
543  /* Configure Primary UART */
544  USART_InitTypeDef usart;
545  usart.USART_BaudRate = B115200;
546  usart.USART_WordLength = USART_WordLength_8b;
547  usart.USART_StopBits = USART_StopBits_1;
548  usart.USART_Parity = USART_Parity_No;
549  usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
550  usart.USART_Mode = USART_Mode_Rx;
551  USART_Init(PrimaryUart(_reg), &usart);
552  /* Enable Primary UART Receive interrupts */
553  USART_ITConfig(PrimaryUart(_reg), USART_IT_RXNE, ENABLE);
554 
555  /* required to get the correct baudrate on lisa m */
557  /* Enable the Primary UART */
558  USART_Cmd(PrimaryUart(_reg), ENABLE);
559 
560 
561 #ifdef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
562  /* init RCC */
563  SecondaryUart(_remap);
564  SecondaryUart(_clk)(SecondaryUart(_UartPeriph), ENABLE);
565  //RCC_APB1PeriphClockCmd(SecondaryUart(_UartPeriph), ENABLE);
566  /* Enable USART interrupts */
567  nvic.NVIC_IRQChannel = SecondaryUart(_IRQn);
568  nvic.NVIC_IRQChannelPreemptionPriority = 2;
569  nvic.NVIC_IRQChannelSubPriority = 2;
570  nvic.NVIC_IRQChannelCmd = ENABLE;
571  NVIC_Init(&nvic);
572  /* Init GPIOS */;
573  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
574  /* Secondary UART Rx pin as floating input */
575  GPIO_InitStructure.GPIO_Pin = SecondaryUart(_RxPin);
576  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
577  GPIO_Init(SecondaryUart(_RxPort), &GPIO_InitStructure);
578  /* Configure secondary UART */
579  usart.USART_BaudRate = B115200;
580  usart.USART_WordLength = USART_WordLength_8b;
581  usart.USART_StopBits = USART_StopBits_1;
582  usart.USART_Parity = USART_Parity_No;
583  usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
584  usart.USART_Mode = USART_Mode_Rx;
585  USART_Init(SecondaryUart(_reg), &usart);
586  /* Enable Secondary UART Receive interrupts */
587  USART_ITConfig(SecondaryUart(_reg), USART_IT_RXNE, ENABLE);
588 
589  /* required to get the correct baudrate on lisa m */
591  /* Enable the Primary UART */
592  USART_Cmd(SecondaryUart(_reg), ENABLE);
593 #endif
594 
595 }
596 
597 /*****************************************************************************
598  *
599  * The primary receiver UART interrupt request handler which passes the
600  * received character to Spektrum Parser.
601  *
602  *****************************************************************************/
604 
605  if(USART_GetITStatus(PrimaryUart(_reg), USART_IT_TXE) != RESET) {
606  USART_ITConfig(PrimaryUart(_reg), USART_IT_TXE, DISABLE);
607  }
608 
609  if(USART_GetITStatus(PrimaryUart(_reg), USART_IT_RXNE) != RESET) {
610  uint8_t b = USART_ReceiveData(PrimaryUart(_reg));
611  SpektrumParser(b, PrimarySpektrumState, 0);
612  }
613 }
614 
615 /*****************************************************************************
616  *
617  * The secondary receiver UART interrupt request handler which passes the
618  * received character to Spektrum Parser.
619  *
620  *****************************************************************************/
621 #ifdef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
622 void SecondaryUart(_irq_handler)(void) {
623 
624  if(USART_GetITStatus(SecondaryUart(_reg), USART_IT_TXE) != RESET) {
625  USART_ITConfig(SecondaryUart(_reg), USART_IT_TXE, DISABLE);
626  }
627 
628  if(USART_GetITStatus(SecondaryUart(_reg), USART_IT_RXNE) != RESET) {
629  uint8_t b = USART_ReceiveData(SecondaryUart(_reg));
630  SpektrumParser(b, SecondarySpektrumState, 1);
631  }
632 }
633 #endif
634 
635 /*****************************************************************************
636  *
637  * Use pin to output debug information.
638  *
639  *****************************************************************************/
640 void DebugInit(void) {
641  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);
642  GPIO_InitTypeDef GPIO_InitStructure;
643  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
644  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
645  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
646  GPIO_Init(GPIOC, &GPIO_InitStructure);
647  GPIO_WriteBit(GPIOC, GPIO_Pin_5 , Bit_RESET );
648 }
649 
650 /*****************************************************************************
651  *
652  * The following functions provide functionality to allow binding of
653  * spektrum satellite receivers. The pulse train sent to them means
654  * that Lisa is emulating a 9 channel JR-R921 24.
655  *
656  *****************************************************************************/
657 /*****************************************************************************
658  *
659  * radio_control_spektrum_try_bind(void) must called on powerup as spektrum
660  * satellites can only bind immediately after power up also it must be called
661  * before the call to SpektrumUartInit as we leave them with their Rx pins set
662  * as outputs.
663  *
664  *****************************************************************************/
666 
667  /* init RCC */
668  RCC_APB2PeriphClockCmd(BIND_PIN_PERIPH , ENABLE);
669 
670  /* Init GPIO for the bind pin */
671  GPIO_InitTypeDef GPIO_InitStructure;
672  GPIO_InitStructure.GPIO_Pin = BIND_PIN;
673  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
674  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
675  GPIO_Init(BIND_PIN_PORT, &GPIO_InitStructure);
676  /* exit if the BIND_PIN is high, it needs to
677  be pulled low at startup to initiate bind */
678  if (GPIO_ReadInputDataBit(BIND_PIN_PORT, BIND_PIN))
679  return;
680 
681  /* bind initiated, initialise the delay timer */
683 
684  /* initialise the uarts rx pins as GPIOS */
685  RCC_APB2PeriphClockCmd(PrimaryUart(_Periph) , ENABLE);
686  /* Master receiver Rx push-pull */
687  GPIO_InitStructure.GPIO_Pin = PrimaryUart(_RxPin);
688  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
689  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
690  GPIO_Init(PrimaryUart(_RxPort), &GPIO_InitStructure);
691  /* Master receiver RX line, drive high */
692  GPIO_WriteBit(PrimaryUart(_RxPort), PrimaryUart(_RxPin) , Bit_SET );
693 
694 #ifdef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
695  RCC_APB2PeriphClockCmd(SecondaryUart(_Periph) , ENABLE);
696  /* Slave receiver Rx push-pull */
697  GPIO_InitStructure.GPIO_Pin = SecondaryUart(_RxPin);
698  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
699  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
700  GPIO_Init(SecondaryUart(_RxPort), &GPIO_InitStructure);
701  /* Slave receiver RX line, drive high */
702  GPIO_WriteBit(SecondaryUart(_RxPort), SecondaryUart(_RxPin) , Bit_SET );
703 #endif
704 
705  /* We have no idea how long the window for allowing binding after
706  power up is. This works for the moment but will need revisiting */
707  DelayMs(61);
708 
709  for (int i = 0; i < MASTER_RECEIVER_PULSES ; i++)
710  {
711  GPIO_WriteBit(PrimaryUart(_RxPort), PrimaryUart(_RxPin), Bit_RESET );
712  DelayUs(118);
713  GPIO_WriteBit(PrimaryUart(_RxPort), PrimaryUart(_RxPin), Bit_SET );
714  DelayUs(122);
715  }
716 
717 #ifdef RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT
718  for (int i = 0; i < SLAVE_RECEIVER_PULSES; i++)
719  {
720  GPIO_WriteBit(SecondaryUart(_RxPort), SecondaryUart(_RxPin), Bit_RESET );
721  DelayUs(120);
722  GPIO_WriteBit(SecondaryUart(_RxPort), SecondaryUart(_RxPin), Bit_SET );
723  DelayUs(120);
724  }
725 #endif /* RADIO_CONTROL_SPEKTRUM_SECONDARY_PORT */
726 }
727 
728 /*****************************************************************************
729  *
730  * Functions to implement busy wait loops with micro second granularity
731  *
732  *****************************************************************************/
733 
734 /* set TIM6 to run at DELAY_TIM_FREQUENCY */
735 static void SpektrumDelayInit( void ) {
736  /* Enable timer clock */
737  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
738  /* Time base configuration */
739  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
740  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
741  TIM_TimeBaseStructure.TIM_Prescaler = (AHB_CLK / DELAY_TIM_FREQUENCY) - 1;
742  TIM_TimeBaseStructure.TIM_Period = UINT16_MAX;
743  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
744  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
745  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
746 
747  /* Enable counter */
748  TIM_Cmd(TIM6, ENABLE);
749 }
750 
751 /* wait busy loop, microseconds */
752 static void DelayUs( uint16_t uSecs ) {
753  uint16_t start = TIM6->CNT;
754  /* use 16 bit count wrap around */
755  while((uint16_t)(TIM6->CNT - start) <= uSecs);
756 }
757 
758 /* wait busy loop, milliseconds */
759 static void DelayMs( uint16_t mSecs ) {
760  for(int i = 0; i < mSecs; i++) {
762  }
763 }
int16_t SpektrumBuf[SPEKTRUM_CHANNELS_PER_FRAME *MAX_SPEKTRUM_FRAMES]
Definition: spektrum_arch.c:96
void radio_control_impl_init(void)
Definition: spektrum_arch.c:32
void radio_control_spektrum_try_bind(void)
unsigned short uint16_t
Definition: types.h:16
void DebugInit(void)
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define SLAVE_RECEIVER_PULSES
Definition: spektrum_arch.c:46
#define pprz_usart_set_baudrate(x, y)
Definition: pprz_baudrate.h:10
#define DELAY_TIM_FREQUENCY
Definition: spektrum_arch.c:43
void RadioControlEventImp(void(*frame_handler)(void))
#define SpektrumParser(_c, _SpektrumState, _receiver)
void SpektrumTimerInit(void)
#define MAX_SPEKTRUM_FRAMES
Definition: spektrum_arch.c:38
#define MASTER_RECEIVER_PULSES
Definition: spektrum_arch.c:45
#define BIND_PIN
Definition: spektrum_arch.c:49
#define PrimaryUart(_x)
Definition: spektrum_arch.c:67
static uint8_t ExpectedFrames
#define SecondaryUart(_x)
Definition: spektrum_arch.c:71
#define B115200
Definition: uart_arch.h:41
void tim6_irq_handler(void)
SpektrumStateType PrimarySpektrumState
Definition: spektrum_arch.c:88
#define SPEKTRUM_CHANNELS_PER_FRAME
Definition: spektrum_arch.c:37
#define BIND_PIN_PERIPH
Definition: spektrum_arch.c:51
signed short int16_t
Definition: types.h:17
static uint8_t EncodingType
#define TIM_FREQ_1000000
Definition: spektrum_arch.c:53
struct RadioControl radio_control
Definition: radio_control.c:27
static void DelayUs(uint16_t uSecs)
int8_t SpektrumSigns[]
void PrimaryUart() _irq_handler(void)
static void DelayMs(uint16_t mSecs)
#define RADIO_THROTTLE
Definition: spektrum_arch.h:40
#define TIM_TICS_FOR_100us
Definition: spektrum_arch.c:54
#define RADIO_CONTROL_NB_CHANNEL
Definition: spektrum_arch.h:36
#define RADIO_CONTROL_SPEKTRUM_SIGNS
Definition: spektrum_arch.h:57
unsigned char uint8_t
Definition: types.h:14
void SpektrumUartInit(void)
#define BIND_PIN_PORT
Definition: spektrum_arch.c:50
#define MAX_PPRZ
Definition: paparazzi.h:8
signed char int8_t
Definition: types.h:15
#define RESET
Definition: humid_sht.h:40
int16_t values[SPEKTRUM_CHANNELS_PER_FRAME *MAX_SPEKTRUM_FRAMES]
Definition: spektrum_arch.c:83
#define AHB_CLK
Definition: beth.h:4
static void SpektrumDelayInit(void)