amiro-blt / Target / Source / ARMCM3_STM32 / usb.c @ 72294488
History | View | Annotate | Download (22.852 KB)
| 1 |
/************************************************************************************//** |
|---|---|
| 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 **************************************/
|