nicer code
This commit is contained in:
parent
2435c37f7e
commit
2c5e145084
|
|
@ -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"
|
||||
|
|
@ -39,173 +39,150 @@
|
|||
uint8_t pata_bsy();
|
||||
uint8_t pata_rdy();
|
||||
uint8_t pata_drq();
|
||||
void pata_cmd ( uint8_t cmd );
|
||||
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();
|
||||
|
||||
|
||||
/*
|
||||
* 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 )
|
||||
{
|
||||
port_data_set ( byte );
|
||||
enable_atalatch();
|
||||
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 byte;
|
||||
|
||||
enable_rdwrtoata();
|
||||
nop();
|
||||
nop();
|
||||
return port_data_get();
|
||||
byte = port_data_get();
|
||||
disable_rdwrtoata();
|
||||
|
||||
return(byte);
|
||||
}
|
||||
|
||||
uint8_t pata_get_highbyte ()
|
||||
{
|
||||
uint8_t byte;
|
||||
|
||||
enable_atalatch();
|
||||
nop();
|
||||
nop();
|
||||
nop();
|
||||
byte = port_data_get();
|
||||
init_addressdecoder();
|
||||
disable_atalatch();
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
uint8_t pata_read_byte()
|
||||
uint8_t read_io_register ( uint8_t ioreg )
|
||||
{
|
||||
uint8_t byte;
|
||||
|
||||
configure_port_data_read();
|
||||
|
||||
set_io_register ( ioreg );
|
||||
ata_rd_enable();
|
||||
enable_rdwrtoata();
|
||||
_delay_us ( 1 );
|
||||
byte = pata_get_lowbyte();
|
||||
init_addressdecoder();
|
||||
ata_rd_disable();
|
||||
ata_ctl_high();
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
void pata_write_byte ( uint8_t byte )
|
||||
void write_io_register ( uint8_t ioreg, uint8_t byte )
|
||||
{
|
||||
configure_port_data_write();
|
||||
pata_set_lowbyte ( byte );
|
||||
enable_rdwrtoata();
|
||||
|
||||
set_io_register ( ioreg );
|
||||
ata_wr_enable();
|
||||
_delay_us ( 1 );
|
||||
pata_set_lowbyte ( byte );
|
||||
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();
|
||||
|
||||
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 word;
|
||||
uint8_t byte_l;
|
||||
uint8_t byte_h;
|
||||
|
||||
ata_da0_enable();
|
||||
ata_da1_enable();
|
||||
ata_da2_enable();
|
||||
ata_cs0_enable();
|
||||
configure_port_data_read();
|
||||
|
||||
set_io_register ( PATA_RD_DATA_REGISTER );
|
||||
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();
|
||||
byte_l = pata_get_lowbyte();
|
||||
byte_h = pata_get_highbyte();
|
||||
ata_rd_disable();
|
||||
|
||||
ata_ctl_high();
|
||||
|
||||
word = byte_h << 8;
|
||||
|
|
@ -214,148 +191,67 @@ uint16_t pata_read_single_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()
|
||||
{
|
||||
uint32_t dword;
|
||||
uint16_t word;
|
||||
uint8_t byte_l,byte_h;
|
||||
uint8_t byte_l, byte_h;
|
||||
|
||||
/*command*/
|
||||
while ( pata_bsy() );
|
||||
ata_cs0_enable();
|
||||
pata_write_byte ( 0xEc ); // Identify
|
||||
ata_ctl_high();
|
||||
write_io_register ( PATA_WR_COMMAND_REGISTER, CMD_IDENTIFY_DEVICE );
|
||||
|
||||
/* 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();
|
||||
uart_puts_p ( PSTR ( "Number of logical cylinders: " ) );
|
||||
uart_putw_dec(word);
|
||||
uart_putc('\n');
|
||||
uart_putw_dec ( word );
|
||||
uart_putc ( '\n' );
|
||||
word = pata_read_single_word(); // Specific configuration
|
||||
word = pata_read_single_word();
|
||||
uart_puts_p ( PSTR ( "Number of logical heads: " ) );
|
||||
uart_putw_dec(word);
|
||||
uart_putc('\n');
|
||||
uart_putw_dec ( word );
|
||||
uart_putc ( '\n' );
|
||||
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_putw_dec(word);
|
||||
uart_putc('\n');
|
||||
uart_putw_dec ( word );
|
||||
uart_putc ( '\n' );
|
||||
word = pata_read_single_word(); // CompactFlash
|
||||
word = pata_read_single_word(); // CompactFlash
|
||||
word = pata_read_single_word(); // Retired
|
||||
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();
|
||||
byte_h = word >> 8;
|
||||
byte_l = word & 0x00FF;
|
||||
uart_putc(byte_h);
|
||||
uart_putc(byte_l);
|
||||
uart_putc ( byte_h );
|
||||
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(); // Obsolete
|
||||
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();
|
||||
byte_h = word >> 8;
|
||||
byte_l = word & 0x00FF;
|
||||
uart_putc(byte_h);
|
||||
uart_putc(byte_l);
|
||||
uart_putc ( byte_h );
|
||||
uart_putc ( byte_l );
|
||||
}
|
||||
uart_putc('\n');
|
||||
uart_putc ( '\n' );
|
||||
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();
|
||||
byte_h = word >> 8;
|
||||
byte_l = word & 0x00FF;
|
||||
uart_putc(byte_h);
|
||||
uart_putc(byte_l);
|
||||
uart_putc ( byte_h );
|
||||
uart_putc ( byte_l );
|
||||
}
|
||||
uart_putc('\n');
|
||||
uart_putc ( '\n' );
|
||||
word = pata_read_single_word(); // no idea
|
||||
word = pata_read_single_word(); // Reserved
|
||||
word = pata_read_single_word(); // Capabilities
|
||||
|
|
@ -365,71 +261,64 @@ void ata_identify()
|
|||
word = pata_read_single_word(); // Reserved
|
||||
word = pata_read_single_word();
|
||||
uart_puts_p ( PSTR ( "Number of current logical cylinders: " ) );
|
||||
uart_putw_dec(word);
|
||||
uart_putc('\n');
|
||||
uart_putw_dec ( word );
|
||||
uart_putc ( '\n' );
|
||||
word = pata_read_single_word();
|
||||
uart_puts_p ( PSTR ( "Number of current logical heads: " ) );
|
||||
uart_putw_dec(word);
|
||||
uart_putc('\n');
|
||||
uart_putw_dec ( word );
|
||||
uart_putc ( '\n' );
|
||||
word = pata_read_single_word();
|
||||
uart_puts_p ( PSTR ( "Number of current logical sectors per track: " ) );
|
||||
uart_putw_dec(word);
|
||||
uart_putc('\n');
|
||||
uart_putw_dec ( word );
|
||||
uart_putc ( '\n' );
|
||||
word = pata_read_single_word();
|
||||
dword = 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_putdw_dec(dword);
|
||||
uart_putc('\n');
|
||||
uart_putdw_dec ( dword );
|
||||
uart_putc ( '\n' );
|
||||
word = pata_read_single_word(); // Reserved
|
||||
word = pata_read_single_word();
|
||||
dword = 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_putdw_dec(dword);
|
||||
uart_putc('\n');
|
||||
uart_putdw_dec ( dword );
|
||||
uart_putc ( '\n' );
|
||||
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
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
uint8_t i;
|
||||
if ( ata_get_status_byte() & ATA_STAT_DRQ )
|
||||
i = 1;
|
||||
else
|
||||
i = 0;
|
||||
return i;
|
||||
}
|
||||
/*
|
||||
* Public functions
|
||||
*/
|
||||
|
||||
void pata_cmd ( uint8_t cmd )
|
||||
uint8_t pata_init ()
|
||||
{
|
||||
ata_cs0_enable();
|
||||
pata_write_byte ( cmd );
|
||||
ata_ctl_high();
|
||||
|
||||
// is needed for some disks (for example Maxtor 6L080J4)
|
||||
_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 )
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
@ -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_ERR 0x01 // ATA error
|
||||
|
||||
#define ATA_DH_DEV0 0xE0
|
||||
#define ATA_DH_DEV1 0xF0
|
||||
#define ATA_LBA_DRIVE_0 0xE0
|
||||
#define ATA_LBA_DRIVE_1 0xF0
|
||||
|
||||
//ATA commands (from ATA-3),
|
||||
#define CMD_CFA_ERASE_SECTORS 0xC0
|
||||
|
|
|
|||
Loading…
Reference in New Issue