Digilent provides a Library for the Pmod ToF targeting Digilent FPGA development boards, to be used with the Xilinx SDK development environment.
The library accesses the Pmod ToF hardware in order to implement Pmod ToF functionality.
Please follow the Adding a Hierarchical Block to a Vivado IPI Design to add the Pmod ToF Hierachical Block to your project.
The diagram above shows the general structure of the Pmod ToF Hierarchical Block Library and the relations between the library modules.
The library modules access the Pmod ToF functionality. These modules are as follows:
The ISL29501 Module contains the library functions for communication over I2C with the ISL29501 chip.
The EEPROM Module contains the library functions for communication over I2C with the Atmel® AT24C04D EEPROM memory.
The PmodToF Module implements functionality of the Pmod ToF device such as initialization functions, calibration functions, ISL29501 registry and EEPROM memory access functions.
The I2C Interface, GPIO Interface and UART Interface belong to the lowest level and are provided by the BSP project in Xilinx SDK. These interfaces implement the communication protocols.
The PmodToF library module implements Pmod ToF related functions.
These functions configure and initialize the Pmod ToF device over I2C and access Pmod ToF functionality such as performing calibrations and measurements and, R/W operations from EEPROM and ISL29501 registers.
For more details see the ISL29501 - Time of Flight(ToF) integrated circuit and EEPROM Memory sections.
In order to implement the I2C communication, the PmodToF module accesses functions implemented in ISL29501 Module and EEPROM Module. It uses digital IO pins exposed in the Pmod ToF connector: SCL(I2C clock) and SDA (I2C data). The ISL29501 additionally uses IRQ(Interrupt) and SS(Sample start). While the IRQ and SS pins are specific to ISL29501 chip, the I2C lines (data and clock) are shared with the EEPROM device.
The PmodToF module contains library functions for performing calibration and measurement. Calibration ensures the accuracy of measurement by making adjustments to correct measurement error. For more details about calibration and measurement, see the Calibration and Measurement sections.
void PmodToF_Initialize();
<none>
<none>
This function initializes the EEPROM and ISL29501.
It sets the ISL29501 chip address and EEPROM chip address for communication over I2C protocol and initializes
the ISL29501 registers (see the ISL29501 - Time of Flight(ToF) integrated circuit section), as described in the ISL29501 Firmware Routines (an1724.pdf) documentation for ISL29501 Chip Initialization.
#include “PmodToF.h”
PmodToF_Initialize();
uint8_t PmodToF_start_calibration(double actual_distance);
< actual_distance > | This is the correct distance value in meters for which the manual calibration is performed. Distance needs to be more than 5 cm (0.05 m). |
uint8_t - The error code:
ERRVAL_SUCCESS | 0 | success |
ERRVAL_INCORRECT_CALIB_DISTACE | 0xED | incorrect calibration distance; it has to be more than 5 cm(0.05 m) |
ERRVAL_FAILED_STARTING_CALIB | 0xFC | failed to start calibration, EEPROM or ISL29501 device is busy |
This function performs a manual calibration of device, for the distance that is provided by the value of the actual_distance parameter.
It calls all 3 calibration routines as described in the ISL29501 Firmware Routines (an1724.pdf) documentation.
#include “PmodToF.h”
ErrCode = PmodToF_start_calibration(distance);
double PmodToF_perform_distance_measurement();
<none>
double distance value | the distance measured by the device |
This function initiates a measurement and retrieves the measured distance value in meters.
Before calling this function, it is important that a manual calibration was performed or that a calibration was stored in then imported from the EEPROM user area or that factory calibration was restored from EEPROM.
It follows the steps for making a distance measurement, as described in the ISL29501 Firmware Routines (an1724.pdf) documentation.
#include “PmodToF.h”
measured_distance = PmodToF_perform_distance_measurement();
uint8_t PmodToF_ReadCalibsFromEPROM_User();
<none>
uint8_t - The error code:
ERRVAL_SUCCESS | 0 | success |
ERRVAL_EPROM_MAGICNO | 0xFD | wrong magic number when reading data from EEPROM |
ERRVAL_EPROM_CRC | 0xFE | wrong checksum when reading data from EEPROM |
This function reads the user calibration data from EEPROM.
#include “PmodToF.h”
uint8_t ErrCode = PmodToF_ReadCalibsFromEPROM_User();
uint8_t PmodToF_WriteCalibsToEPROM_User();
<none>
uint8_t - The error code:
ERRVAL_SUCCESS | 0 | success |
ERRVAL_EPROM_WRITE | 0xFA | failed to write EEPROM over I2C communication |
ERRVAL_ToF_READ | 0xF6 | failed to read ISL29501 registers over I2C communication |
This function writes calibration data to the user calibration area of EEPROM.
It must be called after changes are made to calibration data(after a manual calibration),in order to save them in the non-volatile memory.
#include “PmodToF.h”
uint8_t ErrCode = PmodToF_WriteCalibsToEPROM_User();
uint8_t PmodToF_RestoreAllCalibsFromEPROM_Factory();
<none>
uint8_t - The error code:
ERRVAL_SUCCESS | 0 | success |
ERRVAL_EPROM_MAGICNO | 0xFD | wrong magic number when reading data from EEPROM |
ERRVAL_EPROM_CRC | 0xFE | wrong checksum when reading data from EEPROM |
ERRVAL_EPROM_WRITE | 0xFA | failed to write EEPROM over I2C communication |
ERRVAL_ToF_READ | 0xF6 | failed to read ISL29501 registers over I2C communication |
This function restores the factory calibration data from EEPROM.
Factory calibration data is read from EEPROM and written into the user calibration area of EEPROM and into the ISL29501 calibration registers.
#include “PmodToF.h”
uint8_t ErrCode = PmodToF_RestoreAllCalibsFromEPROM_Factory();
uint8_t PmodToF_ReadSerialNoFromEPROM(char *pSzSerialNo);
char *pSzSerialNo | pointer to a character string to hold the serial number sequence |
uint8_t - The error code:
ERRVAL_SUCCESS | 0 | success |
ERRVAL_EPROM_MAGICNO | 0xFD | wrong magic number when reading data from EEPROM |
ERRVAL_EPROM_CRC | 0xFE | wrong checksum when reading data from EEPROM |
This function retrieves the Serial Number information (12 characters) from EEPROM .
It is important that the caller of this function allocates enough space in pSzSerialNo.
#include “PmodToF.h”
char SerialNo[13];
uint8_t ErrCode = PmodToF_ReadSerialNoFromEPROM(SerialNo);
For more details see the Serial Number section.
The ISL29501 Module is used by the PmodToF Module for purposes internal to the library (initialization and R/W operations) to communicate over I2C with the ISL29501 chip.
See the ISL29501 - Time of Flight(ToF) integrated circuit section for more details.
The EEPROM Module is used by the PmodToF Module for purposes internal to the library (initialization and R/W operations) to communicate over I2C with the Atmel® AT24C04D memory chip.
See the EEPROM Memory section for more details.
The ISL29501 chip is accessed using digital IO pins exposed in the Pmod ToF connector: SCL (clock bus), SDA (data bus), IRQ(Interrupt) and SS(Sample start).
SCL and SDA are used by the I2C bus and are shared with the Atmel® AT24C04D memory chip. IRQ and SS are GPIO pins.
The ISL29501 chip can be accessed over the I2C protocol at the address: 0x57h.
Every time the board is power cycled and the Zybo Z7-20 board is programmed, the PmodToF_Initialize function is called and programs values imported from EEPROM user area, into the initialization registers.
The Chip Initialization routine is described in ISL29501 Firmware Routines (an1724.pdf) documentation.
These values (see table below) are set by Digilent and the user must be very careful changing them. In this situation the user must modify these values before performing manual calibration.
Please read ISL29501 documentation before proceeding.
Note: Prior to restoring the factory calibration, if the user modified these register values (located in PmodToF_Initialize function), they must be restored to the values specified below, otherwise the measurements won't be correct.
Register address | Data |
---|---|
0x10 | 0x04 |
0x11 | 0x6E |
0x13 | 0x71 |
0x18 | 0x22 |
0x19 | 0x22 |
0x60 | 0x01 |
0x90 | 0x0F |
0x91 | 0xFF |
In order to perform an accurate distance measurement, the Pmod ToF needs to be calibrated. The EEPROM stores two sets of calibration values.
The factory calibration set contains the values for the generic calibration, loaded when the device was manufactured and cannot be altered.
The user calibration set contains the calibration values used to correct the measurements. The user can overwrite the user calibration set upon performing their own calibration. Initially the user calibration set is loaded with the factory calibration values. It can always be restored to factory calibration by calling the PmodToF_RestoreAllCalibsFromEPROM_Factory function .
At the factory, the EEPROM was programmed with a generic calibration profile that helps in performing measurements in a range of 30cm-3m.
If the user wants more precise measurements, a manual calibration can be done by calling the PmodToF_start_calibration function.
The calibration procedure involves three types of calibrations required for the Pmod ToF: magnitude calibration, crosstalk calibration and distance calibration.
For the calibration procedure, the user needs a support setup that holds the Zybo Z7-20 board vertically and at least 40 cm above the ground or table.
The following image is an example of the setup described.
The steps for the calibration procedure are:
Note: Information about the moment when every calibration starts and ends will be displayed in the terminal application over UART.
For more details about the calibration process, see Best Practices for TOF Crosstalk Calibration.
Calibration Registers can be found in the ISL29501 documentation, at SECTION 0.4A: CLOSED LOOP CALIBRATION REGISTERS .
A measurement can be performed by calling PmodToF_perform_distance_measurement function.
The Pmod ToF provides a non-volatile EEPROM memory Atmel® AT24C04D which has 4-Kbits of available space.
The Atmel® AT24C04D memory chip is accessed using digital IO pins exposed in the Pmod ToF connector: SCL (clock bus) and SDA (data bus).
It shares the I2C bus with the ISL29501 chip.
The Atmel® AT24C04D is internally organized as 32 pages of 16 bytes each.
The EEPROM stores two sets of calibration values. The factory calibration set contains the values for the generic calibration performed when the device was manufactured and cannot be altered.
The user calibration set contains the values generated when the user performs their own calibration. Initially the user calibration set is loaded with the factory calibration vales. It can always be restored by calling the PmodToF_RestoreAllCalibsFromEPROM_Factory function.
Section Content | Section Base Address | Size |
---|---|---|
Serial Number | 0x00 | 16 bytes |
User calibration data | 0x10 | 16 bytes |
Factory calibration data | 0x20 | 16 bytes |
Free Memory | 464 bytes |
Accessing the device requires an 8-bit Device Address word.
The memory can be accessed over the I2C protocol at the address: 0x50h and follows the structure below :
Device Address | |||||||
---|---|---|---|---|---|---|---|
Bit7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
1 | 0 | 1 | 0 | 0 | 0 | A8 | R/W |
Bit 0 of the Device Address byte is the Read/Write operation select bit. Bit 1 of the Device Address byte is the most significant bit of the 9-bit memory array word address.
9-bit memory array word address | ||||||||
---|---|---|---|---|---|---|---|---|
Page number | Address in memory page | |||||||
Bit 8 | Bit7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
A8 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
The EEPROM is used to store the following system information:
A total of 3 memory pages (48 bytes) are used, see the address space table from above.
Note that the structure of User Calibration area is identical to the structure of the Factory Calibration area.
For more details about the Calibration process, read more in the Calibration section.
Each of the memory sections mentioned above contains, for safety reasons, additional information:
When reading a section's content from EEPROM, these two security bytes are checked, returning errors when mismatches are found.
Each board has a unique serial number (called SerialNo), built as follows:
Example of a Pmod ToF SerialNo: “210356A76C0C”
This is written in the EEPROM during the manufacturing procedure and shouldn’t be altered by the user.