LPC1788做U盤的時(shí)候?qū)γ畹捻憫?yīng)
首先是對(duì)于端點(diǎn)的數(shù)據(jù)處理
#ifndef __USBEP2_H_
#define __USBEP2_H_
#include "usb.h"
#include "usbhw.h"
#include "msc.h"
#include "mscuser.h"
void usb_ep2_in_process(void);
void usb_ep2_out_process(void);
#endif
#include "usbep2.h"
//批量輸入事件
void usb_ep2_in_process(void)
{
switch(BulkStage)
{
caseMSC_BS_DATA_IN:
switch(CBW.CB[0])
{
caseSCSI_READ10:
MSC_MemoryRead();//讀取數(shù)據(jù)并等待下一次傳輸
break;
}
break;
caseMSC_BS_DATA_IN_LAST:
MSC_SetCSW();//上一次傳輸并且傳輸已經(jīng)完成
break;
caseMSC_BS_DATA_IN_LAST_STALL:
USB_SetStallEP(MSC_EP_IN);
MSC_SetCSW();
break;
caseMSC_BS_CSW:
BulkStage=MSC_BS_CBW;//簡(jiǎn)單的進(jìn)行狀態(tài)切換
break;
}
}
//批量輸出事件
void usb_ep2_out_process(void)
{
BulkLen=USB_ReadEP(MSC_EP_OUT,BulkBuf);//讀取緩存
switch(BulkStage)//根據(jù)階段判定
{
caseMSC_BS_CBW://最開始的階段必然是命令階段
MSC_GetCBW();//獲取并處理cbw命令
break;
caseMSC_BS_DATA_OUT://數(shù)據(jù)輸出階段
switch(CBW.CB[0])//分辨寫入指令
{
caseSCSI_WRITE10:
MSC_MemoryWrite();
break;
caseSCSI_VERIFY10:
MSC_MemoryVerify();
break;
}
break;
default://不支持的狀態(tài)
USB_SetStallEP(MSC_EP_OUT);
CSW.bStatus=CSW_PHASE_ERROR;
MSC_SetCSW();
break;
}
}
然后再在子程序中對(duì)命令詳細(xì)分析
#ifndef __MSCUSER_H_
#define __MSCUSER_H_
#include "msc.h"
#include "usbhw.h"
#include "memory.h"
//批量傳輸節(jié)點(diǎn)的最大包長(zhǎng)度
#define MSC_MAX_PACKET 64
//批量傳輸節(jié)點(diǎn)地址
#define MSC_EP_IN 0x82
#define MSC_EP_OUT 0x02
extern uint8_t BulkStage; //傳輸狀態(tài),指明下一次如何傳輸
extern uint8_t BulkLen; //輸出接點(diǎn),主機(jī)輸出的數(shù)據(jù)長(zhǎng)度
extern uint8_t BulkBuf[MSC_MAX_PACKET];//數(shù)據(jù)緩存中心
extern MSC_CBW CBW; //cbw塊
extern MSC_CSW CSW; //csw塊
extern uint32_t MemOK; /* 測(cè)試mem是否完好 */
#define MSC_DEBUG 0
#if MSC_DEBUG
#define msc_debug_printf(format,args...) printf(format,##args) //變參宏定義
#else
#define msc_debug_printf(x,...) while(0);
#endif
//枚舉過(guò)程中的重要節(jié)點(diǎn)
extern uint32_t MSC_Reset(void);
extern uint32_t MSC_GetMaxLUN(void);
//msc設(shè)備的方法
extern void MSC_GetCBW(void);
extern void MSC_SetCSW(void);
void MSC_MemoryRead(void);
void MSC_MemoryWrite(void);
void MSC_MemoryVerify(void);
#endif
#include "mscuser.h"
uint32_t MemOK=__TRUE; /* 測(cè)試mem是否完好 */
uint32_t Offset; /* 讀取寫入的定位 */
uint32_t Length; /* 讀取寫入的長(zhǎng)度 */
uint8_t BulkStage; /* 批量傳輸?shù)碾A段, 數(shù)據(jù)階段 命令階段 狀態(tài)階段 */
uint8_t BulkBuf[MSC_MAX_PACKET];/* 讀取批量端點(diǎn)傳輸來(lái)的數(shù)據(jù) */
uint8_t BulkLen; /* 傳輸長(zhǎng)度 */
MSC_CBW CBW; /*CBW結(jié)構(gòu)體 */
MSC_CSW CSW; /*CSW結(jié)構(gòu)體 */
#if NORFLASH
u8 usb_mac_global_buffer[MSC_MAX_PACKET];
#endif
#if NANDFLASH
u8 usb_mac_global_buffer[MSC_MAX_PACKET];
#endif
//msc設(shè)備復(fù)位
uint32_t MSC_Reset(void)
{
BulkStage=MSC_BS_CBW;
return(__TRUE);
}
//獲取標(biāo)號(hào)
uint32_t MSC_GetMaxLUN(void)
{
EP0Buf[0]=0; //0為一個(gè)設(shè)備
return(__TRUE);
}
//設(shè)備讀取數(shù)據(jù),在in階段發(fā)送出去
void MSC_MemoryRead(void)
{
uint32_t n;
if(Length>MSC_MAX_PACKET)//根據(jù)長(zhǎng)度來(lái)計(jì)算,不能大于包長(zhǎng)度
{
n=MSC_MAX_PACKET;
}
else
{
n=Length;
}
if((Offset+n)>MSC_MemorySize)//緩沖區(qū)最大長(zhǎng)度
{
n=MSC_MemorySize-Offset;
BulkStage=MSC_BS_DATA_IN_LAST_STALL;//傳輸失敗的發(fā)送
}
#if NORFLASH
NOR_FLASH_Read_Buffer_Mal(Offset,usb_mac_global_buffer,n);//讀取數(shù)據(jù)
USB_WriteEP(MSC_EP_IN,(u8*)usb_mac_global_buffer,n);
#endif
#if NANDFLASH
while(nandReady==0);
nandReady=0;
NAND_Read_Addr_Mal(Offset,usb_mac_global_buffer,n);
USB_WriteEP(MSC_EP_IN,(u8*)usb_mac_global_buffer,n);
nandReady=1;
#endif
Offset+=n;
Length-=n;//傳輸完成后對(duì)指針進(jìn)行相應(yīng)的處理
CSW.dDataResidue-=n;
if(Length==0)
{
BulkStage=MSC_BS_DATA_IN_LAST;//數(shù)據(jù)傳輸成功
}
if(BulkStage!=MSC_BS_DATA_IN)//上一次傳輸為0 ,命令通過(guò)
{
CSW.bStatus=CSW_CMD_PASSED;
}
}
u8 norflash_buffer[2048]={0};
//寫入數(shù)據(jù)到設(shè)備
void MSC_MemoryWrite(void)
{
if((Offset+BulkLen)>MSC_MemorySize)//防止超界
{
BulkLen=MSC_MemorySize-Offset;
BulkStage=MSC_BS_CSW;
USB_SetStallEP(MSC_EP_OUT);
}
#if NORFLASH
NOR_FLASH_W