STM32 HAL SPI nur 18 Bits senden oder Bitbanging?

Gast #5602523
Lesenswert?

Hallo Zusammen,

ich möchte gerne ein Baustein (HMC6300) via SPI konfigurieren (siehe 
Anhang). Leider umfasst das Register des Bausteins nur 18 Bits. Ein 
Versuch mit der HAL_SPI_TransmitReceive() Funktion 24 Bits (um 5 
führende Nullen ergänzt, welche ggf. durch das FIFO gelatched werden) zu 
übertragen schlug fehl.

Gibt es eine Möglichkeit nur die benötigten 18 Bits zu senden?

Falls nur Bitbanging möglich ist, wie kann ich geschickt auf die 
GPIO-Pins zugreifen? Die bestehende SPI Konfiguration kann nicht ohne 
weiteres geändert werden, da auf dem SPI-BUS noch andere Bausteine sind, 
welche konfiguriert werden müssen.

Wäre sowas in der Art möglich:
void Bitbanging_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t 
*pTxData, uint8_t *pRxData, uint8_t HMC630x_NUM_TX_BITS, uint8_t 
HMC630x_NUM_RX_BITS)
{
//Default Bitbanging
...

//Pseudocode für GPIO-Zugriff über SPI-Handler
HAL_GPIO_WritePin(hspi.MOSI_Port, hspi.MOSI_PIN, MOSI_PIN_SET);
}

Vielen Dank,

Ralph
Angehängte Dateien:
Gast #5602564
Lesenswert?

Ralph schrieb:
> Ein
> Versuch mit der HAL_SPI_TransmitReceive() Funktion 24 Bits (um 5
> führende Nullen ergänzt, welche ggf. durch das FIFO gelatched werden) zu
> übertragen schlug fehl.

Nach Adam Riese (und Eva Zwerg) müssten 6 führende Nullen ergänzt
werden damit 24 Bits aufgefüllt werden.

Aber ich behaupte dass du etwas anderes falsch machst. Es ist
offensichtlich dass die Vorgeschichte (was vor den 18 Bits
passiert) unerheblich ist, was sich aus dem aus dem Datenblatt
zitierten Absatz (speziell der zweite Teil) entnehmen lässt:

--------------------------------------------------------------
After the 18th clock pulse of the write operation, the ENABLE
line returns high to load the register array on the IC; prior
to the rising edge of the ENABLE line, no data is written to
the array.
--------------------------------------------------------------

Also nur die steigende Flanke der ENABLE Leitung entscheidet
was in die Register geschrieben wird.

Entweder ist deine SPI falsch konfiguriert (Clock Polarität,
Clock Phase) oder die Ausrichtung deiner Daten in den 24 Bit
ist nicht korrekt.
Gast #5602573
Lesenswert?

Ralph schrieb:
> Gibt es eine Möglichkeit nur die benötigten 18 Bits zu senden?

Beachte auch dass (eher ungewöhnlich) die Bits vom nieder-
wertigsten zuerst bis zum höchstwertigen gesendet werden.
Das ist eher die Analog Devices Manier, während man bei
(ehemals) Hittite "immer" MSB zuerst überträgt / übertragen hat.
Gast #5602641
Lesenswert?

Hallo Zusammen,

zunächst einmal vielen Dank für eure hilfreichen Antworten.

@Frickelfritze
Du hast natürlich recht, es müssen 6 führende Nullen sein. Die 
Problematik mit dem LSB first habe ich abgehandelt und der Vereinfachung 
nicht erwähnt. Falls es wen interessiert, dass Datenwort erzeuge ich wie 
folgt:
1
 ...
2
  /* SPI1 parameter configuration*/
3
  hspi1.Instance = SPI1;
4
  hspi1.Init.Mode = SPI_MODE_MASTER;
5
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
6
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
7
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
8
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
9
  hspi1.Init.NSS = SPI_NSS_SOFT;
10
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
11
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; //Kompatiblität mit anderen Bausteinen
12
 ...
13

14
 ...
15
uint32_t volatile TxWord, RxWord;
16
  
17
TxWord = (ADDRESS_BIT << HMC630x_ADDRESS_BIT_OFFSET) | (R_W_Bit << HMC630x_R_W_Bit_OFFSET) | (REG_CTRL_Bit << HMC630x_REG_CTRL_BIT_OFFSET) | (Value << HMC630x_VALUE_BIT_OFFSET);  
18

19
TxWord = (TxWord << 6); //führende Nullen anhängen
20
TxWord = Swap4Bytes(TxWord); //Byteweise Swappen
21
TxWord = reverse32(TxWord); //alles Bits reversen
22

23
HAL_SPI_TransmitReceive(hspi, (uint8_t *)&TxWord, (uint8_t *)&RxWord, HMC630x_WORD_WIDTH_BYTES, HAL_MAX_DELAY);
24
 ...

Prinzipell kann ich jetzt das gewünschte Bitpattern senden. Bei 
Anschluss des HMC6300 wird jedoch die Clk und MOSI Leitung auf high 
gezogen, ggf. ist dies noch ein Hardwareproblem bei dem ich bei muss. 
Jedenfalls antwortet der HMC6300, was er eigentlich bei gesetztem 
Write-Bit nicht machen sollte (siehe Timing Diagramm in meinem ersten 
Post).

Hier ein beispielhaftes Bitpattern an den HMC6300 gesendet (lsb first, 
ohne die 6 führende Nullen):
011100000011110000

Anbei die zugehörige Ausgabe auf dem Logikanalyser.

@Peter D.
Ich nutze einen STM32L052K8U. Mir ist noch nicht klar, wie ich die 
Datensize geschickt unter Kompatiblität zu CubeMX ändern kann. Kann ich 
die Datensize auf zur Laufzeit ändern? Wie erwähnt hängen noch andere 
Bausteine mit an dem Bus und müssen konfiguriert werden.
Angehängte Dateien:
#5602780
Lesenswert?

Ralph schrieb:
> Ich nutze einen STM32L052K8U. Mir ist noch nicht klar, wie ich die
> Datensize geschickt unter Kompatiblität zu CubeMX ändern kann.

Das kannst Du ja in CubeMX einstellen, siehe Anhang. (ich sehe aber 
gerade, dass der STM32L052 wohl nur 8- und 16-bit unterstützt)
Gast #5603037
Lesenswert?

Hm, wie den? Ich kann in CubeMX die Pins als Hardware-SPI ODER als GPIO 
Input/Output konfigurieren . Beides geht nicht bzw. wüsste ich nicht 
wie. Kann ich trotz Hardware-SPI Konfiguration eine Art 
HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_SET); 
aufrufen?

Um weiter zu kommen habe ich mal Hardware-SPI durch Bitbanging ersetzt 
und getestet (zwar unschön aber naja.. ).
1
void Bitbanging_SPI_Transmit(uint32_t TxWord)
2
{
3
   for (uint8_t i = 0; i < 18; i++)
4
   {
5
       if (TxWord & 0x1)
6
           HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_SET);          
7
       else
8
           HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_RESET);
9

10
       HMC630x_Delay();
11
       HAL_GPIO_WritePin(SPI_CLK_GPIO_Port, SPI_CLK_Pin, GPIO_PIN_SET);
12
       HMC630x_Delay();
13
       HAL_GPIO_WritePin(SPI_CLK_GPIO_Port, SPI_CLK_Pin, GPIO_PIN_RESET);
14
       HMC630x_Delay();
15

16
       TxWord >>= 1;
17
   }
18
  
19
   HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_RESET);
20
}

Die Ausgabe funktioniert laut Logicanalyser (siehe Anhang). Leider 
antwortet der HMC6300 an MISO, was er bei einem Write nicht machen 
sollte.

Nach meinem Verständnis endspricht die Ausgabe jetzt der des 
Datenblattes. Etwas unsicher bin ich mir bei der TX-Adresse: "the Tx 
Chip Address 110, LSB first)." -> Verstehe ich so, dass ich erst die 
Null sende und dann die beiden Einsen.
Angehängte Dateien:
Gast #5603047
Lesenswert?

Niemand zwingt dich dazu, die Konfiguration der I/O Pins ausschließlich 
über Cube MX zu machen. Dein Programm kann sie zur Laufzeit beliebig 
umkonfigurieren.

Falls Dir das dann in Kombination mit Cube MX zu kompliziert wird - 
willkommen im Club. Ich benutze die ganze HAL gar nicht, CMSIS und ein 
paar Zeilen eigener Code genügen mir.
Gast #5603087
Lesenswert?

@Stefanos
Oky danke. Dann werde ich sobald das Bitbanging funktioniert, versuchen 
den Code zusammenzuführen. Schade, dass dann wahrscheinlich die 
Kompatiblität zu CubeMX verloren gehen wird. Bis jetzt konnte ich immer 
in CubeMX neuen Code generieren und nahtlos in den bestehenden 
einsetzen.

@Johnny B.
Ja genau, ich verwende Pegelwandler (MAX3392EEUD+).
Ich habe anbei drei Screenshots vom Oszilloskope beigefügt (Übersicht, 
Zoom, noch mehr Zoom). Das Oszilloskope ist hinter den Pegelwandlern, 
direkt am HMC6300 angeschlossen. Man sieht relativ starkes 
Überschwingen, ggf. wäre eine Serienterminierung sinnvoll. Was meint 
Ihr?

Ich glaube trotzdem nicht, dass dies der Grund dafür ist, dass der 
HMC6300 nicht funktioniert. Aktuell gehen mir die Ideen etwas aus.
Angehängte Dateien:
Gast #5603110
Lesenswert?

Gesund sehen die Signale nicht aus und 1,2V Pegel haben die auch nicht 
wirklich, jedenfalls nicht für lange.

Ausserdem funkt schon nach 16 Takten das CS dazwischen, so kommt es 
nicht zu Übernahme der 18 bit.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren