1
新增一个class里面没有参考示例的设备
如果用户想增加一个device设备但是在TinyUSB class里面又没有参考示例,本次我们一起来移植一个CDC+printer复合设备。操作步骤还是和上篇一样,先将TinyUSB 从GitHub上克隆下来,将src 整个文件夹copy替换到例程components目录下的src。
图1 TinyUSB源码
将tinyusb 目录下example下的对应文件,将tinyusbexamplesdevicecdc_dual_portssrc 三个文件copy到例程user文件夹里面,其他增加时钟配置函数和添加tud_dcd_port.c 接口函数文件和上一篇一致(tud_dcd_port.c 文件可以参考现有例程或者联系灵动技术支持)。
图2 工程的USER文件
在tinyusbsrcclass里面新增一个printer文件夹,可以参考其他设备比如从hid里面copy两个hid_device.c和hid_device.h 文件做为模板,将文件名修改成printer_device.c和printer_device.h,在这个文件里面修改对应的函数接口。
图3 新增printer文件
工程文件树如下:
1. TinyUSB_CDC_Printer
2. │
3. ├─USER
4. │ main.c
5. │ usb_descriptors.c
6. │ usb_dcd_port.c
7. │
8. └─TinyUSB
9.
10. tusb.c
11. cdc_device.c
12. tud_fifo.c
13. usbd.c
14. usb_control.c
15. printer_device.c
2
修改printer接口函数
1、在printer接口文件里面需要修改实现以下几个函数:
printer_init,//接口变量初始化 printer_reset,//接口变量重置 printer_open, printer_control_xfer_cb,//控制接口回调 printer_xfer_cb//数据接口回调 tud_printer_task//while(1)循环打印机数据处理
图4 需要实现的接口函数
2、在tusb_config.h 文件里面增加宏定义#define CFG_TUD_PRINTER 1 ,同时将对应的设备define改成2 ( #define CFG_TUD_CDC 2 ) ,使能两个CDC设备。
//-------------CLASS-------------// #defineCFG_TUD_CDC2 #defineCFG_TUD_MSC0 #defineCFG_TUD_PRINTER1 #defineCFG_TUD_HID0 #defineCFG_TUD_MIDI0 #defineCFG_TUD_VENDOR0
3、在usbd.c 里面增加printer回调函数接口处理。
#ifCFG_TUD_PRINTER { DRIVER_NAME("PRINTER") .init=printer_init, .reset=printer_reset, .open=printer_open, .control_xfer_cb=printer_control_xfer_cb, .xfer_cb=printer_xfer_cb, .sof=NULL }, #endif
4、在tusb.h增加printer对应的头文件。
#ifCFG_TUD_PRINTER #include"class/printer/printer_device.h" #endif
5、在tusb.h增加printer描述符。
//--------------------------------------------------------------------+ //PRINTERDescriptorTemplates //--------------------------------------------------------------------+ //Lengthoftemplatedescriptor:23bytes #defineTUD_PRINTER_DESC_LEN(9+7+7) //Interfacenumber,stringindex,EPOut&EPInaddress,EPsize #defineTUD_PRINTER_DESCRIPTOR(_itfnum,_stridx,_epout,_epin,_epsize) /*Interface*/ 9,TUSB_DESC_INTERFACE,_itfnum,0,2,TUSB_CLASS_PRINTER,0x01,0x02,0, /*EndpointOut*/ 7,TUSB_DESC_ENDPOINT,_epout,TUSB_XFER_BULK,U16_TO_U8S_LE(_epsize),0x00, /*EndpointIn*/ 7,TUSB_DESC_ENDPOINT,_epin,TUSB_XFER_BULK,U16_TO_U8S_LE(_epsize),0x00
6、修改usb_descriptors.c 的描述符,增加一个printer的描述符和对应的端点。
//--------------------------------------------------------------------+ //ConfigurationDescriptor //--------------------------------------------------------------------+ enum { ITF_NUM_PRINTER=0, ITF_NUM_CDC_0, ITF_NUM_CDC_0_DATA, ITF_NUM_CDC_1, ITF_NUM_CDC_1_DATA, ITF_NUM_TOTAL }; #defineEPNUM_CDC_0_NOTIF0x81 #defineEPNUM_CDC_0_OUT0x02 #defineEPNUM_CDC_0_IN0x82 #defineEPNUM_CDC_1_NOTIF0x83 #defineEPNUM_CDC_1_OUT0x04 #defineEPNUM_CDC_1_IN0x84 #defineEPNUM_PRINTER_OUT0x05 #defineEPNUM_PRINTER_IN0x86 uint8_tconstdesc_fs_configuration[]= { //Confignumber,interfacecount,stringindex,totallength,attribute,powerinmA TUD_CONFIG_DESCRIPTOR(1,ITF_NUM_TOTAL,0,CONFIG_TOTAL_LEN,0x00,100), TUD_PRINTER_DESCRIPTOR(ITF_NUM_PRINTER,5,EPNUM_PRINTER_OUT,EPNUM_PRINTER_IN,64), //1stCDC:Interfacenumber,stringindex,EPnotificationaddressandsize,EPdataaddress(out,in)andsize. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0,4,EPNUM_CDC_0_NOTIF,8,EPNUM_CDC_0_OUT,EPNUM_CDC_0_IN,64), //2ndCDC:Interfacenumber,stringindex,EPnotificationaddressandsize,EPdataaddress(out,in)andsize. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1,4,EPNUM_CDC_1_NOTIF,8,EPNUM_CDC_1_OUT,EPNUM_CDC_1_IN,64), };
7、增加device id描述符和string字符串。
//--------------------------------------------------------------------+ //StringDescriptors //--------------------------------------------------------------------+ //arrayofpointertostringdescriptors charconst*string_desc_arr[]= { (constchar[]){0x09,0x04},//0:issupportedlanguageisEnglish(0x0409) "TinyUSB",//1:Manufacturer "TinyUSBDevice",//2:Product "123456",//3:Serials,shouldusechipID "TinyUSBCDC",//4:CDCInterface "MM32Printer",//5:printerInterface }; uint8_tconstdesc_printer_device_id[]={ 0x00,0x08,'p','r','i','n','t','0','0','0', }; uint8_t*tud_printer_device_id_cb(void) { //(void)itf; returndesc_printer_device_id; }
8、对应的需要在printer_device.c的printer_control_xfer_cb实现 device id的数据回复。
boolprinter_control_xfer_cb(uint8_trhport,uint8_tstage,tusb_control_request_tconst*p_request) { uint8_t*devicedesc; //nothingtodowithDATA&ACKstage if(stage!=CONTROL_STAGE_SETUP)returntrue; //Handleclassrequestonly TU_VERIFY(p_request->bmRequestType_bit.type==TUSB_REQ_TYPE_CLASS); switch(p_request->bRequest){ case0x00: devicedesc=tud_printer_device_id_cb(); tud_control_xfer(rhport,p_request,(void*)devicedesc,10); break; case0x01: devicedesc=tud_printer_device_id_cb(); tud_control_xfer(rhport,p_request,(void*)devicedesc,10); break; default: returnfalse;//stallunsupportedrequest } returntrue; }
9、在tusb_config.h文件里面添加#define CFG_TUSB_MCU OPT_MCU_MM32F016X
Tusb_option.h 文件里面增加:
#defineOPT_MCU_MM32F016X1501///< MindMotion MM32F0160
否则TUP_DCD_ENDPOINT_MAX 没有定义。
图5 增加MM32F0160 宏定义
10、在main.c 里面主循环增加三个处理函数:
tud_task(); cdc_task(); tud_printer_task();
main函数:
/*-------------MAIN-------------*/ intmain(void) { USB_DeviceClockInit();//board_init(); CONSOLE_Init(460800);//Configuart2 //initdevicestackonconfiguredroothubport tud_init(BOARD_TUD_RHPORT); TU_LOG1("TinyUSBPrinter&CDC "); while(1) { tud_task();//tinyusbdevicetask cdc_task(); tud_printer_task();//userprintertask } }
3
功能验证测试
完成上述移植修改解决基本的编译问题后烧录测试能枚举打印机和CDC两个设备。
图6 枚举过程
图7 枚举成功
选择打印机设备,直接打印word的内容,能抓到通过枚举的打印机28号设备端点4下发的数据。
图8 枚举成功
图9 printer EP4 OUT包数据
审核编辑:刘清
-
处理器
+关注
关注
68文章
19286浏览量
229817 -
USB接口
+关注
关注
9文章
701浏览量
55648 -
CDC技术
+关注
关注
0文章
9浏览量
6862 -
MCU芯片
+关注
关注
3文章
252浏览量
11453
原文标题:灵动微课堂 (第264讲)|基于MM32F0163D7P的USB接口TinyUSB应用:移植和新增设备(二)
文章出处:【微信号:MindMotion-MMCU,微信公众号:灵动MM32MCU】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论