2021-06-04 17:56:34 +08:00
|
|
|
#include "GSL61xx.h"
|
|
|
|
#include "GSL61xxCfg.h"
|
|
|
|
#include "hal_spi.h"
|
|
|
|
|
|
|
|
//#define DET_MEAN
|
|
|
|
#ifdef DET_MEAN
|
|
|
|
uint8_t DetMeanDown;
|
|
|
|
uint8_t DetMeanUp;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef TUNE_TEST
|
|
|
|
uint8_t DD[32];
|
|
|
|
uint8_t II;
|
|
|
|
#endif
|
|
|
|
GSL_FP_Data_T *GSL_FP;
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
GSL_FP_Data_T GSL_FP_6163 = {
|
|
|
|
{
|
|
|
|
Config_6163_NormalMode,
|
|
|
|
sizeof(Config_6163_NormalMode) / sizeof(Chip_Config_T),
|
|
|
|
},
|
|
|
|
{ 0xFF000020, 0xFF00002c, 0xFF08000c },
|
|
|
|
{ 120, 104, 120 * 104, { 10, 20, 40, 56, 70, 80, 112, 140 }, { 10, 20, 30, 40, 50, 60, 70, 80 } },
|
|
|
|
{ 0x07, 0xF0, 0x10 },
|
|
|
|
{ 80, 140, 0, 0, 0 },
|
|
|
|
{ 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
GSL_FP_Data_T GSL_FP_6163_00 = {
|
|
|
|
{
|
|
|
|
Config_6163_NormalMode_00,
|
|
|
|
sizeof(Config_6163_NormalMode_00) / sizeof(Chip_Config_T),
|
|
|
|
},
|
|
|
|
{ 0xFF000020, 0xFF00002c, 0xFF08000c },
|
|
|
|
{ 120, 104, 120 * 104, { 10, 20, 40, 56, 70, 80, 112, 140 }, { 10, 20, 30, 40, 50, 60, 70, 80 } },
|
|
|
|
{ 0x03, 0xF0, 0x10 },
|
|
|
|
{ 80, 140, 0, 0, 0 },
|
|
|
|
{ 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
GSL_FP_Data_T GSL_FP_6163_01 = {
|
|
|
|
{
|
|
|
|
Config_6163_NormalMode_01,
|
|
|
|
sizeof(Config_6163_NormalMode_01) / sizeof(Chip_Config_T),
|
|
|
|
},
|
|
|
|
{ 0xFF000020, 0xFF00002c, 0xFF08000c },
|
|
|
|
{ 120, 104, 120 * 104, { 10, 20, 40, 56, 70, 80, 112, 140 }, { 10, 20, 30, 40, 50, 60, 70, 80 } },
|
|
|
|
{ 0x07, 0xF0, 0x10 },
|
|
|
|
{ 80, 140, 0, 0, 0 },
|
|
|
|
{ 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
GSL_FP_Data_T GSL_FP_6163_02 = {
|
|
|
|
{
|
|
|
|
Config_6163_NormalMode_02,
|
|
|
|
sizeof(Config_6163_NormalMode_02) / sizeof(Chip_Config_T),
|
|
|
|
},
|
|
|
|
{ 0xFF000020, 0xFF00002c, 0xFF08000c },
|
|
|
|
{ 120, 104, 120 * 104, { 10, 20, 40, 56, 70, 80, 112, 140 }, { 10, 20, 30, 40, 50, 60, 70, 80 } },
|
|
|
|
{ 0x07, 0xF0, 0x10 },
|
|
|
|
{ 80, 140, 0, 0, 0 },
|
|
|
|
{ 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
GSL_FP_Data_T GSL_FP_6163_35 = {
|
|
|
|
{
|
|
|
|
Config_6163_NormalMode_35,
|
|
|
|
sizeof(Config_6163_NormalMode_35) / sizeof(Chip_Config_T),
|
|
|
|
},
|
|
|
|
{ 0xFF000020, 0xFF00002c, 0xFF08000c },
|
|
|
|
{ 120, 104, 120 * 104, { 10, 20, 40, 56, 70, 80, 112, 140 }, { 10, 20, 30, 40, 50, 60, 70, 80 } },
|
|
|
|
{ 0x03, 0xF0, 0x10 },
|
|
|
|
{ 60, 100, 0, 0, 0 },
|
|
|
|
{ 0, 0, 0 }
|
|
|
|
};
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
void GSL_FP_GetSetupData(uint32_t ChipID)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
if (0x35 == ((uint8_t)ChipID)) {
|
|
|
|
GSL_FP = &GSL_FP_6163_35;
|
|
|
|
} else if (0x02 == ((uint8_t)ChipID)) {
|
|
|
|
GSL_FP = &GSL_FP_6163_02;
|
|
|
|
} else if (0x01 == ((uint8_t)ChipID)) {
|
|
|
|
GSL_FP = &GSL_FP_6163_01;
|
|
|
|
} else if (0x00 == ((uint8_t)ChipID)) {
|
|
|
|
GSL_FP = &GSL_FP_6163_00;
|
|
|
|
} else {
|
|
|
|
GSL_FP = &GSL_FP_6163;
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t FP_Spi_WriteRead(uint8_t Data)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t Ret;
|
|
|
|
struct device *spi = device_find("spi");
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
spi = device_find("spi");
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
spi_transmit_receive(spi, &Data, &Ret, 1, 0);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
return Ret;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void FP_Spi_RegRead(uint8_t Addr, uint32_t *pData)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t Buf[4];
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_CS_ENABLE();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_WriteRead(Addr);
|
|
|
|
FP_Spi_WriteRead(0x00);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
Buf[0] = FP_Spi_WriteRead(0x00);
|
|
|
|
Buf[1] = FP_Spi_WriteRead(0x00);
|
|
|
|
Buf[2] = FP_Spi_WriteRead(0x00);
|
|
|
|
Buf[3] = FP_Spi_WriteRead(0x00);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
*pData = *((uint32_t *)Buf);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_CS_DISABLE();
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void FP_Spi_RegWrite(uint8_t Addr, uint32_t Data)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_CS_ENABLE();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_WriteRead(Addr);
|
|
|
|
FP_Spi_WriteRead(0xFF);
|
|
|
|
FP_Spi_WriteRead((uint8_t)((Data >> 0) & 0xFF));
|
|
|
|
FP_Spi_WriteRead((uint8_t)((Data >> 8) & 0xFF));
|
|
|
|
FP_Spi_WriteRead((uint8_t)((Data >> 16) & 0xFF));
|
|
|
|
FP_Spi_WriteRead((uint8_t)((Data >> 24) & 0xFF));
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_CS_DISABLE();
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void FP_Spi_Reg32Write(uint32_t Addr, uint32_t Data)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t Page = Addr / 0x80;
|
|
|
|
uint32_t Reg = Addr % 0x80;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_RegWrite(0xF0, Page);
|
|
|
|
FP_Spi_RegWrite((uint8_t)Reg, Data);
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_LoadConfig(Chip_Config_T *ChipConfig, uint32_t ConfigLen)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t i;
|
|
|
|
uint32_t Addr;
|
|
|
|
uint32_t Data;
|
|
|
|
Chip_Config_T *Config = ChipConfig;
|
|
|
|
|
|
|
|
for (i = 0; i < ConfigLen; i++, Config++) {
|
|
|
|
Addr = Config->Addr;
|
|
|
|
Data = Config->Data;
|
|
|
|
|
|
|
|
if (0 == (Addr & 0xff000000)) {
|
|
|
|
FP_Spi_RegWrite((uint8_t)Addr, Data);
|
|
|
|
} else {
|
|
|
|
FP_Spi_Reg32Write(Addr, Data);
|
|
|
|
}
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_ReadImageData(uint32_t Page, uint8_t Reg, uint8_t *Buf, uint32_t Len)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t i;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_RegWrite(0xF0, Page);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_CS_ENABLE();
|
|
|
|
bflb_platform_delay_us(SPI_DELAY);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_WriteRead(Reg);
|
|
|
|
FP_Spi_WriteRead(0x00);
|
|
|
|
FP_Spi_WriteRead(0x00);
|
|
|
|
bflb_platform_delay_us(10000);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
for (i = 0; i < GSL_FP->Sensor.ImageW * 2; i++) {
|
|
|
|
FP_Spi_WriteRead(0x00);
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
for (i = 0; i < Len; i++) {
|
|
|
|
Buf[i] = FP_Spi_WriteRead(0x00);
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_CS_DISABLE();
|
|
|
|
bflb_platform_delay_us(SPI_DELAY);
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_SensorReset(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_RST_LOW();
|
|
|
|
bflb_platform_delay_ms(2);
|
|
|
|
FP_RST_HIGH();
|
|
|
|
bflb_platform_delay_ms(6);
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_CaptureStart(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_RegWrite(0xBF, 0x00);
|
|
|
|
FP_Spi_Reg32Write(0xFF080024, 0x2000FFFF);
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t GSL_FP_GetCaptureStatus(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t Status = 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_RegRead(0xBF, &Status);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
return Status;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_WaitCaptureEnd(uint32_t bflb_platform_delay_msMS, uint32_t TimeOut)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t TryTime = 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
bflb_platform_delay_ms(SPI_DELAY);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
while (GSL_FP_GetCaptureStatus() != 1) {
|
|
|
|
if (TryTime++ > TimeOut) {
|
|
|
|
break;
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
bflb_platform_delay_ms(1);
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_ReadChipID(uint32_t *ChipID)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t i;
|
|
|
|
uint32_t Buf;
|
|
|
|
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
FP_Spi_RegRead(0xFC, &Buf);
|
|
|
|
|
|
|
|
if (0x61 == (Buf >> 24)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bflb_platform_delay_ms(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
*ChipID = Buf;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_SensorSetup(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
int i;
|
|
|
|
uint32_t ChipID;
|
|
|
|
Chip_Config_T *Config;
|
|
|
|
uint32_t ConfigLen;
|
|
|
|
|
|
|
|
GSL_FP_ReadChipID(&ChipID);
|
|
|
|
GSL_FP_GetSetupData(ChipID);
|
|
|
|
|
|
|
|
Config = GSL_FP->Config.Config_NormalMode;
|
|
|
|
ConfigLen = GSL_FP->Config.Config_NormalMode_Len;
|
|
|
|
|
|
|
|
for (i = 0; i < ConfigLen; i++, Config++) {
|
|
|
|
if (Config->Addr == GSL_FP->Reg.RegGain12) {
|
|
|
|
GSL_FP->Detect.DetGain12 = Config->Data;
|
|
|
|
GSL_FP->Capture.CapGain12 = Config->Data;
|
|
|
|
} else if (Config->Addr == GSL_FP->Reg.RegGain34) {
|
|
|
|
GSL_FP->Detect.DetGain34 = Config->Data;
|
|
|
|
GSL_FP->Capture.CapGain34 = Config->Data;
|
|
|
|
} else if (Config->Addr == GSL_FP->Reg.RegDac) {
|
|
|
|
GSL_FP->Detect.DetDac = Config->Data;
|
|
|
|
GSL_FP->Capture.CapDac = Config->Data;
|
|
|
|
}
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t GSL_FP_GetDacShift(uint32_t Gain12, uint32_t Gain34, uint8_t *Gain12R, uint8_t *Gain34R, uint32_t Ref)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t Gain2 = (uint8_t)((Gain12 >> 16) & 0x7);
|
|
|
|
uint8_t Gain3 = (uint8_t)(Gain34 & 0x7);
|
|
|
|
uint8_t Gain4 = (uint8_t)((Gain34 >> 8) & 0x7);
|
|
|
|
uint8_t Ref2 = (uint8_t)((Ref >> 4) & 0x7);
|
|
|
|
uint8_t Ref3 = (uint8_t)((Ref >> 8) & 0x7);
|
|
|
|
uint8_t Ref4 = (uint8_t)((Ref >> 12) & 0x7);
|
|
|
|
uint32_t DacShift;
|
|
|
|
|
|
|
|
DacShift = 374 * (Gain12R[Gain2] * Gain34R[Gain3] * Gain34R[Gain4]) / (Gain12R[Ref2] * Gain34R[Ref3] * Gain34R[Ref4]) / 100;
|
|
|
|
|
|
|
|
if (DacShift < 1) {
|
|
|
|
DacShift = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (uint8_t)DacShift;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_SensorTune(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t DacBase, DacDetect;
|
|
|
|
uint32_t Temp;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
#if 0
|
2021-06-20 12:25:46 +08:00
|
|
|
GSL_FP->Tune.DacShift = GSL_FP_GetDacShift(GSL_FP->Capture.CapGain12,
|
|
|
|
GSL_FP->Capture.CapGain34,
|
|
|
|
GSL_FP->Sensor.Gain12Ratio,
|
|
|
|
GSL_FP->Sensor.Gain34Ratio,
|
|
|
|
0x1227);
|
2021-06-04 17:56:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
DacBase = (GSL_FP->Capture.CapDac << 24) >> 24;
|
|
|
|
|
|
|
|
if (DacBase > DAC_TUNE_OFFSET_MIN) {
|
|
|
|
GSL_FP->Tune.DacMin = DacBase - DAC_TUNE_OFFSET_MIN;
|
|
|
|
} else {
|
|
|
|
GSL_FP->Tune.DacMin = 0x00;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DacBase < 0xFF - DAC_TUNE_OFFSET_MAX) {
|
|
|
|
GSL_FP->Tune.DacMax = DacBase + DAC_TUNE_OFFSET_MAX;
|
|
|
|
} else {
|
|
|
|
GSL_FP->Tune.DacMax = 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
Temp = 200 / GSL_FP->Tune.DacShift;
|
|
|
|
|
|
|
|
if (DacBase > Temp) {
|
|
|
|
DacDetect = DacBase - Temp;
|
|
|
|
} else {
|
|
|
|
DacDetect = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Temp = (GSL_FP->Detect.DetDac >> 8) << 8;
|
|
|
|
GSL_FP->Detect.DetDac = Temp + DacDetect;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t GSL_FP_DetectFingerDown(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t i, j;
|
|
|
|
uint8_t Buf[160];
|
|
|
|
uint8_t Mean;
|
|
|
|
uint32_t Temp;
|
|
|
|
uint32_t Page;
|
|
|
|
uint32_t Reg;
|
|
|
|
uint32_t ImageW = GSL_FP->Sensor.ImageW;
|
|
|
|
uint32_t ImageH = GSL_FP->Sensor.ImageH;
|
|
|
|
uint8_t DownCnt = 0;
|
|
|
|
|
|
|
|
FP_Spi_Reg32Write(GSL_FP->Reg.RegDac, GSL_FP->Detect.DetDac);
|
|
|
|
GSL_FP_CaptureStart();
|
|
|
|
GSL_FP_WaitCaptureEnd(5, 50);
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
Temp = (ImageH / 16 + i * (ImageH - ImageH / 8) / 3) * ImageW;
|
|
|
|
Page = Temp / 0x80;
|
|
|
|
Reg = Temp % 0x80;
|
|
|
|
|
|
|
|
GSL_FP_ReadImageData(Page, (uint8_t)Reg, Buf, ImageW);
|
|
|
|
|
|
|
|
for (Temp = 0, j = 0; j < ImageW; j++) {
|
|
|
|
Temp += Buf[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
Mean = (uint8_t)(Temp / ImageW);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
#ifdef DET_MEAN
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
if (Mean < DetMeanDown) {
|
|
|
|
DetMeanDown = Mean;
|
|
|
|
}
|
|
|
|
|
2021-06-04 17:56:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (Mean < GSL_FP->Detect.DownThreshold) {
|
|
|
|
DownCnt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DownCnt >= 3) {
|
|
|
|
return FINGER_DOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FINGER_UP;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t GSL_FP_DetectFingerUp(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t i, j;
|
|
|
|
uint8_t Buf[160];
|
|
|
|
uint8_t Mean;
|
|
|
|
uint32_t Temp;
|
|
|
|
uint32_t Page;
|
|
|
|
uint32_t Reg;
|
|
|
|
uint32_t ImageW = GSL_FP->Sensor.ImageW;
|
|
|
|
uint32_t ImageH = GSL_FP->Sensor.ImageH;
|
|
|
|
uint8_t UpCnt = 0;
|
|
|
|
|
|
|
|
FP_Spi_Reg32Write(GSL_FP->Reg.RegDac, GSL_FP->Detect.DetDac);
|
|
|
|
GSL_FP_CaptureStart();
|
|
|
|
GSL_FP_WaitCaptureEnd(5, 50);
|
|
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
Temp = (ImageH / 16 + i * (ImageH - ImageH / 8) / 3) * ImageW;
|
|
|
|
Page = Temp / 0x80;
|
|
|
|
Reg = Temp % 0x80;
|
|
|
|
|
|
|
|
GSL_FP_ReadImageData(Page, (uint8_t)Reg, Buf, ImageW);
|
|
|
|
|
|
|
|
for (Temp = 0, j = 0; j < ImageW; j++) {
|
|
|
|
Temp += Buf[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
Mean = (uint8_t)(Temp / ImageW);
|
2021-06-04 17:56:34 +08:00
|
|
|
#ifdef DET_MEAN
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
if (Mean > DetMeanUp) {
|
|
|
|
DetMeanUp = Mean;
|
|
|
|
}
|
|
|
|
|
2021-06-04 17:56:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (Mean > GSL_FP->Detect.UpThreshold) {
|
|
|
|
UpCnt++;
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (UpCnt >= 4) {
|
|
|
|
return FINGER_UP;
|
|
|
|
}
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
return FINGER_DOWN;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int GSL_FP_DacTune(uint8_t *Image, uint32_t Width, uint32_t Height, uint32_t *TuneDac)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
int i, j, n;
|
|
|
|
int Ret = 1;
|
|
|
|
uint8_t Dac = (uint8_t)((*TuneDac) & 0xFF);
|
|
|
|
uint8_t DacShift = GSL_FP->Tune.DacShift;
|
|
|
|
uint8_t DacMax = GSL_FP->Tune.DacMax;
|
|
|
|
uint8_t DacMin = GSL_FP->Tune.DacMin;
|
|
|
|
uint8_t DacOffset;
|
|
|
|
uint32_t StartX, StartY;
|
|
|
|
uint32_t Temp;
|
|
|
|
uint32_t Mean = 255;
|
|
|
|
|
|
|
|
for (n = 0; n < 5; n++) {
|
|
|
|
if (0 == n) {
|
|
|
|
StartX = (Width - TUNE_IMAGE_W) / 2;
|
|
|
|
StartY = (Height - TUNE_IMAGE_H) / 2;
|
|
|
|
} else if (1 == n) {
|
|
|
|
StartX = (Width - TUNE_IMAGE_W) / 4;
|
|
|
|
StartY = (Height - TUNE_IMAGE_H) / 4;
|
|
|
|
} else if (2 == n) {
|
|
|
|
StartX = (Width - TUNE_IMAGE_W) * 3 / 4;
|
|
|
|
StartY = (Height - TUNE_IMAGE_H) / 4;
|
|
|
|
} else if (3 == n) {
|
|
|
|
StartX = (Width - TUNE_IMAGE_W) / 4;
|
|
|
|
StartY = (Height - TUNE_IMAGE_H) * 3 / 4;
|
|
|
|
} else if (4 == n) {
|
|
|
|
StartX = (Width - TUNE_IMAGE_W) * 3 / 4;
|
|
|
|
StartY = (Height - TUNE_IMAGE_H) * 3 / 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
Temp = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < TUNE_IMAGE_H; i++) {
|
|
|
|
for (j = 0; j < TUNE_IMAGE_W; j++) {
|
|
|
|
Temp += Image[(StartY + i) * Width + StartX + j];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Temp /= TUNE_IMAGE_W * TUNE_IMAGE_H;
|
|
|
|
|
|
|
|
if (Temp < Mean) {
|
|
|
|
Mean = Temp;
|
|
|
|
}
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
#ifdef TUNE_TEST
|
2021-06-20 12:25:46 +08:00
|
|
|
DD[II++] = Dac;
|
|
|
|
DD[II++] = Mean;
|
2021-06-04 17:56:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (Mean < 100) {
|
|
|
|
DacOffset = (110 - Mean) / DacShift;
|
|
|
|
|
|
|
|
if (DacOffset > DAC_TUNE_STEP_MAX) {
|
|
|
|
DacOffset = DAC_TUNE_STEP_MAX;
|
|
|
|
} else if (DacOffset < 1) {
|
|
|
|
DacOffset = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Dac < 0xFF - DacOffset) {
|
|
|
|
Dac += DacOffset;
|
|
|
|
} else {
|
|
|
|
Dac = 0xFF;
|
|
|
|
}
|
|
|
|
} else if (Mean > 120) {
|
|
|
|
DacOffset = (Mean - 110) / DacShift;
|
|
|
|
|
|
|
|
if (DacOffset > DAC_TUNE_STEP_MAX) {
|
|
|
|
DacOffset = DAC_TUNE_STEP_MAX;
|
|
|
|
} else if (DacOffset < 1) {
|
|
|
|
DacOffset = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Dac > DacOffset) {
|
|
|
|
Dac -= DacOffset;
|
|
|
|
} else {
|
|
|
|
Dac = 0x00;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Dac < DacMin) {
|
|
|
|
Dac = DacMin;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Dac > DacMax) {
|
|
|
|
Dac = DacMax;
|
|
|
|
}
|
|
|
|
|
|
|
|
*TuneDac = ((*TuneDac) & 0xFFFFFF00) + Dac;
|
|
|
|
|
|
|
|
return Ret;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GSL_FP_CaptureImage(BYTE *pImageBmp)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
int Ret;
|
|
|
|
uint8_t CaptureCnt;
|
|
|
|
uint32_t TuneDac;
|
|
|
|
|
|
|
|
TuneDac = GSL_FP->Capture.CapDac;
|
|
|
|
|
|
|
|
for (CaptureCnt = 0; CaptureCnt < DAC_TUNE_CNT_MAX; CaptureCnt++) {
|
|
|
|
FP_Spi_Reg32Write(GSL_FP->Reg.RegDac, TuneDac);
|
|
|
|
GSL_FP_CaptureStart();
|
|
|
|
GSL_FP_WaitCaptureEnd(5, 50);
|
|
|
|
GSL_FP_ReadImageData(0, 0, pImageBmp, GSL_FP->Sensor.ImageSize);
|
|
|
|
Ret = GSL_FP_DacTune(pImageBmp, GSL_FP->Sensor.ImageW, GSL_FP->Sensor.ImageH, &TuneDac);
|
|
|
|
|
|
|
|
if (0 == Ret) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GSL_FP->Capture.CapDac = TuneDac;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void FP_GPIO_Configuration(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
gpio_set_mode(FP_CS_PIN, GPIO_OUTPUT_PP_MODE);
|
|
|
|
gpio_set_mode(FP_RESET_PIN, GPIO_OUTPUT_PP_MODE);
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t FP_Spi_Init()
|
|
|
|
{
|
2021-07-16 16:01:55 +08:00
|
|
|
spi_register(SPI0_INDEX, "spi");
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
struct device *spi = device_find("spi");
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
spi = device_find("spi");
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (spi) {
|
|
|
|
device_open(spi, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_STREAM_RX);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t GSL61xx_init(void)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_GPIO_Configuration();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_Spi_Init();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_CS_DISABLE();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
bflb_platform_delay_ms(1);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
GSL_FP_SensorReset();
|
|
|
|
GSL_FP_SensorSetup();
|
|
|
|
GSL_FP_SensorTune();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_RST_LOW();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
return 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
BYTE CaptureGSL61xx(BYTE *pImageBmp)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t WaitDownCnt;
|
|
|
|
|
|
|
|
/* 6C 63 62 10 D5 6C 63 62 D0 95 */
|
|
|
|
//memset(pImageBmp, 0xFF, GSL_FP->Capture.ImageSize);
|
|
|
|
GSL_FP_SensorReset();
|
|
|
|
GSL_FP_LoadConfig(GSL_FP->Config.Config_NormalMode, GSL_FP->Config.Config_NormalMode_Len);
|
|
|
|
|
|
|
|
for (WaitDownCnt = 0; WaitDownCnt < 3; WaitDownCnt++) {
|
|
|
|
if (GSL_FP_DetectFingerDown() != 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-04 17:56:34 +08:00
|
|
|
#ifdef TUNE_TEST
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
for (II = 0; II < 10; II++) {
|
|
|
|
DD[II] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
II = 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
GSL_FP_CaptureImage(pImageBmp);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
#if 0
|
2021-06-20 12:25:46 +08:00
|
|
|
{
|
|
|
|
uint32_t RR;
|
|
|
|
GSL_FP_ReadChipID(&RR);
|
|
|
|
pImageBmp[0] = (uint8_t)(RR >> 24);
|
|
|
|
pImageBmp[1] = (uint8_t)(RR >> 16);
|
|
|
|
pImageBmp[2] = (uint8_t)(RR >> 8);
|
|
|
|
pImageBmp[3] = (uint8_t)(RR >> 0);
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
FP_RST_LOW();
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
#ifdef TUNE_TEST
|
2021-06-20 12:25:46 +08:00
|
|
|
pImageBmp[0] = GSL_FP->Tune.DacShift;
|
|
|
|
|
|
|
|
for (II = 0; II < 10; II++) {
|
|
|
|
pImageBmp[1 + II] = DD[II];
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef DET_MEAN
|
2021-06-20 12:25:46 +08:00
|
|
|
pImageBmp[0] = DetMeanDown;
|
|
|
|
pImageBmp[1] = DetMeanUp;
|
|
|
|
pImageBmp[2] = 0xFF;
|
2021-06-04 17:56:34 +08:00
|
|
|
#endif
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
return 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|