Boot code for STM32G474 MCU

Micro17
Silvano Seva 2024-05-21 19:03:53 +02:00
rodzic 81f9257888
commit de93cb7bc0
12 zmienionych plików z 19924 dodań i 0 usunięć

Wyświetl plik

@ -225,6 +225,24 @@ stm32f405_inc = ['platform/mcu/CMSIS/Include',
stm32f405_def = {'STM32F405xx': '', 'HSE_VALUE':'8000000'}
##
## STM32G474
##
stm32g474_src = ['platform/mcu/STM32G4xx/boot/startup.cpp',
'platform/mcu/STM32G4xx/boot/bsp.cpp',
'platform/mcu/STM32G4xx/boot/libc_integration.cpp',
'platform/mcu/STM32G4xx/drivers/gpio.c',
'platform/mcu/STM32G4xx/drivers/delays.cpp',
'platform/mcu/CMSIS/Device/ST/STM32G4xx/Source/system_stm32g4xx.c']
stm32g474_inc = ['platform/mcu/CMSIS/Include',
'platform/mcu/CMSIS/Device/ST/STM32G4xx/Include',
'platform/mcu/STM32G4xx',
'platform/mcu/STM32G4xx/drivers']
stm32g474_def = {'STM32G474xx': '', 'HSE_VALUE':'8000000', 'SYSCLK_FREQ_170MHz':''}
##
## MK22FN512
##

Wyświetl plik

@ -0,0 +1,259 @@
/**
******************************************************************************
* @file stm32g4xx.h
* @author MCD Application Team
* @brief CMSIS STM32G4xx Device Peripheral Access Layer Header File.
*
* The file is the unique include file that the application programmer
* is using in the C source code, usually in main.c. This file contains:
* - Configuration section that allows to select:
* - The STM32G4xx device used in the target application
* - To use or not the peripherals drivers in application code(i.e.
* code will be based on direct access to peripherals registers
* rather than drivers API), this option is controlled by
* "#define USE_HAL_DRIVER"
*
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32g4xx
* @{
*/
#ifndef __STM32G4xx_H
#define __STM32G4xx_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** @addtogroup Library_configuration_section
* @{
*/
/**
* @brief STM32 Family
*/
#if !defined (STM32G4)
#define STM32G4
#endif /* STM32G4 */
/* Uncomment the line below according to the target STM32G4 device used in your
application
*/
#if !defined (STM32G431xx) && !defined (STM32G441xx) && !defined (STM32G471xx) && \
!defined (STM32G473xx) && !defined (STM32G474xx) && !defined (STM32G484xx) && \
!defined (STM32GBK1CB) && !defined (STM32G491xx) && !defined (STM32G4A1xx)
/* #define STM32G431xx */ /*!< STM32G431xx Devices */
/* #define STM32G441xx */ /*!< STM32G441xx Devices */
/* #define STM32G471xx */ /*!< STM32G471xx Devices */
/* #define STM32G473xx */ /*!< STM32G473xx Devices */
/* #define STM32G483xx */ /*!< STM32G483xx Devices */
/* #define STM32G474xx */ /*!< STM32G474xx Devices */
/* #define STM32G484xx */ /*!< STM32G484xx Devices */
/* #define STM32G491xx */ /*!< STM32G491xx Devices */
/* #define STM32G4A1xx */ /*!< STM32G4A1xx Devices */
/* #define STM32GBK1CB */ /*!< STM32GBK1CB Devices */
#endif
/* Tip: To avoid modifying this file each time you need to switch between these
devices, you can define the device in your toolchain compiler preprocessor.
*/
#if !defined (USE_HAL_DRIVER)
/**
* @brief Comment the line below if you will not use the peripherals drivers.
In this case, these drivers will not be included and the application code will
be based on direct access to peripherals registers
*/
/*#define USE_HAL_DRIVER */
#endif /* USE_HAL_DRIVER */
/**
* @brief CMSIS Device version number V1.2.3
*/
#define __STM32G4_CMSIS_VERSION_MAIN (0x01U) /*!< [31:24] main version */
#define __STM32G4_CMSIS_VERSION_SUB1 (0x02U) /*!< [23:16] sub1 version */
#define __STM32G4_CMSIS_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */
#define __STM32G4_CMSIS_VERSION_RC (0x00U) /*!< [7:0] release candidate */
#define __STM32G4_CMSIS_VERSION ((__STM32G4_CMSIS_VERSION_MAIN << 24)\
|(__STM32G4_CMSIS_VERSION_SUB1 << 16)\
|(__STM32G4_CMSIS_VERSION_SUB2 << 8 )\
|(__STM32G4_CMSIS_VERSION_RC))
/**
* @}
*/
/** @addtogroup Device_Included
* @{
*/
#if defined(STM32G431xx)
#include "stm32g431xx.h"
#elif defined(STM32G441xx)
#include "stm32g441xx.h"
#elif defined(STM32G471xx)
#include "stm32g471xx.h"
#elif defined(STM32G473xx)
#include "stm32g473xx.h"
#elif defined(STM32G483xx)
#include "stm32g483xx.h"
#elif defined(STM32G474xx)
#include "stm32g474xx.h"
#elif defined(STM32G484xx)
#include "stm32g484xx.h"
#elif defined(STM32G491xx)
#include "stm32g491xx.h"
#elif defined(STM32G4A1xx)
#include "stm32g4a1xx.h"
#elif defined(STM32GBK1CB)
#include "stm32gbk1cb.h"
#else
#error "Please select first the target STM32G4xx device used in your application (in stm32g4xx.h file)"
#endif
/**
* @}
*/
/** @addtogroup Exported_types
* @{
*/
typedef enum
{
RESET = 0,
SET = !RESET
} FlagStatus, ITStatus;
typedef enum
{
DISABLE = 0,
ENABLE = !DISABLE
} FunctionalState;
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
typedef enum
{
SUCCESS = 0,
ERROR = !SUCCESS
} ErrorStatus;
/**
* @}
*/
/** @addtogroup Exported_macros
* @{
*/
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
#define READ_BIT(REG, BIT) ((REG) & (BIT))
#define CLEAR_REG(REG) ((REG) = (0x0))
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
#define READ_REG(REG) ((REG))
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
/* Use of CMSIS compiler intrinsics for register exclusive access */
/* Atomic 32-bit register access macro to set one or several bits */
#define ATOMIC_SET_BIT(REG, BIT) \
do { \
uint32_t val; \
do { \
val = __LDREXW((__IO uint32_t *)&(REG)) | (BIT); \
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
} while(0)
/* Atomic 32-bit register access macro to clear one or several bits */
#define ATOMIC_CLEAR_BIT(REG, BIT) \
do { \
uint32_t val; \
do { \
val = __LDREXW((__IO uint32_t *)&(REG)) & ~(BIT); \
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
} while(0)
/* Atomic 32-bit register access macro to clear and set one or several bits */
#define ATOMIC_MODIFY_REG(REG, CLEARMSK, SETMASK) \
do { \
uint32_t val; \
do { \
val = (__LDREXW((__IO uint32_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
} while ((__STREXW(val,(__IO uint32_t *)&(REG))) != 0U); \
} while(0)
/* Atomic 16-bit register access macro to set one or several bits */
#define ATOMIC_SETH_BIT(REG, BIT) \
do { \
uint16_t val; \
do { \
val = __LDREXH((__IO uint16_t *)&(REG)) | (BIT); \
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
} while(0)
/* Atomic 16-bit register access macro to clear one or several bits */
#define ATOMIC_CLEARH_BIT(REG, BIT) \
do { \
uint16_t val; \
do { \
val = __LDREXH((__IO uint16_t *)&(REG)) & ~(BIT); \
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
} while(0)
/* Atomic 16-bit register access macro to clear and set one or several bits */
#define ATOMIC_MODIFYH_REG(REG, CLEARMSK, SETMASK) \
do { \
uint16_t val; \
do { \
val = (__LDREXH((__IO uint16_t *)&(REG)) & ~(CLEARMSK)) | (SETMASK); \
} while ((__STREXH(val,(__IO uint16_t *)&(REG))) != 0U); \
} while(0)
/**
* @}
*/
#if defined (USE_HAL_DRIVER)
#include "stm32g4xx_hal.h"
#endif /* USE_HAL_DRIVER */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __STM32G4xx_H */
/**
* @}
*/
/**
* @}
*/

Wyświetl plik

@ -0,0 +1,104 @@
/**
******************************************************************************
* @file system_stm32g4xx.h
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device System Source File for STM32G4xx devices.
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32g4xx_system
* @{
*/
/**
* @brief Define to prevent recursive inclusion
*/
#ifndef __SYSTEM_STM32G4XX_H
#define __SYSTEM_STM32G4XX_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup STM32G4xx_System_Includes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Exported_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */
extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Exported_Constants
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Exported_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Exported_Functions
* @{
*/
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /*__SYSTEM_STM32G4XX_H */
/**
* @}
*/
/**
* @}
*/

Wyświetl plik

@ -0,0 +1,420 @@
/**
******************************************************************************
* @file system_stm32g4xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32g4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the HSI (16 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32g4xx.s" file, to
* configure the system clock before to branch to main program.
*
* This file configures the system clock as follows:
*=============================================================================
*-----------------------------------------------------------------------------
* System Clock source | HSI
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 16000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 16000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* PLL_M | 1
*-----------------------------------------------------------------------------
* PLL_N | 16
*-----------------------------------------------------------------------------
* PLL_P | 7
*-----------------------------------------------------------------------------
* PLL_Q | 2
*-----------------------------------------------------------------------------
* PLL_R | 2
*-----------------------------------------------------------------------------
* Require 48MHz for RNG | Disabled
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* Copyright (c) 2019 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32g4xx_system
* @{
*/
/** @addtogroup STM32G4xx_System_Private_Includes
* @{
*/
#include "interfaces/arch_registers.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE 24000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Private_Defines
* @{
*/
/************************* Miscellaneous Configuration ************************/
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
// -- Begin patch --
// this was backported from an older version. Now this code seems to be
// moved in a function called HAL_something...
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M (HSE_VALUE/4000000)
/* SYSCLK = PLL_VCO / PLL_P */
#ifdef SYSCLK_FREQ_170MHz
#define PLL_N 85
#define PLL_R 2
#elif SYSCLK_FREQ_100MHz
#define PLL_N 50
#define PLL_R 2
#elif SYSCLK_FREQ_84MHz
#define PLL_N 84
#define PLL_R 4
#else
#error Clock not selected
#endif
/******************************************************************************/
// -- End patch --
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
#ifdef SYSCLK_FREQ_170MHz
uint32_t SystemCoreClock = 170000000;
#elif SYSCLK_FREQ_100MHz
uint32_t SystemCoreClock = 100000000;
#elif SYSCLK_FREQ_84MHz
uint32_t SystemCoreClock = 84000000;
#else
#error No clock defined
#endif
const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Private_FunctionPrototypes
* @{
*/
static void SetSysClock(void);
/**
* @}
*/
/** @addtogroup STM32G4xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2))); /* set CP10 and CP11 Full Access */
#endif
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set HSION bit */
RCC->CR = RCC_CR_HSION;
/* Set HSI as clock source */
RCC->CFGR = 0x00000001;
RCC->PLLCFGR = RCC_PLLCFGR_PLLN_4;
/* Disable all interrupts */
RCC->CIER = 0x00000000;
/* Clear all interrupt flags */
RCC->CICR = 0xFFFFFFFF;
/* Configure the System clock source, PLL Multiplier and Divider factors,
AHB/APBx prescalers and Flash settings ----------------------------------*/
SetSysClock();
/* Configure the Vector Table location add offset address ------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (**) HSI_VALUE is a constant defined in stm32g4xx_hal.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32g4xx_hal.h file (default value
* 24 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp, pllvco, pllr, pllsource, pllm;
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case 0x04: /* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x08: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x0C: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4) + 1U ;
if (pllsource == 0x02UL) /* HSI used as PLL clock source */
{
pllvco = (HSI_VALUE / pllm);
}
else /* HSE used as PLL clock source */
{
pllvco = (HSE_VALUE / pllm);
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * 2U;
SystemCoreClock = pllvco/pllr;
break;
default:
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK clock frequency */
SystemCoreClock >>= tmp;
}
// -- Begin patch --
// this was backported from an older version. Now this code seems to be
// moved in a function called HAL_something...
static void SetSysClock(void)
{
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != 0x500));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
RCC_SYNC();
PWR->CR1 |= PWR_CR1_VOS;
/* HCLK = SYSCLK */
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= RCC_CFGR_PPRE1_DIV1;
/* Configure the main PLL */
RCC->PLLCFGR = RCC_PLLCFGR_PLLSRC_HSE
| ((PLL_M - 1) << 4)
| (PLL_N << 8)
| RCC_PLLCFGR_PLLREN
| (((PLL_R >> 1) - 1) << 25);
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0) { }
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_ICEN
| FLASH_ACR_DCEN
#ifdef SYSCLK_FREQ_170MHz
| FLASH_ACR_LATENCY_4WS;
#elif SYSCLK_FREQ_100MHz
| FLASH_ACR_LATENCY_3WS;
#elif SYSCLK_FREQ_84MHz
| FLASH_ACR_LATENCY_2WS;
#endif
/* Select the main PLL as system clock source */
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL) { }
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
// -- End patch --
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

Wyświetl plik

@ -0,0 +1,12 @@
#ifndef ARCH_REGISTERS_IMPL_H
#define ARCH_REGISTERS_IMPL_H
//Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency
#include "stm32g4xx.h"
#include "core_cm4.h"
#include "system_stm32g4xx.h"
#define RCC_SYNC() //Workaround for a bug in stm32f42x
#endif //ARCH_REGISTERS_IMPL_H

Wyświetl plik

@ -0,0 +1,79 @@
/***************************************************************************
* Copyright (C) 2024 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN *
* Frederik Saraci IU2NRO *
* Silvano Seva IU2KWO *
* Federico Terraneo *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
/***********************************************************************
* bsp.cpp Part of the Miosix Embedded OS.
* Board support package, this file initializes hardware.
************************************************************************/
#include <interfaces/bsp.h>
#include <kernel/kernel.h>
#include <kernel/sync.h>
#include <hwconfig.h>
namespace miosix
{
//
// Initialization
//
void IRQbspInit()
{
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_GPIOBEN |
RCC_AHB2ENR_GPIOCEN | RCC_AHB2ENR_GPIODEN |
RCC_AHB2ENR_GPIOEEN | RCC_AHB2ENR_GPIOFEN |
RCC_AHB2ENR_GPIOGEN;
RCC_SYNC();
GPIOA->OSPEEDR=0xaaaaaaaa; //Default to 50MHz speed for all GPIOS
GPIOB->OSPEEDR=0xaaaaaaaa;
GPIOC->OSPEEDR=0xaaaaaaaa;
GPIOD->OSPEEDR=0xaaaaaaaa;
GPIOE->OSPEEDR=0xaaaaaaaa;
GPIOF->OSPEEDR=0xaaaaaaaa;
GPIOG->OSPEEDR=0xaaaaaaaa;
// Configure SysTick
SysTick->LOAD = SystemCoreClock / miosix::TICK_FREQ;
}
void bspInit2()
{
}
//
// Shutdown and reboot
//
void shutdown()
{
reboot();
}
void reboot()
{
disableInterrupts();
miosix_private::IRQsystemReboot();
}
} //namespace miosix

Wyświetl plik

@ -0,0 +1,60 @@
/***************************************************************************
* Copyright (C) 2024 by Silvano Seva IU2KWO *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <stdio.h>
#include <reent.h>
#include "filesystem/file_access.h"
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \internal
* _write_r, write to a file
*/
int _write_r(struct _reent *ptr, int fd, const void *buf, size_t cnt)
{
(void) ptr;
(void) fd;
(void) buf;
(void) cnt;
ptr->_errno = EBADF;
return -1;
}
/**
* \internal
* _read_r, read from a file.
*/
int _read_r(struct _reent *ptr, int fd, void *buf, size_t cnt)
{
(void) ptr;
(void) fd;
(void) buf;
(void) cnt;
ptr->_errno = EBADF;
return -1;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,448 @@
/***************************************************************************
* Copyright (C) 2024 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN *
* Frederik Saraci IU2NRO *
* Silvano Seva IU2KWO *
* Federico Terraneo *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "interfaces/arch_registers.h"
#include "kernel/stage_2_boot.h"
#include "core/interrupts.h"
#include <string.h>
/**
* Called by Reset_Handler, performs initialization and calls main.
* Never returns.
*/
void program_startup() __attribute__((noreturn));
void program_startup()
{
//Cortex M4 core appears to get out of reset with interrupts already enabled
__disable_irq();
//SystemInit() is called *before* initializing .data and zeroing .bss
//Despite all startup files provided by ST do the opposite, there are three
//good reasons to do so:
//First, the CMSIS specifications say that SystemInit() must not access
//global variables, so it is actually possible to call it before
//Second, when running Miosix with the xram linker scripts .data and .bss
//are placed in the external RAM, so we *must* call SystemInit(), which
//enables xram, before touching .data and .bss
//Third, this is a performance improvement since the loops that initialize
//.data and zeros .bss now run with the CPU at full speed instead of 8MHz
SystemInit();
//These are defined in the linker script
extern unsigned char _etext asm("_etext");
extern unsigned char _data asm("_data");
extern unsigned char _edata asm("_edata");
extern unsigned char _bss_start asm("_bss_start");
extern unsigned char _bss_end asm("_bss_end");
//Initialize .data section, clear .bss section
unsigned char *etext=&_etext;
unsigned char *data=&_data;
unsigned char *edata=&_edata;
unsigned char *bss_start=&_bss_start;
unsigned char *bss_end=&_bss_end;
memcpy(data, etext, edata-data);
memset(bss_start, 0, bss_end-bss_start);
//Move on to stage 2
_init();
//If main returns, reboot
NVIC_SystemReset();
for(;;) ;
}
/**
* Reset handler, called by hardware immediately after reset
*/
void Reset_Handler() __attribute__((__interrupt__, noreturn));
void Reset_Handler()
{
/*
* Initialize process stack and switch to it.
* This is required for booting Miosix, a small portion of the top of the
* heap area will be used as stack until the first thread starts. After,
* this stack will be abandoned and the process stack will point to the
* current thread's stack.
*/
asm volatile("ldr r0, =_heap_end \n\t"
"msr psp, r0 \n\t"
"movw r0, #2 \n\n" //Privileged, process stack
"msr control, r0 \n\t"
"isb \n\t":::"r0");
program_startup();
}
/**
* All unused interrupts call this function.
*/
extern "C" void Default_Handler()
{
unexpectedInterrupt();
}
//System handlers
void /*__attribute__((weak))*/ Reset_Handler(); //These interrupts are not
void /*__attribute__((weak))*/ NMI_Handler(); //weak because they are
void /*__attribute__((weak))*/ HardFault_Handler(); //surely defined by Miosix
void /*__attribute__((weak))*/ MemManage_Handler();
void /*__attribute__((weak))*/ BusFault_Handler();
void /*__attribute__((weak))*/ UsageFault_Handler();
void /*__attribute__((weak))*/ SVC_Handler();
void /*__attribute__((weak))*/ DebugMon_Handler();
void /*__attribute__((weak))*/ PendSV_Handler();
void /*__attribute__((weak))*/ SysTick_Handler();
//Interrupt handlers
void __attribute__((weak)) WWDG_IRQHandler();
void __attribute__((weak)) PVD_PVM_IRQHandler();
void __attribute__((weak)) RTC_TAMP_LSECSS_IRQHandler();
void __attribute__((weak)) RTC_WKUP_IRQHandler();
void __attribute__((weak)) FLASH_IRQHandler();
void __attribute__((weak)) RCC_IRQHandler();
void __attribute__((weak)) EXTI0_IRQHandler();
void __attribute__((weak)) EXTI1_IRQHandler();
void __attribute__((weak)) EXTI2_IRQHandler();
void __attribute__((weak)) EXTI3_IRQHandler();
void __attribute__((weak)) EXTI4_IRQHandler();
void __attribute__((weak)) DMA1_Channel1_IRQHandler();
void __attribute__((weak)) DMA1_Channel2_IRQHandler();
void __attribute__((weak)) DMA1_Channel3_IRQHandler();
void __attribute__((weak)) DMA1_Channel4_IRQHandler();
void __attribute__((weak)) DMA1_Channel5_IRQHandler();
void __attribute__((weak)) DMA1_Channel6_IRQHandler();
void __attribute__((weak)) DMA1_Channel7_IRQHandler();
void __attribute__((weak)) ADC1_2_IRQHandler();
void __attribute__((weak)) USB_HP_IRQHandler();
void __attribute__((weak)) USB_LP_IRQHandler();
void __attribute__((weak)) FDCAN1_IT0_IRQHandler();
void __attribute__((weak)) FDCAN1_IT1_IRQHandler();
void __attribute__((weak)) EXTI9_5_IRQHandler();
void __attribute__((weak)) TIM1_BRK_TIM15_IRQHandler();
void __attribute__((weak)) TIM1_UP_TIM16_IRQHandler();
void __attribute__((weak)) TIM1_TRG_COM_TIM17_IRQHandler();
void __attribute__((weak)) TIM1_CC_IRQHandler();
void __attribute__((weak)) TIM2_IRQHandler();
void __attribute__((weak)) TIM3_IRQHandler();
void __attribute__((weak)) TIM4_IRQHandler();
void __attribute__((weak)) I2C1_EV_IRQHandler();
void __attribute__((weak)) I2C1_ER_IRQHandler();
void __attribute__((weak)) I2C2_EV_IRQHandler();
void __attribute__((weak)) I2C2_ER_IRQHandler();
void __attribute__((weak)) SPI1_IRQHandler();
void __attribute__((weak)) SPI2_IRQHandler();
void __attribute__((weak)) USART1_IRQHandler();
void __attribute__((weak)) USART2_IRQHandler();
void __attribute__((weak)) USART3_IRQHandler();
void __attribute__((weak)) EXTI15_10_IRQHandler();
void __attribute__((weak)) RTC_Alarm_IRQHandler();
void __attribute__((weak)) USBWakeUp_IRQHandler();
void __attribute__((weak)) TIM8_BRK_IRQHandler();
void __attribute__((weak)) TIM8_UP_IRQHandler();
void __attribute__((weak)) TIM8_TRG_COM_IRQHandler();
void __attribute__((weak)) TIM8_CC_IRQHandler();
void __attribute__((weak)) ADC3_IRQHandler();
void __attribute__((weak)) FMC_IRQHandler();
void __attribute__((weak)) LPTIM1_IRQHandler();
void __attribute__((weak)) TIM5_IRQHandler();
void __attribute__((weak)) SPI3_IRQHandler();
void __attribute__((weak)) UART4_IRQHandler();
void __attribute__((weak)) UART5_IRQHandler();
void __attribute__((weak)) TIM6_DAC_IRQHandler();
void __attribute__((weak)) TIM7_DAC_IRQHandler();
void __attribute__((weak)) DMA2_Channel1_IRQHandler();
void __attribute__((weak)) DMA2_Channel2_IRQHandler();
void __attribute__((weak)) DMA2_Channel3_IRQHandler();
void __attribute__((weak)) DMA2_Channel4_IRQHandler();
void __attribute__((weak)) DMA2_Channel5_IRQHandler();
void __attribute__((weak)) ADC4_IRQHandler();
void __attribute__((weak)) ADC5_IRQHandler();
void __attribute__((weak)) UCPD1_IRQHandler();
void __attribute__((weak)) COMP1_2_3_IRQHandler();
void __attribute__((weak)) COMP4_5_6_IRQHandler();
void __attribute__((weak)) COMP7_IRQHandler();
void __attribute__((weak)) HRTIM1_Master_IRQHandler();
void __attribute__((weak)) HRTIM1_TIMA_IRQHandler();
void __attribute__((weak)) HRTIM1_TIMB_IRQHandler();
void __attribute__((weak)) HRTIM1_TIMC_IRQHandler();
void __attribute__((weak)) HRTIM1_TIMD_IRQHandler();
void __attribute__((weak)) HRTIM1_TIME_IRQHandler();
void __attribute__((weak)) HRTIM1_FLT_IRQHandler();
void __attribute__((weak)) HRTIM1_TIMF_IRQHandler();
void __attribute__((weak)) CRS_IRQHandler();
void __attribute__((weak)) SAI1_IRQHandler();
void __attribute__((weak)) TIM20_BRK_IRQHandler();
void __attribute__((weak)) TIM20_UP_IRQHandler();
void __attribute__((weak)) TIM20_TRG_COM_IRQHandler();
void __attribute__((weak)) TIM20_CC_IRQHandler();
void __attribute__((weak)) FPU_IRQHandler();
void __attribute__((weak)) I2C4_EV_IRQHandler();
void __attribute__((weak)) I2C4_ER_IRQHandler();
void __attribute__((weak)) SPI4_IRQHandler();
void __attribute__((weak)) FDCAN2_IT0_IRQHandler();
void __attribute__((weak)) FDCAN2_IT1_IRQHandler();
void __attribute__((weak)) FDCAN3_IT0_IRQHandler();
void __attribute__((weak)) FDCAN3_IT1_IRQHandler();
void __attribute__((weak)) RNG_IRQHandler();
void __attribute__((weak)) LPUART1_IRQHandler();
void __attribute__((weak)) I2C3_EV_IRQHandler();
void __attribute__((weak)) I2C3_ER_IRQHandler();
void __attribute__((weak)) DMAMUX_OVR_IRQHandler();
void __attribute__((weak)) QUADSPI_IRQHandler();
void __attribute__((weak)) DMA1_Channel8_IRQHandler();
void __attribute__((weak)) DMA2_Channel6_IRQHandler();
void __attribute__((weak)) DMA2_Channel7_IRQHandler();
void __attribute__((weak)) DMA2_Channel8_IRQHandler();
void __attribute__((weak)) CORDIC_IRQHandler();
void __attribute__((weak)) FMAC_IRQHandler();
//Stack top, defined in the linker script
extern char _main_stack_top asm("_main_stack_top");
//Interrupt vectors, must be placed @ address 0x00000000
//The extern declaration is required otherwise g++ optimizes it out
extern void (* const __Vectors[])();
void (* const __Vectors[])() __attribute__ ((section(".isr_vector"))) =
{
reinterpret_cast<void (*)()>(&_main_stack_top),/* Stack pointer*/
Reset_Handler, /* Reset Handler */
NMI_Handler, /* NMI Handler */
HardFault_Handler, /* Hard Fault Handler */
MemManage_Handler, /* MPU Fault Handler */
BusFault_Handler, /* Bus Fault Handler */
UsageFault_Handler, /* Usage Fault Handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
SVC_Handler, /* SVCall Handler */
DebugMon_Handler, /* Debug Monitor Handler */
0, /* Reserved */
PendSV_Handler, /* PendSV Handler */
SysTick_Handler, /* SysTick Handler */
/* External Interrupts */
WWDG_IRQHandler,
PVD_PVM_IRQHandler,
RTC_TAMP_LSECSS_IRQHandler,
RTC_WKUP_IRQHandler,
FLASH_IRQHandler,
RCC_IRQHandler,
EXTI0_IRQHandler,
EXTI1_IRQHandler,
EXTI2_IRQHandler,
EXTI3_IRQHandler,
EXTI4_IRQHandler,
DMA1_Channel1_IRQHandler,
DMA1_Channel2_IRQHandler,
DMA1_Channel3_IRQHandler,
DMA1_Channel4_IRQHandler,
DMA1_Channel5_IRQHandler,
DMA1_Channel6_IRQHandler,
DMA1_Channel7_IRQHandler,
ADC1_2_IRQHandler,
USB_HP_IRQHandler,
USB_LP_IRQHandler,
FDCAN1_IT0_IRQHandler,
FDCAN1_IT1_IRQHandler,
EXTI9_5_IRQHandler,
TIM1_BRK_TIM15_IRQHandler,
TIM1_UP_TIM16_IRQHandler,
TIM1_TRG_COM_TIM17_IRQHandler,
TIM1_CC_IRQHandler,
TIM2_IRQHandler,
TIM3_IRQHandler,
TIM4_IRQHandler,
I2C1_EV_IRQHandler,
I2C1_ER_IRQHandler,
I2C2_EV_IRQHandler,
I2C2_ER_IRQHandler,
SPI1_IRQHandler,
SPI2_IRQHandler,
USART1_IRQHandler,
USART2_IRQHandler,
USART3_IRQHandler,
EXTI15_10_IRQHandler,
RTC_Alarm_IRQHandler,
USBWakeUp_IRQHandler,
TIM8_BRK_IRQHandler,
TIM8_UP_IRQHandler,
TIM8_TRG_COM_IRQHandler,
TIM8_CC_IRQHandler,
ADC3_IRQHandler,
FMC_IRQHandler,
LPTIM1_IRQHandler,
TIM5_IRQHandler,
SPI3_IRQHandler,
UART4_IRQHandler,
UART5_IRQHandler,
TIM6_DAC_IRQHandler,
TIM7_DAC_IRQHandler,
DMA2_Channel1_IRQHandler,
DMA2_Channel2_IRQHandler,
DMA2_Channel3_IRQHandler,
DMA2_Channel4_IRQHandler,
DMA2_Channel5_IRQHandler,
ADC4_IRQHandler,
ADC5_IRQHandler,
UCPD1_IRQHandler,
COMP1_2_3_IRQHandler,
COMP4_5_6_IRQHandler,
COMP7_IRQHandler,
HRTIM1_Master_IRQHandler,
HRTIM1_TIMA_IRQHandler,
HRTIM1_TIMB_IRQHandler,
HRTIM1_TIMC_IRQHandler,
HRTIM1_TIMD_IRQHandler,
HRTIM1_TIME_IRQHandler,
HRTIM1_FLT_IRQHandler,
HRTIM1_TIMF_IRQHandler,
CRS_IRQHandler,
SAI1_IRQHandler,
TIM20_BRK_IRQHandler,
TIM20_UP_IRQHandler,
TIM20_TRG_COM_IRQHandler,
TIM20_CC_IRQHandler,
FPU_IRQHandler,
I2C4_EV_IRQHandler,
I2C4_ER_IRQHandler,
SPI4_IRQHandler,
0,
FDCAN2_IT0_IRQHandler,
FDCAN2_IT1_IRQHandler,
FDCAN3_IT0_IRQHandler,
FDCAN3_IT1_IRQHandler,
RNG_IRQHandler,
LPUART1_IRQHandler,
I2C3_EV_IRQHandler,
I2C3_ER_IRQHandler,
DMAMUX_OVR_IRQHandler,
QUADSPI_IRQHandler,
DMA1_Channel8_IRQHandler,
DMA2_Channel6_IRQHandler,
DMA2_Channel7_IRQHandler,
DMA2_Channel8_IRQHandler,
CORDIC_IRQHandler,
FMAC_IRQHandler,
};
#pragma weak WWDG_IRQHandler = Default_Handler
#pragma weak PVD_PVM_IRQHandler = Default_Handler
#pragma weak RTC_TAMP_LSECSS_IRQHandler = Default_Handler
#pragma weak RTC_WKUP_IRQHandler = Default_Handler
#pragma weak FLASH_IRQHandler = Default_Handler
#pragma weak RCC_IRQHandler = Default_Handler
#pragma weak EXTI0_IRQHandler = Default_Handler
#pragma weak EXTI1_IRQHandler = Default_Handler
#pragma weak EXTI2_IRQHandler = Default_Handler
#pragma weak EXTI3_IRQHandler = Default_Handler
#pragma weak EXTI4_IRQHandler = Default_Handler
#pragma weak DMA1_Channel1_IRQHandler = Default_Handler
#pragma weak DMA1_Channel2_IRQHandler = Default_Handler
#pragma weak DMA1_Channel3_IRQHandler = Default_Handler
#pragma weak DMA1_Channel4_IRQHandler = Default_Handler
#pragma weak DMA1_Channel5_IRQHandler = Default_Handler
#pragma weak DMA1_Channel6_IRQHandler = Default_Handler
#pragma weak DMA1_Channel7_IRQHandler = Default_Handler
#pragma weak ADC1_2_IRQHandler = Default_Handler
#pragma weak USB_HP_IRQHandler = Default_Handler
#pragma weak USB_LP_IRQHandler = Default_Handler
#pragma weak FDCAN1_IT0_IRQHandler = Default_Handler
#pragma weak FDCAN1_IT1_IRQHandler = Default_Handler
#pragma weak EXTI9_5_IRQHandler = Default_Handler
#pragma weak TIM1_BRK_TIM15_IRQHandler = Default_Handler
#pragma weak TIM1_UP_TIM16_IRQHandler = Default_Handler
#pragma weak TIM1_TRG_COM_TIM17_IRQHandler = Default_Handler
#pragma weak TIM1_CC_IRQHandler = Default_Handler
#pragma weak TIM2_IRQHandler = Default_Handler
#pragma weak TIM3_IRQHandler = Default_Handler
#pragma weak TIM4_IRQHandler = Default_Handler
#pragma weak I2C1_EV_IRQHandler = Default_Handler
#pragma weak I2C1_ER_IRQHandler = Default_Handler
#pragma weak I2C2_EV_IRQHandler = Default_Handler
#pragma weak I2C2_ER_IRQHandler = Default_Handler
#pragma weak SPI1_IRQHandler = Default_Handler
#pragma weak SPI2_IRQHandler = Default_Handler
#pragma weak USART1_IRQHandler = Default_Handler
#pragma weak USART2_IRQHandler = Default_Handler
#pragma weak USART3_IRQHandler = Default_Handler
#pragma weak EXTI15_10_IRQHandler = Default_Handler
#pragma weak RTC_Alarm_IRQHandler = Default_Handler
#pragma weak USBWakeUp_IRQHandler = Default_Handler
#pragma weak TIM8_BRK_IRQHandler = Default_Handler
#pragma weak TIM8_UP_IRQHandler = Default_Handler
#pragma weak TIM8_TRG_COM_IRQHandler = Default_Handler
#pragma weak TIM8_CC_IRQHandler = Default_Handler
#pragma weak ADC3_IRQHandler = Default_Handler
#pragma weak FMC_IRQHandler = Default_Handler
#pragma weak LPTIM1_IRQHandler = Default_Handler
#pragma weak TIM5_IRQHandler = Default_Handler
#pragma weak SPI3_IRQHandler = Default_Handler
#pragma weak UART4_IRQHandler = Default_Handler
#pragma weak UART5_IRQHandler = Default_Handler
#pragma weak TIM6_DAC_IRQHandler = Default_Handler
#pragma weak TIM7_DAC_IRQHandler = Default_Handler
#pragma weak DMA2_Channel1_IRQHandler = Default_Handler
#pragma weak DMA2_Channel2_IRQHandler = Default_Handler
#pragma weak DMA2_Channel3_IRQHandler = Default_Handler
#pragma weak DMA2_Channel4_IRQHandler = Default_Handler
#pragma weak DMA2_Channel5_IRQHandler = Default_Handler
#pragma weak ADC4_IRQHandler = Default_Handler
#pragma weak ADC5_IRQHandler = Default_Handler
#pragma weak UCPD1_IRQHandler = Default_Handler
#pragma weak COMP1_2_3_IRQHandler = Default_Handler
#pragma weak COMP4_5_6_IRQHandler = Default_Handler
#pragma weak COMP7_IRQHandler = Default_Handler
#pragma weak HRTIM1_Master_IRQHandler = Default_Handler
#pragma weak HRTIM1_TIMA_IRQHandler = Default_Handler
#pragma weak HRTIM1_TIMB_IRQHandler = Default_Handler
#pragma weak HRTIM1_TIMC_IRQHandler = Default_Handler
#pragma weak HRTIM1_TIMD_IRQHandler = Default_Handler
#pragma weak HRTIM1_TIME_IRQHandler = Default_Handler
#pragma weak HRTIM1_FLT_IRQHandler = Default_Handler
#pragma weak HRTIM1_TIMF_IRQHandler = Default_Handler
#pragma weak CRS_IRQHandler = Default_Handler
#pragma weak SAI1_IRQHandler = Default_Handler
#pragma weak TIM20_BRK_IRQHandler = Default_Handler
#pragma weak TIM20_UP_IRQHandler = Default_Handler
#pragma weak TIM20_TRG_COM_IRQHandler = Default_Handler
#pragma weak TIM20_CC_IRQHandler = Default_Handler
#pragma weak FPU_IRQHandler = Default_Handler
#pragma weak I2C4_EV_IRQHandler = Default_Handler
#pragma weak I2C4_ER_IRQHandler = Default_Handler
#pragma weak SPI4_IRQHandler = Default_Handler
#pragma weak FDCAN2_IT0_IRQHandler = Default_Handler
#pragma weak FDCAN2_IT1_IRQHandler = Default_Handler
#pragma weak FDCAN3_IT0_IRQHandler = Default_Handler
#pragma weak FDCAN3_IT1_IRQHandler = Default_Handler
#pragma weak RNG_IRQHandler = Default_Handler
#pragma weak LPUART1_IRQHandler = Default_Handler
#pragma weak I2C3_EV_IRQHandler = Default_Handler
#pragma weak I2C3_ER_IRQHandler = Default_Handler
#pragma weak DMAMUX_OVR_IRQHandler = Default_Handler
#pragma weak QUADSPI_IRQHandler = Default_Handler
#pragma weak DMA1_Channel8_IRQHandler = Default_Handler
#pragma weak DMA2_Channel6_IRQHandler = Default_Handler
#pragma weak DMA2_Channel7_IRQHandler = Default_Handler
#pragma weak DMA2_Channel8_IRQHandler = Default_Handler
#pragma weak CORDIC_IRQHandler = Default_Handler
#pragma weak FMAC_IRQHandler = Default_Handler

Wyświetl plik

@ -0,0 +1,94 @@
/***************************************************************************
* Copyright (C) 2024 by Silvano Seva IU2KWO *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <interfaces/delays.h>
#include <miosix.h>
/**
* Implementation of the delay functions for STM32G474 MCU.
*/
void delayMs(unsigned int mseconds)
{
#ifdef SYSCLK_FREQ_170MHz
register const unsigned int count=42500;
#elif SYSCLK_FREQ_100MHz
register const unsigned int count=25000;
#elif SYSCLK_FREQ_84MHz
register const unsigned int count=21000;
#else
#warning "Delays are uncalibrated for this clock frequency"
#endif
for(unsigned int i=0;i<mseconds;i++)
{
// This delay has been calibrated to take 1 millisecond
// It is written in assembler to be independent on compiler optimization
asm volatile(" mov r1, #0 \n"
"___loop_m: cmp r1, %0 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_m \n"::"r"(count):"r1");
}
}
void delayUs(unsigned int useconds)
{
// This delay has been calibrated to take x microseconds
// It is written in assembler to be independent on compiler optimization
#ifdef SYSCLK_FREQ_170MHz
asm volatile(" mov r1, #43 \n"
" mul r2, %0, r1 \n"
" mov r1, #0 \n"
"___loop_u: cmp r1, r2 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_u \n"::"r"(useconds):"r1","r2");
#elif defined(SYSCLK_FREQ_100MHz)
asm volatile(" mov r1, #25 \n"
" mul r2, %0, r1 \n"
" mov r1, #0 \n"
"___loop_u: cmp r1, r2 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_u \n"::"r"(useconds):"r1","r2");
#else //SYSCLK_FREQ_84MHz
asm volatile(" mov r1, #21 \n"
" mul r2, %0, r1 \n"
" mov r1, #0 \n"
"___loop_u: cmp r1, r2 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_u \n"::"r"(useconds):"r1","r2");
#endif
}
void sleepFor(unsigned int seconds, unsigned int mseconds)
{
unsigned int time = (seconds * 1000) + mseconds;
miosix::Thread::sleep(time);
}
void sleepUntil(long long timestamp)
{
miosix::Thread::sleepUntil(timestamp);
}
long long getTick()
{
return miosix::getTick();
}

Wyświetl plik

@ -0,0 +1,137 @@
/***************************************************************************
* Copyright (C) 2020 - 2024 by Silvano Seva IU2KWO *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <peripherals/gpio.h>
#include "stm32g4xx.h"
void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
{
GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
p->MODER &= ~(3 << (pin*2));
p->OTYPER &= ~(1 << pin);
p->PUPDR &= ~(3 << (pin*2));
switch(mode)
{
case INPUT:
// (MODE=00 TYPE=0 PUP=00)
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case INPUT_PULL_UP:
// (MODE=00 TYPE=0 PUP=01)
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x01 << (pin*2);
break;
case INPUT_PULL_DOWN:
// (MODE=00 TYPE=0 PUP=10)
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x02 << (pin*2);
break;
case INPUT_ANALOG:
// (MODE=11 TYPE=0 PUP=00)
p->MODER |= 0x03 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case OUTPUT:
// (MODE=01 TYPE=0 PUP=00)
p->MODER |= 0x01 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case OPEN_DRAIN:
// (MODE=01 TYPE=1 PUP=00)
p->MODER |= 0x01 << (pin*2);
p->OTYPER |= 0x01 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case ALTERNATE:
// (MODE=10 TYPE=0 PUP=00)
p->MODER |= 0x02 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
case ALTERNATE_OD:
// (MODE=10 TYPE=1 PUP=00)
p->MODER |= 0x02 << (pin*2);
p->OTYPER |= 0x01 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
default:
// Default to INPUT mode
p->MODER |= 0x00 << (pin*2);
p->OTYPER |= 0x00 << pin;
p->PUPDR |= 0x00 << (pin*2);
break;
}
}
void gpio_setAlternateFunction(void *port, uint8_t pin, uint8_t afNum)
{
GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
afNum &= 0x0F;
if(pin < 8)
{
p->AFR[0] &= ~(0x0F << (pin*4));
p->AFR[0] |= (afNum << (pin*4));
}
else
{
pin -= 8;
p->AFR[1] &= ~(0x0F << (pin*4));
p->AFR[1] |= (afNum << (pin*4));
}
}
void gpio_setOutputSpeed(void *port, uint8_t pin, enum Speed spd)
{
((GPIO_TypeDef *)(port))->OSPEEDR &= ~(3 << (pin*2)); // Clear old value
((GPIO_TypeDef *)(port))->OSPEEDR |= spd << (pin*2); // Set new value
}
void gpio_setPin(void *port, uint8_t pin)
{
((GPIO_TypeDef *)(port))->BSRR = (1 << pin);
}
void gpio_clearPin(void *port, uint8_t pin)
{
((GPIO_TypeDef *)(port))->BSRR = (1 << (pin + 16));
}
void gpio_togglePin(void *port, uint8_t pin)
{
((GPIO_TypeDef *)(port))->ODR ^= (1 << pin);
}
uint8_t gpio_readPin(const void *port, uint8_t pin)
{
GPIO_TypeDef *p = (GPIO_TypeDef *)(port);
return ((p->IDR & (1 << pin)) != 0) ? 1 : 0;
}

Wyświetl plik

@ -0,0 +1,177 @@
/*
* C++ enabled linker script for stm32 (512k FLASH, 32+96k RAM)
* Developed by TFT: Terraneo Federico Technologies
* Optimized for use with the Miosix kernel
*/
/*
* This chip has an unusual quirk that the RAM is divided in two block mapped
* at two non contiguous memory addresses. I don't know why they've done that,
* probably doing the obvious thing would have made writing code too easy...
* Anyway, since hardware can't be changed, we've got to live with that and
* try to make use of both RAMs.
*
* Given the constraints above, this linker script puts:
* - read only data and code (.text, .rodata, .eh_*) in FLASH
* - the 512Byte main (IRQ) stack, .data and .bss in the "small" 32KB RAM
* - stacks and heap in the "large" 96KB RAM.
*/
/*
* The main stack is used for interrupt handling by the kernel.
*
* *** Readme ***
* This linker script places the main stack (used by the kernel for interrupts)
* at the bottom of the ram, instead of the top. This is done for two reasons:
*
* - as an optimization for microcontrollers with little ram memory. In fact
* the implementation of malloc from newlib requests memory to the OS in 4KB
* block (except the first block that can be smaller). This is probably done
* for compatibility with OSes with an MMU and paged memory. To see why this
* is bad, consider a microcontroller with 8KB of ram: when malloc finishes
* up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will
* fail because the top part of the ram is used by the main stack. As a
* result, the top part of the memory will not be used by malloc, even if
* available (and it is nearly *half* the ram on an 8KB mcu). By placing the
* main stack at the bottom of the ram, the upper 4KB block will be entirely
* free and available as heap space.
*
* - In case of main stack overflow the cpu will fault because access to memory
* before the beginning of the ram faults. Instead with the default stack
* placement the main stack will silently collide with the heap.
* Note: if increasing the main stack size also increase the ORIGIN value in
* the MEMORY definitions below accordingly.
*/
_main_stack_size = 0x00000200; /* main stack = 512Bytes */
_main_stack_top = 0x10000000 + _main_stack_size;
ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error");
/* Mapping the heap into the large 96KB RAM */
_end = 0x20000000;
_heap_end = 0x20018000; /* end of available ram */
/* identify the Entry Point */
ENTRY(_Z13Reset_Handlerv)
/* specify the memory areas */
MEMORY
{
flash(rx) : ORIGIN = 0x08000000, LENGTH = 512K
/*
* Note, the small ram starts at 0x10000000 but it is necessary to add the
* size of the main stack, so it is 0x10000200.
*/
smallram(wx) : ORIGIN = 0x10000200, LENGTH = 32K-0x200
largeram(wx) : ORIGIN = 0x20000000, LENGTH = 96K
}
/* now define the output sections */
SECTIONS
{
. = 0;
/* .text section: code goes to flash */
.text :
{
/* Startup code must go at address 0 */
KEEP(*(.isr_vector))
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
/* these sections for thumb interwork? */
*(.glue_7)
*(.glue_7t)
/* these sections for C++? */
*(.gcc_except_table)
*(.gcc_except_table.*)
*(.ARM.extab*)
*(.gnu.linkonce.armextab.*)
. = ALIGN(4);
/* .rodata: constant data */
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
/* C++ Static constructors/destructors (eabi) */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__miosix_init_array_start = .;
KEEP (*(SORT(.miosix_init_array.*)))
KEEP (*(.miosix_init_array))
__miosix_init_array_end = .;
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
/* C++ Static constructors/destructors (elf) */
. = ALIGN(4);
_ctor_start = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
_ctor_end = .;
. = ALIGN(4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
} > flash
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
/* .data section: global variables go to ram, but also store a copy to
flash to initialize them */
.data : ALIGN(8)
{
_data = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
_edata = .;
} > smallram AT > flash
_etext = LOADADDR(.data);
/* .bss section: uninitialized global variables go to ram */
_bss_start = .;
.bss :
{
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
. = ALIGN(8);
} > smallram
_bss_end = .;
/*_end = .;*/
/*PROVIDE(end = .);*/
}