CH579-USB Device & Host
USB Device
1 /********************************** (C) COPYRIGHT ******************************* 2 * File Name : Main.c 3 * Author : WCH 4 * Version : V1.0 5 * Date : 2018/12/15 6 * Description : 自定义USB设备(CH372设备),提供8个非0通道(上传+下传),实现数据先下传,然后数据内容取反上传 7 *******************************************************************************/ 8 9 #include "CH57x_common.h" 10 11 #define DevEP0SIZE 0x40 12 // 设备描述符 13 const UINT8 MyDevDescr[] = { 14 0x12, 0x01, 0x10, 0x01,0xFF, 0x80, 0x55, DevEP0SIZE, 15 0x48, 0x43, 0x37, 0x55, // 厂商ID和产品ID 16 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 17 }; 18 // 配置描述符 19 const UINT8 MyCfgDescr[] = { 20 0x09, 0x02, 0x4A, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 21 0x09, 0x04, 0x00, 0x00, 0x08, 0xFF, 0x80, 0x55, 0x00, 22 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x00, 23 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 24 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, 25 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00, 26 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 27 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 28 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 29 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00, 30 }; 31 // 语言描述符 32 const UINT8 MyLangDescr[] = { 0x04, 0x03, 0x09, 0x04 }; 33 // 厂家信息 34 const UINT8 MyManuInfo[] = { 0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 }; 35 // 产品信息 36 const UINT8 MyProdInfo[] = { 0x0C, 0x03, 'C', 0, 'H', 0, '5', 0, '7', 0, 'x', 0 }; 37 38 /**********************************************************/ 39 UINT8 DevConfig; 40 UINT8 SetupReqCode; 41 UINT16 SetupReqLen; 42 const UINT8 *pDescr; 43 44 /******** 用户自定义分配端点RAM ****************************************/ 45 __align(4) UINT8 EP0_Databuf[64+64+64]; //ep0(64)+ep4_out(64)+ep4_in(64) 46 __align(4) UINT8 EP1_Databuf[64+64]; //ep1_out(64)+ep1_in(64) 47 __align(4) UINT8 EP2_Databuf[64+64]; //ep2_out(64)+ep2_in(64) 48 __align(4) UINT8 EP3_Databuf[64+64]; //ep3_out(64)+ep3_in(64) 49 50 51 void USB_DevTransProcess( void ) 52 { 53 UINT8 len, chtype; 54 UINT8 intflag, errflag = 0; 55 56 intflag = R8_USB_INT_FG; 57 if( intflag & RB_UIF_TRANSFER ) 58 { 59 switch ( R8_USB_INT_ST & ( MASK_UIS_TOKEN | MASK_UIS_ENDP ) ) //分析操作令牌和端点号 60 { 61 case UIS_TOKEN_SETUP: 62 R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK; 63 len = R8_USB_RX_LEN; 64 if ( len == sizeof( USB_SETUP_REQ ) ) 65 { 66 SetupReqLen = pSetupReqPak->wLength; 67 SetupReqCode = pSetupReqPak->bRequest; 68 chtype = pSetupReqPak->bRequestType; 69 70 len = 0; 71 errflag = 0; 72 if ( ( pSetupReqPak->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) 73 { 74 errflag = 0xFF; /* 非标准请求 */ 75 } 76 else /* 标准请求 */ 77 { 78 switch( SetupReqCode ) 79 { 80 case USB_GET_DESCRIPTOR: 81 { 82 switch( ((pSetupReqPak->wValue)>>8) ) 83 { 84 case USB_DESCR_TYP_DEVICE: 85 pDescr = MyDevDescr; 86 len = MyDevDescr[0]; 87 break; 88 89 case USB_DESCR_TYP_CONFIG: 90 pDescr = MyCfgDescr; 91 len = MyCfgDescr[2]; 92 break; 93 94 case USB_DESCR_TYP_STRING: 95 switch( (pSetupReqPak->wValue)&0xff ) 96 { 97 case 1: 98 pDescr = MyManuInfo; 99 len = MyManuInfo[0]; 100 break; 101 case 2: 102 pDescr = MyProdInfo; 103 len = MyProdInfo[0]; 104 break; 105 case 0: 106 pDescr = MyLangDescr; 107 len = MyLangDescr[0]; 108 break; 109 default: 110 errflag = 0xFF; // 不支持的字符串描述符 111 break; 112 } 113 break; 114 115 default : 116 errflag = 0xff; 117 break; 118 } 119 if( SetupReqLen>len ) SetupReqLen = len; //实际需上传总长度 120 len = (SetupReqLen >= DevEP0SIZE) ? DevEP0SIZE : SetupReqLen; 121 memcpy( pEP0_DataBuf, pDescr, len ); 122 pDescr += len; 123 } 124 break; 125 126 case USB_SET_ADDRESS: 127 SetupReqLen = (pSetupReqPak->wValue)&0xff; 128 break; 129 130 case USB_GET_CONFIGURATION: 131 pEP0_DataBuf[0] = DevConfig; 132 if ( SetupReqLen > 1 ) SetupReqLen = 1; 133 break; 134 135 case USB_SET_CONFIGURATION: 136 DevConfig = (pSetupReqPak->wValue)&0xff; 137 break; 138 139 case USB_CLEAR_FEATURE: 140 if ( ( pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) //端点 141 { 142 switch( (pSetupReqPak->wIndex)&0xff ) 143 { 144 case 0x82: 145 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~( RB_UEP_T_TOG|MASK_UEP_T_RES )) | UEP_T_RES_NAK; 146 break; 147 case 0x02: 148 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~( RB_UEP_R_TOG|MASK_UEP_R_RES )) | UEP_R_RES_ACK; 149 break; 150 case 0x81: 151 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~( RB_UEP_T_TOG|MASK_UEP_T_RES )) | UEP_T_RES_NAK; 152 break; 153 case 0x01: 154 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~( RB_UEP_R_TOG|MASK_UEP_R_RES )) | UEP_R_RES_ACK; 155 break; 156 default: 157 errflag = 0xFF; // 不支持的端点 158 break; 159 } 160 } 161 else errflag = 0xFF; 162 break; 163 164 case USB_GET_INTERFACE: 165 pEP0_DataBuf[0] = 0x00; 166 if ( SetupReqLen > 1 ) SetupReqLen = 1; 167 break; 168 169 case USB_GET_STATUS: 170 pEP0_DataBuf[0] = 0x00; 171 pEP0_DataBuf[1] = 0x00; 172 if ( SetupReqLen > 2 ) SetupReqLen = 2; 173 break; 174 175 default: 176 errflag = 0xff; 177 break; 178 } 179 } 180 } 181 else errflag = 0xff; 182 183 if( errflag == 0xff) // 错误或不支持 184 { 185 // SetupReqCode = 0xFF; 186 R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL; //STALL 187 } 188 else 189 { 190 if( chtype & 0x80 ) // 上传 191 { 192 len = (SetupReqLen>DevEP0SIZE) ? DevEP0SIZE : SetupReqLen; 193 SetupReqLen -= len; 194 } 195 else len = 0; // 下传 196 197 R8_UEP0_T_LEN = len; 198 R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; //默认数据包是DATA1 199 } 200 break; 201 202 case UIS_TOKEN_IN: 203 switch( SetupReqCode ) 204 { 205 case USB_GET_DESCRIPTOR: 206 len = SetupReqLen >= DevEP0SIZE ? DevEP0SIZE : SetupReqLen;//本次传输长度 207 memcpy( pEP0_DataBuf, pDescr, len ); /* 加载上传数据 */ 208 SetupReqLen -= len; 209 pDescr += len; 210 R8_UEP0_T_LEN = len; 211 R8_UEP0_CTRL ^= RB_UEP_T_TOG; // 翻转 212 break; 213 case USB_SET_ADDRESS: 214 R8_USB_DEV_AD = (R8_USB_DEV_AD&RB_UDA_GP_BIT) | SetupReqLen; 215 R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 216 break; 217 default: 218 R8_UEP0_T_LEN = 0; // 状态阶段完成中断或者是强制上传0长度数据包结束控制传输 219 R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 220 break; 221 } 222 break; 223 224 case UIS_TOKEN_OUT: 225 len = R8_USB_RX_LEN; 226 break; 227 228 case UIS_TOKEN_OUT | 1: 229 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 230 { // 不同步的数据包将丢弃 231 len = R8_USB_RX_LEN; 232 DevEP1_OUT_Deal( len ); 233 } 234 break; 235 236 case UIS_TOKEN_IN | 1: 237 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 238 break; 239 240 case UIS_TOKEN_OUT | 2: 241 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 242 { // 不同步的数据包将丢弃 243 len = R8_USB_RX_LEN; 244 DevEP2_OUT_Deal( len ); 245 } 246 break; 247 248 case UIS_TOKEN_IN | 2: 249 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 250 break; 251 252 case UIS_TOKEN_OUT | 3: 253 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 254 { // 不同步的数据包将丢弃 255 len = R8_USB_RX_LEN; 256 DevEP3_OUT_Deal( len ); 257 } 258 break; 259 260 case UIS_TOKEN_IN | 3: 261 R8_UEP3_CTRL = (R8_UEP3_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 262 break; 263 264 case UIS_TOKEN_OUT | 4: 265 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 266 { 267 R8_UEP4_CTRL ^= RB_UEP_R_TOG; 268 len = R8_USB_RX_LEN; 269 DevEP4_OUT_Deal( len ); 270 } 271 break; 272 273 case UIS_TOKEN_IN | 4: 274 R8_UEP4_CTRL ^= RB_UEP_T_TOG; 275 R8_UEP4_CTRL = (R8_UEP4_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK; 276 break; 277 278 default : 279 break; 280 } 281 R8_USB_INT_FG = RB_UIF_TRANSFER; 282 } 283 else if( intflag & RB_UIF_BUS_RST ) 284 { 285 R8_USB_DEV_AD = 0; 286 R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK; 287 R8_UEP1_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG; 288 R8_UEP2_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG; 289 R8_UEP3_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG; 290 R8_USB_INT_FG |= RB_UIF_BUS_RST; 291 } 292 else if( intflag & RB_UIF_SUSPEND ) 293 { 294 if ( R8_USB_MIS_ST & RB_UMS_SUSPEND ) {;} // 挂起 295 else {;} // 唤醒 296 R8_USB_INT_FG = RB_UIF_SUSPEND; 297 } 298 else 299 { 300 R8_USB_INT_FG = intflag; 301 } 302 } 303 304 305 306 void DebugInit(void) 307 { 308 GPIOA_SetBits(GPIO_Pin_9); 309 GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); 310 GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); 311 UART1_DefInit(); 312 } 313 314 int main() 315 { 316 SetSysClock( CLK_SOURCE_HSE_32MHz ); 317 PWR_UnitModCfg( ENABLE, UNIT_SYS_PLL ); //打开PLL 318 DelayMs(5); 319 320 DebugInit(); 321 printf("start\n"); 322 323 pEP0_RAM_Addr = EP0_Databuf; 324 pEP1_RAM_Addr = EP1_Databuf; 325 pEP2_RAM_Addr = EP2_Databuf; 326 pEP3_RAM_Addr = EP3_Databuf; 327 USB_DeviceInit(); 328 NVIC_EnableIRQ( USB_IRQn ); 329 330 while(1); 331 } 332 333 void DevEP1_OUT_Deal( UINT8 l ) 334 { /* 用户可自定义 */ 335 UINT8 i; 336 337 for(i=0; i<l; i++) 338 { 339 pEP1_IN_DataBuf[i] = ~pEP1_OUT_DataBuf[i]; 340 } 341 DevEP1_IN_Deal( l ); 342 } 343 344 void DevEP2_OUT_Deal( UINT8 l ) 345 { /* 用户可自定义 */ 346 UINT8 i; 347 348 for(i=0; i<l; i++) 349 { 350 pEP2_IN_DataBuf[i] = ~pEP2_OUT_DataBuf[i]; 351 } 352 DevEP2_IN_Deal( l ); 353 } 354 355 void DevEP3_OUT_Deal( UINT8 l ) 356 { /* 用户可自定义 */ 357 UINT8 i; 358 359 for(i=0; i<l; i++) 360 { 361 pEP3_IN_DataBuf[i] = ~pEP3_OUT_DataBuf[i]; 362 } 363 DevEP3_IN_Deal( l ); 364 } 365 366 void DevEP4_OUT_Deal( UINT8 l ) 367 { /* 用户可自定义 */ 368 UINT8 i; 369 370 for(i=0; i<l; i++) 371 { 372 pEP4_IN_DataBuf[i] = ~pEP4_OUT_DataBuf[i]; 373 } 374 DevEP4_IN_Deal( l ); 375 } 376 377 void USB_IRQHandler (void)/*USB中断服务程序,使用寄存器组1 */ 378 { 379 USB_DevTransProcess(); 380 }
U_DISK_EXAM1
1 /********************************** (C) COPYRIGHT ******************************* 2 * File Name : EXAM1.C 3 * Author : WCH 4 * Version : V1.0 5 * Date : 2018/08/15 6 * Description : 7 C语言的U盘文件字节读写示例程序,文件指针偏移,修改文件属性,删除文件等操作 8 支持: FAT12/FAT16/FAT32 9 注意包含 CH579UFI.LIB/USBHOST.C/DEBUG.C 10 *******************************************************************************/ 11 12 /** 不使用U盘文件系统库或者U盘挂载USBhub下面,需要关闭定义 #define FOR_ROOT_UDISK_ONLY */ 13 /** 使用U盘文件系统库,需要开启下面定义, 不使用请关闭 #define DISK_BASE_BUF_LEN 512 */ 14 15 #include "CH57x_common.h" 16 #include "CH579UFI.H" 17 18 __align(4) UINT8 RxBuffer[ MAX_PACKET_SIZE ]; // IN, must even address 19 __align(4) UINT8 TxBuffer[ MAX_PACKET_SIZE ]; // OUT, must even address 20 21 UINT8 buf[100]; //长度可以根据应用自己指定 22 23 24 /* 检查操作状态,如果错误则显示错误代码并停机 */ 25 void mStopIfError( UINT8 iError ) 26 { 27 if ( iError == ERR_SUCCESS ) 28 { 29 return; /* 操作成功 */ 30 } 31 printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 */ 32 /* 遇到错误后,应该分析错误码以及CH554DiskStatus状态,例如调用CH579DiskReady查询当前U盘是否连接,如果U盘已断开那么就重新等待U盘插上再操作, 33 建议出错后的处理步骤: 34 1、调用一次CH579DiskReady,成功则继续操作,例如Open,Read/Write等 35 2、如果CH579DiskReady不成功,那么强行将从头开始操作(等待U盘连接,CH554DiskReady等) */ 36 while ( 1 ) 37 { } 38 } 39 40 int main( ) 41 { 42 UINT8 s, c, i; 43 // UINT16 TotalCount; 44 45 SetSysClock( CLK_SOURCE_HSE_32MHz ); 46 PWR_UnitModCfg( ENABLE, UNIT_SYS_PLL ); // 打开PLL 47 DelayMs(5); 48 49 GPIOA_SetBits(GPIO_Pin_9); 50 GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); 51 GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); 52 UART1_DefInit(); 53 PRINT( "Start @ChipID=%02X %s \n", R8_CHIP_ID, __TIME__); 54 55 pHOST_RX_RAM_Addr = RxBuffer; 56 pHOST_TX_RAM_Addr = TxBuffer; 57 USB_HostInit(); 58 CH579LibInit( ); //初始化U盘程序库以支持U盘文件 59 60 FoundNewDev = 0; 61 while ( 1 ) 62 { 63 s = ERR_SUCCESS; 64 if ( R8_USB_INT_FG & RB_UIF_DETECT ) // 如果有USB主机检测中断则处理 65 { 66 R8_USB_INT_FG = RB_UIF_DETECT ; // 清连接中断标志 67 s = AnalyzeRootHub( ); // 分析ROOT-HUB状态 68 if ( s == ERR_USB_CONNECT ) FoundNewDev = 1; 69 } 70 71 if ( FoundNewDev || s == ERR_USB_CONNECT ) // 有新的USB设备插入 72 { 73 FoundNewDev = 0; 74 mDelaymS( 200 ); // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动 75 s = InitRootDevice(); // 初始化USB设备 76 if ( s == ERR_SUCCESS ) 77 { 78 // U盘操作流程:USB总线复位、U盘连接、获取设备描述符和设置USB地址、可选的获取配置描述符,之后到达此处,由CH579子程序库继续完成后续工作 79 CH579DiskStatus = DISK_USB_ADDR; 80 for ( i = 0; i != 10; i ++ ) 81 { 82 printf( "Wait DiskReady\n" ); 83 s = CH579DiskReady( ); //等待U盘准备好 84 if ( s == ERR_SUCCESS ) 85 { 86 break; 87 } 88 else 89 { 90 printf("%02x\n",(UINT16)s); 91 } 92 mDelaymS( 50 ); 93 } 94 95 if ( CH579DiskStatus >= DISK_MOUNTED ) 96 { 97 // /* 读文件 */ 98 // strcpy( mCmdParam.Open.mPathName, "/C51/CH579HFT.C" ); //设置将要操作的文件路径和文件名/C51/CH579HFT.C 99 // s = CH579FileOpen( ); //打开文件 100 // if ( s == ERR_MISS_DIR || s == ERR_MISS_FILE ) { //没有找到文件 101 // printf( "没有找到文件\n" ); 102 // } 103 // else 104 // { //找到文件或者出错 105 // TotalCount = 100; //设置准备读取总长度100字节 106 // printf( "读出的前%d个字符是:\n",TotalCount ); 107 // while ( TotalCount ) { //如果文件比较大,一次读不完,可以再调用CH579ByteRead继续读取,文件指针自动向后移动 108 // if ( TotalCount > (MAX_PATH_LEN-1) ) c = MAX_PATH_LEN-1;//剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.Other.mBuffer ) 109 // else c = TotalCount;//最后剩余的字节数 110 // mCmdParam.ByteRead.mByteCount = c; //请求读出几十字节数据 111 // mCmdParam.ByteRead.mByteBuffer= &buf[0]; 112 // s = CH579ByteRead( ); //以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读 113 // TotalCount -= mCmdParam.ByteRead.mByteCount; //计数,减去当前实际已经读出的字符数 114 // for ( i=0; i!=mCmdParam.ByteRead.mByteCount; i++ ) printf( "%C", mCmdParam.ByteRead.mByteBuffer[i] );//显示读出的字符 115 // if ( mCmdParam.ByteRead.mByteCount < c ) { //实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾 116 // printf( "\n" ); 117 // printf( "文件已经结束\n" ); 118 // break; 119 // } 120 // } 121 // printf( "Close\n" ); 122 // i = CH579FileClose( ); // 关闭文件 123 // mStopIfError( i ); 124 // } 125 // /*如果希望从指定位置开始读写,可以移动文件指针 */ 126 // mCmdParam.ByteLocate.mByteOffset = 608; //跳过文件的前608个字节开始读写 127 // CH579ByteLocate( ); 128 // mCmdParam.ByteRead.mByteCount = 5; //读取5个字节 129 // mCmdParam.ByteRead.mByteBuffer= &buf[0]; 130 // CH579ByteRead( ); //直接读取文件的第608个字节到612个字节数据,前608个字节被跳过 131 // //如果希望将新数据添加到原文件的尾部,可以移动文件指针 132 // CH579FileOpen( ); 133 // mCmdParam.ByteLocate.mByteOffset = 0xffffffff; //移到文件的尾部 134 // CH579ByteLocate( ); 135 // mCmdParam.ByteWrite.mByteCount = 13; //写入13个字节的数据 136 // CH579ByteWrite( ); //在原文件的后面添加数据,新加的13个字节接着原文件的尾部放置 137 // mCmdParam.ByteWrite.mByteCount = 2; //写入2个字节的数据 138 // CH579ByteWrite( ); //继续在原文件的后面添加数据 139 // mCmdParam.ByteWrite.mByteCount = 0; //写入0个字节的数据,实际上该操作用于通知程序库更新文件长度 140 // CH579ByteWrite( ); //写入0字节的数据,用于自动更新文件的长度,所以文件长度增加15,如果不这样做,那么执行CH554FileClose时也会自动更新文件长度 141 //创建文件演示 142 printf( "Create\n" ); 143 strcpy( (PCHAR)mCmdParam.Create.mPathName, "/NEWFILE.TXT" ); // 新文件名,在根目录下,中文文件名 144 s = CH579FileCreate( ); //新建文件并打开,如果文件已经存在则先删除后再新建 145 mStopIfError( s ); 146 printf( "ByteWrite\n" ); 147 //实际应该判断写数据长度和定义缓冲区长度是否相符,如果大于缓冲区长度则需要多次写入 148 i = sprintf( (PCHAR)buf,"Note: \xd\xa这个程序是以字节为单位进行U盘文件读写,579简单演示功能。\xd\xa"); //演示 149 for(c=0; c<10; c++) 150 { 151 mCmdParam.ByteWrite.mByteCount = i; //指定本次写入的字节数 152 mCmdParam.ByteWrite.mByteBuffer = buf; //指向缓冲区 153 s = CH579ByteWrite( ); //以字节为单位向文件写入数据 154 mStopIfError( s ); 155 printf("成功写入 %02X次\n",(UINT16)c); 156 } 157 //演示修改文件属性 158 // printf( "Modify\n" ); 159 // mCmdParam.Modify.mFileAttr = 0xff; //输入参数: 新的文件属性,为0FFH则不修改 160 // mCmdParam.Modify.mFileTime = 0xffff; //输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间 161 // mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2015, 5, 18 ); //输入参数: 新的文件日期: 2015.05.18 162 // mCmdParam.Modify.mFileSize = 0xffffffff; // 输入参数: 新的文件长度,以字节为单位写文件应该由程序库关闭文件时自动更新长度,所以此处不修改 163 // i = CH579FileModify( ); //修改当前文件的信息,修改日期 164 // mStopIfError( i ); 165 printf( "Close\n" ); 166 mCmdParam.Close.mUpdateLen = 1; //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度 167 i = CH579FileClose( ); 168 mStopIfError( i ); 169 170 // strcpy( (PCHAR)mCmdParam.Create.mPathName, "/NEWFILE.TXT" ); //新文件名,在根目录下,中文文件名 171 // s = CH579FileOpen( ); // 新建文件并打开,如果文件已经存在则先删除后再新建 172 // mStopIfError( s ); 173 174 175 // /* 删除某文件 */ 176 // printf( "Erase\n" ); 177 // strcpy( mCmdParam.Create.mPathName, "/OLD" ); //将被删除的文件名,在根目录下 178 // i = CH579FileErase( ); //删除文件并关闭 179 // if ( i != ERR_SUCCESS ) printf( "Error: %02X\n", (UINT16)i ); //显示错误 180 } 181 } 182 } 183 mDelaymS( 100 ); // 模拟单片机做其它事 184 SetUsbSpeed( 1 ); // 默认为全速 185 } 186 }
USB dev in Reset host port GetDevDescr: x12 x01 x00 x02 x00 x00 x00 x40 x08 x19 x26 x02 x11 x01 x00 x00 x00 x01 GetCfgDescr: x09 x02 x20 x00 x01 x01 x00 x80 x32 x09 x04 x00 x00 x02 x08 x06 x50 x00 x07 x05 x01 x02 x40 x00 x00 x07 x05 x81 x02 x40 x00 x00 Wait DiskReady Create ByteWrite 成功写入 00次 成功写入 01次 成功写入 02次 成功写入 03次 成功写入 04次 成功写入 05次 成功写入 06次 成功写入 07次 成功写入 08次 成功写入 09次 Close USB dev out
U_DISK_EXAM11
1 /********************************** (C) COPYRIGHT ******************************* 2 * File Name : EXAM11.C 3 * Author : WCH 4 * Version : V1.0 5 * Date : 2018/08/15 6 * Description : CH579 C语言的U盘目录文件枚举程序 7 支持: FAT12/FAT16/FAT32 8 注意包含 CH579UFI.LIB/USBHOST.C/DEBUG.C 9 *******************************************************************************/ 10 11 /** 不使用U盘文件系统库或者U盘挂载USBhub下面,需要关闭定义 #define FOR_ROOT_UDISK_ONLY */ 12 /** 使用U盘文件系统库,需要开启下面定义, 不使用请关闭 #define DISK_BASE_BUF_LEN 512 */ 13 14 15 #include "CH57x_common.h" 16 #include "CH579UFI.H" 17 18 __align(4) UINT8 RxBuffer[ MAX_PACKET_SIZE ]; // IN, must even address 19 __align(4) UINT8 TxBuffer[ MAX_PACKET_SIZE ]; // OUT, must even address 20 21 22 /* 检查操作状态,如果错误则显示错误代码并停机 */ 23 void mStopIfError( UINT8 iError ) 24 { 25 if ( iError == ERR_SUCCESS ) 26 { 27 return; /* 操作成功 */ 28 } 29 printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 */ 30 /* 遇到错误后,应该分析错误码以及CH579DiskStatus状态,例如调用CH579DiskReady查询当前U盘是否连接,如果U盘已断开那么就重新等待U盘插上再操作, 31 建议出错后的处理步骤: 32 1、调用一次CH579DiskReady,成功则继续操作,例如Open,Read/Write等 33 2、如果CH579DiskReady不成功,那么强行将从头开始操作(等待U盘连接,CH579DiskReady等) */ 34 while ( 1 ) 35 { } 36 } 37 38 39 int main( ) 40 { 41 UINT8 s, i; 42 PUINT8 pCodeStr; 43 UINT16 j; 44 45 SetSysClock( CLK_SOURCE_HSE_32MHz ); 46 PWR_UnitModCfg( ENABLE, UNIT_SYS_PLL ); //打开PLL 47 DelayMs(5); 48 49 GPIOA_SetBits(GPIO_Pin_9); 50 GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); 51 GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); 52 UART1_DefInit(); 53 PRINT( "Start @ChipID=%02X %s \n", R8_CHIP_ID, __TIME__); 54 55 pHOST_RX_RAM_Addr = RxBuffer; 56 pHOST_TX_RAM_Addr = TxBuffer; 57 USB_HostInit(); 58 CH579LibInit( ); //初始化U盘程序库以支持U盘文件 59 60 61 FoundNewDev = 0; 62 printf( "Wait Device In\n" ); 63 while ( 1 ) 64 { 65 s = ERR_SUCCESS; 66 if ( R8_USB_INT_FG & RB_UIF_DETECT ) // 如果有USB主机检测中断则处理 67 { 68 R8_USB_INT_FG = RB_UIF_DETECT ; // 清连接中断标志 69 s = AnalyzeRootHub( ); // 分析ROOT-HUB状态 70 if ( s == ERR_USB_CONNECT ) FoundNewDev = 1; 71 } 72 73 if ( FoundNewDev || s == ERR_USB_CONNECT ) 74 { 75 // 有新的USB设备插入 76 FoundNewDev = 0; 77 mDelaymS( 200 ); // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动 78 s = InitRootDevice( ); // 初始化USB设备 79 if ( s == ERR_SUCCESS ) 80 { 81 printf( "Start UDISK_demo @CH579UFI library\n" ); 82 // U盘操作流程:USB总线复位、U盘连接、获取设备描述符和设置USB地址、可选的获取配置描述符,之后到达此处,由CH579子程序库继续完成后续工作 83 CH579DiskStatus = DISK_USB_ADDR; 84 for ( i = 0; i != 10; i ++ ) 85 { 86 printf( "Wait DiskReady\n" ); 87 s = CH579DiskReady( ); 88 if ( s == ERR_SUCCESS ) 89 { 90 break; 91 } 92 mDelaymS( 50 ); 93 } 94 if ( CH579DiskStatus >= DISK_MOUNTED ) //U盘准备好 95 { 96 /* 读文件 */ 97 printf( "Open\n" ); 98 strcpy( (PCHAR)mCmdParam.Open.mPathName, "/C51/CH579HFT.C" ); //设置要操作的文件名和路径 99 s = CH579FileOpen( ); //打开文件 100 if ( s == ERR_MISS_DIR ) 101 { 102 printf("不存在该文件夹则列出根目录所有文件\n"); 103 pCodeStr = (PUINT8)"/*"; 104 } 105 else 106 { 107 pCodeStr = (PUINT8)"/C51/*"; //列出\C51子目录下的的文件 108 } 109 110 printf( "List file %s\n", pCodeStr ); 111 for ( j = 0; j < 10000; j ++ ) //限定10000个文件,实际上没有限制 112 { 113 strcpy( (PCHAR)mCmdParam.Open.mPathName, (PCCHAR)pCodeStr );//搜索文件名,*为通配符,适用于所有文件或者子目录 114 i = strlen( (PCHAR)mCmdParam.Open.mPathName ); 115 mCmdParam.Open.mPathName[ i ] = 0xFF; //根据字符串长度将结束符替换为搜索的序号,从0到254,如果是0xFF即255则说明搜索序号在CH579vFileSize变量中 116 CH579vFileSize = j; //指定搜索/枚举的序号 117 i = CH579FileOpen( ); //打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 118 /* CH579FileEnum 与 CH579FileOpen 的唯一区别是当后者返回ERR_FOUND_NAME时那么对应于前者返回ERR_SUCCESS */ 119 if ( i == ERR_MISS_FILE ) 120 { 121 break; //再也搜索不到匹配的文件,已经没有匹配的文件名 122 } 123 if ( i == ERR_FOUND_NAME ) //搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 124 { 125 printf( " match file %04d#: %s\n", (unsigned int)j, mCmdParam.Open.mPathName ); //显示序号和搜索到的匹配文件名或者子目录名 126 continue; //继续搜索下一个匹配的文件名,下次搜索时序号会加1 127 } 128 else //出错 129 { 130 mStopIfError( i ); 131 break; 132 } 133 } 134 i = CH579FileClose( ); //关闭文件 135 printf( "U盘演示完成\n" ); 136 } 137 else 138 { 139 printf( "U盘没有准备好 ERR =%02X\n", (UINT16)s ); 140 } 141 } 142 else 143 { 144 printf("初始化U盘失败,请拔下U盘重试\n"); 145 } 146 } 147 mDelaymS( 100 ); // 模拟单片机做其它事 148 SetUsbSpeed( 1 ); // 默认为全速 149 } 150 }
Start @ChipID=79 14:22:47 Wait Device In USB dev in Reset host port GetDevDescr: x12 x01 x00 x02 x00 x00 x00 x40 x08 x19 x26 x02 x11 x01 x00 x00 x00 x01 GetCfgDescr: x09 x02 x20 x00 x01 x01 x00 x80 x32 x09 x04 x00 x00 x02 x08 x06 x50 x00 x07 x05 x01 x02 x40 x00 x00 x07 x05 x81 x02 x40 x00 x00 Start UDISK_demo @CH579UFI library Wait DiskReady Open 不存在该文件夹则列出根目录所有文件 List file /* match file 0000#: /SYSTEM~1 match file 0001#: /ANTUTU~1.APK match file 0002#: /LOST.DIR match file 0003#: /ANDROID match file 0004#: /NEWFILE.TXT U盘演示完成