mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
Dont use ADC IRQ
This commit is contained in:
committed by
Ben V. Brown
parent
348c86bb2a
commit
7c7c410280
@@ -24,21 +24,34 @@ history<uint16_t, ADC_Filter_Smooth> ADC_Vin;
|
|||||||
history<uint16_t, ADC_Filter_Smooth> ADC_Temp;
|
history<uint16_t, ADC_Filter_Smooth> ADC_Temp;
|
||||||
history<uint16_t, ADC_Filter_Smooth> ADC_Tip;
|
history<uint16_t, ADC_Filter_Smooth> ADC_Tip;
|
||||||
|
|
||||||
// IRQ is called at the end of the 8 set readings, pop these from the FIFO and send to filters
|
void read_adc_fifo(void) {
|
||||||
void adc_fifo_irq(void) {
|
// Read out all entries in the fifo
|
||||||
if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
|
uint8_t pending_readings = ADC_Get_FIFO_Count();
|
||||||
// Read out all entries in the fifo
|
|
||||||
while (ADC_Get_FIFO_Count()) {
|
// There _should_ always be 8 readings here. If there are not, it means that the adc didnt start when we wanted and timing slipped
|
||||||
uint32_t reading = ADC_Read_FIFO();
|
// So if there isn't 8 readings, we throw them out
|
||||||
ADC_Result_Type parsed = {0, 0, 0};
|
if (pending_readings != 8) {
|
||||||
ADC_Parse_Result(&reading, 1, &parsed);
|
MSG((char *)"Discarding out of sync adc %d\r\n", pending_readings);
|
||||||
|
} else {
|
||||||
|
MSG((char *)"FIFO Count %d\r\n", pending_readings);
|
||||||
|
while (pending_readings) {
|
||||||
|
pending_readings--;
|
||||||
|
uint32_t raw_reading = ADC_Read_FIFO();
|
||||||
|
ADC_Result_Type parsed = {0, 0, 0};
|
||||||
|
ADC_Parse_Result(&raw_reading, 1, &parsed);
|
||||||
|
|
||||||
switch (parsed.posChan) {
|
switch (parsed.posChan) {
|
||||||
case TMP36_ADC_CHANNEL:
|
case TMP36_ADC_CHANNEL:
|
||||||
ADC_Temp.update(parsed.value << 2);
|
ADC_Temp.update(parsed.value << 2);
|
||||||
break;
|
break;
|
||||||
case TIP_TEMP_ADC_CHANNEL:
|
case TIP_TEMP_ADC_CHANNEL: {
|
||||||
|
int32_t avg = ADC_Tip.average();
|
||||||
|
int32_t delta = (int32_t)parsed.value - (avg >> 2);
|
||||||
|
if (delta > 4000) {
|
||||||
|
MSG((char *)"ADC Chan %d -> %d -> %d\r\n", pending_readings, parsed.value, delta);
|
||||||
|
}
|
||||||
ADC_Tip.update(parsed.value << 2);
|
ADC_Tip.update(parsed.value << 2);
|
||||||
break;
|
} break;
|
||||||
case VIN_ADC_CHANNEL:
|
case VIN_ADC_CHANNEL:
|
||||||
ADC_Vin.update(parsed.value << 2);
|
ADC_Vin.update(parsed.value << 2);
|
||||||
break;
|
break;
|
||||||
@@ -46,17 +59,16 @@ void adc_fifo_irq(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// unblock the PID controller thread
|
}
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
ADC_FIFO_Clear();
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
// unblock the PID controller thread
|
||||||
if (pidTaskNotification) {
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
if (pidTaskNotification) {
|
||||||
}
|
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
|
||||||
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clear IRQ
|
|
||||||
ADC_IntClr(ADC_INT_ALL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool inFastPWMMode = false;
|
volatile bool inFastPWMMode = false;
|
||||||
@@ -68,8 +80,23 @@ volatile uint16_t PWMSafetyTimer = 0;
|
|||||||
volatile uint8_t pendingPWM = 0;
|
volatile uint8_t pendingPWM = 0;
|
||||||
volatile bool pendingNextPeriodIsFast = false;
|
volatile bool pendingNextPeriodIsFast = false;
|
||||||
|
|
||||||
inline void start_PWM_output(void) {
|
void timer0_comp0_callback(void) {
|
||||||
|
// Trigged at end of output cycle; turn off the tip PWM
|
||||||
|
PWM_Channel_Disable(PWM_Channel);
|
||||||
|
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer 0 is used to co-ordinate the ADC and the output PWM
|
||||||
|
void timer0_comp1_callback(void) {
|
||||||
|
ADC_Start();
|
||||||
|
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_1);
|
||||||
|
}
|
||||||
|
void timer0_comp2_callback(void) {
|
||||||
|
// Triggered at end of timer cycle; re-start the tip driver
|
||||||
|
ADC_Stop();
|
||||||
TIMER_Disable(TIMER_CH0);
|
TIMER_Disable(TIMER_CH0);
|
||||||
|
// Read the ADC data _now_. So that if things have gone out of sync, we know about it
|
||||||
|
read_adc_fifo();
|
||||||
|
|
||||||
if (PWMSafetyTimer) {
|
if (PWMSafetyTimer) {
|
||||||
PWMSafetyTimer--;
|
PWMSafetyTimer--;
|
||||||
@@ -86,62 +113,24 @@ inline void start_PWM_output(void) {
|
|||||||
// Turn on output
|
// Turn on output
|
||||||
PWM_Channel_Enable(PWM_Channel);
|
PWM_Channel_Enable(PWM_Channel);
|
||||||
} else {
|
} else {
|
||||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 255 - 1);
|
|
||||||
// Leave output off
|
|
||||||
PWM_Channel_Disable(PWM_Channel);
|
PWM_Channel_Disable(PWM_Channel);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PWM_Channel_Disable(PWM_Channel);
|
PWM_Channel_Disable(PWM_Channel);
|
||||||
switchToFastPWM();
|
|
||||||
}
|
}
|
||||||
TIMER_Enable(TIMER_CH0);
|
TIMER_Enable(TIMER_CH0);
|
||||||
}
|
|
||||||
|
|
||||||
void timer0_comp0_callback(void) {
|
|
||||||
// Trigged at end of output cycle; turn off the tip PWM
|
|
||||||
PWM_Channel_Disable(PWM_Channel);
|
|
||||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timer 0 is used to co-ordinate the ADC and the output PWM
|
|
||||||
void timer0_comp1_callback(void) {
|
|
||||||
if (PWM_Channel_Is_Enabled(PWM_Channel)) {
|
|
||||||
ADC_FIFO_Clear();
|
|
||||||
// So there appears to be a bug _somewhere_ where sometimes the comparator doesn't fire
|
|
||||||
// Its not re-occurring with specific values, so suspect its a weird bug
|
|
||||||
// For now, we just skip the cycle and throw away the ADC readings. Its a waste but
|
|
||||||
// It stops stupid glitches in readings, i'd take slight instability from the time jump
|
|
||||||
// Over the readings we get that are borked as the heater is left on
|
|
||||||
// <Ralim 2023/10/14>
|
|
||||||
PWM_Channel_Disable(PWM_Channel);
|
|
||||||
// Trigger the PID now instead
|
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
||||||
if (pidTaskNotification) {
|
|
||||||
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
|
|
||||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ADC_Start();
|
|
||||||
}
|
|
||||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_1);
|
|
||||||
}
|
|
||||||
void timer0_comp2_callback(void) {
|
|
||||||
// Triggered at end of timer cycle; re-start the tip driver
|
|
||||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_2);
|
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_2);
|
||||||
start_PWM_output();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchToFastPWM(void) {
|
void switchToFastPWM(void) {
|
||||||
inFastPWMMode = true;
|
inFastPWMMode = true;
|
||||||
holdoffTicks = 10;
|
holdoffTicks = 10;
|
||||||
tempMeasureTicks = 10;
|
tempMeasureTicks = 10;
|
||||||
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;
|
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;
|
||||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM);
|
|
||||||
|
|
||||||
// ~10Hz
|
|
||||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, powerPWM + holdoffTicks);
|
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, powerPWM + holdoffTicks);
|
||||||
|
|
||||||
|
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM);
|
||||||
// Set divider to 10 ~= 10.5Hz
|
// Set divider to 10 ~= 10.5Hz
|
||||||
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
||||||
|
|
||||||
@@ -157,10 +146,10 @@ void switchToSlowPWM(void) {
|
|||||||
tempMeasureTicks = 5;
|
tempMeasureTicks = 5;
|
||||||
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;
|
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;
|
||||||
|
|
||||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM);
|
|
||||||
// Adjust ADC
|
// Adjust ADC
|
||||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, powerPWM + holdoffTicks);
|
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, powerPWM + holdoffTicks);
|
||||||
|
|
||||||
|
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM);
|
||||||
// Set divider for ~ 5Hz
|
// Set divider for ~ 5Hz
|
||||||
|
|
||||||
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
||||||
@@ -169,9 +158,11 @@ void switchToSlowPWM(void) {
|
|||||||
|
|
||||||
BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmpVal);
|
BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmpVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) {
|
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
|
PWMSafetyTimer = 10;
|
||||||
// disabled if the PID task is not scheduled often enough.
|
// 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;
|
pendingPWM = pulse;
|
||||||
pendingNextPeriodIsFast = shouldUseFastModePWM;
|
pendingNextPeriodIsFast = shouldUseFastModePWM;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ extern "C" {
|
|||||||
void timer0_comp0_callback(void);
|
void timer0_comp0_callback(void);
|
||||||
void timer0_comp1_callback(void);
|
void timer0_comp1_callback(void);
|
||||||
void timer0_comp2_callback(void);
|
void timer0_comp2_callback(void);
|
||||||
void adc_fifo_irq(void);
|
|
||||||
void GPIO_IRQHandler(void);
|
void GPIO_IRQHandler(void);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ void hardware_init() {
|
|||||||
// Note on I2C clock rate @ 100Khz the screen update == 20ms which is too long for USB-PD to work
|
// Note on I2C clock rate @ 100Khz the screen update == 20ms which is too long for USB-PD to work
|
||||||
// 200kHz and above works
|
// 200kHz and above works
|
||||||
I2C_ClockSet(I2C0_ID, 300000); // Sets clock to around 25 kHz less than set here
|
I2C_ClockSet(I2C0_ID, 300000); // Sets clock to around 25 kHz less than set here
|
||||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, 0);
|
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 0);
|
||||||
}
|
}
|
||||||
void setup_pwm(void) {
|
void setup_pwm(void) {
|
||||||
// Setup PWM we use for driving the tip
|
// Setup PWM we use for driving the tip
|
||||||
@@ -96,10 +96,6 @@ void setup_adc(void) {
|
|||||||
ADC_CFG_Type adc_cfg = {};
|
ADC_CFG_Type adc_cfg = {};
|
||||||
ADC_FIFO_Cfg_Type adc_fifo_cfg = {};
|
ADC_FIFO_Cfg_Type adc_fifo_cfg = {};
|
||||||
|
|
||||||
CPU_Interrupt_Disable(GPADC_DMA_IRQn);
|
|
||||||
|
|
||||||
ADC_IntMask(ADC_INT_ALL, MASK);
|
|
||||||
|
|
||||||
// Please also see PR #1529 for even more context
|
// Please also see PR #1529 for even more context
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -178,16 +174,11 @@ void setup_adc(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
adc_fifo_cfg.dmaEn = DISABLE;
|
adc_fifo_cfg.dmaEn = DISABLE;
|
||||||
adc_fifo_cfg.fifoThreshold = ADC_FIFO_THRESHOLD_8; // Triger FIFO when all 8 measurements are done
|
adc_fifo_cfg.fifoThreshold = ADC_FIFO_THRESHOLD_1;
|
||||||
ADC_FIFO_Cfg(&adc_fifo_cfg);
|
ADC_FIFO_Cfg(&adc_fifo_cfg);
|
||||||
ADC_MIC_Bias_Disable();
|
ADC_MIC_Bias_Disable();
|
||||||
ADC_Tsen_Disable();
|
ADC_Tsen_Disable();
|
||||||
ADC_Gain_Trim();
|
ADC_Gain_Trim();
|
||||||
|
|
||||||
// Enable FiFo IRQ
|
|
||||||
Interrupt_Handler_Register(GPADC_DMA_IRQn, adc_fifo_irq);
|
|
||||||
ADC_IntMask(ADC_INT_FIFO_READY, UNMASK);
|
|
||||||
CPU_Interrupt_Enable(GPADC_DMA_IRQn);
|
|
||||||
ADC_Stop();
|
ADC_Stop();
|
||||||
ADC_FIFO_Clear();
|
ADC_FIFO_Clear();
|
||||||
ADC_Scan_Channel_Config(adc_tip_pos_chans, adc_tip_neg_chans, sizeof(adc_tip_pos_chans) / sizeof(ADC_Chan_Type), DISABLE);
|
ADC_Scan_Channel_Config(adc_tip_pos_chans, adc_tip_neg_chans, sizeof(adc_tip_pos_chans) / sizeof(ADC_Chan_Type), DISABLE);
|
||||||
|
|||||||
Reference in New Issue
Block a user