/* **************************************************************
* File: I2C_3.c
*
* Copyright (c) 2010 by Conspec Controls Ltd.
* All rights reserved. Property of Conspec Controls Ltd.
*
* Created by Frank Tu
*
* July 07, 2010
*
* Revision Date Description
* ========= ============= ===================================
* 0.00 April 22, 2010 Original
*
*
* **************************************************************
*/
#include "I2C_3.h" // common definitions
#include "msp430x26x.h"
//#include "Delay.h"
extern unsigned char IRpulseBuff1[];
/****************** Public Variables ***********************************/
unsigned char ucI2C_3_Err;
/****************** Private Variables **********************************/
static char cI2C_3_Status; // Status code
// used also to indicating if
// Data has been sent / received
/**************** Private Functions Definitions **********************/
void I2C_3_SendStop ( void ); // sends stop signal
void I2C_3_SendStart ( void ); // sends start signal
// clears error code !!!
void I2C_3_SCL_3_High ( void ); // sets SCL_3 = 1 and checks if it is high
// if it is not, there is a vDelay
// error is generated if SCL_3 is hold low
// for certain duration
void I2C_3_SendByte ( unsigned char ucData );
// sends 1 byte, checks ACK / NACK
unsigned char I2C_3_GetByte ( unsigned char ucLastByteFlag );
// receives 1 byte.
// If ucLastByteFlag > 0 receives last byte - sends NACK
// at the end of the transmission
/********************** Public Functions ****************************/
/******** Initialization procedure *************/
void vInitI2C_3 ( void )
{
I2C_3_PORT_DIR &= ~I2C_3_MASK; // set SCL_3 and SDA_3 to inputs = high SCL_3 and SDA_3 lines
I2C_3_PORT_OUT &= ~I2C_3_MASK; // SDA_3 and SCL_3 outputs low
// output pin is controled only by I2C_3_PORT_DIR
// configured as output = 0
// input = 1
}
/*********************************************/
void I2C_3_DelayWriteByte ( unsigned char ucDevAddr,
unsigned char ucDataAddr,
unsigned char ucData,
unsigned int uivDelay )
{
//I2C_3_MASK_IE_PORT &= ~I2C_3_IRQ_MASK; // forbid IRQ
vDelay ( uivDelay );
// move IRQ mask here ????
I2C_3_SendStart();
if ( cI2C_3_Status == I2C_3_OK )
{
I2C_3_SendByte( ucDevAddr );
I2C_3_SendByte( ucDataAddr );
I2C_3_SendByte( ucData );
}
I2C_3_SendStop();
ucI2C_3_Err = cI2C_3_Status;
//I2C_3_MASK_IE_PORT |= I2C_3_IRQ_MASK; // allow IRQ
}
/*********************************************/
void vI2C_3_DelayWrite4Bytes (unsigned char ucDevAddr,
unsigned char ucDataAddr,
unsigned long ulData,
unsigned int uivDelay )
{
char i;
//I2C_3_MASK_IE_PORT &= ~I2C_3_IRQ_MASK; // forbid IRQ
vDelay ( uivDelay );
// move IRQ mask here ???
I2C_3_SendStart();
if ( cI2C_3_Status == I2C_3_OK )
{
I2C_3_SendByte( ucDevAddr );
I2C_3_SendByte( ucDataAddr );
for ( i = 0; i < 4; i++ ) // does not check cI2C_3_Status for bytes
{
I2C_3_SendByte( (unsigned char) (ulData >>(24-8*i)) );
}
}
I2C_3_SendStop();
ucI2C_3_Err = cI2C_3_Status;
//I2C_3_MASK_IE_PORT |= I2C_3_IRQ_MASK; // allow IRQ
}
/*********************************************/
void I2C_3_DelayWriteByteNum ( unsigned char ucDevAddr,
unsigned char ucDataAddr,
unsigned char const *pucData,
unsigned char ucNumBytes,
unsigned int uivDelay )
{
char i;
//I2C_3_MASK_IE_PORT &= ~I2C_3_IRQ_MASK; // forbid IRQ
vDelay ( uivDelay );
// move IRQ mask here ???
I2C_3_SendStart();
if ( cI2C_3_Status == I2C_3_OK )
{
I2C_3_SendByte( ucDevAddr );
I2C_3_SendByte( ucDataAddr );
for ( i = 0; i < ucNumBytes; i++ ) // does not check cI2C_3_Status for bytes
I2C_3_SendByte( *(pucData + i) );
}
I2C_3_SendStop();
ucI2C_3_Err = cI2C_3_Status;
//I2C_3_MASK_IE_PORT |= I2C_3_IRQ_MASK; // allow IRQ
}
/********************************************/
unsigned char I2C_3_ReadByte ( unsigned char ucDevAddr,
unsigned char ucDataAddr)
{
unsigned char ucData;
//I2C_3_MASK_IE_PORT &= ~I2C_3_IRQ_MASK; // forbid IRQ
_NOP();
I2C_3_SendStart();
if ( cI2C_3_Status == I2C_3_OK )
{
I2C_3_SendByte( ucDevAddr ); // write address !!
I2C_3_SendByte( ucDataAddr );
I2C_3_SendStop();
I2C_3_SendStart();
I2C_3_SendByte( ucDevAddr | I2C_3_READ ); // read address
//ucData = I2C_3_Get_two_Bytes( I2C_3_LAST_BYTE ); // return value
ucData = I2C_3_GetByte( I2C_3_LAST_BYTE ); // return value
//I2C_3_SendStop();
//I2C_3_SendStart();
//I2C_3_SendByte( ucDataAddr );
//I2C_3_SendStop();
//I2C_3_SendStart();
//I2C_3_SendByte( ucDevAddr | I2C_3_READ ); // read address
//ucData = I2C_3_GetByte( I2C_3_LAST_BYTE ); // return value
}
I2C_3_SendStop();
ucI2C_3_Err = cI2C_3_Status;
//I2C_3_MASK_IE_PORT |= I2C_3_IRQ_MASK; // allow IRQ
return ucData;
}
/****************** Private Functions ******************************/
/******** Start Signal procedure ************/
void I2C_3_SendStart ( void ) // check if I2C_3 bus is being used
{ // must be high state at both SCL_3 and SDA_3
unsigned char ucvDelay = I2C_3_WAIT;
cI2C_3_Status = I2C_3_OK; // Clear previous error ... new try
I2C_3_SCL_3_High(); //
/**/
while ( (( I2C_3_PORT_IN & I2C_3_MASK) != I2C_3_MASK) // both SCL_3 and SDA_3 must be high to continue
&& ( ucvDelay != 0 )) // vDelay - waiting for the BUS to become available
{
ucvDelay--;
}
if ( ucvDelay == 0 ) // uivDelay = 0 => time-out
cI2C_3_Status = I2C_3_BUSY; // error
else // no error
{
cI2C_3_Status = I2C_3_OK;
I2C_3_PORT_DIR |= SDA_3; // SDA_3 pin = 0
vDelay ( I2C_3_DELAY ); // vDelay
I2C_3_PORT_DIR |= SCL_3; // SCL_3 pin = 0
}
}
/********** Set SCL_3 high *****************/
void I2C_3_SCL_3_High ( void )
{
unsigned int uiCycle = SCL_3_MAX_WAIT_CYCLES; // maximum waiting cycles
vDelay ( I2C_3_DELAY ); // Delay
_NOP();
I2C_3_PORT_DIR &= ( ~SCL_3 ); // SCL_3 pin = 1
vDelay ( I2C_3_DELAY ); // Delay
_NOP();
while ( !(I2C_3_PORT_IN & SCL_3) ) // is the slave IC holding SCL_3 = 0 ?
{
uiCycle--;
vDelay ( 10 ); // each cycle approximately = 1ms
if ( uiCycle == 0 )
{
cI2C_3_Status = I2C_3_SCL_3_LOW; // time-out => SCL_3 line is stuck low for too long
return;
}
}
}
void I2C_3_SCL_3_High_for_CP_writting ( void )
{
unsigned int
评论0