Check System frequency of Nucleo F411RE board. Also F401RE.
<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.
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?
Diff: main.cpp
- 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 + } +}