Subversion Repositories Projects

Rev

Blame | Last modification | View Log | RSS feed

/**
 * source for the Bluetooth driver
 * @file bluetooth.c
 * @author Linus Lotz<lotz@in.tum.de>
 * @author Salomon Sickert
 */




#include "cpu.h"
#include <string.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "bluetooth.h"
#include "main.h"
#ifdef HWVERSION3_9
#include "uart1.h"
#include "usart.h"
#include "timer.h"
#include "fifo.h"
#include "error.h"
#include "lcd.h"
#include "eeprom.h"
#include "error.h"
#include "setup.h"
#include "bluetooth.h"
#include "tracking.h"


//#define SaveMem

//
// Baudrate for the UART-connection to the BTM-222 on SQUIRREL
//

#define SQUIRREL

#ifdef SQUIRREL
#define UART_BAUD_RATE      19200
#endif

#ifdef NUT
#define UART_BAUD_RATE      19200
#endif


typedef enum {
        BT_RAW,
        BT_DATA,
        BT_CMD,
        BT_NOECHO,
        BT_NOANSWER
} communication_mode_t;

#define BT_CMD_TIMEOUT_MS 2000

typedef enum {
        BT_TEST,                                // AT
        BT_CONNECT,                             // ATA
        BT_DISCONNECT,                  // ATH
        BT_CLEAR_ADDRESS,               // ATD0
        BT_SET_ADDRESS,                 // ATD=_____
        BT_FIND_DEVICES,                // ATF?
        BT_DISABLE_AUTOCONNECT,         // ATO1
        BT_SET_MASTER,                  // ATR0
        BT_SET_SLAVE,                   // ATR1
        BT_SET_PIN,                     // ATP=1234
        BT_SET_2400,                    // ATL* Baudrate 2400
        BT_SET_9600,                    // ATL1 Baudrate 9600
        BT_SET_19200,                   // ATL2 Baudrate 19200
        BT_SET_38400,                   // ATL3 Baudrate 38400
        BT_SET_57600,                   // ATL4 Baudrate 57600
        BT_SET_115200,                  // ATL5 Baudrate 115200
        BT_SET_NOANSWER,                // ATQ1 Rückmeldungen aus
        BT_SET_NOECHO,                  // ATE0 ECHO deaktivieren
        BT_SET_ANSWER,                  // ATQ0 Rückmeldungen
        BT_SET_ECHO,                    // ATE1 ECHO aktivieren
        BT_SET_DEFAULT,                 // Defaultwerte setzen
        BT_SET_NAME,                    // Devicename
        BT_SET_DISPWRDOWN               // disable auto Powerdown
} bt_cmd_t;


#define IN_FIFO_SIZE 512


static uint8_t bt_buffer[IN_FIFO_SIZE];
static fifo_t in_fifo;

char rx_buffer[RXD_BUFFER_SIZE];
volatile uint8_t rx_len;
volatile uint8_t rx_ready = 0;
uint8_t rx_GPS;
static char start = '$';
static char end = '\n';

char data_decode[RXD_BUFFER_SIZE];
volatile uint16_t rx_timeout;


static bt_mode_t bt_mode = BLUETOOTH_SLAVE;
static communication_mode_t comm_mode = BT_CMD;

uint8_t i = 0;
uint8_t NoEcho = 0;
uint8_t NoAnswer = 0;

uint8_t bt_devicecount = 0;

uint8_t bt_rxerror = 0;

device_info device_list[NUTS_LIST];

// Set a timeout of Y ms and a Conditon X, which have to be true while timeout
#define while_timeout(X, Y) for(uint16_t __timeout = 0; __timeout++ <= Y && (X); Delay_MS(Y ? 1 : 0))

//--------------------------------------------------------------
void Delay_MS(int count)
{
        for (int i = 0; i < count; i++)
                _delay_ms(1);
}


//--------------------------------------------------------------
void uart_receive(void)
{
        unsigned int uart_data;

        while (!fifo_is_full(&in_fifo))
        {
                uart_data = uart1_getc();

//              USART_puts(".");

                switch (uart_data & 0xFF00) {
                        // Framing Error detected, i.e no stop bit detected
                case UART_FRAME_ERROR:
#ifdef DEBUG
                        warn_pgm(PSTR("FRM ERR"));
#endif
                        bt_rxerror++;
                        return;

                        // Overrun, a character already presend in the UART UDR register was
                        // not read by the interrupt handler before the next character arrived,
                        // one or more received characters have been dropped
                        //
                case UART_OVERRUN_ERROR:
#ifdef DEBUG
                        warn_pgm(PSTR("OVR ERR"));
#endif
                        bt_rxerror++;
                        return;

                        // We are not reading the receive buffer fast enough,
                        // one or more received character have been dropped
                        //
                case UART_BUFFER_OVERFLOW:
#ifdef DEBUG
                        warn_pgm(PSTR("BUF ERR"));
#endif
                        bt_rxerror++;
                        return;

                        // UART Inputbuffer empty, nothing to do
                case UART_NO_DATA:
                        return;

                default:
                {
                        fifo_write(&in_fifo, uart_data);
#ifdef DEBUG
                        USART_putc(uart_data);
#endif
                }
                }
        }
#ifdef DEBUG
        warn_pgm(PSTR("FIFO OVR ERR"));
#endif
}


//--------------------------------------------------------------
static void uart_send(const char *data, const uint8_t length)
{
#ifdef DEBUG
  debug_pgm(PSTR("bt_uart_send"));
#endif

        char echo;

        lcd_printp_at (i++, 1, PSTR("."), 0);
        for (uint8_t i = 0; i < length; i++)
        {

#ifdef DEBUG
                USART_putc((data[i]));    //test
#endif
//              debug_pgm(PSTR("bt_init_S"));

                if (uart1_putc(data[i]) == 0)
                {
#ifdef DEBUG
                        warn_pgm(PSTR("UART: Remote not ready"));
#endif
                        return;
                }

                if (comm_mode == BT_RAW)
                        _delay_ms(50);

                if (comm_mode == BT_DATA)
                        _delay_ms(1);

                if (comm_mode == BT_NOECHO)
                        _delay_ms(1);

                if (comm_mode == BT_CMD)
                {
                        uint8_t x = 0;
                        for (; x < 3; x++)
                        {
//                              //      while_timeout(X, Y) for(uint16_t __timeout = 0; __timeout++ <= Y && (X); _delay_ms(Y ? 1 : 0))
//                              while_timeout(fifo_is_empty(&in_fifo), 200)
                                for(uint16_t __timeout = 0; __timeout++ <= 200 && (fifo_is_empty(&in_fifo)); _delay_ms(200 ? 1 : 0))
                                {
                                        uart_receive();
                                }

                                fifo_read(&in_fifo, &echo);

                                if (echo != data[i]) {
                                        if (uart1_putc(data[i]) == 0)
                                        {
                                                warn_pgm(PSTR ("UART: Remote not ready"));
                                                return;
                                        }
                                }
                                else
                                        break;
                        }

                        if (x == 3)
                        {
                                error_putc(data[i]);
                                error_pgm(PSTR("BT: WRONG ECHO"));
                        }
                }
        }
}


//--------------------------------------------------------------
static uint16_t send_cmd(const bt_cmd_t command, const char *data)
{
  uint16_t CommandDelay=0;        // nach BTM222 Kommandos verschiedene Verzögerungszeiten bevor es weitergehen kann

//      _delay_ms(500);         // org 500 300 zu wenig
        char full_command[20];  // Maximum command size

        switch (command)
        {
        case BT_SET_PIN:
                strcpy_P(full_command, PSTR("ATP="));
                for (uint8_t i = 0; i < bt_pin_length; i++)
                {
                        full_command[i+4] = bt_pin[i];
                }
                full_command[(bt_pin_length+4)] =0;
                CommandDelay = 100;             //100ms
                break;

        case BT_SET_DEFAULT:
                strcpy_P(full_command, PSTR("ATZ0"));
                CommandDelay = 1000;
                break;


        case BT_SET_2400:
                strcpy_P(full_command, PSTR("ATL*"));
                CommandDelay = 100;
                break;

        case BT_SET_9600:
                strcpy_P(full_command, PSTR("ATL1"));
                CommandDelay = 100;
                break;

        case BT_SET_19200:
                strcpy_P(full_command, PSTR("ATL2"));
                CommandDelay = 100;
                break;

        case BT_SET_38400:
                strcpy_P(full_command, PSTR("ATL3"));
                CommandDelay = 100;
                break;

        case BT_SET_57600:
                strcpy_P(full_command, PSTR("ATL4"));
                CommandDelay = 100;
                break;

        case BT_SET_115200:
                strcpy_P(full_command, PSTR("ATL5"));
                CommandDelay = 100;
                break;

        case BT_SET_NOANSWER:
                strcpy_P(full_command, PSTR("ATQ1"));
                CommandDelay = 100;
                break;

        case BT_SET_NOECHO:
                strcpy_P(full_command, PSTR("ATE0"));
                CommandDelay = 100;
                break;

        case BT_SET_ANSWER:
                strcpy_P(full_command, PSTR("ATQ0"));
                CommandDelay = 100;
                break;

        case BT_SET_ECHO:
                strcpy_P(full_command, PSTR("ATE1"));
                CommandDelay = 100;
                break;

        case BT_TEST:
                strcpy_P(full_command, PSTR("AT"));
                CommandDelay = 100;
                break;

        case BT_CONNECT:
                strcpy_P(full_command, PSTR("ATA"));
                CommandDelay = 100;
                break;

        case BT_DISCONNECT:
                strcpy_P(full_command, PSTR("ATH"));
                CommandDelay = 100;
                break;

        case BT_CLEAR_ADDRESS:
                strcpy_P(full_command, PSTR("ATD0"));
                CommandDelay = 100;
                break;

        case BT_SET_ADDRESS:
                strcpy_P(full_command, PSTR("ATD="));
                memcpy((full_command + strlen(full_command)), data, 12);
                full_command[16] = 0;
                CommandDelay = 100;
                break;

        case BT_FIND_DEVICES:
                strcpy_P(full_command, PSTR("ATF?"));
                CommandDelay = 100;
                break;

        case BT_DISABLE_AUTOCONNECT:
                strcpy_P(full_command, PSTR("ATO1"));
                CommandDelay = 3500;
                break;

        case BT_SET_MASTER:
                strcpy_P(full_command, PSTR("ATR0"));
                CommandDelay = 3000;
                break;

        case BT_SET_SLAVE:
                strcpy_P(full_command, PSTR("ATR1"));
                CommandDelay = 3000;
                break;

        case BT_SET_NAME:
                strcpy_P(full_command, PSTR("ATN="));
                for (uint8_t i = 0; i < bt_name_len; i++)
                {
                        full_command[i + 4] = bt_name[i];
                }
                full_command[(bt_name_len + 4)] = 0;
                CommandDelay = 100;
                break;

        case BT_SET_DISPWRDOWN:
                strcpy_P(full_command, PSTR("ATS1"));
                CommandDelay = 100;
                break;

        default:
                warn_pgm(PSTR("CMD UNK"));
                return false;
        }

        strcat_P(full_command, PSTR("\r"));

        // throw away your television
        uart_receive();
        fifo_clear(&in_fifo);
//      debug_pgm(PSTR("bt_init3"));
        // send command
        uart_send(full_command, strlen(full_command));

        if (command== BT_SET_NOECHO)
          {
            _delay_ms(CommandDelay);
            return true;
          }

        if (command== BT_SET_NOANSWER)
          {
            _delay_ms(CommandDelay);
            return true;
          }

        if (command== BT_SET_ECHO)
          {
            _delay_ms(CommandDelay);
            return true;
          }
        if (command== BT_SET_ANSWER)
          {
            _delay_ms(CommandDelay);
            return true;
          }
        // get response
        while_timeout(true, BT_CMD_TIMEOUT_MS)
        {
                uart_receive();
                if (fifo_strstr_pgm(&in_fifo, PSTR("OK\r\n")))
                {
                        info_pgm(PSTR("CMD SEND: OK"));
                        _delay_ms(CommandDelay);
                        return true;
                }

                if (fifo_strstr_pgm(&in_fifo, PSTR("ERROR\r\n")))
                {
#ifdef DEBUG
                        info_pgm(PSTR("CMD SEND: Error"));
#endif
                        return false;
                }
        }

#ifdef DEBUG
        if (command != BT_TEST)
                warn_pgm(PSTR("CMD SEND: TIMEOUT"));
#endif


        return false;
}


//--------------------------------------------------------------
void test(void)
{
        comm_mode = BT_RAW;
        for (uint8_t i = 0; i < 2; i++)
                if (send_cmd(BT_TEST, NULL))
                        break;
        comm_mode = BT_CMD;
}


#ifndef SaveMem

//--------------------------------------------------------------
static void clean_line(void)
{
        while_timeout(true, 50)
        uart_receive();
        fifo_strstr_pgm(&in_fifo, PSTR("\r\n"));
}

static communication_mode_t update_comm_mode(uint16_t timeout_ms)
{
        while_timeout(true, timeout_ms)
        {
                uart_receive();

                if (fifo_strstr_pgm(&in_fifo, PSTR("DISCONNECT")))
                {
                        clean_line();
                        test();
                        comm_mode = BT_CMD;
                        return comm_mode;
                }

                if (fifo_strstr_pgm(&in_fifo, PSTR("CONNECT")))
                {
                        _delay_ms(100); //don't delete this, else there will be no success!!!!!!!!!
                        comm_mode = BT_DATA;
                        return comm_mode;
                }

                if (fifo_strstr_pgm (&in_fifo, PSTR("Time out,Fail to connect!")))
                {
                        clean_line();
#ifdef DEBUG
                        debug_pgm(PSTR("CONNECT FAILED"));
#endif
                        test();
                        comm_mode = BT_CMD;
                        return comm_mode;
                }
        }

        return comm_mode;
}
#endif


//--------------------------------------------------------------
uint16_t bt_init(void)
{
        uint8_t init_error = false;
        uint8_t BT_found = 0;
        i = 0;

        set_BTOn();

        lcd_cls();
        lcd_printp_at (0, 0, PSTR("BT initialisieren.."), 0);
//      _delay_ms(200);

        for (uint8_t z = (bt_name_length); z > 0; z--)
        {
                if (bt_name[z - 1] != ' ')
                {
                        bt_name_len = z;
                        break;
                }
        }

        uart1_init(UART_BAUD_SELECT(57600, F_CPU));
        fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE);
        _delay_ms(100);
//      debug_pgm(PSTR("bt_init"));
//      uart_receive();
//      debug_pgm(PSTR("bt_init1"));
        fifo_clear(&in_fifo);
        send_cmd(BT_TEST, NULL);
        comm_mode = BT_NOECHO;
        send_cmd(BT_SET_ECHO, NULL);
        send_cmd(BT_SET_ANSWER, NULL);

//      debug_pgm(PSTR("bt_init2"));
#ifdef DEBUG
        debug_pgm(PSTR("Check with 57600"));
#endif
//      send_cmd(BT_TEST, NULL); // Schrott löschen

        if (send_cmd(BT_TEST, NULL)) // Test mit 57600
        {
#ifdef DEBUG
                debug_pgm(PSTR("BT found 57600 Baud"));
#endif
        BT_found = 1;
        }

        if (BT_found == 0)
        {
#ifdef DEBUG
                debug_pgm(PSTR("Check with 19200"));
#endif
                uart1_init(UART_BAUD_SELECT(19200, F_CPU));// Test mit 19200
                _delay_ms(100);
                send_cmd(BT_TEST, NULL); // Schrott löschen
                send_cmd(BT_SET_ANSWER, NULL);
                send_cmd(BT_SET_ECHO, NULL);

                if (send_cmd(BT_TEST, NULL))
                {
                        debug_pgm(PSTR("19200 OK"));
                        if (send_cmd(BT_TEST, NULL))
                        {
#ifdef DEBUG
                                debug_pgm(PSTR("BT found 19200 Baud"));
#endif
                                BT_found = 2;
                        }
                }
        }

        if (BT_found == 0)
        {
#ifdef DEBUG
                debug_pgm(PSTR("Check with 9600"));
#endif
                uart1_init(UART_BAUD_SELECT(9600, F_CPU));//test mit 9600
                _delay_ms(100);
                send_cmd(BT_TEST, NULL);
                send_cmd(BT_SET_ANSWER, NULL);
                send_cmd(BT_SET_ECHO, NULL);
                if (send_cmd(BT_TEST, NULL));
                {
#ifdef DEBUG
                        debug_pgm(PSTR("9600 OK"));
#endif
                        if (send_cmd(BT_TEST, NULL))
                        {
#ifdef DEBUG
                                debug_pgm(PSTR("BT found 9600 Baud"));
#endif
                                BT_found = 3;
                        }
                }
        }


        if (BT_found == 0)
        {
#ifdef DEBUG
                debug_pgm(PSTR("Check with 4800"));
#endif
                uart1_init(UART_BAUD_SELECT(4800, F_CPU));//test mit 4800
                _delay_ms(100);
                send_cmd(BT_TEST, NULL);
                send_cmd(BT_SET_ANSWER, NULL);
                send_cmd(BT_SET_ECHO, NULL);
                if (send_cmd(BT_TEST, NULL));
                {
#ifdef DEBUG
                        debug_pgm(PSTR("4800 OK"));
#endif
                        if (send_cmd(BT_TEST, NULL))
                        {
#ifdef DEBUG
                                debug_pgm(PSTR("BT found 4800 Baud"));
#endif
                                BT_found = 4;
                        }
                }
        }

        if (BT_found > 0)
        {
                /* Set comm_mode to CMD */
                comm_mode = BT_CMD;
//              test();
//              if (BTIsSlave==false)
//                {
                    /* Set BTM Baudrate */
                    if (!(send_cmd(BT_SET_57600, NULL)))
                            init_error = true;
                    uart1_init(UART_BAUD_SELECT(57600, F_CPU));
                    _delay_ms(100);
    //          test();
                    /* Clear remote address */
                    if(!(send_cmd(BT_CLEAR_ADDRESS, NULL)))
                            init_error = true;
    //          test();
                    /* Set BTM to SLAVE */
                    if (!(send_cmd(BT_SET_SLAVE, NULL)))
                            init_error = true;
    //          test();
                    /* Set BTM PIN */
                    if(!(send_cmd(BT_SET_PIN, NULL)))
                            init_error = true;
    //          test();
                    /* Set BTM Name */
                    if(!(send_cmd(BT_SET_NAME, NULL)))
                            init_error = true;
                    _delay_ms(300);
    //          test();
                    if(!(send_cmd(BT_SET_DISPWRDOWN, NULL)))
                            init_error = true;
//                }
//              test();
                /* Set BTM Echo aus */
                send_cmd(BT_SET_NOECHO, NULL);
//              test();
                comm_mode = BT_NOECHO;
                /* Set BTM Answer aus */
                send_cmd(BT_SET_NOANSWER, NULL);
//              test();

                bt_mode = BLUETOOTH_SLAVE;

                set_BTOff();


                if (!init_error)
                {
                        WriteBTInitFlag();  // Init merken
                        WriteBTSlaveFlag();
                        return true;
                }
                else
                        return false;
        }
        else
        {
                set_BTOff();
                return false;
        }

}


#ifndef SaveMem

//--------------------------------------------------------------
uint16_t bt_set_mode(const bt_mode_t mode)
{
//      if (update_comm_mode(0) == BT_DATA) // 30.1.2012 CB
//              return false;

        if (mode == bt_mode)
                return true;

        if (mode == BLUETOOTH_MASTER)
                if (send_cmd(BT_SET_MASTER, NULL))
                {
                        bt_mode = BLUETOOTH_MASTER;
//                      test();
                        send_cmd(BT_DISABLE_AUTOCONNECT, NULL);
                        debug_pgm(PSTR("bt_setmode: Master is set"));
                        WriteBTMasterFlag();


                }

        if (mode == BLUETOOTH_SLAVE)
          {
                if (send_cmd(BT_SET_SLAVE, NULL))
                {
                        bt_mode = BLUETOOTH_SLAVE;
                        debug_pgm(PSTR("bt_setmode: Slave is set"));
                }
                send_cmd(BT_SET_NOECHO, NULL);
                comm_mode = BT_NOECHO;
                /* Set BTM Answer aus */
                send_cmd(BT_SET_NOANSWER, NULL);

                bt_mode = BLUETOOTH_SLAVE;
                WriteBTSlaveFlag();
          }
//      test();
        return mode == bt_mode;
}


//--------------------------------------------------------------
uint16_t bt_receive(void *data, uint8_t length, uint16_t timeout_ms)
{
        uint8_t rec_length = 0;
        uint8_t i = 0;

//      while_timeout(true, timeout_ms);
        for(uint16_t __timeout = 0; __timeout++ <= true && (timeout_ms); _delay_ms(true ? 1 : 0))
        {
                if (i == length)
                        return true;

                uart_receive();

                if (fifo_is_empty(&in_fifo))
                        continue;

                if (update_comm_mode(0) != BT_DATA)
                {
#ifdef DEBUG
                        debug_pgm(PSTR("not connected"));
#endif
                        return false;
                }
                // We have a connection
                if (timeout_ms == 0)
                        timeout_ms += 2000;

                if (fifo_is_empty(&in_fifo))
                        continue;

                // Find starting point of packet
                if (!rec_length)
                {
                        fifo_read(&in_fifo, (char *)&rec_length);

                        if (rec_length != length)
                        {
                                rec_length = 0;
                        }
                        else
                        {
                                // You've got mail!
                                timeout_ms += 2000;
                        }
                }
                else
                {
                        fifo_read(&in_fifo, (char *)data + i);
                        i++;
                }
        }
        return false;
}

#endif

#ifndef SaveMem


//--------------------------------------------------------------
uint16_t bt_send(void *data, const uint8_t length)
{
        if (update_comm_mode(0) == BT_CMD)
                return false;

        uart_send((const char *)&length, 1);
        uart_send((char *)data, length);
        return (update_comm_mode(0) == BT_DATA);
}


#ifdef SQUIRREL

//--------------------------------------------------------------
uint16_t bt_connect(const char *address)
{
  fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE);
  uart_receive();
  fifo_clear(&in_fifo);

        // Maybe we already disconnected???
        if (BT_DATA == update_comm_mode(0))
        {
#ifdef DEBUG
                debug_pgm(PSTR("We are still connected..."));
#endif
                return false;
        }
        test();


/*
        if (!send_cmd(BT_DISABLE_AUTOCONNECT, address))
                return false;
*/


        test();
#ifdef DEBUG
        debug_pgm (PSTR ("SET_ADD"));
#endif

        if (!send_cmd(BT_SET_ADDRESS, address))
                return false;

        test();
#ifdef DEBUG
        debug_pgm (PSTR ("CONNECT"));
#endif

        if (!send_cmd(BT_CONNECT, NULL))
                return false;
#ifdef DEBUG
        debug_pgm (PSTR ("WAIT FOR COMM"));
#endif
        return (BT_DATA == update_comm_mode(60000));
}


//--------------------------------------------------------------
uint16_t bt_disconnect(void)
{


        if (BT_CMD == update_comm_mode(0))
        {
                fifo_clear(&in_fifo);
                return true;
        }

        // Switch to online cmd mode
        for (uint8_t i = 0; i < 4; i++)
        {
                const char plus = '+';
                uart_send(&plus, 1);
                _delay_ms(1000);
        }

        comm_mode = BT_CMD;

        if (!send_cmd(BT_DISCONNECT, NULL))
                return false;

//      test();
        if (!send_cmd(BT_CLEAR_ADDRESS, NULL))
                return false;
//      test();

        if (BT_CMD == update_comm_mode(10000))
        {
                fifo_clear(&in_fifo);
                return true;
        }
#ifdef DEBUG
        debug_pgm(PSTR("Still in DATA??"));
#endif
        return false;

}

/*

BTM-222 Softwareversion 4.35
Inquiry Results:
           111111111222222222233333333334
01234567890123456789012345678901234567890

1  LE091452          0024-2C-BEB0CA
2  E71 c             0024-7C-3EC9B9

BTM-222 Softwareversion 6.26
Inquiry Results:
1  E71 c  0024-7C-3EC9B9 N.A.
2  LE091452  0024-2C-BEB0CA N.A.

*/



//--------------------------------------------------------------
void copy_mac(const char *src, char *dst)
{
        uint8_t off = 0;

        for (uint8_t i = 0; i < 40; i++)
        {
            if (src[i] == '-') if (src[i+3] == '-')// MAC Adresse suchen
                                {
                                  off = i-4;
                                  break;
                                }
        }

        for (uint8_t i = 0; i < 14; i++)
        {
                if (src[i + off] == '-')
                        off++;

                dst[i] = src[i + off];
        }
}
//--------------------------------------------------------------
void copy_DevName(const char *src, char *dst)
{
        uint8_t off = 0;


        for (uint8_t i = 0; i < 14; i++)
        {
            if (src[i] == ' ') if (src[i+1] == ' ') break; // nach zwei Leerzeichen ist der Name zuende
             dst[i] = src[i + off];
        }
}

//--------------------------------------------------------------
uint16_t bt_discover(char result[8][12])


{


//      if (!bt_set_mode(BLUETOOTH_MASTER))
//              return false;

        if (!send_cmd(BT_FIND_DEVICES, NULL))
                return false;

        char buffer[255];       //oversized, but who cares?
        char *bufferhead = buffer;
        uint16_t pos = 0;
        uint16_t Timeout = 28000;
        uint16_t pos1 = 0;
        uint16_t posC = 0;
#ifdef DEBUG
        debug_pgm(PSTR("discover2"));
#endif
        do
        {
                uart_receive();
                Timeout--;
                pos1++;
                posC++;
                _delay_ms(1);
                  write_ndigit_number_u(0,5,fifo_getcount(&in_fifo),5,0,0);
                if (posC ==1000)
                  {
                   lcd_printp_at (i++, 1, PSTR("."), 0);
                   posC = 0;

                  }


                if (fifo_is_full(&in_fifo)) break;
#ifdef DEBUG
                if (fifo_search(&in_fifo, PSTR("Found."))) debug_pgm(PSTR("Suchen ende1"));
#endif
        }

//      while (((Timeout > 0) ||(!fifo_strstr_pgm(&in_fifo, PSTR("Inquiry Results:\r\n")))) && (!fifo_strstr_pgm(&in_fifo, PSTR("Found"))));
        while ((Timeout > 0)||(!fifo_strstr_pgm(&in_fifo, PSTR("Inquiry Results:\r\n"))));
#ifdef DEBUG
        debug_pgm(PSTR("Suchen ende2"));


        if (Timeout == 0) debug_pgm(PSTR("Timeout"));

        if (fifo_is_full(&in_fifo)) debug_pgm(PSTR("Fifo Overrun, zuviele BT Devices"));
#endif
        while (!fifo_is_empty(&in_fifo))
        {
                // Get next line
                while (!fifo_cmp_pgm(&in_fifo, PSTR("\r\n")))
                {
                        fifo_read(&in_fifo, bufferhead);
                        bufferhead++;
                }
                // terminate string
                *bufferhead = 0;

                //reset bufferhead
                bufferhead = buffer;

                if (strlen(buffer) == 0)
                        continue;       //the empty line before end of inquiry

                if (strstr_P(buffer, PSTR("Inquiry End")))
//              if (searchend)
                {
                        fifo_clear(&in_fifo);
//                      test();
                        return true;
                }


                        copy_DevName(&buffer[3],device_list[pos].DevName);
                        device_list[pos].DevName[14] = 0;   // Stringende

                        copy_mac(&buffer[3], device_list[pos].mac);

//                      for (uint16_t i = 0; i < 15; i++)
//                        {
//
////                        USART_putc((device_list[pos].DevName[i]));
//                          lcd_print_hex((device_list[pos].DevName[i]),0);
//                        }
//                      USART_putc('\n');
//
//
//                        for (uint16_t i = 0; i < 12; i++)
//                          {
//
//                            USART_putc((device_list[pos].mac[i]));
//
//                          }
//
//                        USART_putc('\n');
//                        USART_putc('\r');
                        pos++;
        }

        return false;
}

device_info device_list[NUTS_LIST];

void bt_downlink_init(void)
{


        fifo_init(&in_fifo, bt_buffer, IN_FIFO_SIZE);
        _delay_ms(100);
//      debug_pgm(PSTR("bt_init"));
        uart_receive();
        fifo_clear(&in_fifo);
//        send_cmd(BT_TEST, NULL);
        debug_pgm(PSTR("Downlink_init Start"));
//        if (BTIsSlave == true)          // nur Init wenn BT ist Slave
//          {
            comm_mode = BT_NOECHO;

            if (!send_cmd (BT_SET_ECHO,NULL)) {
                    debug_pgm(PSTR("Downlink_init:Couldn't set Echo!"));

            }

            comm_mode = BT_CMD;
            if (!send_cmd(BT_SET_ANSWER,NULL)) {
                    debug_pgm(PSTR("Downlink_init:Couldn't set Answer!"));

            }
    //       send_cmd(BT_TEST, NULL);

            if (!bt_set_mode(BLUETOOTH_MASTER)==BLUETOOTH_MASTER)

            {
//                    debug_pgm(PSTR("Downlink_init:Couldn't set master!"));
//                    return;
            }
    #ifdef DEBUG
            debug_pgm(PSTR("Downlink_init:master set is "));
    #endif

            WriteBTMasterFlag();  // Master merken

}


void bt_searchDevice(void)              //Bluetoothgeräte suchen

{

  char result[8][12];



  for (uint8_t i = 0; i < 8; i++)                 // alte Liste löschen
           for (uint8_t j = 0; j < 12; j++)
                   result[i][j] = 0;
#ifdef DEBUG
   debug_pgm(PSTR("Search Device:BT_discover"));
#endif
   if (bt_discover(result))
   {
           bt_devicecount = 0;
#ifdef DEBUG
           debug_pgm(PSTR("Search Device:Search ok"));
#endif
           for (uint8_t i = 0; i < 8; i++)
           {
                   if (valid(i))
                     bt_devicecount++;
                   else break;
           }
   }
#ifdef DEBUG
   else

           debug_pgm(PSTR("Search Device:Search failed"));
#endif
//    }

}


//--------------------------------------------------------------
uint16_t bt_receiveNMEA(void)
{

        char received;
        static uint8_t line_flag = 1;
        static char* ptr_write = rx_buffer;

        uart_receive();

        if (fifo_is_empty(&in_fifo))
//                        continue;
//                      break;
          return true;



            if (update_comm_mode(0) != BT_DATA)
                {
#ifdef DEBUG
                        debug_pgm(PSTR("not connected"));
#endif
                        return false;
                }

                // We have a connection
//                if (timeout_ms == 0)
//                        timeout_ms += 2000;

                if (fifo_is_empty(&in_fifo))
//                        continue;
//                    break;
                    return true;

                fifo_read(&in_fifo, &received);
                // Find starting point of packet
                if (rx_ready == 0)
                  {
                    if ((received == start) && line_flag)
                      { // start '$'
                        line_flag = 0;                          // New line has begun
                        ptr_write = rx_buffer;                  // Begin at start of buffer
                        rx_len = 0;
                      }
                    if (line_flag == 0)
                      {                                         // Are we receiving a line?
                            *ptr_write = received;              // Add current byte
                            rx_len++;

                            // GPS Datensatzende

                                   if (received == end)
                                     {  // End of MK-GPS or NMEA-line?
                                       line_flag = 1;            // Yes, start new line
                                       rx_ready = 1;             // Lock buffer until line has been processed
                                     }


                            }

                            ptr_write++;
                                        if(rx_len == RXD_BUFFER_SIZE) line_flag = 1; // Line too long? Try again
                  }//if (rx_ready == 0)
                return true;
                }
//
//        return false;
//}

//#endif




#endif
#endif
#endif