Configure V4, Add src files

This commit is contained in:
jonny 2025-12-01 23:37:29 +01:00
parent 4352d8eaa1
commit 2e1f37bddf
49 changed files with 21698 additions and 42 deletions

File diff suppressed because one or more lines are too long

11
Versuch4/Core/Inc/gui.h Normal file
View File

@ -0,0 +1,11 @@
/*******************************************************************
File: gui.h
Date: 09-Sep-2020
Author: Peter Spindler
********************************************************************/
#ifndef _GUI_H_
#define _GUI_H_
void GUI_Init( void );
void GUI_AddButton( uint16_t xPos, uint16_t yPos, char *Text, uint8_t Msg );
extern QueueHandle_t GUIQueue;
#endif

View File

@ -71,7 +71,7 @@
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
/* #define HAL_PCD_MODULE_ENABLED */
/* #define HAL_HCD_MODULE_ENABLED */
#define HAL_HCD_MODULE_ENABLED
/* #define HAL_DFSDM_MODULE_ENABLED */
/* #define HAL_DSI_MODULE_ENABLED */
/* #define HAL_JPEG_MODULE_ENABLED */

View File

@ -53,6 +53,7 @@ void BusFault_Handler(void);
void UsageFault_Handler(void);
void DebugMon_Handler(void);
void TIM8_TRG_COM_TIM14_IRQHandler(void);
void OTG_FS_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

13
Versuch4/Core/Inc/touch.h Normal file
View File

@ -0,0 +1,13 @@
/*******************************************************************
File: touch.h
Date: 9-September-2020
Author: Peter Spindler
********************************************************************/
#ifndef _TOUCH_H_
#define _TOUCH_H_
void Touch_Init( void );
void Touch_Calibrate( void );
uint8_t Touch_IsPressed( void );
uint8_t Touch_ReadPos( uint16_t *x, uint16_t *y );
#endif

138
Versuch4/Core/Src/gui.c Normal file
View File

@ -0,0 +1,138 @@
/*******************************************************************
File: gui.c
Date: 29-September-2025
Author: Peter Spindler
Description: Functions to create a simple grafical user interface (gui)
********************************************************************/
#include "stm32f7xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include <string.h>
#include "display.h"
#include "touch.h"
TaskHandle_t GUITaskHandle = NULL;
QueueHandle_t GUIQueue;
#define BUTTON_MARGIN_X 20
#define BUTTON_MARGIN_Y 22
#define GUI_BUTTONSIZE 16
typedef struct {
uint16_t xPos;
uint16_t yPos;
uint16_t Width;
uint16_t Height;
char Text[16];
uint8_t Msg;
} GUI_BUTTON_TypeDef;
static uint8_t GUI_ButtonCnt = 0;
static GUI_BUTTON_TypeDef GUI_Button[GUI_BUTTONSIZE];
uint8_t GUI_IsPressed( void )
{
if( HAL_GPIO_ReadPin( GPIOC,GPIO_PIN_13 ) == 0 ) {
return 1;
} else {
return 0;
}
}
void GUI_AddButton( uint16_t xPos, uint16_t yPos, char *Text, uint8_t Msg )
{
uint8_t i;
i = GUI_ButtonCnt;
if( i < GUI_BUTTONSIZE ) {
GUI_Button[i].xPos = xPos;
GUI_Button[i].yPos = yPos;
memset(GUI_Button[i].Text, 0, sizeof(GUI_Button[i].Text) );
strncpy(GUI_Button[i].Text, Text, sizeof(GUI_Button[i].Text) );
GUI_Button[i].Msg = Msg;
GUI_Button[i].Width = Display_GetStringWidth(&FontBig,Text)+2*BUTTON_MARGIN_X;
GUI_Button[i].Height = Display_GetFontCharHeight(&FontBig)+2*BUTTON_MARGIN_Y;
GUI_ButtonCnt ++;
}
}
static void GUI_DisplayButton( uint8_t Index, uint8_t State )
{
GUI_BUTTON_TypeDef *Button = &GUI_Button[Index];
uint16_t ColorBack;
if( State == 0 ) {
ColorBack = LCD_COLOR_BLACK;
} else {
ColorBack = LCD_COLOR_BLUE;
}
Display_FillRect( Button->xPos,Button->yPos, Button->Width,Button->Height, ColorBack );
Display_DrawRect(Button->xPos,Button->yPos, Button->Width,Button->Height, LCD_COLOR_WHITE );
Display_PrintString( Button->xPos+BUTTON_MARGIN_X, Button->yPos+BUTTON_MARGIN_Y, LCD_COLOR_WHITE,ColorBack, &FontBig, Button->Text);
}
static void GUI_Task( void *arguments ) {
uint8_t TouchState = 0;
uint16_t xTouch, yTouch;
uint8_t i;
uint8_t ButtonPressedIndex=0;
uint8_t Msg;
uint32_t EventTime;
for(i=0;i<GUI_ButtonCnt;i++) {
GUI_DisplayButton(i,0);
}
while( 1 ) {
vTaskDelay(20);
if( TouchState == 0 && Touch_IsPressed() ) {
if( Touch_ReadPos( &xTouch, &yTouch ) ) {
ButtonPressedIndex = 0xff;
for(i=0;i<GUI_ButtonCnt;i++) {
if( xTouch >= GUI_Button[i].xPos &&
xTouch <= GUI_Button[i].xPos + GUI_Button[i].Width &&
yTouch >= GUI_Button[i].yPos &&
yTouch <= GUI_Button[i].yPos + GUI_Button[i].Height ) {
ButtonPressedIndex = i;
}
}
if( ButtonPressedIndex != 0xff ) {
GUI_DisplayButton(ButtonPressedIndex,1);
xQueueSendToBack( GUIQueue, ( void * ) &GUI_Button[ButtonPressedIndex].Msg, ( portTickType ) 0 );
TouchState = 1;
EventTime = HAL_GetTick() + 500;
}
}
} else if( TouchState == 1 ) {
if( !Touch_IsPressed() ) {
if( ButtonPressedIndex != 0xff ) {
GUI_DisplayButton(ButtonPressedIndex,0);
}
TouchState = 0;
} else if( HAL_GetTick() > EventTime ) {
if( ButtonPressedIndex != 0xff ) {
Msg = GUI_Button[ButtonPressedIndex].Msg; // | 0x80;
xQueueSendToBack( GUIQueue, ( void * ) &Msg, ( portTickType ) 0 );
}
EventTime = HAL_GetTick() + 50;
}
}
}
}
void GUI_Init( void ) {
portENABLE_INTERRUPTS(); // Workaround to re-enable interrupts after FreeRTOS functions
Touch_Init();
GUIQueue = xQueueCreate( 10, sizeof( uint8_t) );
xTaskCreate(GUI_Task,"GUI", configMINIMAL_STACK_SIZE,NULL,0,&GUITaskHandle);
portENABLE_INTERRUPTS(); // Workaround to re-enable interrupts after FreeRTOS functions
}

View File

@ -19,11 +19,15 @@
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "fatfs.h"
#include "usb_host.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "display.h"
#include "fonts.h"
#include "touch.h"
#include "gui.h"
#include <stdbool.h>
#include <stdio.h>
@ -286,6 +290,7 @@ int main(void)
MX_USART6_UART_Init();
MX_FMC_Init();
MX_I2C3_Init();
MX_FATFS_Init();
/* USER CODE BEGIN 2 */
Usage_Init();
@ -717,14 +722,6 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : PA12 PA11 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : SAI2_FS_A_Pin SAI2_SD_A_Pin SAI2_SCK_A_Pin SAI2_MCLK_A_Pin */
GPIO_InitStruct.Pin = SAI2_FS_A_Pin|SAI2_SD_A_Pin|SAI2_SCK_A_Pin|SAI2_MCLK_A_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@ -786,12 +783,6 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/*Configure GPIO pin : PA9 */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : LCD_TE_INT_Pin */
GPIO_InitStruct.Pin = LCD_TE_INT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
@ -937,6 +928,8 @@ static void MX_GPIO_Init(void)
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
/* init code for USB_HOST */
MX_USB_HOST_Init();
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)

View File

@ -55,6 +55,7 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
extern TIM_HandleTypeDef htim14;
/* USER CODE BEGIN EV */
@ -173,6 +174,20 @@ void TIM8_TRG_COM_TIM14_IRQHandler(void)
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 1 */
}
/**
* @brief This function handles USB On The Go FS global interrupt.
*/
void OTG_FS_IRQHandler(void)
{
/* USER CODE BEGIN OTG_FS_IRQn 0 */
/* USER CODE END OTG_FS_IRQn 0 */
HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
/* USER CODE BEGIN OTG_FS_IRQn 1 */
/* USER CODE END OTG_FS_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

269
Versuch4/Core/Src/touch.c Normal file
View File

@ -0,0 +1,269 @@
/*******************************************************************
File: touch.c
Date: 9-September-2020
Author: Peter Spindler
Description: Touch controller driver
********************************************************************/
#include "stm32f7xx_hal.h"
#include "main.h"
#include "touch.h"
#include "display.h"
#include <stdio.h>
#define TS_I2C_HANDLE hi2c3
extern I2C_HandleTypeDef TS_I2C_HANDLE;
#define TS_I2C_ADDRESS 0x70
#define TOUCH_WIDTH 240
#define TOUCH_HEIGHT 240
uint16_t Touch_Calx1 = 20, Touch_Caly1 = 20;
uint16_t Touch_Calx2 = 220, Touch_Caly2 = 220;
// Default calibration values:
uint16_t Touch_Calx1Raw = 33, Touch_Caly1Raw = 72;
uint16_t Touch_Calx2Raw = 230, Touch_Caly2Raw = 190;
static uint8_t Touch_ReadReg( uint8_t Reg ) {
uint8_t DataRx = 0;
HAL_I2C_Mem_Read( &TS_I2C_HANDLE, TS_I2C_ADDRESS, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &DataRx, 1, 1000);
return DataRx;
}
static void Touch_ReadRegMulti( uint8_t Reg, uint8_t *DataRx, uint16_t DataSize ) {
HAL_I2C_Mem_Read( &TS_I2C_HANDLE, TS_I2C_ADDRESS, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, DataRx, DataSize, 1000);
}
static void Touch_WriteReg( uint8_t Reg, uint8_t Value ) {
HAL_I2C_Mem_Write( &TS_I2C_HANDLE, TS_I2C_ADDRESS, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, &Value, 1, 1000);
}
uint8_t Touch_IsPressed( void ) {
GPIO_PinState Pin = HAL_GPIO_ReadPin( CTP_INT_GPIO_Port, CTP_INT_Pin );
if( Pin == GPIO_PIN_RESET ) {
uint8_t Status = Touch_ReadReg( 0x02 ) & 0x0f;
if( Status > 0 ) {
return 1;
}
}
return 0;
}
uint8_t Touch_ReadPosRaw( uint16_t *x, uint16_t *y ) {
uint8_t DataRx[2][4];
uint8_t Status = Touch_ReadReg( 0x02 ) & 0x0f;
if( Status == 1 ) {
Touch_ReadRegMulti( 0x03, DataRx[0], 4 );
} else if( Status == 2 ) {
Touch_ReadRegMulti( 0x03, DataRx[0], 4 );
Touch_ReadRegMulti( 0x09, DataRx[1], 4 );
} else {
*x = 0;
*y = 0;
return 0;
}
uint16_t xRaw = ((DataRx[0][0] & 0x0f) << 8) | DataRx[0][1];
uint16_t yRaw = ((DataRx[0][2] & 0x0f) << 8) | DataRx[0][3];
// Swap x-y:
*x = yRaw;
*y = xRaw;
// Mirror x:
if( *x <= TOUCH_WIDTH-1 ) {
*x = TOUCH_WIDTH-1 - *x;
} else {
*x = 0;
}
return 1;
}
void Touch_SetCalibration( uint16_t x1Raw, uint16_t y1Raw, uint16_t x2Raw, uint16_t y2Raw ) {
Touch_Calx1Raw = x1Raw;
Touch_Caly1Raw = y1Raw;
Touch_Calx2Raw = x2Raw;
Touch_Caly2Raw = y2Raw;
}
void Touch_ConvertPos( uint16_t *x, uint16_t *y ) {
int16_t x_, y_;
x_ = (*x - Touch_Calx1Raw)*(Touch_Calx2-Touch_Calx1)/(Touch_Calx2Raw-Touch_Calx1Raw) + Touch_Calx1;
y_ = (*y - Touch_Caly1Raw)*(Touch_Caly2-Touch_Caly1)/(Touch_Caly2Raw-Touch_Caly1Raw) + Touch_Caly1;
if( x_ < 0 ) x_ = 0;
if( x_ > TOUCH_WIDTH-1 ) x_ = TOUCH_WIDTH-1;
if( y_ < 0 ) y_ = 0;
if( y_ > TOUCH_HEIGHT-1 ) y_ = TOUCH_HEIGHT-1;
*x = x_;
*y = y_;
}
uint8_t Touch_ReadPos( uint16_t *x, uint16_t *y ) {
uint8_t ret;
ret = Touch_ReadPosRaw( x, y );
Touch_ConvertPos( x, y );
return ret;
}
void Touch_Calibrate( void ) {
uint16_t x, y, xTouch, yTouch;
uint16_t x1=0, y1=0, x2=0, y2=0;
uint8_t i=0, iPressed, Pressed;
Display_PrintString( 0, 150, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "Press" );
Display_PrintString( 0, 180, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "top/left");
Display_FillCircle( Touch_Calx1, Touch_Caly1, 10, LCD_COLOR_WHITE );
Pressed = 0;
while( 1 ) {
if( Touch_IsPressed() ) {
if( Touch_ReadPosRaw( &x, &y ) ) {
Display_Printf( 00, 210, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "%3d %3d ", x, y );
xTouch = x;
yTouch = y;
Pressed = 1;
}
}
// Abort with user button down:
if( HAL_GPIO_ReadPin( GPIOA, GPIO_PIN_0 ) == GPIO_PIN_SET ) {
if( Pressed ) {
x1 = xTouch;
y1 = yTouch;
}
break;
}
}
// Wait for user button up:
while( 1 ) {
HAL_Delay(50);
if( HAL_GPIO_ReadPin( GPIOA, GPIO_PIN_0 ) == GPIO_PIN_RESET ) {
HAL_Delay(50);
break;
}
}
Display_Clear( LCD_COLOR_BLACK );
Display_PrintString( 0, 0, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "Press" );
Display_PrintString( 0, 30, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "buttom/right");
Display_FillCircle( Touch_Calx2, Touch_Caly2, 10, LCD_COLOR_WHITE );
Pressed = 0;
while( 1 ) {
if( Touch_IsPressed() ) {
if( Touch_ReadPosRaw( &x, &y ) ) {
Display_Printf( 0, 60, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "%3d %3d ", x, y );
xTouch = x;
yTouch = y;
Pressed = 1;
}
}
// Abort with user button down:
if( HAL_GPIO_ReadPin( GPIOA, GPIO_PIN_0 ) == GPIO_PIN_SET ) {
if( Pressed ) {
x2 = xTouch;
y2 = yTouch;
}
break;
}
}
Display_Clear( LCD_COLOR_BLACK );
Display_PrintString( 0, 0, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "Done" );
Display_Printf( 0, 30, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "x1: %3d", x1 );
Display_Printf( 0, 60, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "y1: %3d", y1 );
Display_Printf( 0, 90, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "x2: %3d", x2 );
Display_Printf( 0, 120, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "y2: %3d", y2 );
// Stop if any calibration point not pressed:
if( x1 == 0 || y1 == 0 || x2 == 0 || y2 == 0 ) {
Display_PrintString( 0, 150, LCD_COLOR_WHITE, LCD_COLOR_BLACK, &FontBig, "Error!" );
while( 1 );
}
// Wait for used button up:
while( 1 ) {
HAL_Delay(50);
if( HAL_GPIO_ReadPin( GPIOA, GPIO_PIN_0 ) == GPIO_PIN_RESET ) {
HAL_Delay(50);
break;
}
}
// Wait for user button down:
while( 1 ) {
if( HAL_GPIO_ReadPin( GPIOA, GPIO_PIN_0 ) == GPIO_PIN_SET ) {
break;
}
}
// Use calibration values and test with six buttons:
Touch_SetCalibration( x1, y1, x2, y2 );
struct {
uint16_t x, y;
uint16_t Width, Height;
} Rect[6];
x = 0;
y = 0;
for( i = 0; i < 6; i++ ) {
Rect[i].x = x;
Rect[i].y = y;
Rect[i].Width = 110;
Rect[i].Height = 70;
x += 120;
if( x+110 >= 240 ) {
x = 0;
y += 75;
}
}
Display_Clear( LCD_COLOR_BLACK );
for( i = 0; i < 6; i++ ) {
Display_DrawRect( Rect[i].x, Rect[i].y, Rect[i].Width, Rect[i].Height, LCD_COLOR_WHITE );
}
uint8_t State = 0;
while( 1 ) {
if( State == 0 && Touch_ReadPos( &x, &y ) ) {
iPressed = 0xff;
for( i = 0; i < 6; i++ ) {
if( x >= Rect[i].x && x <= Rect[i].x+Rect[i].Width &&
y >= Rect[i].y && y <= Rect[i].y+Rect[i].Height ) {
Display_FillRect( Rect[i].x, Rect[i].y, Rect[i].Width, Rect[i].Height, LCD_COLOR_WHITE );
State = 1;
iPressed = i;
break;
}
}
} else if( State == 1 && !Touch_IsPressed() ) {
if( iPressed != 0xff ) {
Display_FillRect( Rect[iPressed].x, Rect[iPressed].y, Rect[iPressed].Width, Rect[iPressed].Height, LCD_COLOR_BLACK );
Display_DrawRect( Rect[i].x, Rect[i].y, Rect[i].Width, Rect[i].Height, LCD_COLOR_WHITE );
}
State = 0;
}
}
while( 1 );
}
void Touch_Init( void ) {
uint8_t ID;
ID = Touch_ReadReg(0xA8);
if( ID != 0xcd ) {
printf("Error: Touch ID is %x, expected %x\n", ID, 0xcd );
return;
}
Touch_WriteReg( 0xA4, 0 ); // Disable interrupt
}

View File

@ -0,0 +1,328 @@
/**
******************************************************************************
* @file stm32f7xx_hal_hcd.h
* @author MCD Application Team
* @brief Header file of HCD HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32F7xx_HAL_HCD_H
#define STM32F7xx_HAL_HCD_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx_ll_usb.h"
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
/** @addtogroup STM32F7xx_HAL_Driver
* @{
*/
/** @addtogroup HCD HCD
* @{
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup HCD_Exported_Types HCD Exported Types
* @{
*/
/** @defgroup HCD_Exported_Types_Group1 HCD State Structure definition
* @{
*/
typedef enum
{
HAL_HCD_STATE_RESET = 0x00,
HAL_HCD_STATE_READY = 0x01,
HAL_HCD_STATE_ERROR = 0x02,
HAL_HCD_STATE_BUSY = 0x03,
HAL_HCD_STATE_TIMEOUT = 0x04
} HCD_StateTypeDef;
typedef USB_OTG_GlobalTypeDef HCD_TypeDef;
typedef USB_OTG_CfgTypeDef HCD_InitTypeDef;
typedef USB_OTG_HCTypeDef HCD_HCTypeDef;
typedef USB_OTG_URBStateTypeDef HCD_URBStateTypeDef;
typedef USB_OTG_HCStateTypeDef HCD_HCStateTypeDef;
/**
* @}
*/
/** @defgroup HCD_Exported_Types_Group2 HCD Handle Structure definition
* @{
*/
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
typedef struct __HCD_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
{
HCD_TypeDef *Instance; /*!< Register base address */
HCD_InitTypeDef Init; /*!< HCD required parameters */
HCD_HCTypeDef hc[16]; /*!< Host channels parameters */
HAL_LockTypeDef Lock; /*!< HCD peripheral status */
__IO HCD_StateTypeDef State; /*!< HCD communication state */
__IO uint32_t ErrorCode; /*!< HCD Error code */
void *pData; /*!< Pointer Stack Handler */
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
void (* SOFCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD SOF callback */
void (* ConnectCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Connect callback */
void (* DisconnectCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Disconnect callback */
void (* PortEnabledCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Port Enable callback */
void (* PortDisabledCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Port Disable callback */
void (* HC_NotifyURBChangeCallback)(struct __HCD_HandleTypeDef *hhcd, uint8_t chnum,
HCD_URBStateTypeDef urb_state); /*!< USB OTG HCD Host Channel Notify URB Change callback */
void (* MspInitCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Msp Init callback */
void (* MspDeInitCallback)(struct __HCD_HandleTypeDef *hhcd); /*!< USB OTG HCD Msp DeInit callback */
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
} HCD_HandleTypeDef;
/**
* @}
*/
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup HCD_Exported_Constants HCD Exported Constants
* @{
*/
/** @defgroup HCD_Speed HCD Speed
* @{
*/
#define HCD_SPEED_HIGH USBH_HS_SPEED
#define HCD_SPEED_FULL USBH_FSLS_SPEED
#define HCD_SPEED_LOW USBH_FSLS_SPEED
/**
* @}
*/
/** @defgroup HCD_Device_Speed HCD Device Speed
* @{
*/
#define HCD_DEVICE_SPEED_HIGH 0U
#define HCD_DEVICE_SPEED_FULL 1U
#define HCD_DEVICE_SPEED_LOW 2U
/**
* @}
*/
/** @defgroup HCD_PHY_Module HCD PHY Module
* @{
*/
#define HCD_PHY_ULPI 1U
#define HCD_PHY_EMBEDDED 2U
/**
* @}
*/
/** @defgroup HCD_Error_Code_definition HCD Error Code definition
* @brief HCD Error Code definition
* @{
*/
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
#define HAL_HCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
/**
* @}
*/
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/** @defgroup HCD_Exported_Macros HCD Exported Macros
* @brief macros to handle interrupts and specific clock configurations
* @{
*/
#define __HAL_HCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_HCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_HCD_GET_FLAG(__HANDLE__, __INTERRUPT__) ((USB_ReadInterrupts((__HANDLE__)->Instance)\
& (__INTERRUPT__)) == (__INTERRUPT__))
#define __HAL_HCD_GET_CH_FLAG(__HANDLE__, __chnum__, __INTERRUPT__) \
((USB_ReadChInterrupts((__HANDLE__)->Instance, (__chnum__)) & (__INTERRUPT__)) == (__INTERRUPT__))
#define __HAL_HCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) = (__INTERRUPT__))
#define __HAL_HCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
#define __HAL_HCD_CLEAR_HC_INT(chnum, __INTERRUPT__) (USBx_HC(chnum)->HCINT = (__INTERRUPT__))
#define __HAL_HCD_MASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_CHHM)
#define __HAL_HCD_UNMASK_HALT_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM)
#define __HAL_HCD_MASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK &= ~USB_OTG_HCINTMSK_ACKM)
#define __HAL_HCD_UNMASK_ACK_HC_INT(chnum) (USBx_HC(chnum)->HCINTMSK |= USB_OTG_HCINTMSK_ACKM)
#define __HAL_HCD_SET_HC_CSPLT(chnum) (USBx_HC(chnum)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT)
#define __HAL_HCD_CLEAR_HC_CSPLT(chnum) (USBx_HC(chnum)->HCSPLT &= ~USB_OTG_HCSPLT_COMPLSPLT)
#define __HAL_HCD_CLEAR_HC_SSPLT(chnum) (USBx_HC(chnum)->HCSPLT &= ~USB_OTG_HCSPLT_SPLITEN)
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup HCD_Exported_Functions HCD Exported Functions
* @{
*/
/** @defgroup HCD_Exported_Functions_Group1 Initialization and de-initialization functions
* @{
*/
HAL_StatusTypeDef HAL_HCD_Init(HCD_HandleTypeDef *hhcd);
HAL_StatusTypeDef HAL_HCD_DeInit(HCD_HandleTypeDef *hhcd);
HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
uint8_t epnum, uint8_t dev_address,
uint8_t speed, uint8_t ep_type, uint16_t mps);
HAL_StatusTypeDef HAL_HCD_HC_Halt(HCD_HandleTypeDef *hhcd, uint8_t ch_num);
void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd);
void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd);
#if (USE_HAL_HCD_REGISTER_CALLBACKS == 1U)
/** @defgroup HAL_HCD_Callback_ID_enumeration_definition HAL USB OTG HCD Callback ID enumeration definition
* @brief HAL USB OTG HCD Callback ID enumeration definition
* @{
*/
typedef enum
{
HAL_HCD_SOF_CB_ID = 0x01, /*!< USB HCD SOF callback ID */
HAL_HCD_CONNECT_CB_ID = 0x02, /*!< USB HCD Connect callback ID */
HAL_HCD_DISCONNECT_CB_ID = 0x03, /*!< USB HCD Disconnect callback ID */
HAL_HCD_PORT_ENABLED_CB_ID = 0x04, /*!< USB HCD Port Enable callback ID */
HAL_HCD_PORT_DISABLED_CB_ID = 0x05, /*!< USB HCD Port Disable callback ID */
HAL_HCD_MSPINIT_CB_ID = 0x06, /*!< USB HCD MspInit callback ID */
HAL_HCD_MSPDEINIT_CB_ID = 0x07 /*!< USB HCD MspDeInit callback ID */
} HAL_HCD_CallbackIDTypeDef;
/**
* @}
*/
/** @defgroup HAL_HCD_Callback_pointer_definition HAL USB OTG HCD Callback pointer definition
* @brief HAL USB OTG HCD Callback pointer definition
* @{
*/
typedef void (*pHCD_CallbackTypeDef)(HCD_HandleTypeDef *hhcd); /*!< pointer to a common USB OTG HCD callback function */
typedef void (*pHCD_HC_NotifyURBChangeCallbackTypeDef)(HCD_HandleTypeDef *hhcd,
uint8_t epnum,
HCD_URBStateTypeDef urb_state); /*!< pointer to USB OTG HCD host channel callback */
/**
* @}
*/
HAL_StatusTypeDef HAL_HCD_RegisterCallback(HCD_HandleTypeDef *hhcd,
HAL_HCD_CallbackIDTypeDef CallbackID,
pHCD_CallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_HCD_UnRegisterCallback(HCD_HandleTypeDef *hhcd,
HAL_HCD_CallbackIDTypeDef CallbackID);
HAL_StatusTypeDef HAL_HCD_RegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd,
pHCD_HC_NotifyURBChangeCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_HCD_UnRegisterHC_NotifyURBChangeCallback(HCD_HandleTypeDef *hhcd);
#endif /* USE_HAL_HCD_REGISTER_CALLBACKS */
/**
* @}
*/
/* I/O operation functions ***************************************************/
/** @addtogroup HCD_Exported_Functions_Group2 Input and Output operation functions
* @{
*/
HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
uint8_t direction, uint8_t ep_type,
uint8_t token, uint8_t *pbuff,
uint16_t length, uint8_t do_ping);
HAL_StatusTypeDef HAL_HCD_HC_SetHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num,
uint8_t addr, uint8_t PortNbr);
HAL_StatusTypeDef HAL_HCD_HC_ClearHubInfo(HCD_HandleTypeDef *hhcd, uint8_t ch_num);
/* Non-Blocking mode: Interrupt */
void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd);
void HAL_HCD_WKUP_IRQHandler(HCD_HandleTypeDef *hhcd);
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd);
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd);
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd);
void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd);
void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd);
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum,
HCD_URBStateTypeDef urb_state);
/**
* @}
*/
/* Peripheral Control functions **********************************************/
/** @addtogroup HCD_Exported_Functions_Group3 Peripheral Control functions
* @{
*/
HAL_StatusTypeDef HAL_HCD_ResetPort(HCD_HandleTypeDef *hhcd);
HAL_StatusTypeDef HAL_HCD_Start(HCD_HandleTypeDef *hhcd);
HAL_StatusTypeDef HAL_HCD_Stop(HCD_HandleTypeDef *hhcd);
/**
* @}
*/
/* Peripheral State functions ************************************************/
/** @addtogroup HCD_Exported_Functions_Group4 Peripheral State functions
* @{
*/
HCD_StateTypeDef HAL_HCD_GetState(HCD_HandleTypeDef const *hhcd);
HCD_URBStateTypeDef HAL_HCD_HC_GetURBState(HCD_HandleTypeDef const *hhcd, uint8_t chnum);
HCD_HCStateTypeDef HAL_HCD_HC_GetState(HCD_HandleTypeDef const *hhcd, uint8_t chnum);
uint32_t HAL_HCD_HC_GetXferCount(HCD_HandleTypeDef const *hhcd, uint8_t chnum);
uint32_t HAL_HCD_GetCurrentFrame(HCD_HandleTypeDef *hhcd);
uint32_t HAL_HCD_GetCurrentSpeed(HCD_HandleTypeDef *hhcd);
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup HCD_Private_Macros HCD Private Macros
* @{
*/
/**
* @}
*/
/* Private functions prototypes ----------------------------------------------*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
#ifdef __cplusplus
}
#endif
#endif /* STM32F7xx_HAL_HCD_H */

View File

@ -0,0 +1,600 @@
/**
******************************************************************************
* @file stm32f7xx_ll_usb.h
* @author MCD Application Team
* @brief Header file of USB Low Layer HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32F7xx_LL_USB_H
#define STM32F7xx_LL_USB_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx_hal_def.h"
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
/** @addtogroup STM32F7xx_HAL_Driver
* @{
*/
/** @addtogroup USB_LL
* @{
*/
/* Exported types ------------------------------------------------------------*/
#ifndef HAL_USB_TIMEOUT
#define HAL_USB_TIMEOUT 0xF000000U
#endif /* define HAL_USB_TIMEOUT */
#ifndef HAL_USB_CURRENT_MODE_MAX_DELAY_MS
#define HAL_USB_CURRENT_MODE_MAX_DELAY_MS 200U
#endif /* define HAL_USB_CURRENT_MODE_MAX_DELAY_MS */
/**
* @brief USB Mode definition
*/
typedef enum
{
USB_DEVICE_MODE = 0,
USB_HOST_MODE = 1,
USB_DRD_MODE = 2
} USB_ModeTypeDef;
/**
* @brief URB States definition
*/
typedef enum
{
URB_IDLE = 0,
URB_DONE,
URB_NOTREADY,
URB_NYET,
URB_ERROR,
URB_STALL
} USB_URBStateTypeDef;
/**
* @brief Host channel States definition
*/
typedef enum
{
HC_IDLE = 0,
HC_XFRC,
HC_HALTED,
HC_ACK,
HC_NAK,
HC_NYET,
HC_STALL,
HC_XACTERR,
HC_BBLERR,
HC_DATATGLERR
} USB_HCStateTypeDef;
/**
* @brief USB Instance Initialization Structure definition
*/
typedef struct
{
uint8_t dev_endpoints; /*!< Device Endpoints number.
This parameter depends on the used USB core.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t Host_channels; /*!< Host Channels number.
This parameter Depends on the used USB core.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t dma_enable; /*!< USB DMA state.
If DMA is not supported this parameter shall be set by default to zero */
uint8_t speed; /*!< USB Core speed.
This parameter can be any value of @ref PCD_Speed/HCD_Speed
(HCD_SPEED_xxx, HCD_SPEED_xxx) */
uint8_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */
uint8_t phy_itface; /*!< Select the used PHY interface.
This parameter can be any value of @ref PCD_PHY_Module/HCD_PHY_Module */
uint8_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
uint8_t low_power_enable; /*!< Enable or disable the low Power Mode. */
uint8_t lpm_enable; /*!< Enable or disable Link Power Management. */
uint8_t battery_charging_enable; /*!< Enable or disable Battery charging. */
uint8_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */
uint8_t use_dedicated_ep1; /*!< Enable or disable the use of the dedicated EP1 interrupt. */
uint8_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */
} USB_CfgTypeDef;
typedef struct
{
uint8_t num; /*!< Endpoint number
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t is_in; /*!< Endpoint direction
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t is_stall; /*!< Endpoint stall condition
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t is_iso_incomplete; /*!< Endpoint isoc condition
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t type; /*!< Endpoint type
This parameter can be any value of @ref USB_LL_EP_Type */
uint8_t data_pid_start; /*!< Initial data PID
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint32_t maxpacket; /*!< Endpoint Max packet size
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
uint32_t xfer_len; /*!< Current transfer length */
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
uint8_t even_odd_frame; /*!< IFrame parity
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint16_t tx_fifo_num; /*!< Transmission FIFO number
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */
uint32_t xfer_size; /*!< requested transfer size */
} USB_EPTypeDef;
typedef struct
{
uint8_t dev_addr; /*!< USB device address.
This parameter must be a number between Min_Data = 1 and Max_Data = 255 */
uint8_t ch_num; /*!< Host channel number.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t ep_num; /*!< Endpoint number.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t ep_is_in; /*!< Endpoint direction
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t speed; /*!< USB Host Channel speed.
This parameter can be any value of @ref HCD_Device_Speed:
(HCD_DEVICE_SPEED_xxx) */
uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */
uint8_t do_ssplit; /*!< Enable start split transaction in HS mode. */
uint8_t do_csplit; /*!< Enable complete split transaction in HS mode. */
uint8_t ep_ss_schedule; /*!< Enable periodic endpoint start split schedule . */
uint32_t iso_splt_xactPos; /*!< iso split transfer transaction position. */
uint8_t hub_port_nbr; /*!< USB HUB port number */
uint8_t hub_addr; /*!< USB HUB address */
uint8_t ep_type; /*!< Endpoint Type.
This parameter can be any value of @ref USB_LL_EP_Type */
uint16_t max_packet; /*!< Endpoint Max packet size.
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
uint8_t data_pid; /*!< Initial data PID.
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */
uint32_t XferSize; /*!< OTG Channel transfer size. */
uint32_t xfer_len; /*!< Current transfer length. */
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */
uint8_t toggle_in; /*!< IN transfer current toggle flag.
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t toggle_out; /*!< OUT transfer current toggle flag
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */
uint32_t ErrCnt; /*!< Host channel error count. */
uint32_t NyetErrCnt; /*!< Complete Split NYET Host channel error count. */
USB_URBStateTypeDef urb_state; /*!< URB state.
This parameter can be any value of @ref USB_URBStateTypeDef */
USB_HCStateTypeDef state; /*!< Host Channel state.
This parameter can be any value of @ref USB_HCStateTypeDef */
} USB_HCTypeDef;
typedef USB_ModeTypeDef USB_OTG_ModeTypeDef;
typedef USB_CfgTypeDef USB_OTG_CfgTypeDef;
typedef USB_EPTypeDef USB_OTG_EPTypeDef;
typedef USB_URBStateTypeDef USB_OTG_URBStateTypeDef;
typedef USB_HCStateTypeDef USB_OTG_HCStateTypeDef;
typedef USB_HCTypeDef USB_OTG_HCTypeDef;
/* Exported constants --------------------------------------------------------*/
/** @defgroup PCD_Exported_Constants PCD Exported Constants
* @{
*/
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
/** @defgroup USB_OTG_CORE VERSION ID
* @{
*/
#define USB_OTG_CORE_ID_300A 0x4F54300AU
#define USB_OTG_CORE_ID_310A 0x4F54310AU
/**
* @}
*/
/** @defgroup USB_Core_Mode_ USB Core Mode
* @{
*/
#define USB_OTG_MODE_DEVICE 0U
#define USB_OTG_MODE_HOST 1U
#define USB_OTG_MODE_DRD 2U
/**
* @}
*/
/** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed
* @{
*/
#define USB_OTG_SPEED_HIGH 0U
#define USB_OTG_SPEED_HIGH_IN_FULL 1U
#define USB_OTG_SPEED_FULL 3U
/**
* @}
*/
/** @defgroup USB_LL_Core_PHY USB Low Layer Core PHY
* @{
*/
#define USB_OTG_ULPI_PHY 1U
#define USB_OTG_EMBEDDED_PHY 2U
#define USB_OTG_HS_EMBEDDED_PHY 3U
#if !defined (USB_HS_PHYC_TUNE_VALUE)
#define USB_HS_PHYC_TUNE_VALUE 0x00000F13U /*!< Value of USB HS PHY Tune */
#endif /* USB_HS_PHYC_TUNE_VALUE */
/**
* @}
*/
/** @defgroup USB_LL_Turnaround_Timeout Turnaround Timeout Value
* @{
*/
#ifndef USBD_HS_TRDT_VALUE
#define USBD_HS_TRDT_VALUE 9U
#endif /* USBD_HS_TRDT_VALUE */
#ifndef USBD_FS_TRDT_VALUE
#define USBD_FS_TRDT_VALUE 5U
#define USBD_DEFAULT_TRDT_VALUE 9U
#endif /* USBD_HS_TRDT_VALUE */
/**
* @}
*/
/** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS
* @{
*/
#define USB_OTG_HS_MAX_PACKET_SIZE 512U
#define USB_OTG_FS_MAX_PACKET_SIZE 64U
#define USB_OTG_MAX_EP0_SIZE 64U
/**
* @}
*/
/** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency
* @{
*/
#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0U << 1)
#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1U << 1)
#define DSTS_ENUMSPD_FS_PHY_48MHZ (3U << 1)
/**
* @}
*/
/** @defgroup USB_LL_CORE_Frame_Interval USB Low Layer Core Frame Interval
* @{
*/
#define DCFG_FRAME_INTERVAL_80 0U
#define DCFG_FRAME_INTERVAL_85 1U
#define DCFG_FRAME_INTERVAL_90 2U
#define DCFG_FRAME_INTERVAL_95 3U
/**
* @}
*/
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
* @{
*/
#define EP_MPS_64 0U
#define EP_MPS_32 1U
#define EP_MPS_16 2U
#define EP_MPS_8 3U
/**
* @}
*/
/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
* @{
*/
#define EP_TYPE_CTRL 0U
#define EP_TYPE_ISOC 1U
#define EP_TYPE_BULK 2U
#define EP_TYPE_INTR 3U
#define EP_TYPE_MSK 3U
/**
* @}
*/
/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed
* @{
*/
#define EP_SPEED_LOW 0U
#define EP_SPEED_FULL 1U
#define EP_SPEED_HIGH 2U
/**
* @}
*/
/** @defgroup USB_LL_CH_PID_Type USB Low Layer Channel PID Type
* @{
*/
#define HC_PID_DATA0 0U
#define HC_PID_DATA2 1U
#define HC_PID_DATA1 2U
#define HC_PID_SETUP 3U
/**
* @}
*/
/** @defgroup USB_LL Device Speed
* @{
*/
#define USBD_HS_SPEED 0U
#define USBD_HSINFS_SPEED 1U
#define USBH_HS_SPEED 0U
#define USBD_FS_SPEED 2U
#define USBH_FSLS_SPEED 1U
/**
* @}
*/
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
/** @defgroup USB_LL_STS_Defines USB Low Layer STS Defines
* @{
*/
#define STS_GOUT_NAK 1U
#define STS_DATA_UPDT 2U
#define STS_XFER_COMP 3U
#define STS_SETUP_COMP 4U
#define STS_SETUP_UPDT 6U
/**
* @}
*/
/** @defgroup USB_LL_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines
* @{
*/
#define HCFG_30_60_MHZ 0U
#define HCFG_48_MHZ 1U
#define HCFG_6_MHZ 2U
/**
* @}
*/
/** @defgroup USB_LL_HFIR_Defines USB Low Layer frame interval Defines
* @{
*/
#define HFIR_6_MHZ 6000U
#define HFIR_60_MHZ 60000U
#define HFIR_48_MHZ 48000U
/**
* @}
*/
/** @defgroup USB_LL_PHYC_CLK_INIT_Defines USB Low Layer PHYC Clock Init Defines
* @{
*/
#define PHYC_12_MHZ 12000000U
#define PHYC_12_5_MHZ 12500000U
#define PHYC_16_MHZ 16000000U
#define PHYC_24_MHZ 24000000U
#define PHYC_25_MHZ 25000000U
#define PHYC_32_MHZ 32000000U
/**
* @}
*/
/** @defgroup USB_LL_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines
* @{
*/
#define HPRT0_PRTSPD_HIGH_SPEED 0U
#define HPRT0_PRTSPD_FULL_SPEED 1U
#define HPRT0_PRTSPD_LOW_SPEED 2U
/**
* @}
*/
#define HCCHAR_CTRL 0U
#define HCCHAR_ISOC 1U
#define HCCHAR_BULK 2U
#define HCCHAR_INTR 3U
#define GRXSTS_PKTSTS_IN 2U
#define GRXSTS_PKTSTS_IN_XFER_COMP 3U
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U
#define GRXSTS_PKTSTS_CH_HALTED 7U
#define CLEAR_INTERRUPT_MASK 0xFFFFFFFFU
#define HC_MAX_PKT_CNT 256U
#define ISO_SPLT_MPS 188U
#define HCSPLT_BEGIN 1U
#define HCSPLT_MIDDLE 2U
#define HCSPLT_END 3U
#define HCSPLT_FULL 4U
#define TEST_J 1U
#define TEST_K 2U
#define TEST_SE0_NAK 3U
#define TEST_PACKET 4U
#define TEST_FORCE_EN 5U
#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_PCGCCTL_BASE)
#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_HOST_PORT_BASE)
#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)(USBx_BASE + USB_OTG_DEVICE_BASE))
#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)(USBx_BASE\
+ USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)(USBx_BASE\
+ USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
#define USBx_DFIFO(i) *(__IO uint32_t *)(USBx_BASE + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE))
#define USBx_HOST ((USB_OTG_HostTypeDef *)(USBx_BASE + USB_OTG_HOST_BASE))
#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)(USBx_BASE\
+ USB_OTG_HOST_CHANNEL_BASE\
+ ((i) * USB_OTG_HOST_CHANNEL_SIZE)))
/* Legacy name for USBPHYC defined in CMSIS device but USBCPHYC used in USB driver
to determine if peripheral is present or not */
#ifdef USB_HS_PHYC
#define USBPHYC USB_HS_PHYC
#endif /* USB_HS_PHYC */
#define EP_ADDR_MSK 0xFU
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/** @defgroup USB_LL_Exported_Macros USB Low Layer Exported Macros
* @{
*/
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__))
#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__))
#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__))
#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__))
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
* @{
*/
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx, uint32_t hclk, uint8_t speed);
HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode);
HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed);
HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num);
HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma);
HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
uint8_t ch_ep_num, uint16_t len, uint8_t dma);
void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len);
HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address);
HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup);
uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx);
uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum);
uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt);
HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq);
HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state);
uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx);
uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx);
HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
uint8_t epnum, uint8_t dev_address, uint8_t speed,
uint8_t ep_type, uint16_t mps);
HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx,
USB_OTG_HCTypeDef *hc, uint8_t dma);
uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num);
HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num);
HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx);
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* STM32F7xx_LL_USB_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file fatfs.c
* @brief Code for fatfs applications
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
#include "fatfs.h"
uint8_t retUSBH; /* Return value for USBH */
char USBHPath[4]; /* USBH logical drive path */
FATFS USBHFatFS; /* File system object for USBH logical drive */
FIL USBHFile; /* File object for USBH */
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
void MX_FATFS_Init(void)
{
/*## FatFS: Link the USBH driver ###########################*/
retUSBH = FATFS_LinkDriver(&USBH_Driver, USBHPath);
/* USER CODE BEGIN Init */
/* additional user code for init */
/* USER CODE END Init */
}
/**
* @brief Gets Time from RTC
* @param None
* @retval Time in DWORD
*/
DWORD get_fattime(void)
{
/* USER CODE BEGIN get_fattime */
return 0;
/* USER CODE END get_fattime */
}
/* USER CODE BEGIN Application */
/* USER CODE END Application */

View File

@ -0,0 +1,47 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file fatfs.h
* @brief Header for fatfs applications
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __fatfs_H
#define __fatfs_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ff.h"
#include "ff_gen_drv.h"
#include "usbh_diskio.h" /* defines USBH_Driver as external */
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern uint8_t retUSBH; /* Return value for USBH */
extern char USBHPath[4]; /* USBH logical drive path */
extern FATFS USBHFatFS; /* File system object for USBH logical drive */
extern FIL USBHFile; /* File object for USBH */
void MX_FATFS_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__fatfs_H */

View File

@ -0,0 +1,272 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* FatFs - Generic FAT file system module R0.12c (C)ChaN, 2017
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
#ifndef _FFCONF
#define _FFCONF 68300 /* Revision ID */
/*-----------------------------------------------------------------------------/
/ Additional user header to be used
/-----------------------------------------------------------------------------*/
#include "main.h"
#include "stm32f7xx_hal.h"
#include "usbh_core.h"
#include "usbh_msc.h"
#include "cmsis_os.h" /* _FS_REENTRANT set to 1 and CMSIS API chosen */
/* Handle for USB Host */
#define hUSB_Host hUsbHostFS
/*-----------------------------------------------------------------------------/
/ Function Configurations
/-----------------------------------------------------------------------------*/
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define _FS_MINIMIZE 0 /* 0 to 3 */
/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define _USE_MKFS 1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_FASTSEEK 1
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define _USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define _USE_CHMOD 0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
#define _USE_LABEL 0
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*-----------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/-----------------------------------------------------------------------------*/
#define _CODE_PAGE 850
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
*/
#define _USE_LFN 0 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
/* The _USE_LFN switches the support of long file name (LFN).
/
/ 0: Disable support of LFN. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
/ It should be set 255 to support full featured LFN operations.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/ This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/
/ 0: ANSI/OEM
/ 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 0 /* 0 to 2 */
/* This option configures support of relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/----------------------------------------------------------------------------*/
#define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */
/* USER CODE BEGIN Volumes */
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
/* _STR_VOLUME_ID switches string support of volume ID.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
/* USER CODE END Volumes */
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Multiple partition */
/* This option switches support of multi-partition on a physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When multi-partition is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ function will be available. */
#define _MIN_SS 512 /* 512, 1024, 2048 or 4096 */
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_TRIM 0
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0 /* 0,1,2 or 3 */
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/----------------------------------------------------------------------------*/
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
#define _FS_EXFAT 0
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 0
#define _NORTC_MON 6
#define _NORTC_MDAY 4
#define _NORTC_YEAR 2015
/* The option _FS_NORTC switches timestamp function. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to get current time form real-time clock. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
#define _FS_LOCK 2 /* 0:Disable or >=1:Enable */
/* The option _FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t osSemaphoreId
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* define the ff_malloc ff_free macros as FreeRTOS pvPortMalloc and vPortFree macros */
#if !defined(ff_malloc) && !defined(ff_free)
#define ff_malloc pvPortMalloc
#define ff_free vPortFree
#endif
#endif /* _FFCONF */

View File

@ -0,0 +1,267 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usbh_diskio.c (based on usbh_diskio_template.c v2.0.2)
* @brief USB Host Disk I/O driver
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* USER CODE BEGIN firstSection */
/* can be used to modify / undefine following code or add new definitions */
/* USER CODE END firstSection */
/* Includes ------------------------------------------------------------------*/
#include "ff_gen_drv.h"
#include "usbh_diskio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USB_DEFAULT_BLOCK_SIZE 512
/* Private variables ---------------------------------------------------------*/
extern USBH_HandleTypeDef hUSB_Host;
/* Private function prototypes -----------------------------------------------*/
DSTATUS USBH_initialize (BYTE);
DSTATUS USBH_status (BYTE);
DRESULT USBH_read (BYTE, BYTE*, DWORD, UINT);
#if _USE_WRITE == 1
DRESULT USBH_write (BYTE, const BYTE*, DWORD, UINT);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT USBH_ioctl (BYTE, BYTE, void*);
#endif /* _USE_IOCTL == 1 */
const Diskio_drvTypeDef USBH_Driver =
{
USBH_initialize,
USBH_status,
USBH_read,
#if _USE_WRITE == 1
USBH_write,
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
USBH_ioctl,
#endif /* _USE_IOCTL == 1 */
};
/* USER CODE BEGIN beforeFunctionSection */
/* can be used to modify / undefine following code or add new code */
/* USER CODE END beforeFunctionSection */
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes a Drive
* @param lun : lun id
* @retval DSTATUS: Operation status
*/
DSTATUS USBH_initialize(BYTE lun)
{
/* CAUTION : USB Host library has to be initialized in the application */
return RES_OK;
}
/**
* @brief Gets Disk Status
* @param lun : lun id
* @retval DSTATUS: Operation status
*/
DSTATUS USBH_status(BYTE lun)
{
DRESULT res = RES_ERROR;
if(USBH_MSC_UnitIsReady(&hUSB_Host, lun))
{
res = RES_OK;
}
else
{
res = RES_ERROR;
}
return res;
}
/* USER CODE BEGIN beforeReadSection */
/* can be used to modify previous code / undefine following code / add new code */
/* USER CODE END beforeReadSection */
/**
* @brief Reads Sector(s)
* @param lun : lun id
* @param *buff: Data buffer to store read data
* @param sector: Sector address (LBA)
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
DRESULT USBH_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_ERROR;
MSC_LUNTypeDef info;
if(USBH_MSC_Read(&hUSB_Host, lun, sector, buff, count) == USBH_OK)
{
res = RES_OK;
}
else
{
USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info);
switch (info.sense.asc)
{
case SCSI_ASC_LOGICAL_UNIT_NOT_READY:
case SCSI_ASC_MEDIUM_NOT_PRESENT:
case SCSI_ASC_NOT_READY_TO_READY_CHANGE:
USBH_ErrLog ("USB Disk is not ready!");
res = RES_NOTRDY;
break;
default:
res = RES_ERROR;
break;
}
}
return res;
}
/* USER CODE BEGIN beforeWriteSection */
/* can be used to modify previous code / undefine following code / add new code */
/* USER CODE END beforeWriteSection */
/**
* @brief Writes Sector(s)
* @param lun : lun id
* @param *buff: Data to be written
* @param sector: Sector address (LBA)
* @param count: Number of sectors to write (1..128)
* @retval DRESULT: Operation result
*/
#if _USE_WRITE == 1
DRESULT USBH_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_ERROR;
MSC_LUNTypeDef info;
if(USBH_MSC_Write(&hUSB_Host, lun, sector, (BYTE *)buff, count) == USBH_OK)
{
res = RES_OK;
}
else
{
USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info);
switch (info.sense.asc)
{
case SCSI_ASC_WRITE_PROTECTED:
USBH_ErrLog("USB Disk is Write protected!");
res = RES_WRPRT;
break;
case SCSI_ASC_LOGICAL_UNIT_NOT_READY:
case SCSI_ASC_MEDIUM_NOT_PRESENT:
case SCSI_ASC_NOT_READY_TO_READY_CHANGE:
USBH_ErrLog("USB Disk is not ready!");
res = RES_NOTRDY;
break;
default:
res = RES_ERROR;
break;
}
}
return res;
}
#endif /* _USE_WRITE == 1 */
/* USER CODE BEGIN beforeIoctlSection */
/* can be used to modify previous code / undefine following code / add new code */
/* USER CODE END beforeIoctlSection */
/**
* @brief I/O control operation
* @param lun : lun id
* @param cmd: Control code
* @param *buff: Buffer to send/receive control data
* @retval DRESULT: Operation result
*/
#if _USE_IOCTL == 1
DRESULT USBH_ioctl(BYTE lun, BYTE cmd, void *buff)
{
DRESULT res = RES_ERROR;
MSC_LUNTypeDef info;
switch (cmd)
{
/* Make sure that no pending write process */
case CTRL_SYNC:
res = RES_OK;
break;
/* Get number of sectors on the disk (DWORD) */
case GET_SECTOR_COUNT :
if(USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info) == USBH_OK)
{
*(DWORD*)buff = info.capacity.block_nbr;
res = RES_OK;
}
else
{
res = RES_ERROR;
}
break;
/* Get R/W sector size (WORD) */
case GET_SECTOR_SIZE :
if(USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info) == USBH_OK)
{
*(DWORD*)buff = info.capacity.block_size;
res = RES_OK;
}
else
{
res = RES_ERROR;
}
break;
/* Get erase block size in unit of sector (DWORD) */
case GET_BLOCK_SIZE :
if(USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info) == USBH_OK)
{
*(DWORD*)buff = info.capacity.block_size / USB_DEFAULT_BLOCK_SIZE;
res = RES_OK;
}
else
{
res = RES_ERROR;
}
break;
default:
res = RES_PARERR;
}
return res;
}
#endif /* _USE_IOCTL == 1 */
/* USER CODE BEGIN lastSection */
/* can be used to modify / undefine previous code or add new code */
/* USER CODE END lastSection */

View File

@ -0,0 +1,40 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usbh_diskio.h (based on usbh_diskio_template.h v2.0.2)
* @brief Header for usbh_diskio.c module
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBH_DISKIO_H
#define __USBH_DISKIO_H
/* USER CODE BEGIN firstSection */
/* can be used to modify / undefine following code or add new definitions */
/* USER CODE END firstSection */
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "usbh_msc.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
extern const Diskio_drvTypeDef USBH_Driver;
/* USER CODE BEGIN lastSection */
/* can be used to modify / undefine previous code or add new definitions */
/* USER CODE END lastSection */
#endif /* __USBH_DISKIO_H */

View File

@ -0,0 +1,216 @@
/**
******************************************************************************
* @file usbh_msc.h
* @author MCD Application Team
* @brief This file contains all the prototypes for the usbh_msc.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_H
#define __USBH_MSC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "usbh_msc_bot.h"
#include "usbh_msc_scsi.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_CORE
* @brief This file is the Header file for usbh_msc.c
* @{
*/
/** @defgroup USBH_MSC_CORE_Exported_Types
* @{
*/
typedef enum
{
MSC_INIT = 0,
MSC_IDLE,
MSC_TEST_UNIT_READY,
MSC_READ_CAPACITY10,
MSC_READ_INQUIRY,
MSC_REQUEST_SENSE,
MSC_READ,
MSC_WRITE,
MSC_UNRECOVERED_ERROR,
MSC_PERIODIC_CHECK,
MSC_USER_NOTIFY
}
MSC_StateTypeDef;
typedef enum
{
MSC_OK,
MSC_NOT_READY,
MSC_ERROR,
}
MSC_ErrorTypeDef;
typedef enum
{
MSC_REQ_IDLE = 0,
MSC_REQ_RESET,
MSC_REQ_GET_MAX_LUN,
MSC_REQ_ERROR,
}
MSC_ReqStateTypeDef;
#ifndef MAX_SUPPORTED_LUN
#define MAX_SUPPORTED_LUN 2U
#endif
/* Structure for LUN */
typedef struct
{
MSC_StateTypeDef state;
MSC_ErrorTypeDef error;
USBH_StatusTypeDef prev_ready_state;
SCSI_CapacityTypeDef capacity;
SCSI_SenseTypeDef sense;
SCSI_StdInquiryDataTypeDef inquiry;
uint8_t state_changed;
}
MSC_LUNTypeDef;
/* Structure for MSC process */
typedef struct _MSC_Process
{
uint8_t max_lun;
uint8_t Reserved[3];
uint8_t InPipe;
uint8_t OutPipe;
uint8_t OutEp;
uint8_t InEp;
uint16_t OutEpSize;
uint16_t InEpSize;
MSC_StateTypeDef state;
MSC_ErrorTypeDef error;
MSC_ReqStateTypeDef req_state;
MSC_ReqStateTypeDef prev_req_state;
BOT_HandleTypeDef hbot;
MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN];
uint16_t current_lun;
uint16_t lun;
uint16_t rw_lun;
uint32_t timer;
}
MSC_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Defines
* @{
*/
#define USB_REQ_BOT_RESET 0xFFU
#define USB_REQ_GET_MAX_LUN 0xFEU
/* MSC Class Codes */
#define USB_MSC_CLASS 0x08U
/* Interface Descriptor field values for HID Boot Protocol */
#define MSC_BOT 0x50U
#define MSC_TRANSPARENT 0x06U
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Variables
* @{
*/
extern USBH_ClassTypeDef USBH_msc;
#define USBH_MSC_CLASS &USBH_msc
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_FunctionsPrototype
* @{
*/
uint8_t USBH_MSC_IsReady(USBH_HandleTypeDef *phost);
uint8_t USBH_MSC_GetMaxLUN(USBH_HandleTypeDef *phost);
uint8_t USBH_MSC_UnitIsReady(USBH_HandleTypeDef *phost, uint8_t lun);
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun,
MSC_LUNTypeDef *info);
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost, uint8_t lun,
uint32_t address, uint8_t *pbuf, uint32_t length);
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost, uint8_t lun,
uint32_t address, uint8_t *pbuf, uint32_t length);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_MSC_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,230 @@
/**
******************************************************************************
* @file usbh_msc_bot.h
* @author MCD Application Team
* @brief Header file for usbh_msc_bot.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_BOT_H
#define __USBH_MSC_BOT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_BOT
* @brief This file is the Header file for usbh_msc_bot.c
* @{
*/
/** @defgroup USBH_MSC_BOT_Exported_Types
* @{
*/
typedef enum
{
BOT_OK = 0,
BOT_FAIL = 1,
BOT_PHASE_ERROR = 2,
BOT_BUSY = 3
}
BOT_StatusTypeDef;
typedef enum
{
BOT_CMD_IDLE = 0,
BOT_CMD_SEND,
BOT_CMD_WAIT,
}
BOT_CMDStateTypeDef;
/* CSW Status Definitions */
typedef enum
{
BOT_CSW_CMD_PASSED = 0x00,
BOT_CSW_CMD_FAILED = 0x01,
BOT_CSW_PHASE_ERROR = 0x02,
}
BOT_CSWStatusTypeDef;
typedef enum
{
BOT_SEND_CBW = 1,
BOT_SEND_CBW_WAIT,
BOT_DATA_IN,
BOT_DATA_IN_WAIT,
BOT_DATA_OUT,
BOT_DATA_OUT_WAIT,
BOT_RECEIVE_CSW,
BOT_RECEIVE_CSW_WAIT,
BOT_ERROR_IN,
BOT_ERROR_OUT,
BOT_UNRECOVERED_ERROR
}
BOT_StateTypeDef;
typedef union
{
struct __CBW
{
uint32_t Signature;
uint32_t Tag;
uint32_t DataTransferLength;
uint8_t Flags;
uint8_t LUN;
uint8_t CBLength;
uint8_t CB[16];
} field;
uint8_t data[31];
}
BOT_CBWTypeDef;
typedef union
{
struct __CSW
{
uint32_t Signature;
uint32_t Tag;
uint32_t DataResidue;
uint8_t Status;
} field;
uint8_t data[13];
}
BOT_CSWTypeDef;
typedef struct
{
uint32_t data[16];
BOT_StateTypeDef state;
BOT_StateTypeDef prev_state;
BOT_CMDStateTypeDef cmd_state;
BOT_CBWTypeDef cbw;
uint8_t Reserved1;
BOT_CSWTypeDef csw;
uint8_t Reserved2[3];
uint8_t *pbuf;
}
BOT_HandleTypeDef;
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Defines
* @{
*/
#define BOT_CBW_SIGNATURE 0x43425355U
#define BOT_CBW_TAG 0x20304050U
#define BOT_CSW_SIGNATURE 0x53425355U
#define BOT_CBW_LENGTH 31U
#define BOT_CSW_LENGTH 13U
#define BOT_SEND_CSW_DISABLE 0U
#define BOT_SEND_CSW_ENABLE 1U
#define BOT_DIR_IN 0U
#define BOT_DIR_OUT 1U
#define BOT_DIR_BOTH 2U
#define BOT_PAGE_LENGTH 512U
#define BOT_CBW_CB_LENGTH 16U
#define MAX_BULK_STALL_COUNT_LIMIT 0x04U /* If STALL is seen on Bulk
Endpoint continuously, this means
that device and Host has phase error
Hence a Reset is needed */
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun);
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_MSC_BOT_Process(USBH_HandleTypeDef *phost, uint8_t lun);
USBH_StatusTypeDef USBH_MSC_BOT_Error(USBH_HandleTypeDef *phost, uint8_t lun);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_MSC_BOT_H__ */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,215 @@
/**
******************************************************************************
* @file usbh_msc_scsi.h
* @author MCD Application Team
* @brief Header file for usbh_msc_scsi.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_MSC_SCSI_H
#define __USBH_MSC_SCSI_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_SCSI
* @brief This file is the Header file for usbh_msc_scsi.c
* @{
*/
/* Capacity data */
typedef struct
{
uint32_t block_nbr;
uint16_t block_size;
} SCSI_CapacityTypeDef;
/* Sense data */
typedef struct
{
uint8_t key;
uint8_t asc;
uint8_t ascq;
} SCSI_SenseTypeDef;
/* INQUIRY data */
typedef struct
{
uint8_t PeripheralQualifier;
uint8_t DeviceType;
uint8_t RemovableMedia;
uint8_t vendor_id[9];
uint8_t product_id[17];
uint8_t revision_id[5];
} SCSI_StdInquiryDataTypeDef;
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define OPCODE_TEST_UNIT_READY 0x00U
#define OPCODE_READ_CAPACITY10 0x25U
#define OPCODE_READ10 0x28U
#define OPCODE_WRITE10 0x2AU
#define OPCODE_REQUEST_SENSE 0x03U
#define OPCODE_INQUIRY 0x12U
#define DATA_LEN_MODE_TEST_UNIT_READY 0U
#define DATA_LEN_READ_CAPACITY10 8U
#define DATA_LEN_INQUIRY 36U
#define DATA_LEN_REQUEST_SENSE 14U
#define CBW_CB_LENGTH 16U
#define CBW_LENGTH 10U
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define SCSI_SENSE_KEY_NO_SENSE 0x00U
#define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01U
#define SCSI_SENSE_KEY_NOT_READY 0x02U
#define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03U
#define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04U
#define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05U
#define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06U
#define SCSI_SENSE_KEY_DATA_PROTECT 0x07U
#define SCSI_SENSE_KEY_BLANK_CHECK 0x08U
#define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09U
#define SCSI_SENSE_KEY_COPY_ABORTED 0x0AU
#define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0BU
#define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0DU
#define SCSI_SENSE_KEY_MISCOMPARE 0x0EU
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define SCSI_ASC_NO_ADDITIONAL_SENSE_INFORMATION 0x00
#define SCSI_ASC_LOGICAL_UNIT_NOT_READY 0x04
#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
#define SCSI_ASC_WRITE_PROTECTED 0x27
#define SCSI_ASC_FORMAT_ERROR 0x31
#define SCSI_ASC_INVALID_COMMAND_OPERATION_CODE 0x20
#define SCSI_ASC_NOT_READY_TO_READY_CHANGE 0x28
#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Defines
* @{
*/
#define SCSI_ASCQ_FORMAT_COMMAND_FAILED 0x01
#define SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
#define SCSI_ASCQ_OPERATION_IN_PROGRESS 0x07
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup _Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady(USBH_HandleTypeDef *phost,
uint8_t lun);
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_CapacityTypeDef *capacity);
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_StdInquiryDataTypeDef *inquiry);
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_SenseTypeDef *sense_data);
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length);
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_MSC_SCSI_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,869 @@
/**
******************************************************************************
* @file usbh_msc.c
* @author MCD Application Team
* @brief This file implements the MSC class driver functions
*
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
* @verbatim
*
* ===================================================================
* MSC Class Description
* ===================================================================
* This module manages the MSC class V1.0 following the "Universal
* Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0
* Sep. 31, 1999".
* This driver implements the following aspects of the specification:
* - Bulk-Only Transport protocol
* - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3))
*
* @endverbatim
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc.h"
#include "usbh_msc_bot.h"
#include "usbh_msc_scsi.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_CORE
* @brief This file includes the mass storage related functions
* @{
*/
/** @defgroup USBH_MSC_CORE_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_MSC_InterfaceInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_InterfaceDeInit(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost);
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun);
USBH_ClassTypeDef USBH_msc =
{
"MSC",
USB_MSC_CLASS,
USBH_MSC_InterfaceInit,
USBH_MSC_InterfaceDeInit,
USBH_MSC_ClassRequest,
USBH_MSC_Process,
USBH_MSC_SOFProcess,
NULL,
};
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_CORE_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_InterfaceInit
* The function init the MSC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_InterfaceInit(USBH_HandleTypeDef *phost)
{
USBH_StatusTypeDef status;
uint8_t interface;
MSC_HandleTypeDef *MSC_Handle;
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, MSC_TRANSPARENT, MSC_BOT);
if ((interface == 0xFFU) || (interface >= USBH_MAX_NUM_INTERFACES)) /* Not Valid Interface */
{
USBH_DbgLog("Cannot Find the interface for %s class.", phost->pActiveClass->Name);
return USBH_FAIL;
}
status = USBH_SelectInterface(phost, interface);
if (status != USBH_OK)
{
return USBH_FAIL;
}
phost->pActiveClass->pData = (MSC_HandleTypeDef *)USBH_malloc(sizeof(MSC_HandleTypeDef));
MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if (MSC_Handle == NULL)
{
USBH_DbgLog("Cannot allocate memory for MSC Handle");
return USBH_FAIL;
}
/* Initialize msc handler */
(void)USBH_memset(MSC_Handle, 0, sizeof(MSC_HandleTypeDef));
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress & 0x80U) != 0U)
{
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress);
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
else
{
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].bEndpointAddress);
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[0].wMaxPacketSize;
}
if ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress & 0x80U) != 0U)
{
MSC_Handle->InEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress);
MSC_Handle->InEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
else
{
MSC_Handle->OutEp = (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].bEndpointAddress);
MSC_Handle->OutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[1].wMaxPacketSize;
}
MSC_Handle->state = MSC_INIT;
MSC_Handle->error = MSC_OK;
MSC_Handle->req_state = MSC_REQ_IDLE;
MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp);
MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp);
(void)USBH_MSC_BOT_Init(phost);
/* Open the new channels */
if ((MSC_Handle->OutEp != 0U) && (MSC_Handle->OutEpSize != 0U))
{
(void)USBH_OpenPipe(phost, MSC_Handle->OutPipe, MSC_Handle->OutEp,
phost->device.address, phost->device.speed,
USB_EP_TYPE_BULK, MSC_Handle->OutEpSize);
}
else
{
return USBH_NOT_SUPPORTED;
}
if ((MSC_Handle->InEp != 0U) && (MSC_Handle->InEpSize != 0U))
{
(void)USBH_OpenPipe(phost, MSC_Handle->InPipe, MSC_Handle->InEp,
phost->device.address, phost->device.speed, USB_EP_TYPE_BULK,
MSC_Handle->InEpSize);
}
else
{
return USBH_NOT_SUPPORTED;
}
(void)USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0U);
(void)USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 0U);
return USBH_OK;
}
/**
* @brief USBH_MSC_InterfaceDeInit
* The function DeInit the Pipes used for the MSC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_InterfaceDeInit(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((MSC_Handle->OutPipe) != 0U)
{
(void)USBH_ClosePipe(phost, MSC_Handle->OutPipe);
(void)USBH_FreePipe(phost, MSC_Handle->OutPipe);
MSC_Handle->OutPipe = 0U; /* Reset the Channel as Free */
}
if ((MSC_Handle->InPipe != 0U))
{
(void)USBH_ClosePipe(phost, MSC_Handle->InPipe);
(void)USBH_FreePipe(phost, MSC_Handle->InPipe);
MSC_Handle->InPipe = 0U; /* Reset the Channel as Free */
}
if ((phost->pActiveClass->pData) != NULL)
{
USBH_free(phost->pActiveClass->pData);
phost->pActiveClass->pData = 0U;
}
return USBH_OK;
}
/**
* @brief USBH_MSC_ClassRequest
* The function is responsible for handling Standard requests
* for MSC class.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_ClassRequest(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_StatusTypeDef status = USBH_BUSY;
uint8_t lun_idx;
/* Switch MSC REQ state machine */
switch (MSC_Handle->req_state)
{
case MSC_REQ_IDLE:
case MSC_REQ_GET_MAX_LUN:
/* Issue GetMaxLUN request */
status = USBH_MSC_BOT_REQ_GetMaxLUN(phost, &MSC_Handle->max_lun);
/* When devices do not support the GetMaxLun request, this should
be considered as only one logical unit is supported */
if (status == USBH_NOT_SUPPORTED)
{
MSC_Handle->max_lun = 0U;
status = USBH_OK;
}
if (status == USBH_OK)
{
MSC_Handle->max_lun = (MSC_Handle->max_lun > MAX_SUPPORTED_LUN) ? MAX_SUPPORTED_LUN : (MSC_Handle->max_lun + 1U);
USBH_UsrLog("Number of supported LUN: %d", MSC_Handle->max_lun);
for (lun_idx = 0U; lun_idx < MSC_Handle->max_lun; lun_idx++)
{
MSC_Handle->unit[lun_idx].prev_ready_state = USBH_FAIL;
MSC_Handle->unit[lun_idx].state_changed = 0U;
}
}
break;
case MSC_REQ_ERROR:
/* a Clear Feature should be issued here */
if (USBH_ClrFeature(phost, 0x00U) == USBH_OK)
{
MSC_Handle->req_state = MSC_Handle->prev_req_state;
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_MSC_Process
* The function is for managing state machine for MSC data transfers
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_StatusTypeDef error = USBH_BUSY;
USBH_StatusTypeDef scsi_status = USBH_BUSY;
USBH_StatusTypeDef ready_status = USBH_BUSY;
switch (MSC_Handle->state)
{
case MSC_INIT:
if (MSC_Handle->current_lun < MSC_Handle->max_lun)
{
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
/* Switch MSC REQ state machine */
switch (MSC_Handle->unit[MSC_Handle->current_lun].state)
{
case MSC_INIT:
USBH_UsrLog("LUN #%d: ", MSC_Handle->current_lun);
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_INQUIRY;
MSC_Handle->timer = phost->Timer;
break;
case MSC_READ_INQUIRY:
scsi_status = USBH_MSC_SCSI_Inquiry(phost, (uint8_t)MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].inquiry);
if (scsi_status == USBH_OK)
{
USBH_UsrLog("Inquiry Vendor : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.vendor_id);
USBH_UsrLog("Inquiry Product : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.product_id);
USBH_UsrLog("Inquiry Version : %s", MSC_Handle->unit[MSC_Handle->current_lun].inquiry.revision_id);
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_TEST_UNIT_READY:
ready_status = USBH_MSC_SCSI_TestUnitReady(phost, (uint8_t)MSC_Handle->current_lun);
if (ready_status == USBH_OK)
{
if (MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_OK)
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1U;
USBH_UsrLog("MSC Device ready");
}
else
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0U;
}
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_CAPACITY10;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_OK;
}
else if (ready_status == USBH_FAIL)
{
/* Media not ready, so try to check again during 10s */
if (MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state != USBH_FAIL)
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 1U;
USBH_UsrLog("MSC Device NOT ready");
}
else
{
MSC_Handle->unit[MSC_Handle->current_lun].state_changed = 0U;
}
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_NOT_READY;
MSC_Handle->unit[MSC_Handle->current_lun].prev_ready_state = USBH_FAIL;
}
else
{
if (ready_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_READ_CAPACITY10:
scsi_status = USBH_MSC_SCSI_ReadCapacity(phost, (uint8_t)MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].capacity);
if (scsi_status == USBH_OK)
{
if (MSC_Handle->unit[MSC_Handle->current_lun].state_changed == 1U)
{
USBH_UsrLog("MSC Device capacity : %u Bytes", \
(unsigned int)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr *
MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
USBH_UsrLog("Block number : %u", (unsigned int)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_nbr));
USBH_UsrLog("Block Size : %u", (unsigned int)(MSC_Handle->unit[MSC_Handle->current_lun].capacity.block_size));
}
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_OK;
MSC_Handle->current_lun++;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_REQUEST_SENSE:
scsi_status = USBH_MSC_SCSI_RequestSense(phost, (uint8_t)MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].sense);
if (scsi_status == USBH_OK)
{
if ((MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_UNIT_ATTENTION) ||
(MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_NOT_READY))
{
if ((phost->Timer - MSC_Handle->timer) < 10000U)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
break;
}
}
USBH_UsrLog("Sense Key : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.key);
USBH_UsrLog("Additional Sense Code : %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.asc);
USBH_UsrLog("Additional Sense Code Qualifier: %x", MSC_Handle->unit[MSC_Handle->current_lun].sense.ascq);
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_IDLE;
MSC_Handle->current_lun++;
}
else if (scsi_status == USBH_FAIL)
{
USBH_UsrLog("MSC Device NOT ready");
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_UNRECOVERED_ERROR;
MSC_Handle->unit[MSC_Handle->current_lun].error = MSC_ERROR;
}
}
break;
case MSC_UNRECOVERED_ERROR:
MSC_Handle->current_lun++;
break;
default:
break;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
MSC_Handle->current_lun = 0U;
MSC_Handle->state = MSC_USER_NOTIFY;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
break;
case MSC_USER_NOTIFY:
if (MSC_Handle->lun < MSC_Handle->max_lun)
{
MSC_Handle->current_lun = MSC_Handle->lun;
if (MSC_Handle->unit[MSC_Handle->current_lun].error == MSC_OK)
{
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
}
else
{
phost->pUser(phost, HOST_USER_UNRECOVERED_ERROR);
}
MSC_Handle->lun++;
}
else
{
MSC_Handle->lun = 0U;
MSC_Handle->state = MSC_IDLE;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case MSC_IDLE:
error = USBH_OK;
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SOFProcess
* The function is for SOF state
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_SOFProcess(USBH_HandleTypeDef *phost)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
return USBH_OK;
}
/**
* @brief USBH_MSC_RdWrProcess
* The function is for managing state machine for MSC I/O Process
* @param phost: Host handle
* @param lun: logical Unit Number
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_t lun)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
USBH_StatusTypeDef error = USBH_BUSY;
USBH_StatusTypeDef scsi_status = USBH_BUSY;
/* Switch MSC REQ state machine */
switch (MSC_Handle->unit[lun].state)
{
case MSC_READ:
scsi_status = USBH_MSC_SCSI_Read(phost, lun, 0U, NULL, 0U);
if (scsi_status == USBH_OK)
{
MSC_Handle->unit[lun].state = MSC_IDLE;
error = USBH_OK;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL;
}
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case MSC_WRITE:
scsi_status = USBH_MSC_SCSI_Write(phost, lun, 0U, NULL, 0U);
if (scsi_status == USBH_OK)
{
MSC_Handle->unit[lun].state = MSC_IDLE;
error = USBH_OK;
}
else if (scsi_status == USBH_FAIL)
{
MSC_Handle->unit[lun].state = MSC_REQUEST_SENSE;
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL;
}
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
case MSC_REQUEST_SENSE:
scsi_status = USBH_MSC_SCSI_RequestSense(phost, lun, &MSC_Handle->unit[lun].sense);
if (scsi_status == USBH_OK)
{
USBH_UsrLog("Sense Key : %x", MSC_Handle->unit[lun].sense.key);
USBH_UsrLog("Additional Sense Code : %x", MSC_Handle->unit[lun].sense.asc);
USBH_UsrLog("Additional Sense Code Qualifier: %x", MSC_Handle->unit[lun].sense.ascq);
MSC_Handle->unit[lun].state = MSC_IDLE;
MSC_Handle->unit[lun].error = MSC_ERROR;
error = USBH_FAIL;
}
else if (scsi_status == USBH_FAIL)
{
USBH_UsrLog("MSC Device NOT ready");
}
else
{
if (scsi_status == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL;
}
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_CLASS_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_IsReady
* The function check if the MSC function is ready
* @param phost: Host handle
* @retval USBH Status
*/
uint8_t USBH_MSC_IsReady(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
uint8_t res;
if ((phost->gState == HOST_CLASS) && (MSC_Handle->state == MSC_IDLE))
{
res = 1U;
}
else
{
res = 0U;
}
return res;
}
/**
* @brief USBH_MSC_GetMaxLUN
* The function return the Max LUN supported
* @param phost: Host handle
* @retval logical Unit Number supported
*/
uint8_t USBH_MSC_GetMaxLUN(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->gState == HOST_CLASS) && (MSC_Handle->state == MSC_IDLE))
{
return (uint8_t)MSC_Handle->max_lun;
}
return 0xFFU;
}
/**
* @brief USBH_MSC_UnitIsReady
* The function check whether a LUN is ready
* @param phost: Host handle
* @param lun: logical Unit Number
* @retval Lun status (0: not ready / 1: ready)
*/
uint8_t USBH_MSC_UnitIsReady(USBH_HandleTypeDef *phost, uint8_t lun)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
uint8_t res;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if ((phost->gState == HOST_CLASS) && (MSC_Handle->unit[lun].error == MSC_OK))
{
res = 1U;
}
else
{
res = 0U;
}
return res;
}
/**
* @brief USBH_MSC_GetLUNInfo
* The function return a LUN information
* @param phost: Host handle
* @param lun: logical Unit Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, MSC_LUNTypeDef *info)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if (phost->gState == HOST_CLASS)
{
(void)USBH_memcpy(info, &MSC_Handle->unit[lun], sizeof(MSC_LUNTypeDef));
return USBH_OK;
}
else
{
return USBH_FAIL;
}
}
/**
* @brief USBH_MSC_Read
* The function performs a Read operation
* @param phost: Host handle
* @param lun: logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to read
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
uint32_t timeout;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if ((phost->device.PortEnabled == 0U) ||
(phost->gState != HOST_CLASS) ||
(MSC_Handle->unit[lun].state != MSC_IDLE))
{
return USBH_FAIL;
}
MSC_Handle->unit[lun].state = MSC_READ;
(void)USBH_MSC_SCSI_Read(phost, lun, address, pbuf, length);
timeout = phost->Timer;
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
{
if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.PortEnabled == 0U))
{
return USBH_FAIL;
}
}
return USBH_OK;
}
/**
* @brief USBH_MSC_Write
* The function performs a Write operation
* @param phost: Host handle
* @param lun: logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to write
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
uint32_t timeout;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
/* Store the current lun */
MSC_Handle->current_lun = lun;
if ((phost->device.PortEnabled == 0U) ||
(phost->gState != HOST_CLASS) ||
(MSC_Handle->unit[lun].state != MSC_IDLE))
{
return USBH_FAIL;
}
MSC_Handle->unit[lun].state = MSC_WRITE;
(void)USBH_MSC_SCSI_Write(phost, lun, address, pbuf, length);
timeout = phost->Timer;
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
{
if (((phost->Timer - timeout) > (10000U * length)) || (phost->device.PortEnabled == 0U))
{
return USBH_FAIL;
}
}
return USBH_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,687 @@
/**
******************************************************************************
* @file usbh_msc_bot.c
* @author MCD Application Team
* @brief This file includes the BOT protocol related functions
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc_bot.h"
#include "usbh_msc.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_BOT
* @brief This file includes the mass storage related functions
* @{
*/
/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir);
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost);
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_BOT_REQ_Reset
* The function the MSC BOT Reset request.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_Reset(USBH_HandleTypeDef *phost)
{
phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS
| USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_BOT_RESET;
phost->Control.setup.b.wValue.w = 0U;
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = 0U;
return USBH_CtlReq(phost, NULL, 0U);
}
/**
* @brief USBH_MSC_BOT_REQ_GetMaxLUN
* The function the MSC BOT GetMaxLUN request.
* @param phost: Host handle
* @param Maxlun: pointer to Maxlun variable
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_REQ_GetMaxLUN(USBH_HandleTypeDef *phost, uint8_t *Maxlun)
{
phost->Control.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS
| USB_REQ_RECIPIENT_INTERFACE;
phost->Control.setup.b.bRequest = USB_REQ_GET_MAX_LUN;
phost->Control.setup.b.wValue.w = 0U;
phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wLength.w = 1U;
return USBH_CtlReq(phost, Maxlun, 1U);
}
/**
* @brief USBH_MSC_BOT_Init
* The function Initializes the BOT protocol.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_Init(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
MSC_Handle->hbot.cbw.field.Signature = BOT_CBW_SIGNATURE;
MSC_Handle->hbot.cbw.field.Tag = BOT_CBW_TAG;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
return USBH_OK;
}
/**
* @brief USBH_MSC_BOT_Process
* The function handle the BOT protocol.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_BOT_Process(USBH_HandleTypeDef *phost, uint8_t lun)
{
USBH_StatusTypeDef status = USBH_BUSY;
USBH_StatusTypeDef error = USBH_BUSY;
BOT_CSWStatusTypeDef CSW_Status = BOT_CSW_CMD_FAILED;
USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
uint8_t toggle = 0U;
switch (MSC_Handle->hbot.state)
{
case BOT_SEND_CBW:
MSC_Handle->hbot.cbw.field.LUN = lun;
MSC_Handle->hbot.state = BOT_SEND_CBW_WAIT;
(void)USBH_BulkSendData(phost, MSC_Handle->hbot.cbw.data,
BOT_CBW_LENGTH, MSC_Handle->OutPipe, 1U);
break;
case BOT_SEND_CBW_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
if (URB_Status == USBH_URB_DONE)
{
if (MSC_Handle->hbot.cbw.field.DataTransferLength != 0U)
{
/* If there is Data Transfer Stage */
if (((MSC_Handle->hbot.cbw.field.Flags) & USB_REQ_DIR_MASK) == USB_D2H)
{
/* Data Direction is IN */
MSC_Handle->hbot.state = BOT_DATA_IN;
}
else
{
/* Data Direction is OUT */
MSC_Handle->hbot.state = BOT_DATA_OUT;
}
}
else
{
/* If there is NO Data Transfer Stage */
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else if (URB_Status == USBH_URB_NOTREADY)
{
/* Re-send CBW */
MSC_Handle->hbot.state = BOT_SEND_CBW;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
if (URB_Status == USBH_URB_STALL)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
}
break;
case BOT_DATA_IN:
/* Send first packet */
(void)USBH_BulkReceiveData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->InEpSize, MSC_Handle->InPipe);
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
phost->NakTimer = phost->Timer;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
break;
case BOT_DATA_IN_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
if (URB_Status == USBH_URB_DONE)
{
/* Adjust Data pointer and data length */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->InEpSize)
{
MSC_Handle->hbot.pbuf += MSC_Handle->InEpSize;
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->InEpSize;
}
else
{
MSC_Handle->hbot.cbw.field.DataTransferLength = 0U;
}
/* More Data To be Received */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > 0U)
{
/* Send next packet */
(void)USBH_BulkReceiveData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->InEpSize, MSC_Handle->InPipe);
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
phost->NakTimer = phost->Timer;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
}
else
{
/* If value was 0, and successful transfer, then change the state */
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
}
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
else if (URB_Status == USBH_URB_NAK_WAIT)
{
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
if ((phost->Timer - phost->NakTimer) > phost->NakTimeout)
{
phost->NakTimer = phost->Timer;
USBH_ActivatePipe(phost, MSC_Handle->InPipe);
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
else if (URB_Status == USBH_URB_STALL)
{
/* This is Data IN Stage STALL Condition */
MSC_Handle->hbot.state = BOT_ERROR_IN;
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
6.7.2 Host expects to receive data from the device
3. On a STALL condition receiving data, then:
The host shall accept the data received.
The host shall clear the Bulk-In pipe.
4. The host shall attempt to receive a CSW.*/
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
}
break;
case BOT_DATA_OUT:
(void)USBH_BulkSendData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->OutEpSize, MSC_Handle->OutPipe, 1U);
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
break;
case BOT_DATA_OUT_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
if (URB_Status == USBH_URB_DONE)
{
/* Adjust Data pointer and data length */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->OutEpSize)
{
MSC_Handle->hbot.pbuf += MSC_Handle->OutEpSize;
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->OutEpSize;
}
else
{
MSC_Handle->hbot.cbw.field.DataTransferLength = 0U;
}
/* More Data To be Sent */
if (MSC_Handle->hbot.cbw.field.DataTransferLength > 0U)
{
(void)USBH_BulkSendData(phost, MSC_Handle->hbot.pbuf,
MSC_Handle->OutEpSize, MSC_Handle->OutPipe, 1U);
}
else
{
/* If value was 0, and successful transfer, then change the state */
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else if (URB_Status == USBH_URB_NOTREADY)
{
/* Resend same data */
MSC_Handle->hbot.state = BOT_DATA_OUT;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else if (URB_Status == USBH_URB_STALL)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
6.7.3 Ho - Host expects to send data to the device
3. On a STALL condition sending data, then:
" The host shall clear the Bulk-Out pipe.
4. The host shall attempt to receive a CSW.
*/
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
}
break;
case BOT_RECEIVE_CSW:
(void)USBH_BulkReceiveData(phost, MSC_Handle->hbot.csw.data,
BOT_CSW_LENGTH, MSC_Handle->InPipe);
MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT;
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
phost->NakTimer = phost->Timer;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
break;
case BOT_RECEIVE_CSW_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
/* Decode CSW */
if (URB_Status == USBH_URB_DONE)
{
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_SEND;
CSW_Status = USBH_MSC_DecodeCSW(phost);
if (CSW_Status == BOT_CSW_CMD_PASSED)
{
status = USBH_OK;
}
else
{
status = USBH_FAIL;
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
else if (URB_Status == USBH_URB_NAK_WAIT)
{
MSC_Handle->hbot.state = BOT_RECEIVE_CSW_WAIT;
if ((phost->Timer - phost->NakTimer) > phost->NakTimeout)
{
phost->NakTimer = phost->Timer;
USBH_ActivatePipe(phost, MSC_Handle->InPipe);
}
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
else if (URB_Status == USBH_URB_STALL)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
#if (USBH_USE_OS == 1U)
USBH_OS_PutMessage(phost, USBH_URB_EVENT, 0U, 0U);
#endif /* (USBH_USE_OS == 1U) */
}
else
{
}
break;
case BOT_ERROR_IN:
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_IN);
if (error == USBH_OK)
{
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else if (error == USBH_UNRECOVERED_ERROR)
{
/* This means that there is a STALL Error limit, Do Reset Recovery */
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
}
else
{
}
break;
case BOT_ERROR_OUT:
error = USBH_MSC_BOT_Abort(phost, lun, BOT_DIR_OUT);
if (error == USBH_OK)
{
toggle = USBH_LL_GetToggle(phost, MSC_Handle->OutPipe);
(void)USBH_LL_SetToggle(phost, MSC_Handle->OutPipe, 1U - toggle);
(void)USBH_LL_SetToggle(phost, MSC_Handle->InPipe, 0U);
MSC_Handle->hbot.state = BOT_ERROR_IN;
}
else
{
if (error == USBH_UNRECOVERED_ERROR)
{
MSC_Handle->hbot.state = BOT_UNRECOVERED_ERROR;
}
}
break;
case BOT_UNRECOVERED_ERROR:
status = USBH_MSC_BOT_REQ_Reset(phost);
if (status == USBH_OK)
{
MSC_Handle->hbot.state = BOT_SEND_CBW;
}
break;
default:
break;
}
return status;
}
/**
* @brief USBH_MSC_BOT_Abort
* The function handle the BOT Abort process.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param dir: direction (0: out / 1 : in)
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(lun);
USBH_StatusTypeDef status = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (dir)
{
case BOT_DIR_IN :
/* send ClrFeture on Bulk IN endpoint */
status = USBH_ClrFeature(phost, MSC_Handle->InEp);
break;
case BOT_DIR_OUT :
/*send ClrFeature on Bulk OUT endpoint */
status = USBH_ClrFeature(phost, MSC_Handle->OutEp);
break;
default:
break;
}
return status;
}
/**
* @brief USBH_MSC_BOT_DecodeCSW
* This function decodes the CSW received by the device and updates the
* same to upper layer.
* @param phost: Host handle
* @retval USBH Status
* @notes
* Refer to USB Mass-Storage Class : BOT (www.usb.org)
* 6.3.1 Valid CSW Conditions :
* The host shall consider the CSW valid when:
* 1. dCSWSignature is equal to 53425355h
* 2. the CSW is 13 (Dh) bytes in length,
* 3. dCSWTag matches the dCBWTag from the corresponding CBW.
*/
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
BOT_CSWStatusTypeDef status = BOT_CSW_CMD_FAILED;
/*Checking if the transfer length is different than 13*/
if (USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != BOT_CSW_LENGTH)
{
/*(4) Hi > Dn (Host expects to receive data from the device,
Device intends to transfer no data)
(5) Hi > Di (Host expects to receive data from the device,
Device intends to send data to the host)
(9) Ho > Dn (Host expects to send data to the device,
Device intends to transfer no data)
(11) Ho > Do (Host expects to send data to the device,
Device intends to receive data from the host)*/
status = BOT_CSW_PHASE_ERROR;
}
else
{
/* CSW length is Correct */
/* Check validity of the CSW Signature and CSWStatus */
if (MSC_Handle->hbot.csw.field.Signature == BOT_CSW_SIGNATURE)
{
/* Check Condition 1. dCSWSignature is equal to 53425355h */
if (MSC_Handle->hbot.csw.field.Tag == MSC_Handle->hbot.cbw.field.Tag)
{
/* Check Condition 3. dCSWTag matches the dCBWTag from the
corresponding CBW */
if (MSC_Handle->hbot.csw.field.Status == 0U)
{
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
Hn Host expects no data transfers
Hi Host expects to receive data from the device
Ho Host expects to send data to the device
Dn Device intends to transfer no data
Di Device intends to send data to the host
Do Device intends to receive data from the host
Section 6.7
(1) Hn = Dn (Host expects no data transfers,
Device intends to transfer no data)
(6) Hi = Di (Host expects to receive data from the device,
Device intends to send data to the host)
(12) Ho = Do (Host expects to send data to the device,
Device intends to receive data from the host)
*/
status = BOT_CSW_CMD_PASSED;
}
else if (MSC_Handle->hbot.csw.field.Status == 1U)
{
status = BOT_CSW_CMD_FAILED;
}
else if (MSC_Handle->hbot.csw.field.Status == 2U)
{
/* Refer to USB Mass-Storage Class : BOT (www.usb.org)
Section 6.7
(2) Hn < Di ( Host expects no data transfers,
Device intends to send data to the host)
(3) Hn < Do ( Host expects no data transfers,
Device intends to receive data from the host)
(7) Hi < Di ( Host expects to receive data from the device,
Device intends to send data to the host)
(8) Hi <> Do ( Host expects to receive data from the device,
Device intends to receive data from the host)
(10) Ho <> Di (Host expects to send data to the device,
Di Device intends to send data to the host)
(13) Ho < Do (Host expects to send data to the device,
Device intends to receive data from the host)
*/
status = BOT_CSW_PHASE_ERROR;
}
else
{
}
} /* CSW Tag Matching is Checked */
} /* CSW Signature Correct Checking */
else
{
/* If the CSW Signature is not valid, We sall return the Phase Error to
Upper Layers for Reset Recovery */
status = BOT_CSW_PHASE_ERROR;
}
} /* CSW Length Check*/
return status;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,469 @@
/**
******************************************************************************
* @file usbh_msc_scsi.c
* @author MCD Application Team
* @brief This file implements the SCSI commands
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbh_msc.h"
#include "usbh_msc_scsi.h"
#include "usbh_msc_bot.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_SCSI
* @brief This file includes the mass storage related functions
* @{
*/
/** @defgroup USBH_MSC_SCSI_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_SCSI_Private_Functions
* @{
*/
/**
* @brief USBH_MSC_SCSI_TestUnitReady
* Issue TestUnitReady command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_TestUnitReady(USBH_HandleTypeDef *phost,
uint8_t lun)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_MODE_TEST_UNIT_READY;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_TEST_UNIT_READY;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_ReadCapacity
* Issue Read Capacity command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param capacity: pointer to the capacity structure
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_ReadCapacity(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_CapacityTypeDef *capacity)
{
USBH_StatusTypeDef error = USBH_BUSY;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_READ_CAPACITY10;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ_CAPACITY10;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = (uint8_t *)(void *)MSC_Handle->hbot.data;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
if (error == USBH_OK)
{
/* Assign the capacity */
capacity->block_nbr = MSC_Handle->hbot.pbuf[3] | ((uint32_t)MSC_Handle->hbot.pbuf[2] << 8U) | \
((uint32_t)MSC_Handle->hbot.pbuf[1] << 16U) | ((uint32_t)MSC_Handle->hbot.pbuf[0] << 24U);
/* Assign the page length */
capacity->block_size = (uint16_t)(MSC_Handle->hbot.pbuf[7] | ((uint32_t)MSC_Handle->hbot.pbuf[6] << 8U));
}
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_Inquiry
* Issue Inquiry command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param capacity: pointer to the inquiry structure
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_Inquiry(USBH_HandleTypeDef *phost, uint8_t lun,
SCSI_StdInquiryDataTypeDef *inquiry)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_INQUIRY;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_INQUIRY;
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
MSC_Handle->hbot.cbw.field.CB[2] = 0U;
MSC_Handle->hbot.cbw.field.CB[3] = 0U;
MSC_Handle->hbot.cbw.field.CB[4] = 0x24U;
MSC_Handle->hbot.cbw.field.CB[5] = 0U;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = (uint8_t *)(void *)MSC_Handle->hbot.data;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
if (error == USBH_OK)
{
(void)USBH_memset(inquiry, 0, sizeof(SCSI_StdInquiryDataTypeDef));
/* Assign Inquiry Data */
inquiry->DeviceType = MSC_Handle->hbot.pbuf[0] & 0x1FU;
inquiry->PeripheralQualifier = MSC_Handle->hbot.pbuf[0] >> 5U;
if (((uint32_t)MSC_Handle->hbot.pbuf[1] & 0x80U) == 0x80U)
{
inquiry->RemovableMedia = 1U;
}
else
{
inquiry->RemovableMedia = 0U;
}
(void)USBH_memcpy(inquiry->vendor_id, &MSC_Handle->hbot.pbuf[8], 8U);
(void)USBH_memcpy(inquiry->product_id, &MSC_Handle->hbot.pbuf[16], 16U);
(void)USBH_memcpy(inquiry->revision_id, &MSC_Handle->hbot.pbuf[32], 4U);
}
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_RequestSense
* Issue RequestSense command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param capacity: pointer to the sense data structure
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense(USBH_HandleTypeDef *phost,
uint8_t lun,
SCSI_SenseTypeDef *sense_data)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = DATA_LEN_REQUEST_SENSE;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_REQUEST_SENSE;
MSC_Handle->hbot.cbw.field.CB[1] = (lun << 5);
MSC_Handle->hbot.cbw.field.CB[2] = 0U;
MSC_Handle->hbot.cbw.field.CB[3] = 0U;
MSC_Handle->hbot.cbw.field.CB[4] = DATA_LEN_REQUEST_SENSE;
MSC_Handle->hbot.cbw.field.CB[5] = 0U;
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = (uint8_t *)(void *)MSC_Handle->hbot.data;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
if (error == USBH_OK)
{
sense_data->key = MSC_Handle->hbot.pbuf[2] & 0x0FU;
sense_data->asc = MSC_Handle->hbot.pbuf[12];
sense_data->ascq = MSC_Handle->hbot.pbuf[13];
if (sense_data->asc == SCSI_ASC_MEDIUM_NOT_PRESENT)
{
USBH_UsrLog("MSC Device MEDIUM not present");
error = USBH_UNRECOVERED_ERROR;
}
}
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_Write
* Issue write10 command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to write
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_WRITE10;
/* Logical block address */
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t *)(void *)&address)[3]);
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t *)(void *)&address)[2]);
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t *)(void *)&address)[1]);
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t *)(void *)&address)[0]);
/*Transfer length */
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)(void *)&length)[1]);
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)(void *)&length)[0]);
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = pbuf;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
break;
default:
break;
}
return error;
}
/**
* @brief USBH_MSC_SCSI_Read
* Issue Read10 command.
* @param phost: Host handle
* @param lun: Logical Unit Number
* @param address: sector address
* @param pbuf: pointer to data
* @param length: number of sector to read
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint8_t *pbuf,
uint32_t length)
{
USBH_StatusTypeDef error = USBH_FAIL;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
switch (MSC_Handle->hbot.cmd_state)
{
case BOT_CMD_SEND:
/* Prepare the CBW and relevant field */
MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
(void)USBH_memset(MSC_Handle->hbot.cbw.field.CB, 0, CBW_CB_LENGTH);
MSC_Handle->hbot.cbw.field.CB[0] = OPCODE_READ10;
/* Logical block address */
MSC_Handle->hbot.cbw.field.CB[2] = (((uint8_t *)(void *)&address)[3]);
MSC_Handle->hbot.cbw.field.CB[3] = (((uint8_t *)(void *)&address)[2]);
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t *)(void *)&address)[1]);
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t *)(void *)&address)[0]);
/* Transfer length */
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)(void *)&length)[1]);
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)(void *)&length)[0]);
MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = pbuf;
error = USBH_BUSY;
break;
case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun);
break;
default:
break;
}
return error;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,178 @@
/**
******************************************************************************
* @file usbh_core.h
* @author MCD Application Team
* @brief Header file for usbh_core.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_CORE_H
#define __USBH_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_conf.h"
#include "usbh_def.h"
#include "usbh_ioreq.h"
#include "usbh_pipes.h"
#include "usbh_ctlreq.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_CORE
* @brief This file is the Header file for usbh_core.c
* @{
*/
/** @defgroup USBH_CORE_Exported_Defines
* @{
*/
/**
* @}
*/
#define HOST_USER_SELECT_CONFIGURATION 0x01U
#define HOST_USER_CLASS_ACTIVE 0x02U
#define HOST_USER_CLASS_SELECTED 0x03U
#define HOST_USER_CONNECTION 0x04U
#define HOST_USER_DISCONNECTION 0x05U
#define HOST_USER_UNRECOVERED_ERROR 0x06U
/**
* @}
*/
/** @defgroup USBH_CORE_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CORE_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CORE_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_Init(USBH_HandleTypeDef *phost,
void (*pUsrFunc)(USBH_HandleTypeDef *phost, uint8_t id), uint8_t id);
USBH_StatusTypeDef USBH_DeInit(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_Start(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_Stop(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_ReEnumerate(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_RegisterClass(USBH_HandleTypeDef *phost, USBH_ClassTypeDef *pclass);
USBH_StatusTypeDef USBH_SelectInterface(USBH_HandleTypeDef *phost, uint8_t interface);
uint8_t USBH_FindInterfaceIndex(USBH_HandleTypeDef *phost, uint8_t interface_number, uint8_t alt_settings);
uint8_t USBH_FindInterface(USBH_HandleTypeDef *phost, uint8_t Class, uint8_t SubClass, uint8_t Protocol);
uint8_t USBH_GetActiveClass(USBH_HandleTypeDef *phost);
uint8_t USBH_IsPortEnabled(USBH_HandleTypeDef *phost);
/* USBH Low Level Driver */
USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_LL_DeInit(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_LL_Stop(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_LL_Connect(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_LL_Disconnect(USBH_HandleTypeDef *phost);
USBH_SpeedTypeDef USBH_LL_GetSpeed(USBH_HandleTypeDef *phost);
USBH_StatusTypeDef USBH_LL_ResetPort(USBH_HandleTypeDef *phost);
uint32_t USBH_LL_GetLastXferSize(USBH_HandleTypeDef *phost, uint8_t pipe);
USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state);
USBH_StatusTypeDef USBH_LL_OpenPipe(USBH_HandleTypeDef *phost,
uint8_t pipe,
uint8_t epnum,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps);
USBH_StatusTypeDef USBH_LL_ActivatePipe(USBH_HandleTypeDef *phost, uint8_t pipe);
USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe);
USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost,
uint8_t pipe,
uint8_t direction,
uint8_t ep_type,
uint8_t token,
uint8_t *pbuff,
uint16_t length,
uint8_t do_ping);
USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, uint8_t pipe);
#if (USBH_USE_OS == 1U)
USBH_StatusTypeDef USBH_LL_NotifyURBChange(USBH_HandleTypeDef *phost);
void USBH_OS_PutMessage(USBH_HandleTypeDef *phost, USBH_OSEventTypeDef message, uint32_t timeout, uint32_t priority);
#endif /*(USBH_USE_OS == 1U) */
USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle);
uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe);
void USBH_LL_PortDisabled(USBH_HandleTypeDef *phost);
void USBH_LL_PortEnabled(USBH_HandleTypeDef *phost);
/* USBH Time base */
void USBH_LL_SetTimer(USBH_HandleTypeDef *phost, uint32_t time);
void USBH_LL_IncTimer(USBH_HandleTypeDef *phost);
void USBH_Delay(uint32_t Delay);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_CORE_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,138 @@
/**
******************************************************************************
* @file usbh_ctlreq.h
* @author MCD Application Team
* @brief Header file for usbh_ctlreq.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_CTLREQ_H
#define __USBH_CTLREQ_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_CTLREQ
* @brief This file is the
* @{
*/
/** @defgroup USBH_CTLREQ_Exported_Defines
* @{
*/
/*Standard Feature Selector for clear feature command*/
#define FEATURE_SELECTOR_ENDPOINT 0x00U
#define FEATURE_SELECTOR_DEVICE 0x01U
#define FEATURE_SELECTOR_REMOTEWAKEUP 0X01U
#define INTERFACE_DESC_TYPE 0x04U
#define ENDPOINT_DESC_TYPE 0x05U
#define INTERFACE_DESC_SIZE 0x09U
/**
* @}
*/
/** @defgroup USBH_CTLREQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CTLREQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CTLREQ_Exported_Variables
* @{
*/
extern uint8_t USBH_CfgDesc[512];
/**
* @}
*/
/** @defgroup USBH_CTLREQ_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_CtlReq(USBH_HandleTypeDef *phost, uint8_t *buff,
uint16_t length);
USBH_StatusTypeDef USBH_GetDescriptor(USBH_HandleTypeDef *phost,
uint8_t req_type, uint16_t value_idx,
uint8_t *buff, uint16_t length);
USBH_StatusTypeDef USBH_Get_DevDesc(USBH_HandleTypeDef *phost, uint16_t length);
USBH_StatusTypeDef USBH_Get_StringDesc(USBH_HandleTypeDef *phost,
uint8_t string_index, uint8_t *buff,
uint16_t length);
USBH_StatusTypeDef USBH_SetCfg(USBH_HandleTypeDef *phost, uint16_t cfg_idx);
USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost, uint16_t length);
USBH_StatusTypeDef USBH_SetAddress(USBH_HandleTypeDef *phost,
uint8_t DeviceAddress);
USBH_StatusTypeDef USBH_SetInterface(USBH_HandleTypeDef *phost, uint8_t ep_num,
uint8_t altSetting);
USBH_StatusTypeDef USBH_SetFeature(USBH_HandleTypeDef *phost, uint8_t wValue);
USBH_StatusTypeDef USBH_ClrFeature(USBH_HandleTypeDef *phost, uint8_t ep_num);
USBH_DescHeader_t *USBH_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_CTLREQ_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,519 @@
/**
******************************************************************************
* @file usbh_def.h
* @author MCD Application Team
* @brief Definitions used in the USB host library
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef USBH_DEF_H
#define USBH_DEF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_conf.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_DEF
* @brief This file is includes USB descriptors
* @{
*/
#ifndef NULL
#define NULL 0U
#endif
#ifndef FALSE
#define FALSE 0U
#endif
#ifndef TRUE
#define TRUE 1U
#endif
#ifndef USBH_DEV_RESET_TIMEOUT
#define USBH_DEV_RESET_TIMEOUT 1000U
#endif
#define ValBit(VAR,POS) (VAR & (1 << POS))
#define SetBit(VAR,POS) (VAR |= (1 << POS))
#define ClrBit(VAR,POS) (VAR &= ((1 << POS)^255))
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#define LE16(addr) (((uint16_t)(addr)[0]) | \
((uint16_t)(((uint32_t)(addr)[1]) << 8)))
#define LE24(addr) (((uint32_t)(addr)[0]) | \
(((uint32_t)(addr)[1]) << 8) | \
(((uint32_t)(addr)[2]) << 16))
#define LE32(addr) (((uint32_t)(addr)[0]) | \
(((uint32_t)(addr)[1]) << 8) | \
(((uint32_t)(addr)[2]) << 16) | \
(((uint32_t)(addr)[3]) << 24))
#define LE64(addr) (((uint64_t)(addr)[0]) | \
(((uint64_t)(addr)[1]) << 8) | \
(((uint64_t)(addr)[2]) << 16) | \
(((uint64_t)(addr)[3]) << 24) | \
(((uint64_t)(addr)[4]) << 32) | \
(((uint64_t)(addr)[5]) << 40) | \
(((uint64_t)(addr)[6]) << 48) | \
(((uint64_t)(addr)[7]) << 56))
#define LE16S(addr) ((int16_t)(LE16((addr))))
#define LE24S(addr) ((int32_t)(LE24((addr))))
#define LE32S(addr) ((int32_t)(LE32((addr))))
#define LE64S(addr) ((int64_t)(LE64((addr))))
#ifndef USBH_MAX_DATA_BUFFER
#define USBH_MAX_DATA_BUFFER 0x400U
#endif
#define USBH_MAX_EP_PACKET_SIZE 0x400U
#define USB_LEN_DESC_HDR 0x02U
#define USB_LEN_DEV_DESC 0x12U
#define USB_LEN_CFG_DESC 0x09U
#define USB_LEN_IF_DESC 0x09U
#define USB_LEN_EP_DESC 0x07U
#define USB_LEN_OTG_DESC 0x03U
#define USB_LEN_SETUP_PKT 0x08U
/* bmRequestType :D7 Data Phase Transfer Direction */
#define USB_REQ_DIR_MASK 0x80U
#define USB_H2D 0x00U
#define USB_D2H 0x80U
/* bmRequestType D6..5 Type */
#define USB_REQ_TYPE_STANDARD 0x00U
#define USB_REQ_TYPE_CLASS 0x20U
#define USB_REQ_TYPE_VENDOR 0x40U
#define USB_REQ_TYPE_RESERVED 0x60U
/* bmRequestType D4..0 Recipient */
#define USB_REQ_RECIPIENT_DEVICE 0x00U
#define USB_REQ_RECIPIENT_INTERFACE 0x01U
#define USB_REQ_RECIPIENT_ENDPOINT 0x02U
#define USB_REQ_RECIPIENT_OTHER 0x03U
/* Table 9-4. Standard Request Codes */
/* bRequest , Value */
#define USB_REQ_GET_STATUS 0x00U
#define USB_REQ_CLEAR_FEATURE 0x01U
#define USB_REQ_SET_FEATURE 0x03U
#define USB_REQ_SET_ADDRESS 0x05U
#define USB_REQ_GET_DESCRIPTOR 0x06U
#define USB_REQ_SET_DESCRIPTOR 0x07U
#define USB_REQ_GET_CONFIGURATION 0x08U
#define USB_REQ_SET_CONFIGURATION 0x09U
#define USB_REQ_GET_INTERFACE 0x0AU
#define USB_REQ_SET_INTERFACE 0x0BU
#define USB_REQ_SYNCH_FRAME 0x0CU
/* Table 9-5. Descriptor Types of USB Specifications */
#define USB_DESC_TYPE_DEVICE 0x01U
#define USB_DESC_TYPE_CONFIGURATION 0x02U
#define USB_DESC_TYPE_STRING 0x03U
#define USB_DESC_TYPE_INTERFACE 0x04U
#define USB_DESC_TYPE_ENDPOINT 0x05U
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
#define USB_DESC_TYPE_INTERFACE_POWER 0x08U
#define USB_DESC_TYPE_HID 0x21U
#define USB_DESC_TYPE_HID_REPORT 0x22U
#define USB_DEVICE_DESC_SIZE 0x12U
#define USB_CONFIGURATION_DESC_SIZE 0x09U
#define USB_HID_DESC_SIZE 0x09U
#define USB_INTERFACE_DESC_SIZE 0x09U
#define USB_ENDPOINT_DESC_SIZE 0x07U
/* Descriptor Type and Descriptor Index */
/* Use the following values when calling the function USBH_GetDescriptor */
#define USB_DESC_DEVICE ((USB_DESC_TYPE_DEVICE << 8) & 0xFF00U)
#define USB_DESC_CONFIGURATION ((USB_DESC_TYPE_CONFIGURATION << 8) & 0xFF00U)
#define USB_DESC_STRING ((USB_DESC_TYPE_STRING << 8) & 0xFF00U)
#define USB_DESC_INTERFACE ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00U)
#define USB_DESC_ENDPOINT ((USB_DESC_TYPE_INTERFACE << 8) & 0xFF00U)
#define USB_DESC_DEVICE_QUALIFIER ((USB_DESC_TYPE_DEVICE_QUALIFIER << 8) & 0xFF00U)
#define USB_DESC_OTHER_SPEED_CONFIGURATION ((USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8) & 0xFF00U)
#define USB_DESC_INTERFACE_POWER ((USB_DESC_TYPE_INTERFACE_POWER << 8) & 0xFF00U)
#define USB_DESC_HID_REPORT ((USB_DESC_TYPE_HID_REPORT << 8) & 0xFF00U)
#define USB_DESC_HID ((USB_DESC_TYPE_HID << 8) & 0xFF00U)
#define USB_EP_TYPE_CTRL 0x00U
#define USB_EP_TYPE_ISOC 0x01U
#define USB_EP_TYPE_BULK 0x02U
#define USB_EP_TYPE_INTR 0x03U
#define USB_EP_DIR_OUT 0x00U
#define USB_EP_DIR_IN 0x80U
#define USB_EP_DIR_MSK 0x80U
#ifndef USBH_MAX_PIPES_NBR
#define USBH_MAX_PIPES_NBR 16U
#endif /* USBH_MAX_PIPES_NBR */
#ifndef USBH_NAK_SOF_COUNT
#define USBH_NAK_SOF_COUNT 0x01U
#endif /* USBH_NAK_SOF_COUNT */
#define USBH_DEVICE_ADDRESS_DEFAULT 0x00U
#define USBH_DEVICE_ADDRESS 0x01U
#define USBH_MAX_ERROR_COUNT 0x02U
#if (USBH_USE_OS == 1U)
#define MSGQUEUE_OBJECTS 0x10U
#endif /* (USBH_USE_OS == 1U) */
/**
* @}
*/
#define USBH_CONFIGURATION_DESCRIPTOR_SIZE (USB_CONFIGURATION_DESC_SIZE \
+ USB_INTERFACE_DESC_SIZE\
+ (USBH_MAX_NUM_ENDPOINTS * USB_ENDPOINT_DESC_SIZE))
#define CONFIG_DESC_wTOTAL_LENGTH (ConfigurationDescriptorData.ConfigDescfield.\
ConfigurationDescriptor.wTotalLength)
typedef union
{
uint16_t w;
struct BW
{
uint8_t msb;
uint8_t lsb;
}
bw;
}
uint16_t_uint8_t;
typedef union _USB_Setup
{
uint32_t d8[2];
struct _SetupPkt_Struc
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t_uint8_t wValue;
uint16_t_uint8_t wIndex;
uint16_t_uint8_t wLength;
} b;
}
USB_Setup_TypeDef;
typedef struct _DescHeader
{
uint8_t bLength;
uint8_t bDescriptorType;
}
USBH_DescHeader_t;
typedef struct _DeviceDescriptor
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB; /* USB Specification Number which device complies too */
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
/* If equal to Zero, each interface specifies its own class
code if equal to 0xFF, the class code is vendor specified.
Otherwise field is valid Class Code.*/
uint8_t bMaxPacketSize;
uint16_t idVendor; /* Vendor ID (Assigned by USB Org) */
uint16_t idProduct; /* Product ID (Assigned by Manufacturer) */
uint16_t bcdDevice; /* Device Release Number */
uint8_t iManufacturer; /* Index of Manufacturer String Descriptor */
uint8_t iProduct; /* Index of Product String Descriptor */
uint8_t iSerialNumber; /* Index of Serial Number String Descriptor */
uint8_t bNumConfigurations; /* Number of Possible Configurations */
}
USBH_DevDescTypeDef;
typedef struct _EndpointDescriptor
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress; /* indicates what endpoint this descriptor is describing */
uint8_t bmAttributes; /* specifies the transfer type. */
uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving */
uint8_t bInterval; /* is used to specify the polling interval of certain transfers. */
}
USBH_EpDescTypeDef;
typedef struct _InterfaceDescriptor
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting; /* Value used to select alternative setting */
uint8_t bNumEndpoints; /* Number of Endpoints used for this interface */
uint8_t bInterfaceClass; /* Class Code (Assigned by USB Org) */
uint8_t bInterfaceSubClass; /* Subclass Code (Assigned by USB Org) */
uint8_t bInterfaceProtocol; /* Protocol Code */
uint8_t iInterface; /* Index of String Descriptor Describing this interface */
USBH_EpDescTypeDef Ep_Desc[USBH_MAX_NUM_ENDPOINTS];
}
USBH_InterfaceDescTypeDef;
typedef struct _ConfigurationDescriptor
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength; /* Total Length of Data Returned */
uint8_t bNumInterfaces; /* Number of Interfaces */
uint8_t bConfigurationValue; /* Value to use as an argument to select this configuration*/
uint8_t iConfiguration; /* Index of String Descriptor Describing this configuration */
uint8_t bmAttributes; /* D7 Bus Powered , D6 Self Powered, D5 Remote Wakeup , D4..0 Reserved (0)*/
uint8_t bMaxPower; /* Maximum Power Consumption */
USBH_InterfaceDescTypeDef Itf_Desc[USBH_MAX_NUM_INTERFACES];
}
USBH_CfgDescTypeDef;
/* Following USB Host status */
typedef enum
{
USBH_OK = 0,
USBH_BUSY,
USBH_FAIL,
USBH_NOT_SUPPORTED,
USBH_UNRECOVERED_ERROR,
USBH_ERROR_SPEED_UNKNOWN,
} USBH_StatusTypeDef;
/** @defgroup USBH_CORE_Exported_Types
* @{
*/
typedef enum
{
USBH_SPEED_HIGH = 0U,
USBH_SPEED_FULL = 1U,
USBH_SPEED_LOW = 2U,
} USBH_SpeedTypeDef;
/* Following states are used for gState */
typedef enum
{
HOST_IDLE = 0U,
HOST_DEV_WAIT_FOR_ATTACHMENT,
HOST_DEV_ATTACHED,
HOST_DEV_DISCONNECTED,
HOST_DETECT_DEVICE_SPEED,
HOST_ENUMERATION,
HOST_CLASS_REQUEST,
HOST_INPUT,
HOST_SET_CONFIGURATION,
HOST_SET_WAKEUP_FEATURE,
HOST_CHECK_CLASS,
HOST_CLASS,
HOST_SUSPENDED,
HOST_ABORT_STATE,
} HOST_StateTypeDef;
/* Following states are used for EnumerationState */
typedef enum
{
ENUM_IDLE = 0U,
ENUM_GET_FULL_DEV_DESC,
ENUM_SET_ADDR,
ENUM_GET_CFG_DESC,
ENUM_GET_FULL_CFG_DESC,
ENUM_GET_MFC_STRING_DESC,
ENUM_GET_PRODUCT_STRING_DESC,
ENUM_GET_SERIALNUM_STRING_DESC,
} ENUM_StateTypeDef;
/* Following states are used for CtrlXferStateMachine */
typedef enum
{
CTRL_IDLE = 0U,
CTRL_SETUP,
CTRL_SETUP_WAIT,
CTRL_DATA_IN,
CTRL_DATA_IN_WAIT,
CTRL_DATA_OUT,
CTRL_DATA_OUT_WAIT,
CTRL_STATUS_IN,
CTRL_STATUS_IN_WAIT,
CTRL_STATUS_OUT,
CTRL_STATUS_OUT_WAIT,
CTRL_ERROR,
CTRL_STALLED,
CTRL_COMPLETE
} CTRL_StateTypeDef;
/* Following states are used for RequestState */
typedef enum
{
CMD_IDLE = 0U,
CMD_SEND,
CMD_WAIT
} CMD_StateTypeDef;
typedef enum
{
USBH_URB_IDLE = 0U,
USBH_URB_DONE,
USBH_URB_NOTREADY,
USBH_URB_NYET,
USBH_URB_ERROR,
USBH_URB_STALL,
USBH_URB_NAK_WAIT
} USBH_URBStateTypeDef;
typedef enum
{
USBH_PORT_EVENT = 1U,
USBH_URB_EVENT,
USBH_CONTROL_EVENT,
USBH_CLASS_EVENT,
USBH_STATE_CHANGED_EVENT,
}
USBH_OSEventTypeDef;
/* Control request structure */
typedef struct
{
uint8_t pipe_in;
uint8_t pipe_out;
uint8_t pipe_size;
uint8_t *buff;
uint16_t length;
uint16_t timer;
USB_Setup_TypeDef setup;
CTRL_StateTypeDef state;
uint8_t errorcount;
} USBH_CtrlTypeDef;
/* Attached device structure */
typedef struct
{
uint8_t CfgDesc_Raw[USBH_MAX_SIZE_CONFIGURATION];
uint8_t Data[USBH_MAX_DATA_BUFFER];
uint8_t address;
uint8_t speed;
uint8_t EnumCnt;
uint8_t RstCnt;
__IO uint8_t is_connected;
__IO uint8_t is_disconnected;
__IO uint8_t is_ReEnumerated;
__IO uint8_t PortEnabled;
uint8_t current_interface;
USBH_DevDescTypeDef DevDesc;
USBH_CfgDescTypeDef CfgDesc;
} USBH_DeviceTypeDef;
struct _USBH_HandleTypeDef;
/* USB Host Class structure */
typedef struct
{
const char *Name;
uint8_t ClassCode;
USBH_StatusTypeDef(*Init)(struct _USBH_HandleTypeDef *phost);
USBH_StatusTypeDef(*DeInit)(struct _USBH_HandleTypeDef *phost);
USBH_StatusTypeDef(*Requests)(struct _USBH_HandleTypeDef *phost);
USBH_StatusTypeDef(*BgndProcess)(struct _USBH_HandleTypeDef *phost);
USBH_StatusTypeDef(*SOFProcess)(struct _USBH_HandleTypeDef *phost);
void *pData;
} USBH_ClassTypeDef;
/* USB Host handle structure */
typedef struct _USBH_HandleTypeDef
{
__IO HOST_StateTypeDef gState; /* Host State Machine Value */
ENUM_StateTypeDef EnumState; /* Enumeration state Machine */
CMD_StateTypeDef RequestState;
USBH_CtrlTypeDef Control;
USBH_DeviceTypeDef device;
USBH_ClassTypeDef *pClass[USBH_MAX_NUM_SUPPORTED_CLASS];
USBH_ClassTypeDef *pActiveClass;
uint32_t ClassNumber;
uint32_t Pipes[16];
__IO uint32_t Timer;
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
uint32_t NakTimer;
uint32_t NakTimeout;
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
uint32_t Timeout;
uint8_t id;
void *pData;
void (* pUser)(struct _USBH_HandleTypeDef *pHandle, uint8_t id);
#if (USBH_USE_OS == 1U)
#if osCMSIS < 0x20000
osMessageQId os_event;
osThreadId thread;
#else
osMessageQueueId_t os_event;
osThreadId_t thread;
#endif
uint32_t os_msg;
#endif /* (USBH_USE_OS == 1U) */
} USBH_HandleTypeDef;
#if defined ( __GNUC__ )
#ifndef __weak
#define __weak __attribute__((weak))
#endif /* __weak */
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif /* __packed */
#endif /* __GNUC__ */
#ifdef __cplusplus
}
#endif
#endif /* USBH_DEF_H */

View File

@ -0,0 +1,157 @@
/**
******************************************************************************
* @file usbh_ioreq.h
* @author MCD Application Team
* @brief Header file for usbh_ioreq.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_IOREQ_H
#define __USBH_IOREQ_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_conf.h"
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_IOREQ
* @brief This file is the header file for usbh_ioreq.c
* @{
*/
/** @defgroup USBH_IOREQ_Exported_Defines
* @{
*/
#define USBH_PID_SETUP 0U
#define USBH_PID_DATA 1U
#define USBH_EP_CONTROL 0U
#define USBH_EP_ISO 1U
#define USBH_EP_BULK 2U
#define USBH_EP_INTERRUPT 3U
#define USBH_SETUP_PKT_SIZE 8U
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_CtlSendSetup(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_CtlSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num,
uint8_t do_ping);
USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_BulkSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num,
uint8_t do_ping);
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint32_t length,
uint8_t pipe_num);
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint32_t length,
uint8_t pipe_num);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_IOREQ_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,122 @@
/**
******************************************************************************
* @file usbh_pipes.h
* @author MCD Application Team
* @brief Header file for usbh_pipes.c
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Define to prevent recursive ----------------------------------------------*/
#ifndef __USBH_PIPES_H
#define __USBH_PIPES_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_PIPES
* @brief This file is the header file for usbh_pipes.c
* @{
*/
/** @defgroup USBH_PIPES_Exported_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Exported_FunctionsPrototype
* @{
*/
USBH_StatusTypeDef USBH_OpenPipe(USBH_HandleTypeDef *phost,
uint8_t pipe_num,
uint8_t epnum,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps);
USBH_StatusTypeDef USBH_ClosePipe(USBH_HandleTypeDef *phost,
uint8_t pipe_num);
uint8_t USBH_AllocPipe(USBH_HandleTypeDef *phost,
uint8_t ep_addr);
USBH_StatusTypeDef USBH_FreePipe(USBH_HandleTypeDef *phost,
uint8_t idx);
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
USBH_StatusTypeDef USBH_ActivatePipe(USBH_HandleTypeDef *phost,
uint8_t pipe_num);
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_PIPES_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,347 @@
/**
******************************************************************************
* @file usbh_ioreq.c
* @author MCD Application Team
* @brief This file handles the issuing of the USB transactions
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_ioreq.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_IOREQ
* @brief This file handles the standard protocol processing (USB v2.0)
* @{
*/
/** @defgroup USBH_IOREQ_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @defgroup USBH_IOREQ_Private_Functions
* @{
*/
/**
* @brief USBH_CtlSendSetup
* Sends the Setup Packet to the Device
* @param phost: Host Handle
* @param buff: Buffer pointer from which the Data will be send to Device
* @param pipe_num: Pipe Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_CtlSendSetup(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t pipe_num)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : OUT */
USBH_EP_CONTROL, /* EP type */
USBH_PID_SETUP, /* Type setup */
buff, /* data buffer */
USBH_SETUP_PKT_SIZE, /* data length */
0U);
return USBH_OK;
}
/**
* @brief USBH_CtlSendData
* Sends a data Packet to the Device
* @param phost: Host Handle
* @param buff: Buffer pointer from which the Data will be sent to Device
* @param length: Length of the data to be sent
* @param pipe_num: Pipe Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_CtlSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num,
uint8_t do_ping)
{
if (phost->device.speed != USBH_SPEED_HIGH)
{
do_ping = 0U;
}
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : OUT */
USBH_EP_CONTROL, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
length, /* data length */
do_ping); /* do ping (HS Only)*/
return USBH_OK;
}
/**
* @brief USBH_CtlReceiveData
* Receives the Device Response to the Setup Packet
* @param phost: Host Handle
* @param buff: Buffer pointer in which the response needs to be copied
* @param length: Length of the data to be received
* @param pipe_num: Pipe Number
* @retval USBH Status.
*/
USBH_StatusTypeDef USBH_CtlReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_CONTROL, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
length, /* data length */
0U);
return USBH_OK;
}
/**
* @brief USBH_BulkSendData
* Sends the Bulk Packet to the device
* @param phost: Host Handle
* @param buff: Buffer pointer from which the Data will be sent to Device
* @param length: Length of the data to be sent
* @param pipe_num: Pipe Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_BulkSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num,
uint8_t do_ping)
{
if (phost->device.speed != USBH_SPEED_HIGH)
{
do_ping = 0U;
}
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : IN */
USBH_EP_BULK, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
length, /* data length */
do_ping); /* do ping (HS Only)*/
return USBH_OK;
}
/**
* @brief USBH_BulkReceiveData
* Receives IN bulk packet from device
* @param phost: Host Handle
* @param buff: Buffer pointer in which the received data packet to be copied
* @param length: Length of the data to be received
* @param pipe_num: Pipe Number
* @retval USBH Status.
*/
USBH_StatusTypeDef USBH_BulkReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint16_t length,
uint8_t pipe_num)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_BULK, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
length, /* data length */
0U);
return USBH_OK;
}
/**
* @brief USBH_InterruptReceiveData
* Receives the Device Response to the Interrupt IN token
* @param phost: Host Handle
* @param buff: Buffer pointer in which the response needs to be copied
* @param length: Length of the data to be received
* @param pipe_num: Pipe Number
* @retval USBH Status.
*/
USBH_StatusTypeDef USBH_InterruptReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t length,
uint8_t pipe_num)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_INTERRUPT, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
return USBH_OK;
}
/**
* @brief USBH_InterruptSendData
* Sends the data on Interrupt OUT Endpoint
* @param phost: Host Handle
* @param buff: Buffer pointer from where the data needs to be copied
* @param length: Length of the data to be sent
* @param pipe_num: Pipe Number
* @retval USBH Status.
*/
USBH_StatusTypeDef USBH_InterruptSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint8_t length,
uint8_t pipe_num)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : OUT */
USBH_EP_INTERRUPT, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
return USBH_OK;
}
/**
* @brief USBH_IsocReceiveData
* Receives the Device Response to the Isochronous IN token
* @param phost: Host Handle
* @param buff: Buffer pointer in which the response needs to be copied
* @param length: Length of the data to be received
* @param pipe_num: Pipe Number
* @retval USBH Status.
*/
USBH_StatusTypeDef USBH_IsocReceiveData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint32_t length,
uint8_t pipe_num)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
1U, /* Direction : IN */
USBH_EP_ISO, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
return USBH_OK;
}
/**
* @brief USBH_IsocSendData
* Sends the data on Isochronous OUT Endpoint
* @param phost: Host Handle
* @param buff: Buffer pointer from where the data needs to be copied
* @param length: Length of the data to be sent
* @param pipe_num: Pipe Number
* @retval USBH Status.
*/
USBH_StatusTypeDef USBH_IsocSendData(USBH_HandleTypeDef *phost,
uint8_t *buff,
uint32_t length,
uint8_t pipe_num)
{
(void)USBH_LL_SubmitURB(phost, /* Driver handle */
pipe_num, /* Pipe index */
0U, /* Direction : OUT */
USBH_EP_ISO, /* EP type */
USBH_PID_DATA, /* Type Data */
buff, /* data buffer */
(uint16_t)length, /* data length */
0U);
return USBH_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,200 @@
/**
******************************************************************************
* @file usbh_pipes.c
* @author MCD Application Team
* @brief This file implements functions for opening and closing Pipes
******************************************************************************
* @attention
*
* Copyright (c) 2015 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbh_pipes.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_LIB_CORE
* @{
*/
/** @defgroup USBH_PIPES
* @brief This file includes opening and closing Pipes
* @{
*/
/** @defgroup USBH_PIPES_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_PIPES_Private_Functions
* @{
*/
static uint16_t USBH_GetFreePipe(USBH_HandleTypeDef *phost);
/**
* @brief USBH_Open_Pipe
* Open a pipe
* @param phost: Host Handle
* @param pipe_num: Pipe Number
* @param dev_address: USB Device address allocated to attached device
* @param speed : USB device speed (Full/Low)
* @param ep_type: end point type (Bulk/int/ctl)
* @param mps: max pkt size
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_OpenPipe(USBH_HandleTypeDef *phost, uint8_t pipe_num,
uint8_t epnum, uint8_t dev_address,
uint8_t speed, uint8_t ep_type, uint16_t mps)
{
(void)USBH_LL_OpenPipe(phost, pipe_num, epnum, dev_address, speed, ep_type, mps);
return USBH_OK;
}
#if defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U)
/**
* @brief USBH_ActivatePipe
* Activate a pipe
* @param phost: Host Handle
* @param pipe_num: Pipe Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_ActivatePipe(USBH_HandleTypeDef *phost, uint8_t pipe_num)
{
USBH_LL_ActivatePipe(phost, pipe_num);
return USBH_OK;
}
#endif /* defined (USBH_IN_NAK_PROCESS) && (USBH_IN_NAK_PROCESS == 1U) */
/**
* @brief USBH_ClosePipe
* Close a pipe
* @param phost: Host Handle
* @param pipe_num: Pipe Number
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe_num)
{
(void)USBH_LL_ClosePipe(phost, pipe_num);
return USBH_OK;
}
/**
* @brief USBH_Alloc_Pipe
* Allocate a new Pipe
* @param phost: Host Handle
* @param ep_addr: End point for which the Pipe to be allocated
* @retval Pipe number
*/
uint8_t USBH_AllocPipe(USBH_HandleTypeDef *phost, uint8_t ep_addr)
{
uint16_t pipe;
pipe = USBH_GetFreePipe(phost);
if (pipe != 0xFFFFU)
{
phost->Pipes[pipe & 0xFU] = (uint32_t)(0x8000U | ep_addr);
}
return (uint8_t)pipe;
}
/**
* @brief USBH_Free_Pipe
* Free the USB Pipe
* @param phost: Host Handle
* @param idx: Pipe number to be freed
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_FreePipe(USBH_HandleTypeDef *phost, uint8_t idx)
{
if (idx < USBH_MAX_PIPES_NBR)
{
phost->Pipes[idx] &= 0x7FFFU;
}
return USBH_OK;
}
/**
* @brief USBH_GetFreePipe
* @param phost: Host Handle
* Get a free Pipe number for allocation to a device endpoint
* @retval idx: Free Pipe number
*/
static uint16_t USBH_GetFreePipe(USBH_HandleTypeDef *phost)
{
uint8_t idx = 0U;
for (idx = 0U; idx < USBH_MAX_PIPES_NBR; idx++)
{
if ((phost->Pipes[idx] & 0x8000U) == 0U)
{
return (uint16_t)idx;
}
}
return 0xFFFFU;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,86 @@
This software component is provided to you as part of a software package and
applicable license terms are in the Package_license file. If you received this
software component outside of a package or without applicable license terms,
the terms of the SLA0044 license shall apply and are fully reproduced below:
SLA0044 Rev5/February 2018
Software license agreement
ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT
BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE
OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS
INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES
(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON
BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES
TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT.
Under STMicroelectronics intellectual property rights, the redistribution,
reproduction and use in source and binary forms of the software or any part
thereof, with or without modification, are permitted provided that the following
conditions are met:
1. Redistribution of source code (modified or not) must retain any copyright
notice, this list of conditions and the disclaimer set forth below as items 10
and 11.
2. Redistributions in binary form, except as embedded into microcontroller or
microprocessor device manufactured by or for STMicroelectronics or a software
update for such device, must reproduce any copyright notice provided with the
binary code, this list of conditions, and the disclaimer set forth below as
items 10 and 11, in documentation and/or other materials provided with the
distribution.
3. Neither the name of STMicroelectronics nor the names of other contributors to
this software may be used to endorse or promote products derived from this
software or part thereof without specific written permission.
4. This software or any part thereof, including modifications and/or derivative
works of this software, must be used and execute solely and exclusively on or in
combination with a microcontroller or microprocessor device manufactured by or
for STMicroelectronics.
5. No use, reproduction or redistribution of this software partially or totally
may be done in any manner that would subject this software to any Open Source
Terms. “Open Source Terms” shall mean any open source license which requires as
part of distribution of software that the source code of such software is
distributed therewith or otherwise made available, or open source license that
substantially complies with the Open Source definition specified at
www.opensource.org and any other comparable open source license such as for
example GNU General Public License (GPL), Eclipse Public License (EPL), Apache
Software License, BSD license or MIT license.
6. STMicroelectronics has no obligation to provide any maintenance, support or
updates for the software.
7. The software is and will remain the exclusive property of STMicroelectronics
and its licensors. The recipient will not take any action that jeopardizes
STMicroelectronics and its licensors' proprietary rights or acquire any rights
in the software, except the limited rights specified hereunder.
8. The recipient shall comply with all applicable laws and regulations affecting
the use of the software or any part thereof including any applicable export
control law or regulation.
9. Redistribution and use of this software or any part thereof other than as
permitted under this license is void and will automatically terminate your
rights under this license.
10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE
DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL
STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER
EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY
RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.

View File

@ -0,0 +1,141 @@
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2017 */
/* */
/* Portions COPYRIGHT 2017 STMicroelectronics */
/* Portions Copyright (C) 2017, ChaN, all right reserved */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various existing */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
/* Includes ------------------------------------------------------------------*/
#include "diskio.h"
#include "ff_gen_drv.h"
#if defined ( __GNUC__ )
#ifndef __weak
#define __weak __attribute__((weak))
#endif
#endif
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern Disk_drvTypeDef disk;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Gets Disk Status
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive number to identify the drive */
)
{
DSTATUS stat;
stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
return stat;
}
/**
* @brief Initializes a Drive
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat = RES_OK;
if(disk.is_initialized[pdrv] == 0)
{
disk.is_initialized[pdrv] = 1;
stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
}
return stat;
}
/**
* @brief Reads Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data buffer to store read data
* @param sector: Sector address (LBA)
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res;
res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
return res;
}
/**
* @brief Writes Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data to be written
* @param sector: Sector address (LBA)
* @param count: Number of sectors to write (1..128)
* @retval DRESULT: Operation result
*/
#if _USE_WRITE == 1
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res;
res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
return res;
}
#endif /* _USE_WRITE == 1 */
/**
* @brief I/O control operation
* @param pdrv: Physical drive number (0..)
* @param cmd: Control code
* @param *buff: Buffer to send/receive control data
* @retval DRESULT: Operation result
*/
#if _USE_IOCTL == 1
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
return res;
}
#endif /* _USE_IOCTL == 1 */
/**
* @brief Gets Time from RTC
* @param None
* @retval Time in DWORD
*/
__weak DWORD get_fattime (void)
{
return 0;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,80 @@
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2014 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
#define _USE_WRITE 1 /* 1: Enable disk_write function */
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl function */
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
DWORD get_fattime (void);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,361 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT file system module R0.12c /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2017, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/
#ifndef _FATFS
#define _FATFS 68300 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h).
#endif
/* Definitions of volume management */
#if _MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#endif
/* Type of path name strings on FatFs API */
#if _LFN_UNICODE /* Unicode (UTF-16) string */
#if _USE_LFN == 0
#error _LFN_UNICODE must be 0 at non-LFN cfg.
#endif
#ifndef _INC_TCHAR
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#endif
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
#endif
/* Type of file size variables */
#if _FS_EXFAT
#if _USE_LFN == 0
#error LFN must be enabled when enable exFAT
#endif
typedef QWORD FSIZE_t;
#else
typedef DWORD FSIZE_t;
#endif
/* File system object structure (FATFS) */
typedef struct {
BYTE fs_type; /* File system type (0:N/A) */
BYTE drv; /* Physical drive number */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
#if _MAX_SS != _MIN_SS
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
#endif
#if _USE_LFN != 0
WCHAR* lfnbuf; /* LFN working buffer */
#endif
#if _FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
#endif
#if _FS_RPATH != 0
DWORD cdir; /* Current directory start cluster (0:root) */
#if _FS_EXFAT
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD volbase; /* Volume base sector */
DWORD fatbase; /* FAT base sector */
DWORD dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* Object ID and allocation information (_FDID) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if _FS_EXFAT
DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
#endif
#if _FS_LOCK != 0
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} _FDID;
/* File object structure (FIL) */
typedef struct {
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct {
_FDID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if _USE_LFN != 0
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if _USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
/* File information structure (FILINFO) */
typedef struct {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if _USE_LFN != 0
TCHAR altname[13]; /* Alternative file name */
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
#else
TCHAR fname[13]; /* File name */
#endif
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->obj.objsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#define f_rmdir(path) f_unlink(path)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
#if !_FS_READONLY && !_FS_NORTC
DWORD get_fattime (void);
#endif
/* Unicode support functions */
#if _USE_LFN != 0 /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
#endif
/* Sync functions */
#if _FS_REENTRANT
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01
#define FA_WRITE 0x02
#define FA_OPEN_EXISTING 0x00
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA_OPEN_APPEND 0x30
/* Fast seek controls (2nd argument of f_lseek) */
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
/* Format options (2nd argument of f_mkfs) */
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_EXFAT 4
/* File attribute bits for directory entry (FILINFO.fattrib) */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#ifdef __cplusplus
}
#endif
#endif /* _FATFS */

View File

@ -0,0 +1,122 @@
/**
******************************************************************************
* @file ff_gen_drv.c
* @author MCD Application Team
* @brief FatFs generic low level driver.
*****************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
**/
/* Includes ------------------------------------------------------------------*/
#include "ff_gen_drv.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
Disk_drvTypeDef disk = {{0},{0},{0},0};
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Links a compatible diskio driver/lun id and increments the number of active
* linked drivers.
* @note The number of linked drivers (volumes) is up to 10 due to FatFs limits.
* @param drv: pointer to the disk IO Driver structure
* @param path: pointer to the logical drive path
* @param lun : only used for USB Key Disk to add multi-lun management
else the parameter must be equal to 0
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, uint8_t lun)
{
uint8_t ret = 1;
uint8_t DiskNum = 0;
if(disk.nbr < _VOLUMES)
{
disk.is_initialized[disk.nbr] = 0;
disk.drv[disk.nbr] = drv;
disk.lun[disk.nbr] = lun;
DiskNum = disk.nbr++;
path[0] = DiskNum + '0';
path[1] = ':';
path[2] = '/';
path[3] = 0;
ret = 0;
}
return ret;
}
/**
* @brief Links a compatible diskio driver and increments the number of active
* linked drivers.
* @note The number of linked drivers (volumes) is up to 10 due to FatFs limits
* @param drv: pointer to the disk IO Driver structure
* @param path: pointer to the logical drive path
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path)
{
return FATFS_LinkDriverEx(drv, path, 0);
}
/**
* @brief Unlinks a diskio driver and decrements the number of active linked
* drivers.
* @param path: pointer to the logical drive path
* @param lun : not used
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_UnLinkDriverEx(char *path, uint8_t lun)
{
uint8_t DiskNum = 0;
uint8_t ret = 1;
if(disk.nbr >= 1)
{
DiskNum = path[0] - '0';
if(disk.drv[DiskNum] != 0)
{
disk.drv[DiskNum] = 0;
disk.lun[DiskNum] = 0;
disk.nbr--;
ret = 0;
}
}
return ret;
}
/**
* @brief Unlinks a diskio driver and decrements the number of active linked
* drivers.
* @param path: pointer to the logical drive path
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_UnLinkDriver(char *path)
{
return FATFS_UnLinkDriverEx(path, 0);
}
/**
* @brief Gets number of linked drivers to the FatFs module.
* @param None
* @retval Number of attached drivers.
*/
uint8_t FATFS_GetAttachedDriversNbr(void)
{
return disk.nbr;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,80 @@
/**
******************************************************************************
* @file ff_gen_drv.h
* @author MCD Application Team
* @brief Header for ff_gen_drv.c module.
*****************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
**/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FF_GEN_DRV_H
#define __FF_GEN_DRV_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "diskio.h"
#include "ff.h"
#include "stdint.h"
/* Exported types ------------------------------------------------------------*/
/**
* @brief Disk IO Driver structure definition
*/
typedef struct
{
DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */
DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */
DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */
#if _USE_WRITE == 1
DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */
#endif /* _USE_IOCTL == 1 */
}Diskio_drvTypeDef;
/**
* @brief Global Disk IO Drivers structure definition
*/
typedef struct
{
uint8_t is_initialized[_VOLUMES];
const Diskio_drvTypeDef *drv[_VOLUMES];
uint8_t lun[_VOLUMES];
volatile uint8_t nbr;
}Disk_drvTypeDef;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path);
uint8_t FATFS_UnLinkDriver(char *path);
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, BYTE lun);
uint8_t FATFS_UnLinkDriverEx(char *path, BYTE lun);
uint8_t FATFS_GetAttachedDriversNbr(void);
#ifdef __cplusplus
}
#endif
#endif /* __FF_GEN_DRV_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,38 @@
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef _FF_INTEGER
#define _FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
typedef unsigned __int64 QWORD;
#else /* Embedded platform */
/* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE;
/* These types MUST be 16-bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
#endif
#endif

View File

@ -0,0 +1,177 @@
/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs */
/* (C)ChaN, 2014 */
/* Portions COPYRIGHT 2017 STMicroelectronics */
/* Portions Copyright (C) 2014, ChaN, all right reserved */
/*------------------------------------------------------------------------*/
/**
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
**/
#include "../ff.h"
#if _FS_REENTRANT
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
_SYNC_t *sobj /* Pointer to return the created sync object */
)
{
int ret;
#if _USE_MUTEX
#if (osCMSIS < 0x20000U)
osMutexDef(MTX);
*sobj = osMutexCreate(osMutex(MTX));
#else
*sobj = osMutexNew(NULL);
#endif
#else
#if (osCMSIS < 0x20000U)
osSemaphoreDef(SEM);
*sobj = osSemaphoreCreate(osSemaphore(SEM), 1);
#else
*sobj = osSemaphoreNew(1, 1, NULL);
#endif
#endif
ret = (*sobj != NULL);
return ret;
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to any error */
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
#if _USE_MUTEX
osMutexDelete (sobj);
#else
osSemaphoreDelete (sobj);
#endif
return 1;
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
_SYNC_t sobj /* Sync object to wait */
)
{
int ret = 0;
#if (osCMSIS < 0x20000U)
#if _USE_MUTEX
if(osMutexWait(sobj, _FS_TIMEOUT) == osOK)
#else
if(osSemaphoreWait(sobj, _FS_TIMEOUT) == osOK)
#endif
#else
#if _USE_MUTEX
if(osMutexAcquire(sobj, _FS_TIMEOUT) == osOK)
#else
if(osSemaphoreAcquire(sobj, _FS_TIMEOUT) == osOK)
#endif
#endif
{
ret = 1;
}
return ret;
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
_SYNC_t sobj /* Sync object to be signaled */
)
{
#if _USE_MUTEX
osMutexRelease(sobj);
#else
osSemaphoreRelease(sobj);
#endif
}
#endif
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
UINT msize /* Number of bytes to allocate */
)
{
return ff_malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free */
)
{
ff_free(mblock); /* Discard the memory block with POSIX API */
}
#endif

View File

@ -0,0 +1,128 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usb_host.c
* @version : v1.0_Cube
* @brief : This file implements the USB Host
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usb_host.h"
#include "usbh_core.h"
#include "usbh_msc.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USB Host core handle declaration */
USBH_HandleTypeDef hUsbHostFS;
ApplicationTypeDef Appli_state = APPLICATION_IDLE;
/*
* -- Insert your variables declaration here --
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*
* user callback declaration
*/
static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id);
/*
* -- Insert your external function declaration here --
*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Init USB host library, add supported class and start the library
* @retval None
*/
void MX_USB_HOST_Init(void)
{
/* USER CODE BEGIN USB_HOST_Init_PreTreatment */
/* USER CODE END USB_HOST_Init_PreTreatment */
/* Init host Library, add supported class and start the library. */
if (USBH_Init(&hUsbHostFS, USBH_UserProcess, HOST_FS) != USBH_OK)
{
Error_Handler();
}
if (USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS) != USBH_OK)
{
Error_Handler();
}
if (USBH_Start(&hUsbHostFS) != USBH_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USB_HOST_Init_PostTreatment */
/* USER CODE END USB_HOST_Init_PostTreatment */
}
/*
* user callback definition
*/
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
break;
case HOST_USER_DISCONNECTION:
Appli_state = APPLICATION_DISCONNECT;
break;
case HOST_USER_CLASS_ACTIVE:
Appli_state = APPLICATION_READY;
break;
case HOST_USER_CONNECTION:
Appli_state = APPLICATION_START;
break;
default:
break;
}
/* USER CODE END CALL_BACK_1 */
}
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,90 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usb_host.h
* @version : v1.0_Cube
* @brief : Header for usb_host.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_HOST__H__
#define __USB_HOST__H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx.h"
#include "stm32f7xx_hal.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup USBH_OTG_DRIVER
* @{
*/
/** @defgroup USBH_HOST USBH_HOST
* @brief Host file for Usb otg low level driver.
* @{
*/
/** @defgroup USBH_HOST_Exported_Variables USBH_HOST_Exported_Variables
* @brief Public variables.
* @{
*/
/**
* @}
*/
/** Status of the application. */
typedef enum {
APPLICATION_IDLE = 0,
APPLICATION_START,
APPLICATION_READY,
APPLICATION_DISCONNECT
}ApplicationTypeDef;
/** @defgroup USBH_HOST_Exported_FunctionsPrototype USBH_HOST_Exported_FunctionsPrototype
* @brief Declaration of public functions for Usb host.
* @{
*/
/* Exported functions -------------------------------------------------------*/
/** @brief USB Host initialization function. */
void MX_USB_HOST_Init(void);
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_HOST__H__ */

View File

@ -0,0 +1,575 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : Target/usbh_conf.c
* @version : v1.0_Cube
* @brief : This file implements the board support package for the USB host library
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbh_core.h"
#include "usbh_platform.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
HCD_HandleTypeDef hhcd_USB_OTG_FS;
void Error_Handler(void);
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status);
/* USER CODE END PFP */
/* Private functions ---------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/*******************************************************************************
LL Driver Callbacks (HCD -> USB Host Library)
*******************************************************************************/
/* MSP Init */
void HAL_HCD_MspInit(HCD_HandleTypeDef* hcdHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hcdHandle->Instance==USB_OTG_FS)
{
/* USER CODE BEGIN USB_OTG_FS_MspInit 0 */
/* USER CODE END USB_OTG_FS_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48;
PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USB_OTG_FS GPIO Configuration
PA12 ------> USB_OTG_FS_DP
PA11 ------> USB_OTG_FS_DM
PA9 ------> USB_OTG_FS_VBUS
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(OTG_FS_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
/* USER CODE BEGIN USB_OTG_FS_MspInit 1 */
/* USER CODE END USB_OTG_FS_MspInit 1 */
}
}
void HAL_HCD_MspDeInit(HCD_HandleTypeDef* hcdHandle)
{
if(hcdHandle->Instance==USB_OTG_FS)
{
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */
/* USER CODE END USB_OTG_FS_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
/**USB_OTG_FS GPIO Configuration
PA12 ------> USB_OTG_FS_DP
PA11 ------> USB_OTG_FS_DM
PA9 ------> USB_OTG_FS_VBUS
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12|GPIO_PIN_11|GPIO_PIN_9);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */
/* USER CODE END USB_OTG_FS_MspDeInit 1 */
}
}
/**
* @brief SOF callback.
* @param hhcd: HCD handle
* @retval None
*/
void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd)
{
USBH_LL_IncTimer(hhcd->pData);
}
/**
* @brief SOF callback.
* @param hhcd: HCD handle
* @retval None
*/
void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
{
USBH_LL_Connect(hhcd->pData);
}
/**
* @brief SOF callback.
* @param hhcd: HCD handle
* @retval None
*/
void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
{
USBH_LL_Disconnect(hhcd->pData);
}
/**
* @brief Notify URB state change callback.
* @param hhcd: HCD handle
* @param chnum: channel number
* @param urb_state: state
* @retval None
*/
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
{
/* To be used with OS to sync URB state with the global state machine */
#if (USBH_USE_OS == 1)
USBH_LL_NotifyURBChange(hhcd->pData);
#endif
}
/**
* @brief Port Port Enabled callback.
* @param hhcd: HCD handle
* @retval None
*/
void HAL_HCD_PortEnabled_Callback(HCD_HandleTypeDef *hhcd)
{
USBH_LL_PortEnabled(hhcd->pData);
}
/**
* @brief Port Port Disabled callback.
* @param hhcd: HCD handle
* @retval None
*/
void HAL_HCD_PortDisabled_Callback(HCD_HandleTypeDef *hhcd)
{
USBH_LL_PortDisabled(hhcd->pData);
}
/*******************************************************************************
LL Driver Interface (USB Host Library --> HCD)
*******************************************************************************/
/**
* @brief Initialize the low level portion of the host driver.
* @param phost: Host handle
* @retval USBH status
*/
USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost)
{
/* Init USB_IP */
if (phost->id == HOST_FS) {
/* Link the driver to the stack. */
hhcd_USB_OTG_FS.pData = phost;
phost->pData = &hhcd_USB_OTG_FS;
hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
hhcd_USB_OTG_FS.Init.Host_channels = 12;
hhcd_USB_OTG_FS.Init.speed = USB_OTG_SPEED_FULL;
hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
hhcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
if (HAL_HCD_Init(&hhcd_USB_OTG_FS) != HAL_OK)
{
Error_Handler( );
}
USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd_USB_OTG_FS));
}
return USBH_OK;
}
/**
* @brief De-Initialize the low level portion of the host driver.
* @param phost: Host handle
* @retval USBH status
*/
USBH_StatusTypeDef USBH_LL_DeInit(USBH_HandleTypeDef *phost)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBH_StatusTypeDef usb_status = USBH_OK;
hal_status = HAL_HCD_DeInit(phost->pData);
usb_status = USBH_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Start the low level portion of the host driver.
* @param phost: Host handle
* @retval USBH status
*/
USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBH_StatusTypeDef usb_status = USBH_OK;
hal_status = HAL_HCD_Start(phost->pData);
usb_status = USBH_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Stop the low level portion of the host driver.
* @param phost: Host handle
* @retval USBH status
*/
USBH_StatusTypeDef USBH_LL_Stop(USBH_HandleTypeDef *phost)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBH_StatusTypeDef usb_status = USBH_OK;
hal_status = HAL_HCD_Stop(phost->pData);
usb_status = USBH_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Return the USB host speed from the low level driver.
* @param phost: Host handle
* @retval USBH speeds
*/
USBH_SpeedTypeDef USBH_LL_GetSpeed(USBH_HandleTypeDef *phost)
{
USBH_SpeedTypeDef speed = USBH_SPEED_FULL;
switch (HAL_HCD_GetCurrentSpeed(phost->pData))
{
case 0 :
speed = USBH_SPEED_HIGH;
break;
case 1 :
speed = USBH_SPEED_FULL;
break;
case 2 :
speed = USBH_SPEED_LOW;
break;
default:
speed = USBH_SPEED_FULL;
break;
}
return speed;
}
/**
* @brief Reset the Host port of the low level driver.
* @param phost: Host handle
* @retval USBH status
*/
USBH_StatusTypeDef USBH_LL_ResetPort(USBH_HandleTypeDef *phost)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBH_StatusTypeDef usb_status = USBH_OK;
hal_status = HAL_HCD_ResetPort(phost->pData);
usb_status = USBH_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Return the last transferred packet size.
* @param phost: Host handle
* @param pipe: Pipe index
* @retval Packet size
*/
uint32_t USBH_LL_GetLastXferSize(USBH_HandleTypeDef *phost, uint8_t pipe)
{
return HAL_HCD_HC_GetXferCount(phost->pData, pipe);
}
/**
* @brief Open a pipe of the low level driver.
* @param phost: Host handle
* @param pipe: Pipe index
* @param epnum: Endpoint number
* @param dev_address: Device USB address
* @param speed: Device Speed
* @param ep_type: Endpoint type
* @param mps: Endpoint max packet size
* @retval USBH status
*/
USBH_StatusTypeDef USBH_LL_OpenPipe(USBH_HandleTypeDef *phost,
uint8_t pipe,
uint8_t epnum,
uint8_t dev_address,
uint8_t speed,
uint8_t ep_type,
uint16_t mps)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBH_StatusTypeDef usb_status = USBH_OK;
hal_status = HAL_HCD_HC_Init(phost->pData, pipe, epnum,
dev_address, speed, ep_type, mps);
usb_status = USBH_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Close a pipe of the low level driver.
* @param phost: Host handle
* @param pipe: Pipe index
* @retval USBH status
*/
USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
return USBH_OK;
}
/**
* @brief USBH_LL_ActivatePipe
* Activate a pipe of the Low Level Driver.
* @param phost: Host handle
* @param pipe: Pipe index
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_LL_ActivatePipe(USBH_HandleTypeDef *phost, uint8_t pipe)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(phost);
UNUSED(pipe);
return USBH_OK;
}
/**
* @brief Submit a new URB to the low level driver.
* @param phost: Host handle
* @param pipe: Pipe index
* This parameter can be a value from 1 to 15
* @param direction : Channel number
* This parameter can be one of the these values:
* 0 : Output
* 1 : Input
* @param ep_type : Endpoint Type
* This parameter can be one of the these values:
* @arg EP_TYPE_CTRL: Control type
* @arg EP_TYPE_ISOC: Isochrounous type
* @arg EP_TYPE_BULK: Bulk type
* @arg EP_TYPE_INTR: Interrupt type
* @param token : Endpoint Type
* This parameter can be one of the these values:
* @arg 0: PID_SETUP
* @arg 1: PID_DATA
* @param pbuff : pointer to URB data
* @param length : Length of URB data
* @param do_ping : activate do ping protocol (for high speed only)
* This parameter can be one of the these values:
* 0 : do ping inactive
* 1 : do ping active
* @retval Status
*/
USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t direction,
uint8_t ep_type, uint8_t token, uint8_t *pbuff, uint16_t length,
uint8_t do_ping)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBH_StatusTypeDef usb_status = USBH_OK;
hal_status = HAL_HCD_HC_SubmitRequest(phost->pData, pipe, direction ,
ep_type, token, pbuff, length,
do_ping);
usb_status = USBH_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Get a URB state from the low level driver.
* @param phost: Host handle
* @param pipe: Pipe index
* This parameter can be a value from 1 to 15
* @retval URB state
* This parameter can be one of the these values:
* @arg URB_IDLE
* @arg URB_DONE
* @arg URB_NOTREADY
* @arg URB_NYET
* @arg URB_ERROR
* @arg URB_STALL
*/
USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, uint8_t pipe)
{
return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState (phost->pData, pipe);
}
/**
* @brief Drive VBUS.
* @param phost: Host handle
* @param state : VBUS state
* This parameter can be one of the these values:
* 0 : VBUS Inactive
* 1 : VBUS Active
* @retval Status
*/
USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, uint8_t state)
{
if (phost->id == HOST_FS) {
MX_DriverVbusFS(state);
}
/* USER CODE BEGIN 0 */
/* USER CODE END 0*/
HAL_Delay(200);
return USBH_OK;
}
/**
* @brief Set toggle for a pipe.
* @param phost: Host handle
* @param pipe: Pipe index
* @param toggle: toggle (0/1)
* @retval Status
*/
USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, uint8_t pipe, uint8_t toggle)
{
HCD_HandleTypeDef *pHandle;
pHandle = phost->pData;
if(pHandle->hc[pipe].ep_is_in)
{
pHandle->hc[pipe].toggle_in = toggle;
}
else
{
pHandle->hc[pipe].toggle_out = toggle;
}
return USBH_OK;
}
/**
* @brief Return the current toggle of a pipe.
* @param phost: Host handle
* @param pipe: Pipe index
* @retval toggle (0/1)
*/
uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe)
{
uint8_t toggle = 0;
HCD_HandleTypeDef *pHandle;
pHandle = phost->pData;
if(pHandle->hc[pipe].ep_is_in)
{
toggle = pHandle->hc[pipe].toggle_in;
}
else
{
toggle = pHandle->hc[pipe].toggle_out;
}
return toggle;
}
/**
* @brief Delay routine for the USB Host Library
* @param Delay: Delay in ms
* @retval None
*/
void USBH_Delay(uint32_t Delay)
{
HAL_Delay(Delay);
}
/**
* @brief Returns the USB status depending on the HAL status:
* @param hal_status: HAL status
* @retval USB status
*/
USBH_StatusTypeDef USBH_Get_USB_Status(HAL_StatusTypeDef hal_status)
{
USBH_StatusTypeDef usb_status = USBH_OK;
switch (hal_status)
{
case HAL_OK :
usb_status = USBH_OK;
break;
case HAL_ERROR :
usb_status = USBH_FAIL;
break;
case HAL_BUSY :
usb_status = USBH_BUSY;
break;
case HAL_TIMEOUT :
usb_status = USBH_FAIL;
break;
default :
usb_status = USBH_FAIL;
break;
}
return usb_status;
}

View File

@ -0,0 +1,193 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : Target/usbh_conf.h
* @version : v1.0_Cube
* @brief : Header for usbh_conf.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBH_CONF__H__
#define __USBH_CONF__H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
#include "stm32f7xx.h"
#include "stm32f7xx_hal.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/** @addtogroup STM32_USB_HOST_LIBRARY
* @{
*/
/** @defgroup USBH_CONF
* @brief usb host low level driver configuration file
* @{
*/
/** @defgroup USBH_CONF_Exported_Variables USBH_CONF_Exported_Variables
* @brief Public variables.
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Defines USBH_CONF_Exported_Defines
* @brief Defines for configuration of the Usb host.
* @{
*/
/*---------- -----------*/
#define USBH_MAX_NUM_ENDPOINTS 2U
/*---------- -----------*/
#define USBH_MAX_NUM_INTERFACES 2U
/*---------- -----------*/
#define USBH_MAX_NUM_CONFIGURATION 1U
/*---------- -----------*/
#define USBH_KEEP_CFG_DESCRIPTOR 1U
/*---------- -----------*/
#define USBH_MAX_NUM_SUPPORTED_CLASS 1U
/*---------- -----------*/
#define USBH_MAX_SIZE_CONFIGURATION 256U
/*---------- -----------*/
#define USBH_MAX_DATA_BUFFER 512U
/*---------- -----------*/
#define USBH_DEBUG_LEVEL 3U
/*---------- -----------*/
#define USBH_USE_OS 1U
/****************************************/
/* #define for FS and HS identification */
#define HOST_HS 0
#define HOST_FS 1
#if (USBH_USE_OS == 1)
#include "cmsis_os.h"
#define USBH_PROCESS_PRIO osPriorityNormal
#define USBH_PROCESS_STACK_SIZE ((uint16_t)1024)
#endif /* (USBH_USE_OS == 1) */
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Macros USBH_CONF_Exported_Macros
* @brief Aliases.
* @{
*/
/* Memory management macros */
/** Alias for memory allocation. */
#define USBH_malloc malloc
/** Alias for memory release. */
#define USBH_free free
/** Alias for memory set. */
#define USBH_memset memset
/** Alias for memory copy. */
#define USBH_memcpy memcpy
/* DEBUG macros */
#if (USBH_DEBUG_LEVEL > 0U)
#define USBH_UsrLog(...) do { \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBH_UsrLog(...) do {} while (0)
#endif
#if (USBH_DEBUG_LEVEL > 1U)
#define USBH_ErrLog(...) do { \
printf("ERROR: "); \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBH_ErrLog(...) do {} while (0)
#endif
#if (USBH_DEBUG_LEVEL > 2U)
#define USBH_DbgLog(...) do { \
printf("ERROR: "); \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBH_DbgLog(...) do {} while (0)
#endif
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_Types USBH_CONF_Exported_Types
* @brief Types.
* @{
*/
/**
* @}
*/
/** @defgroup USBH_CONF_Exported_FunctionsPrototype USBH_CONF_Exported_FunctionsPrototype
* @brief Declaration of public functions for Usb host.
* @{
*/
/* Exported functions -------------------------------------------------------*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBH_CONF__H__ */

View File

@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbh_platform.c
* @brief : This file implements the USB platform
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usbh_platform.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/**
* @brief Drive VBUS.
* @param state : VBUS state
* This parameter can be one of the these values:
* - 1 : VBUS Active
* - 0 : VBUS Inactive
*/
void MX_DriverVbusFS(uint8_t state)
{
uint8_t data = state;
/* USER CODE BEGIN PREPARE_GPIO_DATA_VBUS_FS */
if(state == 1)
{
/* Drive high Charge pump */
data = GPIO_PIN_RESET;
}
else
{
/* Drive low Charge pump */
data = GPIO_PIN_SET;
}
/* USER CODE END PREPARE_GPIO_DATA_VBUS_FS */
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,(GPIO_PinState)data);
}

View File

@ -0,0 +1,42 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : usbh_platform.h
* @brief : Header for usbh_platform.c file.
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBH_PLATFORM_H__
#define __USBH_PLATFORM_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "usb_host.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
void MX_DriverVbusFS(uint8_t state);
#ifdef __cplusplus
}
#endif
#endif /* __USBH_PLATFORM_H__ */

View File

@ -20,14 +20,17 @@ KeepUserPlacement=false
Mcu.CPN=STM32F723IEK6
Mcu.Family=STM32F7
Mcu.IP0=CORTEX_M7
Mcu.IP1=FMC
Mcu.IP2=FREERTOS
Mcu.IP3=I2C3
Mcu.IP4=NVIC
Mcu.IP5=RCC
Mcu.IP6=SYS
Mcu.IP7=USART6
Mcu.IPNb=8
Mcu.IP1=FATFS
Mcu.IP10=USB_OTG_FS
Mcu.IP2=FMC
Mcu.IP3=FREERTOS
Mcu.IP4=I2C3
Mcu.IP5=NVIC
Mcu.IP6=RCC
Mcu.IP7=SYS
Mcu.IP8=USART6
Mcu.IP9=USB_HOST
Mcu.IPNb=11
Mcu.Name=STM32F723I(C-E)Kx
Mcu.Package=UFBGA176
Mcu.Pin0=PE3
@ -70,8 +73,10 @@ Mcu.Pin130=PB10
Mcu.Pin131=PB11
Mcu.Pin132=PB14
Mcu.Pin133=PB15
Mcu.Pin134=VP_FREERTOS_VS_CMSIS_V1
Mcu.Pin135=VP_SYS_VS_tim14
Mcu.Pin134=VP_FATFS_VS_USB
Mcu.Pin135=VP_FREERTOS_VS_CMSIS_V1
Mcu.Pin136=VP_SYS_VS_tim14
Mcu.Pin137=VP_USB_HOST_VS_USB_HOST_MSC_FS
Mcu.Pin14=PA13
Mcu.Pin15=PE4
Mcu.Pin16=PE5
@ -166,7 +171,7 @@ Mcu.Pin96=PA0-WKUP
Mcu.Pin97=PA4
Mcu.Pin98=PC4
Mcu.Pin99=PF13
Mcu.PinsNb=136
Mcu.PinsNb=138
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F723IEKx
@ -178,6 +183,7 @@ NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false
NVIC.OTG_FS_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:true\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:true\:false\:false
@ -200,8 +206,10 @@ PA10.GPIO_Label=USB_OTG_FS_ID
PA10.Locked=true
PA10.Signal=GPIO_Output
PA11.Locked=true
PA11.Mode=Host_Only
PA11.Signal=USB_OTG_FS_DM
PA12.Locked=true
PA12.Mode=Host_Only
PA12.Signal=USB_OTG_FS_DP
PA13.Locked=true
PA13.Mode=Serial_Wire
@ -241,6 +249,7 @@ PA8.Locked=true
PA8.Mode=I2C
PA8.Signal=I2C3_SCL
PA9.Locked=true
PA9.Mode=Activate_VBUS
PA9.Signal=USB_OTG_FS_VBUS
PB0.GPIOParameters=GPIO_Label
PB0.GPIO_Label=ARD_D5_STMOD_TIM3_CH3
@ -729,8 +738,8 @@ ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=Versuch3.ioc
ProjectManager.ProjectName=Versuch3
ProjectManager.ProjectFileName=Versuch4.ioc
ProjectManager.ProjectName=Versuch4
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
@ -908,10 +917,33 @@ SH.S_TIM9_CH2.0=TIM9_CH2
SH.S_TIM9_CH2.ConfNb=1
USART6.IPParameters=VirtualMode-Asynchronous
USART6.VirtualMode-Asynchronous=VM_ASYNC
USB_HOST.BSP.number=1
USB_HOST.IPParameters=USBH_HandleTypeDef-MSC_FS,VirtualModeFS,USBH_DEBUG_LEVEL-MSC_FS,USBH_PROCESS_STACK_SIZE-MSC_FS
USB_HOST.USBH_DEBUG_LEVEL-MSC_FS=3
USB_HOST.USBH_HandleTypeDef-MSC_FS=hUsbHostFS
USB_HOST.USBH_PROCESS_STACK_SIZE-MSC_FS=1024
USB_HOST.VirtualModeFS=Msc
USB_HOST0.BSP.STBoard=false
USB_HOST0.BSP.api=Unknown
USB_HOST0.BSP.component=
USB_HOST0.BSP.condition=SW_VBUS_DRIVE_MSC_FS \= false
USB_HOST0.BSP.instance=PG8
USB_HOST0.BSP.ip=GPIO
USB_HOST0.BSP.mode=Output
USB_HOST0.BSP.name=Drive_VBUS_FS
USB_HOST0.BSP.semaphore=
USB_HOST0.BSP.solution=PG8
USB_OTG_FS.IPParameters=VirtualMode,phy_itface
USB_OTG_FS.VirtualMode=Host_Only
USB_OTG_FS.phy_itface=HCD_PHY_EMBEDDED
VP_FATFS_VS_USB.Mode=USB
VP_FATFS_VS_USB.Signal=FATFS_VS_USB
VP_FREERTOS_VS_CMSIS_V1.Mode=CMSIS_V1
VP_FREERTOS_VS_CMSIS_V1.Signal=FREERTOS_VS_CMSIS_V1
VP_SYS_VS_tim14.Mode=TIM14
VP_SYS_VS_tim14.Signal=SYS_VS_tim14
VP_USB_HOST_VS_USB_HOST_MSC_FS.Mode=MSC_FS
VP_USB_HOST_VS_USB_HOST_MSC_FS.Signal=USB_HOST_VS_USB_HOST_MSC_FS
board=STM32F723E-DISCO
boardIOC=true
rtos.0.ip=FREERTOS