Forum: Mikrocontroller und Digitale Elektronik STM32L4 SPI, seltsames verhalten


von Steve K. (sktron)


Angehängte Dateien:

Lesenswert?

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...

von Arduinoquäler (Gast)


Lesenswert?

Programme in Prosa-Form sind scheisse.

Zeige relevante Programmteile.

von Steve K. (sktron)


Lesenswert?

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
}

von STM Apprentice (Gast)


Lesenswert?

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"

von Steve K. (sktron)


Lesenswert?

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
Noch kein Account? Hier anmelden.