/* * device_soft_rst.c * * Created on: 21-Apr-2023 * Author: pushpkant */ #include "device_soft_rst.h" int device_power_on_soft_rst(void) { /* * DCTL Default value taken from hardware */ DCTL_data *dctl = dctl_setup(); /* * LPM NYET Response Threshold. */ dctl->LPM_NYET_thres = 0xf; /* * This bit clears the interrupts and all the CSRs except GSTS, GSNPSID, * GGPIO, GUID, GUSB2PHYCFGn registers, GUSB3PIPECTLn registers, DCFG, * DCTL, DEVTEN, and DSTS registers. */ dctl->CSFTRST = 1; if(dctl_write() != 0) { return -12; } if(dctl_read()!=0) { return -16; } // int count = RETRY_COUNT; /* * Wait until the hardware pull dctl.CSFTRST down. * This resets the device controller. */ while(dctl->CSFTRST != 0) { /** @todo FPGA team to provide delay values for this.*/ // rv_delay_us(1000); dctl_read(); // if(!(count--)) // { // return -1; // } } /* * Global Event Buffer Address (Low) Register. Holds the lower 32 bits of * start address of the external memory for the Event Buffer. * During operation, hardware does not update this address. * Global Event Buffer Address (High) Register.Holds the higher 32 bits of * start address of the external memory for the Event Buffer. * During operation, hardware does not update this address. */ uint64_t evnt_address = EVENT_FIFO_ADDR_USB23; uint32_t dev_number = 0; //this number is zero in device mode if(gevntadr_init(dev_number, evnt_address) != 0) { return -2; } if(gevntadr_get(dev_number, &evnt_address) != 0) { return -3; } if(evnt_address != EVENT_FIFO_ADDR_USB23) { return -4; } /* * Event Buffer Size in bytes (EVNTSiz) Holds the size of the Event Buffer * in bytes must be a multiple of four. * This is programmed by software once during initialization. * The minimum size of the event buffer is 32 bytes */ uint32_t event_size = EVENT_FIFO_SIZE; uint32_t gevntsiz_dev_number = 0; uint32_t event_intr_mask = 0; //interrupt is enabled if(gevntsiz_init(gevntsiz_dev_number, event_size, event_intr_mask) != 0) { return -5; } if(gevntsiz_get(gevntsiz_dev_number,&event_size,&event_intr_mask) != 0) { return -6; } if(event_size != EVENT_FIFO_SIZE) { return -7; } /* * This register holds the number of valid bytes in the Event Buffer */ uint32_t event_count = 0x0; uint32_t gevntcount_dev_number = 0; uint32_t event_hndlr_busy = 0; if(gevntcount_init(gevntcount_dev_number, event_count,event_hndlr_busy) != 0) { return -8; } if(gevntcount_get(gevntcount_dev_number, &event_count,&event_hndlr_busy) != 0) { return -9; } if(event_count != 0) { return -10; } /* * Simulation Speed Up Factor. Program this register (GCTL) to * override scaledown. */ GCTL_data *gctl = gctl_setup(); /* * Table 1-17, Link waits for 8us of LFPS before it detects a valid * U2 Exit. */ gctl->U2EXIT_LFPS = 0x1; /* * Table 1-17, * Port capability direction for device configuration. */ gctl->PRTCAPDIR = 0x2; /* * Table 1-17 * If this bit is set, then device attempts three more times to * connect at SS, even if it previously failed to operate in SS * mode. For each attempt, the device checks receiver * termination eight times. */ gctl->U2RSTECN = 0x1; /* * Table 1-17, * More info from PWERDNSCALE from the document. */ gctl->PWRDNSCALE = 0x0618; if(SIM_EN) { /* * Table 1-17, Enables scale-down of all timing values except * Device mode suspend and resume. These include Speed * enumeration, HNP/SRP, and Host mode suspend and * resume. */ gctl->SCALEDOWN = 0x01; } else { gctl->SCALEDOWN = 0x0; } if(gctl_write() != 0) { return -11; } /* * Program device speed [2:0] bits and periodic frame interval * DCFG.DEVSPD=3'b000: High-speed * DCFG.DEVSPD=3'b001: Full-speed * DCFG.DEVSPD=3'b100: Super-speed */ DCFG_data *dcfg = dcfg_setup(); dcfg ->DEVSPD = (USB_SPEED & 0x7); /**@todo why reserved bit are set, ask FPGA team.*/ dcfg ->reserved_11_10 = 0x2; /* * Refer Table number 1-78 for more information. */ dcfg ->NUMP = 0x4; if(dcfg_write() != 0) { return -13; } /* * At a minimum, enable USB Reset, Connection Done, * and USB/Link State Change events (DEVTEN) */ DEVTEN_data *devten = devten_setup(); devten ->DISSCONNEVTEN = 0x1; devten ->USBRSTEVTEN = 0x1; devten ->CONNECTDONEEVTEN = 0x1; devten->ULSTCNGEN = 0x1; if(devten_write() != 0) { return -14; } if(DEPSTARTCFG_cmd(0x0) != 0) { return -15; } DEPCFG_Par1 DEPCFG_Par1_EP0 = {0}; DEPCFG_Par1_EP0.event_enable_mask = 0x5; DEPCFG_Par0 DEPCFG_Par0_EP0 = {0}; DEPCFG_Par0_EP0.maximum_packet_size = 0x040; if(DEPCFG_cmd(0x0, 0x00000000,&DEPCFG_Par1_EP0,&DEPCFG_Par0_EP0)!=0) { return -19; } DEPCFG_Par1 DEPCFG_Par1_EP1 = {0}; DEPCFG_Par1_EP1.USB_ep_dir = 0x1; DEPCFG_Par1_EP1.event_enable_mask = 0x5; DEPCFG_Par0 DEPCFG_Par0_EP1 = {0}; DEPCFG_Par0_EP1.maximum_packet_size = 0x40; if(DEPCFG_cmd(0x1, 0x00000000,&DEPCFG_Par1_EP1,&DEPCFG_Par0_EP1) != 0) { return -20; } if(DEPXFERCFG_cmd(0x0) != 0) { return -21; } if(DEPXFERCFG_cmd(0x1) != 0) { return -22; } /* * Prepare a buffer for a setup packet, initialize a setup TRB. */ if(TRB_control_setup() != 0) { return -23; } /* * Write DALEPENA.Enable physical endpoints 0 & 1 by writing 0x3 to * this register. */ DALEPENA_data *dalepena_data = dalepena_setup(); dalepena_data ->USBACTEP = 0x00000003; if(dalepena_write()!=0) { return -17; } /* * Write DCTL.Set DCTL.RunStop to ‘1’ to allow the device to attach * to the host. */ DCTL_data *dctl_data = dctl_setup(); dctl_data->LPM_NYET_thres = 0xf; dctl_data->RUN_STOP = 0x1; if(dctl_write()!=0) { return -18; } return 0; }