Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / ARMCM4_STM32 / bluetoothUart.c @ fb5a5c5b

History | View | Annotate | Download (15.906 KB)

1 69661903 Thomas Schöpping
/************************************************************************************//**
2
* \file         Source\ARMCM4_STM32\bluetoothUart.c
3
* \brief        Bootloader BLUETOOTH UART communication interface source file.
4
* \ingroup      Target_ARMCM4_STM32
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2013  by Feaser    http://www.feaser.com    All rights reserved
10
*
11
*----------------------------------------------------------------------------------------
12
*                            L I C E N S E
13
*----------------------------------------------------------------------------------------
14
* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License as published by the Free
16
* Software Foundation, either version 3 of the License, or (at your option) any later
17
* version.
18
*
19
* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
20
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21
* PURPOSE. See the GNU General Public License for more details.
22
*
23
* You should have received a copy of the GNU General Public License along with OpenBLT.
24
* If not, see <http://www.gnu.org/licenses/>.
25
*
26
* A special exception to the GPL is included to allow you to distribute a combined work 
27
* that includes OpenBLT without being obliged to provide the source code for any 
28
* proprietary components. The exception text is included at the bottom of the license
29
* file <license.html>.
30
* 
31
* \endinternal
32
****************************************************************************************/
33
34
/****************************************************************************************
35
* Include files
36
****************************************************************************************/
37
#include "boot.h"                                /* bootloader generic header          */
38
#include "stm32f4xx.h"                           /* STM32 registers                    */
39
#include "stm32f4xx_conf.h"                      /* STM32 peripheral drivers           */
40
41
42
#if (BOOT_COM_BLUETOOTH_UART_ENABLE > 0)
43
/****************************************************************************************
44
* Macro definitions
45
****************************************************************************************/
46
/* map the configured BLUETOOTH UART channel index to the STM32's BLUETOOTH USART peripheral */
47
#if (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 0)
48
/** \brief Set BLUETOOTH UART base address to USART1. */
49
#define BLUETOOTH_USART_CHANNEL   USART1
50
#elif (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 1)
51
/** \brief Set BLUETOOTH UART base address to USART2. */
52
#define BLUETOOTH_USART_CHANNEL   USART2
53
#elif (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 2)
54
/** \brief Set BLUETOOTH UART base address to USART3. */
55
#define BLUETOOTH_USART_CHANNEL   USART3
56
#elif (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 3)
57
/** \brief Set BLUETOOTH UART base address to USART4. */
58
#define BLUETOOTH_USART_CHANNEL   USART4
59
#elif (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 4)
60
/** \brief Set BLUETOOTH UART base address to USART5. */
61
#define BLUETOOTH_USART_CHANNEL   USART5
62
#elif (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 5)
63
/** \brief Set BLUETOOTH UART base address to USART6. */
64
#define BLUETOOTH_USART_CHANNEL   USART6
65
#endif
66
67
/* Commands of bluetooth communication */
68
/** \brief Define bluetooth start of frame */
69
#define BLUETOOTH_START_FRAME   0xBF
70
/** \brief Define bluetooth link address to iWRAP control */
71
#define BLUETOOTH_LINK          0x00
72
/** \brief Define bluetooth frame flags */
73
#define BLUETOOTH_FLAGS         0x00
74
/** \brief Define nLINK = {LINK} XOR 0xFF */
75
#define BLUETOOTH_NLINK         0xFF
76
77
/* States of bluetooth communication */
78
/** \brief bluetooth waiting for start frame signal */
79
#define BLUETOOTH_STATUS_START    0
80
/** \brief bluetooth waiting for link address */
81
#define BLUETOOTH_STATUS_LINK     1
82
/** \brief bluetooth waiting for frame flags */
83
#define BLUETOOTH_STATUS_FLAGS    2
84
/** \brief bluetooth waiting for data length */
85
#define BLUETOOTH_STATUS_LENGTH   3
86
/** \brief bluetooth waiting for data */
87
#define BLUETOOTH_STATUS_DATA     4
88
/** \brief bluetooth waiting for frame end (nLINK) */
89
#define BLUETOOTH_STATUS_END      5
90
static blt_int8u bluetoothStatus = BLUETOOTH_STATUS_START;
91
92
93
/****************************************************************************************
94
* Function prototypes
95
****************************************************************************************/
96
static blt_bool BluetoothUartReceiveByte(blt_int8u *data);
97
static blt_bool BluetoothUartTransmitByte(blt_int8u data);
98
99
100
/************************************************************************************//**
101
** \brief     Initializes the BLUETOOTH UART communication interface.
102
** \return    none.
103
**
104
****************************************************************************************/
105
void BluetoothUartInit(void)
106
{
107
  USART_InitTypeDef USART_InitStructure;
108
109
  /* the current implementation supports USART1 - USART6. throw an assertion error in 
110
   * case a different BLUETOOTH UART channel is configured.  
111
   */
112
  ASSERT_CT((BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 0) ||
113
            (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 1) ||
114
            (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 2) ||
115
            (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 3) ||
116
            (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 4) ||
117
            (BOOT_COM_BLUETOOTH_UART_CHANNEL_INDEX == 5)); 
118
  /* initialize the BLUETOOTH UART for the specified communication speed */
119
  USART_InitStructure.USART_BaudRate = BOOT_COM_UART_BAUDRATE;
120
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
121
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
122
  USART_InitStructure.USART_Parity = USART_Parity_No;
123
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
124
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
125
  USART_Init(BLUETOOTH_USART_CHANNEL, &USART_InitStructure);
126
  /* enable BLUETOOTH UART */
127
  USART_Cmd(BLUETOOTH_USART_CHANNEL, ENABLE);
128
129
  blt_int32u counter = 0;
130
  while (counter < 20000000) {
131
    counter++;
132
  }
133
134
/*  BluetoothUartTransmitByte(BLUETOOTH_START_FRAME);
135
  BluetoothUartTransmitByte(0xFF);
136
  BluetoothUartTransmitByte(BLUETOOTH_FLAGS);
137
  BluetoothUartTransmitByte(18);
138
  BluetoothUartTransmitByte('S');
139
  BluetoothUartTransmitByte('E');
140
  BluetoothUartTransmitByte('T');
141
  BluetoothUartTransmitByte(' ');
142
  BluetoothUartTransmitByte('P');
143
  BluetoothUartTransmitByte('R');
144
  BluetoothUartTransmitByte('O');
145
  BluetoothUartTransmitByte('F');
146
  BluetoothUartTransmitByte('I');
147
  BluetoothUartTransmitByte('L');
148
  BluetoothUartTransmitByte('E');
149
  BluetoothUartTransmitByte(' ');
150
  BluetoothUartTransmitByte('S');
151
  BluetoothUartTransmitByte('P');
152
  BluetoothUartTransmitByte('P');
153
  BluetoothUartTransmitByte(' ');
154
  BluetoothUartTransmitByte('O');
155
  BluetoothUartTransmitByte('N');
156
  BluetoothUartTransmitByte(0x00);*/
157
158
  BluetoothUartTransmitByte(BLUETOOTH_START_FRAME);
159
  BluetoothUartTransmitByte(0xFF);
160
  BluetoothUartTransmitByte(BLUETOOTH_FLAGS);
161
  BluetoothUartTransmitByte(22);
162
  BluetoothUartTransmitByte('S');
163
  BluetoothUartTransmitByte('E');
164
  BluetoothUartTransmitByte('T');
165
  BluetoothUartTransmitByte(' ');
166
  BluetoothUartTransmitByte('B');
167
  BluetoothUartTransmitByte('T');
168
  BluetoothUartTransmitByte(' ');
169
  BluetoothUartTransmitByte('S');
170
  BluetoothUartTransmitByte('N');
171
  BluetoothUartTransmitByte('I');
172
  BluetoothUartTransmitByte('F');
173
  BluetoothUartTransmitByte('F');
174
  BluetoothUartTransmitByte(' ');
175
  BluetoothUartTransmitByte('4');
176
  BluetoothUartTransmitByte(' ');
177
  BluetoothUartTransmitByte('2');
178
  BluetoothUartTransmitByte(' ');
179
  BluetoothUartTransmitByte('1');
180
  BluetoothUartTransmitByte(' ');
181
  BluetoothUartTransmitByte('8');
182
  BluetoothUartTransmitByte('\r');
183
  BluetoothUartTransmitByte('\n');
184
  BluetoothUartTransmitByte(0x00);
185
186
  BluetoothUartTransmitByte(BLUETOOTH_START_FRAME);
187
  BluetoothUartTransmitByte(0xFF);
188
  BluetoothUartTransmitByte(BLUETOOTH_FLAGS);
189
  BluetoothUartTransmitByte(5);
190
  BluetoothUartTransmitByte('R');
191
  BluetoothUartTransmitByte('E');
192
  BluetoothUartTransmitByte('S');
193
  BluetoothUartTransmitByte('E');
194
  BluetoothUartTransmitByte('T');
195
  BluetoothUartTransmitByte(0x00);
196
} /*** end of BluetoothUartInit ***/
197
198
199
/************************************************************************************//**
200
** \brief     Transmits a packet formatted for the communication interface.
201
** \param     data Pointer to byte array with data that it to be transmitted.
202
** \param     len  Number of bytes that are to be transmitted.
203
** \return    none.
204
**
205
****************************************************************************************/
206
void BluetoothUartTransmitPacket(blt_int8u *data, blt_int8u len)
207
{
208
  blt_int16u data_index;
209
  blt_bool result; 
210
211
  /* verify validity of the len-paramenter */
212
  ASSERT_RT(len <= BOOT_COM_UART_TX_MAX_DATA);
213
  
214
  /* Send bluetooth header first */
215
  result = BluetoothUartTransmitByte(BLUETOOTH_START_FRAME);
216
  ASSERT_RT(result == BLT_TRUE);
217
  result = BluetoothUartTransmitByte(BLUETOOTH_LINK);
218
  ASSERT_RT(result == BLT_TRUE);
219
  result = BluetoothUartTransmitByte(BLUETOOTH_FLAGS);
220
  ASSERT_RT(result == BLT_TRUE);
221
  result = BluetoothUartTransmitByte(len+1);
222
  ASSERT_RT(result == BLT_TRUE);
223
  /* end of bluetooth header */
224
225
  /* first transmit the length of the packet */ 
226
  result = BluetoothUartTransmitByte(len);
227
  ASSERT_RT(result == BLT_TRUE);
228
229
  /* transmit all the packet bytes one-by-one */
230
  for (data_index = 0; data_index < len; data_index++)
231
  {
232
    /* keep the watchdog happy */
233
    CopService();
234
    /* write byte */
235
    result = BluetoothUartTransmitByte(data[data_index]);
236
    ASSERT_RT(result == BLT_TRUE);  
237
  }
238
239
  /* Send bluetooth closer */
240
  result = BluetoothUartTransmitByte(BLUETOOTH_NLINK);
241
  ASSERT_RT(result == BLT_TRUE);
242
  /* end of bluetooth closer */
243
244
} /*** end of BluetoothUartTransmitPacket ***/
245
246
247
/************************************************************************************//**
248
** \brief     Receives a communication interface packet if one is present.
249
** \param     data Pointer to byte array where the data is to be stored.
250
** \return    BLT_TRUE if a packet was received, BLT_FALSE otherwise.
251
**
252
****************************************************************************************/
253
blt_int8u BluetoothUartReceivePacket(blt_int8u *data)
254
{
255
  static blt_int8u xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA+1];  /* one extra for length */
256
  static blt_int8u bluetoothDataLength;
257
  static blt_int8u xcpUartDataLength;
258
  static blt_int8u xcpCtoRxLength;
259
  static blt_int8u bluetoothLinkID;
260
  static blt_int8u byteData;
261
  static blt_bool  xcpCtoRxInProgress = BLT_FALSE;
262
263
  /* store the message length when received */
264
    if (BluetoothUartReceiveByte(&byteData) == BLT_TRUE)
265
    {
266
 
267
      /* Check bluetooth status */
268
      switch (bluetoothStatus) {
269
270
        case BLUETOOTH_STATUS_START:
271
          if (byteData == BLUETOOTH_START_FRAME) {
272
            bluetoothStatus++;
273
          }
274
          break;
275
276
        case BLUETOOTH_STATUS_LINK:
277
          //if (xcpCtoReqPacket[0] == BLUETOOTH_LINK) {
278
            bluetoothLinkID = byteData;
279
            bluetoothStatus++;
280
          //} else {
281
          //  bluetoothStatus = BLUETOOTH_STATUS_START;
282
          //}
283
          break;
284
285
        case BLUETOOTH_STATUS_FLAGS:
286
          if (byteData == BLUETOOTH_FLAGS) {
287
            bluetoothStatus++;
288
          } else {
289
            bluetoothStatus = BLUETOOTH_STATUS_START;
290
          }
291
          break;
292
293
        case BLUETOOTH_STATUS_LENGTH:
294
          bluetoothStatus++;
295
          bluetoothDataLength = byteData;
296
          break;
297
298
        case BLUETOOTH_STATUS_DATA:
299
          if (--bluetoothDataLength == 0) {
300
            bluetoothStatus++;
301
          }
302
          if (bluetoothLinkID == 0xFF) {
303
          } else {
304
            /* start of cto packet received? */
305
            if (xcpCtoRxInProgress == BLT_FALSE)
306
            {
307
              xcpCtoReqPacket[0] = byteData;
308
              /* save message length */
309
              xcpUartDataLength = xcpCtoReqPacket[0];
310
              if (xcpCtoReqPacket[0] > 0)
311
              {
312
                /* indicate that a cto packet is being received */
313
                xcpCtoRxInProgress = BLT_TRUE;
314
                /* reset packet data count */
315
                xcpCtoRxLength = 0;
316
              }
317
            }
318
            else
319
            {
320
              /* store the next packet byte */
321
              /* increment the packet data count */
322
              xcpCtoReqPacket[++xcpCtoRxLength] = byteData;
323
 
324
              /* check to see if the entire packet was received */
325
              if (xcpCtoRxLength == xcpCtoReqPacket[0])
326
              {
327
                /* copy the packet data */
328
                CpuMemCopy((blt_int32u)data, (blt_int32u)&xcpCtoReqPacket[1], xcpCtoRxLength);        
329
                /* done with cto packet reception */
330
                xcpCtoRxInProgress = BLT_FALSE;
331
332
                /* packet reception complete */
333
                return xcpUartDataLength;
334
              }
335
            }
336
          }
337
          break;
338
339
        default:
340
          bluetoothStatus = BLUETOOTH_STATUS_START;
341
          if (byteData == ~bluetoothLinkID) {
342
                /* copy the packet data */
343
                //CpuMemCopy((blt_int32u)data, (blt_int32u)&xcpCtoReqPacket[1], xcpCtoRxLength);
344
                //return xcpCtoRxLength;
345
          }
346
          break;
347
      }
348
    }
349
  /* packet reception not yet complete */
350
  return 0;
351
} /*** end of BluetoothUartReceivePacket ***/
352
353
354
/************************************************************************************//**
355
** \brief     Receives a communication interface byte if one is present.
356
** \param     data Pointer to byte where the data is to be stored.
357
** \return    BLT_TRUE if a byte was received, BLT_FALSE otherwise.
358
**
359
****************************************************************************************/
360
static blt_bool BluetoothUartReceiveByte(blt_int8u *data)
361
{
362
  /* check flag to see if a byte was received */
363
  if (USART_GetFlagStatus(BLUETOOTH_USART_CHANNEL, USART_FLAG_RXNE) == SET)
364
  {
365
    /* retrieve and store the newly received byte */
366
    *data = (unsigned char)USART_ReceiveData(BLUETOOTH_USART_CHANNEL);
367
    //UartTransmitPacket(data, 1);
368
    //UartTransmitPacket("\n", 1);
369
    /* all done */
370
    return BLT_TRUE;
371
  }
372
  /* still here to no new byte received */
373
  return BLT_FALSE;
374
} /*** end of BluetoothUartReceiveByte ***/
375
376
377
/************************************************************************************//**
378
** \brief     Transmits a communication interface byte.
379
** \param     data Value of byte that is to be transmitted.
380
** \return    BLT_TRUE if the byte was transmitted, BLT_FALSE otherwise.
381
**
382
****************************************************************************************/
383
static blt_bool BluetoothUartTransmitByte(blt_int8u data)
384
{
385
  /* check if tx holding register can accept new data */
386
  if (USART_GetFlagStatus(BLUETOOTH_USART_CHANNEL, USART_FLAG_TXE) == RESET)
387
  {
388
    /* BLUETOOTH UART not ready. should not happen */
389
    return BLT_FALSE;
390
  }
391
  /* write byte to transmit holding register */
392
  USART_SendData(BLUETOOTH_USART_CHANNEL, data);
393
  /* wait for tx holding register to be empty */
394
  while (USART_GetFlagStatus(BLUETOOTH_USART_CHANNEL, USART_FLAG_TXE) == RESET) 
395
  { 
396
    ;
397
  }
398
  /* byte transmitted */
399
  return BLT_TRUE;
400
} /*** end of BluetoothUartTransmitByte ***/
401
#endif /* BOOT_COM_BLUETOOTH_UART_ENABLE > 0 */
402
403
404
/*********************************** end of bluetoothUart.c *************************************/