网站公告列表

  没有公告

加入收藏
设为首页
联系本站
您现在的位置: Analog安诺电子网 >> 文章 >> 技术交流 >> 文章正文
  BF533 EZ-KIT video GP receive mode (8bit) for the Omnivision chip OV6630           ★★★ 【字体:
BF533 EZ-KIT video GP receive mode (8bit) for the Omnivision chip OV6630
作者:佚名    文章来源:Internet    点击数:    更新时间:2008-4-2    

/******************************************************************************/
//
// Name: BF533 EZ-KIT video GP receive mode (8bit) for the Omnivision chip OV6630
//
/*****************************************************************************************************************

(C) Copyright 2003 - Analog Devices, Inc.  All rights reserved.

File Name:  

Date Modified:   08/12/05  TL  Rev 1.0

Software:         VisualDSP++4.0, Assembler 2.6.7.5, Linker 3.5.2.2

Hardware:    BF533 EZ-KIT Board (rev 1.7), Blackfin EZ-Extender (rev 1.2)

Chip:     ADSP-BF533 REV 0.4

Special Connections:  None

Purpose:  To configure the ADV video devices
    
    
Program Parameters:

************************************************************************************************/

/*************** SCCB Start Settings**************************************/
/*Before Calling the SCCB_Interface the inputs to the SCCB_Taskmanager   */
/*must be done.                */
/* Write to the "SCCB_Control" a "1" for reading from the Device or   */
/* a "2" for writing to the Device.           */
/*                   */
/* Leave the number of bytes totaly in "SCCB_Wordcount". Device Addresses*/
/* and Word Addresses included.            */
/*                   */
/* Write all data to the "SCCB_DataIn".          */
/* e.g.Writing to the device:            */
/*                   */
/*   SCCB_DataIn    Device Address (LSB must be Zero)  */
/*         Word Address       */
/*         Data 1         */
/*           .          */
/*           .          */
/*************************************************************************/
/* (e.g.Reading from the device:           */
/*   SCCB_DataIn    Device Address (LSB must be zero)   */
/*         Word Address       */
/*         Device Address (LSB must be one)  */
/*         Data can be read via SCCB_DataOut  */
/*************************************************************************/


#include <defBF533.h>

/*************** SCCB Constants  ************************************/
#define ISR_SCCB_Timer 0xFFE0202C //Address of the interrupt register (EVT11 in this case)
#define System_MMR_High_Address 0xFFC00000 //The high address word is handled like pages
#define Core_MMR_High_Address 0xFFE00000 //The high address word is handled like pages
#define SCL_PERIOD 0x200                  // scl_period >= 133MHz/(3 x 0.4MHz)
#define SCL_HIGH SCL_PERIOD >> 1
#define SCL 0x1            // serial clock is PF0
#define SDA 0x2            // serial data is PF1
#define scl_bit 0          // scl = PF0
#define sda_bit 1          // sda = PF1
/*************** SCCB Variables  ************************************/
.section L1_data_a;
.var  SCCB_Variable_High_Address;
.var  SCCB_Control;
.var  SCCB_Bit_Count;
.var  SCCB_Word_Count;
.var  SCCB_Write_Read_Register;
.var  SCCB_Data_Pointer;
.var  SCCB_DataIn[60];    
.var  SCCB_DataOut[60];    
.var  SCCB_Point_of_State;
.var  SCCB_Read_Count;
.var        SCCB_In_Progress = 0;
.var  SCCB_Read_Start_Cond0_Task_Val;
/*************** SCCB Macros ****************************************/
//These macros are used in all routine to push/pop all registers
//and to reset the timer interrupt again
#define SCCB_Start_Macro\
  [--SP] = ASTAT;\
  [-- SP] = (R7:0, P5:0)

#define SCCB_End_Macro\
  p0.h = hi(TIMER_STATUS);\
  p0.l = lo(TIMER_STATUS);\
  R0 = 0x0011 (z);\
  w[p0] = R0;\
  \
  (R7:0, P5:0) = [SP++];\
  ASTAT = [SP++];\
  SSYNC

/**********************************************************************/

/*************** SCCB Global Settings *********************************/
.section L1_code;
.global  SCCB_Interface;
.global  SCCB_Control;
.global  SCCB_Word_Count;
.global  SCCB_DataIn;    
.global  SCCB_DataOut;
.global  SCCB_Read_Count;
.global     SCCB_In_Progress;
/**********************************************************************/

 

/*************** SCCB Main Init ***************************************/
///////////////////////////////////////////////////////////////////////////
//No register must be kept for this Interface because all contents are  //
//stored in the variables above. As you can see before entering the     //
//SCCB_Interface Subroutine all registers will be pushed onto the stack. //
//For each access to the SCCB device this subroutine will just be executed/
//one time. After execution the pushed registers are poped back again.   //
//The Timer interrupt initialized in this "asm" file will link to the    //
//subroutines required for this interface each time it comes up          //
//The data sent to the device will be eight bits wide for configuration  //
//purposes to video devices only.           //
///////////////////////////////////////////////////////////////////////////
SCCB_Interface:
   [--SP] = ASTAT;
   [-- SP] = (R7:0, P5:0) ;

/*************** SCCB Timer Interrupt Vector Init ***********************/
//In case the timer will be used for several applications the Interrupt
//vetctor for this Interface is set here. The address of the routine to be
//executed at first is filled in the interrupt register here.

P0.H = hi(ISR_SCCB_Timer);
P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
r0.h =  SCCB_Start_Cond1;
r0.l =  SCCB_Start_Cond1;
[p0] = R0;    //ISR Start Address will be written in the EVT register

/*************** SCCB GPIO init as SDA and SCL ****************************/
 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers

 // disable PF inputs   
    p0.l = lo(FIO_INEN);
    r0 = w[p0](z);
    bitclr(r0, scl_bit);
    bitclr(r0, sda_bit);
    w[p0] = r0;

 //The Flag PF1(SDA) and PF0(SCL) shall be high
 p0.l = lo(FIO_FLAG_S);  
 r0 = w[p0](z);
 bitset(r0, scl_bit);
 bitset(r0, sda_bit);
 w[p0] = r0;


    //Set bit PF1(SDA) & PF0(SCL) as outputs
 p0.l = lo(FIO_DIR);
 r0 = w[p0](z);
 bitset(r0, scl_bit);
 bitset(r0, sda_bit);
 w[p0] = r0;


/*************************************************************************/

/***************** SCCB Timer0 Init ***************************************/
 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers

 p0.l = lo(TIMER_STATUS); 
 r0.l = 0x0011; w[p0] = r0;   //Clear Timer Interrupt and Overflow bit

 p0.l = lo(TIMER_DISABLE);   //disable timer
 r1 = 0x0001(z); 
 w[p0] = r0;
 
 /* Setup Timer0:  PWM_OUT mode, pulse hi, count to end of */
 /* period, interrupt, sample TMR0 pin, enable pad,     */
 /* Bit configuration:  0x001D = 0000 0000 0001 1101    */
 
 P0.L = lo(TIMER0_CONFIG);
 P0.H = hi(TIMER0_CONFIG);
 R0.L = 0x001D;
 W[P0] = R0.L;

 // The period is set to provide a 3:1 ratio of SCL to TMR0
 
 P0.L = lo(TIMER0_PERIOD);
 P0.H = hi(TIMER0_PERIOD);
 R0 = SCL_PERIOD (z);
 [P0] = R0;

 // Width of provides 50% duty cycle: scl_high = 1/2 of scl_period
 
 P0.L = lo(TIMER0_WIDTH);
 P0.H = hi(TIMER0_WIDTH);
 R0 = SCL_PERIOD >> 1 (z);
 [P0] = R0;

/*************************************************************************/

/*************** SCCB Timer0 Interrupt ************************************/
 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers


 p0.l = lo(SIC_IMASK);  //Timer0 has been enabled
 r0 = [p0];
 bitset(r0,16);    
 [p0] = r0;


 p0.h = hi(IMASK);
 p0.l = lo(IMASK);
 r0 = [p0];
 bitset(r0,11);
 [p0] = r0;       //Enable the "IVEC11" interrupt

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p0.l = lo(TIMER_ENABLE);    //enable timer
 r1 = 0x0001(z); 
 w[p0] = r0;

/*************************************************************************/

/*************** SCCB Start Setup ****************************************/
/*                   */
/*************************************************************************/
//prepares the variables used in this Interface

 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables
 p2.h = SCCB_Variable_High_Address;

 p1.l = SCCB_Bit_Count;
 r0 = 0x8;
 [p1] = r0; 

 p1.l = SCCB_Read_Count;
 r0 = 0x2;               // dev wr addr + word addr to start
 [p1] = r0;
 
 
 p1.l = SCCB_Read_Start_Cond0_Task_Val;
 r0 = 0;               // due to an extra start condition at reading from device
 [p1] = r0;     // this variable is reqired
 
 
 
 p1.l = SCCB_DataIn;
 p2.l = SCCB_Data_Pointer;
 [p2] = p1;
 p2.l = SCCB_Write_Read_Register;
 r0 = [p1];
 [p2] = r0;
/*************************************************************************/

  (R7:0, P5:0) = [SP++];
  ASTAT = [SP++];

SCCB_Interface.END:  
RTS;

//This is the end of the Init program. All other subroutine will be called
//by the Timer Interrupt separately.
/*************** SCCB End of Init ****************************************/

 


/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
//Each timer interrupt will just call one of the following subroutines.
//That restults to a SCCB speed depending of the Timer speed. The time
//between the timer interrupts can be used for processing of user data
//there are no loops that would cause a decrease of processor speed

/*************** SCCB Start Cond1 ****************************************/
SCCB_Start_Cond1:
 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers

 p0.l = lo(FIO_FLAG_C);  //The Flag PF1 (SDA) will be cleared at first (Start Condition!) 
 r0.l = SDA;
 w[p0] = r0;


 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Start_Cond2; r0.l =  SCCB_Start_Cond2;
 [p0] = R0;    //ISR Start Address will be written in the EVT register


 SCCB_End_Macro;
RTI;
/*************** SCCB Start Cond2 ****************************************/
SCCB_Start_Cond2:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers

 p0.l = lo(FIO_FLAG_C);  //The Flag PF0 (SCL) will be cleared at second (Start Condition!)
 r0.l = SCL;
 w[p0] = r0;

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Send_Data; r0.l =  SCCB_Send_Data;
 [p0] = R0;    //ISR Start Address will be written in the EVT register


 SCCB_End_Macro;
RTI;
/*************** SCCB Send Data to the Device*******************************/
//"SCCB_Send_Data" will send all the addresses and data required for communication
//to the device. The data must be shifted through the GPIO Pin PF1 (SDA)
SCCB_Send_Data:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address); //High address of all the system registers
 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables

 p1.l = SCCB_Write_Read_Register;
 r0 = [p1];

 CC = BITTST(r0, 7);
 IF CC JUMP SCCB_Send_DATA_SET_SDA; //Check the data bit in order to clear or
 p0.l = lo(FIO_FLAG_C);    //The contents of the bit check was zero
 r5.l = SDA;
 w[p0] = r5;   //so the GPIO pin must been cleared
JUMP SCCB_Bit_Sent_End;
 
SCCB_Send_DATA_SET_SDA: 
 p0.l = lo(FIO_FLAG_S);    //So, the GPIO pin must been set
 r5.l = SDA;
 w[p0] = r5; 

SCCB_Bit_Sent_End:     
 r0 = r0 << 1;      //shift the byte to get the next bit
 p1.l = SCCB_Write_Read_Register; //save the shifted byte for the run
 [p1] = r0;

 p1.l = SCCB_Bit_Count;    //load the bit counter to count the
 r1 = [p1];
 r1 += -1;       //decrement the bit counter.
 [p1] = r1;       //So, that last bit can be detected

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Write_Clock; r0.l =  SCCB_Write_Clock;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI;

SCCB_Send_DATA_Word_Sent: //byte has been sent
 // enable PF inputs   
    p0.l = lo(FIO_INEN);
    r0 = w[p0](z);
    bitset(r0, sda_bit);
    w[p0] = r0;

 p0.l = lo(FIO_DIR);  
 r0.l = w[p0];
 bitclr(r0, sda_bit);    //configure SDA bit as an input to accept slave acknowledge
 w[p0] = r0;   

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_ACK_TST; r0.l =  SCCB_ACK_TST;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI;
/*************** SCCB Send Data to the Device finish *******************************/

/*************** SCCB SCCB Clock routine********************************************/
SCCB_Write_Clock:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables

 p0.l = lo(FIO_FLAG_S);
 r0.l = W[p0];
 CC = BITTST (r0, scl_bit);
 IF CC JUMP SCCB_Set_Write_Clock_Low; // if scl high, then set it low
 r0 = SCL(z);                         // if scl low, then set it high
 w[p0] = r0;  

 SCCB_End_Macro;
RTI;     // remain in this state upon the next interrupt

SCCB_Set_Write_Clock_Low:

 p0.l = lo(FIO_FLAG_C);
 r0 = SCL(z);
 w[p0] = r0;

 p1.l = SCCB_Bit_Count;    //load the bit counter to count the
 r1 = [p1];
 CC = r1 == 0;
 IF CC JUMP SCCB_Send_DATA_Word_Sent;//If eight bits are sent get the next byte

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Send_Data; r0.l =  SCCB_Send_Data;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI;

/**************************************************************/
/*************** SCCB SCCB Acknowledge routines****************/

SCCB_ACK_Wait:   // After receiving a word an extra delay is insterted

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address); //High address of all the system registers
 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables
 
 p1.l = SCCB_Word_Count;
 r1 = [p1];
 CC = r1 == 1;
 IF CC JUMP No_Acknowledge_By_Master; 

 // disable PF inputs   
    p0.l = lo(FIO_INEN);
    r0 = w[p0](z);
    bitclr(r0, sda_bit);
    w[p0] = r0;

 //Acknowledge by master
 p0.l = lo(FIO_DIR);  
 r0.l = w[p0];   //Clear SDA to drive the master acknowledge
 bitset(r0, sda_bit);    //configure SDA bit as an output
 w[p0] = r0;   
 
 p0.l = lo(FIO_FLAG_C);             // drive SDA low    
 r0 = SDA(z);
 w[p0] = r0;


 P0.H = hi(ISR_SCCB_Timer);
 P0.L = lo(ISR_SCCB_Timer); // Int Vector Base Addr
 r0.h =  SCCB_ACK_TST;
 r0.l =  SCCB_ACK_TST;       // next state: test for ACK
 [p0] = R0;
 
 SCCB_End_Macro;
RTI;

 


No_Acknowledge_By_Master: 

 p0.l = lo(FIO_FLAG_S);             // drive SCL high   
 r0 = SCL(z);
 w[p0] = r0;

 P0.H = hi(ISR_SCCB_Timer);
 P0.L = lo(ISR_SCCB_Timer); // Int Vector Base Addr
 r0.h =  SCCB_ACK_MNGR;
 r0.l =  SCCB_ACK_MNGR;       // next state: test for ACK
 [p0] = R0;

 SCCB_End_Macro;
RTI;

 

SCCB_ACK_TST:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address); //High address of all the system registers
 
 p0.l = lo(FIO_FLAG_S);             // drive SCL high   
 r0 = SCL(z);
 w[p0] = r0;
 
 r0.l = W[p0];
 CC = BITTST (r0,sda_bit);  //Check SDA input. It should be low

 IF CC JUMP SCCB_ACK_Error;     //If not, something is wrong

 P0.H = hi(ISR_SCCB_Timer);
 P0.L = lo(ISR_SCCB_Timer); // Int Vector Base Addr
 r0.h =  SCCB_ACK_MNGR;
 r0.l =  SCCB_ACK_MNGR; // task manager state
 [p0] = R0;
 
 SCCB_End_Macro;
RTI;
 
SCCB_ACK_MNGR:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables

 p0.l = lo(FIO_FLAG_C);
 r0 = SCL (z);
 w[p0] = r0;      // toggle SCL to low
 
 
 [--SP] = RETS;   // enable nesting;  save return address to the stack
 CALL SCCB_Taskmanger;
 RETS = [sp++];

 SCCB_End_Macro;
RTI;


SCCB_ACK_Error:
NOP; // An error occured due to a miss of a slave Acknowledge!
JUMP SCCB_ACK_Error;

 SCCB_End_Macro;
RTI;
/*****************************************************************************************/

/*************** SCCB SCCB Taskmanger routine********************************************/
//The Taskmanager handles the different use of the interface. It can be written to the
//device or read from the device. Up to sixty bytes can be written to
//or read from the device. Finishing the data transfer links to the stop condition.

SCCB_Taskmanger:

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p1.h = SCCB_Variable_High_Address;  //works as a page for all Variables
 p2.h = SCCB_Variable_High_Address;

 p1.l = SCCB_Bit_Count;   //The bit counter must be loaded again after sending each byte
 r0 = 0x8;
 [p1] = r0; 

 p1.l = SCCB_Control;
 r0 = [p1];
 CC = r0 == 2;    //"1" means read from the device. "2" means write to the device
 IF CC JUMP SCCB_Write_Task;

 p1.l = SCCB_Read_Count;  //If read has been chosen care must been taken of the write read
 r1 = [p1];     //interaction
 CC = r1 == 0;
 IF CC JUMP SCCB_Read1_Task;  // jump after first 3 bytes got sent

 p2.l = SCCB_Read_Start_Cond0_Task_Val; 
 r2 = [p2];        // in read mode after device addr and sub addr has
 r2 = r1 | r2;       // been sent an extra start condition must be inserted 
 CC = r2 == 1;       // before the second device addr can be sent
 IF CC JUMP SCCB_Read_Start_Cond0_Task; 
 
 CC = r1 == 3;
 IF CC JUMP SCCB_Read2_Task; //"3" means start reading the device
 r1 += -1;                   // otherwise, decrement the count and keep writing
 [p1] = r1;

SCCB_Write_Task:
 // disable PF inputs   
    p0.l = lo(FIO_INEN);
    r0 = w[p0](z);
    bitclr(r0, sda_bit);
    w[p0] = r0;

 p0.l = lo(FIO_DIR);  
 r0.l = w[p0];
 bitset(r0, sda_bit);  //configure SDA as output
 w[p0] = r0;

 p1.l = SCCB_Word_Count;
 r1 = [p1];
 r1 += -1;
 [p1] = r1; 
 CC = r1 == 0;  //check the number of bytes already sent
 IF CC JUMP SCCB_Stop_Cond_Task; //invoke the stop condition when all bytes are sent
 
 p1.l = SCCB_Data_Pointer;
 p2 = [p1];
 NOP;
 NOP;
 NOP;
 p3 = [p2++];  //Increment the pointer to the data array
 [p1] = p2;

 p1.l = SCCB_Write_Read_Register;
 r1 = [p2];
 [p1] = r1;
 
 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Send_Data; r0.l =  SCCB_Send_Data;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

RTS;

SCCB_Read_Start_Cond0_Task:
//insert a delay to place the read start condition
 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Read_Start_Cond1_Task; r0.l =  SCCB_Read_Start_Cond1_Task;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

RTS;

SCCB_Read_Start_Cond1_Task:
 SCCB_Start_Macro;
//in order to generate the read start condition SDA & SCL must be set to high

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables

 // disable PF inputs   
    p0.l = lo(FIO_INEN);
    r0 = w[p0](z);
    bitclr(r0, sda_bit);
    w[p0] = r0;
 
 p0.l = lo(FIO_DIR);  
 r0.l = w[p0];
 bitset(r0, sda_bit); //configure SDA as output
 w[p0] = r0;

 p0.l = lo(FIO_FLAG_S);
 r0 = SCL | SDA(z);
 w[p0] = r0;    // set SDA & SCL

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Read_Start_Cond2_Task; r0.l =  SCCB_Read_Start_Cond2_Task;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI; 

SCCB_Read_Start_Cond2_Task:
 SCCB_Start_Macro;
//clear SDA at first to begin the start condition
 
 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables
 
 
 p0.l = lo(FIO_FLAG_C);
 r0 = SDA(z);
 w[p0] = r0;    //SDA to low
 
 p1.l = SCCB_Read_Start_Cond0_Task_Val; //after the read start condition has been executed
 r0 = 0x8 (z);      //it must never apear again
 [p1] = r0;
 
 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_ACK_MNGR; r0.l =  SCCB_ACK_MNGR;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI; 
 
SCCB_Stop_Cond_Task:
//start the stop condition procedure after all bytes has been sent
 
 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Stop_Cond0; r0.l =  SCCB_Stop_Cond0;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

RTS;

SCCB_Read1_Task:
 p1.l = SCCB_Read_Count;
 r0 = 3;
 [p1] = r0;

 p1.l = SCCB_Write_Read_Register; //Get the data to send
 r0 = 0;
 [p1] = r0;

 p1.l = SCCB_DataOut;
 p2.l = SCCB_Data_Pointer;
 [p2] = p1;

SCCB_Read2_Task:

 p1.l = SCCB_Word_Count;
 r1 = [p1];
 r1 += -1;
 [p1] = r1; 

 CC = r1 == 0;
 IF CC JUMP SCCB_Stop_Cond_Task; // Link to the Stop condition after all bytes has been received
 
 // make sure SDA is configured as input
 // enable PF inputs   
    p0.l = lo(FIO_INEN);
    r0 = w[p0](z);
    bitset(r0, sda_bit);
    w[p0] = r0;
 
 p0.l = lo(FIO_DIR);
 r0 = w[p0](z);
 bitclr(r0, sda_bit);
 w[p0] = r0;
 
 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Rcv_Clk_Test; r0.l =  SCCB_Rcv_Clk_Test;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

RTS;


/*************** SCCB Receive Data***************************************/
SCCB_Receive_Data:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address); //High address of all the system registers
 p1.h = SCCB_Variable_High_Address;  //works as a page for all Variables
 p2.h = SCCB_Variable_High_Address;

 p1.l = SCCB_Write_Read_Register; //Get the current rcv byte
 r0 = [p1];
 r0 = r0 << 1;      //shift the byte to get the next bit

 p1.l = SCCB_Word_Count;
 r1 = [p1];
 CC = r1 == 0;  //check the number of bytes already received
 IF CC JUMP SCCB_Stop_Receive_Data; 

 p0.l = lo(FIO_FLAG_S);
 r5.l = w[p0];
 CC = BITTST (r5,sda_bit);  //Check the SDA bit.
 IF CC JUMP SCCB_Receive_High_detected; 
 
 BITCLR (r0,0);
JUMP SCCB_End_of_Receive_Bit;

SCCB_Receive_High_detected:
 BITSET (r0,0);

SCCB_End_of_Receive_Bit:

 p0.l = lo(FIO_FLAG_C);
 r5.l = SCL;                      // drive SCL low
 w[p0] = r5;

 p1.l = SCCB_Write_Read_Register; //save the shifted byte for the run
 [p1] = r0;

 p1.l = SCCB_Bit_Count;           // update the bit count
 r1 = [p1];
 r1 += -1;
 [p1] = r1; 
 CC = r1 == 0;                   // check if it was the last bit
 IF CC JUMP SCCB_Receive_Data_Word_Sent; // jump when last bit

 P0.H = hi(ISR_SCCB_Timer);
 P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Rcv_Clk_Test;
 r0.l =  SCCB_Rcv_Clk_Test;   // next state
 [p0] = R0;

 SCCB_End_Macro;
RTI;

SCCB_Receive_Data_Word_Sent:

 p1.l = SCCB_Data_Pointer;
 p2 = [p1];
 p3.l = SCCB_Write_Read_Register; //save the shifted byte for the run
 p3.h = SCCB_Write_Read_Register; 
 r0 = [p3];
 [p2] = r0;
 r0 = 0;
 [p3] = r0;   //clear the content of "SCCB_Write_Read_Register" for next byte
 NOP;    //3 cycles will be required for read an write action
 NOP;
 NOP;
 p3 = [p2++];  //Increment the pointer to the data array
 [p1] = p2;

 P0.H = hi(ISR_SCCB_Timer);
 P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_ACK_Wait;
 r0.l =  SCCB_ACK_Wait;    //go to this state to wait one int period
 [p0] = R0;

 SCCB_End_Macro;
RTI;

SCCB_Stop_Receive_Data:
 // disable PF inputs   
    p0.l = lo(FIO_INEN);
    r0 = w[p0](z);
    bitclr(r0, sda_bit);
    w[p0] = r0;
 
 p0.l = lo(FIO_DIR);  
 r0.l = w[p0];
 bitset(r0, sda_bit); // configure SDA as output
 w[p0] = r0;

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Stop_Cond2; r0.l =  SCCB_Stop_Cond2;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI;
/*************** SCCB Receive Clock Test routine********************************************/

SCCB_Rcv_Clk_Test:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address); //High address of all the system registers
 p1.h = SCCB_Variable_High_Address; //works as a page for all Variables

 p0.l = lo(FIO_FLAG_S);
 r0.l = W[p0];
 CC = BITTST (r0, scl_bit);
 IF CC JUMP SCCB_Set_Rcv_Clk_Lo;    // if scl high, jump to clear it
 
 // if scl low, then set it high in the next state
 P0.H = hi(ISR_SCCB_Timer);
 P0.L = lo(ISR_SCCB_Timer);  //interrupt vector base addr
 r0.h =  SCCB_Rcv_Clk_Hi;
 r0.l =  SCCB_Rcv_Clk_Hi;    // next state
 [p0] = R0;
 
 SCCB_End_Macro;
RTI;

SCCB_Set_Rcv_Clk_Lo:

 p0.l = lo(FIO_FLAG_C);
 r0 = SCL(z);
 w[p0] = r0;                  // set SCL low

 SCCB_End_Macro;
RTI;      // stay in this state until the next interrupt

/*****************************************************************/
/*************** SCCB Receive Clock Hi routine********************/

SCCB_Rcv_Clk_Hi:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p0.l = lo(FIO_FLAG_S);
 r0 = SCL (z);
 w[p0] = r0;                             // set SCL high
 
 P0.H = hi(ISR_SCCB_Timer);
 P0.L = lo(ISR_SCCB_Timer);  //interrupt vector base addr
 r0.h =  SCCB_Receive_Data;
 r0.l =  SCCB_Receive_Data;  // next state
 [p0] = R0;
 
 SCCB_End_Macro;
RTI;


/**************************************************************/

/*************** SCCB Stop Cond0,1 ****************************/
//Invoke stop condition if the transmission is complete
SCCB_Stop_Cond0:  // do nothing (just a delay)

 SCCB_Start_Macro;

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Stop_Cond1; r0.l =  SCCB_Stop_Cond1;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI;

SCCB_Stop_Cond1:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p0.l = lo(FIO_FLAG_S); 
 r0 = SCL(z);
 w[p0] = r0;

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_Stop_Cond2; r0.l =  SCCB_Stop_Cond2;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI;
/*************** SCCB Stop Cond2 ****************************************/
SCCB_Stop_Cond2:

 SCCB_Start_Macro;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p0.l = lo(FIO_FLAG_S);              //set SDA high to stop
 r0 = SDA (z);
 w[p0] = r0;

 P0.H = hi(ISR_SCCB_Timer); P0.L = lo(ISR_SCCB_Timer); //Base address of the interrupt vector
 r0.h =  SCCB_End_of_Transmission; r0.l =  SCCB_End_of_Transmission;
 [p0] = R0;    //ISR Start Address will be written in the EVT register

 SCCB_End_Macro;
RTI;
/*************** SCCB Stop Cond2 ****************************************/
//The transmission ends and all the timer settings must be diabled
//This would be a good place to set a bit to replay the transfer is done
SCCB_End_of_Transmission:

 SCCB_Start_Macro;

 p0.l = lo(TIMER_DISABLE);   //disable timer
 r1 = 0x0001(z); 
 w[p0] = r0;

 p0.h = hi(System_MMR_High_Address);  //High address of all the system registers
 p0.l = lo(TIMER_STATUS); 
 r0 = 0x1011(z);
 w[p0] = r0; //disable the timer clear interrupt bit and overflow bit

    p0.l = lo(SIC_IMASK);    //disable mask the Timer0 again
 r0 = [p0];
 bitclr(r0,16);
 [p0] = r0;
 
 p0.h = SCCB_In_Progress;       //keeps the core away from calling the SCCB twice
 p0.l = SCCB_In_Progress;
 r0 = 0;
 [p0] = r0;
 
 SCCB_End_Macro;

RTI;
/*****************************************************************************************/

//本代码Blackfin示例

文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    FPGA+DSP实时三维图像信息处
    ADP-TS101 EzFlash示例程序
    ADSP TS101EzFlash (C)源代码
    ADI DSP双精度除法的例子
    ADI GPS导航解决方案
    用对数放大器实现射频功率控
    ADI DSP的单精度随机斜率滤波
    多路跟踪滤波同步数据采集系
    基于单片机的车载超级电容测
    设计面向高清电视的全数字音
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    版权所有:Analog安诺电子网 湘ICP备06016315号