2020-01-23 17:32:51 -08:00
# if defined(CORE_STM32_GENERIC)
2019-03-04 04:45:33 -08:00
# include "board_stm32_generic.h"
2019-01-22 20:20:14 -08:00
# include "globals.h"
# include "auxiliaries.h"
# include "idle.h"
# include "scheduler.h"
2019-02-23 06:35:06 -08:00
# include "HardwareTimer.h"
2019-02-20 13:46:10 -08:00
2021-04-20 21:36:27 -07:00
# if defined(FRAM_AS_EEPROM)
# if defined(STM32F407xx)
FramClass EEPROM ( PB5 , PB4 , PB3 , PB0 ) ; /*(mosi, miso, sclk, ssel, clockspeed) 31/01/2020*/
# else
FramClass EEPROM ( PB15 , PB14 , PB13 , PB12 ) ; //Blue/Black Pills
# endif
# endif
2019-01-19 19:13:24 -08:00
void initBoard ( )
{
2019-01-21 13:56:25 -08:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* General
*/
2019-03-02 20:43:43 -08:00
# ifndef FLASH_LENGTH
# define FLASH_LENGTH 8192
# endif
delay ( 10 ) ;
2019-01-21 15:04:21 -08:00
/*
2019-01-21 13:56:25 -08:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Idle
*/
if ( ( configPage6 . iacAlgorithm = = IAC_ALGORITHM_PWM_OL ) | | ( configPage6 . iacAlgorithm = = IAC_ALGORITHM_PWM_CL ) )
{
2020-07-02 00:25:16 -07:00
idle_pwm_max_count = 1000000L / ( TIMER_RESOLUTION * configPage6 . idleFreq * 2 ) ; //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 5KHz
2019-01-21 13:56:25 -08:00
}
//This must happen at the end of the idle init
2019-02-23 06:35:06 -08:00
Timer1 . setMode ( 4 , TIMER_OUTPUT_COMPARE ) ;
2020-01-23 17:32:51 -08:00
Timer1 . attachInterrupt ( 4 , idleInterrupt ) ; //on first flash the configPage4.iacAlgorithm is invalid
2019-01-21 13:56:25 -08:00
2019-01-21 15:04:21 -08:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Timers
*/
2020-01-23 17:32:51 -08:00
# if defined(ARDUINO_BLUEPILL_F103C8) || defined(ARDUINO_BLUEPILL_F103CB)
2019-01-21 15:04:21 -08:00
Timer4 . setPeriod ( 1000 ) ; // Set up period
Timer4 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
Timer4 . attachInterrupt ( 1 , oneMSInterval ) ;
Timer4 . resume ( ) ; //Start Timer
2020-01-23 17:32:51 -08:00
# else
Timer11 . setPeriod ( 1000 ) ; // Set up period
Timer11 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
Timer11 . attachInterrupt ( 1 , oneMSInterval ) ;
Timer11 . resume ( ) ; //Start Timer
2019-01-21 15:04:21 -08:00
# endif
pinMode ( LED_BUILTIN , OUTPUT ) ; //Visual WDT
2019-01-22 15:04:54 -08:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2022-04-10 17:49:58 -07:00
* Auxiliaries
2019-01-22 15:04:54 -08:00
*/
//2uS resolution Min 8Hz, Max 5KHz
2022-04-10 17:49:58 -07:00
boost_pwm_max_count = 1000000L / ( TIMER_RESOLUTION * configPage6 . boostFreq * 2 ) ; //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow frequencies up to 511Hz
2020-07-02 00:25:16 -07:00
vvt_pwm_max_count = 1000000L / ( TIMER_RESOLUTION * configPage6 . vvtFreq * 2 ) ; //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle
2021-11-23 17:18:41 -08:00
fan_pwm_max_count = 1000000L / ( TIMER_RESOLUTION * configPage6 . fanFreq * 2 ) ; //Converts the frequency in Hz to the number of ticks (at 4uS) it takes to complete 1 cycle
2019-01-21 15:04:21 -08:00
2019-01-25 23:34:20 -08:00
//Need to be initialised last due to instant interrupt
2021-11-23 17:18:41 -08:00
Timer1 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer1 . setMode ( 2 , TIMER_OUTPUT_COMPARE ) ;
Timer1 . setMode ( 3 , TIMER_OUTPUT_COMPARE ) ;
2021-11-23 17:18:41 -08:00
Timer1 . attachInterrupt ( 1 , fanInterrupt ) ;
2020-01-23 17:32:51 -08:00
Timer1 . attachInterrupt ( 2 , boostInterrupt ) ;
Timer1 . attachInterrupt ( 3 , vvtInterrupt ) ;
2019-02-23 06:35:06 -08:00
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Schedules
*/
2020-01-23 17:32:51 -08:00
# if defined(ARDUINO_BLUEPILL_F103C8) || defined(ARDUINO_BLUEPILL_F103CB)
2019-03-02 20:43:43 -08:00
//(CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
2019-07-08 00:56:02 -07:00
//Timer2 to 4 is on APB1, Timer1 on APB2. www.st.com/resource/en/datasheet/stm32f103cb.pdf sheet 12
2020-07-02 00:25:16 -07:00
Timer1 . setPrescaleFactor ( ( ( Timer1 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
Timer2 . setPrescaleFactor ( ( ( Timer2 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
Timer3 . setPrescaleFactor ( ( ( Timer3 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
2020-01-23 17:32:51 -08:00
# else
2019-03-02 20:43:43 -08:00
//(CYCLES_PER_MICROSECOND == 168, APB2 at 84MHz, APB1 at 42MHz).
2019-07-08 00:56:02 -07:00
//Timer2 to 14 is on APB1, Timers 1, 8, 9 and 10 on APB2. www.st.com/resource/en/datasheet/stm32f407vg.pdf sheet 120
2020-07-02 00:25:16 -07:00
Timer1 . setPrescaleFactor ( ( ( Timer1 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
Timer2 . setPrescaleFactor ( ( ( Timer2 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
Timer3 . setPrescaleFactor ( ( ( Timer3 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
Timer4 . setPrescaleFactor ( ( ( Timer4 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
Timer5 . setPrescaleFactor ( ( ( Timer5 . getBaseFrequency ( ) / 1000000 ) * TIMER_RESOLUTION ) - 1 ) ; //2us resolution
2019-02-23 06:35:06 -08:00
# endif
Timer2 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( 2 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( 3 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( 4 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 2 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 3 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 4 , TIMER_OUTPUT_COMPARE ) ;
2022-04-10 17:49:58 -07:00
//Attach interrupt functions
2019-01-26 13:56:27 -08:00
//Injection
2019-02-23 06:35:06 -08:00
Timer2 . attachInterrupt ( 1 , fuelSchedule1Interrupt ) ;
Timer2 . attachInterrupt ( 2 , fuelSchedule2Interrupt ) ;
Timer2 . attachInterrupt ( 3 , fuelSchedule3Interrupt ) ;
Timer2 . attachInterrupt ( 4 , fuelSchedule4Interrupt ) ;
2019-01-26 13:56:27 -08:00
# if (INJ_CHANNELS >= 5)
2019-03-02 20:43:43 -08:00
Timer5 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer5 . attachInterrupt ( 1 , fuelSchedule5Interrupt ) ;
2019-01-26 13:56:27 -08:00
# endif
# if (INJ_CHANNELS >= 6)
2019-03-02 20:43:43 -08:00
Timer5 . setMode ( 2 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer5 . attachInterrupt ( 2 , fuelSchedule6Interrupt ) ;
2019-01-26 13:56:27 -08:00
# endif
# if (INJ_CHANNELS >= 7)
2019-03-02 20:43:43 -08:00
Timer5 . setMode ( 3 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer5 . attachInterrupt ( 3 , fuelSchedule7Interrupt ) ;
2019-01-26 13:56:27 -08:00
# endif
# if (INJ_CHANNELS >= 8)
2019-03-02 20:43:43 -08:00
Timer5 . setMode ( 4 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer5 . attachInterrupt ( 4 , fuelSchedule8Interrupt ) ;
2019-01-26 13:56:27 -08:00
# endif
2019-01-21 13:56:25 -08:00
2019-02-23 06:35:06 -08:00
//Ignition
Timer3 . attachInterrupt ( 1 , ignitionSchedule1Interrupt ) ;
Timer3 . attachInterrupt ( 2 , ignitionSchedule2Interrupt ) ;
Timer3 . attachInterrupt ( 3 , ignitionSchedule3Interrupt ) ;
Timer3 . attachInterrupt ( 4 , ignitionSchedule4Interrupt ) ;
2019-01-21 13:56:25 -08:00
# if (IGN_CHANNELS >= 5)
2019-03-02 20:43:43 -08:00
Timer4 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer4 . attachInterrupt ( 1 , ignitionSchedule5Interrupt ) ;
2019-01-26 13:56:27 -08:00
# endif
# if (IGN_CHANNELS >= 6)
2019-03-02 20:43:43 -08:00
Timer4 . setMode ( 2 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer4 . attachInterrupt ( 2 , ignitionSchedule6Interrupt ) ;
2019-01-26 13:56:27 -08:00
# endif
# if (IGN_CHANNELS >= 7)
2019-03-02 20:43:43 -08:00
Timer4 . setMode ( 3 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer4 . attachInterrupt ( 3 , ignitionSchedule7Interrupt ) ;
2019-01-26 13:56:27 -08:00
# endif
# if (IGN_CHANNELS >= 8)
2019-03-02 20:43:43 -08:00
Timer4 . setMode ( 4 , TIMER_OUTPUT_COMPARE ) ;
2019-02-23 06:35:06 -08:00
Timer4 . attachInterrupt ( 4 , ignitionSchedule8Interrupt ) ;
2019-01-21 13:56:25 -08:00
# endif
2019-03-02 20:43:43 -08:00
Timer1 . setOverflow ( 0xFFFF ) ;
2019-02-23 06:35:06 -08:00
Timer1 . resume ( ) ;
2019-03-02 20:43:43 -08:00
Timer2 . setOverflow ( 0xFFFF ) ;
2019-02-23 06:35:06 -08:00
Timer2 . resume ( ) ;
2019-03-02 20:43:43 -08:00
Timer3 . setOverflow ( 0xFFFF ) ;
2019-02-23 06:35:06 -08:00
Timer3 . resume ( ) ;
# if (IGN_CHANNELS >= 5)
2019-03-02 20:43:43 -08:00
Timer4 . setOverflow ( 0xFFFF ) ;
2019-02-23 06:35:06 -08:00
Timer4 . resume ( ) ;
# endif
# if (INJ_CHANNELS >= 5)
2019-03-02 20:43:43 -08:00
Timer5 . setOverflow ( 0xFFFF ) ;
2019-02-23 06:35:06 -08:00
Timer5 . resume ( ) ;
# endif
2019-01-21 13:56:25 -08:00
}
uint16_t freeRam ( )
{
char top = ' t ' ;
return & top - reinterpret_cast < char * > ( sbrk ( 0 ) ) ;
2019-01-19 19:13:24 -08:00
}
2019-02-20 08:21:16 -08:00
2020-12-02 14:24:15 -08:00
void doSystemReset ( void )
{
__disable_irq ( ) ;
NVIC_SystemReset ( ) ;
}
void jumpToBootloader ( void ) // https://github.com/3devo/Arduino_Core_STM32/blob/jumpSysBL/libraries/SrcWrapper/src/stm32/bootloader.c
{ // https://github.com/markusgritsch/SilF4ware/blob/master/SilF4ware/drv_reset.c
HAL_RCC_DeInit ( ) ;
HAL_DeInit ( ) ;
SysTick - > VAL = SysTick - > LOAD = SysTick - > CTRL = 0 ;
SYSCFG - > MEMRMP = 0x01 ;
# if defined(STM32F7xx) || defined(STM32H7xx)
const uint32_t DFU_addr = 0x1FF00000 ; // From AN2606
# else
const uint32_t DFU_addr = 0x1FFF0000 ; // Default for STM32F10xxx and STM32F40xxx/STM32F41xxx from AN2606
# endif
// This is assembly to prevent modifying the stack pointer after
// loading it, and to ensure a jump (not call) to the bootloader.
// Not sure if the barriers are really needed, they were taken from
// https://github.com/GrumpyOldPizza/arduino-STM32L4/blob/ac659033eadd50cfe001ba1590a1362b2d87bb76/system/STM32L4xx/Source/boot_stm32l4xx.c#L159-L165
asm volatile (
" ldr r0, [%[DFU_addr], #0] \n \t " // get address of stack pointer
" msr msp, r0 \n \t " // set stack pointer
" ldr r0, [%[DFU_addr], #4] \n \t " // get address of reset handler
" dsb \n \t " // data sync barrier
" isb \n \t " // instruction sync barrier
" bx r0 \n \t " // branch to bootloader
: : [ DFU_addr ] " l " ( DFU_addr ) : " r0 "
) ;
__builtin_unreachable ( ) ;
}
2022-04-10 17:49:58 -07:00
# endif