📄 usb_prop.c
字号:
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name : usb_prop.c
* Author : MCD Application Team
* Version : V3.0.0
* Date : 04/06/2009
* Description : All processings related to DFU demo
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "spi_flash.h"
#include "usb_lib.h"
#include "hw_config.h"
#include "usb_conf.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "dfu_mal.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t wBlockNum = 0, wlength = 0;
uint32_t Manifest_State = Manifest_complete;
uint32_t Pointer = ApplicationAddress; /* Base Address to Erase, Program or Read */
DEVICE Device_Table =
{
EP_NUM,
1
};
DEVICE_PROP Device_Property =
{
DFU_init,
DFU_Reset,
DFU_Status_In,
DFU_Status_Out,
DFU_Data_Setup,
DFU_NoData_Setup,
DFU_Get_Interface_Setting,
DFU_GetDeviceDescriptor,
DFU_GetConfigDescriptor,
DFU_GetStringDescriptor,
0, /*DFU_EP0Buffer*/
bMaxPacketSize0 /*Max Packet size*/
};
USER_STANDARD_REQUESTS User_Standard_Requests =
{
DFU_GetConfiguration,
DFU_SetConfiguration,
DFU_GetInterface,
DFU_SetInterface,
DFU_GetStatus,
DFU_ClearFeature,
DFU_SetEndPointFeature,
DFU_SetDeviceFeature,
DFU_SetDeviceAddress
};
ONE_DESCRIPTOR Device_Descriptor =
{
(uint8_t*)DFU_DeviceDescriptor,
DFU_SIZ_DEVICE_DESC
};
ONE_DESCRIPTOR Config_Descriptor =
{
(uint8_t*)DFU_ConfigDescriptor,
DFU_SIZ_CONFIG_DESC
};
#ifdef USE_STM3210E_EVAL
ONE_DESCRIPTOR DFU_String_Descriptor[7] =
#else
ONE_DESCRIPTOR DFU_String_Descriptor[6] =
#endif
{
{ (uint8_t*)DFU_StringLangId, DFU_SIZ_STRING_LANGID },
{ (uint8_t*)DFU_StringVendor, DFU_SIZ_STRING_VENDOR },
{ (uint8_t*)DFU_StringProduct, DFU_SIZ_STRING_PRODUCT },
{ (uint8_t*)DFU_StringSerial, DFU_SIZ_STRING_SERIAL },
{ (uint8_t*)DFU_StringInterface0, DFU_SIZ_STRING_INTERFACE0 },
{ (uint8_t*)DFU_StringInterface1, DFU_SIZ_STRING_INTERFACE1 }
#ifdef USE_STM3210E_EVAL
,
{ (uint8_t*)DFU_StringInterface2_1, DFU_SIZ_STRING_INTERFACE2 },
#endif
};
/* Extern variables ----------------------------------------------------------*/
extern uint8_t DeviceState ;
extern uint8_t DeviceStatus[6];
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : DFU_init.
* Description : DFU init routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void DFU_init(void)
{
DEVICE_INFO *pInfo = &Device_Info;
/* Update the serial number string descriptor with the data from the unique ID*/
Get_SerialNum();
pInfo->Current_Configuration = 0;
/* Connect the device */
PowerOn();
/* USB interrupts initialization */
_SetISTR(0); /* clear pending interrupts */
wInterrupt_Mask = IMR_MSK;
_SetCNTR(wInterrupt_Mask); /* set interrupts mask */
/* Enable USB interrupts */
USB_Interrupts_Config();
bDeviceState = UNCONNECTED;
}
/*******************************************************************************
* Function Name : DFU_Reset.
* Description : DFU reset routine
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void DFU_Reset(void)
{
/* Set DFU_DEVICE as not configured */
Device_Info.Current_Configuration = 0;
/* Current Feature initialization */
pInformation->Current_Feature = DFU_ConfigDescriptor[7];
_SetBTABLE(BTABLE_ADDRESS);
/* Initialize Endpoint 0 */
_SetEPType(ENDP0, EP_CONTROL);
_SetEPTxStatus(ENDP0, EP_TX_NAK);
_SetEPRxAddr(ENDP0, ENDP0_RXADDR);
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
_SetEPTxAddr(ENDP0, ENDP0_TXADDR);
SetEPTxCount(ENDP0, Device_Property.MaxPacketSize);
Clear_Status_Out(ENDP0);
SetEPRxValid(ENDP0);
bDeviceState = ATTACHED;
/* Set this device to response on default address */
SetDeviceAddress(0);
}
/*******************************************************************************
* Function Name : DFU_SetConfiguration.
* Description : Udpade the device state to configured.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void DFU_SetConfiguration(void)
{
DEVICE_INFO *pInfo = &Device_Info;
if (pInfo->Current_Configuration != 0)
{
/* Device configured */
bDeviceState = CONFIGURED;
}
}
/*******************************************************************************
* Function Name : DFU_SetConfiguration.
* Description : Udpade the device state to addressed.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void DFU_SetDeviceAddress (void)
{
bDeviceState = ADDRESSED;
}
/*******************************************************************************
* Function Name : DFU_Status_In.
* Description : DFU status IN routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void DFU_Status_In(void)
{}
/*******************************************************************************
* Function Name : DFU_Status_Out.
* Description : DFU status OUT routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void DFU_Status_Out (void)
{
DEVICE_INFO *pInfo = &Device_Info;
uint32_t Addr;
if (pInfo->USBbRequest == DFU_GETSTATUS)
{
if (DeviceState == STATE_dfuDNBUSY)
{
if (wBlockNum == 0) /* Decode the Special Command*/
{
if ((MAL_Buffer[0] == CMD_GETCOMMANDS) && (wlength == 1))
{}
else if (( MAL_Buffer[0] == CMD_SETADDRESSPOINTER ) && (wlength == 5))
{
Pointer = MAL_Buffer[1];
Pointer += MAL_Buffer[2] << 8;
Pointer += MAL_Buffer[3] << 16;
Pointer += MAL_Buffer[4] << 24;
}
else if (( MAL_Buffer[0] == CMD_ERASE ) && (wlength == 5))
{
Pointer = MAL_Buffer[1];
Pointer += MAL_Buffer[2] << 8;
Pointer += MAL_Buffer[3] << 16;
Pointer += MAL_Buffer[4] << 24;
MAL_Erase(Pointer);
}
}
else if (wBlockNum > 1) // Download Command
{
Addr = ((wBlockNum - 2) * wTransferSize) + Pointer;
MAL_Write(Addr, wlength);
}
wlength = 0;
wBlockNum = 0;
DeviceState = STATE_dfuDNLOAD_SYNC;
DeviceStatus[4] = DeviceState;
DeviceStatus[1] = 0;
DeviceStatus[2] = 0;
DeviceStatus[3] = 0;
return;
}
else if (DeviceState == STATE_dfuMANIFEST)/* Manifestation in progress*/
{
DFU_write_crc();
return;
}
}
return;
}
/*******************************************************************************
* Function Name : DFU_Data_Setup.
* Description : Handle the data class specific requests.
* Input : RequestNb.
* Output : None.
* Return : USB_SUCCESS or USB_UNSUPPORT.
*******************************************************************************/
RESULT DFU_Data_Setup(uint8_t RequestNo)
{
uint8_t *(*CopyRoutine)(uint16_t);
CopyRoutine = NULL;
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
if (RequestNo == DFU_UPLOAD && (DeviceState == STATE_dfuIDLE
|| DeviceState == STATE_dfuUPLOAD_IDLE ))
{
CopyRoutine = UPLOAD;
}
else if (RequestNo == DFU_DNLOAD && (DeviceState == STATE_dfuIDLE
|| DeviceState == STATE_dfuDNLOAD_IDLE))
{
DeviceState = STATE_dfuDNLOAD_SYNC;
CopyRoutine = DNLOAD;
}
else if (RequestNo == DFU_GETSTATE)
{
CopyRoutine = GETSTATE;
}
else if (RequestNo == DFU_GETSTATUS)
{
CopyRoutine = GETSTATUS;
}
else
{
return USB_UNSUPPORT;
}
}
else
{
return USB_UNSUPPORT;
}
if (CopyRoutine == NULL)
{
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : DFU_NoData_Setup.
* Description : Handle the No data class specific requests.
* Input : Request Nb.
* Output : None.
* Return : USB_SUCCESS or USB_UNSUPPORT.
*******************************************************************************/
RESULT DFU_NoData_Setup(uint8_t RequestNo)
{
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
/*DFU_NDLOAD*/
if (RequestNo == DFU_DNLOAD)
{
/* End of DNLOAD operation*/
if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE )
{
Manifest_State = Manifest_In_Progress;
DeviceState = STATE_dfuMANIFEST_SYNC;
DeviceStatus[1] = 0;
DeviceStatus[2] = 0;
DeviceStatus[3] = 0;
DeviceStatus[4] = DeviceState;
return USB_SUCCESS;
}
}
/*DFU_UPLOAD*/
else if (RequestNo == DFU_UPLOAD)
{
DeviceState = STATE_dfuIDLE;
DeviceStatus[1] = 0;
DeviceStatus[2] = 0;
DeviceStatus[3] = 0;
DeviceStatus[4] = DeviceState;
return USB_SUCCESS;
}
/*DFU_CLRSTATUS*/
else if (RequestNo == DFU_CLRSTATUS)
{
if (DeviceState == STATE_dfuERROR)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -