📄 ch375.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 + -