-         

Ergebnis 1 bis 5 von 5

Thema: Probleme bei der Ansteuerung einer IDE-Festplatte

  1. #1

    Probleme bei der Ansteuerung einer IDE-Festplatte

    Anzeige

    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():
    Code:
    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:
    Code:
    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():
    Code:
    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:
    Code:
    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!
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken schematic_591.png  
    Angehängte Dateien Angehängte Dateien

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Hi,

    zu cbi/sbi, mit diesen kann man nur Register bis $3F ansprechen, PortF liegt aber ausserhalb, deshalb gehts ned.
    Es geht nur über die SRAM-Adresse zu PortF.

  3. #3
    Hallo,
    aber ich benutze doch gar kein sbi()/cbi(). Deswegen sind sie rauskommentiert und durch Bitmanipulation/C-Standard ersetzt. Oder was meinst du?

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Ich hab die Frage so verstanden, dass Du wissen wolltest, warum man mit cbi usw. nicht auf den Port zugreifen kann
    Doch mit SBI und Co kann man sogar nur bis $1F zugreifen, bei IN/Out war es $3F !

  5. #5
    OK, dann haben wir uns falsch verstanden. Meine Frage war, warum ich mit ataReadByte() nicht auf zB. das Alternate Status Register zugreifen kann.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •