mikrocontroller.net

Forum: FPGA, VHDL & Co. Kommunikation mit NIOSII SPI


Autor: Niko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich arbeite gerade an einem Projekt für die FH und muss dabei über das 
SPI im NIOS II Prozessor die Register eines Bauteils beschreiben um die 
Funktion des Bauteils richtig testen zu können.

Das SPI soll 7 bit Reg-Addr, 1 r/w bit und 16 bit daten übertragen.

Ich bin leider was FPGAs anbelangt und NIOS recht unerfahren und da 
happerts schon an Kleinigkeiten.

Kann mir jemand bitte erklären wie man die SPI im NIOS anspricht?
z.B.: im Reg1 den Wert 1 schreiben.


Momentan versuche ich es mit einem normalen IOWR(base,Reg-Nr,data) 
-Befehl, doch beim lesen im I-Net bin ich auf eigene SPI-Aufrufe 
gestoßen, die ich nicht ganz verstehe.

Die sageh dann so aus:
while (!(IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK));
IOWR_ALTERA_AVALON_SPI_TXDATA(SPI_BASE, 0x0001);
dazu die meist
int alt_avalon_spi_command(alt_u32 base, alt_u32 slave,
                           alt_u32 write_length,
const alt_u8 * write_data,
                           alt_u32 read_length, alt_u8 * read_data,
                           alt_u32 flags);

Ich hoffe hier hat jemand mehr Erfahrung wie ich.

Gruß
Niko

Autor: niko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versteh es immernoch nicht. Ich will 24 bit senden.
Wie sag ich der SPI das nach 24 bit schluss ist?

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du mal ein Link zum Datenblatt des SPI-Cores?

Duke

Autor: Niko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Danke für die Antwort.


Hier das Datenblatt.

http://www.altera.com/literature/ug/ug_embedded_ip.pdf

Ab Seite 83 beginnt der Teil über die SPI.
Ab Seite 91 beginnt die Software.

Momentan sieht es bei mir zusammengefasst so aus:
#include <altera_avalon_spi_regs.h>
#include <altera_avalon_spi.h>
 
 
main{
int test;
 
while (!(IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK));
 
IOWR_ALTERA_AVALON_SPI_TXDATA(SPI_BASE, 0xFFFF);
 
while (!(IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK));
 
test=IORD_ALTERA_AVALON_SPI_RXDATA(SPI_BASE);

Ich sollte eigentlich FFFF am Register auslesen können... oder?
Momentan ergibt das auslesen nur "0".
Muss ich noch andere Sachen beachten ausser die hier genannten?




Gruß
Niko

Autor: Harald Flügel (hfl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin Niko!

Eine Frage: Wieso nudelst Du auf der Hardware herum? Du hast doch die 
Seite 91 im Manual gefunden. Dort steht die Funktion 
alt_avalon_spi_command die für dich die ganze Bitpopelei übernimmt. Nimm 
doch diese Funktion und gut ?!?

Grüße,
Harald

Autor: Niko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genao daran scheitert es wie gesagt :D
Wie verwendet man die?

Ich hab gerade seit gestern einen Hänger im Verständniss des commands
unsigned char wdata[3];
wdata[0]=0x00;       // Addr. 0 & w
wdata[0]=0x02;       // MSB
wdata[0]=0x03;       // LSB

int alt_avalon_spi_command(meine_base, 0,3,wdata,0, rdata,0);



Sollte das meine Register beschreiben ?

Autor: Niko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bekomme beim lesen immer eine 0.
Auch mit dem command.
Das schreiben auf das Register tut nicht.... :(

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Harald:

Im Datenblatt steht:
alt_avalon_spi_command()
...
Description: ... It supports only SPI masters with
data width less than or equal to 8 bits.
Passt also nicht für 24 Bit :-/


@Niko:
1.
Hast Du schon mal nach alt_avalon_spi_command gegoogelt?

2.
> Ich bekomme beim lesen immer eine 0.
> Das schreiben auf das Register tut nicht.... :(
Wie stellst Du das fest? Auf der Hardware oder im Simulator?

3.
Im Datenblatt sind auf Seite 89 ein paar Timingdiagramme. Hast Du das 
richtige Timing eingestellt? Wie sieht den die Instanziierung Deines 
Cores aus? Stimmt die base-address?

Duke

Autor: Niko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Duke, hallo Harald,

danke schonmal für eure Antworten.
Messungen mit dem Oszi haben ergeben, dass die SPI 16 Bit pro zyklus 
schreibt. Am Programm lag es wohl doch nicht. (Habs ausgemessen die 
schreibbefehle würden für 8 Bit passen).

Jetzt ist die Frage wo kann ich einstellen das die SPI nur 8 Bit senden 
(fals das möglich ist) und dann stellt sich natürlich die Frage ob
3x8 bit wirklich 24 bit ergeben.

Zur Erklärung:

ich habe mir eine Funktion erstellt die genau das gleiche wie commands 
macht..

write (Reg-adress);
write (MSB);
write(LSB);       // das ist jetzt nur veranschaulicht


Zwischen den einzelnen schreib befehlen habe ich eine totzeit.
liegt wohl teilweise auch am buffer befehl:

while (!(read(TRDY_MSK)); // warte auf ready

doch ich bezweifle das es ohne diesen befehl viel besser wird.

Am Baustein das ich mit der SPI konfigurieren will benötige ich laut 
Datenblatt 24 aufeinanderfolgene Takte.
Ich habe dann zwar 24 sclk Takte, doch die sind jeweils in 8er Blöcke 
unterteilt. Ob es wirklich nichts ausmacht wenn zwischen den sclk's so 
ein abstand ist wird sich zeigen ...
(hoffentlich kann es der Baustein... )

Autor: Harald Flügel (hfl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
----(snip)----
unsigned char wdata[3];
wdata[0]=0x00;       // Addr. 0 & w
wdata[0]=0x02;       // MSB
wdata[0]=0x03;       // LSB

int alt_avalon_spi_command(meine_base, 0,3,wdata,0, rdata,0);

Sollte das meine Register beschreiben ?
----(snap)----

Ja. Das und nix anderes. Wobei Du sicher auch ein array für die 
Emfpangsdaten definiert hast, in dem Fall unsigned char rdata[3]. Und 
meine_base hat hoffentlich den richtigen Wert. Dann solltest Du bei dem 
Funktionsaufruf oben 48 Takte bekommen, 3*8 für wdata und 3*8 für rdata.

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niko schrieb:
> Ich habe dann zwar 24 sclk Takte, doch die sind jeweils in 8er Blöcke
> unterteilt. Ob es wirklich nichts ausmacht wenn zwischen den sclk's so
> ein abstand ist wird sich zeigen ...
> (hoffentlich kann es der Baustein... )

Das sollte kein Problem sein. Zur Absicherung hilft ein Blick ins 
Datenblatt.

Duke

Autor: Niko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut damit wäre das Problemm gelöst und ich verstehe mittlerweile viel 
mehr vom SPI-Core.
(auch wenn es eigentlich nicht meine Baustelle war :D, doch als Student 
lernt man ja nie umsonst :D)

Vielen Dank Duke, vielen Dank Harald.

Autor: Rumpelstielzchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Wie hast du das Problem mit der Totzeit gelöst? Ich versuche auch 
mittels alt_avalon_spi_command auf die Register des Flashs zuzugreifen. 
Aber bei mir landet er immer in der Endlosschleife, weil die Readys 
nicht kommen.

Beim Systemstart wird das Flash durch 
ALTERA_AVALON_EPCS_FLASH_CONTROLLER_INIT gestartet, wo u.a. auch 
alt_avalon_spi_command aufgerufen wird und auch erfolgreich aus der 
Schleife zurückkehrt.

Hat jemand ne Idee?

Das ist der alt_avalon_spi_command Aufruf, der im Init klappt, aber wenn 
ich ihn manuell ausführe, hängen bleibt:
const alt_u8 rd_id_cmd[] = {epcs_rdid};
  alt_u8 id[3];

  alt_avalon_spi_command(
    base,
    0,
    sizeof(rd_id_cmd) / sizeof(*rd_id_cmd),
    rd_id_cmd,
    3,
    id,
    0
  );

  return (alt_u32) ((id[0] << 16) | (id[1] << 8) | id[2]);


An dieser Stelle bleibt er hängen:
/* Wait until the interface has finished transmitting */
  do
  {
    status = IORD_ALTERA_AVALON_SPI_STATUS(base);
  }
  while ((status & ALTERA_AVALON_SPI_STATUS_TMT_MSK) == 0);

Autor: Rumpelstielzchen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrektur: In dieser Schleife bleibt er hängen.
do
    {
      status = IORD_ALTERA_AVALON_SPI_STATUS(base);
    }
    while (((status & ALTERA_AVALON_SPI_STATUS_TRDY_MSK) == 0 || credits == 0) &&
            (status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0);

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.