amiro-blt / Target / Source / ARMCM3_STM32 / usb.c @ d7238092
History | View | Annotate | Download (22.852 KB)
1 | 69661903 | Thomas Schöpping | /************************************************************************************//** |
---|---|---|---|
2 | * \file Source\ARMCM3_STM32\usb.c
|
||
3 | * \brief Bootloader USB communication interface source file.
|
||
4 | * \ingroup Target_ARMCM3_STM32
|
||
5 | * \internal
|
||
6 | *----------------------------------------------------------------------------------------
|
||
7 | * C O P Y R I G H T
|
||
8 | *----------------------------------------------------------------------------------------
|
||
9 | * Copyright (c) 2011 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 | #if (BOOT_COM_USB_ENABLE > 0 || BOOT_GATE_USB_ENABLE > 0) |
||
39 | #include "usb_lib.h" /* USB library driver header */ |
||
40 | #include "usb_desc.h" /* USB descriptor header */ |
||
41 | #include "usb_pwr.h" /* USB power management header */ |
||
42 | #include "usb_istr.h" /* USB interrupt routine header */ |
||
43 | |||
44 | |||
45 | /****************************************************************************************
|
||
46 | * Macro definitions
|
||
47 | ****************************************************************************************/
|
||
48 | /** \brief Total number of fifo buffers. */
|
||
49 | #define FIFO_MAX_BUFFERS (2) |
||
50 | /** \brief Invalid value for a fifo buffer handle. */
|
||
51 | #define FIFO_ERR_INVALID_HANDLE (255) |
||
52 | /** \brief Number of bytes that fit in the fifo pipe. */
|
||
53 | #define FIFO_PIPE_SIZE (64) |
||
54 | |||
55 | |||
56 | /****************************************************************************************
|
||
57 | * Type definitions
|
||
58 | ****************************************************************************************/
|
||
59 | /** \brief Structure type for fifo control. */
|
||
60 | typedef struct t_fifo_ctrl |
||
61 | { |
||
62 | blt_int8u *startptr; /**< pointer to start of buffer */
|
||
63 | blt_int8u *endptr; /**< pointer to end of buffer */
|
||
64 | blt_int8u *readptr; /**< pointer to next read location */
|
||
65 | blt_int8u *writeptr; /**< pointer to next free location */
|
||
66 | blt_int8u length; /**< number of buffer elements */
|
||
67 | blt_int8u entries; /**< # of full buffer elements */
|
||
68 | blt_int8u handle; /**< handle of the buffer */
|
||
69 | struct t_fifo_ctrl *fifoctrlptr; /**< pointer to free buffer control */ |
||
70 | } tFifoCtrl; |
||
71 | |||
72 | /** \brief Structure type for a fifo pipe. */
|
||
73 | typedef struct |
||
74 | { |
||
75 | blt_int8u handle; /**< fifo handle */
|
||
76 | blt_int8u data[FIFO_PIPE_SIZE]; /**< fifo data buffer */
|
||
77 | } tFifoPipe; /**< USB pipe fifo type */
|
||
78 | |||
79 | |||
80 | /****************************************************************************************
|
||
81 | * Hook functions
|
||
82 | ****************************************************************************************/
|
||
83 | extern void UsbEnterLowPowerModeHook(void); |
||
84 | extern void UsbLeaveLowPowerModeHook(void); |
||
85 | extern void UsbConnectHook(blt_bool connect); |
||
86 | |||
87 | |||
88 | /****************************************************************************************
|
||
89 | * Function prototypes
|
||
90 | ****************************************************************************************/
|
||
91 | static blt_bool UsbReceiveByte(blt_int8u *data);
|
||
92 | static blt_bool UsbTransmitByte(blt_int8u data);
|
||
93 | static void UsbFifoMgrInit(void); |
||
94 | static blt_int8u UsbFifoMgrCreate(blt_int8u *buffer, blt_int8u length);
|
||
95 | static blt_bool UsbFifoMgrWrite(blt_int8u handle, blt_int8u data);
|
||
96 | static blt_bool UsbFifoMgrRead(blt_int8u handle, blt_int8u *data);
|
||
97 | static blt_int8u UsbFifoMgrScan(blt_int8u handle);
|
||
98 | |||
99 | |||
100 | /****************************************************************************************
|
||
101 | * Local data declarations
|
||
102 | ****************************************************************************************/
|
||
103 | /** \brief Local variable that holds the fifo control structures. */
|
||
104 | static tFifoCtrl fifoCtrl[FIFO_MAX_BUFFERS];
|
||
105 | /** \brief Local pointer that points to the next free fifo control structure. */
|
||
106 | static tFifoCtrl *fifoCtrlFree;
|
||
107 | /** \brief Fifo pipe used for the bulk in endpoint. */
|
||
108 | static tFifoPipe fifoPipeBulkIN;
|
||
109 | /** \brief Fifo pipe used for the bulk out endpoint. */
|
||
110 | static tFifoPipe fifoPipeBulkOUT;
|
||
111 | |||
112 | |||
113 | /************************************************************************************//** |
||
114 | ** \brief Initializes the USB communication interface.
|
||
115 | ** \return none.
|
||
116 | **
|
||
117 | ****************************************************************************************/
|
||
118 | void UsbInit(void) |
||
119 | { |
||
120 | /* initialize the FIFO manager */
|
||
121 | UsbFifoMgrInit(); |
||
122 | /* place 2 buffers under FIFO management */
|
||
123 | fifoPipeBulkIN.handle = UsbFifoMgrCreate(fifoPipeBulkIN.data, FIFO_PIPE_SIZE); |
||
124 | fifoPipeBulkOUT.handle = UsbFifoMgrCreate(fifoPipeBulkOUT.data, FIFO_PIPE_SIZE); |
||
125 | /* validate fifo handles */
|
||
126 | ASSERT_RT( (fifoPipeBulkIN.handle != FIFO_ERR_INVALID_HANDLE) && \ |
||
127 | (fifoPipeBulkOUT.handle != FIFO_ERR_INVALID_HANDLE) ); |
||
128 | /* initialize the low level USB driver */
|
||
129 | USB_Init(); |
||
130 | } /*** end of UsbInit ***/
|
||
131 | |||
132 | |||
133 | /************************************************************************************//** |
||
134 | ** \brief Releases the USB communication interface.
|
||
135 | ** \return none.
|
||
136 | **
|
||
137 | ****************************************************************************************/
|
||
138 | void UsbFree(void) |
||
139 | { |
||
140 | /* disconnect the USB device from the USB host */
|
||
141 | UsbConnectHook(BLT_FALSE); |
||
142 | } /*** end of UsbFree ***/
|
||
143 | |||
144 | |||
145 | /************************************************************************************//** |
||
146 | ** \brief Transmits a packet formatted for the communication interface.
|
||
147 | ** \param data Pointer to byte array with data that it to be transmitted.
|
||
148 | ** \param len Number of bytes that are to be transmitted.
|
||
149 | ** \return none.
|
||
150 | **
|
||
151 | ****************************************************************************************/
|
||
152 | void UsbTransmitPacket(blt_int8u *data, blt_int8u len)
|
||
153 | { |
||
154 | blt_int16u data_index; |
||
155 | blt_bool result; |
||
156 | |||
157 | /* verify validity of the len-paramenter */
|
||
158 | ASSERT_RT(len <= BOOT_COM_USB_TX_MAX_DATA); |
||
159 | |||
160 | /* first transmit the length of the packet */
|
||
161 | result = UsbTransmitByte(len); |
||
162 | ASSERT_RT(result == BLT_TRUE); |
||
163 | |||
164 | /* transmit all the packet bytes one-by-one */
|
||
165 | for (data_index = 0; data_index < len; data_index++) |
||
166 | { |
||
167 | /* keep the watchdog happy */
|
||
168 | CopService(); |
||
169 | /* write byte */
|
||
170 | result = UsbTransmitByte(data[data_index]); |
||
171 | ASSERT_RT(result == BLT_TRUE); |
||
172 | } |
||
173 | } /*** end of UsbTransmitPacket ***/
|
||
174 | |||
175 | |||
176 | /************************************************************************************//** |
||
177 | ** \brief Receives a communication interface packet if one is present.
|
||
178 | ** \param data Pointer to byte array where the data is to be stored.
|
||
179 | ** \return Length of message (if the message is invalid, the length will be 0).
|
||
180 | **
|
||
181 | ****************************************************************************************/
|
||
182 | blt_int8u UsbReceivePacket(blt_int8u *data) |
||
183 | { |
||
184 | static blt_int8u xcpCtoReqPacket[BOOT_COM_USB_RX_MAX_DATA+1]; /* one extra for length */ |
||
185 | static blt_int8u xcpCtoRxLength;
|
||
186 | static blt_int8u xcpUsbDataLength;
|
||
187 | static blt_bool xcpCtoRxInProgress = BLT_FALSE;
|
||
188 | |||
189 | /* poll USB interrupt flags to process USB related events */
|
||
190 | USB_Istr(); |
||
191 | |||
192 | /* start of cto packet received? */
|
||
193 | if (xcpCtoRxInProgress == BLT_FALSE)
|
||
194 | { |
||
195 | /* store the message length when received */
|
||
196 | if (UsbReceiveByte(&xcpCtoReqPacket[0]) == BLT_TRUE) |
||
197 | { |
||
198 | /* save message length */
|
||
199 | xcpUsbDataLength = xcpCtoReqPacket[0];
|
||
200 | if (xcpCtoReqPacket[0] > 0) |
||
201 | { |
||
202 | /* indicate that a cto packet is being received */
|
||
203 | xcpCtoRxInProgress = BLT_TRUE; |
||
204 | /* reset packet data count */
|
||
205 | xcpCtoRxLength = 0;
|
||
206 | } |
||
207 | } |
||
208 | } |
||
209 | else
|
||
210 | { |
||
211 | /* store the next packet byte */
|
||
212 | if (UsbReceiveByte(&xcpCtoReqPacket[xcpCtoRxLength+1]) == BLT_TRUE) |
||
213 | { |
||
214 | /* increment the packet data count */
|
||
215 | xcpCtoRxLength++; |
||
216 | |||
217 | /* check to see if the entire packet was received */
|
||
218 | if (xcpCtoRxLength == xcpCtoReqPacket[0]) |
||
219 | { |
||
220 | /* copy the packet data */
|
||
221 | CpuMemCopy((blt_int32u)data, (blt_int32u)&xcpCtoReqPacket[1], xcpCtoRxLength);
|
||
222 | /* done with cto packet reception */
|
||
223 | xcpCtoRxInProgress = BLT_FALSE; |
||
224 | |||
225 | /* packet reception complete */
|
||
226 | // return BLT_TRUE;
|
||
227 | return xcpUsbDataLength;
|
||
228 | } |
||
229 | } |
||
230 | } |
||
231 | /* packet reception not yet complete */
|
||
232 | // return BLT_FALSE;
|
||
233 | return 0; |
||
234 | } /*** end of UsbReceivePacket ***/
|
||
235 | |||
236 | |||
237 | /************************************************************************************//** |
||
238 | ** \brief Receives a communication interface byte if one is present.
|
||
239 | ** \param data Pointer to byte where the data is to be stored.
|
||
240 | ** \return BLT_TRUE if a byte was received, BLT_FALSE otherwise.
|
||
241 | **
|
||
242 | ****************************************************************************************/
|
||
243 | static blt_bool UsbReceiveByte(blt_int8u *data)
|
||
244 | { |
||
245 | blt_bool result; |
||
246 | |||
247 | /* obtain data from the fifo */
|
||
248 | result = UsbFifoMgrRead(fifoPipeBulkOUT.handle, data); |
||
249 | return result;
|
||
250 | } /*** end of UsbReceiveByte ***/
|
||
251 | |||
252 | |||
253 | /************************************************************************************//** |
||
254 | ** \brief Transmits a communication interface byte.
|
||
255 | ** \param data Value of byte that is to be transmitted.
|
||
256 | ** \return BLT_TRUE if the byte was transmitted, BLT_FALSE otherwise.
|
||
257 | **
|
||
258 | ****************************************************************************************/
|
||
259 | static blt_bool UsbTransmitByte(blt_int8u data)
|
||
260 | { |
||
261 | blt_bool result; |
||
262 | |||
263 | /* write data from to fifo */
|
||
264 | result = UsbFifoMgrWrite(fifoPipeBulkIN.handle, data); |
||
265 | return result;
|
||
266 | } /*** end of UsbTransmitByte ***/
|
||
267 | |||
268 | |||
269 | /************************************************************************************//** |
||
270 | ** \brief Power-off system clocks and power while entering suspend mode.
|
||
271 | ** \return none.
|
||
272 | **
|
||
273 | ****************************************************************************************/
|
||
274 | void UsbEnterLowPowerMode(void) |
||
275 | { |
||
276 | /* Set the device state to suspend */
|
||
277 | bDeviceState = SUSPENDED; |
||
278 | /* power-off system clocks and power */
|
||
279 | UsbEnterLowPowerModeHook(); |
||
280 | } /*** end of UsbEnterLowPowerMode ***/
|
||
281 | |||
282 | |||
283 | /************************************************************************************//** |
||
284 | ** \brief Restores system clocks and power while exiting suspend mode.
|
||
285 | ** \return none.
|
||
286 | **
|
||
287 | ****************************************************************************************/
|
||
288 | void UsbLeaveLowPowerMode(void) |
||
289 | { |
||
290 | DEVICE_INFO *pInfo = &Device_Info; |
||
291 | |||
292 | /* restore power and system clocks */
|
||
293 | UsbLeaveLowPowerModeHook(); |
||
294 | /* Set the device state to the correct state */
|
||
295 | if (pInfo->Current_Configuration != 0) |
||
296 | { |
||
297 | /* Device configured */
|
||
298 | bDeviceState = CONFIGURED; |
||
299 | } |
||
300 | else
|
||
301 | { |
||
302 | bDeviceState = ATTACHED; |
||
303 | } |
||
304 | } /*** end of UsbLeaveLowPowerMode ***/
|
||
305 | |||
306 | |||
307 | /************************************************************************************//** |
||
308 | ** \brief Checks if there is still data left to transmit and if so submits it
|
||
309 | ** for transmission with the USB endpoint.
|
||
310 | ** \return none.
|
||
311 | **
|
||
312 | ****************************************************************************************/
|
||
313 | void UsbTransmitPipeBulkIN(void) |
||
314 | { |
||
315 | /* USB_Tx_Buffer is static for run-time optimalization */
|
||
316 | static uint8_t USB_Tx_Buffer[BULK_DATA_SIZE];
|
||
317 | blt_int8u nr_of_bytes_for_tx_endpoint; |
||
318 | blt_int8u byte_counter; |
||
319 | blt_int8u byte_value; |
||
320 | blt_bool result; |
||
321 | |||
322 | /* read how many bytes should be transmitted */
|
||
323 | nr_of_bytes_for_tx_endpoint = UsbFifoMgrScan(fifoPipeBulkIN.handle); |
||
324 | /* only continue if there is actually data left to transmit */
|
||
325 | if (nr_of_bytes_for_tx_endpoint == 0) |
||
326 | { |
||
327 | return;
|
||
328 | } |
||
329 | /* make sure to not transmit more than the USB endpoint can handle */
|
||
330 | if (nr_of_bytes_for_tx_endpoint > BULK_DATA_SIZE)
|
||
331 | { |
||
332 | nr_of_bytes_for_tx_endpoint = BULK_DATA_SIZE; |
||
333 | } |
||
334 | /* copy the transmit data to the transmit buffer */
|
||
335 | for (byte_counter=0; byte_counter < nr_of_bytes_for_tx_endpoint; byte_counter++) |
||
336 | { |
||
337 | /* obtain data from the fifo */
|
||
338 | result = UsbFifoMgrRead(fifoPipeBulkIN.handle, &byte_value); |
||
339 | ASSERT_RT(result == BLT_TRUE); |
||
340 | /* store it in the endpoint's RAM */
|
||
341 | USB_Tx_Buffer[byte_counter] = byte_value; |
||
342 | } |
||
343 | /* store it in the endpoint's RAM */
|
||
344 | UserToPMABufferCopy(&USB_Tx_Buffer[0], ENDP1_TXADDR, nr_of_bytes_for_tx_endpoint);
|
||
345 | /* set the number of bytes that need to be transmitted from this endpoint */
|
||
346 | SetEPTxCount(ENDP1, nr_of_bytes_for_tx_endpoint); |
||
347 | /* inform the endpoint that it can start its transmission because the data is valid */
|
||
348 | SetEPTxValid(ENDP1); |
||
349 | } /*** end of UsbTransmitPipeBulkIN ***/
|
||
350 | |||
351 | |||
352 | /************************************************************************************//** |
||
353 | ** \brief Stores data that was received on the Bulk OUT pipe in the fifo.
|
||
354 | ** \return none.
|
||
355 | **
|
||
356 | ****************************************************************************************/
|
||
357 | void UsbReceivePipeBulkOUT(void) |
||
358 | { |
||
359 | /* USB_Rx_Buffer is static for run-time optimalization */
|
||
360 | static uint8_t USB_Rx_Buffer[BULK_DATA_SIZE];
|
||
361 | uint16_t USB_Rx_Cnt; |
||
362 | uint16_t byte_counter; |
||
363 | blt_bool result; |
||
364 | |||
365 | /* Get the received data buffer and update the counter */
|
||
366 | USB_Rx_Cnt = USB_SIL_Read(EP1_OUT, USB_Rx_Buffer); |
||
367 | |||
368 | /* USB data will be immediately processed, this allow next USB traffic being
|
||
369 | * NAKed till the end of the USART Xfer
|
||
370 | */
|
||
371 | for (byte_counter=0; byte_counter<USB_Rx_Cnt; byte_counter++) |
||
372 | { |
||
373 | /* add the data to the fifo */
|
||
374 | result = UsbFifoMgrWrite(fifoPipeBulkOUT.handle, USB_Rx_Buffer[byte_counter]); |
||
375 | /* verify that the fifo wasn't full */
|
||
376 | ASSERT_RT(result == BLT_TRUE); |
||
377 | } |
||
378 | /* Enable the reception of data on EP1 */
|
||
379 | SetEPRxValid(ENDP1); |
||
380 | } /*** end of UsbReceivePipeBulkOUT ***/
|
||
381 | |||
382 | |||
383 | /************************************************************************************//** |
||
384 | ** \brief Converts Hex 32Bits value into char.
|
||
385 | ** \param value The hexadecimal value to convert.
|
||
386 | ** \param pbuf Pointer to where the resulting string should be stored.
|
||
387 | ** \param len Number of characters to convert.
|
||
388 | ** \return none.
|
||
389 | **
|
||
390 | ****************************************************************************************/
|
||
391 | static void IntToUnicode (blt_int32u value , blt_int8u *pbuf , blt_int8u len) |
||
392 | { |
||
393 | blt_int8u idx = 0;
|
||
394 | |||
395 | for( idx = 0 ; idx < len ; idx ++) |
||
396 | { |
||
397 | if( ((value >> 28)) < 0xA ) |
||
398 | { |
||
399 | pbuf[ 2* idx] = (value >> 28) + '0'; |
||
400 | } |
||
401 | else
|
||
402 | { |
||
403 | pbuf[2* idx] = (value >> 28) + 'A' - 10; |
||
404 | } |
||
405 | |||
406 | value = value << 4;
|
||
407 | |||
408 | pbuf[ 2* idx + 1] = 0; |
||
409 | } |
||
410 | } /*** end of IntToUnicode ***/
|
||
411 | |||
412 | |||
413 | /************************************************************************************//** |
||
414 | ** \brief Creates the serial number string descriptor.
|
||
415 | ** \return none.
|
||
416 | **
|
||
417 | ****************************************************************************************/
|
||
418 | void UsbGetSerialNum(void) |
||
419 | { |
||
420 | blt_int32u Device_Serial0, Device_Serial1, Device_Serial2; |
||
421 | |||
422 | Device_Serial0 = *(volatile blt_int32u*)(0x1FFFF7E8); |
||
423 | Device_Serial1 = *(volatile blt_int32u*)(0x1FFFF7EC); |
||
424 | Device_Serial2 = *(volatile blt_int32u*)(0x1FFFF7F0); |
||
425 | |||
426 | Device_Serial0 += Device_Serial2; |
||
427 | |||
428 | if (Device_Serial0 != 0) |
||
429 | { |
||
430 | IntToUnicode(Device_Serial0, &Bulk_StringSerial[2] , 8); |
||
431 | IntToUnicode(Device_Serial1, &Bulk_StringSerial[18], 4); |
||
432 | } |
||
433 | } /*** end of UsbGetSerialNum ***/
|
||
434 | |||
435 | |||
436 | /************************************************************************************//** |
||
437 | ** \brief Initializes the fifo manager. Each controlled fifo is assigned a
|
||
438 | ** unique handle, which is the same as its index into fifoCtrl[]. Each
|
||
439 | ** controlled fifo holds a pointer to the next free fifo control.
|
||
440 | ** For the last fifo in fifoCtrl[] this one is set to a null-pointer as
|
||
441 | ** an out of fifo control indicator. Function should be called once
|
||
442 | ** before any of the other fifo management functions are called.
|
||
443 | ** \return none.
|
||
444 | **
|
||
445 | ****************************************************************************************/
|
||
446 | static void UsbFifoMgrInit(void) |
||
447 | { |
||
448 | blt_int8u i; |
||
449 | tFifoCtrl *pbc1, *pbc2; |
||
450 | |||
451 | pbc1 = &fifoCtrl[0];
|
||
452 | pbc2 = &fifoCtrl[1];
|
||
453 | /* assign fifo handles and pointer to next free fifo */
|
||
454 | for (i = 0; i < (FIFO_MAX_BUFFERS - 1); i++) |
||
455 | { |
||
456 | pbc1->handle = i; |
||
457 | pbc1->fifoctrlptr = pbc2; |
||
458 | pbc1++; |
||
459 | pbc2++; |
||
460 | } |
||
461 | /* initialize handle for the last one and use null-pointer for the next free fifo */
|
||
462 | pbc1->handle = i; |
||
463 | pbc1->fifoctrlptr = (tFifoCtrl *)0;
|
||
464 | fifoCtrlFree = &fifoCtrl[0];
|
||
465 | } /*** end of UsbFifoMgrInit ***/
|
||
466 | |||
467 | |||
468 | /************************************************************************************//** |
||
469 | ** \brief Places a data storage array under fifo management control. A handle
|
||
470 | ** for identifying the fifo in subsequent fifo management function
|
||
471 | ** calls is returned, if successful.
|
||
472 | ** \param buffer Pointer to the first element in the data storage fifo.
|
||
473 | ** \param length Maximum number of data elements that can be stored in the fifo.
|
||
474 | ** \return Fifo handle if successfull, or FIFO_ERR_INVALID_HANDLE.
|
||
475 | **
|
||
476 | ****************************************************************************************/
|
||
477 | static blt_int8u UsbFifoMgrCreate(blt_int8u *buffer, blt_int8u length)
|
||
478 | { |
||
479 | tFifoCtrl *pbc; |
||
480 | |||
481 | /* first determine if these is still a free fifo control available */
|
||
482 | if (fifoCtrlFree == (tFifoCtrl *)0) |
||
483 | { |
||
484 | return FIFO_ERR_INVALID_HANDLE;
|
||
485 | } |
||
486 | /* store pointer to free fifo and update pointer to next free one */
|
||
487 | pbc = fifoCtrlFree; |
||
488 | fifoCtrlFree = pbc->fifoctrlptr; |
||
489 | |||
490 | /* initialize the buffer control */
|
||
491 | pbc->length = length; |
||
492 | pbc->readptr = buffer; |
||
493 | pbc->writeptr = buffer; |
||
494 | pbc->entries = 0;
|
||
495 | pbc->startptr = buffer; |
||
496 | pbc->endptr = (blt_int8u*)(buffer + length - 1);
|
||
497 | |||
498 | /* return the handle to the successfully created fifo control */
|
||
499 | return pbc->handle;
|
||
500 | } /*** end of UsbFifoMgrCreate ***/
|
||
501 | |||
502 | |||
503 | /************************************************************************************//** |
||
504 | ** \brief Stores data in the fifo.
|
||
505 | ** \param handle Identifies the fifo to write data to.
|
||
506 | ** \param data Pointer to the data that is to be written to the fifo.
|
||
507 | ** \return BLT_TRUE if the data was successfully stored in the fifo, BLT_FALSE
|
||
508 | ** otherwise.
|
||
509 | **
|
||
510 | ****************************************************************************************/
|
||
511 | static blt_bool UsbFifoMgrWrite(blt_int8u handle, blt_int8u data)
|
||
512 | { |
||
513 | /* check the validity of the handle parameter */
|
||
514 | ASSERT_RT(handle < FIFO_MAX_BUFFERS); |
||
515 | /* check if fifo is full */
|
||
516 | if (fifoCtrl[handle].entries == fifoCtrl[handle].length)
|
||
517 | { |
||
518 | return BLT_FALSE;
|
||
519 | } |
||
520 | /* copy data to fifo */
|
||
521 | *fifoCtrl[handle].writeptr = data; |
||
522 | /* data written so update number of entries */
|
||
523 | fifoCtrl[handle].entries++; |
||
524 | /* update write pointer */
|
||
525 | fifoCtrl[handle].writeptr++; |
||
526 | /* check end of fifo */
|
||
527 | if (fifoCtrl[handle].writeptr > fifoCtrl[handle].endptr)
|
||
528 | { |
||
529 | /* set write pointer to start of the cyclic fifo */
|
||
530 | fifoCtrl[handle].writeptr = fifoCtrl[handle].startptr; |
||
531 | } |
||
532 | /* still here so all is okay */
|
||
533 | return BLT_TRUE;
|
||
534 | } /*** end of UsbFifoMgrWrite ***/
|
||
535 | |||
536 | |||
537 | /************************************************************************************//** |
||
538 | ** \brief Retrieves data from the fifo.
|
||
539 | ** \param handle Identifies the fifo to read data from.
|
||
540 | ** \param data Pointer to where the read data is to be stored.
|
||
541 | ** \return BLT_TRUE if the data was successfully read from the fifo, BLT_FALSE
|
||
542 | ** otherwise.
|
||
543 | **
|
||
544 | ****************************************************************************************/
|
||
545 | static blt_bool UsbFifoMgrRead(blt_int8u handle, blt_int8u *data)
|
||
546 | { |
||
547 | /* check the validity of the handle parameter */
|
||
548 | ASSERT_RT(handle < FIFO_MAX_BUFFERS); |
||
549 | /* check if fifo is empty */
|
||
550 | if (fifoCtrl[handle].entries == 0) |
||
551 | { |
||
552 | return BLT_FALSE;
|
||
553 | } |
||
554 | /* read the data */
|
||
555 | *data = *fifoCtrl[handle].readptr; |
||
556 | /* data read so update number of entries */
|
||
557 | fifoCtrl[handle].entries--; |
||
558 | /* update read pointer */
|
||
559 | fifoCtrl[handle].readptr++; |
||
560 | /* check end of fifo */
|
||
561 | if (fifoCtrl[handle].readptr > fifoCtrl[handle].endptr)
|
||
562 | { |
||
563 | /* set read pointer to start of the cyclic fifo */
|
||
564 | fifoCtrl[handle].readptr = fifoCtrl[handle].startptr; |
||
565 | } |
||
566 | /* still here so all is good */
|
||
567 | return BLT_TRUE;
|
||
568 | } /*** end of UsbFifoMgrRead ***/
|
||
569 | |||
570 | |||
571 | /************************************************************************************//** |
||
572 | ** \brief Returns the number of data entries currently present in the fifo.
|
||
573 | ** \param handle Identifies the fifo that is to be scanned.
|
||
574 | ** \return Number of data entries in the fifo if successful, otherwise 0.
|
||
575 | **
|
||
576 | ****************************************************************************************/
|
||
577 | static blt_int8u UsbFifoMgrScan(blt_int8u handle)
|
||
578 | { |
||
579 | /* check the validity of the handle parameter */
|
||
580 | ASSERT_RT(handle < FIFO_MAX_BUFFERS); |
||
581 | /* read and return the number of data entries */
|
||
582 | return fifoCtrl[handle].entries;
|
||
583 | } /*** end of UsbFifoMgrScan ***/
|
||
584 | #endif /* BOOT_COM_USB_ENABLE > 0 || BOOT_GATE_USB_ENABLE > 0 */ |
||
585 | |||
586 | |||
587 | /*********************************** end of usb.c **************************************/
|