Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1198 - 1
 
2
/****************************************************************/
3
/*                                                                                                                              */
4
/*                               NG-Video 5,8GHz                                                        */
5
/*                                                                                                                              */
6
/*                              Copyright (C) 2011 - gebad                                              */
7
/*                                                                                                                              */
8
/*  This code is distributed under the GNU Public License               */
9
/*      which can be found at http://www.gnu.org/licenses/gpl.txt       */
10
/*                                                                                                                              */
11
/****************************************************************/
12
 
13
#include <avr/io.h>
14
#include <avr/interrupt.h>
15
 
16
#include "usart.h"
17
 
18
/********************************************************************************************************************/
19
/*                                                                                                                                                                                                                                      */
20
/* MK Protokoll                                                                                                                                                                                                         */
21
/*   http://www.mikrokopter.de/ucwiki/en/SerialCommands?highlight=(command)                                                                                     */
22
/*   http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol)                                                                            */
23
/*                                                                                                                                                                                                                                      */
24
/*      Slave-Address Part                                                                                                                                                                                              */
25
/*              1                  FC                                                                                                                                                                                           */
26
/*              2                  NC                                                                                                                                                                                           */
27
/*              3                  MK3MAG                                                                                                                                                                                       */
28
/*                                                                                                                                                                                                                                      */
29
/*      Auszug von Commands, nur OSD verwendet:                                                                                                                                                 */
30
/*                                                                                              Received by NC             |                    Sent by NC                                              */
31
/*                                                                                                                                         |                                                              since NC  */
32
/*      Description        ID  Address  Data                                                               | ID  Address        Data                      Firmware  */
33
/*      Debug Request  'd' AnyAddr      u8 AutoSendInterval. Value is              | 'D' SlaveAddr      Debug Data Struct                       */
34
/*                                                              multiplied by 10 in receiver and ,     |                                                                                        */
35
/*                                                              then used as milliseconds. Subsciption |                                                                                        */
36
/*                                                              needs to be renewed every 4s.              |                                                                                    */
37
/*      Request OSD        'o' NC-Addr  1 byte sending interval (in 10ms steps)| 'O' NC-Addr    NaviDataStruct    0.12h         */
38
/*      -Data                                                                                                                      |                                                                                    */
39
/*      Redirect UART  'u' NC-Addr      1 byte param for uart selector (0=FC,  |  -             -                               -                 0.12h         */
40
/*                                                              1=MK3MAG, 2=MKGPS), can be switched    |                                                                                        */
41
/*                                                              back to NC debug by sending the magic  |                                                                                        */
42
/*                                                              packet "0x1B,0x1B,0x55,0xAA,0x00"          |                                                                                    */
43
/*      Set 3D-Data    'c' AnyAddr      u8 Interval                                                        | 'C' NC-Addr        struct Data3D     0.14a         */
44
/*      Interval                                                                                                                                                                                                                */
45
/*                                                                                                                                                                                                                                      */
46
/********************************************************************************************************************/
47
 
48
char rx_buffer[RXD_BUFFER_SIZE];
49
 
50
volatile uint8_t rx_len;
51
volatile uint8_t rx_ready = 0;
52
uint8_t rx_GPS;
53
char start;
54
 
55
/**************************************************************/
56
/*                                                                                                                        */
57
/*                           USART                                                    */
58
/*                      8 Datenbits, 1 Stopbit, keine Parität                     */
59
/*                                                                                                                        */
60
/**************************************************************/
61
 
62
void USART_Init(unsigned int baud)
63
{ uint16_t ubrx;
64
 
65
  ubrx = F_CPU/(baud * 16L) - 1;
66
  /* Set baud rate */
67
  UBRR0H = (unsigned char)(ubrx>>8);
68
  UBRR0L = (unsigned char)ubrx;
69
  /* RX Complete Interrupt Enable, Enable receiver and transmitter */
70
  UCSR0B = (1<<RXCIE0) | (1<<RXEN0) | (1<<TXEN0);
71
  /* Asynchronous USART, no Parity, Set frame format: 8data, 1stop bit */
72
  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); // 8data Bit
73
 }
74
 
75
void USART_send_Chr(unsigned char data)
76
{
77
  /* Wait for empty transmit Puffer */
78
  while ( !( UCSR0A & (1<<UDRE0)) ) ;
79
  /* Put data into Puffer, sends the data */
80
  UDR0 = data;
81
}
82
 
83
void USART_send_Str(char *str )
84
{
85
  while (*str) {
86
    USART_send_Chr(*str);
87
    str++;
88
  }
89
}
90
 
91
/*
92
// verwendet Orginal H&I MK-Software http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol)
93
// kann auch vereinfacht werden ==> gleich kodierten String senden char *tx_osd = {"#co?]==EH\r\0"}
94
// Funktion getestet und funktioniert
95
void tx_Mk(unsigned char addr, char cmd, char *data, uint8_t len)
96
{ char tx_buffer[TXD_BUFFER_SIZE];
97
  uint8_t tx_i = 0;
98
  uint8_t i = 0;
99
  unsigned char a,b,c;
100
  unsigned int tmpCRC = 0;
101
 
102
  tx_buffer[tx_i++] = '#';                      // Start-Byte
103
  tx_buffer[tx_i++] = 'a' + addr;       // Adress
104
  tx_buffer[tx_i++] = cmd;                      // Command
105
  // code64
106
  while (len) {
107
    if (len) { a = data[i++]; len--;} else a = 0;
108
    if (len) { b = data[i++]; len--;} else b = 0;
109
    if (len) { c = data[i++]; len--;} else c = 0;
110
    tx_buffer[tx_i++] = '=' + (a >> 2);
111
    tx_buffer[tx_i++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4));
112
    tx_buffer[tx_i++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6));
113
    tx_buffer[tx_i++] = '=' + (c & 0x3f);
114
  }
115
  // add crc
116
  for (i = 0; i < tx_i; i++) {
117
    tmpCRC += tx_buffer[i];
118
  }
119
  tmpCRC %= 4096;
120
  tx_buffer[i++] = '=' + tmpCRC / 64;
121
  tx_buffer[i++] = '=' + tmpCRC % 64;
122
  tx_buffer[i++] = '\r';                        // End-Byte
123
 
124
  tx_buffer[i++] = '\0';                        // USART_send_Str(...) ==> End-while
125
  USART_send_Str(tx_buffer);
126
} */
127
 
128
ISR(USART0_RX_vect)
129
{ char received;
130
  static uint8_t line_flag = 1;
131
  static char* ptr_write = rx_buffer;
132
  static uint8_t frame = 6;
133
 
134
  // von '#' bis '\r' Puffer, einschließlich Satzzeichen schreiben
135
  received = UDR0;
136
  if (rx_ready == 0) {
137
        if ((received == start) && line_flag) { // start '#' oder 0x80
138
          line_flag = 0;                        // MK-Datensatzanfang wurde erkannt
139
          ptr_write = rx_buffer;        // Schreibzeiger auf Anfang Puffer setzen
140
          rx_len = 0;
141
    }
142
        if (line_flag == 0) {           // MK/Pololu-Datensatz ?
143
          *ptr_write = received;
144
          rx_len++;
145
 
146
      /* GPS Datensatzende */
147
          if (rx_GPS) {
148
        if (received == '\r') { // Ende MK-Datensatz ?
149
          line_flag = 1;
150
              rx_ready = 1; // Puffer Schreiben sperren, MK-Datensatz kann nun verarbeitet werden
151
            }
152
          }
153
          /* Pololu Micro Serial stark reduziert/vereinfacht; rx_len-Abfrage 1 höher ==> bereits incrementiert */
154
          else {
155
            if ((rx_len == 2) && (received != 0x01)) line_flag = 1;                             // device
156
                if ((rx_len == 3) && (received > 0x01)) frame = 6; else frame = 5;      // command
157
                if (rx_len == frame) {
158
                  line_flag = 1;
159
                  rx_ready = 1; // Puffer Schreiben sperren, Pololu-Datensatz kann nun verarbeitet werden
160
                }
161
          }
162
 
163
      ptr_write++;
164
          if(rx_len == RXD_BUFFER_SIZE) line_flag = 1; // ungültiger MK/Pololu-Datensatz ? ==> neu beginnen
165
    }
166
  }
167
}
168
 
169
// verwendet aus Orginal H&I MK-Software http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol)
170
void Decode64(char *ptrOut, uint8_t len, uint8_t ptrIn)
171
{ unsigned char a,b,c,d;
172
  unsigned char ptr = 0;
173
  unsigned char x,y,z;
174
 
175
  while(len)
176
  {
177
    a = rx_buffer[ptrIn++] - '=';
178
    b = rx_buffer[ptrIn++] - '=';
179
    c = rx_buffer[ptrIn++] - '=';
180
    d = rx_buffer[ptrIn++] - '=';
181
 
182
    x = (a << 2) | (b >> 4);
183
    y = ((b & 0x0f) << 4) | (c >> 2);
184
    z = ((c & 0x03) << 6) | d;
185
    if(len--) ptrOut[ptr++] = x; else break;
186
    if(len--) ptrOut[ptr++] = y; else break;
187
    if(len--) ptrOut[ptr++] = z; else break;
188
  }
189
}
190
 
191
// eingearbeitet Orginal H&I MK-Software mkprotocol.h und mkprotocol.c
192
uint8_t rx_line_decode(char rx_ID)
193
{ uint8_t ret = 0;
194
  uint8_t crc1,crc2;
195
  int tmpCRC = 0;
196
 
197
  // rx_ready gleichzeitig usart rx_buffer schreiben gesperrt
198
  if ((rx_ready == 1) && (rx_len > 0) && (rx_buffer[2] == rx_ID)) {
199
    // Checksumme
200
        // verwendet http://www.mikrokopter.de/ucwiki/en/SerialProtocol?highlight=(protocol)
201
    for(uint8_t i = 0; i <  rx_len - 3;i++) {
202
      tmpCRC += rx_buffer[i];
203
    }
204
    tmpCRC %= 4096;
205
    crc1 = '=' + tmpCRC / 64;
206
    crc2 = '=' + tmpCRC % 64;
207
 
208
        if ((crc1 == rx_buffer[rx_len-3]) && (crc2 == rx_buffer[rx_len-2])) {
209
      Decode64(MK.data_decode, rx_len - 6, 3); // Daten ohne Satzzeichen, header und crc
210
          ret = 1;
211
    }
212
    cli();
213
        rx_timeout = 0; // wenn kein gültiger Datensatz für rx_ID ==> Counter wird nicht mehr rückgesetzt 
214
        sei();
215
  }
216
  // für Blinken des Antennenzeichens, MK antwortet immer mit cmd Großbuchstaben
217
  if ((rx_timeout < RX_TIME_OLD) && (rx_buffer[2] >= 'A') &&  (rx_buffer[2] <= 'Z')) wi232RX = 1;
218
  rx_ready = 0; // Puffer Schreiben entsperren, neuer MK-Datensatz kann wieder empfangen/gepuffert werden
219
  return(ret);
220
}
221
 
222
void USART_RX_Mode(uint8_t tracking)
223
{
224
  rx_GPS = (tracking == TRACKING_GPS);
225
  if (rx_GPS) start ='#'; else start = 0x80;
226
}
227
 
228
uint8_t Get_Pololu_cmd(char *ptrOut, uint8_t ptrIn)
229
{
230
  rx_len -=2; // ohne Start-Char und device
231
  if (rx_ready == 1) {
232
        for (uint8_t i = 0; i < rx_len; i++)
233
          ptrOut[i] = rx_buffer[ptrIn++]; // ab Pololu-Command
234
  }
235
  else
236
    rx_len = 0;
237
  rx_ready = 0; // Puffer Schreiben entsperren, neuer Pololu-Datensatz kann wieder empfangen/gepuffert werden
238
  return(rx_len);
239
}