kopia lustrzana https://github.com/OpenRTX/OpenRTX
Boot code for STM32G474 MCU
rodzic
81f9257888
commit
de93cb7bc0
18
meson.build
18
meson.build
|
@ -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
|
||||
##
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -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 peripheral’s drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral’s 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 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
@ -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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
|
@ -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 --
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 = .);*/
|
||||
}
|
Ładowanie…
Reference in New Issue