⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbotgi2c.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
字号:
/******************************************************************************
**
**  COPYRIGHT (C) 2000 - 2003 Intel Corporation.
**
**  This software as well as the software described in it is furnished under 
**  license and may only be used or copied in accordance with the terms of the 
**  license. The information in this file is furnished for informational use 
**  only, is subject to change without notice, and should not be construed as 
**  a commitment by Intel Corporation. Intel Corporation assumes no 
**  responsibility or liability for any errors or inaccuracies that may appear 
**  in this document or any software that may be provided in association with 
**  this document. 
**  Except as permitted by such license, no part of this document may be 
**  reproduced, stored in a retrieval system, or transmitted in any form or by 
**  any means without the express written consent of Intel Corporation. 
**
**  FILENAME:       UsbOTGi2c.c
**
**  PURPOSE:   		This file contains the APIs used to communicate with 
**                  Phillips ISP1301 USB OTG Transeiver via I2C interface. 
**
**  LAST MODIFIED: $Modtime: 9/17/03 9:50a $
**
******************************************************************************/

/*
*******************************************************************************
*   HEADER FILES
*******************************************************************************
*/                                                                      

#include <string.h>
#include "systypes.h"
#include "DM_Debug.h"
#include "xllp_defs.h"
#include "DRV_i2c.h"
#include "UsbOTGi2c.h"
#include "xsuart.h"
#include "xsffuart.h"
#include "XsGpioApi.h"
#include "xllp_ost.h"

extern USB_OTG_TRV_ADDRESS;

static volatile P_XLLP_OST_T TimerRegBaseP = (P_XLLP_OST_T)OST_REGISTER_BASE;

static
XLLP_UINT32_T getTimebase (void)
{
    return 13000000;
}

static
XLLP_UINT32_T getDelta (P_XLLP_OST_T regsP, unsigned start)
{
    volatile P_XLLP_OST_T OstControlRegsP = regsP;

    unsigned stop = OstControlRegsP->oscr0;
    if (stop < start)
        return stop + (start^0xffffffff) + 1;
    return stop - start;
}

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

  Function Name: 
    UsbOTGi2cConfigGpio

  Description: 
    This function configures GPIOs connected to the control signals of the Phillips ISP1301 
    USB OTG Transeiver.

  Global Register Modified: 
    None 

  Input Arguments:
    XLLP_UINT32_T debugMode - if one, configures GPIOs to support debug mode.
                              
  Output Arguments:
    None.

  Return Value:
    None.

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

void UsbOTGi2cConfigGpio (XLLP_UINT32_T debugMode)
{
    if (debugMode)
    {
        // Set OE_TP_INT_N - FFRXD (GPIO34): OUT, low
        XsGpioSetAlternateFunction(XS_GPIO_ID_34, XS_GPIO_ALT_FUNC_GPIO);
        XsGpioSetDirection(XS_GPIO_ID_34, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_0);

        // Set SPEED - FFTXD (GPIO39): OUT, low
        XsGpioSetAlternateFunction(XS_GPIO_ID_39, XS_GPIO_ALT_FUNC_GPIO);
        XsGpioSetDirection(XS_GPIO_ID_39, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_0);

        // Set SUSPEND - FFDSR (GPIO37): OUT, low
        XsGpioSetAlternateFunction(XS_GPIO_ID_37, XS_GPIO_ALT_FUNC_GPIO);
        XsGpioSetDirection(XS_GPIO_ID_37, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_0);

        // Set nINT - FFCTS (GPIO35): IN
        // Set SE0_VM - FFDCD (GPIO36): IN
        // Set DAT_VP - FFDTR (GPIO40): IN
    }
    else
    {
        // Set FFRXD (GPIO34): IN, Alt. Function 1, low
        XsGpioSetAlternateFunction(XS_GPIO_ID_34, XS_GPIO_ALT_FUNC_GPIO);
        XsGpioSetDirection(XS_GPIO_ID_34, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_0);
        XsGpioSetAlternateFunction(XS_GPIO_ID_34, XS_GPIO_ALT_FUNC_1);

        // Set FFTXD (GPIO39): OUT, Alt. Function 2, high
        XsGpioSetAlternateFunction(XS_GPIO_ID_39, XS_GPIO_ALT_FUNC_GPIO);
        XsGpioSetDirection(XS_GPIO_ID_39, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_1);
        XsGpioSetAlternateFunction(XS_GPIO_ID_39, XS_GPIO_ALT_FUNC_2);

        // Set FFDSR (GPIO37): IN, Alt. Function 1, low
        XsGpioSetAlternateFunction(XS_GPIO_ID_37, XS_GPIO_ALT_FUNC_GPIO);
        XsGpioSetDirection(XS_GPIO_ID_37, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_0);
        XsGpioSetAlternateFunction(XS_GPIO_ID_37, XS_GPIO_ALT_FUNC_1);
    }
}

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

  Function Name: 
    UsbOTGi2cTxEmpty

  Description: 
    This function returns status of the TX Empty interupt of the I2C controller. 

  Global Register Modified: 
    None 

  Input Arguments:
    P_POST_I2C_T regsP - a pointer to I2C controller's register base address                          
                              
  Output Arguments:
    None.

  Return Value:
    XLLP_BOOL_T - zero if TxEmpty bit was set

*******************************************************************************/
static
XLLP_BOOL_T UsbOTGi2cTxEmpty (P_POST_I2C_T regsP)
{
    XLLP_UINT32_T start, timebase = getTimebase();
    XLLP_UINT32_T timeout = XLLP_OTG_TIMEOUT * timebase;
    XLLP_BOOL_T intStatus = XLLP_TRUE;

    // Prepare for timeout by getting the initial time interval.
    start = TimerRegBaseP->oscr0;
    while (intStatus)
    {    
        intStatus = PostI2cTxEmpty(regsP);
        if (getDelta(TimerRegBaseP, start) > timeout)
        {
            // TxEmpty bit was not set
            return (intStatus);
        }
    }

    // Write ISR.ITE=1 bit to clear interrupt.
    regsP->ISR &= POST_ISR_ITE;
    
    // TxEmpty bit was set
    return (intStatus);
}

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

  Function Name: 
    UsbOTGi2cRxFull

  Description: 
    This function returns status of the RxFull interupt of the I2C controller. 

  Global Register Modified: 
    None 

  Input Arguments:
    P_POST_I2C_T regsP - a pointer to I2C controller's register base address                          
                              
  Output Arguments:
    None.

  Return Value:
    XLLP_BOOL_T - zero if RxFull bit was set

*******************************************************************************/
static
XLLP_BOOL_T UsbOTGi2cRxFull (P_POST_I2C_T regsP)
{
    XLLP_UINT32_T start, timebase = getTimebase();
    XLLP_UINT32_T timeout = XLLP_OTG_TIMEOUT * timebase;
    XLLP_BOOL_T intStatus = XLLP_TRUE;

    // Prepare for timeout by getting the initial time interval.
    start = TimerRegBaseP->oscr0;
    while (intStatus)
    {    
        intStatus = PostI2cRxFull(regsP);
        if (getDelta(TimerRegBaseP, start) > timeout)
        {
            // RxFull bit was not set
            return (intStatus);
        }
    }
    
    // Write ISR.IRF=1 bit to clear interrupt.
    regsP->ISR &= POST_ISR_IRF;

    // RxFull bit was set
    return (intStatus);
}

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

  Function Name: 
    UsbOTGi2cSetRegisterAddress

  Description: 
    This function writes the starting address of the registers of the Phillips ISP1301 
    USB OTG Transeiver via I2C interface.

  Global Register Modified: 
    None 

  Input Arguments:
    XLLP_UINT32_T regAddr   - USB OTG Transeiver registers starting address.
                              This is the starting address of the registers 
                              where the data are going to be read.
  Output Arguments:
    None.

  Return Value:
    XLLP_STATUS_T - error code if failed, zero if success

*******************************************************************************/
static
XLLP_STATUS_T UsbOTGi2cSetRegisterAddress (XLLP_UINT32_T regAddr)
{
    XLLP_STATUS_T error = 0;
	XLLP_UINT32_T status;
	volatile P_POST_I2C_T I2CRegsBaseP = (P_POST_I2C_T)STAND_I2C_BASE;

    // Write the starting address of the registers
    // Load target slave address and R/nW bit in IDBR. R/nW=0 for a write.
    I2CRegsBaseP->IDBR =  USB_OTG_TRV_ADDRESS & (~POST_IDBR_MODE);

    // Initiate write. Set ICR.START, clear ICR.STOP, set ICR.TB.
    I2CRegsBaseP->ICR &= ~POST_ICR_STOP; 
    I2CRegsBaseP->ICR |= (POST_ICR_START | POST_ICR_TB);

    // Wait for for transmit empty interrupt 
    status = UsbOTGi2cTxEmpty (I2CRegsBaseP);
    if (status == XLLP_TRUE)
    {
        // Report a timout on TxEmpty
        return (XLLP_TRUE);
    }

    // Write register address of the USB OTG Transeiver
    I2CRegsBaseP->IDBR = regAddr;

    // Initiate write. Clear ICR.START, clear ICR.STOP, set ICR.TB.
    I2CRegsBaseP->ICR &= ~POST_ICR_START; 
    I2CRegsBaseP->ICR |= POST_ICR_TB;

    // Wait for for transmit empty interrupt 
    status = UsbOTGi2cTxEmpty (I2CRegsBaseP);
    if (status == XLLP_TRUE)
    {
        // Report a timout on TxEmpty
        return (XLLP_TRUE);
    }

    return error;
}

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

  Function Name: 
    UsbOTGi2cWrite

  Description: 
    This function writes number of bytes to the Phillips ISP1301 USB OTG Transeiver registers 
    via I2C interface, starting with register address, passed as a parameter.

  Global Register Modified: 
    None 

  Input Arguments:
    XLLP_UINT32_T numBytes  - number of bytes to write. 
    P_XLLP_UINT8_T dataP    - a pointer to the array where the data are going to be taken from.

  Output Arguments:
    None
          
  Return Value:
    XLLP_STATUS_T - error code if failed, zero if success

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

XLLP_STATUS_T UsbOTGi2cWrite (XLLP_UINT32_T regAddr, XLLP_UINT32_T numBytes, P_XLLP_UINT8_T dataP) 
{
    XLLP_STATUS_T error = 0;
    XLLP_UINT32_T i;
	XLLP_UINT32_T status;
	volatile P_POST_I2C_T I2CRegsBaseP = (P_POST_I2C_T)STAND_I2C_BASE;

    // Write the starting address of the registers
    UsbOTGi2cSetRegisterAddress(regAddr);
    
    // Write number of bytes from the registers beginning with the starting address
    for (i = 0; i < numBytes-1; ++i)
    {
        // Write byte
        I2CRegsBaseP->IDBR = *(dataP + i);

        // Initiate write. Clear ICR.START, clear ICR.STOP, set ICR.TB.
        I2CRegsBaseP->ICR &= ~POST_ICR_STOP; 
        I2CRegsBaseP->ICR |= POST_ICR_TB;

        // Wait for for transmit empty interrupt 
        status = UsbOTGi2cTxEmpty (I2CRegsBaseP);
        if (status == XLLP_TRUE)
        {
            // Report a timout on TxEmpty
            return (XLLP_TRUE);
        }
    }

    // Write last byte
    I2CRegsBaseP->IDBR = *(dataP + i);

    // Initiate write. Clear ICR.START, set ICR.STOP, set ICR.TB.
    I2CRegsBaseP->ICR &= ~POST_ICR_START; 
    I2CRegsBaseP->ICR |= (POST_ICR_STOP | POST_ICR_TB);

    // Wait for for transmit empty interrupt 
    status = UsbOTGi2cTxEmpty (I2CRegsBaseP);
    if (status == XLLP_TRUE)
    {
        // Report a timout on TxEmpty
        return (XLLP_TRUE);
    }

    return error;
}

/******************************************************************************
 
  Function Name: 
    UsbOTGi2cRead

  Description: 
    This function reads number of bytes from the Phillips ISP1301 USB OTG Transeiver registers 
    via I2C interface, starting with register address, passed as a parameter.

  Global Register Modified: 
    None 

  Input Arguments:
    XLLP_UINT32_T numBytes  - number of bytes to read. 

  Output Arguments:
    P_XLLP_UINT8_T dataP    - a pointer to the array where the data are going to be placed.

  Return Value:
    XLLP_STATUS_T - error code if failed, zero if success

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

XLLP_STATUS_T UsbOTGi2cRead (XLLP_UINT32_T regAddr, XLLP_UINT32_T numBytes, P_XLLP_UINT8_T dataP)
{
    XLLP_STATUS_T error = 0;
    XLLP_UINT32_T i;
	XLLP_UINT32_T status;
	volatile P_POST_I2C_T I2CRegsBaseP = (P_POST_I2C_T)STAND_I2C_BASE;

    // Write the starting address of the registers
    UsbOTGi2cSetRegisterAddress(regAddr);

    // Load target slave address and R/nW bit in IDBR. R/nW=1 for a read.
    I2CRegsBaseP->IDBR =  USB_OTG_TRV_ADDRESS | POST_IDBR_MODE;

    // Initiate write. Set ICR.START, clear ICR.STOP, set ICR.TB.
    I2CRegsBaseP->ICR &= ~POST_ICR_STOP; 
    I2CRegsBaseP->ICR |= (POST_ICR_START | POST_ICR_TB);

    // Wait for for transmit empty interrupt 
    status = UsbOTGi2cTxEmpty (I2CRegsBaseP);
    if (status == XLLP_TRUE)
    {
        // Report a timout on TxEmpty
        return (XLLP_TRUE);
    }

    // Wait for for transmit empty interrupt ISR.ITE=1, ISR.UB=1, ISR.RWM=1
/*
    while (((I2CRegsBaseP->ISR & POST_ISR_UB) != POST_ISR_UB) && 
            ((I2CRegsBaseP->ISR & POST_ISR_RWM) != POST_ISR_RWM));
    
    while ((I2CRegsBaseP->ISR & POST_ISR_ITE) != POST_ISR_ITE);

    // Write ISR.ITE=1 bit to clear interrupt.
    I2CRegsBaseP->ISR &= POST_ISR_ITE;
*/
    // Read number of bytes from the registers beginning with the starting address
    for (i = 0; i < numBytes-1; ++i)
    {
        // Initiate read. Clear ICR.START, clear ICR.STOP, set ICR.ALDIE,
        // clear ICR.ACKNAC, set ICR.TB.
        I2CRegsBaseP->ICR &= ~(POST_ICR_START | POST_ICR_STOP); 
        I2CRegsBaseP->ICR |= (POST_ICR_TB | POST_ICR_ALDIE);  
        
        // Wait for for receive-full interrupt 
        status = UsbOTGi2cRxFull (I2CRegsBaseP);
        if (status == XLLP_TRUE)
        {
            // Report a timout on RxFull
            return (XLLP_TRUE);
        }
        
        // Read data
        *(dataP + i) = I2CRegsBaseP->IDBR;

        // Clear ICR.STOP bit and ICR.ACKNAK
        I2CRegsBaseP->ICR &= ~(POST_ICR_STOP | POST_ICR_ACKNACK);
    }

    // Read a last byte
    // Terminate communication with STOP condition
    // Clear ICR.START, clear ICR.STOP, set ICR.ALDIE, clear ICR.ACKNAC, set ICR.TB.
    I2CRegsBaseP->ICR |= (POST_ICR_TB | POST_ICR_STOP | POST_ICR_ACKNACK);

    // Wait for for receive-full interrupt 
    status = UsbOTGi2cRxFull (I2CRegsBaseP);
    if (status == XLLP_TRUE)
    {
        // Report a timout on RxFull
        return (XLLP_TRUE);
    }
    
    // Read last byte of data
    *(dataP + i) = I2CRegsBaseP->IDBR;

    // Clear ICR.STOP and ICR.ACKNACK bits
    I2CRegsBaseP->ICR &= ~(POST_ICR_STOP | POST_ICR_ACKNACK);

    return error;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -