天天看點

【.Net Micro Framework PortingKit(補) – 1】USB驅動開發

在前段時間我連續寫了15篇關于【.Net Micro Framework PortingKit–?】的系列文章,初步介紹了.Net Micro Framework在Cortex-M3平台上的移植過程,最近一段時間又對另外兩塊Cortex-M3開發闆進行了相關的移植工作,新實作了USB驅動、SPI驅動、觸摸屏驅動、LCD驅動(ILI9325),除此之外還新開發了TinyGUI圖形庫,該圖形庫僅需要極少量的記憶體便能運作在Cortex-M3平台上。從今天開始,我會陸續寫這方面開發的相關文章。

第一次編寫USB的驅動,是在Ti DM355平台上,當時用了大概二個多月的時間才移植成功,花了這麼長的時間,一是USB運作機制非常複雜,二是對嵌入式開發當時并不是特别熟悉。在此期間我寫四篇關于USB的文章,有興趣的朋友可參考一下《Micro Framework USB Driver開發》、《MF Porting之USB驅動開發》、《【.Net MF新特性】Usb雙接口支援》和《.Net Micro Framework - USB Mass Storage功能實作》。

STM32F103系列的晶片,其USB接口僅支援Device模式,不像Ti DM355其接口支援OTG、Host、Device三種模式,是以寄存器通路相對比較簡單(不過ST最新推出的互聯性晶片,其USB接口和Ti的一樣了)。

USB接口支援8個端點,資料傳輸支援三種模式:DMA、雙緩沖、單緩沖,簡單期間,我僅實作了單緩沖模式。

首先,我們需要聲明USB寄存器相對應的結構體,以期友善操作相關的寄存器。

struct CortexM3_USB_Base

{

    //+ 0x40

    /****/ volatile UINT16 CNTR;  //控制寄存器

    static const    UINT16 CNTR_CTRM = ((UINT16)0x8000);            //成功傳輸中斷标志

    static const    UINT16 CNTR_PMAOVRM = ((UINT16)0x4000);    //分組緩沖區溢出中斷标志

    略……

};

 

struct CortexM3_USB_EndPoint

{

     /****/ volatile UINT16 EP;   //端點寄存器

    static const    UINT16 EP_CTR_RX = ((UINT16)0x8000);               //正确接收标志

    static const    UINT16 EP_DTOG_RX = ((UINT16)0x4000);            //用于資料接收的資料翻轉位

略…….

};

 

struct CortexM3_USB_BTABLE

{

    static const UINT32 c_Base = 0x40006000;  //~0x400063FF USB/CAN共享的SRAM 512位元組(c_PMA_Base)

    

    /****/ volatile UINT16 ADDR_TX;     //發送緩沖區位址

    static const    UINT16 ADDR_TX_Mask = ((UINT16)0xFFFE);    

    UINT16  RESERVED0;

    略…….

};

 

struct CortexM3_USB

{

    static const UINT32 c_Base = 0x40005C00;

    static const UINT32 c_CFGR_USBPRE_BB = 0x42000000 + 0x21004 * 32 + 0x16 * 4;

    static const UINT32 c_USB_MAX_EP = 3;  //8

    CortexM3_USB_EndPoint EP[8]; //0x0-0x1c   

    UINT16 RESERVED0[16];    

    CortexM3_USB_Base Base;      //0x40-0x4c 

};           

USB提供兩個中斷信号,一個是c_IRQ_Index_USB_HP_CAN_TX,另一個是c_IRQ_Index_USB_LP_CAN_RX0,不過前一個對低速傳輸似乎必要性不大。

是以這裡僅啟用第二種中斷,代碼如下:

if(!CPU_INTC_ActivateInterruptEx( CortexM3_NVIC::c_IRQ_Index_USB_LP_CAN_RX0, (UINT32)(void *)USB_LP_IRQHandler)) return  FALSE;           

此外控制USB軟連接配接的GPIO為PB14,啟用USB功能前,要置位該Pin腳。

CPU_GPIO_DisablePin( USB_EN_PIN,RESISTOR_DISABLED,TRUE,GPIO_ALT_MODE_9);  //DISABLE

CPU_GPIO_DisablePin( USB_EN_PIN,RESISTOR_DISABLED,TRUE,GPIO_ALT_MODE_5);  //ENABLE           

針對.Net Micro Framework來說,USB僅用到三個端點,是以隻需用初始化這三個端點即可,相關代碼如下:

CortexM3_USB &USB = CortexM3::USB();     

USB.Base.DADDR = CortexM3_USB_Base::DADDR_EF | 0;

 

 //EP0

 USB.EP[0].EP = CortexM3_USB_EndPoint::EP_TYPE_CONTROL |   (0 & CortexM3_USB_EndPoint::EP_EA); 

 SetTxStatus(0,CortexM3_USB_EndPoint::EP_TX_NAK);

 SetRxStatus(0,CortexM3_USB_EndPoint::EP_RX_VALID);

 //lcd_printf("EP0:%x/r/n",USB.EP[0].EP);

    

 //EP1

 USB.EP[1].EP = CortexM3_USB_EndPoint::EP_TYPE_BULK | (1 & CortexM3_USB_EndPoint::EP_EA);

SetTxStatus(1,CortexM3_USB_EndPoint::EP_TX_NAK);

SetRxStatus(1,CortexM3_USB_EndPoint::EP_RX_DISABLED);     

 if(USB.EP[1].EP & CortexM3_USB_EndPoint::EP_DTOG_RX)  USB.EP[1].EP |= CortexM3_USB_EndPoint::EP_DTOG_RX;     

if(USB.EP[1].EP & CortexM3_USB_EndPoint::EP_DTOG_TX)  USB.EP[1].EP |= CortexM3_USB_EndPoint::EP_DTOG_TX;

      

 //EP2

 USB.EP[2].EP = CortexM3_USB_EndPoint::EP_TYPE_BULK | (2 & CortexM3_USB_EndPoint::EP_EA);

SetTxStatus(2,CortexM3_USB_EndPoint::EP_TX_DISABLED);

SetRxStatus(2,CortexM3_USB_EndPoint::EP_RX_VALID);

if(USB.EP[2].EP & CortexM3_USB_EndPoint::EP_DTOG_RX)  USB.EP[2].EP |= CortexM3_USB_EndPoint::EP_DTOG_RX;     

if(USB.EP[2].EP & CortexM3_USB_EndPoint::EP_DTOG_TX)  USB.EP[2].EP |= CortexM3_USB_EndPoint::EP_DTOG_TX;           

限于篇幅,這裡的代碼僅列這麼多,有興趣的朋友請參考.Net Micro Framework的相關USB驅動的源碼,其架構大同小異。

最終成功運作的效果圖如下:

【.Net Micro Framework PortingKit(補) – 1】USB驅動開發

繼續閱讀