1
0
forked from me/IronOS

Roughing out scheduling timer0

This commit is contained in:
Ben V. Brown
2022-04-13 20:46:51 +10:00
parent d4e27a5b9b
commit 8ec723a749
7 changed files with 158 additions and 112 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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 <string.h>
#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<uint16_t, ADC_FILTER_LEN> filter = {{0}, 0, 0};
if (sample) {

View File

@@ -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

View File

@@ -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();