Tach auch, ich habe hier ein STM32L476RG nucleoboard als SPI master, und einen Kionix KX122 accelerometer als slave. Wie dem timing diagramm zu entnehmen, werden active-low CS, und active-high clock verwendet. Ich habe somit die werte für clock polarität und phase auf 0 configuriert. CS toggle ich vor und nach dem senden auf lo / hi, manuell (soft NSS), und schalte vor dem setzendes CS noch die SPi peripherie ein, damit sie den clock outupt auf den richtigen anfangswert setzt, bevor CS kommt. Die zeitabstände dort sehen auch dem datsheet genehm aus. Mit der 2.5 MHz clock bin ich weit unter den angegebenen 10 MHz, die das Kx122 unterstützen soll. Lt. dem datasheet des KX122 soll auch das byte für die register adresse zuerst kommen, dann das für den wert. MSB-first. Ist alles so eingestellt, bekomme aber so keine antwort vom KX122. Das bizarre ist, dass wenn ich beim schreiben von einem {regAddr, regVal} byte paar die reihenfolge vertausche, sodass es lt. datasheet falsch ist, bekomme ich an den richtigen stellen der ersten teile der init sequenz antworten, undzwar die richtigen (z.b. chip ID via WHO_AM_I register). Wobei ich die byte reihenfolge beim lesen von registern aber nicht vertauscht habe, die ist wie vorher und lt. datasheet richtig herum ;-) Ich hatte vor den versuchen mit dem stm32L4 mit einem microchip MCP2210 USB-SPI bridge modul schon das KX122 angesprochen, da funktionierte die init sequenz ganz durch und ich konnte werte auslesen. Und lt. logic analyzer stimmte da die reihenfolge auch mit dem datasheet überein, sollte also def. richtig sein. Also ist es wahrsch. bloß zufall, dass der slave die richtigen werte bekommt z.b. durch nachfolgende nachrichten...? Oder was kann hier sonst noch los sein? Was ich nicht verstehe ist, dass, von der reihenfolge von signalen (auch wenn andere timings, da das MCP riesige pausen zw. den bytes lässt) alles so aussieht wie mit dem MCP als master... aber es gibt keine antwort vom slave...
Programme in Prosa-Form sind scheisse. Zeige relevante Programmteile.
Wenn du dir wirklich cube HAL code antun möchtest, so sei es ;-)
1 | // SPI config
|
2 | |
3 | m_spiHandle.Instance = SPI1; |
4 | m_spiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; // 80 MHz / 32 = 2.5 MHz |
5 | m_spiHandle.Init.Direction = SPI_DIRECTION_2LINES; |
6 | m_spiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; |
7 | m_spiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; |
8 | m_spiHandle.Init.DataSize = SPI_DATASIZE_8BIT; |
9 | m_spiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB; |
10 | m_spiHandle.Init.TIMode = SPI_TIMODE_DISABLE; |
11 | m_spiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; |
12 | m_spiHandle.Init.NSS = SPI_NSS_SOFT; |
13 | m_spiHandle.Init.Mode = SPI_MODE_MASTER; |
14 | |
15 | if (HAL_SPI_Init(&m_spiHandle) != HAL_OK) |
16 | { error_handler(); |
17 | }
|
Pins sind von dem, was sie sichtbar tun, richtig konfiguriert. Dann gibts noch diese routine, die zum übertragen aufgerufen wird. Entweder für 2-byte commands {regAddr, regVal}, über die CS gezogen sein soll, oder ein (1 + bufferSize) command, mit dem der buffer des slave ausgelesen wird, wobei nur am anfang einmal das read register adressiert wird, worüber auch CS die ganze zeit gezogen sein soll:
1 | static void spi_transmit(uint8_t* txbuf, uint8_t* rxbuf, uint16_t count) |
2 | {
|
3 | __HAL_SPI_ENABLE( & m_spiHandle ); // stellt sicher, dass clock initialwert richtig ist, bevor CS gezogen wird |
4 | SPIx_NCS_GPIO_PORT->BRR = SPIx_NCS_PIN; // nCS LOW |
5 | |
6 | if ( HAL_SPI_TransmitReceive( & m_spiHandle, txbuf, rxbuf, count, 1000 ) != HAL_OK ) |
7 | { error_handler(); |
8 | }
|
9 | |
10 | SPIx_NCS_GPIO_PORT->BSRR = SPIx_NCS_PIN; // nCS HIGH |
11 | }
|
Prüfe doch mal ob eventuell dein CS zu früh inaktiv wird so wie das Problem hier angesprochen wird: Beitrag "STM32F2 SPI DMA CS Handling" oder früher hier: Beitrag "[STM32F4xx] SPI Optimierung"
Hahah, manchmal sollte man einfach seine eigenen kommentare noch mal lesen ;-) Danke für die links. Aber das problem schienen nicht die SPI settings zu sein. In der version mit dem MCP als master, von windows aus, hatte ich an einer stelle in der init sequenz ein delay, da sollte man auch warten, damit der KX122 mit etwas fertig wird. Das war für den MCU port des codes erstmal auskommentiert, und tja, war wohl wichtig ;-) Ich sehe noch nicht ganz, wie ich durch die absichtlich falsche byte order dem ding eine antwort entlocken konnte, aber mit der jetzigen änderung geht die init sequenz mit allen SPI einstellungen gemäß datasheet wiederholbar korrekt durch.
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.