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

📄 isp1301.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
字号:
//------------------------------------------------------------------------------
//
// Copyright (C) 2005-2006, 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
//  Purpose:  Initialization and configuration routines specific to 1301 transceiver
//
#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


typedef struct USB_ISP1301{
    HANDLE hI2C;
    HANDLE hIntrThread;
    DWORD irq;
    DWORD sysintr;
    HANDLE hIntrEvent;
    BOOL exitIntrThread;
}USB_ISP1301;


USB_ISP1301 g_trans;

//-----------------------------------------------------------------------------
//
// 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;

    g_trans.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 (g_trans.hI2C == INVALID_HANDLE_VALUE) {
            ERRORMSG(TRUE, (TEXT("%s: CreateFile for I2C failed!\r\n"), __WFUNCTION__));
        return FALSE;
    }

    freq=ISP1301_I2C_SPEED;
    I2C_MACRO_SET_FREQUENCY(g_trans.hI2C,  freq);
    addr = CSI_I2C_ADDRESS;
    I2C_MACRO_SET_SELF_ADDR(g_trans.hI2C, addr);

    RETAILMSG(1, (L"Dump ISP1301 registers\r\n"));
    dataw=I2CReadTwoBytes(g_trans.hI2C, addr, 0, &r);
    RETAILMSG(1, (L"\tVendorID=%x\r\n", dataw));
    dataw=I2CReadTwoBytes(g_trans.hI2C, addr, 2, &r);
    RETAILMSG(1, (L"\tProduct ID=%x\r\n", dataw));
    dataw=I2CReadTwoBytes(g_trans.hI2C, addr, 0x14, &r);
    RETAILMSG(1, (L"\tVersion ID=%x\r\n", dataw));
    I2CWriteOneByte(g_trans.hI2C, addr, 0x4, 0x4, &r);
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0x4, &r);
    RETAILMSG(1, (L"\tMode Control 1=%x\r\n", dataw));
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0x12, &r);
    RETAILMSG(1, (L"\tMode Control 2=%x\r\n", dataw));
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0x6, &r);
    RETAILMSG(1, (L"\tOTG Control=%x\r\n", dataw));
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0x10, &r);
    RETAILMSG(1, (L"\tOTG Status=%x\r\n", dataw));
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0x8, &r);
    RETAILMSG(1, (L"\tInterrupt Source=%x\r\n", dataw));
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0xA, &r);
    RETAILMSG(1, (L"\tInterrupt Latch=%x\r\n", dataw));
    
    I2CWriteOneByte(g_trans.hI2C, addr, 0xC, 0xff, &r);  
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0xC, &r);
    RETAILMSG(1, (L"\tInterrupt Enable Low=%x\r\n", dataw));
    I2CWriteOneByte(g_trans.hI2C, addr, 0xE, 0xff, &r);  
    dataw=I2CReadOneByte(g_trans.hI2C, addr, 0xE, &r);
    RETAILMSG(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.PE=1; //Port Enabled
        portsc.PTS=3;       //Serial/1.1 PHY (FS Only)
        portsc.STS=1;       //Serial/1.1 PHY (FS Only)
        portsc.PFSC=1;  //Port Force Full Speed Connect 
        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);   
    }   

    // Request SYSINTR for interrupts
    if (!KernelIoControl(
            IOCTL_HAL_REQUEST_SYSINTR, &(g_trans.irq), sizeof(DWORD),
            &g_trans.sysintr, sizeof(g_trans.sysintr), NULL
        )) goto clean;

    // Create interrupt event
    g_trans.hIntrEvent = CreateEvent(0, FALSE, FALSE, NULL);
    if (g_trans.hIntrEvent== NULL) {
        ERRORMSG(TRUE, (
            L"ERROR: UfnPdd_Init: Error creating interrupt event\r\n"
        ));
        goto clean;
        }

    // Initialize interrupt
    if (!InterruptInitialize(g_trans.sysintr, g_trans.hIntrEvent, NULL, 0)) {
        ERRORMSG(TRUE, (
            L"ERROR: UfnPdd_Init: Interrupt initialization failed\r\n"
        ));
        goto clean;
        }

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

#pragma optimize( "", on )



⌨️ 快捷键说明

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