Commit bb2e984b authored by Projects's avatar Projects

USB mass storage application in release mode.

parent 141383cb
This diff is collapsed.
......@@ -11,20 +11,21 @@ struct rle_bitmap
};
extern const struct rle_bitmap comp_circle;
extern const struct rle_bitmap battery;
extern const struct rle_bitmap game_ico;
extern const struct rle_bitmap battery_charging;
extern const struct rle_bitmap gps_searching;
extern const struct rle_bitmap clock_icon;
extern const struct rle_bitmap comp_ico;
extern const struct rle_bitmap gps_disconnected;
extern const struct rle_bitmap comp_circle3;
extern const struct rle_bitmap date_icon;
extern const struct rle_bitmap comp_arrow;
extern const struct rle_bitmap comp_circle2;
extern const struct rle_bitmap comp_ico;
extern const struct rle_bitmap gps_receiving;
extern const struct rle_bitmap comp_circle2;
extern const struct rle_bitmap comp_arrow;
extern const struct rle_bitmap usb_ms_icon;
extern const struct rle_bitmap battery;
extern const struct rle_bitmap clock_icon;
extern const struct rle_bitmap example_icon;
extern const struct rle_bitmap battery_charging;
extern const struct rle_bitmap gps_searching;
extern const struct rle_bitmap settings_icon;
extern const struct rle_bitmap game_ico;
extern const struct rle_bitmap comp_arrow2;
extern const struct rle_bitmap comp_circle3;
extern const struct rle_bitmap example_icon;
#endif /* BITMAPS_H */
/***************************************************************************//**
* @file msdbot.c
* @brief Implements the host side of the Bulk Only Transport protocol for
* USB Mass Storage class Devices.
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
* 4. The source and compiled code may only be used on Energy Micro "EFM32"
* microcontrollers and "EFR4" radios.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
*****************************************************************************/
#include "em_usb.h"
#include "msdbot.h"
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
#define TIMEOUT_1SEC 1000
#define TIMEOUT_2SEC 2000
#define DEFAULT_TIMEOUT TIMEOUT_2SEC
/* Bulk endpoint "handles". */
static USBH_Ep_TypeDef *epOut = NULL;
static USBH_Ep_TypeDef *epIn = NULL;
/* Bulk transfer timeout scale factor. */
static int timeoutFactor;
/* CSW buffer. */
STATIC_UBUF(csw, CSW_LEN);
static MSDBOT_CSW_TypeDef *pCsw = (MSDBOT_CSW_TypeDef*) csw;
/* Function prototypes. */
static bool CswMeaningful(MSDBOT_CBW_TypeDef *pCbw);
static bool CswValid(MSDBOT_CBW_TypeDef *pCbw);
static void ResetRecovery(void);
/** @endcond */
/***************************************************************************//**
* @brief
* MSDBOT module initialization.
*
* @param[in] out
* Pointer to an MSD bulk OUT endpoint structure.
*
* @param[in] in
* Pointer to an MSD bulk IN endpoint structure.
*
* @return
* @ref MSDBOT_STATUS_OK on success, else @ref MSDBOT_INIT_ERROR.
******************************************************************************/
int MSDBOT_Init(USBH_Ep_TypeDef *out, USBH_Ep_TypeDef *in)
{
/* Check if typedef's are properly packed. */
if ((sizeof(MSDBOT_CBW_TypeDef) != CBW_LEN) ||
(sizeof(MSDBOT_CSW_TypeDef) != CSW_LEN))
{
DEBUG_USB_API_PUTS("\nMSDBOT_Init(), typedef size error");
EFM_ASSERT(false);
return MSDBOT_INIT_ERROR;
}
/* Keep a local copy of bulk IN/OUT endpoint handles. */
epOut = out;
epIn = in;
/* Transfer timeouts are scaled according to device bus speed. */
if (epIn->parentDevice->speed == PORT_FULL_SPEED)
timeoutFactor = 512;
else
timeoutFactor = 64;
return MSDBOT_STATUS_OK;
}
/***************************************************************************//**
* @brief
* Perform an MSD Bulk Only Transfer (BOT).
*
* @param[in] cbw
* Pointer to a Command Block Wrapper (CBW) data structure.
*
* @param[in] data
* Data buffer for data to be transferred.
*
* @return
* A positive (or zero) value indicating the number of bytes transferred.
* @n A negative value indicates a transfer error code enumerated in
* @ref MSDBOT_Status_TypeDef.
******************************************************************************/
int MSDBOT_Xfer(void* cbw, void* data)
{
uint32_t len;
int timeout, result, direction, retVal;
MSDBOT_CBW_TypeDef *pCbw = (MSDBOT_CBW_TypeDef*) cbw;
/* Send CBW. */
result = USBH_WriteB(epOut, cbw, CBW_LEN, DEFAULT_TIMEOUT);
if (result != CBW_LEN)
{
ResetRecovery();
return MSDBOT_XFER_ERROR;
}
retVal = 0;
direction = pCbw->Direction;
len = pCbw->dCBWDataTransferLength;
/* Send/receive data (optional phase). */
if (len)
{
timeout = DEFAULT_TIMEOUT + (len / timeoutFactor);
if (direction)
result = USBH_ReadB(epIn, data, len, timeout);
else
result = USBH_WriteB(epOut, data, len, timeout);
retVal = result;
if (result == USB_STATUS_EP_STALLED)
{
if (direction)
USBH_UnStallEpB(epIn);
else
USBH_UnStallEpB(epOut);
}
else if (result <= 0)
{
ResetRecovery();
return MSDBOT_XFER_ERROR;
}
}
/* Retrieve CSW. */
result = USBH_ReadB(epIn, csw, CSW_LEN, DEFAULT_TIMEOUT);
if (result != CSW_LEN)
{
if (result == USB_STATUS_EP_STALLED)
{
if (direction)
USBH_UnStallEpB(epIn);
else
USBH_UnStallEpB(epOut);
result = USBH_ReadB(epIn, csw, CSW_LEN, DEFAULT_TIMEOUT);
if (result != CSW_LEN)
{
ResetRecovery();
return MSDBOT_XFER_ERROR;
}
}
else
{
ResetRecovery();
return MSDBOT_XFER_ERROR;
}
}
if (CswValid(pCbw) && CswMeaningful(pCbw))
{
if (pCsw->bCSWStatus == USB_CLASS_MSD_CSW_CMDPASSED)
{
return retVal;
}
return MSDBOT_CMD_FAILED;
}
ResetRecovery();
return MSDBOT_XFER_ERROR;
}
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Check if a Command Status Wrapper (CSW) is meaningful.
* The term "meaningful" is defined in the MSD BOT standard.
*
* @param[in] cbw
* Pointer to a Command Block Wrapper (CBW) data structure.
*
* @return
* True if the CSW is meaningful, false otherwise.
******************************************************************************/
static bool CswMeaningful(MSDBOT_CBW_TypeDef *cbw)
{
if (((pCsw->bCSWStatus == USB_CLASS_MSD_CSW_CMDPASSED) ||
(pCsw->bCSWStatus == USB_CLASS_MSD_CSW_CMDFAILED)) &&
(pCsw->dCSWDataResidue <= cbw->dCBWDataTransferLength))
return true;
return false;
}
/***************************************************************************//**
* @brief
* Check if a Command Status Wrapper (CSW) is valid.
* The term "valid" is defined in the MSD BOT standard.
*
* @param[in] cbw
* Pointer to a Command Block Wrapper (CBW) data structure.
*
* @return
* True if the CSW is valid, false otherwise.
******************************************************************************/
static bool CswValid(MSDBOT_CBW_TypeDef *cbw)
{
if ((pCsw->dCSWSignature == CSW_SIGNATURE) &&
(pCsw->dCSWTag == cbw->dCBWTag))
return true;
return false;
}
/***************************************************************************//**
* @brief
* Perform an MSD BOT reset recovery operation.
******************************************************************************/
static void ResetRecovery(void)
{
USBH_ControlMsgB(&epIn->parentDevice->ep0,
USB_SETUP_DIR_H2D | USB_SETUP_RECIPIENT_INTERFACE |
USB_SETUP_TYPE_CLASS_MASK, /* bmRequestType */
USB_MSD_BOTRESET, /* bRequest */
0, /* wValue */
0, /* wIndex */
0, /* wLength */
NULL, /* void* data */
TIMEOUT_1SEC); /* int timeout */
USBH_UnStallEpB(epIn);
USBH_UnStallEpB(epOut);
}
/** @endcond */
This diff is collapsed.
......@@ -82,8 +82,119 @@ static int XferBotDataCallback(USB_Status_TypeDef status, uint32_t xf
static int XferBotDataIndirectCallback(USB_Status_TypeDef status, uint32_t xferred, uint32_t remaining);
/*** Include device descriptor definitions. ***/
EFM32_ALIGN(4)
static const USB_DeviceDescriptor_TypeDef deviceDesc __attribute__ ((aligned(4)))=
{
.bLength = USB_DEVICE_DESCSIZE,
.bDescriptorType = USB_DEVICE_DESCRIPTOR,
.bcdUSB = 0x0200,
.bDeviceClass = 0,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = USB_EP0_SIZE,
.idVendor = 0x2544,
.idProduct = 0x0004,
.bcdDevice = 0x0000,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1
};
#include "descriptors.h"
EFM32_ALIGN(4)
static const uint8_t configDesc[] __attribute__ ((aligned(4)))=
{
/*** Configuration descriptor ***/
USB_CONFIG_DESCSIZE, /* bLength */
USB_CONFIG_DESCRIPTOR, /* bDescriptorType */
USB_CONFIG_DESCSIZE + /* wTotalLength (LSB) */
USB_INTERFACE_DESCSIZE +
(USB_ENDPOINT_DESCSIZE * NUM_EP_USED),
(USB_CONFIG_DESCSIZE + /* wTotalLength (MSB) */
USB_INTERFACE_DESCSIZE +
(USB_ENDPOINT_DESCSIZE * NUM_EP_USED))>>8,
1, /* bNumInterfaces */
1, /* bConfigurationValue */
0, /* iConfiguration */
#if defined(BUSPOWERED)
CONFIG_DESC_BM_RESERVED_D7, /* bmAttrib: Bus powered */
#else
CONFIG_DESC_BM_RESERVED_D7 | /* bmAttrib: Self powered */
CONFIG_DESC_BM_SELFPOWERED,
#endif
CONFIG_DESC_MAXPOWER_mA( 50 ), /* bMaxPower: 50 mA */
/*** Interface descriptor ***/
USB_INTERFACE_DESCSIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR,/* bDescriptorType */
0, /* bInterfaceNumber */
0, /* bAlternateSetting */
NUM_EP_USED, /* bNumEndpoints */
USB_CLASS_MSD, /* bInterfaceClass */
USB_CLASS_MSD_SCSI_CMDSET, /* bInterfaceSubClass */
USB_CLASS_MSD_BOT_TRANSPORT,/* bInterfaceProtocol*/
0, /* iInterface */
/*** Endpoint descriptors ***/
USB_ENDPOINT_DESCSIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR,/* bDescriptorType */
BULK_OUT, /* bEndpointAddress (OUT)*/
USB_EPTYPE_BULK, /* bmAttributes */
USB_MAX_EP_SIZE, /* wMaxPacketSize (LSB) */
0, /* wMaxPacketSize (MSB) */
0, /* bInterval */
USB_ENDPOINT_DESCSIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR,/* bDescriptorType */
BULK_IN, /* bEndpointAddress (IN) */
USB_EPTYPE_BULK, /* bmAttributes */
USB_MAX_EP_SIZE, /* wMaxPacketSize (LSB) */
0, /* wMaxPacketSize (MSB) */
0, /* bInterval */
};
STATIC_CONST_STRING_DESC_LANGID( langID, 0x04, 0x09 );
STATIC_CONST_STRING_DESC( iManufacturer, 'o','h','w','r','.','o','r', 'g' );
STATIC_CONST_STRING_DESC( iProduct , 'F','*','w','a','t','c','h' );
STATIC_CONST_STRING_DESC( iSerialNumber, '0','0','0','0','1','2', \
'3','4','5','6','7','8' );
static const void * const strings[] =
{
&langID,
&iManufacturer,
&iProduct,
&iSerialNumber
};
/* Endpoint buffer sizes */
/* 1 = single buffer, 2 = double buffering, 3 = tripple buffering ... */
static const uint8_t bufferingMultiplier[ NUM_EP_USED + 1 ] = { 1, 2, 2 };
static const USBD_Callbacks_TypeDef callbacks =
{
.usbReset = NULL,
.usbStateChange = UsbStateChangeEvent,
.setupCmd = UsbSetupCmd,
.isSelfPowered = NULL,
.sofInt = NULL
};
static const USBD_Init_TypeDef initstruct =
{
.deviceDescriptor = &deviceDesc,
.configDescriptor = configDesc,
.stringDescriptors = strings,
.numberOfStrings = sizeof(strings)/sizeof(void*),
.callbacks = &callbacks,
.bufferingMultiplier = bufferingMultiplier,
.reserved = 0
};
/*** Variables ***/
......@@ -130,7 +241,7 @@ static const MSDSCSI_InquiryData_TypeDef InquiryData __attribute__ ((aligned(4))
.Sync = 0, .Wbus16 = 0, .Obsolete4 = 0 },
.T10VendorId = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
.ProductId = { 'E', 'F', 'M', '3', '2', ' ', 'M', 'S', 'D', ' ', 'D', 'e', 'v', 'i', 'c', 'e' },
.ProductId = { 'F', '*', 'w', 'a', 't', 'c', 'h' },
.ProductRevisionLevel ={ '1', '.', '0', '0' }
};
......
/***************************************************************************//**
* @file usbconfig.h
* @brief USB protocol stack library, application supplied configuration options.
* @author Energy Micro AS
* @version 3.20.3
*******************************************************************************
* @section License
* <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
* 4. The source and compiled code may only be used on Energy Micro "EFM32"
* microcontrollers and "EFR4" radios.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Energy Micro AS will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
*****************************************************************************/
#ifndef __USBCONFIG_H
#define __USBCONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
//#define BUSPOWERED /* Uncomment to build buspowered device */
#define USB_DEVICE /* Compile stack for device mode. */
#if defined(BUSPOWERED)
#define USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONSUSPEND)
#else
#define USB_PWRSAVE_MODE (USB_PWRSAVE_MODE_ONSUSPEND | USB_PWRSAVE_MODE_ONVBUSOFF)
#endif
/****************************************************************************
** **
** Specify number of endpoints used (in addition to EP0). **
** **
*****************************************************************************/
#define NUM_EP_USED 2
/****************************************************************************
** **
** Specify number of application timers you need. **
** **
*****************************************************************************/
#define NUM_APP_TIMERS 1
/****************************************************************************
** **
** Configure serial port debug output. **
** **
*****************************************************************************/
#if 0
#if !defined(BUSPOWERED)
/* Define a function for transmitting a single char on the serial port. */
extern int RETARGET_WriteChar(char c);
#define USER_PUTCHAR RETARGET_WriteChar
/* Debug USB API functions (illegal input parameters etc.) */
#define DEBUG_USB_API
#endif /* !defined(BUSPOWERED) */
#endif
#ifdef __cplusplus
}
#endif
#endif /* __USBCONFIG_H */
/***************************************************************************//**
* @file usbconfig.h
* @brief USB protocol stack library, application supplied configuration options.
* @version 3.20.5
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensensed under the Silabs License Agreement. See the file
* "Silabs_License_Agreement.txt" for details. Before using this software for
* any purpose, you must agree to the terms of that agreement.
*
******************************************************************************/
#ifndef __USBCONFIG_H
#define __USBCONFIG_H
#ifdef __cplusplus
extern "C" {
#ifdef DEBUG
#include "usbdbg_config.h"
#else
#include "msdd_config.h"
#endif
#define USB_DEVICE /* Compile stack for device mode. */
/****************************************************************************
** **
** Specify number of endpoints used (in addition to EP0). **
** **
*****************************************************************************/
#define NUM_EP_USED 3
/****************************************************************************
** **
** Specify number of application timers you need. **
** **
*****************************************************************************/
#define NUM_APP_TIMERS 1
#ifdef __cplusplus
}
#endif
#endif /* __USBCONFIG_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment