Files
Loongson_2k0300_SmartCar/vl53l0x_test/vl53l0x_test.c
T

390 lines
11 KiB
C

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <signal.h>
#include "vl53l0x_def.h"
#define MODE_RANGE 0
#define MODE_XTAKCALIB 1
#define MODE_OFFCALIB 2
#define MODE_HELP 3
#define MODE_PARAMETER 6
//******************************** IOCTL definitions
#define VL53L0X_IOCTL_INIT _IO('p', 0x01)
#define VL53L0X_IOCTL_XTALKCALB _IOW('p', 0x02, unsigned int)
#define VL53L0X_IOCTL_OFFCALB _IOW('p', 0x03, unsigned int)
#define VL53L0X_IOCTL_STOP _IO('p', 0x05)
#define VL53L0X_IOCTL_SETXTALK _IOW('p', 0x06, unsigned int)
#define VL53L0X_IOCTL_SETOFFSET _IOW('p', 0x07, int8_t)
#define VL53L0X_IOCTL_GETDATAS _IOR('p', 0x0b, VL53L0X_RangingMeasurementData_t)
#define VL53L0X_IOCTL_PARAMETER _IOWR('p', 0x0d, struct stmvl53l0x_parameter)
//modify the following macro accoring to testing set up
#define OFFSET_TARGET 100//200
#define XTALK_TARGET 600//400
#define NUM_SAMPLES 20//20
typedef enum {
OFFSET_PAR = 0,
XTALKRATE_PAR = 1,
XTALKENABLE_PAR = 2,
GPIOFUNC_PAR = 3,
LOWTHRESH_PAR = 4,
HIGHTHRESH_PAR = 5,
DEVICEMODE_PAR = 6,
INTERMEASUREMENT_PAR = 7,
REFERENCESPADS_PAR = 8,
REFCALIBRATION_PAR = 9,
} parameter_name_e;
/*
* IOCTL parameter structs
*/
struct stmvl53l0x_parameter {
uint32_t is_read; //1: Get 0: Set
parameter_name_e name;
int32_t value;
int32_t value2;
int32_t status;
};
static void help(void)
{
fprintf(stderr,
"Usage: vl53l0x_test [-c] [-h]\n"
" -h for usage\n"
" -c for crosstalk calibration\n"
" -o for offset calibration\n"
" -O <low> <high> for testing interrupt threshold (out mode)\n"
" -L <low> for testing interrupt threshold (low mode)\n"
" -H <high> for testing interrupt threshold (high mode)\n"
" default for ranging\n"
);
exit(1);
}
static int loop_break=0;
void sig_handler(int signum)
{
if(signum == SIGINT)
{
loop_break=1;
}
}
int main(int argc, char *argv[])
{
int fd;
unsigned long data;
VL53L0X_RangingMeasurementData_t range_datas;
struct stmvl53l0x_parameter parameter;
int flags = 0;
int mode = MODE_RANGE;
unsigned int targetDistance=0;
int i = 0;
int rc = 0;
unsigned int low_threshold = 0, high_threshold = 0;
int configure_int_thresholds = 0;
int gpio_functionnality_threshold = 0;
if (signal(SIGINT, sig_handler) == SIG_ERR)
fprintf(stderr, "Can't catch SIGINT");
/* handle (optional) flags first */
while (1+flags < argc && argv[1+flags][0] == '-') {
switch (argv[1+flags][1]) {
case 'c': mode= MODE_XTAKCALIB; break;
case 'h': mode= MODE_HELP; break;
case 'o': mode = MODE_OFFCALIB; break;
case 'O':
if (argc < 4) {
fprintf(stderr, "USAGE: %s <low_threshold_value> <high_threshold_value>\n", argv[0]);
exit(1);
}
low_threshold = atoi(argv[2]);
high_threshold = atoi(argv[3]);
configure_int_thresholds = 1;
fprintf(stderr, "Configuring Low threshold = %u, High threhold = %u\n", low_threshold, high_threshold);
break;
case 'L':
if (argc < 3) {
fprintf(stderr, "USAGE: %s <low_threshold_value> \n", argv[0]);
exit(1);
}
low_threshold = atoi(argv[2]);
configure_int_thresholds = 2;
fprintf(stderr, "Configuring Low threshold = %u, High threhold = %u\n", low_threshold, high_threshold);
break;
case 'H':
if (argc < 3) {
fprintf(stderr, "USAGE: %s <high_threshold_value>\n", argv[0]);
exit(1);
}
high_threshold = atoi(argv[2]);
configure_int_thresholds = 3;
fprintf(stderr, "Configuring Low threshold = %u, High threhold = %u\n", low_threshold, high_threshold);
break;
default:
fprintf(stderr, "Error: Unsupported option "
"\"%s\"!\n", argv[1+flags]);
help();
exit(1);
}
flags++;
}
if (mode == MODE_HELP)
{
help();
exit(0);
}
fd = open("/dev/stmvl53l0x_ranging",O_RDWR | O_SYNC);
if (fd <= 0)
{
fprintf(stderr,"Error open stmvl53l0x_ranging device: %s\n", strerror(errno));
return -1;
}
//make sure it's not started
if (ioctl(fd, VL53L0X_IOCTL_STOP , NULL) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_STOP : %s\n", strerror(errno));
close(fd);
return -1;
}
if (mode == MODE_XTAKCALIB)
{
unsigned int XtalkInt = 0;
uint8_t XtalkEnable = 0;
fprintf(stderr, "xtalk Calibrate place black target at %dmm from glass===\n",XTALK_TARGET);
// to xtalk calibration
targetDistance = XTALK_TARGET;
if (ioctl(fd, VL53L0X_IOCTL_XTALKCALB , &targetDistance) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_XTALKCALB : %s\n", strerror(errno));
close(fd);
return -1;
}
// to get xtalk parameter
parameter.is_read = 1;
parameter.name = XTALKRATE_PAR;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER , &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s\n", strerror(errno));
close(fd);
return -1;
}
XtalkInt = (unsigned int)parameter.value;
parameter.name = XTALKENABLE_PAR;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER , &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s\n", strerror(errno));
close(fd);
return -1;
}
XtalkEnable = (uint8_t)parameter.value;
fprintf(stderr, "VL53L0 Xtalk Calibration get Xtalk Compensation rate in fixed 16 point as %u, enable:%u\n",XtalkInt,XtalkEnable);
for(i = 0; i <= NUM_SAMPLES; i++)
{
usleep(30 *1000); /*100ms*/
// to get all range data
ioctl(fd, VL53L0X_IOCTL_GETDATAS,&range_datas);
}
fprintf(stderr," VL53L0 DMAX calibration Range Data:%d, signalRate_mcps:%d\n",range_datas.RangeMilliMeter, range_datas.SignalRateRtnMegaCps);
// get rangedata of last measurement to avoid incorrect datum from unempty buffer
//to close
close(fd);
return -1;
}
else if (mode == MODE_OFFCALIB)
{
int offset=0;
uint32_t SpadCount=0;
uint8_t IsApertureSpads=0;
uint8_t VhvSettings=0,PhaseCal=0;
// to xtalk calibration
targetDistance = OFFSET_TARGET;
if (ioctl(fd, VL53L0X_IOCTL_OFFCALB , &targetDistance) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_OFFCALB : %s\n", strerror(errno));
close(fd);
return -1;
}
// to get current offset
parameter.is_read = 1;
parameter.name = OFFSET_PAR;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s\n", strerror(errno));
close(fd);
return -1;
}
offset = (int)parameter.value;
fprintf(stderr, "get offset %d micrometer===\n",offset);
parameter.name = REFCALIBRATION_PAR;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s\n", strerror(errno));
close(fd);
return -1;
}
VhvSettings = (uint8_t) parameter.value;
PhaseCal=(uint8_t) parameter.value2;
fprintf(stderr, "get VhvSettings is %u ===\nget PhaseCas is %u ===\n", VhvSettings,PhaseCal);
parameter.name =REFERENCESPADS_PAR;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s\n", strerror(errno));
close(fd);
return -1;
}
SpadCount = (uint32_t)parameter.value;
IsApertureSpads=(uint8_t) parameter.value2;
fprintf(stderr, "get SpadCount is %d ===\nget IsApertureSpads is %u ===\n", SpadCount,IsApertureSpads);
//to close
close(fd);
return -1;
}
else
{
switch(configure_int_thresholds)
{
case 1:
gpio_functionnality_threshold = VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT;
break;
case 2:
gpio_functionnality_threshold = VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW;
break;
case 3:
gpio_functionnality_threshold = VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH;
break;
default:
gpio_functionnality_threshold = VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY;
}
if (configure_int_thresholds) {
parameter.is_read = 0;
parameter.name = DEVICEMODE_PAR;
parameter.value = VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING;
//parameter.value = VL53L0X_DEVICEMODE_CONTINUOUS_RANGING;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER(CONTINOUS_TIMED_RANGING) : %s\n",
strerror(errno));
close(fd);
return -1;
}
parameter.name = GPIOFUNC_PAR;
parameter.value = gpio_functionnality_threshold;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s, low_threshold = %u\n",
strerror(errno),
low_threshold);
close(fd);
return -1;
}
if (configure_int_thresholds != 3)
{
parameter.name = LOWTHRESH_PAR;
parameter.value = low_threshold;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s, low_threshold = %u\n",
strerror(errno),
low_threshold);
close(fd);
return -1;
}
}
if (configure_int_thresholds != 2)
{
parameter.name = HIGHTHRESH_PAR;
parameter.value = high_threshold;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s, high_threshold = %u\n",
strerror(errno),
high_threshold);
close(fd);
return -1;
}
}
}
else {
parameter.name = DEVICEMODE_PAR;
parameter.value = VL53L0X_DEVICEMODE_CONTINUOUS_RANGING;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER(CONTINUOUS_RANGING) : %s\n",
strerror(errno));
close(fd);
return -1;
}
parameter.name = GPIOFUNC_PAR;
parameter.value = gpio_functionnality_threshold;
if (ioctl(fd, VL53L0X_IOCTL_PARAMETER, &parameter) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_PARAMETER : %s, low_threshold = %u\n",
strerror(errno),
low_threshold);
close(fd);
return -1;
}
}
// to init
if (ioctl(fd, VL53L0X_IOCTL_INIT , NULL) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_INIT : %s\n", strerror(errno));
close(fd);
return -1;
}
}
// get data testing
while (1)
{
usleep(30 *1000); /*100ms*/
// to get all range data
rc = ioctl(fd, VL53L0X_IOCTL_GETDATAS,&range_datas);
if (rc) {
fprintf(stderr, "VL53L0X_IOCTL_GETDATAS failed = %d\n", rc);
close(fd);
exit(1);
}
fprintf(stderr,"Range:%4d, Error:%u, SigRate_mcps:%7d, AmbRate_mcps:%7d\r",
range_datas.RangeMilliMeter, range_datas.RangeStatus, range_datas.SignalRateRtnMegaCps, range_datas.AmbientRateRtnMegaCps);
if(loop_break)
break;
}
fprintf(stderr, "\n");
fprintf(stderr, "Stop driver\n");
if (ioctl(fd, VL53L0X_IOCTL_STOP , NULL) < 0) {
fprintf(stderr, "Error: Could not perform VL53L0X_IOCTL_STOP : %s\n", strerror(errno));
close(fd);
return -1;
}
close(fd);
return 0;
}