nicer code

This commit is contained in:
Oliver Lehmann 2012-06-16 00:33:26 +00:00
parent 2435c37f7e
commit 2c5e145084
2 changed files with 152 additions and 263 deletions

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_drv_pata.c,v 1.4 2012/06/15 22:42:42 olivleh1 Exp $ * $Id: wdc_drv_pata.c,v 1.5 2012/06/16 00:33:26 olivleh1 Exp $
*/ */
#include "wdc_config.h" #include "wdc_config.h"
@ -39,173 +39,150 @@
uint8_t pata_bsy(); uint8_t pata_bsy();
uint8_t pata_rdy(); uint8_t pata_rdy();
uint8_t pata_drq(); uint8_t pata_drq();
void pata_cmd ( uint8_t cmd );
void ata_identify(); void ata_identify();
void pata_set_highbyte(uint8_t byte);
void pata_set_lowbyte(uint8_t byte);
uint8_t pata_get_highbyte();
uint8_t pata_get_lowbyte();
void set_io_register( uint8_t ioreg );
uint8_t read_io_register( uint8_t ioreg );
void write_io_register( uint8_t ioreg, uint8_t byte );
uint16_t pata_read_single_word ();
/*
* +----- CS0
* |+---- CS1
* ||+--- DA0
* |||+-- DA1
* ||||+- DA2
* |||||*/
#define PATA_RD_STATUS_REGISTER 0x0F /* 0b01111*/
#define PATA_WR_COMMAND_REGISTER 0x0F /* 0b01111*/
#define PATA_WR_DEVICE_CONTROL_REGISTER 0x0B /* 0b01011*/
#define PATA_RD_DATA_REGISTER 0x08 /* 0b01000*/
#define ata_ctl_high() ata_cs0_disable();ata_cs1_disable();ata_da0_disable();ata_da1_disable();ata_da2_disable(); #define ata_ctl_high() ata_cs0_disable();ata_cs1_disable();ata_da0_disable();ata_da1_disable();ata_da2_disable();
/*
* Private functions
*/
uint8_t pata_rdy()
{
return (read_io_register ( PATA_RD_STATUS_REGISTER ) & ATA_STAT_RDY )?1:0;
}
uint8_t pata_bsy()
{
return (read_io_register ( PATA_RD_STATUS_REGISTER ) & ATA_STAT_BSY )?1:0;
}
uint8_t pata_drq()
{
return (read_io_register ( PATA_RD_STATUS_REGISTER ) & ATA_STAT_DRQ )?1:0;
}
void set_io_register ( uint8_t ioreg )
{
if ( ! ( ioreg & ( 1 << 0 ) ) )
ata_da2_enable();
if ( ! ( ioreg & ( 1 << 1 ) ) )
ata_da1_enable();
if ( ! ( ioreg & ( 1 << 2 ) ) )
ata_da0_enable();
if ( ! ( ioreg & ( 1 << 3 ) ) )
ata_cs1_enable();
if ( ! ( ioreg & ( 1 << 4 ) ) )
ata_cs0_enable();
}
void pata_set_lowbyte ( uint8_t byte )
{
port_data_set ( byte );
enable_rdwrtoata();
nop();
nop();
disable_rdwrtoata();
}
void pata_set_highbyte ( uint8_t byte ) void pata_set_highbyte ( uint8_t byte )
{ {
port_data_set ( byte ); port_data_set ( byte );
enable_atalatch(); enable_atalatch();
nop(); nop();
nop(); nop();
init_addressdecoder(); disable_atalatch();
} }
void pata_set_lowbyte ( uint8_t byte )
{
port_data_set ( byte );
}
void pata_send_data()
{
enable_rdwrtoata();
_delay_us ( 10 );
init_addressdecoder();
}
uint8_t pata_get_lowbyte () uint8_t pata_get_lowbyte ()
{ {
uint8_t byte;
enable_rdwrtoata();
nop(); nop();
nop(); nop();
return port_data_get(); byte = port_data_get();
disable_rdwrtoata();
return(byte);
} }
uint8_t pata_get_highbyte () uint8_t pata_get_highbyte ()
{ {
uint8_t byte; uint8_t byte;
enable_atalatch(); enable_atalatch();
nop(); nop();
nop(); nop();
nop();
byte = port_data_get(); byte = port_data_get();
init_addressdecoder(); disable_atalatch();
return byte; return byte;
} }
uint8_t pata_read_byte() uint8_t read_io_register ( uint8_t ioreg )
{ {
uint8_t byte; uint8_t byte;
configure_port_data_read(); configure_port_data_read();
set_io_register ( ioreg );
ata_rd_enable(); ata_rd_enable();
enable_rdwrtoata();
_delay_us ( 1 );
byte = pata_get_lowbyte(); byte = pata_get_lowbyte();
init_addressdecoder();
ata_rd_disable(); ata_rd_disable();
ata_ctl_high();
return byte; return byte;
} }
void pata_write_byte ( uint8_t byte ) void write_io_register ( uint8_t ioreg, uint8_t byte )
{ {
configure_port_data_write(); configure_port_data_write();
pata_set_lowbyte ( byte );
enable_rdwrtoata(); set_io_register ( ioreg );
ata_wr_enable(); ata_wr_enable();
_delay_us ( 1 ); pata_set_lowbyte ( byte );
ata_wr_disable(); ata_wr_disable();
init_addressdecoder();
}
uint8_t ata_get_status_byte ( void )
{
uint8_t byte;
ata_cs0_enable();
byte = pata_read_byte();
ata_ctl_high(); ata_ctl_high();
return byte;
} }
uint8_t ata_get_alt_status_byte ( void )
{
uint8_t byte;
ata_cs1_enable();
ata_da0_enable();
byte = pata_read_byte();
ata_ctl_high();
return byte;
}
uint16_t pata_read_word ( uint8_t ofs, uint8_t count )
{
uint16_t word;
uint8_t byte_l;
uint8_t byte_h;
uint8_t c = 0;
ata_da0_enable();
ata_da1_enable();
ata_da2_enable();
ata_cs0_enable();
do {
ata_rd_enable();
enable_rdwrtoata();
nop();
nop();
nop();
byte_l = port_data_get();
disable_rdwrtoata();
enable_atalatch();
nop();
nop();
nop();
byte_h = port_data_get();
disable_atalatch();
ata_rd_disable();
if ( count && ( c >= ofs ) ) {
uart_putc ( byte_h );
uart_putc ( byte_l );
count--;
}
} while ( ++c );
ata_ctl_high();
word = byte_h << 8;
word |= byte_l;
return ( word );
}
uint16_t pata_read_single_word () uint16_t pata_read_single_word ()
{ {
uint16_t word; uint16_t word;
uint8_t byte_l; uint8_t byte_l;
uint8_t byte_h; uint8_t byte_h;
ata_da0_enable(); configure_port_data_read();
ata_da1_enable();
ata_da2_enable();
ata_cs0_enable();
set_io_register ( PATA_RD_DATA_REGISTER );
ata_rd_enable(); ata_rd_enable();
enable_rdwrtoata(); byte_l = pata_get_lowbyte();
nop(); byte_h = pata_get_highbyte();
nop();
nop();
byte_l = port_data_get();
disable_rdwrtoata();
enable_atalatch();
nop();
nop();
nop();
byte_h = port_data_get();
disable_atalatch();
ata_rd_disable(); ata_rd_disable();
ata_ctl_high(); ata_ctl_high();
word = byte_h << 8; word = byte_h << 8;
@ -214,148 +191,67 @@ uint16_t pata_read_single_word ()
return ( word ); return ( word );
} }
uint8_t pata_init ()
{
// is needed for some disks (for example Maxtor 6L080J4)
_delay_ms ( 100 );
uart_puts_p ( PSTR ( "Init start\n" ) );
while ( ( !pata_rdy() ) & pata_bsy() );
uart_putc_hex ( ata_get_status_byte() );
/*device register*/
ata_da0_enable();
ata_cs0_enable();
#ifdef PIO
pata_write_byte ( 0 ); // Drive 0, PIO
#else
pata_write_byte ( 0xE0 ); // Drive 0, LBA
#endif
ata_ctl_high();
#ifdef PIO
while ( pata_bsy() );
//device control
ata_da0_enable();
ata_cs1_enable();
pata_write_byte ( 0x40 | 0x20 ); // reset + no interrupt
ata_ctl_high();
_delay_ms ( 20 );
ata_da0_enable();
ata_cs1_enable();
pata_write_byte ( 0x20 ); // no interrupt
ata_ctl_high();
_delay_ms ( 20 );
while ( ( !pata_rdy() ) & pata_bsy() );
//feature register
ata_da1_enable();
ata_da2_enable();
ata_cs0_enable();
pata_write_byte ( 3 ); // PIO
ata_ctl_high();
//sector count
ata_da0_enable();
ata_da2_enable();
ata_cs0_enable();
pata_write_byte ( 1 );
ata_ctl_high();
//command
ata_cs0_enable();
pata_write_byte ( 0xEF ); // Set Features
ata_ctl_high();
#else
while ( ( !pata_rdy() ) & pata_bsy() );
/*command*/
ata_cs0_enable();
pata_write_byte ( 0x10 ); // Recalibrate
ata_ctl_high();
#endif
while ( pata_bsy() );
uart_puts_p ( PSTR ( "disk is now ready\n" ) );
ata_identify();
return 1;
}
void ata_identify() void ata_identify()
{ {
uint32_t dword; uint32_t dword;
uint16_t word; uint16_t word;
uint8_t byte_l,byte_h; uint8_t byte_l, byte_h;
/*command*/
while ( pata_bsy() ); while ( pata_bsy() );
ata_cs0_enable(); write_io_register ( PATA_WR_COMMAND_REGISTER, CMD_IDENTIFY_DEVICE );
pata_write_byte ( 0xEc ); // Identify
ata_ctl_high();
/* Wait for BSY goes low and DRQ goes high */ /* Wait for BSY goes low and DRQ goes high */
while ( ( ata_get_status_byte() & ( ATA_STAT_BSY | ATA_STAT_DRQ ) ) != ATA_STAT_DRQ ); while ( pata_bsy() & !pata_drq() );
word = pata_read_single_word(); // General configuration bit word = pata_read_single_word(); // General configuration bit
word = pata_read_single_word(); word = pata_read_single_word();
uart_puts_p ( PSTR ( "Number of logical cylinders: " ) ); uart_puts_p ( PSTR ( "Number of logical cylinders: " ) );
uart_putw_dec(word); uart_putw_dec ( word );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); // Specific configuration word = pata_read_single_word(); // Specific configuration
word = pata_read_single_word(); word = pata_read_single_word();
uart_puts_p ( PSTR ( "Number of logical heads: " ) ); uart_puts_p ( PSTR ( "Number of logical heads: " ) );
uart_putw_dec(word); uart_putw_dec ( word );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); word = pata_read_single_word();
word = pata_read_single_word(); word = pata_read_single_word();
word = pata_read_single_word(); word = pata_read_single_word();
uart_puts_p ( PSTR ( "Number of logical sectors per logical track: " ) ); uart_puts_p ( PSTR ( "Number of logical sectors per logical track: " ) );
uart_putw_dec(word); uart_putw_dec ( word );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); // CompactFlash word = pata_read_single_word(); // CompactFlash
word = pata_read_single_word(); // CompactFlash word = pata_read_single_word(); // CompactFlash
word = pata_read_single_word(); // Retired word = pata_read_single_word(); // Retired
uart_puts_p ( PSTR ( "Serial number: " ) ); uart_puts_p ( PSTR ( "Serial number: " ) );
for(uint8_t i=0;i<10;i++) { for ( uint8_t i = 0; i < 10; i++ ) {
word = pata_read_single_word(); word = pata_read_single_word();
byte_h = word >> 8; byte_h = word >> 8;
byte_l = word & 0x00FF; byte_l = word & 0x00FF;
uart_putc(byte_h); uart_putc ( byte_h );
uart_putc(byte_l); uart_putc ( byte_l );
} }
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); // Retired word = pata_read_single_word(); // Retired
word = pata_read_single_word(); // Retired word = pata_read_single_word(); // Retired
word = pata_read_single_word(); // Obsolete word = pata_read_single_word(); // Obsolete
uart_puts_p ( PSTR ( "Firmware revision: " ) ); uart_puts_p ( PSTR ( "Firmware revision: " ) );
for(uint8_t i=0;i<4;i++) { for ( uint8_t i = 0; i < 4; i++ ) {
word = pata_read_single_word(); word = pata_read_single_word();
byte_h = word >> 8; byte_h = word >> 8;
byte_l = word & 0x00FF; byte_l = word & 0x00FF;
uart_putc(byte_h); uart_putc ( byte_h );
uart_putc(byte_l); uart_putc ( byte_l );
} }
uart_putc('\n'); uart_putc ( '\n' );
uart_puts_p ( PSTR ( "Model number: " ) ); uart_puts_p ( PSTR ( "Model number: " ) );
for(uint8_t i=0;i<20;i++) { for ( uint8_t i = 0; i < 20; i++ ) {
word = pata_read_single_word(); word = pata_read_single_word();
byte_h = word >> 8; byte_h = word >> 8;
byte_l = word & 0x00FF; byte_l = word & 0x00FF;
uart_putc(byte_h); uart_putc ( byte_h );
uart_putc(byte_l); uart_putc ( byte_l );
} }
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); // no idea word = pata_read_single_word(); // no idea
word = pata_read_single_word(); // Reserved word = pata_read_single_word(); // Reserved
word = pata_read_single_word(); // Capabilities word = pata_read_single_word(); // Capabilities
@ -365,71 +261,64 @@ void ata_identify()
word = pata_read_single_word(); // Reserved word = pata_read_single_word(); // Reserved
word = pata_read_single_word(); word = pata_read_single_word();
uart_puts_p ( PSTR ( "Number of current logical cylinders: " ) ); uart_puts_p ( PSTR ( "Number of current logical cylinders: " ) );
uart_putw_dec(word); uart_putw_dec ( word );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); word = pata_read_single_word();
uart_puts_p ( PSTR ( "Number of current logical heads: " ) ); uart_puts_p ( PSTR ( "Number of current logical heads: " ) );
uart_putw_dec(word); uart_putw_dec ( word );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); word = pata_read_single_word();
uart_puts_p ( PSTR ( "Number of current logical sectors per track: " ) ); uart_puts_p ( PSTR ( "Number of current logical sectors per track: " ) );
uart_putw_dec(word); uart_putw_dec ( word );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); word = pata_read_single_word();
dword = word; dword = word;
word = pata_read_single_word(); word = pata_read_single_word();
dword |= (uint32_t)word<<16; dword |= ( uint32_t ) word << 16;
uart_puts_p ( PSTR ( "Current capacity in sectors: " ) ); uart_puts_p ( PSTR ( "Current capacity in sectors: " ) );
uart_putdw_dec(dword); uart_putdw_dec ( dword );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); // Reserved word = pata_read_single_word(); // Reserved
word = pata_read_single_word(); word = pata_read_single_word();
dword = word; dword = word;
word = pata_read_single_word(); word = pata_read_single_word();
dword |= (uint32_t)word <<16; dword |= ( uint32_t ) word << 16;
uart_puts_p ( PSTR ( "Total number of user addressable sectors (LBA mode only): " ) ); uart_puts_p ( PSTR ( "Total number of user addressable sectors (LBA mode only): " ) );
uart_putdw_dec(dword); uart_putdw_dec ( dword );
uart_putc('\n'); uart_putc ( '\n' );
word = pata_read_single_word(); // Obsolete word = pata_read_single_word(); // Obsolete
for(uint8_t i=0;i<193;i++) for ( uint8_t i = 0; i < 193; i++ )
word = pata_read_single_word(); // ignore it word = pata_read_single_word(); // ignore it
} }
uint8_t pata_rdy()
{
uint8_t i;
if ( ata_get_status_byte() & ATA_STAT_RDY )
i = 1;
else
i = 0;
return i;
}
uint8_t pata_bsy()
{
uint8_t i;
if ( ata_get_status_byte() & ATA_STAT_BSY )
i = 1;
else
i = 0;
return i;
}
uint8_t pata_drq() /*
{ * Public functions
uint8_t i; */
if ( ata_get_status_byte() & ATA_STAT_DRQ )
i = 1;
else
i = 0;
return i;
}
void pata_cmd ( uint8_t cmd ) uint8_t pata_init ()
{ {
ata_cs0_enable();
pata_write_byte ( cmd ); // is needed for some disks (for example Maxtor 6L080J4)
ata_ctl_high(); _delay_ms ( 200 );
uart_puts_p ( PSTR ( "Init start\n" ) );
while ( ( !pata_rdy() ) & pata_bsy() );
/*set drive 0 to LBA mode*/
write_io_register ( PATA_WR_DEVICE_CONTROL_REGISTER, ATA_LBA_DRIVE_0 );
while ( ( !pata_rdy() ) & pata_bsy() );
/*recalibrate*/
write_io_register ( PATA_WR_COMMAND_REGISTER, CMD_RECALIBRATE );
while ( pata_bsy() );
uart_puts_p ( PSTR ( "disk is now ready\n" ) );
ata_identify();
return 1;
} }
uint8_t pata_read_block ( uint32_t addr, uint8_t *buffer ) uint8_t pata_read_block ( uint32_t addr, uint8_t *buffer )

View File

@ -26,7 +26,7 @@
*/ */
/* /*
* $Id: wdc_drv_pata.h,v 1.4 2012/06/15 22:42:42 olivleh1 Exp $ * $Id: wdc_drv_pata.h,v 1.5 2012/06/16 00:33:26 olivleh1 Exp $
*/ */
#ifndef WDC_DRV_PATA_H_ #ifndef WDC_DRV_PATA_H_
@ -50,8 +50,8 @@ extern uint8_t pata_write_multiblock ( uint32_t addr, uint8_t *buffer, uint8_t n
#define ATA_STAT_IDX 0x02 // ATA index #define ATA_STAT_IDX 0x02 // ATA index
#define ATA_STAT_ERR 0x01 // ATA error #define ATA_STAT_ERR 0x01 // ATA error
#define ATA_DH_DEV0 0xE0 #define ATA_LBA_DRIVE_0 0xE0
#define ATA_DH_DEV1 0xF0 #define ATA_LBA_DRIVE_1 0xF0
//ATA commands (from ATA-3), //ATA commands (from ATA-3),
#define CMD_CFA_ERASE_SECTORS 0xC0 #define CMD_CFA_ERASE_SECTORS 0xC0