📄 i2c.c
字号:
// ***************************************************************************
//
// Filename: i2c.c
//
// Created: Louis Lai (7/20/2003)
//
// Modified: $Author: $ $Date: $
//
// ***************************************************************************
// ***************************************************************************
// pragmas
// ***************************************************************************
// ***************************************************************************
// includes
// ***************************************************************************
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "tht_memory_map_defines.h"
#include "common.h"
// ***************************************************************************
// macros
// ***************************************************************************
// Status
#define I2C_ICF 0x00000080 // I2C Data Transfer
#define I2C_IAAS 0x00000040 // I2C Address As a slave
#define I2C_IBB 0x00000020 // I2C Bus Busy Bit
#define I2C_IAL 0x00000010 // I2C Arbitration Lost
#define I2C_SRW 0x00000004 // I2C Slave read/write
#define I2C_RXAK 0x00000001 // I2C Receive Acknowledge
#define I2C_IIF 0x00000002 // I2C Interrupt
// Control
#define I2C_MS 0x00000020 // I2C Master Mode
#define I2C_SL 0x00000000 // I2C Slave Mode
#define I2C_TX 0x00000010
#define I2C_RX 0x00000000 // I2C Receive Mode
#define I2C_IC 0xFFFFFFFD // I2C Interrupt Clear
#define I2C_IEN 0x00000080; // I2C module enable
#define I2C_TXAK 0X00000008;
// ***************************************************************************
// definitions
// ***************************************************************************
// ***************************************************************************
// types
// ***************************************************************************
// ***************************************************************************
// structures
// ***************************************************************************
// ***************************************************************************
// data
// ***************************************************************************
// ***************************************************************************
// function implementations
// ***************************************************************************
// *******************************************************************
//
// Function: I2c_Init
// Initialize the I2C module
// Set SCL to HCLK/2/320
// Slave Address = 0001000
//
// Parameters: void
//
//
// Return: void
// *******************************************************************
void I2c_Init (void)
{
*(volatile U32*)CRM_PCCR0 |= 0x1000; // Enable the ipg_clk to I2C
*(volatile U32*)GPIOD_GIUS &= 0xFFFCFFFF;
*(volatile U32*)GPIOD_GPR &= 0xFFFCFFFF;
*(volatile U32*)I2C_IFDR = (0 << 5) |
(1 << 4) |
(0 << 3) |
(1 << 2) |
(1 << 1) |
(1 << 0); // SCL = HCLK/2/320
// = 103kHz @ 66MHz
*(volatile U32*)I2C_IADR = (0 << 7) |
(0 << 6) |
(0 << 5) |
(1 << 4) |
(0 << 3) |
(0 << 2) |
(0 << 1); // I2C ADDRESS = 0001000
*(volatile U32*)I2C_I2CR = 0X0;
*(volatile U32*)I2C_I2CR |= I2C_IEN; // ENABLE I2C MODULE
*(volatile U32*)I2C_I2CR |= I2C_TXAK; // send ack. after receive
// one byte of data
}
// *******************************************************************
//
// Function: i2c_sltx
// This function set the I2C module to slave
// transmit mode.
//
// Parameters: U8* data data to store
// U32 dlength number of byte to receive
// U32 s_address address of slave
//
// Return: void
// *******************************************************************
//U8 i2c_slrx (void)
//{
//
//}
// *******************************************************************
//
// Function: i2c_slrx
// This function set the I2C module to slave
// receive mode.
//
// Parameters: U8* data data to store
// U32 dlength number of byte to receive
// U32 s_address address of slave
//
// Return: void
// *******************************************************************
//void i2c_sltx (U8)
//{
// BOOL selected = FALSE;
//
// if (*(volatile U32*)I2C_I2SR & I2C_IIF)
// {
// *(volatile U32*)I2C_I2SR = (0 << 1);
// }
//
// ***********************************************************
// Address Cycle
// send out slave address and wait for acknowledgement
// After receive acknowledgement from slave, switch to receive
// mode.
// ***********************************************************
// I2CR = (0 << 5); // Slave
//
// while (selected)
// {
// if (*(volatile U32*)I2C_ISDR & IAAS)
// {
// selected = TRUE;
// }
//
// }
//
// if (*(volatile U32*)I2C_ISDR & I2C_SRW)
// {
// *(volatile U32*)I2C_I2CR = (1 << 4); // transmit mode
// i2c_transmit(
// {
// else
// {
// *(volatile U32*)I2C_I2CR = (0 << 4); // receive mode
// }
//
//
//
//
//
//}
// *******************************************************************
//
// Function: i2c_msrx
// This function set the I2C module to master
// receive mode.
//
// Parameters: U8* data data to store
// U32 dlength number of byte to receive
// U32 s_address address of slave
//
// Return: void
// *******************************************************************
void i2c_msrx (U8* data, U32 dlength, U32 s_address)
{
BOOL add_sent = FALSE;
BOOL data_receive;
BOOL busfree = FALSE;
BOOL ack = FALSE;
U8 dummy;
U32 dWalk;
if (*(volatile U32*)I2C_I2SR & I2C_IIF) // Check any interrupt pending
{
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
while (busfree) // to ensure that the bus is free
{ // before sending out the start signal
if (*(volatile U32*)I2C_I2SR & I2C_IBB)
{
busfree = TRUE;
}
}
// ***********************************************************
// Address Cycle
// send out slave address and wait for acknowledgement
// After receive acknowlt tedgement from slave, switch to receive
// mode.
// ***********************************************************
*(volatile U32*)I2C_I2CR = (1 << 5) | // Master
(1 << 4); // Tramit
*(volatile U32*)I2C_I2DR = s_address;
while (ack)
{
while (add_sent)
{
if ((*(volatile U32*)I2C_I2SR & I2C_ICF) && (*(volatile U32*)I2C_I2SR & I2C_IIF))
{
add_sent = TRUE;
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
}
if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
{
ack = TRUE;
}
}
*(volatile U32*)I2C_I2CR = (1 << 5) | // Master
(0 << 4); // Receive
dummy = *(volatile U32*)I2C_I2DR; // dummy read;
// ***********************************************************
// Data Cycle
// receive data byte by byte
// ***********************************************************
for (dWalk = 1; dWalk <= dlength; dWalk++)
{
data_receive = FALSE;
while (data_receive)
{
if ((*(volatile U32*)I2C_I2SR & I2C_ICF) && (*(volatile U32*)I2C_I2SR & I2C_IIF))
{
data_receive = TRUE;
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
}
if (dWalk == dlength - 1) // second last byte
{ // do not acknowledge
*(volatile U32*)I2C_I2CR = (1 <<3);
}
*data = *(volatile U32*)I2C_I2DR;
data++;
}
*(volatile U32*)I2C_I2CR = (0 << 5); // reset to slave and
// generate STOP
}
/*
// *******************************************************************
//
// Function: i2c_mstx
// This function set the I2C module to master
// transmit mode.
//
// Parameters: U32* data data to send
// U32 dlength number of byte to send
// U32 s_address address of slave
//
// Return: void
// *******************************************************************
void i2c_mstx (U32* data, U32 dlength, U32 s_address)
{
U32 dWalk;
BOOL busfree = FALSE;
BOOL datasent = FALSE;
BOOL ack =FALSE;
if (*(volatile U32*)I2C_I2SR & I2C_IIF) // Check any interrupt pending
{
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
while (!busfree) // to ensure that the bus is free
{ // before sending out the start signal
if (!(*(volatile U32*)I2C_I2SR & I2C_IBB))
{
busfree = TRUE;
}
}
// ***********************************************************
// Address Cycle
// send out slave address and wait for acknowledgement
// ***********************************************************
*(volatile U32*)I2C_I2CR |= I2C_MS; // Master
*(volatile U32*)I2C_I2CR |= I2C_TX; // Transmit
*(volatile U32*)I2C_I2DR = s_address;
while (!ack)
{
while (!datasent)
{
if (*(volatile U32*)I2C_I2SR & I2C_IIF)
{
datasent = TRUE;
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
}
if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
{
ack = TRUE;
}
}
// ***********************************************************
// Data Cycle
// send data byte by byte
// ***********************************************************
for (dWalk = 1; dWalk <= dlength; dWalk++)
{
datasent = FALSE;
ack = FALSE;
*(volatile U32*)I2C_I2DR = *data;
while (!ack)
{
while (!datasent)
{
if (*(volatile U32*)I2C_I2SR & I2C_IIF)
{
datasent = TRUE;
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
}
if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
{
ack = TRUE;
}
}
data++;
}
*(volatile U32*)I2C_I2CR = (0 << 4); // Return to Slave mode and
// generate Stop signal
}
*/
// *******************************************************************
//
// Function: I2c_Mode
// This function config. the I2C module as Master/Slave
// and Transmit/Receive
//
// Parameters: BOOL master master/slave mode?
// BOOL transmit transmit/receive ??
//
// Return: void
// *******************************************************************
void I2c_Mode(BOOL master, BOOL transmit)
{
BOOL busfree = FALSE;
if (master)
{
if (*(volatile U32*)I2C_I2SR & I2C_IIF) // Check any interrupt pending
{
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
while (!busfree) // to ensure that the bus is free
{ // before sending out the start signal
if (!(*(volatile U32*)I2C_I2SR & I2C_IBB))
{
busfree = TRUE;
}
}
*(volatile U32*)I2C_I2CR |= I2C_MS; // Config. as Master
}
else
{
*(volatile U32*)I2C_I2CR &= !I2C_MS;
}
if (transmit)
{
*(volatile U32*)I2C_I2CR |= I2C_TX; // Config. as Transmit
}
else
{
*(volatile U32*)I2C_I2CR &= !I2C_TX; // Config. as Receive
}
}
// *******************************************************************
//
// Function: i2c_tx
// This function send a byte of data to SDA
//
// Parameters: U32 data data to send
//
// Return: void
// *******************************************************************
void I2c_Tx(U32 data)
{
BOOL ack = FALSE;
BOOL datasent = FALSE;
*(volatile U32*)I2C_I2DR = data;
while (!ack)
{
while (!datasent)
{
if (*(volatile U32*)I2C_I2SR & I2C_IIF)
{
datasent = TRUE;
*(volatile U32*)I2C_I2SR &= I2C_IC;
}
}
if (*(volatile U32*)I2C_I2SR & I2C_RXAK)
{
ack = TRUE;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -