@@ -19,17 +19,17 @@ extern "C" {
1919}
2020void start_PWM_output (void );
2121
22- #define ADC_Filter_Smooth 1
22+ #define ADC_Filter_Smooth 4 /* This basically smooths over one PWM cycle / set of readings */
2323history<uint16_t , ADC_Filter_Smooth> ADC_Vin;
2424history<uint16_t , ADC_Filter_Smooth> ADC_Temp;
2525history<uint16_t , ADC_Filter_Smooth> ADC_Tip;
26- volatile uint8_t ADCBurstCounter = 0 ;
27- void adc_fifo_irq (void ) {
26+
27+ // IRQ is called at the end of the 8 set readings, pop these from the FIFO and send to filters
28+ void adc_fifo_irq (void ) {
2829 if (ADC_GetIntStatus (ADC_INT_FIFO_READY) == SET) {
2930 // Read out all entries in the fifo
3031 while (ADC_Get_FIFO_Count ()) {
31- ADCBurstCounter++;
32- volatile uint32_t reading = ADC_Read_FIFO ();
32+ uint32_t reading = ADC_Read_FIFO ();
3333 // As per manual, 26 bit reading; lowest 16 are the ADC
3434 uint16_t sample = reading & 0xFFFF ;
3535 uint8_t source = (reading >> 21 ) & 0b11111 ;
@@ -43,23 +43,16 @@ void adc_fifo_irq(void) {
4343 case VIN_ADC_CHANNEL:
4444 ADC_Vin.update (sample);
4545 break ;
46-
4746 default :
4847 break ;
4948 }
5049 }
51-
52- if (ADCBurstCounter >= 8 ) {
53- ADCBurstCounter = 0 ;
54- start_PWM_output ();
55-
56- // unblock the PID controller thread
57- if (xTaskGetSchedulerState () != taskSCHEDULER_NOT_STARTED) {
58- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
59- if (pidTaskNotification) {
60- vTaskNotifyGiveFromISR (pidTaskNotification, &xHigherPriorityTaskWoken);
61- portYIELD_FROM_ISR (xHigherPriorityTaskWoken);
62- }
50+ // unblock the PID controller thread
51+ if (xTaskGetSchedulerState () != taskSCHEDULER_NOT_STARTED) {
52+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
53+ if (pidTaskNotification) {
54+ vTaskNotifyGiveFromISR (pidTaskNotification, &xHigherPriorityTaskWoken);
55+ portYIELD_FROM_ISR (xHigherPriorityTaskWoken);
6356 }
6457 }
6558 }
@@ -100,16 +93,43 @@ void start_PWM_output(void) {
10093 PWM_Channel_Disable (PWM_Channel);
10194 switchToFastPWM ();
10295 }
103- TIMER_Enable (TIMER_CH0);
10496}
10597
10698// Timer 0 is used to co-ordinate the ADC and the output PWM
10799void timer0_comp0_callback (void ) {
108- TIMER_Disable (TIMER_CH0);
109- ADC_Start ();
100+ if (PWM_Channel_Is_Enabled (PWM_Channel)) {
101+ // So there appears to be a bug _somewhere_ where sometimes the comparator doesn't fire
102+ // Its not re-occurring with specific values, so suspect its a weird bug
103+ // For now, we just skip the cycle and throw away the ADC readings. Its a waste but
104+ // It stops stupid glitches in readings, i'd take slight instability from the time jump
105+ // Over the readings we get that are borked as the header is left on
106+ // <Ralim 2023/10/14>
107+ PWM_Channel_Disable (PWM_Channel);
108+ // MSG("ALERT PWM Glitch\r\n");
109+ // Triger the PID now instead
110+ if (xTaskGetSchedulerState () != taskSCHEDULER_NOT_STARTED) {
111+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
112+ if (pidTaskNotification) {
113+ vTaskNotifyGiveFromISR (pidTaskNotification, &xHigherPriorityTaskWoken);
114+ portYIELD_FROM_ISR (xHigherPriorityTaskWoken);
115+ }
116+ }
117+ } else {
118+ ADC_Start ();
119+ }
120+ TIMER_ClearIntStatus (TIMER_CH0, TIMER_COMP_ID_0);
121+ }
122+ void timer0_comp1_callback (void ) {
123+ // Trigged at end of output cycle; turn off the tip PWM
124+ PWM_Channel_Disable (PWM_Channel);
125+ TIMER_ClearIntStatus (TIMER_CH0, TIMER_COMP_ID_1);
110126}
111- void timer0_comp1_callback (void ) { PWM_Channel_Disable (PWM_Channel); } // Trigged at end of output cycle; turn off the tip PWM
112127
128+ void timer0_comp2_callback (void ) {
129+ // Triggered at end of timer cycle; re-start the tip driver
130+ start_PWM_output ();
131+ TIMER_ClearIntStatus (TIMER_CH0, TIMER_COMP_ID_2);
132+ }
113133void switchToFastPWM (void ) {
114134 inFastPWMMode = true ;
115135 holdoffTicks = 10 ;
@@ -119,8 +139,8 @@ void switchToFastPWM(void) {
119139
120140 // ~10Hz
121141 TIMER_SetCompValue (TIMER_CH0, TIMER_COMP_ID_0, powerPWM + holdoffTicks);
122- // Set divider to 10 ~= 10.5Hz
123142
143+ // Set divider to 10 ~= 10.5Hz
124144 uint32_t tmpVal = BL_RD_REG (TIMER_BASE, TIMER_TCDR);
125145
126146 tmpVal = BL_SET_REG_BITS_VAL (tmpVal, TIMER_TCDR2, 10 );
@@ -139,7 +159,7 @@ void switchToSlowPWM(void) {
139159 // Adjust ADC
140160 TIMER_SetCompValue (TIMER_CH0, TIMER_COMP_ID_0, powerPWM + holdoffTicks);
141161
142- // Set divider to 22
162+ // Set divider for ~ 5Hz
143163
144164 uint32_t tmpVal = BL_RD_REG (TIMER_BASE, TIMER_TCDR);
145165
@@ -193,5 +213,6 @@ uint16_t getADCHandleTemp(uint8_t sample) { return ADC_Temp.average(); }
193213
194214uint16_t getADCVin (uint8_t sample) { return ADC_Vin.average (); }
195215
196- // 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
216+ // Returns the current raw tip reading after any cleanup filtering
217+ // For Pinecil V2 we dont do any rolling filtering other than just averaging all 4 readings in the adc snapshot
197218uint16_t getTipRawTemp (uint8_t sample) { return ADC_Tip.average () >> 1 ; }
0 commit comments