aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/rcc.c
diff options
context:
space:
mode:
authorMichael Hope <michael.hope@linaro.org>2010-09-29 20:45:57 +1300
committerMichael Hope <michael.hope@linaro.org>2010-09-29 20:45:57 +1300
commit6fcd4cd306dbecf56f5b0b506a3c23762d1219fa (patch)
tree467125eca5a2e6706001cad8e09bc475e58a12d9 /libmaple/rcc.c
parent368e4fc1662c2594b2a0908900713a2555a3ed8e (diff)
parentadde11b099ff5dad176e410279d21feac39d2c7e (diff)
downloadlibrambutan-6fcd4cd306dbecf56f5b0b506a3c23762d1219fa.tar.gz
librambutan-6fcd4cd306dbecf56f5b0b506a3c23762d1219fa.zip
Merge remote branch 'upstream/master'
Diffstat (limited to 'libmaple/rcc.c')
-rw-r--r--libmaple/rcc.c190
1 files changed, 93 insertions, 97 deletions
diff --git a/libmaple/rcc.c b/libmaple/rcc.c
index 9bd2663..582e9a9 100644
--- a/libmaple/rcc.c
+++ b/libmaple/rcc.c
@@ -1,4 +1,4 @@
-/* *****************************************************************************
+/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
@@ -20,11 +20,11 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
- * ****************************************************************************/
+ *****************************************************************************/
/**
- * @brief Implements pretty much only the basic clock setup on the stm32,
- * clock enable/disable and peripheral reset commands.
+ * @brief Implements pretty much only the basic clock setup on the
+ * stm32, clock enable/disable and peripheral reset commands.
*/
#include "libmaple.h"
@@ -32,139 +32,135 @@
#include "rcc.h"
enum {
- APB1,
- APB2,
- AHB
+ APB1,
+ APB2,
+ AHB
};
struct rcc_dev_info {
- const uint8 clk_domain;
- const uint8 line_num;
+ const uint8 clk_domain;
+ const uint8 line_num;
};
/* device descriptor tables */
static const struct rcc_dev_info rcc_dev_table[] = {
- [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 },
- [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 },
- [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 },
- [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 },
- [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, // High-density devices only
- [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, // High-density devices only
- [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, // High-density devices only
- [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 },
- [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 },
- [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 },
- [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 },
- [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 },
- [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 },
- [RCC_USART4] = { .clk_domain = APB1, .line_num = 19 }, // High-density devices only
- [RCC_USART5] = { .clk_domain = APB1, .line_num = 20 }, // High-density devices only
- [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 },
- [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 },
- [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 },
- [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 },
- [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, // High-density devices only
- [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, // High-density devices only
- [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, // High-density devices only
- [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, // High-density devices only
- [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 },
- [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 },
- [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, // High-density devices only
- [RCC_DAC] = { .clk_domain = APB1, .line_num = 9 }, // High-density devices only
+ [RCC_GPIOA] = { .clk_domain = APB2, .line_num = 2 },
+ [RCC_GPIOB] = { .clk_domain = APB2, .line_num = 3 },
+ [RCC_GPIOC] = { .clk_domain = APB2, .line_num = 4 },
+ [RCC_GPIOD] = { .clk_domain = APB2, .line_num = 5 },
+ [RCC_GPIOE] = { .clk_domain = APB2, .line_num = 6 }, // High-density only
+ [RCC_GPIOF] = { .clk_domain = APB2, .line_num = 7 }, // High-density only
+ [RCC_GPIOG] = { .clk_domain = APB2, .line_num = 8 }, // High-density only
+ [RCC_AFIO] = { .clk_domain = APB2, .line_num = 0 },
+ [RCC_ADC1] = { .clk_domain = APB2, .line_num = 9 },
+ [RCC_ADC2] = { .clk_domain = APB2, .line_num = 10 },
+ [RCC_USART1] = { .clk_domain = APB2, .line_num = 14 },
+ [RCC_USART2] = { .clk_domain = APB1, .line_num = 17 },
+ [RCC_USART3] = { .clk_domain = APB1, .line_num = 18 },
+ [RCC_USART4] = { .clk_domain = APB1, .line_num = 19 }, // High-density only
+ [RCC_USART5] = { .clk_domain = APB1, .line_num = 20 }, // High-density only
+ [RCC_TIMER1] = { .clk_domain = APB2, .line_num = 11 },
+ [RCC_TIMER2] = { .clk_domain = APB1, .line_num = 0 },
+ [RCC_TIMER3] = { .clk_domain = APB1, .line_num = 1 },
+ [RCC_TIMER4] = { .clk_domain = APB1, .line_num = 2 },
+ [RCC_TIMER5] = { .clk_domain = APB1, .line_num = 3 }, // High-density only
+ [RCC_TIMER6] = { .clk_domain = APB1, .line_num = 4 }, // High-density only
+ [RCC_TIMER7] = { .clk_domain = APB1, .line_num = 5 }, // High-density only
+ [RCC_TIMER8] = { .clk_domain = APB2, .line_num = 13 }, // High-density only
+ [RCC_SPI1] = { .clk_domain = APB2, .line_num = 12 },
+ [RCC_SPI2] = { .clk_domain = APB1, .line_num = 14 },
+ [RCC_FSMC] = { .clk_domain = AHB, .line_num = 8 }, // High-density only
+ [RCC_DAC] = { .clk_domain = APB1, .line_num = 9 }, // High-density only
};
/**
* @brief Initialize the clock control system. Initializes the system
- * clock source to use the PLL driven by an external oscillator
+ * clock source to use the PLL driven by an external oscillator
* @param sysclk_src system clock source, must be PLL
* @param pll_src pll clock source, must be HSE
* @param pll_mul pll multiplier
*/
void rcc_clk_init(uint32 sysclk_src, uint32 pll_src, uint32 pll_mul) {
- /* Assume that we're going to clock the chip off the PLL, fed by
- * the HSE */
- ASSERT(sysclk_src == RCC_CLKSRC_PLL &&
- pll_src == RCC_PLLSRC_HSE);
-
- uint32 cfgr = 0;
- uint32 cr = RCC_READ_CR();
-
- cfgr = (pll_src | pll_mul);
- RCC_WRITE_CFGR(cfgr);
-
- /* Turn on the HSE */
- cr |= RCC_CR_HSEON;
- RCC_WRITE_CR(cr);
- while (!(RCC_READ_CR() & RCC_CR_HSERDY))
- ;
-
- /* Now the PLL */
- cr |= RCC_CR_PLLON;
- RCC_WRITE_CR(cr);
- while (!(RCC_READ_CR() & RCC_CR_PLLRDY))
- ;
-
- /* Finally, let's switch over to the PLL */
- cfgr &= ~RCC_CFGR_SW;
- cfgr |= RCC_CFGR_SW_PLL;
- RCC_WRITE_CFGR(cfgr);
- while ((RCC_READ_CFGR() & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
- ;
+ /* Assume that we're going to clock the chip off the PLL, fed by
+ * the HSE */
+ ASSERT(sysclk_src == RCC_CLKSRC_PLL &&
+ pll_src == RCC_PLLSRC_HSE);
+
+ uint32 cfgr = 0;
+ uint32 cr = RCC_READ_CR();
+
+ cfgr = (pll_src | pll_mul);
+ RCC_WRITE_CFGR(cfgr);
+
+ /* Turn on the HSE */
+ cr |= RCC_CR_HSEON;
+ RCC_WRITE_CR(cr);
+ while (!(RCC_READ_CR() & RCC_CR_HSERDY))
+ ;
+
+ /* Now the PLL */
+ cr |= RCC_CR_PLLON;
+ RCC_WRITE_CR(cr);
+ while (!(RCC_READ_CR() & RCC_CR_PLLRDY))
+ ;
+
+ /* Finally, let's switch over to the PLL */
+ cfgr &= ~RCC_CFGR_SW;
+ cfgr |= RCC_CFGR_SW_PLL;
+ RCC_WRITE_CFGR(cfgr);
+ while ((RCC_READ_CFGR() & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL)
+ ;
}
-
-
/**
* @brief Turn on the clock line on a device
* @param dev_num device to turn on
*/
void rcc_clk_enable(uint32 dev_num) {
- static const uint32 enable_regs[] = {
- [APB1] = RCC_APB1ENR,
- [APB2] = RCC_APB2ENR,
- [AHB] = RCC_AHBENR,
- };
+ static const uint32 enable_regs[] = {
+ [APB1] = RCC_APB1ENR,
+ [APB2] = RCC_APB2ENR,
+ [AHB] = RCC_AHBENR,
+ };
- uint8 clk_domain = rcc_dev_table[dev_num].clk_domain;
+ uint8 clk_domain = rcc_dev_table[dev_num].clk_domain;
- __set_bits(enable_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
+ __set_bits(enable_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
}
-
/**
* @brief Set the divider on a device prescaler
* @param prescaler prescaler to set
* @param divider prescaler divider
*/
void rcc_set_prescaler(uint32 prescaler, uint32 divider) {
- static const uint32 masks[] = {
- [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE,
- [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1,
- [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2,
- [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE,
- [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE,
- };
-
- uint32 cfgr = RCC_READ_CFGR();
-
- cfgr &= ~masks[prescaler];
- cfgr |= divider;
- RCC_WRITE_CFGR(cfgr);
+ static const uint32 masks[] = {
+ [RCC_PRESCALER_AHB] = RCC_CFGR_HPRE,
+ [RCC_PRESCALER_APB1] = RCC_CFGR_PPRE1,
+ [RCC_PRESCALER_APB2] = RCC_CFGR_PPRE2,
+ [RCC_PRESCALER_USB] = RCC_CFGR_USBPRE,
+ [RCC_PRESCALER_ADC] = RCC_CFGR_ADCPRE,
+ };
+
+ uint32 cfgr = RCC_READ_CFGR();
+
+ cfgr &= ~masks[prescaler];
+ cfgr |= divider;
+ RCC_WRITE_CFGR(cfgr);
}
-
/**
* @brief reset a device
* @param dev_num device to reset
*/
void rcc_reset_dev(uint32 dev_num) {
- static const uint32 reset_regs[] = {
- [APB1] = RCC_APB1RSTR,
- [APB2] = RCC_APB2RSTR,
- };
+ static const uint32 reset_regs[] = {
+ [APB1] = RCC_APB1RSTR,
+ [APB2] = RCC_APB2RSTR,
+ };
- uint8 clk_domain = rcc_dev_table[dev_num].clk_domain;
+ uint8 clk_domain = rcc_dev_table[dev_num].clk_domain;
- __set_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
- __clear_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
+ __set_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
+ __clear_bits(reset_regs[clk_domain], BIT(rcc_dev_table[dev_num].line_num));
}