📄 ata.c
字号:
*****************************************************************************/
bit hdd_read_sector (Uint16 nb_sector)
{
Byte i;
Byte status;
bit begin_ping_pong;
begin_ping_pong = TRUE;
do
{
for (i = 8; i != 0; i--)
{
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
Usb_write_byte(ide_data); Usb_write_byte(DAT16H);
if (begin_ping_pong)
{
begin_ping_pong = FALSE;
}
else
{
while (!Usb_tx_complete()); /* wait end of transfer */
Usb_clear_TXCMPL(); /* ack transfer */
}
Usb_set_TXRDY(); /* start usb transfer */
}
gl_ptr_mem++;
status = ide_alt_status;
status = ide_status;
nb_sector--;
if (nb_sector != 0)
{
while (Ide_notbsy_drq() == KO);
}
}
while (nb_sector != 0);
while (!Usb_tx_complete()); /* wait end of last transfer */
Usb_clear_TXCMPL(); /* ack transfer */
return OK;
}
/*F**************************************************************************
* NAME: hdd_write_open
*----------------------------------------------------------------------------
* PARAMS:
* sect: address of the the next write data
* size: number of sector
* global: gl_ptr_mem
*
* return:
* status: OK: open done
* KO: open not done
*----------------------------------------------------------------------------
* PURPOSE:
* Open media in write mode (write block)
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
* drive/head register -> LBA 27-24
* cylinder high register -> LBA 23-16
* cylinder low register -> LBA 15-8
* sector number register -> LBA 7-0
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit hdd_write_open (Uint32 sect, Byte nb_sector)
{
Byte dummy;
if (Ide_notbsy_drq() == OK)
{
if (previous_op == 0)
{
while (Ide_notbsy_drq() == OK)
dummy = ide_data;
}
else
{
if (previous_op == 1)
{
while (Ide_notbsy_drq() == OK)
{
DAT16H = 0xFF;
ide_data = 0xFF;
}
}
}
}
while (Ide_notbsy_notdrq() == KO); /* Wait for BSY = 0 */
Ide_set_drive_head(ATA_LBA_MODE + (((Byte*)§)[0] & 0x0F)); /* LBA 27-24 */
previous_op = 1;
ide_parity = 0;
gl_cpt_page = 0;
while (Ide_notbsy_notdrq() == KO); /* Wait for BSY = 0 and DRQ = 0 */
Ide_set_sector_count ( nb_sector ); /* sending parameters */
Ide_set_sector_number(((Byte*)§)[3]); /* LBA 7-0 */
Ide_set_cylinder_low (((Byte*)§)[2]); /* LBA 15-8 */
Ide_set_cylinder_high(((Byte*)§)[1]); /* LBA 23-16 */
Ide_send_command(ATA_CMD_WRITE_SECTOR); /* send command*/
gl_ptr_mem = sect; /* Update global memory pointer */
if (ide_status & IDE_ERR)
{
error |= 0x02;
}
while (Ide_notbsy_drq() == KO); /* Wait for BSY = 0 and DRQ = 1 */
return OK;
}
/*F**************************************************************************
* NAME: hdd_write_close
*----------------------------------------------------------------------------
* PARAMS:
*
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* Media write close
* finish programming end of block
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void hdd_write_close (void)
{
Byte status;
if (gl_cpt_page != 0)
{
while (gl_cpt_page != 512)
{
ide_write_databyte(0xFF);
gl_cpt_page++;
}
}
status = ide_alt_status;
status = ide_status;
}
/*F**************************************************************************
* NAME: hdd_write_byte
*----------------------------------------------------------------------------
* PARAMS:
* b: data to write
* global: gl_ptr_mem
*
* return:
* write status: OK: write done
* KO: write not done
*----------------------------------------------------------------------------
* PURPOSE:
* byte write function
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit hdd_write_byte(Byte b)
{
Byte status;
if (gl_cpt_page == 512)
{
status = ide_alt_status;
status = ide_status;
gl_ptr_mem++;
hdd_write_open(gl_ptr_mem, 1); /* open at next sector */
}
gl_cpt_page++;
ide_write_databyte(b);
return OK;
}
/*F*************************************************************************
* NAME: hdd_write_one_sector
*---------------------------------------------------------------------------
* PARAMS:
* global: gl_ptr_mem
*
* return:
*
*----------------------------------------------------------------------------
* PURPOSE:
* write one sector from buffer
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
****************************************************************************/
void hdd_write_one_sector(void)
{
if (gl_cpt_page == 512)
{
status = ide_alt_status;
status = ide_status;
gl_ptr_mem++;
hdd_write_open(gl_ptr_mem, 1); /* open the next sector */
}
ata_download_sector();
gl_cpt_page += 512;
}
/*F**************************************************************************
* NAME: hdd_write_sector
*----------------------------------------------------------------------------
* PARAMS:
* global: gl_ptr_mem
*
* return:
* write status: OK: write done
* KO: write not done
*----------------------------------------------------------------------------
* PURPOSE:
* This function is an optimized function that writes 512 bytes from USB
* controller to HDD card
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit hdd_write_sector (Uint16 nb_sector)
{
Byte i;
do
{
for (i = 8; i != 0; i--)
{
while (!Usb_rx_complete()); /* wait end of reception */
hdd_download_data_usb();
Usb_clear_RXOUT_PP(); /* usb read acknowledgement */
}
nb_sector--;
i = ide_alt_status;
i = ide_status;
if (nb_sector != 0)
{
while (Ide_notbsy_drq() == KO);
i = ide_status;
}
}
while (nb_sector != 0);
return OK;
}
/*F**************************************************************************
* NAME: hdd_check_presence
*----------------------------------------------------------------------------
* PARAMS:
*
*
* return:
*
*----------------------------------------------------------------------------
* PURPOSE:
*
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit hdd_check_presence(void)
{
return OK;
}
/*F**************************************************************************
* NAME: hdd_format
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*
*----------------------------------------------------------------------------
* PURPOSE:
* This function is called by the fat_format function and returns a pointer
* to a table containing the format parameters.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
s_format xdata *hdd_format(void)
{
Byte i, temp;
Uint16 dummy;
xdata s_format format;
format.nb_cylinder = 0x00; /* Number of cylinders */
format.nb_head = 0x00; /* Number of heads */
format.nb_sector = 0x00; /* Number of sector/track */
format.nb_hidden_sector = 0x00;
while (Ide_notbsy() == KO); /* Wait for BSY = 0 */
Ide_set_drive_head (ATA_LBA_MODE); /* Select Drive / Head */
while (Ide_notbsy_drdy() == KO);
Ide_send_command(ATA_CMD_IDENTIFY_DRIVE);/* send command */
while ( Ide_notbsy_drq() == KO ); /* Check if data request bit set */
for (i = 54; i != 0; i--)
{
dummy = ide_read_dataword(); /* dummy reads */
}
format.nb_cylinder = ide_read_dataword(); /* Number of cylinders */
format.nb_head = ide_read_dataword(); /* Number of heads */
format.nb_sector = ide_read_dataword(); /* Number of sector/track */
format.nb_hidden_sector = 32;
/* cluster size determination */
if (hdd_mem_size <= 532480) /* up to 260Mb, 0.5K cluster FAT32 */
temp = 1;
else
if (hdd_mem_size <= 16777216) /* up to 8Gb, 4K cluster FAT32 */
temp = 8;
else
if (hdd_mem_size <= 33554432) /* up to 16Gb, 8K cluster FAT32 */
temp = 16;
else
if (hdd_mem_size <= 67108864) /* up to 32Gb, 16K cluster FAT32 */
temp = 32;
else
temp = 64; /* disks greater than 32Gb, 32K cluster size */
format.nb_sector_per_cluster = temp;
i = 54;
while (Ide_notbsy_drq() == OK)
{
dummy = ide_read_dataword(); /* dummy reads */
i++;
}
return &format;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -