/* ******************************************************************************* * fastboot_reset * * Description: * void * * Parameters: * void * * Return value: * void * * note: * void * ******************************************************************************* */ static void fastboot_reset(void) { DMSG_INFO("fastboot_reset\n"); udc.address = 0; udc.speed = USB_SPEED_UNKNOWN; udc.bulk_ep_size = HIGH_SPEED_EP_MAX_PACKET_SIZE; udc.fifo_size = BULK_FIFOSIZE; USBC_ForceId(udc.bsp, USBC_ID_TYPE_DEVICE); USBC_ForceVbusValid(udc.bsp, USBC_VBUS_TYPE_HIGH); USBC_Dev_ConectSwitch(udc.bsp, USBC_DEVICE_SWITCH_OFF); USBC_EnableDpDmPullUp(udc.bsp); USBC_EnableIdPullUp(udc.bsp); USBC_SelectBus(udc.bsp, USBC_IO_TYPE_PIO, 0, 0); USBC_ConfigFIFO_Base(udc.bsp, udc.sram_base, USBC_FIFO_MODE_8K); USBC_EnhanceSignal(udc.bsp); #ifdef CONFIG_USB_1_1_DEVICE USBC_Dev_ConfigTransferMode(udc.bsp, USBC_TS_TYPE_BULK, USBC_TS_MODE_FS); #else USBC_Dev_ConfigTransferMode(udc.bsp, USBC_TS_TYPE_BULK, USBC_TS_MODE_HS); #endif /* disable all interrupt */ USBC_INT_DisableUsbMiscAll(udc.bsp); USBC_INT_DisableEpAll(udc.bsp, USBC_EP_TYPE_RX); USBC_INT_DisableEpAll(udc.bsp, USBC_EP_TYPE_TX); /* 开启session end, reset、resume、suspend中断 */ USBC_INT_EnableUsbMiscUint(udc.bsp, USBC_BP_INTUSB_SOF); USBC_INT_EnableUsbMiscUint(udc.bsp, USBC_BP_INTUSB_SUSPEND); USBC_INT_EnableUsbMiscUint(udc.bsp, USBC_BP_INTUSB_RESUME); USBC_INT_EnableUsbMiscUint(udc.bsp, USBC_BP_INTUSB_RESET); USBC_INT_EnableUsbMiscUint(udc.bsp, USBC_BP_INTUSB_DISCONNECT); /* enbale ep0_tx_irq */ USBC_INT_EnableEp(udc.bsp, USBC_EP_TYPE_TX, 0); fastboot_bulk_endpoint_reset(); // USBC_PrintAllReg(udc.usb_base, 0, 5, "fastboot_reset", printf); USBC_Dev_ConectSwitch(udc.bsp, USBC_DEVICE_SWITCH_ON); return; }
/* ******************************************************************************* * sw_udc_bsp_exit * * Description: * void * * Parameters: * void * * Return value: * void * * note: * void * ******************************************************************************* */ __s32 sw_udc_bsp_exit(__u32 usbc_no, sw_udc_io_t *sw_udc_io) { USBC_DisableDpDmPullUp(sw_udc_io->usb_bsp_hdle); USBC_DisableIdPullUp(sw_udc_io->usb_bsp_hdle); USBC_ForceId(sw_udc_io->usb_bsp_hdle, USBC_ID_TYPE_DISABLE); USBC_ForceVbusValid(sw_udc_io->usb_bsp_hdle, USBC_VBUS_TYPE_DISABLE); USBC_close_otg(sw_udc_io->usb_bsp_hdle); sw_udc_io->usb_bsp_hdle = 0; // USBC_exit(&sw_udc_io->usbc); return 0; }
/* ******************************************************************************* * sw_udc_bsp_init * * Description: * initialize usb bsp * * Parameters: * void * * Return value: * void * * note: * void * ******************************************************************************* */ __s32 sw_udc_bsp_init(__u32 usbc_no, sw_udc_io_t *sw_udc_io) { sw_udc_io->usbc.usbc_info[usbc_no].num = usbc_no; sw_udc_io->usbc.usbc_info[usbc_no].base = (u32)sw_udc_io->usb_vbase; sw_udc_io->usbc.sram_base = (u32)sw_udc_io->sram_vbase; // USBC_init(&sw_udc_io->usbc); sw_udc_io->usb_bsp_hdle = USBC_open_otg(usbc_no); if(sw_udc_io->usb_bsp_hdle == 0){ DMSG_PANIC("ERR: sw_udc_init: USBC_open_otg failed\n"); return -1; } USBC_EnhanceSignal(sw_udc_io->usb_bsp_hdle); USBC_EnableDpDmPullUp(sw_udc_io->usb_bsp_hdle); USBC_EnableIdPullUp(sw_udc_io->usb_bsp_hdle); USBC_ForceId(sw_udc_io->usb_bsp_hdle, USBC_ID_TYPE_DEVICE); USBC_ForceVbusValid(sw_udc_io->usb_bsp_hdle, USBC_VBUS_TYPE_HIGH); USBC_SelectBus(sw_udc_io->usb_bsp_hdle, USBC_IO_TYPE_PIO, 0, 0); return 0; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : usb初始化动作,完成后,即可开启中断后,使用中断处理程序 * * ************************************************************************************************************ */ int sunxi_usb_init(int delaytime) { sunxi_dma_setting_t usb_send_by_dma; sunxi_dma_setting_t usb_recv_by_dma; if(sunxi_udev_active->state_init()) { printf("sunxi usb err: fail to init usb device\n"); return -1; } //预先关闭usb中断 irq_disable(AW_IRQ_USB_OTG); //初始化 sunxi_udc用到的资源 memset(&sunxi_udc_source, 0, sizeof(sunxi_udc_t)); //获取控制器地址资源 sunxi_udc_source.usbc_hd = USBC_open_otg(0); if(sunxi_udc_source.usbc_hd == 0) { printf("sunxi usb err : USBC_open_otg failed\n"); return -1; } //断开usb USBC_Dev_ConectSwitch(sunxi_udc_source.usbc_hd, USBC_DEVICE_SWITCH_OFF); //预先关闭usb时钟 usb_close_clock(); //延时 delaytime ms printf("delay time %d\n", delaytime); __msdelay(delaytime); //申请DMA资源 sunxi_udc_source.dma_send_channal = sunxi_dma_request(0); if(!sunxi_udc_source.dma_send_channal) { printf("sunxi usb err : unable to request dma for usb send data\n"); goto __sunxi_usb_init_fail; } sunxi_udc_source.dma_recv_channal = sunxi_dma_request(0); if(!sunxi_udc_source.dma_recv_channal) { printf("sunxi usb err : unable to request dma for usb receive data\n"); goto __sunxi_usb_init_fail; } //配置dma资源 usb_recv_by_dma.loop_mode = 0; usb_recv_by_dma.wait_cyc = 8; usb_recv_by_dma.data_block_size = 1 * 32/8; //config recv(from usb fifo to dram) usb_recv_by_dma.cfg.src_drq_type = DMAC_CFG_SRC_TYPE_OTG_EP2; //OTG EP2 usb_recv_by_dma.cfg.src_addr_mode = DMAC_CFG_SRC_ADDR_TYPE_IO_MODE; usb_recv_by_dma.cfg.src_burst_length = DMAC_CFG_SRC_1_BURST; usb_recv_by_dma.cfg.src_data_width = DMAC_CFG_SRC_DATA_WIDTH_32BIT; usb_recv_by_dma.cfg.reserved0 = 0; usb_recv_by_dma.cfg.dst_drq_type = DMAC_CFG_DEST_TYPE_DRAM; //DRAM usb_recv_by_dma.cfg.dst_addr_mode = DMAC_CFG_DEST_ADDR_TYPE_LINEAR_MODE; usb_recv_by_dma.cfg.dst_burst_length = DMAC_CFG_DEST_1_BURST; usb_recv_by_dma.cfg.dst_data_width = DMAC_CFG_DEST_DATA_WIDTH_32BIT; usb_recv_by_dma.cfg.reserved1 = 0; //注册dma中断函数 sunxi_usb_dbg("install dma isr\n"); sunxi_dma_install_int(sunxi_udc_source.dma_recv_channal, __usb_recv_by_dma_isr, 0); //sunxi_dma_install_int(sunxi_udc_source.dma_recv_channal, __usb_recv_by_dma_isr, 0); //使能dma中断 sunxi_usb_dbg("enable dma isr\n"); sunxi_dma_enable_int(sunxi_udc_source.dma_recv_channal); //配置dma资源 usb_send_by_dma.loop_mode = 0; usb_send_by_dma.wait_cyc = 8; usb_send_by_dma.data_block_size = 1 * 32/8; //usb_send_by_dma. //config send(from dram to usb fifo) usb_send_by_dma.cfg.src_drq_type = DMAC_CFG_SRC_TYPE_DRAM; //OTG, EP2 usb_send_by_dma.cfg.src_addr_mode = DMAC_CFG_SRC_ADDR_TYPE_LINEAR_MODE; usb_send_by_dma.cfg.src_burst_length = DMAC_CFG_SRC_1_BURST; usb_send_by_dma.cfg.src_data_width = DMAC_CFG_SRC_DATA_WIDTH_32BIT; usb_send_by_dma.cfg.reserved0 = 0; usb_send_by_dma.cfg.dst_drq_type = DMAC_CFG_DEST_TYPE_OTG_EP1; //OTG EP1 usb_send_by_dma.cfg.dst_addr_mode = DMAC_CFG_DEST_ADDR_TYPE_IO_MODE; usb_send_by_dma.cfg.dst_burst_length = DMAC_CFG_DEST_1_BURST; usb_send_by_dma.cfg.dst_data_width = DMAC_CFG_DEST_DATA_WIDTH_32BIT; usb_send_by_dma.cfg.reserved1 = 0; sunxi_dma_setting(sunxi_udc_source.dma_recv_channal, &usb_recv_by_dma); sunxi_dma_setting(sunxi_udc_source.dma_send_channal, &usb_send_by_dma); //假定usb运行在高速模式下 sunxi_udc_source.address = 0; sunxi_udc_source.speed = USB_SPEED_HIGH; sunxi_udc_source.bulk_ep_max = HIGH_SPEED_EP_MAX_PACKET_SIZE; sunxi_udc_source.fifo_size = BULK_FIFOSIZE; sunxi_udc_source.bulk_in_addr = 100; sunxi_udc_source.bulk_out_addr = sunxi_udc_source.bulk_in_addr + sunxi_udc_source.fifo_size * 2; memset(&sunxi_ubuf, 0, sizeof(sunxi_ubuf_t)); sunxi_ubuf.rx_base_buffer = (uchar *)malloc(1024); if(!sunxi_ubuf.rx_base_buffer) { printf("sunxi usb err: fail to malloc memory for rx command buffer\n"); goto __sunxi_usb_init_fail; } sunxi_ubuf.rx_req_buffer = sunxi_ubuf.rx_base_buffer; usb_open_clock(); //设置为device模式 USBC_ForceId(sunxi_udc_source.usbc_hd, USBC_ID_TYPE_DEVICE); //设置VBUS为高 USBC_ForceVbusValid(sunxi_udc_source.usbc_hd, USBC_VBUS_TYPE_HIGH); USBC_Dev_ConectSwitch(sunxi_udc_source.usbc_hd, USBC_DEVICE_SWITCH_OFF); //soft connect USBC_EnableDpDmPullUp(sunxi_udc_source.usbc_hd); USBC_EnableIdPullUp(sunxi_udc_source.usbc_hd); //选择使用PIO模式搬移数据 USBC_SelectBus(sunxi_udc_source.usbc_hd, USBC_IO_TYPE_PIO, 0, 0); //映射SRAM buffer USBC_ConfigFIFO_Base(sunxi_udc_source.usbc_hd, 0, 0); // USBC_EnhanceSignal(sunxi_udc_source.usbc_hd); //默认采用高速模式传输 #ifdef CONFIG_USB_1_1_DEVICE USBC_Dev_ConfigTransferMode(sunxi_udc_source.usbc_hd, USBC_TS_TYPE_BULK, USBC_TS_MODE_FS); #else USBC_Dev_ConfigTransferMode(sunxi_udc_source.usbc_hd, USBC_TS_TYPE_BULK, USBC_TS_MODE_HS); #endif /* disable all interrupt */ USBC_INT_DisableUsbMiscAll(sunxi_udc_source.usbc_hd); USBC_INT_DisableEpAll(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX); USBC_INT_DisableEpAll(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_TX); /* 开启 reset、resume、suspend中断 */ USBC_INT_EnableUsbMiscUint(sunxi_udc_source.usbc_hd, USBC_INTUSB_SUSPEND | USBC_INTUSB_RESUME \ | USBC_INTUSB_RESET); /* enbale ep0_tx_irq */ USBC_INT_EnableEp(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_TX, SUNXI_USB_CTRL_EP_INDEX); __usb_bulk_ep_reset(); USBC_Dev_ConectSwitch(sunxi_udc_source.usbc_hd, USBC_DEVICE_SWITCH_ON); irq_install_handler(AW_IRQ_USB_OTG, sunxi_usb_irq, NULL); irq_enable(AW_IRQ_USB_OTG); return 0; __sunxi_usb_init_fail: if(sunxi_udc_source.usbc_hd) { USBC_close_otg(sunxi_udc_source.usbc_hd); } if(sunxi_udc_source.dma_send_channal) { sunxi_dma_release(sunxi_udc_source.dma_send_channal); } if(sunxi_udc_source.dma_recv_channal) { sunxi_dma_release(sunxi_udc_source.dma_recv_channal); } if(sunxi_ubuf.rx_base_buffer) { free(sunxi_ubuf.rx_base_buffer); } return -1; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : usb初始化动作,完成后,即可开启中断后,使用中断处理程序 * * ************************************************************************************************************ */ int sunxi_usb_init(int delaytime) { if(sunxi_udev_active->state_init()) { printf("sunxi usb err: fail to init usb device\n"); return -1; } //预先关闭usb中断 irq_disable(AW_IRQ_USB_OTG); //初始化 sunxi_udc用到的资源 memset(&sunxi_udc_source, 0, sizeof(sunxi_udc_t)); //获取控制器地址资源 sunxi_udc_source.usbc_hd = USBC_open_otg(0); if(sunxi_udc_source.usbc_hd == 0) { printf("sunxi usb err : USBC_open_otg failed\n"); return -1; } usb_dma_init(sunxi_udc_source.usbc_hd); //断开usb USBC_Dev_ConectSwitch(sunxi_udc_source.usbc_hd, USBC_DEVICE_SWITCH_OFF); //预先关闭usb时钟 usb_close_clock(); //延时 delaytime ms printf("delay time %d\n", delaytime); __msdelay(delaytime); //申请DMA资源 sunxi_udc_source.dma_send_channal = usb_dma_request(); if(!sunxi_udc_source.dma_send_channal) { printf("sunxi usb err : unable to request dma for usb send data\n"); goto __sunxi_usb_init_fail; } sunxi_usb_dbg("dma send ch %d\n", sunxi_udc_source.dma_send_channal); sunxi_udc_source.dma_recv_channal = usb_dma_request(); if(!sunxi_udc_source.dma_recv_channal) { printf("sunxi usb err : unable to request dma for usb receive data\n"); goto __sunxi_usb_init_fail; } sunxi_usb_dbg("dma recv ch %d\n", sunxi_udc_source.dma_recv_channal); sunxi_udc_source.address = 0; sunxi_udc_source.speed = USB_SPEED_HIGH; sunxi_udc_source.bulk_ep_max = HIGH_SPEED_EP_MAX_PACKET_SIZE; sunxi_udc_source.fifo_size = BULK_FIFOSIZE; sunxi_udc_source.bulk_in_addr = 100; sunxi_udc_source.bulk_out_addr = sunxi_udc_source.bulk_in_addr + sunxi_udc_source.fifo_size * 2; //内存资源 memset(&sunxi_ubuf, 0, sizeof(sunxi_ubuf_t)); sunxi_ubuf.rx_base_buffer = (uchar *)malloc(1024); if(!sunxi_ubuf.rx_base_buffer) { printf("sunxi usb err: fail to malloc memory for rx command buffer\n"); goto __sunxi_usb_init_fail; } sunxi_ubuf.rx_req_buffer = sunxi_ubuf.rx_base_buffer; usb_open_clock(); //设置为device模式 USBC_ForceId(sunxi_udc_source.usbc_hd, USBC_ID_TYPE_DEVICE); //设置VBUS为高 USBC_ForceVbusValid(sunxi_udc_source.usbc_hd, USBC_VBUS_TYPE_HIGH); USBC_Dev_ConectSwitch(sunxi_udc_source.usbc_hd, USBC_DEVICE_SWITCH_OFF); //soft connect USBC_EnableDpDmPullUp(sunxi_udc_source.usbc_hd); USBC_EnableIdPullUp(sunxi_udc_source.usbc_hd); //选择使用PIO模式搬移数据 USBC_SelectBus(sunxi_udc_source.usbc_hd, USBC_IO_TYPE_PIO, 0, 0); //映射SRAM buffer USBC_ConfigFIFO_Base(sunxi_udc_source.usbc_hd, 0, 0); // USBC_EnhanceSignal(sunxi_udc_source.usbc_hd); //默认采用高速模式传输 #ifdef CONFIG_USB_1_1_DEVICE USBC_Dev_ConfigTransferMode(sunxi_udc_source.usbc_hd, USBC_TS_TYPE_BULK, USBC_TS_MODE_FS); #else USBC_Dev_ConfigTransferMode(sunxi_udc_source.usbc_hd, USBC_TS_TYPE_BULK, USBC_TS_MODE_HS); #endif //配置发送端dma资源 usb_dma_setting(sunxi_udc_source.dma_send_channal, USB_DMA_FROM_DRAM_TO_HOST, SUNXI_USB_BULK_IN_EP_INDEX); usb_dma_set_pktlen(sunxi_udc_source.dma_send_channal, HIGH_SPEED_EP_MAX_PACKET_SIZE); //配置接收端dma资源 usb_dma_setting(sunxi_udc_source.dma_recv_channal, USB_DMA_FROM_HOST_TO_DRAM, SUNXI_USB_BULK_OUT_EP_INDEX); usb_dma_set_pktlen(sunxi_udc_source.dma_recv_channal, HIGH_SPEED_EP_MAX_PACKET_SIZE); /* disable all interrupt */ USBC_INT_DisableUsbMiscAll(sunxi_udc_source.usbc_hd); USBC_INT_DisableEpAll(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX); USBC_INT_DisableEpAll(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_TX); /* 开启 reset、resume、suspend中断 */ USBC_INT_EnableUsbMiscUint(sunxi_udc_source.usbc_hd, USBC_INTUSB_SUSPEND | USBC_INTUSB_RESUME \ | USBC_INTUSB_RESET | USBC_INTUSB_SOF); /* enbale ep0_tx_irq */ USBC_INT_EnableEp(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_TX, SUNXI_USB_CTRL_EP_INDEX); __usb_bulk_ep_reset(); USBC_Dev_ConectSwitch(sunxi_udc_source.usbc_hd, USBC_DEVICE_SWITCH_ON); irq_install_handler(AW_IRQ_USB_OTG, sunxi_usb_irq, NULL); irq_enable(AW_IRQ_USB_OTG); return 0; __sunxi_usb_init_fail: if(sunxi_udc_source.dma_send_channal) { usb_dma_release(sunxi_udc_source.dma_send_channal); } if(sunxi_udc_source.dma_recv_channal) { usb_dma_release(sunxi_udc_source.dma_recv_channal); } if(sunxi_udc_source.usbc_hd) { USBC_close_otg(sunxi_udc_source.usbc_hd); } if(sunxi_ubuf.rx_base_buffer) { free(sunxi_ubuf.rx_base_buffer); } return -1; }