534 lines
13 KiB
C
534 lines
13 KiB
C
/**
|
||
******************************************************************************
|
||
* @file scanmode.c
|
||
* @author TMC Scan Team
|
||
* @version V1.0.0
|
||
* @date 09/06/2019
|
||
* @brief This file provides the different modes of scanning.
|
||
******************************************************************************
|
||
*
|
||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||
* TIME. AS A RESULT, TMC SHALL NOT BE HELD LIABLE FOR ANY
|
||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||
*
|
||
* <h2><center>© COPYRIGHT 2016 TMC</center></h2>
|
||
******************************************************************************
|
||
**/
|
||
|
||
#include "global.h"
|
||
|
||
uint8_t gAutoModeOverTimeFlag = TRUE; //连续模式下,同码延时和异码延时,第一次解码不需要延时;或者扫码一直不成功,定时器如果超时,解码也不需要延时
|
||
uint8_t gCmdStartFlag = FALSE; //命令模式下,开启扫码命令标记;FALSE表示禁止扫码,TRUE表示使能扫码
|
||
uint8_t gSensorChangeFlag = FALSE; //环境变化标记,FALSE表明环境无变化,TRUE表明环境有变化
|
||
ImageSizeType gLastPictureSize = DCMI_640_480; //感应模式下上一次采图标记,感知环境变化时由于RAM不足,需要采集小图;当进入解码状态时,采集图像尺寸恢复到640*480
|
||
uint32_t gCurrentPictureAddr = DCMIBUFADDR; //感应模式下,需要采集两张图像,标记当前采集图像的地址
|
||
uint8_t gPreImage[MAXCODELEN] = {0};
|
||
uint32_t gPrebarcodelen = 0;
|
||
int gPreCodeType = Communication_Id;
|
||
uint8_t gCmdModeTimeFlag = FALSE; //命令模式下,定时器开启标志,默认未开启
|
||
extern uint8_t gLicenseFlag;
|
||
extern uint32_t gFunTrace;
|
||
|
||
/**
|
||
* @function AppScanModeInit
|
||
* @brief 配置识读模块的初始条件
|
||
* @param[in] 无
|
||
* @return 无
|
||
*/
|
||
void AppScanModeInit(void)
|
||
{
|
||
switch(gConfgBuf.scanCodeMode)
|
||
{
|
||
case AUTOMODE:
|
||
gAutoModeOverTimeFlag = TRUE;
|
||
break;
|
||
|
||
case CMDMODE:
|
||
gCmdStartFlag = TRUE; //命令模式下,开启扫码命令标记;FALSE表示禁止扫码,TRUE表示使能扫码
|
||
break;
|
||
|
||
case CMDTIMEMODE:
|
||
gCmdStartFlag = FALSE; //命令模式下,开启扫码命令标记;FALSE表示禁止扫码,TRUE表示使能扫码
|
||
break;
|
||
|
||
case SENSORMODE:
|
||
gAutoModeOverTimeFlag = TRUE;
|
||
gSensorChangeFlag = FALSE; //环境变化标记,FALSE表明环境无变化,TRUE表明环境有变化
|
||
gLastPictureSize = DCMI_640_480;
|
||
gCurrentPictureAddr = DCMIBUFADDR;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function AutoScanMode
|
||
* @brief 连续模式,一直处于解码状态
|
||
* @param[in] BarData 结构体,存放解码数据
|
||
* @return 返回值为正,则为成功解码
|
||
*/
|
||
int AutoScanMode(BarData *pCode)
|
||
{
|
||
int result = 0;
|
||
|
||
//灯光控制
|
||
AppLEDControl(gConfgBuf.ledStatus);
|
||
//采集图像
|
||
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
|
||
//解码
|
||
result = TMC_Scan_Decode(pCode);
|
||
|
||
if(result > 0)
|
||
{
|
||
if(gPrebarcodelen && (gPrebarcodelen == pCode->datalen))
|
||
{
|
||
if(!memcmp(gPreImage, pCode->bardata, pCode->datalen))
|
||
{
|
||
//同码延时,定时器时间大于延时,输出;或者超时标记为真
|
||
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE)))
|
||
{
|
||
gPrebarcodelen = pCode->datalen;
|
||
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
|
||
gAutoModeOverTimeFlag = FALSE;
|
||
TimerHSIClockCount(TIM4, STOP_TIMER);
|
||
TimerHSIClockCount(TIM4, START_TIMER);
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
}
|
||
|
||
//异码延时,定时器时间大于延时,输出;或者超时标记为真
|
||
|
||
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
|
||
{
|
||
gPrebarcodelen = pCode->datalen;
|
||
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
|
||
gAutoModeOverTimeFlag = FALSE;
|
||
TimerHSIClockCount(TIM4, STOP_TIMER);
|
||
TimerHSIClockCount(TIM4, START_TIMER);
|
||
return TRUE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if((TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE))
|
||
&& (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
|
||
{
|
||
gAutoModeOverTimeFlag = TRUE;
|
||
}
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
/**
|
||
* @function CmdScanMode
|
||
* @brief 命令模式,如果接收到开启扫码命令,才开始解码
|
||
* @param[in] BarData 结构体,存放解码数据
|
||
* @return 返回值为正,则为成功解码
|
||
*/
|
||
int CmdScanMode(BarData *pCode)
|
||
{
|
||
int result = 0;
|
||
|
||
//判断是否收到解码命令
|
||
if(gCmdStartFlag)
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(gConfgBuf.ledStatus);
|
||
//采集图像
|
||
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
|
||
//解码
|
||
result = TMC_Scan_Decode(pCode);
|
||
|
||
//识读成功
|
||
if(result > 0)
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
|
||
//记录码制类型
|
||
gPreCodeType = pCode->bartype;
|
||
//清除命令标记
|
||
gCmdStartFlag = FALSE; //关闭扫码
|
||
TimerHSIClockCount(TIM5, STOP_TIMER);
|
||
return result;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* @function CmdScanTimeMode
|
||
* @brief 命令超时模式,如果接收到开启扫码命令,才开始解码,如果超时则自动关闭扫码
|
||
* @param[in] BarData 结构体,存放解码数据
|
||
* @return 返回值为正,则为成功解码
|
||
*/
|
||
int CmdScanTimeMode(BarData *pCode)
|
||
{
|
||
int result = 0;
|
||
|
||
//判断是否收到解码命令
|
||
if(gCmdStartFlag)
|
||
{
|
||
//如果开启定时,并且时间未超时,则扫码
|
||
if(TimerHSIClockCount(TIM5, GET_TIMER) <= gConfgBuf.cmdModeTime * 12000)
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(gConfgBuf.ledStatus);
|
||
//采集图像
|
||
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
|
||
//解码
|
||
result = TMC_Scan_Decode(pCode);
|
||
|
||
//识读成功
|
||
if(result > 0)
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
|
||
//记录码制类型
|
||
gPreCodeType = pCode->bartype;
|
||
//清除命令标记
|
||
gCmdStartFlag = FALSE; //关闭扫码
|
||
TimerHSIClockCount(TIM5, STOP_TIMER);
|
||
return result;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//超时则关闭扫码
|
||
gCmdStartFlag = FALSE;
|
||
TimerHSIClockCount(TIM5, STOP_TIMER);
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
#ifdef LIGHTING
|
||
|
||
/**
|
||
* @function SensorScanMode
|
||
* @brief 感应模式,如果感应环境有变化,再开启解码
|
||
* @param[in] BarData 结构体,存放解码数据
|
||
* @return 返回值为正,则为成功解码
|
||
*/
|
||
int SensorScanMode(BarData *pCode)
|
||
{
|
||
int result = 0;
|
||
|
||
//环境是否有变化,默认值是"无变化"
|
||
if(!gSensorChangeFlag) //环境无变化
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
|
||
//判断上一次采图尺寸是否为640*480,是的情况下需要采两张图
|
||
if(gLastPictureSize == DCMI_640_480)
|
||
{
|
||
TimerDelay(TIM2, gConfgBuf.stableTime);
|
||
gLastPictureSize = DCMI_320_240;
|
||
gCurrentPictureAddr = DCMIBUFADDR;
|
||
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
|
||
gCurrentPictureAddr += HALF_BUF_SIZE;
|
||
}
|
||
|
||
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
|
||
|
||
if(gCurrentPictureAddr == DCMIBUFADDR)
|
||
{
|
||
gCurrentPictureAddr += HALF_BUF_SIZE;
|
||
}
|
||
else
|
||
{
|
||
gCurrentPictureAddr = DCMIBUFADDR;
|
||
}
|
||
|
||
//图像差异明显?
|
||
if(DCMI_Differ(HALF_BUF_SIZE) == TMC_OK)
|
||
{
|
||
gSensorChangeFlag = TRUE;
|
||
gLastPictureSize = DCMI_640_480;
|
||
TimerHSIClockCount(TIM5, START_TIMER);
|
||
}
|
||
else
|
||
{
|
||
return result;
|
||
}
|
||
}
|
||
|
||
//环境有变化
|
||
//灯光控制
|
||
AppLEDControl(gConfgBuf.ledStatus);
|
||
//图像采集
|
||
if(!DCMI_CaptureOnePic(DCMIBUFADDR, gLastPictureSize))return FALSE;
|
||
//解码
|
||
result = TMC_Scan_Decode(pCode);
|
||
|
||
//识读成功 或 超时
|
||
if(result > 0)
|
||
{
|
||
if(gPrebarcodelen && (gPrebarcodelen == pCode->datalen))
|
||
{
|
||
if(!memcmp(gPreImage, pCode->bardata, pCode->datalen))
|
||
{
|
||
//同码延时,定时器时间大于延时,输出;或者超时标记为真
|
||
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE)))
|
||
{
|
||
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
|
||
gPrebarcodelen = pCode->datalen;
|
||
gAutoModeOverTimeFlag = FALSE;
|
||
TimerHSIClockCount(TIM4, STOP_TIMER);
|
||
TimerHSIClockCount(TIM4, START_TIMER);
|
||
TimerHSIClockCount(TIM5, STOP_TIMER);
|
||
gSensorChangeFlag = FALSE;
|
||
return TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
//异码延时,定时器时间大于延时,输出;或者超时标记为真
|
||
if((gAutoModeOverTimeFlag == TRUE) || (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
|
||
{
|
||
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
|
||
gPrebarcodelen = pCode->datalen;
|
||
gAutoModeOverTimeFlag = FALSE;
|
||
TimerHSIClockCount(TIM4, STOP_TIMER);
|
||
TimerHSIClockCount(TIM4, START_TIMER);
|
||
TimerHSIClockCount(TIM5, STOP_TIMER);
|
||
gSensorChangeFlag = FALSE;
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
else
|
||
{
|
||
if((TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.sameCodeInterval * CLK_BASE)) && (TimerHSIClockCount(TIM4, GET_TIMER) >= (gConfgBuf.differentCodeInterval * CLK_BASE)))
|
||
{
|
||
gAutoModeOverTimeFlag = TRUE;
|
||
TimerHSIClockCount(TIM4, STOP_TIMER);
|
||
}
|
||
}
|
||
|
||
if ((TimerHSIClockCount(TIM5, GET_TIMER) >= SENSOR_TIME_OUT))
|
||
{
|
||
TimerHSIClockCount(TIM5, STOP_TIMER);
|
||
gSensorChangeFlag = FALSE;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
#else
|
||
|
||
/**
|
||
* @function SensorScanMode
|
||
* @brief 感应模式,如果感应环境有变化,再开启解码
|
||
* @param[in] BarData 结构体,存放解码数据
|
||
* @return 返回值为正,则为成功解码
|
||
*/
|
||
int SensorScanMode(BarData *pCode)
|
||
{
|
||
int result = 0;
|
||
|
||
//环境是否有变化,默认值是"无变化"
|
||
if(!gSensorChangeFlag) //环境无变化
|
||
{
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
|
||
//判断上一次采图尺寸是否为640*480,是的情况下需要采两张图
|
||
if(gLastPictureSize == DCMI_640_480)
|
||
{
|
||
gLastPictureSize = DCMI_320_240;
|
||
gCurrentPictureAddr = DCMIBUFADDR;
|
||
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
|
||
gCurrentPictureAddr += HALF_BUF_SIZE;
|
||
}
|
||
|
||
if(!DCMI_CaptureOnePic(gCurrentPictureAddr, gLastPictureSize))return FALSE;
|
||
|
||
if(gCurrentPictureAddr == DCMIBUFADDR)
|
||
{
|
||
gCurrentPictureAddr += HALF_BUF_SIZE;
|
||
}
|
||
else
|
||
{
|
||
gCurrentPictureAddr = DCMIBUFADDR;
|
||
}
|
||
|
||
//图像差异明显?
|
||
if(DCMI_Differ(HALF_BUF_SIZE) == TMC_OK)
|
||
{
|
||
gSensorChangeFlag = TRUE;
|
||
gLastPictureSize = DCMI_640_480;
|
||
TimerHSIClockCount(TIM4, START_TIMER);
|
||
memset(gPreImage, 0, MAXCODELEN);
|
||
}
|
||
else
|
||
{
|
||
return result;
|
||
}
|
||
}
|
||
|
||
//环境有变化
|
||
//灯光控制
|
||
AppLEDControl(gConfgBuf.ledStatus);
|
||
//图像采集
|
||
if(!DCMI_CaptureOnePic(DCMIBUFADDR, gLastPictureSize))return FALSE;
|
||
//解码
|
||
result = TMC_Scan_Decode(pCode);
|
||
|
||
//识读成功 或 超时
|
||
if(result > 0)
|
||
{
|
||
if(!memcmp(gPreImage, pCode->bardata, pCode->datalen)) //如果成功,相同条码延时
|
||
{
|
||
TimerHSIClockCount(TIM4, START_TIMER);
|
||
return FALSE;
|
||
}
|
||
else
|
||
{
|
||
Memcpy(gPreImage, pCode->bardata, pCode->datalen);
|
||
TimerHSIClockCount(TIM4, START_TIMER);
|
||
return TRUE;
|
||
}
|
||
}
|
||
|
||
if(TimerHSIClockCount(TIM4, GET_TIMER) >= TIME_OUT)
|
||
{
|
||
gSensorChangeFlag = FALSE;
|
||
//灯光控制
|
||
AppLEDControl(!gConfgBuf.ledStatus);
|
||
TimerHSIClockCount(TIM4, STOP_TIMER);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
#endif
|
||
|
||
/**
|
||
* @function SingleMode
|
||
* @brief 扫码成功一次,移开,再移入才成功
|
||
* @param[in] BarData 结构体,存放解码数据
|
||
* @return 返回值为正,则为成功解码
|
||
*/
|
||
int SingleMode(BarData *pCode)
|
||
{
|
||
int result = 0;
|
||
//灯光控制
|
||
AppLEDControl(gConfgBuf.ledStatus);
|
||
//采集图像
|
||
if(!DCMI_CaptureOnePic(DCMIBUFADDR, DCMI_640_480))return FALSE;
|
||
//解码
|
||
result = TMC_Scan_Decode(pCode);
|
||
|
||
//识读成功
|
||
if(result > 0)
|
||
{
|
||
//长度相等
|
||
if(gPrebarcodelen && (gPrebarcodelen == pCode->datalen))
|
||
{
|
||
if(memcmp(pCode->bardata, gPreImage, gPrebarcodelen)) //码不同
|
||
{
|
||
gPrebarcodelen = pCode->datalen;
|
||
memcpy(gPreImage, pCode->bardata, gPrebarcodelen);
|
||
return TRUE;
|
||
}
|
||
}
|
||
else //长度不等,码不同
|
||
{
|
||
gPrebarcodelen = pCode->datalen;
|
||
memcpy(gPreImage, pCode->bardata, gPrebarcodelen);
|
||
return TRUE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
gPrebarcodelen = 0;
|
||
memset(gPreImage, 0, MAXCODELEN);
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
/**
|
||
* @function ScanModeReceiveData
|
||
* @brief 扫码模块
|
||
* @param[in] BarData 结构体,存放解码数据
|
||
* @return TRUE 解码成功
|
||
* FALSE 解码失败
|
||
*/
|
||
uint8_t ScanModeReceiveData(BarData *bardata)
|
||
{
|
||
int ret = 0;
|
||
|
||
if(gLicenseFlag)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
gFunTrace = 36;
|
||
|
||
switch(gConfgBuf.scanCodeMode)
|
||
{
|
||
case AUTOMODE:
|
||
ret = AutoScanMode(bardata);
|
||
break;
|
||
|
||
case CMDMODE: //命令模式
|
||
ret = CmdScanMode(bardata);
|
||
break;
|
||
|
||
case CMDTIMEMODE: //命令时间模式
|
||
ret = CmdScanTimeMode(bardata);
|
||
break;
|
||
|
||
case SENSORMODE://感应模式
|
||
ret = SensorScanMode(bardata);
|
||
break;
|
||
|
||
case SINGLEMODE: //单次模式
|
||
ret = SingleMode(bardata);
|
||
break;
|
||
|
||
default:
|
||
ret = AutoScanMode(bardata);
|
||
break;
|
||
}
|
||
|
||
if(ret > 0)
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|