Forum: Mikrocontroller und Digitale Elektronik SPI clocks/modes: Umschalten bei slaves mit verschiedenen specs (ATSAM4S)


von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Ich bin gerade am debuggen einer SPI-Konfiguration, die sich gerade 
recht eigenwillig verhält - und schuld ist mit ziemlicher sicherheit 
mein code/die µC config:

Ein ATSAM4S als Master mit zwei Slaves (ein ADC und ein Accelerometer) 
mit jeweils eigenen CS, die jedoch
a) verschiedene Clockrates (1MHz und 2MHz) und
b) verschiedene SPI modes (Mode 1 und Mode 3)
benutzen.

Für die Implementierung habe ich den Atmel Software Framework mit seinen 
spi/spi_master routines genutzt.

Der spi_master_setup_device routine gibt man baudrate, flags, chip 
select ids etc und bekommt eine device descriptor struct zurück, die man 
dann für weitere spi funktionen nutzt um das zu nutzende spi slave 
device zu spezifizieren.

Das hat irgendwann auch schonmal funktioniert, der ADC und das ACCEL 
konnten nacheinander angefragt werden und haben daten übertragen, mit 
open-bench logic sniffer auch sichtbar gemacht.

Nun habe ich aber folgendes problem: Mit der implementierung, wie sie 
nun steht, frage ich in der main loop die jeweils  von den slaves 
bereitgestelten DataReady (DRDY) Pinlevels ab - und wenn das jeweilige 
DRDY high ist, hole ich über spi die daten vom slave:
1
/*** GET MEASUREMENTS ***/
2
      if(dev_status.running){
3
        if (SLAVE1.is_enabled){
4
          //In case of SLAVE1 DATA READY signal: Get data package
5
          if (ioport_get_pin_level(SLAVE1_INT1_GPIO)){
6
            // Gets data via SPI
7
            slave1_get_measurement(SLAVE1, &adxl_buf, g_ul_ms_ticks);
8
            printf("#ACCEL: \t X: \t %d \t Y: \t %d \t Z: \t %d \t time: \t %lu \r\n", adxl_buf.x, adxl_buf.y, adxl_buf.z, adxl_buf.timestamp);
9
          }
10
          // In case of ADXL ACTIVE Interrupt signal: Send message
11
          if (ioport_get_pin_level(SLAVE1_INT2_GPIO)){
12
            puts("#Artifact Warning: Active Threshold Interrupt\r\n");
13
            slave1_ack_interrupts(SLAVE1);
14
          }
15
        }
16
        if (SLAVE2.is_enabled)
17
        {
18
          // In case of SLAVE2 DATA READY signal: Get data package via SPI
19
          slave2_get_measurement(SLAVE2, &ads_buf, g_ul_ms_ticks);
20
          if (ioport_get_pin_level(SLAVE2_INT1_GPIO)){
21
            printf("SLAVE2 DATA. T=%lu\r\n",ads_buf.timestamp);
22
            for(int i=1; i<9; i++){
23
              if (SLAVE2configuration.ch_conf[i-1].usechannel){
24
                printf("CH%d: %ld;\r\n", i, ads_buf.ch[i-1]);
25
              }
26
            }
27
          }
28
        }
29
      }

Wie man sieht, kann ich SLAVE1/2 enablen/disablen - einfach über uart 
konsole und damit zur übertragung nutzen oder nicht.

Mein Problem nun: Sind beide slaves enabled, schickt mir der ADC nur 
mist (nullen und manchmal ne zahl). Habe ich immer nur einen enabled, 
dann klappt alles.

Hat da jemand tips? Der ATSAM4S sollte eigentlich in der lage sein 
zwischen verschiedenen modes und taktraten hin und herzuschalten (was er 
ja auch schon erfolgreich getan hat). Woran kann es liegen?

von Tim S. (tim_seidel) Benutzerseite


Lesenswert?

Alex V. L. schrieb:
> slave2_get_measurement(SLAVE2, &ads_buf, g_ul_ms_ticks);
>           if (ioport_get_pin_level(SLAVE2_INT1_GPIO)){

Hier passt deine Beschreibung nicht mit deinem Code überein.
Was passiert mit Slave2, wenn du Daten abholst, die nicht verfügbar 
sind?

von Alex V. (bastel_alex) Benutzerseite


Lesenswert?

Tim Seidel schrieb:
> Hier passt deine Beschreibung nicht mit deinem Code überein.

Du hast recht, ich habe das eben auch (endlich) entdeckt, das könnte der 
Fehler auch schon gewesen sein. Schön doof. Ich schaue grade mal tiefer 
rein.

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.