?? chapter9.c
字號:
#include "ds89c4xx.h"
#include "mytype.h"
#include "D12CI.h"
#include "D12HAL.h"
#include "Chapter9.h"
#include "Descriptor.h"
#include "uart0.h"
#ifndef _swap_data_
#define _swap_data_
#define SWAP16(x) ((((uint16)(x))<<8)|(((uint16)(x))>>8)) //高低字節交換
#define LSB(x) ((uint8)(x)) //取一個整數的低字節
#define MSB(x) ((uint8)(((uint16)(x))>>8)) //取一個整數的高字節
#endif
//定義傳輸控制結構變量
CONTROL_XFER idata ControlData;
//定義USB事件標志變量
EPPFLAGS idata bEPPflags;
uint8 idata idle,protocol;
//*************************************************************************
//USB標準設備請求入口地址指針表
//*************************************************************************
void (*StandardDeviceRequest[])(void) =
{
get_status,
clear_feature,
reserved,
set_feature,
reserved,
set_address,
get_descriptor,
reserved,
get_configuration,
set_configuration,
get_interface,
set_interface,
reserved,
reserved,
reserved,
reserved
};
void (*ClassDeviceRequest[])(void) =
{
reserved,
get_report,
get_idle,
get_protocol,
reserved,
reserved,
reserved,
reserved,
reserved,
set_report,
set_idle,
set_protocol
};
//*************************************************************************
// USB 協議層函數
//*************************************************************************
/*************************************
** 函數名稱: void stall_ep0(void)
** 功能描述: 使控制端點處于停止狀態
**************************************/
void stall_ep0(void)
{
D12_SetEndpointStatus(0, 1);
D12_SetEndpointStatus(1, 1);
}
/*************************************
** 函數名稱: void reserved(void)
** 功能描述: 保留子程序
**************************************/
void reserved(void)
{
stall_ep0(); //返回STALL
}
/**********************************************
** 函數名稱: void init_unconfig(void)
** 功能描述: 進入地址狀態,禁止0除外的所有端點
***********************************************/
void init_unconfig(void)
{
D12_SetEndpointEnable(0); //禁止0除外的所有端點
}
/**********************************************
** 函數名稱: void init_config(void)
** 功能描述: 配置處理,允許端點收發
***********************************************/
void init_config(void)
{
D12_SetEndpointEnable(1); //使能普通/同步端點使能
}
/*********************************************************
** 函數名稱: void single_transmit(uint8 * buf, uint8 len)
** 功能描述: 通過端點索引 1 發送數據(DATA 類型)
** 輸 入: uint8 * buf: 發送數據指針
uint8 len: 發送數據長度
** 輸 出: 無
**********************************************************/
void single_transmit(uint8 *buf, uint8 len)
{
if( len <= EP0_PACKET_SIZE) { //長度小于EP0最大信息包大小才允許發送
D12_WriteEndpoint(1, len, buf);
}
}
/*************************************************************
** 函數名稱: void code_transmit(uint8 * pRomData, uint16 len)
** 功能描述: 通過端點索引 1 發送數據(CODE類型)
** 輸 入: uint8 *pRomData: 發送數據指針
uint16 len: 發送數據長度
** 輸 出: 無
**************************************************************/
void code_transmit(uint8 * pRomData, uint16 idata len)
{
if(!bEPPflags.bits.transmit_not_end)
{
ControlData.wCount = 0; //傳輸字節數計數器清0
if(ControlData.wLength > len)
ControlData.wLength = len; //傳輸數據總字節數不得超過len
ControlData.pData = pRomData; //傳輸數據指針指向pRomData
}
if( ControlData.wLength >= EP0_PACKET_SIZE) //傳輸數據總字節數大于端點0最大信息包大小
{
D12_WriteEndpoint(1, EP0_PACKET_SIZE, (ControlData.pData + ControlData.wCount)); //發送端點0最大信息包大小個字節
ControlData.wCount += EP0_PACKET_SIZE; //統計已發送字節數
bEPPflags.bits.control_state = USB_TRANSMIT; //標志數據發送狀態
bEPPflags.bits.transmit_not_end = 1; //數據未發送完成
//ControlData.wLength -= EP0_PACKET_SIZE;
//PutUint320(ControlData.wLength,10);
}
else if(ControlData.wLength > 0)
{
//PutUint320(ControlData.wLength,10);
D12_WriteEndpoint(1, ControlData.wLength, (ControlData.pData + ControlData.wCount)); //寫入傳輸數據總字節數
ControlData.wCount += ControlData.wLength; //統計已發送字節數
bEPPflags.bits.control_state = USB_IDLE; //標志空閑狀態
//bEPPflags.bits.transmit_not_end = 0; //傳輸結束
ControlData.wLength = 0;
}
else
{
//PutUint320(ControlData.wLength,10);
D12_WriteEndpoint(1, 0, 0); //發送完畢,發0個字節
bEPPflags.bits.control_state = USB_IDLE;
//bEPPflags.bits.transmit_not_end = 0; //傳輸結束
}
}
//*************************************************************************
// USB 標準設備請求服務程序
//*************************************************************************
/********************************************************************
** 函數名稱: void get_status(void)
** 功能描述: 主機要求獲取狀態,設備返回16位的狀態描述給主機
*********************************************************************/
void get_status(void)
{
uint8 idata endp, txdat[2], c;
uint8 idata bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
//取得設備請求類型
if (bRecipient == USB_RECIPIENT_DEVICE) //對設備請求
{
if(bEPPflags.bits.remote_wakeup == 1)
txdat[0] = 2; //支持遠程喚醒、總線供電
else
txdat[0] = 0; //不支持遠程喚醒、總線供電
txdat[1]=0; //高8位為0
single_transmit(txdat, 2); //發送16位的狀態到主機
}
else if (bRecipient == USB_RECIPIENT_INTERFACE) //對接口請求
{
txdat[0]=0;
txdat[1]=0;
single_transmit(txdat, 2); //發送16位的狀態到主機
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT) //對端點請求
{
endp = (uint8)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (uint8)USB_ENDPOINT_DIRECTION_MASK)
c = D12_SelectEndpoint(endp*2 + 1); //讀取輸入端點狀態
else
c = D12_SelectEndpoint(endp*2); //讀取輸出端點狀態
if(c & D12_STALL)
txdat[0] = 1; //端點禁止
else
txdat[0] = 0; //端點有效
txdat[1] = 0;
single_transmit(txdat, 2); //發送16位的狀態到主機
} else
stall_ep0(); //非標準請求,發STALL
}
/****************************************
** 函數名稱: void clear_feature(void)
** 功能描述: 清除特性
*****************************************/
void clear_feature(void)
{
uint8 idata endp; //讀取請求類型中的接收方
uint8 idata bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;//讀取請求類型
if (bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)//對設備請求
{
bEPPflags.bits.remote_wakeup = 0; //清0遠程喚醒標志
single_transmit(0, 0); //返回一個空的數據表示執行完畢
}
else if(bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)//對端點請求
{
//清除端點禁止特性,恢復其使用
endp = (uint8)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (uint8)USB_ENDPOINT_DIRECTION_MASK)
D12_SetEndpointStatus(endp*2 + 1, 0); //清除控制輸入端點STALL特性
else
D12_SetEndpointStatus(endp*2, 0); //清除控制輸出端點STALL特性
single_transmit(0, 0); //返回一個空的數據表示執行完畢
}
else
stall_ep0(); //沒有該請求,返回STALL
}
/****************************************
** 函數名稱: void set_feature(void)
** 功能描述: 設置特性
*****************************************/
void set_feature(void)
{
uint8 idata endp; //讀取請求類型中的接收方
uint8 idata bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;//讀取請求類型
if (bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)//對設備請求
{
//設置遠程喚醒特性
bEPPflags.bits.remote_wakeup = 1; //置1遠程喚醒標志
single_transmit(0, 0); //返回一個空的數據表示執行完畢
}
else if (bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) //對端點請求
{
//禁止端點
endp = (uint8)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if (ControlData.DeviceRequest.wIndex & (uint8)USB_ENDPOINT_DIRECTION_MASK)
D12_SetEndpointStatus(endp*2 + 1, 1); //設置輸入端點禁止
else
D12_SetEndpointStatus(endp*2, 1); //設置輸出端點禁止
single_transmit(0, 0); //返回一個空的數據表示執行完畢
}
else
stall_ep0(); //沒有該請求,返回STALL
}
/****************************************
** 函數名稱: void set_address(void)
** 功能描述: 設置地址
*****************************************/
void set_address(void)
{
D12_SetAddressEnable((uint8)(ControlData.DeviceRequest.wValue & DEVICE_ADDRESS_MASK), 1);
single_transmit(0, 0); //發送一個空的數據響應
}
/****************************************
** 函數名稱: void get_descriptor(void)
** 功能描述: 獲取描述符
*****************************************/
void get_descriptor(void)
{
uint8 idata bDescriptor = MSB(ControlData.DeviceRequest.wValue); //讀取請求的描述符類型
uint8 idata bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
#ifdef debug
PutString0("Get usb descriptors.......\r\n",50);
#endif
if(bRecipient == USB_RECIPIENT_DEVICE)
{
if (bDescriptor == USB_DEVICE_DESCRIPTOR)//獲取設備描述符
{
#ifdef debug
PutString0(" Get usb device descriptor....\r\n",50);
#endif
code_transmit((uint8 *)&device_descriptor, sizeof(DEVICE_DESCRIPTOR_STRUCT));
}
else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR) //獲取其它描述符
{
if (ControlData.DeviceRequest.wLength > SWAP16(usb_descriptor.configuration_descriptor.wTotalLength))
{
ControlData.DeviceRequest.wLength = SWAP16(usb_descriptor.configuration_descriptor.wTotalLength);
}
#ifdef debug
PutString0(" Get usb config&interface&HID&endpoints descriptor....\r\n",100);
#endif
code_transmit((uint8 *)&(usb_descriptor), ControlData.DeviceRequest.wLength);//發送描述符內容
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -