mirror of https://github.com/ARMmbed/mbed-os.git
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 1MHzpull/140/head
parent
7df2622a76
commit
eedce209c5
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue