Skip to content

Commit eedce20

Browse files
committed
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
1 parent 7df2622 commit eedce20

File tree

5 files changed

+36
-22
lines changed

5 files changed

+36
-22
lines changed

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/analogin_api.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "pinmap.h"
2020
#include "error.h"
2121

22+
#define MAX_FADC 6000000
23+
2224
static const PinMap PinMap_ADC[] = {
2325
{PTE20, ADC0_SE0, 0},
2426
{PTE22, ADC0_SE3, 0},
@@ -54,14 +56,24 @@ void analogin_init(analogin_t *obj, PinName pin) {
5456
if (obj->adc & (1 << CHANNELS_A_SHIFT)) {
5557
cfg2_muxsel = 0;
5658
}
59+
60+
// bus clk
61+
uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1);
62+
uint32_t clkdiv;
63+
for (clkdiv = 0; clkdiv < 4; clkdiv++) {
64+
if ((PCLK >> clkdiv) <= MAX_FADC)
65+
break;
66+
}
67+
if (clkdiv == 4) //Set max div
68+
clkdiv = 0x7;
5769

5870
ADC0->SC1[1] = ADC_SC1_ADCH(obj->adc & ~(1 << CHANNELS_A_SHIFT));
5971

60-
ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration
61-
| ADC_CFG1_ADIV(3) // Clock Divide Select: (Input Clock)/8
62-
| ADC_CFG1_ADLSMP_MASK // Long Sample Time
63-
| ADC_CFG1_MODE(3) // (16)bits Resolution
64-
| ADC_CFG1_ADICLK(1); // Input Clock: (Bus Clock)/2
72+
ADC0->CFG1 = ADC_CFG1_ADLPC_MASK // Low-Power Configuration
73+
| ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select: (Input Clock)/8
74+
| ADC_CFG1_ADLSMP_MASK // Long Sample Time
75+
| ADC_CFG1_MODE(3) // (16)bits Resolution
76+
| ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock: (Bus Clock)/2
6577

6678
ADC0->CFG2 = cfg2_muxsel // ADxxb or ADxxa channels
6779
| ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/i2c_api.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ void i2c_frequency(i2c_t *obj, int hz) {
206206
uint32_t ref = 0;
207207
uint8_t i, j;
208208
// bus clk
209-
uint32_t PCLK = 24000000u;
209+
uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1);
210210
uint32_t pulse = PCLK / (hz * 2);
211211

212212
// we look for the values that minimize the error

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,25 @@ static const PinMap PinMap_PWM[] = {
6464
{NC , NC , 0}
6565
};
6666

67-
#define PWM_CLOCK_MHZ (0.75) // (48)MHz / 64 = (0.75)MHz
67+
static float pwm_clock;
6868

6969
void pwmout_init(pwmout_t* obj, PinName pin) {
7070
// determine the channel
7171
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
7272
if (pwm == (PWMName)NC)
7373
error("PwmOut pin mapping failed");
74-
74+
75+
uint32_t clkdiv = 0;
76+
float clkval = SystemCoreClock / 1000000.0f;
77+
78+
while (clkval > 1) {
79+
clkdiv++;
80+
clkval /= 2.0;
81+
if (clkdiv == 7)
82+
break;
83+
}
84+
85+
pwm_clock = clkval;
7586
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
7687
unsigned int tpm_n = (pwm >> TPM_SHIFT);
7788
unsigned int ch_n = (pwm & 0xFF);
@@ -125,7 +136,7 @@ void pwmout_period_ms(pwmout_t* obj, int ms) {
125136
// Set the PWM period, keeping the duty cycle the same.
126137
void pwmout_period_us(pwmout_t* obj, int us) {
127138
float dc = pwmout_read(obj);
128-
*obj->MOD = PWM_CLOCK_MHZ * us;
139+
*obj->MOD = (uint32_t)(pwm_clock * (float)us);
129140
pwmout_write(obj, dc);
130141
}
131142

@@ -138,5 +149,5 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
138149
}
139150

140151
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
141-
*obj->CnV = PWM_CLOCK_MHZ * us;
152+
*obj->CnV = (uint32_t)(pwm_clock * (float)us);
142153
}

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,6 @@ void serial_free(serial_t *obj) {
111111
// serial_baud
112112
//
113113
// set the baud rate, taking in to account the current SystemFrequency
114-
//
115-
// The LPC2300 and LPC1700 have a divider and a fractional divider to control the
116-
// baud rate. The formula is:
117-
//
118-
// Baudrate = (1 / PCLK) * 16 * DL * (1 + DivAddVal / MulVal)
119-
// where:
120-
// 1 < MulVal <= 15
121-
// 0 <= DivAddVal < 14
122-
// DivAddVal < MulVal
123-
//
124114
void serial_baud(serial_t *obj, int baudrate) {
125115

126116
// save C2 state
@@ -130,7 +120,7 @@ void serial_baud(serial_t *obj, int baudrate) {
130120
obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
131121

132122
// [TODO] not hardcode this value
133-
uint32_t PCLK = (obj->uart == UART0) ? 48000000u : 24000000u;
123+
uint32_t PCLK = (obj->uart == UART0) ? SystemCoreClock : SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1);
134124

135125
// First we check to see if the basic divide with no DivAddVal/MulVal
136126
// ratio gives us an integer result. If it does, we set DivAddVal = 0,

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ static void pit_init(void) {
4343
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // Start timer 1
4444

4545
// Use channel 0 as a prescaler for channel 1
46-
PIT->CHANNEL[0].LDVAL = 23;
46+
uint32_t PCLK = SystemCoreClock / (((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >> SIM_CLKDIV1_OUTDIV4_SHIFT) + 1);
47+
PIT->CHANNEL[0].LDVAL = PCLK / 1000000 - 1;
4748
PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // Start timer 0, disable interrupts
4849
}
4950

0 commit comments

Comments
 (0)