[LPC11U68] Fixed PLL lock issue etc

Fixed PLL lock issue
Corrected system clock related code
pull/301/head
Toyomasa Watarai 2014-05-12 15:25:23 +09:00
parent 94f9d1fcc1
commit e756237ebf
7 changed files with 193 additions and 59 deletions

View File

@ -91,7 +91,7 @@
// <2=> P = 4
// <3=> P = 8
// </h>
#define SYSPLLCTRL_Val 0x00000003 // Reset value: 0x000
#define SYSPLLCTRL_Val 0x00000023 // Reset value: 0x000
//
// <o.0..1> Main Clock Source Select (MAINCLKSEL)
// <0=> IRC Oscillator
@ -445,6 +445,25 @@ void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
}
#define PDRUN_VALID_BITS 0x000025FFL
#define PDRUN_RESERVED_ONE 0x0000C800L
static void power_down_config(uint32_t val)
{
volatile uint32_t tmp;
tmp = (LPC_SYSCON->PDRUNCFG & PDRUN_VALID_BITS);
tmp |= (val & PDRUN_VALID_BITS);
LPC_SYSCON->PDRUNCFG = (tmp | PDRUN_RESERVED_ONE);
}
static void power_up_config(uint32_t val)
{
volatile uint32_t tmp;
tmp = (LPC_SYSCON->PDRUNCFG & PDRUN_VALID_BITS);
tmp &= ~(val & PDRUN_VALID_BITS);
LPC_SYSCON->PDRUNCFG = (tmp | PDRUN_RESERVED_ONE);
}
/**
* Initialize the system
*
@ -455,27 +474,30 @@ void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
*/
void SystemInit (void) {
#if (CLOCK_SETUP)
volatile uint32_t i;
volatile uint32_t i, tmp;
#endif
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
#warning "should not return here, need to fix an issue with PLL lock"
return;
#if (CLOCK_SETUP) /* Clock Setup */
#if ((SYSPLLCLKSEL_Val & 0x03) == 1)
// Initialize XTALIN/XTALOUT pins
LPC_IOCON->PIO2_0 = 0x01;
LPC_IOCON->PIO2_1 = 0x01;
LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* Power-up sysosc */
for (i = 0; i < 200; i++) __NOP(); /* Wait for osc to stabilize */
power_up_config(1<<5); /* Power-up sysosc */
for (i = 0; i < 2500; i++) __NOP(); /* Wait for osc to stabilize */
#endif
#if ((SYSPLLCLKSEL_Val & 0x03) == 3)
LPC_SYSCON->RTCOSCCTRL = (1 << 0); /* Enable 32 kHz output */
for (i = 0; i < 200; i++) __NOP(); /* Wait for osc to stabilize */
#endif
LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
//LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */
LPC_SYSCON->SYSPLLCLKUEN = 0x01;
while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
@ -485,13 +507,13 @@ void SystemInit (void) {
#if (((MAINCLKSEL_Val & 0x03) == 2) )
LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(1 << 6); /* Power-up WDT Clock */
for (i = 0; i < 2000; i++) __NOP(); /* Wait for osc to stabilize */
for (i = 0; i < 2000; i++) __NOP(); /* Wait for osc to stabilize */
#endif
#if ((MAINCLKSEL_Val & 0x03) == 3) /* Main Clock is PLL Out */
LPC_SYSCON->PDRUNCFG |= (1 << 7); /* Power-down SYSPLL */
power_down_config(1<<7); /* Power-down SYSPLL */
LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* Power-up SYSPLL */
power_up_config(1<<7); /* Power-up SYSPLL */
while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
#endif
@ -549,7 +571,4 @@ void SystemInit (void) {
#endif /* Clock Setup */
/* System clock to the IOCON needs to be enabled or
most of the I/O related peripherals won't work. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
}

View File

@ -31,30 +31,18 @@ typedef enum {
} UARTName;
typedef enum {
ADC0_0 = 0,
ADC0_1,
ADC0_2,
ADC0_3,
ADC0_4,
ADC0_5,
ADC0_6,
ADC0_7,
ADC0_8,
ADC0_9,
ADC0_10,
ADC0_11,
ADC1_0,
ADC1_1,
ADC1_2,
ADC1_3,
ADC1_4,
ADC1_5,
ADC1_6,
ADC1_7,
ADC1_8,
ADC1_9,
ADC1_10,
ADC1_11,
ADC_0 = 0,
ADC_1,
ADC_2,
ADC_3,
ADC_4,
ADC_5,
ADC_6,
ADC_7,
ADC_8,
ADC_9,
ADC_10,
ADC_11,
} ADCName;
typedef enum {

View File

@ -0,0 +1,131 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "analogin_api.h"
#include "cmsis.h"
#include "pinmap.h"
#include "error.h"
#ifdef DEVICE_ANALOGIN
#define ANALOGIN_MEDIAN_FILTER 1
#define ADC_10BIT_RANGE 0x3FF
#define ADC_12BIT_RANGE 0xFFF
#define PDRUN_VALID_BITS 0x000025FFL
#define PDRUN_RESERVED_ONE 0x0000C800L
#define ADC_RANGE ADC_12BIT_RANGE
static const PinMap PinMap_ADC[] = {
{P1_9 , ADC_0, 3},
{P0_23, ADC_1, 1},
{P0_16, ADC_2, 1},
{P0_15, ADC_3, 3},
{P1_22, ADC_4, 3},
{P1_3 , ADC_5, 4},
{P0_14, ADC_6, 2},
{P0_13, ADC_7, 2},
{P0_12, ADC_8, 2},
{P0_11, ADC_9, 2},
{P1_29, ADC_10,4},
{P0_22, ADC_11,1},
{NC , NC ,0}
};
void analogin_init(analogin_t *obj, PinName pin) {
volatile uint32_t tmp;
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
if (obj->adc == (uint32_t)NC) {
error("ADC pin mapping failed");
}
pinmap_pinout(pin, PinMap_ADC);
// ADC Powered
tmp = (LPC_SYSCON->PDRUNCFG & PDRUN_VALID_BITS);
tmp &= ~((1 << 4) & PDRUN_VALID_BITS);
LPC_SYSCON->PDRUNCFG = (tmp | PDRUN_RESERVED_ONE);
// Enable clock for ADC
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13);
// Start ADC self-calibration
LPC_ADC->CTRL = (1UL << 30) || (100);
do {
tmp = LPC_ADC->CTRL;
} while ((tmp & (1UL << 30)) != 0);
LPC_ADC->CTRL = 100;
}
static inline uint32_t adc_read(analogin_t *obj) {
// select channel
LPC_ADC->SEQA_CTRL &= ~(0xFFF);
LPC_ADC->SEQA_CTRL |= (1UL << obj->adc);
// start conversion, sequence enable with async mode
LPC_ADC->SEQA_CTRL |= ((1UL << 26) | (1UL << 31) | (1UL << 29) /*| (1UL << 19)*/);
// Repeatedly get the sample data until DONE bit
volatile uint32_t data;
do {
data = LPC_ADC->SEQA_GDAT;
} while ((data & (1UL << 31)) == 0);
data = LPC_ADC->DAT[obj->adc];
// Stop conversion
LPC_ADC->SEQA_CTRL &= ~(1UL << 31);
return ((data >> 4) & ADC_RANGE);
}
static inline void order(uint32_t *a, uint32_t *b) {
if (*a > *b) {
uint32_t t = *a;
*a = *b;
*b = t;
}
}
static inline uint32_t adc_read_u32(analogin_t *obj) {
uint32_t value;
#if ANALOGIN_MEDIAN_FILTER
uint32_t v1 = adc_read(obj);
uint32_t v2 = adc_read(obj);
uint32_t v3 = adc_read(obj);
order(&v1, &v2);
order(&v2, &v3);
order(&v1, &v2);
value = v2;
#else
value = adc_read(obj);
#endif
return value;
}
uint16_t analogin_read_u16(analogin_t *obj) {
uint32_t value = adc_read_u32(obj);
return (value << 4) | ((value >> 8) & 0x000F); // 12 bit
}
float analogin_read(analogin_t *obj) {
uint32_t value = adc_read_u32(obj);
return (float)value * (1.0f / (float)ADC_RANGE);
}
#endif

View File

@ -22,14 +22,14 @@
#define DEVICE_INTERRUPTIN 1
#define DEVICE_ANALOGIN 0
#define DEVICE_ANALOGIN 1
#define DEVICE_ANALOGOUT 0
#define DEVICE_SERIAL 1
#define DEVICE_SERIAL_FC 1
#define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 0
#define DEVICE_I2CSLAVE 1
#define DEVICE_SPI 1
#define DEVICE_SPISLAVE 0

View File

@ -44,10 +44,9 @@ static const PinMap PinMap_I2C_SCL[] = {
#define I2C_SCLL(x, val) (x->i2c->SCLL = val)
#define I2C_SCLH(x, val) (x->i2c->SCLH = val)
#warning [TODO] just copied from LPC11UXX code, need to check
static const uint32_t I2C_addr_offset[2][4] = {
{0x0C, 0x20, 0x24, 0x28},
{0x30, 0x34, 0x38, 0x3C}
{0x0C, 0x20, 0x24, 0x28}, // slave address offset
{0x30, 0x34, 0x38, 0x3C} // slave address mask offset
};
static inline void i2c_conclr(i2c_t *obj, int start, int stop, int interrupt, int acknowledge) {
@ -183,8 +182,7 @@ static inline int i2c_do_read(i2c_t *obj, int last) {
void i2c_frequency(i2c_t *obj, int hz) {
// No peripheral clock divider on the M0
#warning "[TODO] This should be fixed to handle system core clock correctly."
uint32_t PCLK = 12000000; //SystemCoreClock;
uint32_t PCLK = SystemCoreClock;
uint32_t pulse = PCLK / (hz * 2);

View File

@ -29,17 +29,17 @@
* INITIALIZATION
******************************************************************************/
#define UART_NUM 5
#define UART_NUM 1
static const PinMap PinMap_UART_TX[] = {
{P0_19, UART_0, 1},
{P1_18, UART_0, 2},
{P1_27, UART_0, 2},
{P1_18, UART_1, 2},
{P1_0 , UART_2, 3},
{P1_23, UART_2, 3},
{P2_4 , UART_3, 1},
{P2_12, UART_4, 1},
// {P1_18, UART_1, 2},
// {P1_0 , UART_2, 3},
// {P1_23, UART_2, 3},
// {P2_4 , UART_3, 1},
// {P2_12, UART_4, 1},
{ NC , NC , 0}
};
@ -47,11 +47,11 @@ static const PinMap PinMap_UART_RX[] = {
{P0_18, UART_0, 1},
{P1_17, UART_0, 2},
{P1_26, UART_0, 2},
{P1_2 , UART_1, 3},
{P0_20, UART_2, 2},
{P1_6 , UART_2, 2},
{P2_3 , UART_3, 1},
{P2_11, UART_4, 1},
// {P1_2 , UART_1, 3},
// {P0_20, UART_2, 2},
// {P1_6 , UART_2, 2},
// {P2_3 , UART_3, 1},
// {P2_11, UART_4, 1},
{NC , NC , 0}
};
@ -129,8 +129,7 @@ void serial_free(serial_t *obj) {
// set the baud rate, taking in to account the current SystemFrequency
void serial_baud(serial_t *obj, int baudrate) {
LPC_SYSCON->USART0CLKDIV = 0x1;
#warning "[TODO] This should be fixed to handle system core clock correctly."
uint32_t PCLK = 12000000; //SystemCoreClock;
uint32_t PCLK = SystemCoreClock;
// First we check to see if the basic divide with no DivAddVal/MulVal
// ratio gives us an integer result. If it does, we set DivAddVal = 0,
// MulVal = 1. Otherwise, we search the valid ratio value range to find

View File

@ -27,8 +27,7 @@ void us_ticker_init(void) {
us_ticker_inited = 1;
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<10); // Clock CT32B1
#warning "[TODO] this should read from SystemCoreClock grobal variable."
uint32_t PCLK = 12000000;//SystemCoreClock;
uint32_t PCLK = SystemCoreClock;
US_TICKER_TIMER->TCR = 0x2; // reset