Forum: FPGA, VHDL & Co. SPI AXI Sensor


von User (Gast)


Lesenswert?

Ich verweise auf den Beitrag 
Beitrag "Xilinx Spartan6 SPI ADC". Da dieser älter als sechs 
Monate ist, eröffne ich an dieser Stelle einen neuen Beitrag.

Ich habe wie in dem Beitrag in einem FPGA einen MicroBlaze 
implementiert. Dieser ist über den AXI-Bus mit dem AXI SPI Core 
verbunden. Zum Initialisieren rufe ich SPI_Initialize() auf. Es wird bei 
mir "SPI_Initialize ... XST_SUCCESS" zurückgegeben. Klinkt schonmal gut.

int SPI_Initialize(uint32_t Device_ID)
{
 int Status     = 0x00;
 uint8_t Option = 0x00;

 SPI_Config = XSpi_LookupConfig(Device_ID);
 if (SPI_Config == NULL){
    print("SPI_Initialize ... XST_DEVICE_NOT_FOUND\n\r");
    return XST_DEVICE_NOT_FOUND;}

 Status = XSpi_CfgInitialize(&SPI_Instance, SPI_Config, 
SPI_Config->BaseAddress);

/*XSP_MASTER_OPTION 0x1
XSP_CLK_ACTIVE_LOW_OPTION 0x2
XSP_CLK_PHASE_1_OPTION 0x4
XSP_LOOPBACK_OPTION 0x8
XSP_MANUAL_SSELECT_OPTION 0x10 */

Option = XSP_MASTER_OPTION | XSP_CLK_PHASE_1_OPTION 
|XSP_MANUAL_SSELECT_OPTION;

XSpi_SetOptions(&SPI_Instance, Option);
if (Status != XST_SUCCESS){
 print("SPI_Initialize ... XST_FAILURE\n\r");
 return XST_FAILURE;}
else{
 print("SPI_Initialize ... XST_SUCCESS\n\r");
 return XST_SUCCESS;}
}


Ich muss dazu sagen, dass am FPGA ein Sensor angeschloßen ist, den ich 
über SPI auslesen möchte. -> SPI wird als Master konfiguriert.
Nun meine bisherige Lese-Funktion aufbauend auf dem oben genannten 
Beitrag und den Dokumentationen zur xspi.h Datei.

uint32_t SPI_Read(uint32_t Address)
{  int Status = 0;

   uint8_t ReadBuffer[1]       = {0x00};
   uint16_t WriteBuffer[1]   = {0x147}; /*Instruction Format*/

   XSpi_SetSlaveSelect(&SPI_Instance, 1);
   XSpi_Start(&SPI_Instance);
   XSpi_IntrGlobalDisable(&SPI_Instance);
   Status = XSpi_Transfer(&SPI_Instance, &WriteBuffer[0], 
&ReadBuffer[0], 1);
   switch(Status){
   case XST_SUCCESS:print("XST_SUCCESS\n\r");break;
   case XST_DEVICE_IS_STOPPED:print("XST_DEVICE_IS_STOPPED\n\r");break;
   case XST_DEVICE_BUSY:print("XST_DEVICE_BUSY\n\r");break;
   case XST_SPI_NO_SLAVE: print("XST_SPI_NO_SLAVE\n\r");break; }

   xil_printf("Register-Wert: %x\n\r",ReadBuffer);
   return XST_SUCCESS;
}

Hier wird erneut ein Register-Wert ausgegeben. Allerding "Null", statt 
dem Default-Wert.

1. Frage: Fällt generell etwas auf, was an den beiden Funktionen falsch 
läuft?
2. Frage: Ich möchte lediglich pro Funktionsaufruf "einmal" einen 
registerwert lesen. Wieso muss ich ein Array an die Funktion 
XSpi_Transfer() übergeben)
3. Frage: Mein Instruction Format (welches den Lesevorgang einleitet: 
Lesebit, Adresse etc.) ist 15 Bit lang, die WriteBuffer darf lediglich 
vom Typ u8 sein. Gibt es einen Ausweg?

Vielen Dank

von User (Gast)


Lesenswert?

Ich sehe gerade, die Formatierung ist missglückt. Entschuldigung dafür. 
Ich habe mir die Signale EN, SCK, MISO, MOSI aufs Oszilloskop gelegt. 
Ich sehe jedoch keine Signale. Nicht einmal das CLK Signal. Trotz 
positiver Rückmeldung bei der Initialisierung und Read-Funktion. Hat wer 
Vorschläge?

von Philip K. (philip_k)


Lesenswert?

Schonmal simuliert?

von User (Gast)


Angehängte Dateien:

Lesenswert?

Anbei ein Ausschnitt aus der Simulation. (Simulationsumgebung 
funktioniert (habe es zuvor einmal mit der Ausgabe eines Characters 
versucht) Der zugehörige C-Code:

main.c -------------------------------------------------------

#include <stdio.h>
#include "platform.h"
#include "parameters.h"
#include "spi.h"

void print(char *str);

int main()
{
    init_platform();

    SPI_Initialize(SPI_DEVICE_ID);

    while(1)
    {
      test();
    };

    return 0;
}

spi.c ---------------------------------------------------------
#include "spi.h"
#include "xspi.h"
#include "parameters.h"
#include "stdint.h"

XSpi_Config     *SPI_Config;
static XSpi      SPI_Instance;

int SPI_Initialize(uint32_t Device_ID)
{
  XSpi_LookupConfig(Device_ID);
  XSpi_CfgInitialize(&SPI_Instance, SPI_Config,SPI_Config->BaseAddress);

  Option = XSP_MASTER_OPTION |
           XSP_CLK_PHASE_1_OPTION|
           XSP_MANUAL_SSELECT_OPTION;

  XSpi_SetOptions(&SPI_Instance, Option);

  // Control Register (SPICR)

  #define SPI_CR_LOOP 0x01
  #define SPI_CR_SPE 0x02
  #define SPI_CR_MASTER 0x03
  #define SPI_CPOL 0x04
  #define SPI_CPHA 0x05
  #define SPI_CR_TX_FIFO_RESET 0x06
  #define SPI_CR_RX_FIFO_RESET 0x07
  #define SPI_CR MANUAL_SLAVE_SELECT 0x08
  #define SPI_CR MASTER_TRANSACTION_INHIBIT 0x09

  uint32_t spicr_reg = SPI_CR_SPE | SPI_CR_MASTER | SPI_CPOL |SPI_CPHA;

  XSpi_WriteReg(SPI_Base_ADDRESS, 0x60, spicr_reg );
}

void test(void)
{
int8_t out[4];
int8_t in[4];

out[0] = 0x9F;
out[1] = 0xFF;
out[2] = 0xFF;
out[3] = 0xFF;

in[0] = 0x00;
in[1] = 0x00;
in[2] = 0x00;
in[3] = 0x00;


XSpi_Start(&SPI_Instance);
XSpi_SetSlaveSelect(&SPI_Instance, 1);
XSpi_Transfer(&SPI_Instance, out, in, 4);
}


Sieht jemand den Fehler?

von Dach (Gast)


Lesenswert?

Diese Zeile kommt mir etwas komsich vor:

uint32_t spicr_reg = SPI_CR_SPE | SPI_CR_MASTER | SPI_CPOL |SPI_CPHA;


wahrscheinlich braucht es da noch ein paar shift operationen oder du 
musst die Defines anders definiern.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Dach schrieb:
> wahrscheinlich braucht es da noch ein paar shift operationen
Bitmanipulation

von pks (Gast)


Lesenswert?

Du definierst einen Pointer auf eine Config-Struktur:
XSpi_Config     *SPI_Config;

Der wird aber nirgendwo initialisiert, und es wird auch keine 
entsprechende Struktur instanziiert.

von pks (Gast)


Lesenswert?

Ok, ich seh gerade dass die XSpi_CfgInitialize() die Struktur füllt. 
Anlegen muss Du sie aber trotzdem.

Also meiner Meinung nach müsste das so aussehen.
1
XSpi_Config     *SPI_Config;
2
static XSpi      SPI_Instance;
3
4
int SPI_Initialize(uint32_t Device_ID)
5
{
6
  XSpi_LookupConfig(Device_ID);
7
  XSpi_CfgInitialize(&SPI_Instance, SPI_Config, SPI_Base_ADDRESS);
8
9
10
  ...

von pks (Gast)


Lesenswert?

Sorry, ich meinte so:
1
static XSpi_Config      SPI_Config;
2
static XSpi      SPI_Instance;
3
 
4
int SPI_Initialize(uint32_t Device_ID)
5
{
6
   XSpi_LookupConfig(Device_ID);
7
   XSpi_CfgInitialize(&SPI_Instance, &SPI_Config, SPI_Base_ADDRESS);
8
 
9
 
10
   ...

von User (Gast)


Lesenswert?

Beispiel:

#define SPI_CR_LOOP 0x01
#define SPI_CR_SPE 0x02
#define SPI_CR_MASTER 0x03
#define SPI_CPOL 0x04

Ich möchte Bit SPI_CR_LOOP und Bit SPI_CR_MASTER auf High setzen. Alter 
Registerinhalt ist beispielsweise 0b1001

=> spicr_reg |= SPI_CR_LOOP | SPI_CPOL;
=> 0b1001 |= 0b0001 | 0b0100;
=> spicr_reg  = 0b1101

Somit müsste die Zeile nun stimmen. Meine Änderung:

uint32_t spicr_reg = XSpi_ReadReg(SPI_Base_ADDRESS, 0x60);
spicr_reg  |= ((1 << SPI_CR_SPE) |
              (1 << SPI_CR_MASTER)|
              (1 << SPI_CPOL) |
              (1 << SPI_CPHA));

XSpi_WriteReg(SPI_Base_ADDRESS, 0x60, spicr_reg );

Die ISim-Diagramme sehen jedoch unverändert aus.


Zu anderen Anmerkung:

static XSpi_Config      SPI_Config;
static XSpi             SPI_Instance;

habe ich doch geschrieben (siehe oben). Ich habe lediglich einmal das 
"static" vergessen. Laut Beispiel muss es:

static XSpi_Config      *SPI_Config;
static XSpi      SPI_Instance;

lauten. (mit Stern). Ansonsten gibt es Fehlermeldungen.

von pks (Gast)


Lesenswert?

Dir ist aber schon der Unterschied zischen SPI_Config und *SPI_Config 
klar?
Wo wird denn in Deinem Beispiel die Struktur angelegt?

von User (Gast)


Lesenswert?

Im xspi.h file dachte ich. Siehe hierzu

http://www.cs.indiana.edu/hmg/le/project-home/xilinx/ise_13.2/ISE_DS/EDK/sw/XilinxProcessorIPLib/drivers/spi_v3_01_a/doc/html/api/xspi_8h.html

Dort ist die Struktur definiert. Der Rückgabewert von

XSpi_CfgInitialize() und  XSpi_LookupConfig() ist auch "XST_SUCCESS".

von User (Gast)


Lesenswert?

Ein Beispiel, welches ich zuvor angesprochen habe. Hier wird es 
ebenfalls mit Sternchen in der main() aufgeführt.

http://www.cs.indiana.edu/hmg/le/project-home/xilinx/ise_13.2/ISE_DS/EDK/sw/XilinxProcessorIPLib/drivers/spi_v3_01_a/examples/xspi_stm_flash_example.c

von pks (Gast)


Lesenswert?

Und da wird dem Pointer auch was zugewiesen:
ConfigPtr = XSpi_LookupConfig(SPI_DEVICE_ID);

Du rufst die Funktion auf, ohne den Rückgabewert zu verwenden und Dein 
Pointer bleibt uninitialisiert.

von User (Gast)


Lesenswert?

Das ist jetzt mein abgeänderter Code. Habe es eingearbeitet. Ich habe 
somit den Rückgabewert aufgerufen, richtig? Ich sehe jedoch immernoch 
das selbe Bild. :(

#include "spi.h"
#include "xspi.h"
#include "parameters.h"
#include "stdint.h"

static XSpi_Config      *SPI_Config;
static XSpi      SPI_Instance;

int SPI_Initialize(uint32_t Device_ID)
{
 int Status   = 0x00;
 uint8_t Option   = 0x00;

 SPI_Config=XSpi_LookupConfig(Device_ID);

 if (SPI_Config == NULL)
 {
    //print("SPI_Initialize ... XST_DEVICE_NOT_FOUND\n\r");
    return XST_DEVICE_NOT_FOUND;
 }

Status = XSpi_CfgInitialize(&SPI_Instance, SPI_Config, 
SPI_Config->BaseAddress);

 Option = XSP_MASTER_OPTION |
           XSP_CLK_PHASE_1_OPTION  |
           XSP_MANUAL_SSELECT_OPTION;

 XSpi_SetOptions(&SPI_Instance, Option);


 #define PI_CR_LOOP   0x01
 #define PI_CR_SPE 0x02
 #define PI_CR_MASTER 0x03
 #define PI_CPOL 0x04
 #define SPI_CPHA 0x05
 #define SPI_CR_TX_FIFO_RESET 0x06
 #define SPI_CR_RX_FIFO_RESET 0x07
 #define SPI_CR MANUAL_SLAVE_SELECT 0x08
 #define SPI_CR MASTER_TRANSACTION_INHIBIT 0x09


 uint32_t spicr_reg = XSpi_ReadReg(SPI_Base_ADDRESS, 0x60);
 spicr_reg  |= ((1 << SPI_CR_SPE)
            | (1 << SPI_CR_MASTER)
            | (1 << SPI_CPOL)
            | (1 << SPI_CPHA));

 XSpi_WriteReg(SPI_Base_ADDRESS, 0x60, spicr_reg );

 if (Status != XST_SUCCESS)
 {
  //print("SPI_Initialize ... XST_FAILURE\n\r");
  return XST_FAILURE;
 }
 else
 {
  //print("SPI_Initialize ... XST_SUCCESS\n\r");
  return XST_SUCCESS;
 }
}

von User (Gast)


Lesenswert?

Ist es ansonsten möglich, dass hier ein Bug in der Xilinx-Version 14.6 
ist?

von User (Gast)


Lesenswert?

Ok ISE 14.7 bringt auch keine Abhilfe.

von User (Gast)


Lesenswert?

Ich habe jetzt einmal genau folgenden Code übernommen:

Beitrag "Xilinx Spartan6 SPI ADC".

In diesem Beitrag hat derjenige jedenfalls irgendein Signal am SPI_CLK, 
SPI_ENB etc.
Ich bin ratlos. Wenn ich noch weitere Einstellungen hochladen soll, 
damit eine Analyse des Problems einfacher wird, sagt bescheid.
Vielen Dank euch.

von Philip K. (philip_k)


Lesenswert?

Schau Dir doch mal in der Simulation gezielt den SPI-Core an, ob da 
überhaupt Registerzugriffe stattfinden und ob in den Registern das steht 
was Du denkst. Es muss ja nicht an der Software liegen, das 
Prozessor-System an sich kann auch Fehler haben. XPS vergisst auch gern 
mal Signale zu verbinden, ich musste da schon oft manuell ran.

von Philip K. (philip_k)


Lesenswert?

Poste doch mal das MHS-File.

von User (Gast)


Angehängte Dateien:

Lesenswert?

anbei das mhs-File. Den SPI-Core schaue ich mir nun gezielt an, danke.

von Philip K. (philip_k)


Lesenswert?

User schrieb:
> anbei das mhs-File.

Da kann ich jetzt nicht auffälliges entdecken. Allerdings ist mir 
aufgefallen, dass Deine #defines für die Flags alle um 1 zu groß sind.

Das hier:
 #define PI_CR_SPE 0x02
...
 spicr_reg  |= ((1 << SPI_CR_SPE)
...

setzt z.B. das Master-Flag.

von User (Gast)


Angehängte Dateien:

Lesenswert?

Anbei die gezielte Analyse. Wieso sind die Registereinträge nur 5 Bit 
lang? Im Datenblatt zum IP-Core steht 32 Bit. Das ist nun nur der Teil, 
wo zum Test


#include <stdio.h>
#include "platform.h"
#include "parameters.h"
#include "spi.h"
#include "xspi.h"

static XSpi InstancePtr;

int main()
{
    init_platform();
    XSpi_Initialize(&InstancePtr, SPI_DEVICE_ID);
    return 0;
}

simuliert wird. Ich wollte den Registerinhalt einmal mit den 
Default-Werten vergleichen. Hat wer eine Idee?

von User (Gast)


Angehängte Dateien:

Lesenswert?

Anbei einmal der Registerinhalt vom Register "SPICR" für folgendes File:

#include <stdio.h>
#include "platform.h"
#include "parameters.h"
#include "spi.h"
#include "xspi.h"

static XSpi InstancePtr;
static XSpi_Config *SPI_Config;

int main()
{
    init_platform();
    XSpi_Initialize(&InstancePtr, SPI_DEVICE_ID);
    SPI_Config = XSpi_LookupConfig(SPI_DEVICE_ID);
    XSpi_CfgInitialize(&InstancePtr, SPI_Config, 
SPI_Config->BaseAddress);
    uint32_t Option = XSP_MASTER_OPTION |
                      XSP_CLK_PHASE_1_OPTION|
                      XSP_CLK_ACTIVE_LOW_OPTION|
                      XSP_MANUAL_SSELECT_OPTION;

     XSpi_SetOptions(&InstancePtr, Option);
     XSpi_Enable(&InstancePtr);

    return 0;
}

In der Simulation sieht das doch schonmal korrekt aus, was sagt ihr?

von User (Gast)


Angehängte Dateien:

Lesenswert?

Mir ist noch aufgefallen, dass "mst_trans_inhibit" nach einer Zeit 
wieder von High auf Low wechselt. (-> deaktivieren der Master 
Transaktion)

Und "sr2_spisel_slave" sieht irgendwie nicht korrekt aus.

von User (Gast)


Angehängte Dateien:

Lesenswert?

Das letzte Foto erst einmal. Sorry. Das ist der komplette Abschnitt 
diesesmal: Initialisieren und Senden.

Man sieht, dass der TX-Speicher einmal voll ist und auch wieder geleert 
wird. Trotzdem keine Reaktion an SPI_CLK, SPI_ENB etc.

#include <stdio.h>
#include "platform.h"
#include "parameters.h"
#include "spi.h"
#include "xspi.h"

void print(char *str);

static XSpi InstancePtr;
static XSpi_Config *SPI_Config;

int main()
{
 init_platform();

 uint8_t  in[4] = {0xf0, 0x0f, 0xf0, 0x1f};
 uint8_t out[4] = {0x0f, 0x0f0, 0x10, 0x03};

 XSpi_Initialize(&InstancePtr, SPI_DEVICE_ID);
 SPI_Config = XSpi_LookupConfig(SPI_DEVICE_ID);
 XSpi_CfgInitialize(&InstancePtr, SPI_Config, SPI_Config->BaseAddress);
 uint32_t Option = XSP_MASTER_OPTION
                  | XSP_CLK_PHASE_1_OPTION
                  |XSP_CLK_ACTIVE_LOW_OPTION
                  |XSP_MANUAL_SSELECT_OPTION;

 XSpi_SetOptions(&InstancePtr, Option);
 XSpi_SetSlaveSelect(&InstancePtr, 0);
 XSpi_Enable(&InstancePtr);
 XSpi_Start(&InstancePtr);
 XSpi_Transfer(&InstancePtr, out, in, 4);
 return 0;
}

von User (Gast)


Lesenswert?

Also sr_2_spisel_slave habe ich mit Setzen des Eingangs SPI_SEL auf '1' 
gesetzt, bzw. zum Test auf '0'.

von User (Gast)


Angehängte Dateien:

Lesenswert?

Ich sehe nun die Sendedaten, CLK und ENB an den Signalen:

spi_enb_o
spi_clk_o
spi_di_o

Ich sehe sie eine Ebene höher nicht mehr. Also bei SPI_ENB, SPI_CLK, 
SPI_Do.

Nun dachte ich, dass ich es umändern muss (siehe Foto). Dann erscheint 
folgende Fehlermeldung:

ERROR:EDK:4068 - INSTANCE: axi_spi_0, PORT: MISO_I - THREE_STATE port, 
MISO, in
   use. Multiple drivers found on TRI_I port, MISO_I - 
Z:\EDK_Projekt\system.mhs
   line 163
ERROR:EDK:4074 - INSTANCE: axi_spi_0, PORT: SCK, CONNECTOR: 
axi_spi_0_SCK - No
   driver found - Z:\EDK_Projekt\system.mhs line 156
ERROR:EDK:4074 - INSTANCE: axi_spi_0, PORT: MISO, CONNECTOR: 
axi_spi_0_MISO - No
   driver found - Z:\EDK_Projekt\system.mhs line 157
ERROR:EDK:4074 - INSTANCE: axi_spi_0, PORT: MOSI, CONNECTOR: 
axi_spi_0_MOSI - No
   driver found - Z:\EDK_Projekt\system.mhs line 158
ERROR:EDK:4074 - INSTANCE: axi_spi_0, PORT: SS, CONNECTOR: axi_spi_0_SS 
- No
   driver found - Z:\EDK_Projekt\system.mhs line 159

Also scheint es wohl ein Problem mit der Schnittstelle nach Außen zu 
sein.

von Xilinx Phreak (Gast)


Lesenswert?

Ich lese aufmerksam mit, weil ich an einem ähnlichen Problem laboriere. 
Scheiss AXI-Mist.

von Philip K. (philip_k)


Lesenswert?

Der arme Bus kann nun wirklich nichts dafür :-)

von user (Gast)


Lesenswert?

Ok. Der Bus ist nicht schuld ;). Hast du einen Vorschlag für Abhilfe ? 
Bzw wie Ich weiter vorgehen kann dem Fehler auf die Spur zu kommen ? 
Danke euch

von Philip K. (philip_k)


Lesenswert?

Ich vermute mal, da wird noch irgendeine Einstellung falsch sein. Bist 
Du sicher, dass der Core nicht im loopback-mode ist?

von User (Gast)


Lesenswert?

loopback-mode steht auf '0'. Also ( "Normal operation")

von User (Gast)


Angehängte Dateien:

Lesenswert?

Hier nocheinmal die Registerinhalte etc.

von User (Gast)


Lesenswert?

CLK-Signal liegt nun am Pin an. Hatte SlaveSelect nicht auf null. MISO, 
MOSI, EN liegen jedoch noch nicht an. Vorschläge?

von Philip K. (philip_k)


Lesenswert?

Wie sehen denn die Tristate-Enable Ausgänge aus?

von User (Gast)


Lesenswert?

Wo finde ich die, bzw. wo stelle ich die ein?

von User (Gast)


Angehängte Dateien:

Lesenswert?

Hat irgendwer die Möglichkeit es bei sich einmal zu simulieren. Finde 
den Fehler nicht. Habe versucht alle Einstellungen anzuhängen. Ratlos.

von User (Gast)


Lesenswert?

Wenn ich in Abbildung 1.gif axi_spi_o_sck_pin usw. auf die direction IO 
statt O stelle funktioniert es. Die Signale liegen nun am Pin an. Kann 
mir das einer erklären? SCK ist doch definitiv ein Ausgang, wenn der SPI 
ein Master ist.

von Hagen R. (hagen)


Lesenswert?

User schrieb:
> SCK ist doch definitiv ein Ausgang, wenn der SPI
> ein Master ist.

Korrekt, wenn er denn ein Master ist. Kenne mich mit AXI nicht aus, 
denke aber das du den Master/Slave Modus auch dynamisch zur Laufzeit 
umstellen kannst, ergo: sollte schon beim Design der SCK Pin 
bidirektional konfiguriert worden sein.

von User (Gast)


Angehängte Dateien:

Lesenswert?

Danke. Das Thema mit dem Tri-State-Ausgängen habe ich mir durchgelesen. 
Deren Einstellung in EDK bzw. SDK noch nicht ganz verstanden wie es 
scheint. Anbei der aktuelle ISim-Verlauf. Das Signal SS kommt immernoch 
nicht bis ans obere Layer. Irgendwie wird immer wieder der hochohmige 
Z-Zustand eingenommen. Außerdem dachte ich, dass das SS_Signal 
(entspricht ja Enable) automatisch beim Start eines Transfers auf Low 
gezogen wird und nach dem Transfer wieder auf High gesetzt wird. 
Scheinbar muss ich das manuel mit XSpi_Enable() bzw. XSpi_Disable() 
machen. Ein weiterer Punkt: Scheinbar ist es egal, ob ich SPISEL auf Low 
oder High lege, wenn ich das Device als Master vorgesehen habe, richtig?
Ich möchte die Übertragung gemäß Datenblatt (Figure 14 auf Seite 20) 
aufbauen. ->

http://www.xilinx.com/support/documentation/ip_documentation/axi_spi/v1_02_a/axi_spi_ds742.pdf

von User (Gast)


Angehängte Dateien:

Lesenswert?

Ein weiteres Problem: Möchte ich z.B. 24 Bit senden, dann muss ich 
schreiben:

uint8_t Byte_1 = 0x01;
uint8_t Byte_2 = 0x03;
uint8_t Byte_3 = 0x02;

uint8_t  in[1] = {0x00,0x00,0x00};
uint8_t out[1] = {Byte_1, Byte_2, Byte_3};

XSpi_Initialize(&InstancePtr, SPI_DEVICE_ID);
ConfigPtr = XSpi_LookupConfig(SPI_DEVICE_ID);
XSpi_CfgInitialize(&InstancePtr, ConfigPtr,ConfigPtr->BaseAddress);
uint32_t Option = XSP_MASTER_OPTION
                  |XSP_CLK_ACTIVE_LOW_OPTION
                  |XSP_MANUAL_SSELECT_OPTION;
XSpi_SetOptions(&InstancePtr, Option);
XSpi_SetSlaveSelect(&InstancePtr, 0);
XSpi_Start(&InstancePtr);
XSpi_Enable(&InstancePtr);
XSpi_Transfer(&InstancePtr, out, in, 3);

cleanup_platform();
return 0;

Dann sehe ich zwischen den Bytes immer undefinierte kurze Zustände.

von User (Gast)


Lesenswert?

Hat einer eine Idee, wo die Zustande (rot dargestellt) nach Byte 1, Byte 
2 u.s.w. herkommen? Bzw. wie man diese beseitigt? Kommt ja oft vor, dass 
man per SPI ein Befehl bit 2 Byte senden muss.

von Holger H. (holger-h-hennef) Benutzerseite


Lesenswert?

User schrieb:
> Hat einer eine Idee, wo die Zustande (rot dargestellt) nach Byte 1, Byte

Das ist das 8 Bit Reg. das muss im Zyklus neu geladen werden.+
Der Teiler-Takt für den SPI Clock muss aus dem Master-Takt eingesyncht 
werden. Da ist eben Pause ...bis es weiter geht.

#############################################################

Transaction Width: Selects 8, 16 or 32-bit transactions. Each SPI 
transaction
incorporates the selected number of bits. In dual and quad SPI modes, 
the transaction
width is restricted to 8 bits.
Seite 90
Transaction Width
Link:
http://www.xilinx.com/support/documentation/ip_documentation/axi_quad_spi/v3_1/pg153-axi-quad-spi.pdf

Gruss Holger.
Hier muss man auch warten,bis die MCU das SPI shiften erledigt hat.
static unsigned char spiByte(unsigned char val)
{

    USISR = (1<<USIOIF);    // Clear Counter Overflow Interrupt Flag (by 
writing 1 to the USIOIF bit)
     USIDR = val;           // Set data byte to send
    do
    {

    } while ((USISR & (1<<USIOIF)) == 0);   // Check for OIF set which 
will happen after 16 cycles.
     //I.e. 8 bits since the clock toggles twice per bit.
    return ( USIDR);    // Return data value
}


Mcu-isMaster SPI_S0#  SPI Slave select out_put

: Bearbeitet durch User
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.