?? i2c.c
字號:
//--------------------------------------------------------------------------//
// //
// Name: I2C Communication for the ADSP-BF533 EZ-KIT Lite //
// //
//--------------------------------------------------------------------------//
// //
// (C) Copyright 2003 - Carsten Knop. All rights reserved. //
// //
// Project Name: BF533 C I2C Communication (Bit Banged) //
// //
// Date Modified: 09/30/03 CK Rev 0.9 //
// Date Modified: 11/18/03 CK Rev 1.0 //
// Fixed Read() function thanks to Andrew Seddon and the //
// www.blackfin.org's forum. //
// //
// Software: VisualDSP++3.1 //
// //
// Hardware: ADSP-BF533 EZ-KIT Board //
// //
// Connections: //
// //
// Purpose: I2C Communication with ADV7171 Encoder and //
// ADV7183 Decoder. //
// //
// To Do: Fix dDelay Method. (100 khz/400 khz or faster to support //
// extra added I2C ICs such as the fast serial FRAMs. //
// Extra functions should be added to read and write //
// strings. //
//--------------------------------------------------------------------------//
#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
RESULT Write(u8 pByDataOut); // Writes data over the I2C bus
RESULT Read(u8 *pByDataIn, bool bSendAck);// Reads data from the I2C bus
void SetSCLK(bool state); // Set SCLK to <state>
void SetSDATA(bool state); // Set SDATA to <state>
bool GetSDATA(void); // Get SDATA state
//------------------------------------------------------------------------------
// I2C Peripheral Variables
//------------------------------------------------------------------------------
u8 byIdentAddr = 0x00;
u32 dDelay = 0x00000000;
//------------------------------------------------------------------------------
// Procedure: I2C_Init
// Inputs: identaddr
// Outputs: RESULT
// Description: Initialize I2C and setup Slave Ident Addr. then check the ident
// for response and returns EJ_ERR_NONE if ok.
//------------------------------------------------------------------------------
RESULT I2C_Init(u8 identaddr)
{
RESULT ret;
// Calculate dDelay NEED FIX!!!
dDelay = ((*pPLL_CTL & 0x7e00) >> 9);
if ((*pPLL_CTL & 0x0001) == 0x0001)
dDelay /= 2;
byIdentAddr = identaddr;
Init(); // Initialize I2C port
Start(); // Check Slave Ident Addr
ret = Write(byIdentAddr);
Stop();
return ret; // Return EJ_ERR_NONE if Ident Addr. Ok
}
//------------------------------------------------------------------------------
// Procedure: I2C_Write
// Inputs: data out, address
// Outputs: RESULT
// Description: Writes a byte to the given address and return status.
//------------------------------------------------------------------------------
RESULT I2C_Write(u8 *pDataOut, u8 address,char num_data)
{
u8 count = 0;
Start(); // Send start signal
if (Write(byIdentAddr) != EJ_ERR_NONE) // Send identifier I2C address
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
if (Write(address) != EJ_ERR_NONE) // Send address to device
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
for (count = 0;count < num_data;count++)
{
if (Write(*pDataOut) != EJ_ERR_NONE) // Send byte to device
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
pDataOut ++;
}
Stop(); // Send I2C Stop Transfer
return EJ_ERR_NONE;
}
//------------------------------------------------------------------------------
// Procedure: I2C_Read
// Inputs: *data_in, address
// Outputs: RESULT
// Description: Reads a byte from the given address and return status.
//------------------------------------------------------------------------------
RESULT I2C_Read(u8 *pbyDataIn, u8 byAddress,char numData)
{
u8 count = 0;
Start(); // Send start signal
if (Write(byIdentAddr) != EJ_ERR_NONE) // Send identifer I2C address
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
if (Write(byAddress) != EJ_ERR_NONE) // Send address to device
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
Start(); // Send I2C Start Transer
if (Write(byIdentAddr+1) != EJ_ERR_NONE) // Send identifer I2C address
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
for (count = 0;count < numData;count++)
{
if(count == numData)
{
if (Read(pbyDataIn, EJ_ERR_UNKNOWN) != EJ_ERR_NONE) // Read byte
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
}
else
{
if (Read(pbyDataIn, EJ_ERR_NONE)!= EJ_ERR_NONE) // Read byte
{
Stop(); // Send I2C Stop Transfer
return EJ_ERR_UNKNOWN;
}
pbyDataIn ++;
}
}
Stop(); // Send I2C Stop Transfer
return EJ_ERR_NONE;
}
//------------------------------------------------------------------------------
// I2C Functions - Master
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Routine: Init
// Inputs: none
// Outputs: none
// Purpose: Initialize I2C for the ADu812C
//------------------------------------------------------------------------------
void INL Init(void)
{
#if defined(__ADSP_EDINBURGH__)
*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
#endif
#if defined(__ADSP_TETON__)
*pFIO0_DIR |= SCLK; // Set SCLK as output and SDATA as input/high
*pFIO0_POLAR &= ~SDATA; // Enable Active Hight
*pFIO0_EDGE &= ~SDATA; // Enable Level Sensitivity
*pFIO0_INEN |= SDATA; // Enable SDATA Input Buffer
#endif
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: pDataOut
// Outputs: RESULT
// Purpose: Writes data over the I2C bus and return status.
//------------------------------------------------------------------------------
RESULT INL Write(u8 pByDataOut)
{
u8 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(((pByDataOut & 0x80) ? 1 : 0));
pByDataOut <<= 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 EJ_ERR_NONE; // ACK from slave
} else
{
SetSCLK(0); // Set SCLK low
return EJ_ERR_UNKNOWN; // NACK from slave
}
}
//------------------------------------------------------------------------------
// Routine: Read
// Inputs: *data_in, send_ack (if EJ_ERR_NONE send the ACK signal else send NACK)
// Outputs: RESULT
// Purpose: Reads data from the I2C bus and return it in data_in.
// Returns status.
//------------------------------------------------------------------------------
RESULT INL Read(u8 *pByDataIn, bool bSendAck)
{
u8 index;
*pByDataIn = 0x00;
SetSDATA(1); // Set SDATA input/high
SetSCLK(0); // Set SCLK low
// Get 8 bits from the device
for(index = 0; index < 8; index++)
{
*pByDataIn <<= 1; // Shift the data right 1 bit
SetSCLK(1); // Set SCLK high
// 11182003 - Line moved...
// SetSCLK(0); // Set SCLK low
*pByDataIn |= GetSDATA(); // Read the data bit
// 11182003 - to here! (Fixed thanks to Andrew Seddon).
SetSCLK(0); // Set SCLK low
}
if (bSendAck)
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 EJ_ERR_NONE;
}
//------------------------------------------------------------------------------
// Routine: SetSDATA
// Inputs: state
// Outputs: none
// Purpose: Set the I2C port SDATA pin to <state>.
//------------------------------------------------------------------------------
void INL SetSDATA(bool state)
{
u32 i, d;
#if defined(__ADSP_EDINBURGH__)
if (state)
{
*pFIO_DIR &= ~SDATA; // Set SDATA as input/high.
*pFIO_INEN |= SDATA; // Enable SDATA Input Buffer
} else
{
*pFIO_DIR |= SDATA; // Set SDATA as output.
*pFIO_INEN &= ~SDATA; // Disable SDATA Input Buffer
*pFIO_FLAG_D &= ~SDATA; // Set SDATA low.
}
#endif
#if defined(__ADSP_TETON__)
if (state)
{
*pFIO0_DIR &= ~SDATA; // Set SDATA as input/high.
*pFIO0_INEN |= SDATA; // Enable SDATA Input Buffer
} else
{
*pFIO0_DIR |= SDATA; // Set SDATA as output.
*pFIO0_INEN &= ~SDATA; // Disable SDATA Input Buffer
*pFIO0_FLAG_D &= ~SDATA; // Set SDATA low.
}
#endif
// dDelay
for (i = 0; i < dDelay; i++) { asm("nop;"); }
}
//------------------------------------------------------------------------------
// Routine: SetSCLK
// Inputs: state
// Outputs: none
// Purpose: Set the I2C port SCLK pin to <state>.
//------------------------------------------------------------------------------
void INL SetSCLK(bool state)
{
unsigned int i, d;
#if defined(__ADSP_EDINBURGH__)
if (state)
{
*pFIO_FLAG_D |= SCLK; // Set SCLK high.
} else
{
*pFIO_FLAG_D &= ~SCLK; // Set SCLK low.
}
#endif
#if defined(__ADSP_TETON__)
if (state)
{
*pFIO0_FLAG_D |= SCLK; // Set SCLK high.
} else
{
*pFIO0_FLAG_D &= ~SCLK; // Set SCLK low.
}
#endif
// dDelay
for (i = 0; i < dDelay; i++) { asm("nop;"); }
}
//------------------------------------------------------------------------------
// Routine: GetSDATA
// Inputs: none
// Outputs: RESULT
// Purpose: Get the I2C port SDATA pin state.
//------------------------------------------------------------------------------
bool INL GetSDATA(void)
{
#if defined(__ADSP_EDINBURGH__)
return ((*pFIO_FLAG_D & SDATA) ? 1 : 0);
#endif
#if defined(__ADSP_TETON__)
return ((*pFIO0_FLAG_D & SDATA) ? 1 : 0);
#endif
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -