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

📄 isp1301.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
字号:
/*---------------------------------------------------------------------------
* Copyright (C) 2005, Freescale Semiconductor, Inc. All Rights Reserved.
* THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
* AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
*--------------------------------------------------------------------------*/


//
//  File:  hwinit.c
//
#pragma optimize( "", off )
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#include "bsp.h"
#include "i2cbus.h"

// ADR/PSW is set to high
#define CSI_I2C_ADDRESS         0x20
#define USBOTG_I2C_ADDR         0x2D

// I2C File Name
#define I2C_FID_USBOTG                 _T("I2C1:")     // CAM File Index


HANDLE hI2C;

//-----------------------------------------------------------------------------
//
// Function: I2CWriteOneByte
//
// This function writes a single byte byData to the register stated in byReg.
//
// Parameters:
//      hI2C 
//          [in] File handle to I2C Bus Interface.
//
//      byAddr
//          [in] I2C Slave device address.
//
//      byReg
//          [in] Register Index.
//
//      byData
//          [in] Data to write to byReg.
//
//      lpiResult
//          [in] Pointer of the result. The I2C Bus will store the
//            result of the operation in location pointed to by
//            lpiResult.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID I2CWriteOneByte(HANDLE hI2C, BYTE byAddr, BYTE byReg, BYTE byData, LPINT lpiResult)
{
    I2C_TRANSFER_BLOCK I2CXferBlock;
    I2C_PACKET I2CPacket;
    BYTE byOutData[2];

    byOutData[0] = byReg;
    byOutData[1] = byData;
    I2CPacket.wLen = sizeof(byOutData);
    I2CPacket.pbyBuf = (PBYTE) &byOutData;

    I2CPacket.byRW = I2C_RW_WRITE;
    I2CPacket.byAddr = byAddr;
    I2CPacket.lpiResult = lpiResult;

    I2CXferBlock.pI2CPackets = &I2CPacket;
    I2CXferBlock.iNumPackets = 1;

    I2C_MACRO_TRANSFER(hI2C, &I2CXferBlock);
}

//-----------------------------------------------------------------------------
//
// Function: I2CReadOneByte
//
// This function read a single byte data from the register stated in byReg.
//
// Parameters:
//      hI2C 
//          [in] File handle to I2C Bus Interface.
//
//      byAddr
//          [in] I2C Slave device address.
//
//      byReg
//          [in] Register Index.
//
//      lpiResult
//          [in] Pointer of the result. The I2C Bus will store the
//            result of the operation in location pointed to by
//            lpiResult.
//
// Returns:  
//      The single byte content stored in byReg.
//
//-----------------------------------------------------------------------------
BYTE I2CReadOneByte(HANDLE hI2C, BYTE byAddr, BYTE byReg, LPINT lpiResult)
{
    I2C_TRANSFER_BLOCK I2CXferBlock;
    I2C_PACKET I2CPacket[2];
    BYTE byOutData;
    BYTE byInData;

    byOutData = byReg;

    I2CPacket[0].pbyBuf = (PBYTE) &byOutData;
    I2CPacket[0].wLen = sizeof(byOutData);

    I2CPacket[0].byRW = I2C_RW_WRITE;
    I2CPacket[0].byAddr = byAddr;
    I2CPacket[0].lpiResult = lpiResult;


    I2CPacket[1].pbyBuf = (PBYTE) &byInData;
    I2CPacket[1].wLen = sizeof(byInData);

    I2CPacket[1].byRW = I2C_RW_READ;
    I2CPacket[1].byAddr = byAddr;
    I2CPacket[1].lpiResult = lpiResult;

    I2CXferBlock.pI2CPackets = I2CPacket;
    I2CXferBlock.iNumPackets = 2;

    I2C_MACRO_TRANSFER(hI2C, &I2CXferBlock);

    return byInData;
}

//-----------------------------------------------------------------------------
//
// Function: I2CWriteTwoBytes
//
// This function writes a two byte data to the register stated in byReg. The
// function will write byData1 first, followed by byData2. If byData1 is not
// written properly, the entire function will terminate without attempting to
// write byData2.
//
// Parameters:
//      hI2C 
//          [in] File handle to I2C Bus Interface.
//
//      byAddr
//          [in] I2C Slave device address.
//
//      byReg
//          [in] Register Index.
//
//      byData1
//          [in] 1st Data to write to byReg.
//
//      byData2
//          [in] 2nd Data to write to byReg
//
//      lpiResult
//          [in] Pointer of the result. The I2C Bus will store the
//            result of the operation in location pointed to by
//            lpiResult.
//
// Returns:  
//      None.
//
//-----------------------------------------------------------------------------
VOID I2CWriteTwoBytes(HANDLE hI2C, BYTE byAddr, BYTE byReg, BYTE byData1, BYTE byData2, LPINT lpiResult)
{
    I2C_TRANSFER_BLOCK I2CXferBlock;
    I2C_PACKET I2CPacket;
    BYTE byOutData[3];

    byOutData[0] = byReg;
    byOutData[1] = byData1;
    byOutData[2] = byData2;

    I2CPacket.wLen = sizeof(byOutData);
    I2CPacket.pbyBuf = (PBYTE) &byOutData;

    I2CPacket.byRW = I2C_RW_WRITE;
    I2CPacket.byAddr = byAddr;
    I2CPacket.lpiResult = lpiResult;

    I2CXferBlock.pI2CPackets = &I2CPacket;
    I2CXferBlock.iNumPackets = 1;

    I2C_MACRO_TRANSFER(hI2C, &I2CXferBlock);
}

//-----------------------------------------------------------------------------
//
// Function: I2CReadTwoBytes
//
// This function reads two bytes of data from the register stated in byReg.
//
// Parameters:
//      hI2C 
//          [in] File handle to I2C Bus Interface.
//
//      byAddr
//          [in] I2C Slave device address.
//
//      byReg
//          [in] Register Index.
//
//      lpiResult
//          [in] Pointer of the result. The I2C Bus will store the
//          result of the operation in location pointed to by
//          lpiResult.
//
// Returns:  
//      The two byte content stored in byReg.
//
//-----------------------------------------------------------------------------
WORD I2CReadTwoBytes(HANDLE hI2C, BYTE byAddr, BYTE byReg, LPINT lpiResult)
{
    I2C_TRANSFER_BLOCK I2CXferBlock;
    I2C_PACKET I2CPacket[2];
    BYTE byOutData;
    BYTE byInData[2];

    byOutData = byReg;

    I2CPacket[0].pbyBuf = (PBYTE) &byOutData;
    I2CPacket[0].wLen = sizeof(byInData);

    I2CPacket[0].byRW = I2C_RW_WRITE;
    I2CPacket[0].byAddr = byAddr;
    I2CPacket[0].lpiResult = lpiResult;


    I2CPacket[1].pbyBuf = (PBYTE) &byInData;
    I2CPacket[1].wLen = sizeof(byInData);

    I2CPacket[1].byRW = I2C_RW_READ;
    I2CPacket[1].byAddr = byAddr;
    I2CPacket[1].lpiResult = lpiResult;

    I2CXferBlock.pI2CPackets = I2CPacket;
    I2CXferBlock.iNumPackets = 2;

    I2C_MACRO_TRANSFER(hI2C, &I2CXferBlock);

    return ((0xFF & byInData[1]) | (((WORD) byInData[0]) << 8));
}

#define ISP1301_I2C_SPEED 8100

//-----------------------------------------------------------------------------
//
//  Function: Initialize1301
//
//  This function is to configure the ISP1301 transceiver and corresponding 
//  USB OTG Core. This function is called by InitializeTransceiver in hwinit.c
//
//  Parameters:
//     regs - Pointer to the 3 USB Core registers.
//     
//  Returns:
//     TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
BOOL Initialize1301(CSP_USB_REGS * regs)
{
    DWORD r, freq;
    BYTE    addr;
    WORD  dataw;

    hI2C = CreateFile(I2C_FID_CAM,                              // name of device
                GENERIC_READ|GENERIC_WRITE,              // desired access
                FILE_SHARE_READ|FILE_SHARE_WRITE,     // sharing mode
                NULL,                                                             // security attributes (ignored)
                OPEN_EXISTING,                                        // creation disposition
                FILE_FLAG_RANDOM_ACCESS,                  // flags/attributes
            NULL);

    if (hI2C == INVALID_HANDLE_VALUE) {
        return FALSE;
        }
    freq=ISP1301_I2C_SPEED;
    I2C_MACRO_SET_FREQUENCY(hI2C,  freq);
    addr = CSI_I2C_ADDRESS;
    I2C_MACRO_SET_SELF_ADDR(hI2C, addr);

    DEBUGMSG (1, (L"Dump ISP1301 registers\r\n"));
    dataw=I2CReadTwoBytes(hI2C, addr, 0, &r);
    DEBUGMSG (1, (L"\tVendorID=%x\r\n", dataw));
    dataw=I2CReadTwoBytes(hI2C, addr, 2, &r);
    DEBUGMSG (1, (L"\tProduct ID=%x\r\n", dataw));
    dataw=I2CReadTwoBytes(hI2C, addr, 0x14, &r);
    DEBUGMSG (1, (L"\tVersion ID=%x\r\n", dataw));
    I2CWriteOneByte(hI2C, addr, 0x4, 0x4, &r);
    dataw=I2CReadOneByte(hI2C, addr, 0x4, &r);
    DEBUGMSG (1, (L"\tMode Control 1=%x\r\n", dataw));
    dataw=I2CReadOneByte(hI2C, addr, 0x12, &r);
    DEBUGMSG (1, (L"\tMode Control 2=%x\r\n", dataw));
    dataw=I2CReadOneByte(hI2C, addr, 0x6, &r);
    DEBUGMSG (1, (L"\tOTG Control=%x\r\n", dataw));
    dataw=I2CReadOneByte(hI2C, addr, 0x10, &r);
    DEBUGMSG (1, (L"\tOTG Status=%x\r\n", dataw));
    dataw=I2CReadOneByte(hI2C, addr, 0x8, &r);
    DEBUGMSG (1, (L"\tInterrupt Source=%x\r\n", dataw));
    dataw=I2CReadOneByte(hI2C, addr, 0xA, &r);
    DEBUGMSG (1, (L"\tInterrupt Latch=%x\r\n", dataw));
    
    I2CWriteOneByte(hI2C, addr, 0xC, 1, &r);  // Detect vbus invalid
    dataw=I2CReadOneByte(hI2C, addr, 0xC, &r);
    DEBUGMSG (1, (L"\tInterrupt Enable Low=%x\r\n", dataw));
    dataw=I2CReadOneByte(hI2C, addr, 0xE, &r);
    DEBUGMSG (1, (L"\tInterrupt Enable High=%x\r\n", dataw));

    {
        USB_PORTSC_T portsc;
        USB_CTRL_T ctrl;
        DWORD * temp=(DWORD *)&portsc;

        *temp=0;
        // Set PORTSC 
         portsc.PTS=3;       //Serial/1.1 PHY (FS Only)
        portsc.STS=1;       //Serial/1.1 PHY (FS Only)
        OUTREG32(&regs->OTG.PORTSC[0], *temp);

        temp=(DWORD *)&ctrl;
        *temp=0;
        ctrl.OSIC=2;    // usb_otg_serial_interface_config(); Single Ended / Unidirectional (6-wire)
        ctrl.OWIE=1;  // usb_otg_interrupt_enable()
        ctrl.OPM=1; // usb_otg_power_mask_enable();
        SETREG32(&regs->USB_CTRL, *temp);   

        *temp=0;
        ctrl.BPE=1;
        
        CLRREG32(&regs->USB_CTRL, *temp);   
    }   

    OUTREG8(&regs->USB_OTG_MIRROR, 0xA);    // ASESVLD & VBUSVAL 
    return TRUE;
}

//-----------------------------------------------------------------------------
//
//  Function: HardwarePullupDP1301
//
//  This function is being called by HardwarePullupDP in hwinit.c
//
//  Parameters:
//     regs - Pointer to the 3 USB Core registers.
//     
//  Returns:
//     NONE
//
//-----------------------------------------------------------------------------
void HardwarePullupDP1301(CSP_USB_REGS * regs)
{
    DWORD r;
    WORD  dataw;
    BYTE  addr;

    addr = USBOTG_I2C_ADDR;

    I2CWriteOneByte(hI2C, addr, 0x7, 0x4, &r);      // Clear DP_PULLDOWN
    I2CWriteOneByte(hI2C, addr, 0x6, 0x1, &r);      // Set DP_PULLUP
    dataw=I2CReadOneByte(hI2C, addr, 0x10, &r);
    DEBUGMSG (1, (L"Get OTG Status=%x\r\n", dataw));
    if (dataw&0x80) {
        OUTREG8(&regs->USB_OTG_MIRROR, 0xD);    // BSESVLD & VBUSVAL & IDDIG
        DEBUGMSG (1,(L"USB_OTG_MIRROR(%xh)=%x\r\n",offset(CSP_USB_REGS,USB_OTG_MIRROR),INREG32(&regs->USB_OTG_MIRROR)));
    }
    dataw=I2CReadOneByte(hI2C, addr, 0x6, &r);
    DEBUGMSG (1, (L"Set OTG Control=%x\r\n", dataw));
}

#pragma optimize( "", on )



⌨️ 快捷键说明

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