Hallo Leute..... Ich habe ein riesiges Problem und hoffe ihr könnt mir helfen. Im Rahmen eines Projekts habe ich den AT91SAM7X bereits mit einem ECOS in betrieb genommen und funktioniert soweit auch alles super. Habe bereits folgende Schnittstellen in Betrieb: DEBUG, USART, TWI und CAN.... Nur die SPI_Schnittstelle macht mir richtig sorgen, die macht nämlich gar nichts! Versuche sie die ganze Zeit zu initialisieren und etwas zu senden um den Clock mit dem Oszilloskop messen zu können, so wüßte ich ja das die Schnittstelle initialisiert wäre aber da passiert nichts...... Hat zufällig jemand eine funktionierende Applikation die die SPI_Schnittstelle in Betrieb nimmt und irgendwas sendet???? Damit könnte ich zumindest schon mal meine Hardware testen und mir genauer ansehen wie die SPI_Schnittstelle funktioniert und wie sie reagiert. Ich gehe jetzt nicht näher auf meinen Code ein, da ich im Moment wirklich keine Ahnung mehr habe was ich falsch gemacht haben könnte, ich habe Bereits alles ausprobiert und selbst die Register direkt beschrieben. Na ja vielleicht hat ja von euch einer noch eine gute Idee und kann mir ein paar Tips geben..... Als anhalt für die Initialisierung habe ich folgende Schritte durchgeführt: // Port-Multiplexer für SPI-Schnittstelle konf. AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, ......); // Clock auf SPI-Modul schalten AT91F_SPI1_CfgPMC(); // Mode einstellen: // ist abh. von deiner hardware AT91F_SPI_CfgMode(AT91C_BASE_SPI1, ....); // CS-Register init. (am besten 16bit breite einstellen AT91F_SPI_CfgCs(AT91C_BASE_SPI1,...); // PDC öffnen AT91F_PDC_Open(AT91C_BASE_PDC_SPI); // SPI-Modul aktivieren AT91F_SPI_Enable(AT91C_BASE_SPI1); Ist die Reihenfolge der Initialisierung irgendwie zwingend??? MFG Rafael
hier mal ein Code-Bsp. wie ich das mal gemacht habe. Das ist aber schon 
ein Jahr her.  Ich hoffe, es hilft.
#define SPI_SCKDIV  4
//-------------------------------------------------------
// Port Init
//-------------------------------------------------------
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA, // PIO controller base address
((unsigned int) AT91C_PA0_RXD0        ) | //- IRDA - RXD Peripheral A
((unsigned int) AT91C_PA1_TXD0        ),  //- IRDA - TXD Peripheral A
((unsigned int) AT91C_PA30_PCK2       ) | //- Clock-Sound // Peripheral 
B
((unsigned int) AT91C_PA23_SPI1_MOSI  ) | //- MOSI      // Peripheral B
((unsigned int) AT91C_PA24_SPI1_MISO  ) | //- MISO      // Peripheral B
((unsigned int) AT91C_PA22_SPI1_SPCK  ) | //- SCK       // Peripheral B
((unsigned int) AT91C_PA21_SPI1_NPCS0 )); //- CS_DATA   // Peripheral B
 AT91F_PIO_CfgPeriph( AT91C_BASE_PIOB, // PIO controller base address
 ( 0 ),
 ((unsigned int) AT91C_PB11_SPI1_NPCS2   ));  //- CS_SOUND // Peripheral 
B
//-------------------------------------------------------
// SPI-Init
//-------------------------------------------------------
  AT91PS_SPI     pSPI = AT91C_BASE_SPI1;
  pSPI->SPI_CR  = AT91C_SPI_SPIDIS;
  // Configure PMC by enabling SPI clock
  AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_SPI1);
  // reset and enable SPI
  pSPI->SPI_CR  = AT91C_SPI_SWRST; // SW reset
  asm("nop"); //K_Task_Wait (10);
  asm("nop");
  pSPI->SPI_CR  = AT91C_SPI_SPIEN; // SPI is enable
  asm("nop"); //K_Task_Wait (10);
  asm("nop");
  // Cfg SPI MR
  pSPI->SPI_MR = (AT91C_SPI_MSTR + AT91C_SPI_MODFDIS | AT91C_SPI_PCS );
  pSPI->SPI_CSR[SPI_CS_SOUND] = AT91C_SPI_NCPHA |
                                AT91C_SPI_CPOL  |
                              AT91C_SPI_BITS_16 |
                                (SPI_SCKDIV<<8);
//-------------------------------------------------------
//
//-------------------------------------------------------
WORD spiTransfer16(WORD data)
{
  AT91PS_SPI     pSPI = AT91C_BASE_SPI1;
        // wait for transmit completion/ready
  while(!(pSPI->SPI_SR & AT91C_SPI_TDRE));
  // write data to be transmitted
  pSPI->SPI_TDR = data;
        // wait for completion
        while(!(pSPI->SPI_SR & AT91C_SPI_RDRF));
        // return received data
  return pSPI->SPI_RDR;
}
  hallo rafael, meine Init. des SPI-Moduls sieht deiner sehr ähnlich. ich würde nach dem Enable des Clock und vor dem Einstellen des Mode noch einen SPI-Reset ausführen, damit sollte es funktionieren.
| 1 | // Port-Multiplexer für SPI-Schnittstelle konf.
 | 
| 2 | AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, ......); | 
| 3 | // Clock auf SPI-Modul schalten
 | 
| 4 | AT91F_SPI1_CfgPMC(); | 
| 5 | // SW-Reset ausführen
 | 
| 6 | AT91F_SPI_Reset(AT91C_BASE_SPI); | 
| 7 | // Mode einstellen:
 | 
| 8 | // ist abh. von deiner hardware
 | 
| 9 | AT91F_SPI_CfgMode(AT91C_BASE_SPI1, ....); | 
| 10 | // CS-Register init. (am besten 16bit breite einstellen
 | 
| 11 | AT91F_SPI_CfgCs(AT91C_BASE_SPI1,...); | 
| 12 | // PDC öffnen
 | 
| 13 | AT91F_PDC_Open(AT91C_BASE_PDC_SPI); | 
| 14 | // SPI-Modul aktivieren
 | 
| 15 | AT91F_SPI_Enable(AT91C_BASE_SPI1); | 
wenn es das nicht war dann liegt es vermutlich an der sende-funktion. wie sieht den die aus? gruss gerhard
Hallo....
Erst mal vielen Dank für die schnellen Antworten und eure Hilfe...
@Steffen:
also alles in allem sieht mein Code deinem sehr ähnlich aber 
funktioniert trotzdem nicht! Selbst wenn ich deinen Code 1 zu 1 
übernehme und die senden Methode aufrufe:
char data = 0xFF;
while(1)
{
    spiTransfer16(data);
}
passiert bei mir auf dem Clock (mit Oszi gemessen) nichts......
Einzige was ich noch geändert habe ist das ich den Empfang auskomentiert 
habe:
//wait for completion
//while(!(pSPI->SPI_SR & AT91C_SPI_RDRF));
//return received data
//return pSPI->SPI_RDR;
@Gerhard:
ja scheinbar liegt das Problem wirklich nicht bei der Initialisierung 
bzw. weiß ich es halt nicht zu 100%. Habe alles ausprobiert und geht 
nichts.
Der Code bei mir sieht etwas komplizierter aus wegen dem ECOS aber zeige 
hier mal die beiden Funktionen die zum Senden bei mir verantwortlich 
sind als Dateianhang.
Falls mir jemand eine funktionierende Applikation geben könnte dann wäre 
das echt der Hammer, da ich echt nicht mehr weiter weiß.
MFG
Rafael
  Muss noch kurz was nachtragen was ich vorher auch noch nicht gesehen hatte! Also mit dem ECOS läuft das alles über einen Interrupthändler und die Funktionen hatte ich vergessen. Im Dateianhang.... Gruß Rafael
ein SPI Bsp. ist auch in der "armlib" vorhanden, die Du Dir ja mal anschauen kannst. http://hubbard.engr.scu.edu/embedded/arm/armlib/index.html
danke Steffen!
Habe jetzt auch erste mal auf dem SPI0 ein Clock!!!!!
Der Code unten hat es möglich gemacht....
#include "lib_AT91SAM7X256.h"
#include <stdio.h>
#include <string.h>
#define SPI_SCKDIV  4
void spiInit(void)
{
  // enable clock to SPI interface
  AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_SPI0);
  // setup PIO pins for SPI bus
    *AT91C_PIOA_ASR   = 
AT91C_PA16_SPI0_MISO|AT91C_PA17_SPI0_MOSI|AT91C_PA18_SPI0_SPCK;  // 
assign pins to SPI interface
    *AT91C_PIOA_PDR   = 
AT91C_PA16_SPI0_MISO|AT91C_PA17_SPI0_MOSI|AT91C_PA18_SPI0_SPCK;
    *AT91C_PIOA_PPUER = 
AT91C_PA16_SPI0_MISO|AT91C_PA17_SPI0_MOSI|AT91C_PA18_SPI0_SPCK;  // set 
pullups
  // setup PIO pins for SPI chip selects
  //AT91C_BASE_PIOA->PIO_ASR = AT91C_PA11_NPCS0|AT91C_PA31_NPCS1;
  //AT91C_BASE_PIOA->PIO_PDR = AT91C_PA11_NPCS0|AT91C_PA31_NPCS1;
  //AT91C_BASE_PIOA->PIO_OER = AT91C_PA11_NPCS0|AT91C_PA31_NPCS1;
  // reset and enable SPI
    AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;
  AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
  // set master mode with:
  //  - SPI master
  //  - no mode fault
  //  - variable peripheral chip select
  AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MODFDIS | AT91C_SPI_PS_VARIABLE | 
AT91C_SPI_MSTR;
//  *AT91C_SPI_MR = AT91C_SPI_MODFDIS | AT91C_SPI_PS_FIXED | 
AT91C_SPI_MSTR | (0x0E<<16);
  // setup data transfer format and rate for device 0-3 => 8bits, 
CPOL=0, NCPHA=1
  AT91C_BASE_SPI0->SPI_CSR[0] = 
AT91C_SPI_NCPHA|AT91C_SPI_BITS_8|(SPI_SCKDIV<<8);
  AT91C_BASE_SPI0->SPI_CSR[1] = 
AT91C_SPI_NCPHA|AT91C_SPI_BITS_8|(SPI_SCKDIV<<8);
  AT91C_BASE_SPI0->SPI_CSR[2] = 
AT91C_SPI_NCPHA|AT91C_SPI_BITS_8|(SPI_SCKDIV<<8);
  AT91C_BASE_SPI0->SPI_CSR[3] = 
AT91C_SPI_NCPHA|AT91C_SPI_BITS_8|(SPI_SCKDIV<<8);
}
char spiTransferByte(char data)
{
  // wait for transmit completion/ready
  while(!(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE));
  // write data to be transmitted
  AT91C_BASE_SPI0->SPI_TDR = data;
  // wait for completion
  while(!(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF));
  // return received data
  return AT91C_BASE_SPI0->SPI_RDR;
}
int main()
{
  spiInit();
  char data = 0xFF;
    while(1){
      spiTransferByte(data);
    }
    return 0;
}
Leider hatte die SPI1_Schnittstelle nicht so funktioniert.....
Nun gut jetzt das ganze noch mit dem ECOS zum laufen bekommen und dann 
mal schauen.....
Danke euch!
Gruß
Rafael
  So Leute..... Jetzt habe ich nochmal eine weitere Frage. Gibt es bei dem AT91SAM7X einen unterschied zwischen den beiden SPI-Schnittstellen??? Also zwischen SPI0 und SPI1???? Gem. Datenblatt liegt der einzige Unterschied den ich erkennen konnte, darin das SPI0 Peripheral A ist und SPI1 Peripheral B ist. Ich frage deshalb, weil mit dem o.a. Code konnte ich die SPI0-Schnittstelle ansprechen aber wenn ich den Code soweit geändert habe das die SPI1-Schnittstelle angesprochen wird (AT91C_BASE_SPI0 auf AT91C_BASE_SPI1 geändert, alle Pins von SPI0 auf SPI1 usw.) dann konnte ich wieder keinen Clock messen. Hätte ich am Code noch etwas anderes ändern müssen??? Funktioniert die SPI1_Schnittstelle des AT91 nicht korrekt???? Oder hatte jemand auch schon mal ein ähnliches Problem???? Wäre auch hier wieder für eure Hilfe sehr dankbar, ich muss nämlich die SPI1-Schnittstelle in betrieb nehmen. MFG Rafael
Habe den Fehler gefunden..... Hier ist das AT91C_PIOA_ASR bzw. das AT91C_PIOA_BSR Register verantwortlich. Je nachdem ob man halt Peripheral A oder Peripheral B haben möchte... Gruß Rafael
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
  
  Bestehender Account
  
  
  
  Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
  Noch kein Account? Hier anmelden.
 Thread beobachten
 Thread beobachten Seitenaufteilung abschalten
 Seitenaufteilung abschalten