Check System frequency of Nucleo F411RE board. Also F401RE.

Dependencies:   mbed

<May 12th, 2015>
I have confirmed that both mbed lib. and mbed-src lib. have updated to change F411RE mbed System clock and USB clock as below.

fVCO = fPLL-in x (PLLN/PLLM), fPLL-out = fVCO/PLLP, fUSB-out = fVCO/PLLQ
Use PLL with PLLN=192, PLLM=4
Use HSE(not Xtal but External Clock)=8000000Hz
PLL/Base   freq= 384000000Hz
Use PLL with PLLP=4, PLLQ=8
PLL/System freq=  96000000Hz
PLL/USB    freq=  48000000Hz

SYSCLK clock freq. =  96000000Hz
HCLK   clock freq. =  96000000Hz
PCLK1  clock freq. =  48000000Hz
PCLK2  clock freq. =  96000000Hz


mbed lib. Rev. -> 98 & mbed-src lib. Rev. ->539
We can use USB with proper colok!.

If you would like to use 100MHz System clock, please refer updated "Nucleo_F411RE_SysClk".
--------

I made a clock checking program for Nucleo F411RE and F401 mbed board.
Picture shows F411RE example.
/media/uploads/kenjiArai/f411_clk.png
System frequency is 100MHz. Looks okay for me.
USB frequency is 44.4MHz? -> USB clock needs accurate frequency 48MHz.
Once keeping 100MHz system clock freq., we can select PLLQ value only 9 or 8.
If PLLQ=9, USB Freq. is 44.4MHz (current setting).
If PLLQ=8, USB Freq. is 50.0MHz.

Best selection looks follows.
PLL clock -> HSE = 8MHz
PLLN= 192, PLLM = 4
PLL Freq. = (PLL Clock)*(PLLN/PLLM) = 8MHz * 192 / 4 = 384MHz
System clock = (PLL Freq.)/PLLP = 384MHz/4 = 96MHz
USB clock = (PLL Freq.)/PLLQ = 384MHz/8 = 48MHz

Is this result okay?
or
Is my program wrong?

Revision:
0:0766e37fd3d6
Child:
1:2d6d2ccd87f8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Nov 02 04:58:59 2014 +0000
@@ -0,0 +1,233 @@
+/*
+ * mbed Application program / Frequency Counter with GPS 1PPS Compensation
+ *
+ * Copyright (c) 2014 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Created: Nobember   2nd, 2014
+ *      Revised: Nobember   2nd, 2014
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mbed.h"
+
+//  Object ----------------------------------------------------------------------------------------
+Serial pc(USBTX, USBRX);
+DigitalOut myled(LED1);
+
+//  Definition ------------------------------------------------------------------------------------
+#define BAUD(x)                 pc.baud(x)
+#define GETC(x)                 pc.getc(x)
+#define PUTC(x)                 pc.putc(x)
+#define PRINTF(...)             pc.printf(__VA_ARGS__)
+#define READABLE(x)             pc.readable(x)
+
+// USB Frequency
+#define USB_FREQ_H          48100000
+#define USB_FREQ_L          47900000
+
+//  RAM -------------------------------------------------------------------------------------------
+
+//  ROM / Constant data ---------------------------------------------------------------------------
+char *const cmsg1 = "freq=";
+char *const cmsg2 = "Use HSI(internal RC/High speed)";
+char *const cmsg3 = "Use HSE(External Xtal)";
+char *const cmsg4 = "Use PLL with";
+char *const cmsg5 = "??? following infromation is not valid !";
+char *const cmsg6 = "clock freq. =";
+char *const cmsg7 = "No clock";
+char *const cmsg8 = "Use LSE(external Xtal)=32768Hz";
+char *const cmsg9 = "Use LSI(internal RC/Low speed), RC=";
+char *const cmsg10= "Use HSE(external Xtal & prescaler)";
+
+//  Function prototypes ---------------------------------------------------------------------------
+
+//  Function prototypes ---------------------------------------------------------------------------
+
+//-------------------------------------------------------------------------------------------------
+//  Control Program
+//-------------------------------------------------------------------------------------------------
+void put_rn ( void )
+{
+    PUTC('\r');
+    PUTC('\n');
+}
+
+void cpu_freq(void)
+{
+    uint32_t m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0;
+
+    PRINTF("--- Power Control ---");
+    put_rn();
+    m1 = PWR->CR;
+    PRINTF( "CR       = 0x%08x", m1 );
+    put_rn();
+    m1 = PWR->CSR;
+    PRINTF( "CSR      = 0x%08x", m1 );
+    put_rn();
+    PRINTF("--- Clocks related Reg. ---");
+    put_rn();
+    m1 = RCC->CR;
+    PRINTF( "CR       = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->PLLCFGR;
+    PRINTF( "PLLCFGR  = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->CFGR;
+    PRINTF( "CFGR     = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->CIR;
+    PRINTF( "CIR      = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->AHB1RSTR;
+    PRINTF( "AHB1RSTR = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->APB2RSTR;
+    PRINTF( "APB2RSTR = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->APB1RSTR;
+    PRINTF( "APB1RSTR = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->AHB1ENR;
+    PRINTF( "AHB1ENR  = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->APB2ENR;
+    PRINTF( "APB2ENR  = 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->APB2LPENR;
+    PRINTF( "APB2LPENR= 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->APB1LPENR;
+    PRINTF( "APB1LPENR= 0x%08x", m1 );
+    put_rn();
+    m1 = RCC->CSR;
+    PRINTF( "CSR      = 0x%08x", m1 );
+    put_rn();
+    put_rn();
+    m1 = RCC->CFGR & RCC_CFGR_SWS;  /* Get SYSCLK source */
+    switch (m1) {
+        case 0x00:  // HSI used as system clock
+            PRINTF( "%s, %s%dHz", cmsg2, cmsg1,HSI_VALUE );
+            m2 = HSI_VALUE;
+            break;
+        case 0x04:  // HSE used as system clock
+            PRINTF( "%s, %s%dHz", cmsg3, cmsg1, HSE_VALUE );
+            m2 = HSE_VALUE;
+            break;
+        case 0x08:  // PLL used as system clock
+            PRINTF("fVCO = fPLL-in x (PLLN/PLLM), fPLL-out = fVCO/PLLP, fUSB-out = fVCO/PLLQ");
+            put_rn();
+            m5 = (RCC->PLLCFGR >> 6) & 0x1ff;   // PLLN
+            m1 = RCC->PLLCFGR & 0x3f;           // PLLM
+            PRINTF( "%s PLLN=%d, PLLM=%d", cmsg4, m5, m1 );
+            put_rn();
+            m3 = (RCC->PLLCFGR >> 22) & 0x1;    // Clock source
+            if (m3 == 0) {
+                // HSI oscillator clock selected as PLL clock source
+                m2 = (HSI_VALUE * (m5 / m1));
+                PRINTF( "%s, RC=%dHz", cmsg2, HSI_VALUE );
+            } else {
+                // HSE selected
+                m2 = (((HSE_VALUE) * m5) / m1);
+                if ((RCC->CR >> 18) & 0x01) {  // check HSEBYP bit
+                    // HSE(not Xtal) selected as PLL clock source
+                    PRINTF( "Use HSE(not Xtal but External Clock)=%dHz", HSE_VALUE );
+                } else {
+                    // HSE(Xtal) selected as PLL clock source
+                    PRINTF( "%s, Xtal=%dHz", cmsg3, HSE_VALUE );
+                }
+            }
+            put_rn();
+            PRINTF("PLL/Base   %s%10dHz", cmsg1, m2);
+            put_rn();
+            m3 = (RCC->PLLCFGR >> 16) & 0x03;  // PLLP
+            switch (m3) {
+                case 0:
+                    m3 = 2;
+                    break;
+                case 1:
+                    m3 = 4;
+                    break;
+                case 2:
+                    m3 = 6;
+                    break;
+                case 3:
+                    m3 = 8;
+                    break;
+            }
+            m4 = (RCC->PLLCFGR >> 24) & 0x0f;  // PLLQ
+            PRINTF("%s PLLP=%d, PLLQ=%d", cmsg4, m3, m4);
+            put_rn();
+            PRINTF("PLL/System %s%10dHz", cmsg1, m2/m3);
+            put_rn();
+            PRINTF("PLL/USB    %s%10dHz", cmsg1, m2/m4);
+            m2 = m2/m4;
+            if ((m2 > USB_FREQ_H) || (m2 <USB_FREQ_L)){
+                PRINTF(" -> USB Freq. is out of range!");
+            }
+            put_rn();
+            break;
+        default:    // Not come here
+            PRINTF( cmsg5 );
+            break;
+    }
+    put_rn();
+    PRINTF( "SYSCLK %s%10dHz", cmsg6, HAL_RCC_GetSysClockFreq());
+    put_rn();
+    PRINTF( "HCLK   %s%10dHz", cmsg6, HAL_RCC_GetHCLKFreq());
+    put_rn();
+    PRINTF( "PCLK1  %s%10dHz", cmsg6, HAL_RCC_GetPCLK1Freq());
+    put_rn();
+    PRINTF( "PCLK2  %s%10dHz", cmsg6, HAL_RCC_GetPCLK2Freq());
+    put_rn();
+    put_rn();
+    // Check RTC Clock
+    PRINTF("--- RTC Clock ---");
+    put_rn();
+    m1 = (RCC->BDCR >> 8) & 0x03;
+    switch (m1) {
+        case 0: // no clock
+            PRINTF(cmsg7);
+            break;
+        case 1: // LSE
+            PRINTF(cmsg8);
+            break;
+        case 2: // LSI
+            PRINTF("%s 17 to 47, typ.32KHz", cmsg9);
+            break;
+        case 3: // HSE
+            PRINTF( cmsg10 );
+            m2 = (RCC->PLLCFGR >> 16) & 0x1f;   // RTCPRE
+            m3 = HSE_VALUE / m2;
+            PRINTF("%s%10dHz", cmsg6, m3);
+            put_rn();
+            break;
+        default:    // Not come here
+            PRINTF(cmsg5);
+            break;
+    }
+    put_rn();
+}
+
+int main() {
+    char c;
+    
+    put_rn();
+    put_rn();
+    PRINTF("Are you ready? (Hit any key)");
+    put_rn();
+    c = GETC();
+    PUTC(c);
+    cpu_freq();
+    while(1) {
+        myled = 1; // LED is ON
+        wait(0.2); // 200 ms
+        myled = 0; // LED is OFF
+        wait(1.0); // 1 sec
+    }
+}