diff --git a/Core/Src/main.c b/Core/Src/main.c deleted file mode 100644 index c7fa85d..0000000 --- a/Core/Src/main.c +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include -#include -#include - -#include "main.h" - -IWDG_HandleTypeDef hiwdg; -UART_HandleTypeDef huart2; - -void SystemClock_Config(void); -static void MX_GPIO_Init(void); -static void MX_USART2_UART_Init(void); -static void MX_IWDG_Init(void); - -#ifdef __GNUC__ -#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) -#else -#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) -#endif /* __GNUC__ */ - -PUTCHAR_PROTOTYPE -{ - HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF); - - return ch; -} - -int main(void) -{ - unsigned int i = 1, j = 40; - - HAL_Init(); - SystemClock_Config(); - MX_GPIO_Init(); - MX_USART2_UART_Init(); - MX_IWDG_Init(); - - while (1) { - if (j < 100) { - j += 10; - } - else if (j < 200) { - j += 20; - } - else if (j < 400) { - j += 40; - } - if (j > 800) { - j = 800; - } - - printf("%u: Hello World\r\n", i++); - HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin); - HAL_Delay(j); - HAL_IWDG_Refresh(&hiwdg); - } -} - -void SystemClock_Config(void) -{ - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; - - HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); - - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; - RCC_OscInitStruct.PLL.PLLN = 8; - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; - RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; - RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - Error_Handler(); - } - - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; - - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { - Error_Handler(); - } - - PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2; - PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { - Error_Handler(); - } -} - -static void MX_IWDG_Init(void) -{ - hiwdg.Instance = IWDG; - hiwdg.Init.Prescaler = IWDG_PRESCALER_4; - hiwdg.Init.Window = 4095; - hiwdg.Init.Reload = 4095; - if (HAL_IWDG_Init(&hiwdg) != HAL_OK) { - Error_Handler(); - } -} - -static void MX_USART2_UART_Init(void) -{ - huart2.Instance = USART2; - huart2.Init.BaudRate = 115200; - huart2.Init.WordLength = UART_WORDLENGTH_8B; - huart2.Init.StopBits = UART_STOPBITS_1; - huart2.Init.Parity = UART_PARITY_NONE; - huart2.Init.Mode = UART_MODE_TX_RX; - huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; - huart2.Init.OverSampling = UART_OVERSAMPLING_16; - huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; - huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1; - huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; - if (HAL_UART_Init(&huart2) != HAL_OK) { - Error_Handler(); - } -} - -static void MX_GPIO_Init(void) -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOF_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - - HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET); - - GPIO_InitStruct.Pin = LED_GREEN_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(LED_GREEN_GPIO_Port, &GPIO_InitStruct); -} - -void Error_Handler(void) -{ - __disable_irq(); - while (1) { - } -} - -#ifdef USE_FULL_ASSERT -void assert_failed(uint8_t *file, uint32_t line) -{ - /* User can add his own implementation to report the file name and line number, - ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ -} -#endif /* USE_FULL_ASSERT */ diff --git a/Core/Src/main.cc b/Core/Src/main.cc new file mode 100644 index 0000000..e1bb58d --- /dev/null +++ b/Core/Src/main.cc @@ -0,0 +1,226 @@ +#include +#include +#include +#include + +#include "main.h" + +IWDG_HandleTypeDef hiwdg; +UART_HandleTypeDef huart2; + +static void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_USART2_UART_Init(void); +static void MX_IWDG_Init(void); + +#define SYS_TICK_PRIO 0 + +class My +{ + public: + My() {printf("Constructor\r\n");}; + ~My() {printf("Destructor\r\n");}; +}; + +int main(void) +{ + unsigned int i = 1, j = 40; + + SET_BIT(FLASH->ACR, FLASH_ACR_PRFTEN); + SysTick_Config(SystemCoreClock / 1000U); // 1kHz + NVIC_SetPriority(SysTick_IRQn, SYS_TICK_PRIO); + + SET_BIT(RCC->APBENR2, RCC_APBENR2_SYSCFGEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->APBENR2, RCC_APBENR2_SYSCFGEN); + + SET_BIT(RCC->APBENR1, RCC_APBENR1_PWREN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->APBENR1, RCC_APBENR1_PWREN); + + /* Change strobe configuration of GPIO depending on UCPDx dead battery settings */ + MODIFY_REG(SYSCFG->CFGR1, (SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE), SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE); + + SystemClock_Config(); + MX_GPIO_Init(); + MX_USART2_UART_Init(); + + My* my = new My(); + + delete(my); + + // MX_IWDG_Init(); + while (1) { + if (j < 100) { + j += 10; + } + else if (j < 200) { + j += 20; + } + else if (j < 400) { + j += 40; + } + if (j > 800) { + j = 800; + } + printf("%u: Hello World\r\n", i++); + HAL_GPIO_TogglePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin); + HAL_Delay(j); + // HAL_IWDG_Refresh(&hiwdg); + } +} + +void SystemClock_Config(void) +{ + /* Modify voltage scaling range */ + MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1); + /* Wait until VOSF is reset */ + while(HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)); + + /* HSI clock config */ + MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSITRIM, RCC_HSICALIBRATION_DEFAULT << RCC_ICSCR_HSITRIM_Pos); + /* Adjust the HSI16 division factor */ + MODIFY_REG(RCC->CR, RCC_CR_HSIDIV, RCC_HSI_DIV1); + /* Update the SystemCoreClock global variable with HSISYS value */ + SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos))); + + /* Adapt Systick interrupt period */ + SysTick_Config(SystemCoreClock / 1000U); // 1kHz + NVIC_SetPriority(SysTick_IRQn, SYS_TICK_PRIO); + + + /* LSI config */ + /* Disable the Internal Low Speed oscillator (LSI). */ + CLEAR_BIT(RCC->CSR, RCC_CSR_LSION); + /* Wait till LSI is disabled */ + while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U); + + /* PLL config */ + /* Disable the main PLL. */ + CLEAR_BIT(RCC->CR, RCC_CR_PLLON); + /* Wait till PLL is ready */ + while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U); + /* Configure the main PLL clock source, multiplication and division factors. */ + MODIFY_REG(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLP | RCC_PLLCFGR_PLLQ | RCC_PLLCFGR_PLLR), + (RCC_PLLSOURCE_HSI | RCC_PLLM_DIV1 | (8 << RCC_PLLCFGR_PLLN_Pos) | RCC_PLLP_DIV2 | RCC_PLLQ_DIV2 | RCC_PLLR_DIV2)); + /* Enable the main PLL. */ + SET_BIT(RCC->CR, RCC_CR_PLLON); + /* Enable PLLR Clock output. */ + SET_BIT(RCC->PLLCFGR, RCC_PLLRCLK); + /* Wait till PLL is ready */ + while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U); + + /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ + MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_LATENCY_2); + /* Check that the new number of wait states is taken into account to access the Flash + memory by polling the FLASH_ACR register */ + while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_LATENCY_2); + + /* HCLK config */ + /* Set the highest APB divider in order to ensure that we do not go through + a non-spec phase whatever we decrease or increase HCLK. */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16); + /* Set the new HCLK clock divider */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1); + + /* SYSCLK config */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_SYSCLKSOURCE_PLLCLK); + while ((RCC->CFGR & RCC_CFGR_SWS) != (RCC_SYSCLKSOURCE_PLLCLK << RCC_CFGR_SWS_Pos)); + + /* PCLK1 Configuration */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV1); + + /* TODO: Update the SystemCoreClock global variable */ + SystemCoreClock = 64000000; + + /* Configure the USART2 clock source */ + MODIFY_REG(RCC->CCIPR, RCC_CCIPR_USART2SEL, RCC_USART2CLKSOURCE_PCLK1); +} + +static void MX_IWDG_Init(void) +{ + hiwdg.Instance = IWDG; + hiwdg.Init.Prescaler = IWDG_PRESCALER_4; + hiwdg.Init.Window = 4095; + hiwdg.Init.Reload = 4095; + if (HAL_IWDG_Init(&hiwdg) != HAL_OK) { + Error_Handler(); + } +} + +static void MX_USART2_UART_Init(void) +{ + huart2.Instance = USART2; + huart2.Init.BaudRate = 115200; + huart2.Init.WordLength = UART_WORDLENGTH_8B; + huart2.Init.StopBits = UART_STOPBITS_1; + huart2.Init.Parity = UART_PARITY_NONE; + huart2.Init.Mode = UART_MODE_TX_RX; + huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart2.Init.OverSampling = UART_OVERSAMPLING_16; + huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1; + huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + if (HAL_UART_Init(&huart2) != HAL_OK) { + Error_Handler(); + } +} + +static void MX_GPIO_Init(void) +{ + /* Enable PORT C clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOCEN); + + /* Enable PORT F clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOFEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOFEN); + + /* Enable PORT A clock*/ + SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN); + /* Delay after an RCC peripheral clock enabling */ + READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOAEN); + + GPIOA->BSRR = 1 << 5; // PORTA PIN5 (green LED) + + /* Configure the IO Speed */ + uint32_t temp = GPIOA->OSPEEDR; + temp &= ~(GPIO_OSPEEDR_OSPEED0 << (5 * 2u)); + temp |= (GPIO_SPEED_FREQ_HIGH << (5 * 2u)); + GPIOA->OSPEEDR = temp; + + /* Configure the IO Output Type */ + temp = GPIOA->OTYPER; + temp &= ~(GPIO_OTYPER_OT0 << 5); + temp |= (((GPIO_MODE_OUTPUT_PP & 0x00000010u) >> 4u) << 5); + GPIOA->OTYPER = temp; + + /* Activate the Pull-up or Pull down resistor for the current IO */ + temp = GPIOA->PUPDR; + temp &= ~(GPIO_PUPDR_PUPD0 << (5 * 2u)); + temp |= ((GPIO_NOPULL) << (5 * 2u)); + GPIOA->PUPDR = temp; + + /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ + temp = GPIOA->MODER; + temp &= ~(GPIO_MODER_MODE0 << (5 * 2u)); + temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003u) << (5 * 2u)); + GPIOA->MODER = temp; +} + +void Error_Handler(void) +{ + __disable_irq(); + while (1) { + } +} + +#ifdef USE_FULL_ASSERT +void assert_failed(uint8_t *file, uint32_t line) +{ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/Core/Src/print.c b/Core/Src/print.c new file mode 100644 index 0000000..b22ce8b --- /dev/null +++ b/Core/Src/print.c @@ -0,0 +1,16 @@ +#include +#include "main.h" + +#ifdef __GNUC__ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#else +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#endif /* __GNUC__ */ + +extern UART_HandleTypeDef huart2; + +int __io_putchar(int ch) +{ + HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF); + return ch; +} diff --git a/Makefile b/Makefile index c8ef2f5..2e5fa12 100644 --- a/Makefile +++ b/Makefile @@ -5,13 +5,16 @@ OPT = -O0 BUILD_DIR = build -C_SOURCES = \ -Core/Src/main.c \ +CC_SOURCES = \ +Core/Src/main.cc \ + +C_SOURCES = \ Core/Src/stm32g0xx_it.c \ Core/Src/stm32g0xx_hal_msp.c \ Core/Src/system_stm32g0xx.c \ Core/Src/syscalls.c \ Core/Src/sysmem.c \ +Core/Src/print.c \ Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc.c \ Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal.c \ Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_cortex.c \ @@ -37,6 +40,7 @@ Core/Startup/startup_stm32g071rbtx.s PREFIX = arm-none-eabi- CC = $(PREFIX)gcc +CXX = $(PREFIX)g++ AS = $(PREFIX)gcc -x assembler-with-cpp CP = $(PREFIX)objcopy SZ = $(PREFIX)size @@ -81,12 +85,18 @@ LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BU all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin -OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(CC_SOURCES:.cc=.o))) +vpath %.cc $(sort $(dir $(CC_SOURCES))) + +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) vpath %.c $(sort $(dir $(C_SOURCES))) OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) vpath %.s $(sort $(dir $(ASM_SOURCES))) +$(BUILD_DIR)/%.o: %.cc Makefile | $(BUILD_DIR) + $(CXX) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.cc=.lst)) $< -o $@ + $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ @@ -94,7 +104,8 @@ $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) $(AS) -c $(CFLAGS) $< -o $@ $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + $(CXX) $(OBJECTS) $(LDFLAGS) -o $@ + # $(CC) $(OBJECTS) $(LDFLAGS) -o $@ $(SZ) $@ $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)