Forum: Mikrocontroller und Digitale Elektronik AT91SAM7 SPI Interface


von Thorsten (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei das SPI Interface zu programmieren. Ich habe ein 
SPI Teilnehmer am PA31. Die Initialisierungsroutine sieht wie folgt aus:
1
BYTE spi_Init(BYTE bChipSelect)
2
{
3
  int i;
4
  AT91PS_PMC pPMC      = AT91C_BASE_PMC;
5
6
  // disable
7
  pSPI->SPI_CR = AT91C_SPI_SPIDIS;
8
9
    // disable PIO from controlling MOSI, MISO, SCK (=hand over to SPI)
10
  // keep CS untouched - used as GPIO pin during init
11
  pPIOA->PIO_PDR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK; //  | NCPS_PDR_BIT;
12
  // set pin-functions in PIO Controller
13
  pPIOA->PIO_ASR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK; /// not here: | NCPS_ASR_BIT;
14
  
15
  AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, SPI_CHIP_SELECT_INCL_PIN, (AT91C_BASE_PIOA->PIO_BSR));
16
  pPIOA->PIO_PER  |= SPI_CHIP_SELECT_INCL_PIN;   // enable GPIO of CS-pin
17
  pPIOA->PIO_OER  |= SPI_CHIP_SELECT_INCL_PIN;   // output enable
18
  pPIOA->PIO_SODR &= SPI_CHIP_SELECT_INCL_PIN;  // set low
19
  
20
  
21
  // enable peripheral clock for SPI ( PID Bit 5 )
22
  pPMC->PMC_PCER = ( (DWORD) 1 << AT91C_ID_SPI ); // n.b. IDs are just bit-numbers
23
  
24
  // SPI enable and reset
25
  pSPI->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;
26
  
27
  // SPI mode: master, FDIV=0, fault detection disabled
28
  pSPI->SPI_MR  = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS;
29
  
30
  pSPI->SPI_CSR[1] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | AT91C_SPI_CSAAT;
31
  
32
  // enable
33
  pSPI->SPI_CR = AT91C_SPI_SPIEN;
34
  
35
  return F_OK;
36
}
37
38
void spi_SendByte(BYTE bSendByte)
39
{
40
  while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
41
  pSPI->SPI_TDR = (WORD)(bSendByte);
42
}

Betrachte ich jetzt mit dem Oszilloskop MISO/MOSI/SCK sehe ich, dass der 
ChipSelect auf LOW geht und der Clock eine einzige LOW State hat und 
dann dauerhaft HIGH bleibt. Ich erkenne nicht wo meine Fehler ist.
Die Zuordnung PA31 -> NPCS1 -> SPI_CSR[1] ist doch so richtig oder 
nicht???

Wäre über eine Hilfe dankbar.

Gruss THorsten

von Udo (Gast)


Lesenswert?

Hallo,

versuch es mal so rum
1
void spi_SendByte(BYTE bSendByte)
2
{
3
  pSPI->SPI_TDR = (WORD)(bSendByte);
4
  while( !( pSPI->SPI_SR & AT91C_SPI_TDRE ) ); // transfer compl. wait
5
}

Gruß
Udo

von Thorsten (Gast)


Lesenswert?

Hallo,

danke für deine Antwort.
Das Problem war, dass ich die Chipselectleitung nicht entsprechend im 
Mode Register gesetzt habe.

Jetzt habe ich aber noch ein anderes Problem. Ich möcht über das SPI 
Interface schreiben und gleich lesen.
Also in etwa so:
1
spi_WriteByte(...);
2
spi_ReceiveByte(...);
3
4
BYTE spi_ReceiveByte(BYTE bChipSelect)
5
{
6
  BYTE val = 0;
7
  while( !( pSPI->SPI_SR & AT91C_SPI_RDRF ) ); // wait for char
8
  val = (BYTE)( pSPI->SPI_RDR );
9
  return val;
10
}

Jetzt habe ich das Problem, dass er nur sendet, aber nichts empfängt. 
Man erkennt, dass er ständig mit 8 Taktzyklen das Byte schreibt und 
wieder von Vorne anfängt.

Noch jemand eine Idee.

Danke

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
Noch kein Account? Hier anmelden.