From 1f66e33b4a33a210b243a32a838f21a830b16389 Mon Sep 17 00:00:00 2001 From: Alberto Nidasio <alberto.nidasio@skywarder.eu> Date: Fri, 9 Dec 2022 20:21:40 +0100 Subject: [PATCH] Added port for stm32f769ni_discovery --- Makefile | 16 +- miosix/Makefile | 27 +- .../Source/Templates/system_stm32f7xx.c | 53 +- .../core/stage_1_boot.cpp | 479 ++++++++++++++++++ .../interfaces-impl/arch_registers_impl.h | 17 + .../interfaces-impl/bsp.cpp | 287 +++++++++++ .../interfaces-impl/bsp_impl.h | 105 ++++ .../stm32_2m+16m_xram.ld | 179 +++++++ .../stm32_2m+384k_ram.ld | 178 +++++++ miosix/config/Makefile.inc | 43 +- .../stm32f769ni_discovery/board_settings.h | 73 +++ miosix/config/boards.cmake | 1 + miosix/config/options.cmake | 43 +- 13 files changed, 1443 insertions(+), 58 deletions(-) create mode 100644 miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp create mode 100644 miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/arch_registers_impl.h create mode 100644 miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp create mode 100644 miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp_impl.h create mode 100644 miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+16m_xram.ld create mode 100644 miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+384k_ram.ld create mode 100644 miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h diff --git a/Makefile b/Makefile index ac00c36f..1d5d4bce 100644 --- a/Makefile +++ b/Makefile @@ -11,14 +11,6 @@ KPATH := miosix CONFPATH := $(KPATH) include $(CONFPATH)/config/Makefile.inc -ifeq ("$(BUILD_VERBOSE)","1") -Q := @ -ECHO := @echo -else -Q := -ECHO := @true -endif - ## ## List here subdirectories which contains makefiles ## @@ -106,19 +98,19 @@ main: main.elf $(Q)$(SZ) main.elf main.elf: $(OBJ) all-recursive - $(ECHO) "[LD] main.elf" + $(ECHO) "[LD ] main.elf" $(Q)$(CXX) $(LFLAGS) -o main.elf $(OBJ) $(KPATH)/$(BOOT_FILE) $(LINK_LIBS) %.o: %.s - $(ECHO) "[AS] $<" + $(ECHO) "[AS ] $<" $(Q)$(AS) $(AFLAGS) $< -o $@ %.o : %.c - $(ECHO) "[CC] $<" + $(ECHO) "[CC ] $<" $(Q)$(CC) $(DFLAGS) $(CFLAGS) $< -o $@ %.o : %.cpp - $(ECHO) "[CXX] $<" + $(ECHO) "[CXX ] $<" $(Q)$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@ #pull in dependecy info for existing .o files diff --git a/miosix/Makefile b/miosix/Makefile index 31cd85e5..afb5aff8 100644 --- a/miosix/Makefile +++ b/miosix/Makefile @@ -9,14 +9,6 @@ GCCMAJOR := $(shell arm-miosix-eabi-gcc --version | \ ## KPATH and CONFPATH are forwarded by the parent Makefile include $(CONFPATH)/config/Makefile.inc -ifeq ("$(BUILD_VERBOSE)","1") -Q := -ECHO := @true -else -Q := @ -ECHO := @echo -endif - ## List of all Miosix OS source files that have no special requirements ## and that must be built for each architecture (both .c and .cpp) ## These files will end up in libmiosix.a @@ -68,7 +60,6 @@ Q := @ ECHO := @echo endif -BINDIR := bin/$(OPT_BOARD) ## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o" OBJ := $(addsuffix .o, $(basename $(SRC))) @@ -84,33 +75,27 @@ DFLAGS := -MMD -MP ## Build libmiosix.a and stage_1_boot.o (whose path is in BOOT_FILE) ## The file stage_1_boot.o is compiled separately because ## it must not end up in libmiosix.a -all: makedir $(OBJ) $(BOOT_FILE) +all: $(OBJ) $(BOOT_FILE) $(ECHO) "[PERL] Checking global objects" $(Q)perl _tools/kernel_global_objects.pl $(OBJ) $(ECHO) "[AR ] libmiosix.a" - $(Q)$(AR) rcs $(BINDIR)/libmiosix.a $(OBJ) - -makedir: - $(Q) mkdir -p $(BINDIR) + $(Q)$(AR) rcs libmiosix.a $(OBJ) clean: - -rm -f $(OBJ) $(BOOT_FILE) $(BINDIR)/libmiosix.a $(OBJ:.o=.d) + -rm -f $(OBJ) $(BOOT_FILE) libmiosix.a $(OBJ:.o=.d) -rm -f $(BOOT_FILE:.o=.d) %.o: %.s - $(ECHO) "[AS] $<" + $(ECHO) "[AS ] $<" $(Q)$(AS) $(AFLAGS) $< -o $@ %.o : %.c - $(ECHO) "[CC] $<" + $(ECHO) "[CC ] $<" $(Q)$(CC) $(DFLAGS) $(CFLAGS) $< -o $@ %.o : %.cpp - $(ECHO) "[CXX] $<" + $(ECHO) "[CXX ] $<" $(Q)$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@ #pull in dependecy info for existing .o files -include $(OBJ:.o=.d) - -.PHONY: clean makedir -.NOTPARALLEL: clean makedir diff --git a/miosix/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c b/miosix/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c index b8faf8a9..29c0603e 100644 --- a/miosix/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c +++ b/miosix/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c @@ -98,6 +98,22 @@ This value must be a multiple of 0x200. */ /******************************************************************************/ +// By Alberto Nidasio -- begin + +// Divide the input clock +#define PLL_M (HSE_VALUE/1000000) + +#ifdef SYSCLK_FREQ_216MHz +#define PLL_Q 9 +#define PLL_R 7 +#define PLL_N 432 +#define PLL_P 2 +#else +#error Clock not selected +#endif + +// By Alberto Nidasio -- end + /** * @} */ @@ -237,7 +253,7 @@ void SystemInit(void) */ void SystemCoreClockUpdate(void) { - uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllSource = 0, pllm = 2; /* Get SYSCLK source -------------------------------------------------------*/ tmp = RCC->CFGR & RCC_CFGR_SWS; @@ -255,10 +271,10 @@ void SystemCoreClockUpdate(void) /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N SYSCLK = PLL_VCO / PLL_P */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllSource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; - if (pllsource != 0) + if (pllSource != 0) { /* HSE used as PLL clock source */ pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); @@ -286,21 +302,12 @@ void SystemCoreClockUpdate(void) //By TFT: added PLL initialization that was not present in the CMSIS code void SetSysClk(void) { - register uint32_t tmpreg = 0, timeout = 0xFFFF; + register uint32_t tmpReg = 0, timeout = 0xFFFF; /******************************************************************************/ /* PLL (clocked by HSE) used as System clock source */ /******************************************************************************/ -/************************* PLL Parameters for clock at 216MHz******************/ - //By TFT: the original settings were for a boar with a 25MHz clock, not 8MHz - //They also mention a PLL_R that doesn't exist in the datasheet and maps to - //reseved bits. Finally, the PLL input frequency was set to 2MHz to reduce - //PLL jitter as suggested by the datasheet. - - //uint32_t PLL_M = 25,PLL_Q = 9, PLL_R = 7, PLL_N = 432, PLL_P = 2; - uint32_t PLL_M = 4,PLL_Q = 9, PLL_R = 7, PLL_N = 216, PLL_P = 2; - /* Enable Power Control clock */ RCC->APB1ENR |= RCC_APB1ENR_PWREN; @@ -313,8 +320,8 @@ void SetSysClk(void) /* Wait till HSE is ready and if Time out is reached exit */ do { - tmpreg = RCC->CR & RCC_CR_HSERDY; - } while((tmpreg != RCC_CR_HSERDY) && (timeout-- > 0)); + tmpReg = RCC->CR & RCC_CR_HSERDY; + } while((tmpReg != RCC_CR_HSERDY) && (timeout-- > 0)); if(timeout != 0) { @@ -330,8 +337,8 @@ void SetSysClk(void) /* Wait till ODR is ready and if Time out is reached exit */ do { - tmpreg = PWR->CSR1 & PWR_CSR1_ODRDY; - } while((tmpreg != PWR_CSR1_ODRDY) && (timeout-- > 0)); + tmpReg = PWR->CSR1 & PWR_CSR1_ODRDY; + } while((tmpReg != PWR_CSR1_ODRDY) && (timeout-- > 0)); /* Enable ODSW */ PWR->CR1 |= 0x00020000; @@ -339,8 +346,8 @@ void SetSysClk(void) /* Wait till ODR is ready and if Time out is reached exit */ do { - tmpreg = PWR->CSR1 & PWR_CSR1_ODSWRDY; - } while((tmpreg != PWR_CSR1_ODSWRDY) && (timeout-- > 0)); + tmpReg = PWR->CSR1 & PWR_CSR1_ODSWRDY; + } while((tmpReg != PWR_CSR1_ODSWRDY) && (timeout-- > 0)); /* HCLK = SYSCLK / 1*/ RCC->CFGR |= RCC_CFGR_HPRE_DIV1; @@ -362,8 +369,8 @@ void SetSysClk(void) timeout = 0xFFFF; do { - tmpreg = (RCC->CR & RCC_CR_PLLRDY); - } while((tmpreg != RCC_CR_PLLRDY) && (timeout-- > 0)); + tmpReg = (RCC->CR & RCC_CR_PLLRDY); + } while((tmpReg != RCC_CR_PLLRDY) && (timeout-- > 0)); if(timeout != 0) { @@ -377,8 +384,8 @@ void SetSysClk(void) timeout = 0xFFFF; do { - tmpreg = (RCC->CFGR & RCC_CFGR_SWS); - } while((tmpreg != RCC_CFGR_SWS) && (timeout-- > 0)); + tmpReg = (RCC->CFGR & RCC_CFGR_SWS); + } while((tmpReg != RCC_CFGR_SWS) && (timeout-- > 0)); } } diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp new file mode 100644 index 00000000..c7c0042b --- /dev/null +++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/core/stage_1_boot.cpp @@ -0,0 +1,479 @@ +#include <string.h> + +#include "core/cache_cortexMx.h" +#include "core/interrupts.h" //For the unexpected interrupt call +#include "core/interrupts_cortexMx.h" +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f769 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() { + // Cortex M7 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + miosix::IRQconfigureCache(); + + // 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() { + /** + * 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: + * 1. First, the CMSIS specifications say that SystemInit() must not access + * global variables, so it is actually possible to call it before + * 2. 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 + * 3. 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(); + + /** + * ST does not provide code to initialize the SDRAM at boot. + * Put after SystemInit() as SDRAM is timing-sensitive and needs the full + * clock speed. + */ +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Load into the program stack pointer the heap end address and switch from + * the msp to sps. + * 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" // Set the control register to use + "msr control, r0 \n\t" // the process stack + "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_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_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_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_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)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDMMC1_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_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); +void __attribute__((weak)) SAI2_IRQHandler(); +void __attribute__((weak)) QUADSPI_IRQHandler(); +void __attribute__((weak)) LPTIM1_IRQHandler(); +void __attribute__((weak)) CEC_IRQHandler(); +void __attribute__((weak)) I2C4_EV_IRQHandler(); +void __attribute__((weak)) I2C4_ER_IRQHandler(); +void __attribute__((weak)) SPDIF_RX_IRQHandler(); +void __attribute__((weak)) DSIHOST_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT0_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT1_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT2_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT3_IRQHandler(); +void __attribute__((weak)) SDMMC2_IRQHandler(); +void __attribute__((weak)) CAN3_TX_IRQHandler(); +void __attribute__((weak)) CAN3_RX0_IRQHandler(); +void __attribute__((weak)) CAN3_RX1_IRQHandler(); +void __attribute__((weak)) CAN3_SCE_IRQHandler(); +void __attribute__((weak)) JPEG_IRQHandler(); +void __attribute__((weak)) MDIOS_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_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_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, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDMMC1_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, + SAI2_IRQHandler, + QUADSPI_IRQHandler, + LPTIM1_IRQHandler, + CEC_IRQHandler, + I2C4_EV_IRQHandler, + I2C4_ER_IRQHandler, + SPDIF_RX_IRQHandler, + DSIHOST_IRQHandler, + DFSDM1_FLT0_IRQHandler, + DFSDM1_FLT1_IRQHandler, + DFSDM1_FLT2_IRQHandler, + DFSDM1_FLT3_IRQHandler, + SDMMC2_IRQHandler, + CAN3_TX_IRQHandler, + CAN3_RX0_IRQHandler, + CAN3_RX1_IRQHandler, + CAN3_SCE_IRQHandler, + JPEG_IRQHandler, + MDIOS_IRQHandler, +}; + +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_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_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_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 OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDMMC1_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_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +#pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +#pragma weak UART7_IRQHandler = Default_Handler +#pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler +#pragma weak SAI2_IRQHandler = Default_Handler +#pragma weak QUADSPI_IRQHandler = Default_Handler +#pragma weak LPTIM1_IRQHandler = Default_Handler +#pragma weak CEC_IRQHandler = Default_Handler +#pragma weak I2C4_EV_IRQHandler = Default_Handler +#pragma weak I2C4_ER_IRQHandler = Default_Handler +#pragma weak SPDIF_RX_IRQHandler = Default_Handler +#pragma weak DSIHOST_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT0_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT1_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT2_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT3_IRQHandler = Default_Handler +#pragma weak SDMMC2_IRQHandler = Default_Handler +#pragma weak CAN3_TX_IRQHandler = Default_Handler +#pragma weak CAN3_RX0_IRQHandler = Default_Handler +#pragma weak CAN3_RX1_IRQHandler = Default_Handler +#pragma weak CAN3_SCE_IRQHandler = Default_Handler +#pragma weak JPEG_IRQHandler = Default_Handler +#pragma weak MDIOS_IRQHandler = Default_Handler diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/arch_registers_impl.h b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/arch_registers_impl.h new file mode 100644 index 00000000..29cb8822 --- /dev/null +++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,17 @@ +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// stm32f7xx.h defines a few macros like __ICACHE_PRESENT, __DCACHE_PRESENT and +// includes core_cm7.h. Do not include core_cm7.h before. +#define STM32F769xx +#include "CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h" + +#if (__ICACHE_PRESENT != 1) || (__DCACHE_PRESENT != 1) +#error "Wrong include order" +#endif + +#include "CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h" + +#define RCC_SYNC() __DSB() // TODO: can this dsb be removed? + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp new file mode 100644 index 00000000..c6ea2f50 --- /dev/null +++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp.cpp @@ -0,0 +1,287 @@ +/*************************************************************************** + * Copyright (C) 2018 by Terraneo Federico * + * * + * 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 2 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. * + * * + * As a special exception, if other files instantiate templates or use * + * macros or inline functions from this file, or you compile this file * + * and link it with other works to produce a work based on this file, * + * this file does not by itself cause the resulting work to be covered * + * by the GNU General Public License. However the source code for this * + * file must still be made available in accordance with the GNU General * + * Public License. This exception does not invalidate any other reasons * + * why a work based on this file might be covered by the GNU General * + * Public License. * + * * + * 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 <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/serial.h" +#include "drivers/serial_stm32.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix { + +// +// Initialization +// + +static void sdramCommandWait() { + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() { + // Enable all gpios, passing clock + RCC->AHB1ENR |= + RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | + RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN | RCC_AHB1ENR_GPIOIEN | + RCC_AHB1ENR_GPIOJEN | RCC_AHB1ENR_GPIOKEN; + RCC_SYNC(); + + // On the Discovery F769NI, the SDRAM pins are: + // - PG8: FMC_SDCLK + // - PH2: FMC_SDCKE0 + // - PH3: FMC_SDNE0 + // - PF0: FMC_A0 + // - PF1: FMC_A1 + // - PF2: FMC_A2 + // - PF3: FMC_A3 + // - PF4: FMC_A4 + // - PF5: FMC_A5 + // - PF12: FMC_A6 + // - PF13: FMC_A7 + // - PF14: FMC_A8 + // - PF15: FMC_A9 + // - PG0: FMC_A10 + // - PG1: FMC_A11 + // - PG2: FMC_A12 + // - PD14: FMC_D0 + // - PD15: FMC_D1 + // - PD0: FMC_D2 + // - PD1: FMC_D3 + // - PE7: FMC_D4 + // - PE8: FMC_D5 + // - PE9: FMC_D6 + // - PE10: FMC_D7 + // - PE11: FMC_D8 + // - PE12: FMC_D9 + // - PE13: FMC_D10 + // - PE14: FMC_D11 + // - PE15: FMC_D12 + // - PD8: FMC_D13 + // - PD9: FMC_D14 + // - PD10: FMC_D15 + // - PH8: FMC_D16 + // - PH9: FMC_D17 + // - PH10: FMC_D18 + // - PH11: FMC_D19 + // - PH12: FMC_D20 + // - PH13: FMC_D21 + // - PH14: FMC_D22 + // - PH15: FMC_D23 + // - PI0: FMC_D24 + // - PI1: FMC_D25 + // - PI2: FMC_D26 + // - PI3: FMC_D27 + // - PI6: FMC_D28 + // - PI7: FMC_D29 + // - PI9: FMC_D30 + // - PI10: FMC_D31 + // - PG4: FMC_BA0 + // - PG5: FMC_BA1 + // - PF11: FMC_SDNRAS + // - PG15: FMC_SDNCAS + // - PH5: FMC_SDNWE + // - PE0: FMC_NBL0 + // - PE1: FMC_NBL1 + // - PI4: FMC_NBL2 + // - PI5: FMC_NBL3 + + // All SDRAM GPIOs needs to be configured with alternate function 12 and + // maximum speed + + // Alternate functions + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc0ccc; + GPIOG->AFR[1] = 0xc000000c; + GPIOH->AFR[0] = 0x00c0cc00; + GPIOH->AFR[1] = 0xcccccccc; + GPIOI->AFR[0] = 0xcccccccc; + GPIOI->AFR[1] = 0x00000cc0; + + // Mode + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a2a; + GPIOH->MODER = 0xaaaa08a0; + GPIOI->MODER = 0x0028aaaa; + + // Speed (high speed for all, very high speed for SDRAM pins) + GPIOA->OSPEEDR = 0xaaaaaaaa; + GPIOB->OSPEEDR = 0xaaaaaaaa; + GPIOC->OSPEEDR = 0xaaaaaaaa; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f3f; + GPIOH->OSPEEDR = 0xaaaaaaaa | 0xffff0cf0; + GPIOI->OSPEEDR = 0xaaaaaaaa | 0x003cffff; + GPIOJ->OSPEEDR = 0xaaaaaaaa; + GPIOK->OSPEEDR = 0xaaaaaaaa; + + // Enable the SDRAM controller clock + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // The SDRAM is a IS42S32400F-6BL + // HCLK = 216MHz -> SDRAM clock = HCLK/2 = 133MHz + + // 1. Memory device features + FMC_Bank5_6->SDCR[0] = 0 // 0 delay after CAS latency + | FMC_SDCR1_RBURST // Enable read bursts + | FMC_SDCR1_SDCLK_1 // SDCLK = HCLK / 2 + | 0 // Write accesses allowed + | FMC_SDCR1_CAS_1 // 2 cycles CAS latency + | FMC_SDCR1_NB // 4 internal banks + | FMC_SDCR1_MWID_1 // 32 bit data bus + | FMC_SDCR1_NR_0 // 12 bit row address + | 0; // 8 bit column address + + // 2. Memory device timings +#ifdef SYSCLK_FREQ_216MHz + // SDRAM timings. One clock cycle is 9.26ns + FMC_Bank5_6->SDTR[0] = + (2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns) + | (2 - 1) << FMC_SDTR1_TRP_Pos // 2 cycles TRP (18.52ns > 18ns) + | (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (18.52ns > 12ns) + | (7 - 1) << FMC_SDTR1_TRC_Pos // 7 cycles TRC (64.82ns > 60ns) + | (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns) + | (8 - 1) << FMC_SDTR1_TXSR_Pos // 8 cycles TXSR (74.08ns > 70ns) + | (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (18.52ns > 12ns) +#else +#error No SDRAM timings for this clock +#endif + + // 3. Enable the bank 1 clock + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable + | FMC_SDCMR_CTB1; // Bank 1 + sdramCommandWait(); + + // 4. Wait during command execution + delayUs(100); + + // 5. Issue a "Precharge All" command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 // Precharge all + | FMC_SDCMR_CTB1; // Bank 1 + sdramCommandWait(); + + // 6. Issue Auto-Refresh commands + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh + | FMC_SDCMR_CTB1 // Bank 1 + | (8 - 1) << FMC_SDCMR_NRFS_Pos; // 2 Auto-Refresh + sdramCommandWait(); + + // 7. Issue a Load Mode Register command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_2 /// Load mode register + | FMC_SDCMR_CTB1 // Bank 1 + | 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1 + sdramCommandWait(); + + // 8. Program the refresh rate (4K / 64ms) + // 64ms / 4096 = 15.625us +#ifdef SYSCLK_FREQ_216MHz + // 15.625us * 108MHz = 1687 - 20 = 1667 + FMC_Bank5_6->SDRTR = 1667 << FMC_SDRTR_COUNT_Pos; +#else +#error No SDRAM refresh timings for this clock +#endif +} + +void IRQbspInit() { +// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here +#ifndef __ENABLE_XRAM + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN | + RCC_AHB1ENR_GPIOIEN | RCC_AHB1ENR_GPIOJEN; + RCC_SYNC(); +#endif //__ENABLE_XRAM + + userLed1::mode(Mode::OUTPUT); + userLed2::mode(Mode::OUTPUT); + userLed3::mode(Mode::OUTPUT); + userBtn::mode(Mode::INPUT); + sdCardDetect::mode(Mode::INPUT); + + ledOn(); + delayMs(100); + ledOff(); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial( + defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() { + // Nothing to do +} + +// +// Shutdown and reboot +// + +void shutdown() { + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + + disableInterrupts(); + for (;;) + ; +} + +void reboot() { + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp_impl.h b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp_impl.h new file mode 100644 index 00000000..6b276803 --- /dev/null +++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/interfaces-impl/bsp_impl.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2018 by Terraneo Federico * + * * + * 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 2 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. * + * * + * As a special exception, if other files instantiate templates or use * + * macros or inline functions from this file, or you compile this file * + * and link it with other works to produce a work based on this file, * + * this file does not by itself cause the resulting work to be covered * + * by the GNU General Public License. However the source code for this * + * file must still be made available in accordance with the GNU General * + * Public License. This exception does not invalidate any other reasons * + * why a work based on this file might be covered by the GNU General * + * Public License. * + * * + * 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_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ***************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "interfaces/gpio.h" + +namespace miosix { + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * Board pin definition + */ +typedef Gpio<GPIOJ_BASE, 13> userLed1; +typedef Gpio<GPIOJ_BASE, 5> userLed2; +typedef Gpio<GPIOA_BASE, 12> userLed3; +typedef Gpio<GPIOA_BASE, 0> userBtn; +typedef Gpio<GPIOI_BASE, 15> sdCardDetect; + +inline void ledOn() { + userLed1::high(); + userLed2::high(); + userLed3::high(); +} + +inline void ledOff() { + userLed1::low(); + userLed2::low(); + userLed3::low(); +} + +inline void led1On() { userLed1::high(); } + +inline void led1Off() { userLed1::low(); } + +inline void led2On() { userLed2::high(); } + +inline void led2Off() { userLed2::low(); } + +inline void led3On() { userLed3::high(); } + +inline void led3Off() { userLed3::low(); } + +/** + * Polls the SD card sense GPIO. + * + * This board has no SD card whatsoever, but a card can be connected to the + * following GPIOs: + * TODO: never tested + * + * \return true. As there's no SD card sense switch, let's pretend that + * the card is present. + */ +inline bool sdCardSense() { return sdCardDetect::value() == 0; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+16m_xram.ld b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+16m_xram.ld new file mode 100644 index 00000000..683956e8 --- /dev/null +++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+16m_xram.ld @@ -0,0 +1,179 @@ +/* + * C++ enabled linker script for stm32f769ni (2M FLASH, 512K RAM, 16MB XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the external 16MB SDRAM. + */ + +/* + * 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 = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xc0000000 + 16M; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + xram(wx) : ORIGIN = 0xc0000000, LENGTH = 16M + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* 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 xram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to xram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+384k_ram.ld b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+384k_ram.ld new file mode 100644 index 00000000..5c82915f --- /dev/null +++ b/miosix/arch/cortexM7_stm32f7/stm32f769ni_discovery/stm32_2m+384k_ram.ld @@ -0,0 +1,178 @@ +/* + * C++ enabled linker script for stm32f769ni (2M FLASH, 384K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the internal 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 = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap to the end of SRAM2 */ +_heap_end = 0x20000000 + 512K; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* 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 sram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > sram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to sram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > sram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc index fe137259..77282063 100644 --- a/miosix/config/Makefile.inc +++ b/miosix/config/Makefile.inc @@ -63,6 +63,7 @@ #OPT_BOARD := stm32l476rg_nucleo #OPT_BOARD := atsam4lc2aa_generic #OPT_BOARD := stm32f411ce_blackpill +OPT_BOARD := stm32f769ni_discovery ## ## Optimization flags, choose one. @@ -1071,6 +1072,8 @@ else ifeq ($(OPT_BOARD),atsam4lc2aa_generic) ARCH := cortexM4_atsam4l else ifeq ($(OPT_BOARD),stm32f411ce_blackpill) ARCH := cortexM4_stm32f4 +else ifeq ($(OPT_BOARD),stm32f769ni_discovery) + ARCH := cortexM7_stm32f7 else $(info Error: no board specified in miosix/config/Makefile.inc) $(error Error) @@ -2959,6 +2962,45 @@ else ifeq ($(ARCH),cortexM7_stm32f7) ## board. PROGRAM_CMDLINE := echo 'make program not supported.' + ##------------------------------------------------------------------------- + ## BOARD: stm32f769ni_discovery + ## + else ifeq ($(OPT_BOARD),stm32f769ni_discovery) + ## Select appropriate compiler flags for both ASM/C/C++/linker + ## The stm32f769 has the double precision FPU, so we will build for m7 + ARCHOPTS := -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 + + ## Base directory with header files for this board + BOARD_INC := arch/cortexM7_stm32f7/stm32f769ni_discovery + + ## Select linker script and boot file + ## Their path must be relative to the miosix directory. + BOOT_FILE := $(BOARD_INC)/core/stage_1_boot.o + # LINKER_SCRIPT := $(BOARD_INC)/stm32_2m+384k_ram.ld + LINKER_SCRIPT := $(BOARD_INC)/stm32_2m+16m_xram.ld + + ## Select architecture specific files + ## These are the files in arch/<arch name>/<board name> + ARCH_SRC := $(BOARD_INC)/interfaces-impl/bsp.cpp + + ## Add a #define to allow querying board name + CFLAGS_BASE += -D_BOARD_STM32F769NI_DISCO + CXXFLAGS_BASE += -D_BOARD_STM32F769NI_DISCO + + ## Enables the initialization of the external 16MB SDRAM memory + XRAM := -D__ENABLE_XRAM + + ## Select clock frequency (HSE_VALUE is the xtal on board, fixed) + CLOCK_FREQ := -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000 + + ## Select programmer command line + ## This is the program that is invoked when the user types + ## 'make program' + ## The command must provide a way to program the board, or print an + ## error message saying that 'make program' is not supported for that + ## board. + PROGRAM_CMDLINE := st-flash --reset write "main.bin" 0x8000000 + ##------------------------------------------------------------------------- ## End of board list ## @@ -2993,7 +3035,6 @@ else ifeq ($(ARCH),cortexM7_stm32f7) arch/common/core/mpu_cortexMx.cpp \ arch/common/core/cache_cortexMx.cpp \ arch/common/drivers/serial_stm32.cpp \ - arch/common/drivers/sd_stm32f2_f4.cpp \ arch/common/drivers/dcc.cpp \ $(ARCH_INC)/interfaces-impl/portability.cpp \ $(ARCH_INC)/interfaces-impl/delays.cpp \ diff --git a/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h b/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h new file mode 100644 index 00000000..ca505da4 --- /dev/null +++ b/miosix/config/arch/cortexM7_stm32f7/stm32f769ni_discovery/board_settings.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2018 by Terraneo Federico * + * * + * 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 2 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. * + * * + * As a special exception, if other files instantiate templates or use * + * macros or inline functions from this file, or you compile this file * + * and link it with other works to produce a work based on this file, * + * this file does not by itself cause the resulting work to be covered * + * by the GNU General Public License. However the source code for this * + * file must still be made available in accordance with the GNU General * + * Public License. This exception does not invalidate any other reasons * + * why a work based on this file might be covered by the GNU General * + * Public License. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, see <http://www.gnu.org/licenses/> * + ***************************************************************************/ + +#pragma once + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 100 + +namespace miosix { + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) +const unsigned int MAIN_STACK_SIZE = 4 * 1024; + +/// Frequency of tick (in Hz). For the priority scheduler this is also the +/// context switch frequency +const unsigned int TICK_FREQ = 1000; + +///\internal Aux timer run @ 100KHz +/// Note that since the timer is only 16 bits this imposes a limit on the +/// burst measurement of 655ms. If due to a pause_kernel() or +/// disable_interrupts() section a thread runs for more than that time, a wrong +/// burst value will be measured +const unsigned int AUX_TIMER_CLOCK = 100000; +const unsigned int AUX_TIMER_MAX = 0xffff; ///<\internal Aux timer is 16 bits + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +// #define SERIAL_1_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V + +/** + * \} + */ + +} // namespace miosix diff --git a/miosix/config/boards.cmake b/miosix/config/boards.cmake index 83bf1a48..83154f5b 100644 --- a/miosix/config/boards.cmake +++ b/miosix/config/boards.cmake @@ -75,4 +75,5 @@ set(BOARDS stm32f429zi_skyward_groundstation_parafoil stm32f429zi_skyward_pyxis_auxiliary stm32f429zi_skyward_parafoil + stm32f769ni_discovery ) diff --git a/miosix/config/options.cmake b/miosix/config/options.cmake index 73797aba..5cdb573a 100644 --- a/miosix/config/options.cmake +++ b/miosix/config/options.cmake @@ -1147,6 +1147,8 @@ elseif(${OPT_BOARD} STREQUAL stm32f429zi_hre_test_stand) set(ARCH cortexM4_stm32f4) elseif(${OPT_BOARD} STREQUAL stm32f429zi_skyward_parafoil) set(ARCH cortexM4_stm32f4) +elseif(${OPT_BOARD} STREQUAL stm32f769ni_discovery) + set(ARCH cortexM7_stm32f7) else() message(FATAL_ERROR "no board specified in miosix/config/options.cmake") endif() @@ -3053,6 +3055,46 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7) ## board. set(PROGRAM_CMDLINE echo "make program not supported.") + ##------------------------------------------------------------------------- + ## BOARD: stm32f769ni_discovery + ## + elseif(${OPT_BOARD} STREQUAL stm32f769ni_discovery) + ## Select appropriate compiler flags for both ASM/C/C++/linker + ## Not all stm32f7 have the double precision FPU. Those that only + ## support single precision are built as cortex m4 + set(ARCHOPTS -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16) + + ## Base directory with header files for this board + set(BOARD_INC arch/cortexM7_stm32f7/stm32f769ni_discovery) + + ## Select linker script and boot file + ## Their path must be relative to the miosix directory. + set(BOOT_FILE ${KPATH}/${BOARD_INC}/core/stage_1_boot.cpp) + #set(LINKER_SCRIPT ${LINKER_SCRIPT_PATH}stm32_2m+384k_ram.ld) + set(LINKER_SCRIPT ${LINKER_SCRIPT_PATH}stm32_2m+16m_xram.ld) + + ## Select architecture specific files + ## These are the files in arch/<arch name>/<board name> + set(ARCH_SRC ${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp) + + ## Add a #define to allow querying board name + list(APPEND CFLAGS_BASE -D_BOARD_STM32F769NI_DISCO) + list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F769NI_DISCO) + + ## Enables the initialization of the external 16MB SDRAM memory + set(XRAM -D__ENABLE_XRAM) + + ## Select clock frequency (HSE_VALUE is the xtal on board, fixed) + set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000) + + ## Select programmer command line + ## This is the program that is invoked when the user types + ## 'make program' + ## The command must provide a way to program the board, or print an + ## error message saying that 'make program' is not supported for that + ## board. + set(PROGRAM_CMDLINE st-flash --reset write "main.bin" 0x8000000) + ##------------------------------------------------------------------------- ## End of board list ## @@ -3070,7 +3112,6 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7) ${KPATH}/arch/common/core/mpu_cortexMx.cpp ${KPATH}/arch/common/core/cache_cortexMx.cpp ${KPATH}/arch/common/drivers/serial_stm32.cpp - ${KPATH}/arch/common/drivers/sd_stm32f2_f4.cpp ${KPATH}/arch/common/drivers/dcc.cpp ${KPATH}/${ARCH_INC}/interfaces-impl/portability.cpp ${KPATH}/${ARCH_INC}/interfaces-impl/delays.cpp -- GitLab