From 8ec723a74900d77117be46eb486ed68a8c2a651c Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 13 Apr 2022 20:46:51 +1000 Subject: [PATCH] Roughing out scheduling timer0 --- source/Core/BSP/Magic/BSP.cpp | 1 + source/Core/BSP/Magic/I2C_Wrapper.cpp | 6 +- source/Core/BSP/Magic/IRQ.cpp | 136 ++++++++++++++++---------- source/Core/BSP/Magic/IRQ.h | 35 +------ source/Core/BSP/Magic/Setup.cpp | 48 +++++++++ source/Core/BSP/Magic/clock_config.h | 8 +- source/Core/Threads/GUIThread.cpp | 36 +++---- 7 files changed, 158 insertions(+), 112 deletions(-) diff --git a/source/Core/BSP/Magic/BSP.cpp b/source/Core/BSP/Magic/BSP.cpp index eb24105c..f749a782 100644 --- a/source/Core/BSP/Magic/BSP.cpp +++ b/source/Core/BSP/Magic/BSP.cpp @@ -10,6 +10,7 @@ #include "history.hpp" #include "main.hpp" +// These control the period's of time used for the PWM const uint16_t powerPWM = 255; const uint8_t holdoffTicks = 10; const uint8_t tempMeasureTicks = 14; diff --git a/source/Core/BSP/Magic/I2C_Wrapper.cpp b/source/Core/BSP/Magic/I2C_Wrapper.cpp index b64b3b63..f97ed9d3 100644 --- a/source/Core/BSP/Magic/I2C_Wrapper.cpp +++ b/source/Core/BSP/Magic/I2C_Wrapper.cpp @@ -43,7 +43,7 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t read_address, uint8_t *p_b i2cCfg.subAddrSize = 1; // one byte address err = I2C_MasterReceiveBlocking(I2C0_ID, &i2cCfg); - MSG((char *)"I2C Mem_Read %02X - %d - %d\r\n", DevAddress >> 1, err, number_of_byte); + // MSG((char *)"I2C Mem_Read %02X - %d - %d\r\n", DevAddress >> 1, err, number_of_byte); bool res = err == SUCCESS; if (!res) { I2C_Unstick(); @@ -66,7 +66,7 @@ bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, uint8_t *p_bu i2cCfg.subAddrSize = 1; // one byte address err = I2C_MasterSendBlocking(I2C0_ID, &i2cCfg); - MSG((char *)"I2C Mem_Write %02X - %d\r\n", DevAddress >> 1, err); + // MSG((char *)"I2C Mem_Write %02X - %d\r\n", DevAddress >> 1, err); bool res = err == SUCCESS; if (!res) { I2C_Unstick(); @@ -120,7 +120,7 @@ bool FRToSI2C::wakePart(uint16_t DevAddress) { i2cCfg.subAddrSize = 0; // one byte address err = I2C_MasterReceiveBlocking(I2C0_ID, &i2cCfg); - MSG((char *)"I2C wakePart %02X - %d\r\n", DevAddress >> 1, err); + // MSG((char *)"I2C wakePart %02X - %d\r\n", DevAddress >> 1, err); bool res = err == SUCCESS; if (!res) { I2C_Unstick(); diff --git a/source/Core/BSP/Magic/IRQ.cpp b/source/Core/BSP/Magic/IRQ.cpp index babdc6cd..bffe7757 100644 --- a/source/Core/BSP/Magic/IRQ.cpp +++ b/source/Core/BSP/Magic/IRQ.cpp @@ -8,7 +8,15 @@ #include "IRQ.h" #include "Pins.h" #include "configuration.h" - +extern "C" { +#include "bflb_platform.h" +#include "bl702_glb.h" +#include "bl702_pwm.h" +#include "bl702_timer.h" +#include "hal_clock.h" +#include "hal_pwm.h" +#include "hal_timer.h" +} void ADC0_1_IRQHandler(void) { // adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC); @@ -22,65 +30,85 @@ void ADC0_1_IRQHandler(void) { } } -// static bool fastPWM; -// static void switchToSlowPWM(void); -// static void switchToFastPWM(void); +static bool fastPWM; +static void switchToSlowPWM(void); +static void switchToFastPWM(void); -// volatile uint16_t PWMSafetyTimer = 0; -volatile uint8_t pendingPWM = 200; -// void TIMER1_IRQHandler(void) { -// static bool lastPeriodWasFast = false; +volatile uint16_t PWMSafetyTimer = 0; +volatile uint8_t pendingPWM = 200; +volatile bool lastPeriodWasFast = false; -// if (timer_interrupt_flag_get(TIMER1, TIMER_INT_UP) == SET) { -// timer_interrupt_flag_clear(TIMER1, TIMER_INT_UP); -// // rollover turn on output if required -// if (PWMSafetyTimer) { -// PWMSafetyTimer--; -// if (lastPeriodWasFast != fastPWM) { -// if (fastPWM) { -// switchToFastPWM(); -// } else { -// switchToSlowPWM(); -// } -// } -// if (pendingPWM) { -// timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, pendingPWM); -// timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 50); -// } else { -// timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 0); -// } -// } -// } -// if (timer_interrupt_flag_get(TIMER1, TIMER_INT_CH1) == SET) { -// timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH1); -// timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 0); -// } -// } +// Timer 0 is used to co-ordinate the ADC and the output PWM +void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) { + if (state == TIMER_EVENT_COMP0) { + // MSG((char *)"timer event comp0! \r\n"); + // We use channel 0 to trigger the ADC, this occurs after the main PWM is done with a delay -// void switchToFastPWM(void) { -// // fastPWM = true; -// // totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; -// // TIMER_CAR(TIMER1) = (uint32_t)totalPWM; + } else if (state == TIMER_EVENT_COMP1) { + // MSG((char *)"timer event comp1! \r\n"); + // Channel 1 is end of the main PWM section; so turn off the output PWM + } else if (state == TIMER_EVENT_COMP2) { + // This occurs at timer rollover, so if we want to turn on the output PWM; we do so + if (PWMSafetyTimer) { + PWMSafetyTimer--; + if (lastPeriodWasFast != fastPWM) { + if (fastPWM) { + switchToFastPWM(); + } else { + switchToSlowPWM(); + } + } + // Update trigger for the end point of the PWM cycle + if (pendingPWM > 0) { + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, pendingPWM - 1); + // Turn on output + } else { + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, 0); + // Leave output off + } + } + // MSG((char *)"timer event comp2! \r\n"); + } +} -// // // ~10Hz -// // TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks; -// // // 1 kHz tick rate -// // TIMER_PSC(TIMER1) = 18000; -// } +void switchToFastPWM(void) { + fastPWM = true; + totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM); -// void switchToSlowPWM(void) { -// // 5Hz -// // fastPWM = false; -// // totalPWM = powerPWM + tempMeasureTicks / 2 + holdoffTicks / 2; -// // TIMER_CAR(TIMER1) = (uint32_t)totalPWM; -// // TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks / 2; -// // TIMER_PSC(TIMER1) = 36000; -// } + // ~10Hz + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, powerPWM + holdoffTicks); + // Set divider to 11 + + uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 11); + + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmpVal); +} + +void switchToSlowPWM(void) { + // 5Hz + fastPWM = false; + totalPWM = powerPWM + tempMeasureTicks / 2 + holdoffTicks / 2; + + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM); + // Adjust ADC + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, powerPWM + (holdoffTicks / 2)); + + // Set divider to 22 + + uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR); + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 22); + + BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmpVal); +} void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) { - // // PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is - // // // disabled if the PID task is not scheduled often enough. - // // pendingPWM = pulse; - // // fastPWM = shouldUseFastModePWM; + PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is + // disabled if the PID task is not scheduled often enough. + pendingPWM = pulse; + fastPWM = shouldUseFastModePWM; } extern osThreadId POWTaskHandle; diff --git a/source/Core/BSP/Magic/IRQ.h b/source/Core/BSP/Magic/IRQ.h index 37198562..b6e0ed48 100644 --- a/source/Core/BSP/Magic/IRQ.h +++ b/source/Core/BSP/Magic/IRQ.h @@ -16,39 +16,8 @@ #ifdef __cplusplus extern "C" { #endif -void ADC0_1_IRQHandler(void); -void TIMER1_IRQHandler(void); -void EXTI5_9_IRQHandler(void); -/* handle I2C0 event interrupt request */ -void I2C0_EV_IRQHandler(void); -/* handle I2C0 error interrupt request */ -void I2C0_ER_IRQHandler(void); -typedef enum { - I2C_SEND_ADDRESS_FIRST = 0, // Sending slave address - I2C_CLEAR_ADDRESS_FLAG_FIRST, // Clear address send - I2C_TRANSMIT_WRITE_READ_ADD, // Transmit the memory address to read/write from - I2C_SEND_ADDRESS_SECOND, // Send address again for read - I2C_CLEAR_ADDRESS_FLAG_SECOND, // Clear address again - I2C_TRANSMIT_DATA, // Transmit recieve data - I2C_STOP, // Send stop - I2C_ABORTED, // - I2C_DONE, // I2C transfer is complete - I2C_START, - I2C_END, - I2C_OK, - I2C_SEND_ADDRESS, - I2C_CLEAR_ADDRESS_FLAG, -} i2c_process_enum; -extern volatile uint8_t i2c_slave_address; -extern volatile uint8_t i2c_read_process; -extern volatile uint8_t i2c_write_process; -extern volatile uint8_t i2c_error_code; -extern volatile uint8_t *i2c_write; -extern volatile uint8_t *i2c_read; -extern volatile uint16_t i2c_nbytes; -extern volatile uint16_t i2c_write_dress; -extern volatile uint16_t i2c_read_dress; -extern volatile uint8_t i2c_process_flag; +void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state); + #ifdef __cplusplus } #endif diff --git a/source/Core/BSP/Magic/Setup.cpp b/source/Core/BSP/Magic/Setup.cpp index c0aa6058..50ebd78d 100644 --- a/source/Core/BSP/Magic/Setup.cpp +++ b/source/Core/BSP/Magic/Setup.cpp @@ -11,8 +11,15 @@ #include "Pins.h" extern "C" { #include "bflb_platform.h" +#include "bl702_glb.h" #include "bl702_i2c.h" +#include "bl702_pwm.h" +#include "bl702_timer.h" +#include "hal_clock.h" +#include "hal_pwm.h" +#include "hal_timer.h" } +#include "IRQ.h" #include "history.hpp" #include #define ADC_NORM_SAMPLES 16 @@ -21,12 +28,53 @@ uint16_t ADCReadings[ADC_NORM_SAMPLES]; // room for 32 lots of the pair of readi // Functions +void setup_slow_PWM(); void hardware_init() { gpio_set_mode(OLED_RESET_Pin, GPIO_OUTPUT_MODE); // gpio_set_mode(KEY_A_Pin, GPIO_INPUT_PD_MODE); // gpio_set_mode(KEY_B_Pin, GPIO_INPUT_PD_MODE); + setup_slow_PWM(); } +struct device *timer0; + +volatile uint32_t cnt = 0; + +void setup_slow_PWM() { + + timer_register(TIMER0_INDEX, "timer0"); + + timer0 = device_find("timer0"); + + if (timer0) { + + device_open(timer0, DEVICE_OFLAG_INT_TX); /* 1s,2s,3s timing*/ + // Set interrupt handler + device_set_callback(timer0, timer0_irq_callback); + // Enable both interrupts (0 and 1) + device_control(timer0, DEVICE_CTRL_SET_INT, (void *)(TIMER_COMP0_IT | TIMER_COMP1_IT | TIMER_COMP2_IT)); + + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 255 + 10 - 2); // Channel 0 is used to trigger the ADC + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, 128 - 2); + TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, (255 + 10 + 10) - 2); // We are using compare 2 to set the max duration of the timer + TIMER_SetPreloadValue(TIMER_CH0, 0); + TIMER_SetCountMode(TIMER_CH0, TIMER_COUNT_PRELOAD); + } else { + MSG((char *)"timer device open failed! \n"); + } +} + +/* + * ADC + * ADC is a bit of a mess as we dont have injected mode sampling to use with timers on this device + * So instead we do this: + * + * Main timer0 runs at 5/10hz and schedules everything + * Its running PWM in the 0-255 range for tip control + sample time at the end of the ADC + * It triggers the ADC at the end of the PWM cycle + * + * + */ uint16_t getADCHandleTemp(uint8_t sample) { static history filter = {{0}, 0, 0}; if (sample) { diff --git a/source/Core/BSP/Magic/clock_config.h b/source/Core/BSP/Magic/clock_config.h index 80a5752d..ce27df5c 100644 --- a/source/Core/BSP/Magic/clock_config.h +++ b/source/Core/BSP/Magic/clock_config.h @@ -38,10 +38,10 @@ #define BSP_I2C_CLOCK_DIV 0 #define BSP_SPI_CLOCK_SOURCE ROOT_CLOCK_SOURCE_BCLK #define BSP_SPI_CLOCK_DIV 0 -#define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK -#define BSP_TIMER0_CLOCK_DIV 0 -#define BSP_TIMER1_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK -#define BSP_TIMER1_CLOCK_DIV 0 +#define BSP_TIMER0_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK +#define BSP_TIMER0_CLOCK_DIV 22 +#define BSP_TIMER1_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK +#define BSP_TIMER1_CLOCK_DIV 31 #define BSP_WDT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK #define BSP_WDT_CLOCK_DIV 0 #define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index 7b8bc220..d9582bdb 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -800,15 +800,15 @@ void showDebugMenu(void) { } void showWarnings() { - MSG((char *)"showWarningsshowWarnings\r\n"); + // MSG((char *)"showWarningsshowWarnings\r\n"); return; // Display alert if settings were reset if (settingsWereReset) { - MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); - MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); - MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); - MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); - MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); + // MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); + // MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); + // MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); + // MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); + // MSG((char *)"WarnUser - %ld\r\n\r\n", (uint64_t)Tr); warnUser(translatedString(Tr->SettingsResetMessage), 10 * TICKS_SECOND); } @@ -817,7 +817,7 @@ void showWarnings() { // In this case though, we dont want to nag the user _too_ much // So only show first 2 times while (DetectedAccelerometerVersion == AccelType::Scanning) { - MSG((char *)"Accel Detect"); + // MSG((char *)"Accel Detect"); osDelay(5); } // Display alert if accelerometer is not detected @@ -847,14 +847,14 @@ uint8_t disconnectedTipF[sizeof(disconnectedTip)]; /* StartGUITask function */ void startGUITask(void const *argument) { (void)argument; - MSG((char *)"startGUITask\r\n"); + // MSG((char *)"startGUITask\r\n"); prepareTranslations(); - MSG((char *)"OLEDInit\r\n"); + // MSG((char *)"OLEDInit\r\n"); OLED::initialize(); // start up the LCD - MSG((char *)"setBrightness\r\n"); + // MSG((char *)"setBrightness\r\n"); OLED::setBrightness(getSettingValue(SettingsOptions::OLEDBrightness)); - MSG((char *)"setInverseDisplay\r\n"); + // MSG((char *)"setInverseDisplay\r\n"); OLED::setInverseDisplay(getSettingValue(SettingsOptions::OLEDInversion)); uint8_t tempWarningState = 0; @@ -862,7 +862,7 @@ void startGUITask(void const *argument) { bool tempOnDisplay = false; bool tipDisconnectedDisplay = false; bool showExitMenuTransition = false; - MSG((char *)"flip\r\n"); + // MSG((char *)"flip\r\n"); { // Generate the flipped screen into ram for later use @@ -875,24 +875,24 @@ void startGUITask(void const *argument) { } } } - MSG((char *)"tipTemp\r\n"); + // MSG((char *)"tipTemp\r\n"); getTipRawTemp(1); // reset filter - MSG((char *)"setRotation\r\n"); + // MSG((char *)"setRotation\r\n"); OLED::setRotation(getSettingValue(SettingsOptions::OrientationMode) & 1); - MSG((char *)"Bootlogo\r\n"); + // MSG((char *)"Bootlogo\r\n"); // BootLogo::handleShowingLogo((uint8_t *)FLASH_LOGOADDR); - MSG((char *)"showWarnings\r\n"); + // MSG((char *)"showWarnings\r\n"); showWarnings(); - MSG((char *)"AutoStartMode\r\n"); + // MSG((char *)"AutoStartMode\r\n"); if (getSettingValue(SettingsOptions::AutoStartMode)) { // jump directly to the autostart mode gui_solderingMode(getSettingValue(SettingsOptions::AutoStartMode) - 1); buttonLockout = true; } - MSG((char *)"GUI Thread Start\r\n"); + // MSG((char *)"GUI Thread Start\r\n"); for (;;) { ButtonState buttons = getButtonState();