//###########################################################################
// FILE: smbus.c
// TITLE: SMBus protocol layer API.
//###########################################################################
// $TI Release: F28M35x Support Library v201 $
// $Release Date: Fri Jun 7 10:51:13 CDT 2013 $
//###########################################################################
#include "inc/hw_i2c.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "inc/hw_udma.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#include "driverlib/i2c.h"
#include "driverlib/sysctl.h"
#include "driverlib/udma.h"
#include "utils/crc.h"
#include "utils/smbus.h"
//*****************************************************************************
//! \addtogroup smbus_api
//! @{
//*****************************************************************************
//*****************************************************************************
// The states for the master and slave interrupt handler state machines.
//*****************************************************************************
#define SMBUS_STATE_IDLE 0
#define SMBUS_STATE_SLAVE_POST_COMMAND 1
#define SMBUS_STATE_WRITE_BLOCK_SIZE 2
#define SMBUS_STATE_WRITE_NEXT 3
#define SMBUS_STATE_WRITE_FINAL 4
#define SMBUS_STATE_WRITE_DMA_FINAL 5
#define SMBUS_STATE_WRITE_DONE 6
#define SMBUS_STATE_READ_ONE 7
#define SMBUS_STATE_READ_FIRST 8
#define SMBUS_STATE_READ_BLOCK_SIZE 9
#define SMBUS_STATE_READ_NEXT 10
#define SMBUS_STATE_READ_FINAL 11
#define SMBUS_STATE_READ_DMA_FINAL 12
#define SMBUS_STATE_READ_WAIT 13
#define SMBUS_STATE_READ_PEC 14
#define SMBUS_STATE_READ_DONE 15
#define SMBUS_STATE_READ_ERROR_STOP 16
#define SMBUS_STATE_DMA_TX_SEND_SIZE 32
#define SMBUS_STATE_DMA_TX_SEND_DATA 33
#define SMBUS_STATE_DMA_TX_WAIT_DMA 34
#define SMBUS_STATE_DMA_TX_WAIT_DONE 35
#define SMBUS_STATE_DMA_TX_WAIT_CRC 36
#define SMBUS_STATE_DMA_RX_START_DMA 38
#define SMBUS_STATE_DMA_RX_START_2_DMA 39
#define SMBUS_STATE_DMA_RX_WAIT_DMA 40
#define SMBUS_STATE_DMA_RX_WAIT_DONE 41
#define SMBUS_STATE_DMA_RAW_TX_SEND_DATA 42
#define SMBUS_STATE_DMA_RAW_TX_SEND_2_DATA 43
#define SMBUS_STATE_DMA_RAW_RX_START 44
#define SMBUS_STATE_DMA_RAW_TXRX_TURN 46
#define SMBUS_STATE_DMA_TX_LAST_BYTE 47
#define SMBUS_STATE_DMA_RAW_RX_WAIT 48
//*****************************************************************************
// Status flags for various instance-specific tasks.
//*****************************************************************************
#define FLAG_PEC 0
#define FLAG_DMA 1
#define FLAG_PROCESS_CALL 2
#define FLAG_BLOCK_TRANSFER 3
#define FLAG_TRANSFER_IN_PROGRESS 4
#define FLAG_RAW_I2C 5
#define FLAG_ADDRESS_RESOLVED 6
#define FLAG_ADDRESS_VALID 7
#define FLAG_ARP 8
#define FLAG_USE_DMA_TX 9
#define FLAG_USE_DMA_RX 10
#define DMA_MIN_TRANSFER 5
typedef struct
{
unsigned long ulI2CBase;
unsigned long ulTxDMAChannel;
unsigned long ulRxDMAChannel;
} tDMAChannelTable;
// Mapping of I2C base address to DMA channel.
static const tDMAChannelTable psDMAChannelMap[] =
{
{ I2C0_MASTER_BASE, UDMA_CH7_I2C0TX, UDMA_CH6_I2C0RX },
{ I2C1_MASTER_BASE, UDMA_CH9_I2C1TX, UDMA_CH8_I2C1RX },
{ I2C2_MASTER_BASE, UDMA_CH11_I2C2TX, UDMA_CH10_I2C2RX },
{ I2C3_MASTER_BASE, UDMA_CH19_I2C3TX, UDMA_CH18_I2C3RX },
{ I2C4_MASTER_BASE, UDMA_CH21_I2C4TX, UDMA_CH20_I2C4RX },
{ I2C5_MASTER_BASE, UDMA_CH23_I2C5TX, UDMA_CH22_I2C5RX },
};
// Generate constant size of the DMA channel map table.
static const int iDMAChannelMapEntries = sizeof(psDMAChannelMap)/
sizeof(tDMAChannelTable);
static unsigned long ulRun = I2C_MCS_RUN;
static unsigned long ulStop = I2C_MCS_STOP;
static unsigned long ulDMADisable = 0;
//*****************************************************************************
//! Enables DMA for SMBus and I2C transfers.
//!
//! \param pSMBus specifies the SMBus configuration structure.
//!
//! This function enables DMA use when using the SMBus API.
//!
//! This function also enables the DMA error interrupt. If an error handler
//! is not implemented and a DMA error occurs then the error will not be
//! handled.
//!
//! The only functions that support DMA are SMBusMasterI2CWrite() and
//! SMBusMasterI2CRead(). All other functions use interrupt-driven transfers,
//! even if DMA is enabled at the stack level (i.e. calling this function).
//!
//! \return None.
//*****************************************************************************
void
SMBusDMAEnable(tSMBus *pSMBus)
{
// Set the DMA flag in the configuration structure.
HWREGBITB(&pSMBus->usFlags, FLAG_DMA) = 1;
// Enable the uDMA controller error interrupt. This interrupt will occur
// if there is a bus error during a transfer.
IntEnable(INT_UDMAERR);
}
//*****************************************************************************
//! \internal
//! Disable DMA for I2C transfers.
//!
//! \param pSMBus specifies the SMBus configuration structure.
//!
//! This function disables DMA use when using the SMBus API.
//!
//! \return None.
//*****************************************************************************
void
SMBusDMADisable(tSMBus *pSMBus)
{
// Clear the DMA flag in the configuration structure.
HWREGBITB(&pSMBus->usFlags, FLAG_DMA) = 0;
// Clear the DMA bits in the I2C.
I2CDMAConfigSet(pSMBus->ulI2CBase, 0);
// Enable the uDMA controller error interrupt. This interrupt will occur
// if there is a bus error during a transfer.
IntDisable(INT_UDMAERR);
}
//*****************************************************************************
//! Enables Packet Error Checking (PEC).
//!
//! \param pSMBus specifies the SMBus configuration structure.
//!
//! This function enables the transmission and checking of a PEC byte in SMBus
//! transactions.
//!
//! \return None.
//*****************************************************************************
void
SMBusPECEnable(tSMBus *pSMBus)
{
// Set the PEC flag in the configuration structure.
HWREGBITB(&pSMBus->usFlags, FLAG_PEC) = 1;
}
//*****************************************************************************
//! Disables Packet Error Checking (PEC).
//!
//! \param pSMBus specifies the SMBus configuration structure.
//!
//! This function disables the transmission and checking of a PEC byte in SMBus
//! transactions.
//!
//! \return None.
//*****************************************************************************
void
SMBusPECDisable(tSMBus *pSMBus)
{
// Clear the PEC flag in the configuration structure.
HWREGBITB(&pSMBus->usFlags, FLAG_PEC) = 0;
}
//*****************************************************************************
//! Sets the ARP flag in the configuration structure.
//!
//! \param pSMBus specifies the SMBus configuration structure.
//!
//! This function sets the Address Resolution Protocol (ARP) flag in the
//! configuration structure. This flag can be used to track the state of a
//! device during the ARP process.
//!
//! \return None.
//*****************************************************************************
void
SMBusARPEnable(tSMBus *pSMBus)
{
// Set the ARP flag in the configuration structure.
HWREGBITB(&pSMBus->usFlags, FLAG_ARP) = 1;
}
//*****************************************************************************
//! Clears the ARP flag in the configuration structure.
//!
//! \param pSMBus specifies the SMBus configuration structure.
//!
//! This function clears the Address Resolution Protocol (ARP) flag in the
//! configuration structure.
- 1
- 2
- 3
前往页