Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / ARMCM4_STM32 / uart.c @ 68bf1211

History | View | Annotate | Download (9.838 KB)

1 69661903 Thomas Schöpping
/************************************************************************************//**
2
* \file         Source\ARMCM4_STM32\uart.c
3
* \brief        Bootloader 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_UART_ENABLE > 0 || BOOT_GATE_UART_ENABLE > 0)
43
/****************************************************************************************
44
* Macro definitions
45
****************************************************************************************/
46
/* map the configured UART channel index to the STM32's USART peripheral */
47
#if (BOOT_COM_UART_CHANNEL_INDEX == 0)
48
/** \brief Set UART base address to USART1. */
49
#define USART_CHANNEL   USART1
50
#elif (BOOT_COM_UART_CHANNEL_INDEX == 1)
51
/** \brief Set UART base address to USART2. */
52
#define USART_CHANNEL   USART2
53
#elif (BOOT_COM_UART_CHANNEL_INDEX == 2)
54
/** \brief Set UART base address to USART3. */
55
#define USART_CHANNEL   USART3
56
#elif (BOOT_COM_UART_CHANNEL_INDEX == 3)
57
/** \brief Set UART base address to USART4. */
58
#define USART_CHANNEL   USART4
59
#elif (BOOT_COM_UART_CHANNEL_INDEX == 4)
60
/** \brief Set UART base address to USART5. */
61
#define USART_CHANNEL   USART5
62
#elif (BOOT_COM_UART_CHANNEL_INDEX == 5)
63
/** \brief Set UART base address to USART6. */
64
#define USART_CHANNEL   USART6
65
#endif
66
67
68
/****************************************************************************************
69
* Function prototypes
70
****************************************************************************************/
71
static blt_bool UartReceiveByte(blt_int8u *data);
72
static blt_bool UartTransmitByte(blt_int8u data);
73
74
75
/************************************************************************************//**
76
** \brief     Initializes the UART communication interface.
77
** \return    none.
78
**
79
****************************************************************************************/
80
void UartInit(void)
81
{
82
  USART_InitTypeDef USART_InitStructure;
83
84
  /* the current implementation supports USART1 - USART6. throw an assertion error in 
85
   * case a different UART channel is configured.  
86
   */
87
  ASSERT_CT((BOOT_COM_UART_CHANNEL_INDEX == 0) ||
88
            (BOOT_COM_UART_CHANNEL_INDEX == 1) ||
89
            (BOOT_COM_UART_CHANNEL_INDEX == 2) ||
90
            (BOOT_COM_UART_CHANNEL_INDEX == 3) ||
91
            (BOOT_COM_UART_CHANNEL_INDEX == 4) ||
92
            (BOOT_COM_UART_CHANNEL_INDEX == 5)); 
93
  /* initialize the uart for the specified communication speed */
94
  USART_InitStructure.USART_BaudRate = BOOT_COM_UART_BAUDRATE;
95
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
96
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
97
  USART_InitStructure.USART_Parity = USART_Parity_No;
98
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
99
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
100
  USART_Init(USART_CHANNEL, &USART_InitStructure);
101
  /* enable UART */
102
  USART_Cmd(USART_CHANNEL, ENABLE);
103
} /*** end of UartInit ***/
104
105
106
/************************************************************************************//**
107
** \brief     Transmits a packet formatted for the communication interface.
108
** \param     data Pointer to byte array with data that it to be transmitted.
109
** \param     len  Number of bytes that are to be transmitted.
110
** \return    none.
111
**
112
****************************************************************************************/
113
void UartTransmitPacket(blt_int8u *data, blt_int8u len)
114
{
115
  blt_int16u data_index;
116
  blt_bool result; 
117
118
  /* verify validity of the len-paramenter */
119
  ASSERT_RT(len <= BOOT_COM_UART_TX_MAX_DATA);  
120
121
  /* first transmit the length of the packet */ 
122
  result = UartTransmitByte(len);
123
  ASSERT_RT(result == BLT_TRUE);  
124
  
125
  /* transmit all the packet bytes one-by-one */
126
  for (data_index = 0; data_index < len; data_index++)
127
  {
128
    /* keep the watchdog happy */
129
    CopService();
130
    /* write byte */
131
    result = UartTransmitByte(data[data_index]);
132
    ASSERT_RT(result == BLT_TRUE);  
133
  }
134
} /*** end of UartTransmitPacket ***/
135
136
137
/************************************************************************************//**
138
** \brief     Receives a communication interface packet if one is present.
139
** \param     data Pointer to byte array where the data is to be stored.
140
** \return    BLT_TRUE if a packet was received, BLT_FALSE otherwise.
141
**
142
****************************************************************************************/
143
blt_int8u UartReceivePacket(blt_int8u *data)
144
{
145
  static blt_int8u xcpCtoReqPacket[BOOT_COM_UART_RX_MAX_DATA+1];  /* one extra for length */
146
  static blt_int8u xcpCtoRxLength;
147
  static blt_int8u xcpUartDataLength;
148
  static blt_bool  xcpCtoRxInProgress = BLT_FALSE;
149
150
  /* start of cto packet received? */
151
  if (xcpCtoRxInProgress == BLT_FALSE)
152
  {
153
    /* store the message length when received */
154
    if (UartReceiveByte(&xcpCtoReqPacket[0]) == BLT_TRUE)
155
    {
156
      /* save message length */
157
      xcpUartDataLength = xcpCtoReqPacket[0];
158
      if (xcpCtoReqPacket[0] > 0)
159
      {
160
        /* indicate that a cto packet is being received */
161
        xcpCtoRxInProgress = BLT_TRUE;
162
        /* reset packet data count */
163
        xcpCtoRxLength = 0;
164
      }
165
    }
166
  }
167
  else
168
  {
169
    /* store the next packet byte */
170
    if (UartReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == BLT_TRUE)
171
    {
172
      /* increment the packet data count */
173
      xcpCtoRxLength++;
174
175
      /* check to see if the entire packet was received */
176
      if (xcpCtoRxLength == xcpCtoReqPacket[0])
177
      {
178
        /* copy the packet data */
179
        CpuMemCopy((blt_int32u)data, (blt_int32u)&xcpCtoReqPacket[1], xcpCtoRxLength);        
180
        /* done with cto packet reception */
181
        xcpCtoRxInProgress = BLT_FALSE;
182
183
        /* packet reception complete */
184
        return xcpUartDataLength;
185
      }
186
    }
187
  }
188
  /* packet reception not yet complete */
189
  return 0;
190
} /*** end of UartReceivePacket ***/
191
192
193
/************************************************************************************//**
194
** \brief     Receives a communication interface byte if one is present.
195
** \param     data Pointer to byte where the data is to be stored.
196
** \return    BLT_TRUE if a byte was received, BLT_FALSE otherwise.
197
**
198
****************************************************************************************/
199
static blt_bool UartReceiveByte(blt_int8u *data)
200
{
201
  /* check flag to see if a byte was received */
202
  if (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_RXNE) == SET)
203
  {
204
    /* retrieve and store the newly received byte */
205
    *data = (unsigned char)USART_ReceiveData(USART_CHANNEL);
206
    /* all done */
207
    return BLT_TRUE;
208
  }
209
  /* still here to no new byte received */
210
  return BLT_FALSE;
211
} /*** end of UartReceiveByte ***/
212
213
214
/************************************************************************************//**
215
** \brief     Transmits a communication interface byte.
216
** \param     data Value of byte that is to be transmitted.
217
** \return    BLT_TRUE if the byte was transmitted, BLT_FALSE otherwise.
218
**
219
****************************************************************************************/
220
static blt_bool UartTransmitByte(blt_int8u data)
221
{
222
  /* check if tx holding register can accept new data */
223
  if (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET)
224
  {
225
    /* UART not ready. should not happen */
226
    return BLT_FALSE;
227
  }
228
  /* write byte to transmit holding register */
229
  USART_SendData(USART_CHANNEL, data);
230
  /* wait for tx holding register to be empty */
231
  while (USART_GetFlagStatus(USART_CHANNEL, USART_FLAG_TXE) == RESET) 
232
  { 
233
    ;
234
  }
235
  /* byte transmitted */
236
  return BLT_TRUE;
237
} /*** end of UartTransmitByte ***/
238
#endif /* BOOT_COM_UART_ENABLE > 0 || BOOT_GATE_UART_ENABLE > 0 */
239
240
241
/*********************************** end of uart.c *************************************/