1
0
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:
gussy 2010-01-31 16:48:23 +00:00 committed by gussy
parent 2234d0a0bf
commit efdb5c5f2b
27 changed files with 2887 additions and 115 deletions

View File

@ -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.

View File

@ -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
View 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));
}
}

View 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 */

View 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****/

View 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****/

View 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****/

View 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****/

View 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****/

View 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****/

View 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****/

View 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****/

View 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****/

View 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.

View File

@ -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

View File

@ -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) {

View File

@ -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 */

View File

@ -55,7 +55,7 @@ int32_t PIOS_IRQ_Disable(void)
);
}
/* disable interrupts */
/* Disable interrupts */
__asm volatile ( \
" mov r0, #1 \n" \
" msr primask, r0\n" \

View File

@ -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
}

View File

@ -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

View 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;
}

View File

@ -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

View File

@ -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 */

View File

@ -28,5 +28,6 @@
/* Public Functions */
extern void PIOS_SYS_Init(void);
extern int32_t PIOS_SYS_SerialNumberGet(char *str);
#endif /* PIOS_SYS_H */

View 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 */

View File

@ -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
*/

View File

@ -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>