Statistics
| Branch: | Tag: | Revision:

amiro-blt / Host / Source / SerialBoot / port / win32 / xcptransport.c @ 69661903

History | View | Annotate | Download (10.574 KB)

1 69661903 Thomas Schöpping
/************************************************************************************//**
2
* \file         port\win32\xcptransport.c
3
* \brief        XCP transport layer interface source file.
4
* \ingroup      SerialBoot
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2014  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 <assert.h>                                   /* assertion module              */
38
#include <sb_types.h>                                 /* C types                       */
39
#include <windows.h>                                  /* for WIN32 library             */
40
#include <string.h>                                   /* string library                */
41
#include "xcpmaster.h"                                /* XCP master protocol module    */
42
#include "timeutil.h"                                 /* time utility module           */
43
44
45
/****************************************************************************************
46
* Macro definitions
47
****************************************************************************************/
48
#define UART_TX_BUFFER_SIZE      (1024)               /**< transmission buffer size    */
49
#define UART_RX_BUFFER_SIZE      (1024)               /**< reception buffer size       */
50
51
/** \brief maximum number of bytes in a transmit/receive XCP packet in UART. */
52
#define XCP_MASTER_UART_MAX_DATA ((XCP_MASTER_TX_MAX_DATA>XCP_MASTER_RX_MAX_DATA) ? \
53
                                   (XCP_MASTER_TX_MAX_DATA+1) : (XCP_MASTER_RX_MAX_DATA+1))
54
55
/** \brief The smallest time in millisecond that the UART is configured for. */
56
#define UART_RX_TIMEOUT_MIN_MS   (5)
57
58
59
/****************************************************************************************
60
* Local data declarations
61
****************************************************************************************/
62
static tXcpTransportResponsePacket responsePacket;
63
static HANDLE hUart = INVALID_HANDLE_VALUE;
64
65
66
/************************************************************************************//**
67
** \brief     Initializes the communication interface used by this transport layer.
68
** \param     device Serial communication device name. For example "COM4".
69
** \param     baudrate Communication speed in bits/sec.
70
** \return    SB_TRUE if successful, SB_FALSE otherwise.
71
**
72
****************************************************************************************/
73
sb_uint8 XcpTransportInit(sb_char *device, sb_uint32 baudrate, sb_uint8 comIsUart)
74
{
75
  COMMTIMEOUTS timeouts = { 0 };
76
  DCB dcbSerialParams = { 0 };
77
  char portStr[64] = "\\\\.\\\0"; 
78
79
  if (hUart != INVALID_HANDLE_VALUE) {
80
    return SB_TRUE;
81
  }
82
83
  /* construct the COM port name as a string */
84
  strncat(portStr, device, 59);
85
86
  /* obtain access to the COM port */
87
  hUart = CreateFile(portStr, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 
88
                       FILE_ATTRIBUTE_NORMAL, 0);
89
90
  /* validate COM port handle */
91
  if (hUart == INVALID_HANDLE_VALUE)
92
  {
93
    return SB_FALSE;
94
  }
95
96
  /* get current COM port configuration */
97
  dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
98
  if (!GetCommState(hUart, &dcbSerialParams))
99
  {
100
    XcpTransportClose();
101
    return SB_FALSE;
102
  }
103
104
  /* configure the baudrate and 8,n,1 */
105
  dcbSerialParams.BaudRate = baudrate;
106
  dcbSerialParams.ByteSize = 8;
107
  dcbSerialParams.StopBits = ONESTOPBIT;
108
  dcbSerialParams.Parity = NOPARITY;
109
  if (!SetCommState(hUart, &dcbSerialParams))
110
  {
111
    XcpTransportClose();
112
    return SB_FALSE;
113
  }
114
115
  /* set communication timeout parameters */
116
  timeouts.ReadIntervalTimeout = UART_RX_TIMEOUT_MIN_MS;
117
  timeouts.ReadTotalTimeoutConstant = UART_RX_TIMEOUT_MIN_MS;
118
  timeouts.ReadTotalTimeoutMultiplier = 1;
119
  timeouts.WriteTotalTimeoutConstant = UART_RX_TIMEOUT_MIN_MS;
120
  timeouts.WriteTotalTimeoutMultiplier = 1;
121
  if (!SetCommTimeouts(hUart, &timeouts))
122
  {
123
    XcpTransportClose();
124
    return SB_FALSE;
125
  }
126
127
  if (!EscapeCommFunction(hUart,SETDTR))
128
  {
129
    XcpTransportClose();
130
    return SB_FALSE;
131
  }
132
/*  if (!EscapeCommFunction(hUart,CLRDTR))
133
  {
134
    XcpTransportClose();
135
    return SB_FALSE;
136
  }*/
137
  if (!EscapeCommFunction(hUart,SETRTS))
138
  {
139
    XcpTransportClose();
140
    return SB_FALSE;
141
  }
142
  if (!EscapeCommFunction(hUart,CLRRTS))
143
  {
144
    XcpTransportClose();
145
    return SB_FALSE;
146
  }
147
148
  /* set transmit and receive buffer sizes */
149
  if(!SetupComm(hUart, UART_RX_BUFFER_SIZE, UART_TX_BUFFER_SIZE))
150
  {
151
    XcpTransportClose();
152
    return SB_FALSE;
153
  }
154
155
  /* empty the transmit and receive buffers */
156
  if (!FlushFileBuffers(hUart))
157
  {
158
    XcpTransportClose();
159
    return SB_FALSE;
160
  }
161
  /* successfully connected to the serial device */
162
  return SB_TRUE;
163
} /*** end of XcpTransportInit ***/
164
165
166
/************************************************************************************//**
167
** \brief     Transmits an XCP packet on the transport layer and attemps to receive the
168
**            response within the given timeout. The data in the response packet is 
169
**            stored in an internal data buffer that can be obtained through function
170
**            XcpTransportReadResponsePacket().
171
** \return    SB_TRUE is the response packet was successfully received and stored, 
172
**            SB_FALSE otherwise.
173
**
174
****************************************************************************************/
175
sb_uint8 XcpTransportSendPacket(sb_uint8 *data, sb_uint8 len, sb_uint16 timeOutMs)
176
{
177
  DWORD dwWritten = 0;
178
  DWORD dwRead = 0;
179
  sb_uint32 dwToRead;
180
  sb_uint16 cnt;
181
  static sb_uint8 xcpUartBuffer[XCP_MASTER_UART_MAX_DATA]; /* static to lower stack load */
182
  sb_uint16 xcpUartLen;
183
  sb_uint8 *uartReadDataPtr;
184
  sb_uint32 timeoutTime;
185
186
  /* ------------------------ XCP packet transmission -------------------------------- */
187
  /* prepare the XCP packet for transmission on UART. this is basically the same as the
188
   * xcp packet data but just the length of the packet is added to the first byte. 
189
   */
190
  xcpUartLen = len+1;
191
  xcpUartBuffer[0] = len;
192
  for (cnt=0; cnt<len; cnt++)
193
  {
194
    xcpUartBuffer[cnt+1] = data[cnt];
195
  }
196
197
  /* first submit the XCP packet for transmission */
198
  if (!WriteFile(hUart, xcpUartBuffer, xcpUartLen, &dwWritten, SB_NULL)) 
199
  {
200
    return SB_FALSE;
201
  }
202
  /* double check that all bytes were actually transmitted */
203
  if (dwWritten != xcpUartLen)
204
  {
205
    return SB_FALSE;
206
  }
207
208
  /* ------------------------ XCP packet reception ----------------------------------- */
209
  /* determine timeout time */
210
  timeoutTime = TimeUtilGetSystemTimeMs() + timeOutMs + UART_RX_TIMEOUT_MIN_MS;
211
212
  /* read the first byte, which contains the length of the xcp packet that follows */
213
  dwToRead = 1;
214
  uartReadDataPtr = &responsePacket.len;
215
  while(dwToRead > 0)
216
  {
217
    dwRead = 0;
218
    if (ReadFile(hUart, uartReadDataPtr, dwToRead, &dwRead, NULL))
219
    {
220
      /* update the bytes that were already read */
221
      uartReadDataPtr += dwRead;
222
      dwToRead -= dwRead;
223
    }
224
    /* check for timeout if not yet done */
225
    if ( (dwToRead > 0) && (TimeUtilGetSystemTimeMs() >= timeoutTime) )
226
    {
227
      /* timeout occurred */
228
      return SB_FALSE;
229
    }
230
  }
231
232
  /* read the rest of the packet */
233
  dwToRead = responsePacket.len;
234
  uartReadDataPtr = &responsePacket.data[0];
235
  while(dwToRead > 0)
236
  {
237
    dwRead = 0;
238
    if (ReadFile(hUart, uartReadDataPtr, dwToRead, &dwRead, NULL))
239
    {
240
      /* update the bytes that were already read */
241
      uartReadDataPtr += dwRead;
242
      dwToRead -= dwRead;
243
    }
244
    /* check for timeout if not yet done */
245
    if ( (dwToRead > 0) && (TimeUtilGetSystemTimeMs() >= timeoutTime) )
246
    {
247
      /* timeout occurred */
248
      return SB_FALSE;
249
    }
250
  }
251
  /* still here so the complete packet was received */
252
  return SB_TRUE;
253
} /*** end of XcpMasterTpSendPacket ***/
254
255
256
/************************************************************************************//**
257
** \brief     Reads the data from the response packet. Make sure to not call this 
258
**            function while XcpTransportSendPacket() is active, because the data won't be
259
**            valid then.
260
** \return    Pointer to the response packet data.
261
**
262
****************************************************************************************/
263
tXcpTransportResponsePacket *XcpTransportReadResponsePacket(void)
264
{
265
  return &responsePacket;
266
} /*** end of XcpTransportReadResponsePacket ***/
267
268
269
/************************************************************************************//**
270
** \brief     Closes the communication channel.
271
** \return    none.
272
**
273
****************************************************************************************/
274
void XcpTransportClose(void)
275
{
276
  /* close the COM port handle if valid */
277
  if (hUart != INVALID_HANDLE_VALUE)
278
  {
279
    CloseHandle(hUart);
280
  }
281
282
  /* set handles to invalid */
283
  hUart = INVALID_HANDLE_VALUE;
284
} /*** end of XcpTransportClose ***/
285
286
287
/*********************************** end of xcptransport.c *****************************/