1  | /*
  | 
2  | This program is free software: you can redistribute it and/or modify
  | 
3  | it under the terms of the GNU General Public License as published by
  | 
4  | the Free Software Foundation, either version 3 of the License, or
  | 
5  | (at your option) any later version.
  | 
6  | 
  | 
7  | This program is distributed in the hope that it will be useful,
  | 
8  | but WITHOUT ANY WARRANTY; without even the implied warranty of
  | 
9  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  | 
10  | GNU General Public License for more details.
  | 
11  | 
  | 
12  | You should have received a copy of the GNU General Public License
  | 
13  | along with this program.  If not, see <http://www.gnu.org/licenses/>.
  | 
14  | *
  | 
15  | *  @ Project : MultiSensor
  | 
16  | *  @ File Name :SBUS_usart.cpp
  | 
17  | *  @ Date : 6/12/2013
  | 
18  | *  @ Author : Bart Keser
  | 
19  | *
  | 
20  | */
  | 
21  | 
  | 
22  | #include <avr/io.h>
  | 
23  | #include <avr/interrupt.h>
  | 
24  | #include <stdarg.h>
  | 
25  | #include <stdlib.h>
  | 
26  | #include <string.h>
  | 
27  | 
  | 
28  | #include "myavr.h"
  | 
29  | #include "SBUS_usart.h"
  | 
30  | #include "usart.h"
  | 
31  | 
  | 
32  | 
  | 
33  | #define F_CPU                   8000000
  | 
34  | 
  | 
35  | #define SLOT_DATA_LENGTH        3
  | 
36  | #define NUMBER_OF_FRAMES        4
  | 
37  | #define NUMBER_OF_SLOT          32
  | 
38  | #define NUMBER_OF_SLOT_IN_FRAME 8
  | 
39  | #define SBUS_FRAME_SIZE         25
  | 
40  | #define SBUS_CHANNEL_SIZE       11
  | 
41  | 
  | 
42  | 
  | 
43  | #define UART_RXBUFSIZE  30
  | 
44  | #define FRAME_TIME_OUT  200 //ms
  | 
45  | 
  | 
46  | 
  | 
47  | #define TRANSMIT_PIN  PIN_0 // digital IO C
  | 
48  | #define RECEIVE_PIN   PIN_5 // digital IO B
  | 
49  | #define TRANSMIT_RECEIVE_ENABLE  LOW
  | 
50  | #define TRANSMIT_RECEIVE_DISABLE HIGH
  | 
51  | 
  | 
52  | #define SLOT_TIME 90    //165
  | 
53  | #define SLOT_TIME2 165    
  | 
54  | 
  | 
55  | 
  | 
56  | uint8_t  swaps_slot_bits[8] = {0,4,2,6,1,5,3,7};
 | 
57  |    
  | 
58  | uint8_t toggle  = 0;   
  | 
59  | 
  | 
60  | 
  | 
61  | //static bool      command_received = false;
  | 
62  | //static uint8_t   command[UART_RXBUFSIZE];
  | 
63  | //static uint8_t   command_length = 9;
  | 
64  | 
  | 
65  | // 248 is around 1 ms
  | 
66  | uint8_t  transmit_sequence_timer[15] = {250,250,SLOT_TIME2,SLOT_TIME,SLOT_TIME,SLOT_TIME,SLOT_TIME,SLOT_TIME,SLOT_TIME,SLOT_TIME,226,226,226,226,180};
 | 
67  | uint8_t  receive_timeout_timer = ( uint8_t ) (248.0 * (FRAME_TIME_OUT / 1000.0));
  | 
68  | uint16_t overflow_counter = 0; // should not occur
  | 
69  | 
  | 
70  | static volatile uint8_t   rxbuf[UART_RXBUFSIZE];
  | 
71  | static volatile bool      frame_ready = false;
  | 
72  | static volatile uint8_t   gl_current_frame = 0;
  | 
73  | static volatile uint16_t  uart_lost_frame = 0;
  | 
74  | 
  | 
75  | typedef enum
  | 
76  | {
 | 
77  |    EMPTY = 0,
  | 
78  |    TRANSMITTING,
  | 
79  |    AVAILABLE
  | 
80  | } SLOT_DATA_STATUS;
  | 
81  | 
  | 
82  | typedef struct
  | 
83  | {
 | 
84  |    volatile bool    data_status;
  | 
85  |    volatile uint8_t data[SLOT_DATA_LENGTH];
  | 
86  | } SLOT_RAW_DATA;
  | 
87  | 
  | 
88  | // low resolution timer
  | 
89  | volatile uint8_t         frameLength = 15;
  | 
90  | volatile int8_t          previousFrame = 0;
  | 
91  | volatile uint32_t        frameCounter = 0;
  | 
92  | 
  | 
93  | 
  | 
94  | volatile uint8_t        tx_data_counter;
  | 
95  | volatile uint8_t        buffer_index;
  | 
96  | 
  | 
97  | volatile SLOT_DATA_STATUS transmit_data_per_slot_status[NUMBER_OF_SLOT];
  | 
98  | volatile uint8_t          transmit_data_per_slot_data[NUMBER_OF_SLOT][SLOT_DATA_LENGTH];
  | 
99  | volatile uint8_t          gl_slot;
  | 
100  | 
  | 
101  | void sbus_uart_init();
  | 
102  | void sbus_timer_init();
  | 
103  | void start_receiving();
  | 
104  | void enable_receiving();
  | 
105  | void enable_transmiting();
  | 
106  | void disable_receiving();
  | 
107  | void disable_transmiting();
  | 
108  | void start_transmit_sequencer(uint8_t frame_number);
  | 
109  | void sbus2_send_slot(uint8_t slot);
  | 
110  | 
  | 
111  | void ISR_receive_timeout();
  | 
112  | void ISR_transmit();
  | 
113  | 
  | 
114  | volatile void    (*do_servo_pulls)(uint32_t counter);
  | 
115  | 
  | 
116  | volatile void    (*timer_ISR)();
  | 
117  | 
  | 
118  | //*****************************************************************************
  | 
119  | //
  | 
120  | void SBUS2_uart_setup (void (*start_pulse)(uint32_t))
  | 
121  | {
 | 
122  |    uint32_t counter  = 640000;
  | 
123  |    uint8_t  response = 0x00;
  | 
124  |    
  | 
125  |    noInterrupts();
  | 
126  |    sbus_uart_init();
  | 
127  |    sbus_timer_init();
  | 
128  | 
  | 
129  |    PinBasOutput(RECEIVE_PIN);
  | 
130  |    PinCasOutput(TRANSMIT_PIN);
  | 
131  |    PinCasOutput(PIN_4);
  | 
132  |    
  | 
133  |    disable_transmiting();
  | 
134  |    disable_receiving();
  | 
135  |    
  | 
136  |    UDR = 0xAA;
  | 
137  |    response = 0x00;
  | 
138  |    while(!(UCSRA & (1 << UDRE)));
  | 
139  |    
  | 
140  |    while ((counter > 1)  && ( response != 0x55 ))
  | 
141  |    {
 | 
142  |      response = UDR;
  | 
143  |      while ( UCSRA & (1 << RXC) );
  | 
144  |      counter--;
  | 
145  |    }      
  | 
146  |           
  | 
147  |    do_servo_pulls =  (volatile void    (*)(uint32_t))start_pulse;     
  | 
148  |    start_receiving();
  | 
149  |    
  | 
150  |    if(response != 0x55 )
  | 
151  |    {
 | 
152  |       enable_receiving();       
  | 
153  |    }   
  | 
154  |    interrupts();
  | 
155  |    
  | 
156  | }
  | 
157  | /*
  | 
158  | void SBUS2_uart_command_length(uint8_t length )
  | 
159  | {
 | 
160  |    command_length = length;   
  | 
161  | }
  | 
162  | */
  | 
163  | 
  | 
164  | void sbus_uart_init()
  | 
165  | {
 | 
166  |    // set clock divider
  | 
167  | #undef BAUD
  | 
168  | #define BAUD USART_BAUD
  | 
169  | 
  | 
170  | #include <util/setbaud.h>
  | 
171  | 
  | 
172  |    UBRRH = UBRRH_VALUE;
  | 
173  |    UBRRL = UBRRL_VALUE;
  | 
174  | 
  | 
175  | #if USE_2X
  | 
176  |    UCSRA |= (1 << U2X);  // enable double speed operation
  | 
177  | #else
  | 
178  |    UCSRA &= ~(1 << U2X);  // disable double speed operation
  | 
179  | #endif
  | 
180  | 
  | 
181  |    // set 8E2
  | 
182  |    UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
  | 
183  |    UCSRB &= ~(1 << UCSZ2);
  | 
184  | 
  | 
185  |    UCSRC |= (1 << UPM1);
  | 
186  |    UCSRC |= (1 << USBS);
  | 
187  | 
  | 
188  |    // flush receive buffer
  | 
189  |    while ( UCSRA & (1 << RXC) ) UDR;
  | 
190  | 
  | 
191  |    UCSRB |= (1 << RXEN);
  | 
192  |    UCSRB |= (1 << RXCIE);
  | 
193  |    UCSRB |= (1 << TXEN);
  | 
194  |    UCSRB |= (1 << TXCIE);
  | 
195  | }
  | 
196  | 
  | 
197  | void sbus_timer_init()
  | 
198  | {
 | 
199  |    //memset( (void*)transmit_data_per_slot, 0, sizeof(transmit_data_per_slot));
  | 
200  |    for(uint8_t i = 0; i < 32; i++)
  | 
201  |    {
 | 
202  |       transmit_data_per_slot_status[i] = EMPTY;
  | 
203  |    }
  | 
204  | 
  | 
205  |    TCCR2B = 0x00;        //disable Timer2 while we set it up
  | 
206  |    TCNT2  = 0;           //Reset Timer 0
  | 
207  |    TIFR2  = 0x02;        //Timer2 INT Flag Reg: Clear Timer Overflow Flag
  | 
208  |    TIMSK2 = 0x03;        //Timer2 INT Reg: Timer2 compare A
  | 
209  |    TCCR2A = 0x02;        //Timer2 Control Reg A: CTC
  | 
210  | }
  | 
211  | 
  | 
212  | uint8_t SBUS_get_frame(uint8_t *frame)
  | 
213  | {
 | 
214  |    if( frame_ready )
  | 
215  |    {
 | 
216  |       memcpy(frame, (void*)rxbuf, SBUS_FRAME_SIZE);
  | 
217  |       frame_ready = false;
  | 
218  |       return true;
  | 
219  |    }
  | 
220  |    else
  | 
221  |    {
 | 
222  |       return false;
  | 
223  |    }
  | 
224  | }
  | 
225  | 
  | 
226  | void start_receiving()
  | 
227  | {
 | 
228  |    TCCR2B = 0x00;        //disable Timer2 while we set it up
  | 
229  |    buffer_index = 0;
  | 
230  |    timer_ISR = (volatile void    (*)())ISR_receive_timeout;
  | 
231  |    TCNT2  = 0;           //Reset Timer 0
  | 
232  |    OCR2A = receive_timeout_timer; 
  | 
233  | }
  | 
234  | 
  | 
235  | inline void disable_receiving()
  | 
236  | {
 | 
237  |    PinBOutput( RECEIVE_PIN, TRANSMIT_RECEIVE_DISABLE);
  | 
238  | }
  | 
239  | 
  | 
240  | inline void enable_receiving()
  | 
241  | {
 | 
242  |    PinCOutput( TRANSMIT_PIN, TRANSMIT_RECEIVE_DISABLE);
  | 
243  |    PinBOutput( RECEIVE_PIN, TRANSMIT_RECEIVE_ENABLE);
  | 
244  | }
  | 
245  | 
  | 
246  | inline void disable_transmiting()
  | 
247  | {
 | 
248  |    PinCOutput( TRANSMIT_PIN, TRANSMIT_RECEIVE_DISABLE);
  | 
249  | }
  | 
250  | 
  | 
251  | inline void enable_transmiting()
  | 
252  | {
 | 
253  |    PinBOutput( RECEIVE_PIN, TRANSMIT_RECEIVE_DISABLE);
  | 
254  |    PinCOutput( TRANSMIT_PIN, TRANSMIT_RECEIVE_ENABLE);
  | 
255  | }
  | 
256  | 
  | 
257  | ISR(TIMER2_COMPA_vect)
  | 
258  | {
 | 
259  |    timer_ISR();
  | 
260  | }
  | 
261  | 
  | 
262  | inline void IncreaseTimer( int8_t frameNumber)
  | 
263  | {
 | 
264  |    int8_t temp = (frameNumber - previousFrame) % NUMBER_OF_FRAMES;
  | 
265  |    if (temp <= 0 )
  | 
266  |       temp += NUMBER_OF_FRAMES;          
  | 
267  |    if (temp > 1)
  | 
268  |       uart_lost_frame++;
  | 
269  |    frameCounter += temp;
  | 
270  |    previousFrame = frameNumber;   
  | 
271  | }
  | 
272  | 
  | 
273  | ISR (USART_RX_vect)
  | 
274  | {
 | 
275  |    uint8_t cdata = 0;
  | 
276  |    
  | 
277  |    frame_ready = false;
  | 
278  |    TCNT2  = 0; //Reset Timer 2 for new usart time of char
  | 
279  |    //enable Timer2 Control Reg B: for receive timeout this is done here because we can only start the timeout after first bye is received
  | 
280  |    TCCR2B = 0x03;
  | 
281  |    cdata = UDR;   
  | 
282  |    rxbuf[buffer_index] = cdata;
  | 
283  |    buffer_index++;
  | 
284  |    if (buffer_index == SBUS_FRAME_SIZE)
  | 
285  |    {
 | 
286  |       frame_ready = true;
  | 
287  |       disable_receiving();
  | 
288  |       IncreaseTimer((cdata&0x30) >> 4);
  | 
289  |       start_transmit_sequencer(((cdata&0x30) >> 4)); // frame number needed to select correct telemetry slot
  | 
290  | 
  | 
291  |       if (do_servo_pulls != NULL )
  | 
292  |       {
 | 
293  |          do_servo_pulls(frameCounter * frameLength);
  | 
294  |       }
  | 
295  |       buffer_index = 0;
  | 
296  |    } 
  | 
297  | }
  | 
298  | 
  | 
299  | 
  | 
300  | // receive timeout check for set packed length
  | 
301  | void ISR_receive_timeout()
  | 
302  | {   
 | 
303  | /*   if ( buffer_index == command_length )
  | 
304  |    {
 | 
305  |       // -1 don't add crc in crc :-)
  | 
306  |       uint8_t crc = 0;
  | 
307  |       //crc = crc_cal( (uint8_t*)rxbuf, command_length -1);
  | 
308  |       
  | 
309  |       if ( (crc == rxbuf[command_length -1]) || true )
  | 
310  |       {
 | 
311  |          disable_receiving(); // this puts the module in setup mode 
  | 
312  |          // setup command   
  | 
313  |          memcpy(command, (void*)rxbuf, command_length);    
  | 
314  |          command_received = true;
  | 
315  |       }      
  | 
316  |    }
  | 
317  |    */
  | 
318  |    buffer_index = 0;
  | 
319  | }
  | 
320  | 
  | 
321  | //****************************************************************
  | 
322  | //* TRANSMIT SEQUENCER
  | 
323  | //****************************************************************
  | 
324  | 
  | 
325  | void ISR_transmit()
  | 
326  | {
 | 
327  |    static  uint8_t sequence_count = 1; // first sequence step delay will be filled in when the transmit sequence is enabled
  | 
328  |    //Increments the interrupt counter
  | 
329  |    TCNT2  = 0; // reset at the beginning so that  there is no delay for the next segment of the sequence
  | 
330  | 
  | 
331  |    interrupts();
  | 
332  | 
  | 
333  |    if (sequence_count < 2 )
  | 
334  |    {
 | 
335  |       // don't do anything this is delay to the transmission slots
  | 
336  |       OCR2A = transmit_sequence_timer[sequence_count];
  | 
337  |    }
  | 
338  |    else if (sequence_count < 10 ) // transmit slots
  | 
339  |    {
 | 
340  |       OCR2A = transmit_sequence_timer[sequence_count]; // first set next slot interrupt
  | 
341  |       sbus2_send_slot((sequence_count-2) + (gl_current_frame * NUMBER_OF_SLOT_IN_FRAME) );
  | 
342  |    }
  | 
343  |    else if (sequence_count < 11 )
  | 
344  |    {
 | 
345  |       OCR2A = transmit_sequence_timer[sequence_count];
  | 
346  | 
  | 
347  |    }
  | 
348  |    else if (sequence_count < 14 )
  | 
349  |    {
 | 
350  |       // delay to enabling receive again
  | 
351  |       OCR2A = transmit_sequence_timer[sequence_count];
  | 
352  |    }
  | 
353  |    else if (sequence_count < 15 )
  | 
354  |    {
 | 
355  |       // delay to enabling receive again
  | 
356  |       OCR2A = transmit_sequence_timer[sequence_count];
  | 
357  |       frame_ready = false;  // this will give  ms to collect the servo data
  | 
358  |    }
  | 
359  |    else
  | 
360  |    {
 | 
361  |       // reset transmit sequencer
  | 
362  |       TCCR2B = 0x00;        //Disbale Timer2 while we set it up
  | 
363  |       sequence_count = 0;  // first sequence step delay will be filled in when the transmit sequence is enabled
  | 
364  | 
  | 
365  |       enable_receiving();
  | 
366  |       start_receiving();
  | 
367  |    }
  | 
368  |    sequence_count++;
  | 
369  | 
  | 
370  |    TIFR2 = 0x00;          //Timer2 INT Flag Reg: Clear Timer Overflow Flag
  | 
371  | };
  | 
372  | 
  | 
373  | ISR(TIMER2_OVF_vect)
  | 
374  | {
 | 
375  |    // for debugging should not occur
  | 
376  |    overflow_counter++;
  | 
377  | };
  | 
378  | 
  | 
379  | 
  | 
380  | void start_transmit_sequencer(uint8_t frame_number)
  | 
381  | {
 | 
382  |    //set transmit ISR
  | 
383  |    timer_ISR = (volatile void    (*)())ISR_transmit;
  | 
384  | 
  | 
385  |    OCR2A  = transmit_sequence_timer[0]; //set first delay value
  | 
386  |    TCCR2B = 0x03;                       //enable Timer2 Control Reg B: Timer Prescaler set to 128
  | 
387  | 
  | 
388  |    gl_current_frame = frame_number;
  | 
389  | }
  | 
390  | 
  | 
391  | 
  | 
392  | //****************************************************************
  | 
393  | //* TRANSMIT usart send
  | 
394  | //****************************************************************
  | 
395  | void sbus2_send_slot(uint8_t slot)
  | 
396  | {
 | 
397  |    // if data available in slot then send it
  | 
398  |    if ( transmit_data_per_slot_status[slot] == AVAILABLE )
  | 
399  |    {
 | 
400  |       
  | 
401  |       transmit_data_per_slot_status[slot] = TRANSMITTING;
  | 
402  |       enable_transmiting();
  | 
403  |       //sending_slot = &transmit_data_per_slot[slot];
  | 
404  |       gl_slot = slot;
  | 
405  |       //send first byte
  | 
406  |       UDR = transmit_data_per_slot_data[gl_slot][0]; // the reset will be done by TX ISR
  | 
407  |       tx_data_counter = 1;
  | 
408  |    }
  | 
409  | }
  | 
410  | 
  | 
411  | ISR (USART_TX_vect)
  | 
412  | {
 | 
413  |    interrupts();
  | 
414  |    if (transmit_data_per_slot_status[gl_slot] != EMPTY) 
  | 
415  |    {
 | 
416  |       if ( tx_data_counter < SLOT_DATA_LENGTH ) 
  | 
417  |       {
 | 
418  |          UDR = transmit_data_per_slot_data[gl_slot][tx_data_counter];
  | 
419  |          tx_data_counter++;
  | 
420  |       }
  | 
421  |       else
  | 
422  |       {
 | 
423  |          // disable transmitter line and set data status to empty so that it can be written again
  | 
424  |          disable_transmiting();
  | 
425  |          transmit_data_per_slot_status[gl_slot] = EMPTY;
  | 
426  |       }
  | 
427  |    }   
  | 
428  | }
  | 
429  | 
  | 
430  | void SBUS2_transmit_telemetry_data( uint8_t slot, uint8_t data[SLOT_DATA_LENGTH] )
  | 
431  | {
 | 
432  |    uint8_t swapped_slot = 0;
  | 
433  |    if ( transmit_data_per_slot_status[slot] != TRANSMITTING )
  | 
434  |    {
 | 
435  |       //swap slot ID
  | 
436  |       swapped_slot = swaps_slot_bits[slot % 8] << 5;
  | 
437  |       memcpy( (void*)transmit_data_per_slot_data[slot], data, SLOT_DATA_LENGTH);
  | 
438  |       transmit_data_per_slot_data[slot][0] &= 0x1F; // reset frame slot ID
  | 
439  |       transmit_data_per_slot_data[slot][0] |= swapped_slot;
  | 
440  | 
  | 
441  |       transmit_data_per_slot_status[slot] = AVAILABLE;
  | 
442  |    }
  | 
443  | }
  | 
444  | 
  | 
445  | bool SBUS2_get_all_servo_data( uint16_t channels[16] )
  | 
446  | {
 | 
447  |    if ( frame_ready )
  | 
448  |    {
 | 
449  |       uint8_t byte_in_sbus = 1;
  | 
450  |       uint16_t bit_in_sbus = 0;
  | 
451  |       uint8_t ch = 0;
  | 
452  |       uint16_t bit_in_channel = 0;
  | 
453  |       //uint16_t temp;
  | 
454  |       uint8_t channel_data[UART_RXBUFSIZE];
  | 
455  |       //noInterrupts();
  | 
456  |       memcpy(channel_data, (void*)rxbuf, 24);
  | 
457  |       //interrupts();
  | 
458  | 
  | 
459  |       for (uint8_t i=0; i<16; i++)
  | 
460  |          channels[i] = 0;
  | 
461  | 
  | 
462  |       // process actual sbus data
  | 
463  |       for (uint8_t i=0; i<176; i++)
  | 
464  |       {
 | 
465  |          //temp = 1<<bit_in_sbus;
  | 
466  |          if (channel_data[byte_in_sbus] & (1<<bit_in_sbus))
  | 
467  |          {
 | 
468  |             //temp = (1<<bit_in_channel);
  | 
469  |             channels[ch] |= (1<<bit_in_channel);
  | 
470  |          }
  | 
471  |          bit_in_sbus++;
  | 
472  |          bit_in_channel++;
  | 
473  | 
  | 
474  |          if (bit_in_sbus == 8)
  | 
475  |          {
 | 
476  |             bit_in_sbus =0;
  | 
477  |             byte_in_sbus++;
  | 
478  |          }
  | 
479  |          if (bit_in_channel == 11)
  | 
480  |          {
 | 
481  |             bit_in_channel =0;
  | 
482  |             ch++;
  | 
483  |          }
  | 
484  |       }
  | 
485  |       // DigiChannel 1
  | 
486  |       if (channel_data[23] & (1<<0))
  | 
487  |       {
 | 
488  |          channels[16] = 1;
  | 
489  |       }
  | 
490  |       else
  | 
491  |       {
 | 
492  |          channels[16] = 0;
  | 
493  |       }
  | 
494  |       // DigiChannel 2
  | 
495  |       if (channel_data[23] & (1<<1))
  | 
496  |       {
 | 
497  |          channels[17] = 1;
  | 
498  |       }
  | 
499  |       else
  | 
500  |       {
 | 
501  |          channels[17] = 0;
  | 
502  |       }
  | 
503  | 
  | 
504  |       return true;
  | 
505  |    }
  | 
506  |    else
  | 
507  |    {
 | 
508  |       return false;
  | 
509  |    }
  | 
510  | }
  | 
511  | 
  | 
512  | 
  | 
513  | void SBUS2_get_status( uint16_t *uart_dropped_frame, bool *transmision_dropt_frame, bool *failsave )
  | 
514  | {
 | 
515  |    if (frameCounter < 60)
  | 
516  |    {
 | 
517  |       uart_lost_frame = 0;
  | 
518  |    }
  | 
519  |    *uart_dropped_frame = uart_lost_frame;
  | 
520  |    *transmision_dropt_frame = rxbuf[23] & 0x20 ? true : false;
  | 
521  |    *failsave = rxbuf[23] & 0x10 ? true : false;
  | 
522  | }
  | 
523  | 
  | 
524  | /*
  | 
525  | bool SBUS2_get_command( uint8_t   *p_command )
  | 
526  | {   
 | 
527  |    if (command_received)
  | 
528  |    {  
 | 
529  |       memcpy(p_command, command, command_length);       
  | 
530  |       command_received = false;   
  | 
531  | 
  | 
532  |       return true;
  | 
533  |    }
  | 
534  |    return false;
  | 
535  | }
  | 
536  | 
  | 
537  | 
  | 
538  | void SBUS2_send_command( uint8_t   *p_command )
  | 
539  | {
 | 
540  |    int index = 0;   
  | 
541  |    
  | 
542  |    for( index = 0; index < command_length; index++)
  | 
543  |    {
 | 
544  |       while( !(UCSRA & (1<<UDRE))){}   
 | 
545  |       UDR = p_command[index];      
  | 
546  |    } 
  | 
547  | }
  | 
548  | */   
  | 
549  | 
  | 
550  | int16_t SBUS2_get_servo_data( uint8_t channel )
  | 
551  | {
 | 
552  |    uint8_t byte_in_sbus = 1;
  | 
553  |    uint16_t bit_in_sbus = 0;
  | 
554  |    uint8_t ch = 0;
  | 
555  |    uint16_t bit_in_channel = 0;
  | 
556  |    uint8_t channel_data[UART_RXBUFSIZE];
  | 
557  | 
  | 
558  |    uint16_t  servo = 0;
  | 
559  |    uint8_t  start_bit  = 0;
  | 
560  | 
  | 
561  |    //noInterrupts();
  | 
562  |    memcpy(channel_data, (void*)rxbuf, 24);
  | 
563  |    //interrupts();
  | 
564  | 
  | 
565  |    if ( frame_ready )
  | 
566  |    {
 | 
567  |       start_bit  = channel * SBUS_CHANNEL_SIZE ;
  | 
568  |       bit_in_sbus  = start_bit % 8;
  | 
569  |       byte_in_sbus = (start_bit / 8) + 1;
  | 
570  | 
  | 
571  |       // process actual sbus data
  | 
572  |       for (uint8_t i=start_bit; i<(start_bit+11); i++)
  | 
573  |       {
 | 
574  |          if (channel_data[byte_in_sbus] & (1<<bit_in_sbus))
  | 
575  |          {
 | 
576  |             servo |= (1<<bit_in_channel);
  | 
577  |          }
  | 
578  |          bit_in_sbus++;
  | 
579  |          bit_in_channel++;
  | 
580  | 
  | 
581  |          if (bit_in_sbus == 8)
  | 
582  |          {
 | 
583  |             bit_in_sbus =0;
  | 
584  |             byte_in_sbus++;
  | 
585  |          }
  | 
586  |          if (bit_in_channel == 11)
  | 
587  |          {
 | 
588  |             bit_in_channel =0;
  | 
589  |             ch++;
  | 
590  |          }
  | 
591  |       }
  | 
592  |       return (int16_t)servo;
  | 
593  |    }
  | 
594  |    else
  | 
595  |    {
 | 
596  |       return -1;
  | 
597  |    }
  | 
598  | }
  |