Contains Ayoub's Ranging and Custom interfaces for the VL53L3CX

Committer:
charlesmn
Date:
Wed Jul 21 14:47:53 2021 +0000
Revision:
1:dae4cb24beec
Parent:
0:c1910e04fc6c
strip out commented out code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:c1910e04fc6c 1 /**
charlesmn 0:c1910e04fc6c 2 ******************************************************************************
charlesmn 0:c1910e04fc6c 3 * @file 53l3a2.c
charlesmn 0:c1910e04fc6c 4 * @author IMG SW Application Team
charlesmn 0:c1910e04fc6c 5 * @brief This file contains the X-NUCLEO-53L3A2 BSP implementation.
charlesmn 0:c1910e04fc6c 6 ******************************************************************************
charlesmn 0:c1910e04fc6c 7 * @attention
charlesmn 0:c1910e04fc6c 8 *
charlesmn 0:c1910e04fc6c 9 * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
charlesmn 0:c1910e04fc6c 10 * All rights reserved.</center></h2>
charlesmn 0:c1910e04fc6c 11 *
charlesmn 0:c1910e04fc6c 12 * This software component is licensed by ST under BSD 3-Clause license,
charlesmn 0:c1910e04fc6c 13 * the "License"; You may not use this file except in compliance with the
charlesmn 0:c1910e04fc6c 14 * License. You may obtain a copy of the License at:
charlesmn 0:c1910e04fc6c 15 * opensource.org/licenses/BSD-3-Clause
charlesmn 0:c1910e04fc6c 16 *
charlesmn 0:c1910e04fc6c 17 ******************************************************************************
charlesmn 0:c1910e04fc6c 18 */
charlesmn 0:c1910e04fc6c 19
charlesmn 0:c1910e04fc6c 20 /* Includes ------------------------------------------------------------------ */
charlesmn 0:c1910e04fc6c 21 #include <stdio.h>
charlesmn 0:c1910e04fc6c 22 #include <stdlib.h>
charlesmn 0:c1910e04fc6c 23 #include <string.h>
charlesmn 0:c1910e04fc6c 24 #include "53l3a2.h"
charlesmn 0:c1910e04fc6c 25 #include "spi_interface.h"
charlesmn 0:c1910e04fc6c 26
charlesmn 0:c1910e04fc6c 27
charlesmn 0:c1910e04fc6c 28 /** @addtogroup BSP
charlesmn 0:c1910e04fc6c 29 * @{
charlesmn 0:c1910e04fc6c 30 */
charlesmn 0:c1910e04fc6c 31
charlesmn 0:c1910e04fc6c 32 /** @addtogroup XNUCLEO_53L3A2
charlesmn 0:c1910e04fc6c 33 * @{
charlesmn 0:c1910e04fc6c 34 */
charlesmn 0:c1910e04fc6c 35
charlesmn 0:c1910e04fc6c 36 /** @addtogroup XNUCLEO_53L3A2_COMMON
charlesmn 0:c1910e04fc6c 37 * @{
charlesmn 0:c1910e04fc6c 38 */
charlesmn 0:c1910e04fc6c 39
charlesmn 0:c1910e04fc6c 40 /* This macro can be overloaded by the user to report error log messages with printf format */
charlesmn 0:c1910e04fc6c 41 #define VL53L3A2_ErrLog(...) (void)0
charlesmn 0:c1910e04fc6c 42
charlesmn 0:c1910e04fc6c 43 /* These macros can be overloaded by the user to enforce i2c sharing in RTOS context */
charlesmn 0:c1910e04fc6c 44 #define VL53L3A2_GetI2cBus(...) (void)0
charlesmn 0:c1910e04fc6c 45 #define VL53L3A2_PutI2cBus(...) (void)0
charlesmn 0:c1910e04fc6c 46
charlesmn 0:c1910e04fc6c 47 #define I2C_EXPANDER_ADDR0 ((int)(0x43*2)) /*!< Expander 0 i2c address[7..0] format */
charlesmn 0:c1910e04fc6c 48 #define I2C_EXPANDER_ADDR1 ((int)(0x42*2)) /*!< Expander 1 i2c address[7..0] format */
charlesmn 0:c1910e04fc6c 49
charlesmn 0:c1910e04fc6c 50 /**
charlesmn 0:c1910e04fc6c 51 * GPIO monitor pin state register
charlesmn 0:c1910e04fc6c 52 * 16 bit register LSB at lowest offset (little endian)
charlesmn 0:c1910e04fc6c 53 */
charlesmn 0:c1910e04fc6c 54 #define GPMR (0x10)
charlesmn 0:c1910e04fc6c 55 /**
charlesmn 0:c1910e04fc6c 56 * STMPE1600 GPIO set pin state register
charlesmn 0:c1910e04fc6c 57 * 16 bit register LSB at lowest offset (little endian)
charlesmn 0:c1910e04fc6c 58 */
charlesmn 0:c1910e04fc6c 59 #define GPSR (0x12)
charlesmn 0:c1910e04fc6c 60 /**
charlesmn 0:c1910e04fc6c 61 * STMPE1600 GPIO set pin direction register
charlesmn 0:c1910e04fc6c 62 * 16 bit register LSB at lowest offset
charlesmn 0:c1910e04fc6c 63 */
charlesmn 0:c1910e04fc6c 64 #define GPDR (0x14)
charlesmn 0:c1910e04fc6c 65
charlesmn 0:c1910e04fc6c 66 /**
charlesmn 0:c1910e04fc6c 67 * @defgroup VL53L3A2_7Segment 7 segment display
charlesmn 0:c1910e04fc6c 68 *
charlesmn 0:c1910e04fc6c 69 * macro use for human readable segment building
charlesmn 0:c1910e04fc6c 70 * @code
charlesmn 0:c1910e04fc6c 71 * --s0--
charlesmn 0:c1910e04fc6c 72 * s s
charlesmn 0:c1910e04fc6c 73 * 5 1
charlesmn 0:c1910e04fc6c 74 * --s6--
charlesmn 0:c1910e04fc6c 75 * s s
charlesmn 0:c1910e04fc6c 76 * 4 2
charlesmn 0:c1910e04fc6c 77 * --s3-- . s7 (dp)
charlesmn 0:c1910e04fc6c 78 * @endcode
charlesmn 0:c1910e04fc6c 79 *
charlesmn 0:c1910e04fc6c 80 * @{
charlesmn 0:c1910e04fc6c 81 */
charlesmn 0:c1910e04fc6c 82 #define DP (1U << 7) /*!< decimal point bit mapping */
charlesmn 0:c1910e04fc6c 83 #define S0 (1U << 3) /*!< segment s0 bit mapping */
charlesmn 0:c1910e04fc6c 84 #define S1 (1U << 5) /*!< segment s1 bit mapping */
charlesmn 0:c1910e04fc6c 85 #define S2 (1U << 6) /*!< segment s2 bit mapping */
charlesmn 0:c1910e04fc6c 86 #define S3 (1U << 4) /*!< segment s3 bit mapping */
charlesmn 0:c1910e04fc6c 87 #define S4 (1U << 0) /*!< segment s4 bit mapping */
charlesmn 0:c1910e04fc6c 88 #define S5 (1U << 1) /*!< segment s5 bit mapping */
charlesmn 0:c1910e04fc6c 89 #define S6 (1U << 2) /*!< segment s6 bit mapping */
charlesmn 0:c1910e04fc6c 90
charlesmn 0:c1910e04fc6c 91 /**
charlesmn 0:c1910e04fc6c 92 * build a character by defining the non lighted segment (not one and no DP)
charlesmn 0:c1910e04fc6c 93 *
charlesmn 0:c1910e04fc6c 94 * @param ... literal sum and or combine of any macro to define any segment #S0 .. #S6
charlesmn 0:c1910e04fc6c 95 *
charlesmn 0:c1910e04fc6c 96 * example '9' is all segment on but S4
charlesmn 0:c1910e04fc6c 97 * @code
charlesmn 0:c1910e04fc6c 98 * ['9']= NOT_7_NO_DP(S4),
charlesmn 0:c1910e04fc6c 99 * @endcode
charlesmn 0:c1910e04fc6c 100 */
charlesmn 0:c1910e04fc6c 101 #define NOT_7_NO_DP( ... ) (uint8_t) ~( __VA_ARGS__ + DP )
charlesmn 0:c1910e04fc6c 102
charlesmn 0:c1910e04fc6c 103 /**
charlesmn 0:c1910e04fc6c 104 * Ascii to 7 segment lookup table
charlesmn 0:c1910e04fc6c 105 *
charlesmn 0:c1910e04fc6c 106 * Most common character are supported and follow http://www.twyman.org.uk/Fonts/
charlesmn 0:c1910e04fc6c 107 * few extra special \@ ^~ ... etc are present for specific demo purpose
charlesmn 0:c1910e04fc6c 108 */
charlesmn 0:c1910e04fc6c 109 static const uint8_t ascii_to_display_lut[256] =
charlesmn 0:c1910e04fc6c 110 {
charlesmn 0:c1910e04fc6c 111 [' '] = 0,
charlesmn 0:c1910e04fc6c 112 ['-'] = S6,
charlesmn 0:c1910e04fc6c 113 ['_'] = S3,
charlesmn 0:c1910e04fc6c 114 ['='] = S3 + S6,
charlesmn 0:c1910e04fc6c 115 ['~'] = S0 + S3 + S6, /* 3 h bar */
charlesmn 0:c1910e04fc6c 116 ['^'] = S0, /* use as top bar */
charlesmn 0:c1910e04fc6c 117
charlesmn 0:c1910e04fc6c 118 ['?'] = NOT_7_NO_DP(S5 + S3 + S2),
charlesmn 0:c1910e04fc6c 119 ['*'] = NOT_7_NO_DP(),
charlesmn 0:c1910e04fc6c 120 ['['] = S0 + S3 + S4 + S5,
charlesmn 0:c1910e04fc6c 121 [']'] = S0 + S3 + S2 + S1,
charlesmn 0:c1910e04fc6c 122 ['@'] = S0 + S3,
charlesmn 0:c1910e04fc6c 123
charlesmn 0:c1910e04fc6c 124 ['0'] = NOT_7_NO_DP(S6),
charlesmn 0:c1910e04fc6c 125 ['1'] = S1 + S2,
charlesmn 0:c1910e04fc6c 126 ['2'] = S0 + S1 + S6 + S4 + S3,
charlesmn 0:c1910e04fc6c 127 ['3'] = NOT_7_NO_DP(S4 + S5),
charlesmn 0:c1910e04fc6c 128 ['4'] = S5 + S1 + S6 + S2,
charlesmn 0:c1910e04fc6c 129 ['5'] = NOT_7_NO_DP(S1 + S4),
charlesmn 0:c1910e04fc6c 130 ['6'] = NOT_7_NO_DP(S1),
charlesmn 0:c1910e04fc6c 131 ['7'] = S0 + S1 + S2,
charlesmn 0:c1910e04fc6c 132 ['8'] = NOT_7_NO_DP(0),
charlesmn 0:c1910e04fc6c 133 ['9'] = NOT_7_NO_DP(S4),
charlesmn 0:c1910e04fc6c 134
charlesmn 0:c1910e04fc6c 135 ['a'] = S2 + S3 + S4 + S6,
charlesmn 0:c1910e04fc6c 136 ['b'] = NOT_7_NO_DP(S0 + S1),
charlesmn 0:c1910e04fc6c 137 ['c'] = S6 + S4 + S3,
charlesmn 0:c1910e04fc6c 138 ['d'] = NOT_7_NO_DP(S0 + S5),
charlesmn 0:c1910e04fc6c 139 ['e'] = NOT_7_NO_DP(S2),
charlesmn 0:c1910e04fc6c 140 ['f'] = S6 + S5 + S4 + S0, /* same as F */
charlesmn 0:c1910e04fc6c 141 ['g'] = NOT_7_NO_DP(S4), /* same as 9 */
charlesmn 0:c1910e04fc6c 142 ['h'] = S6 + S5 + S4 + S2,
charlesmn 0:c1910e04fc6c 143 ['i'] = S4,
charlesmn 0:c1910e04fc6c 144 ['j'] = S1 + S2 + S3 + S4,
charlesmn 0:c1910e04fc6c 145 ['k'] = S6 + S5 + S4 + S2, /* a h */
charlesmn 0:c1910e04fc6c 146 ['l'] = S3 + S4,
charlesmn 0:c1910e04fc6c 147 ['m'] = S0 + S4 + S2, /* same as */
charlesmn 0:c1910e04fc6c 148 ['n'] = S2 + S4 + S6,
charlesmn 0:c1910e04fc6c 149 ['o'] = S6 + S4 + S3 + S2,
charlesmn 0:c1910e04fc6c 150 ['p'] = NOT_7_NO_DP(S3 + S2), /* same as P */
charlesmn 0:c1910e04fc6c 151 ['q'] = S0 + S1 + S2 + S5 + S6,
charlesmn 0:c1910e04fc6c 152 ['r'] = S4 + S6,
charlesmn 0:c1910e04fc6c 153 ['s'] = NOT_7_NO_DP(S1 + S4),
charlesmn 0:c1910e04fc6c 154 ['t'] = NOT_7_NO_DP(S0 + S1 + S2),
charlesmn 0:c1910e04fc6c 155 ['u'] = S4 + S3 + S2 + S5 + S1, /* U */
charlesmn 0:c1910e04fc6c 156 ['v'] = S4 + S3 + S2, /* is u but u use U */
charlesmn 0:c1910e04fc6c 157 ['w'] = S1 + S3 + S5,
charlesmn 0:c1910e04fc6c 158 ['x'] = NOT_7_NO_DP(S0 + S3), /* similar to H */
charlesmn 0:c1910e04fc6c 159 ['y'] = NOT_7_NO_DP(S0 + S4),
charlesmn 0:c1910e04fc6c 160 ['z'] = S0 + S1 + S6 + S4 + S3, /* same as 2 */
charlesmn 0:c1910e04fc6c 161
charlesmn 0:c1910e04fc6c 162 ['A'] = NOT_7_NO_DP(S3),
charlesmn 0:c1910e04fc6c 163 ['B'] = NOT_7_NO_DP(S0 + S1), /* as b */
charlesmn 0:c1910e04fc6c 164 ['C'] = S0 + S3 + S4 + S5, /* same as [ */
charlesmn 0:c1910e04fc6c 165 ['E'] = NOT_7_NO_DP(S1 + S2),
charlesmn 0:c1910e04fc6c 166 ['F'] = S6 + S5 + S4 + S0,
charlesmn 0:c1910e04fc6c 167 ['G'] = NOT_7_NO_DP(S4), /* same as 9 */
charlesmn 0:c1910e04fc6c 168 ['H'] = NOT_7_NO_DP(S0 + S3),
charlesmn 0:c1910e04fc6c 169 ['I'] = S1 + S2,
charlesmn 0:c1910e04fc6c 170 ['J'] = S1 + S2 + S3 + S4,
charlesmn 0:c1910e04fc6c 171 ['K'] = NOT_7_NO_DP(S0 + S3), /* same as H */
charlesmn 0:c1910e04fc6c 172 ['L'] = S3 + S4 + S5,
charlesmn 0:c1910e04fc6c 173 ['M'] = S0 + S4 + S2, /* same as m*/
charlesmn 0:c1910e04fc6c 174 ['N'] = S2 + S4 + S6, /* same as n*/
charlesmn 0:c1910e04fc6c 175 ['O'] = NOT_7_NO_DP(S6),
charlesmn 0:c1910e04fc6c 176 ['P'] = NOT_7_NO_DP(S3 + S2),
charlesmn 0:c1910e04fc6c 177 ['Q'] = NOT_7_NO_DP(S3 + S2),
charlesmn 0:c1910e04fc6c 178 ['R'] = S4 + S6,
charlesmn 0:c1910e04fc6c 179 ['S'] = NOT_7_NO_DP(S1 + S4), /* sasme as 5 */
charlesmn 0:c1910e04fc6c 180 ['T'] = NOT_7_NO_DP(S0 + S1 + S2), /* sasme as t */
charlesmn 0:c1910e04fc6c 181 ['U'] = NOT_7_NO_DP(S6 + S0),
charlesmn 0:c1910e04fc6c 182 ['V'] = S4 + S3 + S2, /* is u but u use U */
charlesmn 0:c1910e04fc6c 183 ['W'] = S1 + S3 + S5,
charlesmn 0:c1910e04fc6c 184 ['X'] = NOT_7_NO_DP(S0 + S3), /* similar to H */
charlesmn 0:c1910e04fc6c 185 ['Y'] = NOT_7_NO_DP(S0 + S4),
charlesmn 0:c1910e04fc6c 186 ['Z'] = S0 + S1 + S6 + S4 + S3, /* same as 2 */
charlesmn 0:c1910e04fc6c 187 };
charlesmn 0:c1910e04fc6c 188
charlesmn 0:c1910e04fc6c 189 #undef S0
charlesmn 0:c1910e04fc6c 190 #undef S1
charlesmn 0:c1910e04fc6c 191 #undef S2
charlesmn 0:c1910e04fc6c 192 #undef S3
charlesmn 0:c1910e04fc6c 193 #undef S4
charlesmn 0:c1910e04fc6c 194 #undef S5
charlesmn 0:c1910e04fc6c 195 #undef S6
charlesmn 0:c1910e04fc6c 196 #undef DP
charlesmn 0:c1910e04fc6c 197 /**
charlesmn 0:c1910e04fc6c 198 * @}
charlesmn 0:c1910e04fc6c 199 */
charlesmn 0:c1910e04fc6c 200
charlesmn 1:dae4cb24beec 201
charlesmn 0:c1910e04fc6c 202 static uint32_t InitCounter = 0;
charlesmn 0:c1910e04fc6c 203
charlesmn 0:c1910e04fc6c 204 /* cache the full set of expanded GPIO values to avoid i2c reading */
charlesmn 0:c1910e04fc6c 205 static union CurIOVal_u
charlesmn 0:c1910e04fc6c 206 {
charlesmn 0:c1910e04fc6c 207 uint8_t bytes[4]; /*!< 4 bytes array i/o view */
charlesmn 0:c1910e04fc6c 208 uint32_t u32; /*!< single dword i/o view */
charlesmn 0:c1910e04fc6c 209 } CurIOVal; /* cache the extended IO values */
charlesmn 1:dae4cb24beec 210
charlesmn 0:c1910e04fc6c 211
charlesmn 0:c1910e04fc6c 212 /** @defgroup XNUCLEO_53L3A2_COMMON_Private_Functions_Prototypes Private Functions Prototypes
charlesmn 0:c1910e04fc6c 213 * @{
charlesmn 0:c1910e04fc6c 214 */
charlesmn 0:c1910e04fc6c 215 static void _I2cFailRecover(void);
charlesmn 0:c1910e04fc6c 216 static int32_t _ExpanderRd(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data);
charlesmn 0:c1910e04fc6c 217 static int32_t _ExpanderWR(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data);
charlesmn 0:c1910e04fc6c 218 static int32_t _ExpandersSetAllIO(void);
charlesmn 1:dae4cb24beec 219
charlesmn 0:c1910e04fc6c 220
charlesmn 0:c1910e04fc6c 221 /**
charlesmn 0:c1910e04fc6c 222 * @brief Initialize X-NUCLEO-53L3A2 STM32 expansion board
charlesmn 0:c1910e04fc6c 223 * @note All devices XSDN are asserted and display is turned off
charlesmn 0:c1910e04fc6c 224 * @return 0 on success
charlesmn 0:c1910e04fc6c 225 */
charlesmn 0:c1910e04fc6c 226 int32_t VL53L3A2_Init(void)
charlesmn 0:c1910e04fc6c 227 {
charlesmn 0:c1910e04fc6c 228 int32_t status = 0;
charlesmn 0:c1910e04fc6c 229 uint8_t ExpanderData[2];
charlesmn 0:c1910e04fc6c 230
charlesmn 0:c1910e04fc6c 231 if (InitCounter++ == 0U)
charlesmn 0:c1910e04fc6c 232 {
charlesmn 0:c1910e04fc6c 233 CurIOVal.u32 = 0x0U;
charlesmn 0:c1910e04fc6c 234
charlesmn 0:c1910e04fc6c 235 // setup expander i/o direction all output but exp1 bit 14
charlesmn 0:c1910e04fc6c 236 ExpanderData[0] = 0xFFU;
charlesmn 0:c1910e04fc6c 237 ExpanderData[1] = 0xFFU;
charlesmn 0:c1910e04fc6c 238
charlesmn 0:c1910e04fc6c 239 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPDR, ExpanderData, 2);
charlesmn 0:c1910e04fc6c 240
charlesmn 0:c1910e04fc6c 241 if (status)
charlesmn 0:c1910e04fc6c 242 {
charlesmn 0:c1910e04fc6c 243 VL53L3A2_ErrLog("Set Expander @0x%02X DR", I2C_EXPANDER_ADDR0);
charlesmn 0:c1910e04fc6c 244 goto done_err;
charlesmn 0:c1910e04fc6c 245 }
charlesmn 0:c1910e04fc6c 246
charlesmn 0:c1910e04fc6c 247 ExpanderData[0] = 0xFFU;
charlesmn 0:c1910e04fc6c 248 ExpanderData[1] = 0xBFU; /* all but bit 14-15 that is pb1 and xhurt */
charlesmn 0:c1910e04fc6c 249 status = _ExpanderWR(I2C_EXPANDER_ADDR1, GPDR, ExpanderData, 2);
charlesmn 0:c1910e04fc6c 250
charlesmn 0:c1910e04fc6c 251 if (status)
charlesmn 0:c1910e04fc6c 252 {
charlesmn 0:c1910e04fc6c 253 VL53L3A2_ErrLog("Set Expander @0x%02X DR", I2C_EXPANDER_ADDR1);
charlesmn 0:c1910e04fc6c 254 goto done_err;
charlesmn 0:c1910e04fc6c 255 }
charlesmn 0:c1910e04fc6c 256
charlesmn 0:c1910e04fc6c 257 /* shut down all segment and all device */
charlesmn 0:c1910e04fc6c 258 CurIOVal.u32 = 0x7FU + (0x7FU << 7) + (0x7FU << 16) + (0x7FU << (16 + 7));
charlesmn 0:c1910e04fc6c 259
charlesmn 0:c1910e04fc6c 260 CurIOVal.bytes[3] = 0x0f;
charlesmn 0:c1910e04fc6c 261 CurIOVal.bytes[1] = 0x0f;
charlesmn 0:c1910e04fc6c 262 status = _ExpandersSetAllIO();
charlesmn 0:c1910e04fc6c 263
charlesmn 0:c1910e04fc6c 264 if (status)
charlesmn 0:c1910e04fc6c 265 {
charlesmn 0:c1910e04fc6c 266 VL53L3A2_ErrLog("Set initial i/o ");
charlesmn 0:c1910e04fc6c 267 }
charlesmn 0:c1910e04fc6c 268 }
charlesmn 0:c1910e04fc6c 269
charlesmn 0:c1910e04fc6c 270 done_err:
charlesmn 0:c1910e04fc6c 271 return status;
charlesmn 0:c1910e04fc6c 272 }
charlesmn 0:c1910e04fc6c 273
charlesmn 0:c1910e04fc6c 274 /**
charlesmn 0:c1910e04fc6c 275 * @brief De-initialize X-NUCLEO-53L3A2 STM32 expansion board
charlesmn 0:c1910e04fc6c 276 * @return 0 on success
charlesmn 0:c1910e04fc6c 277 */
charlesmn 0:c1910e04fc6c 278 int32_t VL53L3A2_DeInit(void)
charlesmn 0:c1910e04fc6c 279 {
charlesmn 0:c1910e04fc6c 280 int32_t status = 0;
charlesmn 0:c1910e04fc6c 281
charlesmn 0:c1910e04fc6c 282 if (InitCounter > 0U)
charlesmn 0:c1910e04fc6c 283 {
charlesmn 0:c1910e04fc6c 284 if (--InitCounter == 0U)
charlesmn 0:c1910e04fc6c 285 {
charlesmn 0:c1910e04fc6c 286 // status = VL53L3A2_I2C_DeInit();
charlesmn 0:c1910e04fc6c 287 }
charlesmn 0:c1910e04fc6c 288 }
charlesmn 0:c1910e04fc6c 289
charlesmn 0:c1910e04fc6c 290 return status;
charlesmn 0:c1910e04fc6c 291 }
charlesmn 0:c1910e04fc6c 292
charlesmn 0:c1910e04fc6c 293 /**
charlesmn 0:c1910e04fc6c 294 * @brief Set Reset (XSDN) state of a given "id" device
charlesmn 0:c1910e04fc6c 295 * @param DevNo The device number, use @ref VL53L3A2_dev_e.
charlesmn 0:c1910e04fc6c 296 * @param state State of the device reset (xsdn) pin @warning reset pin is active low
charlesmn 0:c1910e04fc6c 297 * i.e. xshut is raised to enable device
charlesmn 0:c1910e04fc6c 298 * @return 0 on success
charlesmn 0:c1910e04fc6c 299 */
charlesmn 0:c1910e04fc6c 300
charlesmn 1:dae4cb24beec 301 // VL53L3A2_DEV_LEFT = 0, /* !< left satellite device P21 header */
charlesmn 1:dae4cb24beec 302 // VL53L3A2_DEV_CENTER = 1, /* !< center (built-in) device */
charlesmn 0:c1910e04fc6c 303 // VL53L3A2_DEV_RIGHT = 2 /* !< Right satellite device P22 header */
charlesmn 0:c1910e04fc6c 304 int32_t VL53L3A2_ResetId(uint8_t DevNo, uint8_t state)
charlesmn 0:c1910e04fc6c 305 {
charlesmn 0:c1910e04fc6c 306 int32_t status;
charlesmn 0:c1910e04fc6c 307 printf("VL53L3A2_ResetId %d %d %d %d \n",DevNo,state,CurIOVal.bytes[1],CurIOVal.bytes[3]);
charlesmn 0:c1910e04fc6c 308 switch (DevNo)
charlesmn 0:c1910e04fc6c 309 {
charlesmn 0:c1910e04fc6c 310 case VL53L3A2_DEV_CENTER :
charlesmn 0:c1910e04fc6c 311 CurIOVal.bytes[3] &= ~0x80U; /* bit 15 expander 1 => byte #3 */
charlesmn 0:c1910e04fc6c 312
charlesmn 0:c1910e04fc6c 313 if (state)
charlesmn 0:c1910e04fc6c 314 {
charlesmn 0:c1910e04fc6c 315 CurIOVal.bytes[3] |= 0x80U; /* bit 15 expander 1 => byte #3 */
charlesmn 0:c1910e04fc6c 316 }
charlesmn 0:c1910e04fc6c 317
charlesmn 0:c1910e04fc6c 318 status = _ExpanderWR(I2C_EXPANDER_ADDR1, GPSR , &CurIOVal.bytes[3], 1);
charlesmn 0:c1910e04fc6c 319 break;
charlesmn 0:c1910e04fc6c 320
charlesmn 0:c1910e04fc6c 321 case VL53L3A2_DEV_LEFT :
charlesmn 0:c1910e04fc6c 322 printf("VL53L3A2_DEV_LEFT \n");
charlesmn 0:c1910e04fc6c 323 CurIOVal.bytes[1] &= ~0x40U; /* bit 14 expander 0 => byte #1*/
charlesmn 0:c1910e04fc6c 324
charlesmn 0:c1910e04fc6c 325 if (state)
charlesmn 0:c1910e04fc6c 326 {
charlesmn 0:c1910e04fc6c 327 CurIOVal.bytes[1] |= 0x40U; /* bit 14 expander 0 => byte #1*/
charlesmn 0:c1910e04fc6c 328 }
charlesmn 0:c1910e04fc6c 329
charlesmn 0:c1910e04fc6c 330 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPSR , &CurIOVal.bytes[1], 1);
charlesmn 0:c1910e04fc6c 331 break;
charlesmn 0:c1910e04fc6c 332
charlesmn 0:c1910e04fc6c 333 case VL53L3A2_DEV_RIGHT :
charlesmn 0:c1910e04fc6c 334 CurIOVal.bytes[1] &= ~0x80U; /* bit 15 expander 0 => byte #1 */
charlesmn 0:c1910e04fc6c 335
charlesmn 0:c1910e04fc6c 336 if (state)
charlesmn 0:c1910e04fc6c 337 {
charlesmn 0:c1910e04fc6c 338 CurIOVal.bytes[1] |= 0x80U; /* bit 15 expander 0 => byte #1*/
charlesmn 0:c1910e04fc6c 339 }
charlesmn 0:c1910e04fc6c 340
charlesmn 0:c1910e04fc6c 341 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPSR , &CurIOVal.bytes[1], 1);
charlesmn 0:c1910e04fc6c 342 break;
charlesmn 0:c1910e04fc6c 343
charlesmn 0:c1910e04fc6c 344 default:
charlesmn 0:c1910e04fc6c 345 VL53L3A2_ErrLog("Invalid DevNo %d", DevNo);
charlesmn 0:c1910e04fc6c 346 status = -1;
charlesmn 0:c1910e04fc6c 347 goto done;
charlesmn 0:c1910e04fc6c 348 }
charlesmn 0:c1910e04fc6c 349
charlesmn 0:c1910e04fc6c 350 /* error with valid id */
charlesmn 0:c1910e04fc6c 351 if (status)
charlesmn 0:c1910e04fc6c 352 {
charlesmn 0:c1910e04fc6c 353 VL53L3A2_ErrLog("expander i/o error for DevNo %d state %d ", DevNo, state);
charlesmn 0:c1910e04fc6c 354 }
charlesmn 0:c1910e04fc6c 355
charlesmn 0:c1910e04fc6c 356 done:
charlesmn 0:c1910e04fc6c 357 printf("VL53L3A2_ResetId %d %d %d %d\n",status,DevNo,CurIOVal.bytes[1],CurIOVal.bytes[3]);
charlesmn 0:c1910e04fc6c 358 return status;
charlesmn 0:c1910e04fc6c 359 }
charlesmn 0:c1910e04fc6c 360
charlesmn 0:c1910e04fc6c 361 /**
charlesmn 0:c1910e04fc6c 362 * @brief Set the 7 segments display
charlesmn 0:c1910e04fc6c 363 * @param str String to set on display
charlesmn 0:c1910e04fc6c 364 * @warning When string is less than 4 digits, display is left-justified and lower digits are blanked.
charlesmn 0:c1910e04fc6c 365 * To display a 2 digits value, left justified on the 4 digits, use "%4d" formating
charlesmn 0:c1910e04fc6c 366 * @warning When more than 4 char are present only first 4 are displayed
charlesmn 0:c1910e04fc6c 367 * @note Characters that do not have 7 segment font matching in ascii_to_display_lut are left blank
charlesmn 0:c1910e04fc6c 368 * @return 0 on success
charlesmn 0:c1910e04fc6c 369 */
charlesmn 0:c1910e04fc6c 370 int32_t VL53L3A2_SetDisplayString(const char *str)
charlesmn 0:c1910e04fc6c 371 {
charlesmn 0:c1910e04fc6c 372 int32_t status;
charlesmn 0:c1910e04fc6c 373 uint32_t BitPos;
charlesmn 0:c1910e04fc6c 374 uint32_t i;
charlesmn 0:c1910e04fc6c 375 uint32_t Segments;
charlesmn 0:c1910e04fc6c 376
charlesmn 0:c1910e04fc6c 377 /* lookup table for for digit to bit position in @a CurIOVal u32 */
charlesmn 0:c1910e04fc6c 378 uint8_t DisplayBitPos[4] = {0, 7, 16, 16 + 7};
charlesmn 0:c1910e04fc6c 379
charlesmn 0:c1910e04fc6c 380 for (i = 0; (i < 4U) && (str[i] != 0U); i++)
charlesmn 0:c1910e04fc6c 381 {
charlesmn 0:c1910e04fc6c 382 Segments = (uint32_t)ascii_to_display_lut[(uint8_t)str[i]];
charlesmn 0:c1910e04fc6c 383 Segments = (~Segments) & 0x7FU;
charlesmn 0:c1910e04fc6c 384 BitPos = DisplayBitPos[i];
charlesmn 0:c1910e04fc6c 385 CurIOVal.u32 &= ~(0x7FU << BitPos);
charlesmn 0:c1910e04fc6c 386 CurIOVal.u32 |= Segments << BitPos;
charlesmn 0:c1910e04fc6c 387 }
charlesmn 0:c1910e04fc6c 388
charlesmn 0:c1910e04fc6c 389 /* clear unused digit */
charlesmn 0:c1910e04fc6c 390 for (; i < 4U; i++)
charlesmn 0:c1910e04fc6c 391 {
charlesmn 0:c1910e04fc6c 392 BitPos = DisplayBitPos[i];
charlesmn 0:c1910e04fc6c 393 CurIOVal.u32 |= 0x7FU << BitPos;
charlesmn 0:c1910e04fc6c 394 }
charlesmn 0:c1910e04fc6c 395
charlesmn 0:c1910e04fc6c 396 status = _ExpandersSetAllIO();
charlesmn 0:c1910e04fc6c 397
charlesmn 0:c1910e04fc6c 398 if (status)
charlesmn 0:c1910e04fc6c 399 {
charlesmn 0:c1910e04fc6c 400 VL53L3A2_ErrLog("Set i/o");
charlesmn 0:c1910e04fc6c 401 }
charlesmn 0:c1910e04fc6c 402
charlesmn 0:c1910e04fc6c 403 return status;
charlesmn 0:c1910e04fc6c 404 }
charlesmn 0:c1910e04fc6c 405
charlesmn 0:c1910e04fc6c 406 /** @defgroup XNUCLEO_53L3A2_COMMON_Private_Functions Private Functions
charlesmn 0:c1910e04fc6c 407 * @{
charlesmn 0:c1910e04fc6c 408 */
charlesmn 0:c1910e04fc6c 409
charlesmn 0:c1910e04fc6c 410 /**
charlesmn 0:c1910e04fc6c 411 * @brief Expansion board i2c bus recovery
charlesmn 0:c1910e04fc6c 412 * We may get reset in middle of an i2c access (h/w reset button, debug or f/w load)
charlesmn 0:c1910e04fc6c 413 * hence some agent on bus may be in middle of a transaction and can create issue or even prevent starting (SDA is low)
charlesmn 0:c1910e04fc6c 414 * this routine does use gpio to manipulate and recover i2c bus line in all cases.
charlesmn 0:c1910e04fc6c 415 */
charlesmn 0:c1910e04fc6c 416 static void _I2cFailRecover()
charlesmn 0:c1910e04fc6c 417 {
charlesmn 0:c1910e04fc6c 418 printf("_I2cFailRecover \n");
charlesmn 0:c1910e04fc6c 419 #if 0
charlesmn 0:c1910e04fc6c 420 GPIO_InitTypeDef GPIO_InitStruct;
charlesmn 0:c1910e04fc6c 421 uint8_t i, nRetry = 0;
charlesmn 0:c1910e04fc6c 422
charlesmn 0:c1910e04fc6c 423 /* We can't assume bus state based on SDA and SCL state (we may be in a data or NAK bit so SCL=SDA=1)
charlesmn 0:c1910e04fc6c 424 * by setting SDA high and toggling SCL at least 10 time we ensure whatever agent and state
charlesmn 0:c1910e04fc6c 425 * all agent should end up seeing a "stop" and bus get back to an known idle i2c bus state */
charlesmn 0:c1910e04fc6c 426
charlesmn 0:c1910e04fc6c 427 /* Enable I/O */
charlesmn 0:c1910e04fc6c 428 __GPIOB_CLK_ENABLE();
charlesmn 0:c1910e04fc6c 429 HAL_GPIO_WritePin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SCL_GPIO_PIN, GPIO_PIN_SET);
charlesmn 0:c1910e04fc6c 430 HAL_GPIO_WritePin(VL53L3A2_I2C_SDA_GPIO_PORT, VL53L3A2_I2C_SDA_GPIO_PIN, GPIO_PIN_SET);
charlesmn 0:c1910e04fc6c 431 GPIO_InitStruct.Pin = VL53L3A2_I2C_SCL_GPIO_PIN | VL53L3A2_I2C_SDA_GPIO_PIN ;
charlesmn 0:c1910e04fc6c 432 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
charlesmn 0:c1910e04fc6c 433 GPIO_InitStruct.Pull = GPIO_PULLUP;
charlesmn 0:c1910e04fc6c 434 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
charlesmn 0:c1910e04fc6c 435
charlesmn 0:c1910e04fc6c 436 /* we could do this faster by not using HAL delay 1ms for clk timing */
charlesmn 0:c1910e04fc6c 437 do
charlesmn 0:c1910e04fc6c 438 {
charlesmn 0:c1910e04fc6c 439 for (i = 0; i < 10U; i++)
charlesmn 0:c1910e04fc6c 440 {
charlesmn 0:c1910e04fc6c 441 HAL_GPIO_WritePin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SCL_GPIO_PIN, GPIO_PIN_RESET);
charlesmn 0:c1910e04fc6c 442 HAL_Delay(1);
charlesmn 0:c1910e04fc6c 443 HAL_GPIO_WritePin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SCL_GPIO_PIN, GPIO_PIN_SET);
charlesmn 0:c1910e04fc6c 444 HAL_Delay(1);
charlesmn 0:c1910e04fc6c 445 }
charlesmn 0:c1910e04fc6c 446
charlesmn 0:c1910e04fc6c 447 } while ((HAL_GPIO_ReadPin(VL53L3A2_I2C_SDA_GPIO_PORT, VL53L3A2_I2C_SDA_GPIO_PIN) == 0) && (nRetry++ < 7U));
charlesmn 0:c1910e04fc6c 448
charlesmn 0:c1910e04fc6c 449 if (HAL_GPIO_ReadPin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SDA_GPIO_PIN) == 0)
charlesmn 0:c1910e04fc6c 450 {
charlesmn 0:c1910e04fc6c 451 /* We are still in a bad i2c state, block the program here
charlesmn 0:c1910e04fc6c 452 * A hardware reset is necessary */
charlesmn 0:c1910e04fc6c 453 while (1);
charlesmn 0:c1910e04fc6c 454 }
charlesmn 0:c1910e04fc6c 455 #endif
charlesmn 0:c1910e04fc6c 456 }
charlesmn 0:c1910e04fc6c 457
charlesmn 0:c1910e04fc6c 458 /**
charlesmn 0:c1910e04fc6c 459 * @brief Set all i2c expended gpio in one go
charlesmn 0:c1910e04fc6c 460 * @return i/o operation status
charlesmn 0:c1910e04fc6c 461 */
charlesmn 0:c1910e04fc6c 462 static int32_t _ExpandersSetAllIO(void)
charlesmn 0:c1910e04fc6c 463 {
charlesmn 0:c1910e04fc6c 464 int32_t status;
charlesmn 0:c1910e04fc6c 465
charlesmn 0:c1910e04fc6c 466 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPSR, &CurIOVal.bytes[0], 2);
charlesmn 0:c1910e04fc6c 467
charlesmn 0:c1910e04fc6c 468 if (status)
charlesmn 0:c1910e04fc6c 469 {
charlesmn 0:c1910e04fc6c 470 goto done_err;
charlesmn 0:c1910e04fc6c 471 }
charlesmn 0:c1910e04fc6c 472
charlesmn 0:c1910e04fc6c 473 status = _ExpanderWR(I2C_EXPANDER_ADDR1, GPSR, &CurIOVal.bytes[2], 2);
charlesmn 0:c1910e04fc6c 474
charlesmn 0:c1910e04fc6c 475 done_err:
charlesmn 0:c1910e04fc6c 476 printf("_ExpandersSetAllIO end \n");
charlesmn 0:c1910e04fc6c 477 return status;
charlesmn 0:c1910e04fc6c 478 }
charlesmn 0:c1910e04fc6c 479
charlesmn 0:c1910e04fc6c 480 /**
charlesmn 0:c1910e04fc6c 481 * @brief STMPE1600 i2c Expander register read
charlesmn 0:c1910e04fc6c 482 * @param I2cExpAddr Expander address
charlesmn 0:c1910e04fc6c 483 * @param index register index
charlesmn 0:c1910e04fc6c 484 * @param data read data buffer
charlesmn 0:c1910e04fc6c 485 * @param n_data number of byte to read
charlesmn 0:c1910e04fc6c 486 * @return of if ok else i2c I/O operation status
charlesmn 0:c1910e04fc6c 487 */
charlesmn 0:c1910e04fc6c 488 static int32_t _ExpanderRd(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data)
charlesmn 0:c1910e04fc6c 489 {
charlesmn 0:c1910e04fc6c 490 int32_t status;
charlesmn 0:c1910e04fc6c 491 uint8_t RegAddr;
charlesmn 0:c1910e04fc6c 492
charlesmn 0:c1910e04fc6c 493 RegAddr = index;
charlesmn 0:c1910e04fc6c 494
charlesmn 1:dae4cb24beec 495 status = v53l1x_i2c_read_if(data,I2cExpAddr, index,2);
charlesmn 0:c1910e04fc6c 496
charlesmn 0:c1910e04fc6c 497 return status;
charlesmn 0:c1910e04fc6c 498 }
charlesmn 0:c1910e04fc6c 499
charlesmn 0:c1910e04fc6c 500 /**
charlesmn 0:c1910e04fc6c 501 * @brief STMPE1600 i2c Expander register write
charlesmn 0:c1910e04fc6c 502 * @param I2cExpAddr Expander address
charlesmn 0:c1910e04fc6c 503 * @param index register index
charlesmn 0:c1910e04fc6c 504 * @param data data buffer
charlesmn 0:c1910e04fc6c 505 * @param n_data number of byte to write
charlesmn 0:c1910e04fc6c 506 * @return of if ok else i2c I/O operation status
charlesmn 0:c1910e04fc6c 507 */
charlesmn 0:c1910e04fc6c 508 static int32_t _ExpanderWR(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data)
charlesmn 0:c1910e04fc6c 509 {
charlesmn 0:c1910e04fc6c 510 int32_t status = 0;
charlesmn 0:c1910e04fc6c 511 uint8_t RegAddr[0x10];
charlesmn 0:c1910e04fc6c 512 uint8_t i;
charlesmn 0:c1910e04fc6c 513 for (i = 0 ; i < 0x10 ; i++)
charlesmn 0:c1910e04fc6c 514 {
charlesmn 0:c1910e04fc6c 515 RegAddr[i] =0;
charlesmn 0:c1910e04fc6c 516 }
charlesmn 0:c1910e04fc6c 517 // build packet to send
charlesmn 0:c1910e04fc6c 518 if (n_data == 1)
charlesmn 0:c1910e04fc6c 519 {
charlesmn 0:c1910e04fc6c 520 RegAddr[0] = (uint8_t)index; // the register in the chip we are sending to
charlesmn 0:c1910e04fc6c 521 RegAddr[1]= 255; // the lower byte of the control word. We just set to FF
charlesmn 0:c1910e04fc6c 522 RegAddr[2]= data[0]; //the byte that controls the xshut pins
charlesmn 0:c1910e04fc6c 523 }
charlesmn 0:c1910e04fc6c 524 else{
charlesmn 0:c1910e04fc6c 525 RegAddr[0] = (uint8_t)index; // the register in the chip we are sending to
charlesmn 0:c1910e04fc6c 526 RegAddr[1]=data[0]; // the lower byte of the control word. We just set to FF
charlesmn 0:c1910e04fc6c 527 RegAddr[2]=data[1]; //the byte that controls the xshut pins
charlesmn 0:c1910e04fc6c 528 }
charlesmn 0:c1910e04fc6c 529
charlesmn 0:c1910e04fc6c 530 // printf("_ExpanderWR %d %d %d \n",data[0],data[1],n_data);
charlesmn 0:c1910e04fc6c 531 // printf("_ExpanderWR %d %d %d %d %d %d %d\n",I2cExpAddr,index,RegAddr[0],RegAddr[1],RegAddr[2],status,n_data+2);
charlesmn 0:c1910e04fc6c 532 status = v53l1x_i2c_write_direct(RegAddr,I2cExpAddr,n_data + 2);
charlesmn 0:c1910e04fc6c 533
charlesmn 0:c1910e04fc6c 534
charlesmn 0:c1910e04fc6c 535
charlesmn 0:c1910e04fc6c 536
charlesmn 0:c1910e04fc6c 537
charlesmn 0:c1910e04fc6c 538 return (status);
charlesmn 0:c1910e04fc6c 539 }
charlesmn 0:c1910e04fc6c 540
charlesmn 0:c1910e04fc6c 541
charlesmn 0:c1910e04fc6c 542 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
charlesmn 0:c1910e04fc6c 543