1. 程式人生 > >缺少{}導致的camera 初始化 iic通訊失敗

缺少{}導致的camera 初始化 iic通訊失敗

   最近除錯一款攝像頭,prob時sensor id能正確讀到,但是進入camera時會出現寫camera sensor init失敗,

<3>[   66.087427] msm_cci_irq:854 MASTER_1 error 40000
<3>[   66.091294] msm_cci_irq:854 MASTER_1 error 20000
<3>[   66.095799] msm_cci_validate_queue failed rc -22
<3>[   66.100526] msm_cci_data_queue: failed 250
<3>[   66.104840] msm_camera_cci_i2c_write_table: line 200 rc = -22
<3>[   66.113033] msm_sensor_config:1292 ov5648_oty5f03 cfgtype = 6

根據經驗,只要id讀取正常,一般說明iic通訊沒有問題,查閱datasheet發現

error 40000 : This bit asserts when Queue#0 of I2C Master #1  overflows

error 20000 :This bit asserts when Queue#0 of I2C Master #1 underflows

初步可以認證是傳送iic 初始化隊列出現異常,或者iic寫初始化過程中出現異常,如沒有收到nack,但是master又一直再發送init引數給iic queue。

所以先從傳送佇列開始檢查,發現傳送主初始化引數前會先發送2個暫存器的寫操作,如下

static struct msm_camera_i2c_reg_array init_reg_array0[] = {
  {0x0100, 0x00},
  {0x0103, 0x01},
};

並沒有出現iic寫失敗,

但是寫主初始化就會異常,主初始化佇列如下:

static struct msm_camera_i2c_reg_array init_reg_array1[] = {

0x3001, 0x00, // D[7:0] set to input

0x3002, 0x00, // D[11:8] set to input
0x3011, 0x02, // Drive strength 2x
0x3017, 0x05, // AM05
0x3018, 0x4c, // MIPI 2 lane
0x301c, 0xd2, // AM05
0x3022, 0x00,
0x3034, 0x1a, // 10-bit mode
0x3035, 0x21, // PLL
0x3036, 0x7f, // PLL
0x3037, 0x03, // PLL
0x3038, 0x00, // PLL
0x3039, 0x00, // PLL
0x303a, 0x00, // PLLS
0x303b, 0x19, // PLLS
0x303c, 0x11, // PLLS
0x303d, 0x30, // PLLS
0x3105, 0x11,
0x3106, 0x05, // PLL
0x3304, 0x28,
0x3305, 0x41,
0x3306, 0x30,
0x3308, 0x00,
0x3309, 0xc8,
0x330a, 0x01,
0x330b, 0x90,
0x330c, 0x02,
0x330d, 0x58,
0x330e, 0x03,
0x330f, 0x20,
0x3300, 0x00,
0x3500, 0x00, // exposure [19:16]
0x3501, 0x3d, // exposure [15:8]
0x3502, 0x00, // exposure [7:0], exposure = 0x3d0 = 976
0x3503, 0x07, // gain has no delay, manual agc/aec
0x350a, 0x00, // gain[9:8]
0x350b, 0x40, // gain[7:0], gain = 4x
0x3601, 0x33, // analog control
0x3602, 0x00, // analog control
0x3611, 0x0e, // analog control
0x3612, 0x2b, // analog control
0x3614, 0x50, // analog control
0x3620, 0x33, // analog control
0x3622, 0x00, // analog control
0x3630, 0xad, // analog control
0x3631, 0x00, // analog control
0x3632, 0x94, // analog control
0x3633, 0x17, // analog control
0x3634, 0x14, // analog control
0x3704, 0xc0, // AM05
0x3705, 0x2a, // analog control
0x3708, 0x66, // analog control
0x3709, 0x52, // analog control
0x370b, 0x23, // analog control
0x370c, 0xc3, // analog control
0x370d, 0x00, // analog control
0x370e, 0x00, // analog control
0x371c, 0x07, // analog control
0x3739, 0xd2, // analog control
0x373c, 0x00,
0x3800, 0x00, // xstart = 0
0x3801, 0x00, // xstart
0x3802, 0x00, // ystart = 0
0x3803, 0x00, // ystart
0x3804, 0x0a, // xend = 2623
0x3805, 0x3f, // yend
0x3806, 0x07, // yend = 1955
0x3807, 0xa3, // yend
0x3808, 0x05, // x output size = 1296
0x3809, 0x10, // x output size
0x380a, 0x03, // y output size = 972
0x380b, 0xcc, // y output size
0x380c, 0x0b, // hts = 2816
0x380d, 0x00, // hts
0x380e, 0x03, // vts = 992
0x380f, 0xe0, // vts
0x3810, 0x00, // isp x win = 8
0x3811, 0x08, // isp x win
0x3812, 0x00, // isp y win = 4
0x3813, 0x04, // isp y win
0x3814, 0x31, // x inc
0x3815, 0x31, // y inc
0x3817, 0x00, // hsync start
0x3820, 0x08, // flip off, v bin off
0x3821, 0x07, // mirror on, h bin on
0x3826, 0x03,
0x3829, 0x00,
0x382b, 0x0b,
0x3830, 0x00,
0x3836, 0x00,
0x3837, 0x00,
0x3838, 0x00,
0x3839, 0x04,
0x383a, 0x00,
0x383b, 0x01,
0x3b00, 0x00, // strobe off
0x3b02, 0x08, // shutter delay
0x3b03, 0x00, // shutter delay
0x3b04, 0x04, // frex_exp
0x3b05, 0x00, // frex_exp
0x3b06, 0x04,
0x3b07, 0x08, // frex inv
0x3b08, 0x00, // frex exp req
0x3b09, 0x02, // frex end option
0x3b0a, 0x04, // frex rst length
0x3b0b, 0x00, // frex strobe width
0x3b0c, 0x3d, // frex strobe width
0x3f01, 0x0d,
0x3f0f, 0xf5,
0x4000, 0x89, // blc enable
0x4001, 0x02, // blc start line
0x4002, 0x45, // blc auto, reset frame number = 5
0x4004, 0x02, // black line number
0x4005, 0x18, // blc normal freeze
0x4006, 0x08,
0x4007, 0x10,
0x4008, 0x00,
0x4050, 0x6e, // AM05 blc level trigger
0x4051, 0x8f, // blc level trigger
0x4300, 0xf8,
0x4303, 0xff,
0x4304, 0x00,
0x4307, 0xff,
0x4520, 0x00,
0x4521, 0x00,
0x4511, 0x22,
0x4801, 0x0f, // AM05
0x4814, 0x2a, // AM05
0x481f, 0x3c, // MIPI clk prepare min
0x4823, 0x3c, // AM05
0x481b, 0x3c, // AM05
0x4826, 0x00, // MIPI hs prepare min
0x4827, 0x32, // AM05
0x4837, 0x18, // MIPI global timing
0x4b00, 0x06,
0x4b01, 0x0a,
0x4b04, 0x10, // AM05
0x5000, 0xff, // bpc on, wpc on
0x5001, 0x00, // awb disable
0x5002, 0x41, // win enable, awb gain enable
0x5003, 0x0a, // buf en, bin auto en
0x5004, 0x00, // size man off
0x5043, 0x00,
0x5013, 0x00,
0x501f, 0x03, // ISP output data
0x503d, 0x00, // test pattern off
0x5180, 0x08, // manual wb gain on
0x5a00, 0x08,
0x5b00, 0x01,
0x5b01, 0x40,
0x5b02, 0x00,
0x5b03, 0xf0,
0x0100, 0x01, // wake up from software sleep
0x301a, 0xf1, // MIPI stream off
0x301c, 0xd6, // clock lane in LP11 mode
0x350b, 0x80, // gain = 8x
0x4837, 0x18, // MIPI global timing

},

於是把以上主初始化佇列在啟動camera時打印出來,如下:

E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  0  addr 3001 data 0
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  1  addr 0 data 3011
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  2  addr 3017 data 5
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  3  addr 4c data 301c
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  4  addr 3022 data 0
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  5  addr 1a data 3035
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  6  addr 3036 data 7f
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  7  addr 3 data 3038
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  8  addr 3039 data 0

E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  9  addr 0 data 303b
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  10  addr 303c data 11
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  11  addr 30 data 3105
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  12  addr 3106 data 5
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  13  addr 28 data 3305
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  14  addr 3306 data 30
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  15  addr 0 data 3309
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  16  addr 330a data 1
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  17  addr 90 data 330c
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  18  addr 330d data 58
E/mm-camera-sensor(  272): sensor_write_init_settings:186  i  19  addr 3 data 330f

發現,會出現初始化引數會出現暫存器、資料交叉取錯的現象,初始化陣列元素結構如下

struct msm_camera_i2c_reg_array {
uint16_t reg_addr;
uint16_t reg_data;
};

所以,在陣列中需要 {暫存器地址,暫存器值} ,加上{}後,果然沒有出現暫存器、資料交叉取錯的現象,iic寫正常了。

但是其實需不需要加{},也要看編譯器優化等級,早期版本沒加{} iic 寫也是正常的,所以為了保險起見和編碼規範,還是加上{}。

至於為什麼會出現iic queue overflow,以下僅僅是推測:

ii2初始化時會設定addr_type、data_type分別為word 和 byte,一旦出現暫存器、資料交叉取錯的現象,就會導致addr 為byte,data為word,導致iic controller異常

static struct msm_camera_i2c_reg_setting init_reg_setting[] = {
  {
    .reg_setting = init_reg_array,
    .size = ARRAY_SIZE(init_reg_array),
    .addr_type = MSM_CAMERA_I2C_WORD_ADDR,
    .data_type = MSM_CAMERA_I2C_BYTE_DATA,
    .delay = 0,
  },
};