From 5fe019f40bafb7570743d9b19c63669ceca5e903 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Mon, 23 Jan 2023 17:40:06 +1100 Subject: [PATCH 1/3] Change timing scheduler to only run main timer once ADC is done --- source/Core/BSP/Pinecilv2/IRQ.cpp | 15 +++++++++------ source/Core/BSP/Pinecilv2/Setup.cpp | 30 +++++++++++++---------------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/source/Core/BSP/Pinecilv2/IRQ.cpp b/source/Core/BSP/Pinecilv2/IRQ.cpp index 60a20474..b1d058c9 100644 --- a/source/Core/BSP/Pinecilv2/IRQ.cpp +++ b/source/Core/BSP/Pinecilv2/IRQ.cpp @@ -17,6 +17,7 @@ extern "C" { #include "bl702_pwm.h" #include "bl702_timer.h" } +void start_PWM_output(void); #define ADC_Filter_Smooth 4 history ADC_Vin; @@ -24,6 +25,7 @@ history ADC_Temp; history ADC_Tip; void adc_fifo_irq(void) { if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) { + start_PWM_output(); // Restart the tip PWM // Read out all entries in the fifo while (ADC_Get_FIFO_Count()) { volatile uint32_t reading = ADC_Read_FIFO(); @@ -45,7 +47,6 @@ void adc_fifo_irq(void) { break; } } - // unblock the PID controller thread if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; @@ -66,12 +67,10 @@ volatile uint16_t PWMSafetyTimer = 0; volatile uint8_t pendingPWM = 0; volatile bool lastPeriodWasFast = false; -// Timer 0 is used to co-ordinate the ADC and the output PWM -void timer0_comp0_callback(void) { ADC_Start(); } -void timer0_comp1_callback(void) { PWM_Channel_Disable(PWM_Channel); } -void timer0_comp2_callback(void) { +void start_PWM_output(void) { + + TIMER_Enable(TIMER_CH0); - // This occurs at timer rollover, so if we want to turn on the output PWM; we do so if (PWMSafetyTimer) { PWMSafetyTimer--; if (lastPeriodWasFast != fastPWM) { @@ -95,6 +94,10 @@ void timer0_comp2_callback(void) { } } +// Timer 0 is used to co-ordinate the ADC and the output PWM +void timer0_comp0_callback(void) { ADC_Start(); } +void timer0_comp1_callback(void) { PWM_Channel_Disable(PWM_Channel); } // Trigged at end of output cycle; turn off the tip PWM + void switchToFastPWM(void) { fastPWM = true; totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; diff --git a/source/Core/BSP/Pinecilv2/Setup.cpp b/source/Core/BSP/Pinecilv2/Setup.cpp index 788d5312..aec09031 100644 --- a/source/Core/BSP/Pinecilv2/Setup.cpp +++ b/source/Core/BSP/Pinecilv2/Setup.cpp @@ -62,10 +62,10 @@ void hardware_init() { setup_timer_scheduler(); setup_adc(); setup_pwm(); - I2C_SetSclSync(I2C0_ID,1); - I2C_SetDeglitchCount(I2C0_ID,1); // Turn on de-glitch - //Note on I2C clock rate @ 100Khz the screen update == 20ms which is too long for USB-PD to work - //200kHz and above works + I2C_SetSclSync(I2C0_ID, 1); + I2C_SetDeglitchCount(I2C0_ID, 1); // Turn on de-glitch + // Note on I2C clock rate @ 100Khz the screen update == 20ms which is too long for USB-PD to work + // 200kHz and above works I2C_ClockSet(I2C0_ID, 300000); // Sets clock to around 25 kHz less than set here TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, 0); } @@ -139,32 +139,28 @@ void setup_timer_scheduler() { TIMER_Disable(TIMER_CH0); TIMER_CFG_Type cfg = { - TIMER_CH0, // Channel - TIMER_CLKSRC_32K, // Clock source - TIMER_PRELOAD_TRIG_COMP2, // Trigger - TIMER_COUNT_PRELOAD, // Counter mode - 22, // Clock div - (uint16_t)(powerPWM + holdoffTicks), // CH0 compare (adc) - 0, // CH1 compare (pwm out) - (uint16_t)(powerPWM + tempMeasureTicks + holdoffTicks), // CH2 comapre (total period) - 0, // Preload + TIMER_CH0, // Channel + TIMER_CLKSRC_32K, // Clock source + TIMER_PRELOAD_TRIG_COMP0, // Trigger; reset after trigger 0 + TIMER_COUNT_PRELOAD, // Counter mode + 22, // Clock div + (uint16_t)(powerPWM + holdoffTicks), // CH0 compare (adc) + 0, // CH1 compare (pwm out) + 0, // CH2 compare not used + 0, // Preload }; TIMER_Init(&cfg); Timer_Int_Callback_Install(TIMER_CH0, TIMER_INT_COMP_0, timer0_comp0_callback); Timer_Int_Callback_Install(TIMER_CH0, TIMER_INT_COMP_1, timer0_comp1_callback); - Timer_Int_Callback_Install(TIMER_CH0, TIMER_INT_COMP_2, timer0_comp2_callback); TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_0); TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_1); - TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_2); TIMER_IntMask(TIMER_CH0, TIMER_INT_COMP_0, UNMASK); TIMER_IntMask(TIMER_CH0, TIMER_INT_COMP_1, UNMASK); - TIMER_IntMask(TIMER_CH0, TIMER_INT_COMP_2, UNMASK); CPU_Interrupt_Enable(TIMER_CH0_IRQn); TIMER_Enable(TIMER_CH0); - // switchToSlowPWM(); } void setupFUSBIRQ() { From f3b4abf434e8c5f0bee7a9bf5c730def54075e70 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 24 Jan 2023 18:11:44 +1100 Subject: [PATCH 2/3] Update IRQ.cpp --- source/Core/BSP/Pinecilv2/IRQ.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/Core/BSP/Pinecilv2/IRQ.cpp b/source/Core/BSP/Pinecilv2/IRQ.cpp index b1d058c9..0d2acd93 100644 --- a/source/Core/BSP/Pinecilv2/IRQ.cpp +++ b/source/Core/BSP/Pinecilv2/IRQ.cpp @@ -95,7 +95,10 @@ void start_PWM_output(void) { } // Timer 0 is used to co-ordinate the ADC and the output PWM -void timer0_comp0_callback(void) { ADC_Start(); } +void timer0_comp0_callback(void) { + PWM_Channel_Disable(PWM_Channel); + ADC_Start(); +} void timer0_comp1_callback(void) { PWM_Channel_Disable(PWM_Channel); } // Trigged at end of output cycle; turn off the tip PWM void switchToFastPWM(void) { From 7e103ccf2d1080885d8384074537053bc5691178 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 24 Jan 2023 18:56:49 +1100 Subject: [PATCH 3/3] Wait for full ADC Burst --- source/Core/BSP/Pinecilv2/IRQ.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/source/Core/BSP/Pinecilv2/IRQ.cpp b/source/Core/BSP/Pinecilv2/IRQ.cpp index 0d2acd93..623bba3c 100644 --- a/source/Core/BSP/Pinecilv2/IRQ.cpp +++ b/source/Core/BSP/Pinecilv2/IRQ.cpp @@ -23,11 +23,12 @@ void start_PWM_output(void); history ADC_Vin; history ADC_Temp; history ADC_Tip; +volatile uint8_t ADCBurstCounter = 0; void adc_fifo_irq(void) { if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) { - start_PWM_output(); // Restart the tip PWM // Read out all entries in the fifo while (ADC_Get_FIFO_Count()) { + ADCBurstCounter++; volatile uint32_t reading = ADC_Read_FIFO(); // As per manual, 26 bit reading; lowest 16 are the ADC uint16_t sample = reading & 0xFFFF; @@ -47,12 +48,18 @@ void adc_fifo_irq(void) { break; } } - // unblock the PID controller thread - if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - if (pidTaskNotification) { - vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + + 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); + } } } } @@ -69,8 +76,6 @@ volatile bool lastPeriodWasFast = false; void start_PWM_output(void) { - TIMER_Enable(TIMER_CH0); - if (PWMSafetyTimer) { PWMSafetyTimer--; if (lastPeriodWasFast != fastPWM) { @@ -92,11 +97,12 @@ void start_PWM_output(void) { } else { PWM_Channel_Disable(PWM_Channel); } + TIMER_Enable(TIMER_CH0); } // Timer 0 is used to co-ordinate the ADC and the output PWM void timer0_comp0_callback(void) { - PWM_Channel_Disable(PWM_Channel); + TIMER_Disable(TIMER_CH0); ADC_Start(); } void timer0_comp1_callback(void) { PWM_Channel_Disable(PWM_Channel); } // Trigged at end of output cycle; turn off the tip PWM