Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: VL6160SRC/6180a1.c
- Revision:
- 0:1da5e4bcb8e5
- Child:
- 1:b4bdb0356af0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/VL6160SRC/6180a1.c Wed Oct 28 14:51:47 2020 +0000
@@ -0,0 +1,721 @@
+/*******************************************************************************
+Copyright © 2019, STMicroelectronics International N.V.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of STMicroelectronics nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
+IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+********************************************************************************/
+
+#include <string.h>
+
+/** Configure VL6180 pins to Output */
+//#include "stm32xxx_hal.h"
+#ifndef HAL_I2C_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+//#pragma message("hal conf should enable i2c")
+#endif
+
+#include "6180a1.h"
+#include "spi_interface.h"
+
+#define V1_CHIP_SWITCH_PORT GPIOA
+#define V1_CHIP_SWITCH_PIN GPIO_PIN_7
+#define V1_CHIP_ENABLE_PORT GPIOA
+#define V1_CHIP_ENABLE_PIN GPIO_PIN_5
+
+#define V1_IRQ_PIN GPIO_PIN_6
+#define V2_IRQ_PIN GPIO_PIN_0
+
+#define NEW_SENSOR_CENTRE_ADDRESS 0x56 // cgm fix
+
+#ifdef __STM32F4xx_HAL_H
+ #define V1_IRQ EXTI9_5_IRQn
+ #define V2_IRQ EXTI0_IRQn
+#else
+#ifdef STM32L4xx_HAL_H
+ #define V1_IRQ EXTI9_5_IRQn
+ #define V2_IRQ EXTI0_IRQn
+#else
+ #define V1_IRQ EXTI4_15_IRQn
+ #define V2_IRQ EXTI0_1_IRQn
+#endif
+#endif
+
+
+
+/* local private prototypes */
+//static void _V1_GPIO_Init(void);
+static void _V1_Set7SegmentDP( int dp);
+static void _V1_Set7Segment(uint8_t value);
+static void _V1_DisplayOff(void);
+
+
+static void _V2_GPIO_Init(void);
+static int _V2_GetSwicth(void);
+
+
+#define EXPANDER_I2C_ADDRESS (0x42*2)
+#define GPMR 0x10
+#define GPSR 0x12
+#define GPDR 0x14
+
+
+
+#define V2_D1 (1<<7)
+// second byte or word MSB
+#define V2_D2 (1<<8)
+#define V2_D3 (1<<9)
+#define V2_D4 (1<<10)
+#define V2_DISP_SEL (1<<11)
+#define V2_CHIPEN (1<<12)
+#define V2_CHIPEN_B (1<<13)
+#define V2_CHIPEN_L (1<<14)
+#define V2_CHIPEN_R (1<<15)
+
+#define GPIO_PIN_RESET 0
+#define GPIO_PIN_SET 1
+
+static int IsV2=0;
+//I2C_HandleTypeDef *_hi2c;
+uint16_t _V2PadVal; /* gpio SR value caching to avoid reading on each new bit set */
+//static int I2cExpAddr=EXPANDER_I2C_ADDRESS;
+
+static int _err=0;
+
+static void _V2_DisplayOff(void);
+static void _V2_SetChipEn( int No, int state );
+
+
+
+int XNUCLEO6180XA1_IsV2(void){
+ return IsV2;
+}
+
+
+
+int XNUCLEO6180XA1_EXTI_CallBackHandle(uint16_t GPIO_Pin){
+ // int IsVL6180XIntPin = IsV2 ? GPIO_Pin == V2_IRQ_PIN : GPIO_Pin == V1_IRQ_PIN;
+// if( IsVL6180XIntPin){
+// XNUCLEO6180XA1_UserIntHandler();
+// }
+ // return IsVL6180XIntPin;
+ return 1;
+}
+
+void XNUCLEO6180XA1_Reset(int state){
+
+ _V2_SetChipEn(0, state);
+}
+
+
+int XNUCLEO6180XA1_ResetId(int state, int id)
+{
+ int status;
+ if( IsV2 && id>=0 && id<4){
+ _V2_SetChipEn(id, state);
+ status=0;
+ }
+ else{
+ /* Error case */
+ status=-1;
+ }
+ return status;
+}
+
+int XNUCLEO6180XA1_GetSwitch(void){
+
+ int state;
+ state= _V2_GetSwicth() ? GPIO_PIN_SET : GPIO_PIN_RESET ;
+ return state;
+}
+
+/* public API */
+void XNUCLEO6180XA1_GPIO_Init(void) {
+// this must be done after i2c init _V1_GPIO_Init();
+}
+
+
+
+int V2_ExpanderRd(int index, uint8_t *data, int n_data){
+
+ int status;
+ uint8_t RegAddr;
+ RegAddr=index;
+
+ do{
+// status = vl6180_i2c_write_stmpe1600(data,EXPANDER_I2C_ADDRESS, index,n_data);
+
+
+// dev_I2C->v53l1x_i2c_write(buff, EXPANDER_I2C_ADDRESS, addr, len);
+ // status=HAL_I2C_Master_Transmit(_hi2c, I2cExpAddr, &RegAddr, 1, 100);
+ // if( status )
+// break;
+ status = vl6180_i2c_read_stmpe(data,EXPANDER_I2C_ADDRESS, index,n_data);
+ //status =HAL_I2C_Master_Receive(_hi2c, I2cExpAddr, data, n_data, n_data*100);
+ }while(0);
+ return status;
+}
+
+int V2_ExpanderWR( int index, uint8_t *data, int n_data){
+
+ int status;
+
+
+ uint8_t RegAddr[0x10];
+ RegAddr[0]=index;
+ memcpy(RegAddr, data, n_data);
+ status = vl6180_i2c_write_stmpe1600(data,EXPANDER_I2C_ADDRESS, index,n_data);
+ // if (status)
+ // printf("vl6180_i2c_write_stmpe1600 %d %d %d %d %d %d \n",RegAddr[0],RegAddr[1],EXPANDER_I2C_ADDRESS,index,n_data,status);
+ //status=HAL_I2C_Master_Transmit(_hi2c, I2cExpAddr, RegAddr, n_data+1, 100);
+ return status;
+}
+
+
+/**
+ * set or clear the shutdown pin for the satellites
+ * @param No 0= top , 1= Left, 2=Bottom 3=Right
+ * @param state
+ */
+static void _V2_SetChipEn( int No, int state ){
+ //int mask = V2_CHIPEN << No;
+ int mask = (No==3) ? V2_CHIPEN_R : ((No==2) ? V2_CHIPEN_B : ((No==1) ? V2_CHIPEN_L : V2_CHIPEN));
+ if( state)
+ _V2PadVal|=mask ;
+ else
+ _V2PadVal&=~mask;
+
+ V2_ExpanderWR(GPSR, (uint8_t*)&_V2PadVal,2);
+}
+
+int _V2_GetSwicth(){
+ int status;
+ uint16_t Value;
+ status=V2_ExpanderRd(GPMR, (uint8_t*)&Value,2); // read the current sense of the stmpe1600 pins
+
+ if(status ==0 ){
+ Value&=V2_DISP_SEL; //we only want the display select pin - pin11
+ }
+ else{
+ printf("VL6180x Expander rd fail\n");
+ _err++;
+ Value=0;
+ }
+ return Value;
+}
+
+/*
+static void _I2cFailRecover(){
+ GPIO_InitTypeDef GPIO_InitStruct;
+ int i, nRetry=0;
+
+
+ // We may get reset after in middle of an i2c access (h/w reset button use or debug load)
+ // hence some agent on bus may be in middle of a a transaction and will create issue or even prevent starting (SDA is low)
+ // 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)
+ // by setting SDA high and toggling SCL at least 10 time we ensure whatever agent and state
+ // all agent will end up seeing a "stop" end bus we back to an known idle i2c bus state
+
+ // Enable I/O
+ __GPIOB_CLK_ENABLE();
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9 ;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+ //TODO we could do this faster by not using HAL delay 1ms for clk timing
+ do{
+ for( i=0; i<10; i++){
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
+ HAL_Delay(1);
+ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
+ HAL_Delay(1);
+ }
+// if( HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == 0 ){
+// static int RetryRecover;
+// RetryRecover++;
+// }
+ }while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == 0 && nRetry++<7);
+
+ if( HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == 0 ){
+ __GPIOA_CLK_ENABLE();
+ //We are still in bad i2c state warm user by blinking led but stay here
+ GPIO_InitStruct.Pin = GPIO_PIN_5 ;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+ do{
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_Delay(33);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_Delay(33);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
+ HAL_Delay(33);
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
+ HAL_Delay(33*20);
+ }while(1);
+ }
+}
+*/
+
+/**
+ * F401 valid may not work for over device
+ */
+
+#ifdef 0
+void XNUCLEO6180XA1_I2C1_Init(I2C_HandleTypeDef *hi2c1) {
+ GPIO_InitTypeDef GPIO_InitStruct;
+ uint8_t ExpanderID[2];
+
+ int status;
+
+ _I2cFailRecover();
+ // Peripheral clock enable
+ __GPIOB_CLK_ENABLE();
+ __I2C1_CLK_ENABLE();
+ //I2C1 GPIO Configuration
+ // PB8 ------> I2C1_SCL
+ // PB9 ------> I2C1_SDA
+
+
+ GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ hi2c1->Instance = I2C1;
+#ifdef __STM32F4xx_HAL_H
+ hi2c1->Init.ClockSpeed = 400000;
+ hi2c1->Init.DutyCycle = I2C_DUTYCYCLE_2;
+#else
+ hi2c1->Init.Timing = 0x00300F38; // set 400KHz fast mode i2c
+#endif
+ hi2c1->Init.OwnAddress1 = 0;
+ hi2c1->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ hi2c1->Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
+ hi2c1->Init.OwnAddress2 = 0;
+ hi2c1->Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
+ hi2c1->Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
+
+ HAL_I2C_Init(hi2c1);
+
+
+ // try to detect v1 v2 by reading i2c expander register
+ // if rd i2c fail assume it is a v1 shield it may be a v2 with an i2c bus hangs (happen some time)
+ _hi2c=hi2c1;
+ status = V2_ExpanderRd( 0, ExpanderID, 2);
+ if( status == 0 && ExpanderID[0]==0 && ExpanderID[1]==0x16){
+ IsV2=1;
+ _V2_GPIO_Init();
+ }
+ else{
+ _V1_GPIO_Init();
+ }
+}
+#endif
+
+/**
+ * @brief Default do nothing interrupt callback
+ */
+#pragma weak XNUCLEO6180XA1_UserIntHandler
+void XNUCLEO6180XA1_UserIntHandler(void) {
+}
+
+void XNUCLEO6180XA1_ClearInterrupt(void){
+ /*
+ if( !IsV2 )
+ NVIC_ClearPendingIRQ(V1_IRQ);
+ else
+ NVIC_ClearPendingIRQ(V2_IRQ);
+ */
+}
+
+
+void XNUCLEO6180XA1_DisableInterrupt(void){
+ /*
+ if( !IsV2){
+ HAL_NVIC_DisableIRQ(V1_IRQ);
+ __HAL_GPIO_EXTI_CLEAR_IT(V1_IRQ_PIN);
+ NVIC_ClearPendingIRQ(V1_IRQ);
+ }
+ else{
+ HAL_NVIC_DisableIRQ(V2_IRQ);
+ __HAL_GPIO_EXTI_CLEAR_IT(V2_IRQ_PIN);
+ NVIC_ClearPendingIRQ(V2_IRQ);
+ }
+ */
+
+}
+void XNUCLEO6180XA1_EnableInterrupt(void){
+ /*
+ if( !IsV2 ){
+ __HAL_GPIO_EXTI_CLEAR_IT(V1_IRQ_PIN);
+ NVIC_ClearPendingIRQ(V1_IRQ);
+ HAL_NVIC_EnableIRQ(V1_IRQ);
+ }
+ else{
+ __HAL_GPIO_EXTI_CLEAR_IT(V2_IRQ_PIN);
+ NVIC_ClearPendingIRQ(V2_IRQ);
+ HAL_NVIC_EnableIRQ(V2_IRQ);
+ }
+ */
+
+}
+
+/**
+ * Display digit enable pad/pin LUT
+ * D1 is left most digit (ms nibble) on the display
+ * D3 is right most digit (ls nibble) on the display
+ */
+#define PA 0
+#define PB 1
+#define PC 2
+#define MAKE_PAD(port, pin) (((port)<<4)|pin)
+
+/* digit enable pad/pin LUT */
+static uint8_t DisplayEn[] = {
+ MAKE_PAD( PB, 0), /* D1 0 */
+ MAKE_PAD( PA, 4), /* D2 1 */
+ MAKE_PAD( PA, 1), /* D3 2 */
+ MAKE_PAD( PA, 0), /* D4 3 */
+};
+
+/* 7 segment code to pad/pin LUT */
+static uint8_t DisplaySeg[] = {
+ MAKE_PAD( PB, 6 ), /* 0 A */
+ MAKE_PAD( PC, 7 ), /* 1 B */
+ MAKE_PAD( PA, 9 ), /* 2 C */
+ MAKE_PAD( PA, 8 ), /* 3 D */
+ MAKE_PAD( PB, 10), /* 4 E */
+ MAKE_PAD( PB, 4 ), /* 5 F */
+ MAKE_PAD( PB, 5 ), /* 6 G */
+ MAKE_PAD( PB, 3 ), /* 7 DP */
+ /* Note that PB3 these is conflicting wit jtag/SWO used for trace
+ * activating PB3 as ooutput will prevent trace to work */
+};
+#undef MAKE_PAD
+#undef PA
+#undef PB
+#undef PC
+
+#define pad_write(pad, state) HAL_GPIO_WritePin( (void*)((char*)GPIOA + (pad>>4)*((char*)GPIOB-(char*)GPIOA)), 1<<(pad&0x0F), state);
+
+/*
+ --s0--
+ s s
+ 5 1
+ --s6--
+ s s
+ 4 2
+ --s3-- s7
+
+ */
+
+#define DP (1<<7)
+#define NOT_7_NO_DP( ... ) (uint8_t) ~( __VA_ARGS__ + DP )
+#define S0 (1<<0)
+#define S1 (1<<1)
+#define S2 (1<<2)
+#define S3 (1<<3)
+#define S4 (1<<4)
+#define S5 (1<<5)
+#define S6 (1<<6)
+
+/* refer to http://www.twyman.org.uk/Fonts/ */
+static const uint8_t ascii_to_display_lut[256]={
+ [' ']= 0,
+ ['-']= S6,
+ ['_']= S3,
+ ['=']= S3+S6,
+ ['~']= S0+S3+S6, /* 3 h bar */
+ ['^']= S0, /* use as top bar */
+
+ ['?']= NOT_7_NO_DP(S5+S3+S2),
+ ['*']= NOT_7_NO_DP(),
+ ['[']= S0+S3+S4+S5,
+ [']']= S0+S3+S2+S1,
+ ['@']= S0+S3,
+
+ ['0']= NOT_7_NO_DP(S6),
+ ['1']= S1+S2,
+ ['2']= S0+S1+S6+S4+S3,
+ ['3']= NOT_7_NO_DP(S4+S5),
+ ['4']= S5+S1+S6+S2,
+ ['5']= NOT_7_NO_DP(S1+S4),
+ ['6']= NOT_7_NO_DP(S1),
+ ['7']= S0+S1+S2,
+ ['8']= NOT_7_NO_DP(0),
+ ['9']= NOT_7_NO_DP(S4),
+
+ ['a']= S2+ S3+ S4+ S6 ,
+ ['b']= NOT_7_NO_DP(S0+S1),
+ ['c']= S6+S4+S3,
+ ['d']= NOT_7_NO_DP(S0+S5),
+ ['e']= NOT_7_NO_DP(S2),
+ ['f']= S6+S5+S4+S0, /* same as F */
+ ['g']= NOT_7_NO_DP(S4), /* same as 9 */
+ ['h']= S6+S5+S4+S2,
+ ['i']= S4,
+ ['j']= S1+S2+S3+S4,
+ ['k']= S6+S5+S4+S2, /* a h */
+ ['l']= S3+S4,
+ ['m']= S0+S4+S2, /* same as */
+ ['n']= S2+S4+S6,
+ ['o']= S6+S4+S3+S2,
+ ['p']= NOT_7_NO_DP(S3+S2), // same as P
+ ['q']= S0+S1+S2+S5+S6,
+ ['r']= S4+S6,
+ ['s']= NOT_7_NO_DP(S1+S4),
+ ['t']= NOT_7_NO_DP(S0+S1+S2),
+ ['u']= S4+S3+S2+S5+S1, // U
+ ['v']= S4+S3+S2, // is u but u use U
+ ['w']= S1+S3+S5,
+ ['x']= NOT_7_NO_DP(S0+S3), // similar to H
+ ['y']= NOT_7_NO_DP(S0+S4),
+ ['z']= S0+S1+S6+S4+S3, // same as 2
+
+ ['A']= NOT_7_NO_DP(S3),
+ ['B']= NOT_7_NO_DP(S0+S1), /* as b */
+ ['C']= S0+S3+S4+S5, // same as [
+ ['E']= NOT_7_NO_DP(S1+S2),
+ ['F']= S6+S5+S4+S0,
+ ['G']= NOT_7_NO_DP(S4), /* same as 9 */
+ ['H']= NOT_7_NO_DP(S0+S3),
+ ['I']= S1+S2,
+ ['J']= S1+S2+S3+S4,
+ ['K']= NOT_7_NO_DP(S0+S3), /* same as H */
+ ['L']= S3+S4+S5,
+ ['M']= S0+S4+S2, /* same as m*/
+ ['N']= S2+S4+S6, /* same as n*/
+ ['O']= NOT_7_NO_DP(S6),
+ ['P']= S0+S1+S2+S5+S6, // sames as 'q'
+ ['Q']= NOT_7_NO_DP(S3+S2),
+ ['R']= S4+S6,
+ ['S']= NOT_7_NO_DP(S1+S4), /* sasme as 5 */
+ ['T']= NOT_7_NO_DP(S0+S1+S2), /* sasme as t */
+ ['U']= NOT_7_NO_DP(S6+S0),
+ ['V']= S4+S3+S2, // is u but u use U
+ ['W']= S1+S3+S5,
+ ['X']= NOT_7_NO_DP(S0+S3), // similar to H
+ ['Y']= NOT_7_NO_DP(S0+S4),
+ ['Z']= S0+S1+S6+S4+S3, // same as 2
+
+
+};
+
+#undef S0
+#undef S1
+#undef S2
+#undef S3
+#undef S4
+#undef S5
+#undef S6
+#undef DP
+
+#ifdef 0
+static void _V1_DisplayString(const char *str, int SegDelayMs){
+ int i;
+ const char *pc;
+ for( i=0, pc=str; i<4 && *pc!=0 ; i++, pc++){
+ _V1_Set7Segment( ascii_to_display_lut[(uint8_t)*pc]);
+ if( *(pc+1)== '.'){
+ _V1_Set7SegmentDP(1);
+ pc++;
+ }
+ /* digit on */
+ pad_write(DisplayEn[i], GPIO_PIN_RESET); /* activate led */
+ XNUCLEO6180XA1_WaitMilliSec(SegDelayMs);
+ /* digit off */
+ pad_write(DisplayEn[i], GPIO_PIN_SET); /* turn off led */
+ }
+}
+#endif
+
+static void _V2_Set7Segment( int Leds, int digit ){
+ _V2PadVal = 0xf000; /* set sensor c/s pins */
+ _V2PadVal |= 0x7F; /* clear 7 seg bits */
+
+ _V2PadVal |= V2_D1|V2_D2|V2_D3|V2_D4; /* all segment off */
+ _V2PadVal &= ~(V2_D1<<digit); /* digit on */
+ _V2PadVal &= ~(Leds&0x7F);
+
+ V2_ExpanderWR(GPSR, (uint8_t*)&_V2PadVal, 2);
+}
+
+
+static void _V2_DisplayString(const char *str, int SegDelayMs){
+ int i;
+ const char *pc;
+
+ for( i=0, pc=str; i<4 && *pc!=0 ; i++, pc++){
+ _V2_Set7Segment( ascii_to_display_lut[(uint8_t)*pc], i);
+ if( *(pc+1)== '.'){
+ pc++;
+ }
+ wait_us(SegDelayMs*1000); // 1000 = 1ms
+
+ _V2_DisplayOff();
+ }
+}
+
+/**
+ * accept . on any digit
+ */
+void XNUCLEO6180XA1_DisplayString(const char *str, int SegDelayMs){
+ // if( !IsV2)
+ // _V1_DisplayString(str, SegDelayMs);
+ // else
+ _V2_DisplayString(str, SegDelayMs);
+ }
+
+
+
+#ifdef 0
+static void _V1_GPIO_Init(void) {
+
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ /* GPIO Ports Clock Enable */
+ __GPIOC_CLK_ENABLE();
+ __GPIOH_CLK_ENABLE();
+ __GPIOA_CLK_ENABLE();
+ __GPIOB_CLK_ENABLE();
+
+
+ /*Configure GPIO pins : PA0 PA1 PA4 PA5 PA8 PA9 */
+ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_9;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /*Configure GPIO pins : PA7 select */
+ GPIO_InitStruct.Pin = GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+
+ /*Configure GPIO pins : PA6 interrupt */
+ GPIO_InitStruct.Pin = GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /*Configure GPIO pins : PB0 PB10 PB3 PB4 PB5 PB6 */
+ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_10 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6;
+#ifndef OS_USE_TRACE_ITM
+ GPIO_InitStruct.Pin |= GPIO_PIN_3;
+#endif
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+
+
+ /*Configure GPIO pin : PC7 7 segment B */
+ GPIO_InitStruct.Pin = GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+ /* turn off all 7 seg digit */
+ _V1_DisplayOff();
+}
+#endif
+
+
+static void _V2_GPIO_Init(){
+ uint16_t PadDir;
+#ifdef 0
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ __GPIOA_CLK_ENABLE();
+ __GPIOB_CLK_ENABLE();
+
+ /*Configure GPIO pins interrupt PA4 = INTB , PA5 = INTL, pA10 = INTR */
+ GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5 |GPIO_PIN_10 ;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+
+ /* PB0 = INT */
+ GPIO_InitStruct.Pin = GPIO_PIN_0;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+#endif
+ /* expender config */
+ PadDir=~V2_DISP_SEL;
+ V2_ExpanderWR(GPDR, (uint8_t*)&PadDir, 2);
+
+ _V2_DisplayOff();
+
+}
+
+
+static void _V2_DisplayOff() {
+ _V2PadVal |= (V2_D1|V2_D2|V2_D3| V2_D4); /* segment en off */
+ V2_ExpanderWR(GPSR, (uint8_t*)&_V2PadVal, 2);
+}
+
+#ifdef 0
+static void _V1_DisplayOff() {
+ int i;
+ for( i=0; i<4; i++ ){
+ pad_write(DisplayEn[i], GPIO_PIN_SET); /* turn off led */
+ }
+}
+#endif
+
+#ifdef 0
+/* set 7 segment bus to display decode "value" */
+static void _V1_Set7Segment(const uint8_t value) {
+ int i;
+ GPIO_PinState state;
+ for (i = 0; i < sizeof(DisplaySeg)/sizeof(DisplaySeg[0]); i++) {
+ int cur_bit;
+ cur_bit = value & (1 << i);
+ state = cur_bit ? GPIO_PIN_RESET: GPIO_PIN_SET; /* port clear= segment on */
+ pad_write(DisplaySeg[i], state);
+ }
+}
+
+/* set state of decimal point on 7 segment bus */
+static void _V1_Set7SegmentDP( int dp_state) {
+ GPIO_PinState state;
+
+
+ state = dp_state ? GPIO_PIN_RESET: GPIO_PIN_SET; // port clear= segment on
+ pad_write(DisplaySeg[7], state);
+ //HAL_GPIO_WritePin((void*)GPIOA + DisplaySeg[7].port*((void*)GPIOB-(void*)GPIOA), 1<<DisplaySeg[7].pin, state);
+}
+#endif
+
+
+
