Library to access LPC17xx peripherals. It uses static inline functions, constant propagation and dead code elimination to be as fast as possible.
Dependents: Chua-VGA Wolfram-1D-VGA WolframRnd-1D-VGA Basin-VGA ... more
clock.h@0:7a91348b4a02, 2011-07-03 (annotated)
- Committer:
- Ivop
- Date:
- Sun Jul 03 17:11:55 2011 +0000
- Revision:
- 0:7a91348b4a02
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Ivop | 0:7a91348b4a02 | 1 | /* Copyright (C) 2010, 2011 by Ivo van Poorten <ivop@euronet.nl> |
Ivop | 0:7a91348b4a02 | 2 | * This file is licensed under the terms of the GNU Lesser |
Ivop | 0:7a91348b4a02 | 3 | * General Public License, version 3. |
Ivop | 0:7a91348b4a02 | 4 | */ |
Ivop | 0:7a91348b4a02 | 5 | |
Ivop | 0:7a91348b4a02 | 6 | /* see chapter 4 of user manual for details on clocks and power */ |
Ivop | 0:7a91348b4a02 | 7 | |
Ivop | 0:7a91348b4a02 | 8 | #ifndef FASTLIB_CLKPWR_H |
Ivop | 0:7a91348b4a02 | 9 | #define FASTLIB_CLKPWR_H |
Ivop | 0:7a91348b4a02 | 10 | |
Ivop | 0:7a91348b4a02 | 11 | #include "fastlib/common.h" |
Ivop | 0:7a91348b4a02 | 12 | |
Ivop | 0:7a91348b4a02 | 13 | #define FL_CLKSRCSEL ((volatile uint32_t *) 0x400FC10C) |
Ivop | 0:7a91348b4a02 | 14 | |
Ivop | 0:7a91348b4a02 | 15 | #define FL_PLL0CON ((volatile uint32_t *) 0x400FC080) |
Ivop | 0:7a91348b4a02 | 16 | #define FL_PLL0CFG ((volatile uint32_t *) 0x400FC084) |
Ivop | 0:7a91348b4a02 | 17 | #define FL_PLL0STAT ((volatile uint32_t *) 0x400FC088) |
Ivop | 0:7a91348b4a02 | 18 | #define FL_PLL0FEED ((volatile uint32_t *) 0x400FC08C) |
Ivop | 0:7a91348b4a02 | 19 | |
Ivop | 0:7a91348b4a02 | 20 | #define FL_PLL1CON ((volatile uint32_t *) 0x400FC0A0) |
Ivop | 0:7a91348b4a02 | 21 | #define FL_PLL1CFG ((volatile uint32_t *) 0x400FC0A4) |
Ivop | 0:7a91348b4a02 | 22 | #define FL_PLL1STAT ((volatile uint32_t *) 0x400FC0A8) |
Ivop | 0:7a91348b4a02 | 23 | #define FL_PLL1FEED ((volatile uint32_t *) 0x400FC0AC) |
Ivop | 0:7a91348b4a02 | 24 | |
Ivop | 0:7a91348b4a02 | 25 | #define FL_CCLKCFG ((volatile uint32_t *) 0x400FC104) |
Ivop | 0:7a91348b4a02 | 26 | #define FL_USBCLKCFG ((volatile uint32_t *) 0x400FC108) |
Ivop | 0:7a91348b4a02 | 27 | #define FL_PCLKSEL0 ((volatile uint32_t *) 0x400FC1A8) |
Ivop | 0:7a91348b4a02 | 28 | #define FL_PCLKSEL1 ((volatile uint32_t *) 0x400FC1AC) |
Ivop | 0:7a91348b4a02 | 29 | |
Ivop | 0:7a91348b4a02 | 30 | #define FL_CLKOUTCFG ((volatile uint32_t *) 0x400FC1C8) |
Ivop | 0:7a91348b4a02 | 31 | |
Ivop | 0:7a91348b4a02 | 32 | /* Internal RC oscillator, nominal frequency is 4MHz |
Ivop | 0:7a91348b4a02 | 33 | * Main oscillator --> mbed: 12MHz slave mode |
Ivop | 0:7a91348b4a02 | 34 | * RTC oscillator --> mbed: FC-135 32.7680kHz 12.5pF |
Ivop | 0:7a91348b4a02 | 35 | */ |
Ivop | 0:7a91348b4a02 | 36 | |
Ivop | 0:7a91348b4a02 | 37 | /* for USB, use only Main oscillator |
Ivop | 0:7a91348b4a02 | 38 | * for CAN over 100 kbit/s, do not use Internal RC oscillator |
Ivop | 0:7a91348b4a02 | 39 | */ |
Ivop | 0:7a91348b4a02 | 40 | |
Ivop | 0:7a91348b4a02 | 41 | #define FL_PLL0_CLOCK_SOURCE_INTERNAL 0 |
Ivop | 0:7a91348b4a02 | 42 | #define FL_PLL0_CLOCK_SOURCE_MAIN 1 |
Ivop | 0:7a91348b4a02 | 43 | #define FL_PLL0_CLOCK_SOURCE_RTC 2 |
Ivop | 0:7a91348b4a02 | 44 | |
Ivop | 0:7a91348b4a02 | 45 | static inline void fl_select_pll0_clock_source(const int source) { |
Ivop | 0:7a91348b4a02 | 46 | *FL_CLKSRCSEL = source; |
Ivop | 0:7a91348b4a02 | 47 | } |
Ivop | 0:7a91348b4a02 | 48 | |
Ivop | 0:7a91348b4a02 | 49 | /* PLL0: |
Ivop | 0:7a91348b4a02 | 50 | * input source --> PLL input divider (N) --> PLL multiplier (M) |
Ivop | 0:7a91348b4a02 | 51 | * |
Ivop | 0:7a91348b4a02 | 52 | * input: 32kHz-50MHz --> |
Ivop | 0:7a91348b4a02 | 53 | * N: 1-256 --> |
Ivop | 0:7a91348b4a02 | 54 | * M: 6-512 --> 275MHz-550MHz |
Ivop | 0:7a91348b4a02 | 55 | * |
Ivop | 0:7a91348b4a02 | 56 | * PLL0 output dividers below |
Ivop | 0:7a91348b4a02 | 57 | */ |
Ivop | 0:7a91348b4a02 | 58 | |
Ivop | 0:7a91348b4a02 | 59 | static inline void fl_pll0_control(const int enable, const int connect) { |
Ivop | 0:7a91348b4a02 | 60 | *FL_PLL0CON = enable | (connect<<1); |
Ivop | 0:7a91348b4a02 | 61 | } |
Ivop | 0:7a91348b4a02 | 62 | |
Ivop | 0:7a91348b4a02 | 63 | static inline void fl_pll0_config(const unsigned int N, const unsigned int M) { |
Ivop | 0:7a91348b4a02 | 64 | *FL_PLL0CFG = (M-1) | ((N-1)<<16); |
Ivop | 0:7a91348b4a02 | 65 | } |
Ivop | 0:7a91348b4a02 | 66 | |
Ivop | 0:7a91348b4a02 | 67 | static inline unsigned fl_pll0_get_M(void) { |
Ivop | 0:7a91348b4a02 | 68 | return (*FL_PLL0STAT & 0x7fff) + 1; |
Ivop | 0:7a91348b4a02 | 69 | } |
Ivop | 0:7a91348b4a02 | 70 | |
Ivop | 0:7a91348b4a02 | 71 | static inline unsigned fl_pll0_get_N(void) { |
Ivop | 0:7a91348b4a02 | 72 | return ((*FL_PLL0STAT >> 16) & 0xff) + 1; |
Ivop | 0:7a91348b4a02 | 73 | } |
Ivop | 0:7a91348b4a02 | 74 | |
Ivop | 0:7a91348b4a02 | 75 | static inline int fl_pll0_get_enable(void) { |
Ivop | 0:7a91348b4a02 | 76 | return *FL_PLL0STAT & (1U<<24); |
Ivop | 0:7a91348b4a02 | 77 | } |
Ivop | 0:7a91348b4a02 | 78 | |
Ivop | 0:7a91348b4a02 | 79 | static inline int fl_pll0_get_connect(void) { |
Ivop | 0:7a91348b4a02 | 80 | return *FL_PLL0STAT & (1U<<25); |
Ivop | 0:7a91348b4a02 | 81 | } |
Ivop | 0:7a91348b4a02 | 82 | |
Ivop | 0:7a91348b4a02 | 83 | static inline int fl_pll0_get_lock(void) { |
Ivop | 0:7a91348b4a02 | 84 | return *FL_PLL0STAT & (1U<<26); |
Ivop | 0:7a91348b4a02 | 85 | } |
Ivop | 0:7a91348b4a02 | 86 | |
Ivop | 0:7a91348b4a02 | 87 | static inline void fl_pll0_feed(void) { |
Ivop | 0:7a91348b4a02 | 88 | *FL_PLL0FEED = 0xaa; |
Ivop | 0:7a91348b4a02 | 89 | *FL_PLL0FEED = 0x55; |
Ivop | 0:7a91348b4a02 | 90 | } |
Ivop | 0:7a91348b4a02 | 91 | |
Ivop | 0:7a91348b4a02 | 92 | /* PLL1: |
Ivop | 0:7a91348b4a02 | 93 | * input main oscillator --> PLL multiplier (M) --> output divider (2P) |
Ivop | 0:7a91348b4a02 | 94 | */ |
Ivop | 0:7a91348b4a02 | 95 | |
Ivop | 0:7a91348b4a02 | 96 | static inline void fl_pll1_control(const int enable, const int connect) { |
Ivop | 0:7a91348b4a02 | 97 | *FL_PLL1CON = enable | (connect<<1); |
Ivop | 0:7a91348b4a02 | 98 | } |
Ivop | 0:7a91348b4a02 | 99 | |
Ivop | 0:7a91348b4a02 | 100 | static inline void fl_pll1_config(const unsigned int M, const unsigned int P) { |
Ivop | 0:7a91348b4a02 | 101 | *FL_PLL1CFG = M | (P<<5); |
Ivop | 0:7a91348b4a02 | 102 | } |
Ivop | 0:7a91348b4a02 | 103 | |
Ivop | 0:7a91348b4a02 | 104 | static inline int fl_pll1_get_M(void) { |
Ivop | 0:7a91348b4a02 | 105 | return *FL_PLL1STAT & 0x1f; |
Ivop | 0:7a91348b4a02 | 106 | } |
Ivop | 0:7a91348b4a02 | 107 | |
Ivop | 0:7a91348b4a02 | 108 | static inline int fl_pll1_get_P(void) { |
Ivop | 0:7a91348b4a02 | 109 | return (*FL_PLL1STAT >> 5) & 3; |
Ivop | 0:7a91348b4a02 | 110 | } |
Ivop | 0:7a91348b4a02 | 111 | |
Ivop | 0:7a91348b4a02 | 112 | static inline int fl_pll1_get_enable(void) { |
Ivop | 0:7a91348b4a02 | 113 | return *FL_PLL1STAT & (1U<<8); |
Ivop | 0:7a91348b4a02 | 114 | } |
Ivop | 0:7a91348b4a02 | 115 | |
Ivop | 0:7a91348b4a02 | 116 | static inline int fl_pll1_get_connect(void) { |
Ivop | 0:7a91348b4a02 | 117 | return *FL_PLL1STAT & (1U<<9); |
Ivop | 0:7a91348b4a02 | 118 | } |
Ivop | 0:7a91348b4a02 | 119 | |
Ivop | 0:7a91348b4a02 | 120 | static inline int fl_pll1_get_lock(void) { |
Ivop | 0:7a91348b4a02 | 121 | return *FL_PLL1STAT & (1U<<10); |
Ivop | 0:7a91348b4a02 | 122 | } |
Ivop | 0:7a91348b4a02 | 123 | |
Ivop | 0:7a91348b4a02 | 124 | static inline void fl_pll1_feed(void) { |
Ivop | 0:7a91348b4a02 | 125 | *FL_PLL1FEED = 0xaa; |
Ivop | 0:7a91348b4a02 | 126 | *FL_PLL1FEED = 0x55; |
Ivop | 0:7a91348b4a02 | 127 | } |
Ivop | 0:7a91348b4a02 | 128 | |
Ivop | 0:7a91348b4a02 | 129 | /* PLL0 output --> CPU Clock */ |
Ivop | 0:7a91348b4a02 | 130 | |
Ivop | 0:7a91348b4a02 | 131 | /* CPU clock must be at least 18MHz for USB to function */ |
Ivop | 0:7a91348b4a02 | 132 | |
Ivop | 0:7a91348b4a02 | 133 | /* div: 3-256 */ |
Ivop | 0:7a91348b4a02 | 134 | static inline void fl_set_cpu_clock_divider(const int div) { |
Ivop | 0:7a91348b4a02 | 135 | *FL_CCLKCFG = div - 1; |
Ivop | 0:7a91348b4a02 | 136 | } |
Ivop | 0:7a91348b4a02 | 137 | |
Ivop | 0:7a91348b4a02 | 138 | static inline int fl_get_cpu_clock_divider(void) { |
Ivop | 0:7a91348b4a02 | 139 | return *FL_CCLKCFG + 1; |
Ivop | 0:7a91348b4a02 | 140 | } |
Ivop | 0:7a91348b4a02 | 141 | |
Ivop | 0:7a91348b4a02 | 142 | /* use only if USBPLL/PLL1 is not connected */ |
Ivop | 0:7a91348b4a02 | 143 | /* div: 1-16 (only 6, 8 and 10 produce even number multiples */ |
Ivop | 0:7a91348b4a02 | 144 | static inline void fl_set_pll0_usb_divider(const unsigned int div) { |
Ivop | 0:7a91348b4a02 | 145 | *FL_USBCLKCFG = div - 1; |
Ivop | 0:7a91348b4a02 | 146 | } |
Ivop | 0:7a91348b4a02 | 147 | |
Ivop | 0:7a91348b4a02 | 148 | static inline int fl_get_pll0_usb_divider(void) { |
Ivop | 0:7a91348b4a02 | 149 | return *FL_USBCLKCFG + 1; |
Ivop | 0:7a91348b4a02 | 150 | } |
Ivop | 0:7a91348b4a02 | 151 | |
Ivop | 0:7a91348b4a02 | 152 | #define FL_CLOCK_DIV4 0 |
Ivop | 0:7a91348b4a02 | 153 | #define FL_CLOCK_DIV1 1 |
Ivop | 0:7a91348b4a02 | 154 | #define FL_CLOCK_DIV2 2 |
Ivop | 0:7a91348b4a02 | 155 | #define FL_CLOCK_DIV8 3 |
Ivop | 0:7a91348b4a02 | 156 | |
Ivop | 0:7a91348b4a02 | 157 | #define FL_SELECT_CLOCK(peripheral, reg, pos) \ |
Ivop | 0:7a91348b4a02 | 158 | static inline void fl_select_clock_##peripheral(const unsigned int clock) { \ |
Ivop | 0:7a91348b4a02 | 159 | *reg &= ~(3U << pos); \ |
Ivop | 0:7a91348b4a02 | 160 | *reg |= clock << pos; \ |
Ivop | 0:7a91348b4a02 | 161 | } |
Ivop | 0:7a91348b4a02 | 162 | |
Ivop | 0:7a91348b4a02 | 163 | FL_SELECT_CLOCK(wdt, FL_PCLKSEL0, 0) |
Ivop | 0:7a91348b4a02 | 164 | FL_SELECT_CLOCK(timer0, FL_PCLKSEL0, 2) |
Ivop | 0:7a91348b4a02 | 165 | FL_SELECT_CLOCK(timer1, FL_PCLKSEL0, 4) |
Ivop | 0:7a91348b4a02 | 166 | FL_SELECT_CLOCK(uart0, FL_PCLKSEL0, 6) |
Ivop | 0:7a91348b4a02 | 167 | FL_SELECT_CLOCK(uart1, FL_PCLKSEL0, 8) |
Ivop | 0:7a91348b4a02 | 168 | FL_SELECT_CLOCK(pwm1, FL_PCLKSEL0, 12) |
Ivop | 0:7a91348b4a02 | 169 | FL_SELECT_CLOCK(i2c0, FL_PCLKSEL0, 14) |
Ivop | 0:7a91348b4a02 | 170 | FL_SELECT_CLOCK(spi, FL_PCLKSEL0, 16) |
Ivop | 0:7a91348b4a02 | 171 | FL_SELECT_CLOCK(ssp1, FL_PCLKSEL0, 20) |
Ivop | 0:7a91348b4a02 | 172 | FL_SELECT_CLOCK(dac, FL_PCLKSEL0, 22) |
Ivop | 0:7a91348b4a02 | 173 | FL_SELECT_CLOCK(adc, FL_PCLKSEL0, 24) |
Ivop | 0:7a91348b4a02 | 174 | FL_SELECT_CLOCK(can1, FL_PCLKSEL0, 26) |
Ivop | 0:7a91348b4a02 | 175 | FL_SELECT_CLOCK(can2, FL_PCLKSEL0, 28) |
Ivop | 0:7a91348b4a02 | 176 | FL_SELECT_CLOCK(acf, FL_PCLKSEL0, 30) |
Ivop | 0:7a91348b4a02 | 177 | |
Ivop | 0:7a91348b4a02 | 178 | FL_SELECT_CLOCK(qei, FL_PCLKSEL1, 0) |
Ivop | 0:7a91348b4a02 | 179 | FL_SELECT_CLOCK(gpioint, FL_PCLKSEL1, 2) |
Ivop | 0:7a91348b4a02 | 180 | FL_SELECT_CLOCK(pcb, FL_PCLKSEL1, 4) |
Ivop | 0:7a91348b4a02 | 181 | FL_SELECT_CLOCK(i2c1, FL_PCLKSEL1, 6) |
Ivop | 0:7a91348b4a02 | 182 | FL_SELECT_CLOCK(ssp0, FL_PCLKSEL1, 10) |
Ivop | 0:7a91348b4a02 | 183 | FL_SELECT_CLOCK(timer2, FL_PCLKSEL1, 12) |
Ivop | 0:7a91348b4a02 | 184 | FL_SELECT_CLOCK(timer3, FL_PCLKSEL1, 14) |
Ivop | 0:7a91348b4a02 | 185 | FL_SELECT_CLOCK(uart2, FL_PCLKSEL1, 16) |
Ivop | 0:7a91348b4a02 | 186 | FL_SELECT_CLOCK(uart3, FL_PCLKSEL1, 18) |
Ivop | 0:7a91348b4a02 | 187 | FL_SELECT_CLOCK(i2c2, FL_PCLKSEL1, 20) |
Ivop | 0:7a91348b4a02 | 188 | FL_SELECT_CLOCK(i2s, FL_PCLKSEL1, 22) |
Ivop | 0:7a91348b4a02 | 189 | FL_SELECT_CLOCK(rit, FL_PCLKSEL1, 26) |
Ivop | 0:7a91348b4a02 | 190 | FL_SELECT_CLOCK(syscon, FL_PCLKSEL1, 28) |
Ivop | 0:7a91348b4a02 | 191 | FL_SELECT_CLOCK(mcpwm, FL_PCLKSEL1, 30) |
Ivop | 0:7a91348b4a02 | 192 | |
Ivop | 0:7a91348b4a02 | 193 | #define FL_CLOCK_OUT_CPU 0 |
Ivop | 0:7a91348b4a02 | 194 | #define FL_CLOCK_OUT_MAIN 1 |
Ivop | 0:7a91348b4a02 | 195 | #define FL_CLOCK_OUT_IRC 2 |
Ivop | 0:7a91348b4a02 | 196 | #define FL_CLOCK_OUT_USB 3 |
Ivop | 0:7a91348b4a02 | 197 | #define FL_CLOCK_OUT_RTC 4 |
Ivop | 0:7a91348b4a02 | 198 | |
Ivop | 0:7a91348b4a02 | 199 | static inline void fl_set_output_clock(const int clock) { |
Ivop | 0:7a91348b4a02 | 200 | *FL_CLKOUTCFG = clock; |
Ivop | 0:7a91348b4a02 | 201 | } |
Ivop | 0:7a91348b4a02 | 202 | |
Ivop | 0:7a91348b4a02 | 203 | #endif |