Reverted Endpoint/Pipe non-sequential configuration hack, placed restriction on the configuration order instead to ensure maximum reliability.
Altered all low level device and host mode demos to ensure that endpoints and pipes are configured in ascending order properly. Rewrote all low level host mode demos' configuration descriptor parser code to ensure that pipes are enumerated in ascending order, and to ensure maximum compatibility with devices. Incremented all device mode demo's device descriptor revision numbers to ensure that any descriptor changes are re-fetched on machines which have enumerated previous versions.
This commit is contained in:
		
							parent
							
								
									a509729b2d
								
							
						
					
					
						commit
						158afe9109
					
				
					 106 changed files with 838 additions and 796 deletions
				
			
		| 
						 | 
				
			
			@ -43,8 +43,7 @@ bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
 | 
			
		|||
                                    const uint8_t UECFG0XData,
 | 
			
		||||
                                    const uint8_t UECFG1XData)
 | 
			
		||||
{
 | 
			
		||||
#if defined(CONTROL_ONLY_DEVICE)
 | 
			
		||||
	Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
 | 
			
		||||
	Endpoint_SelectEndpoint(Number);
 | 
			
		||||
	Endpoint_EnableEndpoint();
 | 
			
		||||
 | 
			
		||||
	UECFG1X = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -52,51 +51,6 @@ bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number,
 | 
			
		|||
	UECFG1X = UECFG1XData;
 | 
			
		||||
 | 
			
		||||
	return Endpoint_IsConfigured();
 | 
			
		||||
#else
 | 
			
		||||
	uint8_t UECFG0XTemp[ENDPOINT_TOTAL_ENDPOINTS];
 | 
			
		||||
	uint8_t UECFG1XTemp[ENDPOINT_TOTAL_ENDPOINTS];
 | 
			
		||||
	uint8_t UEIENXTemp[ENDPOINT_TOTAL_ENDPOINTS];
 | 
			
		||||
	
 | 
			
		||||
	for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
 | 
			
		||||
	{
 | 
			
		||||
		Endpoint_SelectEndpoint(EPNum);
 | 
			
		||||
		UECFG0XTemp[EPNum] = UECFG0X;
 | 
			
		||||
		UECFG1XTemp[EPNum] = UECFG1X;
 | 
			
		||||
		UEIENXTemp[EPNum]  = UEIENX;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	UECFG0XTemp[Number] = UECFG0XData;
 | 
			
		||||
	UECFG1XTemp[Number] = UECFG1XData;
 | 
			
		||||
	UEIENXTemp[Number]  = 0;
 | 
			
		||||
	
 | 
			
		||||
	for (uint8_t EPNum = 1; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
 | 
			
		||||
	{
 | 
			
		||||
		Endpoint_SelectEndpoint(EPNum);	
 | 
			
		||||
		UEIENX  = 0;
 | 
			
		||||
		UEINTX  = 0;
 | 
			
		||||
		UECFG1X = 0;
 | 
			
		||||
		Endpoint_DisableEndpoint();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++)
 | 
			
		||||
	{
 | 
			
		||||
		if (!(UECFG1XTemp[EPNum] & (1 << ALLOC)))
 | 
			
		||||
		  continue;
 | 
			
		||||
		
 | 
			
		||||
		Endpoint_SelectEndpoint(EPNum);		
 | 
			
		||||
		Endpoint_EnableEndpoint();
 | 
			
		||||
 | 
			
		||||
		UECFG0X = UECFG0XTemp[EPNum];
 | 
			
		||||
		UECFG1X = UECFG1XTemp[EPNum];
 | 
			
		||||
		UEIENX  = UEIENXTemp[EPNum];
 | 
			
		||||
		
 | 
			
		||||
		if (!(Endpoint_IsConfigured()))
 | 
			
		||||
		  return false;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	Endpoint_SelectEndpoint(Number);
 | 
			
		||||
	return true;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Endpoint_ClearEndpoints(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -267,6 +267,9 @@
 | 
			
		|||
			 *                        More banks uses more USB DPRAM, but offers better performance. Isochronous type
 | 
			
		||||
			 *                        endpoints <b>must</b> have at least two banks.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note Endpoints <b>must</b> be configured in ascending order, or bank corruption will occur.
 | 
			
		||||
			 *        \n\n
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note Certain models of USB AVR's endpoints may have different maximum packet sizes based on the endpoint's
 | 
			
		||||
			 *        index - refer to the chosen USB AVR's datasheet to determine the maximum bank size for each endpoint.
 | 
			
		||||
			 *        \n\n
 | 
			
		||||
| 
						 | 
				
			
			@ -442,7 +445,7 @@
 | 
			
		|||
				return ((UEINT & (1 << EndpointNumber)) ? true : false);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			/** Determines if the selected IN endpoint is ready for a new packet.
 | 
			
		||||
			/** Determines if the selected IN endpoint is ready for a new packet to be sent to the host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \ingroup Group_EndpointPacketManagement
 | 
			
		||||
			 *
 | 
			
		||||
| 
						 | 
				
			
			@ -454,7 +457,7 @@
 | 
			
		|||
				return ((UEINTX & (1 << TXINI)) ? true : false);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			/** Determines if the selected OUT endpoint has received new packet.
 | 
			
		||||
			/** Determines if the selected OUT endpoint has received new packet from the host.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \ingroup Group_EndpointPacketManagement
 | 
			
		||||
			 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,61 +44,17 @@ bool Pipe_ConfigurePipe(const uint8_t Number,
 | 
			
		|||
                        const uint16_t Size,
 | 
			
		||||
                        const uint8_t Banks)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t UPCFG0XTemp[PIPE_TOTAL_PIPES];
 | 
			
		||||
	uint8_t UPCFG1XTemp[PIPE_TOTAL_PIPES];
 | 
			
		||||
	uint8_t UPCFG2XTemp[PIPE_TOTAL_PIPES];
 | 
			
		||||
	uint8_t UPCONXTemp[PIPE_TOTAL_PIPES];
 | 
			
		||||
	uint8_t UPINRQXTemp[PIPE_TOTAL_PIPES];
 | 
			
		||||
	uint8_t UPIENXTemp[PIPE_TOTAL_PIPES];
 | 
			
		||||
	
 | 
			
		||||
	for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
 | 
			
		||||
	{
 | 
			
		||||
		Pipe_SelectPipe(PNum);
 | 
			
		||||
		UPCFG0XTemp[PNum] = UPCFG0X;
 | 
			
		||||
		UPCFG1XTemp[PNum] = UPCFG1X;
 | 
			
		||||
		UPCFG2XTemp[PNum] = UPCFG2X;
 | 
			
		||||
		UPCONXTemp[PNum]  = UPCONX;
 | 
			
		||||
		UPINRQXTemp[PNum] = UPINRQX;
 | 
			
		||||
		UPIENXTemp[PNum]  = UPIENX;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	UPCFG0XTemp[Number] = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
 | 
			
		||||
	UPCFG1XTemp[Number] = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
 | 
			
		||||
	UPCFG2XTemp[Number] = 0;
 | 
			
		||||
	UPCONXTemp[Number]  = (1 << INMODE);
 | 
			
		||||
	UPINRQXTemp[Number] = 0;
 | 
			
		||||
	UPIENXTemp[Number]  = 0;
 | 
			
		||||
	
 | 
			
		||||
	for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
 | 
			
		||||
	{
 | 
			
		||||
		Pipe_SelectPipe(PNum);
 | 
			
		||||
		UPIENX  = 0;
 | 
			
		||||
		UPINTX  = 0;
 | 
			
		||||
		UPCFG1X = 0;
 | 
			
		||||
		Pipe_DisablePipe();
 | 
			
		||||
	}
 | 
			
		||||
	Pipe_SelectPipe(Number);
 | 
			
		||||
	Pipe_EnablePipe();
 | 
			
		||||
 | 
			
		||||
	for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++)
 | 
			
		||||
	{
 | 
			
		||||
		if (!(UPCFG1XTemp[PNum] & (1 << ALLOC)))
 | 
			
		||||
		  continue;
 | 
			
		||||
		
 | 
			
		||||
		Pipe_SelectPipe(PNum);		
 | 
			
		||||
		Pipe_EnablePipe();
 | 
			
		||||
	UPCFG1X = 0;
 | 
			
		||||
	
 | 
			
		||||
	UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointNumber & PIPE_EPNUM_MASK) << PEPNUM0));
 | 
			
		||||
	UPCFG1X = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size));
 | 
			
		||||
 | 
			
		||||
		UPCFG0X  = UPCFG0XTemp[PNum];
 | 
			
		||||
		UPCFG1X  = UPCFG1XTemp[PNum];
 | 
			
		||||
		UPCFG2X  = UPCFG2XTemp[PNum];
 | 
			
		||||
		UPCONX  |= UPCONXTemp[PNum];
 | 
			
		||||
		UPINRQX  = UPINRQXTemp[PNum];
 | 
			
		||||
		UPIENX   = UPIENXTemp[PNum];
 | 
			
		||||
	Pipe_SetInfiniteINRequests();
 | 
			
		||||
 | 
			
		||||
		if (!(Pipe_IsConfigured()))
 | 
			
		||||
		  return false;
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	Pipe_SelectPipe(Number);	
 | 
			
		||||
	return true;
 | 
			
		||||
	return Pipe_IsConfigured();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Pipe_ClearPipes(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -462,7 +462,7 @@
 | 
			
		|||
				return ((UPINTX & (1 << RWAL)) ? true : false);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			/** Determines if an IN request has been received on the currently selected pipe.
 | 
			
		||||
			/** Determines if a packet has been received on the currently selected IN pipe from the attached device.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \ingroup Group_PipePacketManagement
 | 
			
		||||
			 *
 | 
			
		||||
| 
						 | 
				
			
			@ -474,7 +474,7 @@
 | 
			
		|||
				return ((UPINTX & (1 << RXINI)) ? true : false);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			/** Determines if the currently selected pipe is ready to send an OUT request.
 | 
			
		||||
			/** Determines if the currently selected OUT pipe is ready to send an OUT packet to the attached device.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \ingroup Group_PipePacketManagement
 | 
			
		||||
			 *
 | 
			
		||||
| 
						 | 
				
			
			@ -839,6 +839,9 @@
 | 
			
		|||
			 *                             uses more USB DPRAM, but offers better performance. Isochronous type pipes <b>must</b>
 | 
			
		||||
			 *                             have at least two banks.
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note Endpoints <b>must</b> be configured in ascending order, or bank corruption will occur.
 | 
			
		||||
			 *        \n\n
 | 
			
		||||
			 *
 | 
			
		||||
			 *  \note Certain models of USB AVR's pipes may have different maximum packet sizes based on the pipe's
 | 
			
		||||
			 *        index - refer to the chosen USB AVR's datasheet to determine the maximum bank size for each pipe.
 | 
			
		||||
			 *        \n\n
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue