调试扫描头
Android版本:4.4
?
前前后后調試了快一個月,最后調試到產品穩定。
掃描頭本質是攝像頭,遵循Camera架構.
?
第一階段:
驅動掛上了,i2c讀寫不穩定,用系統前置預覽,沒有圖像。
示波器量mipi,沒有波形,查看手冊才發現掃描頭支持并口和mipi接口,需要手動配置成mipi接口,0x86寄存器寫入0x3。
?
static int32_t scan_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl)
{
..........
reg_addr = 0x86;
data = 0x03;
rc = scan_i2c_write(this_client, reg_addr, &data, 1);
........
return rc;
}
?
配置完mipi接口輸出后,前置預覽還是出不了圖像,mipi已經出波形了,電平1.2V也符合要求,說明掃描頭已經有傳輸數據,高通平臺這層出了問題。
按照以往經驗,Vendor 配置是YUV圖像輸出,
{0, CSI_YUV422_8, CSI_DECODE_8BIT},?
剛開始以為mipi通路問題,試了一個調試過的前置,預覽正常,證明mipi通路是正確的。聯系了FAE才知道是RAW8格式。修改成RAW8后,系統前置預覽圖像出來了。
{0, CSI_RAW8, CSI_DECODE_8BIT},格式設置錯了,能預覽但是沒提示又錯誤,framebuff也一直有,格式錯了應該也會花屏,這個地方糾結了一陣子。
?
第二階段:
demo應用預覽圖像有條紋或者顯示不全,圖像可以看得不清晰,無法解碼。FAE強調分辨率是1280 * 720。后面幾番嘗試,修改分辨率為1360 * 800,應用demo預覽正常了。這有一部分原因是i2c不穩定而導致誤判,FAE demo和我用也不一樣。
Kernel層代碼:
?
reg_addr = 0x84;
data = 0x01;
rc = scan_i2c_write(this_client, reg_addr, &data, 1);
Vendor層代碼:
.x_output = 1360,
.y_output = 800,
.line_length_pclk = 1688,
.frame_length_lines = 832,
?
?
第三階段:
掃描頭I2c不穩定,偶爾能正常出圖像,代碼上優化也不能避免i2c讀寫出錯。
掃描頭命令協議是cmd + data + checksum,大部分命令長度是3個。
?
I2C Command Format:
<I2C-Start Bit> <SLA-W> <Cmd-Opcode> <[Cmd-Data]> <Checksum> <I2C-Stop-Bit>
調試以來,使用的都是高通i2c接口i2c_write_seq和i2c_read_seq接口。
i2c_write_seq(s_ctrl->sensor_i2c_client, reg_addr,txdata, tx_len);
i2c_read_seq(s_ctrl->sensor_i2c_client, reg_addr,rxdata, rx_len);
高通架構i2c為發送命令4字節對齊,和掃描頭通信協議沖突,校驗值計算錯誤,造成i2c錯亂。掃描頭i2c電路上飛線到其他路i2c,驅動在掃描頭加載的時候加入新的i2c掛載.
static int32_t scan_platform_probe(struct platform_device *pdev)
{
..........
i2c_add_driver(&real_i2c_driver);
rc = msm_sensor_platform_probe(pdev, match->data);
return rc;
}
注冊一個i2c設備,實際使用到i2c的地方,就用這個新注冊的i2c讀寫,使用i2c_transfer接口,i2c就此穩定。
static int scan_i2c_write(struct i2c_client *client, u8 reg, u8 *val, u8 len)?
{
? ? struct i2c_msg msg;?
? ? u8 data[4];
? ? int i = 0;
? ? int rc = -1, cnt = 0;
? ??
? ? data[0] = reg;?
? ? for ( i = 0; i < len; i++)
? ? {
? ? ? ? data[i+1] = val[i];
? ? }
? ? data[i+1] = scan_calc_checksum(data, len+1);
? ? msg.addr = client->addr;
? ? msg.flags = 0;?
? ? msg.len = len + 2;?
? ? msg.buf = data;
? ? do {
? ? ? ? rc = i2c_transfer(client->adapter, &msg, 1);
? ? ? ? msleep(1);
? ? }while(cnt++ < 3 && rc < 0);
? ? return ?rc;
}
使用普通i2c讀寫接口
?
第四階段:
優化代碼,單個命令不會出錯,寫多個命令經常會i2c出錯,實際調試發現,每個寫命令之間最好要有1ms間隔,讀字符串命令需要等待5ms。
總結
- 上一篇: Android预优化那些事
- 下一篇: Android Usb的研究