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

📄 ch375.c

📁 MP3源码 内有SD2.0 驱动 FAT32 驱动
💻 C
字号:
/*****************************************************/
/*            File name : CH375.c                                                   */
/* Description : Code  for CH375 usb host , use internal firmware  */
/* Platform     : AVRStudio4.13 + WinAVR20070525  for AVR     */
/* Author       : Michael Zhang - 章其波                            */
/* Email         : sudazqb@163.com                                          */
/* MSN          : zhangqibo_1985@hotmail.com                          */
/* Date          : 2007-10-21                                                    */
/* NOT FOR COMMERCIAL USE,     ALL RIGHT RESERVED!         */
/*****************************************************/
/* Change Log:                                                                      */
/*                   20071021: original version (from old version)      */
/*****************************************************/



#include"ch375.h"
#include<util/delay.h>

/*
#define CH375_WR_H CH375_WR_PORT |= 1<<CH375_WR_BIT
#define CH375_WR_L CH375_WR_PORT &= ~(1<<CH375_WR_BIT)

#define CH375_RD_H CH375_WR_PORT |= 1<<CH375_RD_BIT
#define CH375_RD_L CH375_RD_PORT &= ~(1<<CH375_RD_BIT)

#define CH375_A0_H CH375_A0_PORT |= 1<<CH375_A0_BIT
#define CH375_A0_L CH375_A0_PORT &= ~(1<<CH375_A0_BIT)

#define CH375_CS_H CH375_CS_PORT |= 1<<CH375_CS_BIT
#define CH375_CS_L CH375_CS_PORT &= ~(1<<CH375_CS_BIT)

#define CH375_INT_ACTIVE (CH375_INT_PIN &= 1<<CH375_INT_BIT) == 0

#define CH375_TO_MCU CH375_DDR = 0x00
#define MCU_TO_CH375 CH375_DDR = 0xff

#define CH375_DAT_OUT CH375_PIN
#define CH375_DAT_IN  CH375_PORT
*/



void CH375_DelayNms(uint16 n)//不精确
{
	while(n--)_delay_ms(1);
}


//CH375写命令
void CH375_WriteCMD(uint8 _CMD)
{
	//CH375_CS_L();				//使能芯片
	MCU_TO_CH375;
	CH375_A0_H;	
	CH375_DAT_IN = _CMD;
	CH375_WR_L;
	asm("nop;");
	asm("nop;");
	//asm("nop;");
	//asm("nop;");
	CH375_WR_H;
	_delay_us(1);
}

//CH375写数据
void CH375_WriteDAT(uint8 _DAT)
{
	//CH375_CS_L();
	MCU_TO_CH375;
	CH375_A0_L;
	CH375_DAT_IN = _DAT;
	CH375_WR_L;
	asm("nop;");
	asm("nop;");
	//asm("nop;");
	//asm("nop;");
	CH375_WR_H;
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");

	//_delay_us(1);
}

//CH375度数据
uint8 CH375_ReadDAT(void)
{
	uint8 temp;
    CH375_TO_MCU;
	CH375_A0_L;
	CH375_RD_L;
	asm("nop;");
	asm("nop;");
	//asm("nop;");
	//asm("nop;");
	temp = CH375_DAT_OUT;		//写命令
	CH375_RD_H;
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");
	//asm("nop;");

	//_delay_us(1);
	return temp;
}

//CH375等待中断,并返回中断状态
uint8 CH375_WaitInterrupt()
{
	uint8 temp;
	while(!CH375_INT_ACTIVE);
	CH375_WriteCMD(GET_STATUS);
	temp = CH375_ReadDAT();
	return temp;
}

uint8 CH375_WaitInterrupt_NEW()//带超时处理
{
	uint8 temp;
	uint16 retry =0;
	while((!CH375_INT_ACTIVE) && (retry++ < 0xffff));
	if(retry == 0x0)return 0xff;
	CH375_WriteCMD(GET_STATUS);
	temp = CH375_ReadDAT();
	return temp;
}

//初始化U盘
uint8 CH375_IniDisk(void)
{
	//printf(("\r\n375 reset"));
	CH375_CS_L;
	CH375_WriteCMD(RESET_ALL);			//复位全部
	CH375_DelayNms(100);					//延时40ms
	CH375_WriteCMD(CHECK_EXIST);		//检查芯片是否存在
	CH375_WriteDAT(0x55);				//填数据0x55 取反为0xaa
	if(CH375_ReadDAT() != 0xaa){CH375_CS_H;return 1;}//不存在则退出
	CH375_WriteCMD(SET_USB_MODE);		//设置CH375模式
	CH375_WriteDAT(HOST_ACTIVE_EOF);	//主机模式,自动产生EOF
	_delay_us(40);					//延时20us
	if(CH375_WaitInterrupt() != USB_INT_CONNECT){CH375_CS_H;return 1;}//不成功责返回
	CH375_DelayNms(500);				//延时500ms让U盘准备好
	CH375_WriteCMD(DISK_INIT);			//初始化U盘
	if(CH375_WaitInterrupt() != USB_INT_SUCCESS){CH375_CS_H;return 1;}//不成功则退出
	CH375_CS_H;
	return 0;							//正常返回0
}

//CH375读一个扇区 //带出错处理
uint8 CH375_ReadOneSector(uint32 LBA,uint8 *buffer)
{
	uint8 cnt;					//数据需分8次读		
	uint8 temp;						//单次数据长度
retry:
	CH375_CS_L;
	CH375_WriteCMD(DISK_READ);		//发读命令
	CH375_WriteDAT(LBA);			//填充目的地址
	CH375_WriteDAT(LBA>>8);
	CH375_WriteDAT(LBA>>16);
	CH375_WriteDAT(LBA>>24);
	CH375_WriteCMD(1);
	cnt = 8;				//读一个扇区
	while(cnt--)
	{
		if(CH375_WaitInterrupt_NEW() != USB_INT_DISK_READ)break;	//等待就绪 出错跳出
		CH375_WriteCMD(RD_USB_DATA);							//发读数据命令
		temp = CH375_ReadDAT();									//读数据长度
		while(temp--)*buffer++ = CH375_ReadDAT();				//依次读出数据
		CH375_WriteCMD(DISK_RD_GO);								//发继续命令
	} 
	if(cnt != 0xff)//当所接设备出错时重新复位处理
	{
		CH375_CS_H;
		CH375_IniDisk();//复位
		goto retry;
	}
	if(CH375_WaitInterrupt_NEW() != USB_INT_SUCCESS){CH375_CS_H;return 1;}//如果出错则返回1
	CH375_CS_H;
	return 0;														//正常返回0
}

//CH375写一个扇区
uint8 CH375_WriteOneSector(uint32 LBA,uint8 *buffer)
{
	uint8 cnt = 8;						//数据需分8次送出
	uint8 temp = 64;					//每次64字节
	CH375_CS_L;
	CH375_WriteCMD(DISK_WRITE);			//发写命令
	CH375_WriteDAT(LBA);				//填充目的地址
	CH375_WriteDAT(LBA>>8);
	CH375_WriteDAT(LBA>>16);
	CH375_WriteDAT(LBA>>24);
	CH375_WriteCMD(1);					//写一个扇区
	while(cnt--)
	{
		if(CH375_WaitInterrupt() != USB_INT_DISK_WRITE)break;		//等待就绪 出错则跳出
		CH375_WriteCMD(WR_USB_DATA7);								//发写数据命令
		CH375_WriteDAT(64);											//设定数据长度
		while(temp--)CH375_WriteDAT(*buffer++);						//依次送出数据
		CH375_WriteCMD(DISK_WR_GO);									//发继续写命令
	}
	if(cnt != 0xff || CH375_WaitInterrupt() != USB_INT_SUCCESS){CH375_CS_H;return 1;}//出错则退出
	CH375_CS_H;
	return 0;														//正常返回0
}


uint32 CH375_ReadDiskSize(void)
{
	uint8 buffer[8];
	uint8 cnt;
	uint8 i;
	uint32 temp1, temp2;
	CH375_CS_L;
	CH375_WriteCMD(DISK_SIZE);
	if(CH375_WaitInterrupt() != USB_INT_SUCCESS)
	{
		CH375_CS_L;
		return 0;
	}
	CH375_WriteCMD(RD_USB_DATA);
	cnt = CH375_ReadDAT();
	for(i=0;i<cnt;i++)buffer[i] = CH375_ReadDAT();
	CH375_CS_H;

	/* data format is big endian */	
	temp1 =   (uint32)buffer[0]<<24;
	temp1 += (uint32)buffer[1]<<16;
	temp1 += (uint32)buffer[2]<<8;
	temp1 += (uint32)buffer[3]<<0;
	
	temp2 =   (uint32)buffer[4]<<24;
	temp2 += (uint32)buffer[5]<<16;
	temp2 += (uint32)buffer[6]<<8;
	temp2 += (uint32)buffer[7]<<0;

	return temp1 * temp2;
}

uint8 CH375_CheckExist(void)
{
	CH375_CS_L;
	CH375_WriteCMD(RESET_ALL);			//复位全部
	CH375_DelayNms(40);					//延时40ms
	CH375_WriteCMD(CHECK_EXIST);		//检查芯片是否存在
	CH375_WriteDAT(0x55);				//填数据0x55 取反为0xaa
	if(CH375_ReadDAT() != 0xaa){CH375_CS_H;return 0;}//不存在则退出
	CH375_CS_L;
	return 1;
}
/*
//cs 脚的宏定义
#define CH375_CS_H() CH375_CS_PORT |=  (1<<CH375_CS_BIT)
#define CH375_CS_L() CH375_CS_PORT &= ~(1<<CH375_CS_BIT)

void CH375_DelayNus(uint16 n)//不精确
{
	while(n--)asm("nop;");
}

void CH375_DelayNms(uint16 n)//不精确
{
	while(n--)CH375_DelayNus(1000);
}

void CH375_PortIni()
{
	MCUCR |= (1<<SRE);							//使能总线
	CH375_CS_DDR  |= (1<<CH375_CS_BIT);		//cs输出
	CH375_CS_PORT |= (1<<CH375_CS_BIT);
	CH375_INT_DDR  &= ~(1<<CH375_INT_BIT);		//int输入
	CH375_INT_PORT |=  (1<<CH375_INT_BIT);
}

//CH375写命令
void CH375_WriteCMD(uint8 _CMD)
{
	//CH375_CS_L();				//使能芯片
	CH375_CMD_PORT = _CMD;		//写命令
	//CH375_CS_H();				//禁止芯片
//	CH375_DelayNus(2);			//延时
	asm("nop;");
	asm("nop;");
	asm("nop;");
	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
}

//CH375写数据
void CH375_WriteDAT(uint8 _DAT)
{
	//CH375_CS_L();
	CH375_DAT_PORT = _DAT;
	//CH375_CS_H();
	//CH375_DelayNus(2);
	asm("nop;");
	asm("nop;");
	asm("nop;");
	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
}

//CH375度数据
uint8 CH375_ReadDAT(void)
{
	uint8 temp;
	asm("nop;");
	asm("nop;");
	asm("nop;");
	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
//	asm("nop;");
	//CH375_DelayNus(2);
	//CH375_CS_L();
	temp = CH375_DAT_PORT;
	//CH375_CS_H();
	return temp;
}

//CH375等待中断,并返回中断状态
uint8 CH375_WaitInterrupt()
{
	uint8 temp;
	while(CH375_INT_PIN & (1<<CH375_INT_BIT));
	CH375_WriteCMD(GET_STATUS);
	temp = CH375_ReadDAT();
	return temp;
}

uint8 CH375_WaitInterrupt_NEW()//带超时处理
{
	uint8 temp;
	uint16 retry =0;
	while((CH375_INT_PIN & (1<<CH375_INT_BIT)) && retry++ < 0xffff);
	if(retry == 0x0)return 0xff;
	CH375_WriteCMD(GET_STATUS);
	temp = CH375_ReadDAT();
	return temp;
}

//初始化U盘
uint8 CH375_IniDisk(void)
{
	CH375_CS_L();
	CH375_WriteCMD(RESET_ALL);			//复位全部
	CH375_DelayNms(40);					//延时40ms
	CH375_WriteCMD(CHECK_EXIST);		//检查芯片是否存在
	CH375_WriteDAT(0x55);				//填数据0x55 取反为0xaa
	if(CH375_ReadDAT() != 0xaa){CH375_CS_H();return 1;}//不存在则退出
	CH375_WriteCMD(SET_USB_MODE);		//设置CH375模式
	CH375_WriteDAT(HOST_ACTIVE_EOF);	//主机模式,自动产生EOF
	CH375_DelayNus(20);					//延时20us
	if(CH375_WaitInterrupt() != USB_INT_CONNECT){CH375_CS_H();return 1;}//不成功责返回
	//CH375_DelayNms(50);				//延时500ms让U盘准备好
	CH375_WriteCMD(DISK_INIT);			//初始化U盘
	if(CH375_WaitInterrupt() != USB_INT_SUCCESS){CH375_CS_H();return 1;}//不成功则退出
	CH375_CS_H();
	return 0;							//正常返回0
}

//CH375读一个扇区 //带出错处理
uint8 CH375_ReadOneSector(uint32 LBA,uint8 *buffer)
{
	uint8 cnt;					//数据需分8次读		
	uint8 temp;						//单次数据长度
retry:
	CH375_CS_L();
	CH375_WriteCMD(DISK_READ);		//发读命令
	CH375_WriteDAT(LBA);			//填充目的地址
	CH375_WriteDAT(LBA>>8);
	CH375_WriteDAT(LBA>>16);
	CH375_WriteDAT(LBA>>24);
	CH375_WriteCMD(1);
	cnt = 8;				//读一个扇区
	while(cnt--)
	{
		if(CH375_WaitInterrupt_NEW() != USB_INT_DISK_READ)break;	//等待就绪 出错跳出
		CH375_WriteCMD(RD_USB_DATA);							//发读数据命令
		temp = CH375_ReadDAT();									//读数据长度
		while(temp--)*buffer++ = CH375_ReadDAT();				//依次读出数据
		CH375_WriteCMD(DISK_RD_GO);								//发继续命令
	} 
	if(cnt != 0xff)//当所接设备出错时重新复位处理
	{
		CH375_CS_H();
		CH375_IniDisk();//复位
		goto retry;
	}
	if(CH375_WaitInterrupt_NEW() != USB_INT_SUCCESS){CH375_CS_H();return 1;}//如果出错则返回1
	CH375_CS_H();
	return 0;														//正常返回0
}

//CH375写一个扇区
uint8 CH375_WriteOneSector(uint32 LBA,uint8 *buffer)
{
	uint8 cnt = 8;						//数据需分8次送出
	uint8 temp = 64;					//每次64字节
	CH375_CS_L();
	CH375_WriteCMD(DISK_WRITE);			//发写命令
	CH375_WriteDAT(LBA);				//填充目的地址
	CH375_WriteDAT(LBA>>8);
	CH375_WriteDAT(LBA>>16);
	CH375_WriteDAT(LBA>>24);
	CH375_WriteCMD(1);					//写一个扇区
	while(cnt--)
	{
		if(CH375_WaitInterrupt() != USB_INT_DISK_WRITE)break;		//等待就绪 出错则跳出
		CH375_WriteCMD(WR_USB_DATA7);								//发写数据命令
		CH375_WriteDAT(64);											//设定数据长度
		while(temp--)CH375_WriteDAT(*buffer++);						//依次送出数据
		CH375_WriteCMD(DISK_WR_GO);									//发继续写命令
	}
	if(cnt != 0xff || CH375_WaitInterrupt() != USB_INT_SUCCESS){CH375_CS_H();return 1;}//出错则退出
	CH375_CS_H();
	return 0;														//正常返回0
}*/


/* This is the end of file CH375.c */

⌨️ 快捷键说明

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