mt9d131 效果一般, 因為海思帶它的驅動, 所以用的人還挺多, 呵呵.
很多晶片的驅動比較簡單, 就是直接給某個寄存器賦某個值, 就ok, 具體這個寄存器是什麼意思, 值是什麼意思, 看datasheet就可以了.
mt9d131 要略微複雜一點
因為 mt9d131 裡面可以配置的東西很多, 所以 mt9d131 把可以設定的東西分成3類
1. 硬體寄存器
2. driver變數
3. MCU記憶體
1.硬體寄存器
硬體寄存器和普通晶片的寄存器沒有區別, 只是因為mt9d131的寄存器比較多, 所以, 一共分成了3頁, page0,page1,page2
page0包含sensor的一些核心功能
page1包含顏色管線的一些控制
page2包含jpeg和其他一些處理
因此, 給mt9d131的某個寄存器賦值之前,先要明確是賦值給那一page,這是通過寫入 0xF0寄存器來實現的.
寫入0,表示後續操作都是針對page0, 寫入1表示後續操作都是針對page1, 寫入2表示page2
明確哪一頁之後,就可以正常讀寫需要的寄存器了
比如下面的代碼用於讀取晶片標識
gpio_i2c_write(I2C_MT9D131, 0xf0, 0x00);
gpio_i2c_write(I2C_MT9D131, 0xf1, 0x00);
上面2行,表示切換到 page0
這裡需要注意的是, 如果操作的目標是16位的,
而我們如果一次讀寫8位,需要額外讀寫0xf1寄存器,來讀寫後8位.
下面2行表示,讀取page0的,r0寄存器,
因為一個寄存器是16位的, 所以要每次讀寫0xf1,把資料讀寫完整
unsigned char regvalue = gpio_i2c_read(I2C_MT9D131, 0x00);
int loop1 = gpio_i2c_read(I2C_MT9D131, 0xf1);
if((regvalue != 0x15) || (loop1 != 0x19))
{
printk("read Prodect ID Number MSB is %x\n",regvalue);
printk("read Prodect ID Number LSB is %x\n",loop1);
printk("check mt9d131 ID error.\n");
}
通過datasheet,我們知道r0隻讀,恒為0x1519
其他對於寄存器的讀寫與此類似.
2.driver變數
mt9d131裡面很多功能通過driver方式實現, 每個driver有一個id
所有這些driver組成mt9d131的韌體, 這個韌體可以運行在6811相容的處理器(帶數學副處理器)上.
比如
driver id 1 對應序列控制相關
driver id 2 對應自動曝光
driver id 3 對應自動白平衡
等等
每個driver有很多變數, 通過給這些變數賦值,來控制對應driver的行為
這是通過 0xC6 和 0xC8寄存器來實現的.
0xC6 是由driver id 和 相應的變數位移組成
0xC8 是給對應的變數賦的值.
根據Datasheet, 給0xC6的賦值,由四部分組成
8~12位 為 driver id
0~7位 為 這個driver裡面對應的變數的位移
13~14位 為 1 表示 邏輯操作
15 為 0 表示 16位操作, 為 1 表示8位操作
比如下面的代碼, 用於把 上下文A 的輸出寬高設為 800x600
gpio_i2c_write(I2C_MT9D131, 0xf0, 0x00);
gpio_i2c_write(I2C_MT9D131, 0xf1, 0x01);
上面的代碼切換到page1
根據datasheet,我們知道 對應的驅動為7, 變數位移為3和5
gpio_i2c_write(I2C_MT9D131,0xC6, 0x27);
gpio_i2c_write(I2C_MT9D131,0xf1, 0x03);
gpio_i2c_write(I2C_MT9D131,0xC8, 0x03);
gpio_i2c_write(I2C_MT9D131,0xf1, 0x20);
上面的代碼賦值 0x2703 給 0xC6
按規則分解開,可以知道
driver id = 7
變數地址 = 3
16位,邏輯操作
0x0320 也就是 800, 賦值給 0xC8
gpio_i2c_write(I2C_MT9D131,0xC6, 0x27);
gpio_i2c_write(I2C_MT9D131,0xf1, 0x05);
gpio_i2c_write(I2C_MT9D131,0xC8, 0x02);
gpio_i2c_write(I2C_MT9D131,0xf1, 0x58);
上面的代碼賦值 0x2705 給 0xC6
按規則分解開,可以知道
driver id = 7
變數地址 = 5
16位,邏輯操作
0x0258 也就是 600, 賦值給 0xC8
當然,要完整地改變映像大小,還需要其他動作.
3. MCU記憶體
略