トラ技 頒布カメラB(OV7670 FIFO AL422B)の動作確認
接続
接続には、3番ピン(SCL)にプルアップ抵抗が必要。10kΩで動作した。そのほかは、直結で問題なかった。
ピント合わせ
レンズ先端が回せるようになっているので、そちらでピントを合わせることができる。 ピントを合わせた後は、ドライバでねじを固定すれば、動かない。
FIFO関連
レジスタの設定
OV7670のVSYNCとAL422のWriteReset(Active Low)が接続されているので、AL422のWriteResetを行うためにVSYNCの信号をネガティブにする必要がある。
WriteReg(REG_COM10,0x02);
容量限界
FIFO(AL422B)は393,216Byteを搭載している。
RGB444/RGB555/RGB666フォーマットで出力した場合、1画素、2Byte使用するため、393,216 / 2 = 196,608画素まで、保存可能。
YUV422フォーマットで出力した場合、2画素、4Byte使用するため、393,216 / (4 / 2) = 196,608画素まで、保存可能(RGBフォーマットと同様の容量となる)。
VGA(640x480) = 307,200画素なので、メモリ内を読み込んでも崩れた画像が出力される。
RGB444/RGB555/RGB666/YUV422では、544x360 = 195,840画素で出力できることが確認できた。 544x360の設定は、下記の解像度の2byte 1pixelの場合のFIFOの容量限界近辺(544x360)を参照のこと。
Bayerフォーマットで出力した場合、1画素、1Byte(ただし、各画素RGBのどれか1色を保持)なので、VGA(640x480) = 307,200画素=Byte < FIFO(AL422B) 393,216Byteとなり、カメラの限界のVGA分の画素を保存できる。
データフォーマット
Linuxのov7670ドライバ及び、トラ技の2012年3月号の設定を元にしている。
定数を新たに設定/変更している部分があるので、参考のコードにそのまま追記してもコンパイルできない場合がある。
RGB444
WriteReg(REG_COM7, COM7_RGB);
WriteReg(REG_RGB444, RGB444_ENABLE|RGB444_XBGR);
WriteReg(REG_COM15, COM15_R01FE|COM15_RGB444);
WriteReg(REG_COM1, 0x40); // Magic reserved bit
WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit
WriteReg(0x4f, 0xb3); // "matrix coefficient 1"
WriteReg(0x50, 0xb3); // "matrix coefficient 2"
WriteReg(0x51, 0x00); // vb
WriteReg(0x52, 0x3d); // "matrix coefficient 4"
WriteReg(0x53, 0xa7); // "matrix coefficient 5"
WriteReg(0x54, 0xe4); // "matrix coefficient 6"
WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2); // Magic rsvd bit
WriteReg(REG_TSLB, 0x04);
取得したデータをRGB888に変換する場合。
d1 = camera.ReadOneByte();
d2 = camera.ReadOneByte();
// RGB444 to RGB888
b = (d1 & 0x0F) << 4;
g = (d2 & 0xF0);
r = (d2 & 0x0F) << 4;
RGB555
WriteReg(REG_COM7, COM7_RGB);
WriteReg(REG_RGB444, RGB444_DISABLE);
WriteReg(REG_COM15, COM15_RGB555|COM15_R00FF);
WriteReg(REG_TSLB, 0x04);
WriteReg(REG_COM1, 0x00);
WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit
WriteReg(0x4f, 0xb3); // "matrix coefficient 1"
WriteReg(0x50, 0xb3); // "matrix coefficient 2"
WriteReg(0x51, 0x00); // vb
WriteReg(0x52, 0x3d); // "matrix coefficient 4"
WriteReg(0x53, 0xa7); // "matrix coefficient 5"
WriteReg(0x54, 0xe4); // "matrix coefficient 6"
WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT);
取得したデータをRGB888に変換する場合。
d1 = camera.ReadOneByte();
d2 = camera.ReadOneByte();
// RGB555 to RGB888
b = (d1 & 0x1F) << 3;
g = (((d1 & 0xE0) >> 2) | ((d2 & 0x03) << 6));
r = (d2 & 0x7c) << 1;
RGB565
WriteReg(REG_COM7, COM7_RGB);
WriteReg(REG_RGB444, RGB444_DISABLE);
WriteReg(REG_COM15, COM15_R00FF|COM15_RGB565);
WriteReg(REG_TSLB, 0x04);
WriteReg(REG_COM1, 0x00);
WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit
WriteReg(0x4f, 0xb3); // "matrix coefficient 1"
WriteReg(0x50, 0xb3); // "matrix coefficient 2"
WriteReg(0x51, 0x00); // vb
WriteReg(0x52, 0x3d); // "matrix coefficient 4"
WriteReg(0x53, 0xa7); // "matrix coefficient 5"
WriteReg(0x54, 0xe4); // "matrix coefficient 6"
WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT);
取得したデータをRGB888に変換する場合。
d1 = camera.ReadOneByte();
d2 = camera.ReadOneByte();
// RGB565 to RGB888
b = (d1 & 0x1F) << 3;
g = (((d1 & 0xE0) >> 3) | ((d2 & 0x07) << 5));
r = (d2 & 0xF8);
YUV422
WriteReg(REG_COM7, COM7_YUV);
WriteReg(REG_RGB444, RGB444_DISABLE);
WriteReg(REG_COM15, COM15_R00FF);
WriteReg(REG_TSLB, 0x04);
// WriteReg(REG_TSLB, 0x14); //この部分を有効にすると、UVの値を0x00固定できるので、
// WriteReg(REG_MANU, 0x00); //グレースケールの画像が取得できる。
// WriteReg(REG_MANV, 0x00);
WriteReg(REG_COM1, 0x00);
WriteReg(REG_COM9, 0x18); // 4x gain ceiling; 0x8 is reserved bit
WriteReg(0x4f, 0x80); // "matrix coefficient 1"
WriteReg(0x50, 0x80); // "matrix coefficient 2"
WriteReg(0x51, 0x00); // vb
WriteReg(0x52, 0x22); // "matrix coefficient 4"
WriteReg(0x53, 0x5e); // "matrix coefficient 5"
WriteReg(0x54, 0x80); // "matrix coefficient 6"
WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|COM13_UVSWAP);
取得したデータをRGB888に変換する場合。 データを確認したところ、Yのレンジは0-255までのようなので、下記の変換式を使ってRGB888に変換できた。
シフト演算と論理演算で効率化したいところだが、飽和計算のアルゴリズムが思い浮かばなかったので、非効率なままとしている。
U0 = camera.ReadOneByte();
Y0 = camera.ReadOneByte();
V0 = camera.ReadOneByte();
Y1 = camera.ReadOneByte();
b0 = Y0 + 1.77200 * (U0 - 128);
g0 = Y0 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128);
r0 = Y0 + 1.40200 * (V0 - 128);
b1 = Y1 + 1.77200 * (U0 - 128);
g1 = Y1 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128);
r1 = Y1 + 1.40200 * (V0 - 128);
b0 = min(max(b0, 0), 255);
g0 = min(max(g0, 0), 255);
r0 = min(max(r0, 0), 255);
b1 = min(max(b1, 0), 255);
g1 = min(max(g1, 0), 255);
r1 = min(max(r1, 0), 255);
Bayer RGB
int reg_com7 = ReadReg(REG_COM7);
WriteReg(REG_COM7, reg_com7|COM7_PBAYER);
WriteReg(REG_RGB444, RGB444_DISABLE);
WriteReg(REG_COM15, COM15_R00FF);
WriteReg(REG_TSLB, 0x04);
WriteReg(REG_COM13, 0x08); /* No gamma, magic rsvd bit */
WriteReg(REG_COM16, 0x3d); /* Edge enhancement, denoise */
WriteReg(REG_REG76, 0xe1); /* Pix correction, magic rsvd */
取得したデータをRGB888に変換する場合。 アド・サイエンス: ベイヤーパターンカメラとは? RGBカラー画像への変換方法というページを参考にして、変換を行った。
unsigned char *bayer_line[2]; //操作行列を入れ替えるためのポインタ
unsigned char *bayer_line_data[2]; //画像1行分のRGB情報を格納する2行分
for(int i=0; i<2; i++) {
if((bayer_line_data[i] = (unsigned char *)malloc(sizeof(unsigned char)*sizex)) == NULL){
fprintf(stderr, "Error: Allocation error.\n");
return 1;
}
}
// 1行目の処理
for (int x=0; x<sizex; x++) {
// odd line GBGB... even line RGRG...
bayer_line_data[0][x] = (unsigned char)camera.ReadOneByte();
}
bayer_line[1] = bayer_line_data[0];
// 2行目以降の処理
for (int y=1; y<sizey; y++) {
int line = y%2;
for (int x=0; x<sizex; x++) {
// odd line GBGB... even line RGRG...
bayer_line_data[line][x] = (unsigned char)camera.ReadOneByte();
}
// 操作行列のindex入れ替え
bayer_line[0] = bayer_line[1];
bayer_line[1] = bayer_line_data[line];
for (int x=0; x<sizex - 1; x++) {
if(y%2==1) {
if(x%2==0) {
// GB
// RG
b = bayer_line[0][x+1];
g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1;
r = bayer_line[1][x];
} else {
// BG
// GR
b = bayer_line[0][x];
g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1;
r = bayer_line[1][x+1];
}
} else {
if(x%2==0) {
// RG
// GB
b = bayer_line[1][x+1];
g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1;
r = bayer_line[0][x];
} else {
// GR
// BG
b = bayer_line[1][x];
g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1;
r = bayer_line[0][x+1];
}
}
}
}
生成したbitmapファイルBayer VGAトラ技の表紙とワイヤーストリッパーを映してみた。
また、Bayerフォーマットの場合、QVGA、QQVGAの設定だと、正常に画像出力できなかった。
原因は不明。
解像度
Linuxのov7670ドライバ及び、トラ技の2012年3月号の設定を元にしている。
定数を新たに設定/変更している部分があるので、参考のコードにそのまま追記してもコンパイルできない場合がある。
トラ技の設定は、すべてREG_HREFでエッジオフセット設定されているが、設定しないことでTSLBで、ネガポジ反転しなくても良くなった。 QQVGAは、エッジオフセット設定を残したままにしている。
VGA(640x480)
※FIFOの容量の関係で、Bayerフォーマット指定時のみ、画像取得できる。
WriteReg(REG_COM7,COM7_VGA);
WriteReg(REG_HSTART,HSTART_VGA);
WriteReg(REG_HSTOP,HSTOP_VGA);
WriteReg(REG_HREF,HREF_VGA);
WriteReg(REG_VSTART,VSTART_VGA);
WriteReg(REG_VSTOP,VSTOP_VGA);
WriteReg(REG_VREF,VREF_VGA);
WriteReg(REG_COM3, COM3_VGA);
WriteReg(REG_COM14, COM14_VGA);
WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA);
WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA);
WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA);
WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA);
WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA);
2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
WriteReg(REG_COM7,COM7_VGA);
WriteReg(REG_HSTART,HSTART_VGA);
WriteReg(REG_HSTOP,HSTOP_VGA);
WriteReg(REG_HREF,HREF_VGA);
WriteReg(REG_VSTART,VSTART_VGA);
WriteReg(REG_VSTOP,VSTOP_VGA);
WriteReg(REG_VREF,VREF_VGA);
WriteReg(REG_COM3, COM3_VGA);
WriteReg(REG_COM14, COM14_VGA);
WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA);
WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA);
WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA);
WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA);
WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA);
WriteReg(REG_HSTART, 0x17);
WriteReg(REG_HSTOP, 0x5b);
WriteReg(REG_VSTART, 0x12);
WriteReg(REG_VSTOP, 0x6c);
(HREF, VREFの設定も厳密にした方が良いかもしれない。)
VGAの4分の3サイズ(480x360)
WriteReg(REG_COM7,COM7_VGA);
WriteReg(REG_HSTART,HSTART_VGA);
WriteReg(REG_HSTOP,HSTOP_VGA);
WriteReg(REG_HREF,HREF_VGA);
WriteReg(REG_VSTART,VSTART_VGA);
WriteReg(REG_VSTOP,VSTOP_VGA);
WriteReg(REG_VREF,VREF_VGA);
WriteReg(REG_COM3, COM3_VGA);
WriteReg(REG_COM14, COM14_VGA);
WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA);
WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA);
WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA);
WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA);
WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA);
WriteReg(REG_HSTART, 0x1b);
WriteReg(REG_HSTOP, 0x57);
WriteReg(REG_VSTART, 0x12);
WriteReg(REG_VSTOP, 0x6c);
QVGA
WriteReg(REG_COM7,COM7_QVGA);
WriteReg(REG_HSTART,HSTART_QVGA);
WriteReg(REG_HSTOP,HSTOP_QVGA);
WriteReg(REG_HREF,HREF_QVGA);
WriteReg(REG_VSTART,VSTART_QVGA);
WriteReg(REG_VSTOP,VSTOP_QVGA);
WriteReg(REG_VREF,VREF_QVGA);
WriteReg(REG_COM3, COM3_QVGA);
WriteReg(REG_COM14, COM14_QVGA);
WriteReg(REG_SCALING_XSC, SCALING_XSC_QVGA);
WriteReg(REG_SCALING_YSC, SCALING_YSC_QVGA);
WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QVGA);
WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QVGA);
WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QVGA);
QQVGA
WriteReg(REG_COM7,COM7_QQVGA);
WriteReg(REG_HSTART,HSTART_QQVGA);
WriteReg(REG_HSTOP,HSTOP_QQVGA);
WriteReg(REG_HREF,HREF_QQVGA);
WriteReg(REG_VSTART,VSTART_QQVGA);
WriteReg(REG_VSTOP,VSTOP_QQVGA);
WriteReg(REG_VREF,VREF_QQVGA);
WriteReg(REG_COM3, COM3_QQVGA);
WriteReg(REG_COM14, COM14_QQVGA);
WriteReg(REG_SCALING_XSC, SCALING_XSC_QQVGA);
WriteReg(REG_SCALING_YSC, SCALING_YSC_QQVGA);
WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QQVGA);
WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QQVGA);
WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QQVGA);
デフォルト設定
Linuxドライバのデフォルト設定から、不都合なものを除外した設定。
// Gamma curve values
WriteReg(0x7a, 0x20);
WriteReg(0x7b, 0x10);
WriteReg(0x7c, 0x1e);
WriteReg(0x7d, 0x35);
WriteReg(0x7e, 0x5a);
WriteReg(0x7f, 0x69);
WriteReg(0x80, 0x76);
WriteReg(0x81, 0x80);
WriteReg(0x82, 0x88);
WriteReg(0x83, 0x8f);
WriteReg(0x84, 0x96);
WriteReg(0x85, 0xa3);
WriteReg(0x86, 0xaf);
WriteReg(0x87, 0xc4);
WriteReg(0x88, 0xd7);
WriteReg(0x89, 0xe8);
// AGC and AEC parameters. Note we start by disabling those features,
//then turn them only after tweaking the values.
WriteReg(REG_COM8, COM8_FASTAEC | COM8_AECSTEP | COM8_BFILT);
WriteReg(REG_GAIN, 0);
WriteReg(REG_AECH, 0);
WriteReg(REG_COM4, 0x40);
// magic reserved bit
WriteReg(REG_COM9, 0x18);
// 4x gain + magic rsvd bit
WriteReg(REG_BD50MAX, 0x05);
WriteReg(REG_BD60MAX, 0x07);
WriteReg(REG_AEW, 0x95);
WriteReg(REG_AEB, 0x33);
WriteReg(REG_VPT, 0xe3);
WriteReg(REG_HAECC1, 0x78);
WriteReg(REG_HAECC2, 0x68);
WriteReg(0xa1, 0x03);
// magic
WriteReg(REG_HAECC3, 0xd8);
WriteReg(REG_HAECC4, 0xd8);
WriteReg(REG_HAECC5, 0xf0);
WriteReg(REG_HAECC6, 0x90);
WriteReg(REG_HAECC7, 0x94);
WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC);
// Almost all of these are magic "reserved" values.
WriteReg(REG_COM5, 0x61);
WriteReg(REG_COM6, 0x4b);
WriteReg(0x16, 0x02);
WriteReg(REG_MVFP, 0x07);
WriteReg(0x21, 0x02);
WriteReg(0x22, 0x91);
WriteReg(0x29, 0x07);
WriteReg(0x33, 0x0b);
WriteReg(0x35, 0x0b);
WriteReg(0x37, 0x1d);
WriteReg(0x38, 0x71);
WriteReg(0x39, 0x2a);
WriteReg(REG_COM12, 0x78);
WriteReg(0x4d, 0x40);
WriteReg(0x4e, 0x20);
WriteReg(REG_GFIX, 0);
WriteReg(0x6b, 0x0a);
WriteReg(0x74, 0x10);
WriteReg(0x8d, 0x4f);
WriteReg(0x8e, 0);
WriteReg(0x8f, 0);
WriteReg(0x90, 0);
WriteReg(0x91, 0);
WriteReg(0x96, 0);
WriteReg(0x9a, 0);
WriteReg(0xb0, 0x84);
WriteReg(0xb1, 0x0c);
WriteReg(0xb2, 0x0e);
WriteReg(0xb3, 0x82);
WriteReg(0xb8, 0x0a);
// More reserved magic, some of which tweaks white balance
WriteReg(0x43, 0x0a);
WriteReg(0x44, 0xf0);
WriteReg(0x45, 0x34);
WriteReg(0x46, 0x58);
WriteReg(0x47, 0x28);
WriteReg(0x48, 0x3a);
WriteReg(0x59, 0x88);
WriteReg(0x5a, 0x88);
WriteReg(0x5b, 0x44);
WriteReg(0x5c, 0x67);
WriteReg(0x5d, 0x49);
WriteReg(0x5e, 0x0e);
WriteReg(0x6c, 0x0a);
WriteReg(0x6d, 0x55);
WriteReg(0x6e, 0x11);
WriteReg(0x6f, 0x9f);
// "9e for advance AWB"
WriteReg(0x6a, 0x40);
WriteReg(REG_BLUE, 0x40);
WriteReg(REG_RED, 0x60);
WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC|COM8_AWB);
// Matrix coefficients
WriteReg(0x4f, 0x80);
WriteReg(0x50, 0x80);
WriteReg(0x51, 0);
WriteReg(0x52, 0x22);
WriteReg(0x53, 0x5e);
WriteReg(0x54, 0x80);
WriteReg(0x58, 0x9e);
WriteReg(REG_COM16, COM16_AWBGAIN);
WriteReg(REG_EDGE, 0);
WriteReg(0x75, 0x05);
WriteReg(0x76, 0xe1);
WriteReg(0x4c, 0);
WriteReg(0x77, 0x01);
WriteReg(0x4b, 0x09);
WriteReg(0xc9, 0x60);
WriteReg(REG_COM16, 0x38);
WriteReg(0x56, 0x40);
WriteReg(0x34, 0x11);
WriteReg(REG_COM11, COM11_EXP|COM11_HZAUTO_ON);
WriteReg(0xa4, 0x88);
WriteReg(0x96, 0);
WriteReg(0x97, 0x30);
WriteReg(0x98, 0x20);
WriteReg(0x99, 0x30);
WriteReg(0x9a, 0x84);
WriteReg(0x9b, 0x29);
WriteReg(0x9c, 0x03);
WriteReg(0x9d, 0x4c);
WriteReg(0x9e, 0x3f);
WriteReg(0x78, 0x04);
// Extra-weird stuff. Some sort of multiplexor register
WriteReg(0x79, 0x01);
WriteReg(0xc8, 0xf0);
WriteReg(0x79, 0x0f);
WriteReg(0xc8, 0x00);
WriteReg(0x79, 0x10);
WriteReg(0xc8, 0x7e);
WriteReg(0x79, 0x0a);
WriteReg(0xc8, 0x80);
WriteReg(0x79, 0x0b);
WriteReg(0xc8, 0x01);
WriteReg(0x79, 0x0c);
WriteReg(0xc8, 0x0f);
WriteReg(0x79, 0x0d);
WriteReg(0xc8, 0x20);
WriteReg(0x79, 0x09);
WriteReg(0xc8, 0x80);
WriteReg(0x79, 0x02);
WriteReg(0xc8, 0xc0);
WriteReg(0x79, 0x03);
WriteReg(0xc8, 0x40);
WriteReg(0x79, 0x05);
WriteReg(0xc8, 0x30);
WriteReg(0x79, 0x26);
定数表
// size register #define REG_COM7 0x12 /* Control 7 */ #define REG_HSTART 0x17 /* Horiz start high bits */ #define REG_HSTOP 0x18 /* Horiz stop high bits */ #define REG_HREF 0x32 /* HREF pieces */ #define REG_VSTART 0x19 /* Vert start high bits */ #define REG_VSTOP 0x1a /* Vert stop high bits */ #define REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ #define REG_COM3 0x0c /* Control 3 */ #define REG_COM14 0x3e /* Control 14 */ #define REG_SCALING_XSC 0x70 #define REG_SCALING_YSC 0x71 #define REG_SCALING_DCWCTR 0x72 #define REG_SCALING_PCLK_DIV 0x73 #define REG_SCALING_PCLK_DELAY 0xa2 // VGA setting #define COM7_VGA 0x00 #define HSTART_VGA 0x13 #define HSTOP_VGA 0x01 #define HREF_VGA 0x36 #define VSTART_VGA 0x02 #define VSTOP_VGA 0x7a #define VREF_VGA 0x0a #define COM3_VGA 0x00 #define COM14_VGA 0x00 #define SCALING_XSC_VGA 0x3a #define SCALING_YSC_VGA 0x35 #define SCALING_DCWCTR_VGA 0x11 #define SCALING_PCLK_DIV_VGA 0xf0 #define SCALING_PCLK_DELAY_VGA 0x02 // QVGA setting #define COM7_QVGA 0x00 #define HSTART_QVGA 0x16 #define HSTOP_QVGA 0x04 #define HREF_QVGA 0x00 #define VSTART_QVGA 0x02 #define VSTOP_QVGA 0x7a #define VREF_QVGA 0x0a #define COM3_QVGA 0x04 #define COM14_QVGA 0x19 #define SCALING_XSC_QVGA 0x3a #define SCALING_YSC_QVGA 0x35 #define SCALING_DCWCTR_QVGA 0x11 #define SCALING_PCLK_DIV_QVGA 0xf1 #define SCALING_PCLK_DELAY_QVGA 0x02 // QQVGA setting #define COM7_QQVGA 0x00 #define HSTART_QQVGA 0x16 #define HSTOP_QQVGA 0x04 #define HREF_QQVGA 0xa4 //0x24? 0xa4? #define VSTART_QQVGA 0x02 #define VSTOP_QQVGA 0x7a #define VREF_QQVGA 0x0a #define COM3_QQVGA 0x04 #define COM14_QQVGA 0x1a #define SCALING_XSC_QQVGA 0x3a #define SCALING_YSC_QQVGA 0x35 #define SCALING_DCWCTR_QQVGA 0x22 #define SCALING_PCLK_DIV_QQVGA 0xf2 #define SCALING_PCLK_DELAY_QQVGA 0x02 // YUV #define REG_COM13 0x3d /* Control 13 */ #define REG_TSLB 0x3a /* lots of stuff */ #define COM7_YUV 0x00 /* YUV */ #define COM13_UV 0x00 /* U before V - w/TSLB */ #define COM13_UVSWAP 0x01 /* V before U - w/TSLB */ #define TSLB_VLAST 0x00 /* YUYV - see com13 */ #define TSLB_ULAST 0x00 /* YVYU - see com13 */ #define TSLB_YLAST 0x08 /* UYVY or VYUY - see com13 */ // RGB #define COM7_RGB 0x04 /* bits 0 and 2 - RGB format */ // RGB444 #define REG_RGB444 0x8c /* RGB 444 control */ #define REG_COM15 0x40 /* Control 15 */ #define RGB444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */ #define RGB444_XBGR 0x00 #define RGB444_BGRX 0x01 /* Empty nibble at end */ #define COM15_RGB444 0x10 /* RGB444 output */ // RGB555 #define RGB444_DISABLE 0x00 /* Turn off RGB444, overrides 5x5 */ #define COM15_RGB555 0x30 /* RGB555 output */ // RGB565 #define COM15_RGB565 0x10 /* RGB565 output */ // Bayer RGB #define COM7_BAYER 0x01 /* Bayer format */ #define COM7_PBAYER 0x05 /* "Processed bayer" */ // data format #define COM15_R10F0 0x00 /* Data range 10 to F0 */ #define COM15_R01FE 0x80 /* 01 to FE */ #define COM15_R00FF 0xc0 /* 00 to FF */
bitmapファイル
実際にmbed内でbitmapファイル化した画像データ集
上記の設定の組み合わせて、トラ技の2012年3月号の表紙を保存してみた。
RGB444 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
RGB555 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
RGB565 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
YUV422 2Byte 1pixelの場合のFIFOの容量限界近辺のサイズ(544x360)
検証に使用したコードはこちら。
Import programOV7670_with_AL422B_Color_Size_test
OV7670_with_AL422B Color & Size Test Program
参考
Import programOV7670_with_AL422B_QQVGA_test
OV7670 with FIFO AL422B (TORAGI Camera TYPE B) test program
OV7670+FIFOカメラモジュール(SCCBインタフェース)
HR2_blog: mbedでトラ技3月号の頒布カメラBを使う
Robot No.8080のブログ: mbed + トラ技カメラBの実験。(その1)
2 comments on トラ技 頒布カメラB(OV7670 FIFO AL422B)の動作確認:
Please log in to post comments.

何のマイコンを利用している?