mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
ADC timing faster + timer without HAL
This commit is contained in:
@@ -12,8 +12,8 @@
|
||||
|
||||
// These control the period's of time used for the PWM
|
||||
const uint16_t powerPWM = 255;
|
||||
const uint8_t holdoffTicks = 10;
|
||||
const uint8_t tempMeasureTicks = 14;
|
||||
const uint8_t holdoffTicks = 14;
|
||||
const uint8_t tempMeasureTicks = 10;
|
||||
|
||||
uint16_t totalPWM = 255; // Total length of the cycle's ticks
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ bool FRToSI2C::wakePart(uint16_t DevAddress) {
|
||||
i2cCfg.subAddrSize = 0;
|
||||
|
||||
err = I2C_MasterReceiveBlocking(I2C0_ID, &i2cCfg);
|
||||
MSG((char *)"I2C wakePart %02X - %d\r\n", DevAddress >> 1, err);
|
||||
// MSG((char *)"I2C wakePart %02X - %d\r\n", DevAddress >> 1, err);
|
||||
bool res = err == SUCCESS;
|
||||
if (!res) {
|
||||
I2C_Unstick();
|
||||
|
||||
@@ -16,9 +16,7 @@ extern "C" {
|
||||
#include "bl702_glb.h"
|
||||
#include "bl702_pwm.h"
|
||||
#include "bl702_timer.h"
|
||||
#include "hal_adc.h"
|
||||
#include "hal_clock.h"
|
||||
#include "hal_timer.h"
|
||||
}
|
||||
|
||||
#define ADC_Filter_Smooth 4
|
||||
@@ -27,10 +25,8 @@ history<uint16_t, ADC_Filter_Smooth> ADC_Temp;
|
||||
history<uint16_t, ADC_Filter_Smooth> ADC_Tip;
|
||||
|
||||
void adc_fifo_irq(void) {
|
||||
|
||||
MSG((char *)"ADC IRQ\r\n");
|
||||
if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
|
||||
ADC_IntClr(ADC_INT_FIFO_READY);
|
||||
|
||||
// Read out all entries in the fifo
|
||||
const uint8_t cnt = ADC_Get_FIFO_Count();
|
||||
for (uint8_t i = 0; i < cnt; i++) {
|
||||
@@ -50,27 +46,17 @@ void adc_fifo_irq(void) {
|
||||
break;
|
||||
|
||||
default:
|
||||
MSG((char *)"ADC Invalid chan %d\r\n", source);
|
||||
// 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());
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
void start_adc_tip(void) {
|
||||
// Reconfigure the ADC to measure the tip temp
|
||||
// Single channel input mode
|
||||
// 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
|
||||
ADC_Start();
|
||||
}
|
||||
|
||||
void stop_adc(void) {}
|
||||
|
||||
static bool fastPWM;
|
||||
static void switchToSlowPWM(void);
|
||||
static bool fastPWM = false;
|
||||
static void switchToFastPWM(void);
|
||||
|
||||
volatile uint16_t PWMSafetyTimer = 0;
|
||||
@@ -78,16 +64,16 @@ volatile uint8_t pendingPWM = 200;
|
||||
volatile bool lastPeriodWasFast = false;
|
||||
|
||||
// Timer 0 is used to co-ordinate the ADC and the output PWM
|
||||
void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state) {
|
||||
if (state == TIMER_EVENT_COMP0) {
|
||||
// MSG((char *)"timer event comp0! \r\n");
|
||||
// Used to start the ADC
|
||||
start_adc_tip();
|
||||
} else if (state == TIMER_EVENT_COMP1) {
|
||||
// MSG((char *)"timer event comp1! \r\n");
|
||||
// Used to turn tip off at set point in cycle
|
||||
void timer0_comp0_callback(void) {
|
||||
MSG((char *)"Timer CMP0\r\n");
|
||||
ADC_Start();
|
||||
}
|
||||
void timer0_comp1_callback(void) {
|
||||
MSG((char *)"Timer CMP1\r\n");
|
||||
PWM_Channel_Disable(PWM_Channel);
|
||||
} else if (state == TIMER_EVENT_COMP2) {
|
||||
}
|
||||
void timer0_comp2_callback(void) {
|
||||
MSG((char *)"Timer CMP2\r\n");
|
||||
// This occurs at timer rollover, so if we want to turn on the output PWM; we do so
|
||||
if (PWMSafetyTimer) {
|
||||
PWMSafetyTimer--;
|
||||
@@ -117,8 +103,6 @@ void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
// MSG((char *)"timer event comp2! \r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void switchToFastPWM(void) {
|
||||
@@ -132,7 +116,7 @@ void switchToFastPWM(void) {
|
||||
|
||||
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
||||
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 11);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 20);
|
||||
|
||||
BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmpVal);
|
||||
}
|
||||
@@ -150,7 +134,7 @@ void switchToSlowPWM(void) {
|
||||
|
||||
uint32_t tmpVal = BL_RD_REG(TIMER_BASE, TIMER_TCDR);
|
||||
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 22);
|
||||
tmpVal = BL_SET_REG_BITS_VAL(tmpVal, TIMER_TCDR2, 40);
|
||||
|
||||
BL_WR_REG(TIMER_BASE, TIMER_TCDR, tmpVal);
|
||||
}
|
||||
@@ -194,10 +178,10 @@ void GPIO_IRQHandler(void) {
|
||||
|
||||
bool getFUS302IRQLow() {
|
||||
// Return true if the IRQ line is still held low
|
||||
return false;
|
||||
// return (RESET == gpio_input_bit_get(FUSB302_IRQ_GPIO_Port, FUSB302_IRQ_Pin));
|
||||
return !gpio_read(FUSB302_IRQ_Pin);
|
||||
}
|
||||
uint16_t rescaleADC(const uint16_t value) {
|
||||
// TODO This can be removed once we figure out final op-amp scaling
|
||||
// return value;
|
||||
uint32_t temp = value * 33;
|
||||
uint16_t res = temp / 32;
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void timer0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state);
|
||||
void timer0_comp0_callback(void);
|
||||
void timer0_comp1_callback(void);
|
||||
void timer0_comp2_callback(void);
|
||||
void adc_fifo_irq(void);
|
||||
void start_adc_misc(void);
|
||||
void GPIO_IRQHandler(void);
|
||||
void switchToSlowPWM(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@ void setup_pwm(void) {
|
||||
PWM_CH_CFG_Type cfg = {
|
||||
PWM_Channel, // channel
|
||||
PWM_CLK_XCLK, // Clock
|
||||
PWM_STOP_GRACEFUL, // Stop mode
|
||||
PWM_STOP_ABRUPT, // Stop mode
|
||||
PWM_POL_NORMAL, // Normal Polarity
|
||||
50, // Clock Div
|
||||
100, // Period
|
||||
@@ -49,9 +49,7 @@ void setup_pwm(void) {
|
||||
0, // Interrupt pulse count
|
||||
};
|
||||
|
||||
BL_Err_Type err = PWM_Channel_Init(&cfg);
|
||||
uint32_t pwm_clk = peripheral_clock_get(PERIPHERAL_CLOCK_PWM);
|
||||
MSG((char *)"PWM Setup returns %d %d\r\n", err, pwm_clk);
|
||||
PWM_Channel_Init(&cfg);
|
||||
PWM_Channel_Disable(PWM_Channel);
|
||||
}
|
||||
|
||||
@@ -61,7 +59,6 @@ const ADC_Chan_Type adc_tip_neg_chans[] = {ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_
|
||||
static_assert(sizeof(adc_tip_pos_chans) == sizeof(adc_tip_neg_chans));
|
||||
|
||||
void setup_adc(void) {
|
||||
MSG((char *)"Setting up ADC\r\n");
|
||||
//
|
||||
ADC_CFG_Type adc_cfg = {};
|
||||
ADC_FIFO_Cfg_Type adc_fifo_cfg = {};
|
||||
@@ -70,9 +67,9 @@ void setup_adc(void) {
|
||||
|
||||
ADC_IntMask(ADC_INT_ALL, MASK);
|
||||
|
||||
adc_cfg.clkDiv = ADC_CLK_DIV_32;
|
||||
adc_cfg.clkDiv = ADC_CLK_DIV_4;
|
||||
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.v18Sel = ADC_V18_SEL_1P82V;
|
||||
adc_cfg.v11Sel = ADC_V11_SEL_1P1V;
|
||||
@@ -102,30 +99,36 @@ void setup_adc(void) {
|
||||
ADC_FIFO_Clear();
|
||||
}
|
||||
|
||||
struct device *timer0;
|
||||
|
||||
void setup_timer_scheduler() {
|
||||
TIMER_Disable(TIMER_CH0);
|
||||
|
||||
timer_register(TIMER0_INDEX, "timer0");
|
||||
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_Init(&cfg);
|
||||
|
||||
timer0 = device_find("timer0");
|
||||
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);
|
||||
|
||||
if (timer0) {
|
||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_0);
|
||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_1);
|
||||
TIMER_ClearIntStatus(TIMER_CH0, TIMER_COMP_ID_2);
|
||||
|
||||
device_open(timer0, DEVICE_OFLAG_INT_TX); /* 1s,2s,3s timing*/
|
||||
// Set interrupt handler
|
||||
device_set_callback(timer0, timer0_irq_callback);
|
||||
// Enable both interrupts (0 and 1)
|
||||
device_control(timer0, DEVICE_CTRL_SET_INT, (void *)(TIMER_COMP0_IT | TIMER_COMP1_IT | TIMER_COMP2_IT));
|
||||
|
||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_0, 255 + 10 - 2); // Channel 0 is used to trigger the ADC
|
||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_1, 128 - 2);
|
||||
TIMER_SetCompValue(TIMER_CH0, TIMER_COMP_ID_2, (255 + 10 + 10) - 2); // We are using compare 2 to set the max duration of the timer
|
||||
TIMER_SetPreloadValue(TIMER_CH0, 0);
|
||||
TIMER_SetCountMode(TIMER_CH0, TIMER_COUNT_PRELOAD);
|
||||
} else {
|
||||
MSG((char *)"timer device open failed! \n");
|
||||
}
|
||||
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() {
|
||||
|
||||
@@ -18,7 +18,6 @@ extern "C" {
|
||||
#include "bl702_timer.h"
|
||||
#include "hal_adc.h"
|
||||
#include "hal_clock.h"
|
||||
#include "hal_timer.h"
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
* @file hal_timer.h
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef __HAL_TIMER__H__
|
||||
#define __HAL_TIMER__H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "hal_common.h"
|
||||
#include "drv_device.h"
|
||||
#include "bl702_config.h"
|
||||
|
||||
enum timer_index_type {
|
||||
#ifdef BSP_USING_TIMER0
|
||||
TIMER0_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_TIMER1
|
||||
TIMER1_INDEX,
|
||||
#endif
|
||||
TIMER_MAX_INDEX
|
||||
};
|
||||
|
||||
enum timer_preload_trigger_type {
|
||||
TIMER_PRELOAD_TRIGGER_NONE,
|
||||
TIMER_PRELOAD_TRIGGER_COMP0,
|
||||
TIMER_PRELOAD_TRIGGER_COMP1,
|
||||
TIMER_PRELOAD_TRIGGER_COMP2,
|
||||
};
|
||||
|
||||
enum timer_cnt_mode_type {
|
||||
TIMER_CNT_PRELOAD,
|
||||
TIMER_CNT_FREERUN,
|
||||
};
|
||||
|
||||
enum timer_compare_id_type {
|
||||
TIMER_COMPARE_ID_0,
|
||||
TIMER_COMPARE_ID_1,
|
||||
TIMER_COMPARE_ID_2,
|
||||
};
|
||||
|
||||
enum timer_it_type {
|
||||
TIMER_COMP0_IT = 1 << 0,
|
||||
TIMER_COMP1_IT = 1 << 1,
|
||||
TIMER_COMP2_IT = 1 << 2,
|
||||
};
|
||||
|
||||
enum timer_event_type {
|
||||
TIMER_EVENT_COMP0,
|
||||
TIMER_EVENT_COMP1,
|
||||
TIMER_EVENT_COMP2,
|
||||
TIMER_EVENT_UNKNOWN
|
||||
};
|
||||
|
||||
typedef struct timer_timeout_cfg {
|
||||
enum timer_compare_id_type timeout_id;
|
||||
uint32_t timeout_val;
|
||||
} timer_timeout_cfg_t;
|
||||
|
||||
typedef struct timer_device {
|
||||
struct device parent;
|
||||
uint8_t id;
|
||||
enum timer_cnt_mode_type cnt_mode;
|
||||
enum timer_preload_trigger_type trigger;
|
||||
uint32_t reload;
|
||||
uint32_t timeout1;
|
||||
uint32_t timeout2;
|
||||
uint32_t timeout3;
|
||||
} timer_device_t;
|
||||
|
||||
#define TIMER_DEV(dev) ((timer_device_t *)dev)
|
||||
|
||||
int timer_register(enum timer_index_type index, const char *name);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,373 +0,0 @@
|
||||
/**
|
||||
* @file hal_timer.c
|
||||
* @brief
|
||||
*
|
||||
* Copyright (c) 2021 Bouffalolab team
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
#include "hal_timer.h"
|
||||
#include "bl702_glb.h"
|
||||
#include "bl702_timer.h"
|
||||
#include "hal_clock.h"
|
||||
|
||||
#ifdef BSP_USING_TIMER0
|
||||
void TIMER0_IRQ(void);
|
||||
#endif
|
||||
#ifdef BSP_USING_TIMER1
|
||||
void TIMER1_IRQ(void);
|
||||
#endif
|
||||
|
||||
static timer_device_t timerx_device[TIMER_MAX_INDEX] = {
|
||||
#ifdef BSP_USING_TIMER0
|
||||
TIMER0_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_TIMER1
|
||||
TIMER1_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param oflag
|
||||
* @return int
|
||||
*/
|
||||
int timer_open(struct device *dev, uint16_t oflag) {
|
||||
timer_device_t *timer_device = (timer_device_t *)dev;
|
||||
|
||||
uint32_t tmpval;
|
||||
uint32_t compare_count1 = 0;
|
||||
uint32_t compare_count2 = 0;
|
||||
uint32_t compare_count3 = 0;
|
||||
uint32_t reload_val = 0;
|
||||
uint32_t clkval = 0;
|
||||
uint32_t unit = 0;
|
||||
|
||||
/* Disable all interrupt */
|
||||
TIMER_IntMask(timer_device->id, TIMER_INT_ALL, MASK);
|
||||
/* Disable timer before config */
|
||||
TIMER_Disable(timer_device->id);
|
||||
|
||||
/* Configure timer count mode: preload or free run */
|
||||
tmpval = BL_RD_WORD(TIMER_BASE + TIMER_TCMR_OFFSET);
|
||||
tmpval &= (~(1 << (timer_device->id + 1)));
|
||||
tmpval |= (timer_device->cnt_mode << (timer_device->id + 1));
|
||||
|
||||
BL_WR_WORD(TIMER_BASE + TIMER_TCMR_OFFSET, tmpval);
|
||||
|
||||
/* Configure timer preload trigger source */
|
||||
BL_WR_WORD(TIMER_BASE + TIMER_TPLCR2_OFFSET + 4 * timer_device->id, timer_device->trigger);
|
||||
|
||||
if (timer_device->cnt_mode == TIMER_CNT_PRELOAD) {
|
||||
BL_WR_WORD(TIMER_BASE + TIMER_TPLVR2_OFFSET + 4 * timer_device->id, timer_device->reload);
|
||||
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 {
|
||||
}
|
||||
|
||||
compare_count1 = timer_device->timeout1 / (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;
|
||||
|
||||
/* Configure match compare values */
|
||||
if ((compare_count1 < 1) || (compare_count2 < 1) || (compare_count3 < 1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
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_2, compare_count3 - 2);
|
||||
|
||||
/* 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);
|
||||
|
||||
if (oflag & DEVICE_OFLAG_STREAM_TX) {
|
||||
/* Enable timer match interrupt */
|
||||
/* Note: if not enable match interrupt, TIMER_GetMatchStatus will not work
|
||||
and status bit will not set */
|
||||
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_2, UNMASK);
|
||||
}
|
||||
|
||||
if (oflag & DEVICE_OFLAG_INT_TX) {
|
||||
#ifdef BSP_USING_TIMER0
|
||||
if (timer_device->id == TIMER_CH0) {
|
||||
Interrupt_Handler_Register(TIMER_CH0_IRQn, TIMER0_IRQ);
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_TIMER1
|
||||
if (timer_device->id == TIMER_CH1) {
|
||||
Interrupt_Handler_Register(TIMER_CH1_IRQn, TIMER1_IRQ);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* Enable timer */
|
||||
TIMER_Enable(timer_device->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @return int
|
||||
*/
|
||||
int timer_close(struct device *dev) {
|
||||
timer_device_t *timer_device = (timer_device_t *)(dev);
|
||||
TIMER_Disable(timer_device->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param dev
|
||||
* @param cmd
|
||||
* @param args
|
||||
* @return int
|
||||
*/
|
||||
int timer_control(struct device *dev, int cmd, void *args) {
|
||||
timer_device_t *timer_device = (timer_device_t *)dev;
|
||||
|
||||
switch (cmd) {
|
||||
case DEVICE_CTRL_SET_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, UNMASK);
|
||||
}
|
||||
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) {
|
||||
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
|
||||
*
|
||||
* @param index
|
||||
* @param name
|
||||
* @return int
|
||||
*/
|
||||
int timer_register(enum timer_index_type index, const char *name) {
|
||||
struct device *dev;
|
||||
|
||||
if (TIMER_MAX_INDEX == 0) {
|
||||
return -DEVICE_EINVAL;
|
||||
}
|
||||
|
||||
dev = &(timerx_device[index].parent);
|
||||
|
||||
dev->open = timer_open;
|
||||
dev->close = timer_close;
|
||||
dev->control = timer_control;
|
||||
dev->write = timer_write;
|
||||
// dev->read = NULL;
|
||||
|
||||
dev->type = DEVICE_CLASS_TIMER;
|
||||
dev->handle = NULL;
|
||||
|
||||
return device_register(dev, name);
|
||||
}
|
||||
|
||||
void timer_isr(timer_device_t *handle) {
|
||||
uint32_t intId = 0;
|
||||
uint32_t tmpVal = 0;
|
||||
uint32_t tmpAddr = 0;
|
||||
|
||||
if (!handle->parent.callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
intId = BL_RD_WORD(TIMER_BASE + TIMER_TMSR2_OFFSET + 4 * handle->id);
|
||||
tmpAddr = TIMER_BASE + TIMER_TICR2_OFFSET + 4 * handle->id;
|
||||
tmpVal = BL_RD_WORD(tmpAddr);
|
||||
|
||||
/* Comparator 0 match interrupt */
|
||||
if (BL_IS_REG_BIT_SET(intId, TIMER_TMSR_0)) {
|
||||
BL_WR_WORD(tmpAddr, BL_SET_REG_BIT(tmpVal, TIMER_TCLR_0));
|
||||
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 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
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
void TIMER0_IRQ(void) { timer_isr(&timerx_device[TIMER0_INDEX]); }
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_TIMER1
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
*/
|
||||
void TIMER1_IRQ(void) { timer_isr(&timerx_device[TIMER1_INDEX]); }
|
||||
|
||||
#endif
|
||||
@@ -572,23 +572,23 @@ BL_Err_Type I2C_MasterReceiveBlocking(I2C_ID_Type i2cNo, I2C_Transfer_Cfg *cfg)
|
||||
I2C_Init(i2cNo, I2C_READ, cfg);
|
||||
I2C_Enable(i2cNo);
|
||||
timeOut = I2C_FIFO_STATUS_TIMEOUT;
|
||||
|
||||
if (cfg->dataSize == 0 && cfg->subAddrSize == 0) {
|
||||
while (BL_RD_REG(I2C_BASE, I2C_BUS_BUSY)) {
|
||||
timeOut--;
|
||||
|
||||
if (timeOut == 0) {
|
||||
I2C_Disable(i2cNo);
|
||||
MSG((char *)"I2C BSY\r\n");
|
||||
return TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
temp = BL_RD_REG(I2C_BASE, I2C_INT_STS); // TODO this sucks as a workaround
|
||||
if (BL_IS_REG_BIT_SET(temp, I2C_NAK_INT)) {
|
||||
temp = BL_RD_REG(I2C_BASE, I2C_BUS_BUSY);
|
||||
MSG((char *)"I2C NACK\r\n");
|
||||
I2C_Disable(i2cNo);
|
||||
return TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* Read I2C data */
|
||||
while (cfg->dataSize - i >= 4) {
|
||||
timeOut = I2C_FIFO_STATUS_TIMEOUT;
|
||||
|
||||
@@ -42,18 +42,22 @@
|
||||
#define BSP_TIMER0_CLOCK_DIV 22
|
||||
#define BSP_TIMER1_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK
|
||||
#define BSP_TIMER1_CLOCK_DIV 31
|
||||
#define BSP_WDT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_FCLK
|
||||
#define BSP_WDT_CLOCK_DIV 0
|
||||
#define BSP_WDT_CLOCK_SOURCE ROOT_CLOCK_SOURCE_32K_CLK
|
||||
#define BSP_WDT_CLOCK_DIV 32
|
||||
#define BSP_PWM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
|
||||
#define BSP_PWM_CLOCK_DIV 22
|
||||
#define BSP_IR_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
|
||||
#define BSP_IR_CLOCK_DIV 0
|
||||
|
||||
#define BSP_ADC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
|
||||
#define BSP_ADC_CLOCK_DIV 255
|
||||
#define BSP_ADC_CLOCK_DIV 16
|
||||
|
||||
#define BSP_DAC_CLOCK_SOURCE ROOT_CLOCK_SOURCE_AUPLL_24000000_HZ
|
||||
#define BSP_DAC_CLOCK_DIV 2
|
||||
|
||||
#define BSP_CAM_CLOCK_SOURCE ROOT_CLOCK_SOURCE_PLL_96M
|
||||
#define BSP_CAM_CLOCK_DIV 3
|
||||
|
||||
#define BSP_QDEC_KEYSCAN_CLOCK_SOURCE ROOT_CLOCK_SOURCE_XCLK
|
||||
#define BSP_QDEC_KEYSCAN_CLOCK_DIV 31
|
||||
|
||||
|
||||
Reference in New Issue
Block a user