www.pudn.com > pdiusbd12 source.rar > MAINLOOP.C


/* 
   //************************************************************************* 
   // 
   //                  P H I L I P S   P R O P R I E T A R Y 
   // 
   //           COPYRIGHT (c)   1997 BY PHILIPS SINGAPORE. 
   //                     --  ALL RIGHTS RESERVED  -- 
   // 
   // File Name:	MainLoop.C 
   // Author:		Wenkai Du 
   // Created:		19 Dec 97 
   // Modified: 
   // Revision:		3.0 
   // 
   //************************************************************************* 
   // 
   // 98/11/25		Added I/O access support on Main endpoints. (WK) 
   //************************************************************************* 
   */ 
 
#include  
#include  
 
#include                 /* special function register declarations   */ 
 
#include "epphal.h" 
#include "d12ci.h" 
#include "mainloop.h" 
#include "usb100.h" 
#include "chap_9.h" 
#include "protodma.h" 
/* 
//************************************************************************* 
// USB protocol function pointer arrays 
//************************************************************************* 
*/ 
code void (*StandardDeviceRequest[])(void) = 
{ 
	get_status, 
	clear_feature, 
	reserved, 
	set_feature, 
	reserved, 
	set_address, 
	get_descriptor, 
	reserved, 
	get_configuration, 
	set_configuration, 
	get_interface, 
	set_interface, 
	reserved, 
	reserved, 
	reserved, 
	reserved 
}; 
 
code void (*VendorDeviceRequest[])(void) = 
{ 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	reserved, 
	read_write_register, 
	reserved, 
	reserved, 
	reserved 
}; 
 
/* 
//************************************************************************* 
//  Public static data 
//************************************************************************* 
*/ 
 
extern EPPFLAGS bEPPflags; 
extern unsigned long ClockTicks; 
extern unsigned char idata GenEpBuf[]; 
extern IO_REQUEST idata ioRequest; 
 
extern unsigned char ioSize, ioCount; 
extern unsigned char xdata MainEpBuf[]; 
extern unsigned char idata EpBuf[]; 
 
CONTROL_XFER ControlData; 
BOOL bNoRAM; 
 
code char * _NAME_USB_REQUEST_DIRECTION[] = 
{ 
"Host_to_device", 
"Device_to_host" 
}; 
 
code char * _NAME_USB_REQUEST_RECIPIENT[] = 
{ 
"Device", 
"Interface", 
"Endpoint(0)", 
"Other" 
}; 
 
code char * _NAME_USB_REQUEST_TYPE[] = 
{ 
"Standard", 
"Class", 
"Vendor", 
"Reserved" 
}; 
 
code char * _NAME_USB_STANDARD_REQUEST[] = 
{ 
"GET_STATUS", 
"CLEAR_FEATURE", 
"RESERVED", 
"SET_FEATURE", 
"RESERVED", 
"SET_ADDRESS", 
"GET_DESCRIPTOR", 
"SET_DESCRIPTOR", 
"GET_CONFIGURATION", 
"SET_CONFIGURATION", 
"GET_INTERFACE", 
"SET_INTERFACE", 
"SYNC_FRAME" 
}; 
 
void help_devreq(unsigned char typ, unsigned char req) 
{ 
	typ >>= 5; 
 
	if(typ == USB_STANDARD_REQUEST) { 
	} 
	else { 
		if(bEPPflags.bits.verbose) 
			printf("Request Type = %s, bRequest = 0x%bx.\n", _NAME_USB_REQUEST_TYPE[typ], 
				req); 
	} 
} 
 
/* Configure Timer 0 
   - Mode                  = 1 
   - Interrupt                   = ENABLED 
   - Clock Source                = INTERNAL 
   - Enable Gating Control    = DISABLED 
*/ 
 
 
void init_timer0(void) 
{ 
	TMOD &= 0XF0;                    /* clear Timer 0   */ 
	TMOD  |= 0X1; 
	TL0 = 0X0;                   /* value set by user    */ 
	TH0 = 0X0;                  /* value set by user  */ 
	ET0 = 1;        /* IE.1*/ 
	TR0 = 1;                /* TCON.4 start timer  */ 
	PT0 = 1; 
 
	EA = 1; 
} 
 
/* Interrupt Control Unit */ 
/*   ****  Enabled interrupts in Interrupt Enable Register **** 
	 ****  GLOBAL INTERRUPT MUST BE ENABLED FOR ANY OTHER 
	 ****  INTERRUPT TO WORK! 
*/ 
/*                  GLOBAL INTERRUPT DISABLED ALL INTERRUPTS 
					ARE DISABLED          */ 
/*                    External interrupt 0      */ 
/*                        Priority Level = 0    */ 
/*                        Timer 0 interrupt     */ 
/*                       Priority Level = 0     */ 
void init_special_interrupts(void) 
{ 
	IT0 = 0; 
	EX0 = 1; 
	PX0 = 0; 
} 
 
void init_port() 
{ 
	P0 = 0xFF; 
	P1 = 0xFF; 
	P2 = 0xFF; 
	P3 = 0xFF; 
	MCU_D12CS = 0x0; 
	D12SUSPD = 0; 
} 
 
/*Serial Port */ 
/*Mode            = 1  /8-bit UART 
  Serial Port Interrupt    = Disabled         */ 
/*Receive         = Enabled   */ 
/*Auto Addressing    = Disabled   */ 
void init_serial(void) 
{ 
	SCON = 0X52; 
	PCON = 0X80 | PCON; 
	TMOD = 0X20; 
	TCON = 0x69;    /* TCON */ 
	TH1 = 0xF3; 
} 
 
void on_exit(void) 
{ 
} 
 
void main(void) 
{ 
	unsigned char key, i; 
 
	init_port(); 
	init_serial(); 
	init_timer0(); 
	init_special_interrupts(); 
 
	MCU_D12CS = 0x1; 
	for(i = 0; i < 16; i ++) 
		MainEpBuf[i] = i; 
	for(i = 0; i < 16; i ++) { 
		if(MainEpBuf[i] != i) 
			break; 
		} 
	if(i < 16) 
		bNoRAM = TRUE; 
	else 
		bNoRAM = FALSE; 
	MCU_D12CS = 0x0; 
 
	if(MCU_SWM0 == 0 && MCU_SWM1 == 0) { 
		MCU_D12RST = 0; 
		MCU_D12RST = 1; 
		D12_SetDMA(0x0); 
	} 
 
	if((i = D12_GetDMA()) == 0xC3) { 
		D12_SendResume(); 
	} 
	else { 
		bEPPflags.value = 0; 
 
		/* Power on reset, lightup LEDs for 1 sec, 
		   disconnect and reconnect Soft-Connect */ 
		printf("\nPDIUSBD12 SMART evaluation board firmware V3.0.\n"); 
 
		reconnect_USB(); 
	} 
	/* Main program loop */ 
 
	while( TRUE ){ 
 
		if (bEPPflags.bits.timer){ 
			DISABLE; 
			bEPPflags.bits.timer = 0; 
			ENABLE; 
 
			if(bEPPflags.bits.configuration) 
				check_key_LED(); 
		} 
 
		if(RI) { 
			key = _getkey(); 
			switch(key) { 
				case 'i': 
					if(bEPPflags.bits.control_state == USB_IDLE) 
						printf("Control state = USB_IDLE."); 
					else if(bEPPflags.bits.control_state == USB_RECEIVE) 
						printf("Control state = USB_RECEIVE."); 
					else if(bEPPflags.bits.control_state == USB_TRANSMIT) 
						printf("Control state = USB_TRANSMIT."); 
					printf(" ControlData.wCount = %x.\n", ControlData.wCount); 
					printf("Endpoint 4 (Bulk Out) Status = %bx, Endpoint 5 (Bulk In) Status = %bx.\n", 
					   D12_ReadEndpointStatus(4), D12_ReadEndpointStatus(5)); 
					if(bEPPflags.bits.dma_state == DMA_IDLE) 
						printf("DMA_State = DMA_IDLE.\n"); 
					else if(bEPPflags.bits.dma_state == DMA_RUNNING) 
						printf("DMA_State = DMA_RUNNING.\n"); 
					else if(bEPPflags.bits.dma_state == DMA_PENDING) 
						printf("DMA_State = DMA_PENDING.\n"); 
 
					printf("Last Device Request: bmRequestType = 0x%bx, bRequest= 0x%bx, wValue = 0x%x, wLength = 0x%x, wIndex = 0x%x.\n", 
 
						ControlData.DeviceRequest.bmRequestType, 
						ControlData.DeviceRequest.bRequest, 
						ControlData.DeviceRequest.wValue, 
						ControlData.DeviceRequest.wLength, 
						ControlData.DeviceRequest.wIndex); 
 
					printf("Data: "); 
					for(i = 0; i < ControlData.DeviceRequest.wLength; i ++) 
						printf("0x%bx, ", *((ControlData.dataBuffer)+i)); 
					printf("\n"); 
 
					break; 
				case '\r': 
					reconnect_USB(); 
					break; 
 
				case 'v': 
					if(bEPPflags.bits.verbose == 0) { 
						printf("Verbose Mode = ON.\n"); 
						DISABLE; 
						bEPPflags.bits.verbose = 1; 
						ENABLE; 
					} 
					else { 
						printf("Verbose Mode = OFF.\n"); 
						DISABLE; 
						bEPPflags.bits.verbose = 0; 
						ENABLE; 
					} 
					break; 
				default: 
					break; 
			} 
		} 
 
 
		if (bEPPflags.bits.bus_reset) { 
			DISABLE; 
			bEPPflags.bits.bus_reset = 0; 
			ENABLE; 
			// Release D12's SUSPEND pin after bus reset 
			// Enable 74HCT123 pulse generation before disconnect 
			D12SUSPD = 1; 
		} // if bus reset 
 
		if (bEPPflags.bits.suspend) { 
			DISABLE; 
			bEPPflags.bits.suspend= 0; 
			ENABLE; 
 
			if(D12SUSPD == 1) { 
				D12SUSPD = 0; 
				P0 = 0xFF; 
				P1 = 0xFF; 
				P2 = 0xFF; 
				P3 = 0xFF; 
				D12_SetDMA(0xC3); 
				D12SUSPD = 1; 
				PCON |= 0x02; 
				while (1); 
			} 
		} // if suspend change 
 
		if (bEPPflags.bits.setup_packet){ 
			DISABLE; 
			bEPPflags.bits.setup_packet = 0; 
			ENABLE; 
			control_handler(); 
			D12SUSPD = 1; 
		} // if setup_packet 
 
		if(bEPPflags.bits.setup_dma != 0) { 
			DISABLE; 
			bEPPflags.bits.setup_dma --; 
			ENABLE; 
			setup_dma(); 
		} // if setup_dma 
 
	} // Main Loop 
 
	on_exit(); 
} 
 
void stall_ep0(void) 
{ 
	D12_SetEndpointStatus(0, 1); 
	D12_SetEndpointStatus(1, 1); 
} 
 
void disconnect_USB(void) 
{ 
	// Initialize D12 configuration 
	D12_SetMode(D12_NOLAZYCLOCK, D12_SETTOONE | D12_CLOCK_12M); 
} 
 
void connect_USB(void) 
{ 
	// reset event flags 
	DISABLE; 
	bEPPflags.value = 0; 
	ENABLE; 
 
	// V2.1 enable normal+sof interrupt 
	D12_SetDMA(D12_ENDP4INTENABLE | D12_ENDP5INTENABLE); 
 
	// Initialize D12 configuration 
	D12_SetMode(D12_NOLAZYCLOCK|D12_SOFTCONNECT, D12_SETTOONE | D12_CLOCK_12M); 
} 
 
 
void reconnect_USB(void) 
{ 
	unsigned long clk_cnt; 
 
	MCU_LED0 = 0; 
	MCU_LED1 = 0; 
 
	// Pull-down D12's SUSPEND pin 
	// Disable 74HCT123 pulse generation before disconnect 
	// Release D12's SUSPEND pin after receiving bus reset from host 
	D12SUSPD = 0; 
	disconnect_USB(); 
 
	printf("Wait for 1 second ...\n"); 
 
	clk_cnt = ClockTicks; 
	while(ClockTicks < clk_cnt + 20) 
		; 
 
	connect_USB(); 
 
	MCU_LED0 = 1; 
	MCU_LED1 = 1; 
} 
 
void init_unconfig(void) 
{ 
	unsigned char i; 
 
	D12_SetEndpointEnable(0);	/* Disable all endpoints but EPP0. */ 
} 
 
void init_config(void) 
{ 
	D12_SetEndpointEnable(1);	/* Enable  generic/iso endpoints. */ 
} 
 
void single_transmit(unsigned char * buf, unsigned char len) 
{ 
	if( len <= EP0_PACKET_SIZE) { 
		D12_WriteEndpoint(1, len, buf); 
	} 
} 
 
void code_transmit(unsigned char code * pRomData, unsigned short len) 
{ 
	ControlData.wCount = 0; 
	if(ControlData.wLength > len) 
		ControlData.wLength = len; 
 
	ControlData.pData = pRomData; 
	if( ControlData.wLength >= EP0_PACKET_SIZE) { 
		D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData); 
		ControlData.wCount += EP0_PACKET_SIZE; 
 
		DISABLE; 
		bEPPflags.bits.control_state = USB_TRANSMIT; 
		ENABLE; 
	} 
	else { 
		D12_WriteEndpoint(1, ControlData.wLength, pRomData); 
		ControlData.wCount += ControlData.wLength; 
		DISABLE; 
		bEPPflags.bits.control_state = USB_IDLE; 
		ENABLE; 
	} 
} 
 
void check_key_LED(void) 
{ 
	static unsigned char c, last_key = 0xf; 
 
	c = MCU_SWM0 & MCU_SWM1; 
	c &= 0x0f; 
	if (c != last_key) { 
		D12_WriteEndpoint(3, 1, &c); 
	} 
 
	last_key = c; 
 
	if(bEPPflags.bits.ep1_rxdone) { 
		DISABLE; 
		bEPPflags.bits.ep1_rxdone = 0; 
		ENABLE; 
		MCU_LED0 = !(GenEpBuf[3] & 0x1); 
		MCU_LED1 = !(GenEpBuf[3] & 0x2); 
	} 
} 
 
void setup_dma() 
{ 
	ioSize = ioRequest.uSize; 
	ioCount = 0; 
 
	DISABLE; 
	bEPPflags.bits.dma_state = DMA_RUNNING; 
	ENABLE; 
 
	single_transmit(0, 0); 
 
	if(ioRequest.bCommand & 0x1) { 
		if(ioSize > 64 || ioSize == 0) { 
			if(bNoRAM) 
				D12_WriteEndpoint(5, 64, EpBuf); 
			else 
				D12_WriteEndpoint(5, 64, MainEpBuf); 
			ioCount += 64; 
		} 
		else { 
			if(bNoRAM) 
				D12_WriteEndpoint(5, ioSize, EpBuf); 
			else 
				D12_WriteEndpoint(5, ioSize, MainEpBuf); 
			ioCount += ioSize; 
		} 
	} 
} 
 
 
void control_handler() 
{ 
	unsigned char type, req; 
 
	type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK; 
	req = ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK; 
 
	help_devreq(type, req); // print out device request 
 
	if (type == USB_STANDARD_REQUEST) 
		(*StandardDeviceRequest[req])(); 
	else if (type == USB_VENDOR_REQUEST) 
		(*VendorDeviceRequest[req])(); 
	else 
		stall_ep0(); 
}