📄 bspi2c.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Freescale Semiconductor, Inc. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// Freescale Semiconductor, Inc.
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// File: bspi2c.c
//
// Provides BSP-specific configuration routines for the I2C peripheral.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include "bsp.h"
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
static const WORD wI2CClockRateDivider[] = {
30, 32, 36, 42, 48, 52, 60, 72, 80, 88, 104, 128, 144, 160, 192, 240,
288, 320, 384, 480, 576, 640, 768, 960, 1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840,
22, 24, 26, 28, 32, 36, 40, 44, 48, 56, 64, 72, 80, 96, 112, 128,
160, 192, 224, 256, 320, 384, 448, 512, 640, 768, 896, 1024, 1280, 1536, 1792, 2048
};
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
#define I2C_INTERRUPT_WAIT_DELAY 1000
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Local Functions
//-----------------------------------------------------------------------------
//
// Function: BSPCalculateClkRateDiv
//
// This function will, on obtaining the frequency, determines the nearest clock
// rate divider needed to step the I2C Bus up/down. DO NOT CALL THIS FUNCTION
// directly. The recommended method is to use I2C_MACRO_SET_FREQUENCY() in
// i2cbus.h
//
// Parameters:
// dwFrequency
// [in] Contains the desired clock frequency of the slave device.
//
// Returns:
// Returns an index to the array wI2CClockRateDivider. The content in the
// index holds the nearest clock rate divider available.
//
//-----------------------------------------------------------------------------
WORD BSPCalculateClkRateDiv(DWORD dwFrequency)
{
INT iFirstRd, iSecondRd;
WORD wEstDivider;
BYTE byCRDALen = sizeof(wI2CClockRateDivider)/sizeof(wI2CClockRateDivider[0]);
UINT32 freq;
// Obtain an estimate of the divider required
DDKClockGetFreq(DDK_CLOCK_SIGNAL_PER, &freq);
wEstDivider = (WORD)(freq / dwFrequency);
// Search for the nearest divider in the first half of the array
for (iFirstRd = 0; iFirstRd < (byCRDALen/2-1); iFirstRd++)
{
// Once found a divider greater than the estimate, stop
if (wEstDivider <= wI2CClockRateDivider[iFirstRd])
break;
}
if (wEstDivider == wI2CClockRateDivider[iFirstRd])
{
// If the estimated divider matched one of the array entries, no need
// to search further
wEstDivider = iFirstRd;
}
else
{
// Going to second round
for (iSecondRd = (byCRDALen/2); iSecondRd < (byCRDALen-1); iSecondRd++)
{
// Again, if a greater entry is found, stop
if (wEstDivider <= wI2CClockRateDivider[iSecondRd])
break;
}
if (wEstDivider == wI2CClockRateDivider[iSecondRd])
{
// If the estimated divider is found in the second round, stop
wEstDivider = iSecondRd;
}
else
{
// Search for the nearest divider among the 2 portion of the array
if ((wI2CClockRateDivider[iFirstRd] > wEstDivider) && (wI2CClockRateDivider[iSecondRd] > wEstDivider))
{
if ((wI2CClockRateDivider[iFirstRd] - wEstDivider) < (wI2CClockRateDivider[iSecondRd] - wEstDivider))
wEstDivider = iFirstRd;
else
wEstDivider = iSecondRd;
}
else
if (wI2CClockRateDivider[iSecondRd] > wEstDivider)
{
wEstDivider = iSecondRd;
}
else
{
// Less than setting, use wI2CClockRateDivider[31] as default
wEstDivider = iFirstRd;
}
}
}
// Obtain the nearest clock rate divider
return wEstDivider;
}
//-----------------------------------------------------------------------------
//
// Function: BSPI2CIOMUXConfig
//
// This function makes the DDK call to configure the IOMUX
// pins required for the I2C.
//
// Parameters:
// index
// [in] Index of the I2C device requested.
//
// Returns:
// TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL BSPI2CIOMUXConfig(UINT32 index)
{
switch (index)
{
case 1:
// Configure IOMUX to set I2C pins
DDKIomuxSetPinMux(DDK_IOMUX_PIN_I2C_DAT, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_I2C_CLK, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
break;
case 3:
DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI2_SS2, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI2_SCLK, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
break;
default:
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: BSPI2CEnableClock
//
// This function is a wrapper for I2C to enable/disable its clock using a valid
// CRM handle.
//
// Parameters:
// index
// [in] Index specifying the I2C module.
// bEnable
// [in] TRUE if I2C Clock is to be enabled. FALSE if I2C Clock is
// to be disabled.
//
// Returns:
// TRUE if successfully performed the required action.
//
//-----------------------------------------------------------------------------
BOOL BSPI2CEnableClock(UINT32 index, BOOL bEnable)
{
DDK_CLOCK_GATE_INDEX clockGateIndex;
switch (index)
{
case 1:
clockGateIndex = DDK_CLOCK_GATE_INDEX_I2C1;
break;
case 2:
clockGateIndex = DDK_CLOCK_GATE_INDEX_I2C2;
break;
case 3:
clockGateIndex = DDK_CLOCK_GATE_INDEX_I2C3;
break;
default:
DEBUGMSG(1, (TEXT("Invalid I2C module index\r\n")));
return FALSE;
}
if (bEnable)
return DDKClockSetGatingMode(clockGateIndex,
DDK_CLOCK_GATE_MODE_ENABLED_ALL);
else
return DDKClockSetGatingMode(clockGateIndex,
DDK_CLOCK_GATE_MODE_DISABLED);
}
//-----------------------------------------------------------------------------
//
// Function: BSPGetTimeoutValue
//
// This function returns an integer representing the wait time that
// occurs before timing out while waiting for an I2C interrupt.
// CRM handle.
//
// Parameters:
// None.
//
// Returns:
// Interrupt wait timeout value.
//
//-----------------------------------------------------------------------------
INT BSPGetTimeoutValue(void)
{
return I2C_INTERRUPT_WAIT_DELAY;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -