⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ata.c

📁 ATMEL 89c51sndc mp3外接硬盘源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*C**************************************************************************
* NAME:         ata.c
*----------------------------------------------------------------------------
* Copyright (c) 2002 Atmel.
*----------------------------------------------------------------------------
* RELEASE:      snd1c-demo-hdd-0_2_0      
* REVISION:     1.1     
*----------------------------------------------------------------------------
* PURPOSE:
* This file contains the high level ATA routines
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/

#include "config.h"                           /* system configuration */
#include "lib_demob\board.h"                  /* board definition  */
#include "lib\usb\usb_drv.h"                  /* usb driver definition */
#include "ide.h"                              /* ide definition */
#include "ata.h"                              /* ata definition */


/*_____ M A C R O S ________________________________________________________*/


/*_____ D E F I N I T I O N ________________________________________________*/

extern  data    Uint32  gl_ptr_mem;               /* memory data pointer    */
xdata           Uint32  hdd_mem_size;             /* HDD size in sector     */

data Uint16 gl_cpt_page;

extern  bdata bit ide_parity;

/* IDE registers */
/*                          name                    |  RD# = 0       |   WR# = 0   | */
extern  xdata Byte volatile ide_data;           /*  | RD data        | WR data     | */
extern  xdata Byte volatile ide_error;          /*  | Error          | Features    | */
extern  xdata Byte ide_sector_count;            /*  | Sect. count    | Sect. count | */
extern  xdata Byte ide_sector_number;           /*  | Sect. No       | Sect. No    | */
extern  xdata Byte ide_cylinder_low;            /*  | Cyl. Low       | Cyl. Low    | */
extern  xdata Byte ide_cylinder_high;           /*  | Cyl. High      | Cyl. High   | */
extern  xdata Byte ide_drive_head;              /*  | Drive/Head     | Drive/Head  | */
extern  xdata Byte volatile ide_status;         /*  | Status         | Command     | */
extern  xdata Byte volatile ide_alt_status;     /*  | Alt status     | Device Ctrl | */

extern  xdata Byte volatile ide_reset_on;
extern  xdata Byte volatile ide_reset_off;
code Uint32 hdd_block_size = Hdd_block_size();

extern xdata Byte fat_buf_sector[]; /* 512 bytes buffer */

Byte previous_op;
Uint16 error;


/*_____ D E C L A R A T I O N ______________________________________________*/

extern void fat_format (void);


/*F**************************************************************************
* NAME: hdd_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   OK if HDD is ready, KO else
*----------------------------------------------------------------------------
* PURPOSE: 
*   Hard Disk Drive initialisation
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
bit hdd_init(void)
{
Byte dummy;

  Ide_set_ide_mode();
  P2 = IDE_PORT_IDLE;
  P5_2 = 1;                                         /* P5_2 is RST# */

  ide_device_control = ATA_RESET_CMD;
  for (dummy = 255; dummy != 0; dummy--);
  ide_device_control = 0xFA;
  for (dummy = 255; dummy != 0; dummy--);
  while (Ide_notbsy() == KO);                       /* Wait for  BSY = 0 */
  while (Ide_notbsy_drdy() == KO);                  /*  Wait for BSY = 0  and DRDY = 1 */
  error = ide_error;

  Ide_set_drive_head(ATA_LBA_MODE);                 /*  Select Drive/Head */
  while (Ide_notbsy_drdy() == KO);                  /*  Wait for BSY = 0  and DRDY = 1 */
  dummy = Ide_get_status();                         /*  Read status byte */        
  if ( ((dummy & IDE_ERR) == IDE_ERR)  ||           /*  Check if there is an error */
       ((dummy & IDE_DRDY) != IDE_DRDY) )           /*  or DRDY = 0 */
    return KO;

  dummy = Ide_get_status();                         /* Clear pending interrupt */

  P1_6 = P1_7 = 1;
  previous_op = 3;
  return OK;
}


/*F**************************************************************************
* NAME: ata_identify_device
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*   General Configuration Information
*----------------------------------------------------------------------------
* PURPOSE: 
*   Identifies a device and gives its characteristics
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Uint16 ata_identify_device (void)
{
Uint16 ata_gci;
Byte i;
Uint16 j;

  while (Ide_notbsy_notdrq() == KO);                      /* Wait for  BSY = 0 */
  Ide_set_drive_head (ATA_LBA_MODE);              /* Select Drive / Head */
  while (Ide_notbsy_drdy() == KO);                /* Wait for BSY = 0 and DRDY = 1 */
  Ide_send_command(ATA_CMD_IDENTIFY_DRIVE);       /* send command */
  while (Ide_notbsy_drq() == KO );                /* Check if data request bit set */
  ata_gci = ide_read_dataword();                  /* General Configuration Information */
  for (i = 56; i !=0 ; i--)                       /* dummy reads */
    ide_read_dataword();                                     
  hdd_mem_size = ide_read_dataword();             /* Number of sectors */
  hdd_mem_size |= (Uint32)(ide_read_dataword()) << 16;                
  while (Ide_notbsy_drq() == OK)                  /* While data request bit is set */
  {
    ide_read_dataword();
  }

  i = 3;
  do
  {
    for (j = 0; j < 20; j++);
    P1_6 = 0;
    hdd_read_open(0,1);
    hdd_read_close();
    hdd_read_open(256, 1);
    hdd_read_close();
    hdd_read_open(512, 1);
    hdd_read_close();
    hdd_read_open(409600, 1);
    hdd_read_close();    
    hdd_read_open(409601, 1);
    hdd_read_close();
    hdd_read_open(409602, 1);
    hdd_read_close();
    P1_6 = 1;
  }
  while (i == 3);

  return (ata_gci);
} 


/*F**************************************************************************
* NAME: hdd_read_open
*----------------------------------------------------------------------------
* PARAMS:
*   sect: address of the logic sector to read (size 512 bytes)
*   size : number of sector
*   global: gl_ptr_mem
*
* return:
*   open status:  OK: open done
*                 KO: open not done
*----------------------------------------------------------------------------
* PURPOSE: 
*   Open memory card in read mode (read 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_read_open (Uint32 sect, Byte nb_sector)
{
Byte ata_status;

  if (Ide_notbsy_drq() == OK)
  {
    if (previous_op == 0)
    {
      while (Ide_notbsy_drq() == OK)
        ata_status = 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 */
  P1_7 = 0;
  Ide_set_drive_head( ATA_LBA_MODE + (((Byte*)&sect)[0] & 0x0F));   /* LBA 27-24 */

  gl_cpt_page = 0;

  ide_parity = 0;
  previous_op = 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*)&sect)[3]);           /* LBA 7-0    */
  Ide_set_cylinder_low (((Byte*)&sect)[2]);           /* LBA 15-8   */
  Ide_set_cylinder_high(((Byte*)&sect)[1]);           /* LBA 23-16  */
  Ide_send_command(ATA_CMD_READ_SECTOR);              /* send command */
  gl_ptr_mem = sect;      /* Initialize the global byte counter */
  if (ide_status & IDE_ERR)
  {
    error = 1;
  }
  ata_status = ide_alt_status;

  while (Ide_notbsy_drq() == KO);
  P1_7 = 1;
  return OK; 
}


/*F**************************************************************************
* NAME: hdd_read_close
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE: 
*   read close
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void hdd_read_close(void)
{
Byte status;

  if (gl_cpt_page != 0)
    if (gl_cpt_page != 512)
      do
      {
        gl_cpt_page++;
        ide_read_databyte();
      }
      while (gl_cpt_page != 512);
  status = ide_alt_status;
  status = ide_status;
}


/*F*************************************************************************
* NAME: hdd_read_byte
*---------------------------------------------------------------------------
* PARAMS:
*   global: gl_ptr_mem
*
* return:
*   Data read from media
*----------------------------------------------------------------------------
* PURPOSE: 
*   Byte read function
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   
*----------------------------------------------------------------------------
* REQUIREMENTS:
****************************************************************************/
Byte hdd_read_byte(void)
{
Byte status;
 
  if (gl_cpt_page == 512)
  {
    status = ide_alt_status;
    status = ide_status;
    gl_ptr_mem++;
    hdd_read_open(gl_ptr_mem, 1);                   /* open the next sector */
  }
  gl_cpt_page++;
  return ide_read_databyte();
}


/*F*************************************************************************
* NAME: hdd_read_long_big_endian
*---------------------------------------------------------------------------
* PARAMS:
*   global: gl_ptr_mem
*
* return:
*   Data read from media
*----------------------------------------------------------------------------
* PURPOSE: 
*   Long word big endian coded read function
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   
*----------------------------------------------------------------------------
* REQUIREMENTS:
****************************************************************************/
Uint32 hdd_read_long_big_endian(void)
{
  Uint32 temp;
  if (gl_cpt_page == 512)
  {
    status = ide_alt_status;
    status = ide_status;
    gl_ptr_mem++;
    hdd_read_open(gl_ptr_mem, 1);                   /* open the next sector */
  }
  ((Byte*)&temp)[3] = ide_data;
  ((Byte*)&temp)[2] = DAT16H;
  ((Byte*)&temp)[1] = ide_data;
  ((Byte*)&temp)[0] = DAT16H;
  gl_cpt_page += 4;
  return temp;
}


/*F*************************************************************************
* NAME: hdd_read_one_sector
*---------------------------------------------------------------------------
* PARAMS:
*   global: gl_ptr_mem
*
* return:
*   
*----------------------------------------------------------------------------
* PURPOSE: 
*   Read one sector from media to buffer
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*   
*----------------------------------------------------------------------------
* REQUIREMENTS:
****************************************************************************/
void hdd_read_one_sector(void)
{
  if (gl_cpt_page == 512)
  {
    status = ide_alt_status;
    status = ide_status;
    gl_ptr_mem++;
    hdd_read_open(gl_ptr_mem, 1);                   /* open the next sector */
  }
  ata_load_sector();
  gl_cpt_page += 512;
}


/*F**************************************************************************
* NAME: hdd_read_sector
*----------------------------------------------------------------------------
* PARAMS:
*   global: gl_ptr_mem
*
* return: OK read done
*         KO read failure
*----------------------------------------------------------------------------
* PURPOSE: 
*   This function is an optimized function that writes 512 bytes from HDD
*   to USB controller 
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -