[nevermind] STM32L4 SPI + KX122 accelerometer - funny behavior - Page 1
Forum section: electronics / general

author: TinkeringSteve
author_rank: Frequent Contributor
timestamp: June 15, 2017, 08:52:51 am
content: See follow up post----Howdy folks!In the attached image, you see the timing diagram of the Kionix Kx122 accelerometer.Forgive me for using the Cube HAL, it was supposed to be a quick thingSo I configured the STM32L476RG nucleo board as master thus:Code:// SPI configm_spiHandle.Instance = SPI1;m_spiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; // 80 MHz / 32 = 2.5 MHzm_spiHandle.Init.Direction = SPI_DIRECTION_2LINES;m_spiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; // data valid on first edgem_spiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; // funny name, this actually makes idleState = LOWm_spiHandle.Init.DataSize = SPI_DATASIZE_8BIT;m_spiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;m_spiHandle.Init.TIMode = SPI_TIMODE_DISABLE;m_spiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;m_spiHandle.Init.NSS = SPI_NSS_SOFT;m_spiHandle.Init.Mode = SPI_MODE_MASTER;if (HAL_SPI_Init(&m_spiHandle) != HAL_OK){ error_handler();}The pins themselves seem to be configured correctly, from what they do on the scope & in the debugger (e.g. I can receive correct replies from slave, just under funny circumstances).Then I have this little routine for transmitting and receiving:Code:static void spi_transmit(uint8_t* txbuf, uint8_t* rxbuf, uint16_t count){__HAL_SPI_ENABLE( & m_spiHandle ); // ensures clock line initial value will be according to SPi setup *before* CS gets drawn and the slave sees itSPIx_NCS_GPIO_PORT->BRR = SPIx_NCS_PIN; // nCS LOWif ( HAL_SPI_TransmitReceive( & m_spiHandle, txbuf, rxbuf, count, 1000 ) != HAL_OK ){ error_handler();}SPIx_NCS_GPIO_PORT->BSRR = SPIx_NCS_PIN; // nCS HIGH}I'm using software CS toggling because the KX122 allows 2 different periods over which CS needs to be drawn:a) 2 byte commands in the form {regAddr, regVal}b) buffer reads {regAddr, byte, byte, ..., byte[n-1]}And the STM32L4 HAL / SPI hardware can only toggle CS per configured frame of e.g. 8 or 16 bits.So what's funny?Well, in the timing diagram you can see that the KX122 wants the data MSB first, and register address byte first, then data byte.When I do that, I get no reply of the thing.When I swap the byte order of the *writing* of a register to wrong, I do get the correct replies at the correct places for the first part of the initiation sequence.Funnier: I did *not* swap the order when reading registers as well, it's still correct while writing to registers has the wrong order.And I'm not just seeing the correctly interpreted values on the logic analyzer (Saleae), I'm actually reading them back and see them in the in-code debugger.The logic analyzer also does show me that the register write bytes are indeed in the wrong order.I also have another logic analyzer capture where the KX122 device was completely configured and delivering measurement values.That was when I used the MCP2210 USB-SPI bridge to communicate to the KX122 from a Windows PC directly (different use case).And there, the byte order was as supposed.So it's not a datasheet error, the way I'm sending it now is definietly wrong.Yet it's the only way I am getting anything back from the device.I have a feeling this could be because of how the KX122 interprets my funny SPI signal, but from what I can tell, the MCP-as-master logic analyzer capture looks the same as my not working one with the STM32L4 as master, when it comes to relations of time distances between edges of the different lines (e.g. what comes first, time distances long enough according to datasheet, etc).So I don't get it. The MCP-as-master capture is not easy to look at big-picture wise, though, as the thing leaves "kilometers" of distances between everything, it's not easy comparing the images visually and I can't make a good screen capture of the MCP one.Has anyone with experience seen such a behavior and knows what the cause may be?Thanks in advance- me

author: TinkeringSteve
author_rank: Frequent Contributor
timestamp: June 15, 2017, 10:02:53 am
content: Okay, it actually was none of the things I was thinking about.When I ported the code from windows from using the microchip USB-SPI bridge, I at first commented-out a line that proved to be more vital than I was aware.It did a "Thread.Sleep( 2 )", and I had no delay function ready when porting this and making it compile at first, and totally forgot about it.You are supposed to wait a while after sw-resetting the KX122 before continuing sending it commands.I put the delay back in there and now it works with correct per datasheet SPI settings.I don't quite see yet how exactly deliberately the false byte order in my short init sequence made the SPI slave output the expected replies at some point...But anyway, it works repeatably now