请问关于CH374 数据映射问题

我现在有个项目需要用CH374读取U盘的块数据映射给stm32的usb设备,然后在电脑上以大容量存储设备显示,目前stm32读取SD卡和NAND在电脑端显示都成功了。但是不知道CH374是否可以像SD卡一样以扇区读写用户U盘,能简单解答一下吗,谢谢! 具体是实现 uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length); uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length); 这两个函数

这个我们有例子程序的,支持到读取U盘的物理扇区的主机程序,你可以去下载CH374EVT.ZIP里面有例子程序。


已经下载了,可以问一下是哪个吗?


你用下面的例子程序: UploadImages/2012378364178.rar


谢谢了,我好好研究


我参照了您给的例子,还是枚举不成功,U盘的指示灯不闪烁,能帮忙看一下程序有什么问题吗? #include "stm32f10x.h" #include "stdio.h" #include "bsp_sdio_sd.h" #include "bsp_led.h" #include "mass_mal.h"

#include "bsp_ch374.h" #include "app_usbdisk.h"

#define printf(...)

uint32_t Mass_Memory_Size[2]; uint32_t Mass_Block_Size[2]; uint32_t Mass_Block_Count[2]; //__IO uint32_t Status = 0;

uint32_t Max_Lun = 1; /* 0 表示SD卡, 1表示NAND Flash ,1表示CH374HOST */

UINT8 i, s; UINT8 buf[64];

/* ********************************************************************************************************* * 函 数 名: MAL_Init * 功能说明: 初始化存储设备(用于USB Mass Storage) * 形 参:lun : SCSI逻辑单元号,0表示SD卡,1表示NAND Flash * 返 回 值: MAL_OK : 成功;MAL_FAIL : 失败 ********************************************************************************************************* */ uint16_t MAL_Init(uint8_t lun) { uint16_t status = MAL_OK;

switch (lun) { case MASS_SD: status = SD_Init(); if (status != SD_OK) /* 初始化SDIO硬件设备(配置时钟、GPIO、中断并启动SD卡) */ { mass_printf_err("SD_Init() fail (%d) : file %s on line %d\r\n", status, __FILE__, __LINE__); status = MAL_FAIL; } else { mass_printf_ok("SD_Init() Ok\r\n"); status = MAL_OK; } break;

case MASS_CH374: { Init374Host( ); // 初始化USB主机 HostSetBusFree( ); // 设定USB主机空闲 printf( "Wait Device In\n" ); while ( 1 ) { if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理 if ( Query374DeviceIn( ) ) break; // 有USB设备 } mDelaymS( 200 ); // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动 if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理

printf( "Reset Device\n" ); HostSetBusReset( ); // USB总线复位 for ( i = 0; i < 100; i ++ ) { // 等待USB设备复位后重新连接 if ( Query374DeviceIn( ) ) break; // 有USB设备 mDelaymS( 1 ); } if ( Query374Interrupt( ) ) HostDetectInterrupt( ); // 如果有USB主机中断则处理 if ( Query374DeviceIn( ) ) { // 有USB设备 if ( Query374DevFullSpeed( ) ) { HostSetFullSpeed( ); // 检测到全速USB设备 printf( "Start Full-Speed Device\n" ); } else { // 建议参考EMB_HUB中的低速例子处理 HostSetLowSpeed( ); // 检测到低速USB设备,建议参考EMB_HUB中的低速例子处理 printf( "Start Low-Speed Device\n" ); } } else { printf( "Device gone !\n" ); // continue; // 设备已经断开,继续等待 } mDelaymS( 20 );

printf( "GetDeviceDescr: " ); s = GetDeviceDescr( buf ); // 获取设备描述符 if ( s != ERR_SUCCESS ) { printf( "ERROR = %02X\n", (UINT16)s ); // goto WaitDeviceOut; // 终止操作,等待USB设备拔出 } // for ( i = 0; i < ( (PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL; i ++ ) printf( "%02X ", (UINT16)( buf[i] ) ); printf( "\n" );

printf( "SetUsbAddress: " ); s = SetUsbAddress( 0x02 ); // 设置USB设备地址 if ( s != ERR_SUCCESS ) { printf( "ERROR = %02X\n", (UINT16)s ); //goto WaitDeviceOut; // 终止操作,等待USB设备拔出 } printf( "\n" );

printf( "GetConfigDescr: " ); s = GetConfigDescr( buf ); // 获取配置描述符 if ( s != ERR_SUCCESS ) { printf( "ERROR = %02X\n", (UINT16)s ); // goto WaitDeviceOut; // 终止操作,等待USB设备拔出 } // for ( i = 0; i < ( (PUSB_CFG_DESCR)buf ) -> wTotalLengthL; i ++ ) printf( "%02X ", (UINT16)( buf[i] ) ); printf( "\n" );

/* 分析配置描述符,获取端点数据/各端点地址/各端点大小等,更新变量endp_addr和endp_size等 */ if ( ( (PUSB_CFG_DESCR_LONG)buf ) ->itf_descr.bInterfaceClass != 0x08 ) //goto WaitDeviceOut; /* 不是USB存储类设备 */ mDiskInterfNumber = ( (PUSB_CFG_DESCR_LONG)buf ) ->itf_descr.bInterfaceNumber; /* 接口号 */ mDiskBulkInEndp = 0; mDiskBulkOutEndp = 0; for ( i = 0; i < 2; i ++ ) { /* 分析前两个端点 */ if ( ( (PUSB_CFG_DESCR_LONG)buf ) ->endp_descr[ i ].wMaxPacketSize == 64 && ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].bmAttributes == 2 ) { /* 64字节长度的批量端点 */ if ( ( (PUSB_CFG_DESCR_LONG)buf ) ->endp_descr[ i ].bEndpointAddress & 0x80 ) mDiskBulkInEndp = ( (PUSB_CFG_DESCR_LONG)buf ) -> endp_descr[ i ].bEndpointAddress & 0x0F; /* IN端点 */ else mDiskBulkOutEndp = ( (PUSB_CFG_DESCR_LONG)buf ) ->endp_descr[ i ].bEndpointAddress & 0x0F; /* OUT端点 */ } } if ( ( (PUSB_CFG_DESCR_LONG)buf ) ->itf_descr.bInterfaceClass != 0x08 || mDiskBulkInEndp == 0 || mDiskBulkOutEndp == 0 ) { /* 不是USB存储类设备,不支持 */ printf( "Not USB Mass Storage Device\n" ); //goto WaitDeviceOut; // 终止操作,等待USB设备拔出 }

printf( "SetUsbConfig: " ); s = SetUsbConfig( ( (PUSB_CFG_DESCR)buf ) ->bConfigurationValue ); // 设置USB设备配置 if ( s != ERR_SUCCESS ) { printf( "ERROR = %02X\n", (UINT16)s ); //goto WaitDeviceOut; // 终止操作,等待USB设备拔出 } printf( "\n" ); mSaveDevEndpTog = 0x00; // 清同步标志 } break; default: break; } return status; }

/* ********************************************************************************************************* * 函 数 名: MAL_Write * 功能说明: 写扇区 * 形 参:lun : SCSI逻辑单元号,0表示SD卡,1表示NAND Flash * Memory_Offset : 存储单元偏移地址 * Writebuff :待写入的数据缓冲区的指针 * Transfer_Length :待写入的字节数, 不大于 512 * 返 回 值: MAL_OK : 成功;MAL_FAIL : 失败 ********************************************************************************************************* */ uint16_t MAL_Write(uint8_t lun, uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length) { uint16_t status = MAL_OK; switch (lun) { case MASS_SD: status = SD_WriteBlock((uint8_t*)Writebuff, Memory_Offset, Transfer_Length); if (status != SD_OK) { mass_printf_err("SD_WriteBlock(, 0x%X, 0x%X) Fail(%d) \r\n", Memory_Offset, Transfer_Length, status); status = MAL_FAIL; } else { mass_printf_ok("SD_WriteBlock(, 0x%X, 0x%X) Ok\r\n", Memory_Offset, Transfer_Length); } break;

case MASS_CH374: status = mWriteSector(Memory_Offset, Transfer_Length,(uint8_t*)Writebuff ); if(status != ERR_SUCCESS) { status = MAL_FAIL; } else { status = MAL_OK; } break; default: break; } return status; }

/* ********************************************************************************************************* * 函 数 名: MAL_Read * 功能说明: 读扇区,支持多个扇区 * 形 参:lun : SCSI逻辑单元号,0表示SD卡,1表示NAND Flash * Memory_Offset : 存储单元偏移地址 * Readbuff :存储读出的数据的缓冲区的指针 * Transfer_Length :需要读出的字节数, 不大于 512 * 返 回 值: MAL_OK : 成功;MAL_FAIL : 失败 ********************************************************************************************************* */ uint16_t MAL_Read(uint8_t lun, uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length) { uint16_t status = MAL_OK; switch (lun) { case MASS_SD: status = SD_ReadBlock((uint8_t*)Readbuff, Memory_Offset, Transfer_Length); if (status != SD_OK) { mass_printf_err("SD_ReadBlock(, 0x%X, 0x%X) Fail(%d) \r\n", Memory_Offset, Transfer_Length, status); status = MAL_FAIL; } else { mass_printf_ok("SD_ReadBlock(, 0x%X, 0x%X) Ok\r\n", Memory_Offset, Transfer_Length); status = MAL_OK; } break;

case MASS_CH374: status = mReadSector(Memory_Offset, Transfer_Length,(uint8_t*)Readbuff ); if(status


枚举不成功说明单片机和CH374之间的通信还有问题,上电之后延时100MS之后读取CH374的00H-1FH的寄存器。读取出来的默认值和我们芯片的默认值是否一样。如果一样说明单片机和CH374之间的硬件连线无问题。 还有如果上述无问题建议你查下USB口那边的硬件连线是否有问题。USB口的正确连线为:VCC,D-,D+,GND


非常感谢您的指导和回答,现在功能已经实现了,但是读取的速度只有300k/s左右,想请教一下如何适当提升一下速度。另外想请教一下PC端是如何检测CH374上U盘插拔动作的,是有什么参数吗?


这个主要优化底层的读写子函数(CH374的读写函数)。另外一次尽可能多的进行扇区的读写。


我用的就是您们的例程,主要是优化哪些地方呢


只有登录才能回复,可以选择微信账号登录