From eedce209c50ecb01fa1af6be68b114d8dcd4d6fc Mon Sep 17 00:00:00 2001 From: Sissors Date: Fri, 10 Jan 2014 21:45:26 +0100 Subject: [PATCH] Removed hardcoded frequencies, replaced by automatically calculated ADC frequency 1.5MHz -> 6MHz (if possible, otherwise it tries as close to, but less than 6MHz) pwm tries to get its clock as close as possible to 1MHz, but not lower than 1MHz --- .../TARGET_KL25Z/analogin_api.c | 22 ++++++++++++++----- .../TARGET_Freescale/TARGET_KL25Z/i2c_api.c | 2 +- .../TARGET_KL25Z/pwmout_api.c | 19 ++++++++++++---- .../TARGET_KL25Z/serial_api.c | 12 +--------- .../TARGET_Freescale/TARGET_KL25Z/us_ticker.c | 3 ++- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/analogin_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/analogin_api.c index 455fa835db..973900fae4 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/analogin_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/analogin_api.c @@ -19,6 +19,8 @@ #include "pinmap.h" #include "error.h" +#define MAX_FADC 6000000 + static const PinMap PinMap_ADC[] = { {PTE20, ADC0_SE0, 0}, {PTE22, ADC0_SE3, 0}, @@ -54,14 +56,24 @@ void analogin_init(analogin_t *obj, PinName pin) { if (obj->adc & (1 << CHANNELS_A_SHIFT)) { cfg2_muxsel = 0; } + + // bus clk + uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1); + uint32_t clkdiv; + for (clkdiv = 0; clkdiv < 4; clkdiv++) { + if ((PCLK >> clkdiv) <= MAX_FADC) + break; + } + if (clkdiv == 4) //Set max div + clkdiv = 0x7; ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc & ~(1 << CHANNELS_A_SHIFT)); - ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration - | ADC_CFG1_ADIV(3) // Clock Divide Select: (Input Clock)/8 - | ADC_CFG1_ADLSMP_MASK // Long Sample Time - | ADC_CFG1_MODE(3) // (16)bits Resolution - | ADC_CFG1_ADICLK(1); // Input Clock: (Bus Clock)/2 + ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration + | ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select: (Input Clock)/8 + | ADC_CFG1_ADLSMP_MASK // Long Sample Time + | ADC_CFG1_MODE(3) // (16)bits Resolution + | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock: (Bus Clock)/2 ADC0->CFG2 = cfg2_muxsel // ADxxb or ADxxa channels | ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/i2c_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/i2c_api.c index 7cf3b2683c..01a6c31437 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/i2c_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/i2c_api.c @@ -206,7 +206,7 @@ void i2c_frequency(i2c_t *obj, int hz) { uint32_t ref = 0; uint8_t i, j; // bus clk - uint32_t PCLK = 24000000u; + uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1); uint32_t pulse = PCLK / (hz * 2); // we look for the values that minimize the error diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c index 4265c8e5bc..c7d3196d91 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c @@ -64,14 +64,25 @@ static const PinMap PinMap_PWM[] = { {NC , NC , 0} }; -#define PWM_CLOCK_MHZ (0.75) // (48)MHz / 64 = (0.75)MHz +static float pwm_clock; void pwmout_init(pwmout_t* obj, PinName pin) { // determine the channel PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); if (pwm == (PWMName)NC) error("PwmOut pin mapping failed"); - + + uint32_t clkdiv = 0; + float clkval = SystemCoreClock / 1000000.0f; + + while (clkval > 1) { + clkdiv++; + clkval /= 2.0; + if (clkdiv == 7) + break; + } + + pwm_clock = clkval; unsigned int port = (unsigned int)pin >> PORT_SHIFT; unsigned int tpm_n = (pwm >> TPM_SHIFT); unsigned int ch_n = (pwm & 0xFF); @@ -125,7 +136,7 @@ void pwmout_period_ms(pwmout_t* obj, int ms) { // Set the PWM period, keeping the duty cycle the same. void pwmout_period_us(pwmout_t* obj, int us) { float dc = pwmout_read(obj); - *obj->MOD = PWM_CLOCK_MHZ * us; + *obj->MOD = (uint32_t)(pwm_clock * (float)us); pwmout_write(obj, dc); } @@ -138,5 +149,5 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { } void pwmout_pulsewidth_us(pwmout_t* obj, int us) { - *obj->CnV = PWM_CLOCK_MHZ * us; + *obj->CnV = (uint32_t)(pwm_clock * (float)us); } diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c index 0d360060be..5b8d4f4ad8 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c @@ -111,16 +111,6 @@ void serial_free(serial_t *obj) { // serial_baud // // set the baud rate, taking in to account the current SystemFrequency -// -// The LPC2300 and LPC1700 have a divider and a fractional divider to control the -// baud rate. The formula is: -// -// Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal) -// where: -// 1 < MulVal <= 15 -// 0 <= DivAddVal < 14 -// DivAddVal < MulVal -// void serial_baud(serial_t *obj, int baudrate) { // save C2 state @@ -130,7 +120,7 @@ void serial_baud(serial_t *obj, int baudrate) { obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK); // [TODO] not hardcode this value - uint32_t PCLK = (obj->uart == UART0) ? 48000000u : 24000000u; + uint32_t PCLK = (obj->uart == UART0) ? SystemCoreClock : SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1); // 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, diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c index 6f593d40b9..6b2e0798df 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c @@ -43,7 +43,8 @@ static void pit_init(void) { PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1 // Use channel 0 as a prescaler for channel 1 - PIT->CHANNEL[0].LDVAL = 23; + uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1); + PIT->CHANNEL[0].LDVAL = PCLK / 1000000 - 1; PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // Start timer 0, disable interrupts }