diff options
-rw-r--r-- | system-clock/include/clock.h | 124 | ||||
-rw-r--r-- | system-clock/include/common.h | 1 | ||||
-rw-r--r-- | system-clock/include/flash.h | 20 | ||||
-rw-r--r-- | system-clock/include/rcc.h | 82 | ||||
-rw-r--r-- | system-clock/include/spin.h | 2 | ||||
-rw-r--r-- | system-clock/src/clock.c | 230 | ||||
-rw-r--r-- | system-clock/src/gpio.c | 5 | ||||
-rw-r--r-- | system-clock/src/main.c | 34 | ||||
-rw-r--r-- | system-clock/src/spin.c | 27 |
9 files changed, 339 insertions, 186 deletions
diff --git a/system-clock/include/clock.h b/system-clock/include/clock.h index 2ba6880..98574d1 100644 --- a/system-clock/include/clock.h +++ b/system-clock/include/clock.h @@ -2,10 +2,10 @@ #define CLOCK_H__ #include <stdint.h> +#include "rcc.h" #define PERIPH_BASE ((uint32_t) 0x40000000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000) -#define RCC_BASE (AHBPERIPH_BASE + 0x00001000) #define FLASH_R_BASE (AHBPERIPH_BASE + 0x00003C00) #define PWR_BASE (PERIPH_BASE + 0x7000) #define PWR_CSR_VOSF ((uint16_t)0x0010) /*!< Voltage Scaling select flag */ @@ -20,42 +20,102 @@ typedef struct { __IO uint32_t csr; } pwr_t; -typedef struct { - __IO uint32_t acr; - __IO uint32_t pecr; - __IO uint32_t pdkeyr; - __IO uint32_t pekeyr; - __IO uint32_t prgkeyr; - __IO uint32_t optkeyr; - __IO uint32_t sr; - __IO uint32_t obr; - __IO uint32_t wrpr; -} flash_t; +// typedef struct { +// __IO uint32_t acr; +// __IO uint32_t pecr; +// __IO uint32_t pdkeyr; +// __IO uint32_t pekeyr; +// __IO uint32_t prgkeyr; +// __IO uint32_t optkeyr; +// __IO uint32_t sr; +// __IO uint32_t obr; +// __IO uint32_t wrpr; +// } flash_t; -typedef struct { - __IO uint32_t cr; - __IO uint32_t icscr; - __IO uint32_t cfgr; - __IO uint32_t cir; - __IO uint32_t ahbrstr; - __IO uint32_t apb2rstr; - __IO uint32_t apb1rstr; - __IO uint32_t ahbenr; - __IO uint32_t apb2enr; - __IO uint32_t apb1enr; - __IO uint32_t ahblpenr; - __IO uint32_t apb2lpenr; - __IO uint32_t apb1lpenr; - __IO uint32_t csr; -} rcc_t; - -#define RCC (*(rcc_t*) (RCC_BASE)) -#define FLASH (*(flash_t*) (FLASH_R_BASE)) +// #define FLASH (*(flash_t*) (FLASH_R_BASE)) #define PWR (*(pwr_t*) (PWR_BASE)) + +/* Valid values for the PLLR/PLLQ bits of the PLLCFG register. */ +typedef enum { + PLL_DIVISOR_2 = 1, + PLL_DIVISOR_4 = 3, + PLL_DIVISOR_6 = 5, + PLL_DIVISOR_8 = 7, + PLL_DIVISOR_OFF = 0, +} pll_divisor_t; + +/* Valid values for the PLLP bits off the PLLCFG register. */ +typedef enum { + PLLP_DIVISOR_7 = 1, + PLLP_DIVISOR_17 = 3, + PLLP_DIVISOR_OFF = 0, +} pllp_divisor_t; + +/* Valid values for the PLLM bits of the PLLCFG register. */ +typedef enum { + PLLM_DIVISOR_1 = 0, + PLLM_DIVISOR_2 = 1, + PLLM_DIVISOR_3 = 2, + PLLM_DIVISOR_4 = 3, + PLLM_DIVISOR_5 = 4, + PLLM_DIVISOR_6 = 5, + PLLM_DIVISOR_7 = 6, + PLLM_DIVISOR_8 = 7, +} pllm_divisor_t; + +/* Possible sources for the input clock. */ +typedef enum { + PLL_SRC_NONE = 0, + PLL_SRC_MSI = 1, + PLL_SRC_HSI = 2, + PLL_SRC_HSE = 3, +} pll_src_t; + +/* Valid sources for the system clock. */ +typedef enum { + SYSTEM_CLOCK_SRC_MSI = 0, + SYSTEM_CLOCK_SRC_HSI = 1, + SYSTEM_CLOCK_SRC_HSE = 2, + SYSTEM_CLOCK_SRC_PLL = 3, +} system_clock_src_t; + +#define E_BADPLLN (-2) +#define E_BADPLLP_DIV (-1) +#define E_TIMEOUT (-3) +#define E_NOT_OFF (-4) +#define E_BAD_ARG (-5) + /* * Sets the system clock to a full 80Mhz. */ -int set_sys_clock(); +int set_system_clock_MHz(uint8_t mhz); + +/* + * Set the PLL on. + */ +int pll_on(); + +/* + * Set the PLL off. + */ +int pll_off(); + +/* + * Sets the source of the system clock. + */ +int set_system_clock_src(system_clock_src_t src); + +/* + * Configure the PLL. + */ +int configure_pll( + uint8_t pllp_div_factor, + pll_divisor_t pllr, /* System clock divisor. */ + pll_divisor_t pllq, /* Divison factor for PLL48M1CLK. */ + pllp_divisor_t pllp, /* Divison factor for PLLSAI2CLK. */ + uint8_t plln, /* PLL numerator. */ + pllm_divisor_t pllm, /* PLL denominator. */ + pll_src_t pllsrc /* PLL source */ ); #endif /* CLOCK_H__ */ diff --git a/system-clock/include/common.h b/system-clock/include/common.h index f58f179..6fc701c 100644 --- a/system-clock/include/common.h +++ b/system-clock/include/common.h @@ -9,5 +9,6 @@ #define bool int #define PACKED __attribute__((packed)) +#define BIT(n) (1 << (n)) #endif /* COMMON_H */ diff --git a/system-clock/include/flash.h b/system-clock/include/flash.h new file mode 100644 index 0000000..ac63bf9 --- /dev/null +++ b/system-clock/include/flash.h @@ -0,0 +1,20 @@ +#ifndef H__FLASH_ +#define H__FLASH_ + +#include "common.h" + +/* + * Header file for dealing with flash. + */ + +#define FLASH_BASE 0x40022000 + +typedef struct { + __IO uint32_t ac_r; /* Flash access control register. */ + + /* TODO fill out the rest. */ +} PACKED flash_t; + +#define FLASH (*(__IO flash_t*) FLASH_BASE) + +#endif /* H__FLASH_ */ diff --git a/system-clock/include/rcc.h b/system-clock/include/rcc.h new file mode 100644 index 0000000..4206dc1 --- /dev/null +++ b/system-clock/include/rcc.h @@ -0,0 +1,82 @@ +#ifndef H__RCC_ +#define H__RCC_ + +#include "common.h" + +#define RCC_BASE ((uint32_t) 0x40021000) + +typedef struct { + __IO uint32_t c_r; /* Clock control register. 0x00 */ + __IO uint32_t icsc_r; /* Internal clock srcs calibration register. 0x04 */ + __IO uint32_t cfg_r; /* clock confguration register. 0x08 */ + __IO uint32_t pllcfg_r; /* PLL Configuration register. 0x0c */ + __IO uint32_t pllsai1cfg_r; /* PLLSAI1 configuration register. 0x10 */ + + __IO uint32_t reserved_1; /* Not used. offset 0x14. */ + + __IO uint32_t cie_r; /* Clock interrupt enable register. 0x18 */ + __IO uint32_t cif_r; /* Clock interrupt flag regiseter. 0x1c */ + __IO uint32_t cic_r; /* Clock interrupt clear register. 0x20 */ + + __IO uint32_t reserved_2; /* Not used. offset 0x24. */ + + __IO uint32_t ahb1rst_r; /* AHB Peripheral 1 reset register. 0x28 */ + __IO uint32_t ahb2rst_r; /* AHB Peripheral 2 reset register. 0x2c */ + __IO uint32_t ahb3rst_r; /* AHB Peripheral 3 reset register. 0x30 */ + + __IO uint32_t reserved_3; /* Not used. offset 0x34. */ + + __IO uint32_t abp1rst1_r; /* APB Peripheral reset register 1. 0x38 */ + __IO uint32_t abp1rst2_r; /* APB Peripheral reset register 2. 0x3C */ + __IO uint32_t abp2rst_r; /* APB Peripheral reset register. 0x40 */ + + __IO uint32_t reserved_4; /* Not used. offset 0x44. */ + + __IO uint32_t ahb1en_r; /* AHB1 Peripheral enable register. 0x48 */ + __IO uint32_t ahb2en_r; /* AHB2 Peripheral enable register. 0x4C */ + __IO uint32_t ahb3en_r; /* AHB3 Peripheral enable register. 0x50 */ + + __IO uint32_t reserved_5; /* Not used. offset 0x54. */ + + __IO uint32_t apb1en1_r; /* APB1 Peripheral enable register 1. 0x58 */ + __IO uint32_t apb1en2_r; /* APB1 Peripheral enable register 2. 0x5C */ + __IO uint32_t apb2en_r; /* APB2 Peripheral enable register. 0x60 */ + + __IO uint32_t reserved_6; /* Not used. offset 0x64. */ + + /* TODO add the rest starting at offset 0x68. */ + +} PACKED rcc_t; + +#define RCC (*(__IO rcc_t*) RCC_BASE) + +/* Macros to operate on the RCC registers. */ + +/* Sets the HSE. rcc is the RCC to use, e is zero for off, non-zero for on. */ +#define set_hse(rcc, e) do \ +{ \ + if (e) { \ + (rcc).c_r |= 1 << 16; \ + } else { \ + (rcc).c_r &= ~(1 << 16); \ + } \ +} while(0) + +/* Sets the HSI. rcc is the RCC to use, e is zero for off, non-zero for on. */ +#define set_hsi(rcc, e) do \ +{ \ + if (e) { \ + (rcc).c_r |= 1 << 8; \ + } else { \ + (rcc).c_r &= ~(1 << 8); \ + } \ +} while(0) + + +/* Checks to see if the hse is ready. */ +#define hse_ready(rcc) ((rcc).c_r & (1 << 17)) + +/* Checks to see if the hse is ready. */ +#define hsi_ready(rcc) ((rcc).c_r & (1 << 10)) + +#endif diff --git a/system-clock/include/spin.h b/system-clock/include/spin.h index a920847..a88d2f8 100644 --- a/system-clock/include/spin.h +++ b/system-clock/include/spin.h @@ -10,7 +10,7 @@ * is a 0. Each independent flashing is succeced by a break of 4 times that * of a long flash. */ -void spin(uint8_t code); +void spin(uint32_t base_delay, uint8_t code); diff --git a/system-clock/src/clock.c b/system-clock/src/clock.c index b846ceb..ec12240 100644 --- a/system-clock/src/clock.c +++ b/system-clock/src/clock.c @@ -3,147 +3,149 @@ */ #include "clock.h" +#include "gpio.h" +#include "spin.h" +#include "flash.h" #include <stdint.h> -#define RCC_CR_HSERDY ((uint32_t)0x00020000) /* High-speed clock ready? */ -#define RCC_CR_HSEON ((uint32_t)0x00020000) /*!< External High Speed clock ready flag */ - -#define FLASH_ACR_LATENCY ((uint32_t)0x00000001) /*!< Latency */ -#define FLASH_ACR_PRFTEN ((uint32_t)0x00000002) /*!< Prefetch Buffer Enable */ -#define FLASH_ACR_ACC64 ((uint32_t)0x00000004) /*!< Access 64 bits */ - -#define RCC_APB1ENR_PWREN ((uint32_t)0x10000000) /*!< Power interface clock enable */ -#define PWR_CR_VOS_0 ((uint16_t)0x0800) /*!< Bit 0 */ - -/*!< HPRE configuration */ -#define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x00000000) /*!< SYSCLK not divided */ -#define RCC_CFGR_HPRE_DIV2 ((uint32_t)0x00000080) /*!< SYSCLK divided by 2 */ -#define RCC_CFGR_HPRE_DIV4 ((uint32_t)0x00000090) /*!< SYSCLK divided by 4 */ -#define RCC_CFGR_HPRE_DIV8 ((uint32_t)0x000000A0) /*!< SYSCLK divided by 8 */ -#define RCC_CFGR_HPRE_DIV16 ((uint32_t)0x000000B0) /*!< SYSCLK divided by 16 */ -#define RCC_CFGR_HPRE_DIV64 ((uint32_t)0x000000C0) /*!< SYSCLK divided by 64 */ -#define RCC_CFGR_HPRE_DIV128 ((uint32_t)0x000000D0) /*!< SYSCLK divided by 128 */ -#define RCC_CFGR_HPRE_DIV256 ((uint32_t)0x000000E0) /*!< SYSCLK divided by 256 */ -#define RCC_CFGR_HPRE_DIV512 ((uint32_t)0x000000F0) /*!< SYSCLK divided by 512 */ - -#define RCC_CFGR_PPRE1 ((uint32_t)0x00000700) /*!< PRE1[2:0] bits (APB1 prescaler) */ -#define RCC_CFGR_PPRE1_0 ((uint32_t)0x00000100) /*!< Bit 0 */ -#define RCC_CFGR_PPRE1_1 ((uint32_t)0x00000200) /*!< Bit 1 */ -#define RCC_CFGR_PPRE1_2 ((uint32_t)0x00000400) /*!< Bit 2 */ - -/*!< PPRE1 configuration */ -#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */ -#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */ - -#define RCC_CFGR_PPRE2 ((uint32_t)0x00003800) /*!< PRE2[2:0] bits (APB2 prescaler) */ -#define RCC_CFGR_PPRE2_0 ((uint32_t)0x00000800) /*!< Bit 0 */ -#define RCC_CFGR_PPRE2_1 ((uint32_t)0x00001000) /*!< Bit 1 */ -#define RCC_CFGR_PPRE2_2 ((uint32_t)0x00002000) /*!< Bit 2 */ - -/*!< PPRE2 configuration */ -#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */ -#define RCC_CFGR_PPRE2_DIV2 ((uint32_t)0x00002000) /*!< HCLK divided by 2 */ -#define RCC_CFGR_PPRE2_DIV4 ((uint32_t)0x00002800) /*!< HCLK divided by 4 */ -#define RCC_CFGR_PPRE2_DIV8 ((uint32_t)0x00003000) /*!< HCLK divided by 8 */ -#define RCC_CFGR_PPRE2_DIV16 ((uint32_t)0x00003800) /*!< HCLK divided by 16 */ -#define RCC_CFGR_PLLMUL ((uint32_t)0x003C0000) /*!< PLLMUL[3:0] bits (PLL multiplication factor) */ -#define RCC_CFGR_PLLDIV ((uint32_t)0x00C00000) /*!< PLLDIV[1:0] bits (PLL Output Division) */ - -#define RCC_CFGR_PLLSRC ((uint32_t)0x00010000) /*!< PLL entry clock source */ -#define RCC_CFGR_PLLSRC_HSE ((uint32_t)0x00010000) /*!< HSE as PLL entry clock source */ -#define RCC_CFGR_PLLMUL8 ((uint32_t)0x000C0000) /*!< PLL input clock * 8 */ -#define RCC_CFGR_PLLDIV2 ((uint32_t)0x00400000) /*!< PLL clock output = CKVCO / 2 */ -#define RCC_CR_PLLON ((uint32_t)0x01000000) /*!< PLL enable */ -#define RCC_CR_PLLRDY ((uint32_t)0x02000000) /*!< PLL clock ready flag */ -#define RCC_CFGR_SW ((uint32_t)0x00000003) /*!< SW[1:0] bits (System clock Switch) */ -#define RCC_CFGR_SW_PLL ((uint32_t)0x00000003) /*!< PLL selected as system clock */ -#define RCC_CFGR_SWS ((uint32_t)0x0000000C) /*!< SWS[1:0] bits (System Clock Switch Status) */ -#define RCC_CFGR_SWS_PLL ((uint32_t)0x0000000C) /*!< PLL used as system clock */ - -inline int is_hse_ready() +#define TIMEOUT 10000 + +int pll_off() { - return RCC.cr & RCC_CR_HSERDY; + uint32_t c; + + RCC.c_r &= ~BIT(24); /* Turn off pll. */ + for(c = 0; c < TIMEOUT && RCC.c_r & BIT(25); ++ c); /* Wait for OFF. */ + + if (c == TIMEOUT) { + return E_TIMEOUT; + } + + return 0; } -inline void hse_on() +int pll_on() { - RCC.cr |= RCC_CR_HSEON; + uint32_t c; + + RCC.c_r |= BIT(24); /* Turn on PLL. */ + for(c = 0; c < TIMEOUT && !(RCC.c_r & BIT(25)); ++ c); /* Wait for RDY. */ + + if (c == TIMEOUT) { + return E_TIMEOUT; + } + + return 0; } -#define TIMER 1000000 -int set_sys_clock() +int configure_pll( + uint8_t pllp_div_factor, + pll_divisor_t pllr, /* System clock divisor. */ + pll_divisor_t pllq, /* Divison factor for PLL48M1CLK. */ + pllp_divisor_t pllp, /* Divison factor for PLLSAI2CLK. */ + uint8_t plln, /* PLL numerator. */ + pllm_divisor_t pllm, /* PLL denominator. */ + pll_src_t pllsrc /* PLL source */ ) { - uint32_t c = 0; /* Time the PLL startup. */ + if (RCC.c_r & BIT(25)) { + /* PLL must be off to configure it. */ + return E_NOT_OFF; + } - /* Turn on the HSE */ - hse_on(); + /* Make sure inputs are valid. */ + if (pllp_div_factor == 1 || pllp_div_factor > 31) { + return E_BADPLLP_DIV; + } + if (plln < 8 || plln > 86) { + return E_BADPLLN; + } - /* Wait 'til ready, or if it takes tool long, (c == TIMER). */ - for (c = 0; !is_hse_ready() && c < TIMER; ++ c); + RCC.pllcfg_r = + (pllp_div_factor << 27) | + (pllr << 24) | + (pllq << 20) | + (pllp << 16) | + (plln << 8) | + (pllm << 4) | + (pllsrc << 0); - if (c == TIMER) { - /* The HSE never came up. That's not cool! */ - return -1; - } + return 0; +} + - /* The HSE came up, now we just need to set it to be the main clock. */ - /* Don't really know why we're touching the flash registers ... */ - FLASH.acr |= FLASH_ACR_ACC64; /* Enable 64-bit access. */ - FLASH.acr |= FLASH_ACR_PRFTEN; /* Enable prefetch buffer. */ - FLASH.acr |= FLASH_ACR_LATENCY; /* Flash 1 wait state. */ +int set_sys_clock_to_hsi() +{ + /* Turn on the HSI, and wait for it to come up. */ + RCC.c_r |= BIT(8); + while(RCC.c_r & BIT(9)); - RCC.apb1enr |= RCC_APB1ENR_PWREN; /* Enable power. */ - PWR.cr = PWR_CR_VOS_0; /* Set voltage to 1.8v. */ + /* Use the HSI. */ + RCC.cfg_r |= BIT(0); + return 0; +} - /* Wait for the vwoltage regulator to turn on. */ - for (c = 0; (PWR.csr & PWR_CSR_VOSF) && c < TIMER; ++ c); +int set_sys_clock_to_pll() +{ + RCC.c_r &= ~BIT(24); /* set PLL to OFF. */ - if (c == TIMER) { - /* Timeout occurred. */ - return -2; - } + RCC.pllcfg_r = + BIT(24) | /* Enable PLLR. This is for system clock output. */ + /* Set PLLM to 2 and PLLN to 10. This gives us a 10/2 multiplier. */ + (10 << 8) | /* Set PLLN to 10. */ + (0 << 4) | /* Set PLLM to 2. */ + /* Set the input to be HSI16. */ + BIT(1); - RCC.cfgr |= RCC_CFGR_HPRE_DIV1; /* HCLK = SYSCLK/1. */ - RCC.cfgr |= RCC_CFGR_PPRE2_DIV1; /* PCLK2 = HCLK/1 */ - RCC.cfgr |= RCC_CFGR_PPRE1_DIV1; /* PCLK1 = HCLK/1 */ - /* PLL Configuration */ - RCC.cfgr &= ~( - RCC_CFGR_PLLSRC | - RCC_CFGR_PLLMUL | - RCC_CFGR_PLLDIV ); + RCC.c_r |= BIT(24); /* Turn PLL on. */ + while(!(RCC.c_r & BIT(25))); /* Wait for PLL to be ready. */ - RCC.cfgr |= - RCC_CFGR_PLLSRC_HSE | - RCC_CFGR_PLLMUL8 | - RCC_CFGR_PLLDIV2; + /* Configure the flash to have 4 wait states. This is required at + * 80 MHz. */ + FLASH.ac_r &= ~0x07; + FLASH.ac_r |= 0x04; - /* Enable the PLL. */ - RCC.cr |= RCC_CR_PLLON; + /* Set the PLL as the system clock. */ + RCC.cfg_r = 0x3; +} - /* Wait for PLL to become ready. */ - for(c = 0; !(RCC.cr & RCC_CR_PLLRDY) && c < TIMER; ++ c); +int set_system_clock_MHz(uint8_t mhz) +{ + /* Set the source of the system colck to MSI temporarily. */ + set_system_clock_src(SYSTEM_CLOCK_SRC_MSI); - if (c == TIMER) { - /* Timeout occurred. */ - return -3; + if (mhz <= 8 || mhz > 80) { + return E_BAD_ARG; } - /* Set PLL as the system clock. */ - RCC.cfgr &= ~RCC_CFGR_SW; - RCC.cfgr |= RCC_CFGR_SW_PLL; + pll_off(); - /* Wait for PLL to be used as system clock. */ - for (c = 0; (RCC.cfgr & RCC_CFGR_SWS) != RCC_CFGR_SW_PLL && c < TIMER; ++ c); + configure_pll( + 0 /* pllp_div_factor */, + PLL_DIVISOR_4 /* pllr: VCO / 4 = mhz MHz. */, + PLL_DIVISOR_4 /* pllq: VCO / 4 = mhz MHz */, + PLLP_DIVISOR_7 /* pllp */, - if (c == TIMER) { - /* Timeout occurred. */ - return -4; - } + /* The following set the frequency of VCO to (mhz*4)MHz: mhz * 1 * 4MHz. */ + mhz /* plln | mhz */, + PLLM_DIVISOR_1 /* pllm | 01 */, + PLL_SRC_MSI /* pll src | 04 Mhz */); + + pll_on(); + + /* Configure the flash to have 4 wait states. This is required at + * 80 MHz. */ + FLASH.ac_r &= ~0x07; + FLASH.ac_r |= 0x04; + /* Set the source of the system colck to PLL. */ + set_system_clock_src(SYSTEM_CLOCK_SRC_PLL); return 0; } + +int set_system_clock_src(system_clock_src_t src) +{ + uint8_t value = RCC.cfg_r & ~0x03; + RCC.cfg_r = value | src; +} diff --git a/system-clock/src/gpio.c b/system-clock/src/gpio.c index ab3606d..f79f233 100644 --- a/system-clock/src/gpio.c +++ b/system-clock/src/gpio.c @@ -1,4 +1,5 @@ #include "gpio.h" +#include "rcc.h" /* * Sets the mode of a pin on a gpio por. @@ -38,11 +39,9 @@ void set_gpio_output_pin( } #define GPIO_PORTS_BASE_ADDR ((uint32_t)0x48000000) -#define RCC_BASE ((uint32_t)0x40021000) -#define RCC_AHB2ENR (*((__IO uint32_t*) (RCC_BASE + 0x4c))) __IO gpio_port_t* enable_gpio(gpio_port_number_t gpio_port_number) { - RCC_AHB2ENR |= 1 << gpio_port_number; /* Enable the port. */ + RCC.ahb2en_r |= 1 << gpio_port_number; /* Enable the GPIO port. */ return (__IO gpio_port_t*) (GPIO_PORTS_BASE_ADDR + (gpio_port_number * 0x400)); } diff --git a/system-clock/src/main.c b/system-clock/src/main.c index da4afd0..39f4a80 100644 --- a/system-clock/src/main.c +++ b/system-clock/src/main.c @@ -1,8 +1,9 @@ #include "gpio.h" #include "delay.h" #include "clock.h" +#include "spin.h" -volatile uint32_t delay_amt = 65535; +volatile uint32_t delay_amt = 20000000 / 4; /* Main function. This gets executed from the interrupt vector defined above. */ int main() @@ -14,35 +15,22 @@ int main() gpio_output_pin_t pin1 = set_gpio_pin_output(port_b, PIN_1); /* Enable a higher clock frequency. */ - set_sys_clock(); + set_system_clock_MHz(80); + uint32_t count = 0; while(1) { /* Set the GPIO pin to high. */ - pin_on(pin3); pin_off(pin1); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); + pin_off(pin3); delay(delay_amt); /* Set the GPIO pin to low. */ - pin_off(pin3); - pin_on(pin1); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); - delay(delay_amt); + if (count % 4 == 0) { + pin_on(pin1); + } + pin_on(pin3); delay(delay_amt); + + ++ count; } } diff --git a/system-clock/src/spin.c b/system-clock/src/spin.c index f233054..f17f678 100644 --- a/system-clock/src/spin.c +++ b/system-clock/src/spin.c @@ -6,20 +6,21 @@ #define LONG_DELAY (SHORT_DELAY * 2) static void flash_bit( + uint32_t base, gpio_output_pin_t out_pin, uint8_t bit /* 0 => 0, non-zero => 1 */) { pin_on(out_pin); if (bit) { - delay(LONG_DELAY); + delay(base * 2); } else { - delay(SHORT_DELAY); + delay(base); } pin_off(out_pin); - delay(SHORT_DELAY); + delay(base); } -void spin(uint8_t c) +void spin(uint32_t base, uint8_t c) { uint8_t code; __IO gpio_port_t* port_b = enable_gpio(GPIO_PORT_B); @@ -27,24 +28,24 @@ void spin(uint8_t c) for(;;) { code = c; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); code <<= 1; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); code <<= 1; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); code <<= 1; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); code <<= 1; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); code <<= 1; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); code <<= 1; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); code <<= 1; - flash_bit(pin3, code & 0x80); + flash_bit(base, pin3, code & 0x80); - delay(LONG_DELAY * 4); + delay(base * 4); } } |