1
0
forked from me/IronOS

Working scheduling of ADC 🎉

This commit is contained in:
Ben V. Brown
2022-04-18 19:21:40 +10:00
parent 1d9b4d851e
commit fc1f28f2b8
9 changed files with 362 additions and 371 deletions

View File

@@ -8,42 +8,80 @@
#include "IRQ.h" #include "IRQ.h"
#include "Pins.h" #include "Pins.h"
#include "configuration.h" #include "configuration.h"
#include "expMovingAverage.h"
extern "C" { extern "C" {
#include "bflb_platform.h" #include "bflb_platform.h"
#include "bl702_adc.h"
#include "bl702_glb.h" #include "bl702_glb.h"
#include "bl702_pwm.h" #include "bl702_pwm.h"
#include "bl702_timer.h" #include "bl702_timer.h"
#include "hal_adc.h"
#include "hal_clock.h" #include "hal_clock.h"
#include "hal_pwm.h" #include "hal_pwm.h"
#include "hal_timer.h" #include "hal_timer.h"
} }
void ADC0_1_IRQHandler(void) {
// adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC); #define ADC_Filter_Weight 32
// unblock the PID controller thread expMovingAverage<uint16_t, ADC_Filter_Weight> ADC_Vin;
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { expMovingAverage<uint16_t, ADC_Filter_Weight> ADC_Temp;
BaseType_t xHigherPriorityTaskWoken = pdFALSE; expMovingAverage<uint16_t, ADC_Filter_Weight> ADC_Tip;
if (pidTaskNotification) {
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}
void adc_fifo_irq(void) { void adc_fifo_irq(void) {
} if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
// Read out all entries in the fifo
const uint8_t cnt = ADC_Get_FIFO_Count();
for (uint8_t i = 0; i < cnt; i++) {
const 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) {
case TMP36_ADC_CHANNEL:
ADC_Temp.update(sample);
break;
case TIP_TEMP_ADC_CHANNEL:
ADC_Tip.update(sample);
break;
case VIN_ADC_CHANNEL:
ADC_Vin.update(sample);
break;
case 0: // 0 turns up when an invalid reading is taken
break;
default:
// MSG((char *)"ADC Invalid chan %d\r\n", source);
break;
}
}
// MSG((char *)"ADC Reading %d %d %d\r\n", ADC_Temp.average(), ADC_Vin.average(), ADC_Tip.average());
// Clear IRQ
ADC_IntClr(ADC_INT_FIFO_READY);
}
}
const ADC_Chan_Type adc_tip_pos_chans[] = {TIP_TEMP_ADC_CHANNEL};
const ADC_Chan_Type adc_tip_neg_chans[] = {ADC_CHAN_GND};
static_assert(sizeof(adc_tip_pos_chans) == sizeof(adc_tip_neg_chans));
// TODO Do we need to do the stop+start here or can we hot-write the config
void start_adc_tip(void) { void start_adc_tip(void) {
// Reconfigure the ADC to measure the tip temp // Reconfigure the ADC to measure the tip temp
// Single channel input mode // Single channel input mode
// The ADC has a 32 sample FiFo; we set this up to fire and interrupt at 16 samples // The ADC has a 32 sample FiFo; we set this up to fire and interrupt at 16 samples
// Then using that IRQ to know that sampling is done and can be stored // Then using that IRQ to know that sampling is done and can be stored
ADC_Stop();
ADC_Scan_Channel_Config((ADC_Chan_Type *)adc_tip_pos_chans, (ADC_Chan_Type *)adc_tip_neg_chans, 2, ENABLE);
ADC_Start();
} }
const ADC_Chan_Type adc_misc_pos_chans[] = {TMP36_ADC_CHANNEL, VIN_ADC_CHANNEL};
const ADC_Chan_Type adc_misc_neg_chans[] = {ADC_CHAN_GND, ADC_CHAN_GND};
static_assert(sizeof(adc_misc_pos_chans) == sizeof(adc_misc_neg_chans));
void start_adc_misc(void) { void start_adc_misc(void) {
// Reconfigure the ADC to measure all other inputs in scan mode when we are not measuring the tip // Reconfigure the ADC to measure all other inputs in scan mode when we are not measuring the tip
ADC_Stop();
ADC_Scan_Channel_Config((ADC_Chan_Type *)adc_misc_pos_chans, (ADC_Chan_Type *)adc_misc_neg_chans, 2, ENABLE);
ADC_Start();
} }
static bool fastPWM; static bool fastPWM;
@@ -58,12 +96,14 @@ volatile bool lastPeriodWasFast = false;
void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) { void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) {
if (state == TIMER_EVENT_COMP0) { if (state == TIMER_EVENT_COMP0) {
// MSG((char *)"timer event comp0! \r\n"); // MSG((char *)"timer event comp0! \r\n");
// We use channel 0 to trigger the ADC, this occurs after the main PWM is done with a delay // Used to start the ADC
start_adc_tip();
} else if (state == TIMER_EVENT_COMP1) { } else if (state == TIMER_EVENT_COMP1) {
// MSG((char *)"timer event comp1! \r\n"); // MSG((char *)"timer event comp1! \r\n");
// Channel 1 is end of the main PWM section; so turn off the output PWM // Used to turn tip off at set point in cycle
} else if (state == TIMER_EVENT_COMP2) { } else if (state == TIMER_EVENT_COMP2) {
start_adc_misc();
// This occurs at timer rollover, so if we want to turn on the output PWM; we do so // This occurs at timer rollover, so if we want to turn on the output PWM; we do so
if (PWMSafetyTimer) { if (PWMSafetyTimer) {
PWMSafetyTimer--; PWMSafetyTimer--;
@@ -83,7 +123,15 @@ void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t
// Leave output off // Leave output off
} }
} }
// MSG((char *)"timer event comp2! \r\n"); // unblock the PID controller thread
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (pidTaskNotification) {
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
MSG((char *)"timer event comp2! \r\n");
} }
} }
@@ -150,3 +198,10 @@ bool getFUS302IRQLow() {
return false; return false;
// return (RESET == gpio_input_bit_get(FUSB302_IRQ_GPIO_Port, FUSB302_IRQ_Pin)); // return (RESET == gpio_input_bit_get(FUSB302_IRQ_GPIO_Port, FUSB302_IRQ_Pin));
} }
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
uint16_t getTipRawTemp(uint8_t sample) { return ADC_Tip.average(); }

View File

@@ -18,6 +18,7 @@ extern "C" {
#endif #endif
void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state); void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state);
void adc_fifo_irq(void); void adc_fifo_irq(void);
void start_adc_misc(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -7,15 +7,17 @@
#ifndef BSP_PINE64_PINS_H_ #ifndef BSP_PINE64_PINS_H_
#define BSP_PINE64_PINS_H_ #define BSP_PINE64_PINS_H_
#include "bl702_adc.h"
#include "hal_gpio.h" #include "hal_gpio.h"
#define KEY_B_Pin GPIO_PIN_25 #define KEY_B_Pin GPIO_PIN_25
#define TMP36_INPUT_Pin GPIO_PIN_20 #define TMP36_INPUT_Pin GPIO_PIN_20
#define TMP36_ADC_CHANNEL #define TMP36_ADC_CHANNEL ADC_CHAN10
#define TIP_TEMP_Pin GPIO_PIN_19 #define TIP_TEMP_Pin GPIO_PIN_19
#define TIP_TEMP_ADC_CHANNEL #define TIP_TEMP_ADC_CHANNEL ADC_CHAN9
#define VIN_Pin GPIO_PIN_18 #define VIN_Pin GPIO_PIN_18
#define VIN_ADC_CHANNEL #define VIN_ADC_CHANNEL ADC_CHAN8
#define OLED_RESET_Pin GPIO_PIN_3 #define OLED_RESET_Pin GPIO_PIN_3
#define KEY_A_Pin GPIO_PIN_28 #define KEY_A_Pin GPIO_PIN_28
#define PWM_Out_Pin GPIO_PIN_21 #define PWM_Out_Pin GPIO_PIN_21

View File

@@ -9,18 +9,7 @@
#include "Debug.h" #include "Debug.h"
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
#include "Pins.h" #include "Pins.h"
extern "C" {
#include "bflb_platform.h"
#include "bl702_adc.h"
#include "bl702_glb.h"
#include "bl702_i2c.h"
#include "bl702_pwm.h"
#include "bl702_timer.h"
#include "hal_adc.h"
#include "hal_clock.h"
#include "hal_pwm.h"
#include "hal_timer.h"
}
#include "IRQ.h" #include "IRQ.h"
#include "history.hpp" #include "history.hpp"
#include <string.h> #include <string.h>
@@ -37,45 +26,48 @@ void hardware_init() {
// gpio_set_mode(KEY_A_Pin, GPIO_INPUT_PD_MODE); // gpio_set_mode(KEY_A_Pin, GPIO_INPUT_PD_MODE);
// gpio_set_mode(KEY_B_Pin, GPIO_INPUT_PD_MODE); // gpio_set_mode(KEY_B_Pin, GPIO_INPUT_PD_MODE);
setup_slow_PWM(); setup_slow_PWM();
setup_adc();
} }
void setup_adc(void) { void setup_adc(void) {
MSG((char *)"Setting up ADC\r\n");
// //
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); CPU_Interrupt_Disable(GPADC_DMA_IRQn);
ADC_IntMask(ADC_INT_ALL, MASK); ADC_IntMask(ADC_INT_ALL, MASK);
adc_cfg.clkDiv = ADC_CLK_DIV_32; adc_cfg.clkDiv = ADC_CLK_DIV_32;
adc_cfg.vref = ADC_VREF_3P2V; adc_cfg.vref = ADC_VREF_3P2V;
adc_cfg.resWidth = ADC_DATA_WIDTH_16_WITH_128_AVERAGE; adc_cfg.resWidth = ADC_DATA_WIDTH_16_WITH_256_AVERAGE;
adc_cfg.inputMode = ADC_INPUT_SINGLE_END; adc_cfg.inputMode = ADC_INPUT_SINGLE_END;
adc_cfg.v18Sel = ADC_V18_SEL_1P82V; adc_cfg.v18Sel = ADC_V18_SEL_1P82V;
adc_cfg.v11Sel = ADC_V11_SEL_1P1V; adc_cfg.v11Sel = ADC_V11_SEL_1P1V;
adc_cfg.gain1 = ADC_PGA_GAIN_1; adc_cfg.gain1 = ADC_PGA_GAIN_NONE;
adc_cfg.gain2 = ADC_PGA_GAIN_2; adc_cfg.gain2 = ADC_PGA_GAIN_NONE;
adc_cfg.chopMode = ADC_CHOP_MOD_AZ_PGA_ON; adc_cfg.chopMode = ADC_CHOP_MOD_AZ_PGA_ON;
adc_cfg.biasSel = ADC_BIAS_SEL_MAIN_BANDGAP; adc_cfg.biasSel = ADC_BIAS_SEL_MAIN_BANDGAP;
adc_cfg.vcm = ADC_PGA_VCM_1V; adc_cfg.vcm = ADC_PGA_VCM_1V;
adc_cfg.offsetCalibEn = DISABLE; adc_cfg.offsetCalibEn = DISABLE;
adc_cfg.offsetCalibVal = 0; adc_cfg.offsetCalibVal = 0;
adc_fifo_cfg.dmaEn = DISABLE;
adc_fifo_cfg.fifoThreshold = ADC_FIFO_THRESHOLD_16;
Interrupt_Handler_Register(GPADC_DMA_IRQn, adc_fifo_irq);
ADC_Disable(); ADC_Disable();
ADC_Enable(); ADC_Enable();
ADC_Reset(); ADC_Reset();
ADC_Init(&adc_cfg); ADC_Init(&adc_cfg);
adc_fifo_cfg.dmaEn = DISABLE;
adc_fifo_cfg.fifoThreshold = ADC_FIFO_THRESHOLD_16;
ADC_FIFO_Cfg(&adc_fifo_cfg); ADC_FIFO_Cfg(&adc_fifo_cfg);
// Enable FiFo IRQ
MSG((char *)"Int Enable\r\n");
Interrupt_Handler_Register(GPADC_DMA_IRQn, adc_fifo_irq);
ADC_IntMask(ADC_INT_FIFO_READY, UNMASK);
CPU_Interrupt_Enable(GPADC_DMA_IRQn);
MSG((char *)"Start\r\n");
start_adc_misc();
MSG((char *)"Started\r\n");
} }
struct device *timer0; struct device *timer0;
@@ -104,61 +96,6 @@ void setup_slow_PWM() {
} }
} }
/*
* ADC
* ADC is a bit of a mess as we dont have injected mode sampling to use with timers on this device
* So instead we do this:
*
* Main timer0 runs at 5/10hz and schedules everything
* Its running PWM in the 0-255 range for tip control + sample time at the end of the ADC
* It triggers the ADC at the end of the PWM cycle
*
*
*/
uint16_t getADCHandleTemp(uint8_t sample) {
static history<uint16_t, ADC_FILTER_LEN> filter = {{0}, 0, 0};
if (sample) {
uint32_t sum = 0;
for (uint8_t i = 0; i < ADC_NORM_SAMPLES; i++) {
sum += ADCReadings[i];
}
filter.update(sum);
}
return filter.average() >> 1;
}
uint16_t getADCVin(uint8_t sample) {
static history<uint16_t, ADC_FILTER_LEN> filter = {{0}, 0, 0};
if (sample) {
uint16_t latestADC = 0;
// latestADC += adc_inserted_data_read(ADC1, 0);
// latestADC += adc_inserted_data_read(ADC1, 1);
// latestADC += adc_inserted_data_read(ADC1, 2);
// latestADC += adc_inserted_data_read(ADC1, 3);
latestADC <<= 1;
filter.update(latestADC);
}
return filter.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
uint16_t getTipRawTemp(uint8_t sample) {
static history<uint16_t, ADC_FILTER_LEN> filter = {{0}, 0, 0};
if (sample) {
uint16_t latestADC = 0;
// latestADC += adc_inserted_data_read(ADC0, 0);
// latestADC += adc_inserted_data_read(ADC0, 1);
// latestADC += adc_inserted_data_read(ADC0, 2);
// latestADC += adc_inserted_data_read(ADC0, 3);
latestADC <<= 1;
filter.update(latestADC);
return latestADC;
}
return filter.average();
}
void setupFUSBIRQ() { void setupFUSBIRQ() {
// #TODO // #TODO
} }

View File

@@ -8,10 +8,24 @@
#ifndef PINE_SETUP_H_ #ifndef PINE_SETUP_H_
#define PINE_SETUP_H_ #define PINE_SETUP_H_
#include <stdint.h> #include <stdint.h>
extern "C" {
#include "bflb_platform.h"
#include "bl702_adc.h"
#include "bl702_common.h"
#include "bl702_glb.h"
#include "bl702_i2c.h"
#include "bl702_pwm.h"
#include "bl702_timer.h"
#include "hal_adc.h"
#include "hal_clock.h"
#include "hal_pwm.h"
#include "hal_timer.h"
}
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
uint16_t getADC(uint8_t channel); uint16_t getADC(uint8_t channel);
void hardware_init(); void hardware_init();
uint16_t getADCHandleTemp(uint8_t sample); uint16_t getADCHandleTemp(uint8_t sample);

View File

@@ -21,9 +21,9 @@
* *
*/ */
#include "hal_timer.h" #include "hal_timer.h"
#include "hal_clock.h"
#include "bl702_glb.h" #include "bl702_glb.h"
#include "bl702_timer.h" #include "bl702_timer.h"
#include "hal_clock.h"
#ifdef BSP_USING_TIMER0 #ifdef BSP_USING_TIMER0
void TIMER0_IRQ(void); void TIMER0_IRQ(void);
@@ -48,8 +48,7 @@ static timer_device_t timerx_device[TIMER_MAX_INDEX] = {
* @param oflag * @param oflag
* @return int * @return int
*/ */
int timer_open(struct device *dev, uint16_t oflag) int timer_open(struct device *dev, uint16_t oflag) {
{
timer_device_t *timer_device = (timer_device_t *)dev; timer_device_t *timer_device = (timer_device_t *)dev;
uint32_t tmpval; uint32_t tmpval;
@@ -153,8 +152,7 @@ int timer_open(struct device *dev, uint16_t oflag)
* @param dev * @param dev
* @return int * @return int
*/ */
int timer_close(struct device *dev) int timer_close(struct device *dev) {
{
timer_device_t *timer_device = (timer_device_t *)(dev); timer_device_t *timer_device = (timer_device_t *)(dev);
TIMER_Disable(timer_device->id); TIMER_Disable(timer_device->id);
return 0; return 0;
@@ -168,8 +166,7 @@ int timer_close(struct device *dev)
* @param args * @param args
* @return int * @return int
*/ */
int timer_control(struct device *dev, int cmd, void *args) int timer_control(struct device *dev, int cmd, void *args) {
{
timer_device_t *timer_device = (timer_device_t *)dev; timer_device_t *timer_device = (timer_device_t *)dev;
switch (cmd) { switch (cmd) {
@@ -243,8 +240,7 @@ int timer_control(struct device *dev, int cmd, void *args)
return 0; return 0;
} }
int timer_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size) int timer_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size) {
{
timer_device_t *timer_device = (timer_device_t *)dev; timer_device_t *timer_device = (timer_device_t *)dev;
timer_timeout_cfg_t *timeout_cfg = (timer_timeout_cfg_t *)buffer; timer_timeout_cfg_t *timeout_cfg = (timer_timeout_cfg_t *)buffer;
uint32_t compare_count = 0; uint32_t compare_count = 0;
@@ -296,10 +292,7 @@ int timer_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t s
TIMER_Enable(timer_device->id); TIMER_Enable(timer_device->id);
return 0; return 0;
} }
int timer_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size) int timer_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size) { return 0; }
{
return 0;
}
/** /**
* @brief * @brief
@@ -308,8 +301,7 @@ int timer_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
* @param name * @param name
* @return int * @return int
*/ */
int timer_register(enum timer_index_type index, const char *name) int timer_register(enum timer_index_type index, const char *name) {
{
struct device *dev; struct device *dev;
if (TIMER_MAX_INDEX == 0) { if (TIMER_MAX_INDEX == 0) {
@@ -330,8 +322,7 @@ int timer_register(enum timer_index_type index, const char *name)
return device_register(dev, name); return device_register(dev, name);
} }
void timer_isr(timer_device_t *handle) void timer_isr(timer_device_t *handle) {
{
uint32_t intId = 0; uint32_t intId = 0;
uint32_t tmpVal = 0; uint32_t tmpVal = 0;
uint32_t tmpAddr = 0; uint32_t tmpAddr = 0;
@@ -348,7 +339,6 @@ void timer_isr(timer_device_t *handle)
if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_0)) { if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_0)) {
BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_0)); BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_0));
handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP0); handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP0);
} }
/* Comparator 1 match interrupt */ /* Comparator 1 match interrupt */
@@ -369,10 +359,7 @@ void timer_isr(timer_device_t *handle)
* @brief * @brief
* *
*/ */
void TIMER0_IRQ(void) void TIMER0_IRQ(void) { timer_isr(&timerx_device[TIMER0_INDEX]); }
{
timer_isr(&timerx_device[TIMER0_INDEX]);
}
#endif #endif
@@ -381,9 +368,6 @@ void TIMER0_IRQ(void)
* @brief * @brief
* *
*/ */
void TIMER1_IRQ(void) void TIMER1_IRQ(void) { timer_isr(&timerx_device[TIMER1_INDEX]); }
{
timer_isr(&timerx_device[TIMER1_INDEX]);
}
#endif #endif

View File

@@ -49,7 +49,7 @@
#define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK #define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_IR_CLOCK_DIV 0 #define BSP_IR_CLOCK_DIV 0
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK #define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
#define BSP_ADC_CLOCK_DIV 0 #define BSP_ADC_CLOCK_DIV 128
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ #define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
#define BSP_DAC_CLOCK_DIV 2 #define BSP_DAC_CLOCK_DIV 2
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M #define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M

View File

@@ -8,7 +8,6 @@
#ifndef INC_EXPMOVINGAVERAGE_H_ #ifndef INC_EXPMOVINGAVERAGE_H_
#define INC_EXPMOVINGAVERAGE_H_ #define INC_EXPMOVINGAVERAGE_H_
// max size = 127
template <class T, uint8_t weighting> struct expMovingAverage { template <class T, uint8_t weighting> struct expMovingAverage {
int32_t sum; int32_t sum;
void update(T const val) { sum = ((val * weighting) + (sum * (256 - weighting))) / 256; } void update(T const val) { sum = ((val * weighting) + (sum * (256 - weighting))) / 256; }

View File

@@ -270,7 +270,7 @@ CPUFLAGS= -march=rv32imafc \
-mabi=ilp32f \ -mabi=ilp32f \
-mcmodel=medany -fsigned-char -fno-builtin -nostartfiles \ -mcmodel=medany -fsigned-char -fno-builtin -nostartfiles \
-DportasmHANDLE_INTERRUPT=FreeRTOS_Interrupt_Handler -DARCH_RISCV -D__RISCV_FEATURE_MVE=0 -DportUSING_MPU_WRAPPERS=0 -DportasmHANDLE_INTERRUPT=FreeRTOS_Interrupt_Handler -DARCH_RISCV -D__RISCV_FEATURE_MVE=0 -DportUSING_MPU_WRAPPERS=0
DEV_LDFLAGS=-nostartfiles --specs=patch.specs DEV_LDFLAGS=-nostartfiles --specs=patch.specs -DDEBUG
DEV_AFLAGS= DEV_AFLAGS=
DEV_GLOBAL_DEFS= DEV_GLOBAL_DEFS=
#Required to be turned off due to their drivers tripping warnings #Required to be turned off due to their drivers tripping warnings
@@ -355,7 +355,6 @@ LINKER_FLAGS= -Wl,--gc-sections \
-Wl,--defsym=__FLASH_SIZE__=$(flash_size) \ -Wl,--defsym=__FLASH_SIZE__=$(flash_size) \
-Wl,--defsym=__BOOTLDR_SIZE__=$(bootldr_size) \ -Wl,--defsym=__BOOTLDR_SIZE__=$(bootldr_size) \
-Wl,--print-memory-usage \ -Wl,--print-memory-usage \
-flto \
--specs=nosys.specs \ --specs=nosys.specs \
--specs=nano.specs \ --specs=nano.specs \
$(DEV_LDFLAGS) $(DEV_LDFLAGS)