ST Expansion SW Team / Mbed 2 deprecated VL6180_MB2_4sensors_interrupts

Dependencies:   X_NUCLEO_6180 mbed

Committer:
charlesmn
Date:
Wed Oct 28 16:22:40 2020 +0000
Revision:
0:ed39e596d896
Child:
1:7e59bdb20309
Sample program to control up to 4 ST VL6180 ToF sensors using interrupts to control getting data from sensors. MBed V2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:ed39e596d896 1 /**
charlesmn 0:ed39e596d896 2 ******************************************************************************
charlesmn 0:ed39e596d896 3 * File Name : main.c
charlesmn 0:ed39e596d896 4 * Date : 21/10/2014 09:21:14
charlesmn 0:ed39e596d896 5 * Description : Main program body
charlesmn 0:ed39e596d896 6 ******************************************************************************
charlesmn 0:ed39e596d896 7 *
charlesmn 0:ed39e596d896 8 * COPYRIGHT(c) 2014 STMicroelectronics
charlesmn 0:ed39e596d896 9 *
charlesmn 0:ed39e596d896 10 * Redistribution and use in source and binary forms, with or without modification,
charlesmn 0:ed39e596d896 11 * are permitted provided that the following conditions are met:
charlesmn 0:ed39e596d896 12 * 1. Redistributions of source code must retain the above copyright notice,
charlesmn 0:ed39e596d896 13 * this list of conditions and the following disclaimer.
charlesmn 0:ed39e596d896 14 * 2. Redistributions in binary form must reproduce the above copyright notice,
charlesmn 0:ed39e596d896 15 * this list of conditions and the following disclaimer in the documentation
charlesmn 0:ed39e596d896 16 * and/or other materials provided with the distribution.
charlesmn 0:ed39e596d896 17 * 3. Neither the name of STMicroelectronics nor the names of its contributors
charlesmn 0:ed39e596d896 18 * may be used to endorse or promote products derived from this software
charlesmn 0:ed39e596d896 19 * without specific prior written permission.
charlesmn 0:ed39e596d896 20 *
charlesmn 0:ed39e596d896 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
charlesmn 0:ed39e596d896 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
charlesmn 0:ed39e596d896 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
charlesmn 0:ed39e596d896 24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
charlesmn 0:ed39e596d896 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
charlesmn 0:ed39e596d896 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
charlesmn 0:ed39e596d896 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
charlesmn 0:ed39e596d896 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
charlesmn 0:ed39e596d896 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
charlesmn 0:ed39e596d896 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
charlesmn 0:ed39e596d896 31 *
charlesmn 0:ed39e596d896 32 ******************************************************************************
charlesmn 0:ed39e596d896 33
charlesmn 0:ed39e596d896 34 This program controls VL6180 ToF sensors running on an STM32F401 card with the
charlesmn 0:ed39e596d896 35 VL6180 shield and up to 3 VL6180 satelite boards. This program works in interrupt
charlesmn 0:ed39e596d896 36 mode with all 4 VL6180s operating at the same time.
charlesmn 0:ed39e596d896 37
charlesmn 0:ed39e596d896 38 Because this program is designed to run on MBed V2 the normal RTOS features
charlesmn 0:ed39e596d896 39 such as threads and the signalling between them don't exist. Because of this
charlesmn 0:ed39e596d896 40 the interupt routine signals the main program by setting flags, there is one to
charlesmn 0:ed39e596d896 41 signal that an interupt has been received from each VL6180. The mainloop then polls
charlesmn 0:ed39e596d896 42 these flags to know that an interrupt has occured.
charlesmn 0:ed39e596d896 43
charlesmn 0:ed39e596d896 44 The display is very crude with no storing of the last digits, each digit is written
charlesmn 0:ed39e596d896 45 and then a wait occurs and then the next digit is written. Tjis means that a lot of time is
charlesmn 0:ed39e596d896 46 taken writing tyhe display and any loong period when the display is not serviced
charlesmn 0:ed39e596d896 47 will cause the display to flicker.
charlesmn 0:ed39e596d896 48
charlesmn 0:ed39e596d896 49 In this program access to the VL6180 api is through wrapper functions in
charlesmn 0:ed39e596d896 50 vl6180_class.cpp. It is also possible to access the api directly. E.G both the lines below
charlesmn 0:ed39e596d896 51 do the same thing.
charlesmn 0:ed39e596d896 52
charlesmn 0:ed39e596d896 53 status = VL6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 54 status = sensor->vl6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 55 */
charlesmn 0:ed39e596d896 56
charlesmn 0:ed39e596d896 57 /* Includes ------------------------------------------------------------------*/
charlesmn 0:ed39e596d896 58 #include <stdio.h>
charlesmn 0:ed39e596d896 59
charlesmn 0:ed39e596d896 60 #include "mbed.h"
charlesmn 0:ed39e596d896 61 #include "XNucleo6810.h"
charlesmn 0:ed39e596d896 62 #include <time.h>
charlesmn 0:ed39e596d896 63
charlesmn 0:ed39e596d896 64 #include "spi_interface.h"
charlesmn 0:ed39e596d896 65
charlesmn 0:ed39e596d896 66
charlesmn 0:ed39e596d896 67 /* Private variables ---------------------------------------------------------*/
charlesmn 0:ed39e596d896 68
charlesmn 0:ed39e596d896 69
charlesmn 0:ed39e596d896 70
charlesmn 0:ed39e596d896 71 //VL6180_SINGLE_DEVICE_DRIVER
charlesmn 0:ed39e596d896 72
charlesmn 0:ed39e596d896 73 // i2c tx and rx pins
charlesmn 0:ed39e596d896 74 #define I2C_SDA D14
charlesmn 0:ed39e596d896 75 #define I2C_SCL D15
charlesmn 0:ed39e596d896 76
charlesmn 0:ed39e596d896 77 /* USER CODE BEGIN 0 */
charlesmn 0:ed39e596d896 78 #include <string.h>
charlesmn 0:ed39e596d896 79 #include <stdlib.h>
charlesmn 0:ed39e596d896 80 #include <stdio.h>
charlesmn 0:ed39e596d896 81
charlesmn 0:ed39e596d896 82 #include "vl6180_api.h"
charlesmn 0:ed39e596d896 83 #include "6180a1.h"
charlesmn 0:ed39e596d896 84
charlesmn 0:ed39e596d896 85 #ifdef DEBUG
charlesmn 0:ed39e596d896 86 //TODO
charlesmn 0:ed39e596d896 87 #include "diag/trace.h"
charlesmn 0:ed39e596d896 88 #define debug(msg, ...) trace_printf(msg,__VA_ARGS__)
charlesmn 0:ed39e596d896 89 #define trace_warn(msg,...) trace_printf("W %s %d" msg "\n", __func__, __LINE__, __VA_ARGS__)
charlesmn 0:ed39e596d896 90 #else
charlesmn 0:ed39e596d896 91 #define debug(msg, ...) (void)0
charlesmn 0:ed39e596d896 92 #endif
charlesmn 0:ed39e596d896 93
charlesmn 0:ed39e596d896 94 #define DigitDisplay_ms 1 /* ms each digit is kept on */
charlesmn 0:ed39e596d896 95
charlesmn 0:ed39e596d896 96
charlesmn 0:ed39e596d896 97
charlesmn 0:ed39e596d896 98
charlesmn 0:ed39e596d896 99
charlesmn 0:ed39e596d896 100 static int int_centre_result = 0;
charlesmn 0:ed39e596d896 101 static int int_left_result = 0;
charlesmn 0:ed39e596d896 102 static int int_right_result = 0;
charlesmn 0:ed39e596d896 103 static int int_bottom_result = 0;
charlesmn 0:ed39e596d896 104 static int int_result = 0;
charlesmn 0:ed39e596d896 105
charlesmn 0:ed39e596d896 106
charlesmn 0:ed39e596d896 107 // timing for debug purposes
charlesmn 0:ed39e596d896 108 uint32_t centre_polling_time_ms;
charlesmn 0:ed39e596d896 109 uint32_t centre_start_time_ms;
charlesmn 0:ed39e596d896 110 uint32_t centre_end_time_ms;
charlesmn 0:ed39e596d896 111
charlesmn 0:ed39e596d896 112 void start_sensor(VL6180Dev_t dev ,VL6180 *sensor);
charlesmn 0:ed39e596d896 113 int get_sensor_data(VL6180Dev_t dev ,VL6180 *sensor);
charlesmn 0:ed39e596d896 114
charlesmn 0:ed39e596d896 115
charlesmn 0:ed39e596d896 116 class WaitForMeasurement {
charlesmn 0:ed39e596d896 117 public:
charlesmn 0:ed39e596d896 118
charlesmn 0:ed39e596d896 119
charlesmn 0:ed39e596d896 120 // this class services the interrupts from the ToF sensors.
charlesmn 0:ed39e596d896 121 // There is a limited amount you can do in an interrupt routine; printfs,mutexes break them among other things.
charlesmn 0:ed39e596d896 122 // We keep things simple by only raising a flag so all the real work is done outside the interrupt.
charlesmn 0:ed39e596d896 123 // This is designed around MBED V2 which doesn't have the RTOS features that would make this work nicely e.g. semaphores/queues.
charlesmn 0:ed39e596d896 124 WaitForMeasurement(): _interrupt(A1)
charlesmn 0:ed39e596d896 125 {
charlesmn 0:ed39e596d896 126 }
charlesmn 0:ed39e596d896 127
charlesmn 0:ed39e596d896 128
charlesmn 0:ed39e596d896 129 // constructor - Sensor is not used and can be removed
charlesmn 0:ed39e596d896 130 WaitForMeasurement(PinName pin,MyVL6180Dev_t Dev) : _interrupt(pin) // create the InterruptIn on the pin specified to Counter
charlesmn 0:ed39e596d896 131 {
charlesmn 0:ed39e596d896 132 int_result = 1;
charlesmn 0:ed39e596d896 133 Devlocal = Dev;
charlesmn 0:ed39e596d896 134 _interrupt.rise(callback(this, &WaitForMeasurement::got_interrupt)); // attach increment function of this counter instance
charlesmn 0:ed39e596d896 135
charlesmn 0:ed39e596d896 136 }
charlesmn 0:ed39e596d896 137
charlesmn 0:ed39e596d896 138 void process_right_interrupt()
charlesmn 0:ed39e596d896 139 {
charlesmn 0:ed39e596d896 140 printf("processing right interrupt\n");
charlesmn 0:ed39e596d896 141 }
charlesmn 0:ed39e596d896 142
charlesmn 0:ed39e596d896 143 // function is called every time an interupt is seen. A flag is raised which allows the main routine to service the interupt.
charlesmn 0:ed39e596d896 144 void got_interrupt()
charlesmn 0:ed39e596d896 145 {
charlesmn 0:ed39e596d896 146
charlesmn 0:ed39e596d896 147 _count++;
charlesmn 0:ed39e596d896 148
charlesmn 0:ed39e596d896 149 if (Devlocal.i2c_addr == NEW_SENSOR_CENTRE_ADDRESS)
charlesmn 0:ed39e596d896 150 int_centre_result = 1; //flag to main that interrupt happened
charlesmn 0:ed39e596d896 151 if (Devlocal.i2c_addr == NEW_SENSOR_LEFT_ADDRESS)
charlesmn 0:ed39e596d896 152 int_left_result = 1; //flag to main that interrupt happened
charlesmn 0:ed39e596d896 153 if (Devlocal.i2c_addr == NEW_SENSOR_RIGHT_ADDRESS)
charlesmn 0:ed39e596d896 154 {
charlesmn 0:ed39e596d896 155 int_right_result = 1; //flag to main that interrupt happened
charlesmn 0:ed39e596d896 156 }
charlesmn 0:ed39e596d896 157 if (Devlocal.i2c_addr == NEW_SENSOR_BOTTOM_ADDRESS)
charlesmn 0:ed39e596d896 158 int_bottom_result = 1; //flag to main that interrupt happened
charlesmn 0:ed39e596d896 159 }
charlesmn 0:ed39e596d896 160
charlesmn 0:ed39e596d896 161 //destructor
charlesmn 0:ed39e596d896 162 ~WaitForMeasurement()
charlesmn 0:ed39e596d896 163 {
charlesmn 0:ed39e596d896 164 printf("destruction \n");
charlesmn 0:ed39e596d896 165 }
charlesmn 0:ed39e596d896 166
charlesmn 0:ed39e596d896 167 private:
charlesmn 0:ed39e596d896 168 InterruptIn _interrupt;
charlesmn 0:ed39e596d896 169 volatile int _count;
charlesmn 0:ed39e596d896 170 MyVL6180Dev_t Devlocal;
charlesmn 0:ed39e596d896 171 int status;
charlesmn 0:ed39e596d896 172
charlesmn 0:ed39e596d896 173 };
charlesmn 0:ed39e596d896 174
charlesmn 0:ed39e596d896 175
charlesmn 0:ed39e596d896 176
charlesmn 0:ed39e596d896 177
charlesmn 0:ed39e596d896 178 MyVL6180Dev_t devCentre; //data for each of the vl6180
charlesmn 0:ed39e596d896 179 MyVL6180Dev_t devLeft;
charlesmn 0:ed39e596d896 180 MyVL6180Dev_t devRight;
charlesmn 0:ed39e596d896 181 MyVL6180Dev_t devBottom;
charlesmn 0:ed39e596d896 182 VL6180Dev_t Dev = &devCentre; // the currently used vl6180
charlesmn 0:ed39e596d896 183
charlesmn 0:ed39e596d896 184 volatile int IntrFired=0;
charlesmn 0:ed39e596d896 185
charlesmn 0:ed39e596d896 186 VL6180 *Sensor;
charlesmn 0:ed39e596d896 187
charlesmn 0:ed39e596d896 188 static XNucleo53L1A1 *board=NULL;
charlesmn 0:ed39e596d896 189
charlesmn 0:ed39e596d896 190 Serial pc(SERIAL_TX, SERIAL_RX);
charlesmn 0:ed39e596d896 191
charlesmn 0:ed39e596d896 192 vl6180_DevI2C *dev_I2C = new vl6180_DevI2C(I2C_SDA, I2C_SCL);
charlesmn 0:ed39e596d896 193
charlesmn 0:ed39e596d896 194 //void WaitMilliSec(int ms);
charlesmn 0:ed39e596d896 195
charlesmn 0:ed39e596d896 196 /**
charlesmn 0:ed39e596d896 197 * VL6180x CubeMX F401 i2c porting implementation
charlesmn 0:ed39e596d896 198 */
charlesmn 0:ed39e596d896 199
charlesmn 0:ed39e596d896 200 #define theVL6180Dev 0x52 // what we use as "API device
charlesmn 0:ed39e596d896 201
charlesmn 0:ed39e596d896 202 #define i2c_bus (&hi2c1)
charlesmn 0:ed39e596d896 203 #define def_i2c_time_out 100
charlesmn 0:ed39e596d896 204
charlesmn 0:ed39e596d896 205
charlesmn 0:ed39e596d896 206 void XNUCLEO6180XA1_WaitMilliSec(int n){
charlesmn 0:ed39e596d896 207 wait_ms(n);
charlesmn 0:ed39e596d896 208 }
charlesmn 0:ed39e596d896 209
charlesmn 0:ed39e596d896 210
charlesmn 0:ed39e596d896 211
charlesmn 0:ed39e596d896 212
charlesmn 0:ed39e596d896 213 /**
charlesmn 0:ed39e596d896 214 * DISPLAY public
charlesmn 0:ed39e596d896 215 */
charlesmn 0:ed39e596d896 216 /*************** DISPLAY PUBLIC *********************/
charlesmn 0:ed39e596d896 217 /*************** DISPLAY PRIVATE *********************/
charlesmn 0:ed39e596d896 218 static char DISP_CurString[10];
charlesmn 0:ed39e596d896 219
charlesmn 0:ed39e596d896 220 /**
charlesmn 0:ed39e596d896 221 * call in the main loop
charlesmn 0:ed39e596d896 222 * when running under debugger it enable doing direct vl6180x reg access
charlesmn 0:ed39e596d896 223 * typcilay breaking at entrance
charlesmn 0:ed39e596d896 224 * change the the local index/data and cmd variable to do what needed
charlesmn 0:ed39e596d896 225 * reg_cmd -1 wr byte -2wr word -3 wr dword
charlesmn 0:ed39e596d896 226 * reg_cmd 1 rd byte 2 rd word 3 rd dword
charlesmn 0:ed39e596d896 227 * step to last statement before return and read variable to get rd result exit
charlesmn 0:ed39e596d896 228 */
charlesmn 0:ed39e596d896 229
charlesmn 0:ed39e596d896 230 void debug_stuff(void) {
charlesmn 0:ed39e596d896 231 int reg_cmd = 0;
charlesmn 0:ed39e596d896 232 static uint32_t reg_data;
charlesmn 0:ed39e596d896 233 static uint16_t reg_index;
charlesmn 0:ed39e596d896 234
charlesmn 0:ed39e596d896 235 if (reg_cmd) {
charlesmn 0:ed39e596d896 236 switch (reg_cmd) {
charlesmn 0:ed39e596d896 237 case -1:
charlesmn 0:ed39e596d896 238 VL6180_WrByte(Dev, reg_index, reg_data);
charlesmn 0:ed39e596d896 239 debug("Wr B 0x%X = %d", reg_index, (int)reg_data);
charlesmn 0:ed39e596d896 240 break;
charlesmn 0:ed39e596d896 241 case -2:
charlesmn 0:ed39e596d896 242 VL6180_WrWord(Dev, reg_index, reg_data);
charlesmn 0:ed39e596d896 243 debug("Wr W 0x%X = %d", reg_index,(int) reg_data);
charlesmn 0:ed39e596d896 244 break;
charlesmn 0:ed39e596d896 245
charlesmn 0:ed39e596d896 246 case -3:
charlesmn 0:ed39e596d896 247 VL6180_WrDWord(Dev, reg_index, reg_data);
charlesmn 0:ed39e596d896 248 debug("WrDW 0x%X = %d", reg_index, (int)reg_data);
charlesmn 0:ed39e596d896 249 break;
charlesmn 0:ed39e596d896 250
charlesmn 0:ed39e596d896 251 case 1:
charlesmn 0:ed39e596d896 252 reg_data=0;
charlesmn 0:ed39e596d896 253 VL6180_RdByte(Dev, reg_index, (uint8_t*)&reg_data);
charlesmn 0:ed39e596d896 254 debug("RD B 0x%X = %d", reg_index, (int)reg_data);
charlesmn 0:ed39e596d896 255 break;
charlesmn 0:ed39e596d896 256 case 2:
charlesmn 0:ed39e596d896 257 reg_data=0;
charlesmn 0:ed39e596d896 258 VL6180_RdWord(Dev, reg_index, (uint16_t*)&reg_data);
charlesmn 0:ed39e596d896 259 debug("RD W 0x%X = %d", reg_index, (int)reg_data);
charlesmn 0:ed39e596d896 260 break;
charlesmn 0:ed39e596d896 261
charlesmn 0:ed39e596d896 262 case 3:
charlesmn 0:ed39e596d896 263 VL6180_RdDWord(Dev, reg_index, &reg_data);
charlesmn 0:ed39e596d896 264 debug("RD DW 0x%X = %d", reg_index, (int)reg_data);
charlesmn 0:ed39e596d896 265 break;
charlesmn 0:ed39e596d896 266 default:
charlesmn 0:ed39e596d896 267 debug("Invalid command %d", reg_cmd);
charlesmn 0:ed39e596d896 268 /* nothing to do*/
charlesmn 0:ed39e596d896 269 ;
charlesmn 0:ed39e596d896 270 }
charlesmn 0:ed39e596d896 271 }
charlesmn 0:ed39e596d896 272 }
charlesmn 0:ed39e596d896 273
charlesmn 0:ed39e596d896 274
charlesmn 0:ed39e596d896 275 volatile int VL6180_IsrFired=0;
charlesmn 0:ed39e596d896 276
charlesmn 0:ed39e596d896 277
charlesmn 0:ed39e596d896 278 char buffer[10];
charlesmn 0:ed39e596d896 279
charlesmn 0:ed39e596d896 280
charlesmn 0:ed39e596d896 281 uint32_t TimeStarted; /* various display and mode delay starting time */
charlesmn 0:ed39e596d896 282 VL6180_RangeData_t Range; /* Range measurmeent */
charlesmn 0:ed39e596d896 283 uint16_t range; /* range average distance */
charlesmn 0:ed39e596d896 284
charlesmn 0:ed39e596d896 285
charlesmn 0:ed39e596d896 286 /* USER CODE END 0 */
charlesmn 0:ed39e596d896 287
charlesmn 0:ed39e596d896 288 /* Private function prototypes -----------------------------------------------*/
charlesmn 0:ed39e596d896 289
charlesmn 0:ed39e596d896 290 int main(void)
charlesmn 0:ed39e596d896 291 {
charlesmn 0:ed39e596d896 292
charlesmn 0:ed39e596d896 293 WaitForMeasurement* int1; // the interrupt handler
charlesmn 0:ed39e596d896 294 WaitForMeasurement* int2; // the interrupt handler
charlesmn 0:ed39e596d896 295 WaitForMeasurement* int3; // the interrupt handler
charlesmn 0:ed39e596d896 296 WaitForMeasurement* int4; // the interrupt handler
charlesmn 0:ed39e596d896 297
charlesmn 0:ed39e596d896 298 pc.baud(115200); // baud rate is important as printf statements take a lot of time
charlesmn 0:ed39e596d896 299
charlesmn 0:ed39e596d896 300
charlesmn 0:ed39e596d896 301 //create I2C channel
charlesmn 0:ed39e596d896 302 vl6180_DevI2C *dev_I2C = new vl6180_DevI2C(I2C_SDA, I2C_SCL);
charlesmn 0:ed39e596d896 303
charlesmn 0:ed39e596d896 304 dev_I2C->frequency(400000); //also needs doing in spi_interface.c
charlesmn 0:ed39e596d896 305 devCentre.i2c_addr = theVL6180Dev; // set to default adress for now
charlesmn 0:ed39e596d896 306
charlesmn 0:ed39e596d896 307 int status;
charlesmn 0:ed39e596d896 308
charlesmn 0:ed39e596d896 309 // create instances for the sensors
charlesmn 0:ed39e596d896 310 board = XNucleo53L1A1::instance(dev_I2C, A3, D13, D2 ,A2);
charlesmn 0:ed39e596d896 311 // find the sensors we have and initialise
charlesmn 0:ed39e596d896 312 status = board->init_board();
charlesmn 0:ed39e596d896 313 if (status) {
charlesmn 0:ed39e596d896 314 printf("Failed to init board!\r\n");
charlesmn 0:ed39e596d896 315 return 0;
charlesmn 0:ed39e596d896 316 }
charlesmn 0:ed39e596d896 317
charlesmn 0:ed39e596d896 318
charlesmn 0:ed39e596d896 319 //select centre sensor
charlesmn 0:ed39e596d896 320 if (board->sensor_centre != NULL ) {
charlesmn 0:ed39e596d896 321 devCentre.i2c_addr = NEW_SENSOR_CENTRE_ADDRESS;
charlesmn 0:ed39e596d896 322 Dev = &devCentre;
charlesmn 0:ed39e596d896 323 Sensor=board->sensor_centre;
charlesmn 0:ed39e596d896 324 int1 = new WaitForMeasurement(A3,devCentre); // create a interrupt class for this interrupt pin
charlesmn 0:ed39e596d896 325 start_sensor(Dev ,Sensor);
charlesmn 0:ed39e596d896 326 }
charlesmn 0:ed39e596d896 327
charlesmn 0:ed39e596d896 328 if (board->sensor_left != NULL ) {
charlesmn 0:ed39e596d896 329 devLeft.i2c_addr = NEW_SENSOR_LEFT_ADDRESS;
charlesmn 0:ed39e596d896 330 Dev = &devLeft;
charlesmn 0:ed39e596d896 331 Sensor=board->sensor_left;
charlesmn 0:ed39e596d896 332 int2 = new WaitForMeasurement(D13,devLeft); // create a interrupt class for this interrupt pin
charlesmn 0:ed39e596d896 333 start_sensor(Dev ,Sensor);
charlesmn 0:ed39e596d896 334 }
charlesmn 0:ed39e596d896 335
charlesmn 0:ed39e596d896 336 if (board->sensor_right != NULL ) {
charlesmn 0:ed39e596d896 337 devRight.i2c_addr = NEW_SENSOR_RIGHT_ADDRESS;
charlesmn 0:ed39e596d896 338 Dev = &devRight;
charlesmn 0:ed39e596d896 339 Sensor=board->sensor_right;
charlesmn 0:ed39e596d896 340 int2 = new WaitForMeasurement(D2,devRight); // create a interrupt class for this interrupt pin
charlesmn 0:ed39e596d896 341 start_sensor(Dev ,Sensor);
charlesmn 0:ed39e596d896 342 }
charlesmn 0:ed39e596d896 343
charlesmn 0:ed39e596d896 344 if (board->sensor_bottom != NULL ) {
charlesmn 0:ed39e596d896 345 devBottom.i2c_addr = NEW_SENSOR_BOTTOM_ADDRESS;
charlesmn 0:ed39e596d896 346 Dev = &devBottom;
charlesmn 0:ed39e596d896 347 Sensor=board->sensor_bottom;
charlesmn 0:ed39e596d896 348 int2 = new WaitForMeasurement(A2,devBottom); // create a interrupt class for this interrupt pin
charlesmn 0:ed39e596d896 349 start_sensor(Dev ,Sensor);
charlesmn 0:ed39e596d896 350 }
charlesmn 0:ed39e596d896 351
charlesmn 0:ed39e596d896 352
charlesmn 0:ed39e596d896 353
charlesmn 0:ed39e596d896 354 /* Infinite loop */
charlesmn 0:ed39e596d896 355 while (1) {
charlesmn 0:ed39e596d896 356
charlesmn 0:ed39e596d896 357 if ( int_centre_result == 1 )
charlesmn 0:ed39e596d896 358 {
charlesmn 0:ed39e596d896 359 int_centre_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 360 Dev = &devCentre;
charlesmn 0:ed39e596d896 361 Sensor=board->sensor_centre;
charlesmn 0:ed39e596d896 362
charlesmn 0:ed39e596d896 363 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 364 if ( result != 0)
charlesmn 0:ed39e596d896 365 printf("C %d \n",result);
charlesmn 0:ed39e596d896 366 }
charlesmn 0:ed39e596d896 367
charlesmn 0:ed39e596d896 368 if ( int_left_result == 1 )
charlesmn 0:ed39e596d896 369 {
charlesmn 0:ed39e596d896 370 int_left_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 371 Dev = &devLeft;
charlesmn 0:ed39e596d896 372 Sensor=board->sensor_left;
charlesmn 0:ed39e596d896 373
charlesmn 0:ed39e596d896 374 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 375 if ( result != 0)
charlesmn 0:ed39e596d896 376 printf("L %d \n",result);
charlesmn 0:ed39e596d896 377 }
charlesmn 0:ed39e596d896 378
charlesmn 0:ed39e596d896 379 if ( int_right_result == 1 )
charlesmn 0:ed39e596d896 380 {
charlesmn 0:ed39e596d896 381 int_right_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 382 Dev = &devRight;
charlesmn 0:ed39e596d896 383 Sensor=board->sensor_right;
charlesmn 0:ed39e596d896 384
charlesmn 0:ed39e596d896 385 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 386 if ( result != 0)
charlesmn 0:ed39e596d896 387 printf("R %d \n",result);
charlesmn 0:ed39e596d896 388 }
charlesmn 0:ed39e596d896 389
charlesmn 0:ed39e596d896 390 if ( int_bottom_result == 1 )
charlesmn 0:ed39e596d896 391 {
charlesmn 0:ed39e596d896 392 int_bottom_result = 0; //clear interrupt flag
charlesmn 0:ed39e596d896 393 Dev = &devBottom;
charlesmn 0:ed39e596d896 394 Sensor=board->sensor_bottom;
charlesmn 0:ed39e596d896 395
charlesmn 0:ed39e596d896 396 int result = get_sensor_data(Dev , Sensor);
charlesmn 0:ed39e596d896 397 if ( result != 0)
charlesmn 0:ed39e596d896 398 printf("B %d \n",result);
charlesmn 0:ed39e596d896 399 }
charlesmn 0:ed39e596d896 400
charlesmn 0:ed39e596d896 401
charlesmn 0:ed39e596d896 402 // the display is very simple and requires written to frequently so
charlesmn 0:ed39e596d896 403 // we are writing to the display when we would normally sleep.
charlesmn 0:ed39e596d896 404 // when we are not writing to the display it is blank
charlesmn 0:ed39e596d896 405 {
charlesmn 0:ed39e596d896 406 for (int i = 0 ;i < 10;i++)
charlesmn 0:ed39e596d896 407 { // write to display
charlesmn 0:ed39e596d896 408 XNUCLEO6180XA1_DisplayString(DISP_CurString, DigitDisplay_ms* 5);
charlesmn 0:ed39e596d896 409 }
charlesmn 0:ed39e596d896 410 }
charlesmn 0:ed39e596d896 411
charlesmn 0:ed39e596d896 412 // debug_stuff();
charlesmn 0:ed39e596d896 413 }
charlesmn 0:ed39e596d896 414
charlesmn 0:ed39e596d896 415 }
charlesmn 0:ed39e596d896 416
charlesmn 0:ed39e596d896 417
charlesmn 0:ed39e596d896 418 void start_sensor(VL6180Dev_t dev ,VL6180 *sensor)
charlesmn 0:ed39e596d896 419 {
charlesmn 0:ed39e596d896 420
charlesmn 0:ed39e596d896 421 /* Note that if we waited 1msec we could bypass VL6180_WaitDeviceBooted(&Dev); */
charlesmn 0:ed39e596d896 422 int status;
charlesmn 0:ed39e596d896 423 status = sensor->vl6180_WaitDeviceBooted(dev);
charlesmn 0:ed39e596d896 424 printf("vl6180_WaitDeviceBooted %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 425 status = sensor->vl6180_InitData(dev);
charlesmn 0:ed39e596d896 426 printf("vl6180_InitData %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 427
charlesmn 0:ed39e596d896 428 status = sensor->vl6180_FilterSetState(dev,0); // disbale as not effective in continuous mose
charlesmn 0:ed39e596d896 429 printf("vl6180_FilterSetState %d \n",status);
charlesmn 0:ed39e596d896 430 status = sensor->vl6180_Prepare(dev); // sensor init
charlesmn 0:ed39e596d896 431 printf("vl6180_Prepare %d \n",status);
charlesmn 0:ed39e596d896 432
charlesmn 0:ed39e596d896 433 status = sensor->vl6180_UpscaleSetScaling(dev, 2); // set scaling by 2 to get ranging in range 0 to 400mm
charlesmn 0:ed39e596d896 434 printf("vl6180_UpscaleSetScaling %d \n",status);
charlesmn 0:ed39e596d896 435
charlesmn 0:ed39e596d896 436 // if slow reaction is enough then set a high time like 100 ms (up to 2550 msec)
charlesmn 0:ed39e596d896 437 // if fastest reaction is required then set 0 that will set minimal possible
charlesmn 0:ed39e596d896 438 status = sensor->vl6180_RangeSetInterMeasPeriod(dev, 100);
charlesmn 0:ed39e596d896 439 printf("vl6180_RangeSetInterMeasPeriod %d \n",status);
charlesmn 0:ed39e596d896 440 // set vl6180x gpio1 pin to range interrupt output with high polarity (rising edge)
charlesmn 0:ed39e596d896 441 status = sensor->vl6180_SetupGPIO1(dev, GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT, INTR_POL_HIGH);
charlesmn 0:ed39e596d896 442 printf("vl6180_SetupGPIO1 %d \n",status);
charlesmn 0:ed39e596d896 443 // set range interrupt reporting to low threshold
charlesmn 0:ed39e596d896 444 status = sensor->vl6180_RangeConfigInterrupt(dev, CONFIG_GPIO_INTERRUPT_LEVEL_LOW);
charlesmn 0:ed39e596d896 445 printf("vl6180_RangeConfigInterrupt %d \n",status);
charlesmn 0:ed39e596d896 446 // we don't care of high threshold as we don't use it , group hold is managed externaly
charlesmn 0:ed39e596d896 447 status = sensor->vl6180_RangeSetThresholds(dev, 100, 00, 0);
charlesmn 0:ed39e596d896 448 printf("vl6180_RangeSetThresholds %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 449
charlesmn 0:ed39e596d896 450 status = sensor->vl6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 451 printf("vl6180_ClearInterrupt %d \n",status);
charlesmn 0:ed39e596d896 452
charlesmn 0:ed39e596d896 453 status = sensor->vl6180_RangeStartContinuousMode(dev);
charlesmn 0:ed39e596d896 454 printf("vl6180_RangeStartContinuousMode %d %d\n",status, dev->i2c_addr);
charlesmn 0:ed39e596d896 455 }
charlesmn 0:ed39e596d896 456
charlesmn 0:ed39e596d896 457
charlesmn 0:ed39e596d896 458 int get_sensor_data(VL6180Dev_t dev ,VL6180 *sensor)
charlesmn 0:ed39e596d896 459 {
charlesmn 0:ed39e596d896 460 int status;
charlesmn 0:ed39e596d896 461 int result = 0;
charlesmn 0:ed39e596d896 462 status = sensor->vl6180_RangeGetMeasurement(dev, &Range);
charlesmn 0:ed39e596d896 463 if( status == 0 ){
charlesmn 0:ed39e596d896 464 // Application must check Range.errorStatus before accessing the other data
charlesmn 0:ed39e596d896 465 // If Range.errorStatus is DataNotReady, application knows that it has to wait a bit before getting a new data
charlesmn 0:ed39e596d896 466 // If Range.errorStatus is 0, application knows it is a valid distance
charlesmn 0:ed39e596d896 467 // If Range.errorStatus is not 0, application knows that reported distance is invalid so may take some decisions depending on the errorStatus
charlesmn 0:ed39e596d896 468 if (Range.errorStatus == DataNotReady){
charlesmn 0:ed39e596d896 469 printf("notready \n");
charlesmn 0:ed39e596d896 470
charlesmn 0:ed39e596d896 471 return result;
charlesmn 0:ed39e596d896 472 }
charlesmn 0:ed39e596d896 473
charlesmn 0:ed39e596d896 474 // only display the centre sensors values
charlesmn 0:ed39e596d896 475
charlesmn 0:ed39e596d896 476 if((Range.errorStatus == 0) && (status == 0))
charlesmn 0:ed39e596d896 477 {
charlesmn 0:ed39e596d896 478 // only display the centre sensors values
charlesmn 0:ed39e596d896 479 if ( dev->i2c_addr == NEW_SENSOR_CENTRE_ADDRESS )
charlesmn 0:ed39e596d896 480 {
charlesmn 0:ed39e596d896 481 sprintf(DISP_CurString, " %d", (int)Range.range_mm);
charlesmn 0:ed39e596d896 482 }
charlesmn 0:ed39e596d896 483 result = (int)Range.range_mm;
charlesmn 0:ed39e596d896 484 }
charlesmn 0:ed39e596d896 485 else
charlesmn 0:ed39e596d896 486 {
charlesmn 0:ed39e596d896 487 // only display the centre sensors values
charlesmn 0:ed39e596d896 488 if ( dev->i2c_addr == NEW_SENSOR_CENTRE_ADDRESS )
charlesmn 0:ed39e596d896 489 {
charlesmn 0:ed39e596d896 490 sprintf(DISP_CurString, " %4d", 0);
charlesmn 0:ed39e596d896 491 }
charlesmn 0:ed39e596d896 492 result = 0;
charlesmn 0:ed39e596d896 493 }
charlesmn 0:ed39e596d896 494
charlesmn 0:ed39e596d896 495
charlesmn 0:ed39e596d896 496 /* re-arm next measurement */
charlesmn 0:ed39e596d896 497 sensor->vl6180_ClearInterrupt(dev,INTERRUPT_CLEAR_ERROR|INTERRUPT_CLEAR_RANGING);
charlesmn 0:ed39e596d896 498
charlesmn 0:ed39e596d896 499 } // status != 0
charlesmn 0:ed39e596d896 500 else{
charlesmn 0:ed39e596d896 501 // it is an critical error
charlesmn 0:ed39e596d896 502 // HandleError("critical error on VL6180x_RangeCheckAndGetMeasurement");
charlesmn 0:ed39e596d896 503 }
charlesmn 0:ed39e596d896 504 return result;
charlesmn 0:ed39e596d896 505
charlesmn 0:ed39e596d896 506 }
charlesmn 0:ed39e596d896 507
charlesmn 0:ed39e596d896 508
charlesmn 0:ed39e596d896 509 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/