Check program for STM32F303K8 System Clock

Dependencies:   mbed

Fork of study_step0 by Team_PjL

See
https://os.mbed.com/users/kenjiArai/notebook/nucleo-f303k8-hse-clock/#

main.cpp

Committer:
kenjiArai
Date:
2017-09-30
Revision:
3:5cba8c19a04b
Parent:
2:68db9770a517

File content as of revision 3:5cba8c19a04b:

/*
 * mbed Application program
 *  Ckeck program for Clocks only for Nucleo-F303K8
 *
 * Copyright (c) 2017 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Created:    September 28th, 2017
 *      Revised:    October    1st, 2017
 */

//  Include --------------------------------------------------------------------
#include "mbed.h"

//  Object ---------------------------------------------------------------------
DigitalOut  my_led(LED1);
DigitalIn   my_sw(USER_BUTTON);
Serial      pc(USBTX, USBRX);

//  Definition -----------------------------------------------------------------
#define SUCESS_FACTOR

#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)

//  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 = "";
char *const cmsg5 = "??? following infromation is not valid !";
char *const cmsg6 = "clock freq. =";
char *const cmsg7 = "fPLL = fPLL-in x PLLMUL";
char *const cmsg8 = "fPLL-in(Clock source)is ";

//  Function prototypes --------------------------------------------------------
void put_rn(void);
uint8_t disable_pll_and_set_hsi(void);
void cpu_freq(void);

extern void SetSysClock_modify(void);
extern void SetSysClock_HSE_none_Xtal(void);

//------------------------------------------------------------------------------
//  Control Program
//------------------------------------------------------------------------------
int main() {
    PRINTF("\r\nCheck program for STM32F303K8 System Clock\r\n\r\n");
    // Output clock on MCO pin(PA8 (D9))
    // 64 MHz or 8 MHz or 72MHz
    HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_SYSCLK, RCC_MCO_DIV1); 
    cpu_freq();
    PRINTF("Het ant key to go next step\r\n");
    while(pc.readable()==0){;}
    pc.getc();  //dummy read
#ifdef SUCESS_FACTOR    // Set System clock 8MHz (Direct HSI)
    if(disable_pll_and_set_hsi()){
        Serial pc(USBTX, USBRX);
        PRINTF("\r\nChanged system clock successfully!!\r\n");       
        cpu_freq();
    } else {
        PRINTF("\r\nNo Change!!\r\n");       
        cpu_freq();
    }
#else
    PRINTF("Skip 8MHz mode then next 72MHz clcok may not success!!\r\n");
#endif
    PRINTF("Het ant key to go next step\r\n");
    while(pc.readable()==0){;}
    pc.getc();  //dummy read
    SetSysClock_HSE_none_Xtal();
    Serial pc(USBTX, USBRX);
    cpu_freq();
    PRINTF("Hit any key to restart\r\n");
    while(1) {
        my_led = !my_led;
        if (pc.readable()){
            NVIC_SystemReset();
        }
        wait(1.0f);
    }
}

uint8_t disable_pll_and_set_hsi(void){
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    /* Select PLL as system clock source
       and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
    RCC_ClkInitStruct.ClockType      = 
    (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 |
     RCC_CLOCKTYPE_PCLK2);
    RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_HSI; // 8 MHz
    RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;         // 8 MHz
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;           // 8 MHz
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;           // 8 MHz
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
        return 0; // FAIL
    }
    RCC->CR &= 0xfeffffff;  // Disable PLL 
    return 1;
}

void cpu_freq(void)
{
    uint32_t m1 = 0, m2 = 0, m3 = 0, m4 = 0;

    PRINTF("--- Clocks related Reg.(RCC->?) ---");      put_rn();
    PRINTF("CR       = 0x%08x", RCC->CR);               put_rn();
    PRINTF("CFGR     = 0x%08x", RCC->CFGR);             put_rn();
    PRINTF("CIR      = 0x%08x", RCC->CIR);              put_rn();
    PRINTF("APB2RSTR = 0x%08x", RCC->APB2RSTR);         put_rn();
    PRINTF("APB1RSTR = 0x%08x", RCC->APB1RSTR);         put_rn();
    PRINTF("AHB1ENR  = 0x%08x", RCC->AHBENR);           put_rn();
    PRINTF("APB2ENR  = 0x%08x", RCC->APB2ENR);          put_rn();
    PRINTF("APB1ENR  = 0x%08x", RCC->APB1ENR);          put_rn();
    PRINTF("APB1LPENR= 0x%08x", RCC->BDCR);             put_rn();
    PRINTF("CSR      = 0x%08x", RCC->CSR);              put_rn();
    PRINTF("AHBRSTR  = 0x%08x", RCC->AHBRSTR);          put_rn();
    PRINTF("CFGR2    = 0x%08x", RCC->CFGR2);            put_rn();
    PRINTF("CFGR3    = 0x%08x", RCC->CFGR3);            put_rn();
    put_rn();
    m1 = (RCC->CFGR & RCC_CFGR_SWS) >> RCC_CFGR_SWS_Pos; /* Get SYSCLK source */
    switch (m1) {
        case 0x00:  // HSI used as system clock
            PRINTF( "%s, %s %uHz", cmsg2, cmsg1, HSI_VALUE );
            m2 = HSI_VALUE;
            break;
        case 0x01:  // HSE used as system clock
            PRINTF( "%s, %s %uHz", cmsg3, cmsg1, HSE_VALUE );
            m2 = HSE_VALUE;
            break;
        case 0x02:  // PLL used as system clock
            PRINTF(cmsg7);
            put_rn();
            m1 = (RCC->CFGR & RCC_CFGR_PLLSRC) >> RCC_CFGR_PLLSRC_Pos;
            PRINTF(cmsg8);
            if (m1 == 0){
                m3 = HSI_VALUE / 2;
                PRINTF("HSI/2 -> fPLL-in = %uHz", m3);
            } else {
                m2 = (RCC->CFGR2 & RCC_CFGR2_PREDIV);
                m2 += 1;
                m3 = HSE_VALUE / m2;
                PRINTF("HSE/PREDIV(=%u) -> fPLL-in = %uHz", m2, m3);
            }
            put_rn();
            PRINTF(cmsg4);
            m4 = (RCC->CFGR & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_Pos;
            m4 += 2;
            if (m4 > 16){
                m4 = 16;
            }
            PRINTF("PLLMUL = %u", m4);
            put_rn();
            PRINTF("fPLL = fPLL-in x PLLMUL = %u x %u = %uHz", m3, m4, m3*m4);
            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();
}

void put_rn(void)
{
    PUTC('\r');
    PUTC('\n');
}