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
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.
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.
Die Datenlänge ist beim STM32F303 von 4-16 Bits konfigurierbar. Also einfach 2*9 Bit senden und schon hast Du die 18 Bits. SPI control register 2 (SPIx_CR2) Bits 11:8 DS [3:0]: Data size These bits configure the data length for SPI transfers: 1000: 9-bit
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.
Ralph schrieb: > hspi1.Init.DataSize = SPI_DATASIZE_8BIT; Ich würde da einfach ne 9 eintragen und schauen, ob der Compiler meckert. Ralph schrieb: > Kann ich > die Datensize auf zur Laufzeit ändern? Du kannst das SPI jederzeit umkonfigurieren, wenn ein Transfer beendet ist.
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)
:
Bearbeitet durch User
Hm oky also kann ich via Hardware nur 8 oder 16 Bit ausgeben. Schade. Besteht die Möglichkeit die SPI-Pins ans Port A zur Laufzeit auch via Bitbanging zu bedienen?
Johnny B. schrieb: > ich sehe aber > gerade, dass der STM32L052 wohl nur 8- und 16-bit unterstützt So siehts aus. Daher sollte man das konkrete Target immer als erstes angeben.
Ralph schrieb: > Besteht die Möglichkeit die SPI-Pins ans Port A zur Laufzeit auch via > Bitbanging zu bedienen? Natürlich, das geht immer.
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.
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.
Zwischenfrage; Elektrisch ist das SPI vom HMC6300 richtig angeschlossen, d.h. mit 1.2V Pegelwandler?
@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.
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.
Den zweiten Satz nehme ich zurück. Da muss ich mich vorhin irgendwie verguckt haben.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.