Contains Ayoub's Ranging and Custom interfaces for the VL53L3CX

Committer:
charlesmn
Date:
Wed Jul 21 14:19:31 2021 +0000
Revision:
0:c1910e04fc6c
Child:
1:dae4cb24beec
Change from directory to lib

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 0:c1910e04fc6c 201 /** @defgroup XNUCLEO_53L3A2_COMMON_Private_Variables Private Variables
charlesmn 0:c1910e04fc6c 202 * @{
charlesmn 0:c1910e04fc6c 203 */
charlesmn 0:c1910e04fc6c 204 static uint32_t InitCounter = 0;
charlesmn 0:c1910e04fc6c 205
charlesmn 0:c1910e04fc6c 206 /* cache the full set of expanded GPIO values to avoid i2c reading */
charlesmn 0:c1910e04fc6c 207 static union CurIOVal_u
charlesmn 0:c1910e04fc6c 208 {
charlesmn 0:c1910e04fc6c 209 uint8_t bytes[4]; /*!< 4 bytes array i/o view */
charlesmn 0:c1910e04fc6c 210 uint32_t u32; /*!< single dword i/o view */
charlesmn 0:c1910e04fc6c 211 } CurIOVal; /* cache the extended IO values */
charlesmn 0:c1910e04fc6c 212 /**
charlesmn 0:c1910e04fc6c 213 * @}
charlesmn 0:c1910e04fc6c 214 */
charlesmn 0:c1910e04fc6c 215
charlesmn 0:c1910e04fc6c 216 /** @defgroup XNUCLEO_53L3A2_COMMON_Private_Functions_Prototypes Private Functions Prototypes
charlesmn 0:c1910e04fc6c 217 * @{
charlesmn 0:c1910e04fc6c 218 */
charlesmn 0:c1910e04fc6c 219 static void _I2cFailRecover(void);
charlesmn 0:c1910e04fc6c 220 static int32_t _ExpanderRd(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data);
charlesmn 0:c1910e04fc6c 221 static int32_t _ExpanderWR(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data);
charlesmn 0:c1910e04fc6c 222 static int32_t _ExpandersSetAllIO(void);
charlesmn 0:c1910e04fc6c 223 /**
charlesmn 0:c1910e04fc6c 224 * @}
charlesmn 0:c1910e04fc6c 225 */
charlesmn 0:c1910e04fc6c 226
charlesmn 0:c1910e04fc6c 227 /**
charlesmn 0:c1910e04fc6c 228 * @brief Initialize X-NUCLEO-53L3A2 STM32 expansion board
charlesmn 0:c1910e04fc6c 229 * @note All devices XSDN are asserted and display is turned off
charlesmn 0:c1910e04fc6c 230 * @return 0 on success
charlesmn 0:c1910e04fc6c 231 */
charlesmn 0:c1910e04fc6c 232 int32_t VL53L3A2_Init(void)
charlesmn 0:c1910e04fc6c 233 {
charlesmn 0:c1910e04fc6c 234 int32_t status = 0;
charlesmn 0:c1910e04fc6c 235 uint8_t ExpanderData[2];
charlesmn 0:c1910e04fc6c 236
charlesmn 0:c1910e04fc6c 237 if (InitCounter++ == 0U)
charlesmn 0:c1910e04fc6c 238 {
charlesmn 0:c1910e04fc6c 239 // _I2cFailRecover();
charlesmn 0:c1910e04fc6c 240
charlesmn 0:c1910e04fc6c 241 //// VL53L3A2_I2C_Init();
charlesmn 0:c1910e04fc6c 242
charlesmn 0:c1910e04fc6c 243 //// status = _ExpanderRd(I2C_EXPANDER_ADDR0, 0, ExpanderData, 2);
charlesmn 0:c1910e04fc6c 244
charlesmn 0:c1910e04fc6c 245 // if ((status != 0) || (ExpanderData[0] != 0x00U) || (ExpanderData[1] != 0x16U))
charlesmn 0:c1910e04fc6c 246 // {
charlesmn 0:c1910e04fc6c 247 // VL53L3A2_ErrLog("I2C Expander @0x%02X not detected", (int)I2C_EXPANDER_ADDR0);
charlesmn 0:c1910e04fc6c 248 // goto done_err;
charlesmn 0:c1910e04fc6c 249 // }
charlesmn 0:c1910e04fc6c 250
charlesmn 0:c1910e04fc6c 251 // status = _ExpanderRd(I2C_EXPANDER_ADDR1, 0, ExpanderData, 2);
charlesmn 0:c1910e04fc6c 252
charlesmn 0:c1910e04fc6c 253 // if ((status != 0) || (ExpanderData[0] != 0x00U) || (ExpanderData[1] != 0x16U))
charlesmn 0:c1910e04fc6c 254 // {
charlesmn 0:c1910e04fc6c 255 // printf("ExpanderData %d %d %d\n",status,ExpanderData[0],ExpanderData[1]);
charlesmn 0:c1910e04fc6c 256 // VL53L3A2_ErrLog("I2C Expander @0x%02X not detected", (int)I2C_EXPANDER_ADDR1);
charlesmn 0:c1910e04fc6c 257 // goto done_err;
charlesmn 0:c1910e04fc6c 258 // }
charlesmn 0:c1910e04fc6c 259
charlesmn 0:c1910e04fc6c 260 CurIOVal.u32 = 0x0U;
charlesmn 0:c1910e04fc6c 261
charlesmn 0:c1910e04fc6c 262 // setup expander i/o direction all output but exp1 bit 14
charlesmn 0:c1910e04fc6c 263 ExpanderData[0] = 0xFFU;
charlesmn 0:c1910e04fc6c 264 ExpanderData[1] = 0xFFU;
charlesmn 0:c1910e04fc6c 265
charlesmn 0:c1910e04fc6c 266 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPDR, ExpanderData, 2);
charlesmn 0:c1910e04fc6c 267
charlesmn 0:c1910e04fc6c 268 if (status)
charlesmn 0:c1910e04fc6c 269 {
charlesmn 0:c1910e04fc6c 270 VL53L3A2_ErrLog("Set Expander @0x%02X DR", I2C_EXPANDER_ADDR0);
charlesmn 0:c1910e04fc6c 271 goto done_err;
charlesmn 0:c1910e04fc6c 272 }
charlesmn 0:c1910e04fc6c 273
charlesmn 0:c1910e04fc6c 274 ExpanderData[0] = 0xFFU;
charlesmn 0:c1910e04fc6c 275 ExpanderData[1] = 0xBFU; /* all but bit 14-15 that is pb1 and xhurt */
charlesmn 0:c1910e04fc6c 276 status = _ExpanderWR(I2C_EXPANDER_ADDR1, GPDR, ExpanderData, 2);
charlesmn 0:c1910e04fc6c 277
charlesmn 0:c1910e04fc6c 278 if (status)
charlesmn 0:c1910e04fc6c 279 {
charlesmn 0:c1910e04fc6c 280 VL53L3A2_ErrLog("Set Expander @0x%02X DR", I2C_EXPANDER_ADDR1);
charlesmn 0:c1910e04fc6c 281 goto done_err;
charlesmn 0:c1910e04fc6c 282 }
charlesmn 0:c1910e04fc6c 283
charlesmn 0:c1910e04fc6c 284 /* shut down all segment and all device */
charlesmn 0:c1910e04fc6c 285 CurIOVal.u32 = 0x7FU + (0x7FU << 7) + (0x7FU << 16) + (0x7FU << (16 + 7));
charlesmn 0:c1910e04fc6c 286
charlesmn 0:c1910e04fc6c 287 CurIOVal.bytes[3] = 0x0f;
charlesmn 0:c1910e04fc6c 288 CurIOVal.bytes[1] = 0x0f;
charlesmn 0:c1910e04fc6c 289 status = _ExpandersSetAllIO();
charlesmn 0:c1910e04fc6c 290
charlesmn 0:c1910e04fc6c 291 if (status)
charlesmn 0:c1910e04fc6c 292 {
charlesmn 0:c1910e04fc6c 293 VL53L3A2_ErrLog("Set initial i/o ");
charlesmn 0:c1910e04fc6c 294 }
charlesmn 0:c1910e04fc6c 295 }
charlesmn 0:c1910e04fc6c 296
charlesmn 0:c1910e04fc6c 297 done_err:
charlesmn 0:c1910e04fc6c 298 return status;
charlesmn 0:c1910e04fc6c 299 }
charlesmn 0:c1910e04fc6c 300
charlesmn 0:c1910e04fc6c 301 /**
charlesmn 0:c1910e04fc6c 302 * @brief De-initialize X-NUCLEO-53L3A2 STM32 expansion board
charlesmn 0:c1910e04fc6c 303 * @return 0 on success
charlesmn 0:c1910e04fc6c 304 */
charlesmn 0:c1910e04fc6c 305 int32_t VL53L3A2_DeInit(void)
charlesmn 0:c1910e04fc6c 306 {
charlesmn 0:c1910e04fc6c 307 int32_t status = 0;
charlesmn 0:c1910e04fc6c 308
charlesmn 0:c1910e04fc6c 309 if (InitCounter > 0U)
charlesmn 0:c1910e04fc6c 310 {
charlesmn 0:c1910e04fc6c 311 if (--InitCounter == 0U)
charlesmn 0:c1910e04fc6c 312 {
charlesmn 0:c1910e04fc6c 313 // status = VL53L3A2_I2C_DeInit();
charlesmn 0:c1910e04fc6c 314 }
charlesmn 0:c1910e04fc6c 315 }
charlesmn 0:c1910e04fc6c 316
charlesmn 0:c1910e04fc6c 317 return status;
charlesmn 0:c1910e04fc6c 318 }
charlesmn 0:c1910e04fc6c 319
charlesmn 0:c1910e04fc6c 320 /**
charlesmn 0:c1910e04fc6c 321 * @brief Set Reset (XSDN) state of a given "id" device
charlesmn 0:c1910e04fc6c 322 * @param DevNo The device number, use @ref VL53L3A2_dev_e.
charlesmn 0:c1910e04fc6c 323 * @param state State of the device reset (xsdn) pin @warning reset pin is active low
charlesmn 0:c1910e04fc6c 324 * i.e. xshut is raised to enable device
charlesmn 0:c1910e04fc6c 325 * @return 0 on success
charlesmn 0:c1910e04fc6c 326 */
charlesmn 0:c1910e04fc6c 327
charlesmn 0:c1910e04fc6c 328 // VL53L3A2_DEV_LEFT = 0, /* !< left satellite device P21 header */
charlesmn 0:c1910e04fc6c 329 // VL53L3A2_DEV_CENTER = 1, /* !< center (built-in) device */
charlesmn 0:c1910e04fc6c 330 // VL53L3A2_DEV_RIGHT = 2 /* !< Right satellite device P22 header */
charlesmn 0:c1910e04fc6c 331 int32_t VL53L3A2_ResetId(uint8_t DevNo, uint8_t state)
charlesmn 0:c1910e04fc6c 332 {
charlesmn 0:c1910e04fc6c 333 int32_t status;
charlesmn 0:c1910e04fc6c 334 printf("VL53L3A2_ResetId %d %d %d %d \n",DevNo,state,CurIOVal.bytes[1],CurIOVal.bytes[3]);
charlesmn 0:c1910e04fc6c 335 switch (DevNo)
charlesmn 0:c1910e04fc6c 336 {
charlesmn 0:c1910e04fc6c 337 case VL53L3A2_DEV_CENTER :
charlesmn 0:c1910e04fc6c 338 CurIOVal.bytes[3] &= ~0x80U; /* bit 15 expander 1 => byte #3 */
charlesmn 0:c1910e04fc6c 339
charlesmn 0:c1910e04fc6c 340 if (state)
charlesmn 0:c1910e04fc6c 341 {
charlesmn 0:c1910e04fc6c 342 CurIOVal.bytes[3] |= 0x80U; /* bit 15 expander 1 => byte #3 */
charlesmn 0:c1910e04fc6c 343 }
charlesmn 0:c1910e04fc6c 344
charlesmn 0:c1910e04fc6c 345 status = _ExpanderWR(I2C_EXPANDER_ADDR1, GPSR , &CurIOVal.bytes[3], 1);
charlesmn 0:c1910e04fc6c 346 break;
charlesmn 0:c1910e04fc6c 347
charlesmn 0:c1910e04fc6c 348 case VL53L3A2_DEV_LEFT :
charlesmn 0:c1910e04fc6c 349 printf("VL53L3A2_DEV_LEFT \n");
charlesmn 0:c1910e04fc6c 350 CurIOVal.bytes[1] &= ~0x40U; /* bit 14 expander 0 => byte #1*/
charlesmn 0:c1910e04fc6c 351
charlesmn 0:c1910e04fc6c 352 if (state)
charlesmn 0:c1910e04fc6c 353 {
charlesmn 0:c1910e04fc6c 354 CurIOVal.bytes[1] |= 0x40U; /* bit 14 expander 0 => byte #1*/
charlesmn 0:c1910e04fc6c 355 }
charlesmn 0:c1910e04fc6c 356
charlesmn 0:c1910e04fc6c 357 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPSR , &CurIOVal.bytes[1], 1);
charlesmn 0:c1910e04fc6c 358 break;
charlesmn 0:c1910e04fc6c 359
charlesmn 0:c1910e04fc6c 360 case VL53L3A2_DEV_RIGHT :
charlesmn 0:c1910e04fc6c 361 CurIOVal.bytes[1] &= ~0x80U; /* bit 15 expander 0 => byte #1 */
charlesmn 0:c1910e04fc6c 362
charlesmn 0:c1910e04fc6c 363 if (state)
charlesmn 0:c1910e04fc6c 364 {
charlesmn 0:c1910e04fc6c 365 CurIOVal.bytes[1] |= 0x80U; /* bit 15 expander 0 => byte #1*/
charlesmn 0:c1910e04fc6c 366 }
charlesmn 0:c1910e04fc6c 367
charlesmn 0:c1910e04fc6c 368 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPSR , &CurIOVal.bytes[1], 1);
charlesmn 0:c1910e04fc6c 369 break;
charlesmn 0:c1910e04fc6c 370
charlesmn 0:c1910e04fc6c 371 default:
charlesmn 0:c1910e04fc6c 372 VL53L3A2_ErrLog("Invalid DevNo %d", DevNo);
charlesmn 0:c1910e04fc6c 373 status = -1;
charlesmn 0:c1910e04fc6c 374 goto done;
charlesmn 0:c1910e04fc6c 375 }
charlesmn 0:c1910e04fc6c 376
charlesmn 0:c1910e04fc6c 377 /* error with valid id */
charlesmn 0:c1910e04fc6c 378 if (status)
charlesmn 0:c1910e04fc6c 379 {
charlesmn 0:c1910e04fc6c 380 VL53L3A2_ErrLog("expander i/o error for DevNo %d state %d ", DevNo, state);
charlesmn 0:c1910e04fc6c 381 }
charlesmn 0:c1910e04fc6c 382
charlesmn 0:c1910e04fc6c 383 done:
charlesmn 0:c1910e04fc6c 384 printf("VL53L3A2_ResetId %d %d %d %d\n",status,DevNo,CurIOVal.bytes[1],CurIOVal.bytes[3]);
charlesmn 0:c1910e04fc6c 385 return status;
charlesmn 0:c1910e04fc6c 386 }
charlesmn 0:c1910e04fc6c 387
charlesmn 0:c1910e04fc6c 388 /**
charlesmn 0:c1910e04fc6c 389 * @brief Set the 7 segments display
charlesmn 0:c1910e04fc6c 390 * @param str String to set on display
charlesmn 0:c1910e04fc6c 391 * @warning When string is less than 4 digits, display is left-justified and lower digits are blanked.
charlesmn 0:c1910e04fc6c 392 * To display a 2 digits value, left justified on the 4 digits, use "%4d" formating
charlesmn 0:c1910e04fc6c 393 * @warning When more than 4 char are present only first 4 are displayed
charlesmn 0:c1910e04fc6c 394 * @note Characters that do not have 7 segment font matching in ascii_to_display_lut are left blank
charlesmn 0:c1910e04fc6c 395 * @return 0 on success
charlesmn 0:c1910e04fc6c 396 */
charlesmn 0:c1910e04fc6c 397 int32_t VL53L3A2_SetDisplayString(const char *str)
charlesmn 0:c1910e04fc6c 398 {
charlesmn 0:c1910e04fc6c 399 int32_t status;
charlesmn 0:c1910e04fc6c 400 uint32_t BitPos;
charlesmn 0:c1910e04fc6c 401 uint32_t i;
charlesmn 0:c1910e04fc6c 402 uint32_t Segments;
charlesmn 0:c1910e04fc6c 403
charlesmn 0:c1910e04fc6c 404 /* lookup table for for digit to bit position in @a CurIOVal u32 */
charlesmn 0:c1910e04fc6c 405 uint8_t DisplayBitPos[4] = {0, 7, 16, 16 + 7};
charlesmn 0:c1910e04fc6c 406
charlesmn 0:c1910e04fc6c 407 for (i = 0; (i < 4U) && (str[i] != 0U); i++)
charlesmn 0:c1910e04fc6c 408 {
charlesmn 0:c1910e04fc6c 409 Segments = (uint32_t)ascii_to_display_lut[(uint8_t)str[i]];
charlesmn 0:c1910e04fc6c 410 Segments = (~Segments) & 0x7FU;
charlesmn 0:c1910e04fc6c 411 BitPos = DisplayBitPos[i];
charlesmn 0:c1910e04fc6c 412 CurIOVal.u32 &= ~(0x7FU << BitPos);
charlesmn 0:c1910e04fc6c 413 CurIOVal.u32 |= Segments << BitPos;
charlesmn 0:c1910e04fc6c 414 }
charlesmn 0:c1910e04fc6c 415
charlesmn 0:c1910e04fc6c 416 /* clear unused digit */
charlesmn 0:c1910e04fc6c 417 for (; i < 4U; i++)
charlesmn 0:c1910e04fc6c 418 {
charlesmn 0:c1910e04fc6c 419 BitPos = DisplayBitPos[i];
charlesmn 0:c1910e04fc6c 420 CurIOVal.u32 |= 0x7FU << BitPos;
charlesmn 0:c1910e04fc6c 421 }
charlesmn 0:c1910e04fc6c 422
charlesmn 0:c1910e04fc6c 423 status = _ExpandersSetAllIO();
charlesmn 0:c1910e04fc6c 424
charlesmn 0:c1910e04fc6c 425 if (status)
charlesmn 0:c1910e04fc6c 426 {
charlesmn 0:c1910e04fc6c 427 VL53L3A2_ErrLog("Set i/o");
charlesmn 0:c1910e04fc6c 428 }
charlesmn 0:c1910e04fc6c 429
charlesmn 0:c1910e04fc6c 430 return status;
charlesmn 0:c1910e04fc6c 431 }
charlesmn 0:c1910e04fc6c 432
charlesmn 0:c1910e04fc6c 433 /** @defgroup XNUCLEO_53L3A2_COMMON_Private_Functions Private Functions
charlesmn 0:c1910e04fc6c 434 * @{
charlesmn 0:c1910e04fc6c 435 */
charlesmn 0:c1910e04fc6c 436
charlesmn 0:c1910e04fc6c 437 /**
charlesmn 0:c1910e04fc6c 438 * @brief Expansion board i2c bus recovery
charlesmn 0:c1910e04fc6c 439 * We may get reset in middle of an i2c access (h/w reset button, debug or f/w load)
charlesmn 0:c1910e04fc6c 440 * 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 441 * this routine does use gpio to manipulate and recover i2c bus line in all cases.
charlesmn 0:c1910e04fc6c 442 */
charlesmn 0:c1910e04fc6c 443 static void _I2cFailRecover()
charlesmn 0:c1910e04fc6c 444 {
charlesmn 0:c1910e04fc6c 445 printf("_I2cFailRecover \n");
charlesmn 0:c1910e04fc6c 446 #if 0
charlesmn 0:c1910e04fc6c 447 GPIO_InitTypeDef GPIO_InitStruct;
charlesmn 0:c1910e04fc6c 448 uint8_t i, nRetry = 0;
charlesmn 0:c1910e04fc6c 449
charlesmn 0:c1910e04fc6c 450 /* 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 451 * by setting SDA high and toggling SCL at least 10 time we ensure whatever agent and state
charlesmn 0:c1910e04fc6c 452 * all agent should end up seeing a "stop" and bus get back to an known idle i2c bus state */
charlesmn 0:c1910e04fc6c 453
charlesmn 0:c1910e04fc6c 454 /* Enable I/O */
charlesmn 0:c1910e04fc6c 455 __GPIOB_CLK_ENABLE();
charlesmn 0:c1910e04fc6c 456 HAL_GPIO_WritePin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SCL_GPIO_PIN, GPIO_PIN_SET);
charlesmn 0:c1910e04fc6c 457 HAL_GPIO_WritePin(VL53L3A2_I2C_SDA_GPIO_PORT, VL53L3A2_I2C_SDA_GPIO_PIN, GPIO_PIN_SET);
charlesmn 0:c1910e04fc6c 458 GPIO_InitStruct.Pin = VL53L3A2_I2C_SCL_GPIO_PIN | VL53L3A2_I2C_SDA_GPIO_PIN ;
charlesmn 0:c1910e04fc6c 459 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
charlesmn 0:c1910e04fc6c 460 GPIO_InitStruct.Pull = GPIO_PULLUP;
charlesmn 0:c1910e04fc6c 461 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
charlesmn 0:c1910e04fc6c 462
charlesmn 0:c1910e04fc6c 463 /* we could do this faster by not using HAL delay 1ms for clk timing */
charlesmn 0:c1910e04fc6c 464 do
charlesmn 0:c1910e04fc6c 465 {
charlesmn 0:c1910e04fc6c 466 for (i = 0; i < 10U; i++)
charlesmn 0:c1910e04fc6c 467 {
charlesmn 0:c1910e04fc6c 468 HAL_GPIO_WritePin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SCL_GPIO_PIN, GPIO_PIN_RESET);
charlesmn 0:c1910e04fc6c 469 HAL_Delay(1);
charlesmn 0:c1910e04fc6c 470 HAL_GPIO_WritePin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SCL_GPIO_PIN, GPIO_PIN_SET);
charlesmn 0:c1910e04fc6c 471 HAL_Delay(1);
charlesmn 0:c1910e04fc6c 472 }
charlesmn 0:c1910e04fc6c 473
charlesmn 0:c1910e04fc6c 474 } while ((HAL_GPIO_ReadPin(VL53L3A2_I2C_SDA_GPIO_PORT, VL53L3A2_I2C_SDA_GPIO_PIN) == 0) && (nRetry++ < 7U));
charlesmn 0:c1910e04fc6c 475
charlesmn 0:c1910e04fc6c 476 if (HAL_GPIO_ReadPin(VL53L3A2_I2C_SCL_GPIO_PORT, VL53L3A2_I2C_SDA_GPIO_PIN) == 0)
charlesmn 0:c1910e04fc6c 477 {
charlesmn 0:c1910e04fc6c 478 /* We are still in a bad i2c state, block the program here
charlesmn 0:c1910e04fc6c 479 * A hardware reset is necessary */
charlesmn 0:c1910e04fc6c 480 while (1);
charlesmn 0:c1910e04fc6c 481 }
charlesmn 0:c1910e04fc6c 482 #endif
charlesmn 0:c1910e04fc6c 483 }
charlesmn 0:c1910e04fc6c 484
charlesmn 0:c1910e04fc6c 485 /**
charlesmn 0:c1910e04fc6c 486 * @brief Set all i2c expended gpio in one go
charlesmn 0:c1910e04fc6c 487 * @return i/o operation status
charlesmn 0:c1910e04fc6c 488 */
charlesmn 0:c1910e04fc6c 489 static int32_t _ExpandersSetAllIO(void)
charlesmn 0:c1910e04fc6c 490 {
charlesmn 0:c1910e04fc6c 491 int32_t status;
charlesmn 0:c1910e04fc6c 492
charlesmn 0:c1910e04fc6c 493 status = _ExpanderWR(I2C_EXPANDER_ADDR0, GPSR, &CurIOVal.bytes[0], 2);
charlesmn 0:c1910e04fc6c 494
charlesmn 0:c1910e04fc6c 495 if (status)
charlesmn 0:c1910e04fc6c 496 {
charlesmn 0:c1910e04fc6c 497 goto done_err;
charlesmn 0:c1910e04fc6c 498 }
charlesmn 0:c1910e04fc6c 499
charlesmn 0:c1910e04fc6c 500 status = _ExpanderWR(I2C_EXPANDER_ADDR1, GPSR, &CurIOVal.bytes[2], 2);
charlesmn 0:c1910e04fc6c 501
charlesmn 0:c1910e04fc6c 502 done_err:
charlesmn 0:c1910e04fc6c 503 printf("_ExpandersSetAllIO end \n");
charlesmn 0:c1910e04fc6c 504 return status;
charlesmn 0:c1910e04fc6c 505 }
charlesmn 0:c1910e04fc6c 506
charlesmn 0:c1910e04fc6c 507 /**
charlesmn 0:c1910e04fc6c 508 * @brief STMPE1600 i2c Expander register read
charlesmn 0:c1910e04fc6c 509 * @param I2cExpAddr Expander address
charlesmn 0:c1910e04fc6c 510 * @param index register index
charlesmn 0:c1910e04fc6c 511 * @param data read data buffer
charlesmn 0:c1910e04fc6c 512 * @param n_data number of byte to read
charlesmn 0:c1910e04fc6c 513 * @return of if ok else i2c I/O operation status
charlesmn 0:c1910e04fc6c 514 */
charlesmn 0:c1910e04fc6c 515 static int32_t _ExpanderRd(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data)
charlesmn 0:c1910e04fc6c 516 {
charlesmn 0:c1910e04fc6c 517 int32_t status;
charlesmn 0:c1910e04fc6c 518 uint8_t RegAddr;
charlesmn 0:c1910e04fc6c 519
charlesmn 0:c1910e04fc6c 520 RegAddr = index;
charlesmn 0:c1910e04fc6c 521 // VL53L3A2_GetI2cBus();
charlesmn 0:c1910e04fc6c 522 // printf("_ExpanderRd %d %d %d %d\n",I2cExpAddr,index,RegAddr,status);
charlesmn 0:c1910e04fc6c 523 // status = v53l1x_i2c_write_if(data,I2cExpAddr, index,n_data);
charlesmn 0:c1910e04fc6c 524
charlesmn 0:c1910e04fc6c 525
charlesmn 0:c1910e04fc6c 526 status = v53l1x_i2c_read_if(RegAddr,I2cExpAddr, index,2);
charlesmn 0:c1910e04fc6c 527
charlesmn 0:c1910e04fc6c 528
charlesmn 0:c1910e04fc6c 529 //// do
charlesmn 0:c1910e04fc6c 530 //// {
charlesmn 0:c1910e04fc6c 531 //// status = HAL_I2C_Master_Transmit(&VL53L3A2_hi2c, I2cExpAddr, &RegAddr, 1, 100);
charlesmn 0:c1910e04fc6c 532
charlesmn 0:c1910e04fc6c 533 //// if (status)
charlesmn 0:c1910e04fc6c 534 //// {
charlesmn 0:c1910e04fc6c 535 //// break;
charlesmn 0:c1910e04fc6c 536 //// }
charlesmn 0:c1910e04fc6c 537
charlesmn 0:c1910e04fc6c 538 //// status = HAL_I2C_Master_Receive(&VL53L3A2_hi2c, I2cExpAddr, data, n_data, n_data * 100);
charlesmn 0:c1910e04fc6c 539 //// } while (0);
charlesmn 0:c1910e04fc6c 540
charlesmn 0:c1910e04fc6c 541 // VL53L3A2_PutI2cBus();
charlesmn 0:c1910e04fc6c 542
charlesmn 0:c1910e04fc6c 543 return status;
charlesmn 0:c1910e04fc6c 544 }
charlesmn 0:c1910e04fc6c 545
charlesmn 0:c1910e04fc6c 546 /**
charlesmn 0:c1910e04fc6c 547 * @brief STMPE1600 i2c Expander register write
charlesmn 0:c1910e04fc6c 548 * @param I2cExpAddr Expander address
charlesmn 0:c1910e04fc6c 549 * @param index register index
charlesmn 0:c1910e04fc6c 550 * @param data data buffer
charlesmn 0:c1910e04fc6c 551 * @param n_data number of byte to write
charlesmn 0:c1910e04fc6c 552 * @return of if ok else i2c I/O operation status
charlesmn 0:c1910e04fc6c 553 */
charlesmn 0:c1910e04fc6c 554 static int32_t _ExpanderWR(uint32_t I2cExpAddr, uint32_t index, uint8_t *data, uint32_t n_data)
charlesmn 0:c1910e04fc6c 555 {
charlesmn 0:c1910e04fc6c 556 int32_t status = 0;
charlesmn 0:c1910e04fc6c 557 uint8_t RegAddr[0x10];
charlesmn 0:c1910e04fc6c 558 uint8_t i;
charlesmn 0:c1910e04fc6c 559 for (i = 0 ; i < 0x10 ; i++)
charlesmn 0:c1910e04fc6c 560 {
charlesmn 0:c1910e04fc6c 561 RegAddr[i] =0;
charlesmn 0:c1910e04fc6c 562 }
charlesmn 0:c1910e04fc6c 563 // build packet to send
charlesmn 0:c1910e04fc6c 564 if (n_data == 1)
charlesmn 0:c1910e04fc6c 565 {
charlesmn 0:c1910e04fc6c 566 RegAddr[0] = (uint8_t)index; // the register in the chip we are sending to
charlesmn 0:c1910e04fc6c 567 RegAddr[1]= 255; // the lower byte of the control word. We just set to FF
charlesmn 0:c1910e04fc6c 568 RegAddr[2]= data[0]; //the byte that controls the xshut pins
charlesmn 0:c1910e04fc6c 569 }
charlesmn 0:c1910e04fc6c 570 else{
charlesmn 0:c1910e04fc6c 571 RegAddr[0] = (uint8_t)index; // the register in the chip we are sending to
charlesmn 0:c1910e04fc6c 572 RegAddr[1]=data[0]; // the lower byte of the control word. We just set to FF
charlesmn 0:c1910e04fc6c 573 RegAddr[2]=data[1]; //the byte that controls the xshut pins
charlesmn 0:c1910e04fc6c 574 }
charlesmn 0:c1910e04fc6c 575
charlesmn 0:c1910e04fc6c 576 // printf("_ExpanderWR %d %d %d \n",data[0],data[1],n_data);
charlesmn 0:c1910e04fc6c 577 // 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 578 status = v53l1x_i2c_write_direct(RegAddr,I2cExpAddr,n_data + 2);
charlesmn 0:c1910e04fc6c 579
charlesmn 0:c1910e04fc6c 580
charlesmn 0:c1910e04fc6c 581
charlesmn 0:c1910e04fc6c 582
charlesmn 0:c1910e04fc6c 583
charlesmn 0:c1910e04fc6c 584 return (status);
charlesmn 0:c1910e04fc6c 585 }
charlesmn 0:c1910e04fc6c 586
charlesmn 0:c1910e04fc6c 587
charlesmn 0:c1910e04fc6c 588 /**
charlesmn 0:c1910e04fc6c 589 * @}
charlesmn 0:c1910e04fc6c 590 */
charlesmn 0:c1910e04fc6c 591
charlesmn 0:c1910e04fc6c 592 /**
charlesmn 0:c1910e04fc6c 593 * @}
charlesmn 0:c1910e04fc6c 594 */
charlesmn 0:c1910e04fc6c 595
charlesmn 0:c1910e04fc6c 596 /**
charlesmn 0:c1910e04fc6c 597 * @}
charlesmn 0:c1910e04fc6c 598 */
charlesmn 0:c1910e04fc6c 599
charlesmn 0:c1910e04fc6c 600 /**
charlesmn 0:c1910e04fc6c 601 * @}
charlesmn 0:c1910e04fc6c 602 */
charlesmn 0:c1910e04fc6c 603
charlesmn 0:c1910e04fc6c 604 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
charlesmn 0:c1910e04fc6c 605