我使用同事的4GU盘,发现可以检测到U盘连接。但375对CMD_DISK_INIT指令却没有任何反应。不清楚为什么。我当初问过是否支持大U盘的事情,你们有人分析说是电流不够,我这次特意加大供电电流,对此没有改善。
U盘容量与CH375本身没什么关系,出现这个问题主要是兼容性的问题,芯片内部自带的CMD_DISK_INIT兼容性有限,对于操作U盘,如果是一些常用单片机,如51、ARM、AVR、430等,最好能使用我们的子程序库,那么样兼容性会更好些。
我用的是DSP2812,不能算是常用的单片机。另外用你们的程序库的话很多东西对我来说都是不必要的,而且我芯片资源有点紧张。能够提供另外一种解决方案?
另外有没有办法绕过这个CMD_DISK_INIT指令,达到相同的效果?或者不发送这个指令,375对U盘的操作会有什么重大的影响?
(1)不知道您具体相实现什么目标,扇区级还是文件级读写,文件级的话可以使用U盘读写模块,此外我们近期准备推出一款内置文件系统的芯片,单片机端占用资源比较少,接口方式有PARA、SPI、UART,可以发送邮件至kfp@wch.cn索取相关资料。 (2)CMD_DISK_INIT相当于多个USB命令和U盘命令,这是U盘初始化命令,必须执行,否则无法识别U盘,不过也可以自行编写程序实现,只是你得去了解USB协议和BulOnly协议。
扇区级读写,牵扯到数据保密,所以不能以文件的形式出现。 了解协议没有问题,就是这“多个USB命令和U盘命令”去哪里找?最重要的是这些命令你们的375芯片能否直接支持
CMD_DISK_INIT相对于USB标准命令:获取设备描述符、配置描述符、设置地址、设置配置值,这些需要参考USB1.1协议(更正:不含U盘命令),这些命令芯片已内置或者用户自行通过ISSUE_TKN_X/ISSUE_TKN执行事务实现,详细参考CH375DS2.PDF
好的。多谢
大概的一个流程你可以参考一下CH375EVT.ZIP里面的CH375EV3.C.另外你可以把你检测U盘初试化U盘的代码贴出来看看.
(1)对CMD_DISK_INIT包含了设备的枚举过程的命令:获取设备描述符,配置描述符,设置配置等命令.这些命令是磁盘初始化所必须的. (2)建议你去看USB协议和BULK_ONLY协议,了解相关命令.另外,你可以用BUSHOUND这个软件在PC上抓PC操作U盘的数据去了解磁盘初始化的过程. (3)CH375芯片不会去管是什么命令或者什么数据,只负责底层的数据按照USB协议来传输,所以不存在是否支持这些命令.至于是否支持这些命令是设备端的问题.
/* 设置CH375为USB主机方式 */ Uint16 CH375_Init( ) { unsigned int i; KickDog(); #if _Test_CH375_ CH375_WR_CMD(CMD_CHECK_EXIST); //测试375工作是否正常 CH375_WR_DAT(0xAA); //发送测试数据 i= CH375_RD_DAT(); //返回数据应该是测试数据取反 if(i!= 0x55) { //375工作状态不正常 for(i=0;i<10;i++) { //强制数据同步 CH375_WR_CMD(CMD_RESET_ALL); //对375芯片执行硬件复位 delayNuS(10); } delayNmS(50); //延时至少35mS } #endif CH375_WR_CMD(CMD_SET_USB_MODE); //设置USB工作模式 CH375_WR_DAT(6); //模式代码,自动检测USB设备连接 for (i=0;i<100;i++) /* 等待操作成功,通常需要等待10uS-20uS */ { if(CH375_RD_DAT()==CMD_RET_SUCCESS ) break; /* 操作成功 */ } if(i<100) return(0); /* 操作成功 */ else return(0xff); /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */ }
/* U盘准备状态查询 */ Uint16 CH375_ReadyCheck(void) { Uint16 mIntStatus; CH375_WR_CMD(CMD_GET_STATUS); //产生操作完成中断, 获取中断状态 mIntStatus = CH375_RD_DAT(); if(mIntStatus == USB_INT_DISCONNECT)return(mIntStatus); //USB设备断开 CH375_WR_CMD(CMD_DISK_INIT); //初始化USB存储器 mIntStatus = CH375_Wait_Interrupt(); //等待中断并获取状态 if(mIntStatus != USB_INT_SUCCESS ) return(mIntStatus); //出现错误 CH375_WR_CMD(CMD_DISK_READY); //获取USB存储器的准备状态 mIntStatus = CH375_Wait_Interrupt(); //等待中断并获取状态 if(mIntStatus != USB_INT_SUCCESS) //出错重试 { delayNmS(200); CH375_WR_CMD(CMD_DISK_READY); //获取USB存储器的准备状态 mIntStatus = CH375_Wait_Interrupt(); //等待中断并获取状态 } if(mIntStatus!= USB_INT_SUCCESS)return(mIntStatus);//出现错误 return(0); }
初始化就上面两个程序,顺序执行,第一个没什么,到第二个的时候发送CMD_DISK_INIT之后,就一直卡在了等待中断的地方,以下是中断程序。程序一直在等待CH375_INT_WIRE的电平。 /* 等待CH375中断并获取状态 */ Uint16 CH375_Wait_Interrupt(void) { while(CH375_INT_WIRE); //查询等待CH375操作完成中断(INT#低电平) CH375_WR_CMD(CMD_GET_STATUS); //产生操作完成中断, 获取中断状态 return(CH375_RD_DAT()); }
对了,上面说到了兼容的问题,我想问一下这个375B都能兼容什么牌子的U盘。
当U盘插入后要做200MS的延时,以保证U盘稳定后在通讯.CH375B能兼容大部分的U盘,我们曾经做过大两的测试,兼容能达到95%. 或者建议你这样试一下 set_usb_mode( 6 ); /* 设置USB主机模式 */ while ( wait_interrupt()!=USB_INT_CONNECT ); /* 等待USB打印机连接上来 */
/* 如果设备端是CH341转打印口或者是CH37X,那么以下步骤是可选的,如果是其它USB芯片,那么可能需要执行以下步骤 */ set_usb_mode( 7 ); /* 复位USB设备,CH375向USB信号线的D+和D-输出低电平 */ /* 如果单片机对CH375的INT#引脚采用中断方式而不是查询方式,那么应该在复制USB设备期间禁止CH375中断,在USB设备复位完成后清除CH375中断标志再允许中断 */ mDelaymS( 10 ); /* 复位时间不少于1mS,建议为10mS */ set_usb_mode( 6 ); /* 结束复位 */ mDelaymS( 100 ); while ( wait_interrupt()!=USB_INT_CONNECT ); /* 等待复位之后的设备端再次连接上来 */ mDelaymS( 200 ); /* 有些USB设备要等待数百毫秒才能正常工作 */
这个不是等待上电的问题,我已经试过了,不可行。郁闷~我这边放的很多U盘插上后第一个初始化程序都能过,就是说都可以U盘插上,总线复位后,都能得到CMD_RET_SUCCESS,然后清掉这个复位状态,获取U盘连接信息,也都OK,能够获得USB_INT_CONNECT的响应。再然后就是CMD_DISK_INIT指令的发送,初始化U盘就过不去了,375B始终不响应。现在我急需解决方案。谢谢了
我们有个简单的示例程序是外置固件来操作U盘的.对U盘进行枚举,到读写U盘的物理扇区.你觉得如果有必要可以发邮件到tech@wch.cn索取来试试在枚举阶段是否还会出现死机的状况.
信已发,请查收。谢谢。