diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 202 |
1 files changed, 202 insertions, 0 deletions
@@ -0,0 +1,202 @@ +/** \file main.c
+ * \brief Sample LPC1114 project
+ * \details This file holds a very basic code for LPC1114. This code configures
+ * flash access time, enables the PLL and all required clocks and peripherals
+ * to achieve the highest allowed frequency for LPC1114 (50MHz). Main code
+ * block just blinks the LED. The LED port and pin are defined in config.h
+ * file. Target core frequency and quartz crystal resonator frequency are
+ * defined there as well.
+ *
+ * \author Freddie Chopin, http://www.freddiechopin.info/
+ * \date 2012-01-08
+ */
+
+/******************************************************************************
+* project: lpc1114_blink_led
+* chip: LPC1114
+* compiler: arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
+*
+* prefix: (none)
+*
+* available global functions:
+* int main(void)
+*
+* available local functions:
+* static void flash_access_time(uint32_t frequency)
+* static uint32_t pll_start(uint32_t crystal, uint32_t frequency)
+* static void system_init(void)
+*
+* available interrupt handlers:
+******************************************************************************/
+
+/*
++=============================================================================+
+| includes
++=============================================================================+
+*/
+
+#include <stdint.h>
+
+#include "inc/LPC11xx.h"
+
+#include "config.h"
+
+#include "hdr/hdr_syscon.h"
+
+/*
++=============================================================================+
+| module variables
++=============================================================================+
+*/
+
+/*
++=============================================================================+
+| local functions' declarations
++=============================================================================+
+*/
+
+static void flash_access_time(uint32_t frequency);
+static uint32_t pll_start(uint32_t crystal, uint32_t frequency);
+static void system_init(void);
+
+/*
++=============================================================================+
+| global functions
++=============================================================================+
+*/
+
+/*------------------------------------------------------------------------*//**
+* \brief main code block
+* \details Call some static initialization functions and blink the led with
+* frequency defined via count_max variable.
+*//*-------------------------------------------------------------------------*/
+
+int main(void)
+{
+ volatile uint32_t count, count_max = 1000000; // with core frequency ~50MHz this gives ~1.5Hz blinking frequency
+
+ pll_start(CRYSTAL, FREQUENCY); // start the PLL
+ system_init(); // initialize other necessary elements
+
+ LED_GPIO->DIR |= LED; // set the direction of the LED pin to output
+
+ while (1)
+ {
+ for (count = 0; count < count_max; count++); // delay
+ LED_gma = LED; // instead of LED_GPIO->DATA |= LED;
+ for (count = 0; count < count_max; count++); // delay
+ LED_gma = 0; // instead of LED_GPIO->DATA &= ~LED;
+ }
+}
+
+/*
++=============================================================================+
+| local functions
++=============================================================================+
+*/
+
+/*------------------------------------------------------------------------*//**
+* \brief Configures flash access time.
+* \details Configures flash access time which allows the chip to run at higher
+* speeds.
+*
+* \param [in] frequency defines the target frequency of the core
+*//*-------------------------------------------------------------------------*/
+
+static void flash_access_time(uint32_t frequency)
+{
+ uint32_t access_time, flashcfg_register;
+
+ if (frequency < 20000000ul) // 1 system clock for core speed below 20MHz
+ access_time = FLASHCFG_FLASHTIM_1CLK;
+ else if (frequency < 40000000ul) // 2 system clocks for core speed between 20MHz and 40MHz
+ access_time = FLASHCFG_FLASHTIM_2CLK;
+ else // 3 system clocks for core speed over 40MHz
+ access_time = FLASHCFG_FLASHTIM_3CLK;
+
+ // do not modify reserved bits in FLASHCFG register
+ flashcfg_register = FLASHCFG; // read register
+ flashcfg_register &= ~(FLASHCFG_FLASHTIM_mask << FLASHCFG_FLASHTIM_bit); // mask the FLASHTIM field
+ flashcfg_register |= access_time << FLASHCFG_FLASHTIM_bit; // use new FLASHTIM value
+ FLASHCFG = flashcfg_register; // save the new value back to the register
+}
+
+/*------------------------------------------------------------------------*//**
+* \brief Starts the PLL.
+* \details Configure and enable PLL to achieve some frequency with some
+* crystal. Before the speed change flash access time is configured via
+* flash_access_time(). Main oscillator is configured and started. PLL
+* parameters m and p are based on function parameters. The PLL is configured,
+* started and selected as the main clock. AHB clock divider is set to 1.
+*
+* \param [in] crystal is the frequency of the crystal resonator connected to
+* the LPC1114 chip.
+* \param [in] frequency is the desired target frequency after enabling the PLL
+*
+* \return real frequency that was set
+*//*-------------------------------------------------------------------------*/
+
+static uint32_t pll_start(uint32_t crystal, uint32_t frequency)
+{
+ uint32_t m, p = 0, fcco;
+
+ flash_access_time(frequency); // configure flash access time first
+
+ // SYSOSCCTRL_FREQRANGE should be 0 for crystals in range 1 - 20MHz
+ // SYSOSCCTRL_FREQRANGE should be 1 for crystals in range 15 - 25MHz
+ if (crystal < 17500000) // divide the ranges on 17.5MHz then
+ LPC_SYSCON->SYSOSCCTRL = 0; // "lower speed" crystals
+ else
+ LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_FREQRANGE; // "higher speed" crystals
+
+ LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_SYSOSC_PD; // power-up main oscillator
+
+ LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_SEL_IRC; // select main oscillator as the input clock for PLL
+ LPC_SYSCON->SYSPLLCLKUEN = 0; // confirm the change of PLL input clock by toggling the...
+ LPC_SYSCON->SYSPLLCLKUEN = SYSPLLUEN_ENA; // ...ENA bit in LPC_SYSCON->SYSPLLCLKUEN register
+
+ // calculate PLL parameters
+ m = frequency / crystal; // M is the PLL multiplier
+ fcco = m * crystal * 2; // FCCO is the internal PLL frequency
+
+ frequency = crystal * m;
+
+ while (fcco < 156000000)
+ {
+ fcco *= 2;
+ p++; // find P which gives FCCO in the allowed range (over 156MHz)
+ }
+
+ LPC_SYSCON->SYSPLLCTRL = ((m - 1) << SYSPLLCTRL_MSEL_bit) | (p << SYSPLLCTRL_PSEL_bit); // configure PLL
+ LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_SYSPLL_PD; // power-up PLL
+
+ while (!(LPC_SYSCON->SYSPLLSTAT & SYSPLLSTAT_LOCK)); // wait for PLL lock
+
+ LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_SEL_PLLOUT; // select PLL output as the main clock
+ LPC_SYSCON->MAINCLKUEN = 0; // confirm the change of main clock by toggling the...
+ LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA; // ...ENA bit in LPC_SYSCON->MAINCLKUEN register
+
+ LPC_SYSCON->SYSAHBCLKDIV = 1; // set AHB clock divider to 1
+
+ return frequency;
+}
+
+/*------------------------------------------------------------------------*//**
+* \brief Initializes system.
+* \details Enables clock for IO configuration block.
+*//*-------------------------------------------------------------------------*/
+
+static void system_init(void)
+{
+ LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_IOCON; // enable clock for IO configuration block
+}
+
+/*
++=============================================================================+
+| ISRs
++=============================================================================+
+*/
+
+/******************************************************************************
+* END OF FILE
+******************************************************************************/
|
