作者的话
ADI的双核DSP,第二颗是Blackfin系列的BF609,这颗DSP我用了很久,比较熟悉,且写过一些给新手的教程。
硬件准备
ADSP-BF609-CORE:ADI BF609开发板
产品链接:https://item.taobao.com/item.htm?id=39901289258
AD-HP530ICE仿真器:ADI DSP通用仿真器
产品链接:https://item.taobao.com/item.htm?id=753233120844
软件准备
CCES2.2.0
硬件环境的搭建

如前面的例程方式来跑CMOS的程序。编译运行程序不再重复,参照DDR章节。
编译完按运行:

待打印"Init ov9653 ok !"之后暂停,再做下面的配置:





核心代码分析
main.c
#include "ov9653.h"
#include <stdio.h>
#include ".../system/adi_initialize.h"
#include <sys/platform.h>
#include <stdint.h>
void read_reg(unsigned short *buf,unsigned char *buf2)
{
unsigned char data;
//TWI0_MasterMode_Write(0x60>>1, data, 1, 1);
TWI0_MasterMode_Write(0x60>>1, buf, 1, 1);
TWI_MasterMode_Read(0x61>>1, buf2, 1);
asm("nop;");
}
void Init_Enable_Port(void)
{
*pREG_PORTG_FER_CLR =BITM_PORT_DATA_PX11 ;
*pREG_PORTG_DIR_SET =BITM_PORT_DATA_PX11;
}
void Enable_CMOS(void)
{
*pREG_PORTG_DATA_CLR = BITM_PORT_DATA_PX11;
//*pREG_PORTG_DATA_SET = BITM_PORT_DATA_PX11;
}
void Disable_CMOS(void)
{
//*pREG_PORTG_DATA_CLR = BITM_PORT_DATA_PX11;
*pREG_PORTG_DATA_SET = BITM_PORT_DATA_PX11;
}
void main(void)
{
unsigned char test[4];
unsigned tmp[2] = {0x00,0x00};
unsigned char temp;
unsigned short temp1=0x11;
printf("sys start!\n");
test[0] = 0x0a;
test[1] = 0x00;
test[2] = 0x00;
test[3] = 0x00;
/* make sure we call adi_sec_init() */
adi_initComponents();
Init_PLL();
//Init_Enable_Port();
// Enable_CMOS();
Reset_TWI0();
printf("start init ov9653!\n");
TWI0_MasterMode_Write( CMOSI2CADD>>1, MY_CMOSConfig, MY_SETTINGNUM, 2);
read_reg(&temp1,&temp);
if(temp==0x80)
printf("Init ov9653 ok !\n");
else
printf("Init ov9653 error !\n");
InitPPI2DMA();
InitEPPI2();
EnableEPPI2_DMA();
while(1)
{
asm("nop;");
};
}
OV9653.C
#include <cdefBF609.h>
#include <ccblkfn.h>
#include <sys\exception.h>
#include <math.h>
#include <signal.h>
#include <stdlib.h>
#define PRESCALE_VALUE 10
#define RESET_TWI 0
#define CLKDIV_HI 90
#define CLKDIV_LO 45
#pragma align(4)
unsigned char cmos_data[6404802];
void InitPPI2DMA(void)
{
*pREG_DMA31_ADDRSTART = cmos_data;
pREG_DMA31_XCNT = 640 2/4;
*pREG_DMA31_XMOD = 0x4;
*pREG_DMA31_YCNT = 480;
*pREG_DMA31_YMOD = 0x4;
*pREG_DMA31_CFG = ENUM_DMA_CFG_WRITE |
ENUM_DMA_CFG_MSIZE04 |
ENUM_DMA_CFG_PSIZE04 |
ENUM_DMA_CFG_ADDR2D |
ENUM_DMA_CFG_SYNC |
//ENUM_DMA_CFG_STOP;
ENUM_DMA_CFG_AUTO;
ssync();
}
unsigned int tmp ;
void InitEPPI2()
{
//==
*pREG_EPPI2_CTL=0;
*pREG_EPPI2_CTL = ENUM_EPPI_CTL_RXMODE |
ENUM_EPPI_CTL_FS1HI_FS2HI |
ENUM_EPPI_CTL_PACK_EN|
ENUM_EPPI_CTL_POLC11 |
ENUM_EPPI_CTL_DLEN08 |
ENUM_EPPI_CTL_NON656 |
ENUM_EPPI_CTL_SYNC2
;
ssync();
*pREG_EPPI2_LINE = 1280;
ssync();
*pREG_EPPI2_FRAME = 480;
ssync();
}
void DisableEPPI2_DMA(void)
{
*pREG_DMA31_CFG &= ~ENUM_DMA_CFG_EN;
ssync();
*pREG_EPPI2_CTL &= ~ENUM_EPPI_CTL_EN;
ssync();
}
void EnableEPPI2_DMA(void)
{
*pREG_DMA31_CFG |= ENUM_DMA_CFG_EN;
ssync();
*pREG_EPPI2_CTL |= ENUM_EPPI_CTL_EN;
ssync();
}
void Reset_TWI0(void)
{
//RESET_TWI CONTROLLER
*pREG_TWI0_CTL = RESET_TWI;
ssync();
//CLEAR ALL ERRONOUS CONDITIONS BEFORE ENABLING TWI
*pREG_TWI0_MSTRSTAT = BITM_TWI_MSTRSTAT_BUFWRERR | BITM_TWI_MSTRSTAT_BUFRDERR |
BITM_TWI_MSTRSTAT_LOSTARB |BITM_TWI_MSTRSTAT_ANAK | BITM_TWI_MSTRSTAT_DNAK;
ssync();
//CLEAR ALL INTERRUPTS BEFORE ENABLING TWI
*pREG_TWI0_ISTAT = BITM_TWI_ISTAT_SINIT | BITM_TWI_ISTAT_SCOMP | BITM_TWI_ISTAT_SERR |
BITM_TWI_ISTAT_SOVF | BITM_TWI_ISTAT_MCOMP | BITM_TWI_ISTAT_MERR | BITM_TWI_ISTAT_TXSERV |
BITM_TWI_ISTAT_RXSERV;
ssync();
//FLUSH THE FIFOs - BOTH TX AND RX.
*pREG_TWI0_FIFOCTL = BITM_TWI_FIFOCTL_TXFLUSH | BITM_TWI_FIFOCTL_RXFLUSH;
ssync();
}
void TWI0_MasterMode_Write(unsigned short DeviceAddr, unsigned short *TWI_Data_Pointer, unsigned short TX_Count, unsigned short TWI_TX_Length)
{
int i, j;
*pREG_TWI0_FIFOCTL = BITM_TWI_FIFOCTL_TXFLUSH | BITM_TWI_FIFOCTL_RXFLUSH;
ssync();
*pREG_TWI0_MSTRSTAT = BITM_TWI_MSTRSTAT_BUFWRERR | BITM_TWI_MSTRSTAT_BUFRDERR |
BITM_TWI_MSTRSTAT_LOSTARB |BITM_TWI_MSTRSTAT_ANAK | BITM_TWI_MSTRSTAT_DNAK;
ssync();
*pREG_TWI0_FIFOCTL = 0;
*pREG_TWI0_CTL = BITM_TWI_CTL_EN | PRESCALE_VALUE;
*pREG_TWI0_CLKDIV = ((CLKDIV_HI) << 8) | (CLKDIV_LO);
*pREG_TWI0_MSTRADDR = DeviceAddr;
for (i = 0; i < TX_Count; i++)
{
delay(10000);
*pREG_TWI0_TXDATA8 = *TWI_Data_Pointer++;
*pREG_TWI0_MSTRCTL = (TWI_TX_Length<<6) | BITM_TWI_MSTRCTL_EN;
for (j = 0; j < (TWI_TX_Length-1); j++)
{
while (*pREG_TWI0_FIFOSTAT == BITM_TWI_FIFOSTAT_TXSTAT)
ssync();
*pREG_TWI0_TXDATA8 = *TWI_Data_Pointer++;
ssync();
}
while ((*pREG_TWI0_ISTAT & BITM_TWI_ISTAT_MCOMP) == 0)
ssync();
*pREG_TWI0_ISTAT = BITM_TWI_ISTAT_TXSERV | BITM_TWI_ISTAT_MCOMP;
}
asm("nop;");
asm("nop;");
asm("nop;");
}
void TWI_MasterMode_Read(unsigned short DeviceAddr, unsigned char *TWI_Data_Pointer, unsigned short Count)
{
int i, j;
/* clear the bit manually */
*pREG_TWI0_FIFOCTL = 0;
/* PRESCALE = fsclk/10MHz */
*pREG_TWI0_CTL = BITM_TWI_CTL_EN | PRESCALE_VALUE;
/* CLKDIV = (1/SCL)/(1/10MHz) */
*pREG_TWI0_CLKDIV = ((CLKDIV_HI) << 8) | (CLKDIV_LO);
/* target address (7-bits plus the read/write bit) */
*pREG_TWI0_MSTRADDR = DeviceAddr;
/* start transmission */
*pREG_TWI0_MSTRCTL = (Count<<6) | BITM_TWI_MSTRCTL_EN | BITM_TWI_MSTRCTL_DIR;
/* for each item */
for (i = 0; i < Count; i++)
{
/* wait for data to be in FIFO */
while (*pREG_TWI0_FIFOSTAT == 0)
ssync();
*TWI_Data_Pointer++ = *pREG_TWI0_RXDATA8; /* read the data */
ssync();
}
/* wait until transmission complete and MCOMP is set */
while ((*pREG_TWI0_ISTAT & BITM_TWI_ISTAT_MCOMP) == 0)
ssync();
/* service TWI for next transmission */
*pREG_TWI0_ISTAT = BITM_TWI_ISTAT_RXSERV | BITM_TWI_ISTAT_MCOMP;
asm("nop;");
asm("nop;");
asm("nop;");
}
ov9653.h
#ifndef OV9653_H
#define OV9653_H
#define CMOSI2CADD 0x60
#define MY_SETTINGNUM 126
unsigned short MY_CMOSConfig[] =
{
0x12,0x80
,0x11,0x80
,0x6b,0x0a
,0x6a,0x7d
,0x3b,0x09
,0x13,0xe0
,0x01,0x80
,0x02,0x80
,0x00,0x00
,0x10,0x00
,0x13,0xe5
,0x39,0x50
,0x38,0x92
,0x37,0x00
,0x35,0x81
,0x0e,0x20
,0x1e,0x24
,0xA8,0x80
,0x12,0x40
,0x04,0x00
,0x0c,0x04
,0x0d,0x80
,0x18,0xc6
,0x17,0x26
,0x32,0xad
,0x03,0x00
,0x1a,0x3d
,0x19,0x01
,0x3f,0xa6
,0x14,0x1a
,0x15,0x02
,0x41,0x12
,0x42,0x08
,0x1b,0x00
,0x16,0x06
,0x33,0xe2
,0x49,0x60
,0x34,0x16
,0x96,0x04
,0x3a,0x00
,0x8e,0x00
,0x3c,0x77
,0x8B,0x06
,0x94,0x88
,0x95,0x88
,0x40,0xc1
,0x29,0x3f
,0x0f,0x42
,0x3d,0x92
,0x69,0x40
,0x5C,0xb9
,0x5D,0x96
,0x5E,0x10
,0x59,0xc0
,0x5A,0xaf
,0x5B,0x55
,0x43,0xf0
,0x44,0x10
,0x45,0x68
,0x46,0x96
,0x47,0x60
,0x48,0x80
,0x5F,0xe0
,0x60,0x8c
,0x61,0x20
,0xa5,0xd9
,0xa4,0x74
,0x8d,0xc2
,0x13,0xe7
,0x4f,0x3a
,0x50,0x3d
,0x51,0x03
,0x52,0x12
,0x53,0x26
,0x54,0x38
,0x55,0x40
,0x56,0x40
,0x57,0x40
,0x58,0x0d
,0x8C,0x23
,0x3E,0x02
,0xa9,0xb8
,0xaa,0x92
,0xab,0x0a
,0x8f,0xdf
,0x90,0x00
,0x91,0x00
,0x9f,0x00
,0xa0,0x00
,0x3A,0x01
/*,0x24,0x80
,0x25,0x70
,0x26,0xd3
*/
,0x24,0xd8
,0x25,0xd0
,0x26,0xfa
,0x2a,0x00
,0x2b,0x00
,0x6c,0x40
,0x6d,0x30
,0x6e,0x4b
,0x6f,0x60
,0x70,0x70
,0x71,0x70
,0x72,0x70
,0x73,0x70
,0x74,0x60
,0x75,0x60
,0x76,0x50
,0x77,0x48
,0x78,0x3a
,0x79,0x2e
,0x7a,0x28
,0x7b,0x22
,0x7c,0x04
,0x7d,0x07
,0x7e,0x10
,0x7f,0x28
,0x80,0x36
,0x81,0x44
,0x82,0x52
,0x83,0x60
,0x84,0x6c
,0x85,0x78
,0x86,0x8c
,0x87,0x9e
,0x88,0xbb
,0x89,0xd2
,0x8a,0xe6
/*0x12, 0x80,
0x11, 0x81,
0x6b, 0x0a,
0x6a, 0x3e,
0x3b, 0x09,
0x13, 0xe0,
0x01, 0x80,
0x02, 0x80,
0x00, 0x00,
0x10, 0x00,
0x13, 0xe5,
0x39, 0x43, //50 for 30fps
0x38, 0x12, //92 for 30fps
0x37, 0x00,
0x35, 0x91, //81 for 30fps
0x0e, 0x20,
0x1e, 0x04,
0xa8, 0x80,
0x12, 0x40,
0x04, 0x00,
0x0c, 0x04,
0x0d, 0x80,
0x18, 0xc6,
0x17, 0x26,
0x32, 0xad,
0x03, 0x00,
0x1a, 0x3d,
0x19, 0x01,
0x3f, 0xa6,
0x14, 0x2e,
0x15, 0x02,
0x41, 0x02,
0x42, 0x08,
0x1b, 0x00,
0x16, 0x06,
0x33, 0xe2, //c0 for internal regulator
0x34, 0xbf,
0x96, 0x04,
0x3a, 0x00,
0x8e, 0x00,
0x3c, 0x77,
0x8b, 0x06,
0x94, 0x88,
0x95, 0x88,
0x40, 0xc1,
0x29, 0x3f, //2f for internal regulator
0x0f, 0x42,
0x3d, 0x92,
0x69, 0x40,
0x5c, 0xb9,
0x5d, 0x96,
0x5e, 0x10,
0x59, 0xc0,
0x5a, 0xaf,
0x5b, 0x55,
0x43, 0xf0,
0x44, 0x10,
0x45, 0x68,
0x46, 0x96,
0x47, 0x60,
0x48, 0x80,
0x5f, 0xe0,
0x60, 0x8c, //0c for advanced AWB (related to lens)
0x61, 0x20,
0xa5, 0xd9,
0xa4, 0x74,
0x8d, 0x02,
0x13, 0xe7,
0x4f, 0x3a,
0x50, 0x3d,
0x51, 0x03,
0x52, 0x12,
0x53, 0x26,
0x54, 0x38,
0x55, 0x40,
0x56, 0x40,
0x57, 0x40,
0x58, 0x0d,
0x8c, 0x23,
0x3e, 0x02,
0xa9, 0xb8,
0xaa, 0x92,
0xab, 0x0a,
0x8f, 0xdf,
0x90, 0x00,
0x91, 0x00,
0x9f, 0x00,
0xa0, 0x00,
0x3a, 0x01,
0x24, 0x70,
0x25, 0x64,
0x26, 0xc3,
0x2a, 0x00, //10 for 50Hz
0x2b, 0x00, //40 for 50Hz
0x6c, 0x40,
0x6d, 0x30,
0x6e, 0x4b,
0x6f, 0x60,
0x70, 0x70,
0x71, 0x70,
0x72, 0x70,
0x73, 0x70,
0x74, 0x60,
0x75, 0x60,
0x76, 0x50,
0x77, 0x48,
0x78, 0x3a,
0x79, 0x2e,
0x7a, 0x28,
0x7b, 0x22,
0x7c, 0x04,
0x7d, 0x07,
0x7e, 0x10,
0x7f, 0x28,
0x80, 0x36,
0x81, 0x44,
0x82, 0x52,
0x83, 0x60,
0x84, 0x6c,
0x85, 0x78,
0x86, 0x8c,
0x87, 0x9e,
0x88, 0xbb,
0x89, 0xd2,
0x8a, 0xe6,
//color
0x89,0xd2,
0x8a,0xe6,
0x8d,0x12
*/
};
#endif