Xiic_i.h

 /******************************************************************************

* Copyright (C) 2002 - 2021 Xilinx, Inc.  All rights reserved.

* SPDX-License-Identifier: MIT

******************************************************************************/


/****************************************************************************/

/**

*

* @file xiic_l.h

* @addtogroup Overview

* @{

*

* This header file contains identifiers and driver functions (or

* macros) that can be used to access the device in normal and dynamic

* controller mode.  High-level driver functions are defined in xiic.h.

*

* <pre>

* MODIFICATION HISTORY:

*

* Ver   Who  Date     Changes

* ----- ---- -------- -----------------------------------------------

* 1.00b jhl  05/07/02 First release

* 1.01c ecm  12/05/02 new rev

* 1.01d jhl  10/08/03 Added general purpose output feature

* 1.02a mta  03/09/06 Implemented Repeated Start in the Low Level Driver.

* 1.03a mta  04/04/06 Implemented Dynamic IIC core routines.

* 1.03a rpm  09/08/06 Added include of xstatus.h for completeness

* 1.13a wgr  03/22/07 Converted to new coding style.

* 1.16a ktn  07/18/09 Updated the notes in XIIC_RESET macro to clearly indicate

*                     that only the Interrupt Registers are reset.

* 1.16a ktn  10/16/09 Updated the notes in the XIIC_RESET macro to mention

*                     that the complete IIC core is Reset on giving a software

*                     reset to the IIC core. Some previous versions of the

*                     core only reset the Interrupt Logic/Registers, please

*                     refer to the HW specification for further details.

* 2.00a sdm  10/22/09 Converted all register accesses to 32 bit access,

*       the register offsets are defined to be on 32 bit boundary.

*       Removed the macro XIIC_RESET, XIic_Reset API should be

*       used in its place.

*       Some of the macros have been renamed to be consistent -

*       XIIC_GINTR_DISABLE is renamed as XIic_IntrGlobalDisable,

*       XIIC_GINTR_ENABLE is renamed as XIic_IntrGlobalEnable,

*       XIIC_IS_GINTR_ENABLED is renamed as

*       XIic_IsIntrGlobalEnabled,

*       XIIC_WRITE_IISR is renamed as XIic_WriteIisr,

*       XIIC_READ_IISR is renamed as XIic_ReadIisr,

*       XIIC_WRITE_IIER is renamed as XIic_WriteIier

*       The _m prefix in the name of the macros has been removed -

*       XIic_mClearIisr is now XIic_ClearIisr,

*       XIic_mSend7BitAddress is now XIic_Send7BitAddress,

*       XIic_mDynSend7BitAddress is now XIic_DynSend7BitAddress,

*       XIic_mDynSendStartStopAddress is now

*       XIic_DynSendStartStopAddress,

*       XIic_mDynSendStop is now XIic_DynSendStop.

* 3.2   sk   11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.

*                     Changed the prototypes of XIic_Recv, XIic_Send,

*                     XIic_DynRecv, XIic_DynSend and XIic_DynInit APIs.

* 3.3   als  06/27/16 Added Low-level XIic_CheckIsBusBusy API.

* 3.3   als  06/27/16 Added low-level XIic_WaitBusFree API.

* </pre>

*

*****************************************************************************/

#ifndef XIIC_L_H /* prevent circular inclusions */

#define XIIC_L_H /* by using protection macros */


#ifdef __cplusplus

extern "C" {

#endif


/***************************** Include Files ********************************/


#include "xil_types.h"

#include "xil_assert.h"

#include "xstatus.h"

#include "xil_io.h"


/************************** Constant Definitions ****************************/


/** @name Register Map

 *

 * Register offsets for the XIic device.

 * @{

 */

#define XIIC_DGIER_OFFSET 0x1C  /**< Global Interrupt Enable Register */

#define XIIC_IISR_OFFSET 0x20  /**< Interrupt Status Register */

#define XIIC_IIER_OFFSET 0x28  /**< Interrupt Enable Register */

#define XIIC_RESETR_OFFSET 0x40  /**< Reset Register */

#define XIIC_CR_REG_OFFSET 0x100 /**< Control Register */

#define XIIC_SR_REG_OFFSET 0x104 /**< Status Register */

#define XIIC_DTR_REG_OFFSET 0x108 /**< Data Tx Register */

#define XIIC_DRR_REG_OFFSET 0x10C /**< Data Rx Register */

#define XIIC_ADR_REG_OFFSET 0x110 /**< Address Register */

#define XIIC_TFO_REG_OFFSET 0x114 /**< Tx FIFO Occupancy */

#define XIIC_RFO_REG_OFFSET 0x118 /**< Rx FIFO Occupancy */

#define XIIC_TBA_REG_OFFSET 0x11C /**< 10 Bit Address reg */

#define XIIC_RFD_REG_OFFSET 0x120 /**< Rx FIFO Depth reg */

#define XIIC_GPO_REG_OFFSET 0x124 /**< Output Register */

/* @} */



/**

 * @name Device Global Interrupt Enable Register masks (CR) mask(s)

 * @{

 */

#define XIIC_GINTR_ENABLE_MASK 0x80000000 /**< Global Interrupt Enable Mask */

/* @} */


/** @name IIC Device Interrupt Status/Enable (INTR) Register Masks

 *

 * <b> Interrupt Status Register (IISR) </b>

 *

 * This register holds the interrupt status flags for the Spi device.

 *

 * <b> Interrupt Enable Register (IIER) </b>

 *

 * This register is used to enable interrupt sources for the IIC device.

 * Writing a '1' to a bit in this register enables the corresponding Interrupt.

 * Writing a '0' to a bit in this register disables the corresponding Interrupt.

 *

 * IISR/IIER registers have the same bit definitions and are only defined once.

 * @{

 */

#define XIIC_INTR_ARB_LOST_MASK 0x00000001 /**< 1 = Arbitration lost */

#define XIIC_INTR_TX_ERROR_MASK 0x00000002 /**< 1 = Tx error/msg complete */

#define XIIC_INTR_TX_EMPTY_MASK 0x00000004 /**< 1 = Tx FIFO/reg empty */

#define XIIC_INTR_RX_FULL_MASK 0x00000008 /**< 1 = Rx FIFO/reg=OCY level */

#define XIIC_INTR_BNB_MASK 0x00000010 /**< 1 = Bus not busy */

#define XIIC_INTR_AAS_MASK 0x00000020 /**< 1 = When addr as slave */

#define XIIC_INTR_NAAS_MASK 0x00000040 /**< 1 = Not addr as slave */

#define XIIC_INTR_TX_HALF_MASK 0x00000080 /**< 1 = Tx FIFO half empty */


/**

 * All Tx interrupts commonly used.

 */

#define XIIC_TX_INTERRUPTS (XIIC_INTR_TX_ERROR_MASK | \

XIIC_INTR_TX_EMPTY_MASK |  \

XIIC_INTR_TX_HALF_MASK)


/**

 * All interrupts commonly used

 */

#define XIIC_TX_RX_INTERRUPTS (XIIC_INTR_RX_FULL_MASK | XIIC_TX_INTERRUPTS)


/* @} */


/**

 * @name Reset Register mask

 * @{

 */

#define XIIC_RESET_MASK 0x0000000A /**< RESET Mask  */

/* @} */



/**

 * @name Control Register masks (CR) mask(s)

 * @{

 */

#define XIIC_CR_ENABLE_DEVICE_MASK 0x00000001 /**< Device enable = 1 */

#define XIIC_CR_TX_FIFO_RESET_MASK 0x00000002 /**< Transmit FIFO reset=1 */

#define XIIC_CR_MSMS_MASK 0x00000004 /**< Master starts Txing=1 */

#define XIIC_CR_DIR_IS_TX_MASK 0x00000008 /**< Dir of Tx. Txing=1 */

#define XIIC_CR_NO_ACK_MASK 0x00000010 /**< Tx Ack. NO ack = 1 */

#define XIIC_CR_REPEATED_START_MASK 0x00000020 /**< Repeated start = 1 */

#define XIIC_CR_GENERAL_CALL_MASK 0x00000040 /**< Gen Call enabled = 1 */

/* @} */


/**

 * @name Status Register masks (SR) mask(s)

 * @{

 */

#define XIIC_SR_GEN_CALL_MASK 0x00000001 /**< 1 = A Master issued

    * a GC */

#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x00000002 /**< 1 = When addressed as

    * slave */

#define XIIC_SR_BUS_BUSY_MASK 0x00000004 /**< 1 = Bus is busy */

#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x00000008 /**< 1 = Dir: Master <--

    * slave */

#define XIIC_SR_TX_FIFO_FULL_MASK 0x00000010 /**< 1 = Tx FIFO full */

#define XIIC_SR_RX_FIFO_FULL_MASK 0x00000020 /**< 1 = Rx FIFO full */

#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x00000040 /**< 1 = Rx FIFO empty */

#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x00000080 /**< 1 = Tx FIFO empty */

/* @} */


/**

 * @name Data Tx Register (DTR) mask(s)

 * @{

 */

#define XIIC_TX_DYN_START_MASK 0x00000100 /**< 1 = Set dynamic start */

#define XIIC_TX_DYN_STOP_MASK 0x00000200 /**< 1 = Set dynamic stop */

#define IIC_TX_FIFO_DEPTH 16     /**< Tx fifo capacity */

/* @} */


/**

 * @name Data Rx Register (DRR) mask(s)

 * @{

 */

#define IIC_RX_FIFO_DEPTH 16 /**< Rx fifo capacity */

/* @} */



#define XIIC_TX_ADDR_SENT 0x00

#define XIIC_TX_ADDR_MSTR_RECV_MASK 0x02



/**

 * The following constants are used to specify whether to do

 * Read or a Write operation on IIC bus.

 */

#define XIIC_READ_OPERATION 1 /**< Read operation on the IIC bus */

#define XIIC_WRITE_OPERATION 0 /**< Write operation on the IIC bus */


/**

 * The following constants are used with the transmit FIFO fill function to

 * specify the role which the IIC device is acting as, a master or a slave.

 */

#define XIIC_MASTER_ROLE 1 /**< Master on the IIC bus */

#define XIIC_SLAVE_ROLE 0 /**< Slave on the IIC bus */


/**

 * The following constants are used with Transmit Function (XIic_Send) to

 * specify whether to STOP after the current transfer of data or own the bus

 * with a Repeated start.

 */

#define XIIC_STOP 0x00 /**< Send a stop on the IIC bus after

* the current data transfer */

#define XIIC_REPEATED_START 0x01 /**< Donot Send a stop on the IIC bus after

* the current data transfer */


/***************** Macros (Inline Functions) Definitions *********************/


#define XIic_In32 Xil_In32

#define XIic_Out32 Xil_Out32


/****************************************************************************/

/**

*

* Read from the specified IIC device register.

*

* @param BaseAddress is the base address of the device.

* @param RegOffset is the offset from the 1st register of the device to

* select the specific register.

*

* @return The value read from the register.

*

* @note C-Style signature:

* u32 XIic_ReadReg(u32 BaseAddress, u32 RegOffset);

*

* This macro does not do any checking to ensure that the

* register exists if the register may be excluded due to

* parameterization, such as the GPO Register.

*

******************************************************************************/

#define XIic_ReadReg(BaseAddress, RegOffset) \

XIic_In32((BaseAddress) + (RegOffset))


/***************************************************************************/

/**

*

* Write to the specified IIC device register.

*

* @param BaseAddress is the base address of the device.

* @param RegOffset is the offset from the 1st register of the

* device to select the specific register.

* @param RegisterValue is the value to be written to the register.

*

* @return None.

*

* @note C-Style signature:

* void XIic_WriteReg(u32 BaseAddress, u32 RegOffset,

* u32 RegisterValue);

* This macro does not do any checking to ensure that the

* register exists if the register may be excluded due to

* parameterization, such as the GPO Register.

*

******************************************************************************/

#define XIic_WriteReg(BaseAddress, RegOffset, RegisterValue) \

XIic_Out32((BaseAddress) + (RegOffset), (RegisterValue))


/******************************************************************************/

/**

*

* This macro disables all interrupts for the device by writing to the Global

* interrupt enable register.

*

* @param BaseAddress is the base address of the IIC device.

*

* @return None.

*

* @note C-Style signature:

* void XIic_IntrGlobalDisable(u32 BaseAddress);

*

******************************************************************************/

#define XIic_IntrGlobalDisable(BaseAddress) \

XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, 0)


/******************************************************************************/

/**

*

* This macro writes to the global interrupt enable register to enable

* interrupts from the device. This function does not enable individual

* interrupts as the Interrupt Enable Register must be set appropriately.

*

* @param BaseAddress is the base address of the IIC device.

*

* @return None.

*

* @note C-Style signature:

* void XIic_IntrGlobalEnable(u32 BaseAddress);

*

******************************************************************************/

#define XIic_IntrGlobalEnable(BaseAddress) \

XIic_WriteReg((BaseAddress), XIIC_DGIER_OFFSET, \

XIIC_GINTR_ENABLE_MASK)


/******************************************************************************/

/**

*

* This function determines if interrupts are enabled at the global level by

* reading the global interrupt register.

*

* @param BaseAddress is the base address of the IIC device.

*

* @return

* - TRUE if the global interrupt is enabled.

* - FALSE if global interrupt is disabled.

*

* @note C-Style signature:

* int XIic_IsIntrGlobalEnabled(u32 BaseAddress);

*

******************************************************************************/

#define XIic_IsIntrGlobalEnabled(BaseAddress) \

(XIic_ReadReg((BaseAddress), XIIC_DGIER_OFFSET) == \

XIIC_GINTR_ENABLE_MASK)


/******************************************************************************/

/**

*

* This function sets the Interrupt status register to the specified value.

*

* This register implements a toggle on write functionality. The interrupt is

* cleared by writing to this register with the bits to be cleared set to a one

* and all others to zero. Setting a bit which is zero within this register

* causes an interrupt to be generated.

*

* This function writes only the specified value to the register such that

* some status bits may be set and others cleared.  It is the caller's

* responsibility to get the value of the register prior to setting the value

* to prevent an destructive behavior.

*

* @param BaseAddress is the base address of the IIC device.

* @param Status is the value to be written to the Interrupt

* status register.

*

* @return None.

*

* @note C-Style signature:

* void XIic_WriteIisr(u32 BaseAddress, u32 Status);

*

******************************************************************************/

#define XIic_WriteIisr(BaseAddress, Status) \

XIic_WriteReg((BaseAddress), XIIC_IISR_OFFSET, (Status))


/******************************************************************************/

/**

*

* This function gets the contents of the Interrupt Status Register.

* This register indicates the status of interrupt sources for the device.

* The status is independent of whether interrupts are enabled such

* that the status register may also be polled when interrupts are not enabled.

*

* @param BaseAddress is the base address of the IIC device.

*

* @return The value read from the Interrupt Status Register.

*

* @note C-Style signature:

* u32 XIic_ReadIisr(u32 BaseAddress);

*

******************************************************************************/

#define XIic_ReadIisr(BaseAddress) \

XIic_ReadReg((BaseAddress), XIIC_IISR_OFFSET)


/******************************************************************************/

/**

*

* This function sets the contents of the Interrupt Enable Register.

*

* This function writes only the specified value to the register such that

* some interrupt sources may be enabled and others disabled.  It is the

* caller's responsibility to get the value of the interrupt enable register

* prior to setting the value to prevent a destructive behavior.

*

* @param BaseAddress is the base address of the IIC device.

* @param Enable is the value to be written to the Interrupt Enable

* Register. Bit positions of 1 will be enabled. Bit positions of 0

* will be disabled.

*

* @return None

*

* @note C-Style signature:

* void XIic_WriteIier(u32 BaseAddress, u32 Enable);

*

******************************************************************************/

#define XIic_WriteIier(BaseAddress, Enable) \

XIic_WriteReg((BaseAddress), XIIC_IIER_OFFSET, (Enable))


/******************************************************************************/

/**

*

*

* This function gets the Interrupt Enable Register contents.

*

* @param BaseAddress is the base address of the IIC device.

*

* @return The contents read from the Interrupt Enable Register.

* Bit positions of 1 indicate that the corresponding interrupt

* is enabled. Bit positions of 0 indicate that the corresponding

* interrupt is disabled.

*

* @note C-Style signature:

* u32 XIic_ReadIier(u32 BaseAddress)

*

******************************************************************************/

#define XIic_ReadIier(BaseAddress) \

XIic_ReadReg((BaseAddress), XIIC_IIER_OFFSET)


/******************************************************************************/

/**

*

* This macro clears the specified interrupt in the Interrupt status

* register.  It is non-destructive in that the register is read and only the

* interrupt specified is cleared.  Clearing an interrupt acknowledges it.

*

* @param BaseAddress is the base address of the IIC device.

* @param InterruptMask is the bit mask of the interrupts to be cleared.

*

* @return None.

*

* @note C-Style signature:

* void XIic_ClearIisr(u32 BaseAddress, u32 InterruptMask);

*

******************************************************************************/

#define XIic_ClearIisr(BaseAddress, InterruptMask) \

XIic_WriteIisr((BaseAddress), \

XIic_ReadIisr(BaseAddress) & (InterruptMask))


/******************************************************************************/

/**

*

* This macro sends the address for a 7 bit address during both read and write

* operations. It takes care of the details to format the address correctly.

* This macro is designed to be called internally to the drivers.

*

* @param BaseAddress is the base address of the IIC Device.

* @param SlaveAddress is the address of the slave to send to.

* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION

*

* @return None.

*

* @note C-Style signature:

* void XIic_Send7BitAddress(u32 BaseAddress, u8 SlaveAddress,

* u8 Operation);

*

******************************************************************************/

#define XIic_Send7BitAddress(BaseAddress, SlaveAddress, Operation) \

{ \

u8 LocalAddr = (u8)(SlaveAddress << 1); \

LocalAddr = (LocalAddr & 0xFE) | (Operation); \

XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, LocalAddr); \

}


/******************************************************************************/

/**

*

* This macro sends the address for a 7 bit address during both read and write

* operations. It takes care of the details to format the address correctly.

* This macro is designed to be called internally to the drivers for Dynamic

* controller functionality.

*

* @param BaseAddress is the base address of the IIC Device.

* @param SlaveAddress is the address of the slave to send to.

* @param Operation indicates XIIC_READ_OPERATION or XIIC_WRITE_OPERATION.

*

* @return None.

*

* @note C-Style signature:

* void XIic_DynSend7BitAddress(u32 BaseAddress,

* u8 SlaveAddress, u8 Operation);

*

******************************************************************************/

#define XIic_DynSend7BitAddress(BaseAddress, SlaveAddress, Operation) \

{ \

u8 LocalAddr = (u8)(SlaveAddress << 1); \

LocalAddr = (LocalAddr & 0xFE) | (Operation); \

XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \

XIIC_TX_DYN_START_MASK | LocalAddr); \

}


/******************************************************************************/

/**

*

* This macro sends the address, start and stop for a 7 bit address during both

* write operations. It takes care of the details to format the address

* correctly. This macro is designed to be called internally to the drivers.

*

* @param BaseAddress is the base address of the IIC Device.

* @param SlaveAddress is the address of the slave to send to.

* @param Operation indicates XIIC_WRITE_OPERATION.

*

* @return None.

*

* @note C-Style signature:

* void XIic_DynSendStartStopAddress(u32 BaseAddress,

* u8 SlaveAddress,

* u8 Operation);

*

******************************************************************************/

#define XIic_DynSendStartStopAddress(BaseAddress, SlaveAddress, Operation) \

{ \

u8 LocalAddr = (u8)(SlaveAddress << 1); \

LocalAddr = (LocalAddr & 0xFE) | (Operation); \

XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \

XIIC_TX_DYN_START_MASK | XIIC_TX_DYN_STOP_MASK | \

LocalAddr); \

}


/******************************************************************************/

/**

*

* This macro sends a stop condition on IIC bus for Dynamic logic.

*

* @param BaseAddress is the base address of the IIC Device.

* @param ByteCount is the number of Rx bytes received before the master.

* doesn't respond with ACK.

*

* @return None.

*

* @note C-Style signature:

* void XIic_DynSendStop(u32 BaseAddress, u32 ByteCount);

*

******************************************************************************/

#define XIic_DynSendStop(BaseAddress, ByteCount) \

{ \

XIic_WriteReg(BaseAddress, XIIC_DTR_REG_OFFSET, \

XIIC_TX_DYN_STOP_MASK | ByteCount); \

}


/************************** Function Prototypes *****************************/


unsigned XIic_Recv(UINTPTR BaseAddress, u8 Address,

   u8 *BufferPtr, unsigned ByteCount, u8 Option);


unsigned XIic_Send(UINTPTR BaseAddress, u8 Address,

   u8 *BufferPtr, unsigned ByteCount, u8 Option);


unsigned XIic_DynRecv(UINTPTR BaseAddress, u8 Address, u8 *BufferPtr, u8 ByteCount);


unsigned XIic_DynSend(UINTPTR BaseAddress, u16 Address, u8 *BufferPtr,

      u8 ByteCount, u8 Option);


int XIic_DynInit(UINTPTR BaseAddress);


u32 XIic_CheckIsBusBusy(UINTPTR BaseAddress);


u32 XIic_WaitBusFree(UINTPTR BaseAddress);


#ifdef __cplusplus

}

#endif


#endif /* end of protection macro */

/** @} */

Comments

Popular posts from this blog

Xiic.c

LMK03318

Pic16f188xx ADC with fvr