www.pudn.com > PPI.rar > I2C.c
#include "I2C.h" /*------------------------------------------------------------------------------ // I2C Peripheral Function Prototypes //------------------------------------------------------------------------------ void Init(void); // Initialize I2C port void Start(void); // Sends I2C Start Trasfer void Stop(void); // Sends I2C Stop Trasfer bool Write(unsigned char data_out); // Writes data over the I2C bus bool Read(unsigned char *data_in, bool send_ack);// Reads data from the I2C bus void SetSCLK(bool state); // Set SCLK tovoid SetSDATA(bool state); // Set SDATA to bool GetSDATA(); // Get SDATA state */ //------------------------------------------------------------------------------ // I2C Peripheral Variables //------------------------------------------------------------------------------ unsigned int Delay = 0x00000000; unsigned char IdentAddr = 0x0; //------------------------------------------------------------------------------ // I2C Functions - Master //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Routine: Init // Inputs: none // Outputs: none // Purpose: Initialize I2C for the ADu812C //------------------------------------------------------------------------------ void INL Init(void) { *pFIO_DIR |= SCLK; // Set SCLK as output and SDATA as input/high *pFIO_POLAR &= ~SDATA; // Enable Active Hight *pFIO_EDGE &= ~SDATA; // Enable Level Sensitivity *pFIO_INEN |= SDATA; // Enable SDATA Input Buffer SetSDATA(1); // Set SDATA as input/high SetSCLK(1); // Set SCLK high } //------------------------------------------------------------------------------ // Routine: Start // Inputs: none // Outputs: none // Purpose: Sends I2C Start Trasfer - "S" //------------------------------------------------------------------------------ void INL Start(void) { // 11182003 - Following line has been added! (Fixed thanks to Andrew Seddon). // Shouldn't Stop() be setting SCLK high? SetSCLK(1); // Set SCLK high SetSDATA(0); // Set SDATA output/low SetSCLK(0); // Set SCLK low } //------------------------------------------------------------------------------ // Routine: Stop // Inputs: none // Outputs: none // Purpose: Sends I2C Stop Trasfer - "P" //------------------------------------------------------------------------------ void INL Stop(void) { SetSDATA(0); // Set SDATA output/low SetSCLK(1); // Set SCLK high SetSDATA(1); // Set SDATA as input/high } //------------------------------------------------------------------------------ // Routine: Write // Inputs: data_out // Outputs: bool // Purpose: Writes data over the I2C bus and return status. //------------------------------------------------------------------------------ bool INL Write(unsigned char data_out) { unsigned char index; // An I2C output byte is bits 7-0 (MSB to LSB). Shift one bit at a time to // the SDATA output, and then clock the data to the I2C Slave device. // Send 8 bits out the port for(index = 0; index < 8; index++) { // Output the data bit to the device SetSDATA(((data_out & 0x80) ? 1 : 0)); data_out <<= 1; // Shift the byte by one bit SetSCLK(1); // Set SCLK high SetSCLK(0); // Set SCLK low } SetSDATA(1); // Set SDATA input/high SetSCLK(1); // Set SCLK high if (!GetSDATA()) { SetSCLK(0); // Set SCLK low return true; // ACK from slave } else { SetSCLK(0); // Set SCLK low return false; // NACK from slave } } //------------------------------------------------------------------------------ // Routine: Read // Inputs: *data_in, send_ack (if true send the ACK signal else send NACK) // Outputs: bool // Purpose: Reads data from the I2C bus and return it in data_in. // Returns status. //------------------------------------------------------------------------------ bool INL Read(unsigned char *data_in, bool send_ack) { unsigned char index; *data_in = 0x00; SetSDATA(1); // Set SDATA input/high SetSCLK(0); // Set SCLK low // Get 8 bits from the device for(index = 0; index < 8; index++) { *data_in <<= 1; // Shift the data right 1 bit SetSCLK(1); // Set SCLK high // 11182003 - Line moved... // SetSCLK(0); // Set SCLK low *data_in |= GetSDATA(); // Read the data bit // 11182003 - to here! (Fixed thanks to Andrew Seddon). SetSCLK(0); // Set SCLK low } if (send_ack) SetSDATA(0); // Set data pin to output/low to ACK the read else SetSDATA(1); // Set data pin to input/high to NACK the read SetSCLK(1); // Set SCLK high SetSCLK(0); // Set SCLK low SetSDATA(0); // Set SDATA output/low SetSDATA(1); // Set SDATA input/high return true; } //------------------------------------------------------------------------------ // Routine: SetSDATA // Inputs: state // Outputs: none // Purpose: Set the I2C port SDATA pin to . //------------------------------------------------------------------------------ void INL SetSDATA(bool state) { unsigned int i, d; if (state) { *pFIO_DIR &= ~SDATA; // Set SDATA as input/high. } else { *pFIO_DIR |= SDATA; // Set SDATA as output. *pFIO_FLAG_D &= ~SDATA; // Set SDATA low. } // Delay for (i = 0; i < Delay; i++) { asm("nop;"); } } //------------------------------------------------------------------------------ // Routine: SetSCLK // Inputs: state // Outputs: none // Purpose: Set the I2C port SCLK pin to . //------------------------------------------------------------------------------ void INL SetSCLK(bool state) { unsigned int i, d; if (state) { *pFIO_FLAG_D |= SCLK; // Set SCLK high. } else { *pFIO_FLAG_D &= ~SCLK; // Set SCLK low. } // Delay for (i = 0; i < Delay; i++) { asm("nop;"); } } //------------------------------------------------------------------------------ // Routine: GetSDATA // Inputs: none // Outputs: bool // Purpose: Get the I2C port SDATA pin state. //------------------------------------------------------------------------------ bool INL GetSDATA() { return ((*pFIO_FLAG_D & SDATA) ? 1 : 0); } //------------------------------------------------------------------------------ // Procedure: I2C_Init // Inputs: identaddr // Outputs: bool // Description: Initialize I2C and setup Slave Ident Addr. then check the ident // for response and returns true if ok. //------------------------------------------------------------------------------ bool I2C_Init(unsigned char identaddr) { bool ret; // Calculate Delay NEED FIX!!! Delay = ((*pPLL_CTL & 0x7e00) >> 9)*15; //Delay = 0x1000; if ((*pPLL_CTL & 0x0001) == 0x0001) Delay /= 2; IdentAddr = identaddr; Init(); // Initialize I2C port Start(); // Check Slave Ident Addr ret = Write(IdentAddr); Stop(); return ret; // Return true if Ident Addr. Ok } //------------------------------------------------------------------------------ // Procedure: I2C_Write // Inputs: data out, address // Outputs: bool // Description: Writes a byte to the given address and return status. //------------------------------------------------------------------------------ extern bool I2C_Write(unsigned char data_out, unsigned char address) { Start(); // Send start signal if (!Write(IdentAddr)) // Send identifier I2C address { Stop(); // Send I2C Stop Transfer return false; } DelayTVP5150(); if (!Write(address)) // Send address to device { Stop(); // Send I2C Stop Transfer return false; } DelayTVP5150(); if (!Write(data_out)) // Send byte to device { Stop(); // Send I2C Stop Transfer return false; } DelayTVP5150(); Stop(); // Send I2C Stop Transfer // DelayTVP5150(); return true; } //------------------------------------------------------------------------------ // Procedure: I2C_Read // Inputs: *data_in, address // Outputs: bool // Description: Reads a byte from the given address and return status. //------------------------------------------------------------------------------ bool I2C_Read(unsigned char *data_in, unsigned char address) { Start(); // Send start signal if (!Write(IdentAddr)) // Send identifer I2C address { Stop(); // Send I2C Stop Transfer return false; } DelayTVP5150(); if (!Write(address)) // Send address to device { Stop(); // Send I2C Stop Transfer return false; } DelayTVP5150(); Start(); // Send I2C Start Transer if (!Write(IdentAddr+1)) // Send identifer I2C address { Stop(); // Send I2C Stop Transfer return false; } DelayTVP5150(); if (!Read(data_in, false)) // Read byte { Stop(); // Send I2C Stop Transfer return false; } DelayTVP5150(); Stop(); // Send I2C Stop Transfer return true; } void INL DelayTVP5150() { asm("p0.l=0x57C0;"); asm("p0.h=0x1;"); asm("lsetup(_delay_begin,_delay_end) lc0=p0;"); asm("_delay_begin:"); asm("_delay_end:"); asm("nop;"); } //------------------------------------------------------------------------------ // Procedure: TVP5150_Reset // Inputs: bReset // Outputs: bool // Description: Reset TVP5150,bReset = 1 is reset =0 is cancel // returns true if ok. //Reset address is 0x05h //------------------------------------------------------------------------------ bool TVP5150_Reset(bool bReset) { bool Status; I2C_Init(0xB8);//0xBA for high I2CSEL if(bReset){ Status = I2C_Write(0x01,0x05); return Status; } else return true; } //------------------------------------------------------------------------------ // Procedure: TVP5150_Cnfg // Inputs: SourceMode£º // 0:from A Channel input the Composite analog Video signal // 1:from B Channel input the Composite analog Video signal // 2:from A and B Channel input luma and chroma signal // else: nothing // OutputMode£º // 0:output ITU-R.BT601 PAL-N signal 625 // 1:output ITU-R.BT601 PAL-M signal 625 // 2:output ITU-R.BT601 NTSC signal 525 // 3:output ITU-R.BT601 SECAM signal 625 // 4:output ITU-R.BT656 NTSC signal 525 // 5:output ITU-R.BT656 PAL signal 625 // other:not support // Outputs: bool // 0=ok,1=error // Description: // Set TVP5150 signal input channel and output signal format. // and set other correlative register //------------------------------------------------------------------------------ bool TVP5150_Cnfg(int SourceMode, int OutputMode) { bool Status; //unsigned char temp; switch(SourceMode){ case 0: Status = I2C_Write(0x0,0x0); break; case 1: Status = I2C_Write(0x02,0x0); break; case 2: Status = I2C_Write(0x01,0x0); break; default: } switch(OutputMode){ case 0: // 601 PAL-N Status = I2C_Write(0x0f,0x03); Status = I2C_Write(0xf4,0x04); Status = I2C_Write(0x40,0x0d); break; case 1://601 PAL-M Status = I2C_Write(0x0f,0x03); Status = I2C_Write(0x0f,0x04); Status = I2C_Write(0x40,0x0d); break; case 2://601 NTSC Status = I2C_Write(0x0f,0x03); Status = I2C_Write(0xec,0x04); Status = I2C_Write(0x40,0x0d); break; case 3://601 SECAM Status = I2C_Write(0x0f,0x03); Status = I2C_Write(0xdc,0x04); Status = I2C_Write(0x40,0x0d); break; case 4://656 NTSC Status = I2C_Write(0x29,0x03); Status = I2C_Write(0xec,0x04); Status = I2C_Write(0x47,0x0d); Status = I2C_Write(0x40,0x07);//insert ancilly header break; case 5://656 PAL Status = I2C_Write(0x7f,0x03); // Status = I2C_Write(0xc0,0x04); Status = I2C_Write(0x40,0x07);//insert ancilly header Status = I2C_Write(0x47,0x0d); Status = I2C_Write(0x0,0x0f); break; default: } }