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

📄 clock.c

📁 一个关于s1d13806的应用程序
💻 C
字号:
/*
**===========================================================================
** CLOCK.C
**---------------------------------------------------------------------------
** Copyright (c) 1998, 2001 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
**
** To program the clock generator, call
**
**    int SetClock(CLOCKSELECT clock, FREQINDEX FreqIndex, BYTE *pRegisterBaseAddress)
**
** where:
**    clock is either CLKI or CLKI2 (defined in CLOCK.H)
**    FreqIndex is the clock index in the frequency table
**          (see CLOCK.H for clock index definitions, such as FREQ_25175)
**    pRegisterBaseAddress is the address of the first register (REG[0])
**
** Return Value:
**    OK      Clock was programmed.
**    FAILED  Clock could not be programmed.
*/

#include "clock.h"

/*-------------------------------------------------------------------------*/

#define S0_HI  0x01
#define S0_LOW 0x00

#define S1_HI  0x02
#define S1_LOW 0x00

/*-------------------------------------------------------------------------*/

#define REG_GPIO_CONFIG0   0x04
#define REG_GPIO_CONFIG1   0x05
#define REG_GPIO_CTRL0     0x08
#define REG_GPIO_CTRL1     0x09

/*-------------------------------------------------------------------------*/

static BYTE *pRegister = (void *) 0;

/*-------------------------------------------------------------------------*/

static unsigned regGpioCtrl0 = 0;

/*-------------------------------------------------------------------------*/

/*
** WARNING: IF YOU CHANGE THE _ClockBits[] ARRAY, ALSO CHANGE THE
** FREQ_??? DEFINITIONS IN CLOCK.H
*/
defFreq ClockBits[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 */
   };

/*-------------------------------------------------------------------------*/

//
// 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) ? 0x02 : 0;
   RisingEdgeData = (RisingEdgeBit) ? 0x02 : 0;

   /*
   ** Write falling edge first
   */
   pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | FallingEdgeData | 0x01);  // CLK=1

   pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | FallingEdgeData | 0x00);  // CLK=0

   /*
   ** Write rising edge next
   */
   pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | RisingEdgeData | 0x00);   // CLK=0

   pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | RisingEdgeData | 0x01);   // 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
*/
static int ProgramClockChip(DWORD bits, int VregSelect)
{
   int i;

   regGpioCtrl0 = pRegister[REG_GPIO_CTRL0] & ~0x03;

   /*
   ** Set GPIO pins to outputs
   */
   pRegister[REG_GPIO_CONFIG0] |= 0x03;

   /*
   ** Set clocks and data to high
   */
   pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | 0x03);


   // 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:
         pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | S1_LOW | S0_LOW);
         break;

      case CLK_VREG1:
         pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | S1_LOW | S0_HI);
         break;

      case FEATCLK:
         pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | S1_HI | S0_LOW);
         break;

      case CLK_VREG2:
         pRegister[REG_GPIO_CTRL0] = (BYTE) (regGpioCtrl0 | S1_HI | S0_HI);
         break;

      default:
         return FAILED;
         break;
      }

   return OK;
}

/*-------------------------------------------------------------------------*/

/*
** GetClockChipBits()  gets the programming bits for a preset frequency.
**
** FreqIndex = One of the values listed in clock.h, such as FREQ_25175
**
** 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)
      {
      *bits = ClockBits[FreqIndex].dwProgBits;
      *szFreq = &ClockBits[FreqIndex].szFreq[0];
      }
   else
      {
      *bits = 0;
      *szFreq = (void *) 0;
      return FAILED;
      }

   *bits |= ((DWORD) reg << 21);

   return OK;
}

/*-------------------------------------------------------------------------*/

/*
** To program the clock generator, call
**
**    int SetClock(CLOCKSELECT clock, FREQINDEX FreqIndex, BYTE *pRegisterBaseAddress)
**
** where:
**    clock is either CLKI or CLKI2 (defined in CLOCK.H)
**    FreqIndex is the clock index in the frequency table
**          (see CLOCK.H for clock index definitions, such as FREQ_25175)
**    pRegisterBaseAddress is the address of the first register (REG[0])
**
** Return Value:
**    OK      Clock was programmed.
**    FAILED  Clock could not be programmed.
*/
int SetClock(CLOCKSELECT clock, FREQINDEX FreqIndex, BYTE *pRegisterBaseAddress)
{
   int err;
   DWORD bits;
   char *szFreq;
   unsigned SaveReg;

   pRegister = pRegisterBaseAddress;

   switch (pRegister[REG_GPIO_CTRL0] & 0x03)
      {
      case 0x00:
      default:
         SaveReg = CLK_VREG0;
         break;

      case 0x01:
         SaveReg = CLK_VREG1;
         break;

      case 0x02:
         SaveReg = FEATCLK;
         break;

      case 0x03:
         SaveReg = CLK_VREG2;
      }

   switch (clock)
      {
      case CLKI:
         /*
         ** Program MREG (clock chip registers) for CLKI
         */
         if ((err = GetClockChipBits(FreqIndex, CLK_MREG, &bits, &szFreq)) != OK)
            return err;

         if ((err = ProgramClockChip(bits, CLK_VREG0)) != OK)
            return err;
         break;

      case CLKI2:
         if (FreqIndex == FREQ_FEATCLK)
            {
            /*
            ** Get programming bits for VREG2 (clock chip register) based on FEATCLK frequency
            */
            if ((err = GetClockChipBits(FreqIndex, CLK_VREG2, &bits, &szFreq)) != OK)
               return err;
        

            /*
            ** Program VREG2 and select FEATCLK (which multiplexes the FEATCLK oscillator
            ** to CLKI2)
            */
            if ((err = ProgramClockChip(bits, FEATCLK)) != OK)
               return err;
            }
         else
            {
            /*
            ** Program VREG0 (clock chip register)
            */
            if ((err = GetClockChipBits(FreqIndex, CLK_VREG0, &bits, &szFreq)) != OK)
               return err;
        
            if ((err = ProgramClockChip(bits, SaveReg)) != OK)
               return err;
        
            /*
            ** Program VREG1 (clock chip register)
            */
            if ((err = GetClockChipBits(FreqIndex, CLK_VREG1, &bits, &szFreq)) != OK)
               return err;
        
            /* select SaveReg as active register */
            if ((err = ProgramClockChip(bits, SaveReg)) != OK)
               return err;
            }
         break;
      }

   return OK;
}

/*-------------------------------------------------------------------------*/

⌨️ 快捷键说明

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