官方淘宝店 易迪拓培训 旧站入口
首页 > 手机设计 > MTK手机设计平台 > 6735闪光灯调试遇到问题

6735闪光灯调试遇到问题

05-08
现在6735的平台上调试闪光灯,发现闪光灯工作不正常,首先在系统自带的手电筒的时候会快闪一下然后灭掉,偶尔也能亮,但过几秒亮度会按下来,打开手电筒的时候不管他亮不亮都无法进入摄像头,显示无法连接到相机。关了手电筒进入摄像头的预览的对焦的时候有时候也是快闪一下灭掉,有时候则是闪光灯不灭了,一直亮着,然后摄像头就卡死了,我们用的闪光灯控制IC是SGM3780,有没有哪位朋友遇到过的或者知道是怎么回事的,麻烦帮忙看看,谢谢了!

闪光灯原理图...

闪光灯原理图


#include <linux/kernel.h> //constant xx
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <linux/time.h>
#include "kd_flashlight.h"
#include <asm/io.h>
#include <asm/uaccess.h>
#include "kd_camera_hw.h"
#include <cust_gpio_usage.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include <linux/xlog.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
#include <linux/mutex.h>
#else
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#include <linux/semaphore.h>
#else
#include <asm/semaphore.h>
#endif
#endif

/******************************************************************************
* Debug configuration
******************************************************************************/
// availible parameter
// ANDROID_LOG_ASSERT
// ANDROID_LOG_ERROR
// ANDROID_LOG_WARNING
// ANDROID_LOG_INFO
// ANDROID_LOG_DEBUG
// ANDROID_LOG_VERBOSE
#define TAG_NAME "[leds_strobe.c]"
#define PK_DBG_NONE(fmt, arg...) do {} while (0)
#define PK_DBG_FUNC(fmt, arg...) pr_debug(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
#define PK_WARN(fmt, arg...) pr_warning(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
#define PK_NOTICE(fmt, arg...) pr_notice(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
#define PK_INFO(fmt, arg...) pr_info(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)
#define PK_TRC_FUNC(f) pr_debug(TAG_NAME "<%s>\n", __FUNCTION__)
#define PK_TRC_VERBOSE(fmt, arg...) pr_debug(TAG_NAME fmt, ##arg)
#define PK_ERROR(fmt, arg...) pr_err(TAG_NAME "%s: " fmt, __FUNCTION__ ,##arg)

#define DEBUG_LEDS_STROBE
#ifdef DEBUG_LEDS_STROBE
#define PK_DBG PK_DBG_FUNC
#define PK_VER PK_TRC_VERBOSE
#define PK_ERR PK_ERROR
#else
#define PK_DBG(a,...)
#define PK_VER(a,...)
#define PK_ERR(a,...)
#endif
/******************************************************************************
* local variables
******************************************************************************/
static DEFINE_SPINLOCK(g_strobeSMPLock); /* cotta-- SMP proection */

static u32 strobe_Res = 0;
static u32 strobe_Timeus = 0;
static BOOL g_strobe_On = 0;
static int g_duty=-1;
static int g_timeOutTimeMs=0;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
static DEFINE_MUTEX(g_strobeSem);
#else
static DECLARE_MUTEX(g_strobeSem);
#endif

#define STROBE_DEVICE_ID 0xC6

static struct work_struct workTimeOut;
/*****************************************************************************
Functions
*****************************************************************************/
#ifdef GPIO_CAMERA_FLASH_EN_PIN
#define GPIO_ENF GPIO_CAMERA_FLASH_EN_PIN
#else
#define GPIO_ENF 0xFF
#endif
#ifdef GPIO_CAMERA_FLASH_MODE_PIN
#define GPIO_ENT GPIO_CAMERA_FLASH_MODE_PIN
#define GPIO_ENT_IS_AVALIABLE 1
#else
#define GPIO_ENT 0xFF
#define GPIO_ENT_IS_AVALIABLE 0
#endif
/*CAMERA-FLASH-EN */

extern int iWriteRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u16 i2cId);
extern int iReadRegI2C(u8 *a_pSendData , u16 a_sizeSendData, u8 * a_pRecvData, u16 a_sizeRecvData, u16 i2cId);
static void work_timeOutFunc(struct work_struct *data);

int FL_Enable(void)
{
/* if(g_duty==0)
{
mt_set_gpio_out(GPIO_ENT,GPIO_OUT_ONE);
mt_set_gpio_out(GPIO_ENF,GPIO_OUT_ZERO);
PK_DBG(" FL_Enable line=%d\n",__LINE__);
}
else */
{
mt_set_gpio_out(GPIO_ENT,GPIO_OUT_ZERO);
mt_set_gpio_out(GPIO_ENF,GPIO_OUT_ONE);
PK_DBG(" FL_Enable line=%d\n",__LINE__);
}
return 0;
}
int FL_Disable(void)
{
mt_set_gpio_out(GPIO_ENT,GPIO_OUT_ZERO);
mt_set_gpio_out(GPIO_ENF,GPIO_OUT_ZERO);
PK_DBG(" FL_Disable line=%d\n",__LINE__);
return 0;
}
int FL_dim_duty(kal_uint32 duty)
{
g_duty=duty;
PK_DBG(" FL_dim_duty line=%d\n",__LINE__);
return 0;
}

int FL_Init(void)
{

if(mt_set_gpio_mode(GPIO_ENF,GPIO_MODE_00)){PK_DBG("[constant_flashlight] set gpio mode failed! \n");}
if(mt_set_gpio_dir(GPIO_ENF,GPIO_DIR_OUT)){PK_DBG("[constant_flashlight] set gpio dir failed! \n");}
if(mt_set_gpio_out(GPIO_ENF,GPIO_OUT_ZERO)){PK_DBG("[constant_flashlight] set gpio failed! \n");}
/*Init. to disable*/
if(mt_set_gpio_mode(GPIO_ENT,GPIO_MODE_00)){PK_DBG("[constant_flashlight] set gpio mode failed! \n");}
if(mt_set_gpio_dir(GPIO_ENT,GPIO_DIR_OUT)){PK_DBG("[constant_flashlight] set gpio dir failed! \n");}
if(mt_set_gpio_out(GPIO_ENT,GPIO_OUT_ZERO)){PK_DBG("[constant_flashlight] set gpio failed! \n");}
INIT_WORK(&workTimeOut, work_timeOutFunc);
PK_DBG(" FL_Init line=%d\n",__LINE__);
return 0;
}

int FL_Uninit(void)
{
FL_Disable();
return 0;
}
/*****************************************************************************
User interface
*****************************************************************************/
static void work_timeOutFunc(struct work_struct *data)
{
FL_Disable();
PK_DBG("ledTimeOut_callback\n");
//printk(KERN_ALERT "work handler function./n");
}

enum hrtimer_restart ledTimeOutCallback(struct hrtimer *timer)
{
schedule_work(&workTimeOut);
return HRTIMER_NORESTART;
}
static struct hrtimer g_timeOutTimer;
void timerInit(void)
{
g_timeOutTimeMs=1000; //1s
hrtimer_init( &g_timeOutTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
g_timeOutTimer.function=ledTimeOutCallback;
}

static int constant_flashlight_ioctl(unsigned int cmd, unsigned long arg)
{
int i4RetValue = 0;
int ior_shift;
int iow_shift;
int iowr_shift;
ior_shift = cmd - (_IOR(FLASHLIGHT_MAGIC,0, int));
iow_shift = cmd - (_IOW(FLASHLIGHT_MAGIC,0, int));
iowr_shift = cmd - (_IOWR(FLASHLIGHT_MAGIC,0, int));
PK_DBG("constant_flashlight_ioctl() line=%d ior_shift=%d, iow_shift=%d iowr_shift=%d arg=%d\n",__LINE__, ior_shift, iow_shift, iowr_shift, (int)arg);
switch(cmd)
{
case FLASH_IOC_SET_TIME_OUT_TIME_MS:
PK_DBG("FLASH_IOC_SET_TIME_OUT_TIME_MS: %d\n",(int)arg);
g_timeOutTimeMs=arg;
break;

case FLASH_IOC_SET_DUTY :
PK_DBG("FLASHLIGHT_DUTY: %d\n",(int)arg);
FL_dim_duty(arg);
break;

case FLASH_IOC_SET_STEP:
PK_DBG("FLASH_IOC_SET_STEP: %d\n",(int)arg);
break;
case FLASH_IOC_SET_ONOFF :
PK_DBG("FLASHLIGHT_ONOFF: %d\n",(int)arg);
if(arg==1)
{
int s;
int ms;
if(g_timeOutTimeMs>1000)
{
s = g_timeOutTimeMs/1000;
ms = g_timeOutTimeMs - s*1000;
}
else
{
s = 0;
ms = g_timeOutTimeMs;
}
if(g_timeOutTimeMs!=0)
{
ktime_t ktime;
ktime = ktime_set( s, ms*1000000 );
hrtimer_start( &g_timeOutTimer, ktime, HRTIMER_MODE_REL );
}
FL_Enable();
}
else
{
FL_Disable();
hrtimer_cancel( &g_timeOutTimer );
}
break;
default :
PK_DBG(" No such command \n");
i4RetValue = -EPERM;
break;
}
return i4RetValue;
}

static int constant_flashlight_open(void *pArg)
{
int i4RetValue = 0;
PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
if (0 == strobe_Res)
{
FL_Init();
timerInit();
}
PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
spin_lock_irq(&g_strobeSMPLock);

if(strobe_Res)
{
PK_ERR(" busy!\n");
i4RetValue = -EBUSY;
}
else
{
strobe_Res += 1;
}

spin_unlock_irq(&g_strobeSMPLock);
PK_DBG("constant_flashlight_open line=%d\n", __LINE__);
return i4RetValue;
}

static int constant_flashlight_release(void *pArg)
{
PK_DBG(" constant_flashlight_release\n");
if (strobe_Res)
{
spin_lock_irq(&g_strobeSMPLock);
strobe_Res = 0;
strobe_Timeus = 0;
/* LED On Status */
g_strobe_On = FALSE;
spin_unlock_irq(&g_strobeSMPLock);
FL_Uninit();
}
PK_DBG(" Done\n");
return 0;
}

FLASHLIGHT_FUNCTION_STRUCT constantFlashlightFunc=
{
constant_flashlight_open,
constant_flashlight_release,
constant_flashlight_ioctl
};

MUINT32 constantFlashlightInit(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc)
{
if (pfFunc != NULL)
{
*pfFunc = &constantFlashlightFunc;
}
return 0;
}

/* LED flash control for high current capture mode*/
ssize_t strobe_VDIrq(void)
{
return 0;
}
EXPORT_SYMBOL(strobe_VDIrq);
以上是闪光灯的驱动代码。麻烦各位帮忙分析一下,,谢谢!

1、确认闪光灯物料。闪光灯物料If电流是多少?正负反了没?并用个电源限流(一定要限流)点下正负极保证闪光灯正常。
2、确认芯片工作时序。用示波器测量下U1302第10、11PIN手电和闪光时序对不对。TDFN封装可以飞线的。
3、确认R1301,R1302阻值对照规格书算下电流是否与灯过流能力匹配。
纯硬件分析,以上三点确认完这个料基本工作就没问题。至于你后面ENM要给怎么样的信号那是后话。
开手电筒再进相机这流程不对吧,打开手电的时候就会调用到相机流程,你再去开已经被占用的相机,应该是无法连接的嘛,请软件大神来分析下

量下闪光灯的两个使能脚在工作是的点平状态对不对,从你的描述来看应该是软件bug,看下那两个使能脚有没有在其他地方被复用过。还有你们手电筒模式的电流太大了,采样电阻再改小一点,改个100K还差不多。

两个使能脚的电平是正常的,可以正常拉高拉低。

看逻辑对不对,没让你看能不能正常拉高拉低

感觉GPIO口在哪里被复用了,看看能不能飞到另外一个GPIO口上试试

gpio口没有复用,也能正常拉高拉低,例如我打开手电筒的时候GPIO_FLASH_STROBE这个脚就会拉高,但闪光灯也还是快闪一下就灭了,灭了之后再去量这个脚的电平还是高电平,只有把手电筒关了,电平才会是低电平。

2. Flashlight IC通常会存在低亮和高亮两种模式:

(1) 低亮: 电流低, 持续输出恒定电流, 适用于需要常亮的模式下.

(2) 高亮: 高电流, 瞬间输出电流,不可以持续输出,适用于主闪.

3. 如果常亮模式使用高电流,为了防止烧掉自己,IC会启动自我保护,出现以下异常现象:

(1) 终止电流输出: 闪灯会自己灭掉.

(2)终止输出高电流,更改为低电流: 闪灯先亮后暗.

很可能你torch mode和flash mode配错了

感谢各位的解答,问题终于解决了,首先是把闪光灯换了,开始我们的闪光灯只能通过恒定电流是150MA,换成500MA的就发现正常了,但我们测电流发现增加的比较多,有八九百毫安了,后来又把电阻换成47K的,发现就都正常了。

虚惊一场

............

Top