Nut/OS  5.0.5
API Reference
lpc176x_clk.h
Go to the documentation of this file.
00001 #ifndef _LPC17XX_CLK_H_
00002 #define _LPC17XX_CLK_H_
00003 
00004 /*
00005  * Copyright (C) 2012 by Ole Reinhardt <ole.reinhardt@embedded-it.de>
00006  *
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  *
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. Neither the name of the copyright holders nor the names of
00019  *    contributors may be used to endorse or promote products derived
00020  *    from this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00029  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00030  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00031  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00032  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00033  * SUCH DAMAGE.
00034  *
00035  * For additional information see http://www.ethernut.de/
00036  */
00037 
00038 /*
00039  * \verbatim
00040  * $Id: $
00041  * \endverbatim
00042  */
00043 
00044 /*----------------------------------------------------------------------------*
00045   Define clocks
00046  *----------------------------------------------------------------------------*/
00047 
00048 #define XTAL        (12000000UL)        /* Oscillator frequency               */
00049 #define OSC_CLK     (      XTAL)        /* Main oscillator frequency          */
00050 #define RTC_CLK     (   32000UL)        /* RTC oscillator frequency           */
00051 #define IRC_OSC     ( 4000000UL)        /* Internal RC oscillator frequency   */
00052 
00053 
00054 /*----------------------------------------------------------------------------*
00055   Peripheral clock divider bit positions
00056  *----------------------------------------------------------------------------*/
00057 
00058 #define  CLKPWR_PCLKSEL_WDT          0  /* WDT     */
00059 #define  CLKPWR_PCLKSEL_TIMER0       2  /* TIMER 0 */
00060 #define  CLKPWR_PCLKSEL_TIMER1       4  /* TIMER 1 */
00061 #define  CLKPWR_PCLKSEL_UART0        6  /* UART 0  */
00062 #define  CLKPWR_PCLKSEL_UART1        8  /* UART 1  */
00063 #define  CLKPWR_PCLKSEL_PWM1        12  /* PWM 1   */
00064 #define  CLKPWR_PCLKSEL_I2C0        14  /* I2C 0   */
00065 #define  CLKPWR_PCLKSEL_SPI         16  /* SPI     */
00066 #define  CLKPWR_PCLKSEL_SSP1        20  /* SSP 1   */
00067 #define  CLKPWR_PCLKSEL_DAC         22  /* DAC     */
00068 #define  CLKPWR_PCLKSEL_ADC         24  /* ADC     */
00069 #define  CLKPWR_PCLKSEL_CAN1        26  /* CAN 1   */
00070 #define  CLKPWR_PCLKSEL_CAN2        28  /* CAN 2   */
00071 #define  CLKPWR_PCLKSEL_ACF         30  /* ACF     */
00072 
00073 #define  CLKPWR_PCLKSEL_QEI         32  /* QEI     */
00074 #define  CLKPWR_PCLKSEL_PCB         36  /* PCB     */
00075 #define  CLKPWR_PCLKSEL_I2C1        38  /* I2C 1   */
00076 #define  CLKPWR_PCLKSEL_SSP0        42  /* SSP 0   */
00077 #define  CLKPWR_PCLKSEL_TIMER2      44  /* TIMER 2 */
00078 #define  CLKPWR_PCLKSEL_TIMER3      46  /* TIMER 3 */
00079 #define  CLKPWR_PCLKSEL_UART2       48  /* UART 2  */
00080 #define  CLKPWR_PCLKSEL_UART3       50  /* UART 3  */
00081 #define  CLKPWR_PCLKSEL_I2C2        52  /* I2C 2   */
00082 #define  CLKPWR_PCLKSEL_I2S         54  /* I2S     */
00083 #define  CLKPWR_PCLKSEL_RIT         58  /* RIT     */
00084 #define  CLKPWR_PCLKSEL_SYSCON      60  /* SYSCON  */
00085 #define  CLKPWR_PCLKSEL_MC          62  /* MC      */
00086 
00087 /* Peripheral clock devider selection values
00088  * Note: When CCLK_DIV_8, Peripheral's clock is selected to
00089  * PCLK_xyz = CCLK/8 except for CAN1, CAN2, and CAN filtering
00090  * when 0b11 selects PCLK_xyz = CCLK/6
00091  */
00092 
00093 #define  CLKPWR_PCLKSEL_CCLK_DIV_4  0    /* CCLK / 4 */
00094 #define  CLKPWR_PCLKSEL_CCLK_DIV_1  1    /* CCLK     */
00095 #define  CLKPWR_PCLKSEL_CCLK_DIV_2  2    /* CCLK / 2 */
00096 
00097 
00098 /*----------------------------------------------------------------------------*
00099   Peripheral power control bit positions
00100  *----------------------------------------------------------------------------*/
00101 
00102 #define  CLKPWR_PCONP_PCTIM0         1  /* Timer/Counter 0 */
00103 #define  CLKPWR_PCONP_PCTIM1         2  /* Timer/Counter 1 */
00104 #define  CLKPWR_PCONP_PCUART0        3  /* UART 0          */
00105 #define  CLKPWR_PCONP_PCUART1        4  /* UART 1          */
00106 
00107 #define  CLKPWR_PCONP_PCPWM1         6  /* PWM1            */
00108 #define  CLKPWR_PCONP_PCI2C0         7  /* I2C 0           */
00109 #define  CLKPWR_PCONP_PCSPI          8  /* SPI             */
00110 #define  CLKPWR_PCONP_PCRTC          9  /* RTC             */
00111 #define  CLKPWR_PCONP_PCSSP1        10  /* SSP 1           */
00112 
00113 #define  CLKPWR_PCONP_PCAD          12  /* ADC 0           */
00114 #define  CLKPWR_PCONP_PCAN1         13  /* CAN 1           */
00115 #define  CLKPWR_PCONP_PCAN2         14  /* CAN 2           */
00116 #define  CLKPWR_PCONP_PCGPIO        15  /* GPIO            */
00117 #define  CLKPWR_PCONP_PCRIT         16  /* RIT             */
00118 #define  CLKPWR_PCONP_PCMC          17  /* Motor PWM       */
00119 #define  CLKPWR_PCONP_PCQEI         18  /* QEI             */
00120 #define  CLKPWR_PCONP_PCI2C1        19  /* I2C 1           */
00121 
00122 #define  CLKPWR_PCONP_PCSSP0        21  /* SSP 0           */
00123 #define  CLKPWR_PCONP_PCTIM2        22  /* Timer 2         */
00124 #define  CLKPWR_PCONP_PCTIM3        23  /* Timer 3         */
00125 #define  CLKPWR_PCONP_PCUART2       24  /* UART 2          */
00126 #define  CLKPWR_PCONP_PCUART3       25  /* UART 3          */
00127 #define  CLKPWR_PCONP_PCI2C2        26  /* I2C 2           */
00128 #define  CLKPWR_PCONP_PCI2S         27  /* I2S             */
00129 
00130 #define  CLKPWR_PCONP_PCGPDMA       29  /* GP DMA          */
00131 #define  CLKPWR_PCONP_PCENET        30  /* Ethernet        */
00132 #define  CLKPWR_PCONP_PCUSB         31  /* USB             */
00133 
00134 #define SysCtlPeripheralClkEnable(bit)  CM3BBREG(LPC_SC_BASE, LPC_SC_TypeDef, PCONP, (bit)) = 1
00135 #define SysCtlPeripheralClkDisable(bit) CM3BBREG(LPC_SC_BASE, LPC_SC_TypeDef, PCONP, (bit)) = 0
00136 #define SysCtlPeripheralClkGet(bit)     CM3BBREG(LPC_SC_BASE, LPC_SC_TypeDef, PCONP, (bit))
00137 uint32_t SysCtlClockGet(void);
00138 int SetSysClock(void);
00139 
00140 
00141 uint32_t Lpc17xx_ClockGet(int idx);
00142 
00143 
00144 /* Transform ns into clock cycles (runtime, only 32bit multiplications):
00145  * Valid input range: Clock < 995 MHz, ns = 0..1000000 (1ms)
00146  *
00147  * a) Divide Clock by 16. This gives enough headroom for step b).
00148  * b) Multiply Clock by 69. This will adjust for decimal/binary divisor.
00149  *    This computation will overflow for a clock > 995 MHz!
00150  *    This computation will give results 0,5% larger than the real value.
00151  * c) Divide Clock by 1048576 (2^20). This will give enough headroom for step d).
00152  * d) Multiply Clock by ns. This will not overflow for ns = 0..1000000 (1ms).
00153  * e) Divide Clock by 4096 (2^12). This will give value in clocks.
00154  * f) Add 1 to account for rounding.
00155  * (Use runtime computations because frequencies may change in runtime).
00156  */
00157 #define NS_2_CLKS(clock, ns) (((((((clock) >> 4)*69) >> 20)*(ns))>>12)+1)
00158 
00159 /* Delay loop for short busy waits */
00160 __attribute__( ( always_inline ) ) static inline void wait_clocks( unsigned int clocks)
00161 {
00162    clocks >>= 1;          // 2 clocks per cycle
00163    while(clocks--) {
00164       asm("":::"memory"); // hint for gcc: do not remove this loop!
00165    }
00166 }
00167 
00168 #endif /* _LPC17XX_CLK_H_ */