📄 i2c.c
字号:
//===============================================================================
// TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION
//
// Property of Texas Instruments
// For Unrestricted Internal Use Only
// Unauthorized reproduction and/or distribution is strictly prohibited.
// This product is protected under copyright law and trade secret law
// as an unpublished work.
// Created 1999, (C) Copyright 2000 Texas Instruments. All rights reserved.
//
// Filename : i2c.c
//
// Description : body for I2C module
//
// Project : Samsom
//
// Author : s-albert@ti.com, Sylvie Albert
// Modified for Helen by: jp_ulpiano@ti.com, Jean-Philippe Ulpiano
//
//==================================================================================
#include "test.h"
#include "result.h"
#include "i2c.h"
#include "reset.h"
#include "mapping.h"
#include "errorcodes.h"
extern volatile UWORD32 I2C_IrqCount;
void I2C_TestResetValue(void)
{
TEST_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_SOFT_RESET);
SetGroupBits8(I2C_CMD_REG,
CMD_SOFT_RESET_POS,
CMD_SOFT_RESET_NUMB,
I2C_STOP_RESET);
TEST_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_ENCLK);
SetGroupBits8(I2C_CMD_REG,CMD_ENCLK_POS,CMD_ENCLK_NUMB,I2C_CK_ENABLE);
TEST_FIELD_RESET_VALUE8(&I2C_DEVICE_REG,DEVICE_DEVICE);
I2C_TEST_REGISTER_RESET_VALUE8(I2C_ADDRESS_REG);
I2C_TEST_REGISTER_RESET_VALUE8(I2C_DATA_WRITE_REG);
I2C_TEST_REGISTER_RESET_VALUE8(I2C_DATA_READ_REG);
TEST_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_START);
TEST_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_RW);
TEST_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_COMBREAD);
TEST_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_IRQMSK);
TEST_FIELD_RESET_VALUE8(&I2C_CONF_FIFO_REG,CFIFO_FIFOSIZE);
TEST_FIELD_RESET_VALUE8(&I2C_CONF_CLK_REG,CLK_PTV);
TEST_FIELD_RESET_VALUE8(&I2C_CONF_CLK_REG,CLK_SPKF);
TEST_FIELD_RESET_VALUE8(&I2C_CONF_CLK_REF_REG,CLKREF);
TEST_FIELD_RESET_VALUE8(&I2C_STATUS_FIFO_REG,FIFO_READCPT);
TEST_FIELD_RESET_VALUE8(&I2C_STATUS_FIFO_REG,FIFO_EMPTY);
TEST_FIELD_RESET_VALUE8(&I2C_STATUS_FIFO_REG,FIFO_FULL);
TEST_FIELD_RESET_VALUE8(&I2C_STATUS_ACTIVITY_REG,ACTIVITY_IT);
TEST_FIELD_RESET_VALUE8(&I2C_STATUS_ACTIVITY_REG,ACTIVITY_IDLE);
TEST_FIELD_RESET_VALUE8(&I2C_STATUS_ACTIVITY_REG,ACTIVITY_ERRDEV);
TEST_FIELD_RESET_VALUE8(&I2C_STATUS_ACTIVITY_REG,ACTIVITY_ERRDTA);
PRINT_CURRENT_ERROR_STATUS(I2C_TEST_RESET_VALUE_SUCCEEDED);
}
void I2C_TestRegistersAccess(void)
{
MODIFY_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_SOFT_RESET);
SetGroupBits8(I2C_CMD_REG,
CMD_SOFT_RESET_POS,
CMD_SOFT_RESET_NUMB,
I2C_STOP_RESET);
MODIFY_FIELD_RESET_VALUE8(&I2C_DEVICE_REG,DEVICE_DEVICE);
I2C_MODIFY_REGISTER_RESET_VALUE8(I2C_ADDRESS_REG);
I2C_MODIFY_REGISTER_RESET_VALUE8(I2C_DATA_WRITE_REG);
MODIFY_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_ENCLK);
SetGroupBits8(I2C_CMD_REG,CMD_ENCLK_POS,CMD_ENCLK_NUMB,I2C_CK_ENABLE);
MODIFY_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_START);
MODIFY_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_RW);
I2C_CMD_REG&=0xEF;
if(I2C_CMD_REG&0x10!=0)
{
RES_Set(CMD_COMBREAD_BAD_RESET_VALUE);
RES_Set(DATA_STORE);
RES_Set(0x0001);
}
I2C_CMD_REG|=0x10;
MODIFY_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_COMBREAD);
MODIFY_FIELD_RESET_VALUE8(&I2C_CMD_REG,CMD_IRQMSK);
MODIFY_FIELD_RESET_VALUE8(&I2C_CONF_FIFO_REG,CFIFO_FIFOSIZE);
MODIFY_FIELD_RESET_VALUE8(&I2C_CONF_CLK_REG,CLK_PTV);
MODIFY_FIELD_RESET_VALUE8(&I2C_CONF_CLK_REG,CLK_SPKF);
MODIFY_FIELD_RESET_VALUE8(&I2C_CONF_CLK_REF_REG,CLKREF);
PRINT_CURRENT_ERROR_STATUS(I2C_TEST_REGISTER_ACCESS_SUCCEEDED);
}
/********************************************************************************
NAME : I2C_Config
SYNOPSIS : UWORD32 I2C_Config (UWORD32 rate, UWORD32 spike, UWORD32 FIFOSIZE, UWORD32 IRQ)
DESCRIPTION : Config the I2C bus
PARAMETERS : - rate represent the i2c bus mode
rate = 100 kbits/s for the standard mode
rate = 400 kbits/s for the fast mode
- spike is still equal to 3, it's the spike filter factor
- FIFOSIZE is the size of the FIFO, in this case it's 1, 7 or 15.
- IRQ determine if the interrupts are enable (IRQ=1) or not (IRQ=0)
RETURN VALUE : the return value is RES_OK if no problem occured.
LIMITATIONS : rate must be 100 or 400, spike must be 3, FIFOSIZE must be
1 7 or 15, IRQ must be 0 or 1.
*********************************************************************************/
UWORD32 I2C_Config (UWORD32 Rate, UWORD32 Spike, UWORD32 FifoSize, UWORD32 Irq)
{
UWORD8 fifovalue;
I2C_CLOCK_DISABLE;
/*
// divisor_2 = 10 for the two modes
(I2C_CONF_CLK_REF_REG)= 0x08a;
if (Rate == 100)
{
// divisor_1 = 4
(I2C_CONF_CLK_REG) = 0xd2; ----> 12MHZ / (44 *3 ) = 363.64kHz
}
else if (Rate == 400)
{
// divisor_1 = 1
(I2C_CONF_CLK_REG )= 0xd0; -----> 12 MHz/ (11 *3 ) = 90.91kHz
}
else return RES_BAD;
*/
// divisor_1 = 2
(I2C_CONF_CLK_REG) = 0xd1;
if (Rate == 100)
{
// divisor_2 = 19
(I2C_CONF_CLK_REF_REG)= 0x93; //----> 12MHz / (2*20*3) = 100kHz
}
else if (Rate == 400)
{
// divisor_2 = 4
(I2C_CONF_CLK_REF_REG)= 0x84; //---->12MHz / (2*5*3)= 400kHz
}
else return RES_BAD;
I2C_CLOCK_ENABLE;
if (Spike != 3) return RES_BAD;
if (FifoSize==0) return RES_BAD;
else
{
// if fifosize == 1 value == f0
// if fifosize == 15 value == fe
fifovalue= 0xf0 + (FifoSize-1);
(I2C_CONF_FIFO_REG) = fifovalue;
I2CFIFO_SIZE;
}
if (Irq == 1) I2CIRQ_MASK_EN;
else if (Irq == 0) I2CIRQ_MASK_DIS;
else return RES_BAD;
return RES_OK;
}
/*******************************************************************************
NAME : I2C_Config_read_mode
SYNOPSIS : void I2C_Config_read_mode(UWORD32 sonr)
DESCRIPTION : define simple read (sonr = 1) or combined read (sonr = 0)
PARAMETERS : sonr
RETURN VALUE : none
LIMITATIONS : sonr must be 0 or 1
********************************************************************************/
void I2C_Config_read_mode(UWORD32 Sonr)
{
I2CREAD;
if (Sonr == 1)
I2CSIMPLE_READ;
else if (Sonr == 0)
I2CCOMBINED_READ;
}
/*******************************************************************************
NAME : I2C_IsErrorDevice
SYNOPSIS : UWORD32 I2C_IsErrorDevice(void)
DESCRIPTION : Test if an error device occured
PARAMETERS : none
RETURN VALUE : 1 for error device and 0 otherwise
LIMITATIONS : none
********************************************************************************/
UWORD32 I2C_IsErrorDevice(void)
{
volatile UWORD8 registre;
UWORD8 ok,i1,i2,i3;
registre= I2C_STATUS_ACTIVITY_REG;
i1=I2C_ERROR_DEVICE;
i2=registre & i1;
if (i2!= 2)
ok=I2C_NOT;
else
{
RES_Set(I2C_IS_ERROR_DEVICE_FUNC);
ok=I2C_IS;
}
return ok;
}
/*******************************************************************************
NAME : I2C_IsErrorData
SYNOPSIS : UWORD32 I2C_IsErrorData(void)
DESCRIPTION : Test if error on sub-address or data are detected
PARAMETERS : none
RETURN VALUE : 1 for error on sub-address or data and 0 otherwise
LIMITATIONS : none
********************************************************************************/
UWORD32 I2C_IsErrorData(void)
{
volatile UWORD8 registre;
UWORD8 ok,i1,i2;
registre= I2C_STATUS_ACTIVITY_REG;
i1=I2C_ERROR_DATA;
i2=registre &i1;
if (i2==0)
ok=I2C_NOT;
else
{
RES_Set (I2C_IS_ERROR_DATA_FUNC);
ok= I2C_IS;
}
return ok;
}
/*******************************************************************************
NAME : I2C_WriteFifo
SYNOPSIS : UWORD32 I2C_WriteFifo(UWORD8 data, UWORD32 number_of_data)
DESCRIPTION : Write in FIFO
PARAMETERS : data is the first data to write, number_of_data represent the
number of data to write
RETURN VALUE : the return value is RES_OK if no problem occured.
LIMITATIONS : input parameters must be valid
********************************************************************************/
UWORD32 I2C_WriteFifo(UWORD8 data, UWORD32 number_of_data, UWORD32 test_five_parameter)
{
UWORD32 i;
for (i=0;i<number_of_data;i++)
{
if (I2CFIFO_FULL == 0)
{
I2CDATA_TO_WRITE(data++);
if ( (test_five_parameter == 1) && (number_of_data == 3) ) I2CSOFT_RESET;
}
else
{
RES_Set(I2C_WR_FIFO_EXPECTED_NOT_TO_BE_FULL);
return RES_BAD;
}
}
return RES_OK;
}
/*******************************************************************************
NAME : I2C_IsIdle
SYNOPSIS : UWORD32 I2C_IsIdle(void)
DESCRIPTION : test the IDLE bit
PARAMETERS : none
RETURN VALUE : the return value is RES_OK if no problem occured.
LIMITATIONS : none
********************************************************************************/
UWORD32 I2C_IsIdle(void)
{
UWORD8 value;
volatile UWORD8 reg;
UWORD32 ok=0;
reg =I2C_STATUS_ACTIVITY_REG;
value= reg & I2C_IDDLE;
if (value == 4 ) ok = I2C_IS;
else ok = I2C_NOT;
return ok;
}
/*******************************************************************************
NAME : I2C_WaitCompletedTransfer
SYNOPSIS : void I2C_WaitCompletedTransfer (void)
DESCRIPTION : Determine if the transfer is completed or not
PARAMETERS : none
RETURN VALUE : none
LIMITATIONS : none
********************************************************************************/
BOOL I2C_WaitCompletedTransfer (void)
{
UWORD16 i;
RES_Set(RESULT_SEPARATOR);
for (i=0;i<MAX_SOFT_WD_VALUE;i++)
{
if (I2C_IsIdle() != I2C_IS) return TRUE;
}
return FALSE;
}
/*************************************************************************************************
NAME : I2C_Write
SYNOPSIS : UWORD32 I2C_Write (UWORD8 device, UWORD8 address, UWORD8 data, UWORD32 number_of_data,UWORD32 waitornot, UWORD32
polorUWORD32)
DESCRIPTION : Execute a write access on the I2C bus.
PARAMETERS : - device is the address of the select device
- address is the suRES_BADdress
- data is the data to write
- waitornot wait bus free after transfer when equal to 0.
- polorint = 1 for polling, = 0 otherwise
- test_five_parameter is 1 for test number 5 and 0 otherwise
RETURN VALUE : the return value is RES_OK if no problem occured.
LIMITATIONS : device, address and data must be valid. waitornot must be 0 or 1.
**************************************************************************************************/
UWORD32 I2C_Write ( UWORD8 device, UWORD8 address, UWORD8 data,
UWORD32 number_of_data,UWORD32 waitornot,
UWORD32 polorint,UWORD32 test_five_parameter)
{
UWORD32 errdev, errdat, fifo;
UWORD16 i;
I2C_IrqCount = 0;
I2CWRITE;
I2CDEVICE(device);
I2CADDRESS(address);
fifo = I2C_WriteFifo(data,number_of_data,test_five_parameter);
if (fifo == RES_BAD)
return RES_BAD;
I2CSTART;
if (waitornot == 0)
{
if (polorint == 1)
if (!I2C_WaitCompletedTransfer()) return RES_BAD;
else if (polorint == 0)
for (i=0;i<MAX_SOFT_WD_VALUE;i++)
{
if (I2C_IrqCount == 1) break;
if (i==MAX_SOFT_WD_VALUE) return RES_BAD;
}
errdev = I2C_IsErrorDevice();
errdat = I2C_IsErrorData();
//#ifdef RTL
if (errdev == I2C_IS)
return RES_BAD;
if (errdat == I2C_IS)
return RES_BAD;
//#endif
}
return RES_OK;
}
/*******************************************************************************
NAME : I2C_Read
SYNOPSIS : UWORD32 I2C_Read (UWORD8 device, UWORD8 address, UWORD32 simpleornot,UWORD32 polorint)
DESCRIPTION : Read Cycle
PARAMETERS : - device is the address of the select device
- address is the suRES_BADdress
- simpleornot = 1 for simple read, = 0 for combined read
- polorint = 1 for polling, = 0 otherwise
RETURN VALUE : the return value is RES_OK if no problem occured.
LIMITATIONS : device and address must be valid. simpleornot must be 0 or 1.
********************************************************************************/
UWORD32 I2C_Read (UWORD8 device, UWORD8 address,UWORD8 data, UWORD32 simpleornot,UWORD32 polorint)
{
UWORD32 errdev;
UWORD16 i;
I2C_IrqCount = 0;
I2CDEVICE(device);
if (simpleornot == 1)
I2C_Config_read_mode(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -