Working scheduling of ADC 🎉
This commit is contained in:
@@ -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(); }
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -7,20 +7,22 @@
|
|||||||
|
|
||||||
#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 TMP36_INPUT_Pin GPIO_PIN_20
|
|
||||||
#define TMP36_ADC_CHANNEL
|
|
||||||
#define TIP_TEMP_Pin GPIO_PIN_19
|
|
||||||
#define TIP_TEMP_ADC_CHANNEL
|
|
||||||
|
|
||||||
#define VIN_Pin GPIO_PIN_18
|
#define KEY_B_Pin GPIO_PIN_25
|
||||||
#define VIN_ADC_CHANNEL
|
#define TMP36_INPUT_Pin GPIO_PIN_20
|
||||||
#define OLED_RESET_Pin GPIO_PIN_3
|
#define TMP36_ADC_CHANNEL ADC_CHAN10
|
||||||
#define KEY_A_Pin GPIO_PIN_28
|
#define TIP_TEMP_Pin GPIO_PIN_19
|
||||||
#define PWM_Out_Pin GPIO_PIN_21
|
#define TIP_TEMP_ADC_CHANNEL ADC_CHAN9
|
||||||
#define SCL_Pin GPIO_PIN_11
|
|
||||||
#define SDA_Pin GPIO_PIN_10
|
#define VIN_Pin GPIO_PIN_18
|
||||||
|
#define VIN_ADC_CHANNEL ADC_CHAN8
|
||||||
|
#define OLED_RESET_Pin GPIO_PIN_3
|
||||||
|
#define KEY_A_Pin GPIO_PIN_28
|
||||||
|
#define PWM_Out_Pin GPIO_PIN_21
|
||||||
|
#define SCL_Pin GPIO_PIN_11
|
||||||
|
#define SDA_Pin GPIO_PIN_10
|
||||||
|
|
||||||
// #define USB_DM_Pin GPIO_PIN_8
|
// #define USB_DM_Pin GPIO_PIN_8
|
||||||
#define QC_DP_LOW_Pin GPIO_PIN_5
|
#define QC_DP_LOW_Pin GPIO_PIN_5
|
||||||
|
|||||||
@@ -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_256_AVERAGE;
|
||||||
adc_cfg.resWidth = ADC_DATA_WIDTH_16_WITH_128_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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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,103 +48,102 @@ 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;
|
||||||
uint32_t compare_count1 = 0;
|
uint32_t compare_count1 = 0;
|
||||||
uint32_t compare_count2 = 0;
|
uint32_t compare_count2 = 0;
|
||||||
uint32_t compare_count3 = 0;
|
uint32_t compare_count3 = 0;
|
||||||
uint32_t reload_val = 0;
|
uint32_t reload_val = 0;
|
||||||
uint32_t clkval = 0;
|
uint32_t clkval = 0;
|
||||||
uint32_t unit = 0;
|
uint32_t unit = 0;
|
||||||
|
|
||||||
/* Disable all interrupt */
|
/* Disable all interrupt */
|
||||||
TIMER_IntMask(timer_device->id, TIMER_INT_ALL, MASK);
|
TIMER_IntMask(timer_device->id, TIMER_INT_ALL, MASK);
|
||||||
/* Disable timer before config */
|
/* Disable timer before config */
|
||||||
TIMER_Disable(timer_device->id);
|
TIMER_Disable(timer_device->id);
|
||||||
|
|
||||||
/* Configure timer count mode: preload or free run */
|
/* Configure timer count mode: preload or free run */
|
||||||
tmpval = BL_RD_WORD(TIMER_BASE + TIMER_TCMR_OFFSET);
|
tmpval = BL_RD_WORD(TIMER_BASE + TIMER_TCMR_OFFSET);
|
||||||
tmpval &= (~(1 << (timer_device->id + 1)));
|
tmpval &= (~(1 << (timer_device->id + 1)));
|
||||||
tmpval |= (timer_device->cnt_mode << (timer_device->id + 1));
|
tmpval |= (timer_device->cnt_mode << (timer_device->id + 1));
|
||||||
|
|
||||||
BL_WR_WORD(TIMER_BASE + TIMER_TCMR_OFFSET, tmpval);
|
BL_WR_WORD(TIMER_BASE + TIMER_TCMR_OFFSET, tmpval);
|
||||||
|
|
||||||
/* Configure timer preload trigger source */
|
/* Configure timer preload trigger source */
|
||||||
BL_WR_WORD(TIMER_BASE + TIMER_TPLCR2_OFFSET + 4 * timer_device->id, timer_device->trigger);
|
BL_WR_WORD(TIMER_BASE + TIMER_TPLCR2_OFFSET + 4 * timer_device->id, timer_device->trigger);
|
||||||
|
|
||||||
if (timer_device->cnt_mode == TIMER_CNT_PRELOAD) {
|
if (timer_device->cnt_mode == TIMER_CNT_PRELOAD) {
|
||||||
BL_WR_WORD(TIMER_BASE + TIMER_TPLVR2_OFFSET + 4 * timer_device->id, timer_device->reload);
|
BL_WR_WORD(TIMER_BASE + TIMER_TPLVR2_OFFSET + 4 * timer_device->id, timer_device->reload);
|
||||||
reload_val = timer_device->reload;
|
reload_val = timer_device->reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer_device->id == TIMER_CH0) {
|
if (timer_device->id == TIMER_CH0) {
|
||||||
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0);
|
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0);
|
||||||
} else {
|
} else {
|
||||||
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1);
|
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clkval % 1000000 == 0) {
|
if (clkval % 1000000 == 0) {
|
||||||
unit = 1000000; //1us
|
unit = 1000000; // 1us
|
||||||
} else if (clkval % 100000 == 0) {
|
} else if (clkval % 100000 == 0) {
|
||||||
unit = 100000; //10us
|
unit = 100000; // 10us
|
||||||
} else if (clkval % 10000 == 0) {
|
} else if (clkval % 10000 == 0) {
|
||||||
unit = 10000; //100us
|
unit = 10000; // 100us
|
||||||
} else if (clkval % 1000 == 0) {
|
} else if (clkval % 1000 == 0) {
|
||||||
unit = 1000; //1ms
|
unit = 1000; // 1ms
|
||||||
} else if (clkval % 100 == 0) {
|
} else if (clkval % 100 == 0) {
|
||||||
unit = 100; //10ms
|
unit = 100; // 10ms
|
||||||
} else if (clkval % 10 == 0) {
|
} else if (clkval % 10 == 0) {
|
||||||
unit = 10; //100ms
|
unit = 10; // 100ms
|
||||||
} else if (clkval % 1 == 0) {
|
} else if (clkval % 1 == 0) {
|
||||||
unit = 1; //s
|
unit = 1; // s
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
compare_count1 = timer_device->timeout1 / (1000000 / unit) * (clkval / unit) + reload_val;
|
compare_count1 = timer_device->timeout1 / (1000000 / unit) * (clkval / unit) + reload_val;
|
||||||
compare_count2 = timer_device->timeout2 / (1000000 / unit) * (clkval / unit) + reload_val;
|
compare_count2 = timer_device->timeout2 / (1000000 / unit) * (clkval / unit) + reload_val;
|
||||||
compare_count3 = timer_device->timeout3 / (1000000 / unit) * (clkval / unit) + reload_val;
|
compare_count3 = timer_device->timeout3 / (1000000 / unit) * (clkval / unit) + reload_val;
|
||||||
|
|
||||||
/* Configure match compare values */
|
/* Configure match compare values */
|
||||||
if ((compare_count1 < 1) || (compare_count2 < 1) || (compare_count3 < 1)) {
|
if ((compare_count1 < 1) || (compare_count2 < 1) || (compare_count3 < 1)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_0, compare_count1 - 2);
|
TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_0, compare_count1 - 2);
|
||||||
TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_1, compare_count2 - 2);
|
TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_1, compare_count2 - 2);
|
||||||
TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_2, compare_count3 - 2);
|
TIMER_SetCompValue(timer_device->id, TIMER_COMP_ID_2, compare_count3 - 2);
|
||||||
|
|
||||||
/* Clear interrupt status*/
|
/* Clear interrupt status*/
|
||||||
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_0);
|
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_0);
|
||||||
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_1);
|
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_1);
|
||||||
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_2);
|
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_2);
|
||||||
|
|
||||||
if (oflag & DEVICE_OFLAG_STREAM_TX) {
|
if (oflag & DEVICE_OFLAG_STREAM_TX) {
|
||||||
/* Enable timer match interrupt */
|
/* Enable timer match interrupt */
|
||||||
/* Note: if not enable match interrupt, TIMER_GetMatchStatus will not work
|
/* Note: if not enable match interrupt, TIMER_GetMatchStatus will not work
|
||||||
and status bit will not set */
|
and status bit will not set */
|
||||||
TIMER_IntMask(timer_device->id, TIMER_INT_COMP_0, UNMASK);
|
TIMER_IntMask(timer_device->id, TIMER_INT_COMP_0, UNMASK);
|
||||||
TIMER_IntMask(timer_device->id, TIMER_INT_COMP_1, UNMASK);
|
TIMER_IntMask(timer_device->id, TIMER_INT_COMP_1, UNMASK);
|
||||||
TIMER_IntMask(timer_device->id, TIMER_INT_COMP_2, UNMASK);
|
TIMER_IntMask(timer_device->id, TIMER_INT_COMP_2, UNMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oflag & DEVICE_OFLAG_INT_TX) {
|
if (oflag & DEVICE_OFLAG_INT_TX) {
|
||||||
#ifdef BSP_USING_TIMER0
|
#ifdef BSP_USING_TIMER0
|
||||||
if (timer_device->id == TIMER_CH0) {
|
if (timer_device->id == TIMER_CH0) {
|
||||||
Interrupt_Handler_Register(TIMER_CH0_IRQn, TIMER0_IRQ);
|
Interrupt_Handler_Register(TIMER_CH0_IRQn, TIMER0_IRQ);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef BSP_USING_TIMER1
|
#ifdef BSP_USING_TIMER1
|
||||||
if (timer_device->id == TIMER_CH1) {
|
if (timer_device->id == TIMER_CH1) {
|
||||||
Interrupt_Handler_Register(TIMER_CH1_IRQn, TIMER1_IRQ);
|
Interrupt_Handler_Register(TIMER_CH1_IRQn, TIMER1_IRQ);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/* Enable timer */
|
#endif
|
||||||
TIMER_Enable(timer_device->id);
|
}
|
||||||
return 0;
|
/* Enable timer */
|
||||||
|
TIMER_Enable(timer_device->id);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,11 +152,10 @@ 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,138 +166,133 @@ 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) {
|
||||||
case DEVICE_CTRL_SET_INT /* constant-expression */: {
|
case DEVICE_CTRL_SET_INT /* constant-expression */: {
|
||||||
uint32_t offset = __builtin_ctz((uint32_t)args);
|
uint32_t offset = __builtin_ctz((uint32_t)args);
|
||||||
|
|
||||||
while (offset < 3) {
|
while (offset < 3) {
|
||||||
if ((uint32_t)args & (1 << offset)) {
|
if ((uint32_t)args & (1 << offset)) {
|
||||||
TIMER_IntMask(timer_device->id, offset, UNMASK);
|
TIMER_IntMask(timer_device->id, offset, UNMASK);
|
||||||
}
|
}
|
||||||
offset++;
|
offset++;
|
||||||
}
|
|
||||||
|
|
||||||
if (timer_device->id == TIMER_CH0) {
|
|
||||||
CPU_Interrupt_Pending_Clear(TIMER_CH0_IRQn);
|
|
||||||
CPU_Interrupt_Enable(TIMER_CH0_IRQn);
|
|
||||||
} else if (timer_device->id == TIMER_CH1) {
|
|
||||||
CPU_Interrupt_Pending_Clear(TIMER_CH1_IRQn);
|
|
||||||
CPU_Interrupt_Enable(TIMER_CH1_IRQn);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DEVICE_CTRL_CLR_INT /* constant-expression */: {
|
|
||||||
uint32_t offset = __builtin_ctz((uint32_t)args);
|
|
||||||
|
|
||||||
while (offset < 3) {
|
|
||||||
if ((uint32_t)args & (1 << offset)) {
|
|
||||||
TIMER_IntMask(timer_device->id, offset, MASK);
|
|
||||||
}
|
|
||||||
offset++;
|
|
||||||
}
|
|
||||||
if (timer_device->id == TIMER_CH0) {
|
|
||||||
CPU_Interrupt_Disable(TIMER_CH0_IRQn);
|
|
||||||
} else if (timer_device->id == TIMER_CH1) {
|
|
||||||
CPU_Interrupt_Disable(TIMER_CH1_IRQn);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DEVICE_CTRL_GET_INT /* constant-expression */: {
|
|
||||||
uint32_t offset = __builtin_ctz((uint32_t)args);
|
|
||||||
uint32_t intstatus = TIMER_GetMatchStatus(timer_device->id, offset);
|
|
||||||
/* Clear interrupt status*/
|
|
||||||
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_0);
|
|
||||||
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_1);
|
|
||||||
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_2);
|
|
||||||
return intstatus;
|
|
||||||
}
|
|
||||||
case DEVICE_CTRL_CONFIG /* constant-expression */:
|
|
||||||
/* code */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEVICE_CTRL_RESUME /* constant-expression */: {
|
|
||||||
/* Enable timer */
|
|
||||||
TIMER_Enable(timer_device->id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case DEVICE_CTRL_SUSPEND /* constant-expression */: {
|
|
||||||
TIMER_Disable(timer_device->id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DEVICE_CTRL_GET_CONFIG:
|
|
||||||
return TIMER_GetCounterValue(timer_device->id);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_timeout_cfg_t *timeout_cfg = (timer_timeout_cfg_t *)buffer;
|
|
||||||
uint32_t compare_count = 0;
|
|
||||||
uint32_t reload_val = 0;
|
|
||||||
uint32_t clkval = 0;
|
|
||||||
uint32_t unit = 0;
|
|
||||||
|
|
||||||
if (size % sizeof(timer_timeout_cfg_t)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* Disable timer before config */
|
|
||||||
TIMER_Disable(timer_device->id);
|
|
||||||
|
|
||||||
if (timer_device->cnt_mode == TIMER_CNT_PRELOAD) {
|
|
||||||
reload_val = timer_device->reload;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer_device->id == TIMER_CH0) {
|
if (timer_device->id == TIMER_CH0) {
|
||||||
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0);
|
CPU_Interrupt_Pending_Clear(TIMER_CH0_IRQn);
|
||||||
} else {
|
CPU_Interrupt_Enable(TIMER_CH0_IRQn);
|
||||||
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1);
|
} else if (timer_device->id == TIMER_CH1) {
|
||||||
|
CPU_Interrupt_Pending_Clear(TIMER_CH1_IRQn);
|
||||||
|
CPU_Interrupt_Enable(TIMER_CH1_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clkval % 1000000 == 0) {
|
break;
|
||||||
unit = 1000000; //1us
|
}
|
||||||
} else if (clkval % 100000 == 0) {
|
|
||||||
unit = 100000; //10us
|
|
||||||
} else if (clkval % 10000 == 0) {
|
|
||||||
unit = 10000; //100us
|
|
||||||
} else if (clkval % 1000 == 0) {
|
|
||||||
unit = 1000; //1ms
|
|
||||||
} else if (clkval % 100 == 0) {
|
|
||||||
unit = 100; //10ms
|
|
||||||
} else if (clkval % 10 == 0) {
|
|
||||||
unit = 10; //100ms
|
|
||||||
} else if (clkval % 1 == 0) {
|
|
||||||
unit = 1; //s
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < size / sizeof(timer_timeout_cfg_t); i++) {
|
case DEVICE_CTRL_CLR_INT /* constant-expression */: {
|
||||||
compare_count = timeout_cfg->timeout_val / (1000000 / unit) * (clkval / unit) + reload_val;
|
uint32_t offset = __builtin_ctz((uint32_t)args);
|
||||||
|
|
||||||
if (compare_count < 1) {
|
while (offset < 3) {
|
||||||
return -1;
|
if ((uint32_t)args & (1 << offset)) {
|
||||||
}
|
TIMER_IntMask(timer_device->id, offset, MASK);
|
||||||
TIMER_SetCompValue(timer_device->id, timeout_cfg->timeout_id, compare_count - 2);
|
}
|
||||||
|
offset++;
|
||||||
}
|
}
|
||||||
|
if (timer_device->id == TIMER_CH0) {
|
||||||
|
CPU_Interrupt_Disable(TIMER_CH0_IRQn);
|
||||||
|
} else if (timer_device->id == TIMER_CH1) {
|
||||||
|
CPU_Interrupt_Disable(TIMER_CH1_IRQn);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DEVICE_CTRL_GET_INT /* constant-expression */: {
|
||||||
|
uint32_t offset = __builtin_ctz((uint32_t)args);
|
||||||
|
uint32_t intstatus = TIMER_GetMatchStatus(timer_device->id, offset);
|
||||||
|
/* Clear interrupt status*/
|
||||||
|
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_0);
|
||||||
|
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_1);
|
||||||
|
TIMER_ClearIntStatus(timer_device->id, TIMER_COMP_ID_2);
|
||||||
|
return intstatus;
|
||||||
|
}
|
||||||
|
case DEVICE_CTRL_CONFIG /* constant-expression */:
|
||||||
|
/* code */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEVICE_CTRL_RESUME /* constant-expression */: {
|
||||||
|
/* Enable timer */
|
||||||
TIMER_Enable(timer_device->id);
|
TIMER_Enable(timer_device->id);
|
||||||
return 0;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DEVICE_CTRL_SUSPEND /* constant-expression */: {
|
||||||
|
TIMER_Disable(timer_device->id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DEVICE_CTRL_GET_CONFIG:
|
||||||
|
return TIMER_GetCounterValue(timer_device->id);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
int timer_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size)
|
|
||||||
{
|
int timer_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size) {
|
||||||
return 0;
|
timer_device_t *timer_device = (timer_device_t *)dev;
|
||||||
|
timer_timeout_cfg_t *timeout_cfg = (timer_timeout_cfg_t *)buffer;
|
||||||
|
uint32_t compare_count = 0;
|
||||||
|
uint32_t reload_val = 0;
|
||||||
|
uint32_t clkval = 0;
|
||||||
|
uint32_t unit = 0;
|
||||||
|
|
||||||
|
if (size % sizeof(timer_timeout_cfg_t)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Disable timer before config */
|
||||||
|
TIMER_Disable(timer_device->id);
|
||||||
|
|
||||||
|
if (timer_device->cnt_mode == TIMER_CNT_PRELOAD) {
|
||||||
|
reload_val = timer_device->reload;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer_device->id == TIMER_CH0) {
|
||||||
|
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER0);
|
||||||
|
} else {
|
||||||
|
clkval = peripheral_clock_get(PERIPHERAL_CLOCK_TIMER1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clkval % 1000000 == 0) {
|
||||||
|
unit = 1000000; // 1us
|
||||||
|
} else if (clkval % 100000 == 0) {
|
||||||
|
unit = 100000; // 10us
|
||||||
|
} else if (clkval % 10000 == 0) {
|
||||||
|
unit = 10000; // 100us
|
||||||
|
} else if (clkval % 1000 == 0) {
|
||||||
|
unit = 1000; // 1ms
|
||||||
|
} else if (clkval % 100 == 0) {
|
||||||
|
unit = 100; // 10ms
|
||||||
|
} else if (clkval % 10 == 0) {
|
||||||
|
unit = 10; // 100ms
|
||||||
|
} else if (clkval % 1 == 0) {
|
||||||
|
unit = 1; // s
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size / sizeof(timer_timeout_cfg_t); i++) {
|
||||||
|
compare_count = timeout_cfg->timeout_val / (1000000 / unit) * (clkval / unit) + reload_val;
|
||||||
|
|
||||||
|
if (compare_count < 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
TIMER_SetCompValue(timer_device->id, timeout_cfg->timeout_id, compare_count - 2);
|
||||||
|
}
|
||||||
|
TIMER_Enable(timer_device->id);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
int timer_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size) { return 0; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
@@ -308,60 +301,57 @@ 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) {
|
||||||
return -DEVICE_EINVAL;
|
return -DEVICE_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = &(timerx_device[index].parent);
|
dev = &(timerx_device[index].parent);
|
||||||
|
|
||||||
dev->open = timer_open;
|
dev->open = timer_open;
|
||||||
dev->close = timer_close;
|
dev->close = timer_close;
|
||||||
dev->control = timer_control;
|
dev->control = timer_control;
|
||||||
dev->write = timer_write;
|
dev->write = timer_write;
|
||||||
// dev->read = NULL;
|
// dev->read = NULL;
|
||||||
|
|
||||||
dev->type = DEVICE_CLASS_TIMER;
|
dev->type = DEVICE_CLASS_TIMER;
|
||||||
dev->handle = NULL;
|
dev->handle = NULL;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (!handle->parent.callback) {
|
if (!handle->parent.callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
intId = BL_RD_WORD(TIMER_BASE + TIMER_TMSR2_OFFSET + 4 * handle->id);
|
intId = BL_RD_WORD(TIMER_BASE + TIMER_TMSR2_OFFSET + 4 * handle->id);
|
||||||
tmpAddr = TIMER_BASE + TIMER_TICR2_OFFSET + 4 * handle->id;
|
tmpAddr = TIMER_BASE + TIMER_TICR2_OFFSET + 4 * handle->id;
|
||||||
tmpVal = BL_RD_WORD(tmpAddr);
|
tmpVal = BL_RD_WORD(tmpAddr);
|
||||||
|
|
||||||
/* Comparator 0 match interrupt */
|
/* Comparator 0 match interrupt */
|
||||||
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 */
|
||||||
|
if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_1)) {
|
||||||
|
BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_1));
|
||||||
|
handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Comparator 1 match interrupt */
|
/* Comparator 2 match interrupt */
|
||||||
if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_1)) {
|
if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_2)) {
|
||||||
BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_1));
|
BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_2));
|
||||||
handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP1);
|
handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Comparator 2 match interrupt */
|
|
||||||
if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_2)) {
|
|
||||||
BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_2));
|
|
||||||
handle->parent.callback(&handle->parent, NULL, 0, TIMER_EVENT_COMP2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BSP_USING_TIMER0
|
#ifdef BSP_USING_TIMER0
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user