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

Target

Select target project
  • avn/swd/skyward-boardcore
  • emilio.corigliano/skyward-boardcore
  • nicolo.caruso/skyward-boardcore
  • ettore.pane/skyward-boardcore
  • giulia.facchi/skyward-boardcore
  • valerio.flamminii/skyward-boardcore
6 results
Show changes
Showing
with 3091 additions and 0 deletions
/* Copyright (c) 2021 Skyward Experimental Rocketry
* Author: Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "core/interrupts.h" //For the unexpected interrupt call
#include "interfaces/arch_registers.h"
#include "kernel/stage_2_boot.h"
/*
* startup.cpp
* STM32 C++ startup.
* NOTE: for stm32f2 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 M3 core appears to get out of reset with interrupts already
// enabled
__disable_irq();
// 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;
// The memcpy is usually enclosed in an #ifndef __ENABLE_XRAM, in other
// boards but in this case it is not, since the *_code_in_xram.ld linker
// script puts code in XRAM, but data in the internal one, so there's still
// the need to copy it in its final place
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:
* First, the CMSIS specifications say that SystemInit() must not access
* global variables, so it is actually possible to call it before
* Second, when running Miosix with the xram linker scripts .data and .bss
* are placed in the external RAM, so we *must* call SystemInit(), which
* enables xram, before touching .data and .bss
* Third, this is a performance improvement since the loops that initialize
* .data and zeros .bss now run with the CPU at full speed instead of 16MHz
* Note that it is called before switching stacks because the memory
* at _heap_end can be unavailable until the external RAM is initialized.
*/
SystemInit();
/*
* Initialize process stack and switch to it.
* This is required for booting Miosix, a small portion of the top of the
* heap area will be used as stack until the first thread starts. After,
* this stack will be abandoned and the process stack will point to the
* current thread's stack.
*/
asm volatile(
"ldr r0, =_heap_end \n\t"
"msr psp, r0 \n\t"
"movw r0, #2 \n\n" // Privileged, process stack
"msr control, r0 \n\t"
"isb \n\t" ::
: "r0");
program_startup();
}
/**
* All unused interrupts call this function.
*/
extern "C" void Default_Handler() { unexpectedInterrupt(); }
// System handlers
void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not
void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are
void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix
void /*__attribute__((weak))*/ MemManage_Handler();
void /*__attribute__((weak))*/ BusFault_Handler();
void /*__attribute__((weak))*/ UsageFault_Handler();
void /*__attribute__((weak))*/ SVC_Handler();
void /*__attribute__((weak))*/ DebugMon_Handler();
void /*__attribute__((weak))*/ PendSV_Handler();
void __attribute__((weak)) SysTick_Handler();
// Interrupt handlers
void __attribute__((weak)) WWDG_IRQHandler();
void __attribute__((weak)) PVD_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)) FSMC_IRQHandler();
void __attribute__((weak)) SDIO_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)) 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)) HASH_RNG_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,
FSMC_IRQHandler,
SDIO_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,
0,
0,
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,
0,
0,
HASH_RNG_IRQHandler,
};
#pragma weak SysTick_IRQHandler = Default_Handler
#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 FSMC_IRQHandler = Default_Handler
#pragma weak SDIO_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 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 HASH_RNG_IRQHandler = Default_Handler
/* Copyright (c) 2021 Skyward Experimental Rocketry
* Author: Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef ARCH_REGISTERS_IMPL_H
#define ARCH_REGISTERS_IMPL_H
#define STM32F205xx
#include "CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h"
#include "CMSIS/Device/ST/STM32F2xx/Include/system_stm32f2xx.h"
#include "CMSIS/Include/core_cm3.h"
#define RCC_SYNC() // Workaround for a bug in stm32f42x
#endif // ARCH_REGISTERS_IMPL_H
/* Copyright (c) 2021 Skyward Experimental Rocketry
* Author: Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************
* 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/dcc.h"
#include "drivers/sd_stm32f2_f4_f7.h"
#include "drivers/serial.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"
using namespace std;
namespace miosix
{
//
// Initialization
//
void IRQbspInit()
{
// Enable all gpios
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
RCC_SYNC();
GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOS
GPIOB->OSPEEDR = 0xaaaaaaaa;
GPIOC->OSPEEDR = 0xaaaaaaaa;
GPIOD->OSPEEDR = 0xaaaaaaaa;
using namespace interfaces;
spi1::cs::mode(Mode::OUTPUT);
spi1::cs::high();
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);
spi2::sck::mode(Mode::ALTERNATE);
spi2::sck::alternateFunction(5);
spi2::miso::mode(Mode::ALTERNATE);
spi2::miso::alternateFunction(5);
spi2::mosi::mode(Mode::ALTERNATE);
spi2::mosi::alternateFunction(5);
usart1::rx::mode(Mode::ALTERNATE);
usart1::rx::alternateFunction(7);
usart1::tx::mode(Mode::ALTERNATE);
usart1::tx::alternateFunction(7);
usart2::rx::mode(Mode::ALTERNATE);
usart2::rx::alternateFunction(7);
usart2::tx::mode(Mode::ALTERNATE);
usart2::tx::alternateFunction(7);
usart3::rx::mode(Mode::ALTERNATE);
usart3::rx::alternateFunction(7);
usart3::tx::mode(Mode::ALTERNATE);
usart3::tx::alternateFunction(7);
can1::rx::mode(Mode::ALTERNATE);
can1::rx::alternateFunction(9);
can1::tx::mode(Mode::ALTERNATE);
can1::tx::alternateFunction(9);
using namespace devices;
lis331hh::cs::mode(Mode::OUTPUT);
lis331hh::cs::high();
ad5204::cs::mode(Mode::OUTPUT);
ad5204::cs::high();
ina188::vsense1::mode(Mode::INPUT_ANALOG);
ina188::vsense2::mode(Mode::INPUT_ANALOG);
ina188::mosfet1::mode(Mode::OUTPUT);
ina188::mosfet1::high();
ina188::mosfet2::mode(Mode::OUTPUT);
ina188::mosfet2::high();
vbat::mode(Mode::INPUT_ANALOG);
buttons::bypass::mode(Mode::INPUT);
buttons::record::mode(Mode::INPUT);
buzzer::drive::mode(Mode::ALTERNATE);
buzzer::drive::alternateFunction(3);
leds::led1::mode(Mode::OUTPUT);
leds::led1::low();
leds::led2::mode(Mode::OUTPUT);
leds::led2::low();
leds::led3::mode(Mode::OUTPUT);
leds::led3::low();
leds::led4::mode(Mode::OUTPUT);
leds::led4::low();
DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(
new STM32Serial(defaultSerial, defaultSerialSpeed,
defaultSerialFlowctrl ? STM32Serial::RTSCTS
: STM32Serial::NOFLOWCTRL)));
}
void bspInit2()
{
#ifdef WITH_FILESYSTEM
basicFilesystemSetup(SDIODriver::instance());
#endif // WITH_FILESYSTEM
}
//
// Shutdown and reboot
//
/**
* For safety reasons, we never want to shutdown. When requested to shutdown, we
* reboot instead.
*/
void shutdown() { reboot(); }
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) 2021 Skyward Experimental Rocketry
* Author: Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************
* 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 "drivers/stm32_hardware_rng.h"
#include "hwmapping.h"
#include "interfaces/gpio.h"
namespace miosix
{
/**
\addtogroup Hardware
\{
*/
inline void ledOn()
{
devices::leds::led1::high();
devices::leds::led2::high();
devices::leds::led3::high();
devices::leds::led4::high();
}
inline void ledOff()
{
devices::leds::led1::low();
devices::leds::led2::low();
devices::leds::led3::low();
devices::leds::led4::low();
}
/**
* Polls the SD card sense GPIO
* \return true if there is an uSD card in the socket.
*/
inline bool sdCardSense() { return true; }
/**
\}
*/
} // namespace miosix
#endif // BSP_IMPL_H
/* Copyright (c) 2021 Skyward Experimental Rocketry
* Author: Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "interfaces/delays.h"
namespace miosix
{
void delayMs(unsigned int mseconds)
{
#ifndef __CODE_IN_XRAM
#ifndef SYSCLK_FREQ_120MHz
#error "Delays are uncalibrated for this clock frequency"
#endif
const unsigned int count = 29999;
for (unsigned int i = 0; i < mseconds; i++)
{
// This delay has been calibrated to take 1 millisecond
// It is written in assembler to be independent on compiler optimization
asm volatile(
" mov r1, #0 \n"
"___loop_m: cmp r1, %0 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_m \n" ::"r"(count)
: "r1");
}
#else //__CODE_IN_XRAM
#error "No delays"
#endif //__CODE_IN_XRAM
}
void delayUs(unsigned int useconds)
{
#ifndef __CODE_IN_XRAM
// This delay has been calibrated to take x microseconds
// It is written in assembler to be independent on compiler optimization
asm volatile(
" mov r1, #30 \n"
" mul r2, %0, r1 \n"
" mov r1, #0 \n"
"___loop_u: cmp r1, r2 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_u \n" ::"r"(useconds)
: "r1", "r2");
#else //__CODE_IN_XRAM
#error "No delays"
#endif //__CODE_IN_XRAM
}
} // namespace miosix
/* Copyright (c) 2021 Skyward Experimental Rocketry
* Author: Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HWMAPPING_H
#define HWMAPPING_H
#include "interfaces/gpio.h"
namespace miosix
{
namespace interfaces
{
namespace spi1
{
using cs = Gpio<GPIOA_BASE, 4>;
using sck = Gpio<GPIOA_BASE, 5>;
using miso = Gpio<GPIOA_BASE, 6>;
using mosi = Gpio<GPIOA_BASE, 7>;
} // namespace spi1
// LIS331HH and AD8403
namespace spi2
{
using sck = Gpio<GPIOB_BASE, 13>;
using miso = Gpio<GPIOB_BASE, 14>;
using mosi = Gpio<GPIOB_BASE, 15>;
} // namespace spi2
// Debug
namespace usart1
{
using tx = Gpio<GPIOA_BASE, 9>;
using rx = Gpio<GPIOA_BASE, 10>;
} // namespace usart1
// Pogo pin
namespace usart2
{
using tx = Gpio<GPIOA_BASE, 2>;
using rx = Gpio<GPIOA_BASE, 3>;
} // namespace usart2
// Pogo pin
namespace usart3
{
using tx = Gpio<GPIOB_BASE, 10>;
using rx = Gpio<GPIOB_BASE, 11>;
} // namespace usart3
namespace can1
{
using rx = Gpio<GPIOA_BASE, 11>;
using tx = Gpio<GPIOA_BASE, 12>;
} // namespace can1
} // namespace interfaces
namespace devices
{
namespace lis331hh
{
using cs = Gpio<GPIOC_BASE, 4>;
}
namespace ad5204
{
using cs = Gpio<GPIOC_BASE, 0>;
}
namespace ina188
{
using vsense1 = Gpio<GPIOA_BASE, 0>;
using vsense2 = Gpio<GPIOA_BASE, 1>;
using mosfet1 = Gpio<GPIOC_BASE, 3>;
using mosfet2 = Gpio<GPIOC_BASE, 2>;
} // namespace ina188
using vbat = Gpio<GPIOC_BASE, 5>;
namespace buttons
{
using bypass = Gpio<GPIOC_BASE, 7>;
using record = Gpio<GPIOA_BASE, 8>;
} // namespace buttons
namespace buzzer
{
using drive = Gpio<GPIOC_BASE, 6>; // PWM TIM8_CH1
}
namespace leds
{
using led1 = Gpio<GPIOB_BASE, 0>; // TIM3_CH3
using led2 = Gpio<GPIOB_BASE, 5>;
using led3 = Gpio<GPIOB_BASE, 6>;
using led4 = Gpio<GPIOB_BASE, 7>;
} // namespace leds
} // namespace devices
} // namespace miosix
#endif // HWMAPPING_H
/*
* C++ enabled linker script for Skyward stormtrooper board
* Developed by Terraneo Federico, adapted by Silvano Seva
* STM32F205RC has 512KB of flash and 128KB of RAM
*/
/*
* This linker script puts:
* - read only data and code (.text, .rodata, .eh_*) in flash
* - stacks, heap and sections .data and .bss 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 = 0x00000200; /* main stack = 512Bytes */
_main_stack_top = 0x20000000 + _main_stack_size;
ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error");
/* end of the heap on 128KB microcontrollers */
_heap_end = 0x20020000; /* end of available ram */
/* identify the Entry Point */
ENTRY(_Z13Reset_Handlerv)
/* specify the memory areas */
MEMORY
{
flash(rx) : ORIGIN = 0, LENGTH = 512K
/*
* Note, the ram starts at 0x20000000 but it is necessary to add the size
* of the main stack, so it is 0x20000200.
*/
ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200
}
/* now define the output sections */
SECTIONS
{
. = 0;
/* .text section: code goes to flash */
.text :
{
/* Startup code must go at address 0 */
KEEP(*(.isr_vector))
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
/* these sections for thumb interwork? */
*(.glue_7)
*(.glue_7t)
/* these sections for C++? */
*(.gcc_except_table)
*(.gcc_except_table.*)
*(.ARM.extab*)
*(.gnu.linkonce.armextab.*)
. = ALIGN(4);
/* .rodata: constant data */
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
/* C++ Static constructors/destructors (eabi) */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__miosix_init_array_start = .;
KEEP (*(SORT(.miosix_init_array.*)))
KEEP (*(.miosix_init_array))
__miosix_init_array_end = .;
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
/* C++ Static constructors/destructors (elf) */
. = ALIGN(4);
_ctor_start = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
_ctor_end = .;
. = ALIGN(4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
} > flash
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
/* .data section: global variables go to ram, but also store a copy to
flash to initialize them */
.data : ALIGN(8)
{
_data = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
_edata = .;
} > ram AT > flash
_etext = LOADADDR(.data);
/* .bss section: uninitialized global variables go to ram */
_bss_start = .;
.bss :
{
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
. = ALIGN(8);
} > ram
_bss_end = .;
_end = .;
PROVIDE(end = .);
}
# Copyright (C) 2023 by Skyward
#
# This program is free software; you can redistribute it and/or
# it under the terms of the GNU General Public License as published
# 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
# Public License. This exception does not invalidate any other
# 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/>
set(BOARD_NAME stm32f429zi_con_rig)
set(ARCH_NAME cortexM4_stm32f4)
# Base directories with header files for this board
set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common)
set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME})
set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config)
# Specify where to find the board specific config/miosix_settings.h
set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH})
# Specify where to find the board specific config/mxgui_settings.h
set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH})
# Optimization flags:
# -O0 do no optimization, the default if no optimization level is specified
# -O or -O1 optimize minimally
# -O2 optimize more
# -O3 optimize even more
# -Ofast optimize very aggressively to the point of breaking the standard
# -Og Optimize debugging experience, enables optimizations that do not
# interfere with debugging
# -Os Optimize for size with -O2 optimizations that do not increase code size
set(OPT_OPTIMIZATION -O2)
# Boot file
set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp)
# Linker script type, there are three options
# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld)
# the most common choice, available for all microcontrollers
# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld)
# You must uncomment -D__ENABLE_XRAM below in this case.
# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld)
set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld)
# Uncommenting __ENABLE_XRAM enables the initialization of the external
# 8MB SDRAM memory. Do not uncomment this even if you don't use a linker
# script that requires it, as it is used for the LCD framebuffer.
set(XRAM -D__ENABLE_XRAM)
# Select clock frequency.
# Warning: the default clock frequency for
# this board is 168MHz and not 180MHz because, due to a limitation in
# the PLL, it is not possible to generate a precise 48MHz output when
# running the core at 180MHz. If 180MHz is chosen the USB peripheral will
# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48)
# Define USE_INTERNAL_CLOCK to bypass the external oscillator
# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000)
set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000)
# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000)
# C++ Exception/rtti support disable flags.
# To save code size if not using C++ exceptions (nor some STL code which
# implicitly uses it) uncomment this option.
# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used.
# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS)
# Specify a custom flash command
# This is the program that is invoked when the flash flag (-f or --flash) is
# used with the Miosix Build System. Use $binary or $hex as placeolders, they
# will be replaced by the build systems with the binary or hex file repectively.
# If a command is not specified, the build system will use st-flash if found
# set(PROGRAM_CMDLINE "here your custom flash command")
# Basic flags
set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16)
# Flags for ASM and linker
set(AFLAGS_BASE ${FLAGS_BASE})
set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib)
# Flags for C/C++
string(TOUPPER ${BOARD_NAME} BOARD_UPPER)
set(CFLAGS_BASE
-D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\"
-D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g
-D_ARCH_CORTEXM4_STM32F4
${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c
)
set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT})
# Select architecture specific files
set(ARCH_SRC
${ARCH_PATH}/interfaces-impl/delays.cpp
${ARCH_PATH}/interfaces-impl/gpio_impl.cpp
${ARCH_PATH}/interfaces-impl/portability.cpp
${BOARD_PATH}/interfaces-impl/bsp.cpp
${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c
${KPATH}/arch/common/core/interrupts_cortexMx.cpp
${KPATH}/arch/common/core/mpu_cortexMx.cpp
${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp
${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
${KPATH}/arch/common/drivers/serial_stm32.cpp
${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
)
/* Copyright (c) 2023 Skyward Experimental Rocketry
* Author: Matteo Pignataro
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef BOARD_SETTINGS_H
#define BOARD_SETTINGS_H
#include "util/version.h"
/**
* \internal
* Versioning for board_settings.h for out of git tree projects
*/
#define BOARD_SETTINGS_VERSION 300
namespace miosix
{
/// Size of stack for main().
/// The C standard library is stack-heavy (iprintf requires 1KB) but the
/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack.
const unsigned int MAIN_STACK_SIZE = 4 * 1024;
/// Serial port
const unsigned int defaultSerial = 1;
const unsigned int defaultSerialSpeed = 115200;
const bool defaultSerialFlowctrl = false;
#define SERIAL_1_DMA
// #define SERIAL_2_DMA
// #define SERIAL_3_DMA
// SD card driver
static const unsigned char sdVoltage = 30; // Board powered @ 3.0V
#define SD_ONE_BIT_DATABUS // Can't use 4 bit databus due to pin conflicts
/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL
#define V_DDA_VOLTAGE 3.0f
} // namespace miosix
#endif /* BOARD_SETTINGS_H */
/* Copyright (c) 2023 Skyward Experimental Rocketry
* Author: Matteo Pignataro
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
// Before you can compile the kernel you have to configure it by editing this
// file. After that, comment out this line to disable the reminder error.
// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never
// defined when compiling the code.
#ifndef PARSING_FROM_IDE
//#error This error is a reminder that you have not edited miosix_settings.h
// yet.
#endif // PARSING_FROM_IDE
/**
* \file miosix_settings.h
* NOTE: this file contains ONLY configuration options that are not dependent
* on architecture specific details. The other options are in the following
* files which are included here:
* miosix/arch/architecture name/common/arch_settings.h
* miosix/config/arch/architecture name/board name/board_settings.h
*/
#include "arch_settings.h"
#include "board_settings.h"
#include "util/version.h"
/**
* \internal
* Versioning for miosix_settings.h for out of git tree projects
*/
#define MIOSIX_SETTINGS_VERSION 300
namespace miosix
{
/**
* \addtogroup Settings
* \{
*/
//
// Scheduler options
//
/// \def SCHED_TYPE_PRIORITY
/// If uncommented selects the priority scheduler
/// \def SCHED_TYPE_CONTROL_BASED
/// If uncommented selects the control based scheduler
/// \def SCHED_TYPE_EDF
/// If uncommented selects the EDF scheduler
// Uncomment only *one* of those
#define SCHED_TYPE_PRIORITY
//#define SCHED_TYPE_CONTROL_BASED
//#define SCHED_TYPE_EDF
/// \def WITH_CPU_TIME_COUNTER
/// Allows to enable/disable CPUTimeCounter to save code size and remove its
/// overhead from the scheduling process. By default it is not defined
/// (CPUTimeCounter is disabled).
//#define WITH_CPU_TIME_COUNTER
//
// Filesystem options
//
/// \def WITH_FILESYSTEM
/// Allows to enable/disable filesystem support to save code size
/// By default it is defined (filesystem support is enabled)
#define WITH_FILESYSTEM
/// \def WITH_DEVFS
/// Allows to enable/disable DevFs support to save code size
/// By default it is defined (DevFs is enabled)
#define WITH_DEVFS
/// \def SYNC_AFTER_WRITE
/// Increases filesystem write robustness. After each write operation the
/// filesystem is synced so that a power failure happens data is not lost
/// (unless power failure happens exactly between the write and the sync)
/// Unfortunately write latency and throughput becomes twice as worse
/// By default it is defined (slow but safe)
#define SYNC_AFTER_WRITE
/// Maximum number of open files. Trying to open more will fail.
/// Cannot be lower than 3, as the first three are stdin, stdout, stderr
const unsigned char MAX_OPEN_FILES = 8;
/// \def WITH_PROCESSES
/// If uncommented enables support for processes as well as threads.
/// This enables the dynamic loader to load elf programs, the extended system
/// call service and, if the hardware supports it, the MPU to provide memory
/// isolation of processes
//#define WITH_PROCESSES
#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
#error Processes require C++ exception support
#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
#error Processes require filesystem support
#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM)
#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
#error Processes require devfs support
#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
//
// C/C++ standard library I/O (stdin, stdout and stderr related)
//
/// \def WITH_BOOTLOG
/// Uncomment to print bootlogs on stdout.
/// By default it is defined (bootlogs are printed)
#define WITH_BOOTLOG
/// \def WITH_ERRLOG
/// Uncomment for debug information on stdout.
/// By default it is defined (error information is printed)
#define WITH_ERRLOG
//
// Kernel related options (stack sizes, priorities)
//
/// \def WITH_DEEP_SLEEP
/// Adds interfaces and required variables to support deep sleep state switch
/// automatically when peripherals are not required
//#define WITH_DEEP_SLEEP
/**
* \def JTAG_DISABLE_SLEEP
* JTAG debuggers lose communication with the device if it enters sleep
* mode, so to use debugging it is necessary to disable sleep in the idle
* thread. By default it is not defined (idle thread calls sleep).
*/
#define JTAG_DISABLE_SLEEP
#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP)
#error Deep sleep cannot work together with jtag
#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS)
/// Minimum stack size (MUST be divisible by 4)
const unsigned int STACK_MIN = 256;
/// \internal Size of idle thread stack.
/// Should be >=STACK_MIN (MUST be divisible by 4)
const unsigned int STACK_IDLE = 256;
/// Default stack size for pthread_create.
/// The chosen value is enough to call C standard library functions
/// such as printf/fopen which are stack-heavy
const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048;
/// Maximum size of the RAM image of a process. If a program requires more
/// the kernel will not run it (MUST be divisible by 4)
const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024;
/// Minimum size of the stack for a process. If a program specifies a lower
/// size the kernel will not run it (MUST be divisible by 4)
const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN;
/// Every userspace thread has two stacks, one for when it is running in
/// userspace and one for when it is running in kernelspace (that is, while it
/// is executing system calls). This is the size of the stack for when the
/// thread is running in kernelspace (MUST be divisible by 4)
const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024;
/// Number of priorities (MUST be >1)
/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as
/// the priority of the idle thread.
/// The meaning of a thread's priority depends on the chosen scheduler.
#ifdef SCHED_TYPE_PRIORITY
// Can be modified, but a high value makes context switches more expensive
const short int PRIORITY_MAX = 4;
#elif defined(SCHED_TYPE_CONTROL_BASED)
// Don't touch, the limit is due to the fixed point implementation
// It's not needed for if floating point is selected, but kept for consistency
const short int PRIORITY_MAX = 64;
#else // SCHED_TYPE_EDF
// Doesn't exist for this kind of scheduler
#endif
/// Priority of main()
/// The meaning of a thread's priority depends on the chosen scheduler.
const unsigned char MAIN_PRIORITY = 1;
#ifdef SCHED_TYPE_PRIORITY
/// Maximum thread time slice in nanoseconds, after which preemption occurs
const unsigned int MAX_TIME_SLICE = 1000000;
#endif // SCHED_TYPE_PRIORITY
//
// Other low level kernel options. There is usually no need to modify these.
//
/// \internal Length of wartermark (in bytes) to check stack overflow.
/// MUST be divisible by 4 and can also be zero.
/// A high value increases context switch time.
const unsigned int WATERMARK_LEN = 16;
/// \internal Used to fill watermark
const unsigned int WATERMARK_FILL = 0xaaaaaaaa;
/// \internal Used to fill stack (for checking stack usage)
const unsigned int STACK_FILL = 0xbbbbbbbb;
// Compiler version checks
#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3
#error \
"You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain"
#endif
#if _MIOSIX_GCC_PATCH_MAJOR > 3
#warning "You are using a too new compiler, which may not be supported"
#endif
/**
* \}
*/
} // namespace miosix
/* Copyright (c) 2023 Skyward Experimental Rocketry
* Author: Matteo Pignataro
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "core/interrupts.h" //For the unexpected interrupt call
#include "interfaces/arch_registers.h"
#include "interfaces/bsp.h"
#include "kernel/stage_2_boot.h"
/*
* startup.cpp
* STM32 C++ startup.
* NOTE: for stm32f42x 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 M3 core appears to get out of reset with interrupts already
// enabled
__disable_irq();
// 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:
// First, the CMSIS specifications say that SystemInit() must not access
// global variables, so it is actually possible to call it before
// Second, when running Miosix with the xram linker scripts .data and .bss
// are placed in the external RAM, so we *must* call SystemInit(), which
// enables xram, before touching .data and .bss
// Third, this is a performance improvement since the loops that initialize
//.data and zeros .bss now run with the CPU at full speed instead of 8MHz
SystemInit();
// ST does not provide code to initialize the stm32f429-disco 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
/*
* Initialize process stack and switch to it.
* This is required for booting Miosix, a small portion of the top of the
* heap area will be used as stack until the first thread starts. After,
* this stack will be abandoned and the process stack will point to the
* current thread's stack.
*/
asm volatile(
"ldr r0, =_heap_end \n\t"
"msr psp, r0 \n\t"
"movw r0, #2 \n\n" // Privileged, process stack
"msr control, r0 \n\t"
"isb \n\t" ::
: "r0");
program_startup();
}
/**
* All unused interrupts call this function.
*/
extern "C" void Default_Handler() { unexpectedInterrupt(); }
// System handlers
void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not
void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are
void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix
void /*__attribute__((weak))*/ MemManage_Handler();
void /*__attribute__((weak))*/ BusFault_Handler();
void /*__attribute__((weak))*/ UsageFault_Handler();
void /*__attribute__((weak))*/ SVC_Handler();
void /*__attribute__((weak))*/ DebugMon_Handler();
void /*__attribute__((weak))*/ PendSV_Handler();
void __attribute__((weak)) SysTick_Handler();
// Interrupt handlers
void __attribute__((weak)) WWDG_IRQHandler();
void __attribute__((weak)) PVD_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)) SDIO_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)) HASH_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();
// 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, SDIO_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, HASH_RNG_IRQHandler,
FPU_IRQHandler, UART7_IRQHandler, UART8_IRQHandler, SPI4_IRQHandler,
SPI5_IRQHandler, SPI6_IRQHandler, SAI1_IRQHandler, LTDC_IRQHandler,
LTDC_ER_IRQHandler, DMA2D_IRQHandler};
#pragma weak SysTick_IRQHandler = Default_Handler
#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 SDIO_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 HASH_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
/* Copyright (c) 2023 Skyward Experimental Rocketry
* Author: Matteo Pignataro
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef ARCH_REGISTERS_IMPL_H
#define ARCH_REGISTERS_IMPL_H
// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency
#define STM32F429xx
#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h"
#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h"
#include "CMSIS/Include/core_cm4.h"
#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x
#endif // ARCH_REGISTERS_IMPL_H
/* Copyright (c) 2023 Skyward Experimental Rocketry
* Author: Matteo Pignataro
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************
* 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 "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
//
/**
* The example code from ST checks for the busy flag after each command.
* Interestingly I couldn't find any mention of this in the datsheet.
*/
static void sdramCommandWait()
{
for (int i = 0; i < 0xffff; i++)
if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0)
return;
}
void configureSdram()
{
// Enable all gpios, passing clock
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN |
RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN;
RCC_SYNC();
// First, configure SDRAM GPIOs
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] = 0x00cc00cc;
GPIOG->AFR[1] = 0xc000000c;
GPIOB->MODER = 0x00002800;
GPIOC->MODER = 0x00000002;
GPIOD->MODER = 0xa02a000a;
GPIOE->MODER = 0xaaaa800a;
GPIOF->MODER = 0xaa800aaa;
GPIOG->MODER = 0x80020a0a;
GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs...
GPIOB->OSPEEDR =
0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins
GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003;
GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f;
GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f;
GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff;
GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f;
GPIOH->OSPEEDR = 0xaaaaaaaa;
// Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST,
// finish the job and remove the default pull-up
GPIOB->PUPDR = 0;
// Second, actually start the SDRAM controller
RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN;
RCC_SYNC();
// SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000)
// Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0],
// they aren't just don't care, the controller will fail if they aren't at 0
FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency
| FMC_SDCR1_RBURST // Enable read burst
| 0; // 0 delay between reads after CAS
FMC_Bank5_6->SDCR[1] = 0 // 8 bit column address
| FMC_SDCR1_NR_0 // 12 bit row address
| FMC_SDCR1_MWID_0 // 16 bit data bus
| FMC_SDCR1_NB // 4 banks
|
FMC_SDCR1_CAS_1; // 2 cycle CAS latency (F<133MHz)
#ifdef SYSCLK_FREQ_180MHz
// One SDRAM clock cycle is 11.1ns
// Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0],
// they aren't just don't care, the controller will fail if they aren't at 0
FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>63ns)
| (2 - 1) << 20; // 2 cycle TRP (22.2ns>15ns)
FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD
| (7 - 1) << 4 // 7 cycle TXSR (77.7ns>70ns)
| (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns)
| (2 - 1) << 16 // 2 cycle TWR
| (2 - 1) << 24; // 2 cycle TRCD (22.2ns>15ns)
#elif defined(SYSCLK_FREQ_168MHz)
// One SDRAM clock cycle is 11.9ns
// Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0],
// they aren't just don't care, the controller will fail if they aren't at 0
FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>63ns)
| (2 - 1) << 20; // 2 cycle TRP (23.8ns>15ns)
FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD
| (6 - 1) << 4 // 6 cycle TXSR (71.4ns>70ns)
| (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns)
| (2 - 1) << 16 // 2 cycle TWR
| (2 - 1) << 24; // 2 cycle TRCD (23.8ns>15ns)
#else
#error No SDRAM timings for this clock
#endif
FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2
| 1; // MODE=001 clock enabled
sdramCommandWait();
// ST and SDRAM datasheet agree a 100us delay is required here.
delayUs(100);
FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2
| 2; // MODE=010 precharge all command
sdramCommandWait();
FMC_Bank5_6->SDCMR = (8 - 1) << 5 // NRFS=8 SDRAM datasheet says
// "at least two AUTO REFRESH cycles"
| FMC_SDCMR_CTB2 // Enable bank 2
| 3; // MODE=011 auto refresh
sdramCommandWait();
FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1
| FMC_SDCMR_CTB2 // Enable bank 2
| 4; // MODE=100 load mode register
sdramCommandWait();
// 64ms/4096=15.625us
#ifdef SYSCLK_FREQ_180MHz
// 15.625us*90MHz=1406-20=1386
FMC_Bank5_6->SDRTR = 1386 << 1;
#elif defined(SYSCLK_FREQ_168MHz)
// 15.625us*84MHz=1312-20=1292
FMC_Bank5_6->SDRTR = 1292 << 1;
#else
#error No refresh timings for this clock
#endif
}
void IRQbspInit()
{
// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here
#ifndef __ENABLE_XRAM
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN |
RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN |
RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN |
RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN;
RCC_SYNC();
#endif //__ENABLE_XRAM
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
RCC->APB2ENR |= RCC_APB2ENR_SPI4EN;
RCC->APB2ENR |= RCC_APB2ENR_SPI5EN;
RCC->APB2ENR |= RCC_APB2ENR_SPI6EN;
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
RCC->APB2ENR |= RCC_APB2ENR_TIM8EN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->APB2ENR |= RCC_APB2ENR_TIM10EN;
RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
RCC_SYNC();
// Initialize everything
interfaces::spi1::sck::mode(Mode::ALTERNATE);
interfaces::spi1::sck::alternateFunction(5);
interfaces::spi1::miso::mode(Mode::ALTERNATE);
interfaces::spi1::miso::alternateFunction(5);
interfaces::spi1::mosi::mode(Mode::ALTERNATE);
interfaces::spi1::mosi::alternateFunction(5);
btns::ignition::mode(Mode::INPUT);
btns::filling::mode(Mode::INPUT);
btns::venting::mode(Mode::INPUT);
btns::release::mode(Mode::INPUT);
btns::detach::mode(Mode::INPUT);
btns::tars::mode(Mode::INPUT);
btns::arm::mode(Mode::INPUT);
radio::cs::mode(Mode::OUTPUT);
radio::cs::high();
radio::dio0::mode(Mode::INPUT_PULL_UP);
radio::dio1::mode(Mode::INPUT_PULL_UP);
radio::dio3::mode(Mode::INPUT_PULL_UP);
radio::txEn::mode(Mode::OUTPUT);
radio::txEn::low();
radio::rxEn::mode(Mode::OUTPUT);
radio::rxEn::low();
radio::nrst::mode(Mode::OUTPUT);
radio::nrst::high();
ui::buzzer::mode(Mode::OUTPUT);
ui::buzzer::high();
ui::armedLed::mode(Mode::OUTPUT);
ui::armedLed::low();
ui::redLed::mode(Mode::OUTPUT);
ui::redLed::low();
DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(
new STM32Serial(defaultSerial, defaultSerialSpeed,
defaultSerialFlowctrl ? STM32Serial::RTSCTS
: STM32Serial::NOFLOWCTRL)));
}
void bspInit2()
{
#ifdef WITH_FILESYSTEM
basicFilesystemSetup(SDIODriver::instance());
#endif // WITH_FILESYSTEM
}
//
// Shutdown and reboot
//
/**
* @brief This function disables filesystem and serial port.
*/
void shutdown()
{
ioctl(STDOUT_FILENO, IOCTL_SYNC, 0);
#ifdef WITH_FILESYSTEM
FilesystemManager::instance().umountAll();
#endif // WITH_FILESYSTEM
disableInterrupts();
while (true)
;
}
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) 2023 Skyward Experimental Rocketry
* Author: Matteo Pignataro
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************
* 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 "drivers/stm32_hardware_rng.h"
#include "hwmapping.h"
#include "interfaces/gpio.h"
namespace miosix
{
/**
* \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();
} // namespace miosix
#endif // BSP_IMPL_H
/* Copyright (c) 2023 Skyward Experimental Rocketry
* Author: Davide Mor
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include "interfaces/gpio.h"
#define MIOSIX_RADIO_DIO0_IRQ EXTI1_IRQHandlerImpl
#define MIOSIX_RADIO_DIO1_IRQ EXTI12_IRQHandlerImpl
#define MIOSIX_RADIO_DIO3_IRQ EXTI13_IRQHandlerImpl
#define MIOSIX_RADIO_SPI SPI1
namespace miosix
{
namespace interfaces
{
// Miosix radio SPI
namespace spi1
{
using sck = Gpio<GPIOA_BASE, 5>;
using miso = Gpio<GPIOA_BASE, 6>;
using mosi = Gpio<GPIOA_BASE, 7>;
} // namespace spi1
} // namespace interfaces
namespace btns
{
using ignition = Gpio<GPIOB_BASE, 4>;
using filling = Gpio<GPIOE_BASE, 6>;
using venting = Gpio<GPIOE_BASE, 4>;
using release = Gpio<GPIOG_BASE, 9>;
using detach = Gpio<GPIOD_BASE, 7>;
using tars = Gpio<GPIOD_BASE, 5>;
using arm = Gpio<GPIOE_BASE, 2>;
} // namespace btns
namespace radio
{
using cs = Gpio<GPIOF_BASE, 6>;
using dio0 = Gpio<GPIOB_BASE, 1>;
using dio1 = Gpio<GPIOD_BASE, 12>;
using dio3 = Gpio<GPIOD_BASE, 13>;
using txEn = Gpio<GPIOG_BASE, 2>;
using rxEn = Gpio<GPIOG_BASE, 3>;
using nrst = Gpio<GPIOB_BASE, 0>;
} // namespace radio
namespace ui
{
using buzzer = Gpio<GPIOB_BASE, 7>;
using armedLed = Gpio<GPIOC_BASE, 13>;
using redLed = Gpio<GPIOG_BASE, 14>;
} // namespace ui
} // namespace miosix
/*
* C++ enabled linker script for stm32 (2M FLASH, 256K RAM)
* Developed by TFT: Terraneo Federico Technologies
* Optimized for use with the Miosix kernel
*/
/*
* This chip has an unusual quirk that the RAM is divided in two block mapped
* at two non contiguous memory addresses. I don't know why they've done that,
* probably doing the obvious thing would have made writing code too easy...
* Anyway, since hardware can't be changed, we've got to live with that and
* try to make use of both RAMs.
*
* Given the constraints above, this linker script puts:
* - read only data and code (.text, .rodata, .eh_*) in FLASH
* - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM
* - stacks and heap in the "large" 192KB RAM.
*
* Unfortunately thread stacks can't be put in the small RAM as Miosix
* allocates them inside the heap.
*/
/*
* The main stack is used for interrupt handling by the kernel.
*
* *** Readme ***
* This linker script places the main stack (used by the kernel for interrupts)
* at the bottom of the ram, instead of the top. This is done for two reasons:
*
* - as an optimization for microcontrollers with little ram memory. In fact
* the implementation of malloc from newlib requests memory to the OS in 4KB
* block (except the first block that can be smaller). This is probably done
* for compatibility with OSes with an MMU and paged memory. To see why this
* is bad, consider a microcontroller with 8KB of ram: when malloc finishes
* up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will
* fail because the top part of the ram is used by the main stack. As a
* result, the top part of the memory will not be used by malloc, even if
* available (and it is nearly *half* the ram on an 8KB mcu). By placing the
* main stack at the bottom of the ram, the upper 4KB block will be entirely
* free and available as heap space.
*
* - In case of main stack overflow the cpu will fault because access to memory
* before the beginning of the ram faults. Instead with the default stack
* placement the main stack will silently collide with the heap.
* Note: if increasing the main stack size also increase the ORIGIN value in
* the MEMORY definitions below accordingly.
*/
_main_stack_size = 0x00000200; /* main stack = 512Bytes */
_main_stack_top = 0x10000000 + _main_stack_size;
ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error");
/* Mapping the heap into the large 192KB RAM */
_end = 0x20000000;
_heap_end = 0x20030000; /* end of available ram */
/* identify the Entry Point */
ENTRY(_Z13Reset_Handlerv)
/* specify the memory areas */
MEMORY
{
flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M
/*
* Note, the small ram starts at 0x10000000 but it is necessary to add the
* size of the main stack, so it is 0x10000200.
*/
smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200
largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K
backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K
}
/* now define the output sections */
SECTIONS
{
. = 0;
/* .text section: code goes to flash */
.text :
{
/* Startup code must go at address 0 */
KEEP(*(.isr_vector))
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
/* these sections for thumb interwork? */
*(.glue_7)
*(.glue_7t)
/* these sections for C++? */
*(.gcc_except_table)
*(.gcc_except_table.*)
*(.ARM.extab*)
*(.gnu.linkonce.armextab.*)
. = ALIGN(4);
/* .rodata: constant data */
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
/* C++ Static constructors/destructors (eabi) */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__miosix_init_array_start = .;
KEEP (*(SORT(.miosix_init_array.*)))
KEEP (*(.miosix_init_array))
__miosix_init_array_end = .;
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
/* C++ Static constructors/destructors (elf) */
. = ALIGN(4);
_ctor_start = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
_ctor_end = .;
. = ALIGN(4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
} > flash
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
/* .data section: global variables go to ram, but also store a copy to
flash to initialize them */
.data : ALIGN(8)
{
_data = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
_edata = .;
} > smallram AT > flash
_etext = LOADADDR(.data);
/* .bss section: uninitialized global variables go to ram */
_bss_start = .;
.bss :
{
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
. = ALIGN(8);
} > smallram
_bss_end = .;
/*_end = .;*/
/*PROVIDE(end = .);*/
}
/*
* C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM)
* Developed by TFT: Terraneo Federico Technologies
* Optimized for use with the Miosix kernel
*/
/*
* This chip has an unusual quirk that the RAM is divided in two block mapped
* at two non contiguous memory addresses. I don't know why they've done that,
* probably doing the obvious thing would have made writing code too easy...
* Anyway, since hardware can't be changed, we've got to live with that and
* try to make use of both RAMs.
*
* Given the constraints above, this linker script puts:
* - read only data and code (.text, .rodata, .eh_*) in FLASH
* - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM
* - .data, .bss, stacks and heap in the external 8MB 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 = 0x00000200; /* main stack = 512Bytes */
_main_stack_top = 0x10000000 + _main_stack_size;
ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error");
/* Mapping the heap into XRAM */
_heap_end = 0xd0800000; /* end of available ram */
/* identify the Entry Point */
ENTRY(_Z13Reset_Handlerv)
/* specify the memory areas */
MEMORY
{
flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M
/*
* Note, the small ram starts at 0x10000000 but it is necessary to add the
* size of the main stack, so it is 0x10000200.
*/
smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200
largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K
backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K
xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M
}
/* now define the output sections */
SECTIONS
{
. = 0;
/* .text section: code goes to flash */
.text :
{
/* Startup code must go at address 0 */
KEEP(*(.isr_vector))
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
/* these sections for thumb interwork? */
*(.glue_7)
*(.glue_7t)
/* these sections for C++? */
*(.gcc_except_table)
*(.gcc_except_table.*)
*(.ARM.extab*)
*(.gnu.linkonce.armextab.*)
. = ALIGN(4);
/* .rodata: constant data */
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
/* C++ Static constructors/destructors (eabi) */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__miosix_init_array_start = .;
KEEP (*(SORT(.miosix_init_array.*)))
KEEP (*(.miosix_init_array))
__miosix_init_array_end = .;
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
/* C++ Static constructors/destructors (elf) */
. = ALIGN(4);
_ctor_start = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
_ctor_end = .;
. = ALIGN(4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
} > flash
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
/* .data section: global variables go to ram, but also store a copy to
flash to initialize them */
.data : ALIGN(8)
{
_data = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
_edata = .;
} > xram AT > flash
_etext = LOADADDR(.data);
/* .bss section: uninitialized global variables go to ram */
_bss_start = .;
.bss :
{
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
. = ALIGN(8);
} > xram
_bss_end = .;
_end = .;
PROVIDE(end = .);
}
# Copyright (C) 2023 by Skyward
#
# This program is free software; you can redistribute it and/or
# it under the terms of the GNU General Public License as published
# 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
# Public License. This exception does not invalidate any other
# 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/>
set(BOARD_NAME stm32f429zi_death_stack_v1)
set(ARCH_NAME cortexM4_stm32f4)
# Base directories with header files for this board
set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common)
set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME})
set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config)
# Specify where to find the board specific config/miosix_settings.h
set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH})
# Specify where to find the board specific config/mxgui_settings.h
set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH})
# Optimization flags:
# -O0 do no optimization, the default if no optimization level is specified
# -O or -O1 optimize minimally
# -O2 optimize more
# -O3 optimize even more
# -Ofast optimize very aggressively to the point of breaking the standard
# -Og Optimize debugging experience, enables optimizations that do not
# interfere with debugging
# -Os Optimize for size with -O2 optimizations that do not increase code size
set(OPT_OPTIMIZATION
$<$<CONFIG:Debug>:-O2>
$<$<CONFIG:Release>:-O2>
)
# Boot and linker files
set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp)
# Linker script type, there are three options
# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld)
# the most common choice, available for all microcontrollers
# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld)
# You must uncomment -D__ENABLE_XRAM below in this case.
# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld)
set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld)
# Uncommenting __ENABLE_XRAM enables the initialization of the external
# 8MB SDRAM memory.
set(XRAM -D__ENABLE_XRAM)
# Select clock frequency. Warning: the default clock frequency for
# this board is 168MHz and not 180MHz because, due to a limitation in
# the PLL, it is not possible to generate a precise 48MHz output when
# running the core at 180MHz. If 180MHz is chosen the USB peripheral will
# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48)
# Define USE_INTERNAL_CLOCK to bypass the external oscillator
# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000)
set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000 -DUSE_INTERNAL_CLOCK)
# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000)
# C++ Exception/rtti support disable flags.
# To save code size if not using C++ exceptions (nor some STL code which
# implicitly uses it) uncomment this option.
# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used.
# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS)
# Specify a custom flash command
# This is the program that is invoked when the flash flag (-f or --flash) is
# used with the Miosix Build System. Use $binary or $hex as placeolders, they
# will be replaced by the build systems with the binary or hex file repectively.
# If a command is not specified, the build system will use st-flash if found
# set(PROGRAM_CMDLINE "here your custom flash command")
# Basic flags
set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16)
# Flags for ASM and linker
set(AFLAGS_BASE ${FLAGS_BASE})
set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib)
# Flags for C/C++
string(TOUPPER ${BOARD_NAME} BOARD_UPPER)
set(CFLAGS_BASE
-D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\"
-D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g
-D_ARCH_CORTEXM4_STM32F4
${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c
)
set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT})
# Select architecture specific files
set(ARCH_SRC
${ARCH_PATH}/interfaces-impl/delays.cpp
${ARCH_PATH}/interfaces-impl/gpio_impl.cpp
${ARCH_PATH}/interfaces-impl/portability.cpp
${BOARD_PATH}/interfaces-impl/bsp.cpp
${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c
${KPATH}/arch/common/core/interrupts_cortexMx.cpp
${KPATH}/arch/common/core/mpu_cortexMx.cpp
${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp
${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp
${KPATH}/arch/common/drivers/serial_stm32.cpp
${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp
${KPATH}/arch/common/drivers/servo_stm32.cpp
${KPATH}/arch/common/drivers/stm32_wd.cpp
${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp
)
This diff is collapsed.
This diff is collapsed.