📄 hal_clk.c
字号:
/*
**===========================================================================
** HAL_CLK.C
**---------------------------------------------------------------------------
** Copyright (c) 2000, 2001 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-------------------------------------------------------------------------*/
static const char Revision[] = "HAL_CLK.C=$Revision: 10 $";
#define S0_HI 0x20
#define S0_LOW 0x00
#define S1_HI 0x40
#define S1_LOW 0x00
/*-------------------------------------------------------------------------*/
static unsigned regGpioCtrl0 = 0;
/*-------------------------------------------------------------------------*/
/*
** WARNING: IF YOU CHANGE THE _VClkBits[] OR _MClkBits[] ARRAY, ALSO CHANGE THE
** FREQ_??? DEFINITIONS IN HAL.H
*/
_defFreq _VClkBits[MAX_FREQ_INDEX] =
{ { "6.000", 6000, 0x16DA0F }, /* 6.000 MHz */
{ "10.000", 10000, 0x1171A0 }, /* 10.000 MHz */
{ "14.318", 14318, 0x046D0D }, /* 14.318 MHz */
{ "17.734", 17734, 0x0DA92A }, /* 17.734 MHz <- THIS FREQ MUST ALWAYS BE IN TABLE */
{ "20.000", 20000, 0x117120 }, /* 20.000 MHz */
{ "24.000", 24000, 0x16D90F }, /* 24.000 MHz */
{ "25.000", 25000, 0x01ACBD }, /* 25.000 MHz */
{ "25.175", 25175, 0x01A8BC }, /* 25.175 MHz */
{ "28.318", 28318, 0x0558AB }, /* 28.318 MHz */
{ "30.000", 30000, 0x06A493 }, /* 30.000 MHz */
{ "31.500", 31500, 0x08788D }, /* 31.500 MHz */
{ "32.000", 32000, 0x088C8F }, /* 32.000 MHz */
{ "33.000", 33000, 0x0AC895 }, /* 33.000 MHz */
{ "33.333", 33333, 0x0BF4B5 }, /* 33.333 MHz */
{ "34.000", 34000, 0x0C8C8E }, /* 34.000 MHz */
{ "35.000", 35000, 0x0CA490 }, /* 35.000 MHz */
{ "36.000", 36000, 0x0D54A1 }, /* 36.000 MHz */
{ "40.000", 40000, 0x1170A0 }, /* 40.000 MHz */
{ "49.500", 49500, 0x17D8A1 }, /* 49.500 MHz */
{ "50.000", 50000, 0x01AC3D }, /* 50.000 MHz */
{ "56.250", 56250, 0x04D01A }, /* 56.250 MHz */
{ "65.000", 65000, 0x0B4423 }, /* 65.000 MHz */
{ "80.000", 80000, 0x117020 }, /* 80.000 MHz */
{ "100.000", 100000, 0x17F823 } /* 100.000 MHz */
};
//
// _MClkBits have a little more error in frequency than _VClkBits in order
// to prevent harmonics in the clock chip.
//
_defFreq _MClkBits[MAX_FREQ_INDEX] =
{ { "6.000", 6000, 0x77E623 }, /* 6.000 MHz */
{ "10.000", 10000, 0x71399B }, /* 10.000 MHz */
{ "14.318", 14318, 0x046D0D }, /* 14.318 MHz */
{ "17.734", 17734, 0x6CC513 }, /* 17.734 MHz <- THIS FREQ MUST ALWAYS BE IN TABLE */
{ "20.000", 20000, 0x71391B }, /* 20.000 MHz */
{ "24.000", 24000, 0x77e523 }, /* 24.000 MHz */
{ "25.000", 25000, 0x61C8C1 }, /* 25.000 MHz */
{ "25.175", 25175, 0x60C09B }, /* 25.175 MHz */
{ "28.318", 28318, 0x6550AA }, /* 28.318 MHz */
{ "30.000", 30000, 0x67B0B3 }, /* 30.000 MHz */
{ "31.500", 31500, 0x69FCB9 }, /* 31.500 MHz */
{ "32.000", 32000, 0x6998AD }, /* 32.000 MHz */
{ "33.000", 33000, 0x6B40A2 }, /* 33.000 MHz */
{ "33.333", 33333, 0x6BD8B2 }, /* 33.333 MHz */
{ "34.000", 34000, 0x6DD8B1 }, /* 34.000 MHz */
{ "35.000", 35000, 0x6DF0B2 }, /* 35.000 MHz */
{ "36.000", 36000, 0x6D68A3 }, /* 36.000 MHz */
{ "40.000", 40000, 0x71389B }, /* 40.000 MHz */
{ "49.500", 49500, 0x774096 }, /* 49.500 MHz */
{ "50.000", 50000, 0x61C841 }, /* 50.000 MHz */
{ "56.250", 56250, 0x65B437 }, /* 56.250 MHz */
{ "65.000", 65000, 0x6AE018 }, /* 65.000 MHz */
{ "80.000", 80000, 0x71381B }, /* 80.000 MHz */
{ "100.000", 100000, 0x77DC21 } /* 100.000 MHz */
};
/*-------------------------------------------------------------------------*/
//
// WriteClockEdge assumes that at the time of the function call, the clock is high.
//
static void _WriteClockEdge(unsigned FallingEdgeBit, unsigned RisingEdgeBit)
{
unsigned FallingEdgeData;
unsigned RisingEdgeData;
FallingEdgeData = (FallingEdgeBit) ? 0x40 : 0;
RisingEdgeData = (RisingEdgeBit) ? 0x40 : 0;
/*
** Write falling edge first
*/
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | FallingEdgeData | 0x20); // CLK=1
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | FallingEdgeData | 0x00); // CLK=0
/*
** Write rising edge next
*/
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | RisingEdgeData | 0x00); // CLK=0
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | RisingEdgeData | 0x20); // CLK=1
}
/*-------------------------------------------------------------------------*/
/*
** ClockChipBits2Freq() converts the programming clock bits to frequency
**
** *freq = returns actual frequency of bits, with 5 decimal places
** (divide *freq by 100000L for frequency in MHz)
*/
void _ClockChipBits2Freq(DWORD bits, DWORD *dwFreq)
{
DWORD P, Q, M;
/*
** Calculate frequency from bits
*/
P = ((bits >> 10) & 0x7f) + 3;
Q = (bits & 0x7f) + 2;
M = 1 << ((bits >> 7) & 0x07);
*dwFreq = (1431818L * 2L * P) / (Q * M);
}
/*-------------------------------------------------------------------------*/
/*
** ProgramClockChip() programs the clock chip with a 24 bit word.
**
** bits = 24 bit programming word
*/
int _ProgramClockChip(DWORD bits, int VregSelect)
{
int i;
int err;
err = ERR_OK;
regGpioCtrl0 = seReadRegByte(REG_GPIO_STATUS_CONTROL0) & ~0x60;
/*
** Set GPIO pins to outputs
*/
seWriteRegByte(REG_GPIO_CONFIG0, seReadRegByte(REG_GPIO_CONFIG0) | 0x60);
/*
** Set clocks and data to high
*/
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | 0x60);
// Unlock sequence
for (i = 0; i < 5; ++i)
_WriteClockEdge(1, 1);
_WriteClockEdge(0, 0); // Last part of unlock sequence
_WriteClockEdge(0, 0); // Start Bit
for (i = 0; i < 24; ++i)
{
if (bits & 1)
_WriteClockEdge(0, 1);
else
_WriteClockEdge(1, 0);
bits >>= 1;
}
_WriteClockEdge(1, 1); // Stop Bit
/*
** Select VREG0, VREG1, VREG2, or VREG3
*/
switch (VregSelect)
{
case CLK_VREG0:
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | S1_LOW | S0_LOW);
break;
case CLK_VREG1:
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | S1_LOW | S0_HI);
break;
case FEATCLK:
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | S1_HI | S0_LOW);
break;
case CLK_VREG2:
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, regGpioCtrl0 | S1_HI | S0_HI);
break;
default:
err = ERR_FAILED;
break;
}
return err;
}
/*-------------------------------------------------------------------------*/
/*
** seGetClockChipBits() gets the programming bits for a preset frequency.
**
** FreqIndex = FREQ_17734, FREQ_25175, FREQ_31500, FREQ_36000, FREQ_40000
**
** reg = CLK_VREG0, CLK_VREG1, CLK_VREG2, CLK_MREG
**
** *bits = programming bits for given frequency
*/
int _GetClockChipBits(int FreqIndex, int reg, DWORD *bits, char **szFreq)
{
if (FreqIndex < MAX_FREQ_INDEX)
{
if (reg == CLK_MREG)
{
*bits = _MClkBits[FreqIndex].dwProgBits;
*szFreq = &_MClkBits[FreqIndex].szFreq[0];
}
else
{
*bits = _VClkBits[FreqIndex].dwProgBits;
*szFreq = &_VClkBits[FreqIndex].szFreq[0];
}
}
else
{
*bits = 0;
*szFreq = NULL;
return ERR_FAILED;
}
*bits &= ~0xe00000;
*bits |= ((DWORD) reg << 21);
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
int seSetClock(CLOCKSELECT clock, FREQINDEX FreqIndex)
{
int err;
DWORD bits;
char *szFreq;
switch (clock)
{
case CLKI:
/*
** Program VREG0 (clock chip register)
*/
if ((err = _GetClockChipBits(FreqIndex, CLK_VREG0, &bits, &szFreq)) != ERR_OK)
return err;
if ((err = _ProgramClockChip(bits, CLK_VREG0)) != ERR_OK)
return err;
break;
case CLKI2:
/*
** Program MREG (clock chip registers)
*/
if ((err = _GetClockChipBits(FreqIndex, CLK_MREG, &bits, &szFreq)) != ERR_OK)
return err;
if ((err = _ProgramClockChip(bits, CLK_VREG0)) != ERR_OK)
return err;
break;
default:
return ERR_FAILED;
break;
}
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -