【.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驅動的源碼,其架構大同小異。
最終成功運行的效果圖如下:
?
轉載于:https://www.cnblogs.com/yefanqiu/archive/2010/05/09/1731314.html
總結
以上是生活随笔為你收集整理的【.Net Micro Framework PortingKit(补) – 1】USB驱动开发的全部內容,希望文章能夠幫你解決所遇到的問題。