Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
@Zuph
203 lines (164 sloc) 7.799 kb
/** \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
******************************************************************************/
Jump to Line
Something went wrong with that request. Please try again.