www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT91SAM7A3 - Problem mit der SPI Initialisierung


Autor: Karl Zeilhofer (griffin27)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine GNU Toolchain:
Eclipse, YAGARTO, openOCD, Parport (Wiggler), AT91SAM7A3-EK

Ich habe mit dem Board nun schon einiges zum laufen gebracht, jedoch 
will die SPI Verbindung einfach nicht.
//------------------------------------------------------------------------------
/// Configure SPI0 to comunicate with the external 16 bit ADC (ADS8344E)
//------------------------------------------------------------------------------
static void ConfigureSPI0()
{
  unsigned int status;

  // disable SPI
  AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIDIS;
  // enable SPI Clock
  AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, AT91C_ID_SPI0);
  // Configure PIO controllers to periph mode
  AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, // PIO controller base address
    ((unsigned int) AT91C_PA16_SPI0_MOSI) |
    ((unsigned int) AT91C_PA11_SPI0_NPCS0) |
    ((unsigned int) AT91C_PA15_SPI0_MISO) |
    ((unsigned int) AT91C_PA17_SPI0_SPCK), // Peripheral A
    0); // Peripheral B
  // enable and software reset SPI
  AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;
  AT91C_BASE_SPI0->SPI_MR =
    1<<0 | // master mode enable
    0<<1 | // peripheral select (0=fixed peripheral)
    0<<2 | // peripheral chip select decode (0=direct connection)
    1<<4 | // mode fault detection disable
    0<<7 | // local loop back enable
    0xE<<16 | // peripheral chip select [0:3]; (see page 247 in the prelimainary)
          // for NPCS0 use 1110_b = 0xE
    0<<24; // delay between chip selects (default minimum 6 MCK cycles)
  //AT91C_BASE_SPI0->SPI_CSR[0]= // SPI chip select register 0
  AT91C_BASE_SPI0->SPI_CSR[0] =
    0<<0 | //clock polarity (
    1<<1 | // clock phase
    // start clk with low level and sample data on falling edge
    1<<3 | // chip select remains active after transfer
    (8-8)<<4 | // bits per transfer (8...16); value = num_bits-8
    20<<8 | // SPCK bautdrate divider. BR=MCK/value = 2.4MHz
    0<<16 | // delay before SPCK (default 1/2 SPCK cycle)
    0<<24; // delay between consecutive transfers
  //SPI_Enable(AT91C_BASE_SPI0);
  status=0;
  while((status & (AT91C_SPI_SPIENS)) == 0)
  {
    AT91C_BASE_SPI0->SPI_CR = (unsigned int) AT91C_SPI_SPIEN; // SPI enable
    status = AT91C_BASE_SPI0->SPI_SR;
  }
}

in der letzten while Schleife bleibt das Programm hängen.
Normalerweise würde man hier keine while-Schleife machen, aber um den 
Fehler zu endecken, habe ich das so gelöst.
Im Statusregister sollte das SPIENS bit gesetzt sein, nachdem man SPI0 
eingeschaltet hat...

Kann mir da bitte jemand weiter helfen?
Das Status Register liefert immer 0!!

Ein änliches Problem hatte ich einmal bei dem MCI (multimedia card 
interface, das nur der SAM7A3 hat). Dazumals programmierte ich auf 
CrossWorks, und ich hab das Problem bis heute nicht gelöst.

lg, Karl

Autor: Karl Zeilhofer (griffin27)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mache ich so viel falsch, dass jedem die Worte fehlen, oder hat wirklich 
niemand eine Idee dazu?

Autor: Karl Zeilhofer (griffin27)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe nun den Fehler mit systematischer Suche durch auslesen aller 
relevanten Register gefunden.
Die Funktion
  AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, AT91C_ID_SPI0);
benötigt nicht die ID selbst, sondern einen 32-bit Wert, in dem das 
entsprechende Bit gesetzt ist. Richtigerweise also:
  AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1<<AT91C_ID_SPI0);

Ich glaube, dieser Fehler war mir eine große Lehre.
Wenn man also den Clock einer Peripherieeinheit nicht einschaltet, tut 
das Statusregister garnix. Es liefert immer 0!!!

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.