cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to communicate with VL53L8CX over SPI

Ce3c
Associate

Hi all,

I'm trying to get the VL53L8CX ToF sensor working for a university project, this is my first time using it. I made a little breakout PCB for it and soldered it, measured resistance between al neighbouring pins, none of them were shorts or open circuits which to me confirms that the sensor was soldered correctly. The breakout PCB includes 1.8V <-> 3.3V level shifting, here's the full circuit diagram:

Screenshot 2025-04-08 160711.png

I've connected it to an ESP32, but it seems like I can't communicate with the sensor over SPI. As I understand, the sensor should be mirroring the given register adres from the MOSI pin to the MISO pin, but there's no activity on MISO, the signal just seems to follow the CS signal. Here's what the waveforms look like, measured at the sensor (1.8V) side of the level shifters:

IMG_0776.jpg

Zoomed in:

IMG_0777.jpg

Here's the code:

#include <Arduino.h>
#include <SPI.h>

#include "vl53l8cx_api.h"
#include "platform.h"

VL53L8CX_Configuration Dev;

void setup()
{
  pinMode(SS, OUTPUT);
  SPI.begin();
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE3));
  Serial.begin(115200);
}

void loop()
{
  uint8_t status, isAlive;
  status = vl53l8cx_is_alive(&Dev, &isAlive);
  if (!isAlive || status)
  {
    Serial.println("VL53L8CX not detected at requested address");
  }

  delay(1);
}

I'm unsure about my implementation of the functions in the sensor's driver platform.c file, but at the very least I should be seeing some activity on the MISO line right?

Any efforts to help me debug this would be greatly appreciated, I've been stuck here for a few days.

5 REPLIES 5

You scope has a USB socket to get screenshots - this will give far clearer results than photographing the screen!

 

AndrewNeil_1-1744127557145.png

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
John E KVAM
ST Employee

I'm going to make a guess here. 

in ST's API, there is a platform.c - and it's basically empty.

We ship a completed on in our example directory, but the one in the main bit of code is empty.

it's your job to fill that out for the MCU you are using. 

ST has it own STM32 processors we think you should use - and we aren't about to ship ESP32 code. 

But it should be an easy matter to go to github.com and find some ESP32 SPI basic functions. 

Use that to fill out the functions in platform.c 

Then I think it's going to work better.

As a software guy i might suggest print out your status after your is_alive() call. I'm pretty sure it's going to tell you that the IO failed. 

- john

 

 


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.

Hi John, thanks for the quick reply.

This is how the read and write byte functions are implemented so far:

#include "platform.h"
#include <SPI.h>
#include <Arduino.h>

uint8_t VL53L8CX_RdByte(
	VL53L8CX_Platform *p_platform,
	uint16_t RegisterAdress,
	uint8_t *p_value)
{
	uint8_t status = 0;
	digitalWrite(SS, LOW);
	SPI.write16(RegisterAdress & 0x7FFF); // Set MSB to 0 (read)
	*p_value = SPI.transfer(0x00); // Write dummy byte to read data
	digitalWrite(SS, HIGH);
	return status;
}

uint8_t VL53L8CX_WrByte(
	VL53L8CX_Platform *p_platform,
	uint16_t RegisterAdress,
	uint8_t value)
{
	uint8_t status = 0;
	digitalWrite(SS, LOW);
	SPI.write16(RegisterAdress | (1 << 15)); // Set MSB to 1 (write)
	SPI.write(value); // Write data
	digitalWrite(SS, HIGH);
	return status;
}

Looking at the waveforms, it's clear data is being sent to the sensor but it's not replying anything. Do you think this is expected behaviour due to an error in the software, or might it be a hardware issue?

I actually looked for a usb drive for this but didn't have one with me at the time of posting so I did my best to take some clear pictures without glare:)

John E KVAM
ST Employee

I don't know anything about how your MCU writes to the SPI bus. 

The best I can do is to include the platform.c used on the STM32. 

Perhaps that will help.

Here we wrote the two functions WrMulti() and RdMulti(). Notice the RdByte and WrByte are just calls to the multi function with length 1. 

What I notice is that there is a device structure that is absent in your code. (might not be a problem. I've no clue.)

status |= HAL_SPI_Transmit(&hspi1, data_write, data_size, 100*data_size);

In our code all the info about the SPI device is contained in that structure. 

typedef struct __SPI_HandleTypeDef
{
  SPI_TypeDef                *Instance;      /*!< SPI registers base address               */

  SPI_InitTypeDef            Init;           /*!< SPI communication parameters             */

  uint8_t                    *pTxBuffPtr;    /*!< Pointer to SPI Tx transfer Buffer        */

  uint16_t                   TxXferSize;     /*!< SPI Tx Transfer size                     */

  __IO uint16_t              TxXferCount;    /*!< SPI Tx Transfer Counter                  */

  uint8_t                    *pRxBuffPtr;    /*!< Pointer to SPI Rx transfer Buffer        */

  uint16_t                   RxXferSize;     /*!< SPI Rx Transfer size                     */

  __IO uint16_t              RxXferCount;    /*!< SPI Rx Transfer Counter                  */

  void (*RxISR)(struct __SPI_HandleTypeDef *hspi);   /*!< function pointer on Rx ISR       */

  void (*TxISR)(struct __SPI_HandleTypeDef *hspi);   /*!< function pointer on Tx ISR       */

  DMA_HandleTypeDef          *hdmatx;        /*!< SPI Tx DMA Handle parameters             */

  DMA_HandleTypeDef          *hdmarx;        /*!< SPI Rx DMA Handle parameters             */

  HAL_LockTypeDef            Lock;           /*!< Locking object                           */

  __IO HAL_SPI_StateTypeDef  State;          /*!< SPI communication state                  */

  __IO uint32_t              ErrorCode;      /*!< SPI Error code                           */

#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
  void (* TxCpltCallback)(struct __SPI_HandleTypeDef *hspi);             /*!< SPI Tx Completed callback          */
  void (* RxCpltCallback)(struct __SPI_HandleTypeDef *hspi);             /*!< SPI Rx Completed callback          */
  void (* TxRxCpltCallback)(struct __SPI_HandleTypeDef *hspi);           /*!< SPI TxRx Completed callback        */
  void (* TxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi);         /*!< SPI Tx Half Completed callback     */
  void (* RxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi);         /*!< SPI Rx Half Completed callback     */
  void (* TxRxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi);       /*!< SPI TxRx Half Completed callback   */
  void (* ErrorCallback)(struct __SPI_HandleTypeDef *hspi);              /*!< SPI Error callback                 */
  void (* AbortCpltCallback)(struct __SPI_HandleTypeDef *hspi);          /*!< SPI Abort callback                 */
  void (* MspInitCallback)(struct __SPI_HandleTypeDef *hspi);            /*!< SPI Msp Init callback              */
  void (* MspDeInitCallback)(struct __SPI_HandleTypeDef *hspi);          /*!< SPI Msp DeInit callback            */

#endif  /* USE_HAL_SPI_REGISTER_CALLBACKS */
} SPI_HandleTypeDef;

i just don't see the equivalent in your code. 

Given that the first function just reads one byte and that doesn't work, it's got to be here somewhere.

- john 


If this or any post solves your issue, please mark them as 'Accept as Solution' It really helps. And if you notice anything wrong do not hesitate to 'Report Inappropriate Content'. Someone will review it.