diff --git a/speeduino/board_stm32.h b/speeduino/board_stm32.h index 81835bca..f1e1b7b9 100644 --- a/speeduino/board_stm32.h +++ b/speeduino/board_stm32.h @@ -1,6 +1,15 @@ #ifndef STM32_H #define STM32_H #if defined(CORE_STM32) +#if defined(STM32F4) + //These should really be in the stm32GENERIC libs, but for somereason they only have timers 1-4 +// #include +// #include "src/HardwareTimers/HardwareTimer.h" +// HardwareTimer Timer5(TIM5, chip_tim5, sizeof(chip_tim5) / sizeof(chip_tim5[0])); +// HardwareTimer Timer8(TIM8, chip_tim8, sizeof(chip_tim8) / sizeof(chip_tim8[0])); +#else + #include "HardwareTimer.h" +#endif /* *********************************************************************************************************** @@ -8,10 +17,13 @@ */ #define PORT_TYPE uint8_t #define micros_safe() micros() //timer5 method is not used on anything but AVR, the micros_safe() macro is simply an alias for the normal micros() + #define USE_SERIAL3 void initBoard(); uint16_t freeRam(); - + extern void oneMSIntervalIRQ(stimer_t *Timer); + + extern void EmptyIRQCallback(stimer_t *Timer, uint32_t channel); #if defined(USE_STM32GENERIC) #define Serial Serial1 #endif @@ -292,4 +304,4 @@ */ #endif //CORE_STM32 -#endif //STM32_H \ No newline at end of file +#endif //STM32_H diff --git a/speeduino/board_stm32.ino b/speeduino/board_stm32.ino index 0b9242e5..8f14ab2b 100644 --- a/speeduino/board_stm32.ino +++ b/speeduino/board_stm32.ino @@ -4,22 +4,47 @@ #include "auxiliaries.h" #include "idle.h" #include "scheduler.h" -#include "HardwareTimer.h" #if defined(STM32F4) + #define NR_OFF_TIMERS 9 + //stimer_t HardwareTimers[NR_OFF_TIMERS + 1]; + stimer_t HardwareTimers_1; + stimer_t HardwareTimers_2; + stimer_t HardwareTimers_3; + stimer_t HardwareTimers_4; + stimer_t HardwareTimers_5; + stimer_t HardwareTimers_8; + //These should really be in the stm32GENERIC libs, but for somereason they only have timers 1-4 - #include - HardwareTimer Timer5(TIM5, chip_tim5, sizeof(chip_tim5) / sizeof(chip_tim5[0])); - HardwareTimer Timer8(TIM8, chip_tim8, sizeof(chip_tim8) / sizeof(chip_tim8[0])); +// #include +// #include "src/HardwareTimers/HardwareTimer.h" +// HardwareTimer Timer5(TIM5, chip_tim5, sizeof(chip_tim5) / sizeof(chip_tim5[0])); +// HardwareTimer Timer8(TIM8, chip_tim8, sizeof(chip_tim8) / sizeof(chip_tim8[0])); +#else + #include "HardwareTimer.h" #endif +extern void oneMSIntervalIRQ(stimer_t *Timer){oneMSInterval();} +extern void EmptyIRQCallback(stimer_t *Timer, uint32_t channel){} + void initBoard() { + /* + * Initialize timers + */ + + HardwareTimers_1.timer = TIM1; + HardwareTimers_2.timer = TIM2; + HardwareTimers_3.timer = TIM3; + HardwareTimers_4.timer = TIM4; + + HardwareTimers_5.timer = TIM5; + HardwareTimers_8.timer = TIM8; + /* *********************************************************************************************************** * General */ - #define FLASH_LENGTH 8192 - + #define FLASH_LENGTH 8192 /* *********************************************************************************************************** @@ -31,10 +56,10 @@ void initBoard() } //This must happen at the end of the idle init - Timer1.setMode(4, TIMER_OUTPUT_COMPARE); + //Timer1.setMode(4, TIMER_OUTPUT_COMPARE); //timer_set_mode(TIMER1, 4, TIMER_OUTPUT_COMPARE; - if(idle_pwm_max_count > 0) { Timer1.attachInterrupt(4, idleInterrupt);} //on first flash the configPage4.iacAlgorithm is invalid - Timer1.resume(); + //if(idle_pwm_max_count > 0) { Timer1.attachInterrupt(4, idleInterrupt);} //on first flash the configPage4.iacAlgorithm is invalid + //Timer1.resume(); /* @@ -42,10 +67,8 @@ void initBoard() * Timers */ #if defined(ARDUINO_BLACK_F407VE) || defined(STM32F4) || defined(_STM32F4_) - Timer8.setPeriod(1000); // Set up period - Timer8.setMode(1, TIMER_OUTPUT_COMPARE); - Timer8.attachInterrupt(1, oneMSInterval); - Timer8.resume(); //Start Timer + TimerHandleInit(&HardwareTimers_8, 1000, 168); + attachIntHandle(&HardwareTimers_8, oneMSIntervalIRQ); #else Timer4.setPeriod(1000); // Set up period Timer4.setMode(1, TIMER_OUTPUT_COMPARE); @@ -63,11 +86,11 @@ void initBoard() vvt_pwm_max_count = 1000000L / (2 * configPage6.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 2uS) it takes to complete 1 cycle //Need to be initialised last due to instant interrupt - Timer1.setMode(2, TIMER_OUTPUT_COMPARE); - Timer1.setMode(3, TIMER_OUTPUT_COMPARE); - if(boost_pwm_max_count > 0) { Timer1.attachInterrupt(2, boostInterrupt);} - if(vvt_pwm_max_count > 0) { Timer1.attachInterrupt(3, vvtInterrupt);} - Timer1.resume(); +// Timer1.setMode(2, TIMER_OUTPUT_COMPARE); +// Timer1.setMode(3, TIMER_OUTPUT_COMPARE); +// if(boost_pwm_max_count > 0) { Timer1.attachInterrupt(2, boostInterrupt);} +// if(vvt_pwm_max_count > 0) { Timer1.attachInterrupt(3, vvtInterrupt);} +// Timer1.resume(); /* *********************************************************************************************************** @@ -75,9 +98,9 @@ void initBoard() */ #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 +// 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__) @@ -94,71 +117,60 @@ void initBoard() 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); + + TimerPulseInit(&HardwareTimers_2, 0xFFFF, 500, EmptyIRQCallback); + attachIntHandleOC(&HardwareTimers_2, fuelSchedule1Interrupt, 1, 0); + attachIntHandleOC(&HardwareTimers_2, fuelSchedule2Interrupt, 2, 0); + attachIntHandleOC(&HardwareTimers_2, fuelSchedule3Interrupt, 3, 0); + attachIntHandleOC(&HardwareTimers_2, fuelSchedule4Interrupt, 4, 0); - 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); + TimerPulseInit(&HardwareTimers_3, 0xFFFF, 500, EmptyIRQCallback); + attachIntHandleOC(&HardwareTimers_3, ignitionSchedule1Interrupt, 1, 0); + attachIntHandleOC(&HardwareTimers_3, ignitionSchedule2Interrupt, 2, 0); + attachIntHandleOC(&HardwareTimers_3, ignitionSchedule3Interrupt, 3, 0); + attachIntHandleOC(&HardwareTimers_3, ignitionSchedule4Interrupt, 4, 0); + +// Timer1.setMode(1, TIMER_OUTPUT_COMPARE); //Attach interupt functions //Injection - Timer2.attachInterrupt(1, fuelSchedule1Interrupt); - Timer2.attachInterrupt(2, fuelSchedule2Interrupt); - Timer2.attachInterrupt(3, fuelSchedule3Interrupt); - Timer2.attachInterrupt(4, fuelSchedule4Interrupt); + + TimerPulseInit(&HardwareTimers_5, 0xFFFF, 0, EmptyIRQCallback); #if (INJ_CHANNELS >= 5) - Timer5.attachInterrupt(1, fuelSchedule5Interrupt); + attachIntHandleOC(&HardwareTimers_5, fuelSchedule5Interrupt, 1, 0); +//Timer5.attachInterrupt(1, fuelSchedule5Interrupt); #endif #if (INJ_CHANNELS >= 6) - Timer5.attachInterrupt(2, fuelSchedule6Interrupt); + attachIntHandleOC(&HardwareTimers_5, fuelSchedule6Interrupt, 2, 0); + //Timer5.attachInterrupt(2, fuelSchedule6Interrupt); #endif #if (INJ_CHANNELS >= 7) - Timer5.attachInterrupt(3, fuelSchedule7Interrupt); + attachIntHandleOC(&HardwareTimers_5, fuelSchedule7Interrupt, 3, 0); + //Timer5.attachInterrupt(3, fuelSchedule7Interrupt); #endif #if (INJ_CHANNELS >= 8) - Timer5.attachInterrupt(4, fuelSchedule8Interrupt); + attachIntHandleOC(&HardwareTimers_5, fuelSchedule8Interrupt, 4, 0); + //Timer5.attachInterrupt(4, fuelSchedule8Interrupt); #endif - //Ignition - #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 + TimerPulseInit(&HardwareTimers_4, 0xFFFF, 0, EmptyIRQCallback); #if (IGN_CHANNELS >= 5) - Timer4.attachInterrupt(1, ignitionSchedule5Interrupt); + attachIntHandleOC(&HardwareTimers_4, ignitionSchedule5Interrupt, 1, 0); + //Timer4.attachInterrupt(1, ignitionSchedule5Interrupt); #endif #if (IGN_CHANNELS >= 6) - Timer4.attachInterrupt(2, ignitionSchedule6Interrupt); + attachIntHandleOC(&HardwareTimers_4, ignitionSchedule6Interrupt, 2, 0); + //Timer4.attachInterrupt(2, ignitionSchedule6Interrupt); #endif #if (IGN_CHANNELS >= 7) - Timer4.attachInterrupt(3, ignitionSchedule7Interrupt); + attachIntHandleOC(&HardwareTimers_4, ignitionSchedule7Interrupt, 3, 0); + //Timer4.attachInterrupt(3, ignitionSchedule7Interrupt); #endif #if (IGN_CHANNELS >= 8) - Timer4.attachInterrupt(4, ignitionSchedule8Interrupt); + attachIntHandleOC(&HardwareTimers_4, ignitionSchedule8Interrupt, 4, 0); + //Timer4.attachInterrupt(4, ignitionSchedule8Interrupt); #endif - Timer1.resume(); - Timer2.resume(); - Timer3.resume(); - #if (IGN_CHANNELS >= 5) - Timer4.resume(); - #endif - #if (INJ_CHANNELS >= 5) - Timer5.resume(); - #endif } uint16_t freeRam() @@ -167,4 +179,4 @@ uint16_t freeRam() return &top - reinterpret_cast(sbrk(0)); } -#endif \ No newline at end of file +#endif diff --git a/speeduino/cancomms.h b/speeduino/cancomms.h index 08ca00f3..3c62cf02 100644 --- a/speeduino/cancomms.h +++ b/speeduino/cancomms.h @@ -16,7 +16,8 @@ uint8_t Glow, Ghigh; HardwareSerial &CANSerial = Serial3; #elif defined(CORE_STM32) #if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core - SerialUART &CANSerial = Serial2; + HardwareSerial CANSerial(PD6,PD5); + //SerialUART &CANSerial = Serial2; #else //libmaple core aka STM32DUINO HardwareSerial &CANSerial = Serial2; #endif diff --git a/speeduino/globals.h b/speeduino/globals.h index 105095ad..dd0ea6f4 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -50,7 +50,7 @@ extern "C" char* sbrk(int incr); //Used to freeRam #if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core - inline unsigned char digitalPinToInterrupt(unsigned char Interrupt_pin) { return Interrupt_pin; } //This isn't included in the stm32duino libs (yet) + //inline unsigned char digitalPinToInterrupt(unsigned char Interrupt_pin) { return Interrupt_pin; } //This isn't included in the stm32duino libs (yet) #define portOutputRegister(port) (volatile byte *)( &(port->ODR) ) #define portInputRegister(port) (volatile byte *)( &(port->IDR) ) #else //libmaple core aka STM32DUINO diff --git a/speeduino/src/HardwareTimers/HardwareTimer.cpp_test b/speeduino/src/HardwareTimers/HardwareTimer.cpp_test new file mode 100644 index 00000000..96c470c9 --- /dev/null +++ b/speeduino/src/HardwareTimers/HardwareTimer.cpp_test @@ -0,0 +1,415 @@ +/* + Copyright (c) 2017 Daniel Fekete + + 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 "HardwareTimer.h" + +//#include CHIP_PERIPHERAL_INCLUDE + +HardwareTimer *interruptTimers[18]; + +void (*pwm_callback_func)(); +static void handleInterrupt(HardwareTimer *timer); + +static const uint32_t OCMODE_NOT_USED = 0xFFFF; + +HardwareTimer::HardwareTimer(TIM_TypeDef* timer) { + // this->tim_pin_list = pin_list; + // this->tim_pin_list_size = pin_list_size; + _timer.timer = timer; + //handle.Instance = timer; + + // for(int i=0; i<4; i++) { + // channelOC[i].OCMode = OCMODE_NOT_USED; + // channelOC[i].OCPolarity = TIM_OCPOLARITY_HIGH; + // channelOC[i].OCNPolarity = TIM_OCNPOLARITY_HIGH; + // channelOC[i].OCFastMode = TIM_OCFAST_DISABLE; + // channelOC[i].OCIdleState = TIM_OCIDLESTATE_RESET; + // channelOC[i].OCNIdleState = TIM_OCNIDLESTATE_RESET; + + // channelIC[i].ICPolarity = OCMODE_NOT_USED; + // channelIC[i].ICSelection = TIM_ICSELECTION_DIRECTTI; + // channelIC[i].ICPrescaler = TIM_ICPSC_DIV1; + // channelIC[i].ICFilter = 0; + // } + +} + +void HardwareTimer::pause() { + HAL_TIM_Base_Stop(&(_timer.handle)); +} + +void HardwareTimer::resume() { + + HAL_TIM_Base_MspInit(_timer) + + + handle.Init.CounterMode = TIM_COUNTERMODE_UP; + handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + handle.Init.RepetitionCounter = 0; + + HAL_TIM_Base_Init(&handle); + + if (callbacks[0] != NULL) { + HAL_TIM_Base_Start_IT(&handle); + } else { + + HAL_TIM_Base_Start(&handle); + } + + resumeChannel(1, TIM_CHANNEL_1); + resumeChannel(2, TIM_CHANNEL_2); + resumeChannel(3, TIM_CHANNEL_3); + resumeChannel(4, TIM_CHANNEL_4); +} + +void HardwareTimer::resumeChannel(int channel, int timChannel) { + + if (channelOC[channel - 1].OCMode != OCMODE_NOT_USED) { + HAL_TIM_OC_ConfigChannel(&handle, &channelOC[channel - 1], timChannel); + + if (callbacks[channel] != NULL) { + HAL_TIM_OC_Start_IT(&handle, timChannel); + } else { + HAL_TIM_OC_Start(&handle, timChannel); + } + } + + if (channelIC[channel - 1].ICPolarity != OCMODE_NOT_USED) { + HAL_TIM_IC_ConfigChannel(&handle, &channelIC[channel - 1], timChannel); + + if (callbacks[channel] != NULL) { + HAL_TIM_IC_Start_IT(&handle, timChannel); + } else { + HAL_TIM_IC_Start(&handle, timChannel); + } + } +} + +uint32_t HardwareTimer::getPrescaleFactor() { + return handle.Init.Prescaler; +} + +void HardwareTimer::setPrescaleFactor(uint32_t prescaler) { + handle.Init.Prescaler = prescaler; +} + +uint32_t HardwareTimer::getOverflow() { + return handle.Init.Period; +} + +void HardwareTimer::setOverflow(uint32_t overflow) { + handle.Init.Period = overflow; +} + +uint32_t HardwareTimer::getCount(void) { + return __HAL_TIM_GET_COUNTER(&handle); +} + +void HardwareTimer::setCount(uint32_t counter) { + __HAL_TIM_SET_COUNTER(&handle, counter); +} + +#define MAX_RELOAD ((1 << 16) - 1) // Not always! 32 bit timers! + +uint32_t HardwareTimer::getBaseFrequency() { + int freqMul = 2; + int freq2Mul = 2; + uint32_t pFreq = HAL_RCC_GetPCLK1Freq(); + +#ifdef STM32F1 + freq2Mul = 1; +#endif + +#ifdef TIM1 + if (handle.Instance == TIM1) { + pFreq = HAL_RCC_GetPCLK2Freq(); + freqMul = freq2Mul; + } +#endif +#ifdef TIM8 + if (handle.Instance == TIM8) { + pFreq = HAL_RCC_GetPCLK2Freq(); + freqMul = freq2Mul; + } +#endif +#ifdef TIM9 + if (handle.Instance == TIM9) { + pFreq = HAL_RCC_GetPCLK2Freq(); + freqMul = freq2Mul; + } +#endif +#ifdef TIM10 + if (handle.Instance == TIM10) { + pFreq = HAL_RCC_GetPCLK2Freq(); + freqMul = freq2Mul; + } +#endif +#ifdef TIM11 + if (handle.Instance == TIM11) { + pFreq = HAL_RCC_GetPCLK2Freq(); + freqMul = freq2Mul; + } +#endif + + return pFreq * freqMul; +} + +uint32_t HardwareTimer::setPeriod(uint32_t microseconds) { + if (!microseconds) { + this->setPrescaleFactor(1); + this->setOverflow(1); + return this->getOverflow(); + } + + uint32_t period_cyc = microseconds * (getBaseFrequency() / 1000000); //TODO! + + uint32_t prescaler = (uint32_t)(period_cyc / MAX_RELOAD + 1); + + uint32_t overflow = (uint32_t)((period_cyc + (prescaler / 2)) / prescaler); + + this->setPrescaleFactor(prescaler); + this->setOverflow(overflow); + return overflow; +} + +static bool isSameChannel(int channel, uint8_t signal) { + // switch(signal) { + // case TIM_CH1: + // case TIM_CH1N: + // return channel == 1; + // case TIM_CH2: + // case TIM_CH2N: + // return channel == 2; + // case TIM_CH3: + // case TIM_CH3N: + // return channel == 3; + // case TIM_CH4: + // case TIM_CH4N: + // return channel == 4; + // } + return false; +} + +static const uint32_t PIN_NOT_USED = 0xFF; + +void HardwareTimer::setMode(int channel, TIMER_MODES mode, uint8_t pin) { + int pinMode = PIN_NOT_USED; + int pull = GPIO_NOPULL; + + switch(mode) { + case TIMER_PWM: + channelOC[channel - 1].OCMode = TIM_OCMODE_PWM1; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_OUTPUT_COMPARE: + channelOC[channel - 1].OCMode = TIM_OCMODE_TIMING; + break; + + case TIMER_OUTPUT_COMPARE_ACTIVE: + channelOC[channel - 1].OCMode = TIM_OCMODE_ACTIVE; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_OUTPUT_COMPARE_INACTIVE: + channelOC[channel - 1].OCMode = TIM_OCMODE_ACTIVE; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_OUTPUT_COMPARE_TOGGLE: + channelOC[channel - 1].OCMode = TIM_OCMODE_TOGGLE; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_OUTPUT_COMPARE_PWM1: + channelOC[channel - 1].OCMode = TIM_OCMODE_PWM1; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_OUTPUT_COMPARE_PWM2: + channelOC[channel - 1].OCMode = TIM_OCMODE_PWM2; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_OUTPUT_COMPARE_FORCED_ACTIVE: + channelOC[channel - 1].OCMode = TIM_OCMODE_FORCED_ACTIVE; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_OUTPUT_COMPARE_FORCED_INACTIVE: + channelOC[channel - 1].OCMode = TIM_OCMODE_FORCED_INACTIVE; + pinMode = GPIO_MODE_AF_PP; + break; + + case TIMER_INPUT_CAPTURE_RISING: + channelIC[channel - 1].ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + pinMode = GPIO_MODE_AF_PP; + pull = GPIO_PULLDOWN; + break; + + case TIMER_INPUT_CAPTURE_FALLING: + channelIC[channel - 1].ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + pinMode = GPIO_MODE_AF_PP; + pull = GPIO_PULLDOWN; + break; + } + + if (pinMode != PIN_NOT_USED) { + //for(int i=0; ihandle, TIM_FLAG_UPDATE) != RESET) { + __HAL_TIM_CLEAR_IT(&timer->handle, TIM_IT_UPDATE); + if (timer->callbacks[0] != NULL) timer->callbacks[0](); + } + + if(__HAL_TIM_GET_FLAG(&timer->handle, TIM_FLAG_CC1) != RESET) { + __HAL_TIM_CLEAR_IT(&timer->handle, TIM_IT_CC1); + if (timer->callbacks[1] != NULL) timer->callbacks[1](); + } + + if(__HAL_TIM_GET_FLAG(&timer->handle, TIM_FLAG_CC2) != RESET) { + __HAL_TIM_CLEAR_IT(&timer->handle, TIM_IT_CC2); + if (timer->callbacks[2] != NULL) timer->callbacks[2](); + } + + if(__HAL_TIM_GET_FLAG(&timer->handle, TIM_FLAG_CC3) != RESET) { + __HAL_TIM_CLEAR_IT(&timer->handle, TIM_IT_CC3); + if (timer->callbacks[3] != NULL) timer->callbacks[3](); + } + + if(__HAL_TIM_GET_FLAG(&timer->handle, TIM_FLAG_CC4) != RESET) { + __HAL_TIM_CLEAR_IT(&timer->handle, TIM_IT_CC4); + if (timer->callbacks[4] != NULL) timer->callbacks[4](); + } +} + +#ifdef TIM1 + HardwareTimer Timer1(TIM1); +#endif + +#ifdef TIM2 + HardwareTimer Timer2(TIM2); +#endif + +#ifdef TIM3 + HardwareTimer Timer3(TIM3); +#endif + +#ifdef TIM4 + HardwareTimer Timer4(TIM4); +#endif + +#ifdef TIM5 + HardwareTimer Timer5(TIM5); +#endif + +#ifdef TIM8 + HardwareTimer Timer8(TIM8); +#endif + +//Timer interrupts: + +// extern "C" void TIM1_CC_IRQHandler(void) { +// if (interruptTimers[0] != NULL) handleInterrupt(interruptTimers[0]); +// } +// extern "C" void TIM1_UP_IRQHandler(void) { +// if (interruptTimers[0] != NULL) handleInterrupt(interruptTimers[0]); +// } +// #ifndef TIM1_UP_TIM10_IRQHandler +// extern "C" void TIM1_UP_TIM10_IRQHandler(void) { +// if (interruptTimers[0] != NULL) handleInterrupt(interruptTimers[0]); +// if (interruptTimers[9] != NULL) handleInterrupt(interruptTimers[9]); +// } +// #endif + +// in stm32_PWM.c +/* +extern "C" void TIM2_IRQHandler(void) { + handleInterrupt(interruptTimers[1]); +}*/ + +// extern "C" void TIM3_IRQHandler(void) { +// if (interruptTimers[2] != NULL) handleInterrupt(interruptTimers[2]); +// } +// extern "C" void TIM4_IRQHandler(void) { +// if (interruptTimers[3] != NULL) handleInterrupt(interruptTimers[3]); +// } diff --git a/speeduino/src/HardwareTimers/HardwareTimer.h_test b/speeduino/src/HardwareTimers/HardwareTimer.h_test new file mode 100644 index 00000000..1cbaaefa --- /dev/null +++ b/speeduino/src/HardwareTimers/HardwareTimer.h_test @@ -0,0 +1,123 @@ +#ifndef HARDWARETIMER_H_ +#define HARDWARETIMER_H_ + +#include "Arduino.h" +#include "timer.h" +//#include "stm32_gpio_af.h" + +typedef enum { + //libmaple: // HAL compatible + TIMER_DISABLED, + TIMER_PWM, // == TIM_OCMODE_PWM1 + TIMER_OUTPUT_COMPARE, // == TIM_OCMODE_TIMING no output, useful for only-interrupt + + //other: + TIMER_OUTPUT_COMPARE_ACTIVE, // == TIM_OCMODE_ACTIVE pin is set high when counter == channel compare + TIMER_OUTPUT_COMPARE_INACTIVE, // == TIM_OCMODE_INACTIVE pin is set low when counter == channel compare + TIMER_OUTPUT_COMPARE_TOGGLE, // == TIM_OCMODE_TOGGLE pin toggles when counter == channel compare + TIMER_OUTPUT_COMPARE_PWM1, // == TIM_OCMODE_PWM1 pin high when counter < channel compare, low otherwise + TIMER_OUTPUT_COMPARE_PWM2, // == TIM_OCMODE_PWM2 pin low when counter < channel compare, high otherwise + TIMER_OUTPUT_COMPARE_FORCED_ACTIVE, // == TIM_OCMODE_FORCED_ACTIVE pin always high + TIMER_OUTPUT_COMPARE_FORCED_INACTIVE, // == TIM_OCMODE_FORCED_INACTIVE pin always low + + //Input capture + TIMER_INPUT_CAPTURE_RISING, // == TIM_INPUTCHANNELPOLARITY_RISING + TIMER_INPUT_CAPTURE_FALLING, // == TIM_INPUTCHANNELPOLARITY_FALLING + + //PWM input capture on channel 1 + channel 2 + //TIMER_INPUT_CAPTURE_PWM, // == TIM_INPUTCHANNELPOLARITY_RISING (channel 1) + TIM_INPUTCHANNELPOLARITY_FALLING (channel 2) + + //Encoder mode + //TIMER_ENCODER // == TIM_ENCODERMODE_TI1 +} TIMER_MODES; + +#define TIMER_DEFAULT_PIN 0xFF + +class HardwareTimer { +public: + HardwareTimer(TIM_TypeDef* timer); + + void pause(void); + + void resume(void); + + uint32_t getPrescaleFactor(); + + void setPrescaleFactor(uint32_t factor); + + uint32_t getOverflow(); + + void setOverflow(uint32_t val); + + uint32_t getCount(void); + + void setCount(uint32_t val); + + uint32_t setPeriod(uint32_t microseconds); + + void setMode(int channel, TIMER_MODES mode, uint8_t pin = TIMER_DEFAULT_PIN); + + uint32_t getCompare(int channel); + + void setCompare(int channel, uint32_t compare); + + //Add interrupt to period update + void attachInterrupt(void (*handler)(void)); + + void detachInterrupt(); + + //Add interrupt to channel + void attachInterrupt(int channel, void (*handler)(void)); + + void detachInterrupt(int channel); + + void refresh(void); + + uint32_t getBaseFrequency(); + + TIM_HandleTypeDef handle = {0}; + + TIM_OC_InitTypeDef channelOC[4]; + + TIM_IC_InitTypeDef channelIC[4]; + + //Callbacks: 0 for update, 1-4 for channels + void (*callbacks[5])(void); + + stimer_t _timer; + + // //const stm32_tim_pin_list_type *tim_pin_list; + + // int tim_pin_list_size; + +private: + void resumeChannel(int channel, int timChannel); + +}; + +#ifdef TIM1 + extern HardwareTimer Timer1; +#endif + +#ifdef TIM2 + extern HardwareTimer Timer2; +#endif + +#ifdef TIM3 + extern HardwareTimer Timer3; +#endif + +#ifdef TIM4 + extern HardwareTimer Timer4; +#endif + +#ifdef TIM5 + extern HardwareTimer Timer5; +#endif + +#ifdef TIM8 + extern HardwareTimer Timer8; +#endif + + +#endif