summaryrefslogtreecommitdiffhomepage
path: root/source/Core/BSP/Pinecilv2/IRQ.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Core/BSP/Pinecilv2/IRQ.cpp')
-rw-r--r--source/Core/BSP/Pinecilv2/IRQ.cpp71
1 files changed, 46 insertions, 25 deletions
diff --git a/source/Core/BSP/Pinecilv2/IRQ.cpp b/source/Core/BSP/Pinecilv2/IRQ.cpp
index bd64a96e..7a857b18 100644
--- a/source/Core/BSP/Pinecilv2/IRQ.cpp
+++ b/source/Core/BSP/Pinecilv2/IRQ.cpp
@@ -19,17 +19,17 @@ extern "C" {
}
void start_PWM_output(void);
-#define ADC_Filter_Smooth 1
+#define ADC_Filter_Smooth 4 /* This basically smooths over one PWM cycle / set of readings */
history<uint16_t, ADC_Filter_Smooth> ADC_Vin;
history<uint16_t, ADC_Filter_Smooth> ADC_Temp;
history<uint16_t, ADC_Filter_Smooth> ADC_Tip;
-volatile uint8_t ADCBurstCounter = 0;
-void adc_fifo_irq(void) {
+
+// IRQ is called at the end of the 8 set readings, pop these from the FIFO and send to filters
+void adc_fifo_irq(void) {
if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
// Read out all entries in the fifo
while (ADC_Get_FIFO_Count()) {
- ADCBurstCounter++;
- volatile uint32_t reading = ADC_Read_FIFO();
+ uint32_t reading = ADC_Read_FIFO();
// As per manual, 26 bit reading; lowest 16 are the ADC
uint16_t sample = reading & 0xFFFF;
uint8_t source = (reading >> 21) & 0b11111;
@@ -43,23 +43,16 @@ void adc_fifo_irq(void) {
case VIN_ADC_CHANNEL:
ADC_Vin.update(sample);
break;
-
default:
break;
}
}
-
- if (ADCBurstCounter >= 8) {
- ADCBurstCounter = 0;
- start_PWM_output();
-
- // unblock the PID controller thread
- if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- if (pidTaskNotification) {
- vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
- portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
- }
+ // unblock the PID controller thread
+ if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ if (pidTaskNotification) {
+ vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}
@@ -100,16 +93,43 @@ void start_PWM_output(void) {
PWM_Channel_Disable(PWM_Channel);
switchToFastPWM();
}
- TIMER_Enable(TIMER_CH0);
}
// Timer 0 is used to co-ordinate the ADC and the output PWM
void timer0_comp0_callback(void) {
- TIMER_Disable(TIMER_CH0);
- ADC_Start();
+ if (PWM_Channel_Is_Enabled(PWM_Channel)) {
+ // 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 header is left on
+ // <Ralim 2023/10/14>
+ PWM_Channel_Disable(PWM_Channel);
+ // MSG("ALERT PWM Glitch\r\n");
+ // Triger 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_0);
+}
+void timer0_comp1_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_1);
}
-void timer0_comp1_callback(void) { PWM_Channel_Disable(PWM_Channel); } // Trigged at end of output cycle; turn off the tip PWM
+void timer0_comp2_callback(void) {
+ // Triggered at end of timer cycle; re-start the tip driver
+ start_PWM_output();
+ TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_2);
+}
void switchToFastPWM(void) {
inFastPWMMode = true;
holdoffTicks = 10;
@@ -119,8 +139,8 @@ void switchToFastPWM(void) {
// ~10Hz
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, powerPWM + holdoffTicks);
- // Set divider to 10 ~= 10.5Hz
+ // Set divider to 10 ~= 10.5Hz
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 10);
@@ -139,7 +159,7 @@ void switchToSlowPWM(void) {
// Adjust ADC
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, powerPWM + holdoffTicks);
- // Set divider to 22
+ // Set divider for ~ 5Hz
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
@@ -193,5 +213,6 @@ uint16_t getADCHandleTemp(uint8_t sample) { return ADC_Temp.average(); }
uint16_t getADCVin(uint8_t sample) { return ADC_Vin.average(); }
-// Returns either average or instant value. When sample is set the samples from the injected ADC are copied to the filter and then the raw reading is returned
+// Returns the current raw tip reading after any cleanup filtering
+// For Pinecil V2 we dont do any rolling filtering other than just averaging all 4 readings in the adc snapshot
uint16_t getTipRawTemp(uint8_t sample) { return ADC_Tip.average() >> 1; }