Forum: Mikrocontroller und Digitale Elektronik AD9910 mit STM32L476 SPI komischer Effekt beim Lesen


von Hans-Georg L. (h-g-l)


Angehängte Dateien:

Lesenswert?

Hallo,
ich steuere einen AD9910 mit einem STM32L476RG an.
Das Schreiben der AD9910 Register (16,32,64 Bit) funktioniert ohne 
Probleme.
Verwendet wird als Grundlage HAL und Cube erzeugter Code.
Auf dem Bild ist die Datenübertragung (half-duplex lesen) eines 64Bit 
Registers vom AD9910 zum LS476 zu sehen. Es werden wie angefordert 8 
Byte übertragen soweit so gut, dann sollte aber der LS476 (MASTER) die 
Taktleitung auf High (STALL) setzen. Das macht er aber nicht sondern 
will 3 weitere Bytes haben. Der AD9910 ist aber mit der Übertragung 
fertig und gibt den Datenbus (MOSI) frei und wartet auf ein neues 
Instruction Byte vom L476. Da aber der Takt weiter läuft liest er nur 
Nullen und 0x00 als Instruction Byte bedeutet: Schreibe Daten in das 
erste Conf-Register, das hat aber 32Bit. Weil der Takt wird nach 2 Bytes 
abgebrochen wird hängt dann der AD9910. Das Problem lässt sich umgehen 
indem ich nach jedem Lesen beim AD99910 ein IO_Reset mache.

Was könnte das sein ? Meine erste Vermutung war das der L476 evtl auf 
CRC wartet. Das ist aber abgeschaltet (Bit im Debugger überprüft).
Ein extra Bit für CRC Empfang habe ich nicht gefunden. Ich verwende 
SPI3.
Im errata steht etwas von einem busy Bit das manchmal nicht 
zurückgesetzt
wird, das könnte es vielleicht auch sein ?

von Darth Moan (Gast)


Lesenswert?

Moin,

vielleicht schaue ich ins falsche Manual, aber bei mir steht da im CR1
nix von einem DFF Bit. Die Frame länge wird im CR2 DS[3:0] festgelegt.
Bits 11:8 DS[3:0]: Data size
These bits configure the data length for SPI transfers.
0000: Not used
0001: Not used
0010: Not used
0011: 4-bit
0100: 5-bit
0101: 6-bit
0110: 7-bit
0111: 8-bit
1000: 9-bit
1001: 10-bit
1010: 11-bit
1011: 12-bit
1100: 13-bit
1101: 14-bit
1110: 15-bit
1111: 16-bit

Im CR1 Bit 11 sehe ich im Manual ein CRCL Bit:
Bit 11 CRCL: CRC length
This bit is set and cleared by software to select the CRC length.
0: 8-bit CRC length
1: 16-bit CRC length

Ist da wirklich das richtige Device (STM32L47x) eingestellt?

von Hans-Georg L. (h-g-l)


Lesenswert?

Darth Moan schrieb:
>
> Ist da wirklich das richtige Device (STM32L47x) eingestellt?

Ja es ist das richtige Device eingestellt und es werden auch die 
richtigen Files included. Aber du hast recht die Anzeige im Debugger 
stimmt nicht mit dem Ref. Manual überein. Habe gerade nachgeschaut der 
Fehler liegt im svd File.

Die Frame Länge steht auf 8.

: Bearbeitet durch User
von Darth Moan (Gast)


Lesenswert?

Moin,

also wenn ich dich richtig verstehe, sind die Schreib Transfers immer
genau 8 bytes lang und nur beim Lesen tritt dieses Problem auf?
Wie bestimmst du denn den Transfer?
Ich meine, ich sende dann eben die benötigte Anzahl an Bytes raus
und mehr macht der dann auch nicht. Aber die HAL Funktionen kenne ich
nicht so gut, weil ich die nicht benutze.

von Hans-Georg L. (h-g-l)


Lesenswert?

Darth Moan schrieb:
> Moin,
>
> also wenn ich dich richtig verstehe, sind die Schreib Transfers immer
> genau 8 bytes lang und nur beim Lesen tritt dieses Problem auf

Es werden immer zuerst 8 Bit geschrieben (Instruction Byte) um das 
Register im AD9910 zu Adressieren und das höchste Bit bestimmt dabei ob 
dieses Register gelesen oder beschrieben werden soll. Die folgenden 
Daten von/zu den Registern können 16/32 oder 64 Bit lang sein. Im Bild 
ist zu sehen das eine Registeradresse geschrieben wird und dann die 
32Bit aus diesem Register gelesen werden. Da der Read-Datentransfer 
halb-duplex stattfindet wird der Takt vom Master (STM32L) geliefert und 
die Daten (4Byte)  vom AD9910. Ich sage der HAL schreibe 1 Byte und dann 
lese 4 Byte. Der STM32L taktet nach den 4. gelesenen Byte aber einfach 
weiter was der AD9910 nicht mag und sich aufhängt. Beim Schreiben in die 
AD9910 Register stimmt die Taktanzahl mit den übertragenen Bytes 
überein.

von Darth Moan (Gast)


Lesenswert?

Moin,

also bei derart kleinen Datenmengen würde ich nur einen bidirektionalen
Transfer machen. Wenn also 1 byte Adresse und dann 4 byte Register Wert
übertragen werden sollen würde ich 5 Byte in den Sendebuffer legen
Register Adresse + 4 Dummy Byte (die man dann auch auf dem Oszi/LA sehen
und identifizieren kann zB 0xAFFEDEAD oder sowas) und abfeuern.
Im Empfangsbuffer liegt dann natürlich zuerst ein Dummy Byte vom AD9910
und dahinter erst die Nutzdaten.
Ich kenne den AD9910 nicht, braucht der zwischen Adresse Daten eine 
Pause?

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.