Handle APB frequency change (#2250)

* Add APB change callbacks and move cpu code to own file

* Properly set esp_timer and FreeRTOS tick dividers

* Improve updated devisors

* No need to update REF_TICK yet

* Add initial handling for UART baud change

* fix uartWriteBuf and uartDetectBaudrate

* trigger callbacks even when APB did not change

* toggle UART ISR on CPU change

* add XTAL freq getter and add cpu freq validation

* Support CPU frequency changes in I2C (#2287)

**esp32-hal-i2c.c**
* add callback for cpu frequency changes
* adjust fifo thresholds based on cpu frequency and i2c bus frequency
* reduce i2c bus frequency if differential is too small
**Wire.h**
* version to 1.1.0

* Implement clock change for the other peripherals

* remove bad CPU clock values from the menu

* Add note to CPU freqs that support WiFi and BT
This commit is contained in:
Me No Dev
2019-01-09 10:07:54 +01:00
committed by GitHub
parent ff18a211e4
commit 2fd39b1aff
13 changed files with 484 additions and 113 deletions

View File

@ -184,6 +184,18 @@ bool timerAlarmEnabled(hw_timer_t *timer){
return timer->dev->config.alarm_en;
}
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
hw_timer_t * timer = (hw_timer_t *)arg;
if(ev_type == APB_BEFORE_CHANGE){
timer->dev->config.enable = 0;
} else {
old_apb /= 1000000;
new_apb /= 1000000;
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb;
timer->dev->config.enable = 1;
}
}
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
if(num > 3){
return NULL;
@ -205,12 +217,14 @@ hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
timerAttachInterrupt(timer, NULL, false);
timerWrite(timer, 0);
timer->dev->config.enable = 1;
addApbChangeCallback(timer, _on_apb_change);
return timer;
}
void timerEnd(hw_timer_t *timer){
timer->dev->config.enable = 0;
timerAttachInterrupt(timer, NULL, false);
removeApbChangeCallback(timer, _on_apb_change);
}
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
@ -271,23 +285,23 @@ void timerDetachInterrupt(hw_timer_t *timer){
uint64_t timerReadMicros(hw_timer_t *timer){
uint64_t timer_val = timerRead(timer);
uint16_t div = timerGetDivider(timer);
return timer_val * div / 80;
return timer_val * div / (getApbFrequency() / 1000000);
}
double timerReadSeconds(hw_timer_t *timer){
uint64_t timer_val = timerRead(timer);
uint16_t div = timerGetDivider(timer);
return (double)timer_val * div / 80000000;
return (double)timer_val * div / getApbFrequency();
}
uint64_t timerAlarmReadMicros(hw_timer_t *timer){
uint64_t timer_val = timerAlarmRead(timer);
uint16_t div = timerGetDivider(timer);
return timer_val * div / 80;
return timer_val * div / (getApbFrequency() / 1000000);
}
double timerAlarmReadSeconds(hw_timer_t *timer){
uint64_t timer_val = timerAlarmRead(timer);
uint16_t div = timerGetDivider(timer);
return (double)timer_val * div / 80000000;
return (double)timer_val * div / getApbFrequency();
}