Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pinecilv2 adc v2 #1916

Merged
merged 20 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ name: CI

on:
push:
branches:
- master
- dev
- main
pull_request:
branches:
- master
Expand Down
4 changes: 4 additions & 0 deletions source/Core/BSP/BSP_Power.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#ifndef BSP_POWER_H_
#define BSP_POWER_H_
#include "Types.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -22,6 +24,8 @@ uint8_t getTipResistanceX10();
uint16_t getTipThermalMass();
uint16_t getTipInertia();

TemperatureType_t getCustomTipMaxInC();

#ifdef __cplusplus
}
#endif
Expand Down
100 changes: 54 additions & 46 deletions source/Core/BSP/Pinecilv2/BSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
#include "TipThermoModel.h"
#include "USBPD.h"
#include "Utils.h"
#include "bl702_adc.h"
#include "configuration.h"
#include "crc32.h"
#include "hal_flash.h"
#include "history.hpp"
#include "main.hpp"

extern ADC_Gain_Coeff_Type adcGainCoeffCal;

// These control the period's of time used for the PWM
const uint16_t powerPWM = 255;
uint8_t holdoffTicks = 25; // This is the tick delay before temp measure starts (i.e. time for op-amp recovery)
Expand All @@ -31,52 +34,44 @@ void resetWatchdog() {
// Stored as ADCReading,Temp in degC
static const int32_t NTCHandleLookup[] = {
// ADC Reading , Temp in C x10

3221, -400, //
4144, -350, //
5271, -300, //
6622, -250, //
8219, -200, //
10075, -150, //
12190, -100, //
14554, -50, //
17151, 0, //
19937, 50, //
22867, 100, //
25886, 150, //
28944, 200, //
29546, 210, //
30159, 220, //
30769, 230, //
31373, 240, //
31969, 250, //
32566, 260, //
33159, 270, //
33749, 280, //
34334, 290, //
34916, 300, //
35491, 310, //
36062, 320, //
36628, 330, //
37186, 340, //
37739, 350, //
38286, 360, //
38825, 370, //
39358, 380, //
39884, 390, //
40400, 400, //
42879, 450, //
45160, 500, //
47235, 550, //
49111, 600, //
50792, 650, //
52292, 700, //
53621, 750, //
54797, 800, //
55836, 850, //
56748, 900, //
57550, 950, //
58257, 1000, //
// Based on NTCG163JF103FTDS thermocouple datasheet values,
// arranged in a voltage divider configuration, with the NTC
// pulling up towards 3.3V, and with a 10k 1% pull-down resistor.
// ADC Reading = 3.3V * 10 / (10 + TypkOhm) / 3.2V * (2 ^ 16)
3405, -400, //
4380, -350, //
5572, -300, //
6999, -250, //
8688, -200, //
10650, -150, //
12885, -100, //
15384, -50, //
18129, 0, //
21074, 50, //
24172, 100, //
27362, 150, //
30595, 200, //
33792, 250, //
36907, 300, //
39891, 350, //
42704, 400, //
45325, 450, //
47736, 500, //
49929, 550, //
51912, 600, //
53689, 650, //
55274, 700, //
56679, 750, //
57923, 800, //
59020, 850, //
59984, 900, //
60832, 950, //
61580, 1000, //
62232, 1050, //
62810, 1100, //
63316, 1150, //
63765, 1200, //
64158, 1250, //

};
#endif
Expand Down Expand Up @@ -282,3 +277,16 @@ void showBootLogo(void) {

BootLogo::handleShowingLogo(scratch);
}

TemperatureType_t getCustomTipMaxInC() {
// have to lookup the max temp while being aware of the coe scaling value
float max_reading = ADC_MAX_READING - 1.0;

if (adcGainCoeffCal.adcGainCoeffEnable) {
max_reading /= adcGainCoeffCal.coe;
}

TemperatureType_t maximumTipTemp = TipThermoModel::convertTipRawADCToDegC(max_reading);
maximumTipTemp += getHandleTemperature(0) / 10; // Add handle offset
return maximumTipTemp - 1;
}
6 changes: 3 additions & 3 deletions source/Core/BSP/Pinecilv2/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ extern "C" {
header file. */
void vAssertCalled(void);

#define configASSERT(x) \
if ((x) == 0) \
#define configASSERT(x) \
if ((x) == 0) \
vAssertCalled()

#ifdef __cplusplus
Expand All @@ -75,7 +75,7 @@ void vApplicationSleep(uint32_t xExpectedIdleTime);
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_eTaskGetState 0
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTaskAbortDelay 0
Expand Down
135 changes: 63 additions & 72 deletions source/Core/BSP/Pinecilv2/IRQ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,48 @@ history<uint16_t, ADC_Filter_Smooth> ADC_Vin;
history<uint16_t, ADC_Filter_Smooth> ADC_Temp;
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 adc_fifo_irq(void) {
if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
// Read out all entries in the fifo
while (ADC_Get_FIFO_Count()) {
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;
switch (source) {
void read_adc_fifo(void) {
// Read out all entries in the fifo
uint8_t pending_readings = 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
// So if there isn't 8 readings, we throw them out
if (pending_readings != 8) {
MSG((char *)"Discarding out of sync adc %d\r\n", pending_readings);
} else {
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);
// Rollover prevention
if (parsed.value > ((1 << 14) - 1)) {
parsed.value = ((1 << 14) - 1);
}

switch (parsed.posChan) {
case TMP36_ADC_CHANNEL:
ADC_Temp.update(sample);
break;
case TIP_TEMP_ADC_CHANNEL:
ADC_Tip.update(sample);
ADC_Temp.update(parsed.value << 2);
break;
case TIP_TEMP_ADC_CHANNEL: {
ADC_Tip.update(parsed.value << 2);
} break;
case VIN_ADC_CHANNEL:
ADC_Vin.update(sample);
ADC_Vin.update(parsed.value << 2);
break;
default:
break;
}
}
// 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);
}
}
// Clear IRQ
ADC_IntClr(ADC_INT_ALL);
}

volatile bool inFastPWMMode = false;
Expand All @@ -69,7 +77,24 @@ volatile uint16_t PWMSafetyTimer = 0;
volatile uint8_t pendingPWM = 0;
volatile bool pendingNextPeriodIsFast = false;

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_FIFO_Clear();
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);
// Read the ADC data _now_. So that if things have gone out of sync, we know about it
read_adc_fifo();

if (PWMSafetyTimer) {
PWMSafetyTimer--;
Expand All @@ -82,64 +107,28 @@ void start_PWM_output(void) {
}
// Update trigger for the end point of the PWM cycle
if (pendingPWM > 0) {
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, pendingPWM - 1);
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, pendingPWM - 1);
// Turn on output
PWM_Channel_Enable(PWM_Channel);
} else {
// Leave output off
PWM_Channel_Disable(PWM_Channel);
}
} else {
PWM_Channel_Disable(PWM_Channel);
switchToFastPWM();
}
}

// Timer 0 is used to co-ordinate the ADC and the output PWM
void timer0_comp0_callback(void) {
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_comp2_callback(void) {
// Triggered at end of timer cycle; re-start the tip driver
start_PWM_output();
TIMER_Enable(TIMER_CH0);
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_2);
}

void switchToFastPWM(void) {
inFastPWMMode = true;
holdoffTicks = 10;
holdoffTicks = 20;
tempMeasureTicks = 10;
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM);

// ~10Hz
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 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
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);

Expand All @@ -151,14 +140,14 @@ void switchToFastPWM(void) {
void switchToSlowPWM(void) {
// 5Hz
inFastPWMMode = false;
holdoffTicks = 5;
holdoffTicks = 10;
tempMeasureTicks = 5;
totalPWM = powerPWM + tempMeasureTicks + holdoffTicks;

TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, totalPWM);
// Adjust ADC
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 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

uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
Expand All @@ -167,9 +156,11 @@ void switchToSlowPWM(void) {

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.
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;
pendingNextPeriodIsFast = shouldUseFastModePWM;
}
Expand Down
1 change: 0 additions & 1 deletion source/Core/BSP/Pinecilv2/IRQ.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ extern "C" {
void timer0_comp0_callback(void);
void timer0_comp1_callback(void);
void timer0_comp2_callback(void);
void adc_fifo_irq(void);
void GPIO_IRQHandler(void);
#ifdef __cplusplus
}
Expand Down
Loading