Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1932 | - | 1 | /** |
2 | * source for the Bluetooth driver |
||
3 | * @file bluetooth.c |
||
4 | * @author Linus Lotz<lotz@in.tum.de> |
||
5 | * @author Salomon Sickert |
||
6 | */ |
||
7 | |||
8 | //2013 Cebra, Erweiterung um BT Local-ID Abfrage |
||
9 | |||
10 | #include <string.h> |
||
11 | #include "../cpu.h" |
||
12 | #define __DELAY_BACKWARD_COMPATIBLE__ |
||
13 | #include <util/delay.h> |
||
14 | #include <avr/interrupt.h> |
||
15 | #include <avr/pgmspace.h> |
||
16 | #include <stdlib.h> |
||
17 | |||
18 | #include "bluetooth.h" |
||
19 | #include "../main.h" |
||
20 | #ifdef HWVERSION3_9 |
||
21 | #include "../uart/uart1.h" |
||
22 | #include "../uart/usart.h" |
||
23 | #include "../timer/timer.h" |
||
24 | #include "fifo.h" |
||
25 | #include "error.h" |
||
26 | #include "../lcd/lcd.h" |
||
27 | #include "../eeprom/eeprom.h" |
||
28 | #include "../setup/setup.h" |
||
29 | #include "bluetooth.h" |
||
30 | #include "../tracking/tracking.h" |
||
31 | |||
32 | |||
33 | //#define SaveMem |
||
34 | |||
35 | // |
||
36 | // Baudrate for the UART-connection to the BTM-222 on SQUIRREL |
||
37 | // |
||
38 | |||
39 | #define SQUIRREL |
||
40 | |||
41 | #ifdef SQUIRREL |
||
42 | #define UART_BAUD_RATE 19200 |
||
43 | #endif |
||
44 | |||
45 | #ifdef NUT |
||
46 | #define UART_BAUD_RATE 19200 |
||
47 | #endif |
||
48 | |||
49 | |||
50 | typedef enum { |
||
51 | BT_RAW, |
||
52 | BT_DATA, |
||
53 | BT_CMD, |
||
54 | BT_NOECHO, |
||
55 | BT_NOANSWER |
||
56 | } communication_mode_t; |
||
57 | |||
58 | #define BT_CMD_TIMEOUT_MS 2000 |
||
59 | |||
60 | typedef enum { |
||
61 | BT_TEST, // AT |
||
62 | BT_CONNECT, // ATA |
||
63 | BT_DISCONNECT, // ATH |
||
64 | BT_CLEAR_ADDRESS, // ATD0 |
||
65 | BT_SET_ADDRESS, // ATD=_____ |
||
66 | BT_GET_LOCALID, // ATB? Inquire the Local BD address |
||
67 | BT_FIND_DEVICES, // ATF? |
||
68 | BT_DISABLE_AUTOCONNECT, // ATO1 |
||
69 | BT_ENABLE_AUTOCONNECT, // ATO0 |
||
70 | BT_SET_MASTER, // ATR0 |
||
71 | BT_SET_SLAVE, // ATR1 |
||
72 | BT_SET_PIN, // ATP=1234 |
||
73 | BT_SET_2400, // ATL* Baudrate 2400 |
||
74 | BT_SET_4800, // ATL0 Baudrate 4800 |
||
75 | BT_SET_9600, // ATL1 Baudrate 9600 |
||
76 | BT_SET_19200, // ATL2 Baudrate 19200 |
||
77 | BT_SET_38400, // ATL3 Baudrate 38400 |
||
78 | BT_SET_57600, // ATL4 Baudrate 57600 |
||
79 | BT_SET_115200, // ATL5 Baudrate 115200 |
||
80 | BT_SET_NOANSWER, // ATQ1 Rückmeldungen aus |
||
81 | BT_SET_NOECHO, // ATE0 ECHO deaktivieren |
||
82 | BT_SET_ANSWER, // ATQ0 Rückmeldungen |
||
83 | BT_SET_ECHO, // ATE1 ECHO aktivieren |
||
84 | BT_SET_DEFAULT, // Defaultwerte setzen |
||
85 | BT_SET_NAME, // Devicename |
||
86 | BT_SET_DISPWRDOWN // disable auto Powerdown |
||
87 | } bt_cmd_t; |
||
88 | |||
89 | //TODO: FIFO Grösse |
||
90 | #define IN_FIFO_SIZE 512 |
||
91 | |||
92 | char localID[15]="12345678901234"; |
||
93 | static uint8_t bt_buffer[IN_FIFO_SIZE]; |
||
94 | static fifo_t in_fifo; |
||
95 | |||
96 | char bt_rx_buffer[RXD_BUFFER_SIZE]; |
||
97 | volatile uint8_t bt_rx_len; |
||
98 | volatile uint8_t bt_rx_ready = 0; |
||
99 | uint8_t rx_GPS; |
||
100 | static char start = '$'; |
||
101 | static char end = '\n'; |
||
102 | |||
103 | char data_decode[RXD_BUFFER_SIZE]; |
||
104 | volatile uint16_t rx_timeout; |
||
105 | |||
106 | uint8_t EchoAnswerOn; //Merkzelle |
||
107 | static bt_mode_t bt_mode = BLUETOOTH_SLAVE; |
||
108 | static communication_mode_t comm_mode = BT_CMD; |
||
109 | |||
110 | uint8_t i = 0; |
||
111 | //uint8_t NoEcho = 0; |
||
112 | //uint8_t NoAnswer = 0; |
||
113 | |||
114 | uint8_t bt_devicecount = 0; |
||
115 | |||
116 | uint8_t bt_rxerror = 0; |
||
117 | |||
118 | device_info device_list[NUTS_LIST]; |
||
119 | |||
120 | uint8_t BT_New_Baudrate = 0; //Merkzelle für zu setzende Baudrate |
||
121 | |||
122 | |||
123 | |||
124 | // Set a timeout of Y ms and a Conditon X, which have to be true while timeout |
||
125 | #define while_timeout(X, Y) for(uint16_t __timeout = 0; __timeout++ <= Y && (X); Delay_MS(Y ? 1 : 0)) |
||
126 | |||
127 | //-------------------------------------------------------------- |
||
128 | void Delay_MS(int count) |
||
129 | { |
||
130 | for (int i = 0; i < count; i++) |
||
131 | _delay_ms(1); |
||
132 | } |
||
133 | |||
134 | |||
135 | void bt_start(void) |
||
136 | { |
||
137 | if (Config.BTIsSlave == true) EchoAnswerOn = false; else EchoAnswerOn = true; |
||
138 | } |
||
139 | |||
140 | //-------------------------------------------------------------- |
||
141 | void uart_receive(void) |
||
142 | { |
||
143 | unsigned int uart_data; |
||
144 | |||
145 | while (!fifo_is_full(&in_fifo)) |
||
146 | { |
||
147 | uart_data = uart1_getc(); |
||
148 | |||
149 | // USART_puts("."); |
||
150 | |||
151 | switch (uart_data & 0xFF00) { |
||
152 | // Framing Error detected, i.e no stop bit detected |
||
153 | case UART_FRAME_ERROR: |
||
154 | #ifdef DEBUG |
||
155 | warn_pgm(PSTR("FRM ERR")); |
||
156 | #endif |
||
157 | bt_rxerror++; |
||
158 | return; |
||
159 | |||
160 | // Overrun, a character already presend in the UART UDR register was |
||
161 | // not read by the interrupt handler before the next character arrived, |
||
162 | // one or more received characters have been dropped |
||
163 | // |
||
164 | case UART_OVERRUN_ERROR: |
||
165 | #ifdef DEBUG |
||
166 | warn_pgm(PSTR("OVR ERR")); |
||
167 | #endif |
||
168 | bt_rxerror++; |
||
169 | return; |
||
170 | |||
171 | // We are not reading the receive buffer fast enough, |
||
172 | // one or more received character have been dropped |
||
173 | // |
||
174 | case UART_BUFFER_OVERFLOW: |
||
175 | #ifdef DEBUG |
||
176 | warn_pgm(PSTR("BUF ERR")); |
||
177 | #endif |
||
178 | bt_rxerror++; |
||
179 | return; |
||
180 | |||
181 | // UART Inputbuffer empty, nothing to do |
||
182 | case UART_NO_DATA: |
||
183 | return; |
||
184 | |||
185 | default: |
||
186 | { |
||
187 | fifo_write(&in_fifo, uart_data); |
||
188 | #ifdef DEBUG |
||
189 | USART_putc(uart_data); |
||
190 | #endif |
||
191 | } |
||
192 | } |
||
193 | } |
||
194 | #ifdef DEBUG |
||
195 | warn_pgm(PSTR("FIFO OVR ERR")); |
||
196 | #endif |
||
197 | } |
||
198 | |||
199 | |||
200 | //-------------------------------------------------------------- |
||
201 | static void uart_send(const char *data, const uint8_t length) |
||
202 | { |
||
203 | #ifdef SND_DEBUG |
||
204 | debug_pgm(PSTR("bt_uart_send")); |
||
205 | if (comm_mode == BT_CMD) debug_pgm(PSTR("bt_uart_send:BT_CMD")); else debug_pgm(PSTR("bt_uart_send:Wrong comm-mode")); |
||
206 | if (EchoAnswerOn == true) debug_pgm(PSTR("bt_uart_send:EchoAnswer ON")); else debug_pgm(PSTR("bt_uart_send:EchoAnswer OFF")); |
||
207 | |||
208 | #endif |
||
209 | |||
210 | char echo; |
||
211 | |||
212 | // lcd_printp_at (i++, 1, PSTR("."), 0); |
||
213 | for (uint8_t i = 0; i < length; i++) |
||
214 | { |
||
215 | |||
216 | #ifdef SND_DEBUG |
||
217 | USART_putc((data[i])); //test |
||
218 | #endif |
||
219 | // debug_pgm(PSTR("bt_init_S")); |
||
220 | |||
221 | if (uart1_putc(data[i]) == 0) |
||
222 | { |
||
223 | #ifdef SND_DEBUG |
||
224 | warn_pgm(PSTR("UART: Remote not ready")); |
||
225 | #endif |
||
226 | return; |
||
227 | } |
||
228 | |||
229 | if (comm_mode == BT_RAW) |
||
230 | _delay_ms(50); |
||
231 | |||
232 | if (comm_mode == BT_DATA) |
||
233 | _delay_ms(1); |
||
234 | |||
235 | |||
236 | if ((comm_mode == BT_CMD) && (EchoAnswerOn == true)) |
||
237 | { |
||
238 | #ifdef SND_DEBUG |
||
239 | warn_pgm(PSTR ("UARTsend: get Echo")); |
||
240 | #endif |
||
241 | uint8_t x = 0; |
||
242 | for (; x < 3; x++) |
||
243 | { |
||
244 | |||
245 | while_timeout(fifo_is_empty(&in_fifo), 200) |
||
246 | // for(uint16_t __timeout = 0; __timeout++ <= 200 && (fifo_is_empty(&in_fifo)); _delay_ms(200 ? 1 : 0)) |
||
247 | |||
248 | uart_receive(); |
||
249 | |||
250 | |||
251 | fifo_read(&in_fifo, &echo); |
||
252 | |||
253 | if (echo != data[i]) { |
||
254 | if (uart1_putc(data[i]) == 0) |
||
255 | { |
||
256 | #ifdef SND_DEBUG |
||
257 | warn_pgm(PSTR ("UART: Remote not ready")); |
||
258 | #endif |
||
259 | return; |
||
260 | } |
||
261 | } |
||
262 | else |
||
263 | break; |
||
264 | } |
||
265 | |||
266 | if (x == 3) |
||
267 | { |
||
268 | error_putc(data[i]); |
||
269 | #ifdef DEBUG |
||
270 | error_pgm(PSTR("BT: WRONG ECHO")); |
||
271 | //_delay_ms(2000); |
||
272 | #endif |
||
273 | } |
||
274 | } |
||
275 | else |
||
276 | { |
||
277 | for(uint16_t __timeout = 0; __timeout++ <= 200 && (fifo_is_empty(&in_fifo)); _delay_ms(200 ? 1 : 0)) |
||
278 | { |
||
279 | uart_receive(); |
||
280 | } |
||
281 | fifo_read(&in_fifo, &echo); |
||
282 | #ifdef SND_DEBUG |
||
283 | warn_pgm(PSTR ("UARTsend: skip Echo")); |
||
284 | #endif |
||
285 | } |
||
286 | } |
||
287 | } |
||
288 | |||
289 | |||
290 | //-------------------------------------------------------------- |
||
291 | static uint16_t send_cmd(const bt_cmd_t command, const char *data) |
||
292 | { |
||
293 | uint16_t CommandDelay=0; // nach BTM222 Kommandos verschiedene Verzögerungszeiten bevor es weitergehen kann |
||
294 | |||
295 | // _delay_ms(500); // org 500 300 zu wenig |
||
296 | char full_command[20]; // Maximum command size |
||
297 | |||
298 | switch (command) |
||
299 | { |
||
300 | case BT_SET_PIN: |
||
301 | strcpy_P(full_command, PSTR("ATP=")); |
||
302 | for (uint8_t i = 0; i < bt_pin_length; i++) |
||
303 | { |
||
304 | full_command[i+4] = Config.bt_pin[i]; |
||
305 | } |
||
306 | full_command[(bt_pin_length+4)] =0; |
||
307 | CommandDelay = 100; //100ms |
||
308 | break; |
||
309 | |||
310 | case BT_SET_DEFAULT: |
||
311 | strcpy_P(full_command, PSTR("ATZ0")); |
||
312 | CommandDelay = 1000; |
||
313 | break; |
||
314 | |||
315 | |||
316 | case BT_SET_2400: |
||
317 | strcpy_P(full_command, PSTR("ATL*")); |
||
318 | CommandDelay = 100; |
||
319 | #ifdef DEBUG |
||
320 | debug_pgm(PSTR("ATL*")); |
||
321 | #endif |
||
322 | break; |
||
323 | case BT_SET_4800: |
||
324 | strcpy_P(full_command, PSTR("ATL0")); |
||
325 | CommandDelay = 100; |
||
326 | #ifdef DEBUG |
||
327 | debug_pgm(PSTR("ATL0")); |
||
328 | #endif |
||
329 | break; |
||
330 | case BT_SET_9600: |
||
331 | strcpy_P(full_command, PSTR("ATL1")); |
||
332 | CommandDelay = 100; |
||
333 | #ifdef DEBUG |
||
334 | debug_pgm(PSTR("ATL1")); |
||
335 | #endif |
||
336 | break; |
||
337 | |||
338 | case BT_SET_19200: |
||
339 | strcpy_P(full_command, PSTR("ATL2")); |
||
340 | CommandDelay = 100; |
||
341 | #ifdef DEBUG |
||
342 | debug_pgm(PSTR("ATL2")); |
||
343 | #endif |
||
344 | break; |
||
345 | |||
346 | case BT_SET_38400: |
||
347 | strcpy_P(full_command, PSTR("ATL3")); |
||
348 | CommandDelay = 100; |
||
349 | #ifdef DEBUG |
||
350 | debug_pgm(PSTR("ATL3")); |
||
351 | #endif |
||
352 | break; |
||
353 | |||
354 | case BT_SET_57600: |
||
355 | strcpy_P(full_command, PSTR("ATL4")); |
||
356 | CommandDelay = 100; |
||
357 | #ifdef DEBUG |
||
358 | debug_pgm(PSTR("ATL4")); |
||
359 | #endif |
||
360 | break; |
||
361 | |||
362 | case BT_SET_115200: |
||
363 | strcpy_P(full_command, PSTR("ATL5")); |
||
364 | CommandDelay = 100; |
||
365 | #ifdef DEBUG |
||
366 | debug_pgm(PSTR("ATL5")); |
||
367 | #endif |
||
368 | break; |
||
369 | |||
370 | case BT_SET_NOANSWER: |
||
371 | strcpy_P(full_command, PSTR("ATQ1")); |
||
372 | CommandDelay = 100; |
||
373 | #ifdef DEBUG |
||
374 | debug_pgm(PSTR("ATQ1")); |
||
375 | #endif |
||
376 | break; |
||
377 | |||
378 | case BT_SET_NOECHO: |
||
379 | strcpy_P(full_command, PSTR("ATE0")); |
||
380 | CommandDelay = 100; |
||
381 | #ifdef DEBUG |
||
382 | debug_pgm(PSTR("ATE0")); |
||
383 | #endif |
||
384 | break; |
||
385 | |||
386 | case BT_SET_ANSWER: |
||
387 | strcpy_P(full_command, PSTR("ATQ0")); |
||
388 | CommandDelay = 100; |
||
389 | #ifdef DEBUG |
||
390 | debug_pgm(PSTR("ATQ0")); |
||
391 | #endif |
||
392 | break; |
||
393 | |||
394 | case BT_SET_ECHO: |
||
395 | strcpy_P(full_command, PSTR("ATE1")); |
||
396 | CommandDelay = 100; |
||
397 | #ifdef DEBUG |
||
398 | debug_pgm(PSTR("ATE1")); |
||
399 | #endif |
||
400 | break; |
||
401 | |||
402 | case BT_TEST: |
||
403 | strcpy_P(full_command, PSTR("AT")); |
||
404 | CommandDelay = 100; |
||
405 | #ifdef DEBUG |
||
406 | debug_pgm(PSTR("AT")); |
||
407 | #endif |
||
408 | break; |
||
409 | |||
410 | case BT_CONNECT: |
||
411 | strcpy_P(full_command, PSTR("ATA")); |
||
412 | CommandDelay = 100; |
||
413 | #ifdef DEBUG |
||
414 | debug_pgm(PSTR("ATA")); |
||
415 | #endif |
||
416 | break; |
||
417 | |||
418 | case BT_DISCONNECT: |
||
419 | strcpy_P(full_command, PSTR("ATH")); |
||
420 | CommandDelay = 100; |
||
421 | #ifdef DEBUG |
||
422 | debug_pgm(PSTR("ATH")); |
||
423 | #endif |
||
424 | break; |
||
425 | |||
426 | case BT_CLEAR_ADDRESS: |
||
427 | strcpy_P(full_command, PSTR("ATD0")); |
||
428 | CommandDelay = 100; |
||
429 | break; |
||
430 | |||
431 | case BT_SET_ADDRESS: |
||
432 | strcpy_P(full_command, PSTR("ATD=")); |
||
433 | memcpy((full_command + strlen(full_command)), data, 12); |
||
434 | full_command[16] = 0; |
||
435 | CommandDelay = 100; |
||
436 | #ifdef DEBUG |
||
437 | debug_pgm(PSTR("ATLD=")); |
||
438 | #endif |
||
439 | break; |
||
440 | |||
441 | case BT_FIND_DEVICES: |
||
442 | strcpy_P(full_command, PSTR("ATF?")); |
||
443 | CommandDelay = 100; |
||
444 | #ifdef DEBUG |
||
445 | debug_pgm(PSTR("ATF?")); |
||
446 | #endif |
||
447 | break; |
||
448 | |||
449 | case BT_DISABLE_AUTOCONNECT: |
||
450 | strcpy_P(full_command, PSTR("ATO1")); |
||
451 | CommandDelay = 3500; |
||
452 | #ifdef DEBUG |
||
453 | debug_pgm(PSTR("ATO1")); |
||
454 | #endif |
||
455 | break; |
||
456 | case BT_ENABLE_AUTOCONNECT: |
||
457 | strcpy_P(full_command, PSTR("ATO0")); |
||
458 | CommandDelay = 3500; |
||
459 | #ifdef DEBUG |
||
460 | debug_pgm(PSTR("ATO0")); |
||
461 | #endif |
||
462 | break; |
||
463 | case BT_SET_MASTER: |
||
464 | strcpy_P(full_command, PSTR("ATR0")); |
||
465 | CommandDelay = 3000; |
||
466 | #ifdef DEBUG |
||
467 | debug_pgm(PSTR("ATR0")); |
||
468 | #endif |
||
469 | break; |
||
470 | |||
471 | case BT_SET_SLAVE: |
||
472 | strcpy_P(full_command, PSTR("ATR1")); |
||
473 | CommandDelay = 3000; |
||
474 | #ifdef DEBUG |
||
475 | debug_pgm(PSTR("ATR1")); |
||
476 | #endif |
||
477 | break; |
||
478 | |||
479 | case BT_SET_NAME: |
||
480 | strcpy_P(full_command, PSTR("ATN=")); |
||
481 | for (uint8_t i = 0; i < bt_name_len; i++) |
||
482 | { |
||
483 | full_command[i + 4] = Config.bt_name[i]; |
||
484 | } |
||
485 | full_command[(bt_name_len + 4)] = 0; |
||
486 | CommandDelay = 100; |
||
487 | #ifdef DEBUG |
||
488 | debug_pgm(PSTR("ATN=")); |
||
489 | #endif |
||
490 | break; |
||
491 | |||
492 | case BT_SET_DISPWRDOWN: |
||
493 | strcpy_P(full_command, PSTR("ATS1")); |
||
494 | CommandDelay = 100; |
||
495 | #ifdef DEBUG |
||
496 | debug_pgm(PSTR("ATS1")); |
||
497 | #endif |
||
498 | break; |
||
499 | case BT_GET_LOCALID: |
||
500 | strcpy_P(full_command, PSTR("ATB?")); |
||
501 | CommandDelay = 100; |
||
502 | #ifdef DEBUG |
||
503 | debug_pgm(PSTR("ATB?")); |
||
504 | #endif |
||
505 | break; |
||
506 | default: |
||
507 | warn_pgm(PSTR("CMD UNK")); |
||
508 | return false; |
||
509 | } |
||
510 | |||
511 | strcat_P(full_command, PSTR("\r")); |
||
512 | |||
513 | // throw away your television |
||
514 | uart_receive(); |
||
515 | fifo_clear(&in_fifo); |
||
516 | // debug_pgm(PSTR("bt_init3, send command")); |
||
517 | // send command |
||
518 | uart_send(full_command, strlen(full_command)); |
||
519 | |||
520 | //TODO: hier ist ein Fehler bei den Bedingungen |
||
521 | // if (command == (BT_SET_NOECHO||BT_SET_NOANSWER||BT_SET_ECHO||BT_SET_ANSWER)) |
||
522 | // { |
||
523 | // uart_receive(); |
||
524 | // fifo_clear(&in_fifo); |
||
525 | // _delay_ms(CommandDelay); |
||
526 | //#ifdef DEBUG |
||
527 | // debug_pgm(PSTR("send_cmd: Echo Answer no Response")); |
||
528 | //#endif |
||
529 | //// return true; |
||
530 | // |
||
531 | // } |
||
532 | // else |
||
533 | { |
||
534 | // get response |
||
535 | #ifdef DEBUG |
||
536 | debug_pgm(PSTR("send_cmd:get Response")); |
||
537 | #endif |
||
538 | while_timeout(true, BT_CMD_TIMEOUT_MS) |
||
539 | { |
||
540 | uart_receive(); |
||
541 | if (command== BT_GET_LOCALID) |
||
542 | { |
||
543 | _delay_ms(CommandDelay); |
||
544 | return bt_getID(); |
||
545 | |||
546 | } |
||
547 | if (fifo_strstr_pgm(&in_fifo, PSTR("OK\r\n"))) |
||
548 | { |
||
549 | info_pgm(PSTR("CMD SEND: OK")); |
||
550 | _delay_ms(CommandDelay); |
||
551 | return true; |
||
552 | } |
||
553 | |||
554 | if (fifo_strstr_pgm(&in_fifo, PSTR("ERROR\r\n"))) |
||
555 | { |
||
556 | #ifdef DEBUG |
||
557 | info_pgm(PSTR("CMD SEND: Error")); |
||
558 | _delay_ms(2000); |
||
559 | #endif |
||
560 | return false; |
||
561 | } |
||
562 | } |
||
563 | } |
||
564 | |||
565 | //#ifdef DEBUG |
||
566 | // if (command != BT_TEST) |
||
567 | // warn_pgm(PSTR("CMD SEND: TIMEOUT")); |
||
568 | // _delay_ms(2000); |
||
569 | //#endif |
||
570 | |||
571 | |||
572 | return false; |
||
573 | } |
||
574 | |||
575 | //bt_init |
||
576 | |||
577 | //-------------------------------------------------------------- |
||
578 | //void test(void) |
||
579 | //{ |
||
580 | // comm_mode = BT_RAW; |
||
581 | // for (uint8_t i = 0; i < 2; i++) |
||
582 | // if (send_cmd(BT_TEST, NULL)) |
||
583 | // break; |
||
584 | // comm_mode = BT_CMD; |
||
585 | //} |
||
586 | |||
587 | |||
588 | #ifndef SaveMem |
||
589 | |||
590 | //-------------------------------------------------------------- |
||
591 | static void clean_line(void) |
||
592 | { |
||
593 | while_timeout(true, 50) |
||
594 | uart_receive(); |
||
595 | fifo_strstr_pgm(&in_fifo, PSTR("\r\n")); |
||
596 | } |
||
597 | |||
598 | static communication_mode_t update_comm_mode(uint16_t timeout_ms) |
||
599 | { |
||
600 | while_timeout(true, timeout_ms) |
||
601 | // for(uint16_t __timeout = 0; __timeout++ <= true && (timeout_ms); _delay_ms(true ? 1 : 0)) |
||
602 | |||
603 | |||
604 | { |
||
605 | uart_receive(); |
||
606 | |||
607 | if (fifo_strstr_pgm(&in_fifo, PSTR("DISCONNECT"))) |
||
608 | { |
||
609 | clean_line(); |
||
610 | // test(); |
||
611 | |||
612 | comm_mode = BT_CMD; |
||
613 | send_cmd(BT_TEST, NULL); |
||
614 | return comm_mode; |
||
615 | } |
||
616 | |||
617 | if (fifo_strstr_pgm(&in_fifo, PSTR("CONNECT"))) |
||
618 | { |
||
619 | _delay_ms(100); //don't delete this, else there will be no success!!!!!!!!! |
||
620 | comm_mode = BT_DATA; |
||
621 | return comm_mode; |
||
622 | } |
||
623 | |||
624 | if (fifo_strstr_pgm (&in_fifo, PSTR("Time out,Fail to connect!"))) |
||
625 | { |
||
626 | clean_line(); |
||
627 | #ifdef DEBUG |
||
628 | debug_pgm(PSTR("CONNECT FAILED\n")); |
||
629 | #endif |
||
630 | // test(); |
||
631 | send_cmd(BT_TEST, NULL); |
||
632 | comm_mode = BT_CMD; |
||
633 | return comm_mode; |
||
634 | } |
||
635 | } |
||
636 | |||
637 | return comm_mode; |
||
638 | } |
||
639 | #endif |
||
640 | //-------------------------------------------------------------- |
||
641 | uint16_t bt_setbaud(uint8_t baudrate) |
||
642 | { |
||
643 | uint8_t init_error = false; |
||
644 | uint8_t BT_found = 0; |
||
645 | i = 0; |
||
646 | |||
647 | // set_BTOn(); |
||
648 | |||
649 | lcd_cls(); |
||
650 | lcd_printp_at (0, 0, PSTR("BT set new Baudrate.."), 0); |
||
651 | |||
652 | SetBaudUart1(Old_Baudrate); |
||
653 | fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE); |
||
654 | _delay_ms(100); |
||
655 | |||
656 | fifo_clear(&in_fifo); |
||
657 | // send_cmd(BT_TEST, NULL); |
||
658 | // comm_mode = BT_NOECHO; |
||
659 | // send_cmd(BT_SET_ECHO, NULL); |
||
660 | // send_cmd(BT_SET_ANSWER, NULL); |
||
661 | bt_set_EchoAnswer(true); |
||
662 | |||
663 | |||
664 | #ifdef DEBUG |
||
665 | debug_pgm(PSTR("Check with PKT Baudrate")); |
||
666 | #endif |
||
667 | |||
668 | if (send_cmd(BT_TEST, NULL)) // Test mit PKT_Baudrate |
||
669 | { |
||
670 | #ifdef DEBUG |
||
671 | debug_pgm(PSTR("BT found with PKT Baudrate")); |
||
672 | #endif |
||
673 | BT_found = 1; |
||
674 | } |
||
675 | |||
676 | if (BT_found == 0) |
||
677 | { |
||
678 | lcd_printp_at (0, 1, PSTR("Error1 set Baudrate.."), 0); |
||
679 | _delay_ms(2100); |
||
680 | set_BTOff(); |
||
681 | return false; |
||
682 | } |
||
683 | |||
684 | else |
||
685 | |||
686 | { |
||
687 | /* Set comm_mode to CMD */ |
||
688 | comm_mode = BT_CMD; |
||
689 | |||
690 | switch (baudrate) |
||
691 | { |
||
692 | // case Baud_2400 : { /* Set BTM Baudrate */ |
||
693 | // if (!(send_cmd(BT_SET_2400, NULL))) init_error = true; |
||
694 | // SetBaudUart1(Baud_2400); |
||
695 | // _delay_ms(100); |
||
696 | // break; |
||
697 | // } |
||
698 | case Baud_4800 : { /* Set BTM Baudrate */ |
||
699 | if (!(send_cmd(BT_SET_4800, NULL))) init_error = true; |
||
700 | SetBaudUart1(Baud_4800); |
||
701 | _delay_ms(100); |
||
702 | break; |
||
703 | } |
||
704 | case Baud_9600 : { /* Set BTM Baudrate */ |
||
705 | if (!(send_cmd(BT_SET_9600, NULL))) init_error = true; |
||
706 | SetBaudUart1(Baud_9600); |
||
707 | _delay_ms(100); |
||
708 | break; |
||
709 | } |
||
710 | case Baud_19200 : { /* Set BTM Baudrate */ |
||
711 | if (!(send_cmd(BT_SET_19200, NULL))) init_error = true; |
||
712 | SetBaudUart1(Baud_19200); |
||
713 | _delay_ms(100); |
||
714 | break; |
||
715 | } |
||
716 | case Baud_38400 : { /* Set BTM Baudrate */ |
||
717 | if (!(send_cmd(BT_SET_38400, NULL))) init_error = true; |
||
718 | SetBaudUart1(Baud_38400); |
||
719 | _delay_ms(100); |
||
720 | break; |
||
721 | } |
||
722 | case Baud_57600 : { /* Set BTM Baudrate */ |
||
723 | if (!(send_cmd(BT_SET_57600, NULL))) init_error = true; |
||
724 | SetBaudUart1(Baud_57600); |
||
725 | _delay_ms(100); |
||
726 | break; |
||
727 | } |
||
728 | case Baud_115200 : { /* Set BTM Baudrate */ |
||
729 | if (!(send_cmd(BT_SET_115200, NULL))) init_error = true; |
||
730 | SetBaudUart1(Baud_115200); |
||
731 | _delay_ms(100); |
||
732 | break; |
||
733 | } |
||
734 | break; |
||
735 | } |
||
736 | |||
737 | // /* Set BTM Echo aus */ |
||
738 | // send_cmd(BT_SET_NOECHO, NULL); |
||
739 | //// test(); |
||
740 | // comm_mode = BT_NOECHO; |
||
741 | // /* Set BTM Answer aus */ |
||
742 | // send_cmd(BT_SET_NOANSWER, NULL); |
||
743 | //// test(); |
||
744 | bt_set_EchoAnswer(false); |
||
745 | bt_mode = BLUETOOTH_SLAVE; |
||
746 | |||
747 | // set_BTOff(); |
||
748 | |||
749 | |||
750 | if (!init_error) |
||
751 | { |
||
752 | lcd_printp_at (0, 2, PSTR("set Baudrate ok"), 0); |
||
753 | _delay_ms(2100); |
||
754 | return true; |
||
755 | } |
||
756 | else |
||
757 | { |
||
758 | lcd_printp_at (0, 2, PSTR("set Baudrate Error"), 0); |
||
759 | _delay_ms(2100); |
||
760 | return true; |
||
761 | } |
||
762 | |||
763 | } |
||
764 | } |
||
765 | |||
766 | void bt_set_EchoAnswer (uint8_t onoff) |
||
767 | |||
768 | { |
||
769 | if (onoff == true) |
||
770 | { |
||
771 | // if (EchoAnswerOn==false) |
||
772 | // { |
||
773 | |||
774 | /* Set comm_mode to CMD */ |
||
775 | comm_mode = BT_CMD; |
||
776 | send_cmd(BT_SET_ECHO, NULL); |
||
777 | send_cmd(BT_SET_ANSWER, NULL); |
||
778 | EchoAnswerOn = true; |
||
779 | send_cmd(BT_TEST, NULL); |
||
780 | |||
781 | // fifo_clear(&in_fifo); |
||
782 | // } |
||
783 | #ifdef DEBUG |
||
784 | debug_pgm(PSTR("bt_set_EchoAnswer: on")); |
||
785 | #endif |
||
786 | } |
||
787 | else |
||
788 | { |
||
789 | // if (EchoAnswerOn==true) |
||
790 | // { |
||
791 | /* Set comm_mode to CMD */ |
||
792 | comm_mode = BT_CMD; |
||
793 | EchoAnswerOn = false; |
||
794 | send_cmd(BT_SET_NOECHO, NULL); |
||
795 | send_cmd(BT_SET_NOANSWER, NULL); |
||
796 | // fifo_clear(&in_fifo); |
||
797 | |||
798 | // } |
||
799 | #ifdef DEBUG |
||
800 | debug_pgm(PSTR("bt_set_EchoAnswer: off")); |
||
801 | #endif |
||
802 | } |
||
803 | |||
804 | } |
||
805 | |||
806 | |||
807 | //-------------------------------------------------------------- |
||
808 | uint16_t bt_init(void) |
||
809 | { |
||
810 | uint8_t init_error = false; |
||
811 | uint8_t BT_found = 0; |
||
812 | i = 0; |
||
813 | |||
814 | set_BTOn(); |
||
815 | |||
816 | lcd_cls(); |
||
817 | lcd_printp_at (0, 0, PSTR("BT initialisieren.."), 0); |
||
818 | // _delay_ms(200); |
||
819 | |||
820 | for (uint8_t z = (bt_name_length); z > 0; z--) |
||
821 | { |
||
822 | if (Config.bt_name[z - 1] != ' ') |
||
823 | { |
||
824 | bt_name_len = z; |
||
825 | break; |
||
826 | } |
||
827 | } |
||
828 | |||
829 | // uart1_init(UART_BAUD_SELECT(57600, F_CPU)); |
||
830 | SetBaudUart1(Config.PKT_Baudrate); |
||
831 | fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE); |
||
832 | _delay_ms(100); |
||
833 | // debug_pgm(PSTR("bt_init")); |
||
834 | uart_receive(); |
||
835 | // debug_pgm(PSTR("bt_init1")); |
||
836 | fifo_clear(&in_fifo); |
||
837 | bt_disconnect(); |
||
838 | bt_set_EchoAnswer(true); |
||
839 | |||
840 | |||
841 | // debug_pgm(PSTR("bt_init2")); |
||
842 | #ifdef DEBUG |
||
843 | debug_pgm(PSTR("Check with PKT Baudrate")); |
||
844 | #endif |
||
845 | send_cmd(BT_TEST, NULL); // Schrott löschen |
||
846 | send_cmd(BT_TEST, NULL); // Schrott löschen |
||
847 | if (send_cmd(BT_TEST, NULL)) // Test mit 57600 |
||
848 | { |
||
849 | #ifdef DEBUG |
||
850 | debug_pgm(PSTR("BT found with PKT Baudrate")); |
||
851 | #endif |
||
852 | BT_found = 1; |
||
853 | } |
||
854 | |||
855 | if (BT_found == 0) |
||
856 | { |
||
857 | #ifdef DEBUG |
||
858 | debug_pgm(PSTR("Check with 19200")); |
||
859 | #endif |
||
860 | // uart1_init(UART_BAUD_SELECT(19200, F_CPU));// Test mit 19200 |
||
861 | SetBaudUart1(Baud_19200); |
||
862 | // _delay_ms(100); |
||
863 | send_cmd(BT_TEST, NULL); // Schrott löschen |
||
864 | send_cmd(BT_TEST, NULL); // Schrott löschen |
||
865 | bt_set_EchoAnswer(true); |
||
866 | |||
867 | if (send_cmd(BT_TEST, NULL)) |
||
868 | { |
||
869 | #ifdef DEBUG |
||
870 | debug_pgm(PSTR("19200 OK")); |
||
871 | #endif |
||
872 | |||
873 | if (send_cmd(BT_TEST, NULL)) |
||
874 | { |
||
875 | #ifdef DEBUG |
||
876 | debug_pgm(PSTR("BT found 19200 Baud")); |
||
877 | |||
878 | #endif |
||
879 | Old_Baudrate = Baud_19200; |
||
880 | BT_found = 2; |
||
881 | } |
||
882 | } |
||
883 | } |
||
884 | if (BT_found == 0) |
||
885 | { |
||
886 | #ifdef DEBUG |
||
887 | debug_pgm(PSTR("Check with 38400")); |
||
888 | #endif |
||
889 | // uart1_init(UART_BAUD_SELECT(19200, F_CPU));// Test mit 19200 |
||
890 | SetBaudUart1(Baud_38400); |
||
891 | // _delay_ms(100); |
||
892 | send_cmd(BT_TEST, NULL); // Schrott löschen |
||
893 | // comm_mode = BT_NOECHO; |
||
894 | // send_cmd(BT_SET_ECHO, NULL); |
||
895 | // comm_mode = BT_NOANSWER; |
||
896 | // send_cmd(BT_SET_ANSWER, NULL); |
||
897 | // comm_mode = BT_CMD; |
||
898 | bt_set_EchoAnswer(true); |
||
899 | |||
900 | if (send_cmd(BT_TEST, NULL)) |
||
901 | { |
||
902 | #ifdef DEBUG |
||
903 | debug_pgm(PSTR("38400 OK")); |
||
904 | #endif |
||
905 | if (send_cmd(BT_TEST, NULL)) |
||
906 | { |
||
907 | #ifdef DEBUG |
||
908 | debug_pgm(PSTR("BT found 38400 Baud")); |
||
909 | #endif |
||
910 | Old_Baudrate = Baud_38400; |
||
911 | BT_found = 2; |
||
912 | } |
||
913 | } |
||
914 | } |
||
915 | |||
916 | if (BT_found == 0) |
||
917 | { |
||
918 | #ifdef DEBUG |
||
919 | debug_pgm(PSTR("Check with 9600")); |
||
920 | #endif |
||
921 | // uart1_init(UART_BAUD_SELECT(9600, F_CPU));//test mit 9600 |
||
922 | SetBaudUart1(Baud_9600); |
||
923 | // _delay_ms(100); |
||
924 | send_cmd(BT_TEST, NULL); |
||
925 | // comm_mode = BT_NOECHO; |
||
926 | // send_cmd(BT_SET_ECHO, NULL); |
||
927 | // comm_mode = BT_NOANSWER; |
||
928 | // send_cmd(BT_SET_ANSWER, NULL); |
||
929 | // comm_mode = BT_CMD; |
||
930 | bt_set_EchoAnswer(true); |
||
931 | if (send_cmd(BT_TEST, NULL)); |
||
932 | { |
||
933 | #ifdef DEBUG |
||
934 | debug_pgm(PSTR("9600 OK")); |
||
935 | #endif |
||
936 | if (send_cmd(BT_TEST, NULL)) |
||
937 | { |
||
938 | #ifdef DEBUG |
||
939 | debug_pgm(PSTR("BT found 9600 Baud")); |
||
940 | #endif |
||
941 | Old_Baudrate = Baud_9600; |
||
942 | BT_found = 3; |
||
943 | } |
||
944 | } |
||
945 | } |
||
946 | |||
947 | if (BT_found == 0) |
||
948 | { |
||
949 | #ifdef DEBUG |
||
950 | debug_pgm(PSTR("Check with 57600")); |
||
951 | #endif |
||
952 | // uart1_init(UART_BAUD_SELECT(9600, F_CPU));//test mit 9600 |
||
953 | SetBaudUart1(Baud_57600); |
||
954 | // _delay_ms(100); |
||
955 | send_cmd(BT_TEST, NULL); |
||
956 | // comm_mode = BT_NOECHO; |
||
957 | // send_cmd(BT_SET_ECHO, NULL); |
||
958 | // comm_mode = BT_NOANSWER; |
||
959 | // send_cmd(BT_SET_ANSWER, NULL); |
||
960 | // comm_mode = BT_CMD; |
||
961 | bt_set_EchoAnswer(true); |
||
962 | if (send_cmd(BT_TEST, NULL)); |
||
963 | { |
||
964 | #ifdef DEBUG |
||
965 | debug_pgm(PSTR("57600 OK")); |
||
966 | #endif |
||
967 | if (send_cmd(BT_TEST, NULL)) |
||
968 | { |
||
969 | #ifdef DEBUG |
||
970 | debug_pgm(PSTR("BT found 57600 Baud")); |
||
971 | #endif |
||
972 | Old_Baudrate = Baud_57600; |
||
973 | BT_found = 4; |
||
974 | } |
||
975 | } |
||
976 | } |
||
977 | |||
978 | |||
979 | if (BT_found == 0) |
||
980 | { |
||
981 | #ifdef DEBUG |
||
982 | debug_pgm(PSTR("Check with 4800")); |
||
983 | #endif |
||
984 | // uart1_init(UART_BAUD_SELECT(4800, F_CPU));//test mit 4800 |
||
985 | SetBaudUart1(Baud_4800); |
||
986 | // _delay_ms(100); |
||
987 | send_cmd(BT_TEST, NULL); |
||
988 | // comm_mode = BT_NOECHO; |
||
989 | // send_cmd(BT_SET_ECHO, NULL); |
||
990 | // comm_mode = BT_NOANSWER; |
||
991 | // send_cmd(BT_SET_ANSWER, NULL); |
||
992 | // comm_mode = BT_CMD; |
||
993 | bt_set_EchoAnswer(true); |
||
994 | if (send_cmd(BT_TEST, NULL)); |
||
995 | { |
||
996 | #ifdef DEBUG |
||
997 | debug_pgm(PSTR("4800 OK")); |
||
998 | #endif |
||
999 | if (send_cmd(BT_TEST, NULL)) |
||
1000 | { |
||
1001 | #ifdef DEBUG |
||
1002 | debug_pgm(PSTR("BT found 4800 Baud")); |
||
1003 | #endif |
||
1004 | Old_Baudrate = Baud_4800; |
||
1005 | BT_found = 5; |
||
1006 | } |
||
1007 | } |
||
1008 | } |
||
1009 | |||
1010 | |||
1011 | if (BT_found > 0) |
||
1012 | { |
||
1013 | |||
1014 | #ifdef DEBUG |
||
1015 | debug_pgm(PSTR("BT found !")); |
||
1016 | #endif |
||
1017 | |||
1018 | /* Set comm_mode to CMD */ |
||
1019 | comm_mode = BT_CMD; |
||
1020 | // test(); |
||
1021 | // if (BTIsSlave==false) |
||
1022 | // { |
||
1023 | |||
1024 | // fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE); |
||
1025 | _delay_ms(100); |
||
1026 | // test(); |
||
1027 | /* Clear remote address */ |
||
1028 | if(!(send_cmd(BT_CLEAR_ADDRESS, NULL))) |
||
1029 | init_error = true; |
||
1030 | // test(); |
||
1031 | /* Set BTM to SLAVE */ |
||
1032 | if (!(send_cmd(BT_SET_SLAVE, NULL))) |
||
1033 | init_error = true; |
||
1034 | // test(); |
||
1035 | /* Set BTM PIN */ |
||
1036 | if(!(send_cmd(BT_SET_PIN, NULL))) |
||
1037 | init_error = true; |
||
1038 | // test(); |
||
1039 | /* Set BTM Name */ |
||
1040 | if(!(send_cmd(BT_SET_NAME, NULL))) |
||
1041 | init_error = true; |
||
1042 | _delay_ms(300); |
||
1043 | // test(); |
||
1044 | if(!(send_cmd(BT_SET_DISPWRDOWN, NULL))) |
||
1045 | init_error = true; |
||
1046 | if(!(send_cmd(BT_GET_LOCALID, NULL))) |
||
1047 | init_error = true; |
||
1048 | |||
1049 | |||
1050 | |||
1051 | |||
1052 | |||
1053 | // } |
||
1054 | |||
1055 | /* Set BTM Baudrate */ |
||
1056 | |||
1057 | // if (!(send_cmd(BT_SET_57600, NULL))) |
||
1058 | // init_error = true; |
||
1059 | if (!bt_setbaud(Config.PKT_Baudrate)) init_error = true; |
||
1060 | |||
1061 | |||
1062 | // uart1_init(UART_BAUD_SELECT(57600, F_CPU)); |
||
1063 | SetBaudUart1(Config.PKT_Baudrate); |
||
1064 | |||
1065 | |||
1066 | |||
1067 | // /* Set BTM Echo aus */ |
||
1068 | // send_cmd(BT_SET_NOECHO, NULL); |
||
1069 | //// test(); |
||
1070 | // comm_mode = BT_NOECHO; |
||
1071 | // /* Set BTM Answer aus */ |
||
1072 | // send_cmd(BT_SET_NOANSWER, NULL); |
||
1073 | //// test(); |
||
1074 | |||
1075 | bt_set_EchoAnswer (false); |
||
1076 | bt_mode = BLUETOOTH_SLAVE; |
||
1077 | |||
1078 | set_BTOff(); |
||
1079 | |||
1080 | |||
1081 | if (!init_error) |
||
1082 | { |
||
1083 | WriteBTInitFlag(); // Init merken |
||
1084 | WriteBTSlaveFlag(); |
||
1085 | |||
1086 | bt_start(); |
||
1087 | return true; |
||
1088 | } |
||
1089 | else |
||
1090 | return false; |
||
1091 | } |
||
1092 | else |
||
1093 | { |
||
1094 | set_BTOff(); |
||
1095 | return false; |
||
1096 | } |
||
1097 | |||
1098 | } |
||
1099 | |||
1100 | |||
1101 | #ifndef SaveMem |
||
1102 | |||
1103 | //-------------------------------------------------------------- |
||
1104 | uint8_t bt_set_mode(const bt_mode_t mode) |
||
1105 | { |
||
1106 | #ifdef DEBUG |
||
1107 | debug_pgm(PSTR("bt_setmode: set Mode")); |
||
1108 | #endif |
||
1109 | |||
1110 | // if (update_comm_mode(0) == BT_DATA) // 30.1.2012 CB |
||
1111 | // return false; |
||
1112 | |||
1113 | if (mode == bt_mode) |
||
1114 | return true; |
||
1115 | |||
1116 | if (mode == BLUETOOTH_MASTER) |
||
1117 | { |
||
1118 | comm_mode = BT_CMD; |
||
1119 | bt_set_EchoAnswer(true); |
||
1120 | |||
1121 | // _delay_ms(1000); |
||
1122 | if (send_cmd(BT_SET_MASTER, NULL)) |
||
1123 | { |
||
1124 | bt_mode = BLUETOOTH_MASTER; |
||
1125 | send_cmd(BT_DISABLE_AUTOCONNECT, NULL); |
||
1126 | WriteBTMasterFlag(); |
||
1127 | |||
1128 | #ifdef DEBUG |
||
1129 | debug_pgm(PSTR("bt_setmode: Master is set")); |
||
1130 | #endif |
||
1131 | } |
||
1132 | } |
||
1133 | if (mode == BLUETOOTH_SLAVE) |
||
1134 | { |
||
1135 | comm_mode = BT_CMD; |
||
1136 | bt_set_EchoAnswer(true); |
||
1137 | |||
1138 | if (send_cmd(BT_ENABLE_AUTOCONNECT, NULL)) |
||
1139 | { |
||
1140 | bt_mode = BLUETOOTH_SLAVE; |
||
1141 | send_cmd(BT_SET_SLAVE, NULL); |
||
1142 | WriteBTSlaveFlag(); |
||
1143 | bt_set_EchoAnswer(false); |
||
1144 | comm_mode = BT_CMD; |
||
1145 | |||
1146 | #ifdef DEBUG |
||
1147 | debug_pgm(PSTR("bt_setmode: Slave is set")); |
||
1148 | #endif |
||
1149 | } |
||
1150 | } |
||
1151 | |||
1152 | // if (bt_mode == BLUETOOTH_MASTER) debug_pgm(PSTR("bt_mode:BLUETOOTH_MASTER ")); |
||
1153 | // if (bt_mode == BLUETOOTH_SLAVE) debug_pgm(PSTR("bt_mode:BLUETOOTH_SLAVE")); |
||
1154 | // if (mode == BLUETOOTH_MASTER) debug_pgm(PSTR("mode:BLUETOOTH_MASTER ")); |
||
1155 | // if (mode == BLUETOOTH_SLAVE) debug_pgm(PSTR("mode:BLUETOOTH_SLAVE")); |
||
1156 | |||
1157 | return (mode == bt_mode); |
||
1158 | } |
||
1159 | |||
1160 | |||
1161 | //-------------------------------------------------------------- |
||
1162 | uint16_t bt_receive(void *data, uint8_t length, uint16_t timeout_ms) |
||
1163 | { |
||
1164 | uint8_t rec_length = 0; |
||
1165 | uint8_t i = 0; |
||
1166 | |||
1167 | // while_timeout(true, timeout_ms); |
||
1168 | for(uint16_t __timeout = 0; __timeout++ <= true && (timeout_ms); _delay_ms(true ? 1 : 0)) |
||
1169 | { |
||
1170 | if (i == length) |
||
1171 | return true; |
||
1172 | |||
1173 | uart_receive(); |
||
1174 | |||
1175 | if (fifo_is_empty(&in_fifo)) |
||
1176 | continue; |
||
1177 | |||
1178 | if (update_comm_mode(0) != BT_DATA) |
||
1179 | { |
||
1180 | #ifdef DEBUG |
||
1181 | debug_pgm(PSTR("not connected")); |
||
1182 | #endif |
||
1183 | return false; |
||
1184 | } |
||
1185 | // We have a connection |
||
1186 | if (timeout_ms == 0) |
||
1187 | timeout_ms += 2000; |
||
1188 | |||
1189 | if (fifo_is_empty(&in_fifo)) |
||
1190 | continue; |
||
1191 | |||
1192 | // Find starting point of packet |
||
1193 | if (!rec_length) |
||
1194 | { |
||
1195 | fifo_read(&in_fifo, (char *)&rec_length); |
||
1196 | |||
1197 | if (rec_length != length) |
||
1198 | { |
||
1199 | rec_length = 0; |
||
1200 | } |
||
1201 | else |
||
1202 | { |
||
1203 | // You've got mail! |
||
1204 | timeout_ms += 2000; |
||
1205 | } |
||
1206 | } |
||
1207 | else |
||
1208 | { |
||
1209 | fifo_read(&in_fifo, (char *)data + i); |
||
1210 | i++; |
||
1211 | } |
||
1212 | } |
||
1213 | return false; |
||
1214 | } |
||
1215 | |||
1216 | #endif |
||
1217 | |||
1218 | #ifndef SaveMem |
||
1219 | |||
1220 | |||
1221 | //-------------------------------------------------------------- |
||
1222 | uint16_t bt_send(void *data, const uint8_t length) |
||
1223 | { |
||
1224 | if (update_comm_mode(0) == BT_CMD) |
||
1225 | return false; |
||
1226 | |||
1227 | uart_send((const char *)&length, 1); |
||
1228 | uart_send((char *)data, length); |
||
1229 | return (update_comm_mode(0) == BT_DATA); |
||
1230 | } |
||
1231 | |||
1232 | |||
1233 | #ifdef SQUIRREL |
||
1234 | |||
1235 | //-------------------------------------------------------------- |
||
1236 | uint16_t bt_connect(const char *address) |
||
1237 | { |
||
1238 | fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE); |
||
1239 | uart_receive(); |
||
1240 | fifo_clear(&in_fifo); |
||
1241 | |||
1242 | // Maybe we already disconnected??? |
||
1243 | if (BT_DATA == update_comm_mode(0)) |
||
1244 | { |
||
1245 | #ifdef DEBUG |
||
1246 | debug_pgm(PSTR("We are still connected...")); |
||
1247 | #endif |
||
1248 | return false; |
||
1249 | } |
||
1250 | // test(); |
||
1251 | send_cmd(BT_TEST, NULL); |
||
1252 | |||
1253 | |||
1254 | /* |
||
1255 | if (!send_cmd(BT_DISABLE_AUTOCONNECT, address)) |
||
1256 | return false; |
||
1257 | */ |
||
1258 | |||
1259 | // Test(); |
||
1260 | send_cmd(BT_TEST, NULL); |
||
1261 | #ifdef DEBUG |
||
1262 | debug_pgm (PSTR ("SET_ADD")); |
||
1263 | #endif |
||
1264 | |||
1265 | if (!send_cmd(BT_SET_ADDRESS, address)) |
||
1266 | return false; |
||
1267 | |||
1268 | // test(); |
||
1269 | send_cmd(BT_TEST, NULL); |
||
1270 | #ifdef DEBUG |
||
1271 | debug_pgm (PSTR ("CONNECT")); |
||
1272 | #endif |
||
1273 | |||
1274 | if (!send_cmd(BT_CONNECT, NULL)) |
||
1275 | return false; |
||
1276 | #ifdef DEBUG |
||
1277 | debug_pgm (PSTR ("WAIT FOR COMM")); |
||
1278 | #endif |
||
1279 | return (BT_DATA == update_comm_mode(20000)); |
||
1280 | } |
||
1281 | |||
1282 | |||
1283 | //-------------------------------------------------------------- |
||
1284 | uint16_t bt_disconnect(void) |
||
1285 | { |
||
1286 | |||
1287 | |||
1288 | if (BT_CMD == update_comm_mode(0)) |
||
1289 | { |
||
1290 | fifo_clear(&in_fifo); |
||
1291 | return true; |
||
1292 | } |
||
1293 | |||
1294 | // Switch to online cmd mode |
||
1295 | for (uint8_t i = 0; i < 4; i++) |
||
1296 | { |
||
1297 | const char plus = '+'; |
||
1298 | uart_send(&plus, 1); |
||
1299 | _delay_ms(1000); |
||
1300 | } |
||
1301 | |||
1302 | comm_mode = BT_CMD; |
||
1303 | |||
1304 | if (!send_cmd(BT_DISCONNECT, NULL)) |
||
1305 | return false; |
||
1306 | |||
1307 | // test(); |
||
1308 | if (!send_cmd(BT_CLEAR_ADDRESS, NULL)) |
||
1309 | return false; |
||
1310 | // test(); |
||
1311 | |||
1312 | if (BT_CMD == update_comm_mode(10000)) |
||
1313 | { |
||
1314 | fifo_clear(&in_fifo); |
||
1315 | return true; |
||
1316 | } |
||
1317 | #ifdef DEBUG |
||
1318 | debug_pgm(PSTR("Still in DATA??")); |
||
1319 | #endif |
||
1320 | return false; |
||
1321 | |||
1322 | } |
||
1323 | |||
1324 | /* |
||
1325 | |||
1326 | BTM-222 Softwareversion 4.35 |
||
1327 | Inquiry Results: |
||
1328 | 111111111222222222233333333334 |
||
1329 | 01234567890123456789012345678901234567890 |
||
1330 | |||
1331 | 1 LE091452 0024-2C-BEB0CA |
||
1332 | 2 E71 c 0024-7C-3EC9B9 |
||
1333 | |||
1334 | BTM-222 Softwareversion 6.26 |
||
1335 | Inquiry Results: |
||
1336 | 1 E71 c 0024-7C-3EC9B9 N.A. |
||
1337 | 2 LE091452 0024-2C-BEB0CA N.A. |
||
1338 | |||
1339 | */ |
||
1340 | |||
1341 | |||
1342 | //-------------------------------------------------------------- |
||
1343 | void copy_mac(const char *src, char *dst) |
||
1344 | { |
||
1345 | uint8_t off = 0; |
||
1346 | |||
1347 | for (uint8_t i = 0; i < 40; i++) |
||
1348 | { |
||
1349 | if (src[i] == '-') if (src[i+3] == '-')// MAC Adresse suchen |
||
1350 | { |
||
1351 | off = i-4; |
||
1352 | break; |
||
1353 | } |
||
1354 | } |
||
1355 | |||
1356 | for (uint8_t i = 0; i < 14; i++) |
||
1357 | { |
||
1358 | if (src[i + off] == '-') |
||
1359 | off++; |
||
1360 | |||
1361 | dst[i] = src[i + off]; |
||
1362 | } |
||
1363 | } |
||
1364 | //-------------------------------------------------------------- |
||
1365 | void copy_localID(const char *src, char *dst) |
||
1366 | { |
||
1367 | uint8_t off = 0; |
||
1368 | |||
1369 | // for (uint8_t i = 0; i < 40; i++) |
||
1370 | // { |
||
1371 | // if (src[i] == '-') if (src[i+3] == '-')// MAC Adresse suchen |
||
1372 | // { |
||
1373 | // off = i-4; |
||
1374 | // break; |
||
1375 | // } |
||
1376 | // } |
||
1377 | |||
1378 | for (uint8_t i = 0; i < 14; i++) |
||
1379 | { |
||
1380 | if (src[i + off] == '-') |
||
1381 | off++; |
||
1382 | |||
1383 | dst[i] = src[i + off]; |
||
1384 | } |
||
1385 | } |
||
1386 | //-------------------------------------------------------------- |
||
1387 | void copy_DevName(const char *src, char *dst) |
||
1388 | { |
||
1389 | uint8_t off = 0; |
||
1390 | |||
1391 | |||
1392 | for (uint8_t i = 0; i < 14; i++) |
||
1393 | { |
||
1394 | if (src[i] == ' ') if (src[i+1] == ' ') break; // nach zwei Leerzeichen ist der Name zuende |
||
1395 | dst[i] = src[i + off]; |
||
1396 | } |
||
1397 | } |
||
1398 | |||
1399 | //-------------------------------------------------------------- |
||
1400 | uint16_t bt_discover(char result[8][12]) |
||
1401 | |||
1402 | |||
1403 | { |
||
1404 | |||
1405 | |||
1406 | if (!bt_set_mode(BLUETOOTH_MASTER)) |
||
1407 | return false; |
||
1408 | |||
1409 | send_cmd(BT_TEST, NULL); |
||
1410 | if (!send_cmd(BT_FIND_DEVICES, NULL)) |
||
1411 | { |
||
1412 | return false; |
||
1413 | } |
||
1414 | |||
1415 | char buffer[255]; //oversized, but who cares? |
||
1416 | char *bufferhead = buffer; |
||
1417 | uint16_t pos = 0; |
||
1418 | uint16_t Timeout = 40000; |
||
1419 | uint16_t pos1 = 0; |
||
1420 | uint16_t posC = 0; |
||
1421 | #ifdef DEBUG |
||
1422 | debug_pgm(PSTR("discover2")); |
||
1423 | #endif |
||
1424 | do |
||
1425 | { |
||
1426 | uart_receive(); |
||
1427 | Timeout--; |
||
1428 | pos1++; |
||
1429 | posC++; |
||
1430 | _delay_ms(1); |
||
1431 | write_ndigit_number_u(0,5,fifo_getcount(&in_fifo),5,0,0); |
||
1432 | if (posC ==1000) |
||
1433 | { |
||
1434 | lcd_printp_at (i++, 1, PSTR("."), 0); |
||
1435 | posC = 0; |
||
1436 | |||
1437 | } |
||
1438 | |||
1439 | |||
1440 | if (fifo_is_full(&in_fifo)) break; |
||
1441 | #ifdef DEBUG |
||
1442 | if (fifo_search(&in_fifo, PSTR("Found."))) debug_pgm(PSTR("Suchen ende1")); |
||
1443 | #endif |
||
1444 | } |
||
1445 | |||
1446 | // while (((Timeout > 0) ||(!fifo_strstr_pgm(&in_fifo, PSTR("Inquiry Results:\r\n")))) && (!fifo_strstr_pgm(&in_fifo, PSTR("Found")))); |
||
1447 | while ((Timeout > 0)||(!fifo_strstr_pgm(&in_fifo, PSTR("Inquiry Results:\r\n")))); |
||
1448 | #ifdef DEBUG |
||
1449 | debug_pgm(PSTR("Suchen ende2")); |
||
1450 | |||
1451 | |||
1452 | if (Timeout == 0) debug_pgm(PSTR("Timeout")); |
||
1453 | |||
1454 | if (fifo_is_full(&in_fifo)) debug_pgm(PSTR("Fifo Overrun, zuviele BT Devices")); |
||
1455 | #endif |
||
1456 | while (!fifo_is_empty(&in_fifo)) |
||
1457 | { |
||
1458 | // Get next line |
||
1459 | while (!fifo_cmp_pgm(&in_fifo, PSTR("\r\n"))) |
||
1460 | { |
||
1461 | fifo_read(&in_fifo, bufferhead); |
||
1462 | bufferhead++; |
||
1463 | } |
||
1464 | // terminate string |
||
1465 | *bufferhead = 0; |
||
1466 | |||
1467 | //reset bufferhead |
||
1468 | bufferhead = buffer; |
||
1469 | |||
1470 | if (strlen(buffer) == 0) |
||
1471 | continue; //the empty line before end of inquiry |
||
1472 | |||
1473 | if (strstr_P(buffer, PSTR("Inquiry End"))) |
||
1474 | // if (searchend) |
||
1475 | { |
||
1476 | fifo_clear(&in_fifo); |
||
1477 | // test(); |
||
1478 | return true; |
||
1479 | } |
||
1480 | |||
1481 | |||
1482 | copy_DevName(&buffer[3],device_list[pos].DevName); |
||
1483 | device_list[pos].DevName[14] = 0; // Stringende |
||
1484 | |||
1485 | copy_mac(&buffer[3], device_list[pos].mac); |
||
1486 | |||
1487 | // for (uint16_t i = 0; i < 15; i++) |
||
1488 | // { |
||
1489 | // |
||
1490 | //// USART_putc((device_list[pos].DevName[i])); |
||
1491 | // lcd_print_hex((device_list[pos].DevName[i]),0); |
||
1492 | // } |
||
1493 | // USART_putc('\n'); |
||
1494 | // |
||
1495 | // |
||
1496 | // for (uint16_t i = 0; i < 12; i++) |
||
1497 | // { |
||
1498 | // |
||
1499 | // USART_putc((device_list[pos].mac[i])); |
||
1500 | // |
||
1501 | // } |
||
1502 | // |
||
1503 | // USART_putc('\n'); |
||
1504 | // USART_putc('\r'); |
||
1505 | pos++; |
||
1506 | } |
||
1507 | |||
1508 | return false; |
||
1509 | } |
||
1510 | |||
1511 | |||
1512 | //-------------------------------------------------------------- |
||
1513 | uint8_t bt_getID (void) |
||
1514 | |||
1515 | |||
1516 | { |
||
1517 | |||
1518 | |||
1519 | char buffer[255]; //oversized, but who cares? |
||
1520 | char *bufferhead = buffer; |
||
1521 | // uint16_t pos = 0; |
||
1522 | #ifdef DEBUG |
||
1523 | debug_pgm(PSTR("bt_getID1")); |
||
1524 | #endif |
||
1525 | |||
1526 | while_timeout(!fifo_strstr_pgm(&in_fifo, PSTR("r\n")), |
||
1527 | 2000) |
||
1528 | uart_receive(); |
||
1529 | |||
1530 | #ifdef DEBUG |
||
1531 | debug_pgm(PSTR("bt_getID:Suchen ende2")); |
||
1532 | |||
1533 | |||
1534 | // if (Timeout == 0) debug_pgm(PSTR("Timeout")); |
||
1535 | |||
1536 | if (fifo_is_full(&in_fifo)) debug_pgm(PSTR("bt_getID:Fifo Overrun")); |
||
1537 | #endif |
||
1538 | |||
1539 | while (!fifo_is_empty(&in_fifo)) |
||
1540 | { |
||
1541 | // Get next line |
||
1542 | while (!fifo_cmp_pgm(&in_fifo, PSTR("\r\n"))) |
||
1543 | { |
||
1544 | fifo_read(&in_fifo, bufferhead); |
||
1545 | bufferhead++; |
||
1546 | // write_ndigit_number_u(10,4,fifo_getcount(&in_fifo),5,0,0); |
||
1547 | } |
||
1548 | // terminate string |
||
1549 | *bufferhead = 0; |
||
1550 | |||
1551 | //reset bufferhead |
||
1552 | bufferhead = buffer; |
||
1553 | if (strlen(buffer) == 0) |
||
1554 | continue; //the empty line before end of inquiry |
||
1555 | |||
1556 | copy_localID(&buffer[0], &localID[0]); |
||
1557 | |||
1558 | for(uint8_t i = 0; i < 13; i++) |
||
1559 | { |
||
1560 | lcd_putc (i, 6, localID[i],0); |
||
1561 | Config.bt_Mac[i] = localID[i]; |
||
1562 | } |
||
1563 | // lcd_printp_at (0, 7, PSTR("lokale ID hier"), 0); |
||
1564 | //// write_ndigit_number_u(0,4,fifo_getcount(&in_fifo),5,0,0); |
||
1565 | // while (!get_key_press (1 << KEY_ENTER)); |
||
1566 | #ifdef DEBUG |
||
1567 | debug_pgm(PSTR("bt_getID:Copy ID")); |
||
1568 | #endif |
||
1569 | if ( fifo_strstr_pgm(&in_fifo, PSTR("OK"))) |
||
1570 | { |
||
1571 | fifo_clear(&in_fifo); |
||
1572 | #ifdef DEBUG |
||
1573 | debug_pgm(PSTR("bt_getID:OK found")); |
||
1574 | #endif |
||
1575 | return true; |
||
1576 | } |
||
1577 | else return false; |
||
1578 | |||
1579 | |||
1580 | return true; |
||
1581 | |||
1582 | // pos++; |
||
1583 | } |
||
1584 | |||
1585 | return false; |
||
1586 | } |
||
1587 | |||
1588 | |||
1589 | |||
1590 | device_info device_list[NUTS_LIST]; |
||
1591 | |||
1592 | void bt_downlink_init(void) |
||
1593 | { |
||
1594 | |||
1595 | |||
1596 | fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE); |
||
1597 | _delay_ms(100); |
||
1598 | // debug_pgm(PSTR("bt_downlink_init")); |
||
1599 | uart_receive(); |
||
1600 | fifo_clear(&in_fifo); |
||
1601 | // send_cmd(BT_TEST, NULL); |
||
1602 | #ifdef DEBUG |
||
1603 | debug_pgm(PSTR("downlink_init Start")); |
||
1604 | #endif |
||
1605 | if (Config.BTIsSlave == true) // nur Init wenn BT ist Slave |
||
1606 | { |
||
1607 | #ifdef DEBUG |
||
1608 | debug_pgm(PSTR("downlink_init:try to set Master")); |
||
1609 | #endif |
||
1610 | // comm_mode = BT_NOECHO; |
||
1611 | // |
||
1612 | // if (!send_cmd (BT_SET_ECHO,NULL)) { |
||
1613 | //#ifdef DEBUG |
||
1614 | // debug_pgm(PSTR("downlink_init:Couldn't set Echo!")); |
||
1615 | //#endif |
||
1616 | // } |
||
1617 | // |
||
1618 | // comm_mode = BT_NOANSWER; |
||
1619 | // if (!send_cmd(BT_SET_ANSWER,NULL)) { |
||
1620 | //#ifdef DEBUG |
||
1621 | // debug_pgm(PSTR("downlink_init:Couldn't set Answer!")); |
||
1622 | //#endif |
||
1623 | // |
||
1624 | // } |
||
1625 | comm_mode = BT_CMD; |
||
1626 | // send_cmd(BT_TEST, NULL); |
||
1627 | |||
1628 | bt_set_EchoAnswer(true); |
||
1629 | |||
1630 | |||
1631 | if (!bt_set_mode(BLUETOOTH_MASTER)) |
||
1632 | |||
1633 | { |
||
1634 | #ifdef DEBUG |
||
1635 | debug_pgm(PSTR("downlink_init:Couldn't set master!")); |
||
1636 | #endif |
||
1637 | return; |
||
1638 | } |
||
1639 | #ifdef DEBUG |
||
1640 | debug_pgm(PSTR("downlink_init:master is set ")); |
||
1641 | #endif |
||
1642 | |||
1643 | // WriteBTMasterFlag(); // Master merken |
||
1644 | comm_mode = BT_CMD; |
||
1645 | } |
||
1646 | else |
||
1647 | { |
||
1648 | #ifdef DEBUG |
||
1649 | debug_pgm(PSTR("downlink_init:Master was set")); |
||
1650 | #endif |
||
1651 | comm_mode = BT_CMD; |
||
1652 | } |
||
1653 | } |
||
1654 | |||
1655 | |||
1656 | void bt_searchDevice(void) //Bluetoothgeräte suchen |
||
1657 | |||
1658 | { |
||
1659 | |||
1660 | char result[8][12]; |
||
1661 | |||
1662 | |||
1663 | |||
1664 | for (uint8_t i = 0; i < 8; i++) // alte Liste löschen |
||
1665 | for (uint8_t j = 0; j < 12; j++) |
||
1666 | result[i][j] = 0; |
||
1667 | #ifdef DEBUG |
||
1668 | debug_pgm(PSTR("Search Device:BT_discover")); |
||
1669 | #endif |
||
1670 | if (bt_discover(result)) |
||
1671 | { |
||
1672 | bt_devicecount = 0; |
||
1673 | #ifdef DEBUG |
||
1674 | debug_pgm(PSTR("Search Device:Search ok")); |
||
1675 | #endif |
||
1676 | for (uint8_t i = 0; i < 8; i++) |
||
1677 | { |
||
1678 | if (valid(i)) |
||
1679 | bt_devicecount++; |
||
1680 | else break; |
||
1681 | } |
||
1682 | } |
||
1683 | #ifdef DEBUG |
||
1684 | else |
||
1685 | |||
1686 | debug_pgm(PSTR("Search Device:Search failed")); |
||
1687 | #endif |
||
1688 | // } |
||
1689 | |||
1690 | } |
||
1691 | |||
1692 | // |
||
1693 | //-------------------------------------------------------------- |
||
1694 | volatile uint8_t bt_receiveNMEA(void) |
||
1695 | { |
||
1696 | |||
1697 | char received; |
||
1698 | static uint8_t line_flag = 1; |
||
1699 | static char* ptr_write = bt_rx_buffer; |
||
1700 | uint32_t timeout=400000; |
||
1701 | |||
1702 | while(!timeout == 0){ |
||
1703 | |||
1704 | if (bt_rx_ready == 1) |
||
1705 | return true; |
||
1706 | |||
1707 | uart_receive(); |
||
1708 | if (fifo_is_empty(&in_fifo)) timeout--; |
||
1709 | if (fifo_is_empty(&in_fifo)) continue; |
||
1710 | |||
1711 | timeout = 400000; |
||
1712 | fifo_read(&in_fifo, &received); |
||
1713 | //#ifdef DEBUG |
||
1714 | // USART_putc(received); |
||
1715 | //#endif |
||
1716 | // Find starting point of packet |
||
1717 | if (bt_rx_ready == 0) |
||
1718 | { |
||
1719 | |||
1720 | if ((received == start) && (line_flag==1)) |
||
1721 | { // start '$' |
||
1722 | line_flag = 0; // New line has begun |
||
1723 | ptr_write = bt_rx_buffer; // Begin at start of buffer |
||
1724 | bt_rx_len = 0; |
||
1725 | //#ifdef DEBUG |
||
1726 | // debug_pgm(PSTR("NMEA $")); |
||
1727 | //#endif |
||
1728 | } |
||
1729 | if (line_flag == 0) |
||
1730 | { // Are we receiving a line? |
||
1731 | *ptr_write = received; // Add current byte |
||
1732 | bt_rx_len++; |
||
1733 | |||
1734 | // GPS Datensatzende |
||
1735 | |||
1736 | if (received == end) |
||
1737 | { // End of MK-GPS or NMEA-line? |
||
1738 | line_flag = 1; // Yes, start new line |
||
1739 | bt_rx_ready = 1; // Lock buffer until line has been processed |
||
1740 | |||
1741 | //#ifdef DEBUG |
||
1742 | // debug_pgm(PSTR("NMEA End")); |
||
1743 | //#endif |
||
1744 | return true; |
||
1745 | } |
||
1746 | } |
||
1747 | |||
1748 | ptr_write++; |
||
1749 | if(bt_rx_len == RXD_BUFFER_SIZE) line_flag = 1; // Line too long? Try again |
||
1750 | }//if (bt_rx_ready == 0) |
||
1751 | |||
1752 | } |
||
1753 | #ifdef DEBUG |
||
1754 | debug_pgm(PSTR("bt_receiveNMEA: Timeout")); |
||
1755 | #endif |
||
1756 | |||
1757 | return false; |
||
1758 | } |
||
1759 | |||
1760 | |||
1761 | |||
1762 | |||
1763 | |||
1764 | |||
1765 | // |
||
1766 | ////-------------------------------------------------------------- |
||
1767 | //uint16_t bt_receiveNMEA2(void) |
||
1768 | //{ |
||
1769 | // |
||
1770 | // char received; |
||
1771 | // static uint8_t line_flag = 1; |
||
1772 | // static char* ptr_write = bt_rx_buffer; |
||
1773 | // uint16_t timeout_ms=2000; |
||
1774 | // |
||
1775 | //// while_timeout(true, timeout_ms) { |
||
1776 | //while(1){ |
||
1777 | // |
||
1778 | // uart_receive(); |
||
1779 | // if (fifo_is_empty(&in_fifo)) |
||
1780 | // continue; |
||
1781 | // fifo_read(&in_fifo, &received); |
||
1782 | // USART_putc(received); |
||
1783 | //// _delay_ms(1); |
||
1784 | // } |
||
1785 | //// |
||
1786 | //return true; |
||
1787 | //} |
||
1788 | |||
1789 | |||
1790 | |||
1791 | #endif |
||
1792 | #endif |
||
1793 | #endif |