Skip to content

Commit 13a0b75

Browse files
committed
Fallback to internal clock if problem with external clock present. The MCU clock in this case is 48MHz instead of 72MHz
1 parent 74098a0 commit 13a0b75

File tree

6 files changed

+88
-3
lines changed

6 files changed

+88
-3
lines changed

firmware/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ USB_SRCS=hw_config.c stm32_it.c usb_prop.c usb_desc.c usb_istr.c usb_pwr.c \
5252

5353

5454
SRCS=main.c system_stm32f10x.c syscalls.c fsmc_nand.c led.c uart.c jtag.c \
55-
cdc.c nand_programmer.c nand_bad_block.c $(USB_SRCS)
55+
clock.c cdc.c nand_programmer.c nand_bad_block.c $(USB_SRCS)
5656

5757
OBJS=$(addprefix $(OBJ_DIR),$(SRCS:.c=.o)) \
5858
$(addprefix $(OBJ_DIR),$(STARTUP:.s=.o))

firmware/clock.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* Copyright (C) 2017 Bogdan Bogush <[email protected]>
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License version 3.
4+
*/
5+
6+
#include "clock.h"
7+
#include <stm32f10x.h>
8+
9+
bool is_external_clock_avail()
10+
{
11+
return (RCC->CR & RCC_CR_HSERDY) != RESET;
12+
}

firmware/clock.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* Copyright (C) 2017 Bogdan Bogush <[email protected]>
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License version 3.
4+
*/
5+
6+
#ifndef _CLOCK_H_
7+
#define _CLOCK_H_
8+
9+
#include <stdbool.h>
10+
11+
bool is_external_clock_avail();
12+
13+
#endif

firmware/libs/spl/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,58 @@ static void SetSysClockTo72(void)
10761076
else
10771077
{ /* If HSE fails to start-up, the application will have wrong clock
10781078
configuration. User can add here some code to deal with this error */
1079+
1080+
/* Fallback to internal HSI clock 8MHz. USB requires 72MHz or 48MHz due to
1081+
* devider 1 or 1.5. Maximum frequency that can be configured for PLL with
1082+
* HSI source is 64MHz so select 48MHz */
1083+
1084+
/* Disable HSE */
1085+
RCC->CR &= ~RCC_CR_HSEON;
1086+
/* Disable PLL */
1087+
RCC->CR &= ~RCC_CR_PLLON;
1088+
1089+
/* At this stage the HSI is already enabled */
1090+
1091+
/* Enable Prefetch Buffer */
1092+
FLASH->ACR |= FLASH_ACR_PRFTBE;
1093+
1094+
/* Flash 2 wait state */
1095+
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
1096+
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
1097+
1098+
/* HCLK = SYSCLK */
1099+
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
1100+
1101+
/* PCLK2 = HCLK */
1102+
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
1103+
1104+
/* PCLK1 = HCLK */
1105+
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
1106+
1107+
/* PLL configuration: PLLCLK = HSI/2 * 12 = 48 MHz */
1108+
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
1109+
RCC_CFGR_PLLMULL));
1110+
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL12);
1111+
1112+
/* Enable PLL */
1113+
RCC->CR |= RCC_CR_PLLON;
1114+
1115+
/* Wait till PLL is ready */
1116+
while((RCC->CR & RCC_CR_PLLRDY) == 0)
1117+
{
1118+
}
1119+
1120+
/* Select PLL as system clock source */
1121+
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
1122+
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
1123+
1124+
/* Wait till PLL is used as system clock source */
1125+
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
1126+
{
1127+
}
1128+
1129+
/* Update frequency */
1130+
SystemCoreClockUpdate();
10791131
}
10801132
}
10811133
#endif

firmware/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "uart.h"
1111
#include "jtag.h"
1212
#include "version.h"
13+
#include "clock.h"
1314
#include <stdio.h>
1415

1516
int main()
@@ -18,6 +19,9 @@ int main()
1819
printf("\r\nNAND programmer ver: %d.%d.%d\r\n", SW_VERSION_MAJOR,
1920
SW_VERSION_MINOR, SW_VERSION_BUILD);
2021

22+
if (!is_external_clock_avail())
23+
printf("External clock not detected. Fallback to internal clock.\r\n");
24+
2125
printf("JTAG init...");
2226
jtag_init();
2327
printf("done.\r\n");

firmware/usb_cdc/hw_config.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ void Set_System(void)
155155
* Input : None.
156156
* Return : None.
157157
*******************************************************************************/
158+
#define CLK_48MHZ 48000000
158159
void Set_USBClock(void)
159160
{
160161
#if defined(STM32L1XX_MD) || defined(STM32L1XX_HD) || defined(STM32L1XX_MD_PLUS)
@@ -163,8 +164,11 @@ void Set_USBClock(void)
163164

164165
#else
165166
/* Select USBCLK source */
166-
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
167-
167+
if (SystemCoreClock == CLK_48MHZ)
168+
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1);
169+
else
170+
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
171+
168172
/* Enable the USB clock */
169173
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
170174
#endif /* STM32L1XX_MD */

0 commit comments

Comments
 (0)