/********************************** (C) COPYRIGHT ******************************* * File Name : SW_CDROM.C * Author : WCH * Version : V1.0.1 * Date : 2022/11/24 * Description : CD-ROM Source File ******************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ /******************************************************************************/ /* Header Files */ #include #include #include "usb_lib.h" #include "ch32v20x_spi.h" /******************************************************************************/ /* Variable Definition */ __attribute__ ((aligned(4))) uint8_t CDROM_Pack_Buffer[DEF_CDROM_PACK_64]; /******************************************************************************/ /* INQUITY */ uint8_t CDROM_Inquity_Tab[ ] = { 0x05, /* Peripheral Device CD-ROM = 0x05 */ 0x80, /* Removable */ 0x02, /* ISO/ECMA */ 0x02, 0x1F, /* Additional Length */ 0x00, /* Reserved */ 0x00, /* Reserved */ 0x00, /* Reserved */ 'F', /* Vendor Information */ 'l', 'a', 's', 'h', ' ', ' ', ' ', 'U', 'S', 'B', ' ', 'S', 'p', 'e', 'c', 'i', 'a', 'l', ' ', 'D', 'i', 's', 'k', '2', '.', 'D', '0' }; /******************************************************************************/ /* formatted capacity information */ uint8_t CDROM_Rd_Format_Capacity[ ] = { 0x00, 0x00, 0x00, 0x08, ( MY_CDROM_SIZE >> 24 ) & 0xFF, ( MY_CDROM_SIZE >> 16 ) & 0xFF, ( MY_CDROM_SIZE >> 8 ) & 0xFF, ( MY_CDROM_SIZE ) & 0xFF, 0x02, ( DEF_CFG_DISK_SEC_SIZE >> 16 ) & 0xFF, /* Number of Blocks */ ( DEF_CFG_DISK_SEC_SIZE >> 8 ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE ) & 0xFF, }; /******************************************************************************/ /* capacity information */ uint8_t CDROM_Rd_Capacity[ ] = { ( ( MY_CDROM_SIZE - 1 ) >> 24 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) >> 16 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) >> 8 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE >> 24 ) & 0xFF, /* Number of Blocks */ ( DEF_CFG_DISK_SEC_SIZE >> 16 ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE >> 8 ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE ) & 0xFF, }; /******************************************************************************/ /* MODE_SENSE data,For CMD 0X1A */ uint8_t CDROM_Mode_Sense_1A[ ] = { 0x0B, 0x00, 0x00, /* 0x00:write-unprotected,0x80:write-protected */ 0x08, ( ( MY_CDROM_SIZE - 1 ) >> 24 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) >> 16 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) >> 8 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE >> 24 ) & 0xFF, /* Number of Blocks */ ( DEF_CFG_DISK_SEC_SIZE >> 16 ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE >> 8 ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE ) & 0xFF, }; /******************************************************************************/ /* MODE_SENSE data,For CMD 0X5A */ uint8_t CDROM_Mode_Senese_5A[ ] = { 0x00, 0x0E, 0x00, 0x00, /* 0x00:write-unprotected,0x80:write-protected */ 0x00, 0x00, 0x00, 0x08, ( ( MY_CDROM_SIZE - 1 ) >> 24 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) >> 16 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) >> 8 ) & 0xFF, ( ( MY_CDROM_SIZE - 1 ) ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE >> 24 ) & 0xFF, /* Number of Blocks */ ( DEF_CFG_DISK_SEC_SIZE >> 16 ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE >> 8 ) & 0xFF, ( DEF_CFG_DISK_SEC_SIZE ) & 0xFF, }; /* command response ->0x46 */ uint8_t CDROM_CMD46_Ret[ 136 ] = { 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, 0x03, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x04, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x1D, 0x03, 0x00, 0x00, 0x1E, 0x05, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2D, 0x01, 0x04, 0x17, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x01, 0x04, 0x2F, 0x00, 0x20, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x03, 0x00, 0x04, 0x07, 0x00, 0x00, 0xFF, 0x01, 0x08, 0x03, 0x0C, 0x41, 0x41, 0x30, 0x31, 0x20, 0x30, 0x30, 0x38, 0x31, 0x39, 0x37, 0x20 }; /* command response ->0x4A */ uint8_t CDROM_CMD4A_00_Ret[ 4 ] = { /* Event Header Return Data */ 0x00, 0x02, /* Event Data Length */ 0x04, /* Returns Media Class events */ 0x10 /* support Media Status Class Events */ }; uint8_t CDROM_CMD4A_10_Ret[ 8 ] = { 0x00, 0x06, /* Event Header Return Data */ 0x84, /* NEA=1 */ 0x10, 0x00, 0x00, 0x00, 0x00 /* Media Event Descriptor */ }; /* command response ->0x43 */ uint8_t CDROM_CMD43_40_Ret[ 12 ] = { 0x00, 0x0a, /* number of bytes below */ 0x01, /*first track */ 0x01, /* last track */ 0x00, /* reserved */ 0x14, /* (adr, control) */ 0x01, /* (track being described) */ 0x00, /* (reserved) */ 0x00, (uint8_t)( ( MY_CDROM_SIZE - 1 ) >>16 ), (uint8_t)( ( MY_CDROM_SIZE - 1 ) >> 8 ), (uint8_t)( MY_CDROM_SIZE - 1 ) /* (start logical block address 0) */ }; uint8_t CDROM_CMD43_00_Ret[ 20 ] = { 0x00, 0x12, /* number of bytes below */ 0x01, /* first track */ 0x01, /* last track */ 0x00, /* reserved */ 0x14, /* (adr, control) */ 0x01, /* (track being described) */ 0x00, /* (reserved) */ 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0xaa, 0x00, 0x00, (uint8_t)( ( MY_CDROM_SIZE - 1 ) >> 16 ), (uint8_t)( ( MY_CDROM_SIZE - 1 ) >> 8 ), (uint8_t)( MY_CDROM_SIZE - 1 ) /* (start logical block address 0) */ }; const uint8_t CDROM_CMD43_80_Ret[ 48 ] = { 0x00, 0x2E, 0x01, 0x01, 0x01, 0x14, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x01, 0x14, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x14, 0x00, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2F, 0x3D, 0x01, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00 }; /******************************************************************************/ /* command response ->0x51 */ const uint8_t CDROM_CMD51_Ret[ 28 ] = { 0x00, 0x20, 0x0e, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; /******************************************************************************/ /* command response ->0x52 */ const uint8_t CDROM_CMD52_Ret[ 28 ] = { 0x00, 0x1A, 0x01, 0x01, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00 }; const uint8_t CDROM_CMD5A_2A_Ret[ 28 ] = { 0x00, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x12, 0x07, 0x07, 0x70, 0x00, 0x28, 0x00, 0x56, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x56, 0xa0, 0x00, 0x00, 0x00, 0x00 }; volatile uint8_t CDROM_Status = 0x00; volatile uint8_t CDROM_Transfer_Status = 0x00; volatile uint32_t CDROM_Capability = 0x00; volatile uint8_t CDROM_CBW_Tag_Save[ 4 ]; volatile uint8_t CDROM_Sense_Key = 0x00; volatile uint8_t CDROM_Sense_ASC = 0x00; volatile uint8_t CDROM_CSW_Status = 0x00; volatile uint32_t CDROM_Transfer_DataLen = 0x00; volatile uint32_t CDROM_Cur_Sec_Lba = 0x00; volatile uint16_t CDROM_Sec_Pack_Count = 0x00; volatile uint16_t CDROM_Pack_Size = DEF_CDROM_PACK_64; BULK_ONLY_CMD mBOC; uint8_t *pEndp2_Buf; /******************************************************************************* * Function Name : CDROM_CMD_Deal_Ret_ErrorData * Description : * Input : None * Output : None * Return : None *******************************************************************************/ void CDROM_CMD_Deal_Ret_ErrorData() { uint16_t i; /* Upload 60 bytes of all 0 data */ if( CDROM_Transfer_DataLen ) { if( CDROM_Transfer_DataLen > 60 ) { CDROM_Transfer_DataLen = 60; } for( i = 0x00; i < CDROM_Transfer_DataLen; i++ ) { mBOC.buf[ i ] = 0x00; } pEndp2_Buf = mBOC.buf; } } /******************************************************************************* * Function Name : CDROM_CMD_Deal_Status * Description : Current command execution status * Input : key------Primary key for disk error details * asc------Minor key for disk error details * status---Current command execution result status * Output : None * Return : None *******************************************************************************/ void CDROM_CMD_Deal_Status( uint8_t key, uint8_t asc, uint8_t status ) { CDROM_Sense_Key = key; CDROM_Sense_ASC = asc; CDROM_CSW_Status = status; } /******************************************************************************* * Function Name : CDROM_CMD_Deal_Fail * Description : The current command failed to execute * Input : None * Output : None * Return : None *******************************************************************************/ void CDROM_CMD_Deal_Fail( void ) { if( CDROM_Transfer_Status & DEF_CDROM_BLUCK_UP_FLAG ) { /* EP2 -> STALL */ SetEPTxStatus(ENDP2, EP_TX_STALL); CDROM_Transfer_Status &= ~DEF_CDROM_BLUCK_DOWN_FLAG; } if( CDROM_Transfer_Status & DEF_CDROM_BLUCK_DOWN_FLAG ) { /* EP3 -> STALL */ SetEPRxStatus(ENDP3, EP_RX_STALL); CDROM_Transfer_Status &= ~DEF_CDROM_BLUCK_DOWN_FLAG; } } /******************************************************************************* * Function Name : CMD_RD_WR_Deal_Pre * Description : Preparation before read and write sector processing * Input : None * Output : None * Return : None *******************************************************************************/ void CMD_RD_WR_Deal_Pre( void ) { /* Save the sector number to be operated currently */ CDROM_Cur_Sec_Lba = (uint32_t)mBOC.mCBW.mCBW_CB_Buf[ 2 ] << 24; CDROM_Cur_Sec_Lba = CDROM_Cur_Sec_Lba + ( (uint32_t)mBOC.mCBW.mCBW_CB_Buf[ 3 ] << 16 ); CDROM_Cur_Sec_Lba = CDROM_Cur_Sec_Lba + ( (uint32_t)mBOC.mCBW.mCBW_CB_Buf[ 4 ] << 8 ); CDROM_Cur_Sec_Lba = CDROM_Cur_Sec_Lba + ( (uint32_t)mBOC.mCBW.mCBW_CB_Buf[ 5 ] ); /* Save the current length of data to be manipulated */ CDROM_Transfer_DataLen = ( (uint32_t)mBOC.mCBW.mCBW_CB_Buf[ 7 ] << 8 ); CDROM_Transfer_DataLen = CDROM_Transfer_DataLen + ( (uint32_t)mBOC.mCBW.mCBW_CB_Buf[ 8 ] ); CDROM_Transfer_DataLen = CDROM_Transfer_DataLen * DEF_CDROM_SECTOR_SIZE; /* Clear related variables */ CDROM_Sec_Pack_Count = 0x00; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); } /******************************************************************************* * Function Name : CDROM_SCSI_CMD_Deal * Description : dealing SCSI command * Input : None * Output : None * Return : None *******************************************************************************/ void CDROM_SCSI_CMD_Deal( void ) { uint8_t i; if( ( mBOC.mCBW.mCBW_Sig[ 0 ] == 'U' ) && ( mBOC.mCBW.mCBW_Sig[ 1 ] == 'S' ) &&( mBOC.mCBW.mCBW_Sig[ 2 ] == 'B' ) && ( mBOC.mCBW.mCBW_Sig[ 3 ] == 'C' ) ) { CDROM_CBW_Tag_Save[ 0 ] = mBOC.mCBW.mCBW_Tag[ 0 ]; CDROM_CBW_Tag_Save[ 1 ] = mBOC.mCBW.mCBW_Tag[ 1 ]; CDROM_CBW_Tag_Save[ 2 ] = mBOC.mCBW.mCBW_Tag[ 2 ]; CDROM_CBW_Tag_Save[ 3 ] = mBOC.mCBW.mCBW_Tag[ 3 ]; CDROM_Transfer_DataLen = ( uint32_t )mBOC.mCBW.mCBW_DataLen[ 3 ] << 24; CDROM_Transfer_DataLen += ( ( uint32_t )mBOC.mCBW.mCBW_DataLen[ 2 ] << 16 ); CDROM_Transfer_DataLen += ( ( uint32_t )mBOC.mCBW.mCBW_DataLen[ 1 ] << 8 ); CDROM_Transfer_DataLen += ( ( uint32_t )mBOC.mCBW.mCBW_DataLen[ 0 ] ); if( CDROM_Transfer_DataLen ) { if( mBOC.mCBW.mCBW_Flag & 0x80 ) { CDROM_Transfer_Status |= DEF_CDROM_BLUCK_UP_FLAG; } else { CDROM_Transfer_Status |= DEF_CDROM_BLUCK_DOWN_FLAG; } } CDROM_Transfer_Status |= DEF_CDROM_CSW_UP_FLAG; /* SCSI command packet processing */ switch( mBOC.mCBW.mCBW_CB_Buf[ 0 ] ) { case CMD_U_INQUIRY: /* CMD: 0x12 */ if( CDROM_Transfer_DataLen > 0x24 ) { CDROM_Transfer_DataLen = 0x24; } /* Add upload FLASH chip ID number */ CDROM_Inquity_Tab[ 32 ] = (uint8_t)( Flash_ID >> 24 ); CDROM_Inquity_Tab[ 33 ] = (uint8_t)( Flash_ID >> 16 ); CDROM_Inquity_Tab[ 34 ] = (uint8_t)( Flash_ID >> 8 ); CDROM_Inquity_Tab[ 35 ] = (uint8_t)( Flash_ID ); /* CD-ROM Mode */ CDROM_Inquity_Tab[ 0 ] = 0x05; pEndp2_Buf = (uint8_t *)CDROM_Inquity_Tab; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); break; case CMD_U_READ_FORMAT_CAPACITY: /* CMD: 0x23 */ if( ( CDROM_Status & DEF_CDROM_EN_FLAG ) ) { if( CDROM_Transfer_DataLen > 0x0C ) { CDROM_Transfer_DataLen = 0x0C; } for( i = 0x00; i < CDROM_Transfer_DataLen; i++ ) { mBOC.buf[ i ] = CDROM_Rd_Format_Capacity[ i ]; } mBOC.buf[ 4 ] = ( ( CDROM_Capability >> 24 ) & 0xFF ); mBOC.buf[ 5 ] = ( ( CDROM_Capability >> 16 ) & 0xFF ); mBOC.buf[ 6 ] = ( ( CDROM_Capability >> 8 ) & 0xFF ); mBOC.buf[ 7 ] = ( ( CDROM_Capability ) & 0xFF ); pEndp2_Buf = mBOC.buf; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); } else { CDROM_CMD_Deal_Status( 0x02, 0x3A, 0x01 ); CDROM_CMD_Deal_Fail( ); } break; case CMD_U_READ_CAPACITY: /* CMD: 0x25 */ if( ( CDROM_Status & DEF_CDROM_EN_FLAG ) ) { if( CDROM_Transfer_DataLen > 0x08 ) { CDROM_Transfer_DataLen = 0x08; } for( i = 0x00; i < CDROM_Transfer_DataLen; i++ ) { mBOC.buf[ i ] = CDROM_Rd_Capacity[ i ]; } mBOC.buf[ 0 ] = ( ( CDROM_Capability - 1 ) >> 24 ) & 0xFF; mBOC.buf[ 1 ] = ( ( CDROM_Capability - 1 ) >> 16 ) & 0xFF; mBOC.buf[ 2 ] = ( ( CDROM_Capability - 1 ) >> 8 ) & 0xFF; mBOC.buf[ 3 ] = ( ( CDROM_Capability - 1 ) ) & 0xFF; pEndp2_Buf = mBOC.buf; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); } else { CDROM_CMD_Deal_Status( 0x02, 0x3A, 0x01 ); CDROM_CMD_Deal_Fail( ); } break; case CMD_U_READ10: /* CMD: 0x28 */ if( ( CDROM_Status & DEF_CDROM_EN_FLAG ) ) { CMD_RD_WR_Deal_Pre( ); } else { CDROM_CMD_Deal_Status( 0x02, 0x3A, 0x01 ); CDROM_CMD_Deal_Fail( ); } break; case CMD_U_WR_VERIFY10: /* CMD: 0x2E */ case CMD_U_WRITE10: /* CMD: 0x2A */ if( CDROM_Status & DEF_CDROM_EN_FLAG ) { CMD_RD_WR_Deal_Pre( ); } else { CDROM_CMD_Deal_Status( 0x02, 0x3A, 0x01 ); CDROM_CMD_Deal_Fail( ); } break; case CMD_U_MODE_SENSE: /* CMD: 0x1A */ if( ( CDROM_Status & DEF_CDROM_EN_FLAG ) ) { if( CDROM_Transfer_DataLen > 0x0C ) { CDROM_Transfer_DataLen = 0x0C; } for( i = 0x00; i < CDROM_Transfer_DataLen; i++ ) { mBOC.buf[ i ] = CDROM_Mode_Sense_1A[ i ]; } mBOC.buf[ 4 ] = ( CDROM_Capability >> 24 ) & 0xFF; mBOC.buf[ 5 ] = ( CDROM_Capability >> 16 ) & 0xFF; mBOC.buf[ 6 ] = ( CDROM_Capability >> 8 ) & 0xFF; mBOC.buf[ 7 ] = ( CDROM_Capability ) & 0xFF; pEndp2_Buf = mBOC.buf; } else { CDROM_CMD_Deal_Status( 0x02, 0x3A, 0x01 ); CDROM_CMD_Deal_Fail( ); } break; case CMD_U_MODE_SENSE2: /* CMD: 0x5A */ if( mBOC.mCBW.mCBW_CB_Buf[ 2 ] == 0x3F ) { if( CDROM_Transfer_DataLen > 0x10 ) { CDROM_Transfer_DataLen = 0x10; } for( i = 0x00; i < CDROM_Transfer_DataLen; i++ ) { mBOC.buf[ i ] = CDROM_Mode_Senese_5A[ i ]; } mBOC.buf[ 8 ] = ( CDROM_Capability >> 24 ) & 0xFF; mBOC.buf[ 9 ] = ( CDROM_Capability >> 16 ) & 0xFF; mBOC.buf[ 10 ] = ( CDROM_Capability >> 8 ) & 0xFF; mBOC.buf[ 11 ] = ( CDROM_Capability ) & 0xFF; pEndp2_Buf = mBOC.buf; } else if (mBOC.mCBW.mCBW_CB_Buf[ 2 ] == 0x2A) { if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD5A_2A_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD5A_2A_Ret ); } for( i = 0x00; i < CDROM_Transfer_DataLen; i++ ) { mBOC.buf[ i ] = CDROM_CMD5A_2A_Ret[ i ]; } pEndp2_Buf = mBOC.buf; } else { CDROM_CMD_Deal_Status( 0x05, 0x20, 0x01 ); CDROM_CMD_Deal_Fail( ); } break; case CMD_U_REQUEST_SENSE: /* CMD: 0x03 */ mBOC.ReqSense.ErrorCode = 0x70; mBOC.ReqSense.Reserved1 = 0x00; mBOC.ReqSense.SenseKey = CDROM_Sense_Key; mBOC.ReqSense.Information[ 0 ] = 0x00; mBOC.ReqSense.Information[ 1 ] = 0x00; mBOC.ReqSense.Information[ 2 ] = 0x00; mBOC.ReqSense.Information[ 3 ] = 0x00; mBOC.ReqSense.SenseLength = 0x0A; mBOC.ReqSense.Reserved2[ 0 ] = 0x00; mBOC.ReqSense.Reserved2[ 1 ] = 0x00; mBOC.ReqSense.Reserved2[ 2 ] = 0x00; mBOC.ReqSense.Reserved2[ 3 ] = 0x00; mBOC.ReqSense.SenseCode = CDROM_Sense_ASC; mBOC.ReqSense.SenseCodeQua = 0x00; mBOC.ReqSense.Reserved3[ 0 ] = 0x00; mBOC.ReqSense.Reserved3[ 1 ] = 0x00; mBOC.ReqSense.Reserved3[ 2 ] = 0x00; mBOC.ReqSense.Reserved3[ 3 ] = 0x00; pEndp2_Buf = mBOC.buf; CDROM_CSW_Status = 0x00; break; case CMD_U_TEST_READY: if( CDROM_Status & DEF_CDROM_EN_FLAG ) { CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); } else { CDROM_CMD_Deal_Status( 0x02, 0x3A, 0x01 ); CDROM_Transfer_Status |= DEF_CDROM_BLUCK_UP_FLAG; CDROM_CMD_Deal_Fail( ); } break; case CMD_U_PREVT_REMOVE: /* CMD: 0x1E */ CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); break; case CMD_U_VERIFY10: /* CMD: 0x1F */ CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); break; case CMD_U_START_STOP: /* CMD: 0x1B */ CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); break; case 0x46: if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD46_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD46_Ret ); } pEndp2_Buf = (uint8_t *)CDROM_CMD46_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ break; case 0x4A: if( mBOC.mCBW.mCBW_CB_Buf[ 4 ] == 0x00 ) { if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD4A_00_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD4A_00_Ret ); } pEndp2_Buf = (uint8_t *)CDROM_CMD4A_00_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ } else if( mBOC.mCBW.mCBW_CB_Buf[ 4 ] == 0x10 ) { if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD4A_10_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD4A_10_Ret ); } pEndp2_Buf = (uint8_t *)CDROM_CMD4A_10_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ } else { CDROM_CMD_Deal_Ret_ErrorData( ); /* return invalid data */ CDROM_CMD_Deal_Status( 0x05, 0x20, 0x01 ); /* report parameter error */ CDROM_CMD_Deal_Fail( ); /* Disk command execution failed */ } break; case 0x43: if( mBOC.mCBW.mCBW_CB_Buf[ 9 ] == 0x40 ) { if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD43_40_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD43_40_Ret ); } CDROM_CMD43_40_Ret[9] = (uint8_t)( ( CDROM_Capability - 1) >>16 ); CDROM_CMD43_40_Ret[10] = (uint8_t)( ( CDROM_Capability - 1 ) >>8 ); CDROM_CMD43_40_Ret[11] = (uint8_t)( CDROM_Capability - 1); pEndp2_Buf = (uint8_t *)CDROM_CMD43_40_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ } else if( mBOC.mCBW.mCBW_CB_Buf[ 9 ] == 0x00 ) { if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD43_00_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD43_00_Ret ); } CDROM_CMD43_00_Ret[17] = (uint8_t)( ( CDROM_Capability - 1) >>16 ); CDROM_CMD43_00_Ret[18] = (uint8_t)( ( CDROM_Capability - 1) >>8 ); CDROM_CMD43_00_Ret[19] = (uint8_t)( CDROM_Capability - 1); pEndp2_Buf = (uint8_t *)CDROM_CMD43_00_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ } else if( mBOC.mCBW.mCBW_CB_Buf[ 9 ] == 0x80 ) { if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD43_80_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD43_80_Ret ); } pEndp2_Buf = (uint8_t *)CDROM_CMD43_80_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ } else { CDROM_CMD_Deal_Ret_ErrorData( ); /* return invalid data */ CDROM_CMD_Deal_Status( 0x05, 0x20, 0x01 ); /* report parameter error */ CDROM_CMD_Deal_Fail( ); /* Disk command execution failed */ } break; case 0xBB: CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ break; case 0x51: if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD51_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD51_Ret ); } pEndp2_Buf = (uint8_t *)CDROM_CMD51_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ break; case 0x52: if( CDROM_Transfer_DataLen > sizeof( CDROM_CMD52_Ret ) ) { CDROM_Transfer_DataLen = sizeof( CDROM_CMD52_Ret ); } pEndp2_Buf = (uint8_t *)CDROM_CMD52_Ret; CDROM_CMD_Deal_Status( 0x00, 0x00, 0x00 ); /* Disk command executed successfully */ break; case 0xAC: case 0x85: CDROM_CMD_Deal_Ret_ErrorData( ); CDROM_CMD_Deal_Status( 0x05, 0x20, 0x01 ); /* report parameter error */ break; default: CDROM_CMD_Deal_Status( 0x05, 0x20, 0x01 ); CDROM_Transfer_Status |= DEF_CDROM_BLUCK_UP_FLAG; CDROM_CMD_Deal_Fail( ); break; } } else { /* Bad package flag for CBW package */ CDROM_CMD_Deal_Status( 0x05, 0x20, 0x02 ); CDROM_Transfer_Status |= DEF_CDROM_BLUCK_UP_FLAG; CDROM_Transfer_Status |= DEF_CDROM_BLUCK_DOWN_FLAG; CDROM_CMD_Deal_Fail( ); } } /******************************************************************************* * Function Name : CDROM_In_EP_Deal * Description : Upload endpoint handling * Input : None * Output : None * Return : None *******************************************************************************/ void CDROM_In_EP_Deal( void ) { if( CDROM_Transfer_Status & DEF_CDROM_BLUCK_UP_FLAG ) { if( mBOC.mCBW.mCBW_CB_Buf[ 0 ] == CMD_U_READ10 ) { CDROM_Up_OnePack( ); } else { CDROM_Bulk_UpData( ); } } else if( CDROM_Transfer_Status & DEF_CDROM_CSW_UP_FLAG ) { CDROM_Up_CSW( ); } } /******************************************************************************* * Function Name : CDROM_Out_EP_Deal * Description : Download endpoint processing * Input : None * Output : None * Return : None *******************************************************************************/ void CDROM_Out_EP_Deal( uint8_t *pbuf, uint16_t packlen ) { uint32_t i; /* Endpoint 2 download data processing */ if( CDROM_Transfer_Status & DEF_CDROM_BLUCK_DOWN_FLAG ) { CDROM_Down_OnePack( pbuf, packlen ); } else { if( packlen == 0x1F ) { for( i = 0; i < packlen; i++ ) { mBOC.buf[ i ] = *pbuf++; } CDROM_SCSI_CMD_Deal( ); if( ( CDROM_Transfer_Status & DEF_CDROM_BLUCK_DOWN_FLAG ) == 0x00 ) { if( CDROM_Transfer_Status & DEF_CDROM_BLUCK_UP_FLAG ) { if( mBOC.mCBW.mCBW_CB_Buf[ 0 ] == CMD_U_READ10 ) { CDROM_Up_OnePack( ); } else { CDROM_Bulk_UpData( ); } } else if( CDROM_CSW_Status == 0x00 ) { /* upload CSW */ CDROM_Up_CSW( ); } } } } } /******************************************************************************* * Function Name : CDROM_Bulk_UpData * Description : EP2 upload data * Input : Transfer_DataLen--- length of data transferred * *pBuf---data address pointer * Output : None * Return : None *******************************************************************************/ void CDROM_Bulk_UpData( void ) { uint32_t len; if( CDROM_Transfer_DataLen > CDROM_Pack_Size ) { len = CDROM_Pack_Size; CDROM_Transfer_DataLen -= CDROM_Pack_Size; } else { len = CDROM_Transfer_DataLen; CDROM_Transfer_DataLen = 0x00; CDROM_Transfer_Status &= ~DEF_CDROM_BLUCK_UP_FLAG; } /* Load the data into the upload buffer and start the upload */ USB_SIL_Write( EP2_IN, pEndp2_Buf, len ); SetEPTxStatus( ENDP2, EP_TX_VALID ); } /******************************************************************************* * Function Name : CDROM_Up_CSW * Description : Bulk endpoint endpoint 2 upload CSW package * Input : CBW_Tag_Save---command block label * CSW_Status---Current command execution result status * Output : None * Return : None *******************************************************************************/ void CDROM_Up_CSW( void ) { CDROM_Transfer_Status = 0x00; mBOC.mCSW.mCSW_Sig[ 0 ] = 'U'; mBOC.mCSW.mCSW_Sig[ 1 ] = 'S'; mBOC.mCSW.mCSW_Sig[ 2 ] = 'B'; mBOC.mCSW.mCSW_Sig[ 3 ] = 'S'; mBOC.mCSW.mCSW_Tag[ 0 ] = CDROM_CBW_Tag_Save[ 0 ]; mBOC.mCSW.mCSW_Tag[ 1 ] = CDROM_CBW_Tag_Save[ 1 ]; mBOC.mCSW.mCSW_Tag[ 2 ] = CDROM_CBW_Tag_Save[ 2 ]; mBOC.mCSW.mCSW_Tag[ 3 ] = CDROM_CBW_Tag_Save[ 3 ]; mBOC.mCSW.mCSW_Residue[ 0 ] = 0x00; mBOC.mCSW.mCSW_Residue[ 1 ] = 0x00; mBOC.mCSW.mCSW_Residue[ 2 ] = 0x00; mBOC.mCSW.mCSW_Residue[ 3 ] = 0x00; mBOC.mCSW.mCSW_Status = CDROM_CSW_Status; /* Load the data into the upload buffer and start the upload */ USB_SIL_Write( EP2_IN, (uint8_t *)mBOC.buf, 0x0D ); SetEPTxStatus( ENDP2, EP_TX_VALID ); } /******************************************************************************* * Function Name : CDROM_Up_OnePack * Description : CD-ROM upload a pack * Input : None * Output : None * Return : None *******************************************************************************/ void CDROM_Up_OnePack( void ) { uint8_t *pbuf = NULL; if( CDROM_Sec_Pack_Count == 0x00 ) { FLASH_RD_Block_Start( CDROM_Cur_Sec_Lba * DEF_CDROM_SECTOR_SIZE ); } FLASH_RD_Block( CDROM_Pack_Buffer, CDROM_Pack_Size ); pbuf = CDROM_Pack_Buffer; /* USB upload this package data */ USB_SIL_Write( EP2_IN, pbuf, CDROM_Pack_Size ); SetEPTxStatus( ENDP2, EP_TX_VALID ); /* Determine whether the current sector data is read and uploaded */ CDROM_Sec_Pack_Count++; CDROM_Transfer_DataLen -= CDROM_Pack_Size; if( CDROM_Sec_Pack_Count == ( DEF_CDROM_SECTOR_SIZE / CDROM_Pack_Size ) ) { PIN_FLASH_CS_HIGH( ); CDROM_Sec_Pack_Count = 0x00; CDROM_Cur_Sec_Lba++; } /* Determine whether the current sector data is read and uploaded */ if( CDROM_Transfer_DataLen == 0x00 ) { CDROM_Transfer_Status &= ~DEF_CDROM_BLUCK_UP_FLAG; } } /******************************************************************************* * Function Name : CDROM_Down_OnePack * Description : Do nothing, cause CD-ROM Mode is read-only. * Input : None * Output : None * Return : None *******************************************************************************/ void CDROM_Down_OnePack( uint8_t *pbuf, uint16_t packlen ) { // CD-ROM Mode is read-only return; }