⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainloop.c

📁 是关于pdiusbd12完整固件程序代码
💻 C
字号:
	#include <stdio.h>
	#include <string.h>

	#include <reg51.h>                /* 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
	//*************************************************************************
	*/


	//USB标准请求
	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 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
	*/
	//定时器0初始化程序
	//定时器用来定时检测按键状态
	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;
	}

	//I/O口初始化程序
	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 main(void)
	{
		unsigned char key, i;

		init_port();//初始化I/O口
		init_serial();//初始化串行口
		//注:串行口是用来外扩LCD和键盘,用于查询显示当前的工作状态
		//在USB Smart Board标准配置中并未带该LCD和键盘,这里给出的程序仅供参考

		init_timer0();//初始化定时器0
		init_special_interrupts();//设置中断

		MCU_D12CS = 0x1;
		
		MCU_D12CS = 0x0;

		D12_ReadChipID();

		if(MCU_SWM0 == 0 && MCU_SWM1 == 0) {
			MCU_D12RST = 0;//DMA设置
			MCU_D12RST = 1;
			D12_SetDMA(0x0);
		}

		bEPPflags.value = 0;
		reconnect_USB();//重新连接USB
	/*
		if((i = D12_GetDMA()) == 0xC3) {
			D12_SendResume();//发送恢复处理
		}
		else {
			bEPPflags.value = 0;
			reconnect_USB();//重新连接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){//Setup包处理
				DISABLE;
				bEPPflags.bits.setup_packet = 0;
				ENABLE;
				control_handler();//调用请求处理子程序
				D12SUSPD = 1;
			} // if setup_packet

			if(bEPPflags.bits.setup_dma != 0) {//DMA状态改变处理
				DISABLE;
				bEPPflags.bits.setup_dma --;
				ENABLE;
				setup_dma();
			} // if setup_dma

		} // Main Loop
	}

	//返回stall应答
	void stall_ep0(void)
	{
		D12_SetEndpointStatus(0, 1);
		D12_SetEndpointStatus(1, 1);
	}

	//断开USB总线
	void disconnect_USB(void)
	{
		// Initialize D12 configuration
		D12_SetMode(D12_NOLAZYCLOCK, D12_SETTOONE | D12_CLOCK_12M);
	}

	//连接USB总线
	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);
	}

	//重新连接到USB总线
	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. */
	}

	//从端点号1发送数据
	void single_transmit(unsigned char * buf, unsigned char len)
	{
		if( len <= EP0_PACKET_SIZE) {
			D12_WriteEndpoint(1, len, buf);
		}
	}

	//发送端点号1建立代码
	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);//发送16字节数据
			ControlData.wCount += EP0_PACKET_SIZE;
			DISABLE;
			bEPPflags.bits.control_state = USB_TRANSMIT;
			ENABLE;
		}
		else {
			D12_WriteEndpoint(1, ControlData.wLength, pRomData);//发送16字节内数据
			ControlData.wCount += ControlData.wLength;
			DISABLE;
			bEPPflags.bits.control_state = USB_IDLE;
			ENABLE;
		}
	}

	//LED和按键处理子程序
	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);//改变LED状态
			MCU_LED1 = !(GenEpBuf[3] & 0x2);
		}
	}

	//DMA建立子程序
	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) {
				//传输大于64字节数据
				D12_WriteEndpoint(5, 64, EpBuf);
				ioCount += 64;
			}
			else {
				//传输64字节数据
				D12_WriteEndpoint(5, ioSize, EpBuf);
				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); //显示设备请求

		if (type == USB_STANDARD_REQUEST)
			(*StandardDeviceRequest[req])();//调用标准请求
		else if (type == USB_VENDOR_REQUEST)
			(*VendorDeviceRequest[req])();//调用厂商请求
		else
			stall_ep0();
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -