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

📄 usb.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	}

	/*由于USBN9603 的中断为电平触发型,而有些MCU的中断触发为边沿型   */
	/*为了使程序有更好的移植性,先禁止USBN9603中断输出,然后再使能它  */
	/*从而得到下一次中断产生时的触发边沿。                          */
	evnt=read_usb(MAMSK);               /*保存原来的中断设置    */
	write_usb(MAMSK,0);                 /*禁止USBN9603的中断输出*/
	write_usb(MAMSK,evnt);              /*恢复原来的中断设置    */
	evnt=0;	/*clear the evnt flag*/
}
/*******************************************************************
*****                       初始化USBN9603                      *****
*******************************************************************/
void init_usb(void)
{
	
	/*toss out any previous state ***********************************/
  	CLR_MLTIPKT;/*exit multi-packet mode  */
  	usb_cfg	=0;

	/*对USBN9603进行一次软件复位*/
	write_usb(MCNTRL,SRST);	/*写 0x01 到 MCNTRL*/
	/*INTOC(1-0)=00	:禁止中断输出      */
	/*NAT=0			:禁止被USB总线检测 */
	/*VEG=0			:禁止内部3.3V稳压  */
	/*SRST=1		:进行软件复位      */

	/*等待软件复位完成*/
	while(read_usb(MCNTRL)&0x01==0x00)
	{
		usb_cfg=0;
	}
	
	evnt=read_usb(RID);		/*读取USBN9603的版本识别号*/
	/*该数值因为0x02,由此可判断USBN9603是否被正确地挂在总线上*/
	if(evnt==0x02)
	{
		Uart_Printf("\n*                USBN9603 is found!                                     *");
		Uart_Printf("\n*                USB interface is active now!                           *");
		Uart_Printf("\n*-----------------------------------------------------------------------*");
	}
	else
		Uart_Printf("\nUSBN9603 is not found!Pls check your hardware!");
	
	write_usb(MCNTRL,VGE+INT_L_O); /*写0x04+0x40=0x44 到 MCNTRL(该句能否省略?)*/
	/*INTOC(1-0)=01	:中断为低电平有效输出*/
	/*VEG=0			:使能内部3.3V稳压   */

	/*设置USBN9603的时钟输出*/
	write_usb(CCONF,CLKDIV);	/*输出时钟频率为4MHZ */
	/* CLKDIV=5=0x0101=11,so frequency=48MHz/(CLKDIV+1)=4MHZ*/

	/*set default address, enable EP0 only **************************/
	write_usb(FAR,AD_EN+0);		/*FAR is "Function Address Register"*/
	/*write 0x80+0x00=0x80 to FAR*/
	/*AD_EN=1		:Address Enable. When set to 1, bits AD6-0 are used in address comparison.*/
	/*               When cleared, the device does not respond to any token on the USB bus.   */
	/*采用寻址方式访问端点*/

	write_usb(EPC0,0x00);	/*设置端点0的寻址地址*/

	/* 设置USBN9603的中断屏蔽位 */
	write_usb(NAKMSK,NAK_O0);                          /*NAK evnts*/
	/*NAK_O0=0x10*/
	/*当EndPoint0收到OUT token时,MAEV中的NAK位将被置位*/
//	write_usb(TXMSK,TXFIFO0);      
	write_usb(TXMSK,TXFIFO0+TXFIFO1+TXFIFO2+TXFIFO3);                  /*TX events*/
	/*使能EndPoint0的发送中断*/
//	write_usb(RXMSK,RXFIFO0);       
	write_usb(RXMSK,RXFIFO0+RXFIFO1+RXFIFO2+RXFIFO3);                  /*RX events*/
	/*使能EndPoint0的接收中断*/

	write_usb(ALTMSK,NORMAL_ALTMSK);
	/*NORMAL_ALTMSK=SD3+RESET_A*/
	/*使能Reset和SD3中断*/
	/*SD3	:Suspend Detect 3 mS. This bit is set after 3 mS of IDLE is detected */
	/*       on the upstream port, indicating that the device should be          */
	/*       suspended. The suspend occurs under firmware control by writing     */
	/*       the suspend value to the Node Functional State (NF-SR) register.    */
	/*       This bit is cleared when the register is read.                      */
	/*RESET	:This bit is set when 2.5 mS of SEO is detected on the upstream port.*/
	/*       In response, the functional state should be reset (NFS in the NFSR  */
	/*       register is set to RESET), where it must remain for at least 100 mS.*/
	/*       The functional state can then return to Op-erational state. This bit*/
	/*       is cleared when the register is read.                               */

	write_usb(MAMSK,(INTR_E+RX_EV+NAK+TX_EV+ALT));
	/*向MAMSK写入INTR_E=0x80(master interrupt enable)*/
	/*        和RX_EV=0x40(receive event)           */
	/*        和NAK=0x10(NAK event)                 */
	/*        和TX_EV=0x04(transmit event)          */
	/*        和ALT=0x02(alternate event)           */
	
	/*enable the receiver and go operational ************************/
	FLUSHTX0;							/*置TX0为Idle,并清除其FIFO的读写指针*/
	
	write_usb(RXC0,RX_EN);              /*使能 RX0接收 */

	write_usb(NFSR,OPR_ST);				/*将OPR_ST=0x02写到NFSR中,置USBN9603为Operational State*/

	write_usb(MCNTRL,VGE+INT_L_O+NAT);	/*允许USB总线检测到USBN9603的接入*/
//	LED1=0;
}
/**********************************************************************/
/* Following are vendor specific command                              */
/**********************************************************************/
/*vendor defined request: send command ane read device status*/
void sendcommand(void)
{
    SET_SENDCMD; /*enter SENDCMD mode      */
    cmd_sze = 0;
	usb_status = WaitForData; //wait for data
    memset(cmd_buf, 0, 64);
}

void readstatus(void)
{
    SET_READSTA; /*enter READSTA mode      */
	cmd_sze = 0;

    memset(cmd_buf, 0, 64);
    cmd_buf[0] = usb_status;
    cmd_buf[1] = CF_NO;
	cmd_buf[2] = OnBoardFalsh_YES;
	cmd_buf[3] = Player_OK;
    /*send the !!first data chunk back                                */
    mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
    mlti_pkt(); mlti_pkt(); mlti_pkt(); mlti_pkt();
}
void root_information(void)
{
	U32 page_num,Pointer,i;
	U8 Page_Buf[512+16];
	
	SET_ROOT;

	/*读入Root informatiom*/
	for(page_num=0;page_num<32;page_num++)
	{
		/*将Root information读到root_buf中*/
		ReadPage(Root_Cluster,page_num,&(Page_Buf[0]));
		for(Pointer=0;Pointer<512;Pointer++)
		{
			root_buf[page_num*16+Pointer/32][Pointer%32]=Page_Buf[Pointer];
		}
	}

	n_size = 256; //256*64=16*1024
	for(i = 0; i < 64; i++)
	{
		Pointer=(256-n_size)*64+i;
    	write_usb(TXD1,root_buf[Pointer/32][Pointer%32]);       /*send data to the tx1 FIFO   */
    }
    n_size--;
}
void memory_size(void)
{
	char temp[64];
	int i;
	SET_MEM;
	
	/* because of edian */
	temp[0] = Disk_Size%256; //LS byte
	temp[1] = Disk_Size/256;
	temp[2] = 0x00;
	temp[3] = 0x00;
	
	for(i = 0; i < 64; i++)
		write_usb(TXD1, temp[i]);       /*send data to the tx1 FIFO   */ 
	//usb_status = 0xFF; 
}
void download_file(void)
{
	SET_DOWNLOAD;	//enter download state!
	if(comp_filename(BIOS_BIN,(U8 *)&cmd_buf[10])==0)
	{
		File2Sdram=1;	//set the File2Sdram flag ,this file is BIOS.bin,and it should load to SDRAM then run in SDRAM
		Uart_Printf("\nBios.bin is under downloading!");
	}
	else
		creat_file((U8 *)&cmd_buf[10]);	//将文件信息添加到Root information
    
	/*计算文件的大小(单位:字节)*/
	fsize = (int)cmd_buf[38] + (int)cmd_buf[39]*256 + (int)cmd_buf[40]*256*256 + (int)cmd_buf[41]*256*256*256;
	/*将文件的大小换算为扇区数(Sector),并圆整*/
	n_size = (fsize%512 == 0) ? fsize/512 : fsize/512+1;
	total = 0;	//清除已接收字节数计数器
}
void upload_file(void)
{
    int i;
	U32 root_location;
    SET_UPLOAD; //enter upload state!
    // get the location of this file via look for its file name in Root Directory //
	root_location=find_file((U8 *)&cmd_buf[10]);
	current_block=root_buf[root_location][27]*256+root_buf[root_location][26];
    /* Get file length(:sector) */
    n_size = cmd_buf[21] + cmd_buf[22]*256 + cmd_buf[23]*256*256 + cmd_buf[24]*256*256*256; 
    
    /* send the first chunk */
	read_file(tx_buf);
    
    total = 0;
    
    for(i = 0; i < 64; i++)
    	write_usb(TXD1, tx_buf[i]);       /*send data to the tx1 FIFO   */
    
    total += 64;					  
}

/*
                                USB通讯协议
一  总体思路
    1.在USB通讯时,除了USB规定的缺省的endpoint0以外,另外开辟2个endpoint进行数据传送.
        endpoint0用来传递USB命令和扩展的命令
        地址01H的endpoint1用来传递上传数据
        地址81H的endpoint2用来传递下传数据。
        这3个endpoint的最大数据包长度都为64字节(对于Host而言)
    2.下传命令基本格式
    主机通过endpoint0向播放机传递命令,除了USB规定的标准的REQUEST以外,我们扩展两个命
    令(Vendor):下传命令和读设备状态.其格式如下:
           bmRequestType   bRequest   wValue   wIndex   wLength
下传命令:  40H             F0H        0H       0H       40H
读设备状态:C0H             F1H        0H       0H       40H
二  下传命令集:
主机下发的F0H命令的64字节的数据含义如下:
	1.格式化命令:
            A.格式化ON-BOARD FLASH芯片
                    8000H+其余为 20 H
            B.格式化扩展CF卡
                    8001H+其余为 20 H 
            C.格式化扩展SMC卡
                    8002H+其余为 20 H
            D.格式化扩展MMC卡
                    8003H+其余为 20 H
    2.读取根目录信息:
            A.读取ON-BOARD FLASH根目录信息
                    8200H+其余为 20 H
            B.读取扩展CF卡根录信息
                    8201H+其余为 20 H
            C.读取扩展SMC卡根目录信息
                    8202H+其余为 20 H
            D.读取扩展MMC卡根目录信息
                    8203H+其余为 20 H

    3.拷贝文件到播放器:
            A.拷贝到ON-BOARD FLASH
                    8400H+8字节目录名+32字节文件名+其余为 20 H
            B.拷贝到扩展CF卡
                    8401H+8字节目录名+32字节文件信息+其余为 20 H
            C.拷贝到扩展SMC卡
                    8402H+8字节目录名+32字节文件信息+其余为 20 H
            D.拷贝到扩展MMC卡
                    8403H+8字节目录名+32字节文件信息+其余为 20 H

    4.删除文件:
            A.删除ON-BOARD FLASH文件
                    8500H+8字节目录名+32字节文件信息+其余为 20 H
            B.删除扩展CF卡文件
                    8501H+8字节目录名+32字节文件信息+其余为 20 H
            C.删除扩展SMC卡文件
                    8502H+8字节目录名+32字节文件信息+其余为 20 H
            D.删除扩展MMC卡文件
                    8503H+8字节目录名+32字节文件信息+其余为 20 H

    5.重命名文件名:
            A.重命名ON-BOARD FLASH 文件
                    8800H+8字节目录名+8字节旧文件名+8字节新文件名+其余为 20 H
            B.重命名扩展CF卡文件
                    8801H+8字节目录名+8字节旧文件名+8字节新文件名+其余为 20 H
            C.重命名扩展SMC卡文件
                    8802H+8字节目录名+8字节旧文件名+8字节新文件名+其余为 20 H
            D.重命名扩展MMC卡文件
                    8803H+8字节目录名+8字节旧文件名+8字节新文件名+其余为 20 H

    6.读取文件到PC机:
            A.读取ON-BOARD FLASH
                    8900H+8字节目录名+11字节文件名+4字节文件大小(单位:扇区)+其余为 20 H
            B.读取扩展CF卡
                    8901H+8字节目录名+11字节文件名+4字节文件大小(单位:扇区)+其余为 20 H
            C.读取扩展SMC卡
                    8902H+8字节目录名+11字节文件名+4字节文件大小(单位:扇区)+其余为 20 H
            D.读取扩展MMC卡
                    8903H+8字节目录名+11字节文件名+4字节文件大小(单位:扇区)+其余为 20 H

    7.程序升级:
        8A00 + 62字节20H

    8.读卡的大小(以1个sector=512B为基本单位)
            A.读取ON-BOARD FLASH 的容量大小
                    8c00H+其余为 20 H
            B.读取扩展CF卡的容量大小
                    8c01H+其余为 20 H
            C.读取扩展SMC卡的容量大小
                    8c02H+其余为 20 H
            D.读取扩展MMC卡的容量大小
                    8c03H+其余为 20 H

    9.上下传取消
            8B00 + 62字节20H

三  读取设备状态命令 
    主机向播放器发送读取设备状态命令后(1s 读一次),播放器应答播放器对主机发来的最后
一条下传命令的执行情况.这条命令的数据长度为固定长度64字节,具体格式如下:
    第一字节:0XFF    PC机可以发送命令
             0X10    PC机可以发送数据
    第二字节:0X00    播放器没有外部CF卡
             0X01    播放器有外部CF卡
    第三字节:0X00    播放器没有内部FLASH
             0X01    播放器有内部FLASH
    第四字节:0X00    播放器运行正常
             0X01    播放器运行出错
四. 其他
    1.启动PC程序,自动刷新
    2.刷新包括读根目录命令,读卡的大小命令
    3.任何的命令完成(例如下传,删除,重命名等)后,都需要运行一遍刷新命令
    4.下传文件的文件名(11byte)需要转化成大写   
    5.下载升级程序时,须对选中的二进制文件进行校验,最后16字节为校验码,比较其中前面7
个字节应为MPF2000,最后一个字节应为对文件的每个字节异或得出的校验码是否相同。

*/

⌨️ 快捷键说明

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