我在翻閱手冊(cè)和學(xué)習(xí)Demo程序的時(shí)候,有以下幾點(diǎn)問題。
當(dāng)我設(shè)置UEP0_DMA=Ep0Buffer之后,是否就代表了當(dāng)UIF_TRANSFER成功且進(jìn)入U(xiǎn)IS_TOKEN_SETUP,則其默認(rèn)把FIFO中的8字節(jié)Setup包填入了Ep0Buffer中了?如果是的話,請(qǐng)問在不設(shè)置DMA的情況下,我是否可以通過什么方法自己讀取FIFO中的數(shù)據(jù)?如果不是的話是哪里我理解錯(cuò)了。
當(dāng)發(fā)送hid請(qǐng)求SetReport的時(shí)候,HID描述符我設(shè)置數(shù)據(jù)包大小是256,處理流程是否是這樣,處理SETUP(識(shí)別指令)->循環(huán)處理OUT(在DMA地址或者FIFO中不斷拿數(shù)據(jù))->結(jié)束。
當(dāng)發(fā)送hid請(qǐng)求GetReport的時(shí)候,HID描述符設(shè)置包大小256,則處理流程是否是,處理SETUP(識(shí)別指令)->循環(huán)處理IN(在DMA地址或者FIFO中把需要寫的數(shù)據(jù)寫入) ->結(jié)束。
我現(xiàn)在碰到的這個(gè)問題比較奇怪,我抄的官方HID的demo,但是始終無法走通第一條報(bào)文,系統(tǒng)總是下發(fā)Get_Descriptor,問我要設(shè)備描述符,可是我走串口調(diào)試,確實(shí)已經(jīng)發(fā)過去了,可是系統(tǒng)依然不停向我發(fā)請(qǐng)求設(shè)備描述符,不知道問題在哪里。
另外,本例只使用低速模式和端點(diǎn)0,其他端點(diǎn)一律禁用。
start
host: 80 6 0 1 0 0 40 0?
is dev scr,18,64
12 1 10 1 0 0 0 8?
send..
11 11 22 22 3 1 0 0?
send..
0 1?
send..
host: 0 5 22 0 0 0 0 0?
host: 80 6 0 1 0 0 40 0?
is dev scr,18,64
12 1 10 1 0 0 0 8?
send..
11 11 22 22 3 1 0 0?
send..
0 1?
send..
host: 0 5 23 0 0 0 0 0?
根據(jù)log來看,第二次主機(jī)下發(fā)的數(shù)據(jù)怎么變成亂碼了,不知道哪里出問題了
#include?"CH552.H"
#include?
#include?
#include?"usb_func.h"
#include?"Debug.H"
UINT8X?Ep0Buffer[THIS_ENDP0_SIZE?+?2]?_at_?0x0000;?//端點(diǎn)0?OUT&IN緩沖區(qū),必須是偶地址
//UINT8X?g_transbuf[256];
UINT8X?SetupReq;?//setup指令
UINT8X?Ready,?UsbConfig;
PUINT8?data_ptr;???//要發(fā)送的數(shù)據(jù)指針
UINT16X?data_len;??//要接收或者發(fā)送的數(shù)據(jù)長(zhǎng)度
UINT16X?setup_len;?//主機(jī)下發(fā)指令需要的長(zhǎng)度
//USB_SETUP_REQ?SetupReqBuf;?//暫存Setup包
#define?UsbSetupBuf?((PUSB_SETUP_REQ)Ep0Buffer)
/*設(shè)備描述符*/
UINT8C?DevDesc[]?=?{0x12,?0x01,?0x10,?0x01,?0x00,?0x00,?0x00,?THIS_ENDP0_SIZE,
????????????????????0x11,?0x11,
????????????????????0x22,?0x22,
????????????????????0x03,?0x01,?//BCD?發(fā)行版本號(hào)
????????????????????0x00,???????//廠商信息索引
????????????????????0x00,???????//產(chǎn)品信息索引
????????????????????0x00,???????//序列號(hào)索引
????????????????????0x01};??????//配置文件數(shù)
UINT8C?CfgDesc[]?=
????{
????????0x09,?0x02,?27,?0x00,?0x01,?0x01,?0x04,?0x80,?0x19,???//配置描述符
????????0x09,?0x04,?0x00,?0x00,?0x00,?0x03,?0x00,?0x00,?0x05,?//接口描述符
????????0x09,?0x21,?0x00,?0x01,?0x00,?0x01,?0x22,?60,?0x00,???//HID類描述符
};
/*字符串描述符?略*/
/*HID類報(bào)表描述符*/
UINT8C?HIDRepDesc[]?=
????{
????????0x06,?0x00,?0xFF,
????????0x09,?0x01,
????????0xA1,?0x01,
????????0x06,?0x00,?0xFF,
????????0x09,?0x01,
????????0xA1,?0x01,
????????0x85,?0x01,
????????0x06,?0x01,?0xFF,
????????0x09,?0x02,
????????0x15,?0x00,
????????0x25,?0xFF,
????????0x96,?0x00,?0x01,?//256
????????0x75,?0x08,
????????0xB1,?0x02,
????????0xC0,
????????0x06,?0x00,?0xFF,
????????0x09,?0x01,
????????0xA1,?0x01,
????????0x85,?0x02,
????????0x06,?0x02,?0xFF,
????????0x09,?0x02,
????????0x15,?0x00,
????????0x25,?0xFF,
????????0x96,?0x00,?0x01,?//256
????????0x75,?0x08,
????????0xB1,?0x02,
????????0xC0,
????????0xC0};
/*******************************************************************************
*?Function?Name??:?usb_init()
*?Description????:?USB設(shè)備模式配置,設(shè)備模式啟動(dòng),收發(fā)端點(diǎn)配置,中斷開啟
*?Input??????????:?None
*?Output?????????:?None
*?Return?????????:?None
*******************************************************************************/
void?usb_init()
{
????IE_USB?=?0;
????USB_CTRL?=?0x00;????????????//?先設(shè)定USB設(shè)備模式
????UDEV_CTRL?=?bUD_PD_DIS;?????//?禁止DP/DM下拉電阻
????UDEV_CTRL?|=?bUD_LOW_SPEED;?//選擇低速12M模式
????USB_CTRL?|=?bUC_LOW_SPEED;
????UEP0_DMA?=?Ep0Buffer;?//端點(diǎn)0數(shù)據(jù)傳輸?shù)刂?/p>
????//UEP4_1_MOD?&=?~(bUEP4_RX_EN?|?bUEP4_TX_EN);?//端點(diǎn)0單64字節(jié)收發(fā)緩沖區(qū)
????UEP0_CTRL?=?UEP_R_RES_ACK?|?UEP_T_RES_NAK;?//OUT事務(wù)返回ACK,IN事務(wù)返回NAK
????USB_DEV_AD?=?0x00;
????USB_CTRL?|=?bUC_DEV_PU_EN?|?bUC_INT_BUSY?|?bUC_DMA_EN;?//?啟動(dòng)USB設(shè)備及DMA,在中斷期間中斷標(biāo)志未清除前自動(dòng)返回NAK
????UDEV_CTRL?|=?bUD_PORT_EN;??????????????????????????????//?允許USB端口
????USB_INT_FG?=?0xFF;?????????????????????????????????????//?清中斷標(biāo)志
????USB_INT_EN?=?bUIE_TRANSFER?|?bUIE_BUS_RST;
????IE_USB?=?1;
}
//處理usb?standard?setup請(qǐng)求
void?usb_setup_standard_process()
{
????UINT8X?process_len;
????process_len?=?0;
????printf("host:?");
????outputdebug(Ep0Buffer?,?8);
????switch?(UsbSetupBuf->bRequest)
????{
????case?USB_GET_DESCRIPTOR:
????????switch?(UsbSetupBuf->wValueH)
????????{
????????case?USB_DESCR_TYP_DEVICE:?//設(shè)備描述符
????????????data_ptr?=?DevDesc;
????????????data_len?=?sizeof(DevDesc);
????????????printf("is?dev?scr,%d,%d\n",?data_len,?setup_len);
????????????break;
????????case?USB_DESCR_TYP_CONFIG:?//配置描述符
????????????printf("conf?scr\n");
????????????data_ptr?=?CfgDesc;
????????????data_len?=?sizeof(CfgDesc);
????????????break;
????????case?USB_DESCR_TYP_REPORT:?//報(bào)表描述符(HID)
????????????printf("hid?scr\n");
????????????data_ptr?=?HIDRepDesc;
????????????data_len?=?sizeof(HIDRepDesc);
????????????break;
????????default:
????????????printf("err?scr\n");
????????????data_len?=?0;
????????????data_ptr?=?DevDesc;
????????????break;
????????}
????????process_len?=?(data_len?>=?THIS_ENDP0_SIZE???THIS_ENDP0_SIZE?:?data_len);
????????if?(process_len?>?0)
????????{
????????????memcpy(Ep0Buffer,?data_ptr,?process_len);
????????????outputdebug(Ep0Buffer,?process_len);
????????????data_len?-=?process_len;
????????????data_ptr?+=?process_len;
????????}
????????UEP0_T_LEN?=?process_len;
????????UEP0_CTRL?=?bUEP_R_TOG?|?bUEP_T_TOG?|?UEP_R_RES_ACK?|?UEP_T_RES_ACK;?//返回應(yīng)答ACK
????????break;
????default:
????????break;
????}
????return;
}
//處理usb?setup請(qǐng)求
void?usb_setup_process()
{
????if?(8?!=?USB_RX_LEN)?//接收到的setup長(zhǎng)度不對(duì),則返回STALL不支持
????{
????????UEP0_CTRL?=?bUEP_R_TOG?|?bUEP_T_TOG?|?UEP_R_RES_STALL?|?UEP_T_RES_STALL;?//STALL
????????return;
????}
????//開始處理setup請(qǐng)求
????setup_len?=?UsbSetupBuf->wLengthH?<<?8;
????setup_len?+=?UsbSetupBuf->wLengthL;
????if?((UsbSetupBuf->bRequestType?&?USB_REQ_TYP_MASK)?==?USB_REQ_TYP_STANDARD)?//處理標(biāo)準(zhǔn)USB請(qǐng)求
????{
????????usb_setup_standard_process();
????}
????return;
}
//主機(jī)要拿數(shù)據(jù)
void?usb_inbuf_process()
{
????UINT8X?process_len;
????process_len?=?(data_len?>=?THIS_ENDP0_SIZE???THIS_ENDP0_SIZE?:?data_len);
????memcpy(Ep0Buffer,?data_ptr,?process_len);
????data_len?-=?process_len;
????data_ptr?+=?process_len;
????UEP0_T_LEN?=?process_len;
????UEP0_CTRL?^=?bUEP_T_TOG;?//同步標(biāo)記位翻轉(zhuǎn)
????printf("send..\n");
????outputdebug(Ep0Buffer,?process_len);
????return;
}
//主機(jī)發(fā)來數(shù)據(jù)
void?usb_outbuf_process()
{
}
/*******************************************************************************
*?Function?Name??:?usb_interrupt()
*?Description????:?CH559USB中斷處理函數(shù)
*******************************************************************************/
void?usb_interrupt(void)?interrupt?INT_NO_USB?//USB中斷服務(wù)程序,使用寄存器組1
{
????if?(UIF_TRANSFER)?//USB傳輸完成標(biāo)記
????{
????????switch?(USB_INT_ST?&?MASK_UIS_TOKEN)
????????{
????????case?UIS_TOKEN_SETUP:
????????????usb_setup_process();
????????????break;
????????case?UIS_TOKEN_IN:
????????????usb_inbuf_process();
????????????break;
????????case?UIS_TOKEN_OUT:
????????????usb_outbuf_process();
????????????break;
????????default:
????????????break;
????????}
????????UIF_TRANSFER?=?0;?//寫0清空中斷
????}
????else?if?(UIF_BUS_RST)
????{
????????UEP0_CTRL?=?UEP_R_RES_ACK?|?UEP_T_RES_NAK;
????????USB_DEV_AD?=?0x00;
????????UIF_SUSPEND?=?0;
????????UIF_TRANSFER?=?0;
????????UIF_BUS_RST?=?0;?//清中斷標(biāo)志
????}
????return;
}