Correctly implementing recommended workarounds for erratas USB4 and USB10.
This commit is contained in:
		| @@ -94,10 +94,6 @@ static void bus_reset(void) | ||||
|   USBOEPCNT_0 &= ~NAK; | ||||
|   USBIEPCNT_0 &= ~NAK; | ||||
|  | ||||
|   // Disable (subsequent) bus reset events from causing a functional | ||||
|   // reset of the USB module. | ||||
|   USBCTL &= ~FRSTE; | ||||
|  | ||||
|   // Enable responding to packets. | ||||
|   USBCTL |= FEN; | ||||
|  | ||||
| @@ -108,6 +104,28 @@ static void bus_reset(void) | ||||
|   USBKEYPID = 0; | ||||
| } | ||||
|  | ||||
| // Controls reset behavior of the USB module on receipt of a bus reset event. | ||||
| // - enable: When true, bus reset events will cause a reset the USB module. | ||||
| static void enable_functional_reset(const bool enable) | ||||
| { | ||||
|   // Check whether or not the USB configuration registers were | ||||
|   // locked prior to this function being called so that, if | ||||
|   // necessary, the lock state can be restored on exit. | ||||
|   bool unlocked = (USBKEYPID == 0xA528) ? true : false; | ||||
|  | ||||
|   if(!unlocked) USBKEYPID = USBKEY; | ||||
|  | ||||
|   if(enable) | ||||
|   { | ||||
|     USBCTL |= FRSTE; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     USBCTL &= ~FRSTE; | ||||
|   } | ||||
|  | ||||
|   if(!unlocked) USBKEYPID = 0; | ||||
| } | ||||
|  | ||||
| /*------------------------------------------------------------------*/ | ||||
| /* Controller API | ||||
| @@ -339,10 +357,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t | ||||
|  | ||||
|   if(epnum == 0) | ||||
|   { | ||||
|     // Enables a bus reset to cause a functional reset of the USB | ||||
|     // module. | ||||
|     USBCTL |= FRSTE; | ||||
|  | ||||
|     if(dir == TUSB_DIR_OUT) | ||||
|     { | ||||
|       // Interrupt will notify us when data was received. | ||||
| @@ -638,7 +652,11 @@ static void handle_setup_packet(void) | ||||
|   // | ||||
|   // "...the SETUPIFG is cleared upon reading USBIV. In addition, the NAK on | ||||
|   // input endpoint 0 and output endpoint 0 is also cleared." | ||||
|   USBIEPCNF_0 &= ~UBME; // Errata USB10 workaround. | ||||
|   USBOEPCNF_0 &= ~UBME; // Errata USB10 workaround. | ||||
|   USBIFG &= ~SETUPIFG; | ||||
|   USBIEPCNF_0 |= UBME;  // Errata USB10 workaround. | ||||
|   USBOEPCNF_0 |= UBME;  // Errata USB10 workaround. | ||||
|   dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); | ||||
| } | ||||
|  | ||||
| @@ -661,7 +679,7 @@ static void handle_bus_power_event(void *param) | ||||
|  | ||||
|     uint16_t attempts = 0; | ||||
|  | ||||
|     do                                // Poll the PLL to check for a successful lock. | ||||
|     do                                // Poll the PLL, checking for a successful lock. | ||||
|     { | ||||
|       USBPLLIR = 0; | ||||
|       osal_task_delay(1); | ||||
| @@ -694,6 +712,7 @@ void dcd_int_handler(uint8_t rhport) | ||||
|  | ||||
|   if(setup_status) | ||||
|   { | ||||
|     enable_functional_reset(true); | ||||
|     handle_setup_packet(); | ||||
|   } | ||||
|  | ||||
| @@ -716,6 +735,7 @@ void dcd_int_handler(uint8_t rhport) | ||||
|       break; | ||||
|  | ||||
|     case USBVECINT_RSTR: | ||||
|       enable_functional_reset(false); // Errata USB4 workaround. | ||||
|       bus_reset(); | ||||
|       dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); | ||||
|       break; | ||||
| @@ -762,10 +782,12 @@ void dcd_int_handler(uint8_t rhport) | ||||
|       break; | ||||
|  | ||||
|     case USBVECINT_INPUT_ENDPOINT0: | ||||
|       enable_functional_reset(true); | ||||
|       transmit_packet(0); | ||||
|       break; | ||||
|  | ||||
|     case USBVECINT_OUTPUT_ENDPOINT0: | ||||
|       enable_functional_reset(true); | ||||
|       receive_packet(0); | ||||
|       break; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Clifroy Henry
					Clifroy Henry