Forum: Mikrocontroller und Digitale Elektronik AT91SAM7S, Chip Select wird nicht per Hardware gesetzt


von Rooney B. (rooney)


Lesenswert?

Hallo!

Hat jemand vielleicht eine Ahnung warum beim AT91SAM7S das Chip Select 
nicht per Hardware gesetzt wird? Ich habe schon so ziemlich alles 
ausprobiert, aber es klappt nicht.
Ich möchte die PDC verwenden und hier wäre es nicht gerade sinnvoll, 
wenn ich das Chip Select per GPIO setzen würde.

Zur Info, ich verwende die Funktionen aus der AT91Lib.


Initialisierung der SPI Schnittstelle
1
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, ((unsigned int) AT91C_PA13_MOSI) | ((unsigned int) AT91C_PA11_NPCS0) | ((unsigned int) AT91C_PA14_SPCK) | ((unsigned int) AT91C_PA12_MISO), 0);  
2
3
SPI_Configure(AT91C_BASE_SPI, AT91C_ID_SPI, AT91C_SPI_MSTR);
4
SPI_ConfigureNPCS(AT91C_BASE_SPI, 0, AT91C_SPI_BITS_8 | 2 << 8);
5
SPI_Enable(AT91C_BASE_SPI);

Senden der Daten über PDC
1
SPI_WriteBuffer(AT91C_BASE_SPI, hdlc.frame, hdlc.sizeByte);

von holger (Gast)


Lesenswert?

Geklaut bei EFSL;)
Ist für ne SD Karte, aber vieleicht hilft es ja.
Das eine oder andere kannst du wohl wegwerfen.
1
  AT91PS_SPI pSPI      = AT91C_BASE_SPI;
2
  AT91PS_PIO pPIOA     = AT91C_BASE_PIOA;
3
  AT91PS_PMC pPMC      = AT91C_BASE_PMC;
4
  // not used: AT91PS_PDC pPDC_SPI  = AT91C_BASE_PDC_SPI;
5
  
6
  // disable PIO from controlling MOSI, MISO, SCK (=hand over to SPI)
7
  // keep CS untouched - used as GPIO pin during init
8
  pPIOA->PIO_PDR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK; //  | NCPS_PDR_BIT;
9
  // set pin-functions in PIO Controller
10
  pPIOA->PIO_ASR = AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK; /// not here: | NCPS_ASR_BIT;
11
  /// not here: pPIOA->PIO_BSR = NPCS_BSR_BIT;
12
  
13
  // set chip-select as output high (unselect card)
14
  pPIOA->PIO_PER  = NCPS_PDR_BIT; // enable GPIO of CS-pin
15
  pPIOA->PIO_SODR = NCPS_PDR_BIT; // set high
16
  pPIOA->PIO_OER  = NCPS_PDR_BIT; // output enable
17
  
18
  // enable peripheral clock for SPI ( PID Bit 5 )
19
  pPMC->PMC_PCER = ( (euint32) 1 << AT91C_ID_SPI ); // n.b. IDs are just bit-numbers
20
  
21
  // SPI enable and reset
22
  pSPI->SPI_CR = AT91C_SPI_SPIEN | AT91C_SPI_SWRST;
23
  
24
#ifdef FIXED_PERIPH
25
  // SPI mode: master, fixed periph. sel., FDIV=0, fault detection disabled
26
  pSPI->SPI_MR  = AT91C_SPI_MSTR | AT91C_SPI_PS_FIXED | AT91C_SPI_MODFDIS;
27
  // set PCS for fixed select
28
  // pSPI->SPI_MR &= 0xFFF0FFFF; // clear old PCS - redundant (AT91lib)
29
  pSPI->SPI_MR |= ( (SPI_MR_PCS<<16) & AT91C_SPI_PCS ); // set PCS
30
#else
31
  // SPI mode: master, variable periph. sel., FDIV=0, fault detection disabled
32
  // Chip-Select-Decoder Mode (write state of CS-Lines in TDR)
33
  pSPI->SPI_MR  = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCSDEC ;
34
#endif
35
  
36
  // set chip-select-register
37
  // 8 bits per transfer, CPOL=1, ClockPhase=0, DLYBCT = 0
38
  // TODO: Why has CPOL to be active here and non-active on LPC2000?
39
  //       Take closer look on timing diagrams in datasheets.
40
  // not working pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | AT91C_SPI_NCPHA;
41
  // not working pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_BITS_8 | AT91C_SPI_NCPHA;
42
  pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_CPOL | AT91C_SPI_BITS_8;
43
  // not working pSPI->SPI_CSR[SPI_CSR_NUM] = AT91C_SPI_BITS_8;
44
  
45
  // slow during init
46
  if_spiSetSpeed(0xFE); 
47
  
48
  // enable
49
  pSPI->SPI_CR = AT91C_SPI_SPIEN;
50
51
  /* Send 20 spi commands with card not selected */
52
  for(i=0;i<21;i++) {
53
    if_spiSend(iface,0xFF);
54
  }
55
56
  /* enable automatic chip-select */
57
  // reset PIO-registers of CS-pin to default
58
  pPIOA->PIO_ODR  = NCPS_PDR_BIT; // input
59
  pPIOA->PIO_CODR = NCPS_PDR_BIT; // clear
60
  // disable PIO from controlling the CS pin (=hand over to SPI)
61
  pPIOA->PIO_PDR = NCPS_PDR_BIT;
62
  // set pin-functions in PIO Controller (function NCPS for CS-pin)
63
  pPIOA->PIO_ASR = NCPS_ASR_BIT;
64
  pPIOA->PIO_BSR = NPCS_BSR_BIT;

von Martin (Gast)


Lesenswert?

Hier eine Funktion für einen AT91SAM7S64:

void initspi ( unsigned int SCBR_VALUE )
{
  *AT91C_PMC_PCER = (1 << 5);              // Enable Peripheral Clock

  *AT91C_PIOA_ASR = AT91C_PA12_MISO  |     // Peripherie A
                    AT91C_PA13_MOSI  |
                    AT91C_PA14_SPCK  |
                    AT91C_PA11_NPCS0 ;

  *AT91C_PIOA_PDR = AT91C_PA12_MISO  |     // PIO abschalten
                    AT91C_PA13_MOSI  |     // Peripherie A ist aktiv
                    AT91C_PA14_SPCK  |
                    AT91C_PA11_NPCS0 ;

  *AT91C_SPI_MR   = AT91C_SPI_MSTR ;

  *AT91C_SPI_CSR  = SCBR_VALUE   << SCBR | // Serial Clock Baud Rate
                    AT91C_SPI_CPOL;


  *AT91C_SPI_CR   = AT91C_SPI_SPIEN ;      // Enable SPI
}

von Rooney B. (rooney)


Lesenswert?

Vielen Dank, funktioniert jetzt!!!

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.