Skip to content

[LPC11U68] Fixed PLL lock issue etc #301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 12, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
*
Expand All @@ -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 */
Expand All @@ -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

Expand Down Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
131 changes: 131 additions & 0 deletions libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/analogin_api.c
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down
25 changes: 12 additions & 13 deletions libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11U6X/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,29 @@
* 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}
};

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}
};

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down