Files
qrcode-reader-hardware/main_prog/vl6180/App/vl6180_app.c
Mysteo 222f758a2b upd
2023-08-01 19:45:40 +03:00

287 lines
7.5 KiB
C

//
// Created by Professional on 7/31/2023.
//
#include "stdint-gcc.h"
#include "vl6180_def.h"
#include "stm32g0xx_hal.h"
#include "vl6180_api.h"
#include "main.h"
#include "i2c.h"
#define max_scale 1
uint8_t changeScale = 0;
#define ALLOW_DISABLE_WAF_FROM_BLUE_BUTTON 1
#define theVL6180Dev 0x52 // what we use as "API device
#define def_i2c_time_out 100
#if VL6180_HAVE_DMAX_RANGING
#define DMaxDispTime 0 /* Set to 1000 to display Dmax during 1 sec when no target is detected */
#else
#define DMaxDispTime 0
#endif
#define OutORangeDispfTime 800
#define g_TickCnt uwTick
enum runmode_t{
RunRangePoll=0,
RunAlsPoll,
InitErr,
ScaleSwap,
WaitForReset,
AlrmStart,
AlrmRun,
FromSwitch,
};
char buffer[10];
struct state_t {
int OutofRAnge:1;
int AutoScale:1;
int FilterEn:1;
uint8_t mode;
int8_t ScaleSwapCnt;
uint8_t InitScale;
uint8_t CurAlrm;
uint8_t AlrmFired; /* just used to keep display at least min time */
}State;
uint32_t TimeStarted; /* various display and mode delay starting time */
VL6180_RangeData_t Range; /* Range measurmeent */
int alpha =(int)(0.85*(1<<16)); /* range distance running average cofs */
uint16_t range; /* range average distance */
#define AutoThreshHigh 80 /*auto scale high thresh => AutoThreshHigh * max_raneg => scale ++ */
#define AutoThreshLow 33 /*auto scale low thresh => AutoThreshHigh * max_raneg => scale ++ */
#define ErrRangeDispTime 0 /* Set to 800 ms to display error code when no target os detected */
#if ErrRangeDispTime == 0
/* supress Warning[Pe186]: pointless comparison of unsigned integer with zero */
# ifdef __ARMCC_VERSION /* ARM/KEIL */
# pragma diag_suppress 186
# endif /* _ARMCC_VERSION */
# ifdef __ICCARM__ /* IAR */
# pragma diag_suppress=Pe186
# endif /* _ARMCC_VERSION */
#endif
#define AlrmDispTime 800
#define AlarmKeepDispTime 250 /* alarm message retain time after it fires */
volatile int IntrFired=0;
extern volatile uint32_t SensorsEnabled;
void AbortErr( const char * msg ){
State.mode= WaitForReset;
}
void DoScalingSwap(int scaling){
State.mode = ScaleSwap;
TimeStarted=g_TickCnt;
}
uint8_t allowIT = 0;
void vl6180_init (void)
{
allowIT = 0;
HAL_GPIO_WritePin(CS_PROXIMITY_GPIO_Port, CS_PROXIMITY_Pin, GPIO_PIN_RESET);
HAL_Delay(200);
HAL_GPIO_WritePin(CS_PROXIMITY_GPIO_Port, CS_PROXIMITY_Pin, GPIO_PIN_SET);
HAL_Delay(200);
VL6180_WaitDeviceBooted(theVL6180Dev);
VL6180_InitData(theVL6180Dev);
State.InitScale=VL6180_UpscaleGetScaling(theVL6180Dev);
State.FilterEn=VL6180_FilterGetState(theVL6180Dev);
VL6180_Prepare(theVL6180Dev);
VL6180_RangeSetMaxConvergenceTime(theVL6180Dev, 20);
VL6180_RangeSetInterMeasPeriod(theVL6180Dev, 25);
//State.InitScale=VL6180_UpscaleGetScaling(theVL6180Dev);
/* Enable Dmax calculation only if value is displayed (to save computation power) */
//VL6180_DMaxSetState(theVL6180Dev, DMaxDispTime>0);
VL6180_ClearAllInterrupt(theVL6180Dev);
allowIT = 1;
}
int VL6180_I2CRead(VL6180Dev_t addr, uint8_t *buff, uint8_t len){
int status;
status = HAL_I2C_Master_Receive(&hi2c2, addr, buff, len , def_i2c_time_out);
if( status ){
MX_I2C2_Init();
}
return status;
}
int VL6180_I2CWrite(VL6180Dev_t addr, uint8_t *buff, uint8_t len){
int status;
status = HAL_I2C_Master_Transmit(&hi2c2, addr, buff, len , def_i2c_time_out);
if( status ){
MX_I2C2_Init();
}
return status;
}
void RangeState(void) {
int status;
uint16_t hlimit;
uint8_t scaling;
VL6180_RangeGetMeasurement(theVL6180Dev, &Range );
scaling = VL6180_UpscaleGetScaling(theVL6180Dev);
if (Range.errorStatus) {
AbortErr("Er r");
return;
}
hlimit = VL6180_GetUpperLimit(theVL6180Dev);
if (Range.range_mm >= (hlimit * AutoThreshHigh) / 100 && scaling < 3 && State.AutoScale) {
VL6180_UpscaleSetScaling(theVL6180Dev, scaling + 1);
}
if (Range.range_mm < (hlimit * AutoThreshLow) / 100 && scaling > 1 && State.AutoScale) {
VL6180_UpscaleSetScaling(theVL6180Dev, scaling - 1);
}
if (Range.errorStatus) {
/* no valid ranging*/
if (State.OutofRAnge) {
#if VL6180_HAVE_DMAX_RANGING
if (g_TickCnt - TimeStarted >= ErrRangeDispTime && g_TickCnt - TimeStarted < ErrRangeDispTime + DMaxDispTime ){
}
else
#endif
if(g_TickCnt - TimeStarted < ErrRangeDispTime )
{
}
else{
State.OutofRAnge=0; /* back to out of range display */
TimeStarted=g_TickCnt;
}
}
else {
int FilterEn;
#if VL6180_WRAP_AROUND_FILTER_SUPPORT
FilterEn = VL6180_FilterGetState(theVL6180Dev);
#else
#endif
if( g_TickCnt - TimeStarted > OutORangeDispfTime ) {
State.OutofRAnge = 1;
TimeStarted = g_TickCnt;
}
}
}
else {
State.OutofRAnge = 0;
TimeStarted = g_TickCnt;
range = (range * alpha + Range.range_mm * ((1 << 16) - alpha)) >> 16;
if (State.AutoScale) {
if (scaling == 1) {
buffer[0] = '_';
}
else
if (scaling == 2)
buffer[0] = '=';
else
buffer[0] = '~';
}
}
if (changeScale == 1) {
changeScale = 0;
TimeStarted = g_TickCnt;
State.ScaleSwapCnt++;
if (State.ScaleSwapCnt % (max_scale + 1) == max_scale) {
State.AutoScale = 1;
scaling = max_scale;
}
else {
#if ALLOW_DISABLE_WAF_FROM_BLUE_BUTTON
/* togle filtering every time we roll over all scaling(pass by autoscale) */
if (State.AutoScale)
State.FilterEn = !State.FilterEn;
#endif
State.AutoScale = 0;
scaling = State.InitScale + (State.ScaleSwapCnt % max_scale);
if (scaling > max_scale)
scaling = scaling - (max_scale);
}
status = VL6180_UpscaleSetScaling(theVL6180Dev, scaling);
if (status<0) {
AbortErr("ErUp");
State.mode = InitErr;
}
else {
/* do not check status may fail when filter support not active */
VL6180_FilterSetState(theVL6180Dev, State.FilterEn);
DoScalingSwap(scaling);
}
}
}
uint32_t resetPressedMs = 0;
uint8_t motionDetected = 0;
__weak void proximityMessureCompleted (void)
{
}
uint8_t getRange (VL6180_RangeData_t* range)
{
if (Range.errorStatus == 0)
{
*range = Range;
return 0;
}
else
{
range->range_mm = -1;
return 1;
}
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_0 && allowIT == 1)
{
RangeState();
proximityMessureCompleted();
VL6180_ClearAllInterrupt(theVL6180Dev);
}
else if (GPIO_Pin == GPIO_PIN_1)
{
uint32_t res = uwTick - resetPressedMs;
if (res > 2000 && resetPressedMs > 0 )
HAL_NVIC_SystemReset();
resetPressedMs = 0;
}
}
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_1)
{
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
{
resetPressedMs = uwTick;
}
}
}
/* USER CODE END 4 */
uint8_t vl6180_single_shot ()
{
VL6180_RangeStartSingleShot(theVL6180Dev);
}
int32_t vl6180_is_ready ()
{
return VL6180_RangeWaitDeviceReady(theVL6180Dev, 3);
}