Skip to content

Commit 2fd39b1

Browse files
authoredJan 9, 2019
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
1 parent ff18a21 commit 2fd39b1

13 files changed

+484
-113
lines changed
 

‎CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(CORE_SRCS
33
cores/esp32/cbuf.cpp
44
cores/esp32/esp32-hal-adc.c
55
cores/esp32/esp32-hal-bt.c
6+
cores/esp32/esp32-hal-cpu.c
67
cores/esp32/esp32-hal-dac.c
78
cores/esp32/esp32-hal-gpio.c
89
cores/esp32/esp32-hal-i2c.c

‎boards.txt

+4-16
Original file line numberDiff line numberDiff line change
@@ -50,34 +50,22 @@ esp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
5050
esp32.menu.PartitionScheme.fatflash=16M Fat
5151
esp32.menu.PartitionScheme.fatflash.build.partitions=ffat
5252

53-
esp32.menu.CPUFreq.240=240MHz
53+
esp32.menu.CPUFreq.240=240MHz (WiFi/BT)
5454
esp32.menu.CPUFreq.240.build.f_cpu=240000000L
55-
esp32.menu.CPUFreq.160=160MHz
55+
esp32.menu.CPUFreq.160=160MHz (WiFi/BT)
5656
esp32.menu.CPUFreq.160.build.f_cpu=160000000L
57-
esp32.menu.CPUFreq.80=80MHz
57+
esp32.menu.CPUFreq.80=80MHz (WiFi/BT)
5858
esp32.menu.CPUFreq.80.build.f_cpu=80000000L
5959
esp32.menu.CPUFreq.40=40MHz (40MHz XTAL)
6060
esp32.menu.CPUFreq.40.build.f_cpu=40000000L
6161
esp32.menu.CPUFreq.26=26MHz (26MHz XTAL)
6262
esp32.menu.CPUFreq.26.build.f_cpu=26000000L
6363
esp32.menu.CPUFreq.20=20MHz (40MHz XTAL)
6464
esp32.menu.CPUFreq.20.build.f_cpu=20000000L
65-
esp32.menu.CPUFreq.13=13MHz
65+
esp32.menu.CPUFreq.13=13MHz (26MHz XTAL)
6666
esp32.menu.CPUFreq.13.build.f_cpu=13000000L
6767
esp32.menu.CPUFreq.10=10MHz (40MHz XTAL)
6868
esp32.menu.CPUFreq.10.build.f_cpu=10000000L
69-
esp32.menu.CPUFreq.8=8MHz (40MHz XTAL)
70-
esp32.menu.CPUFreq.8.build.f_cpu=8000000L
71-
esp32.menu.CPUFreq.5=5MHz
72-
esp32.menu.CPUFreq.5.build.f_cpu=5000000L
73-
esp32.menu.CPUFreq.4=4MHz
74-
esp32.menu.CPUFreq.4.build.f_cpu=4000000L
75-
esp32.menu.CPUFreq.3=3MHz
76-
esp32.menu.CPUFreq.3.build.f_cpu=3000000L
77-
esp32.menu.CPUFreq.2=2MHz
78-
esp32.menu.CPUFreq.2.build.f_cpu=2000000L
79-
esp32.menu.CPUFreq.1=1MHz
80-
esp32.menu.CPUFreq.1.build.f_cpu=1000000L
8169

8270
esp32.menu.FlashMode.qio=QIO
8371
esp32.menu.FlashMode.qio.build.flash_mode=dio

‎cores/esp32/esp32-hal-cpu.c

+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "sdkconfig.h"
16+
#include "freertos/FreeRTOS.h"
17+
#include "freertos/semphr.h"
18+
#include "freertos/task.h"
19+
#include "freertos/xtensa_timer.h"
20+
#include "esp_attr.h"
21+
#include "esp_log.h"
22+
#include "soc/rtc.h"
23+
#include "soc/rtc_cntl_reg.h"
24+
#include "rom/rtc.h"
25+
#include "soc/apb_ctrl_reg.h"
26+
#include "esp32-hal.h"
27+
#include "esp32-hal-cpu.h"
28+
29+
typedef struct apb_change_cb_s {
30+
struct apb_change_cb_s * next;
31+
void * arg;
32+
apb_change_cb_t cb;
33+
} apb_change_t;
34+
35+
const uint32_t MHZ = 1000000;
36+
37+
static apb_change_t * apb_change_callbacks = NULL;
38+
static xSemaphoreHandle apb_change_lock = NULL;
39+
40+
static void initApbChangeCallback(){
41+
static volatile bool initialized = false;
42+
if(!initialized){
43+
initialized = true;
44+
apb_change_lock = xSemaphoreCreateMutex();
45+
if(!apb_change_lock){
46+
initialized = false;
47+
}
48+
}
49+
}
50+
51+
static void triggerApbChangeCallback(apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
52+
initApbChangeCallback();
53+
xSemaphoreTake(apb_change_lock, portMAX_DELAY);
54+
apb_change_t * r = apb_change_callbacks;
55+
while(r != NULL){
56+
r->cb(r->arg, ev_type, old_apb, new_apb);
57+
r=r->next;
58+
}
59+
xSemaphoreGive(apb_change_lock);
60+
}
61+
62+
bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
63+
initApbChangeCallback();
64+
apb_change_t * c = (apb_change_t*)malloc(sizeof(apb_change_t));
65+
if(!c){
66+
log_e("Callback Object Malloc Failed");
67+
return false;
68+
}
69+
c->next = NULL;
70+
c->arg = arg;
71+
c->cb = cb;
72+
xSemaphoreTake(apb_change_lock, portMAX_DELAY);
73+
if(apb_change_callbacks == NULL){
74+
apb_change_callbacks = c;
75+
} else {
76+
apb_change_t * r = apb_change_callbacks;
77+
if(r->cb != cb || r->arg != arg){
78+
while(r->next){
79+
r = r->next;
80+
if(r->cb == cb && r->arg == arg){
81+
free(c);
82+
goto unlock_and_exit;
83+
}
84+
}
85+
r->next = c;
86+
}
87+
}
88+
unlock_and_exit:
89+
xSemaphoreGive(apb_change_lock);
90+
return true;
91+
}
92+
93+
bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
94+
initApbChangeCallback();
95+
xSemaphoreTake(apb_change_lock, portMAX_DELAY);
96+
apb_change_t * r = apb_change_callbacks;
97+
if(r == NULL){
98+
xSemaphoreGive(apb_change_lock);
99+
return false;
100+
}
101+
if(r->cb == cb && r->arg == arg){
102+
apb_change_callbacks = r->next;
103+
free(r);
104+
} else {
105+
while(r->next && (r->next->cb != cb || r->next->arg != arg)){
106+
r = r->next;
107+
}
108+
if(r->next == NULL || r->next->cb != cb || r->next->arg != arg){
109+
xSemaphoreGive(apb_change_lock);
110+
return false;
111+
}
112+
apb_change_t * c = r->next;
113+
r->next = c->next;
114+
free(c);
115+
}
116+
xSemaphoreGive(apb_change_lock);
117+
return true;
118+
}
119+
120+
static uint32_t calculateApb(rtc_cpu_freq_config_t * conf){
121+
if(conf->freq_mhz >= 80){
122+
return 80 * MHZ;
123+
}
124+
return (conf->source_freq_mhz * MHZ) / conf->div;
125+
}
126+
127+
void esp_timer_impl_update_apb_freq(uint32_t apb_ticks_per_us); //private in IDF
128+
129+
bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
130+
rtc_cpu_freq_config_t conf, cconf;
131+
uint32_t capb, apb;
132+
//Get XTAL Frequency and calculate min CPU MHz
133+
rtc_xtal_freq_t xtal = rtc_clk_xtal_freq_get();
134+
uint32_t min_cpu_mhz = 10;
135+
if(xtal > RTC_XTAL_FREQ_AUTO){
136+
if(xtal < RTC_XTAL_FREQ_40M) {
137+
min_cpu_mhz = xtal / 2; //13Mhz for 26Mhz XTAL
138+
if(cpu_freq_mhz <= xtal && cpu_freq_mhz != xtal && cpu_freq_mhz != (xtal/2)){
139+
log_e("Bad frequency: %u MHz! Options are: 240, 160, 80, %u and %u MHz", cpu_freq_mhz, xtal, xtal/2);
140+
return false;
141+
}
142+
} else if(cpu_freq_mhz <= xtal && cpu_freq_mhz != xtal && cpu_freq_mhz != (xtal/2) && cpu_freq_mhz != (xtal/4)){
143+
log_e("Bad frequency: %u MHz! Options are: 240, 160, 80, %u, %u and %u MHz", cpu_freq_mhz, xtal, xtal/2, xtal/4);
144+
return false;
145+
}
146+
}
147+
if(cpu_freq_mhz > xtal && cpu_freq_mhz != 240 && cpu_freq_mhz != 160 && cpu_freq_mhz != 80){
148+
if(xtal >= RTC_XTAL_FREQ_40M){
149+
log_e("Bad frequency: %u MHz! Options are: 240, 160, 80, %u, %u and %u MHz", cpu_freq_mhz, xtal, xtal/2, xtal/4);
150+
} else {
151+
log_e("Bad frequency: %u MHz! Options are: 240, 160, 80, %u and %u MHz", cpu_freq_mhz, xtal, xtal/2);
152+
}
153+
return false;
154+
}
155+
//Get current CPU clock configuration
156+
rtc_clk_cpu_freq_get_config(&cconf);
157+
//return if frequency has not changed
158+
if(cconf.freq_mhz == cpu_freq_mhz){
159+
return true;
160+
}
161+
//Get configuration for the new CPU frequency
162+
if(!rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &conf)){
163+
log_e("CPU clock could not be set to %u MHz", cpu_freq_mhz);
164+
return false;
165+
}
166+
//Current APB
167+
capb = calculateApb(&cconf);
168+
//New APB
169+
apb = calculateApb(&conf);
170+
log_d("%s: %u / %u = %u Mhz, APB: %u Hz", (conf.source == RTC_CPU_FREQ_SRC_PLL)?"PLL":((conf.source == RTC_CPU_FREQ_SRC_APLL)?"APLL":((conf.source == RTC_CPU_FREQ_SRC_XTAL)?"XTAL":"8M")), conf.source_freq_mhz, conf.div, conf.freq_mhz, apb);
171+
//Call peripheral functions before the APB change
172+
if(apb_change_callbacks){
173+
triggerApbChangeCallback(APB_BEFORE_CHANGE, capb, apb);
174+
}
175+
//Make the frequency change
176+
rtc_clk_cpu_freq_set_config_fast(&conf);
177+
if(capb != apb){
178+
//Update REF_TICK (uncomment if REF_TICK is different than 1MHz)
179+
//if(conf.freq_mhz < 80){
180+
// ESP_REG(APB_CTRL_XTAL_TICK_CONF_REG) = conf.freq_mhz / (REF_CLK_FREQ / MHZ) - 1;
181+
//}
182+
//Update APB Freq REG
183+
rtc_clk_apb_freq_update(apb);
184+
//Update esp_timer divisor
185+
esp_timer_impl_update_apb_freq(apb / MHZ);
186+
}
187+
//Update FreeRTOS Tick Divisor
188+
uint32_t fcpu = (conf.freq_mhz >= 80)?(conf.freq_mhz * MHZ):(apb);
189+
_xt_tick_divisor = fcpu / XT_TICK_PER_SEC;
190+
//Call peripheral functions after the APB change
191+
if(apb_change_callbacks){
192+
triggerApbChangeCallback(APB_AFTER_CHANGE, capb, apb);
193+
}
194+
return true;
195+
}
196+
197+
uint32_t getCpuFrequencyMhz(){
198+
rtc_cpu_freq_config_t conf;
199+
rtc_clk_cpu_freq_get_config(&conf);
200+
return conf.freq_mhz;
201+
}
202+
203+
uint32_t getXtalFrequencyMhz(){
204+
return rtc_clk_xtal_freq_get();
205+
}
206+
207+
uint32_t getApbFrequency(){
208+
rtc_cpu_freq_config_t conf;
209+
rtc_clk_cpu_freq_get_config(&conf);
210+
return calculateApb(&conf);
211+
}

‎cores/esp32/esp32-hal-cpu.h

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef _ESP32_HAL_CPU_H_
16+
#define _ESP32_HAL_CPU_H_
17+
18+
#ifdef __cplusplus
19+
extern "C" {
20+
#endif
21+
22+
#include <stdint.h>
23+
#include <stdbool.h>
24+
#include <stdlib.h>
25+
26+
typedef enum { APB_BEFORE_CHANGE, APB_AFTER_CHANGE } apb_change_ev_t;
27+
28+
typedef void (* apb_change_cb_t)(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb);
29+
30+
bool addApbChangeCallback(void * arg, apb_change_cb_t cb);
31+
bool removeApbChangeCallback(void * arg, apb_change_cb_t cb);
32+
33+
//function takes the following frequencies as valid values:
34+
// 240, 160, 80 <<< For all XTAL types
35+
// 40, 20, 10 <<< For 40MHz XTAL
36+
// 26, 13 <<< For 26MHz XTAL
37+
// 24, 12 <<< For 24MHz XTAL
38+
bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz);
39+
40+
uint32_t getCpuFrequencyMhz(); // In MHz
41+
uint32_t getXtalFrequencyMhz(); // In MHz
42+
uint32_t getApbFrequency(); // In Hz
43+
44+
#ifdef __cplusplus
45+
}
46+
#endif
47+
48+
#endif /* _ESP32_HAL_CPU_H_ */

‎cores/esp32/esp32-hal-i2c.c

+67-16
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include "soc/i2c_struct.h"
2525
#include "soc/dport_reg.h"
2626
#include "esp_attr.h"
27-
27+
#include "esp32-hal-cpu.h" // cpu clock change support 31DEC2018
2828
//#define I2C_DEV(i) (volatile i2c_dev_t *)((i)?DR_REG_I2C1_EXT_BASE:DR_REG_I2C_EXT_BASE)
2929
//#define I2C_DEV(i) ((i2c_dev_t *)(REG_I2C_BASE(i)))
3030
#define I2C_SCL_IDX(p) ((p==0)?I2CEXT0_SCL_OUT_IDX:((p==1)?I2CEXT1_SCL_OUT_IDX:0))
@@ -206,8 +206,8 @@ static i2c_t _i2c_bus_array[2] = {
206206
{(volatile i2c_dev_t *)(DR_REG_I2C1_EXT_BASE_FIXED), 1, -1, -1,I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0}
207207
};
208208
#else
209-
#define I2C_MUTEX_LOCK() do {} while (xSemaphoreTake(i2c->lock, portMAX_DELAY) != pdPASS)
210-
#define I2C_MUTEX_UNLOCK() xSemaphoreGive(i2c->lock)
209+
#define I2C_MUTEX_LOCK() do {} while (xSemaphoreTakeRecursive(i2c->lock, portMAX_DELAY) != pdPASS)
210+
#define I2C_MUTEX_UNLOCK() xSemaphoreGiveRecursive(i2c->lock)
211211

212212
static i2c_t _i2c_bus_array[2] = {
213213
{(volatile i2c_dev_t *)(DR_REG_I2C_EXT_BASE_FIXED), NULL, 0, -1, -1, I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0,0},
@@ -445,6 +445,39 @@ static void IRAM_ATTR i2cTriggerDumps(i2c_t * i2c, uint8_t trigger, const char l
445445
}
446446
// end of debug support routines
447447

448+
/* Start of CPU Clock change Support
449+
*/
450+
451+
static void i2cApbChangeCallback(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
452+
i2c_t* i2c = (i2c_t*) arg; // recover data
453+
if(i2c == NULL) { // point to peripheral control block does not exits
454+
return false;
455+
}
456+
uint32_t oldFreq=0;
457+
switch(ev_type){
458+
case APB_BEFORE_CHANGE :
459+
if(new_apb < 3000000) {// too slow
460+
log_e("apb speed %d too slow",new_apb);
461+
break;
462+
}
463+
I2C_MUTEX_LOCK(); // lock will spin until current transaction is completed
464+
break;
465+
case APB_AFTER_CHANGE :
466+
oldFreq = (i2c->dev->scl_low_period.period+i2c->dev->scl_high_period.period); //read old apbCycles
467+
if(oldFreq>0) { // was configured with value
468+
oldFreq = old_apb / oldFreq;
469+
i2cSetFrequency(i2c,oldFreq);
470+
}
471+
I2C_MUTEX_UNLOCK();
472+
break;
473+
default :
474+
log_e("unk ev %u",ev_type);
475+
I2C_MUTEX_UNLOCK();
476+
}
477+
return;
478+
}
479+
/* End of CPU Clock change Support
480+
*/
448481
static void IRAM_ATTR i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bool ack_val, bool ack_exp, bool ack_check)
449482
{
450483
I2C_COMMAND_t cmd;
@@ -1221,6 +1254,12 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
12211254
I2C_MUTEX_UNLOCK();
12221255
return I2C_ERROR_MEMORY;
12231256
}
1257+
if( !addApbChangeCallback( i2c, i2cApbChangeCallback)) {
1258+
log_e("install apb Callback failed");
1259+
I2C_MUTEX_UNLOCK();
1260+
return I2C_ERROR_DEV;
1261+
}
1262+
12241263
}
12251264
//hang until it completes.
12261265

@@ -1352,6 +1391,9 @@ static void i2cReleaseISR(i2c_t * i2c)
13521391
if(i2c->intr_handle) {
13531392
esp_intr_free(i2c->intr_handle);
13541393
i2c->intr_handle=NULL;
1394+
if (!removeApbChangeCallback( i2c, i2cApbChangeCallback)) {
1395+
log_e("unable to release apbCallback");
1396+
}
13551397
}
13561398
}
13571399

@@ -1437,15 +1479,15 @@ i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda)
14371479
* PUBLIC API
14381480
* */
14391481
// 24Nov17 only supports Master Mode
1440-
i2c_t * i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) //before this is called, pins should be detached, else glitch
1441-
{
1482+
i2c_t * i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) {
14421483
log_v("num=%d sda=%d scl=%d freq=%d",i2c_num, sda, scl, frequency);
14431484
if(i2c_num > 1) {
14441485
return NULL;
14451486
}
14461487

14471488
i2c_t * i2c = &_i2c_bus_array[i2c_num];
14481489

1490+
// pins should be detached, else glitch
14491491
if(i2c->sda >= 0){
14501492
i2cDetachSDA(i2c, i2c->sda);
14511493
}
@@ -1457,7 +1499,7 @@ i2c_t * i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) //b
14571499

14581500
#if !CONFIG_DISABLE_HAL_LOCKS
14591501
if(i2c->lock == NULL) {
1460-
i2c->lock = xSemaphoreCreateMutex();
1502+
i2c->lock = xSemaphoreCreateRecursiveMutex();
14611503
if(i2c->lock == NULL) {
14621504
return NULL;
14631505
}
@@ -1604,7 +1646,8 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, b
16041646
return last_error;
16051647
}
16061648

1607-
#define MIN_I2C_CLKS 100
1649+
#define MIN_I2C_CLKS 100 // minimum ratio between cpu and i2c Bus clocks
1650+
#define INTERRUPT_CYCLE_OVERHEAD 16000 // number of cpu clocks necessary to respond to interrupt
16081651
i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
16091652
{
16101653
if(i2c == NULL) {
@@ -1614,17 +1657,18 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
16141657
uint32_t period = (apb/clk_speed) / 2;
16151658

16161659
if((apb/8192 > clk_speed)||(apb/MIN_I2C_CLKS < clk_speed)){ //out of bounds
1617-
log_w("i2c freq(%d) out of bounds.vs APB Clock(%d), min=%d, max=%d",clk_speed,apb,(apb/8192),(apb/MIN_I2C_CLKS));
1660+
log_d("i2c freq(%d) out of bounds.vs APB Clock(%d), min=%d, max=%d",clk_speed,apb,(apb/8192),(apb/MIN_I2C_CLKS));
16181661
}
16191662
if(period < (MIN_I2C_CLKS/2) ){
16201663
period = (MIN_I2C_CLKS/2);
16211664
clk_speed = apb/(period*2);
1622-
log_w("APB Freq too slow, Reducing i2c Freq to %d Hz",clk_speed);
1665+
log_d("APB Freq too slow, Reducing i2c Freq to %d Hz",clk_speed);
16231666
} else if ( period> 4095) {
16241667
period = 4095;
16251668
clk_speed = apb/(period*2);
1626-
log_w("APB Freq too fast, Increasing i2c Freq to %d Hz",clk_speed);
1669+
log_d("APB Freq too fast, Increasing i2c Freq to %d Hz",clk_speed);
16271670
}
1671+
log_v("freq=%dHz",clk_speed);
16281672

16291673
uint32_t halfPeriod = period/2;
16301674
uint32_t quarterPeriod = period/4;
@@ -1633,14 +1677,19 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
16331677

16341678
I2C_FIFO_CONF_t f;
16351679

1636-
// Adjust Fifo thresholds based on frequency
16371680
f.val = i2c->dev->fifo_conf.val;
1638-
uint32_t a = (clk_speed / 50000L )+1;
1639-
if (a > 24) a=24;
1640-
f.rx_fifo_full_thrhd = 32 - a;
1641-
f.tx_fifo_empty_thrhd = a;
1681+
/* Adjust Fifo thresholds based on differential between cpu frequency and bus clock.
1682+
The fifo_delta is calculated such that at least INTERRUPT_CYCLE_OVERHEAD cpu clocks are
1683+
available when a Fifo interrupt is triggered. This allows enough room in the Fifo so that
1684+
interrupt latency does not cause a Fifo overflow/underflow event.
1685+
*/
1686+
log_v("cpu Freq=%dMhz, i2c Freq=%dHz",getCpuFrequencyMhz(),clk_speed);
1687+
uint32_t fifo_delta = (INTERRUPT_CYCLE_OVERHEAD/((getCpuFrequencyMhz()*1000000 / clk_speed)*10))+1;
1688+
if (fifo_delta > 24) fifo_delta=24;
1689+
f.rx_fifo_full_thrhd = 32 - fifo_delta;
1690+
f.tx_fifo_empty_thrhd = fifo_delta;
16421691
i2c->dev->fifo_conf.val = f.val; // set thresholds
1643-
log_v("Fifo threshold=%d",a);
1692+
log_v("Fifo delta=%d",fifo_delta);
16441693

16451694
//the clock num during SCL is low level
16461695
i2c->dev->scl_low_period.period = period;
@@ -1696,6 +1745,8 @@ uint32_t i2cGetStatus(i2c_t * i2c){
16961745
}
16971746
else return 0;
16981747
}
1748+
1749+
16991750
/* todo
17001751
22JUL18
17011752
need to add multi-thread capability, use dq.queueEvent as the group marker. When multiple threads

‎cores/esp32/esp32-hal-ledc.c

+29
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,33 @@ xSemaphoreHandle _ledc_sys_lock;
5353
#define LEDC_CHAN(g,c) LEDC.channel_group[(g)].channel[(c)]
5454
#define LEDC_TIMER(g,t) LEDC.timer_group[(g)].timer[(t)]
5555

56+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
57+
if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){
58+
uint32_t iarg = (uint32_t)arg;
59+
uint8_t chan = iarg;
60+
uint8_t group=(chan/8), timer=((chan/2)%4);
61+
old_apb /= 1000000;
62+
new_apb /= 1000000;
63+
if(LEDC_TIMER(group, timer).conf.tick_sel){
64+
LEDC_MUTEX_LOCK();
65+
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
66+
uint32_t div_num = (new_apb * old_div) / old_apb;
67+
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
68+
new_apb = REF_CLK_FREQ / 1000000;
69+
div_num = (new_apb * old_div) / old_apb;
70+
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
71+
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
72+
}
73+
LEDC_TIMER(group, timer).conf.tick_sel = 0;
74+
} else if(div_num < 256) {
75+
div_num = 256;//highest clock possible
76+
}
77+
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
78+
LEDC_MUTEX_UNLOCK();
79+
}
80+
}
81+
}
82+
5683
//uint32_t frequency = (80MHz or 1MHz)/((div_num / 256.0)*(1 << bit_num));
5784
static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, bool apb_clk)
5885
{
@@ -78,6 +105,8 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
78105
LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset.
79106
LEDC_TIMER(group, timer).conf.rst = 0;
80107
LEDC_MUTEX_UNLOCK();
108+
uint32_t iarg = chan;
109+
addApbChangeCallback((void*)iarg, _on_apb_change);
81110
}
82111

83112
//max div_num 0x3FFFF (262143)

‎cores/esp32/esp32-hal-misc.c

+7-42
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <sys/time.h>
2828
#include "soc/rtc.h"
2929
#include "soc/rtc_cntl_reg.h"
30+
#include "soc/apb_ctrl_reg.h"
3031
#include "rom/rtc.h"
3132
#include "esp_task_wdt.h"
3233
#include "esp32-hal.h"
@@ -100,57 +101,19 @@ void disableCore1WDT(){
100101
}
101102
#endif
102103

103-
static uint32_t _cpu_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
104-
static uint32_t _sys_time_multiplier = 1;
105-
106-
bool setCpuFrequency(uint32_t cpu_freq_mhz){
107-
rtc_cpu_freq_config_t conf, cconf;
108-
rtc_clk_cpu_freq_get_config(&cconf);
109-
if(cconf.freq_mhz == cpu_freq_mhz && _cpu_freq_mhz == cpu_freq_mhz){
110-
return true;
111-
}
112-
if(!rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &conf)){
113-
log_e("CPU clock could not be set to %u MHz", cpu_freq_mhz);
114-
return false;
115-
}
116-
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
117-
log_i("%s: %u / %u = %u Mhz", (conf.source == RTC_CPU_FREQ_SRC_PLL)?"PLL":((conf.source == RTC_CPU_FREQ_SRC_APLL)?"APLL":((conf.source == RTC_CPU_FREQ_SRC_XTAL)?"XTAL":"8M")), conf.source_freq_mhz, conf.div, conf.freq_mhz);
118-
delay(10);
119-
#endif
120-
rtc_clk_cpu_freq_set_config_fast(&conf);
121-
_cpu_freq_mhz = conf.freq_mhz;
122-
_sys_time_multiplier = 80000000 / getApbFrequency();
123-
return true;
124-
}
125-
126-
uint32_t getCpuFrequency(){
127-
rtc_cpu_freq_config_t conf;
128-
rtc_clk_cpu_freq_get_config(&conf);
129-
return conf.freq_mhz;
130-
}
131-
132-
uint32_t getApbFrequency(){
133-
rtc_cpu_freq_config_t conf;
134-
rtc_clk_cpu_freq_get_config(&conf);
135-
if(conf.freq_mhz >= 80){
136-
return 80000000;
137-
}
138-
return (conf.source_freq_mhz * 1000000) / conf.div;
139-
}
140-
141104
unsigned long IRAM_ATTR micros()
142105
{
143-
return (unsigned long) (esp_timer_get_time()) * _sys_time_multiplier;
106+
return (unsigned long) (esp_timer_get_time());
144107
}
145108

146109
unsigned long IRAM_ATTR millis()
147110
{
148-
return (unsigned long) (micros() / 1000);
111+
return (unsigned long) (esp_timer_get_time() / 1000);
149112
}
150113

151114
void delay(uint32_t ms)
152115
{
153-
vTaskDelay((ms * _cpu_freq_mhz) / (portTICK_PERIOD_MS * 240));
116+
vTaskDelay(ms / portTICK_PERIOD_MS);
154117
}
155118

156119
void IRAM_ATTR delayMicroseconds(uint32_t us)
@@ -183,8 +146,10 @@ bool btInUse(){ return false; }
183146

184147
void initArduino()
185148
{
149+
//init proper ref tick value for PLL (uncomment if REF_TICK is different than 1MHz)
150+
//ESP_REG(APB_CTRL_PLL_TICK_CONF_REG) = APB_CLK_FREQ / REF_CLK_FREQ - 1;
186151
#ifdef F_CPU
187-
setCpuFrequency(F_CPU/1000000L);
152+
setCpuFrequencyMhz(F_CPU/1000000);
188153
#endif
189154
#if CONFIG_SPIRAM_SUPPORT
190155
psramInit();

‎cores/esp32/esp32-hal-sigmadelta.c

+22
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@
3131
xSemaphoreHandle _sd_sys_lock;
3232
#endif
3333

34+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
35+
if(old_apb == new_apb){
36+
return;
37+
}
38+
uint32_t iarg = (uint32_t)arg;
39+
uint8_t channel = iarg;
40+
if(ev_type == APB_BEFORE_CHANGE){
41+
SIGMADELTA.cg.clk_en = 0;
42+
} else {
43+
old_apb /= 1000000;
44+
new_apb /= 1000000;
45+
SD_MUTEX_LOCK();
46+
uint32_t old_prescale = SIGMADELTA.channel[channel].prescale + 1;
47+
SIGMADELTA.channel[channel].prescale = ((new_apb * old_prescale) / old_apb) - 1;
48+
SIGMADELTA.cg.clk_en = 0;
49+
SIGMADELTA.cg.clk_en = 1;
50+
SD_MUTEX_UNLOCK();
51+
}
52+
}
53+
3454
uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-312500
3555
{
3656
if(channel > 7) {
@@ -53,6 +73,8 @@ uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-31
5373
SIGMADELTA.cg.clk_en = 0;
5474
SIGMADELTA.cg.clk_en = 1;
5575
SD_MUTEX_UNLOCK();
76+
uint32_t iarg = channel;
77+
addApbChangeCallback((void*)iarg, _on_apb_change);
5678
return apb_freq/((prescale + 1) * 256);
5779
}
5880

‎cores/esp32/esp32-hal-spi.c

+29-15
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,18 @@ void spiSetBitOrder(spi_t * spi, uint8_t bitOrder)
372372
SPI_MUTEX_UNLOCK();
373373
}
374374

375+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb)
376+
{
377+
spi_t * spi = (spi_t *)arg;
378+
if(ev_type == APB_BEFORE_CHANGE){
379+
SPI_MUTEX_LOCK();
380+
while(spi->dev->cmd.usr);
381+
} else {
382+
spi->dev->clock.val = spiFrequencyToClockDiv(old_apb / ((spi->dev->clock.clkdiv_pre + 1) * (spi->dev->clock.clkcnt_n + 1)));
383+
SPI_MUTEX_UNLOCK();
384+
}
385+
}
386+
375387
void spiStopBus(spi_t * spi)
376388
{
377389
if(!spi) {
@@ -388,6 +400,7 @@ void spiStopBus(spi_t * spi)
388400
spi->dev->ctrl2.val = 0;
389401
spi->dev->clock.val = 0;
390402
SPI_MUTEX_UNLOCK();
403+
removeApbChangeCallback(spi, _on_apb_change);
391404
}
392405

393406
spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder)
@@ -434,6 +447,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
434447
}
435448
SPI_MUTEX_UNLOCK();
436449

450+
addApbChangeCallback(spi, _on_apb_change);
437451
return spi;
438452
}
439453

@@ -1008,17 +1022,17 @@ void IRAM_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, size_t len){
10081022
* */
10091023

10101024
typedef union {
1011-
uint32_t regValue;
1025+
uint32_t value;
10121026
struct {
1013-
unsigned regL :6;
1014-
unsigned regH :6;
1015-
unsigned regN :6;
1016-
unsigned regPre :13;
1017-
unsigned regEQU :1;
1027+
uint32_t clkcnt_l: 6; /*it must be equal to spi_clkcnt_N.*/
1028+
uint32_t clkcnt_h: 6; /*it must be floor((spi_clkcnt_N+1)/2-1).*/
1029+
uint32_t clkcnt_n: 6; /*it is the divider of spi_clk. So spi_clk frequency is system/(spi_clkdiv_pre+1)/(spi_clkcnt_N+1)*/
1030+
uint32_t clkdiv_pre: 13; /*it is pre-divider of spi_clk.*/
1031+
uint32_t clk_equ_sysclk: 1; /*1: spi_clk is eqaul to system 0: spi_clk is divided from system clock.*/
10181032
};
10191033
} spiClk_t;
10201034

1021-
#define ClkRegToFreq(reg) (apb_freq / (((reg)->regPre + 1) * ((reg)->regN + 1)))
1035+
#define ClkRegToFreq(reg) (apb_freq / (((reg)->clkdiv_pre + 1) * ((reg)->clkcnt_n + 1)))
10221036

10231037
uint32_t spiClockDivToFrequency(uint32_t clockDiv)
10241038
{
@@ -1038,7 +1052,7 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
10381052
const spiClk_t minFreqReg = { 0x7FFFF000 };
10391053
uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg);
10401054
if(freq < minFreq) {
1041-
return minFreqReg.regValue;
1055+
return minFreqReg.value;
10421056
}
10431057

10441058
uint8_t calN = 1;
@@ -1051,18 +1065,18 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
10511065
int32_t calPre;
10521066
int8_t calPreVari = -2;
10531067

1054-
reg.regN = calN;
1068+
reg.clkcnt_n = calN;
10551069

10561070
while(calPreVari++ <= 1) {
1057-
calPre = (((apb_freq / (reg.regN + 1)) / freq) - 1) + calPreVari;
1071+
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
10581072
if(calPre > 0x1FFF) {
1059-
reg.regPre = 0x1FFF;
1073+
reg.clkdiv_pre = 0x1FFF;
10601074
} else if(calPre <= 0) {
1061-
reg.regPre = 0;
1075+
reg.clkdiv_pre = 0;
10621076
} else {
1063-
reg.regPre = calPre;
1077+
reg.clkdiv_pre = calPre;
10641078
}
1065-
reg.regL = ((reg.regN + 1) / 2);
1079+
reg.clkcnt_l = ((reg.clkcnt_n + 1) / 2);
10661080
calFreq = ClkRegToFreq(&reg);
10671081
if(calFreq == (int32_t) freq) {
10681082
memcpy(&bestReg, &reg, sizeof(bestReg));
@@ -1079,6 +1093,6 @@ uint32_t spiFrequencyToClockDiv(uint32_t freq)
10791093
}
10801094
calN++;
10811095
}
1082-
return bestReg.regValue;
1096+
return bestReg.value;
10831097
}
10841098

‎cores/esp32/esp32-hal-timer.c

+18-4
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,18 @@ bool timerAlarmEnabled(hw_timer_t *timer){
184184
return timer->dev->config.alarm_en;
185185
}
186186

187+
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
188+
hw_timer_t * timer = (hw_timer_t *)arg;
189+
if(ev_type == APB_BEFORE_CHANGE){
190+
timer->dev->config.enable = 0;
191+
} else {
192+
old_apb /= 1000000;
193+
new_apb /= 1000000;
194+
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb;
195+
timer->dev->config.enable = 1;
196+
}
197+
}
198+
187199
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
188200
if(num > 3){
189201
return NULL;
@@ -205,12 +217,14 @@ hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
205217
timerAttachInterrupt(timer, NULL, false);
206218
timerWrite(timer, 0);
207219
timer->dev->config.enable = 1;
220+
addApbChangeCallback(timer, _on_apb_change);
208221
return timer;
209222
}
210223

211224
void timerEnd(hw_timer_t *timer){
212225
timer->dev->config.enable = 0;
213226
timerAttachInterrupt(timer, NULL, false);
227+
removeApbChangeCallback(timer, _on_apb_change);
214228
}
215229

216230
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
@@ -271,23 +285,23 @@ void timerDetachInterrupt(hw_timer_t *timer){
271285
uint64_t timerReadMicros(hw_timer_t *timer){
272286
uint64_t timer_val = timerRead(timer);
273287
uint16_t div = timerGetDivider(timer);
274-
return timer_val * div / 80;
288+
return timer_val * div / (getApbFrequency() / 1000000);
275289
}
276290

277291
double timerReadSeconds(hw_timer_t *timer){
278292
uint64_t timer_val = timerRead(timer);
279293
uint16_t div = timerGetDivider(timer);
280-
return (double)timer_val * div / 80000000;
294+
return (double)timer_val * div / getApbFrequency();
281295
}
282296

283297
uint64_t timerAlarmReadMicros(hw_timer_t *timer){
284298
uint64_t timer_val = timerAlarmRead(timer);
285299
uint16_t div = timerGetDivider(timer);
286-
return timer_val * div / 80;
300+
return timer_val * div / (getApbFrequency() / 1000000);
287301
}
288302

289303
double timerAlarmReadSeconds(hw_timer_t *timer){
290304
uint64_t timer_val = timerAlarmRead(timer);
291305
uint16_t div = timerGetDivider(timer);
292-
return (double)timer_val * div / 80000000;
306+
return (double)timer_val * div / getApbFrequency();
293307
}

‎cores/esp32/esp32-hal-uart.c

+45-10
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ static uart_t _uart_bus_array[3] = {
6767
};
6868
#endif
6969

70+
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb);
71+
7072
static void IRAM_ATTR _uart_isr(void *arg)
7173
{
7274
uint8_t i, c;
@@ -216,6 +218,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
216218
uartAttachTx(uart, txPin, inverted);
217219
}
218220

221+
addApbChangeCallback(uart, uart_on_apb_change);
219222
return uart;
220223
}
221224

@@ -224,11 +227,10 @@ void uartEnd(uart_t* uart)
224227
if(uart == NULL) {
225228
return;
226229
}
230+
removeApbChangeCallback(uart, uart_on_apb_change);
227231

228232
UART_MUTEX_LOCK();
229233
if(uart->queue != NULL) {
230-
uint8_t c;
231-
while(xQueueReceive(uart->queue, &c, 0));
232234
vQueueDelete(uart->queue);
233235
uart->queue = NULL;
234236
}
@@ -248,8 +250,6 @@ size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) {
248250

249251
UART_MUTEX_LOCK();
250252
if(uart->queue != NULL) {
251-
uint8_t c;
252-
while(xQueueReceive(uart->queue, &c, 0));
253253
vQueueDelete(uart->queue);
254254
uart->queue = xQueueCreate(new_size, sizeof(uint8_t));
255255
if(uart->queue == NULL) {
@@ -319,10 +319,9 @@ void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
319319
}
320320
UART_MUTEX_LOCK();
321321
while(len) {
322-
while(len && uart->dev->status.txfifo_cnt < 0x7F) {
323-
uart->dev->fifo.rw_byte = *data++;
324-
len--;
325-
}
322+
while(uart->dev->status.txfifo_cnt == 0x7F);
323+
uart->dev->fifo.rw_byte = *data++;
324+
len--;
326325
}
327326
UART_MUTEX_UNLOCK();
328327
}
@@ -359,13 +358,49 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
359358
UART_MUTEX_UNLOCK();
360359
}
361360

361+
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb)
362+
{
363+
uart_t* uart = (uart_t*)arg;
364+
if(ev_type == APB_BEFORE_CHANGE){
365+
UART_MUTEX_LOCK();
366+
//disabple interrupt
367+
uart->dev->int_ena.val = 0;
368+
uart->dev->int_clr.val = 0xffffffff;
369+
// read RX fifo
370+
uint8_t c;
371+
BaseType_t xHigherPriorityTaskWoken;
372+
while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
373+
c = uart->dev->fifo.rw_byte;
374+
if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
375+
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
376+
}
377+
}
378+
// wait TX empty
379+
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
380+
} else {
381+
//todo:
382+
// set baudrate
383+
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
384+
uint32_t baud_rate = ((old_apb<<4)/clk_div);
385+
clk_div = ((new_apb<<4)/baud_rate);
386+
uart->dev->clk_div.div_int = clk_div>>4 ;
387+
uart->dev->clk_div.div_frag = clk_div & 0xf;
388+
//enable interrupts
389+
uart->dev->int_ena.rxfifo_full = 1;
390+
uart->dev->int_ena.frm_err = 1;
391+
uart->dev->int_ena.rxfifo_tout = 1;
392+
uart->dev->int_clr.val = 0xffffffff;
393+
UART_MUTEX_UNLOCK();
394+
}
395+
}
396+
362397
uint32_t uartGetBaudRate(uart_t* uart)
363398
{
364399
if(uart == NULL) {
365400
return 0;
366401
}
367402
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
368-
return ((UART_CLK_FREQ<<4)/clk_div);
403+
return ((getApbFrequency()<<4)/clk_div);
369404
}
370405

371406
static void IRAM_ATTR uart0_write_char(char c)
@@ -505,7 +540,7 @@ uartDetectBaudrate(uart_t *uart)
505540
uart->dev->auto_baud.en = 0;
506541
uartStateDetectingBaudrate = false; // Initialize for the next round
507542

508-
unsigned long baudrate = UART_CLK_FREQ / divisor;
543+
unsigned long baudrate = getApbFrequency() / divisor;
509544

510545
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400};
511546

‎cores/esp32/esp32-hal.h

+1-9
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ void yield(void);
6262
#include "esp32-hal-timer.h"
6363
#include "esp32-hal-bt.h"
6464
#include "esp32-hal-psram.h"
65+
#include "esp32-hal-cpu.h"
6566

6667
#ifndef BOARD_HAS_PSRAM
6768
#ifdef CONFIG_SPIRAM_SUPPORT
@@ -87,15 +88,6 @@ void enableCore1WDT();
8788
void disableCore1WDT();
8889
#endif
8990

90-
//function takes the following frequencies as valid values:
91-
// 240, 160, 80 <<< For all XTAL types
92-
// 40, 20, 13, 10, 8, 5, 4, 3, 2, 1 <<< For 40MHz XTAL
93-
// 26, 13, 5, 4, 3, 2, 1 <<< For 26MHz XTAL
94-
// 24, 12, 8, 6, 4, 3, 2, 1 <<< For 24MHz XTAL
95-
bool setCpuFrequency(uint32_t cpu_freq_mhz);
96-
uint32_t getCpuFrequency();
97-
uint32_t getApbFrequency();
98-
9991
unsigned long micros();
10092
unsigned long millis();
10193
void delay(uint32_t);

‎libraries/Wire/src/Wire.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#include "freertos/queue.h"
3131
#include "Stream.h"
3232

33-
#define STICKBREAKER V1.0.1
33+
#define STICKBREAKER 'V1.1.0'
3434
#define I2C_BUFFER_LENGTH 128
3535
typedef void(*user_onRequest)(void);
3636
typedef void(*user_onReceive)(uint8_t*, int);
@@ -138,6 +138,7 @@ extern TwoWire Wire1;
138138

139139

140140
/*
141+
V1.1.0 08JAN2019 Support CPU Clock frequency changes
141142
V1.0.2 30NOV2018 stop returning I2C_ERROR_CONTINUE on ReSTART operations, regain compatibility with Arduino libs
142143
V1.0.1 02AUG2018 First Fix after release, Correct ReSTART handling, change Debug control, change begin()
143144
to a function, this allow reporting if bus cannot be initialized, Wire.begin() can be used to recover

0 commit comments

Comments
 (0)
Please sign in to comment.