diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/serial_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/serial_api.c index 56c7a6aefd..1a1c607e32 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/serial_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL43Z/serial_api.c @@ -38,6 +38,29 @@ static uart_irq_handler irq_handler; int stdio_uart_inited = 0; serial_t stdio_uart; +static inline uint32_t serial_get_src_clock(serial_t *obj) { + uint32_t mux, srcclk; + + switch ((int)obj->uart) { + case UART_0: + mux = (SIM->SOPT2 & SIM_SOPT2_LPUART0SRC_MASK) >> SIM_SOPT2_LPUART0SRC_SHIFT; + break; + case UART_1: + mux = (SIM->SOPT2 & SIM_SOPT2_LPUART1SRC_MASK) >> SIM_SOPT2_LPUART1SRC_SHIFT; + break; + case UART_2: /* TODO: add UART2 support */ break; + } + + switch (mux) { + case 1: srcclk = fastirc_frequency(); break; + case 2: srcclk = extosc_frequency(); break; + case 3: srcclk = mcgirc_frequency(); break; + default: srcclk = 0; break; + } + + return srcclk; +} + void serial_init(serial_t *obj, PinName tx, PinName rx) { // determine the UART to use UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); @@ -103,8 +126,8 @@ void serial_baud(serial_t *obj, int baudrate) { int calcBaudrate; uint32_t i, sbr, sbrTemp, osr, temp, baud, baudDiff; - /* Use Fast IRC Clock 48Mhz (set in serial_init(...)) */ - uint32_t PCLK = CPU_INT_FAST_CLK_HZ; + /* get value of serial source clock */ + uint32_t PCLK = serial_get_src_clock(obj); /* loop to find the best osr value possible, one that generates minimum baudDiff * iterate through the rest of the supported values of osr */ diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/clk_freqs.h b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/clk_freqs.h index 78bc3248a1..1b4ace826a 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/clk_freqs.h +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/clk_freqs.h @@ -33,6 +33,10 @@ static inline uint32_t extosc_frequency(void) { return CPU_XTAL_CLK_HZ; } +static inline uint32_t fastirc_frequency(void) { + return CPU_INT_FAST_CLK_HZ; +} + static inline uint32_t mcgirc_frequency(void) { uint32_t mcgirc_clock = 0; @@ -53,7 +57,7 @@ static uint32_t extosc_frequency(void) { if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(2)) //MCG clock = external reference clock return MCGClock; - + uint32_t divider, multiplier; #ifdef MCG_C5_PLLCLKEN0_MASK //PLL available if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0)) { //PLL/FLL is selected @@ -91,18 +95,18 @@ static uint32_t extosc_frequency(void) { multiplier = 2929u; break; } - + return MCGClock * divider / multiplier; } #ifdef MCG_C5_PLLCLKEN0_MASK } else { //PLL is selected divider = (1u + (MCG->C5 & MCG_C5_PRDIV0_MASK)); - multiplier = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u); - return MCGClock * divider / multiplier; + multiplier = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u); + return MCGClock * divider / multiplier; } } #endif - + //In all other cases either there is no crystal or we cannot determine it //For example when the FLL is running on the internal reference, and there is also an //external crystal. However these are unlikely situations @@ -110,10 +114,10 @@ static uint32_t extosc_frequency(void) { } //Get MCG PLL/2 or FLL frequency, depending on which one is active, sets PLLFLLSEL bit -static uint32_t mcgpllfll_frequency(void) { +static uint32_t mcgpllfll_frequency(void) { if ((MCG->C1 & MCG_C1_CLKS_MASK) != MCG_C1_CLKS(0)) //PLL/FLL is not selected return 0; - + uint32_t MCGClock = SystemCoreClock * (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)); #ifdef MCG_C5_PLLCLKEN0_MASK if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) { //FLL is selected @@ -126,8 +130,8 @@ static uint32_t mcgpllfll_frequency(void) { return (MCGClock >> 1); } #endif - - //It is possible the SystemCoreClock isn't running on the PLL, and the PLL is still active + + //It is possible the SystemCoreClock isn't running on the PLL, and the PLL is still active //for the peripherals, this is however an unlikely setup }