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.