📄 upsd3400_usb_app.lst
字号:
300
301 How it works:
302 This SW burns data into internal uPSD NOR FLASH. To save FLASH RW cycles,
303 it is looking for empty sector part you are burning in.
C51 COMPILER V7.50 UPSD3400_USB_APP 09/13/2005 18:00:20 PAGE 6
304 If the area is filled by 0xFF only, the sector part is assumed
305 to be erased before, so only data are written directly to the selected flash
306 sector.
307 If not, the sector is copied to the last flash sector #8,
308 erased afterwards and written back (with the updated data block).
309 ******************************************************************************/
310 {
311 1 data unsigned char j,page;
312 1 data unsigned int i,SectorEndPhysicalDataAddr;
313 1
314 1
315 1 UPSD_xreg.DATAOUT_D = 0; // WRITE, RED LED ON !
316 1
317 1 if (TransferLength != 0)
318 1 {
319 2 // Test the block (following 64B).
320 2 USEL = OUTDIR | UMSC_OUT_ENDPOINT; // Select EP3 OUT
321 2
322 2 i = PhysicalDataAddr;
323 2 j = 0;
324 2 // now check whether is necessary to erase the block or not; it saves Flash RW cycles
325 2 while (j<64)
326 2 {
327 3 if (( ( ((unsigned char volatile xdata *) 0)[i]) | USB_FIFO[j]) != 0xFF)
328 3 {
329 4 j = 255;
330 4 }
331 3 else
332 3 {
333 4 i++;
334 4 j++;
335 4 }
336 3 }
337 2
338 2
339 2 if (j == 255) //check whether the sector needs to be erased or not
340 2 {
341 3 page = UPSD_xreg.PAGE;
342 3 UPSD_xreg.PAGE = 7;
343 3
344 3 EraseMainFlashSector(); //erase sector #8;
345 3 //now calculate the max. FLASH area to be erased
346 3 //TransferLength holds number of 64B packets to be received and written
347 3 if ((TransferLength>=512) || ((PhysicalDataAddr+(TransferLength<<6))<0x8000))
348 3 {
349 4 SectorEndPhysicalDataAddr = 0xFFFF; //the top of memory
350 4 }
351 3 else
352 3 {
353 4 SectorEndPhysicalDataAddr = PhysicalDataAddr+(((unsigned int)TransferLength)<<6)-1;
354 4 }
355 3
356 3
357 3 UPSD_xreg.PAGE = page; // the sector part needs to be erased
358 3 i = 0x8000; //now copy the FLASH sector to the flash sector #8
359 3 while (i != 0) // copy only the area without the part we are updating now
360 3 {
361 4 if ((i<PhysicalDataAddr) || (i>SectorEndPhysicalDataAddr)) //write back
362 4 {
363 5 j = ((unsigned char volatile xdata *) 0)[i];
364 5 if (j != 0xFF) // do not write 0xFF
365 5 {
C51 COMPILER V7.50 UPSD3400_USB_APP 09/13/2005 18:00:20 PAGE 7
366 6 UPSD_xreg.PAGE = 7;
367 6 if (WriteToMainFlash(i,j) == TRUE)
368 6 {
369 7 gbCSWStatus = FAIL; //error during write operation occured!
370 7 i = 0xFFFF;
371 7 }
372 6 UPSD_xreg.PAGE = page;
373 6 }
374 5 }
375 4 i++; // this area will be replaced by a new data
376 4 }
377 3
378 3 EraseMainFlashSector(); // erase sector
379 3
380 3
381 3 // now we have a copy of data in the sector #8 with the erase area we need to update
382 3
383 3 i = 0x8000;
384 3 while (i != 0) //copy the rest of data back to the orig. sector
385 3 {
386 4 UPSD_xreg.PAGE = 7;
387 4 j = ((unsigned char volatile xdata *) 0)[i];
388 4 if (j != 0xFF) // do not write 0xFF, already present
389 4 {
390 5 UPSD_xreg.PAGE = page;
391 5 if (WriteToMainFlash(i,j) == TRUE)
392 5 {
393 6 gbCSWStatus = FAIL; //error during write operation occured!
394 6 i = 0xFFFF; //end loop
395 6 }
396 5 }
397 4 i++;
398 4 }
399 3
400 3 UPSD_xreg.PAGE = page;
401 3 }
402 2
403 2
404 2 // Now the sector is ready for write
405 2
406 2 i = PhysicalDataAddr;
407 2 j =0;
408 2 while (j<64) //now burn the data into flash
409 2 {
410 3 if (WriteToMainFlash(i,~USB_FIFO[j]) == TRUE)
411 3 {
412 4 // an error occured, try it again
413 4 gbCSWStatus = FAIL; //error during write operation occured!
414 4 j = 255;
415 4 }
416 3 else
417 3 {
418 4 i++;
419 4 j++;
420 4 }
421 3 }
422 2
423 2
424 2 UCON |= EPFIFO_BSY;
425 2
426 2
427 2 SpecificIncrementSectorAddress();
C51 COMPILER V7.50 UPSD3400_USB_APP 09/13/2005 18:00:20 PAGE 8
428 2 }
429 1
430 1 if (TransferLength == 0)
431 1 {
432 2 ReturnCSW(); // return status
433 2 }
434 1
435 1 UPSD_xreg.DATAOUT_D = 255; // WRITE done, RED LED OFF !
436 1 }
437
438 void ReadBufferFromFlash(void)
439 /******************************************************************************
440 Function : void ReadBufferFromFlash()
441 Parameters : (none)
442 Description: Reads (sends) TransferLength sectors with length of 512 bytes
443 ******************************************************************************/
444 {
445 1
446 1
447 1 if (TransferLength == 0)
448 1 {
449 2 ReturnCSW(); // return status
450 2 }
451 1 else
452 1 {
453 2 #ifdef __RC51__ //Compiler: Raisonance
#pragma asm
;The following equates are also defined in usb.h
; and should be the same in both places.
;The following EQUates are only needed when using RIDE.
USB_BASE_ADDR EQU 7000H ;USB FIFO mapped in XDATA space
INDIR EQU 0
SELEP1 EQU 1
UMSC_IN_ENDPOINT EQU SELEP1
#pragma endasm
#endif
464 2 #pragma asm
465 2 mov DPTM,#0
466 2 mov DPTC,#1
467 2 mov DPH,PhysicalDataAddr+0
468 2 mov DPL,PhysicalDataAddr+1
469 2 mov DPTM,#10
470 2 mov USEL,#INDIR+UMSC_IN_ENDPOINT
471 2 mov DPTC,#0
472 2 mov DPTR,#USB_BASE_ADDR
473 2 mov DPTC,#64+1
474 2 mov B,#64
475 2 movx A,@DPTR
476 2 cpl A
477 2 movx @DPTR,A
478 2 djnz B,$-3
479 2 mov USIZE,#64 ; FIRE!
480 2 mov DPTM,#0
481 2 mov DPTC,#0
482 2 #pragma endasm
483 2 SpecificIncrementSectorAddress();
484 2
485 2 /*gbCSWStatus = FAIL;*/
486 2 }
487 1 }
488
489 void DoReadWrite(void)
C51 COMPILER V7.50 UPSD3400_USB_APP 09/13/2005 18:00:20 PAGE 9
490 /*--------------------------------------------------------------------
491 Function : void DoReadWrite()
492 Parameters : none
493 Description: Handler for READ and WRITE command
494 ---------------------------------------------------------------------*/
495 {
496 1 data unsigned long LogicalBlockAddr;
497 1
498 1 /* Decode the Command Descriptor Block (CDB)
499 1 Byte 0 OPERATION CODE
500 1 Byte 1 Reserved
501 1 Byte 2,3,4,5 (MSB) LOGICAL BLOCK ADDRESS (LSB)
502 1 Byte 6 Reserved
503 1 Byte 7 (MSB)
504 1 Byte 8 TRANSFER LENGTH (LSB)
505 1 Byte 9 CONTROL = 00h
506 1 The LOGICAL BLOCK ADDRESS field specifies the first logical block of the range
507 1 of logical blocks that shall be read.
508 1 The TRANSFER LENGTH field specifies the number of contiguous logical blocks of
509 1 data that shall be transferred. A TRANSFER LENGTH of zero indicates that no logical
510 1 blocks shall be transferred. This condition shall not be considered an error.
511 1 Any other value indicates the number of logical blocks that shall be transferred.
512 1 */
513 1 LogicalBlockAddr = *(unsigned long int *)&gbCBWCB[2];
514 1
515 1 PhysicalDataAddr = ((unsigned int )(LogicalBlockAddr << 9)) | 0x8000;
516 1 UPSD_xreg.PAGE = (unsigned char)(LogicalBlockAddr >> 6);
517 1 TransferLength = *(unsigned int *)&gbCBWCB[7];
518 1 TransferLength = TransferLength*8;
519 1
520 1 gbBulkPipeStage = BS_DATA_PHASE;
521 1
522 1 if (gbCBWFlags & 0x80) // READ command
523 1 {
524 2 ReadBufferFromFlash();
525 2 }
526 1 }
527
528 void OnRequestSense(void)
529 /*--------------------------------------------------------------------
530 Function : void OnRequestSense()
531 Parameters : none
532 Description: Handler for RequestSense command
533 The REQUEST SENSE command requests that the device server
534 transfer sense data to the application client.
535 ---------------------------------------------------------------------*/
536 {
537 1 USEL = INDIR | UMSC_IN_ENDPOINT; //Select EP1 IN
538 1
539 1 USB_FIFO[ 0] = 0x70;
540 1 USB_FIFO[ 1] = 0x00;
541 1 USB_FIFO[ 2] = 0x03; //sense key
542 1 USB_FIFO[ 3] = 0x00;
543 1 USB_FIFO[ 4] = 0x00;
544 1 USB_FIFO[ 5] = 0x00;
545 1 USB_FIFO[ 6] = 0x00;
546 1 USB_FIFO[ 7] = 0x0A; //additional Length
547 1 USB_FIFO[ 8] = 0x00;
548 1 USB_FIFO[ 9] = 0x00;
549 1 USB_FIFO[10] = 0x00;
550 1 USB_FIFO[11] = 0x00;
551 1 USB_FIFO[12] = 0x30; //ASC
C51 COMPILER V7.50 UPSD3400_USB_APP 09/13/2005 18:00:20 PAGE 10
552 1 USB_FIFO[13] = 0x01; //ASCQ
553 1 USB_FIFO[14] = 0x00;
554 1 USB_FIFO[15] = 0x00;
555 1 USB_FIFO[16] = 0x00;
556 1 USB_FIFO[17] = 0x00;
557 1
558 1 USIZE = 18;
559 1
560 1 gbBulkPipeStage = BS_CSW_PHASE;
561 1 }
562
563 void OnInquiry(void)
564 /*--------------------------------------------------------------------
565 Function : void OnInquiry()
566 Parameters : none
567 Description: Handler for Inquiry command
568 ---------------------------------------------------------------------*/
569 {
570 1 USEL = INDIR | UMSC_IN_ENDPOINT; //Select EP1 IN
571 1 USB_FIFO[ 0] = 0x00;
572 1 USB_FIFO[ 1] = 0x80; //b7 = RMB = 1 if the medium is removable
573 1 USB_FIFO[ 2] = 0x00;
574 1 USB_FIFO[ 3] = 0x01;
575 1
576 1 USB_FIFO[ 4] = 36-4; //additional Length (n-4)
577 1 USB_FIFO[ 5] = 0x80;
578 1 USB_FIFO[ 6] = 0x00;
579 1 USB_FIFO[ 7] = 0x01;
580 1
581 1 #ifdef DK3400
582 1 USB_FIFO[ 8] = 'S'; //Vendor Information
583 1 USB_FIFO[ 9] = 'T';
584 1 USB_FIFO[10] = ' ';
585 1 USB_FIFO[11] = ' ';
586 1 USB_FIFO[12] = ' ';
587 1 USB_FIFO[13] = ' ';
588 1 USB_FIFO[14] = ' ';
589 1 USB_FIFO[15] = ' ';
590 1
591 1 USB_FIFO[16] = 'D'; //Product Identification
592 1 USB_FIFO[17] = 'K';
593 1 USB_FIFO[18] = '3';
594 1 USB_FIFO[19] = '4';
595 1 USB_FIFO[20] = '0';
596 1 USB_FIFO[21] = '0';
597 1 USB_FIFO[22] = ' ';
598 1 USB_FIFO[23] = 'D';
599 1 USB_FIFO[24] = 'e';
600 1 USB_FIFO[25] = 'm';
601 1 USB_FIFO[26] = 'o';
602 1 USB_FIFO[27] = ' ';
603 1 USB_FIFO[28] = ' ';
604 1 USB_FIFO[29] = ' ';
605 1 USB_FIFO[30] = ' ';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -