From a54ad9edce697133a024aff096e50f7e4f389d5b Mon Sep 17 00:00:00 2001 From: Florent Duchon Date: Sun, 18 Mar 2012 12:22:02 +0100 Subject: digital/beacon: import Zigbit stack (bitcloud) & avr sources --- .../Components/HAL/avr/common/src/usb.c | 435 +++++++++++++++++++++ 1 file changed, 435 insertions(+) create mode 100644 digital/beacon/src/Bitcloud_stack/Components/HAL/avr/common/src/usb.c (limited to 'digital/beacon/src/Bitcloud_stack/Components/HAL/avr/common/src/usb.c') diff --git a/digital/beacon/src/Bitcloud_stack/Components/HAL/avr/common/src/usb.c b/digital/beacon/src/Bitcloud_stack/Components/HAL/avr/common/src/usb.c new file mode 100644 index 00000000..b164f1dc --- /dev/null +++ b/digital/beacon/src/Bitcloud_stack/Components/HAL/avr/common/src/usb.c @@ -0,0 +1,435 @@ +/**************************************************************************//** + \file usb.c + + \brief Implementation of usb hardware independent module. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 17/07/08 A. Khromykh - Created + ******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include + +/****************************************************************************** + External global variables section +******************************************************************************/ +// user's request handler +extern void (* sendReqToUpper)(uint8_t *req); +// Holds the internal state for each endpoint of the UDP +extern UsbEndpoint_t endpoints[USB_END_POINTS_NUMBER]; +// Device current state +extern volatile uint8_t deviceState; +// Previous device current state +extern volatile uint8_t previousDeviceState; +// pointer to request memory. Memory allocate by user. +extern uint8_t *requestMemory; + +/****************************************************************************** + Global variables section +******************************************************************************/ +void (* resumeCallback)(void) = NULL; +void (* suspendCallback)(void) = NULL; +void (* endOfBusResetCallback)(void) = NULL; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/****************************************************************************** + Registers user's end of bus reset handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterEndOfBusResetHandler(void (* f)(void)) +{ + endOfBusResetCallback = f; +} + +/****************************************************************************** + Registers user's resume handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterResumeHandler(void (* f)(void)) +{ + resumeCallback = f; +} + +/****************************************************************************** + Registers user's suspend handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterSuspendHandler(void (* f)(void)) +{ + suspendCallback = f; +} + +/****************************************************************************** + Registers user's request handler + +Parameters: + f - pointer to user's callback +******************************************************************************/ +void HAL_RegisterRequestHandler(void (* f)(uint8_t *req)) +{ + sendReqToUpper = f; +} + +/****************************************************************************** +Configures an endpoint according to its Endpoint Descriptor. + +Parameters: + descriptor - Pointer to an Endpoint descriptor. +******************************************************************************/ +void HAL_ConfigureEndpoint(HAL_UsbEndPointDescptr_t *descriptor) +{ + UsbEndpoint_t *endpoint; + uint8_t eptnum; + uint8_t type; + HAL_UsbEndPointDirect_t direction; + + // NULL descriptor -> Control endpoint 0 + if (NULL == descriptor) + { + eptnum = USB_END_POINT_0; + endpoint = &(endpoints[USB_END_POINT_0]); + type = EP_CONTROL; + direction = EP_OUT; + endpoint->size = UDP_ENDPOINTS_MAXPACKETSIZE(USB_END_POINT_0); + } + else + { + eptnum = descriptor->bEndpointAddress & 0x0F; + endpoint = &(endpoints[eptnum]); + type = descriptor->bmAttributes & 0x03; + if (descriptor->bEndpointAddress & 0x80) + direction = EP_IN; + else + direction = EP_OUT; + endpoint->size = descriptor->wMaxPacketSize; + } + + // Abort the current transfer is the endpoint was configured and in + // Write or Read state + if ((UDP_ENDPOINT_RECEIVING == endpoint->state) || (UDP_ENDPOINT_SENDING == endpoint->state)) + halEndOfTransfer(eptnum, STATUS_RESET); + + endpoint->state = UDP_ENDPOINT_IDLE; + halConfigureEndpoint(eptnum, type, direction); +} + +/****************************************************************************** +Sends data through a USB endpoint. Sets up the transfer descriptor, +writes one or two data payloads (depending on the number of FIFO bank +for the endpoint) and then starts the actual transfer. The operation is +complete when all the data has been sent. + +*If the size of the buffer is greater than the size of the endpoint +(or twice the size if the endpoint has two FIFO banks), then the buffer +must be kept allocated until the transfer is finished*. This means that +it is not possible to declare it on the stack (i.e. as a local variable +of a function which returns after starting a transfer). + +Parameters: + eptnum - Endpoint number. + data - Pointer to a buffer with the data to send. + size - Size of the data buffer. + callback - Optional callback function to invoke when the transfer is complete. + argument - Optional argument to the callback function. + +Returns: + STATUS_SUCCESS if the transfer has been started; otherwise, the + corresponding error status code. +******************************************************************************/ +uint8_t HAL_UsbWrite(uint8_t eptnum, void *data, uint32_t size, TransferCallback_t callback, void *argument) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + UsbTransfer_t *transfer = &(endpoint->transfer); + + // Check that the endpoint is in Idle state + if (UDP_ENDPOINT_IDLE != endpoint->state) + return STATUS_BUSY; + + // Setup the transfer descriptor + transfer->data = (void *) data; + transfer->remaining = size; + transfer->buffered = 0; + transfer->transferred = 0; + transfer->callback = callback; + transfer->argument = argument; + + // Send the first packet + endpoint->state = UDP_ENDPOINT_SENDING; + halStartUsbWrite(eptnum); + + // Enable interrupt on endpoint + halEnableEndPointTxInterrupt(eptnum); + + return STATUS_SUCCESS; +} + +/****************************************************************************** +Reads incoming data on an USB endpoint This methods sets the transfer +descriptor and activate the endpoint interrupt. The actual transfer is +then carried out by the endpoint interrupt handler. The Read operation +finishes either when the buffer is full, or a short packet (inferior to +endpoint maximum size) is received. + +*The buffer must be kept allocated until the transfer is finished*. + +Parameters: + eptnum - Endpoint number. + data - Pointer to a data buffer. + size - Size of the data buffer in bytes. + callback - Optional end-of-transfer callback function. + argument - Optional argument to the callback function. + +Returns: + STATUS_SUCCESS if the read operation has been started; otherwise, + the corresponding error code. +******************************************************************************/ +uint8_t HAL_UsbRead(uint8_t eptnum, void *data, uint32_t size, TransferCallback_t callback, void *argument) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + UsbTransfer_t *transfer = &(endpoint->transfer); + + if (NULL == data) + return STATUS_ABORTED; + + // Return if the endpoint is not in IDLE state + if (UDP_ENDPOINT_IDLE != endpoint->state) + return STATUS_BUSY; + + // Endpoint enters Receiving state + endpoint->state = UDP_ENDPOINT_RECEIVING; + + // Set the transfer descriptor + transfer->data = data; + transfer->remaining = size; + transfer->buffered = 0; + transfer->transferred = 0; + transfer->callback = callback; + transfer->argument = argument; + + // Enable interrupt on endpoint + halEnableEndPointRxInterrupt(eptnum); + + return STATUS_SUCCESS; +} + +/****************************************************************************** +Sets the HALT feature on the given endpoint (if not already in this state). + +Parameters: + eptnum - Endpoint number. +******************************************************************************/ +void HAL_Halt(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + + // Check that endpoint is enabled and not already in Halt state + if ((UDP_ENDPOINT_DISABLED != endpoint->state) && (UDP_ENDPOINT_HALTED != endpoint->state)) + { + // Abort the current transfer if necessary + halEndOfTransfer(eptnum, STATUS_ABORTED); + + halEndpointHaltState(eptnum); + + // Enable the endpoint interrupt + halEnableEndPointStallInterrupt(eptnum); + } +} + +/****************************************************************************** +Clears the Halt feature on the given endpoint. + +Parameters: + eptnum - Endpoint number. +******************************************************************************/ +void HAL_Unhalt(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + + // Check if the endpoint is enabled + if (UDP_ENDPOINT_DISABLED != endpoint->state) + { + // Return endpoint to Idle state + endpoint->state = UDP_ENDPOINT_IDLE; + + halEndpointUnHaltState(eptnum); + } +} + +/****************************************************************************** +Returns the current Halt status of an endpoint. + +Parameters: + eptnum - Endpoint number. + +Returns: + 1 - if the endpoint is currently halted; + 0 - otherwise. +******************************************************************************/ +uint8_t HAL_IsHalted(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + if (UDP_ENDPOINT_HALTED == endpoint->state) + return 1; + else + return 0; +} + +/****************************************************************************** +Causes the given endpoint to acknowledge the next packet it receives with +a STALL handshake. + +Parameters: + eptnum - Endpoint number. + +Returns: + STATUS_SUCCESS or STATUS_BUSY. +******************************************************************************/ +uint8_t HAL_Stall(uint8_t eptnum) +{ + UsbEndpoint_t *endpoint = &(endpoints[eptnum]); + + // Check that endpoint is in Idle state + if (UDP_ENDPOINT_IDLE != endpoint->state) + { + return STATUS_BUSY; + } + + halSendStallToHost(eptnum); + // Enable the endpoint interrupt + halEnableEndPointStallInterrupt(eptnum); + + return STATUS_SUCCESS; +} + +/****************************************************************************** +Sets the device address to the given value. + +Parameters: + address - New device address. +******************************************************************************/ +void HAL_SetAddress(uint8_t *address) +{ + halSetUsbAddress(*address); + // If the address is 0, the device returns to the Default state + if (*address) + deviceState = DEVICE_PREADDRESSED; + // If the address is non-zero, the device enters the Address state + else + deviceState = DEVICE_DEFAULT; +} + +/****************************************************************************** +Sets the current device configuration. + +Parameters: + cfgnum - Configuration number to set. +******************************************************************************/ +void HAL_SetConfiguration(uint8_t cfgnum) +{ + // If the configuration number if non-zero, the device enters the + // Configured state + if (cfgnum) + { + deviceState = DEVICE_CONFIGURED; + } + // If the configuration number is zero, the device goes back to the Address + // state + else + { + deviceState = DEVICE_ADDRESS; + // Abort all transfers + halDisableEndpoints(); + } +} + +/****************************************************************************** +Initializes the USB driver. + +Parameters: + reqMem - Memory for usb request. Memory allocate by user. +******************************************************************************/ +void HAL_UsbInit(uint8_t *reqMem) +{ + requestMemory = reqMem; + + // Reset endpoint structures + halResetEndpoints(); + + // Device is in the Attached state + deviceState = DEVICE_SUSPENDED; + previousDeviceState = DEVICE_POWERED; + halInitUsbDevice(); + halUsbInterrupt(); +} + +/****************************************************************************** +Returns the current state of the USB device. + +Returns: + Device current state. +******************************************************************************/ +uint8_t HAL_GetState(void) +{ + return deviceState; +} + +/****************************************************************************** +Endpoint interrupt handler. +******************************************************************************/ +void halEndPointHandler(void) +{ + halCommonEndpointHandler(); +} + +/****************************************************************************** +usb suspend interrupt handler. +******************************************************************************/ +void halSuspendHandler(void) +{ + if (NULL != suspendCallback) + suspendCallback(); +} + +/****************************************************************************** +usb resume interrupt handler. +******************************************************************************/ +void halResumeHandler(void) +{ + if (NULL != resumeCallback) + resumeCallback(); +} + +/****************************************************************************** +usb bus reset interrupt handler. +******************************************************************************/ +void halBusResetHandler(void) +{ + halEndOfBusResetHandler(); + if (NULL != endOfBusResetCallback) + endOfBusResetCallback(); +} + +// eof usb.c -- cgit v1.2.3