📄 isp1301.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(®s->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(®s->USB_CTRL, *temp);
*temp=0;
ctrl.BPE=1;
CLRREG32(®s->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(®s->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(®s->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 + -