Forum: Mikrocontroller und Digitale Elektronik ATSAM4E8C SPI Hilfe


von Helmut W. (upm)


Lesenswert?

Hallo liebe Gemeinde,


Ich habe einen ATSAM4E8C und bekomme einfach die SPI-Kommunikation nicht 
zum laufen, könnt Ihr mir bitte helfen. Ich verzweifele langsam :-(((((

von Helmut W. (upm)


Lesenswert?

keiner???? ;-(((

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Vielleicht beschreibst du ja mal, was du genau getan hast?  Und
natürlich auch, an welcher Schnittstelle du das SPI hängen hast
(SPI oder USART), ob es Master oder Slave ist, wer die Gegenstelle
ist, etc. pp.

Lass dir doch nicht alles aus der Nase ziehen, oder auch: 
Netiquette.

von Kaj (Gast)


Lesenswert?

Helmut W. schrieb:
> Ich habe einen ATSAM4E8C und bekomme einfach die SPI-Kommunikation nicht
> zum laufen, könnt Ihr mir bitte helfen
Wie stellst du das fest und was willst du ueberhaupt per spi ansprechen?

von Helmut W. (upm)


Lesenswert?

Hallo


also ich habe den ATSAM4 und BMI160. Diese möchte ich gern per SPI kein 
USART ansprechen. Ich hab mitlerweile ein Beispiel gefunden und es 
implementiert, ohne Fehler. Doch leider ist kein Takt zu erkennen mit 
dem Oszi. Ich nutze ASF.

status_code_t status;
uint8_t dataTx[4],dataRx[4];
sprintf(dataRx,"0x00");

uint32_t mySPIselect = 5;
uint32_t myBaudRate = 100000;
spi_flags_t mySPIflags = SPI_MODE_3;
struct spi_device mySPI = {.id = 0};

// Insert system clock initialization code here (sysclk_init()).
sysclk_init();
board_init();
configure_buttons();
spi_master_init(SPI);
spi_master_setup_device(SPI, &mySPI, mySPIflags, 
myBaudRate,mySPIselect);
spi_enable(SPI);

while(1)
{
     sprintf(dataTx,"0x00");
     status = spi_write_packet(SPI, &dataTx, sizeof(dataTx));
     spi_read_packet(SPI,&dataRx, sizeof(dataTx));
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Helmut W. schrieb:

> Diese möchte ich gern per SPI kein
> USART ansprechen.

Nee, das hast du komplett falsch verstanden: auch mit der USART kann
man SPI machen.

Du benutzt aber offenbar den SPI-Modul selbst, als Master.

> Ich nutze ASF.

Damit kann ich dir leider nicht helfen.  Um diesen undurchdringlichen
Koloss mache ich immer einen großen Bogen.

Wichtig ist (und keine Ahnung, ob dir das ASF diesen Job mit den
genannten Zeilen bereits abnehmen würde), dass du die PIO auch
passend definierst, also PA12 - PA14 auf Peripheral A und trotzdem
noch (je nach Funktion) Input oder Output, und dazu den korrekten
Pin für das NPCSn mit entsprechendem Peripheral.  (Was genau da
eine 5 sein soll, die du benutzt, habe ich keine Idee.  Es gibt nur
NPCS0 bis NPCS3, aber die können auf verschiedene Pins gemappt werden.)

Nicht zu vergessen natürlich, dass du im Power Manager die
Taktversorgung für den SPI-Block aktivieren musst.  Wiederum keine
Ahnung, ob ASF dir das abnimmt oder nicht.

Genau dieses „keine Ahnung“ sowie der entsprechende Aufwand, das
händisch irgendwo zu recherchieren, ist einer der Gründe, warum ich
ASF nicht mag.  Das ist so ein „du musst eigentlich gar nicht wissen,
was wir hier für dich tun, wir machen das schon!“-Prinzip, mit dem
ich mich schlicht nicht wohl fühle.

von Helmut W. (upm)


Lesenswert?

Hallo Jörg Wunsch,


ich würde auch auf ASF verzichten, könntest du mir vielleicht ein 
Beispiel für die SPI kommunikation zusenden? Damit wäre mir sehr 
geholfen ;-)

VG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Naja, so schlüsselfertig, wie die ASF vorgibt zu sein, natürlich nicht.

Das, was ich hier habe, ist proprietärer Code, den ich so erstmal
nicht rausgeben kann.

Das Prinzip daraus habe ich dir aber skizziert, in erster Linie musst
du halt die PIO-Pins konfigurieren.  Das heißt, für jeden der Pins
das entsprechende Bit im PIO_PER setzen (PIO Enable), danach das
passende Bit im PIO_OER setzen (Output enable) oder im PIO_ODR (Output
disable, also Input) sowie PIO_ABCDSR1/PIO_ABCDSR2 konfigurieren, je
nach gewünschter Funktion (bei Funktion A wäre in beiden Registern
das jeweilige Bit auf 0 zu setzen).

Das eigentliche Aktivieren des SPI-Moduls ist nicht viel:
1
    PMC->PMC_PCER0 = 1 << ID_SPI; // enable clock
2
    SPI->SPI_CR = SPI_CR_SWRST; // software reset
3
    SPI->SPI_CR = SPI_CR_SWRST;
4
    SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS; // master mode
5
    SPI->SPI_CR = SPI_CR_SPIEN;  // enable SPI

Ein wenig sollte man natürlich schon das Datenblatt verstanden
haben an dieser Stelle.

Das jeweilige Slave Select aktivierst du mit
1
SPI->SPI_MR = (SPI->SPI_MR & (~SPI_MR_PCS_Msk)) | SPI_MR_PCS(NPCS);

(„NPCS“ ist dabei die Nummer des Select-Signals, von 0 bis 3,
entsprechend NPCS0 … NPCS3.)

und deaktivierst es mit
1
SPI->SPI_CR |= SPI_CR_LASTXFER;

Ein Byte wird geschrieben mit
1
SPI->SPI_TDR = byte;

Warten, bis du wieder schreiben kannst:
1
while (!(SPI->SPI_SR & SPI_SR_TXEMPTY)) {}

Lesen mit:
1
byte = SPI->SPI_RDR;

So fürchterlich viel isses nicht, ich hoffe mal, ich habe jetzt
nichts übersehen … (bei uns im Code gibt's dann immer noch
#ifdef-Alternativen für den Betrieb mit USART im SPI-Mode).

von Helmut W. (upm)


Lesenswert?

Hallo  Jörg,


vielen Dank schonmal für deine Hilfe ;-).

Aber igendetwas ist noch komisch. Hier ist meine Port-Konfiguration:
1
#define SPCK   PIO_PA14
2
#define MOSI   PIO_PA13
3
#define MISO   PIO_PA12
4
#define CS_DS   PIO_PA11
5
6
PIOA->PIO_PER = (1<<11)|(1<<12)|(1<<13)|(1<<14);//Enable PIO for GPIO
7
PIOA->PIO_OER = (1<<11)|(1<<13)|(1<<14);//Enable port pin for output
8
PIOA->PIO_ODR = (1<<12);    //Enable port pin for input
9
PIOA->PIO_ABCDSR[0] = 0x00000000;   // peripheral A
10
PIOA->PIO_ABCDSR[1] = 0x00007800;   // peripheral A

Jetzt liegt der Takt auf MISO und nicht SPCK, hast du eine Idee ?
Wenn ich nehmlich PA12 ändere in PA14 dan geht es und der Takt ist auf 
SPCK.
Aber PIO_ODR ist doch das Register in dem Inputs definiert werden?

Vielen Dank für deine Hilfe!!!

VG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Helmut W. schrieb:

> Aber igendetwas ist noch komisch. Hier ist meine Port-Konfiguration:
>
>
1
> #define SPCK   PIO_PA14
2
> #define MOSI   PIO_PA13
3
> #define MISO   PIO_PA12
4
> #define CS_DS   PIO_PA11

OK, also NPCS0 (PA11) als Select-Signal, das ist dessen Function A.

> PIOA->PIO_PER = (1<<11)|(1<<12)|(1<<13)|(1<<14);//Enable PIO for GPIO

PIO_PDR, du willst sie ja schließlich nicht als PIO-Pins haben,
sondern als Peripheral-Pins.

> PIOA->PIO_OER = (1<<11)|(1<<13)|(1<<14);//Enable port pin for output
> PIOA->PIO_ODR = (1<<12);    //Enable port pin for input

Ich bin mir aus dem Bauch raus nicht ganz sicher, ob man das überhaupt
noch wirklich bei der PIO konfigurieren muss, oder ob das automatisch
so gesetzt wird, wenn man die peripheral function aktiviert.

> PIOA->PIO_ABCDSR[0] = 0x00000000;   // peripheral A
> PIOA->PIO_ABCDSR[1] = 0x00007800;   // peripheral A

Erstens würde ich an deiner Stelle hier nicht auf Hex-Zahlen
schwenken, sondern die (1<<11)|(1<<13)| ...etc.-Notation beibehalten,
damit man das besser sieht.

Aber: da gehören überall Nullen an die entsprechenden Stellen
rein, denn so, wie das da steht, aktivierst du gerade für all diese
Pins die Funktion C!  Das könnte natürlich schon mal dein Problem
sein.

Also:
1
/* peripheral function A for PA11 ... PA14 */
2
PIOA->PIO_ABCDSR[0] &= ~((1<<11)|(1<<12)|(1<<13)|(1<<14));
3
PIOA->PIO_ABCDSR[1] &= ~((1<<11)|(1<<12)|(1<<13)|(1<<14));

> Jetzt liegt der Takt auf MISO und nicht SPCK, hast du eine Idee ?

Nö, wieso?

> Wenn ich nehmlich PA12 ändere in PA14 dan geht es und der Takt ist auf
> SPCK.

Den Satz verstehe ich nicht.

> Aber PIO_ODR ist doch das Register in dem Inputs definiert werden?

Genauer gesagt: das Register, in dem man die Output-Funktion
abschaltet (output disable register).

: Bearbeitet durch Moderator
von Helmut W. (upm)


Lesenswert?

Hallo Jörg,


gut der pseudo Takt ist weg. Ich hab deine Änderungen eingepflegt, nur 
leider ist kein takt auf SCK vorhanden. ;-(

VG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dann schreib doch mal ein komplettes, compilierbares Minimalbeispiel,
mit dem es bei dir nicht funktioniert.

Eventuell fände ich morgen sogar einen Moment Zeit, das zu testen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich hätte hier auch noch ein SAM4S Xplained Pro liegen, die SPI ist
da identisch zum SAM4E.

Mir ist noch aufgefallen, dass du natürlich das CSR noch einstellen
musst.  Da werden unter anderem Dinge wie die Taktrate festgelegt.

von Helmut W. (upm)


Lesenswert?

Hier ist mein Quelltext, leider kein takt vorhanden ;-(
1
#include <asf.h>
2
#include "Button.h"
3
#include "bmi160.h"
4
#include "bmi160_support.h"
5
#define SPCK   PIO_PA14
6
#define MOSI   PIO_PA13
7
#define MISO   PIO_PA12
8
#define CS_DS   PIO_PA11
9
#define SPI_PINS (MOSI | MISO | SPCK | CS_DS)
10
//#define DEFAULT_CHIP_ID  PIO_PA11A_NPCS0
11
12
13
int main (void)
14
{
15
  status_code_t status;
16
  uint8_t dataTx[4],dataRx[4];
17
  int data_RX,data_TX=100;
18
  sprintf(dataRx,"0x00");
19
  
20
  // Insert system clock initialization code here (sysclk_init()).
21
  //pmc_enable_periph_clk(ID_SPI);
22
  //sysclk_enable_peripheral_clock(ID_SPI);
23
  sysclk_init();
24
  board_init();
25
  configure_buttons();
26
  
27
  PIOA->PIO_PDR = (1<<14)|(1<<13)|(1<<12)|(1<<11);//Enable PIO for GPIO
28
  //PIOA->PIO_OER = (1<<14)|(1<<13)|(1<<11);//Enable port pin for output;
29
  //PIOA->PIO_ODR = (1<<12);        //Enable port pin for input
30
  PIOA->PIO_ABCDSR[0] &= ~((1<<11)|(1<<12)|(1<<13)|(1<<14));
31
  PIOA->PIO_ABCDSR[1] &= ~((1<<11)|(1<<12)|(1<<13)|(1<<14));
32
  
33
  PMC->PMC_PCER0 = 1 << ID_SPI; // enable clock
34
    SPI->SPI_CR = SPI_CR_SWRST; // software reset
35
    SPI->SPI_CR = SPI_CR_SWRST;
36
    SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS; // master mode
37
    SPI->SPI_CR = SPI_CR_SPIEN;  // enable SPI
38
    SPI->SPI_MR = (SPI->SPI_MR & (~SPI_MR_PCS_Msk)) |         SPI_MR_PCS(PIO_PA11A_NPCS0);
39
  
40
  while(1)
41
  {
42
    //sprintf(dataTx,"0x00");
43
    //status = spi_write_packet(SPI, &dataTx, 5);
44
    /*sprintf(dataTx,"0x00");
45
    status = spi_write_packet(SPI, &dataTx, sizeof(dataTx));
46
    spi_read_packet(SPI,&dataRx, sizeof(dataTx));*/
47
    //SPI_Transfer(data_TX,data_RX,3,0xD1);
48
  }
49
}

Vielen Dank für deine Hilfe.

VG

: Bearbeitet durch User
von Helmut W. (upm)


Lesenswert?

Hey,


genauso weiß ich leider nicht wo ich den Quarz mit 32.768 KHz 
initalisiere ;-(

VG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Bitte dafür einen separaten Thread.

von Helmut W. (upm)


Lesenswert?

Hallo,

okay, konntest du schon schauen wegen dem SPI?

VG

von Rudolph (Gast)


Lesenswert?

Was man so findet. :-)
Lag es jetzt wirklich daran, dass SCBR nicht gesetzt wird? :-)

: Wiederhergestellt durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rudolph schrieb:
> Lag es jetzt wirklich daran, dass SCBR nicht gesetzt wird? :-)

Ich vermute schon.  Laut Datenblatt steht der Vorteiler auf 0, was
vermutlich bewirkt, dass eben genau kein Takt erzeugt wird.

SPI->SPI_CSR0[0] = SPI_CSR_SCBR(42) | SPI_CSR_BITS_8_BIT;

könnte da schon gut helfen, ggf. noch NCPHA und CPOL, falls der
Zielschaltkreis das braucht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Code:
1
#include <stdint.h>
2
3
#include "sam.h"
4
5
void
6
_init(void)
7
{
8
}
9
10
11
void
12
spi_init(void)
13
{
14
    PIOA->PIO_OER = (1<<11)|(1<<13)|(1<<14);
15
    PIOA->PIO_ODR = (1<<12);
16
    PIOA->PIO_PDR = (1<<11)|(1<<12)|(1<<13)|(1<<14);
17
    PIOA->PIO_ABCDSR[0] &= ~((1<<11)|(1<<12)|(1<<13)|(1<<14));
18
    PIOA->PIO_ABCDSR[1] &= ~((1<<11)|(1<<12)|(1<<13)|(1<<14));
19
20
    PMC->PMC_PCER0 = 1 << ID_SPI; // enable clock
21
    SPI->SPI_CR = SPI_CR_SWRST; // software reset
22
    SPI->SPI_CR = SPI_CR_SWRST;
23
    SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS; // master mode
24
    SPI->SPI_CR = SPI_CR_SPIEN;  // enable SPI
25
    SPI->SPI_CSR[0] = SPI_CSR_SCBR(42) | SPI_CSR_BITS_8_BIT;
26
}
27
28
uint8_t
29
spi_sendbyte(uint8_t byte)
30
{
31
    SPI->SPI_MR = (SPI->SPI_MR & (~SPI_MR_PCS_Msk)) | SPI_MR_PCS(0);
32
    SPI->SPI_TDR = byte;
33
    while (!(SPI->SPI_SR & SPI_SR_TXEMPTY)) {}
34
    byte = SPI->SPI_RDR;
35
    SPI->SPI_CR |= SPI_CR_LASTXFER;
36
37
    return byte;
38
}
39
40
void
41
_exit(int status)
42
{
43
    for (;;)
44
    {
45
    }
46
}
47
48
49
int
50
main(void)
51
{
52
    spi_init();
53
54
    for (uint8_t i = 0;;)
55
    {
56
        spi_sendbyte(i++);
57
    }
58
}

compiliert mit
1
 arm-none-eabi-gcc -I ../CMSIS_Atmel/CMSIS/Include -I ../CMSIS_Atmel/Device/ATMEL/sam4s/include -I ../CMSIS_Atmel/Device/ATMEL -std=c99 -mcpu=cortex-m4 -mthumb -D__SAM4SD32C__ -nostartfiles -L ../CMSIS_Atmel/Device/ATMEL/sam4s/source/as_gcc -T ../CMSIS_Atmel/Device/ATMEL/sam4s/source/as_gcc/sam4sd32c_flash.ld -Os -o spitest.elf ../CMSIS_Atmel/Device/ATMEL/sam4s/source/as_gcc/startup_sam4s.c spitest.c

ergibt den angehängten Screenshot (Einmal-Trigger direkt nach dem
Booten, also die Werte 0, 1, 2, ..., 5 werden ausgegeben).

Ich hoffe, du kannst das als funktionierendes Minimalbeispiel
akzeptieren. ;-)

von Helmut W. (upm)


Lesenswert?

Hallo Jörg,


ich weiß nicht was ich sagen soll einfach traumhaft, du bist mein Held 
des Tages.

Vielen vielen Dank.

VG

von Helmut W. (upm)


Lesenswert?

Hallo lieber Jörg,


eine Frage habe ich leider doch noch, auch mit der Gefahr das Ich 
gesteinigt werde.

Wenn ich im SPI_CSR_SCBR ein anderes CS wähle bzw. 1 oder 2, 
funktioniert es nicht mehr kein Takt nix, trotz das ich die anderen 
Register angepasst habe.
1
PIOA->PIO_OER = (1<<9)|(1<<10)|(1<<11)|(1<<13)|(1<<14)|(1<<22)|(1<<24);
2
  PIOA->PIO_ODR = (1<<12);
3
  PIOA->PIO_PDR = (1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<22)|(1<<24);
4
  PIOA->PIO_ABCDSR[0] &= ~((1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<22)|(1<<24));
5
  PIOA->PIO_ABCDSR[1] &= ~((1<<9)|(1<<10)|(1<<11)|(1<<12)|(1<<13)|(1<<14)|(1<<22)|(1<<24));
6
7
  PMC->PMC_PCER0 = 1 << ID_SPI; // enable clock
8
  SPI->SPI_CR = SPI_CR_SWRST; // software reset
9
  SPI->SPI_CR = SPI_CR_SWRST;
10
  SPI->SPI_MR = SPI_MR_MSTR | SPI_MR_MODFDIS; // master mode
11
  SPI->SPI_CR = SPI_CR_SPIEN;  // enable SPI
12
  SPI->SPI_CSR[chip_select] = SPI_CSR_SCBR(42) | SPI_CSR_BITS_8_BIT;

VG

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dein Code sieht etwas wirr aus: die anderen NPCSx-Signale liegen
größtenteils auf peripheral function B, die hast du aber nirgends
ausgewählt.

Nichtsdestotrotz ist es mir auf die Schnelle nicht gelungen, die
recht komplexe Logik und den Variantenreichtum hinter all diesen
Chipselect-Signalen zu verstehen.  Im SPI_MR gibt es noch ein Feld
namens PCS, ich habe das Gefühl, das hat damit zu tun.  Vielleicht
guckst du dir den zugehörigen Sourcecode im ASF mal an, möglicherweise
versteht man den Kram im Datenblatt dann besser.

Oder du lebst einfach mit NPCS0. :-)

von Helmut W. (upm)


Angehängte Dateien:

Lesenswert?

Hallo Jörg,


da muss ich dich leider korrigieren die meisten Liegen auf peripheral 
function A, ich werde jetzt mal schauen ob mir es gelingt die anderen zu 
selektieren. Trotzdem vielen Dank für deine Bemühungen. ;-)


VG

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Helmut W. schrieb:
> die meisten Liegen auf peripheral function A

Nein, die NPCSn mit n != 0 liegen größtenteils auf peripheral B.
Ausnahme: PA31 (benutzt du in deinem Beispiel nicht) und PB14 (Port B
hast du gleich gar nicht drin).

Nichtsdestotrotz, ich hatte es gestern abend mit PA3 probiert (weil
der auf meinem Xplained Pro ganz gut greifbar ist), aber ich habe es
trotzdem auf Anhieb nicht geschafft, das hinzubekommen.  Du musst da
wirklich mal durch den ASF-Source hindurchwuseln, was sie im SPI_MR
noch setzen, damit man das zugehörige PCS-Signal tatsächlich aktiviert
bekommt.  Bei n = 0 (wie in meinem Originalbeispiel der Fall) scheint
es halt eher zufällig so zu passen, dass das Select dann auch wirklich
generiert wird.  Lies die mal im Datenblatt die Ausführungen zu
“Peripheral Selection” durch, dann weißt du, worauf ich hinaus will.

Ohne selektierten Slave wiederum tickert die SPI offensichtlich gar
nicht erst los.

Ich kann aber jetzt erstmal keine weitere Zeit da hinein investieren.

von Helmut W. (upm)


Lesenswert?

So nach langem hin und her hab ich eine Variante gefunden. Alles 
funktioniert auch CS
1
#define MISO   PIO_PA12A_MISO   
2
#define MOSI   PIO_PA13A_MOSI   
3
#define SPCK   PIO_PA14A_SPCK  
4
#define NPCS0   PIO_PA11A_NPCS0   
5
#define NPCS1   PIO_PA9B_NPCS1   
6
#define NPCS2   PIO_PA10B_NPCS2   
7
#define NPCS3   PIO_PA22B_NPCS3   
8
#define NPCS4   PIO_PA24
9
#define aktuel_CS  NPCS3
10
11
Pio *p_pio;
12
    uint32_t pin, ul_sr, i;
13
   
14
   
15
    /* assign port A to periph. A and B */
16
   p_pio = (Pio *)((uint32_t)PIOA);
17
   p_pio->PIO_WPMR = 0x50494F00;
18
   pin = SPCK | MISO | MOSI | NPCS0;
19
   ul_sr = p_pio->PIO_ABCDSR[0];
20
   p_pio->PIO_ABCDSR[0] = ~pin & ul_sr;   // PIO_ABCDSR[0] = 0 A
21
   p_pio->PIO_ABCDSR[0] |= aktuel_CS;         // PIO_ABCDSR[0] = 1 B
22
   
23
   ul_sr = p_pio->PIO_ABCDSR[1];
24
   p_pio->PIO_ABCDSR[1] = ~(pin | aktuel_CS) & ul_sr;   // PIO_ABCDSR[1] = 0
25
   p_pio->PIO_PUER = pin;   // Enable Pull up
26
   p_pio->PIO_OER = MOSI | SPCK | NPCS0 | aktuel_CS;   // Configure pin as output
27
   p_pio->PIO_ODR = MISO;   // Configure pin as input
28
   p_pio->PIO_PDR |= pin | aktuel_CS;   // Remove the pins from under the control of PIO
29
30
   
31
        /* assign port B to periph. A and B */
32
   p_pio = (Pio *)((uint32_t)PIOB);
33
   p_pio->PIO_WPMR = 0x50494F00;
34
   pin = NPCS1 | NPCS2;
35
   ul_sr = p_pio->PIO_ABCDSR[0];
36
   p_pio->PIO_ABCDSR[0] = ~NPCS1 & ul_sr;   // PIO_ABCDSR[0] = 0   A
37
   p_pio->PIO_ABCDSR[0] |= NPCS2;      // PIO_ABCDSR[0] = 1   B
38
   
39
   ul_sr = p_pio->PIO_ABCDSR[1];
40
   p_pio->PIO_ABCDSR[1] = ~(NPCS1 | NPCS2) & ul_sr;   // PIO_ABCDSR[1] = 0
41
   p_pio->PIO_PUER = pin;   // Enable Pull up
42
   p_pio->PIO_OER = pin;   // Configure pin as output
43
   p_pio->PIO_PDR |= pin;   // Remove the pins from under the control of PIO
44
   
45
   SPI->SPI_CR = SPI_CR_SWRST | SPI_CR_SPIDIS;   // Software reset
46
  // DLYBCS | PCS      | LLB     | WDRBT   | MODFDIS        | PCSDEC  | PS      | MSTR
47
   SPI->SPI_MR =   0x02<<24 | 0x0B<<16 | 0x00<<7 | 0x00<<5 | SPI_MR_MODFDIS | 0x01<<2 | 0x01<<1 | SPI_MR_MSTR;
48
                               // DLYBCT | DLYBS | MCK/SPI_CK | 8 bit  | CSAAT   | CSNAAT  | NCPHA   | CPOL
49
   for(i=0;i<4;i++) SPI->SPI_CSR[i] = 0x02<<24 | 0x0A<<16 | 0xFA<<8 | 0x00<<4 | 0x00<<3 | 0x01<<2 | 0x00<<1 | 0x01<<0;
50
   
51
   if ((PMC->PMC_PCSR0 & (0x01u << ID_SPI)) != (0x01u << ID_SPI)) PMC->PMC_PCER0 = 0x01u << ID_SPI;   // Enable SPI clock
52
   SPI->SPI_CR = 0x01 << 0;      // SPI enable

von Rudolph R. (rudolph)


Lesenswert?

Ich bin dann noch gespannt, was das Ethernet zu Deinem Layout meint. :-)
Der CAN sollte ja ohne Probleme laufen.

Wenn das Datenblatt an der Stelle besser ist als beim SPI, das fand ich 
jetzt schon verhältnismäßig grausam wie man sich da die Infos zusammen 
stückeln muss - beim AVR kann Atmel das besser.
Dabei ist der ATSAM4E eigentlich schon gut abgehangen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rudolph R. schrieb:
> Dabei ist der ATSAM4E eigentlich schon gut abgehangen.

Ja, aber auch die Peripherals sehen halt alle ein wenig angestaubt
aus.  Ich frage mich ernsthaft, ob wohl jemals jemand auf die Idee
gekommen ist, tatsächlich einen SPI-Bus mit 16 Slaves über einen
externen Adressdekoder zu betreiben …

Die neueren SAMs (SAMD und Konsorten) sehen in dieser Hinsicht
deutlich moderner aus.

von Rudolph R. (rudolph)


Lesenswert?

Jörg W. schrieb:
>> Dabei ist der ATSAM4E eigentlich schon gut abgehangen.
>
> Ja, aber auch die Peripherals sehen halt alle ein wenig angestaubt
> aus.

Ich meinte mehr, dass die Doku etwas seltsam ist dafür das die genug 
Zeit dafür hatten.
Aber vielleicht ist das jetzt auch so, man soll ja das AFS benutzen.

> Die neueren SAMs (SAMD und Konsorten) sehen in dieser Hinsicht
> deutlich moderner aus.

Mal schauen, wann die C21 verfügbar werden.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rudolph R. schrieb:

> Ich meinte mehr, dass die Doku etwas seltsam ist dafür das die genug
> Zeit dafür hatten.

Wenn die Teile erstmal raus sind, bekommt da niemand mehr Zeit
zugestanden, die Doku zu überarbeiten.  Da gibt's nur noch Bugfixes
dann.

> Aber vielleicht ist das jetzt auch so, man soll ja das AFS benutzen.

ASF kam erst sehr viel später (für die SAM3 findet man teilweise auch
nicht „richtige“ Appnotes, die nicht nur ein Doku-Abklatsch vom ASF
sind), wird aber mittlerweile halt als das Allheilmittel gepriesen.

von Aditya K. (stadkama)


Lesenswert?

Ich brauche eine Hilfe zu spi Kommunikation zwischen Gerät und bmi160 
sam4e8c sensors.I nahm Bezug von Ihrem code.I habe einige Fragen.
Brauche ich, um die Sensoren zu initialisieren? Wie kann ich mehr als 4 
Sensoren sprechen?
Brauche ich, um die Schreib- und Lesefunktionen von bmi160_support.c und 
bmi160.c?

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.