?? usbdriver.c
字號:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: USBDriver.c
** Last modified Date: 2005-8-6
** Last Version: V1.0
** Descriptions: LPC23xx USB 應用層
** LPC23xx USB Application Layer
**------------------------------------------------------------------------------------------------------
** Created by: 鄭明遠 MingYuan Zheng
** Created date: 2005-8-6
** Version: V1.0
** Descriptions: 初始版本 The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "config.h"
#include "USBConfig.h"
#include "string.h"
#include "USBHAL.h"
#include "USBCI.h"
#include "USBdma.h"
#include "Chap_9.h"
#include "Descriptor.h"
#include "USBDriver.h"
/* define USB event flag variable */
EPPFLAGS bEPPflags; /* 定義 USB 事件標志變量 */
/* Stack of the task that deal with control transfer */
OS_STK TaskSetupStk[128]; /* Setup包處理任務堆棧 */
/* the pointer of Event that deal SETUP packet */
OS_EVENT *pSetup_Event; /* Setup包處理任務事件指針 */
/* USB receive or transmit control block of LPC23xx USB each endpoint */
CTRL_USB Ctrl_Usb[NUM_ENDPOINTS]; /* LPC23xx USB 各端點對應的 USB 接收或發送控制塊 */
/***********************************************************************************************************************
** 函數名稱 : USB_Initialize() Name : USB_Initialize()
** 功能描述 : 初始化 USB 設備控制器 Function : Initialize the USB device controller
** 輸 入 : 無 Input : NULL
** 輸 出 : 0: 初始化成功 >0: 初始化失敗(錯誤碼) Output : 0: Initialize sucessfully >0: Initialize fail(error code)
***********************************************************************************************************************/
INT8U USB_Initialize(void)
{
int i;
OS_ENTER_CRITICAL();
USB_InitHardware(); /* 初始化硬件 Initialize the hardware */
bEPPflags.value = 0; /* 置USB事件標志為0 set USB event flags to zero */
if (USB_ReadTestRegister() != 0xA50F) /* 讀測試寄存器 read test register */
{
OS_EXIT_CRITICAL();
return USB_ERR_READ_TESTREG; /* 初始化失敗 initialize fail */
}
USB_USBDevIntConfig(); /* 配置中斷 configure the USB interrupt */
USB_ConfigEndpoint(); /* 配置端點 configure the endpoint */
#if DMA_ENGINE_EN
USB_DMAInit(); /* 初始化USB DMA initialize the USB DMA */
USB_SetMode(0x28);
#else
USB_SetMode(0x00); /* 成功傳輸才產生中斷 generate interrupt only transmit sucessfully */
#endif
pSetup_Event = OSSemCreate(0); /* SETUP包處理任務信號量 the semaphore of the task processing SETUP packet */
if (pSetup_Event == NULL)
{
OS_EXIT_CRITICAL();
return USB_ERR_CREATE_SEM; /* 創建失敗,返回錯誤碼 return error code when create fail */
}
for(i = 0; i < NUM_ENDPOINTS; i++)
{
Ctrl_Usb[i].bEpReady = 0;
Ctrl_Usb[i].bTaskWaiting = 0;
Ctrl_Usb[i].Ep_Sem = OSSemCreate(0);
if (Ctrl_Usb[i].Ep_Sem == NULL)
{
OS_EXIT_CRITICAL();
return USB_ERR_CREATE_SEM; /* 創建信號量失敗 create semaphore fail */
}
}
USB_Reconnect();
reconnect_USB(); /* 重新連接USB reconnect the USB */
OS_EXIT_CRITICAL();
return USB_NO_ERR; /* 初始化USB成功 Initialize USB sucessfully */
}
/***********************************************************************************************************************
** 函數名稱: void TaskSetup(void *pdata) Name: void TaskSetup(void *pdata)
** 功能描述: 控制傳輸處理 Function: deal with control transfer
** 輸 入: void *pdata 任務參數 Input: void *pdata: parameter of the task
** 輸 出: 無 Output: NULL
** 注 意: 該任務的優先級應高于其它任務,才能在 Note: the prior of the task must be higher than other,so
任何情況下傳輸SETUP包 it will be sucessful when tranfering SETUP packet
************************************************************************************************************************/
void TaskSetup(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U err;
pdata = pdata; /* Prevent compiler warning */
for (;;)
{
OSSemPend(pSetup_Event,0,&err); /* 等待Setup包 wait for SETUP packet */
if (err == OS_NO_ERR){ /* 接收到Setup包 have received SETUP packet */
OS_ENTER_CRITICAL(); /* 關中斷 disable all interrupt */
control_handler(); /* 進行控制傳輸處理 deal with control transfer */
OS_EXIT_CRITICAL(); /* 開中斷 enable all interrupt */
}
}
}
/*******************************************************************************************************************************
** 函數名稱: INT8U ReadPort1() Name: INT8U ReadPort1()
** 功能描述: 從端口 1 接收len個字節 Function: receive len Bytes from Port1
** 輸 入: INT32U len: 要接收的字節數 Input: INT32U len: numbers will be receive
(取值范圍為0x00000001 ~ 0xFFFFFFFF) (range: 0x00000001 ~ 0xFFFFFFFF)
INT8U recbuff: 接收緩沖區指針 INT8U recbuff: receive buffer
INT16U timeout: 超時等待時間, 等于0表示無限等待 INT16U timeout: timeout of receiving,0 indicates limitless waiting
** 輸 出: 0: 接收成功 > 0: 接收失敗(錯誤碼) Output: 0: sucessfully >0 fail (error code)
*******************************************************************************************************************************/
INT8U ReadPort1(INT32U len, INT8U *recbuff, INT16U timeout)
{
#if DMA_ENGINE_EN
return (USB_ReadPortDMA(2, &Ctrl_Usb[0], len, recbuff, timeout)); /* DMA方式 */
#else
return (USB_ReadPort(2, 16, 1, &Ctrl_Usb[0], len, recbuff, timeout)); /* 非DMA方式 */
#endif
} //從物理端點 2 接收數據
/*******************************************************************************************************************************
** 函數名稱: INT8U ReadPort2() Name: INT8U ReadPort2()
** 功能描述: 從端口 2 接收len個字節 Function: receive len Bytes from Port2
** 輸 入: INT32U len: 要接收的字節數 Input: INT32U len: numbers will be receive
(取值范圍為0x00000001 ~ 0xFFFFFFFF) (range: 0x00000001 ~ 0xFFFFFFFF)
INT8U recbuff: 接收緩沖區指針 INT8U sendbuff: receive buffer
INT16U timeout: 超時等待時間, 等于0表示無限等待 INT16U timeout: timeout of receiving,0 indicates limitless waiting
** 輸 出: 0: 接收成功 > 0: 接收失敗(錯誤碼) Output: 0: sucessfully >0 fail (error code)
*******************************************************************************************************************************/
INT8U ReadPort2(INT32U len, INT8U *recbuff, INT16U timeout)
{
#if DMA_ENGINE_EN
return (USB_ReadPortDMA(4, &Ctrl_Usb[2], len, recbuff, timeout)); /* DMA方式 */
#else
return (USB_ReadPort(4, 64, 2, &Ctrl_Usb[2], len, recbuff, timeout)); /* 非DMA方式 */
#endif
} //從物理端點 4 接收數據
/*******************************************************************************************************************************
** 函數名稱: INT8U WritePort1() Name: INT8U WritePort1()
** 功能描述: 用端口 1 發送len個字節 Function: Send len Bytes via Port1
** 輸 入: INT32U len: 發送的字節數 Input: INT32U len: numbers will be send
(取值范圍為0x00000001 ~ 0xFFFFFFFF) (range: 0x00000001 ~ 0xFFFFFFFF)
INT8U sendbuff: 發送緩沖區指針 INT8U sendbuff: send buffer
INT16U timeout: 超時等待時間, 等于0表示無限等待 INT16U timeout: timeout of transmitting,0 indicates limitless waiting
** 輸 出: 0: 發送成功 > 0: 發送失敗(錯誤碼) Output: 0: sucessfully >0 fail (error code)
*******************************************************************************************************************************/
INT8U WritePort1(INT32U len, INT8U *sendbuff, INT16U timeout)
{
#if DMA_ENGINE_EN
return (USB_WritePortDMA(3, &Ctrl_Usb[1], sendbuff, len, timeout)); /* DMA方式 */
#else
return (USB_WritePort(3, 64, 2, &Ctrl_Usb[1], sendbuff, len, timeout)); /* 非DMA方式 */
#endif
} /* 通過物理端點 3 發送數據 */
/*******************************************************************************************************************************
** 函數名稱: INT8U WritePort2() Name: INT8U WritePort2()
** 功能描述: 用端口 2 發送len個字節 Function: Send len Bytes via Port2
** 輸 入: INT32U len: 發送的字節數 Input: INT32U len: numbers will be send
(取值范圍為0x00000001 ~ 0xFFFFFFFF) (range: 0x00000001 ~ 0xFFFFFFFF)
INT8U sendbuff: 發送緩沖區指針 INT8U sendbuff: send buffer
INT16U timeout: 超時等待時間, 等于0表示無限等待 INT16U timeout: timeout of transmitting,0 indicates limitless waiting
** 輸 出: 0: 發送成功 > 0: 發送失敗(錯誤碼) Output: 0: sucessfully >0 fail (error code)
*******************************************************************************************************************************/
INT8U WritePort2(INT32U len,INT8U *sendbuff,INT16U timeout)
{
#if DMA_ENGINE_EN
return (USB_WritePortDMA(5, &Ctrl_Usb[3], sendbuff, len, timeout)); /* DMA方式 */
#else
return (USB_WritePort(5, 64, 2, &Ctrl_Usb[3], sendbuff, len, timeout)); /* 非DMA方式 */
#endif
} /* 通過物理端點 5 發送數據 */
/***********************************************************************************************************************
** 函數名稱: USB_RW_Param() Name: USB_RW_Param()
** 功能描述: 填寫USB接收或發送控制塊有關參數 Function: fill the CTRL_USB structure
** 輸 入: CTRL_USB *pUsb : USB接收或發送控制塊指針 Input: CTRL_USB *pUsb: the CTRL_USB structure
INT8U *buff : 接收或發送緩沖區指針 INT8U *recbuff: the reception/transmittion buffer
** 輸 出: 0 調用成功 > 0 調用失敗(錯誤碼) Output: 0: sucessfully >0: fail (it is error code)
***********************************************************************************************************************/
INT8U USB_RW_Param(CTRL_USB *pUsb, INT8U *pbuff)
{
if (bEPPflags.bits.configuration == 0)
return USB_ERR_NO_CONFIG; /* USB總線未配置完成 the USB bus is not confirgurated */
if (pbuff == NULL)
return USB_ERR_BUFF_INVALID; /* 緩沖區指針無效錯誤 the pointer of buff is invalid */
if (pUsb->bEpUsed == 1)
return USB_ERR_ENDP_OCCUPY; /* 端點已被其它任務占用 the endpoint have been used */
pUsb->bEpUsed = 1; /* 本任務占用該端點 the task use the endpoint */
return USB_NO_ERR;
}
/***********************************************************************************************************************
** 函數名稱: USB_WaitEpReady() Name: USB_WaitEpReady()
** 功能描述: 等待端點就緒 Function: Waiting for the endpoint is ready
** 輸 入: CTRL_USB *pUsb : USB接收或發送控制塊指針 Input: CTRL_USB *pUsb: the CTRL_USB structure
INT16U timeout : 超時時間 INT8U *recbuff: timeout
** 輸 出: 0 調用成功 > 0 調用失敗(錯誤碼) Output: 0: sucessfully >0: fail (it is error code)
***********************************************************************************************************************/
#if (!DMA_ENGINE_EN)
INT8U USB_WaitEpReady(CTRL_USB *pUsb, INT16U timeout)
{
INT8U err;
OS_ENTER_CRITICAL();
if (pUsb->bEpReady == 1)
{ /* 端點已就緒 the endpoint is ready */
pUsb->bEpReady = 0;
OS_EXIT_CRITICAL();
err = USB_NO_ERR; /* 無須等待 need not waiting */
}
else
{
pUsb->bTaskWaiting = 1; /* 置位,表示任務進入等待的狀態 set the bit, indicate the task enter the waiting status */
OSSemPend(pUsb->Ep_Sem, timeout, &err); /* 等待端點就緒(進入等待狀態) wait for endpoint is ready */
OS_EXIT_CRITICAL();
}
return err;
}
#endif
/*************************************************************************************************************************
** 函數名稱: USB_ReadPort() Name: USB_ReadPort()
** 功能描述: 讀端點(非DMA方式) Function: read data from endpoint(Not DMA)
** 輸 入: INT8U endp: 物理端點索引號 Input: INT8U endp: the physical endpoint number
INT32U eppsize: 端點緩沖區大小 INT32U eppsize: the size of endpoint buffer
INT8U buffnums: 該端點的緩沖區個數 INT8U buffnums: numbers of endpoint buffer
CTRL_USB *pUsb: 接收/發送數據控制塊 CTRL_USB *pUsb: the control block of receiving/sending
INT32U len: 接收字節個數 INT32U len: the numbers(Bytes) that will be received
INT8U *recbuff: 接收緩沖區 INT8U *recbuff: the reception buffer
INT16U timeout: 超時等待時間, 等于0表示無限等待 INT16U timeout: timeout of receiving,0 indicates limitless waiting
** 輸 出: 0: 讀成功 > 0 讀失敗(錯誤碼) Output: 0: sucessfully >0: fail (it is error code)
**************************************************************************************************************************/
#if (!DMA_ENGINE_EN)
INT8U USB_ReadPort(INT8U endp, INT32U eppsize, INT8U buffnums, CTRL_USB *pUsb, INT32U len, INT8U *recbuff, INT16U timeout)
{
INT8U err,i;
INT32U reccnt = 0, tmp;
OS_ENTER_CRITICAL();
err = USB_RW_Param(pUsb, recbuff); /* 檢查參數正確性 check the parameter */
if (err != USB_NO_ERR)
{
OS_EXIT_CRITICAL();
OSTimeDly(1);
return err; /* 返回錯誤碼 return error code */
}
OS_EXIT_CRITICAL();
while(1)
{
err = USB_WaitEpReady(pUsb, timeout); /* 等待端點收到數據 waiting for the endpoint receiving data */
/********** 下面從端點緩沖區中讀取數據 *********/
if (err == OS_NO_ERR)
{
OS_ENTER_CRITICAL();
for(i = 0; i < buffnums; i++)
{
if ((USB_SelectEndpoint(endp) & 0x60) == 0)
break; /* 緩沖區為空 endpoint buffer is empty */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -