|
|
View previous topic :: View next topic |
Author |
Message |
georpo
Joined: 18 Nov 2008 Posts: 281 Location: Athens, Greece.
|
cd-rom music player |
Posted: Tue Apr 19, 2011 11:45 am |
|
|
Hello,
Are there any ideas about the commands needed to play audio cd with a low cost IDE cd-rom?
I am familiar with the interface, I have already a hard disk drive interface working.
I just need the commands for read TOC, play, stop, next track etc.
Thanks
George. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Tue Apr 19, 2011 1:30 pm |
|
|
You could use google to help you out, simple search revealed 50,000+ 'hits' for me couple of minutes ago....
..this 'net stuff' is really useful and fast compared to the old dayze... |
|
|
wslay
Joined: 06 Jun 2009 Posts: 4
|
|
Posted: Fri Dec 02, 2011 8:51 am |
|
|
I think this not easy case to study, you can try my code as below. Good luck to you. Now I have problem as SCSI-2 CD-ROM, if you have good idea, please let me to know.
Code: |
/****************************************************************************
* ATAPI IDE CD-ROM Library
*
* If you have any problem, please contact to me.
* Email:wslay0924@gmail.com
* reference: sff8020i.pdf, d1153r18.pdf
* initial v1.0 ---------------------------- 2011.10.07 by WSLAY
* optimun v1.1 ---------------------------- 2011.11.27 by WSLAY
*****************************************************************************/
#include <ATAPI.h>
/****************************************************************************
*** function : void ATAPI_Register(BYTE reg)
*** input data : reg
*** output data : NA
*** description : reg for address pin
*****************************************************************************/
void ATAPI_Reg(BYTE reg)
{
output_bit(ATA_DIOW_PIN, 1);
output_bit(ATA_DIOR_PIN, 1);
output_bit(ATA_CS0_PIN, 0);
output_bit(ATA_CS1_PIN, 0);
output_bit(ATA_DA0_PIN, bit_test(reg, 0));
output_bit(ATA_DA1_PIN, bit_test(reg, 1));
output_bit(ATA_DA2_PIN, bit_test(reg, 2));
}
/****************************************************************************
*** function : ATAPI_input(BYTE reg, BYTE &LSB, BYTE &MSB)
*** input data : reg
*** output data : LSB, MSB
*** description : reg:define register ; LSB&MSB read from ATAPI device data
*****************************************************************************/
void ATAPI_input(BYTE reg, BYTE &LSB, BYTE &MSB)
{
set_tris_LSB(0xFF);
set_tris_MSB(0xFF);
ATAPI_Reg(reg);
output_bit(ATA_CS1_PIN, 1);
output_low(ATA_DIOR_PIN);
delay_cycles(1);
LSB = input_LSB();
MSB = input_MSB();
output_high(ATA_DIOR_PIN);
output_bit(ATA_CS1_PIN, 0);
set_tris_LSB(0x00);
set_tris_MSB(0x00);
delay_cycles(1);
}
/****************************************************************************
*** function : ATAPI_output(BYTE reg, BYTE LSB, BYTE MSB)
*** input data : reg, LSB, MSB
*** output data : NA
*** description : reg:define register ; LSB&MSB write to ATAPI device data
*****************************************************************************/
void ATAPI_output(BYTE reg, BYTE LSB, BYTE MSB)
{
set_tris_LSB(0x00);
set_tris_MSB(0x00);
ATAPI_Reg(reg);
output_bit(ATA_CS1_PIN, 1);
output_LSB(LSB);
output_MSB(MSB);
output_low(ATA_DIOW_PIN);
delay_cycles(1);
output_high(ATA_DIOW_PIN);
output_bit(ATA_CS1_PIN, 0);
delay_cycles(1);
}
/****************************************************************************
*** function : BYTE ATAPI_ReadStatus()
*** input data : NA
*** output data : ATAPI status
*** description : return ATAPI status
*****************************************************************************/
BYTE ATAPI_ReadStatus()
{
return ATAPI_inputLSB(reg_status);
}
/****************************************************************************
*** function : BYTE ATAPI_ReadError()
*** input data : NA
*** output data : ATAPI error
*** description : return ATAPI status
*****************************************************************************/
BYTE ATAPI_ReadError()
{
return ATAPI_inputLSB(reg_error);
}
/****************************************************************************
*** function : BOOLEAN ATAPI_BSY()
*** input data : NA
*** output data : BOOLEAN
*** description : busy flag status
*****************************************************************************/
BOOLEAN ATAPI_BSY()
{
return bit_test(ATAPI_inputLSB(reg_status), BSY);
}
/****************************************************************************
*** function : BOOLEAN ATAPI_RDRY()
*** input data : NA
*** output data : BOOLEAN
*** description : RDRY flag status
*****************************************************************************/
BOOLEAN ATAPI_RDRY()
{
return bit_test(ATAPI_inputLSB(reg_status), RDRY);
}
/****************************************************************************
*** function : BOOLEAN ATAPI_CHECK()
*** input data : NA
*** output data : BOOLEAN
*** description : CHECK flag status
*****************************************************************************/
BOOLEAN ATAPI_CHECK()
{
return bit_test(ATAPI_inputLSB(reg_status), CHECK);
}
/****************************************************************************
*** function : BOOLEAN ATAPI_RDRY()
*** input data : NA
*** output data : BOOLEAN
*** description : DRQ flag status
*****************************************************************************/
BOOLEAN ATAPI_DRQ()
{
return bit_test(ATAPI_inputLSB(reg_status), DRQ);
}
/****************************************************************************
*** function : BOOLEAN ATAPI_waitDRQ()
*** input data : NA
*** output data : BOOLEAN
*** description : wait DRQ flag status
*****************************************************************************/
BOOLEAN ATAPI_waitDRQ()
{
char i = 0, timeout =100;
do
{
delay_ms(10);
}while(++i<timeout && !ATAPI_DRQ());
if (i == timeout) return 0;
return 1;
}
/****************************************************************************
*** function : void ATAPI_devhead(BYTE dev)
*** input data : dev (0=master, 1=slave)
*** output data : NA
*** description : select device head
*****************************************************************************/
void ATAPI_devhead(BYTE dev)
{
BYTE DevHead = ATAPI_inputLSB(reg_devicehead); //select master device
if (dev == 0) bit_clear(DevHead, 4); //Bit4, This bit selects either Device 0 (DRV=0) or 1(DRV=1).
else bit_set(DevHead, 4);
ATAPI_output(reg_devicehead, DevHead, 0xFF);
}
/****************************************************************************
*** function : void ATAPI_PacketCmd(BYTE *PktCmd, BYTE Count)
*** input data : PktCmd data pointer, data Count (normal = 12)
*** output data : NA
*** description : send packet command
*****************************************************************************/
void ATAPI_PacketCmd(BYTE *PktCmd, BYTE Count)
{
BYTE i=0;
//Select master device
ATAPI_devhead(0);
//Set packet size
ATAPI_output(reg_cylow, PktCmdSize, 0xFF);
ATAPI_output(reg_cyhigh, 0x00, 0xFF);
//Packetsize command
ATAPI_output(reg_cmd, 0xA0, 0xFF);
//wait when DRQ = 1
while(!ATAPI_DRQ());
for (i=0; i<Count; i+=2)
{
ATAPI_output(reg_data, PktCmd[i], PktCmd[i+1]);
}
}
/****************************************************************************
*** function : BYTE ATAPI_inputLSB(BYTE reg)
*** input data : reg
*** output data : BYTE (LSB data)
*** description : reg:define register ; LSB read from ATAPI device data
*****************************************************************************/
BYTE ATAPI_inputLSB(BYTE reg)
{
BYTE LSB, MSB;
ATAPI_input(reg, LSB, MSB);
return LSB;
}
/****************************************************************************
*** function : void ATAPI_ReadPacketData(BYTE Count)
*** input data : read count
*** output data : public data array
*** description : assign read out count
*****************************************************************************/
void ATAPI_ReadPacketData(BYTE Count)
{
BYTE LSB, MSB, i;
for (i=0; i<Count; i+=2)
{
ATAPI_waitDRQ();
ATAPI_input(reg_data, LSB, MSB);
tempPktData[i] = LSB;
tempPktData[i+1] = MSB;
}
}
/****************************************************************************
*** function : void ATAPI_Test()
*** input data : NA
*** output data : NA
*** description : test ATAPI device
*****************************************************************************/
void ATAPI_Test()
{
BYTE PktCmd[12] = {0};
ATAPI_PacketCmd(&PktCmd[0], 12);
}
/****************************************************************************
*** function : void ATAPI_Eject(TEJECT MODE)
*** input data : MODE
*** output data : NA
*** description : STOP=0, START=1, EJECT=2, LOAD=3
*****************************************************************************/
void ATAPI_Eject(TEJECT MODE)
{
BYTE PktCmd[12] = {0};
PktCmd[0] = 0x1B;
PktCmd[4] = MODE;
ATAPI_PacketCmd(&PktCmd[0], 12);
}
/****************************************************************************
*** function : void ATAPI_PlayMSF()
*** input data : NA
*** output data : NA
*** description : play music
*****************************************************************************/
void ATAPI_PlayMSF()
{
BYTE PktCmd[12] = {0};
PktCmd[0] = 0x47;
PktCmd[3] = StartM;
PktCmd[4] = StartS;
PktCmd[5] = StartF;
PktCmd[6] = EndM;
PktCmd[7] = EndS;
PktCmd[8] = EndF;
ATAPI_PacketCmd(&PktCmd[0], 12);
}
/****************************************************************************
*** function : void ATAPI_Stop()
*** input data : NA
*** output data : NA
*** description : stop play music
*****************************************************************************/
void ATAPI_Stop()
{
BYTE PktCmd[12] = {0};
PktCmd[0] = 0x4E; //STOP/SCAN Command
ATAPI_PacketCmd(&PktCmd[0], 12);
}
/****************************************************************************
*** function : void ATAPI_Pause(BOOLEAN flag)
*** input data : flag
*** output data : NA
*** description : flag = 1 as true
*****************************************************************************/
void ATAPI_Pause(BOOLEAN flag)
{
BYTE PktCmd[12] = {0};
PktCmd[0] = 0x4B; //PAUSE/RESUME Command
PktCmd[8] = flag; //1:PAUSE
ATAPI_PacketCmd(&PktCmd[0], 12);
}
/****************************************************************************
*** function : void ATAPI_Next(BYTE NP)
*** input data : NA
*** output data : NA
*** description : play next music
*****************************************************************************/
void ATAPI_Next()
{
ATAPI_ReadSub(); //Read current MSF?
if (++CurrentTrackNum > EndTrackNum) CurrentTrackNum = EndTrackNum;
ATAPI_ReadTOC(CurrentTrackNum);
ATAPI_PlayMSF(); //play MSF
}
/****************************************************************************
*** function : void ATAPI_Prevous()
*** input data : NA
*** output data : NA
*** description : play prev music
*****************************************************************************/
void ATAPI_Prevous()
{
ATAPI_ReadSub(); //Read current MSF?
if (--CurrentTrackNum < StartTrackNum) CurrentTrackNum = StartTrackNum;
ATAPI_ReadTOC(CurrentTrackNum);
ATAPI_PlayMSF(); //play MSF
}
/****************************************************************************
*** function : void ATAPI_ReadTOC(BYTE Track)
*** input data : Track
*** output data : NA
*** description : Read MSF; Track = 0xAA, read end track number
*****************************************************************************/
void ATAPI_ReadTOC(BYTE Track)
{
BYTE PktCmd[12] = {0};
BYTE Count = 12;
PktCmd[0] = 0x43; // Bit 7 6 5 4 3 2 1 0
PktCmd[1] = 0x02; // R R R R R R MSF R
PktCmd[6] = Track; // Starting Track / Session Number
PktCmd[8] = Count; // Allocation Length (LSB)
ATAPI_PacketCmd(&PktCmd[0], 12);
if (!ATAPI_waitDRQ()) return;
ATAPI_ReadPacketData(Count);
StartTrackNum = tempPktData[2];
EndTrackNum = tempPktData[3];
if (Track == 0xAA)
{
EndM = tempPktData[9];
EndS = tempPktData[10];
EndF = tempPktData[11];
}else
{
StartM = tempPktData[9];
StartS = tempPktData[10];
StartF = tempPktData[11];
}
}
/****************************************************************************
*** function : void ATAPI_ReadSub()
*** input data : NA
*** output data : NA
*** description : Read current MSF
*****************************************************************************/
void ATAPI_ReadSub()
{
BYTE PktCmd[12] = {0};
BYTE Count = 16;
PktCmd[0] = 0x42; // Bit 7 6 5 4 3 2 1 0
PktCmd[1] = 0x02; // R R R R R R MSF R
PktCmd[2] = 0x40; // R SubQ R R R R R R
PktCmd[3] = 0x01; // Sub-channel Data Format
PktCmd[8] = Count; // Allocation Length (LSB)
ATAPI_PacketCmd(&PktCmd[0], 12);
if (!ATAPI_waitDRQ()) return;
ATAPI_ReadPacketData(Count);
AudioStatus = tempPktData[1];
CurrentTrackNum = tempPktData[6];
CurrentM = tempPktData[9];
CurrentS = tempPktData[10];
CurrentF = tempPktData[11];
}
/****************************************************************************
*** function : void ATAPI_Inquiry()
*** input data : NA
*** output data : NA
*** description : Inquiry device function, Vendor[8];Product[16];Revision[4];
*****************************************************************************/
void ATAPI_Inquiry()
{
BYTE i =0 ;
BYTE PktCmd[12] = {0};
BYTE Count = 36;
PktCmd[0] = 0x12;
PktCmd[4] = Count;
ATAPI_PacketCmd(&PktCmd[0], 12);
//while(!ATAPI_DRQ());
ATAPI_ReadPacketData(Count);
for (i=8; i<16; i++) Vendor[i-8] = tempPktData[i];
for (i=16; i<32; i++) Product[i-16] = tempPktData[i];
for (i=32; i<Count; i++) Revision[i-32] = tempPktData[i];
while(ATAPI_DRQ()) ATAPI_inputLSB(reg_data); //Readout all data from CD-ROM buffer.
}
/****************************************************************************
*** function : BOOLEAN ATAPI_ReadCDInfo()
*** input data : 1 = OK; 0= fail
*** output data : NA
*** description : read infomation
*****************************************************************************/
BOOLEAN ATAPI_ReadCDInfo()
{
BYTE i = 0, timeout = 10;
do
{
ATAPI_ReadSub();
delay_ms(10);
ATAPI_ReadTOC(0xAA);
}while((++i<timeout) && (CurrentTrackNum != 1));
if (i == timeout) return 0;
ATAPI_ReadTOC(0);
return 1;
}
/****************************************************************************
*** function : BOOLEAN ATAPI_initCDROM()
*** input data : NA
*** output data : 0: no error
*** description : init ATAPI device
*****************************************************************************/
int ATAPI_initCDROM()
{
delay_ms(50);
output_drive(ATA_DA0_PIN);
output_drive(ATA_DA1_PIN);
output_drive(ATA_DA2_PIN);
output_drive(ATA_DIOW_PIN);
output_drive(ATA_DIOR_PIN);
output_drive(ATA_CS0_PIN);
output_drive(ATA_CS1_PIN);
output_drive(ATA_RST_PIN);
ATAPI_Reg(reg_data);
output_low(ATA_RST_PIN);
delay_ms(10);
output_high(ATA_RST_PIN);
delay_ms(50);
while (ATAPI_BSY());
delay_ms(300); //for some CD-ROM response slower, ex:TEAC CD-W552E
//sdelect master device
ATAPI_devhead(0);
//Check device as ATAPI CD-ROM
if((ATAPI_inputLSB(reg_cylow)) != 0x14 || (ATAPI_inputLSB(reg_cyhigh) != 0xEB))
{
return ATA_notATAPI_Error;
}
//Self test
ATAPI_output(reg_cmd, 0x90, 0xFF);
while(ATAPI_BSY());
BYTE RetCode = ATAPI_ReadError();
if ((RetCode != 0x01) && (RetCode != 0x81)) //01h device0 passed, Device 1 passed or not present ;dev=1, device 1 passed
{
return ATA_SelfTest_Error; //81h device0 passed, Device 1 fail ; dev=1, 00h, 02h-7Fh device 1 failed
}
//Identify packet device
ATAPI_output(reg_cmd, 0xA1, 0xFF);
while(!ATAPI_DRQ()); //DRQ=1 data ready read.
BYTE Byte0 = ATAPI_inputLSB(reg_data)<<6; //Byte0-> bit0-1 00:12 byte command packet; 01:16 byte command packet
if (Byte0 == 0) PktCmdSize = 12; //12byte 6word
else if (Byte0 == 0x40) PktCmdSize = 16; //16byte 6word
else return ATA_PacketSize_Error;
while(ATAPI_DRQ()) ATAPI_inputLSB(reg_data); //Readout all data from CD-ROM buffer.
//Test device as ready
while(ATAPI_CHECK()) ATAPI_Test();
ATAPI_Inquiry();
return 0;
}
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|