📄 usb.lst
字号:
340 };
341 //SCSI-Mode_Sense命令的返回数据
342 code unsigned char B_Mode_Sense_ZERO[] = {0x00, 0x06, //Mode Data Length
343 0x00, //Medium Type Code
344 0, //write enabled
345 0, 0, 0, 0 //reserved
346 };
347
348
349
350
351 void SCSI_Mode_Sense()
352 {
353 1 if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_TPP) //Page Code=Timer and Potect Page
354 1 {WriteEpBulk(1, sizeof(B_Mode_Sense_TPP), B_Mode_Sense_TPP);}
355 1 else if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_RETALL) //Page Code=All
356 1 {WriteEpBulk(1, sizeof(B_Mode_Sense_ALL), B_Mode_Sense_ALL);}
357 1 else {WriteEpBulk(1, sizeof(B_Mode_Sense_ZERO), B_Mode_Sense_ZERO);}
358 1 }
359
360 void SCSI_Read_Format_Capacities()
361 {
362 1 if(bulk_CBW.CBWCB[7]==0 && bulk_CBW.CBWCB[8]==0)return;
363 1 WriteEpBulk(1, sizeof(B_Read_Format_capacities), B_Read_Format_capacities);
364 1 }
365
366
367
368 extern void ReadFlash();
369 extern void WriteFlash();
370
371 void SCSI_Read10()
372 {
373 1 unsigned char data i;
374 1 union
375 1 {
376 1 unsigned long Block;
377 1 unsigned char Addr[4];
378 1 }data BLK;
379 1 unsigned char length; //传输的簇数
380 1 //将起始地址变换为K9F5608适合的模式;
381 1 // BLK.Addr[0] = bulk_CBW.CBWCB[2];
382 1 // BLK.Addr[1] = bulk_CBW.CBWCB[3];
383 1 BLK.Addr[2] = bulk_CBW.CBWCB[4];
C51 COMPILER V7.06 USB 03/21/2006 09:38:04 PAGE 6
384 1 BLK.Addr[3] = bulk_CBW.CBWCB[5];
385 1
386 1 //将扇区数填入计数变量每循环一次读出一扇区的值;
387 1 // PG.Addr[0] = bulk_CBW.CBWCB[7];
388 1 // PG.Addr[1] = bulk_CBW.CBWCB[8];
389 1 length = bulk_CBW.CBWCB[8];
390 1 while(length>0)
391 1 {
392 2
393 2 K9F_FUN = COMMAND; //读出一个page
394 2 *((unsigned char xdata *)K9F5608) = 0x00;
395 2 K9F_FUN = ADDRESS;
396 2 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
397 2 *((unsigned char xdata *)K9F5608) = BLK.Addr[3]; //A9-A16
398 2 *((unsigned char xdata *)K9F5608) = BLK.Addr[2]; //A17-A24
399 2
400 2 K9F_FUN = D_DATA;
401 2 UEPNUM=0x01; //指向端点
402 2 UEPSTAX|=DIR; //传输方向
403 2 while(!(K9F_FUN & RB));
404 2
405 2 for(i=0;i<8;i++) //读出512个字节的数据发送到usb
406 2 {
407 3 ReadFlash();
408 3 UEPSTAX|=TXRDY;
409 3 while(!(UEPSTAX&TXCMP)); //等待发送完成
410 3 UEPSTAX&=(~(TXCMP)); //清中断标志clear TXCMP
411 3 UEPINT=0;
412 3 }
413 2 *((unsigned char xdata *)K9F5608) = INACTIVE;
414 2
415 2 length--; //传输的簇数减1
416 2 BLK.Block ++; //flash的页地址加1
417 2 }
418 1 TransmitCSW(); //返回CSW
419 1 }
420
421
422
423 void delay() //延时20us
424 {
425 1 unsigned char data i=20;
426 1 while(i-->0);
427 1 }
428
429 #define BuffBlock (0xc0) //缓冲区为从偶数块开始的连续两个Block 这里定为2046和2047两个Block
430 //BuffBlock只代表块号的低字节
431 void SCSI_Write10() //之所以选用两个Block作为缓冲区,与Flash的Copy - Back功能的特性相关,
432 { //清仔细阅读Flash 的datasheet
433 1 union
434 1 {
435 1 unsigned long page;
436 1 unsigned char addr[4];
437 1 }data PG;
438 1
439 1 unsigned char data i=0,length=0,nBeginPage=0;
440 1
441 1
442 1 //所有写入都要缓冲,所以先清除缓冲区
443 1 K9F_FUN = COMMAND;
444 1 *((unsigned char xdata *)K9F5608) = 0x60; //擦除第2046个Block作为缓冲区
445 1 K9F_FUN = ADDRESS;
446 1 *((unsigned char xdata *)K9F5608) = BuffBlock; //A9-A16
447 1 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
448 1 K9F_FUN = COMMAND;
449 1 *((unsigned char xdata *)K9F5608) = 0xd0;
450 1 K9F_FUN = D_DATA;
451 1 delay();
452 1 // printuf(" %x",PG.addr[0]);printuf(" %x",PG.addr[1]);printuf(" %x",PG.addr[2]);printuf(" %x",PG.addr[3]);
453 1 // printuf(" %x",length); printuf(" %x",nBeginPage);
454 1 while(!(K9F_FUN & RB)); //等待擦除操作的完成
455 1
456 1 K9F_FUN = COMMAND;
457 1 *((unsigned char xdata *)K9F5608) = 0x60; //擦除第2047个Block作为缓冲区
458 1 K9F_FUN = ADDRESS;
459 1 *((unsigned char xdata *)K9F5608) = BuffBlock|0x20; //A9-A16
460 1 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
461 1 K9F_FUN = COMMAND;
C51 COMPILER V7.06 USB 03/21/2006 09:38:04 PAGE 7
462 1 *((unsigned char xdata *)K9F5608) = 0xd0;
463 1 K9F_FUN = D_DATA;
464 1 //从SCSI命令中分离出逻辑地址
465 1 // PG.addr[0] = bulk_CBW.CBWCB[2];
466 1 // PG.addr[1] = bulk_CBW.CBWCB[3];
467 1 PG.addr[2] = bulk_CBW.CBWCB[4];
468 1 PG.addr[3] = bulk_CBW.CBWCB[5];
469 1
470 1 length = bulk_CBW.CBWCB[8]; //windows 系统每次写入的最大长度为0x80个扇区取一字节已够用
471 1 nBeginPage = PG.addr[3]&0x1f; //计算出要写入块内的要写入的起始扇区号
472 1 UEPNUM = 0x02; //指向Bulk端点2
473 1 delay();
474 1 while(!(K9F_FUN & RB)); //等待擦除操作的完成
475 1
476 1 if(nBeginPage>0) //如果起始写入page与flash的Block未对齐,则将当前Block中的前nBeginPage页
477 1 { //拷贝到缓冲区的相同位置
478 2 for(i=0;i<nBeginPage;i++)
479 2 {
480 3 K9F_FUN = COMMAND;
481 3 *((unsigned char xdata *)K9F5608) = 0x00; //命令的第一个字节
482 3 K9F_FUN = ADDRESS;
483 3 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
484 3 *((unsigned char xdata *)K9F5608) = (PG.addr[3]&0xe0)|i; //A9-A16
485 3 *((unsigned char xdata *)K9F5608) = PG.addr[2]; //A17-A24
486 3 K9F_FUN = D_DATA;
487 3 delay();
488 3 while(!(K9F_FUN & RB)); //等待操作的完成
489 3
490 3 K9F_FUN = COMMAND;
491 3 *((unsigned char xdata *)K9F5608) = 0x8a; //命令的第二个字节
492 3 K9F_FUN = ADDRESS;
493 3 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
494 3 *((unsigned char xdata *)K9F5608) = BuffBlock|(PG.addr[3]&0x20)|i; //A9-A16
495 3 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
496 3 K9F_FUN = D_DATA;
497 3 delay();
498 3 while(!(K9F_FUN & RB)); //等待操作的完成
499 3 }
500 2 nBeginPage=0; //起始扇区值赋为0
501 2 }
502 1
503 1 while(length>0) //传输的扇区数大于0
504 1 {
505 2 K9F_FUN = COMMAND; //数据写入到缓冲区的对应位置
506 2 *((unsigned char xdata *)K9F5608) = 0x80;
507 2 K9F_FUN = ADDRESS;
508 2 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
509 2 *((unsigned char xdata *)K9F5608) = (PG.addr[3]&0x3f)|BuffBlock; //A9-A16
510 2 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
511 2 K9F_FUN = D_DATA;
512 2 for(i=0;i<8;i++) //端点数据写入到Flash的缓冲区
513 2 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -