Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • angel-swi
  • clang
  • cmake
  • cmake-old
  • compute-unit-v2
  • con-rig
  • ignition
  • master
  • parafoil-sensortile
  • processes_wip
  • sd-fix
  • shield_stackX
  • testing_ram_cu_v2
  • unstable
  • alderaan-v1
  • miosix-2.22
16 results

Target

Select target project
  • avn/swd/miosix-kernel
  • emilio.corigliano/miosix-kernel
2 results
Select Git revision
  • angel-swi
  • clang
  • cmake
  • cmake-old
  • compute-unit-v2
  • con-rig
  • ignition
  • master
  • parafoil-sensortile
  • processes_wip
  • sd-fix
  • shield_stackX
  • testing_ram_cu_v2
  • unstable
  • alderaan-v1
  • miosix-2.22
16 results
Show changes
Commits on Source (3)
Showing
with 3217 additions and 20 deletions
#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 stm32f767 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((const unsigned int*)0xd0000000, 8 * 1024 * 1024);
// 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
#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 STM32F767xx
#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
/***************************************************************************
* 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/sd_stm32f2_f4_f7.h"
#include "drivers/serial.h"
#include "drivers/serial_stm32.h"
#include "drivers/stm32_backup_domain.h"
#include "filesystem/console/console_device.h"
#include "filesystem/file_access.h"
#include "hwmapping.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 gpios used by the ram
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN |
RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN |
RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN;
RCC_SYNC();
// On the compute unit with F767ZI, the SDRAM pins are:
// - PG8: FMC_SDCLK (sdram clock)
// - PB5: FMC_SDCKE1 (sdram bank 2 clock enable)
// - PB6: FMC_SDNE1 (sdram bank 2 chip enable)
// - 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 (used only by the 32MB ram, not by the 8MB one)
// - 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
// - PG4: FMC_BA0
// - PG5: FMC_BA1
// - PF11: FMC_SDNRAS
// - PG15: FMC_SDNCAS
// - PC0: FMC_SDNWE
// - PE0: FMC_NBL0
// - PE1: FMC_NBL1
// All SDRAM GPIOs needs to be configured with alternate function 12 and
// maximum speed
// WARNING: The current configuration is for the 8MB ram
// Alternate functions
GPIOB->AFR[0] = 0x0cc00000;
GPIOC->AFR[0] = 0x0000000c;
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;
// Mode
GPIOB->MODER = 0x00002800;
GPIOC->MODER = 0x00000002;
GPIOD->MODER = 0xa02a000a;
GPIOE->MODER = 0xaaaa800a;
GPIOF->MODER = 0xaa800aaa;
GPIOG->MODER = 0x80020a2a;
// Speed (high speed for all, very high speed for SDRAM pins)
GPIOB->OSPEEDR = 0x00003c00;
GPIOC->OSPEEDR = 0x00000003;
GPIOD->OSPEEDR = 0xf03f000f;
GPIOE->OSPEEDR = 0xffffc00f;
GPIOF->OSPEEDR = 0xffc00fff;
GPIOG->OSPEEDR = 0xc0030f3f;
// Since we'we un-configured PB3 and PB4 (by default they are SWO and NJRST)
// finish the job and remove the default pull-up
GPIOB->PUPDR = 0;
// Enable the SDRAM controller clock
RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN;
RCC_SYNC();
// The SDRAM is a AS4C4M16SA-6TAN
// 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
FMC_Bank5_6->SDCR[1] = 0 // Write accesses allowed
| FMC_SDCR2_CAS_1 // 2 cycles CAS latency
| FMC_SDCR2_NB // 4 internal banks
| FMC_SDCR2_MWID_0 // 16 bit data bus
| FMC_SDCR2_NR_1 // 13 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_TRP_Pos // 2 cycles TRP (18.52ns > 18ns)
| (7 - 1) << FMC_SDTR1_TRC_Pos; // 7 cycles TRC (64.82ns > 60ns)
FMC_Bank5_6->SDTR[1] =
(2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns)
| (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (min 2cc > 12ns)
| (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns)
| (7 - 1) << FMC_SDTR1_TXSR_Pos // 7 cycles TXSR (74.08ns > 61.5ns)
| (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (min 2cc > 12ns)
#else
#error No SDRAM timings for this clock
#endif
// 3. Enable the bank 2 clock
FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable
| FMC_SDCMR_CTB2; // Bank 2
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_CTB2; // Bank 2
sdramCommandWait();
// 6. Issue Auto-Refresh commands
FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh
| FMC_SDCMR_CTB2 // Bank 2
| (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_CTB2 // Bank 2
| 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1
sdramCommandWait();
// 8. Program the refresh rate (4K / 32ms)
// 64ms / 8192 = 7.8125us
#ifdef SYSCLK_FREQ_216MHz
// 7.8125us * 133MHz = 1039 - 20 = 1019
FMC_Bank5_6->SDRTR = 1019 << FMC_SDRTR_COUNT_Pos;
#else
#error No SDRAM refresh timings for this clock
#endif
}
void IRQbspInit()
{
// Enable USART1 pins port
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
userLed1::mode(Mode::OUTPUT);
userLed2::mode(Mode::OUTPUT);
userLed3_1::mode(Mode::OUTPUT);
userLed3_2::mode(Mode::OUTPUT);
userLed4::mode(Mode::OUTPUT);
userSwitch::mode(Mode::INPUT);
using namespace interfaces;
spi1::sck::mode(Mode::ALTERNATE);
spi1::sck::alternateFunction(5);
spi1::miso::mode(Mode::ALTERNATE);
spi1::miso::alternateFunction(5);
spi1::mosi::mode(Mode::ALTERNATE);
spi1::mosi::alternateFunction(5);
spi3::sck::mode(Mode::ALTERNATE);
spi3::sck::alternateFunction(6);
spi3::miso::mode(Mode::ALTERNATE);
spi3::miso::alternateFunction(6);
spi3::mosi::mode(Mode::ALTERNATE);
spi3::mosi::alternateFunction(5);
spi4::sck::mode(Mode::ALTERNATE);
spi4::sck::alternateFunction(5);
spi4::miso::mode(Mode::ALTERNATE);
spi4::miso::alternateFunction(5);
spi4::mosi::mode(Mode::ALTERNATE);
spi4::mosi::alternateFunction(5);
can2::rx::mode(Mode::ALTERNATE);
can2::rx::alternateFunction(9);
can2::tx::mode(Mode::ALTERNATE);
can2::tx::alternateFunction(9);
usart1::tx::mode(Mode::ALTERNATE);
usart1::tx::alternateFunction(7);
usart1::rx::mode(Mode::ALTERNATE);
usart1::rx::alternateFunction(7);
usart2::tx::mode(Mode::ALTERNATE);
usart2::tx::alternateFunction(7);
usart2::rx::mode(Mode::ALTERNATE);
usart2::rx::alternateFunction(7);
using namespace radio;
cs::mode(Mode::OUTPUT);
cs::getPin().high();
dio0::mode(Mode::INPUT);
dio1::mode(Mode::INPUT);
dio3::mode(Mode::INPUT);
tx_enable::mode(Mode::OUTPUT);
rx_enable::mode(Mode::OUTPUT);
using namespace timers;
tim3ch2::mode(Mode::ALTERNATE);
tim3ch2::alternateFunction(2);
tim4ch1::mode(Mode::ALTERNATE);
tim4ch1::alternateFunction(2);
stepper1::enable::mode(Mode::OUTPUT);
stepper1::direction::mode(Mode::OUTPUT);
stepper2::enable::mode(Mode::OUTPUT);
stepper2::direction::mode(Mode::OUTPUT);
DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial(
defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL)));
}
void bspInit2()
{
#ifdef WITH_FILESYSTEM
basicFilesystemSetup(SDIODriver::instance());
#endif // WITH_FILESYSTEM
#ifdef WITH_BACKUP_SRAM
BackupDomain::instance().enable();
BackupDomain::instance().enableBackupSRAM();
#endif
// Print the reset reason
bootlog("Reset reson: ");
switch (BackupDomain::instance().lastResetReason())
{
case ResetReason::RST_LOW_PWR:
bootlog("low power\n");
break;
case ResetReason::RST_WINDOW_WDG:
bootlog("window watchdog\n");
break;
case ResetReason::RST_INDEPENDENT_WDG:
bootlog("indeendent watchdog\n");
break;
case ResetReason::RST_SW:
bootlog("software reset\n");
break;
case ResetReason::RST_POWER_ON:
bootlog("power on\n");
break;
case ResetReason::RST_PIN:
bootlog("reset pin\n");
break;
case ResetReason::RST_UNKNOWN:
bootlog("unknown\n");
break;
}
}
//
// Shutdown and reboot
//
void shutdown()
{
ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
#ifdef WITH_FILESYSTEM
FilesystemManager::instance().umountAll();
#endif // WITH_FILESYSTEM
disableInterrupts();
for (;;)
;
}
void reboot()
{
ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
#ifdef WITH_FILESYSTEM
FilesystemManager::instance().umountAll();
#endif // WITH_FILESYSTEM
disableInterrupts();
miosix_private::IRQsystemReboot();
}
} // namespace miosix
/***************************************************************************
* 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<GPIOB_BASE, 7> userLed1;
typedef Gpio<GPIOE_BASE, 3> userLed2;
typedef Gpio<GPIOC_BASE, 13> userLed3_1;
typedef Gpio<GPIOG_BASE, 9> userLed3_2;
typedef Gpio<GPIOC_BASE, 2> userLed4;
typedef Gpio<GPIOB_BASE, 2> userSwitch;
inline void ledOn()
{
userLed1::high();
userLed2::high();
userLed3_1::high();
userLed3_2::high();
userLed4::high();
}
inline void ledOff()
{
userLed1::low();
userLed2::low();
userLed3_1::low();
userLed3_2::low();
userLed4::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_1::high();
userLed3_2::high();
}
inline void led3Off()
{
userLed3_1::low();
userLed3_2::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 true; }
/**
\}
*/
} // namespace miosix
#endif // BSP_IMPL_H
/***************************************************************************
* 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 "interfaces/gpio.h"
namespace miosix
{
namespace interfaces
{
// RADIO 1
namespace spi1
{
using sck = Gpio<GPIOA_BASE, 5>;
using miso = Gpio<GPIOA_BASE, 6>;
using mosi = Gpio<GPIOA_BASE, 7>;
} // namespace spi1
// FREE SPI
namespace spi3
{
using sck = Gpio<GPIOB_BASE, 3>;
using miso = Gpio<GPIOB_BASE, 4>;
using mosi = Gpio<GPIOD_BASE, 6>;
} // namespace spi3
// ETHERNET
namespace spi4
{
using sck = Gpio<GPIOE_BASE, 2>;
using miso = Gpio<GPIOE_BASE, 5>;
using mosi = Gpio<GPIOE_BASE, 6>;
} // namespace spi4
namespace can2
{
using rx = Gpio<GPIOB_BASE, 12>;
using tx = Gpio<GPIOB_BASE, 13>;
} // namespace can2
// DBG
namespace usart1
{
using tx = Gpio<GPIOA_BASE, 9>;
using rx = Gpio<GPIOA_BASE, 10>;
} // namespace usart1
// FREE USART
namespace usart2
{
using tx = Gpio<GPIOA_BASE, 2>;
using rx = Gpio<GPIOA_BASE, 3>;
} // namespace usart2
namespace timers
{
using tim3ch2 = Gpio<GPIOC_BASE, 7>; // step 1
using tim1ch4 = Gpio<GPIOA_BASE, 11>; // count 1
using tim4ch1 = Gpio<GPIOD_BASE, 12>; // step 2
using tim8ch4 = Gpio<GPIOC_BASE, 9>; // count 2
} // namespace timers
} // namespace interfaces
namespace radio
{
using sck = interfaces::spi1::sck;
using miso = interfaces::spi1::miso;
using mosi = interfaces::spi1::mosi;
using cs = Gpio<GPIOA_BASE, 4>;
using dio0 = Gpio<GPIOC_BASE, 6>;
using dio1 = Gpio<GPIOD_BASE, 4>;
using dio3 = Gpio<GPIOD_BASE, 5>;
using rx_enable = Gpio<GPIOB_BASE, 9>;
using tx_enable = Gpio<GPIOB_BASE, 8>;
} // namespace radio
namespace stepper1
{
using enable = Gpio<GPIOA_BASE, 8>;
using direction = Gpio<GPIOA_BASE, 12>;
using pulseTimer = interfaces::timers::tim3ch2;
using countTimer = interfaces::timers::tim1ch4;
} // namespace stepper1
namespace stepper2
{
using enable = Gpio<GPIOB_BASE, 14>;
using direction = Gpio<GPIOG_BASE, 7>;
using pulseTimer = interfaces::timers::tim4ch1;
using countTimer = interfaces::timers::tim8ch4;
} // namespace stepper2
} // namespace miosix
\ No newline at end of file
/*
* 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 = 0xd0000000 + 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 = 0xd0000000, LENGTH = 16M
sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K
dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */
bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */
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 = .);
.preserve(NOLOAD) : ALIGN(4)
{
_preserve_start = .;
. = ALIGN(4);
*(.preserve);
*(.preserve*);
. = ALIGN(4);
_preserve_end = .;
} > bram
}
/*
* C++ enabled linker script for stm32f767zi (2M FLASH, 512K 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 */
bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */
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 = .);
.preserve(NOLOAD) : ALIGN(4)
{
_preserve_start = .;
. = ALIGN(4);
*(.preserve);
*(.preserve*);
. = ALIGN(4);
_preserve_end = .;
} > bram
}
#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 stm32f767 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((const unsigned int*)0xd0000000, 8 * 1024 * 1024);
// 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
#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 STM32F767xx
#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
/***************************************************************************
* 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/sd_stm32f2_f4_f7.h"
#include "drivers/serial.h"
#include "drivers/serial_stm32.h"
#include "drivers/stm32_backup_domain.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"
#include "hwmapping.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 gpios used by the ram
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN |
RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN |
RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN;
RCC_SYNC();
// On the compute unit with F767ZI, the SDRAM pins are:
// - PG8: FMC_SDCLK (sdram clock)
// - PB5: FMC_SDCKE1 (sdram bank 2 clock enable)
// - PB6: FMC_SDNE1 (sdram bank 2 chip enable)
// - 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 (used only by the 32MB ram, not by the 8MB one)
// - 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
// - PG4: FMC_BA0
// - PG5: FMC_BA1
// - PF11: FMC_SDNRAS
// - PG15: FMC_SDNCAS
// - PC0: FMC_SDNWE
// - PE0: FMC_NBL0
// - PE1: FMC_NBL1
// All SDRAM GPIOs needs to be configured with alternate function 12 and
// maximum speed
// WARNING: The current configuration is for the 8MB ram
// Alternate functions
GPIOB->AFR[0] = 0x0cc00000;
GPIOC->AFR[0] = 0x0000000c;
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;
// Mode
GPIOB->MODER = 0x00002800;
GPIOC->MODER = 0x00000002;
GPIOD->MODER = 0xa02a000a;
GPIOE->MODER = 0xaaaa800a;
GPIOF->MODER = 0xaa800aaa;
GPIOG->MODER = 0x80020a2a;
// Speed (high speed for all, very high speed for SDRAM pins)
GPIOB->OSPEEDR = 0x00003c00;
GPIOC->OSPEEDR = 0x00000003;
GPIOD->OSPEEDR = 0xf03f000f;
GPIOE->OSPEEDR = 0xffffc00f;
GPIOF->OSPEEDR = 0xffc00fff;
GPIOG->OSPEEDR = 0xc0030f3f;
// Since we'we un-configured PB3 and PB4 (by default they are SWO and NJRST)
// finish the job and remove the default pull-up
GPIOB->PUPDR = 0;
// Enable the SDRAM controller clock
RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN;
RCC_SYNC();
// The SDRAM is a AS4C4M16SA-6TAN
// 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
FMC_Bank5_6->SDCR[1] = 0 // Write accesses allowed
| FMC_SDCR2_CAS_1 // 2 cycles CAS latency
| FMC_SDCR2_NB // 4 internal banks
| FMC_SDCR2_MWID_0 // 16 bit data bus
| FMC_SDCR2_NR_1 // 13 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_TRP_Pos // 2 cycles TRP (18.52ns > 18ns)
| (7 - 1) << FMC_SDTR1_TRC_Pos; // 7 cycles TRC (64.82ns > 60ns)
FMC_Bank5_6->SDTR[1] = (2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns)
| (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (min 2cc > 12ns)
| (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns)
| (7 - 1) << FMC_SDTR1_TXSR_Pos // 7 cycles TXSR (74.08ns > 61.5ns)
| (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (min 2cc > 12ns)
#else
#error No SDRAM timings for this clock
#endif
// 3. Enable the bank 2 clock
FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable
| FMC_SDCMR_CTB2; // Bank 2
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_CTB2; // Bank 2
sdramCommandWait();
// 6. Issue Auto-Refresh commands
FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh
| FMC_SDCMR_CTB2 // Bank 2
| (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_CTB2 // Bank 2
| 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1
sdramCommandWait();
// 8. Program the refresh rate (4K / 32ms)
// 64ms / 8192 = 7.8125us
#ifdef SYSCLK_FREQ_216MHz
// 7.8125us * 133MHz = 1039 - 20 = 1019
FMC_Bank5_6->SDRTR = 1019 << FMC_SDRTR_COUNT_Pos;
#else
#error No SDRAM refresh timings for this clock
#endif
}
void IRQbspInit() {
// Enable USART1 pins port
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
userLed1::mode(Mode::OUTPUT);
userLed2::mode(Mode::OUTPUT);
userLed3_1::mode(Mode::OUTPUT);
userLed3_2::mode(Mode::OUTPUT);
userLed4::mode(Mode::OUTPUT);
userSwitch::mode(Mode::INPUT);
interfaces::spi1::miso::mode(Mode::ALTERNATE);
interfaces::spi1::miso::alternateFunction(5);
interfaces::spi1::mosi::mode(Mode::ALTERNATE);
interfaces::spi1::mosi::alternateFunction(5);
interfaces::spi1::sck::mode(Mode::ALTERNATE);
interfaces::spi1::sck::alternateFunction(5);
interfaces::spi3::miso::mode(Mode::ALTERNATE);
interfaces::spi3::miso::alternateFunction(6);
interfaces::spi3::mosi::mode(Mode::ALTERNATE);
interfaces::spi3::mosi::alternateFunction(5);
interfaces::spi3::sck::mode(Mode::ALTERNATE);
interfaces::spi3::sck::alternateFunction(6);
interfaces::spi4::miso::mode(Mode::ALTERNATE);
interfaces::spi4::miso::alternateFunction(5);
interfaces::spi4::mosi::mode(Mode::ALTERNATE);
interfaces::spi4::mosi::alternateFunction(5);
interfaces::spi4::sck::mode(Mode::ALTERNATE);
interfaces::spi4::sck::alternateFunction(5);
radio1::cs::mode(Mode::OUTPUT);
radio1::cs::high();
radio1::nrst::mode(Mode::OUTPUT);
radio1::nrst::high();
radio1::txen::mode(Mode::OUTPUT);
radio1::txen::low();
radio1::rxen::mode(Mode::OUTPUT);
radio1::rxen::low();
radio1::dio0::mode(Mode::INPUT);
radio1::dio1::mode(Mode::INPUT);
radio1::dio3::mode(Mode::INPUT);
radio2::cs::mode(Mode::OUTPUT);
radio2::cs::high();
radio2::nrst::mode(Mode::OUTPUT);
radio2::nrst::high();
radio2::txen::mode(Mode::OUTPUT);
radio2::txen::low();
radio2::rxen::mode(Mode::OUTPUT);
radio2::rxen::low();
radio2::dio0::mode(Mode::INPUT);
radio2::dio1::mode(Mode::INPUT);
radio2::dio3::mode(Mode::INPUT);
DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial(
defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL)));
}
void bspInit2() {
#ifdef WITH_FILESYSTEM
// Init devfs with empty device
basicFilesystemSetup(intrusive_ref_ptr<Device>());
#endif // WITH_FILESYSTEM
#ifdef WITH_BACKUP_SRAM
BackupDomain::instance().enable();
BackupDomain::instance().enableBackupSRAM();
#endif
// Print the reset reason
bootlog("Reset reson: ");
switch(BackupDomain::instance().lastResetReason()) {
case ResetReason::RST_LOW_PWR:
bootlog("low power\n");
break;
case ResetReason::RST_WINDOW_WDG:
bootlog("window watchdog\n");
break;
case ResetReason::RST_INDEPENDENT_WDG:
bootlog("indeendent watchdog\n");
break;
case ResetReason::RST_SW:
bootlog("software reset\n");
break;
case ResetReason::RST_POWER_ON:
bootlog("power on\n");
break;
case ResetReason::RST_PIN:
bootlog("reset pin\n");
break;
case ResetReason::RST_UNKNOWN:
bootlog("unknown\n");
break;
}
}
//
// Shutdown and reboot
//
void shutdown()
{
ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
#ifdef WITH_FILESYSTEM
FilesystemManager::instance().umountAll();
#endif // WITH_FILESYSTEM
disableInterrupts();
for(;;) ;
}
void reboot()
{
ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
#ifdef WITH_FILESYSTEM
FilesystemManager::instance().umountAll();
#endif // WITH_FILESYSTEM
disableInterrupts();
miosix_private::IRQsystemReboot();
}
} // namespace miosix
/***************************************************************************
* 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<GPIOB_BASE, 7> userLed1;
typedef Gpio<GPIOE_BASE, 3> userLed2;
typedef Gpio<GPIOC_BASE, 13> userLed3_1;
typedef Gpio<GPIOG_BASE, 9> userLed3_2;
typedef Gpio<GPIOC_BASE, 2> userLed4;
typedef Gpio<GPIOB_BASE, 2> userSwitch;
inline void ledOn()
{
userLed1::high();
userLed2::high();
userLed3_1::high();
userLed3_2::high();
userLed4::high();
}
inline void ledOff()
{
userLed1::low();
userLed2::low();
userLed3_1::low();
userLed3_2::low();
userLed4::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_1::high();
userLed3_2::high();
}
inline void led3Off()
{
userLed3_1::low();
userLed3_2::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 true; }
/**
\}
*/
} // namespace miosix
#endif // BSP_IMPL_H
/***************************************************************************
* Copyright (C) 2023 by Skyward *
* *
* 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/> *
***************************************************************************/
#ifndef HWMAPPING_H
#define HWMAPPING_H
#include "interfaces/gpio.h"
#define MIOSIX_RADIO1_DIO0_IRQ EXTI8_IRQHandlerImpl
#define MIOSIX_RADIO1_DIO1_IRQ EXTI10_IRQHandlerImpl
#define MIOSIX_RADIO1_DIO2_IRQ EXTI11_IRQHandlerImpl
#define MIOSIX_RADIO1_DIO3_IRQ EXTI12_IRQHandlerImpl
#define MIOSIX_RADIO1_SPI SPI3
#define MIOSIX_RADIO2_DIO0_IRQ EXTI6_IRQHandlerImpl
#define MIOSIX_RADIO2_DIO1_IRQ EXTI4_IRQHandlerImpl
#define MIOSIX_RADIO2_DIO2_IRQ EXTI7_IRQHandlerImpl
#define MIOSIX_RADIO2_DIO3_IRQ EXTI5_IRQHandlerImpl
#define MIOSIX_RADIO2_DIO4_IRQ EXTI2_IRQHandlerImpl
#define MIOSIX_RADIO2_DIO5_IRQ EXTI3_IRQHandlerImpl
#define MIOSIX_RADIO2_SPI SPI1
#define MIOSIX_ETHERNET_IRQ EXTI1_IRQHandlerImpl
#define MIOSIX_ETHERNET_SPI SPI4
// Remember to modify pins of leds
namespace miosix
{
namespace interfaces
{
// Radio 1
namespace spi3
{
using sck = Gpio<GPIOB_BASE, 3>;
using miso = Gpio<GPIOB_BASE, 4>;
using mosi = Gpio<GPIOD_BASE, 6>;
} // namespace spi3s
// Radio 2
namespace spi1
{
using sck = Gpio<GPIOA_BASE, 5>;
using miso = Gpio<GPIOA_BASE, 6>;
using mosi = Gpio<GPIOA_BASE, 7>;
} // namespace spi1
// Ethernet module
namespace spi4
{
using sck = Gpio<GPIOE_BASE, 2>;
using miso = Gpio<GPIOE_BASE, 5>;
using mosi = Gpio<GPIOE_BASE, 6>;
} // namespace spi4
} // namespace interfaces
namespace radio1
{
namespace spi {
using namespace miosix::interfaces::spi3;
} // namespace spi
using cs = Gpio<GPIOA_BASE, 15>;
using dio0 = Gpio<GPIOC_BASE, 8>;
using dio1 = Gpio<GPIOC_BASE, 10>;
using dio3 = Gpio<GPIOC_BASE, 12>;
using txen = Gpio<GPIOG_BASE, 12>;
using rxen = Gpio<GPIOG_BASE, 14>;
using nrst = Gpio<GPIOA_BASE, 1>;
} // namespace radio1
namespace radio2
{
namespace spi {
using namespace miosix::interfaces::spi1;
} // namespace spi
using cs = Gpio<GPIOA_BASE, 4>;
using dio0 = Gpio<GPIOC_BASE, 6>;
using dio1 = Gpio<GPIOD_BASE, 4>;
using dio3 = Gpio<GPIOD_BASE, 5>;
using txen = Gpio<GPIOB_BASE, 8>;
using rxen = Gpio<GPIOB_BASE, 9>;
using nrst = Gpio<GPIOA_BASE, 0>;
} // namespace radio2
namespace ethernet
{
namespace spi {
using namespace miosix::interfaces::spi4;
} // namespace spi
using cs = Gpio<GPIOE_BASE, 4>;
using intr = Gpio<GPIOC_BASE, 1>;
using nrst = Gpio<GPIOB_BASE, 1>;
} // namespace ethernet
} // namespace miosix
#endif // HWMAPPING_H
/*
* 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 = 0xd0000000 + 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 = 0xd0000000, LENGTH = 16M
sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K
dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */
bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */
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 = .);
.preserve(NOLOAD) : ALIGN(4)
{
_preserve_start = .;
. = ALIGN(4);
*(.preserve);
*(.preserve*);
. = ALIGN(4);
_preserve_end = .;
} > bram
}
/*
* C++ enabled linker script for stm32f767zi (2M FLASH, 512K 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 */
bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */
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 = .);
.preserve(NOLOAD) : ALIGN(4)
{
_preserve_start = .;
. = ALIGN(4);
*(.preserve);
*(.preserve*);
. = ALIGN(4);
_preserve_end = .;
} > bram
}
......@@ -312,7 +312,6 @@ void IRQbspInit()
H3LIS331DL::cs::mode(Mode::OUTPUT);
H3LIS331DL::cs::getPin().high();
H3LIS331DL::interrupt::mode(Mode::INPUT);
LIS2MDL::cs::mode(Mode::OUTPUT);
LIS2MDL::cs::getPin().high();
......
......@@ -125,7 +125,6 @@ using sck = interfaces::spi3::sck;
using miso = interfaces::spi3::miso;
using mosi = interfaces::spi3::mosi;
using cs = Gpio<GPIOD_BASE, 3>;
using interrupt = Gpio<GPIOC_BASE, 3>;
} // namespace H3LIS331DL
namespace LIS2MDL
......@@ -195,7 +194,7 @@ using sck = interfaces::spi6::sck;
using miso = interfaces::spi6::miso;
using mosi = interfaces::spi6::mosi;
using cs = Gpio<GPIOG_BASE, 11>;
using dio0 = Gpio<GPIOA_BASE, 13>;
using dio0 = Gpio<GPIOC_BASE, 3>;
using dio1 = Gpio<GPIOD_BASE, 4>;
using dio3 = Gpio<GPIOC_BASE, 5>;
using rx_enable = Gpio<GPIOB_BASE, 0>;
......
/***************************************************************************
* 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
/**
* \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=16*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
// #define SERIAL_2_DMA
// #define SERIAL_3_DMA
// SD card driver
static const unsigned char sdVoltage=33; //Board powered @ 3.3V
#define SD_ONE_BIT_DATABUS
#define SD_SDMMC 1 //Select either SDMMC1 or SDMMC2
/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL
#define V_DDA_VOLTAGE 3.3f
/**
* \}
*/
} // namespace miosix
/***************************************************************************
* Copyright (C) 2023 by Skyward *
* *
* 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
/**
* \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=16*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
// #define SERIAL_2_DMA
// #define SERIAL_3_DMA
// SD card driver
static const unsigned char sdVoltage=33; //Board powered @ 3.3V
// #define SD_ONE_BIT_DATABUS
#define SD_SDMMC 1 //Select either SDMMC1 or SDMMC2
/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL
#define V_DDA_VOLTAGE 3.3f
/**
* \}
*/
} // namespace miosix
......@@ -77,8 +77,10 @@ set(BOARDS
stm32f429zi_skyward_parafoil
stm32f429zi_skyward_rig
stm32f756zg_nucleo
stm32f767zi_automated_antennas
stm32f767zi_compute_unit
stm32f767zi_gemini_motor
stm32f767zi_gemini_gs
stm32f767zi_nucleo
stm32f767zi_skyward_death_stack_v4
stm32f769ni_discovery
......
......@@ -1183,6 +1183,10 @@ elseif(${OPT_BOARD} STREQUAL stm32f767zi_compute_unit)
set(ARCH cortexM7_stm32f7)
elseif(${OPT_BOARD} STREQUAL stm32f767zi_gemini_motor)
set(ARCH cortexM7_stm32f7)
elseif(${OPT_BOARD} STREQUAL stm32f767zi_gemini_gs)
set(ARCH cortexM7_stm32f7)
elseif(${OPT_BOARD} STREQUAL stm32f767zi_automated_antennas)
set(ARCH cortexM7_stm32f7)
elseif(${OPT_BOARD} STREQUAL stm32f767zi_nucleo)
set(ARCH cortexM7_stm32f7)
elseif(${OPT_BOARD} STREQUAL stm32f767zi_skyward_death_stack_v4)
......@@ -3246,6 +3250,90 @@ elseif(${ARCH} STREQUAL cortexM7_stm32f7)
## board.
set(PROGRAM_CMDLINE st-flash --reset write "main.bin" 0x8000000)
## BOARD: stm32f767zi_gemini_gs
##
elseif(${OPT_BOARD} STREQUAL stm32f767zi_gemini_gs)
## 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/stm32f767zi_gemini_gs)
## 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 ${KPATH}/${BOARD_INC}/stm32_2m+384k_ram.ld)
set(LINKER_SCRIPT ${KPATH}/${BOARD_INC}/stm32_2m+16m_xram.ld)
## Enables the initialization of the external SDRAM memory
set(XRAM -D__ENABLE_XRAM)
## Select architecture specific files
## These are the files in arch/<arch name>/<board name>
set(ARCH_SRC
${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
${KPATH}/arch/common/drivers/stm32_backup_domain.cpp
)
## Add a #define to allow querying board name
list(APPEND CFLAGS_BASE -D_BOARD_STM32F767ZI_GEMINI_GS)
list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F767ZI_GEMINI_GS)
## 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)
##-------------------------------------------------------------------------
## BOARD: stm32f767zi_automated_antennas
##
elseif(${OPT_BOARD} STREQUAL stm32f767zi_automated_antennas)
## 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/stm32f767zi_automated_antennas)
## 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 ${KPATH}/${BOARD_INC}/stm32_2m+384k_ram.ld)
set(LINKER_SCRIPT ${KPATH}/${BOARD_INC}/stm32_2m+16m_xram.ld)
## Enables the initialization of the external SDRAM memory
set(XRAM -D__ENABLE_XRAM)
## Select architecture specific files
## These are the files in arch/<arch name>/<board name>
set(ARCH_SRC
${KPATH}/${BOARD_INC}/interfaces-impl/bsp.cpp
${KPATH}/arch/common/drivers/stm32_backup_domain.cpp
)
## Add a #define to allow querying board name
list(APPEND CFLAGS_BASE -D_BOARD_STM32F767ZI_AUTOMATED_ANTENNAS)
list(APPEND CXXFLAGS_BASE -D_BOARD_STM32F767ZI_AUTOMATED_ANTENNAS)
## 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)
##-------------------------------------------------------------------------
## BOARD: stm32f767zi_nucleo
##
......