www.mikrocontroller.net

Forum: Compiler & IDEs Probleme bei der Ansteuerung einer IDE-Festplatte


Autor: Sven S. (schwerminator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe mir im Zuge meines MP3-Player-Projektes die Ansteuerung einer 
Festplatte als ehrgeizige Zwischenetappe gesetzt. Leider gibts dabei 
(noch) Probleme. Aber nun von Anfang an: Ich habe im Internet 
vollständige Routinen inkl. Doku für die Ansteuerung einer Festplatte 
gefunden. Der Code stammt von den beiden Brasilianern Angelo Bannack und 
Giordano Bruno Wolaniuk. Meine Testschaltung ist der der beiden sehr 
ähnlich. Ich habe sowohl den kompletten Code inkl. Doku sowie meine 
Schaltung angehängt. Hier mal die ersten paar Zeilen der main():
int main(void)
{
  TFILE *farq;
  struct direntry *de;
  char path[12];


  mcuInit();              // start ATMega128
  fdevopen(uart_putc, NULL);      // configure printf to send data to serial port

  printf("FAT16/32 file system driver v1.00\r\n");
  printf("Written by Angelo Bannack and Giordano Bruno Wolaniuk\r\n\r\n");

  ataInit();  // Start ATA
  fatInit();  // Start FAT

  print_hd_info();

...
Also die beiden printf-Ausgaben werden übertragen, aber in der ataInit() 
bleibt das Script hängen. Hier die Funktion:
void ataInit(void)
{
  unsigned char i;
  unsigned char* buffer = (unsigned char*) SECTOR_BUFFER_ADDR;


  DDR_DATAL= 0x00;      // Use DATAL as the input from the hardrive
  DDR_DATAH= 0x00;      // Use DATAH as the input from the hardrive
  PORT_DATAL= 0xFF;      // Enable pullup on DATAL
  PORT_DATAH= 0xFF;      // Enable pullup on DATAH

  DDR_ADDR = 0xDF;      // Use ADDR PORT as the output for the hardrive
                  // But use PORT_ADDR.5 as host interrupt (INPUT)
    PORT_ADDR= 0xc0;            // Initialize PORT_ADDR to c0.


    ataWriteByte(ATA_REG_ACTSTATUS, 0x06);       // Assert Software reboot.
    delay(100);
    ataWriteByte(ATA_REG_ACTSTATUS, 0x00);
    delay(100);
  
  //TESTTEIL: (hinzugefügt von mir)
  printf("ataReadByte(ATA_REG_ACTSTATUS): ");
  printf(ataReadByte(ATA_REG_ACTSTATUS));

  // Wait until drive clear BUSY Bit in Alternate Status Register
    while(IDE_Wait_State(ATA_SR_BSY) == 1);
  
  // issue identify command
  ataWriteByte(ATA_REG_HDDEVSEL, 0);
  ataWriteByte(ATA_REG_ACTSTATUS, 0x02);

    while(IDE_Wait_State(ATA_SR_DRDY) == 0);
  
  ataWriteByte(ATA_REG_CMDSTATUS1, 0xEC);
  // wait for drive to request data transfer

  while(IDE_Wait_State(ATA_SR_DRQ) == 0);
  
  delay(200); // wait 200 us
  // read in the data
  ataReadDataBuffer(buffer, 512);

  // set local drive info parameters
  ataDriveInfo.cylinders =    *( ((unsigned int*) buffer) + ATA_IDENT_CYLINDERS );
  ataDriveInfo.heads =      *( ((unsigned int*) buffer) + ATA_IDENT_HEADS );
  ataDriveInfo.sectors =      *( ((unsigned int*) buffer) + ATA_IDENT_SECTORS );
  ataDriveInfo.LBAsupport =    *( ((unsigned int*) buffer) + ATA_IDENT_FIELDVALID );
  ataDriveInfo.sizeinsectors =  *( (unsigned long*) (buffer + ATA_IDENT_LBASECTORS*2) );
  // copy model string
  for(i=0; i<40; i+=2)
  {
    // correct for byte order
    ataDriveInfo.model[i  ] = buffer[(ATA_IDENT_MODEL*2) + i + 1];
    ataDriveInfo.model[i+1] = buffer[(ATA_IDENT_MODEL*2) + i    ];
  }
  // terminate string
  ataDriveInfo.model[40] = 0;

  // process and print info
  if(!ataDriveInfo.LBAsupport) {
    // CHS, no LBA support
    // calculate drive size
    ataDriveInfo.sizeinsectors = (unsigned long) ataDriveInfo.cylinders*ataDriveInfo.heads*ataDriveInfo.sectors;
  }
}
Der Code kommt über die folgende Zeile einfach nicht hinaus. Außerdem 
die Funktion IDE_Wait_State():
while(IDE_Wait_State(ATA_SR_BSY) == 1);

unsigned char IDE_Wait_State(unsigned char test_bit)
{
  if ((ataReadByte(ATA_REG_ACTSTATUS) & test_bit) == test_bit)
    return 1;
  return 0;
}
Meine Testzeile darüber funktioniert auch nicht. Ich kann einfach kein 
Byte aus dem Alternate Status Register lesen. Hier die entsprechende 
Funktion:
unsigned char ataReadByte(unsigned char reg)
{
  register unsigned char ret;

    PORT_DATAL = 0xFF;        // habilita pull-ups
    DDR_DATAL  = 0x00;             // Use the DATAH as an input
    PORT_ADDR = PORT_ADDR & 0xe0;     // Clear the lower 5 bits of the address line
    PORT_ADDR = PORT_ADDR | (reg & 0x1f);   // Assert the address Line

  //cbi(PORT_IDE_RD, PIN_IDE_RD);                    // Assert DIOR
  PORT_IDE_RD &= ~(1 << PIN_IDE_RD);
    __asm volatile ("NOP");
    __asm volatile ("NOP");
    __asm volatile ("NOP");

    ret = PIN_DATAL;
    //sbi(PORT_IDE_RD, PIN_IDE_RD);              // Negate DIOR
  PORT_IDE_RD |= (1 << PIN_IDE_RD);

    return (ret);
}
Die cbi() und sbi() habe ich wegkommentiert und ersetzt. Kann mir 
vielleicht jemand sagen, warum ich nicht auf die Register zugreifen 
kann? Ich weiß, es handelt sich um sehr viel Code, aber ich komme 
einfach nicht weiter. Ich verwende übrigens eine Seagate ST31720A, 
dessen Datenblatt ich auch angehängt habe.

Ich hoffe auf eure Hilfe!

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schlag mich mit dem gleichen Gerümpel herum. Bei mir funktioniert 
das mit dem Soft-Reset irgendwie nie so wirklich, deshalb hab ich das 
komplett verworfen. Aber ideal ist das natürlich auch net.

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verstehe nicht genau, was du verworfen hast. Den Softwarereset oder 
das gesamte Projekt? ;)

mfG

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein... den Software-Reset natürlich. D.h., ich sende den zwar immer 
noch, und warte dann eine halbe Sekunde (reicht laut Datenblatt locker), 
prüf aber den Status net, sondern mach einfach weiter.

Das Softwareprojekt selbst funktioniert einwandfrei. Kann sogar 
CD-ROM-Laufwerke mit ATAPI öffnen und schließen...

Autor: Sven S. (schwerminator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verwendest du den selben Code? Wenn nein, könntest du deinen Code dann 
hier mal posten?

mfG

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.