diff --git a/driver/inc/usb.h b/driver/inc/usb.h index e725cd2..fe65a9b 100644 --- a/driver/inc/usb.h +++ b/driver/inc/usb.h @@ -44,17 +44,7 @@ extern "C" { #define MAX(a,b) ((a)>(b)?(a):(b)) #endif -/** - * @brief Given an endpoint configuration, returns true if the endpoint - * is transmitting data to the host (i.e. is an IN endpoint) - * - * @param ep, the endpoint configuration - * @return true - * @return false - */ -static inline int ep_is_tx(struct usb_endpoint_configuration *ep) { - return ep->descriptor->bEndpointAddress & USB_DIR_IN; -} +int usb_is_configured(void); void usb_start_transfer(struct usb_endpoint_configuration *ep, uint8_t *buf, uint16_t len); void usb_device_init(struct usb_device_configuration *dev_config); struct usb_endpoint_configuration *usb_get_endpoint_configuration(uint8_t addr); diff --git a/driver/src/usb.c b/driver/src/usb.c index 54e9422..ccfddc3 100644 --- a/driver/src/usb.c +++ b/driver/src/usb.c @@ -12,13 +12,19 @@ static volatile int configured = 0; // Global data buffer for EP0 static uint8_t ep0_buf[64]; +int usb_is_configured(void) +{ + return configured; +} + /** * @brief Take a buffer pointer located in the USB RAM and return as an offset of the RAM. * * @param buf * @return uint32_t */ -static inline uint32_t usb_buffer_offset(volatile uint8_t *buf) { +static inline uint32_t usb_buffer_offset(volatile uint8_t *buf) +{ return (uint32_t) buf ^ (uint32_t) usb_dpram; } @@ -97,6 +103,19 @@ uint8_t usb_prepare_string_descriptor(const unsigned char *str) return bLength; } +/** + * @brief Given an endpoint configuration, returns true if the endpoint + * is transmitting data to the host (i.e. is an IN endpoint) + * + * @param ep, the endpoint configuration + * @return true + * @return false + */ +static inline int ep_is_tx(struct usb_endpoint_configuration *ep) +{ + return ep->descriptor->bEndpointAddress & USB_DIR_IN; +} + /** * @brief Starts a transfer on a given endpoint. * @@ -304,7 +323,8 @@ void usb_handle_setup_packet(void) * * @param ep, the endpoint to notify. */ -static void usb_handle_ep_buff_done(struct usb_endpoint_configuration *ep) { +static void usb_handle_ep_buff_done(struct usb_endpoint_configuration *ep) +{ uint32_t buffer_control = *ep->buffer_control; // Get the transfer length for this endpoint uint16_t len = buffer_control & USB_BUF_CTRL_LEN_MASK; diff --git a/example/peripherals/usb/usb_device/main.c b/example/peripherals/usb/usb_device/main.c index d54585e..d131191 100644 --- a/example/peripherals/usb/usb_device/main.c +++ b/example/peripherals/usb/usb_device/main.c @@ -12,6 +12,8 @@ extern void ep0_out_handler(uint8_t *buf, uint16_t len); void ep1_out_handler(uint8_t *buf, uint16_t len) { printf("RX %d bytes from host\n", len); + buf[len] = 0; + printf("received data: %s\r\n", buf); // Send data back to host struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR); usb_start_transfer(ep, buf, len); @@ -165,11 +167,16 @@ int main(void) system_init(); usb_device_init(&dev_config); + while (usb_is_configured() == 0); + printf("enumed time: %ld\r\n", (uint32_t)timer_count_read()); + + // Get ready to rx from host + usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64); time_start = timer_count_read(); while (1) { time_stop = timer_count_read(); - if (time_stop - time_start > 3000 * 1000) { + if (time_stop - time_start > 30 * 1000 * 1000) { usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS; reset_unreset_blocks_wait(RESETS_BLOCK_USBCTRL); printf("time 1s, stop USB\r\n"); diff --git a/example/peripherals/usb/usb_device/myusb.py b/example/peripherals/usb/usb_device/myusb.py new file mode 100755 index 0000000..53673a1 --- /dev/null +++ b/example/peripherals/usb/usb_device/myusb.py @@ -0,0 +1,74 @@ +import usb.core +import usb.util + +# USB设备参数 +VENDOR_ID = 0x0000 # 替换为实际的VID +PRODUCT_ID = 0x0001 # 替换为实际的PID +OUT_ENDPOINT = 0x01 # EP1 OUT端点 +IN_ENDPOINT = 0x82 # EP2 IN端点 (注意: IN端点通常最高位设为1) +MAX_FIFO_SIZE = 64 # 最大FIFO长度 + +def find_usb_device(): + """查找并返回指定的USB设备""" + dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID) + if dev is None: + raise ValueError("设备未找到,请检查连接或VID/PID") + return dev + +def configure_device(dev): + """配置USB设备""" + # 如果是Linux,可能需要先detach内核驱动 + # if dev.is_kernel_driver_active(0): + # dev.detach_kernel_driver(0) + + # 设置配置 + dev.set_configuration() + + # 获取配置 + cfg = dev.get_active_configuration() + intf = cfg[(0,0)] + + print("设备配置成功") + return dev + +def send_data(dev, data): + """向OUT端点发送数据""" + if len(data) > MAX_FIFO_SIZE: + raise ValueError(f"数据长度超过最大FIFO大小({MAX_FIFO_SIZE}字节)") + + # 发送数据到EP1 OUT + bytes_written = dev.write(OUT_ENDPOINT, data) + print(f"发送成功: {bytes_written} 字节") + return bytes_written + +def receive_data(dev, max_length=MAX_FIFO_SIZE): + """从IN端点接收数据""" + # 从EP2 IN读取数据 + data = dev.read(IN_ENDPOINT, max_length) + print(f"接收成功: {len(data)} 字节") + return data + +def main(): + try: + # 查找并配置设备 + dev = find_usb_device() + dev = configure_device(dev) + + # 示例数据发送 + test_data = b"Hello USB Device!" # 测试数据 + send_data(dev, test_data) + + # 示例数据接收 + received_data = receive_data(dev) + print("接收到的数据:", received_data) + + except usb.core.USBError as e: + print(f"USB错误: {e}") + except Exception as e: + print(f"错误: {e}") + finally: + # 释放设备 + usb.util.dispose_resources(dev) + +if __name__ == "__main__": + main()