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:
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:
1
#include <altera_avalon_spi_regs.h>
2
#include <altera_avalon_spi.h>
3
4
5
main{
6
int test;
7
8
while (!(IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK));
9
10
IOWR_ALTERA_AVALON_SPI_TXDATA(SPI_BASE, 0xFFFF);
11
12
while (!(IORD_ALTERA_AVALON_SPI_STATUS(SPI_BASE) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK));
13
14
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
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
Description: ... It supports only SPI masters with
4
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
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... )
----(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.
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
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.
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:
1
constalt_u8rd_id_cmd[]={epcs_rdid};
2
alt_u8id[3];
3
4
alt_avalon_spi_command(
5
base,
6
0,
7
sizeof(rd_id_cmd)/sizeof(*rd_id_cmd),
8
rd_id_cmd,
9
3,
10
id,
11
0
12
);
13
14
return(alt_u32)((id[0]<<16)|(id[1]<<8)|id[2]);
An dieser Stelle bleibt er hängen:
1
/* Wait until the interface has finished transmitting */