From 0fbab60841aa5b2bbcaba6f294c4bb27cd56f4e1 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Tue, 22 Jan 2019 10:56:25 +1300 Subject: [PATCH] Move most of the stm32 runtime into board file --- speeduino/board_avr2560.h | 1 + speeduino/board_avr2560.ino | 8 ++++ speeduino/board_stm32.h | 4 +- speeduino/board_stm32.ino | 90 +++++++++++++++++++++++++++++++++++- speeduino/board_teensy35.h | 1 + speeduino/board_teensy35.ino | 17 +++++++ speeduino/idle.ino | 13 +----- speeduino/scheduler.ino | 66 ++------------------------ speeduino/utils.h | 1 - speeduino/utils.ino | 29 ------------ 10 files changed, 123 insertions(+), 107 deletions(-) diff --git a/speeduino/board_avr2560.h b/speeduino/board_avr2560.h index bcfb7591..3644d5c8 100644 --- a/speeduino/board_avr2560.h +++ b/speeduino/board_avr2560.h @@ -11,6 +11,7 @@ */ #define PORT_TYPE uint8_t //Size of the port variables (Eg inj1_pin_port). void initBoard(); + uint16_t freeRam(); /* *********************************************************************************************************** diff --git a/speeduino/board_avr2560.ino b/speeduino/board_avr2560.ino index 65eccb41..25ff9e14 100644 --- a/speeduino/board_avr2560.ino +++ b/speeduino/board_avr2560.ino @@ -8,4 +8,12 @@ void initBoard() } +uint16_t freeRam() +{ + extern int __heap_start, *__brkval; + uint16_t v; + + return (uint16_t) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +} + #endif \ No newline at end of file diff --git a/speeduino/board_stm32.h b/speeduino/board_stm32.h index d224b87e..5fd523ff 100644 --- a/speeduino/board_stm32.h +++ b/speeduino/board_stm32.h @@ -2,12 +2,15 @@ #define STM32_H #if defined(CORE_STM32) +#include "HardwareTimer.h" + /* *********************************************************************************************************** * General */ #define PORT_TYPE uint8_t void initBoard(); + uint16_t freeRam(); //Much of the below is not correct, but included to allow compilation //STM32F1/variants/.../board.cpp @@ -58,7 +61,6 @@ #define uS_TO_TIMER_COMPARE(uS) (uS >> 1) //Converts a given number of uS into the required number of timer ticks until that time has passed. #define uS_TO_TIMER_COMPARE_SLOW(uS) (uS >> 1) //Converts a given number of uS into the required number of timer ticks until that time has passed. #if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core - #include "HardwareTimer.h" #define FUEL1_COUNTER (TIM2)->CNT #define FUEL2_COUNTER (TIM2)->CNT #define FUEL3_COUNTER (TIM2)->CNT diff --git a/speeduino/board_stm32.ino b/speeduino/board_stm32.ino index 336b3fb9..d00a1636 100644 --- a/speeduino/board_stm32.ino +++ b/speeduino/board_stm32.ino @@ -1,10 +1,96 @@ #include "globals.h" - #if defined(CORE_STM32) +#include "board_stm32.h" void initBoard() { - + /* + *********************************************************************************************************** + * General + */ + + + /* + *********************************************************************************************************** + * Idle + */ + if( (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_OL) || (configPage6.iacAlgorithm == IAC_ALGORITHM_PWM_CL) ) + { + idle_pwm_max_count = 1000000L / (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 + } + + //This must happen at the end of the idle init + Timer1.setMode(4, TIMER_OUTPUT_COMPARE); + if(idle_pwm_max_count > 0) { Timer1.attachInterrupt(4, idleInterrupt);} //on first flash the configPage4.iacAlgorithm is invalid + Timer1.resume(); + + + /* + *********************************************************************************************************** + * Schedules + */ + #if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core + //see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444 + Timer1.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution + Timer2.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution + Timer3.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution + #else //libmaple core aka STM32DUINO + //see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444 + #if defined (STM32F1) || defined(__STM32F1__) + //(CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). + //Timer2 to 4 is on APB1, Timer1 on APB2. http://www.st.com/resource/en/datasheet/stm32f103cb.pdf sheet 12 + Timer1.setPrescaleFactor((72 * 2U)-1); //2us resolution + Timer2.setPrescaleFactor((36 * 2U)-1); //2us resolution + Timer3.setPrescaleFactor((36 * 2U)-1); //2us resolution + #elif defined(STM32F4) + //(CYCLES_PER_MICROSECOND == 168, APB2 at 84MHz, APB1 at 42MHz). + //Timer2 to 14 is on APB1, Timers 1, 8, 9 and 10 on APB2. http://www.st.com/resource/en/datasheet/stm32f407vg.pdf sheet 120 + Timer1.setPrescaleFactor((84 * 2U)-1); //2us resolution + Timer2.setPrescaleFactor((42 * 2U)-1); //2us resolution + Timer3.setPrescaleFactor((42 * 2U)-1); //2us resolution + #endif + #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); + Timer1.setMode(1, TIMER_OUTPUT_COMPARE); + + Timer2.attachInterrupt(1, fuelSchedule1Interrupt); + Timer2.attachInterrupt(2, fuelSchedule2Interrupt); + Timer2.attachInterrupt(3, fuelSchedule3Interrupt); + Timer2.attachInterrupt(4, fuelSchedule4Interrupt); + + #if (IGN_CHANNELS >= 1) + Timer3.attachInterrupt(1, ignitionSchedule1Interrupt); + #endif + #if (IGN_CHANNELS >= 2) + Timer3.attachInterrupt(2, ignitionSchedule2Interrupt); + #endif + #if (IGN_CHANNELS >= 3) + Timer3.attachInterrupt(3, ignitionSchedule3Interrupt); + #endif + #if (IGN_CHANNELS >= 4) + Timer3.attachInterrupt(4, ignitionSchedule4Interrupt); + #endif + #if (IGN_CHANNELS >= 5) + Timer1.attachInterrupt(1, ignitionSchedule5Interrupt); + #endif + + Timer1.resume(); + Timer2.resume(); + Timer3.resume(); +} + +uint16_t freeRam() +{ + char top = 't'; + return &top - reinterpret_cast(sbrk(0)); } #endif \ No newline at end of file diff --git a/speeduino/board_teensy35.h b/speeduino/board_teensy35.h index 804c2982..51c50948 100644 --- a/speeduino/board_teensy35.h +++ b/speeduino/board_teensy35.h @@ -7,6 +7,7 @@ * General */ void initBoard(); + uint16_t freeRam(); #define PORT_TYPE uint8_t //Size of the port variables #define BOARD_DIGITAL_GPIO_PINS 34 #define BOARD_NR_GPIO_PINS 34 diff --git a/speeduino/board_teensy35.ino b/speeduino/board_teensy35.ino index 00d99e2e..984c35c9 100644 --- a/speeduino/board_teensy35.ino +++ b/speeduino/board_teensy35.ino @@ -207,4 +207,21 @@ void initBoard() } +uint16_t freeRam() +{ + uint32_t stackTop; + uint32_t heapTop; + + // current position of the stack. + stackTop = (uint32_t) &stackTop; + + // current position of heap. + void* hTop = malloc(1); + heapTop = (uint32_t) hTop; + free(hTop); + + // The difference is the free, available ram. + return (uint16_t)stackTop - heapTop; +} + #endif \ No newline at end of file diff --git a/speeduino/idle.ino b/speeduino/idle.ino index 7c24cf47..baf43dac 100644 --- a/speeduino/idle.ino +++ b/speeduino/idle.ino @@ -56,9 +56,7 @@ void initialiseIdle() idle_pin_mask = digitalPinToBitMask(pinIdle1); idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2)); idle2_pin_mask = digitalPinToBitMask(pinIdle2); - #if defined(CORE_STM32) - idle_pwm_max_count = 1000000L / (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 - #elif defined(CORE_AVR) + #if defined(CORE_AVR) idle_pwm_max_count = 1000000L / (16 * configPage6.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz #elif defined(CORE_TEENSY) idle_pwm_max_count = 1000000L / (32 * configPage6.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz @@ -82,9 +80,7 @@ void initialiseIdle() idle_pin_mask = digitalPinToBitMask(pinIdle1); idle2_pin_port = portOutputRegister(digitalPinToPort(pinIdle2)); idle2_pin_mask = digitalPinToBitMask(pinIdle2); - #if defined(CORE_STM32) - idle_pwm_max_count = 1000000L / (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 - #elif defined(CORE_AVR) + #if defined(CORE_AVR) idle_pwm_max_count = 1000000L / (16 * configPage6.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz #elif defined(CORE_TEENSY) idle_pwm_max_count = 1000000L / (32 * configPage6.idleFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. Note that the frequency is divided by 2 coming from TS to allow for up to 512hz @@ -165,11 +161,6 @@ void initialiseIdle() } idleInitComplete = configPage6.iacAlgorithm; //Sets which idle method was initialised currentStatus.idleLoad = 0; - #if defined(CORE_STM32) //Need to be initialised last due to instant interrupt - Timer1.setMode(4, TIMER_OUTPUT_COMPARE); - if(idle_pwm_max_count > 0) { Timer1.attachInterrupt(4, idleInterrupt);} //on first flash the configPage4.iacAlgorithm is invalid - Timer1.resume(); - #endif } void idleControl() diff --git a/speeduino/scheduler.ino b/speeduino/scheduler.ino index a62d9fbb..dfadf3e3 100644 --- a/speeduino/scheduler.ino +++ b/speeduino/scheduler.ino @@ -10,7 +10,7 @@ A full copy of the license may be found in the projects root directory void initialiseSchedulers() - { +{ nullSchedule.Status = OFF; #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this @@ -42,67 +42,7 @@ void initialiseSchedulers() TIFR4 = 0x00; //Timer4 INT Flag Reg: Clear Timer Overflow Flag TCCR4A = 0x00; //Timer4 Control Reg A: Wave Gen Mode normal TCCR4B = (1 << CS12); //Timer4 Control Reg B: aka Divisor = 256 = 122.5HzTimer Prescaler set to 256. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg - -#elif defined (CORE_TEENSY) - - -#elif defined(CORE_STM32) - #if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core - //see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444 - Timer1.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution - Timer2.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution - Timer3.setPrescaleFactor((HAL_RCC_GetHCLKFreq() * 2U)-1); //2us resolution - #else //libmaple core aka STM32DUINO - //see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444 - #if defined (STM32F1) || defined(__STM32F1__) - //(CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz). - //Timer2 to 4 is on APB1, Timer1 on APB2. http://www.st.com/resource/en/datasheet/stm32f103cb.pdf sheet 12 - Timer1.setPrescaleFactor((72 * 2U)-1); //2us resolution - Timer2.setPrescaleFactor((36 * 2U)-1); //2us resolution - Timer3.setPrescaleFactor((36 * 2U)-1); //2us resolution - #elif defined(STM32F4) - //(CYCLES_PER_MICROSECOND == 168, APB2 at 84MHz, APB1 at 42MHz). - //Timer2 to 14 is on APB1, Timers 1, 8, 9 and 10 on APB2. http://www.st.com/resource/en/datasheet/stm32f407vg.pdf sheet 120 - Timer1.setPrescaleFactor((84 * 2U)-1); //2us resolution - Timer2.setPrescaleFactor((42 * 2U)-1); //2us resolution - Timer3.setPrescaleFactor((42 * 2U)-1); //2us resolution - #endif - #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); - Timer1.setMode(1, TIMER_OUTPUT_COMPARE); - - Timer2.attachInterrupt(1, fuelSchedule1Interrupt); - Timer2.attachInterrupt(2, fuelSchedule2Interrupt); - Timer2.attachInterrupt(3, fuelSchedule3Interrupt); - Timer2.attachInterrupt(4, fuelSchedule4Interrupt); - -#if (IGN_CHANNELS >= 1) - Timer3.attachInterrupt(1, ignitionSchedule1Interrupt); -#endif -#if (IGN_CHANNELS >= 2) - Timer3.attachInterrupt(2, ignitionSchedule2Interrupt); -#endif -#if (IGN_CHANNELS >= 3) - Timer3.attachInterrupt(3, ignitionSchedule3Interrupt); -#endif -#if (IGN_CHANNELS >= 4) - Timer3.attachInterrupt(4, ignitionSchedule4Interrupt); -#endif -#if (IGN_CHANNELS >= 5) - Timer1.attachInterrupt(1, ignitionSchedule5Interrupt); -#endif - - Timer1.resume(); - Timer2.resume(); - Timer3.resume(); + #endif fuelSchedule1.Status = OFF; @@ -158,7 +98,7 @@ void initialiseSchedulers() ignitionSchedule7.schedulesSet = 0; ignitionSchedule8.schedulesSet = 0; - } +} /* These 8 function turn a schedule on, provides the time to start and the duration and gives it callback functions. diff --git a/speeduino/utils.h b/speeduino/utils.h index 6878f388..0a26e8c1 100644 --- a/speeduino/utils.h +++ b/speeduino/utils.h @@ -6,7 +6,6 @@ These are some utility functions and variables used through the main code #include -uint16_t freeRam (); void setResetControlPinState(); byte pinTranslate(byte); diff --git a/speeduino/utils.ino b/speeduino/utils.ino index c1aa3b11..cfe5f3ff 100644 --- a/speeduino/utils.ino +++ b/speeduino/utils.ino @@ -14,35 +14,6 @@ #include "utils.h" #include "decoders.h" -uint16_t freeRam () -{ -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) - extern int __heap_start, *__brkval; - uint16_t v; - - return (uint16_t) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); - -#elif defined(CORE_TEENSY) - uint32_t stackTop; - uint32_t heapTop; - - // current position of the stack. - stackTop = (uint32_t) &stackTop; - - // current position of heap. - void* hTop = malloc(1); - heapTop = (uint32_t) hTop; - free(hTop); - - // The difference is the free, available ram. - return (uint16_t)stackTop - heapTop; -#elif defined(CORE_STM32) - char top = 't'; - return &top - reinterpret_cast(sbrk(0)); - -#endif -} - //This function performs a translation between the pin list that appears in TS and the actual pin numbers //For the digital IO, this will simply return the same number as the rawPin value as those are mapped directly. //For analog pins, it will translate them into the currect internal pin number