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
pull/140/head
Sissors 2014-01-10 21:45:26 +01:00
parent 7df2622a76
commit eedce209c5
5 changed files with 36 additions and 22 deletions

View File

@ -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

View File

@ -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

View File

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

View File

@ -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,

View File

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