Interesting thread and using a CD-ROM is not that far-fletched after all. Has anyone tried a DVD-ROM drive? I hear that Meridian uses a ATAPI CD-ROM drive in its 808 series, anyone has any idea what they are using?
C Source code
Could you help me to write this code to eject the cdrom ?
void write_atapi(unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b00000000; // All ports C are output
TRISD = 0b00000000; // All ports D are output
RA1 = 0; // CS0
RA0 = 1; // CS1
RE0 = 1; // DA0
RE1 = 1; // DA1
RE2 = 1; // DA2
PORTD = bytehigh;
PORTC = bytelow;
RA3 = 1; // W
DelayMs(1);
RA3 = 0; // W
}
void read_atapi(int cs0, int cs1, int da0, int da1, int da2, unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 1; // R
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 0; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
read_atapi(1, 0, 1, 1, 1, bytelow, bytehigh): //try 10011
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
write_atapi(0x1e, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
check_status();
write_atapi(0x1b, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x02, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
}
void cdrom()
{
RA5 = 1; // Reset high
open_tray();
}
Andrea Ciuffoli
www.audiodesignguide.com
Could you help me to write this code to eject the cdrom ?
void write_atapi(unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b00000000; // All ports C are output
TRISD = 0b00000000; // All ports D are output
RA1 = 0; // CS0
RA0 = 1; // CS1
RE0 = 1; // DA0
RE1 = 1; // DA1
RE2 = 1; // DA2
PORTD = bytehigh;
PORTC = bytelow;
RA3 = 1; // W
DelayMs(1);
RA3 = 0; // W
}
void read_atapi(int cs0, int cs1, int da0, int da1, int da2, unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 1; // R
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 0; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
read_atapi(1, 0, 1, 1, 1, bytelow, bytehigh): //try 10011
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
write_atapi(0x1e, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
check_status();
write_atapi(0x1b, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x02, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
}
void cdrom()
{
RA5 = 1; // Reset high
open_tray();
}
Andrea Ciuffoli
www.audiodesignguide.com
write_atapi(0x1e, 0x00)
comparing to some asm- I dont think I see a 12 byte group
starting with this?
comparing to some asm- I dont think I see a 12 byte group
starting with this?
How about ASM?
Open_Tray:
MOV R5,#10
CALL LCD_DELAY
MOV DPTR,#LMESS11 ; Open
MOV A,#1
CALL LCD_PRINT
MOV DPTR,#LMESS12 ; Wait....
MOV A,#2
CALL LCD_PRINT
acall do_packet_cmd
mov packet_cmd,#11011b
mov packet_4,#02h
mov packet_8,#00h
acall send_packet
mov next_track,#1
ret
😀
Open_Tray:
MOV R5,#10
CALL LCD_DELAY
MOV DPTR,#LMESS11 ; Open
MOV A,#1
CALL LCD_PRINT
MOV DPTR,#LMESS12 ; Wait....
MOV A,#2
CALL LCD_PRINT
acall do_packet_cmd
mov packet_cmd,#11011b
mov packet_4,#02h
mov packet_8,#00h
acall send_packet
mov next_track,#1
ret
😀
mov packet_cmd,#11011b
this is 1B hex?- makes sense to me
mov packet_4,#02h
mov packet_8,#00h
agreed
If I unroll the code I am looking at I believe the above "packet" is preceded by a single byte pair being sent
"sends ata cmd 0xa0 - atapi packet cmd"
with low CS0, rest high CS1, DA0,DA1, DA2
MCLL?
this is 1B hex?- makes sense to me
mov packet_4,#02h
mov packet_8,#00h
agreed
If I unroll the code I am looking at I believe the above "packet" is preceded by a single byte pair being sent
"sends ata cmd 0xa0 - atapi packet cmd"
with low CS0, rest high CS1, DA0,DA1, DA2
MCLL?
Csource for Audio CDROM
Is this better ?
I see in the assembler source available that in the write both W and R pin of the ATA bus are set to high, why ?
How to set the register in the write and in the read to see if the drive is busy and to send a command like play, eject, stop .. ?
Offcourse now I am starting with eject function but I want all the complete functions.
void write_atapi(unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b00000000; // All ports C are output
TRISD = 0b00000000; // All ports D are output
RA1 = 1; // CS0
RA0 = 0; // CS1
RE0 = 1; // DA0
RE1 = 1; // DA1
RE2 = 1; // DA2
PORTD = bytehigh;
PORTC = bytelow;
RA3 = 1; // W
RA2 = 1; // R
DelayMs(1);
RA3 = 0; // W
}
void read_atapi(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 1; // R
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 0; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
read_atapi(1, 0, 1, 1, 0, bytelow, bytehigh); //try 10011
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
write_atapi(0x1e, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
check_status();
write_atapi(0x1b, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x02, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
}
void cdrom()
{
ata_reset();
open_tray();
}
void ata_reset()
{
RA5 = 1; // Reset high
DelayMs(200);
RA5 = 0; // Reset low
DelayMs(200);
RA5 = 1; // Reset high
DelayMs(200);
DelayMs(200);
DelayMs(200);
DelayMs(200);
DelayMs(200);
return;
}
Is this better ?
I see in the assembler source available that in the write both W and R pin of the ATA bus are set to high, why ?
How to set the register in the write and in the read to see if the drive is busy and to send a command like play, eject, stop .. ?
Offcourse now I am starting with eject function but I want all the complete functions.
void write_atapi(unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b00000000; // All ports C are output
TRISD = 0b00000000; // All ports D are output
RA1 = 1; // CS0
RA0 = 0; // CS1
RE0 = 1; // DA0
RE1 = 1; // DA1
RE2 = 1; // DA2
PORTD = bytehigh;
PORTC = bytelow;
RA3 = 1; // W
RA2 = 1; // R
DelayMs(1);
RA3 = 0; // W
}
void read_atapi(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 1; // R
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 0; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
read_atapi(1, 0, 1, 1, 0, bytelow, bytehigh); //try 10011
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
write_atapi(0x1e, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
check_status();
write_atapi(0x1b, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x02, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
}
void cdrom()
{
ata_reset();
open_tray();
}
void ata_reset()
{
RA5 = 1; // Reset high
DelayMs(200);
RA5 = 0; // Reset low
DelayMs(200);
RA5 = 1; // Reset high
DelayMs(200);
DelayMs(200);
DelayMs(200);
DelayMs(200);
DelayMs(200);
return;
}
C source for Audio CDROM
I am using a PIC 16F877A with a 20MHz crystal.
All the delay functions are visible in the source.
I am using a PIC 16F877A with a 20MHz crystal.
All the delay functions are visible in the source.
"I see in the assembler source available that in the write both W and R pin of the ATA bus are set to high, why ?"
The strobes are active low, high is the rest state.
I think some DMA transfers will run on both clock edges but that beyond me...
Can you give me some reference for this packet containing
write_atapi(0x1e, 0x00) ?
maybe its a newer command?
I have been told they have depreciated some useful commands
so its best to try firstime with an older drive
The strobes are active low, high is the rest state.
I think some DMA transfers will run on both clock edges but that beyond me...
Can you give me some reference for this packet containing
write_atapi(0x1e, 0x00) ?
maybe its a newer command?
I have been told they have depreciated some useful commands
so its best to try firstime with an older drive
C source code for Audio CDROM
void read_atapi(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 1; // R
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 0; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
read_atapi(1, 0, 1, 1, 0, bytelow, bytehigh); //try 10011
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
//*******************************
//* unlock door
//*******************************
write_atapi(0x1e, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
check_status();
//*******************************
//* eject cdrom
//*******************************
write_atapi(0x1b, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x02, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
}
void read_atapi(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 1; // R
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 0; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
read_atapi(1, 0, 1, 1, 0, bytelow, bytehigh); //try 10011
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
//*******************************
//* unlock door
//*******************************
write_atapi(0x1e, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
check_status();
//*******************************
//* eject cdrom
//*******************************
write_atapi(0x1b, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x02, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
write_atapi(0x00, 0x00);
}
I would expect to initialize with similar pseudo code as below
......
set up all you regular stuff
start here
make dio read high
make dio write high
wait a couple of seconds
routine to select device 0
------start routine-----------
low CS0
high CS1
low DA0
high DA1
low DA2
high byte= 0
lowbyte= 0
strobe write
--------end routine-------
;check if cd busy then wait loops here
; read atapi status register
routine to read atapi status
;ATAPI STATUS Register:d7-d0
;BSY,DRDY,DMA,DSC,DRQ,CORR,Reserved,CHECK
------start routine-------
low CS0
high CS1
high DA0
high DA1
high DA2
read cd atapi status and save
--------end routine-------
wait until drq=0 fourth bit and bsy=0 eighth bit
keep reading until above true
routine features_reg - tell it we are not doing dma or ovl fancy stuff
------start routine-----------
low CS0
high CS1
high DA0
low DA1
low DA2
high byte= 0
lowbyte= 0
strobe write
--------end routine-------
rest of the code here....
now we can talk to cd?
......
set up all you regular stuff
start here
make dio read high
make dio write high
wait a couple of seconds
routine to select device 0
------start routine-----------
low CS0
high CS1
low DA0
high DA1
low DA2
high byte= 0
lowbyte= 0
strobe write
--------end routine-------
;check if cd busy then wait loops here
; read atapi status register
routine to read atapi status
;ATAPI STATUS Register:d7-d0
;BSY,DRDY,DMA,DSC,DRQ,CORR,Reserved,CHECK
------start routine-------
low CS0
high CS1
high DA0
high DA1
high DA2
read cd atapi status and save
--------end routine-------
wait until drq=0 fourth bit and bsy=0 eighth bit
keep reading until above true
routine features_reg - tell it we are not doing dma or ovl fancy stuff
------start routine-----------
low CS0
high CS1
high DA0
low DA1
low DA2
high byte= 0
lowbyte= 0
strobe write
--------end routine-------
rest of the code here....
now we can talk to cd?
C source code for Audio DCROM
Could you insert details about how to read atapi status register ?
The my code above is right ?
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
//*****************************************
//* In the call of read_atapi() the params are in the order:
//* cs0, cs1, da2, da1, da0
//*****************************************
read_atapi(1, 0, 1, 1, 0, bytelow, bytehigh);
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
Could you insert details about how to read atapi status register ?
The my code above is right ?
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
//*****************************************
//* In the call of read_atapi() the params are in the order:
//* cs0, cs1, da2, da1, da0
//*****************************************
read_atapi(1, 0, 1, 1, 0, bytelow, bytehigh);
if (bytelow == 7)
DelayMs(1);
else if (bytelow == 3)
DelayMs(1);
else break;
}
}
C source code for Audio CDROM
This is the code following your suggestions, I will try it this morning.
void ata_write(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISC = 0b00000000; // All ports C are output
TRISD = 0b00000000; // All ports D are output
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
PORTD = bytehigh;
PORTC = bytelow;
RA3 = 0; // W
DelayMs(5);
RA3 = 1; // W
}
void ata_read(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 0; // R
DelayMs(5);
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 1; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
ata_read(0, 1, 1, 1, 1, bytelow, bytehigh); //try 10011
if (bytelow & 0b01000000)
DelayMs(1);
else if (bytelow & 0b00000100)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
//*******************************
//* unlock door
//*******************************
ata_write(0x1e, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
check_status();
//*******************************
//* eject cdrom
//*******************************
ata_write(0x1b, 0x00);
ata_write(0x00, 0x00);
ata_write(0x02, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
}
void cdrom()
{
ata_reset();
open_tray();
}
void ata_reset()
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
RA2 = 1; // R
RA3 = 1; // W
RA5 = 1; // Reset high
DelayMs(200);
RA5 = 0; // Reset low
DelayMs(200);
RA5 = 1; // Reset high
//********************************************
//* wait 2 sec
//********************************************
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
//********************************************
// select device 0
// cs0 = 0;
// cs1 = 1;
// da2 = 0;
// da1 = 1;
// da0 = 0;
ata_write(0, 1, 0, 1, 0, 0x00, 0x00);
ata_get_status();
//********************************************
// features reg.
// cs0 = 0;
// cs1 = 1;
// da2 = 0;
// da1 = 0;
// da0 = 1;
ata_write(0, 1, 0, 0, 1, 0x00, 0x00);
return;
}
This is the code following your suggestions, I will try it this morning.
void ata_write(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISC = 0b00000000; // All ports C are output
TRISD = 0b00000000; // All ports D are output
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
PORTD = bytehigh;
PORTC = bytelow;
RA3 = 0; // W
DelayMs(5);
RA3 = 1; // W
}
void ata_read(int cs0, int cs1, int da2, int da1, int da0, unsigned char bytelow, unsigned char bytehigh)
{
TRISC = 0b11111111; // All ports B are input
TRISD = 0b11111111; // All ports D are input
RA1 = cs0; // CS0
RA0 = cs1; // CS1
RE0 = da0; // DA0
RE1 = da1; // DA1
RE2 = da2; // DA2
RA2 = 0; // R
DelayMs(5);
bytelow = PORTC;
bytehigh = PORTD;
RA2 = 1; // R
}
void check_status()
{
unsigned char bytelow;
unsigned char bytehigh;
while(1)
{
ata_read(0, 1, 1, 1, 1, bytelow, bytehigh); //try 10011
if (bytelow & 0b01000000)
DelayMs(1);
else if (bytelow & 0b00000100)
DelayMs(1);
else break;
}
}
void open_tray()
{
check_status();
//*******************************
//* unlock door
//*******************************
ata_write(0x1e, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
check_status();
//*******************************
//* eject cdrom
//*******************************
ata_write(0x1b, 0x00);
ata_write(0x00, 0x00);
ata_write(0x02, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
ata_write(0x00, 0x00);
}
void cdrom()
{
ata_reset();
open_tray();
}
void ata_reset()
{
TRISA = 0b00000000; // All ports A are output
TRISB = 0b00000000; // All ports B are output
TRISE = 0b00000000; // All ports E are output
RA2 = 1; // R
RA3 = 1; // W
RA5 = 1; // Reset high
DelayMs(200);
RA5 = 0; // Reset low
DelayMs(200);
RA5 = 1; // Reset high
//********************************************
//* wait 2 sec
//********************************************
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
//********************************************
// select device 0
// cs0 = 0;
// cs1 = 1;
// da2 = 0;
// da1 = 1;
// da0 = 0;
ata_write(0, 1, 0, 1, 0, 0x00, 0x00);
ata_get_status();
//********************************************
// features reg.
// cs0 = 0;
// cs1 = 1;
// da2 = 0;
// da1 = 0;
// da0 = 1;
ata_write(0, 1, 0, 0, 1, 0x00, 0x00);
return;
}
C source code for Audio CDROM
In respect to this table which is the line to consider in the startup and command phase ?
--- phase 1 - select device 0 ------
low CS0
high CS1
low DA0
high DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 2 - check state -----
low CS0
high CS1
high DA0
high DA1
high DA2
strobe read ?
save status ?
--- phase 3 - features_reg ------
low CS0
high CS1
high DA0
low DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 4 - unlock tray ------
? CS0
? CS1
? DA0
? DA1
? DA2
high byte= 0x00
lowbyte= 0x1e
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 5 - check state -----
? CS0
? CS1
? DA0
? DA1
? DA2
strobe read ?
--- phase 6 - eject ------
? CS0
? CS1
? DA0
? DA1
? DA2
high byte= 0x00
lowbyte= 0x1b
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x02
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 7 - check state -----
? CS0
? CS1
? DA0
? DA1
? DA2
strobe read ?
In respect to this table which is the line to consider in the startup and command phase ?
--- phase 1 - select device 0 ------
low CS0
high CS1
low DA0
high DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 2 - check state -----
low CS0
high CS1
high DA0
high DA1
high DA2
strobe read ?
save status ?
--- phase 3 - features_reg ------
low CS0
high CS1
high DA0
low DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 4 - unlock tray ------
? CS0
? CS1
? DA0
? DA1
? DA2
high byte= 0x00
lowbyte= 0x1e
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 5 - check state -----
? CS0
? CS1
? DA0
? DA1
? DA2
strobe read ?
--- phase 6 - eject ------
? CS0
? CS1
? DA0
? DA1
? DA2
high byte= 0x00
lowbyte= 0x1b
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x02
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 7 - check state -----
? CS0
? CS1
? DA0
? DA1
? DA2
strobe read ?
Attachments
Andrea I'm not sure I'm providing any extra value to you?
I don't know C. I have been giving you my understanding based on the elector pandora code (link in this thread) which i have hacked a little.
I believe you know MPASM and should be able to convert to C?
I see you have ssf80xxxx.pdf its the best doc
how to read the status AFAIK
set up the address via
CS0 CS1 DA0 DA1 DA2 - you know this
read strobe low
maybe some delay to settle
now read low byte this is atapi_status
copy the low byte to some variable
read strobe high
read the bits on the saved variable and apply logic
if the bits are not good do it again (wait)
Not sure of you last qustion,
what must you do to be able to get to the point where you can command the drive?
will answer what I can....
I don't know C. I have been giving you my understanding based on the elector pandora code (link in this thread) which i have hacked a little.
I believe you know MPASM and should be able to convert to C?
I see you have ssf80xxxx.pdf its the best doc
how to read the status AFAIK
set up the address via
CS0 CS1 DA0 DA1 DA2 - you know this
read strobe low
maybe some delay to settle
now read low byte this is atapi_status
copy the low byte to some variable
read strobe high
read the bits on the saved variable and apply logic
if the bits are not good do it again (wait)
Not sure of you last qustion,
what must you do to be able to get to the point where you can command the drive?
will answer what I can....
C source code for Audio CD
The C or the ASM is not important.
Could you try to fill the "?" point of my sequence (no C and no ASM) ?
Im any case I have buy a kit from: pradit@neonmagazine.com at 45$ + 10$ for the shipping
best regards,
A. Ciuffoli
The C or the ASM is not important.
Could you try to fill the "?" point of my sequence (no C and no ASM) ?
Im any case I have buy a kit from: pradit@neonmagazine.com at 45$ + 10$ for the shipping
best regards,
A. Ciuffoli
--- phase 1 - select device 0 ------
low CS0
high CS1
low DA0
high DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 2 - check state -----
low CS0
high CS1
high DA0
high DA1
high DA2
strobe read ?
save status ?
--- phase 3 - features_reg ------
low CS0
high CS1
high DA0
low DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 4 - unlock tray ------
low? CS0
high? CS1
low? DA0
low? DA1
low? DA2
high byte= 0x00
lowbyte= 0x1e
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
* btfss INTRQ PORTE,0 ;interrupt line
* goto $-1
* call read_status
wait until INTRQ is high then read atapi status register
--- phase 5 - check state ----- atapi status register
low? CS0
high? CS1
high? DA0
high? DA1
high? DA2
read strobe low
maybe some delay to settle
now read low byte this is atapi_status
copy the low byte to some variable
read strobe high
read the bits on the saved variable and apply logic
If the bits are not good do it again (wait)
--- phase 6 - eject ------
low? CS0
high? CS1
low? DA0
low? DA1
low? DA2
high byte= 0x00
lowbyte= 0x1b
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x02
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
wait until INTRQ is high then read atapi status register
--- phase 7 - check state ----- atapi status register
low? CS0
high? CS1
high? DA0
high? DA1
high? DA2
read strobe low
maybe some delay to settle
now read low byte this is atapi_status
copy the low byte to some variable
read strobe high
read the bits on the saved variable and apply logic
If the bits are not good do it again (wait)
low CS0
high CS1
low DA0
high DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 2 - check state -----
low CS0
high CS1
high DA0
high DA1
high DA2
strobe read ?
save status ?
--- phase 3 - features_reg ------
low CS0
high CS1
high DA0
low DA1
low DA2
high byte= 0
lowbyte= 0
strobe write = (W = 0, delay 1ms, W = 1)
--- phase 4 - unlock tray ------
low? CS0
high? CS1
low? DA0
low? DA1
low? DA2
high byte= 0x00
lowbyte= 0x1e
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
* btfss INTRQ PORTE,0 ;interrupt line
* goto $-1
* call read_status
wait until INTRQ is high then read atapi status register
--- phase 5 - check state ----- atapi status register
low? CS0
high? CS1
high? DA0
high? DA1
high? DA2
read strobe low
maybe some delay to settle
now read low byte this is atapi_status
copy the low byte to some variable
read strobe high
read the bits on the saved variable and apply logic
If the bits are not good do it again (wait)
--- phase 6 - eject ------
low? CS0
high? CS1
low? DA0
low? DA1
low? DA2
high byte= 0x00
lowbyte= 0x1b
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x02
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write
high byte= 0x00
lowbyte= 0x00
strobe write = (W = 0, delay 1ms, W = 1)
wait until INTRQ is high then read atapi status register
--- phase 7 - check state ----- atapi status register
low? CS0
high? CS1
high? DA0
high? DA1
high? DA2
read strobe low
maybe some delay to settle
now read low byte this is atapi_status
copy the low byte to some variable
read strobe high
read the bits on the saved variable and apply logic
If the bits are not good do it again (wait)
hi everyone;
For those who are interested in MUCOP which is originaly from keith wilson, there are some bugs from the original code.
From the Elektor electronics 4/2004 magazine, article of "Pandora Sound and Music Box"(attached file). The source codes provided very usefull, it provide the comment beside the code. To understand further MUCOP's code, comparing with Pandora Sound and Music Box's code is one of the best way.
To fix the bugs; its very easy. From the original Mucop code (ata_wc.asm)
, subroutine of AtaWrite Packet:
clrf AtaDataLsb
movlw ATA_REG_CYLINDERLOW
call AtaWriteRegister
clrf AtaDataLsb
movlw ATA_REG_CYLINDERHIGH
call AtaWriteRegister
As you refer to Pandora's Code under subroutine of toc_cmd
call cd_busy
movlw 0xff
movwf BCOUNT_LOW
call write_bcount_low
We are simply setting the byte count low register to a value higher than the total number of bytes that will ever be needed, so it has no impact on how the drive decides to return the data. In general, the mainthing is to make sure it's not zero.For further info, please refer to INF8020i under ATAPI Byte Count Register (ATA Cylinder High/ Low Register).
so, after the correction is
movlw 0xff
movwf AtaDataLsb
movlw ATA_REG_CYLINDERLOW
call AtaWriteRegister
movlw 0xff
movwf AtaDataLsb
movlw ATA_REG_CYLINDERHIGH
call AtaWriteRegister
Hope that this is usefull for those who doing MUCOP project.
Copyrighted material removed in agreement with advlusj6.
For those who are interested in MUCOP which is originaly from keith wilson, there are some bugs from the original code.
From the Elektor electronics 4/2004 magazine, article of "Pandora Sound and Music Box"(attached file). The source codes provided very usefull, it provide the comment beside the code. To understand further MUCOP's code, comparing with Pandora Sound and Music Box's code is one of the best way.
To fix the bugs; its very easy. From the original Mucop code (ata_wc.asm)
, subroutine of AtaWrite Packet:
clrf AtaDataLsb
movlw ATA_REG_CYLINDERLOW
call AtaWriteRegister
clrf AtaDataLsb
movlw ATA_REG_CYLINDERHIGH
call AtaWriteRegister
As you refer to Pandora's Code under subroutine of toc_cmd
call cd_busy
movlw 0xff
movwf BCOUNT_LOW
call write_bcount_low
We are simply setting the byte count low register to a value higher than the total number of bytes that will ever be needed, so it has no impact on how the drive decides to return the data. In general, the mainthing is to make sure it's not zero.For further info, please refer to INF8020i under ATAPI Byte Count Register (ATA Cylinder High/ Low Register).
so, after the correction is
movlw 0xff
movwf AtaDataLsb
movlw ATA_REG_CYLINDERLOW
call AtaWriteRegister
movlw 0xff
movwf AtaDataLsb
movlw ATA_REG_CYLINDERHIGH
call AtaWriteRegister
Hope that this is usefull for those who doing MUCOP project.
Copyrighted material removed in agreement with advlusj6.
- Home
- Source & Line
- Digital Source
- DIY CD drive based on a computer CDROM