STM32L4 SPI, seltsames verhalten

OP #5042152
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...
Angehängte Dateien:
OP #5042580
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
}
OP #5042721
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.

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