mbed library with additional peripherals for ST F401 board

Fork of mbed-src by mbed official

This mbed LIB has additional peripherals for ST F401 board

  • UART2 : PA_3 rx, PA_2 tx
  • UART3 : PC_7 rx, PC_6 tx
  • I2C2 : PB_3 SDA, PB_10 SCL
  • I2C3 : PB_4 SDA, PA_8 SCL

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Tue Jan 14 22:15:04 2014 +0000
Parent:
73:299c67215126
Child:
75:99bf659e4489
Commit message:
Synchronized with git revision 8ef99f856226a85d6a0e5fe7902b80ed0f48799d

Full URL: https://github.com/mbedmicro/mbed/commit/8ef99f856226a85d6a0e5fe7902b80ed0f48799d/

Added MCGPLLFLL clock function, squished some 'bugs'

Changed in this revision

targets/hal/TARGET_Freescale/TARGET_KL25Z/clk_freqs.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_Freescale/TARGET_KL25Z/clk_freqs.h	Tue Jan 14 20:45:05 2014 +0000
+++ b/targets/hal/TARGET_Freescale/TARGET_KL25Z/clk_freqs.h	Tue Jan 14 22:15:04 2014 +0000
@@ -72,8 +72,8 @@
             }
         } 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;         
         }
     }
     
@@ -83,6 +83,23 @@
     return 0;
 }
 
+//Get MCG PLL/2 or FLL frequency, depending on which one is active, sets PLLFLLSEL bit
+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));
+    if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) {         //FLL is selected
+        SIM->SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;        //MCG peripheral clock is FLL output
+        return MCGClock;
+    } else {                                            //PLL is selected
+        SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;         //MCG peripheral clock is PLL output
+        return (MCGClock >> 1);
+    }
+    
+    //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
+}
 
 #ifdef __cplusplus
 }
--- a/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c	Tue Jan 14 20:45:05 2014 +0000
+++ b/targets/hal/TARGET_Freescale/TARGET_KL25Z/pwmout_api.c	Tue Jan 14 22:15:04 2014 +0000
@@ -18,6 +18,7 @@
 #include "cmsis.h"
 #include "pinmap.h"
 #include "error.h"
+#include "clk_freqs.h"
 
 static const PinMap PinMap_PWM[] = {
     // LEDs
@@ -73,7 +74,14 @@
         error("PwmOut pin mapping failed");
     
     uint32_t clkdiv = 0;
-    float clkval = SystemCoreClock / 1000000.0f;
+    float clkval;
+    if (mcgpllfll_frequency()) {
+        SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
+        clkval = mcgpllfll_frequency() / 1000000.0f;
+    } else {
+        SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2); // Clock source: ExtOsc
+        clkval = extosc_frequency() / 1000000.0f;
+    } 
     
     while (clkval > 1) {
         clkdiv++;
@@ -89,7 +97,6 @@
 
     SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
     SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n);
-    SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
 
     TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
     tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(clkdiv); // (clock)MHz / clkdiv ~= (0.75)MHz
--- a/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c	Tue Jan 14 20:45:05 2014 +0000
+++ b/targets/hal/TARGET_Freescale/TARGET_KL25Z/serial_api.c	Tue Jan 14 22:15:04 2014 +0000
@@ -71,8 +71,8 @@
     obj->uart = (UARTLP_Type *)uart;
     // enable clk
     switch (uart) {
-        case UART_0: if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0))   //PLL/FLL is selected
-                        SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK | (1<<SIM_SOPT2_UART0SRC_SHIFT);
+        case UART_0: if (mcgpllfll_frequency() != 0)                    //PLL/FLL is selected
+                        SIM->SOPT2 |= (1<<SIM_SOPT2_UART0SRC_SHIFT);
                      else
                         SIM->SOPT2 |= (2<<SIM_SOPT2_UART0SRC_SHIFT);
                      SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; break;
@@ -123,7 +123,14 @@
     // Disable UART before changing registers
     obj->uart->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK);
     
-    uint32_t PCLK = (obj->uart == UART0) ? SystemCoreClock : bus_frequency();
+    uint32_t PCLK;
+    if (obj->uart == UART0) {
+        if (mcgpllfll_frequency() != 0)
+            PCLK = mcgpllfll_frequency();
+        else
+            PCLK = extosc_frequency();
+    } else
+        PCLK = bus_frequency();
 
     // 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,
--- a/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c	Tue Jan 14 20:45:05 2014 +0000
+++ b/targets/hal/TARGET_Freescale/TARGET_KL25Z/us_ticker.c	Tue Jan 14 22:15:04 2014 +0000
@@ -102,10 +102,22 @@
             }
         }
     }
-    //No suitable external oscillator clock -> Use fast internal oscillator (4MHz)
+    //No suitable external oscillator clock -> Use fast internal oscillator (4MHz / divider)
     MCG->C1 |= MCG_C1_IRCLKEN_MASK;
     MCG->C2 |= MCG_C2_IRCS_MASK;
-    LPTMR0->PSR = LPTMR_PSR_PCS(0) | LPTMR_PSR_PRESCALE(1);
+    LPTMR0->PSR =  LPTMR_PSR_PCS(0);
+    switch (MCG->SC & MCG_SC_FCRDIV_MASK) {
+        case MCG_SC_FCRDIV(0):                  //4MHz
+            LPTMR0->PSR |= LPTMR_PSR_PRESCALE(1);
+            break;
+        case MCG_SC_FCRDIV(1):                  //2MHz
+            LPTMR0->PSR |= LPTMR_PSR_PRESCALE(0);
+            break;
+        default:                                //1MHz or anything else, in which case we put it on 1MHz
+            MCG->SC &= ~MCG_SC_FCRDIV_MASK;
+            MCG->SC |= MCG_SC_FCRDIV(2);
+            LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK;
+    }
     
 }