Skip to content

Commit 7cb2596

Browse files
author
stickbreaker
committed
First working test of UART modifications. These modifications:
* Use Shared interrupt * Handle Each UART individually * Support Queue Length of 0, which means only use FiFo's as buffers * Support CPU frequency changes. * Fix Memory leak in Debug Log code * increase concurrency between receiving data and it appearing in Queue * return -1 when queue/fifo empty on read/peek * Support changing baudrate without disburbing Queue content * Add logic to powerdown peripheral and Fifo memory when ports are closed. * disable rx_fifo_full when Queue is full
1 parent 6296be9 commit 7cb2596

File tree

6 files changed

+280
-105
lines changed

6 files changed

+280
-105
lines changed

cores/esp32/HardwareSerial.cpp

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ HardwareSerial Serial1(1);
2828
HardwareSerial Serial2(2);
2929
#endif
3030

31-
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
31+
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL), _baud(0), _rx_pin(-1), _tx_pin(-1) {}
3232

3333
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms)
3434
{
@@ -52,23 +52,29 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
5252
txPin = TX2;
5353
}
5454

55-
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert);
56-
57-
if(!baud) {
58-
time_t startMillis = millis();
59-
unsigned long detectedBaudRate = 0;
60-
while(millis() - startMillis < timeout_ms && !(detectedBaudRate = uartDetectBaudrate(_uart))) {
61-
yield();
62-
}
63-
64-
end();
65-
66-
if(detectedBaudRate) {
67-
delay(100); // Give some time...
68-
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, 256, invert);
69-
} else {
70-
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
71-
_uart = NULL;
55+
if((_uart != NULL)&&(rxPin == _rx_pin)&&( txPin == _tx_pin)&&(baud !=0)){ // just change baud rate,
56+
uartSetBaudRate(_uart,baud);
57+
log_i("begin set baud only");
58+
} else { // completely reconfigure
59+
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert);
60+
// log_i("Init Uart[%d] baud=%d, rx=%d, tx=%d",_uart_nr,baud,rxPin,txPin);
61+
62+
if(!baud) {
63+
time_t startMillis = millis();
64+
unsigned long detectedBaudRate = 0;
65+
while(millis() - startMillis < timeout_ms && !(detectedBaudRate = uartDetectBaudrate(_uart))) {
66+
yield();
67+
}
68+
69+
end();
70+
71+
if(detectedBaudRate) {
72+
delay(100); // Give some time...
73+
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, 256, invert);
74+
} else {
75+
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
76+
_uart = NULL;
77+
}
7278
}
7379
}
7480
}
@@ -79,7 +85,7 @@ void HardwareSerial::end()
7985
uartSetDebug(0);
8086
}
8187
uartEnd(_uart);
82-
_uart = 0;
88+
_uart = NULL;
8389
}
8490

8591
size_t HardwareSerial::setRxBufferSize(size_t new_size) {
@@ -111,23 +117,17 @@ int HardwareSerial::availableForWrite(void)
111117

112118
int HardwareSerial::peek(void)
113119
{
114-
if (available()) {
115-
return uartPeek(_uart);
116-
}
117-
return -1;
120+
return uartPeek(_uart);
118121
}
119122

120123
int HardwareSerial::read(void)
121124
{
122-
if(available()) {
123-
return uartRead(_uart);
124-
}
125-
return -1;
125+
return uartRead(_uart);
126126
}
127127

128128
void HardwareSerial::flush()
129129
{
130-
uartFlush(_uart);
130+
uartDrain(_uart);
131131
}
132132

133133
size_t HardwareSerial::write(uint8_t c)
@@ -141,11 +141,12 @@ size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
141141
uartWriteBuf(_uart, buffer, size);
142142
return size;
143143
}
144-
uint32_t HardwareSerial::baudRate()
145144

145+
uint32_t HardwareSerial::baudRate()
146146
{
147147
return uartGetBaudRate(_uart);
148148
}
149+
149150
HardwareSerial::operator bool() const
150151
{
151152
return true;

cores/esp32/HardwareSerial.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ class HardwareSerial: public Stream
9494
protected:
9595
int _uart_nr;
9696
uart_t* _uart;
97+
uint32_t _baud;
98+
int _rx_pin;
99+
int _tx_pin;
97100
};
98101

99102
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)

cores/esp32/esp32-hal-misc.c

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121
#include "esp_partition.h"
2222
#include "esp_log.h"
2323
#include "esp_timer.h"
24+
#ifdef CONFIG_BT_ENABLED
2425
#include "esp_bt.h"
26+
#endif //CONFIG_BT_ENABLED
2527
#include <sys/time.h>
28+
#include "soc/rtc.h"
29+
#include "soc/rtc_cntl_reg.h"
30+
#include "rom/rtc.h"
2631
#include "esp32-hal.h"
2732

2833
//Undocumented!!! Get chip temperature in Farenheit
@@ -39,19 +44,57 @@ void yield()
3944
vPortYield();
4045
}
4146

47+
static uint32_t _cpu_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
48+
static uint32_t _sys_time_multiplier = 1;
49+
50+
bool setCpuFrequency(uint32_t cpu_freq_mhz){
51+
rtc_cpu_freq_config_t conf, cconf;
52+
rtc_clk_cpu_freq_get_config(&cconf);
53+
if(cconf.freq_mhz == cpu_freq_mhz && _cpu_freq_mhz == cpu_freq_mhz){
54+
return true;
55+
}
56+
if(!rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &conf)){
57+
log_e("CPU clock could not be set to %u MHz", cpu_freq_mhz);
58+
return false;
59+
}
60+
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
61+
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);
62+
delay(300);
63+
#endif
64+
rtc_clk_cpu_freq_set_config_fast(&conf);
65+
_cpu_freq_mhz = conf.freq_mhz;
66+
_sys_time_multiplier = 80 / getApbFrequency();
67+
return true;
68+
}
69+
70+
uint32_t getCpuFrequency(){
71+
rtc_cpu_freq_config_t conf;
72+
rtc_clk_cpu_freq_get_config(&conf);
73+
return conf.freq_mhz;
74+
}
75+
76+
uint32_t getApbFrequency(){
77+
rtc_cpu_freq_config_t conf;
78+
rtc_clk_cpu_freq_get_config(&conf);
79+
if(conf.freq_mhz >= 80){
80+
return 80000000;
81+
}
82+
return (conf.source_freq_mhz * 1000000) / conf.div;
83+
}
84+
4285
unsigned long IRAM_ATTR micros()
4386
{
44-
return (unsigned long) esp_timer_get_time();
87+
return (unsigned long) (esp_timer_get_time()) * _sys_time_multiplier;
4588
}
4689

4790
unsigned long IRAM_ATTR millis()
4891
{
49-
return (unsigned long) (esp_timer_get_time() / 1000);
92+
return (unsigned long) (micros() / 1000);
5093
}
5194

5295
void delay(uint32_t ms)
5396
{
54-
vTaskDelay(ms / portTICK_PERIOD_MS);
97+
vTaskDelay((ms * _cpu_freq_mhz) / (portTICK_PERIOD_MS * 240));
5598
}
5699

57100
void IRAM_ATTR delayMicroseconds(uint32_t us)
@@ -84,6 +127,9 @@ bool btInUse(){ return false; }
84127

85128
void initArduino()
86129
{
130+
#ifdef F_CPU
131+
setCpuFrequency(F_CPU/1000000L);
132+
#endif
87133
#if CONFIG_SPIRAM_SUPPORT
88134
psramInit();
89135
#endif

0 commit comments

Comments
 (0)