DAP数据传输过程:
1)首先进入枚举阶段,在USB配置完成中断(USBD_EVENT_CONFIGURED)中第一次调用usbd_ep_start_read(DAP_OUT_EP, USB_Request[0], DAP_PACKET_SIZE);目的为:初始化端点接收缓存;
2)当主机DAP端点发来数据时,OUT事务完成时,此时数据已经通过DMA放到 USB_Request[0]里面了,之后再进入USBD_IRQHandler中断处理函数;
3)中断函数中,首先将USB设备设置为NAK忙状态,更新下一次接收数据的地址,更新目前接收到的总长度等;
4)再判断数据是否接收完成,或者已经到到了期望接收数据长度;
5)如果没有接收完成,设置USB为ACK继续接收,直到接收完成;
6)如果已经接收完成了,则进入usbd_event_ep_out_complete_handler();
7)函数中实际调用dap_out_callback(uint8_t ep, uint32_t nbytes);
8)函数先把数据处理了(例如把数据通过SWD口将数据发送给单片机),过程中USB中断一直NAK,然后再开启下一次的数据读取准备int usbd_ep_start_read(const uint8_t ep, uint8_t *data, uint32_t data_len)初始化端点接收缓存;
10)之后再允许USB ACK,等待主机发来DAP数据;
11)如此循环往复完成DAP数据传输。
所属系列
从当前文章继续阅读它所在合集中的前后内容。
零基础入门USB 第 5 / 9 篇
查看合集 本作品集介绍USB基础知识,解析USB通信协议,学习USB工作原理,制作USB设备,编写USB上位机软件。
相关文章
优先推荐同专题、同标签和同作者内容,补足热门文章。
评论 1
登录 后参与评论
graph TD A[usbd_desc_register] --> B[usbd_add_interface] B --> C[usbd_add_endpoint] C --> D[usbd_initialize] B --> B_STRUCT["struct usbd_interface<br/>*intf[16];"] C --> C_STRUCT["struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM];<br/>struct usbd_tx_rx_msg rx_msg[CONFIG_USBDEV_EP_NUM];"] D --> E[USBD_IRQHandler] E --> F[usbd_event_reset_handler] E --> G[usbd_event_ep0_setup_complete_handler] E --> H[usbd_event_ep_in_complete_handler] E --> I[usbd_event_ep_out_complete_handler] G --> J[usbd_setup_request_handler] J --> K[usbd_standard_request_handler] J --> L[usbd_class_request_handler] J --> M[usbd_vendor_request_handler] H --> N["tx_msg[ep & 0x7f].cb"] N --> O[usbd_event_ep0_in_complete_handler] N --> P["tx_msg[ep & 0x7f].cb"] I --> Q["rx_msg[ep & 0x7f].cb"] Q --> R[usbd_event_ep0_out_complete_handler] Q --> S["rx_msg[ep & 0x7f].cb"] classDef blue fill:#a8d0ff,stroke:#333,stroke-width:2px; classDef pink fill:#ffc0cb,stroke:#333,stroke-width:2px; classDef red fill:#ff8a80,stroke:#333,stroke-width:2px; classDef lightblue fill:#61c0ff,stroke:#333,stroke-width:2px; class A,B,C,D,B_STRUCT,C_STRUCT blue; class E pink; class F,G,H,I red; class J,K,L,M,N,O,P,Q,R,S lightblue;