mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-17 02:52:12 +01:00
Added MSD library.
Added PIOS_USB. Global improvements, see specific files for changes. git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@144 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
2234d0a0bf
commit
efdb5c5f2b
@ -47,8 +47,8 @@
|
||||
#if !defined (STM32F10X_LD) && !defined (STM32F10X_MD) && !defined (STM32F10X_HD) && !defined (STM32F10X_CL)
|
||||
/* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
|
||||
/* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
|
||||
/* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
|
||||
#define STM32F10X_CL /*!< STM32F10X_CL: STM32 Connectivity line devices */
|
||||
#define STM32F10X_HD /*!< STM32F10X_HD: STM32 High density devices */
|
||||
/* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
|
||||
#endif
|
||||
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||
devices, you can define the device in your toolchain compiler preprocessor.
|
||||
|
@ -165,7 +165,7 @@ int32_t SDCARD_PowerOn(void)
|
||||
PIOS_SPI_RC_PinSet(PIOS_SDCARD_SPI, 0); /* spi, pin_value */
|
||||
|
||||
/* wait for 1 mS */
|
||||
PIOS_DELAY_Wait_uS(1000);
|
||||
PIOS_DELAY_WaituS(1000);
|
||||
|
||||
/* Send CMD0 to reset the media */
|
||||
if((status = SDCARD_SendSDCCmd(SDCMD_GO_IDLE_STATE, 0, SDCMD_GO_IDLE_STATE_CRC)) < 0) {
|
||||
|
429
flight/Libraries/msd/msd.c
Normal file
429
flight/Libraries/msd/msd.c
Normal file
@ -0,0 +1,429 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file msd.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief USB Mass Storage Device Driver
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup MSD MSD Functions
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Include files */
|
||||
#include <pios.h>
|
||||
#include <usb_lib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "msd.h"
|
||||
#include "msd_desc.h"
|
||||
#include "msd_bot.h"
|
||||
#include "msd_memory.h"
|
||||
|
||||
/* Local definitions */
|
||||
|
||||
/* MASS Storage Requests */
|
||||
#define GET_MAX_LUN 0xFE
|
||||
#define MASS_STORAGE_RESET 0xFF
|
||||
#define LUN_DATA_LENGTH 1
|
||||
|
||||
/* ISTR events */
|
||||
/* IMR_MSK */
|
||||
/* mask defining which events has to be handled */
|
||||
/* by the device application software */
|
||||
#define MSD_IMR_MSK (CNTR_RESETM)
|
||||
|
||||
/* Local prototypes */
|
||||
static void MSD_MASS_Reset(void);
|
||||
static void MSD_Mass_Storage_SetConfiguration(void);
|
||||
static void MSD_Mass_Storage_ClearFeature(void);
|
||||
static void MSD_Mass_Storage_SetDeviceAddress(void);
|
||||
static void MSD_MASS_Status_In(void);
|
||||
static void MSD_MASS_Status_Out(void);
|
||||
static RESULT MSD_MASS_Data_Setup(uint8_t);
|
||||
static RESULT MSD_MASS_NoData_Setup(uint8_t);
|
||||
static RESULT MSD_MASS_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
|
||||
static uint8_t *MSD_MASS_GetDeviceDescriptor(uint16_t);
|
||||
static uint8_t *MSD_MASS_GetConfigDescriptor(uint16_t);
|
||||
static uint8_t *MSD_MASS_GetStringDescriptor(uint16_t);
|
||||
static uint8_t *Get_Max_Lun(uint16_t Length);
|
||||
|
||||
/* Local variables */
|
||||
static const DEVICE My_Device_Table = {MSD_EP_NUM, 1};
|
||||
static const DEVICE_PROP My_Device_Property = {
|
||||
0, // Init hook not used, done by PIOS_USB module!
|
||||
MSD_MASS_Reset, MSD_MASS_Status_In, MSD_MASS_Status_Out, MSD_MASS_Data_Setup, MSD_MASS_NoData_Setup, MSD_MASS_Get_Interface_Setting,
|
||||
MSD_MASS_GetDeviceDescriptor, MSD_MASS_GetConfigDescriptor, MSD_MASS_GetStringDescriptor, 0, 0x40 /*MAX PACKET SIZE*/
|
||||
};
|
||||
static const USER_STANDARD_REQUESTS My_User_Standard_Requests = {NOP_Process, MSD_Mass_Storage_SetConfiguration, NOP_Process, NOP_Process, NOP_Process,
|
||||
MSD_Mass_Storage_ClearFeature, NOP_Process, NOP_Process, MSD_Mass_Storage_SetDeviceAddress};
|
||||
static ONE_DESCRIPTOR Device_Descriptor = {(uint8_t *) MSD_MASS_DeviceDescriptor, MSD_MASS_SIZ_DEVICE_DESC};
|
||||
static ONE_DESCRIPTOR Config_Descriptor = {(uint8_t *) MSD_MASS_ConfigDescriptor, MSD_MASS_SIZ_CONFIG_DESC};
|
||||
static ONE_DESCRIPTOR String_Descriptor[5] = { {(uint8_t *) MSD_MASS_StringLangID, MSD_MASS_SIZ_STRING_LANGID}, {(uint8_t *) MSD_MASS_StringVendor,
|
||||
MSD_MASS_SIZ_STRING_VENDOR}, {(uint8_t *) MSD_MASS_StringProduct, MSD_MASS_SIZ_STRING_PRODUCT}, {(uint8_t *) MSD_MASS_StringSerial,
|
||||
MSD_MASS_SIZ_STRING_SERIAL}, {(uint8_t *) MSD_MASS_StringInterface, MSD_MASS_SIZ_STRING_INTERFACE}, };
|
||||
static uint8_t lun_available;
|
||||
|
||||
/**
|
||||
* Initialises the USB Device Driver for a Mass Storage Device
|
||||
*
|
||||
* Should be called during runtime once a SD Card has been connected.<BR>
|
||||
* It is possible to switch back to the original device driver provided
|
||||
* by calling PIOS_USB_Init(1)
|
||||
*
|
||||
* \param[in] mode currently only mode 0 supported
|
||||
* \return < 0 if initialisation failed
|
||||
*/
|
||||
int32_t MSD_Init(uint32_t mode)
|
||||
{
|
||||
/* Update the serial number string descriptor with the data from the unique ID*/
|
||||
uint8_t serial_number_str[40];
|
||||
int i, len;
|
||||
PIOS_SYS_SerialNumberGet((char *) serial_number_str);
|
||||
for(i = 0, len = 0; serial_number_str[i] != '\0' && len < 25; ++i) {
|
||||
MSD_MASS_StringSerial[len++] = serial_number_str[i];
|
||||
MSD_MASS_StringSerial[len++] = 0;
|
||||
}
|
||||
|
||||
lun_available = 0;
|
||||
|
||||
/* All LUNs available after USB init */
|
||||
for(i = 0; i < MSD_NUM_LUN; ++i) {
|
||||
MSD_LUN_AvailableSet(i, 1);
|
||||
}
|
||||
|
||||
PIOS_IRQ_Disable();
|
||||
|
||||
/* Clear all USB interrupt requests */
|
||||
_SetCNTR(0); /* Interrupt Mask */
|
||||
_SetISTR(0); /* clear pending requests */
|
||||
|
||||
/* Switch to MSD driver hooks */
|
||||
memcpy(&Device_Table, (DEVICE *) &My_Device_Table, sizeof(Device_Table));
|
||||
pProperty = (DEVICE_PROP *) &My_Device_Property;
|
||||
pUser_Standard_Requests = (USER_STANDARD_REQUESTS *) &My_User_Standard_Requests;
|
||||
|
||||
/* Change endpoints */
|
||||
pEpInt_IN[0] = MSD_Mass_Storage_In;
|
||||
pEpInt_OUT[1] = MSD_Mass_Storage_Out;
|
||||
|
||||
/* Force re-enumeration w/o overwriting PIOS hooks */
|
||||
PIOS_USB_Init(2);
|
||||
|
||||
/* Clear pending interrupts (again) */
|
||||
_SetISTR(0);
|
||||
|
||||
/* Set interrupts mask */
|
||||
_SetCNTR(MSD_IMR_MSK);
|
||||
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called periodically each millisecond so long this driver is
|
||||
* active (and only then!) to handle USBtransfers.
|
||||
*
|
||||
* Take care that no other task accesses SD Card while this function is
|
||||
* processed!
|
||||
*
|
||||
* Ensure that this function isn't called when a PIOS USB driver is running!
|
||||
*
|
||||
* \return < 0 on errors
|
||||
*/
|
||||
int32_t MSD_Periodic_mS(void)
|
||||
{
|
||||
/* Call endpoint handler of STM32 USB driver */
|
||||
CTR_LP();
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the connection status of the USB MIDI interface
|
||||
* \return 1: interface available
|
||||
* \return 0: interface not available
|
||||
*/
|
||||
int32_t MSD_CheckAvailable(void)
|
||||
{
|
||||
return pInformation->Current_Configuration ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical unit is available whenever MSD_Init() is called, or the USB
|
||||
* cable has been reconnected.
|
||||
*
|
||||
* It will be disabled when the host unmounts the file system (like if the
|
||||
* SD Card would be removed.
|
||||
*
|
||||
* When this happens, the application can either call PIOS_USB_Init(1)
|
||||
* again, e.g. to switch to USB MIDI, or it can make the LUN available
|
||||
* again by calling MSD_LUN_AvailableSet(0, 1)
|
||||
* \param[in] lun Logical Unit number (0)
|
||||
* \param[in] available 0 or 1
|
||||
* \return < 0 on errors
|
||||
*/
|
||||
int32_t MSD_LUN_AvailableSet(uint8_t lun, uint8_t available)
|
||||
{
|
||||
if(lun >= MSD_NUM_LUN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(available) {
|
||||
lun_available |= (1 << lun);
|
||||
} else {
|
||||
lun_available &= ~(1 << lun);
|
||||
}
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \return 1 if device is mounted by host
|
||||
* \return 0 if device is not mounted by host
|
||||
*/
|
||||
int32_t MSD_LUN_AvailableGet(uint8_t lun)
|
||||
{
|
||||
if(lun >= MSD_NUM_LUN)
|
||||
return 0;
|
||||
|
||||
return (lun_available & (1 << lun)) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mass Storage reset routine.
|
||||
*/
|
||||
static void MSD_MASS_Reset()
|
||||
{
|
||||
/* Set the device as not configured */
|
||||
pInformation->Current_Configuration = 0;
|
||||
|
||||
/* Current Feature initialization */
|
||||
pInformation->Current_Feature = MSD_MASS_ConfigDescriptor[7];
|
||||
|
||||
SetBTABLE(MSD_BTABLE_ADDRESS);
|
||||
|
||||
/* Initialize Endpoint 0 */
|
||||
SetEPType(ENDP0, EP_CONTROL);
|
||||
SetEPTxStatus(ENDP0, EP_TX_NAK);
|
||||
SetEPRxAddr(ENDP0, MSD_ENDP0_RXADDR);
|
||||
SetEPRxCount(ENDP0, pProperty->MaxPacketSize);
|
||||
SetEPTxAddr(ENDP0, MSD_ENDP0_TXADDR);
|
||||
Clear_Status_Out(ENDP0);
|
||||
SetEPRxValid(ENDP0);
|
||||
|
||||
/* Initialize Endpoint 1 */
|
||||
SetEPType(ENDP1, EP_BULK);
|
||||
SetEPTxAddr(ENDP1, MSD_ENDP1_TXADDR);
|
||||
SetEPTxStatus(ENDP1, EP_TX_NAK);
|
||||
SetEPRxStatus(ENDP1, EP_RX_DIS);
|
||||
|
||||
/* Initialize Endpoint 2 */
|
||||
SetEPType(ENDP2, EP_BULK);
|
||||
SetEPRxAddr(ENDP2, MSD_ENDP2_RXADDR);
|
||||
SetEPRxCount(ENDP2, pProperty->MaxPacketSize);
|
||||
SetEPRxStatus(ENDP2, EP_RX_VALID);
|
||||
SetEPTxStatus(ENDP2, EP_TX_DIS);
|
||||
|
||||
SetEPRxCount(ENDP0, pProperty->MaxPacketSize);
|
||||
SetEPRxValid(ENDP0);
|
||||
|
||||
/* Set the device to response on default address */
|
||||
SetDeviceAddress(0);
|
||||
|
||||
MSD_CBW.dSignature = BOT_CBW_SIGNATURE;
|
||||
MSD_Bot_State = BOT_IDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the SetConfiguration request.
|
||||
*/
|
||||
static void MSD_Mass_Storage_SetConfiguration(void)
|
||||
{
|
||||
if(pInformation->Current_Configuration != 0) {
|
||||
ClearDTOG_TX(ENDP1);
|
||||
ClearDTOG_RX(ENDP2);
|
||||
MSD_Bot_State = BOT_IDLE; /* Set the Bot state machine to the IDLE state */
|
||||
|
||||
/* All LUNs available after USB (re-)connection */
|
||||
for(int i = 0; i < MSD_NUM_LUN; ++i) {
|
||||
MSD_LUN_AvailableSet(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the ClearFeature request.
|
||||
*/
|
||||
static void MSD_Mass_Storage_ClearFeature(void)
|
||||
{
|
||||
/* When the host send a CBW with invalid signature or invalid length the two */
|
||||
/* Endpoints (IN & OUT) shall stall until receiving a Mass Storage Reset */
|
||||
if(MSD_CBW.dSignature != BOT_CBW_SIGNATURE) {
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Udpade the device state to addressed.
|
||||
*/
|
||||
static void MSD_Mass_Storage_SetDeviceAddress(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Mass Storage Status IN routine.
|
||||
*/
|
||||
static void MSD_MASS_Status_In(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Mass Storage Status OUT routine.
|
||||
*/
|
||||
static void MSD_MASS_Status_Out(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Handle the data class specific requests..
|
||||
* \param[in] RequestNo
|
||||
* \return RESULT
|
||||
*/
|
||||
static RESULT MSD_MASS_Data_Setup(uint8_t RequestNo)
|
||||
{
|
||||
uint8_t *(*CopyRoutine)( uint16_t);
|
||||
|
||||
CopyRoutine = NULL;
|
||||
if((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) && (RequestNo == GET_MAX_LUN) && (pInformation->USBwValue == 0)
|
||||
&& (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x01)) {
|
||||
CopyRoutine = Get_Max_Lun;
|
||||
} else {
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
if(CopyRoutine == NULL) {
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
pInformation->Ctrl_Info.CopyData = CopyRoutine;
|
||||
pInformation->Ctrl_Info.Usb_wOffset = 0;
|
||||
(*CopyRoutine)(0);
|
||||
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the no data class specific requests.
|
||||
* \param[in] RequestNo
|
||||
* \return RESULT
|
||||
*/
|
||||
static RESULT MSD_MASS_NoData_Setup(uint8_t RequestNo)
|
||||
{
|
||||
if((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) && (RequestNo == MASS_STORAGE_RESET) && (pInformation->USBwValue == 0)
|
||||
&& (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x00)) {
|
||||
/* Initialise Endpoint 1 */
|
||||
ClearDTOG_TX(ENDP1);
|
||||
|
||||
/* Initialise Endpoint 2 */
|
||||
ClearDTOG_RX(ENDP2);
|
||||
|
||||
/* Initialise the CBW signature to enable the clear feature*/
|
||||
MSD_CBW.dSignature = BOT_CBW_SIGNATURE;
|
||||
MSD_Bot_State = BOT_IDLE;
|
||||
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the interface and the alternate setting according to the supported one.
|
||||
* \param[in] Interface
|
||||
* \param[in] AlternateSetting
|
||||
* \return RESULT
|
||||
*/
|
||||
static RESULT MSD_MASS_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
|
||||
{
|
||||
if(AlternateSetting > 0) {
|
||||
return USB_UNSUPPORT;/* In this application we don't have AlternateSetting*/
|
||||
} else if(Interface > 0) {
|
||||
return USB_UNSUPPORT;/* In this application we have only 1 interfaces*/
|
||||
}
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the device descriptor.
|
||||
* \param[in] Length
|
||||
*/
|
||||
static uint8_t *MSD_MASS_GetDeviceDescriptor(uint16_t Length)
|
||||
{
|
||||
return Standard_GetDescriptorData(Length, &Device_Descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration descriptor.
|
||||
* \param[in] Length
|
||||
*/
|
||||
static uint8_t *MSD_MASS_GetConfigDescriptor(uint16_t Length)
|
||||
{
|
||||
return Standard_GetDescriptorData(Length, &Config_Descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string descriptors according to the needed index.
|
||||
* \param[in] Length
|
||||
*/
|
||||
static uint8_t *MSD_MASS_GetStringDescriptor(uint16_t Length)
|
||||
{
|
||||
uint8_t wValue0 = pInformation->USBwValue0;
|
||||
|
||||
if(wValue0 > 5) {
|
||||
return NULL;
|
||||
} else {
|
||||
return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the Get Max Lun request.
|
||||
* \param[in] Length
|
||||
*/
|
||||
static uint8_t *Get_Max_Lun(uint16_t Length)
|
||||
{
|
||||
static uint32_t Max_Lun = MSD_NUM_LUN - 1;
|
||||
|
||||
if(Length == 0) {
|
||||
pInformation->Ctrl_Info.Usb_wLength = LUN_DATA_LENGTH;
|
||||
return 0;
|
||||
} else {
|
||||
/* This copy concept requires statically allocated data... grr! */
|
||||
return ((uint8_t*) (&Max_Lun));
|
||||
}
|
||||
}
|
||||
|
78
flight/Libraries/msd/msd.h
Normal file
78
flight/Libraries/msd/msd.h
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file msd.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief MSD functions header.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _MSD_H
|
||||
#define _MSD_H
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Global definitions
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* defines how many bytes are sent per packet */
|
||||
#define MSD_BULK_MAX_PACKET_SIZE 0x40
|
||||
|
||||
/* max. number of supported logical units */
|
||||
#define MSD_NUM_LUN 1
|
||||
|
||||
/* defines how many endpoints are used by the device */
|
||||
#define MSD_EP_NUM 3
|
||||
|
||||
/* buffer table base address */
|
||||
|
||||
#define MSD_BTABLE_ADDRESS (0x00)
|
||||
|
||||
/* EP0 */
|
||||
/* rx/tx buffer base address */
|
||||
#define MSD_ENDP0_RXADDR (0x18)
|
||||
#define MSD_ENDP0_TXADDR (0x58)
|
||||
|
||||
/* EP1 */
|
||||
/* tx buffer base address */
|
||||
#define MSD_ENDP1_TXADDR (0x98)
|
||||
|
||||
/* EP2 */
|
||||
/* Rx buffer base address */
|
||||
#define MSD_ENDP2_RXADDR (0xD8)
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Prototypes
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern s32 MSD_Init(u32 mode);
|
||||
extern s32 MSD_Periodic_mS(void);
|
||||
|
||||
extern s32 MSD_CheckAvailable(void);
|
||||
|
||||
extern s32 MSD_LUN_AvailableSet(u8 lun, u8 available);
|
||||
extern s32 MSD_LUN_AvailableGet(u8 lun);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Export global variables
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif /* _MSD_H */
|
334
flight/Libraries/msd/msd_bot.c
Normal file
334
flight/Libraries/msd/msd_bot.c
Normal file
@ -0,0 +1,334 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : usb_bot.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : BOT State Machine management
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <pios.h>
|
||||
#include <usb_lib.h>
|
||||
|
||||
#include "msd.h"
|
||||
#include "msd_scsi.h"
|
||||
#include "msd_bot.h"
|
||||
#include "msd_memory.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
uint8_t MSD_Bot_State;
|
||||
uint8_t MSD_Bulk_Data_Buff[MSD_BULK_MAX_PACKET_SIZE]; /* data buffer*/
|
||||
uint16_t MSD_Data_Len;
|
||||
Bulk_Only_CBW MSD_CBW;
|
||||
Bulk_Only_CSW MSD_CSW;
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static uint32_t SCSI_LBA , SCSI_BlkLen;
|
||||
|
||||
/* Extern variables ----------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Extern function prototypes ------------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_Mass_Storage_In
|
||||
* Description : Mass Storage IN transfer.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Mass_Storage_In (void)
|
||||
{
|
||||
switch (MSD_Bot_State)
|
||||
{
|
||||
case BOT_CSW_Send:
|
||||
case BOT_ERROR:
|
||||
MSD_Bot_State = BOT_IDLE;
|
||||
SetEPRxStatus(ENDP2, EP_RX_VALID);/* enable the Endpoint to recive the next cmd*/
|
||||
break;
|
||||
case BOT_DATA_IN:
|
||||
switch (MSD_CBW.CB[0])
|
||||
{
|
||||
case SCSI_READ10:
|
||||
MSD_SCSI_Read10_Cmd(MSD_CBW.bLUN , SCSI_LBA , SCSI_BlkLen);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BOT_DATA_IN_LAST:
|
||||
MSD_Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
|
||||
SetEPRxStatus(ENDP2, EP_RX_VALID);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_Mass_Storage_Out
|
||||
* Description : Mass Storage OUT transfer.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Mass_Storage_Out (void)
|
||||
{
|
||||
uint8_t CMD;
|
||||
CMD = MSD_CBW.CB[0];
|
||||
MSD_Data_Len = GetEPRxCount(ENDP2);
|
||||
|
||||
PMAToUserBufferCopy(MSD_Bulk_Data_Buff, MSD_ENDP2_RXADDR, MSD_Data_Len);
|
||||
|
||||
switch (MSD_Bot_State)
|
||||
{
|
||||
case BOT_IDLE:
|
||||
MSD_CBW_Decode();
|
||||
break;
|
||||
case BOT_DATA_OUT:
|
||||
if (CMD == SCSI_WRITE10)
|
||||
{
|
||||
MSD_SCSI_Write10_Cmd(MSD_CBW.bLUN , SCSI_LBA , SCSI_BlkLen);
|
||||
break;
|
||||
}
|
||||
MSD_Bot_Abort(DIR_OUT);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
MSD_Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE);
|
||||
break;
|
||||
default:
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
MSD_Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_CBW_Decode
|
||||
* Description : Decode the received CBW and call the related SCSI command
|
||||
* routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_CBW_Decode(void)
|
||||
{
|
||||
uint32_t Counter;
|
||||
|
||||
for (Counter = 0; Counter < MSD_Data_Len; Counter++)
|
||||
{
|
||||
*((uint8_t *)&MSD_CBW + Counter) = MSD_Bulk_Data_Buff[Counter];
|
||||
}
|
||||
MSD_CSW.dTag = MSD_CBW.dTag;
|
||||
MSD_CSW.dDataResidue = MSD_CBW.dDataLength;
|
||||
if (MSD_Data_Len != BOT_CBW_PACKET_LENGTH)
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
/* reset the MSD_CBW.dSignature to desible the clear feature until receiving a Mass storage reset*/
|
||||
MSD_CBW.dSignature = 0;
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, PARAMETER_LIST_LENGTH_ERROR);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((MSD_CBW.CB[0] == SCSI_READ10 ) || (MSD_CBW.CB[0] == SCSI_WRITE10 ))
|
||||
{
|
||||
/* Calculate Logical Block Address */
|
||||
SCSI_LBA = (MSD_CBW.CB[2] << 24) | (MSD_CBW.CB[3] << 16) | (MSD_CBW.CB[4] << 8) | MSD_CBW.CB[5];
|
||||
/* Calculate the Number of Blocks to transfer */
|
||||
SCSI_BlkLen = (MSD_CBW.CB[7] << 8) | MSD_CBW.CB[8];
|
||||
}
|
||||
|
||||
if (MSD_CBW.dSignature == BOT_CBW_SIGNATURE)
|
||||
{
|
||||
/* Valid CBW */
|
||||
if ((MSD_CBW.bLUN >= MSD_NUM_LUN) || (MSD_CBW.bCBLength < 1) || (MSD_CBW.bCBLength > 16))
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (MSD_CBW.CB[0])
|
||||
{
|
||||
case SCSI_REQUEST_SENSE:
|
||||
MSD_SCSI_RequestSense_Cmd (MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_INQUIRY:
|
||||
MSD_SCSI_Inquiry_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_START_STOP_UNIT:
|
||||
MSD_SCSI_Start_Stop_Unit_Cmd(MSD_CBW.bLUN);
|
||||
MSD_LUN_AvailableSet(MSD_CBW.bLUN, 0);
|
||||
break;
|
||||
case SCSI_ALLOW_MEDIUM_REMOVAL:
|
||||
MSD_SCSI_Start_Stop_Unit_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_MODE_SENSE6:
|
||||
MSD_SCSI_ModeSense6_Cmd (MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_MODE_SENSE10:
|
||||
MSD_SCSI_ModeSense10_Cmd (MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_READ_FORMAT_CAPACITIES:
|
||||
MSD_SCSI_ReadFormatCapacity_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_READ_CAPACITY10:
|
||||
MSD_SCSI_ReadCapacity10_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_TEST_UNIT_READY:
|
||||
MSD_SCSI_TestUnitReady_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_READ10:
|
||||
MSD_SCSI_Read10_Cmd(MSD_CBW.bLUN, SCSI_LBA , SCSI_BlkLen);
|
||||
break;
|
||||
case SCSI_WRITE10:
|
||||
MSD_SCSI_Write10_Cmd(MSD_CBW.bLUN, SCSI_LBA , SCSI_BlkLen);
|
||||
break;
|
||||
case SCSI_VERIFY10:
|
||||
MSD_SCSI_Verify10_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_FORMAT_UNIT:
|
||||
MSD_SCSI_Format_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
/*Unsupported command*/
|
||||
|
||||
case SCSI_MODE_SELECT10:
|
||||
MSD_SCSI_Mode_Select10_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_MODE_SELECT6:
|
||||
MSD_SCSI_Mode_Select6_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
|
||||
case SCSI_SEND_DIAGNOSTIC:
|
||||
MSD_SCSI_Send_Diagnostic_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_READ6:
|
||||
MSD_SCSI_Read6_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_READ12:
|
||||
MSD_SCSI_Read12_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_READ16:
|
||||
MSD_SCSI_Read16_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_READ_CAPACITY16:
|
||||
MSD_SCSI_READ_CAPACITY16_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_WRITE6:
|
||||
MSD_SCSI_Write6_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_WRITE12:
|
||||
MSD_SCSI_Write12_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_WRITE16:
|
||||
MSD_SCSI_Write16_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_VERIFY12:
|
||||
MSD_SCSI_Verify12_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
case SCSI_VERIFY16:
|
||||
MSD_SCSI_Verify16_Cmd(MSD_CBW.bLUN);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid CBW */
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_Transfer_Data_Request
|
||||
* Description : Send the request response to the PC HOST.
|
||||
* Input : uint8_t* Data_Address : point to the data to transfer.
|
||||
* uint16_t Data_Length : the nember of Bytes to transfer.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Transfer_Data_Request(uint8_t* Data_Pointer, uint16_t Data_Len)
|
||||
{
|
||||
UserToPMABufferCopy(Data_Pointer, MSD_ENDP1_TXADDR, Data_Len);
|
||||
|
||||
SetEPTxCount(ENDP1, Data_Len);
|
||||
SetEPTxStatus(ENDP1, EP_TX_VALID);
|
||||
MSD_Bot_State = BOT_DATA_IN_LAST;
|
||||
MSD_CSW.dDataResidue -= Data_Len;
|
||||
MSD_CSW.bStatus = CSW_CMD_PASSED;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_Set_CSW
|
||||
* Description : Set the SCW with the needed fields.
|
||||
* Input : uint8_t CSW_Status this filed can be CSW_CMD_PASSED,CSW_CMD_FAILED,
|
||||
* or CSW_PHASE_ERROR.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission)
|
||||
{
|
||||
MSD_CSW.dSignature = BOT_CSW_SIGNATURE;
|
||||
MSD_CSW.bStatus = CSW_Status;
|
||||
|
||||
UserToPMABufferCopy(((uint8_t *)& MSD_CSW), MSD_ENDP1_TXADDR, CSW_DATA_LENGTH);
|
||||
|
||||
SetEPTxCount(ENDP1, CSW_DATA_LENGTH);
|
||||
MSD_Bot_State = BOT_ERROR;
|
||||
if (Send_Permission)
|
||||
{
|
||||
MSD_Bot_State = BOT_CSW_Send;
|
||||
SetEPTxStatus(ENDP1, EP_TX_VALID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_Bot_Abort
|
||||
* Description : Stall the needed Endpoint according to the selected direction.
|
||||
* Input : Endpoint direction IN, OUT or both directions
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Bot_Abort(uint8_t Direction)
|
||||
{
|
||||
switch (Direction)
|
||||
{
|
||||
case DIR_IN :
|
||||
SetEPTxStatus(ENDP1, EP_TX_STALL);
|
||||
break;
|
||||
case DIR_OUT :
|
||||
SetEPRxStatus(ENDP2, EP_RX_STALL);
|
||||
break;
|
||||
case BOTH_DIR :
|
||||
SetEPTxStatus(ENDP1, EP_TX_STALL);
|
||||
SetEPRxStatus(ENDP2, EP_RX_STALL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
95
flight/Libraries/msd/msd_bot.h
Normal file
95
flight/Libraries/msd/msd_bot.h
Normal file
@ -0,0 +1,95 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : usb_bot.h
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : BOT State Machine management
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_BOT_H
|
||||
#define __USB_BOT_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Bulk-only Command Block Wrapper */
|
||||
|
||||
typedef struct _Bulk_Only_CBW
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataLength;
|
||||
uint8_t bmFlags;
|
||||
uint8_t bLUN;
|
||||
uint8_t bCBLength;
|
||||
uint8_t CB[16];
|
||||
}
|
||||
Bulk_Only_CBW;
|
||||
|
||||
/* Bulk-only Command Status Wrapper */
|
||||
typedef struct _Bulk_Only_CSW
|
||||
{
|
||||
uint32_t dSignature;
|
||||
uint32_t dTag;
|
||||
uint32_t dDataResidue;
|
||||
uint8_t bStatus;
|
||||
}
|
||||
Bulk_Only_CSW;
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********************** Bulk-Only Transfer State machine ********************/
|
||||
/*****************************************************************************/
|
||||
#define BOT_IDLE 0 /* Idle state */
|
||||
#define BOT_DATA_OUT 1 /* Data Out state */
|
||||
#define BOT_DATA_IN 2 /* Data In state */
|
||||
#define BOT_DATA_IN_LAST 3 /* Last Data In Last */
|
||||
#define BOT_CSW_Send 4 /* Command Status Wrapper */
|
||||
#define BOT_ERROR 5 /* error state */
|
||||
|
||||
#define BOT_CBW_SIGNATURE 0x43425355
|
||||
#define BOT_CSW_SIGNATURE 0x53425355
|
||||
#define BOT_CBW_PACKET_LENGTH 31
|
||||
|
||||
#define CSW_DATA_LENGTH 0x000D
|
||||
|
||||
/* CSW Status Definitions */
|
||||
#define CSW_CMD_PASSED 0x00
|
||||
#define CSW_CMD_FAILED 0x01
|
||||
#define CSW_PHASE_ERROR 0x02
|
||||
|
||||
#define SEND_CSW_DISABLE 0
|
||||
#define SEND_CSW_ENABLE 1
|
||||
|
||||
#define DIR_IN 0
|
||||
#define DIR_OUT 1
|
||||
#define BOTH_DIR 2
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
extern void MSD_Mass_Storage_In (void);
|
||||
extern void MSD_Mass_Storage_Out (void);
|
||||
extern void MSD_CBW_Decode(void);
|
||||
extern void MSD_Transfer_Data_Request(uint8_t* Data_Pointer, uint16_t Data_Len);
|
||||
extern void MSD_Set_CSW (uint8_t CSW_Status, uint8_t Send_Permission);
|
||||
extern void MSD_Bot_Abort(uint8_t Direction);
|
||||
|
||||
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
extern uint8_t MSD_Bot_State;
|
||||
extern uint8_t MSD_Bulk_Data_Buff[MSD_BULK_MAX_PACKET_SIZE]; /* data buffer*/
|
||||
extern uint16_t MSD_Data_Len;
|
||||
extern Bulk_Only_CBW MSD_CBW;
|
||||
extern Bulk_Only_CSW MSD_CSW;
|
||||
|
||||
#endif /* __USB_BOT_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
135
flight/Libraries/msd/msd_desc.c
Normal file
135
flight/Libraries/msd/msd_desc.c
Normal file
@ -0,0 +1,135 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : usb_desc.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : Descriptors for Mass Storage Device
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "msd_desc.h"
|
||||
|
||||
const uint8_t MSD_MASS_DeviceDescriptor[MSD_MASS_SIZ_DEVICE_DESC] =
|
||||
{
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x00, /* bcdUSB, version 2.00 */
|
||||
0x02,
|
||||
0x00, /* bDeviceClass : each interface define the device class */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x00, /* bDeviceProtocol */
|
||||
0x40, /* bMaxPacketSize0 0x40 = 64 */
|
||||
0x83, /* idVendor (0483) */
|
||||
0x04,
|
||||
0x20, /* idProduct */
|
||||
0x57,
|
||||
0x00, /* bcdDevice 2.00*/
|
||||
0x02,
|
||||
1, /* index of string Manufacturer */
|
||||
/**/
|
||||
2, /* index of string descriptor of product*/
|
||||
/* */
|
||||
3, /* */
|
||||
/* */
|
||||
/* */
|
||||
0x01 /*bNumConfigurations */
|
||||
};
|
||||
const uint8_t MSD_MASS_ConfigDescriptor[MSD_MASS_SIZ_CONFIG_DESC] =
|
||||
{
|
||||
|
||||
0x09, /* bLength: Configuation Descriptor size */
|
||||
0x02, /* bDescriptorType: Configuration */
|
||||
MSD_MASS_SIZ_CONFIG_DESC,
|
||||
|
||||
0x00,
|
||||
0x01, /* bNumInterfaces: 1 interface */
|
||||
0x01, /* bConfigurationValue: */
|
||||
/* Configuration value */
|
||||
0x00, /* iConfiguration: */
|
||||
/* Index of string descriptor */
|
||||
/* describing the configuration */
|
||||
0xC0, /* bmAttributes: */
|
||||
/* bus powered */
|
||||
0x32, /* MaxPower 100 mA */
|
||||
|
||||
/******************** Descriptor of Mass Storage interface ********************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
0x04, /* bDescriptorType: */
|
||||
/* Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints*/
|
||||
0x08, /* bInterfaceClass: MASS STORAGE Class */
|
||||
0x06, /* bInterfaceSubClass : SCSI transparent*/
|
||||
0x50, /* nInterfaceProtocol */
|
||||
4, /* iInterface: */
|
||||
/* 18 */
|
||||
0x07, /*Endpoint descriptor length = 7*/
|
||||
0x05, /*Endpoint descriptor type */
|
||||
0x81, /*Endpoint address (IN, address 1) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
0x40, /*Maximum packet size (64 bytes) */
|
||||
0x00,
|
||||
0x00, /*Polling interval in milliseconds */
|
||||
/* 25 */
|
||||
0x07, /*Endpoint descriptor length = 7 */
|
||||
0x05, /*Endpoint descriptor type */
|
||||
0x02, /*Endpoint address (OUT, address 2) */
|
||||
0x02, /*Bulk endpoint type */
|
||||
0x40, /*Maximum packet size (64 bytes) */
|
||||
0x00,
|
||||
0x00 /*Polling interval in milliseconds*/
|
||||
/*32*/
|
||||
};
|
||||
const uint8_t MSD_MASS_StringLangID[MSD_MASS_SIZ_STRING_LANGID] =
|
||||
{
|
||||
MSD_MASS_SIZ_STRING_LANGID,
|
||||
0x03,
|
||||
0x09,
|
||||
0x04
|
||||
}
|
||||
; /* LangID = 0x0409: U.S. English */
|
||||
const uint8_t MSD_MASS_StringVendor[MSD_MASS_SIZ_STRING_VENDOR] =
|
||||
{
|
||||
MSD_MASS_SIZ_STRING_VENDOR, /* Size of manufaturer string */
|
||||
0x03, /* bDescriptorType = String descriptor */
|
||||
/* Manufacturer */
|
||||
'O', 0, 'p', 0, 'e', 0, 'n', 0, 'p', 0, 'i', 0, 'l', 0, 'o', 0,
|
||||
't', 0,
|
||||
};
|
||||
const uint8_t MSD_MASS_StringProduct[MSD_MASS_SIZ_STRING_PRODUCT] =
|
||||
{
|
||||
MSD_MASS_SIZ_STRING_PRODUCT,
|
||||
0x03,
|
||||
/* Product name */
|
||||
'O', 0, 'p', 0, 'e', 0, 'n', 0, 'P', 0, 'i', 0, 'l', 0, 'o', 0, 't', 0,
|
||||
' ', 0, 'M', 0, 'a', 0, 's', 0, 's', 0, ' ', 0, 'S', 0, 't', 0, 'o', 0,
|
||||
'r', 0, 'a', 0, 'g', 0, 'e', 0
|
||||
|
||||
};
|
||||
|
||||
uint8_t MSD_MASS_StringSerial[MSD_MASS_SIZ_STRING_SERIAL] =
|
||||
{
|
||||
MSD_MASS_SIZ_STRING_SERIAL,
|
||||
0x03,
|
||||
/* Serial number */
|
||||
'0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0
|
||||
};
|
||||
const uint8_t MSD_MASS_StringInterface[MSD_MASS_SIZ_STRING_INTERFACE] =
|
||||
{
|
||||
MSD_MASS_SIZ_STRING_INTERFACE,
|
||||
0x03,
|
||||
/* Interface 0: */
|
||||
'S', 0, 'D', 0, ' ', 0, 'C', 0, 'a', 0, 'r', 0, 'd', 0
|
||||
};
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
48
flight/Libraries/msd/msd_desc.h
Normal file
48
flight/Libraries/msd/msd_desc.h
Normal file
@ -0,0 +1,48 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : usb_desc.h
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : Descriptor Header for Mass Storage Device
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_DESC_H
|
||||
#define __USB_DESC_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f10x.h"
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported define -----------------------------------------------------------*/
|
||||
#define MSD_MASS_SIZ_DEVICE_DESC 18
|
||||
#define MSD_MASS_SIZ_CONFIG_DESC 32
|
||||
|
||||
#define MSD_MASS_SIZ_STRING_LANGID 4
|
||||
#define MSD_MASS_SIZ_STRING_VENDOR 20
|
||||
#define MSD_MASS_SIZ_STRING_PRODUCT 46
|
||||
#define MSD_MASS_SIZ_STRING_SERIAL 26
|
||||
#define MSD_MASS_SIZ_STRING_INTERFACE 16
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
extern const uint8_t MSD_MASS_DeviceDescriptor[MSD_MASS_SIZ_DEVICE_DESC];
|
||||
extern const uint8_t MSD_MASS_ConfigDescriptor[MSD_MASS_SIZ_CONFIG_DESC];
|
||||
|
||||
extern const uint8_t MSD_MASS_StringLangID[MSD_MASS_SIZ_STRING_LANGID];
|
||||
extern const uint8_t MSD_MASS_StringVendor[MSD_MASS_SIZ_STRING_VENDOR];
|
||||
extern const uint8_t MSD_MASS_StringProduct[MSD_MASS_SIZ_STRING_PRODUCT];
|
||||
extern uint8_t MSD_MASS_StringSerial[MSD_MASS_SIZ_STRING_SERIAL];
|
||||
extern const uint8_t MSD_MASS_StringInterface[MSD_MASS_SIZ_STRING_INTERFACE];
|
||||
|
||||
#endif /* __USB_DESC_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
242
flight/Libraries/msd/msd_memory.c
Normal file
242
flight/Libraries/msd/msd_memory.c
Normal file
@ -0,0 +1,242 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file msd_memory.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief Memory Management Layer
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup MSD MSD Functions
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : memory.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : Memory management layer
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include <pios.h>
|
||||
#include <usb_lib.h>
|
||||
|
||||
#include "msd.h"
|
||||
#include "msd_memory.h"
|
||||
#include "msd_scsi.h"
|
||||
#include "msd_bot.h"
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
uint32_t MSD_Mass_Memory_Size[MSD_NUM_LUN];
|
||||
uint32_t MSD_Mass_Block_Size[MSD_NUM_LUN];
|
||||
uint32_t MSD_Mass_Block_Count[MSD_NUM_LUN];
|
||||
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
static __IO uint32_t Block_Read_count = 0;
|
||||
static __IO uint32_t Block_offset;
|
||||
static __IO uint32_t Counter = 0;
|
||||
static uint32_t Idx;
|
||||
static uint32_t Data_Buffer[MSD_BULK_MAX_PACKET_SIZE *2]; /* 512 bytes*/
|
||||
static uint8_t TransferState = TXFR_IDLE;
|
||||
|
||||
|
||||
/* Extern variables ----------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Extern function prototypes ------------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : Read_Memory
|
||||
* Description : Handle the Read operation from the microSD card.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Read_Memory(uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length)
|
||||
{
|
||||
static uint32_t Offset, Length;
|
||||
|
||||
if (TransferState == TXFR_IDLE )
|
||||
{
|
||||
Offset = Memory_Offset * MSD_Mass_Block_Size[lun];
|
||||
Length = Transfer_Length * MSD_Mass_Block_Size[lun];
|
||||
TransferState = TXFR_ONGOING;
|
||||
}
|
||||
|
||||
if (TransferState == TXFR_ONGOING )
|
||||
{
|
||||
if (!Block_Read_count)
|
||||
{
|
||||
s32 status;
|
||||
|
||||
switch( lun ) {
|
||||
case 0:
|
||||
if( MSD_Mass_Block_Size[lun] != 512 )
|
||||
break;
|
||||
status = PIOS_SDCARD_SectorRead(Offset/512, (u8 *)Data_Buffer);
|
||||
// TK: how to handle an error here?
|
||||
break;
|
||||
|
||||
default:
|
||||
status = -1;
|
||||
// TK: how to handle an error here?
|
||||
}
|
||||
|
||||
UserToPMABufferCopy((uint8_t *)Data_Buffer, MSD_ENDP1_TXADDR, MSD_BULK_MAX_PACKET_SIZE);
|
||||
Block_Read_count = MSD_Mass_Block_Size[lun] - MSD_BULK_MAX_PACKET_SIZE;
|
||||
Block_offset = MSD_BULK_MAX_PACKET_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserToPMABufferCopy((uint8_t *)Data_Buffer + Block_offset, MSD_ENDP1_TXADDR, MSD_BULK_MAX_PACKET_SIZE);
|
||||
Block_Read_count -= MSD_BULK_MAX_PACKET_SIZE;
|
||||
Block_offset += MSD_BULK_MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
SetEPTxCount(ENDP1, MSD_BULK_MAX_PACKET_SIZE);
|
||||
SetEPTxStatus(ENDP1, EP_TX_VALID);
|
||||
Offset += MSD_BULK_MAX_PACKET_SIZE;
|
||||
Length -= MSD_BULK_MAX_PACKET_SIZE;
|
||||
|
||||
MSD_CSW.dDataResidue -= MSD_BULK_MAX_PACKET_SIZE;
|
||||
}
|
||||
if (Length == 0)
|
||||
{
|
||||
Block_Read_count = 0;
|
||||
Block_offset = 0;
|
||||
Offset = 0;
|
||||
MSD_Bot_State = BOT_DATA_IN_LAST;
|
||||
TransferState = TXFR_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : Write_Memory
|
||||
* Description : Handle the Write operation to the microSD card.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Write_Memory (uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length)
|
||||
{
|
||||
|
||||
static uint32_t W_Offset, W_Length;
|
||||
|
||||
uint32_t temp = Counter + 64;
|
||||
|
||||
if (TransferState == TXFR_IDLE )
|
||||
{
|
||||
W_Offset = Memory_Offset * MSD_Mass_Block_Size[lun];
|
||||
W_Length = Transfer_Length * MSD_Mass_Block_Size[lun];
|
||||
TransferState = TXFR_ONGOING;
|
||||
}
|
||||
|
||||
if (TransferState == TXFR_ONGOING )
|
||||
{
|
||||
|
||||
for (Idx = 0 ; Counter < temp; Counter++)
|
||||
{
|
||||
*((uint8_t *)Data_Buffer + Counter) = MSD_Bulk_Data_Buff[Idx++];
|
||||
}
|
||||
|
||||
W_Offset += MSD_Data_Len;
|
||||
W_Length -= MSD_Data_Len;
|
||||
|
||||
if (!(W_Length % MSD_Mass_Block_Size[lun]))
|
||||
{
|
||||
Counter = 0;
|
||||
|
||||
s32 status;
|
||||
u32 Offset = W_Offset - MSD_Mass_Block_Size[lun];
|
||||
|
||||
switch( lun ) {
|
||||
case 0:
|
||||
if( MSD_Mass_Block_Size[lun] != 512 )
|
||||
break;
|
||||
status = PIOS_SDCARD_SectorWrite(Offset/512, (u8 *)Data_Buffer);
|
||||
// TK: how to handle an error here?
|
||||
break;
|
||||
|
||||
default:
|
||||
status = -1;
|
||||
// TK: how to handle an error here?
|
||||
}
|
||||
}
|
||||
|
||||
MSD_CSW.dDataResidue -= MSD_Data_Len;
|
||||
SetEPRxStatus(ENDP2, EP_RX_VALID); /* enable the next transaction*/
|
||||
}
|
||||
|
||||
if ((W_Length == 0) || (MSD_Bot_State == BOT_CSW_Send))
|
||||
{
|
||||
Counter = 0;
|
||||
MSD_Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
|
||||
TransferState = TXFR_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MAL_GetStatus
|
||||
* Description : Get status
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
uint16_t MSD_MAL_GetStatus (uint8_t lun)
|
||||
{
|
||||
// LUN removed or disabled?
|
||||
if( !MSD_LUN_AvailableGet(lun) )
|
||||
return 1;
|
||||
|
||||
if( lun == 0 ) {
|
||||
SDCARDCsdTypeDef csd;
|
||||
if( PIOS_SDCARD_CSDRead(&csd) < 0 )
|
||||
return 1;
|
||||
|
||||
u32 DeviceSizeMul = csd.DeviceSizeMul + 2;
|
||||
u32 temp_block_mul = (1 << csd.RdBlockLen)/ 512;
|
||||
MSD_Mass_Block_Count[lun] = ((csd.DeviceSize + 1) * (1 << (DeviceSizeMul))) * temp_block_mul;
|
||||
MSD_Mass_Block_Size[lun] = 512;
|
||||
MSD_Mass_Memory_Size[lun] = (MSD_Mass_Block_Count[lun] * MSD_Mass_Block_Size[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
43
flight/Libraries/msd/msd_memory.h
Normal file
43
flight/Libraries/msd/msd_memory.h
Normal file
@ -0,0 +1,43 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : memory.h
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : Memory management layer
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __memory_H
|
||||
#define __memory_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f10x.h"
|
||||
#include "msd.h"
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
#define TXFR_IDLE 0
|
||||
#define TXFR_ONGOING 1
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
extern void MSD_Write_Memory (uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length);
|
||||
extern void MSD_Read_Memory (uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length);
|
||||
extern uint16_t MSD_MAL_GetStatus (uint8_t lun);
|
||||
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
extern uint32_t MSD_Mass_Memory_Size[MSD_NUM_LUN];
|
||||
extern uint32_t MSD_Mass_Block_Size[MSD_NUM_LUN];
|
||||
extern uint32_t MSD_Mass_Block_Count[MSD_NUM_LUN];
|
||||
|
||||
#endif /* __memory_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
430
flight/Libraries/msd/msd_scsi.c
Normal file
430
flight/Libraries/msd/msd_scsi.c
Normal file
@ -0,0 +1,430 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : usb_scsi.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : All processing related to the SCSI commands
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <pios.h>
|
||||
#include <usb_lib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "msd.h"
|
||||
#include "msd_scsi.h"
|
||||
#include "msd_bot.h"
|
||||
#include "msd_memory.h"
|
||||
//#include "nand_if.h"
|
||||
//#include "platform_config.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* External variables --------------------------------------------------------*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : SCSI_Inquiry_Cmd
|
||||
* Description : SCSI Inquiry Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Inquiry_Cmd(uint8_t lun)
|
||||
{
|
||||
uint8_t* Inquiry_Data;
|
||||
uint16_t Inquiry_Data_Length;
|
||||
|
||||
if (MSD_CBW.CB[1] & 0x01)/*Evpd is set*/
|
||||
{
|
||||
Inquiry_Data = MSD_Page00_Inquiry_Data;
|
||||
Inquiry_Data_Length = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ( lun == 0)
|
||||
{
|
||||
Inquiry_Data = MSD_Standard_Inquiry_Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
Inquiry_Data = MSD_Standard_Inquiry_Data2;
|
||||
}
|
||||
|
||||
if (MSD_CBW.CB[4] <= STANDARD_INQUIRY_DATA_LEN)
|
||||
Inquiry_Data_Length = MSD_CBW.CB[4];
|
||||
else
|
||||
Inquiry_Data_Length = STANDARD_INQUIRY_DATA_LEN;
|
||||
|
||||
}
|
||||
MSD_Transfer_Data_Request(Inquiry_Data, Inquiry_Data_Length);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_ReadFormatCapacity_Cmd
|
||||
* Description : SCSI ReadFormatCapacity Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_ReadFormatCapacity_Cmd(uint8_t lun)
|
||||
{
|
||||
|
||||
if (MSD_MAL_GetStatus(lun) != 0 )
|
||||
{
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
return;
|
||||
}
|
||||
MSD_ReadFormatCapacity_Data[4] = (uint8_t)(MSD_Mass_Block_Count[lun] >> 24);
|
||||
MSD_ReadFormatCapacity_Data[5] = (uint8_t)(MSD_Mass_Block_Count[lun] >> 16);
|
||||
MSD_ReadFormatCapacity_Data[6] = (uint8_t)(MSD_Mass_Block_Count[lun] >> 8);
|
||||
MSD_ReadFormatCapacity_Data[7] = (uint8_t)(MSD_Mass_Block_Count[lun]);
|
||||
|
||||
MSD_ReadFormatCapacity_Data[9] = (uint8_t)(MSD_Mass_Block_Size[lun] >> 16);
|
||||
MSD_ReadFormatCapacity_Data[10] = (uint8_t)(MSD_Mass_Block_Size[lun] >> 8);
|
||||
MSD_ReadFormatCapacity_Data[11] = (uint8_t)(MSD_Mass_Block_Size[lun]);
|
||||
MSD_Transfer_Data_Request(MSD_ReadFormatCapacity_Data, READ_FORMAT_CAPACITY_DATA_LEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_ReadCapacity10_Cmd
|
||||
* Description : SCSI ReadCapacity10 Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_ReadCapacity10_Cmd(uint8_t lun)
|
||||
{
|
||||
|
||||
if (MSD_MAL_GetStatus(lun))
|
||||
{
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
return;
|
||||
}
|
||||
|
||||
MSD_ReadCapacity10_Data[0] = (uint8_t)((MSD_Mass_Block_Count[lun] - 1) >> 24);
|
||||
MSD_ReadCapacity10_Data[1] = (uint8_t)((MSD_Mass_Block_Count[lun] - 1) >> 16);
|
||||
MSD_ReadCapacity10_Data[2] = (uint8_t)((MSD_Mass_Block_Count[lun] - 1) >> 8);
|
||||
MSD_ReadCapacity10_Data[3] = (uint8_t)((MSD_Mass_Block_Count[lun] - 1));
|
||||
|
||||
MSD_ReadCapacity10_Data[4] = (uint8_t)(MSD_Mass_Block_Size[lun] >> 24);
|
||||
MSD_ReadCapacity10_Data[5] = (uint8_t)(MSD_Mass_Block_Size[lun] >> 16);
|
||||
MSD_ReadCapacity10_Data[6] = (uint8_t)(MSD_Mass_Block_Size[lun] >> 8);
|
||||
MSD_ReadCapacity10_Data[7] = (uint8_t)(MSD_Mass_Block_Size[lun]);
|
||||
MSD_Transfer_Data_Request(MSD_ReadCapacity10_Data, READ_CAPACITY10_DATA_LEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_ModeSense6_Cmd
|
||||
* Description : SCSI ModeSense6 Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_ModeSense6_Cmd (uint8_t lun)
|
||||
{
|
||||
MSD_Transfer_Data_Request(MSD_Mode_Sense6_data, MODE_SENSE6_DATA_LEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_ModeSense10_Cmd
|
||||
* Description : SCSI ModeSense10 Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_ModeSense10_Cmd (uint8_t lun)
|
||||
{
|
||||
MSD_Transfer_Data_Request(MSD_Mode_Sense10_data, MODE_SENSE10_DATA_LEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_RequestSense_Cmd
|
||||
* Description : SCSI RequestSense Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_RequestSense_Cmd (uint8_t lun)
|
||||
{
|
||||
uint8_t Request_Sense_data_Length;
|
||||
|
||||
if (MSD_CBW.CB[4] <= REQUEST_SENSE_DATA_LEN)
|
||||
{
|
||||
Request_Sense_data_Length = MSD_CBW.CB[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
Request_Sense_data_Length = REQUEST_SENSE_DATA_LEN;
|
||||
}
|
||||
MSD_Transfer_Data_Request(MSD_Scsi_Sense_Data, Request_Sense_data_Length);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_Set_Scsi_Sense_Data
|
||||
* Description : Set Scsi Sense Data routine.
|
||||
* Input : uint8_t Sens_Key
|
||||
uint8_t Asc.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_Set_Scsi_Sense_Data(uint8_t lun, uint8_t Sens_Key, uint8_t Asc)
|
||||
{
|
||||
MSD_Scsi_Sense_Data[2] = Sens_Key;
|
||||
MSD_Scsi_Sense_Data[12] = Asc;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Start_Stop_Unit_Cmd
|
||||
* Description : SCSI Start_Stop_Unit Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Start_Stop_Unit_Cmd(uint8_t lun)
|
||||
{
|
||||
MSD_Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Read10_Cmd
|
||||
* Description : SCSI Read10 Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Read10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr)
|
||||
{
|
||||
|
||||
if (MSD_Bot_State == BOT_IDLE)
|
||||
{
|
||||
if (!(MSD_SCSI_Address_Management(MSD_CBW.bLUN, SCSI_READ10, LBA, BlockNbr)))/*address out of range*/
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((MSD_CBW.bmFlags & 0x80) != 0)
|
||||
{
|
||||
MSD_Bot_State = BOT_DATA_IN;
|
||||
MSD_Read_Memory(lun, LBA , BlockNbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (MSD_Bot_State == BOT_DATA_IN)
|
||||
{
|
||||
MSD_Read_Memory(lun , LBA , BlockNbr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Write10_Cmd
|
||||
* Description : SCSI Write10 Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Write10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr)
|
||||
{
|
||||
|
||||
if (MSD_Bot_State == BOT_IDLE)
|
||||
{
|
||||
if (!(MSD_SCSI_Address_Management(MSD_CBW.bLUN, SCSI_WRITE10 , LBA, BlockNbr)))/*address out of range*/
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((MSD_CBW.bmFlags & 0x80) == 0)
|
||||
{
|
||||
MSD_Bot_State = BOT_DATA_OUT;
|
||||
SetEPRxStatus(ENDP2, EP_RX_VALID);
|
||||
}
|
||||
else
|
||||
{
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (MSD_Bot_State == BOT_DATA_OUT)
|
||||
{
|
||||
MSD_Write_Memory(lun , LBA , BlockNbr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Verify10_Cmd
|
||||
* Description : SCSI Verify10 Command routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Verify10_Cmd(uint8_t lun)
|
||||
{
|
||||
if ((MSD_CBW.dDataLength == 0) && !(MSD_CBW.CB[1] & BLKVFY))/* BLKVFY not set*/
|
||||
{
|
||||
MSD_Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Valid_Cmd
|
||||
* Description : Valid Commands routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Valid_Cmd(uint8_t lun)
|
||||
{
|
||||
if (MSD_CBW.dDataLength != 0)
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
}
|
||||
else
|
||||
MSD_Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Valid_Cmd
|
||||
* Description : Valid Commands routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_TestUnitReady_Cmd(uint8_t lun)
|
||||
{
|
||||
if (MSD_MAL_GetStatus(lun))
|
||||
{
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSD_Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Format_Cmd
|
||||
* Description : Format Commands routine.
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Format_Cmd(uint8_t lun)
|
||||
{
|
||||
if (MSD_MAL_GetStatus(lun))
|
||||
{
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
return;
|
||||
}
|
||||
#ifdef USE_STM3210E_EVAL
|
||||
else
|
||||
{
|
||||
NAND_Format();
|
||||
MSD_Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Invalid_Cmd
|
||||
* Description : Invalid Commands routine
|
||||
* Input : None.
|
||||
* Output : None.
|
||||
* Return : None.
|
||||
*******************************************************************************/
|
||||
void MSD_SCSI_Invalid_Cmd(uint8_t lun)
|
||||
{
|
||||
if (MSD_CBW.dDataLength == 0)
|
||||
{
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((MSD_CBW.bmFlags & 0x80) != 0)
|
||||
{
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
}
|
||||
else
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
}
|
||||
}
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : MSD_SCSI_Address_Management
|
||||
* Description : Test the received address.
|
||||
* Input : uint8_t Cmd : the command can be SCSI_READ10 or SCSI_WRITE10.
|
||||
* Output : None.
|
||||
* Return : Read\Write status (bool).
|
||||
*******************************************************************************/
|
||||
bool MSD_SCSI_Address_Management(uint8_t lun , uint8_t Cmd , uint32_t LBA , uint32_t BlockNbr)
|
||||
{
|
||||
|
||||
if ((LBA + BlockNbr) > MSD_Mass_Block_Count[lun] )
|
||||
{
|
||||
if (Cmd == SCSI_WRITE10)
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
}
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
MSD_Set_Scsi_Sense_Data(lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
if (MSD_CBW.dDataLength != BlockNbr * MSD_Mass_Block_Size[lun])
|
||||
{
|
||||
if (Cmd == SCSI_WRITE10)
|
||||
{
|
||||
MSD_Bot_Abort(BOTH_DIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
MSD_Bot_Abort(DIR_IN);
|
||||
}
|
||||
MSD_Set_Scsi_Sense_Data(MSD_CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
|
||||
MSD_Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
142
flight/Libraries/msd/msd_scsi.h
Normal file
142
flight/Libraries/msd/msd_scsi.h
Normal file
@ -0,0 +1,142 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : usb_scsi.h
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : All processing related to the SCSI commands
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USB_SCSI_H
|
||||
#define __USB_SCSI_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f10x.h"
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* SCSI Commands */
|
||||
#define SCSI_FORMAT_UNIT 0x04
|
||||
#define SCSI_INQUIRY 0x12
|
||||
#define SCSI_MODE_SELECT6 0x15
|
||||
#define SCSI_MODE_SELECT10 0x55
|
||||
#define SCSI_MODE_SENSE6 0x1A
|
||||
#define SCSI_MODE_SENSE10 0x5A
|
||||
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
|
||||
#define SCSI_READ6 0x08
|
||||
#define SCSI_READ10 0x28
|
||||
#define SCSI_READ12 0xA8
|
||||
#define SCSI_READ16 0x88
|
||||
|
||||
#define SCSI_READ_CAPACITY10 0x25
|
||||
#define SCSI_READ_CAPACITY16 0x9E
|
||||
|
||||
#define SCSI_REQUEST_SENSE 0x03
|
||||
#define SCSI_START_STOP_UNIT 0x1B
|
||||
#define SCSI_TEST_UNIT_READY 0x00
|
||||
#define SCSI_WRITE6 0x0A
|
||||
#define SCSI_WRITE10 0x2A
|
||||
#define SCSI_WRITE12 0xAA
|
||||
#define SCSI_WRITE16 0x8A
|
||||
|
||||
#define SCSI_VERIFY10 0x2F
|
||||
#define SCSI_VERIFY12 0xAF
|
||||
#define SCSI_VERIFY16 0x8F
|
||||
|
||||
#define SCSI_SEND_DIAGNOSTIC 0x1D
|
||||
#define SCSI_READ_FORMAT_CAPACITIES 0x23
|
||||
|
||||
#define NO_SENSE 0
|
||||
#define RECOVERED_ERROR 1
|
||||
#define NOT_READY 2
|
||||
#define MEDIUM_ERROR 3
|
||||
#define HARDWARE_ERROR 4
|
||||
#define ILLEGAL_REQUEST 5
|
||||
#define UNIT_ATTENTION 6
|
||||
#define DATA_PROTECT 7
|
||||
#define BLANK_CHECK 8
|
||||
#define VENDOR_SPECIFIC 9
|
||||
#define COPY_ABORTED 10
|
||||
#define ABORTED_COMMAND 11
|
||||
#define VOLUME_OVERFLOW 13
|
||||
#define MISCOMPARE 14
|
||||
|
||||
|
||||
#define INVALID_COMMAND 0x20
|
||||
#define INVALID_FIELED_IN_COMMAND 0x24
|
||||
#define PARAMETER_LIST_LENGTH_ERROR 0x1A
|
||||
#define INVALID_FIELD_IN_PARAMETER_LIST 0x26
|
||||
#define ADDRESS_OUT_OF_RANGE 0x21
|
||||
#define MEDIUM_NOT_PRESENT 0x3A
|
||||
#define MEDIUM_HAVE_CHANGED 0x28
|
||||
|
||||
#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C
|
||||
#define READ_CAPACITY10_DATA_LEN 0x08
|
||||
#define MODE_SENSE10_DATA_LEN 0x08
|
||||
#define MODE_SENSE6_DATA_LEN 0x04
|
||||
#define REQUEST_SENSE_DATA_LEN 0x12
|
||||
#define STANDARD_INQUIRY_DATA_LEN 0x24
|
||||
#define BLKVFY 0x04
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
extern void MSD_SCSI_Inquiry_Cmd(uint8_t lun);
|
||||
extern void MSD_SCSI_ReadFormatCapacity_Cmd(uint8_t lun);
|
||||
extern void MSD_SCSI_ReadCapacity10_Cmd(uint8_t lun);
|
||||
extern void MSD_SCSI_RequestSense_Cmd (uint8_t lun);
|
||||
extern void MSD_SCSI_Start_Stop_Unit_Cmd(uint8_t lun);
|
||||
extern void MSD_SCSI_ModeSense6_Cmd (uint8_t lun);
|
||||
extern void MSD_SCSI_ModeSense10_Cmd (uint8_t lun);
|
||||
extern void MSD_SCSI_Write10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr);
|
||||
extern void MSD_SCSI_Read10_Cmd(uint8_t lun , uint32_t LBA , uint32_t BlockNbr);
|
||||
extern void MSD_SCSI_Verify10_Cmd(uint8_t lun);
|
||||
|
||||
extern void MSD_SCSI_Invalid_Cmd(uint8_t lun);
|
||||
extern void MSD_SCSI_Valid_Cmd(uint8_t lun);
|
||||
extern bool MSD_SCSI_Address_Management(uint8_t lun , uint8_t Cmd , uint32_t LBA , uint32_t BlockNbr);
|
||||
|
||||
extern void MSD_Set_Scsi_Sense_Data(uint8_t lun , uint8_t Sens_Key, uint8_t Asc);
|
||||
extern void MSD_SCSI_TestUnitReady_Cmd (uint8_t lun);
|
||||
extern void MSD_SCSI_Format_Cmd (uint8_t lun);
|
||||
|
||||
//#define MSD_SCSI_TestUnitReady_Cmd MSD_SCSI_Valid_Cmd
|
||||
#define MSD_SCSI_Prevent_Removal_Cmd MSD_SCSI_Valid_Cmd
|
||||
|
||||
/* Invalid (Unsupported) commands */
|
||||
#define MSD_SCSI_READ_CAPACITY16_Cmd MSD_SCSI_Invalid_Cmd
|
||||
//#define MSD_SCSI_FormatUnit_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Write6_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Write16_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Write12_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Read6_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Read12_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Read16_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Send_Diagnostic_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Mode_Select6_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Mode_Select10_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Verify12_Cmd MSD_SCSI_Invalid_Cmd
|
||||
#define MSD_SCSI_Verify16_Cmd MSD_SCSI_Invalid_Cmd
|
||||
|
||||
|
||||
/* Exported variables ------------------------------------------------------- */
|
||||
extern uint8_t MSD_Page00_Inquiry_Data[];
|
||||
extern uint8_t MSD_Standard_Inquiry_Data[];
|
||||
extern uint8_t MSD_Standard_Inquiry_Data2[];
|
||||
extern uint8_t MSD_Mode_Sense6_data[];
|
||||
extern uint8_t MSD_Mode_Sense10_data[];
|
||||
extern uint8_t MSD_Scsi_Sense_Data[];
|
||||
extern uint8_t MSD_ReadCapacity10_Data[];
|
||||
extern uint8_t MSD_ReadFormatCapacity_Data [];
|
||||
|
||||
|
||||
#endif /* __USB_SCSI_H */
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
144
flight/Libraries/msd/msd_scsi_data.c
Normal file
144
flight/Libraries/msd/msd_scsi_data.c
Normal file
@ -0,0 +1,144 @@
|
||||
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
||||
* File Name : scsi_data.c
|
||||
* Author : MCD Application Team
|
||||
* Version : V3.0.1
|
||||
* Date : 04/27/2009
|
||||
* Description : Initialization of the SCSI data
|
||||
********************************************************************************
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
||||
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
||||
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
||||
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*******************************************************************************/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "msd_scsi.h"
|
||||
#include "msd_memory.h"
|
||||
uint8_t MSD_Page00_Inquiry_Data[] =
|
||||
{
|
||||
0x00, /* PERIPHERAL QUALIFIER & PERIPHERAL DEVICE TYPE*/
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00 /* Supported Pages 00*/
|
||||
};
|
||||
uint8_t MSD_Standard_Inquiry_Data[] =
|
||||
{
|
||||
0x00, /* Direct Access Device */
|
||||
0x80, /* RMB = 1: Removable Medium */
|
||||
0x02, /* Version: No conformance claim to standard */
|
||||
0x02,
|
||||
|
||||
36 - 4, /* Additional Length */
|
||||
0x00, /* SCCS = 1: Storage Controller Component */
|
||||
0x00,
|
||||
0x00,
|
||||
/* Vendor Identification */
|
||||
'G', 'e', 'n', 'e', 'r', 'i', 'c', ' ',
|
||||
/* Product Identification */
|
||||
'S', 'D', ' ', 'C', 'a', 'r', 'd', ' ',
|
||||
'R', 'e', 'a', 'd', 'e', 'r', ' ', ' ',
|
||||
/* Product Revision Level */
|
||||
'1', '.', '0', ' '
|
||||
};
|
||||
uint8_t MSD_Standard_Inquiry_Data2[] =
|
||||
{
|
||||
0x00, /* Direct Access Device */
|
||||
0x80, /* RMB = 1: Removable Medium */
|
||||
0x02, /* Version: No conformance claim to standard */
|
||||
0x02,
|
||||
|
||||
36 - 4, /* Additional Length */
|
||||
0x00, /* SCCS = 1: Storage Controller Component */
|
||||
0x00,
|
||||
0x00,
|
||||
/* Vendor Identification */
|
||||
'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ',
|
||||
/* Product Identification */
|
||||
'N', 'A', 'N', 'D', ' ', 'F', 'l', 'a', 's', 'h', ' ',
|
||||
'D', 'i', 's', 'k', ' ',
|
||||
/* Product Revision Level */
|
||||
'1', '.', '0', ' '
|
||||
};
|
||||
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||||
uint8_t MSD_Mode_Sense6_data[] =
|
||||
{
|
||||
0x03,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||||
|
||||
uint8_t MSD_Mode_Sense10_data[] =
|
||||
{
|
||||
0x00,
|
||||
0x06,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
uint8_t MSD_Scsi_Sense_Data[] =
|
||||
{
|
||||
0x70, /*RespCode*/
|
||||
0x00, /*SegmentNumber*/
|
||||
NO_SENSE, /* Sens_Key*/
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, /*Information*/
|
||||
0x0A, /*AdditionalSenseLength*/
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, /*CmdInformation*/
|
||||
NO_SENSE, /*Asc*/
|
||||
0x00, /*ASCQ*/
|
||||
0x00, /*FRUC*/
|
||||
0x00, /*TBD*/
|
||||
0x00,
|
||||
0x00 /*SenseKeySpecific*/
|
||||
};
|
||||
uint8_t MSD_ReadCapacity10_Data[] =
|
||||
{
|
||||
/* Last Logical Block */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
/* Block Length */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
uint8_t MSD_ReadFormatCapacity_Data [] =
|
||||
{
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x08, /* Capacity List Length */
|
||||
|
||||
/* Block Count */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
||||
/* Block Length */
|
||||
0x02,/* Descriptor Code: Formatted Media */
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
@ -33,9 +33,9 @@ CODE_SOURCERY=NO
|
||||
TCHAIN_PREFIX = arm-none-eabi-
|
||||
|
||||
ifeq ($(CODE_SOURCERY), YES)
|
||||
REMOVE_CMD=cs-rm
|
||||
REMOVE_CMD = cs-rm
|
||||
else
|
||||
REMOVE_CMD=rm
|
||||
REMOVE_CMD = rm
|
||||
endif
|
||||
|
||||
FLASH_TOOL = OPENOCD
|
||||
@ -76,6 +76,7 @@ STMUSBSRCDIR = $(STMUSBDIR)/src
|
||||
STMUSBINCDIR = $(STMUSBDIR)/inc
|
||||
CMSISDIR = $(STMLIBDIR)/CMSIS/Core/CM3
|
||||
DOSFSDIR = $(APPLIBDIR)/dosfs
|
||||
MSDDIR = $(APPLIBDIR)/msd
|
||||
MININIDIR = $(APPLIBDIR)/minIni
|
||||
RTOSDIR = $(APPLIBDIR)/FreeRTOS
|
||||
RTOSSRCDIR = $(RTOSDIR)/Source
|
||||
@ -103,6 +104,7 @@ SRC += $(PIOSSTM32F10X)/pios_servo.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_i2c.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_spi.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_pwm.c
|
||||
SRC += $(PIOSSTM32F10X)/pios_usb.c
|
||||
|
||||
## PIOS Hardware (Common)
|
||||
SRC += $(PIOSCOMMON)/pios_sdcard.c
|
||||
@ -134,10 +136,11 @@ SRC += $(STMSPDSRCDIR)/stm32f10x_usart.c
|
||||
SRC += $(STMSPDSRCDIR)/misc.c
|
||||
|
||||
## STM32 USB Library
|
||||
#SRC += $(STMUSBSRCDIR)/usb_core.c
|
||||
#SRC += $(STMUSBSRCDIR)/usb_int.c
|
||||
#SRC += $(STMUSBSRCDIR)/usb_mem.c
|
||||
#SRC += $(STMUSBSRCDIR)/usb_regs.c
|
||||
SRC += $(STMUSBSRCDIR)/usb_core.c
|
||||
SRC += $(STMUSBSRCDIR)/usb_init.c
|
||||
SRC += $(STMUSBSRCDIR)/usb_int.c
|
||||
SRC += $(STMUSBSRCDIR)/usb_mem.c
|
||||
SRC += $(STMUSBSRCDIR)/usb_regs.c
|
||||
|
||||
## RTOS
|
||||
SRC += $(RTOSSRCDIR)/list.c
|
||||
@ -156,6 +159,14 @@ SRC += $(DOSFSDIR)/dfs_sdcard.c
|
||||
SRC += $(MININIDIR)/minIni.c
|
||||
SRC += $(MININIDIR)/minGlue.c
|
||||
|
||||
## Mass Storage Device
|
||||
SRC += $(MSDDIR)/msd.c
|
||||
SRC += $(MSDDIR)/msd_bot.c
|
||||
SRC += $(MSDDIR)/msd_desc.c
|
||||
SRC += $(MSDDIR)/msd_memory.c
|
||||
SRC += $(MSDDIR)/msd_scsi.c
|
||||
SRC += $(MSDDIR)/msd_scsi_data.c
|
||||
|
||||
# List C source files here which must be compiled in ARM-Mode (no -mthumb).
|
||||
# use file-extension c for "c-only"-files
|
||||
## just for testing, timer.c could be compiled in thumb-mode too
|
||||
@ -191,12 +202,13 @@ EXTRAINCDIRS += $(PIOSINC)
|
||||
EXTRAINCDIRS += $(PIOSSTM32F10X)
|
||||
EXTRAINCDIRS += $(PIOSCOMMON)
|
||||
EXTRAINCDIRS += $(STMSPDINCDIR)
|
||||
EXTRAINCDIRS += $(STMUSBINCDIR)
|
||||
EXTRAINCDIRS += $(CMSISDIR)
|
||||
EXTRAINCDIRS += $(DOSFSDIR)
|
||||
EXTRAINCDIRS += $(MSDDIR)
|
||||
EXTRAINCDIRS += $(MININIDIR)
|
||||
EXTRAINCDIRS += $(RTOSINCDIR)
|
||||
EXTRAINCDIRS += $(RTOSSRCDIR)/portable/GCC/ARM_CM3
|
||||
EXTRAINCDIRS += $(STMUSBINCDIR)
|
||||
|
||||
|
||||
# List any extra directories to look for library files here.
|
||||
@ -241,7 +253,6 @@ DEBUGF = dwarf-2
|
||||
CDEFS = -DSTM32F10X_$(MODEL)
|
||||
CDEFS += -DUSE_STDPERIPH_DRIVER
|
||||
CDEFS += -DUSE_$(BOARD)
|
||||
CDEFS += -DSTM32_SD_USE_DMA
|
||||
|
||||
# Place project-specific -D and/or -U options for
|
||||
# Assembler with preprocessor here.
|
||||
|
@ -2,7 +2,7 @@
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_com.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
|
||||
* @brief COM layer functions
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup PIOS_COM COM layer functions
|
||||
|
@ -130,7 +130,7 @@ int32_t PIOS_SDCARD_PowerOn(void)
|
||||
PIOS_SPI_RC_PinSet(PIOS_SDCARD_SPI, 0); /* spi, pin_value */
|
||||
|
||||
/* wait for 1 mS */
|
||||
PIOS_DELAY_Wait_uS(1000);
|
||||
PIOS_DELAY_WaituS(1000);
|
||||
|
||||
/* Send CMD0 to reset the media */
|
||||
if((status = PIOS_SDCARD_SendSDCCmd(SDCMD_GO_IDLE_STATE, 0, SDCMD_GO_IDLE_STATE_CRC)) < 0) {
|
||||
|
@ -74,7 +74,7 @@ int32_t PIOS_DELAY_Init(void)
|
||||
* \param[in] uS delay (1..65535 microseconds)
|
||||
* \return < 0 on errors
|
||||
*/
|
||||
int32_t PIOS_DELAY_Wait_uS(uint16_t uS)
|
||||
int32_t PIOS_DELAY_WaituS(uint16_t uS)
|
||||
{
|
||||
uint16_t start = PIOS_DELAY_TIMER->CNT;
|
||||
|
||||
@ -96,10 +96,10 @@ int32_t PIOS_DELAY_Wait_uS(uint16_t uS)
|
||||
* \param[in] mS delay (1..65535 milliseconds)
|
||||
* \return < 0 on errors
|
||||
*/
|
||||
int32_t PIOS_DELAY_Wait_mS(uint16_t mS)
|
||||
int32_t PIOS_DELAY_WaitmS(uint16_t mS)
|
||||
{
|
||||
for(int i = 0; i < mS; i++) {
|
||||
PIOS_DELAY_Wait_uS(1000);
|
||||
PIOS_DELAY_WaituS(1000);
|
||||
}
|
||||
|
||||
/* No error */
|
||||
|
@ -55,7 +55,7 @@ int32_t PIOS_IRQ_Disable(void)
|
||||
);
|
||||
}
|
||||
|
||||
/* disable interrupts */
|
||||
/* Disable interrupts */
|
||||
__asm volatile ( \
|
||||
" mov r0, #1 \n" \
|
||||
" msr primask, r0\n" \
|
||||
|
@ -102,15 +102,17 @@ void TIM3_IRQHandler(void)
|
||||
/* Get the Input Capture value */
|
||||
IC3Value = TIM_GetCapture3(TIM3);
|
||||
|
||||
// if (IC3Value != 0)
|
||||
// {
|
||||
// /* Duty cycle computation */
|
||||
// DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC3Value;
|
||||
//
|
||||
// /* Frequency computation */
|
||||
// Frequency = 72000000 / IC3Value;
|
||||
// } else {
|
||||
// DutyCycle = 0;
|
||||
// Frequency = 0;
|
||||
// }
|
||||
#if 0
|
||||
if (IC3Value != 0)
|
||||
{
|
||||
/* Duty cycle computation */
|
||||
DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC3Value;
|
||||
|
||||
/* Frequency computation */
|
||||
Frequency = 72000000 / IC3Value;
|
||||
} else {
|
||||
DutyCycle = 0;
|
||||
Frequency = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -33,6 +33,9 @@
|
||||
void NVIC_Configuration(void);
|
||||
void SysTick_Handler(void);
|
||||
|
||||
/* Local Macros */
|
||||
#define MEM8(addr) (*((volatile uint8_t *)(addr)))
|
||||
|
||||
/**
|
||||
* Initializes all system peripherals
|
||||
*/
|
||||
@ -75,6 +78,30 @@ void PIOS_SYS_Init(void)
|
||||
PIOS_LED_Init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serial number as a string
|
||||
* param[out] str pointer to a string which can store at least 32 digits + zero terminator!
|
||||
* (24 digits returned for STM32)
|
||||
* return < 0 if feature not supported
|
||||
*/
|
||||
int32_t PIOS_SYS_SerialNumberGet(char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Stored in the so called "electronic signature" */
|
||||
for(i=0; i<24; ++i) {
|
||||
uint8_t b = MEM8(0x1ffff7e8 + (i/2));
|
||||
if( !(i & 1) )
|
||||
b >>= 4;
|
||||
b &= 0x0f;
|
||||
|
||||
str[i] = ((b > 9) ? ('A'-10) : '0') + b;
|
||||
}
|
||||
str[i] = 0;
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Vector Table base location and SysTick
|
||||
|
484
flight/PiOS/STM32F10x/pios_usb.c
Normal file
484
flight/PiOS/STM32F10x/pios_usb.c
Normal file
@ -0,0 +1,484 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_usb.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
|
||||
* Parts by Thorsten Klose (tk@midibox.org)
|
||||
* @brief USB functions
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @defgroup PIOS_USB USB Functions
|
||||
* @{
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Project Includes */
|
||||
#include "pios.h"
|
||||
#define PIOS_DONT_USE_USB_MIDI
|
||||
#define PIOS_USE_USB_COM
|
||||
|
||||
/* Private Function Prototypes */
|
||||
|
||||
/* Local Variables */
|
||||
|
||||
#include <usb_lib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Local definitions */
|
||||
#define DSCR_DEVICE 1 /* Descriptor type: Device */
|
||||
#define DSCR_CONFIG 2 /* Descriptor type: Configuration */
|
||||
#define DSCR_STRING 3 /* Descriptor type: String */
|
||||
#define DSCR_INTRFC 4 /* Descriptor type: Interface */
|
||||
#define DSCR_ENDPNT 5 /* Descriptor type: Endpoint */
|
||||
#define CS_INTERFACE 0x24 /* Class-specific type: Interface */
|
||||
#define CS_ENDPOINT 0x25 /* Class-specific type: Endpoint */
|
||||
/* ISTR events */
|
||||
/* mask defining which events has to be handled by the device application software */
|
||||
#define IMR_MSK (CNTR_CTRM | CNTR_RESETM)
|
||||
|
||||
/* Local types */
|
||||
typedef enum _DEVICE_STATE {
|
||||
UNCONNECTED, ATTACHED, POWERED, SUSPENDED, ADDRESSED, CONFIGURED
|
||||
} DEVICE_STATE;
|
||||
|
||||
/* Global Variables used by STM32 USB Driver */
|
||||
/* (unfortunately no unique names are used...) */
|
||||
/* Points to the DEVICE_INFO/DEVICE_PROP_USER_STANDARD_REQUESTS structure of current device */
|
||||
/* The purpose of this register is to speed up the execution */
|
||||
DEVICE_INFO *pInformation;
|
||||
DEVICE Device_Table;
|
||||
DEVICE_PROP *pProperty;
|
||||
USER_STANDARD_REQUESTS *pUser_Standard_Requests;
|
||||
|
||||
/* Stored in RAM, vectors can be changed on-the-fly */
|
||||
void (*pEpInt_IN[7])(void) = {NOP_Process, NOP_Process, NOP_Process, NOP_Process, NOP_Process, NOP_Process, NOP_Process};
|
||||
void (*pEpInt_OUT[7])(void) = {NOP_Process, NOP_Process, NOP_Process, NOP_Process, NOP_Process, NOP_Process, NOP_Process};
|
||||
|
||||
#define PIOS_USB_NUM_INTERFACES (0)
|
||||
#define PIOS_USB_SIZ_CONFIG_DESC (9 + 0)
|
||||
|
||||
/* USB Standard Device Descriptor */
|
||||
#define PIOS_USB_SIZ_DEVICE_DESC 18
|
||||
static const uint8_t PIOS_USB_DeviceDescriptor[PIOS_USB_SIZ_DEVICE_DESC] = {(uint8_t)(PIOS_USB_SIZ_DEVICE_DESC & 0xff), /* Device Descriptor length */
|
||||
DSCR_DEVICE, /* Descriptor type */
|
||||
(uint8_t)(0x0200 & 0xff), /* Specification Version (BCD, LSB) */
|
||||
(uint8_t)(0x0200 >> 8), /* Specification Version (BCD, MSB) */
|
||||
#if 1
|
||||
0x02, /* Device class "Communication" -- required for MacOS to find the COM device. Audio Device works fine in parallel to this */
|
||||
#else
|
||||
0x00, /* Device class "Composite" */
|
||||
#endif
|
||||
0x00, /* Device sub-class */
|
||||
0x00, /* Device sub-sub-class */
|
||||
0x40, /* Maximum packet size */
|
||||
(uint8_t)((PIOS_USB_VENDOR_ID) & 0xff), /* Vendor ID (LSB) */
|
||||
(uint8_t)((PIOS_USB_VENDOR_ID) >> 8), /* Vendor ID (MSB) */
|
||||
(uint8_t)((PIOS_USB_PRODUCT_ID) & 0xff), /* Product ID (LSB) */
|
||||
(uint8_t)((PIOS_USB_PRODUCT_ID) >> 8), /* Product ID (MSB) */
|
||||
(uint8_t)((PIOS_USB_VERSION_ID) & 0xff), /* Product version ID (LSB) */
|
||||
(uint8_t)((PIOS_USB_VERSION_ID) >> 8), /* Product version ID (MSB) */
|
||||
0x01, /* Manufacturer string index */
|
||||
0x02, /* Product string index */
|
||||
0x03, /* Serial number string index */
|
||||
0x01 /* Number of configurations */
|
||||
};
|
||||
|
||||
/* USB Config Descriptor */
|
||||
static const uint8_t PIOS_USB_ConfigDescriptor[PIOS_USB_SIZ_CONFIG_DESC] = {
|
||||
/* Configuration Descriptor */
|
||||
9, /* Descriptor length */
|
||||
DSCR_CONFIG, // Descriptor type */
|
||||
(PIOS_USB_SIZ_CONFIG_DESC) & 0xff, /* Config + End Points length (LSB) */
|
||||
(PIOS_USB_SIZ_CONFIG_DESC) >> 8, /* Config + End Points length (LSB) */
|
||||
PIOS_USB_NUM_INTERFACES, /* Number of interfaces */
|
||||
0x01, /* Configuration Value */
|
||||
0x00, /* Configuration string */
|
||||
0x80, /* Attributes (b7 - buspwr, b6 - selfpwr, b5 - rwu) */
|
||||
0x32, /* Power requirement (div 2 ma) */
|
||||
|
||||
/* TODO:HID */
|
||||
|
||||
};
|
||||
|
||||
/* Local prototypes */
|
||||
static void PIOS_USB_CB_Reset(void);
|
||||
static void PIOS_USB_CB_SetConfiguration(void);
|
||||
static void PIOS_USB_CB_SetDeviceAddress(void);
|
||||
static void PIOS_USB_CB_Status_In(void);
|
||||
static void PIOS_USB_CB_Status_Out(void);
|
||||
static RESULT PIOS_USB_CB_Data_Setup(uint8_t RequestNo);
|
||||
static RESULT PIOS_USB_CB_NoData_Setup(uint8_t RequestNo);
|
||||
static uint8_t *PIOS_USB_CB_GetDeviceDescriptor(uint16_t Length);
|
||||
static uint8_t *PIOS_USB_CB_GetConfigDescriptor(uint16_t Length);
|
||||
static uint8_t *PIOS_USB_CB_GetStringDescriptor(uint16_t Length);
|
||||
static RESULT PIOS_USB_CB_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
|
||||
|
||||
/* USB callback vectors */
|
||||
static const DEVICE My_Device_Table = {PIOS_USB_EP_NUM, 1};
|
||||
static const DEVICE_PROP My_Device_Property = {
|
||||
0, /* PIOS_USB_CB_Init, */
|
||||
PIOS_USB_CB_Reset, PIOS_USB_CB_Status_In, PIOS_USB_CB_Status_Out, PIOS_USB_CB_Data_Setup, PIOS_USB_CB_NoData_Setup,
|
||||
PIOS_USB_CB_Get_Interface_Setting, PIOS_USB_CB_GetDeviceDescriptor, PIOS_USB_CB_GetConfigDescriptor, PIOS_USB_CB_GetStringDescriptor, 0, 0x40 /*MAX PACKET SIZE*/
|
||||
};
|
||||
static const USER_STANDARD_REQUESTS My_User_Standard_Requests = {NOP_Process, /* PIOS_USB_CB_GetConfiguration, */
|
||||
PIOS_USB_CB_SetConfiguration, NOP_Process, /* PIOS_USB_CB_GetInterface, */
|
||||
NOP_Process, /* PIOS_USB_CB_SetInterface, */
|
||||
NOP_Process, /* PIOS_USB_CB_GetStatus, */
|
||||
NOP_Process, /* PIOS_USB_CB_ClearFeature, */
|
||||
NOP_Process, /* PIOS_USB_CB_SetEndPointFeature, */
|
||||
NOP_Process, /* PIOS_USB_CB_SetDeviceFeature, */
|
||||
PIOS_USB_CB_SetDeviceAddress};
|
||||
|
||||
/* Local Variables */
|
||||
/* USB Device informations */
|
||||
static DEVICE_INFO My_Device_Info;
|
||||
/* USB device status */
|
||||
static __IO uint32_t bDeviceState = UNCONNECTED;
|
||||
|
||||
/**
|
||||
* Initialises USB interface
|
||||
* \param[in] mode
|
||||
* <UL>
|
||||
* <LI>if 0, USB peripheral won't be initialised if this has already been done before
|
||||
* <LI>if 1, USB peripheral re-initialisation will be forced
|
||||
* <LI>if 2, USB peripheral re-initialisation will be forced, STM32 driver hooks won't be overwritten.<BR>
|
||||
* This mode can be used for a local USB driver which installs it's own hooks during runtime.<BR>
|
||||
* The application can switch back to MIOS32 drivers (e.g. PIOS_USB_MIDI) by calling PIOS_USB_Init(1)
|
||||
* </UL>
|
||||
* \return < 0 if initialisation failed
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
int32_t PIOS_USB_Init(uint32_t mode)
|
||||
{
|
||||
/* Currently only mode 0..2 supported */
|
||||
if(mode >= 3) {
|
||||
/* Unsupported mode */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clear all USB interrupt requests */
|
||||
PIOS_IRQ_Disable();
|
||||
_SetCNTR(0); /* Interrupt Mask */
|
||||
PIOS_IRQ_Enable();
|
||||
|
||||
/* if mode != 2: install PIOS hooks */
|
||||
/* a local driver can install it's own hooks and call PIOS_USB_Init(2) to force re-enumeration */
|
||||
if(mode != 2) {
|
||||
pInformation = &My_Device_Info; /* Note: usually no need to duplicate this for external drivers */
|
||||
|
||||
/* Following hooks/pointers should be replaced by external drivers */
|
||||
memcpy(&Device_Table, (DEVICE *) &My_Device_Table, sizeof(Device_Table));
|
||||
pProperty = (DEVICE_PROP *) &My_Device_Property;
|
||||
pUser_Standard_Requests = (USER_STANDARD_REQUESTS *) &My_User_Standard_Requests;
|
||||
}
|
||||
|
||||
pInformation->ControlState = 2;
|
||||
pInformation->Current_Configuration = 0;
|
||||
|
||||
/* if mode == 0: don't initialise USB if not required (important for BSL) */
|
||||
if(mode == 0 && PIOS_USB_IsInitialized()) {
|
||||
pInformation->Current_Feature = PIOS_USB_ConfigDescriptor[7];
|
||||
pInformation->Current_Configuration = 1;
|
||||
pUser_Standard_Requests->User_SetConfiguration();
|
||||
|
||||
} else {
|
||||
/* Force USB reset and power-down (this will also release the USB pins for direct GPIO control) */
|
||||
_SetCNTR(CNTR_FRES | CNTR_PDWN);
|
||||
|
||||
#if 0
|
||||
/* Disabled because it doesn't work, hardware needs to be looked into */
|
||||
/* Configure USB disconnect pin */
|
||||
/* first we hold it low for ca. 50 mS to force a re-enumeration */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_StructInit(&GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = USB_PULLUP_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(USB_ACC_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
GPIO_SetBits(USB_ACC_GPIO_PORT, USB_PULLUP_PIN);
|
||||
PIOS_DELAY_WaitmS(50);
|
||||
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
|
||||
GPIO_Init(USB_ACC_GPIO_PORT, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
/* Using a "dirty" method to force a re-enumeration: */
|
||||
/* Force DPM (Pin PA12) low for ca. 10 mS before USB Tranceiver will be enabled */
|
||||
/* This overrules the external Pull-Up at PA12, and at least Windows & MacOS will enumerate again */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_StructInit(&GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_ResetBits(USB_ACC_GPIO_PORT, USB_PULLUP_PIN);
|
||||
|
||||
PIOS_DELAY_WaitmS(50);
|
||||
|
||||
/* Release power-down, still hold reset */
|
||||
_SetCNTR(CNTR_PDWN);
|
||||
|
||||
PIOS_DELAY_WaituS(5);
|
||||
|
||||
/* CNTR_FRES = 0 */
|
||||
_SetCNTR(0);
|
||||
|
||||
/* Clear pending interrupts */
|
||||
_SetISTR(0);
|
||||
|
||||
/* Configure USB clock */
|
||||
/* USBCLK = PLLCLK / 1.5 */
|
||||
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
|
||||
/* Enable USB clock */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
|
||||
}
|
||||
|
||||
/* Don't set interrupt mask on custom driver installation */
|
||||
if(mode != 2) {
|
||||
/* Clear pending interrupts (again) */
|
||||
_SetISTR(0);
|
||||
|
||||
/* Set interrupts mask */
|
||||
_SetCNTR(IMR_MSK); /* Interrupt mask */
|
||||
}
|
||||
|
||||
bDeviceState = UNCONNECTED;
|
||||
|
||||
/* Enable USB interrupts (unfortunately shared with CAN Rx0, as either CAN or USB can be used, but not at the same time) */
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_USB_PRIORITY;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrupt handler for USB
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
void USB_LP_CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
uint16_t wIstr = _GetISTR();
|
||||
|
||||
if(wIstr & ISTR_RESET) {
|
||||
_SetISTR((uint16_t)CLR_RESET);
|
||||
pProperty->Reset();
|
||||
}
|
||||
|
||||
if(wIstr & ISTR_SOF) {
|
||||
_SetISTR((uint16_t)CLR_SOF);
|
||||
}
|
||||
|
||||
if(wIstr & ISTR_CTR) {
|
||||
/* Servicing of the endpoint correct transfer interrupt */
|
||||
/* Clear of the CTR flag into the sub */
|
||||
CTR_LP();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to query, if the USB interface has already been initialised.<BR>
|
||||
* This function is used by the bootloader to avoid a reconnection, it isn't
|
||||
* relevant for typical applications!
|
||||
* \return 1 if USB already initialised, 0 if not initialised
|
||||
*/
|
||||
int32_t PIOS_USB_IsInitialized(void)
|
||||
{
|
||||
/* We assume that initialisation has been done when endpoint 0 contains a value */
|
||||
return GetEPType(ENDP0) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Hooks of STM32 USB library
|
||||
* \note Applications shouldn't call this function directly, instead please use \ref PIOS_COM layer functions
|
||||
*/
|
||||
/**
|
||||
* Reset Routine
|
||||
*/
|
||||
static void PIOS_USB_CB_Reset(void)
|
||||
{
|
||||
/* Set MIOS32 Device as not configured */
|
||||
pInformation->Current_Configuration = 0;
|
||||
|
||||
/* Current Feature initialization */
|
||||
pInformation->Current_Feature = PIOS_USB_ConfigDescriptor[7];
|
||||
|
||||
/* Set PIOS Device with the default Interface */
|
||||
pInformation->Current_Interface = 0;
|
||||
SetBTABLE(PIOS_USB_BTABLE_ADDRESS);
|
||||
|
||||
/* Initialize Endpoint 0 */
|
||||
SetEPType(ENDP0, EP_CONTROL);
|
||||
SetEPTxStatus(ENDP0, EP_TX_STALL);
|
||||
SetEPRxAddr(ENDP0, PIOS_USB_ENDP0_RXADDR);
|
||||
SetEPTxAddr(ENDP0, PIOS_USB_ENDP0_TXADDR);
|
||||
Clear_Status_Out(ENDP0);
|
||||
SetEPRxCount(ENDP0, pProperty->MaxPacketSize);
|
||||
SetEPRxValid(ENDP0);
|
||||
|
||||
/* Set this device to response on default address */
|
||||
SetDeviceAddress(0);
|
||||
|
||||
bDeviceState = ATTACHED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the device state to configured
|
||||
*/
|
||||
static void PIOS_USB_CB_SetConfiguration(void)
|
||||
{
|
||||
if(pInformation->Current_Configuration != 0) {
|
||||
bDeviceState = CONFIGURED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the device state to addressed
|
||||
*/
|
||||
static void PIOS_USB_CB_SetDeviceAddress(void)
|
||||
{
|
||||
bDeviceState = ADDRESSED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status IN routine
|
||||
*/
|
||||
static void PIOS_USB_CB_Status_In(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Status OUT routine
|
||||
*/
|
||||
static void PIOS_USB_CB_Status_Out(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Data setup routine
|
||||
*/
|
||||
static RESULT PIOS_USB_CB_Data_Setup(uint8_t RequestNo)
|
||||
{
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the non data class specific requests
|
||||
*/
|
||||
static RESULT PIOS_USB_CB_NoData_Setup(uint8_t RequestNo)
|
||||
{
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device descriptor
|
||||
*/
|
||||
static uint8_t *PIOS_USB_CB_GetDeviceDescriptor(uint16_t Length)
|
||||
{
|
||||
ONE_DESCRIPTOR desc = {(uint8_t *) PIOS_USB_DeviceDescriptor, PIOS_USB_SIZ_DEVICE_DESC};
|
||||
return Standard_GetDescriptorData(Length, &desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration descriptor
|
||||
*/
|
||||
static uint8_t *PIOS_USB_CB_GetConfigDescriptor(uint16_t Length)
|
||||
{
|
||||
ONE_DESCRIPTOR desc = {(uint8_t *) PIOS_USB_ConfigDescriptor, PIOS_USB_SIZ_CONFIG_DESC};
|
||||
return Standard_GetDescriptorData(Length, &desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string descriptors according to the needed index
|
||||
*/
|
||||
static uint8_t *PIOS_USB_CB_GetStringDescriptor(uint16_t Length)
|
||||
{
|
||||
const uint8_t vendor_str[] = PIOS_USB_VENDOR_STR;
|
||||
const uint8_t product_str[] = PIOS_USB_PRODUCT_STR;
|
||||
|
||||
uint8_t buffer[200];
|
||||
uint16_t len;
|
||||
int i;
|
||||
|
||||
switch(pInformation->USBwValue0) {
|
||||
case 0: /* Language */
|
||||
/* buffer[0] and [1] initialized below */
|
||||
buffer[2] = 0x09; // CharSet
|
||||
buffer[3] = 0x04; // U.S.
|
||||
len = 4;
|
||||
break;
|
||||
|
||||
case 1: /* Vendor */
|
||||
/* buffer[0] and [1] initialized below */
|
||||
for(i = 0, len = 2; vendor_str[i] != '\0' && len < 200; ++i) {
|
||||
buffer[len++] = vendor_str[i];
|
||||
buffer[len++] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* Product */
|
||||
/* buffer[0] and [1] initialized below */
|
||||
for(i = 0, len = 2; product_str[i] != '\0' && len < 200; ++i) {
|
||||
buffer[len++] = product_str[i];
|
||||
buffer[len++] = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: { /* Serial Number */
|
||||
uint8_t serial_number_str[40];
|
||||
if(PIOS_SYS_SerialNumberGet((char *) serial_number_str) >= 0) {
|
||||
for(i = 0, len = 2; serial_number_str[i] != '\0' && len < 200; ++i) {
|
||||
buffer[len++] = serial_number_str[i];
|
||||
buffer[len++] = 0;
|
||||
}
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default: /* string ID not supported */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[0] = len; /* Descriptor Length */
|
||||
buffer[1] = DSCR_STRING; /* Descriptor Type */
|
||||
ONE_DESCRIPTOR desc = {(uint8_t *) buffer, len};
|
||||
return Standard_GetDescriptorData(Length, &desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the interface and the alternate setting according to the supported one.
|
||||
*/
|
||||
static RESULT PIOS_USB_CB_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
|
||||
{
|
||||
if(AlternateSetting > 0) {
|
||||
return USB_UNSUPPORT;
|
||||
} else if(Interface >= PIOS_USB_NUM_INTERFACES) {
|
||||
return USB_UNSUPPORT;
|
||||
}
|
||||
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
|
@ -32,10 +32,10 @@
|
||||
// DMA Channels Used
|
||||
//------------------------
|
||||
/* Channel 1 - */
|
||||
/* Channel 2 - SPI1 RX */
|
||||
/* Channel 3 - SPI1 TX */
|
||||
/* Channel 4 - SPI2 RX */
|
||||
/* Channel 5 - SPI2 TX */
|
||||
/* Channel 2 - SPI1 RX */
|
||||
/* Channel 3 - SPI1 TX */
|
||||
/* Channel 4 - SPI2 RX */
|
||||
/* Channel 5 - SPI2 TX */
|
||||
/* Channel 6 - */
|
||||
/* Channel 7 - */
|
||||
/* Channel 8 - */
|
||||
@ -47,49 +47,49 @@
|
||||
//------------------------
|
||||
// Leds Definition
|
||||
//------------------------
|
||||
#define LED1_GPIO_PORT GPIOC
|
||||
#define LED1_GPIO_PIN GPIO_Pin_12
|
||||
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOC
|
||||
#define LED2_GPIO_PORT GPIOC
|
||||
#define LED2_GPIO_PIN GPIO_Pin_13
|
||||
#define LED2_GPIO_CLK RCC_APB2Periph_GPIOC
|
||||
#define LED1_GPIO_PORT GPIOC
|
||||
#define LED1_GPIO_PIN GPIO_Pin_12
|
||||
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOC
|
||||
#define LED2_GPIO_PORT GPIOC
|
||||
#define LED2_GPIO_PIN GPIO_Pin_13
|
||||
#define LED2_GPIO_CLK RCC_APB2Periph_GPIOC
|
||||
#define NUM_LED 2
|
||||
|
||||
//------------------------
|
||||
// I2C
|
||||
//------------------------
|
||||
#define I2C_GPIO_PORT GPIOB
|
||||
#define I2C_GPIO_PORT GPIOB
|
||||
#define I2C_SDA_PIN GPIO_Pin_11
|
||||
#define I2C_SCL_PIN GPIO_Pin_10
|
||||
#define I2C_DUTY_CYCLE I2C_DutyCycle_2
|
||||
#define I2C_BUS_FREQUENCY 400000
|
||||
#define I2C_TIMEOUT_VALUE 5000
|
||||
#define IRQ_I2C_EV_PRIORITY 2
|
||||
#define IRQ_I2C_ER_PRIORITY 2
|
||||
#define I2C_DUTY_CYCLE I2C_DutyCycle_2
|
||||
#define I2C_BUS_FREQUENCY 400000
|
||||
#define I2C_TIMEOUT_VALUE 5000
|
||||
#define IRQ_I2C_EV_PRIORITY 2
|
||||
#define IRQ_I2C_ER_PRIORITY 2
|
||||
|
||||
//------------------------
|
||||
// Onboard Pressure sensor
|
||||
//------------------------
|
||||
#define BMP085_EOC_GPIO_PORT GPIOC
|
||||
#define BMP085_EOC_GPIO_PIN GPIO_Pin_15
|
||||
#define BMP085_EOC_PORT_SOURCE GPIO_PortSourceGPIOG
|
||||
#define BMP085_EOC_PIN_SOURCE GPIO_PinSource8
|
||||
#define BMP085_EOC_CLK RCC_APB2Periph_GPIOC
|
||||
#define BMP085_EOC_EXTI_LINE EXTI_Line15
|
||||
#define BMP085_EOC_IRQn EXTI15_10_IRQn
|
||||
#define BMP085_EOC_GPIO_PORT GPIOC
|
||||
#define BMP085_EOC_GPIO_PIN GPIO_Pin_15
|
||||
#define BMP085_EOC_PORT_SOURCE GPIO_PortSourceGPIOG
|
||||
#define BMP085_EOC_PIN_SOURCE GPIO_PinSource8
|
||||
#define BMP085_EOC_CLK RCC_APB2Periph_GPIOC
|
||||
#define BMP085_EOC_EXTI_LINE EXTI_Line15
|
||||
#define BMP085_EOC_IRQn EXTI15_10_IRQn
|
||||
|
||||
/* Unused, repurpose PA1 as another ADC input?
|
||||
#define BMP085_XCLR_GPIO_PORT GPIOA
|
||||
#define BMP085_XCLR_GPIO_PIN GPIO_Pin_1
|
||||
#define BMP085_XCLR_GPIO_PORT GPIOA
|
||||
#define BMP085_XCLR_GPIO_PIN GPIO_Pin_1
|
||||
*/
|
||||
|
||||
//-------------------------
|
||||
// GPS USART
|
||||
//-------------------------
|
||||
#define GPS_USART USART2
|
||||
#define GPS_USART USART2
|
||||
#define GPS_GPIO_PORT GPIOA
|
||||
#define GPS_RX_PIN GPIO_Pin_3
|
||||
#define GPS_TX_PIN GPIO_Pin_2
|
||||
#define GPS_RX_PIN GPIO_Pin_3
|
||||
#define GPS_TX_PIN GPIO_Pin_2
|
||||
#define GPS_REMAP_FUNC { }
|
||||
#define GPS_IRQ_CHANNEL USART2_IRQn
|
||||
#define GPS_IRQHANDLER_FUNC void USART2_IRQHandler(void)
|
||||
@ -105,7 +105,7 @@
|
||||
#define TELEM_TX_PIN GPIO_Pin_10
|
||||
#define TELEM_REMAP_FUNC { GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE); }
|
||||
#define TELEM_IRQ_CHANNEL USART3_IRQn
|
||||
#define TELEM_IRQHANDLER_FUNC void USART3_IRQHandler(void)
|
||||
#define TELEM_IRQHANDLER_FUNC void USART3_IRQHandler(void)
|
||||
#define TELEM_CLK_FUNC RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE)
|
||||
#define TELEM_NVIC_PRIO IRQ_PRIO_HIGHEST
|
||||
|
||||
@ -116,52 +116,52 @@
|
||||
#define AUX_USART_GPIO_PORT GPIOA
|
||||
#define AUX_USART_RX_PIN GPIO_Pin_10
|
||||
#define AUX_USART_TX_PIN GPIO_Pin_9
|
||||
#define AUX_USART_REMAP_FUNC { }
|
||||
#define AUX_USART_IRQ_CHANNEL USART1_IRQn
|
||||
#define AUX_USART_IRQHANDLER_FUNC void USART1_IRQHandler(void)
|
||||
#define AUX_USART_REMAP_FUNC { }
|
||||
#define AUX_USART_IRQ_CHANNEL USART1_IRQn
|
||||
#define AUX_USART_IRQHANDLER_FUNC void USART1_IRQHandler(void)
|
||||
#define AUX_USART_CLK_FUNC RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE)
|
||||
#define AUX_USART_NVIC_PRIO IRQ_PRIO_HIGH
|
||||
|
||||
//-------------------------
|
||||
// USART Serial Ports
|
||||
//-------------------------
|
||||
#define USART_NUM 3
|
||||
#define USART_RX_BUFFER_SIZE 1024
|
||||
#define USART_TX_BUFFER_SIZE 256
|
||||
#define USART_NUM 3
|
||||
#define USART_RX_BUFFER_SIZE 1024
|
||||
#define USART_TX_BUFFER_SIZE 256
|
||||
#define COM_DEBUG_PORT GPS
|
||||
|
||||
//-------------------------
|
||||
// SPI
|
||||
//-------------------------
|
||||
#define PIOS_IRQ_SPI_DMA_PRIORITY IRQ_PRIO_HIGH
|
||||
#define PIOS_SPI0_PTR SPI1
|
||||
#define PIOS_SPI0_DMA_RX_PTR DMA1_Channel2
|
||||
#define PIOS_SPI0_DMA_TX_PTR DMA1_Channel3
|
||||
#define PIOS_SPI0_DMA_RX_IRQ_FLAGS (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2)
|
||||
#define PIOS_SPI0_DMA_IRQ_CHANNEL DMA1_Channel2_IRQn
|
||||
#define PIOS_IRQ_SPI_DMA_PRIORITY IRQ_PRIO_HIGH
|
||||
#define PIOS_SPI0_PTR SPI1
|
||||
#define PIOS_SPI0_DMA_RX_PTR DMA1_Channel2
|
||||
#define PIOS_SPI0_DMA_TX_PTR DMA1_Channel3
|
||||
#define PIOS_SPI0_DMA_RX_IRQ_FLAGS (DMA1_FLAG_TC2 | DMA1_FLAG_TE2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2)
|
||||
#define PIOS_SPI0_DMA_IRQ_CHANNEL DMA1_Channel2_IRQn
|
||||
#define PIOS_SPI0_DMA_IRQHANDLER_FUNC void DMA1_Channel2_IRQHandler(void)
|
||||
#define PIOS_SPI0_RCLK1_PORT GPIOA
|
||||
#define PIOS_SPI0_RCLK1_PIN GPIO_Pin_4
|
||||
#define PIOS_SPI0_SCLK_PORT GPIOA
|
||||
#define PIOS_SPI0_SCLK_PIN GPIO_Pin_5
|
||||
#define PIOS_SPI0_MISO_PORT GPIOA
|
||||
#define PIOS_SPI0_MISO_PIN GPIO_Pin_6
|
||||
#define PIOS_SPI0_MOSI_PORT GPIOA
|
||||
#define PIOS_SPI0_MOSI_PIN GPIO_Pin_7
|
||||
#define PIOS_SPI1_PTR SPI2
|
||||
#define PIOS_SPI1_DMA_RX_PTR DMA1_Channel4
|
||||
#define PIOS_SPI1_DMA_TX_PTR DMA1_Channel5
|
||||
#define PIOS_SPI1_DMA_RX_IRQ_FLAGS (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4)
|
||||
#define PIOS_SPI1_DMA_IRQ_CHANNEL DMA1_Channel4_IRQn
|
||||
#define PIOS_SPI0_RCLK1_PORT GPIOA
|
||||
#define PIOS_SPI0_RCLK1_PIN GPIO_Pin_4
|
||||
#define PIOS_SPI0_SCLK_PORT GPIOA
|
||||
#define PIOS_SPI0_SCLK_PIN GPIO_Pin_5
|
||||
#define PIOS_SPI0_MISO_PORT GPIOA
|
||||
#define PIOS_SPI0_MISO_PIN GPIO_Pin_6
|
||||
#define PIOS_SPI0_MOSI_PORT GPIOA
|
||||
#define PIOS_SPI0_MOSI_PIN GPIO_Pin_7
|
||||
#define PIOS_SPI1_PTR SPI2
|
||||
#define PIOS_SPI1_DMA_RX_PTR DMA1_Channel4
|
||||
#define PIOS_SPI1_DMA_TX_PTR DMA1_Channel5
|
||||
#define PIOS_SPI1_DMA_RX_IRQ_FLAGS (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4)
|
||||
#define PIOS_SPI1_DMA_IRQ_CHANNEL DMA1_Channel4_IRQn
|
||||
#define PIOS_SPI1_DMA_IRQHANDLER_FUNC void DMA1_Channel4_IRQHandler(void)
|
||||
#define PIOS_SPI1_RCLK1_PORT GPIOB
|
||||
#define PIOS_SPI1_RCLK1_PIN GPIO_Pin_12
|
||||
#define PIOS_SPI1_SCLK_PORT GPIOB
|
||||
#define PIOS_SPI1_SCLK_PIN GPIO_Pin_13
|
||||
#define PIOS_SPI1_MISO_PORT GPIOB
|
||||
#define PIOS_SPI1_MISO_PIN GPIO_Pin_14
|
||||
#define PIOS_SPI1_MOSI_PORT GPIOB
|
||||
#define PIOS_SPI1_MOSI_PIN GPIO_Pin_15
|
||||
#define PIOS_SPI1_RCLK1_PORT GPIOB
|
||||
#define PIOS_SPI1_RCLK1_PIN GPIO_Pin_12
|
||||
#define PIOS_SPI1_SCLK_PORT GPIOB
|
||||
#define PIOS_SPI1_SCLK_PIN GPIO_Pin_13
|
||||
#define PIOS_SPI1_MISO_PORT GPIOB
|
||||
#define PIOS_SPI1_MISO_PIN GPIO_Pin_14
|
||||
#define PIOS_SPI1_MOSI_PORT GPIOB
|
||||
#define PIOS_SPI1_MOSI_PIN GPIO_Pin_15
|
||||
|
||||
//-------------------------
|
||||
// SDCard
|
||||
@ -213,24 +213,24 @@
|
||||
// Servo outputs
|
||||
//-------------------------
|
||||
#define SERVO1TO4_PORT GPIOB
|
||||
#define SERVO1_PIN GPIO_Pin_6
|
||||
#define SERVO2_PIN GPIO_Pin_7
|
||||
#define SERVO3_PIN GPIO_Pin_8
|
||||
#define SERVO4_PIN GPIO_Pin_9
|
||||
#define SERVO1_PIN GPIO_Pin_6
|
||||
#define SERVO2_PIN GPIO_Pin_7
|
||||
#define SERVO3_PIN GPIO_Pin_8
|
||||
#define SERVO4_PIN GPIO_Pin_9
|
||||
#define SERVO5TO8_PORT GPIOC
|
||||
#define SERVO5_PIN GPIO_Pin_6
|
||||
#define SERVO6_PIN GPIO_Pin_7
|
||||
#define SERVO7_PIN GPIO_Pin_8
|
||||
#define SERVO8_PIN GPIO_Pin_9
|
||||
#define SERVO5_PIN GPIO_Pin_6
|
||||
#define SERVO6_PIN GPIO_Pin_7
|
||||
#define SERVO7_PIN GPIO_Pin_8
|
||||
#define SERVO8_PIN GPIO_Pin_9
|
||||
#define NUM_SERVO_OUTPUTS 8
|
||||
|
||||
//-------------------------
|
||||
// ADC
|
||||
//-------------------------
|
||||
#define ADC_GPIO_PORT GPIOC
|
||||
#define ADC_Z_PIN GPIO_Pin_0 // ADC123_IN10
|
||||
#define ADC_A_PIN GPIO_Pin_1 // ADC123_IN11
|
||||
#define ADC_B_PIN GPIO_Pin_2 // ADC123_IN12
|
||||
#define ADC_Z_PIN GPIO_Pin_0 // ADC123_IN10
|
||||
#define ADC_A_PIN GPIO_Pin_1 // ADC123_IN11
|
||||
#define ADC_B_PIN GPIO_Pin_2 // ADC123_IN12
|
||||
#define ADC_Z_CHANNEL ADC_Channel_10
|
||||
#define ADC_A_CHANNEL ADC_Channel_11
|
||||
#define ADC_B_CHANNEL ADC_Channel_12
|
||||
@ -243,12 +243,13 @@
|
||||
#define USB_ACC_GPIO_PORT GPIOC
|
||||
#define USB_DETECT_PIN GPIO_Pin_4
|
||||
#define USB_PULLUP_PIN GPIO_Pin_14
|
||||
#define PIOS_IRQ_USB_PRIORITY IRQ_PRIO_MID
|
||||
|
||||
//-------------------------
|
||||
// Delay Timer
|
||||
//-------------------------
|
||||
#define PIOS_DELAY_TIMER TIM2
|
||||
#define PIOS_DELAY_TIMER_RCC RCC_APB1Periph_TIM2
|
||||
#define PIOS_DELAY_TIMER_RCC RCC_APB1Periph_TIM2
|
||||
|
||||
//-------------------------
|
||||
// Master Clock
|
||||
|
@ -29,8 +29,8 @@
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_DELAY_Init(void);
|
||||
extern int32_t PIOS_DELAY_Wait_uS(uint16_t uS);
|
||||
extern int32_t PIOS_DELAY_Wait_mS(uint16_t mS);
|
||||
extern int32_t PIOS_DELAY_WaituS(uint16_t uS);
|
||||
extern int32_t PIOS_DELAY_WaitmS(uint16_t mS);
|
||||
|
||||
|
||||
#endif /* PIOS_DELAY_H */
|
||||
|
@ -28,5 +28,6 @@
|
||||
|
||||
/* Public Functions */
|
||||
extern void PIOS_SYS_Init(void);
|
||||
extern int32_t PIOS_SYS_SerialNumberGet(char *str);
|
||||
|
||||
#endif /* PIOS_SYS_H */
|
||||
|
79
flight/PiOS/inc/pios_usb.h
Normal file
79
flight/PiOS/inc/pios_usb.h
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file pios_usb.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2009.
|
||||
* @brief USB functions header.
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
*
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef PIOS_USB_H
|
||||
#define PIOS_USB_H
|
||||
|
||||
/* Local defines */
|
||||
/* Following settings allow to customise the USB device descriptor */
|
||||
#ifndef PIOS_USB_VENDOR_ID
|
||||
#define PIOS_USB_VENDOR_ID 0x16c0 // sponsored by voti.nl! see http://www.voti.nl/pids
|
||||
#endif
|
||||
|
||||
#ifndef PIOS_USB_VENDOR_STR
|
||||
#define PIOS_USB_VENDOR_STR "midibox.org" // you will see this in the USB device description
|
||||
#endif
|
||||
|
||||
#ifndef PIOS_USB_PRODUCT_STR
|
||||
#define PIOS_USB_PRODUCT_STR "MIOS32" /* You will see this in the USB device list */
|
||||
#endif
|
||||
|
||||
#ifndef PIOS_USB_PRODUCT_ID
|
||||
#define PIOS_USB_PRODUCT_ID 0x03ff /* ==1023; 1020-1029 reserved for T.Klose, 1000 - 1009 free for lab use */
|
||||
#endif
|
||||
|
||||
#ifndef PIOS_USB_VERSION_ID
|
||||
#define PIOS_USB_VERSION_ID 0x0100 /* v1.00 */
|
||||
#endif
|
||||
|
||||
/* Internal defines which are used by MIOS32 USB MIDI/COM (don't touch) */
|
||||
#define PIOS_USB_EP_NUM 5
|
||||
|
||||
/* Buffer table base address */
|
||||
#define PIOS_USB_BTABLE_ADDRESS 0x000
|
||||
|
||||
/* EP0 rx/tx buffer base address */
|
||||
#define PIOS_USB_ENDP0_RXADDR 0x040
|
||||
#define PIOS_USB_ENDP0_TXADDR 0x080
|
||||
|
||||
/* EP1 Rx/Tx buffer base address for MIDI driver */
|
||||
#define PIOS_USB_ENDP1_TXADDR 0x0c0
|
||||
#define PIOS_USB_ENDP1_RXADDR 0x100
|
||||
|
||||
/* EP2/3/4 buffer base addresses for COM driver */
|
||||
#define PIOS_USB_ENDP2_TXADDR 0x140
|
||||
#define PIOS_USB_ENDP3_RXADDR 0x180
|
||||
#define PIOS_USB_ENDP4_TXADDR 0x1c0
|
||||
|
||||
|
||||
/* Global Variables */
|
||||
extern void (*pEpInt_IN[7])(void);
|
||||
extern void (*pEpInt_OUT[7])(void);
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_USB_Init(uint32_t mode);
|
||||
extern int32_t PIOS_USB_IsInitialized(void);
|
||||
|
||||
#endif /* PIOS_USB_H */
|
@ -40,19 +40,20 @@
|
||||
#define STRING_MAX 1024
|
||||
static uint8_t line_buffer[STRING_MAX];
|
||||
static uint16_t line_ix;
|
||||
static uint8_t sdcard_available;
|
||||
|
||||
/* Function Prototypes */
|
||||
static void TaskTick(void *pvParameters);
|
||||
static void TaskHooks(void *pvParameters);
|
||||
int32_t CONSOLE_Parse(COMPortTypeDef port, char c);
|
||||
void OP_ADC_NotifyChange(uint32_t pin, uint32_t pin_value);
|
||||
static void TaskSDCard(void *pvParameters);
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Brings up System using CMSIS functions, enables the LEDs. */
|
||||
PIOS_SYS_Init();
|
||||
|
||||
@ -79,7 +80,7 @@ int main()
|
||||
PIOS_LED_On(LED2);
|
||||
for(uint32_t i = 0; i < 10; i++) {
|
||||
PIOS_LED_Toggle(LED2);
|
||||
PIOS_DELAY_Wait_mS(100);
|
||||
PIOS_DELAY_WaitmS(100);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,18 +94,21 @@ int main()
|
||||
PIOS_Servo_Init();
|
||||
|
||||
/* Analog to digital converter initialise */
|
||||
PIOS_ADC_Init();
|
||||
//PIOS_ADC_Init();
|
||||
|
||||
//PIOS_PWM_Init();
|
||||
|
||||
PIOS_USB_Init(0);
|
||||
|
||||
PIOS_COM_ReceiveCallbackInit(CONSOLE_Parse);
|
||||
|
||||
/* Initialise OpenPilot application */
|
||||
// OpenPilotInit();
|
||||
|
||||
/* Create a FreeRTOS task */
|
||||
xTaskCreate(TaskTick, (signed portCHAR *)"Test", configMINIMAL_STACK_SIZE , NULL, 3, NULL);
|
||||
xTaskCreate(TaskHooks, (signed portCHAR *)"Hooks", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_HOOKS, NULL);
|
||||
//xTaskCreate(TaskTick, (signed portCHAR *)"Test", configMINIMAL_STACK_SIZE , NULL, 1, NULL);
|
||||
//xTaskCreate(TaskHooks, (signed portCHAR *)"Hooks", configMINIMAL_STACK_SIZE, NULL, PRIORITY_TASK_HOOKS, NULL);
|
||||
xTaskCreate(TaskSDCard, (signed portCHAR *)"SDCard", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 2), NULL);
|
||||
|
||||
/* Start the FreeRTOS scheduler */
|
||||
vTaskStartScheduler();
|
||||
@ -147,7 +151,7 @@ void OP_ADC_NotifyChange(uint32_t pin, uint32_t pin_value)
|
||||
|
||||
void TaskTick(void *pvParameters)
|
||||
{
|
||||
const portTickType xDelay = 500 / portTICK_RATE_MS;
|
||||
portTickType xLastExecutionTime;
|
||||
|
||||
/* Setup the LEDs to Alternate */
|
||||
PIOS_LED_On(LED1);
|
||||
@ -156,12 +160,11 @@ void TaskTick(void *pvParameters)
|
||||
for(;;)
|
||||
{
|
||||
PIOS_LED_Toggle(LED1);
|
||||
//PIOS_LED_Toggle(LED2);
|
||||
//PIOS_DELAY_Wait_mS(250);
|
||||
vTaskDelay(xDelay);
|
||||
vTaskDelayUntil(&xLastExecutionTime, 500 / portTICK_RATE_MS);
|
||||
}
|
||||
|
||||
/*
|
||||
#if 0
|
||||
/* For testing servo outputs */
|
||||
const portTickType xDelay = 1 / portTICK_RATE_MS;
|
||||
|
||||
Used to test servos, cycles all servos from one side to the other
|
||||
@ -189,7 +192,7 @@ void TaskTick(void *pvParameters)
|
||||
vTaskDelay(xDelay);
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
static void TaskHooks(void *pvParameters)
|
||||
@ -216,6 +219,46 @@ static void TaskHooks(void *pvParameters)
|
||||
}
|
||||
}
|
||||
|
||||
static void TaskSDCard(void *pvParameters)
|
||||
{
|
||||
uint16_t second_delay_ctr = 0;
|
||||
portTickType xLastExecutionTime;
|
||||
|
||||
/* Initialise the xLastExecutionTime variable on task entry */
|
||||
xLastExecutionTime = xTaskGetTickCount();
|
||||
|
||||
for(;;) {
|
||||
vTaskDelayUntil(&xLastExecutionTime, 1 / portTICK_RATE_MS);
|
||||
|
||||
/* Each second: */
|
||||
/* Check if SD card is available */
|
||||
/* High-speed access if SD card was previously available */
|
||||
if(++second_delay_ctr >= 1000) {
|
||||
second_delay_ctr = 0;
|
||||
|
||||
uint8_t prev_sdcard_available = sdcard_available;
|
||||
sdcard_available = PIOS_SDCARD_CheckAvailable(prev_sdcard_available);
|
||||
|
||||
if(sdcard_available && !prev_sdcard_available) {
|
||||
/* SD Card has been connected! */
|
||||
/* Switch to mass storage device */
|
||||
MSD_Init(0);
|
||||
} else if(!sdcard_available && prev_sdcard_available) {
|
||||
/* Re-init USB for MIDI */
|
||||
PIOS_USB_Init(1);
|
||||
/* SD Card disconnected! */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Each millisecond: */
|
||||
/* Handle USB access if device is available */
|
||||
if(sdcard_available) {
|
||||
MSD_Periodic_mS();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Idle hook function
|
||||
*/
|
||||
|
@ -49,6 +49,9 @@
|
||||
/* minIni Includes */
|
||||
#include <minIni.h>
|
||||
|
||||
/* Mass Storage Device Includes */
|
||||
#include <msd.h>
|
||||
|
||||
/* PIOS Hardware Includes (STM32F10x) */
|
||||
#include <pios_board.h>
|
||||
#include <pios_sys.h>
|
||||
@ -62,6 +65,7 @@
|
||||
#include <pios_i2c.h>
|
||||
#include <pios_spi.h>
|
||||
#include <pios_pwm.h>
|
||||
#include <pios_usb.h>
|
||||
|
||||
/* PIOS Hardware Includes (Common) */
|
||||
#include <pios_settings.h>
|
||||
|
Loading…
x
Reference in New Issue
Block a user