amiro-blt / Target / Source / ARMCM3_STM32 / usb.c @ a270d48f
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 **************************************/
|