Skip to content

Commit 747d391

Browse files
authored
Merge branch 'espressif:master' into main
2 parents 31cc5d0 + 543fad2 commit 747d391

File tree

5 files changed

+116
-98
lines changed

5 files changed

+116
-98
lines changed

cores/esp32/Arduino.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
#include "extra_attr.h"
4242

4343
#include "pins_arduino.h"
44-
#include "io_pin_remap.h"
4544
#include "esp32-hal.h"
4645

4746
#define PI 3.1415926535897932384626433832795
@@ -251,4 +250,8 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
251250
void noTone(uint8_t _pin);
252251

253252
#endif /* __cplusplus */
253+
254+
// must be applied last as it overrides some of the above
255+
#include "io_pin_remap.h"
256+
254257
#endif /* _ESP32_CORE_ARDUINO_H_ */

cores/esp32/esp32-hal-spi.c

+23-23
Original file line numberDiff line numberDiff line change
@@ -152,23 +152,23 @@ struct spi_struct_t {
152152
// clang-format off
153153
static spi_t _spi_bus_array[] = {
154154
#if CONFIG_IDF_TARGET_ESP32S2
155-
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0, -1, -1, -1, -1},
156-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1, -1, -1, -1, -1},
157-
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2, -1, -1, -1, -1}
155+
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0, -1, -1, -1, -1, false},
156+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1, -1, -1, -1, -1, false},
157+
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2, -1, -1, -1, -1, false}
158158
#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
159-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1},
160-
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1, -1, -1, -1, -1}
159+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false},
160+
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 1, -1, -1, -1, -1, false}
161161
#elif CONFIG_IDF_TARGET_ESP32C2
162-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1}
162+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false}
163163
#elif CONFIG_IDF_TARGET_ESP32C3
164-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1}
164+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false}
165165
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
166-
{(spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1}
166+
{(spi_dev_t *)(DR_REG_SPI2_BASE), 0, -1, -1, -1, -1, false}
167167
#else
168-
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0, -1, -1, -1, -1},
169-
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1, -1, -1, -1, -1},
170-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 2, -1, -1, -1, -1},
171-
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3, -1, -1, -1, -1}
168+
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0, -1, -1, -1, -1, false},
169+
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1, -1, -1, -1, -1, false},
170+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 2, -1, -1, -1, -1, false},
171+
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3, -1, -1, -1, -1, false}
172172
#endif
173173
};
174174
// clang-format on
@@ -180,22 +180,22 @@ static spi_t _spi_bus_array[] = {
180180

181181
static spi_t _spi_bus_array[] = {
182182
#if CONFIG_IDF_TARGET_ESP32S2
183-
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0, -1, -1, -1, -1},
184-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1, -1, -1, -1, -1},
185-
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2, -1, -1, -1, -1}
183+
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0, -1, -1, -1, -1, false},
184+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1, -1, -1, -1, -1, false},
185+
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2, -1, -1, -1, -1, false}
186186
#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
187-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1, -1, -1, -1, -1}
187+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}, {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 1, -1, -1, -1, -1, false}
188188
#elif CONFIG_IDF_TARGET_ESP32C2
189-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1}
189+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}
190190
#elif CONFIG_IDF_TARGET_ESP32C3
191-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1}
191+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}
192192
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
193-
{(spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1}
193+
{(spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 0, -1, -1, -1, -1, false}
194194
#else
195-
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0, -1, -1, -1, -1},
196-
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1, -1, -1, -1, -1},
197-
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2, -1, -1, -1, -1},
198-
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3, -1, -1, -1, -1}
195+
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0, -1, -1, -1, -1, false},
196+
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1, -1, -1, -1, -1, false},
197+
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2, -1, -1, -1, -1, false},
198+
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3, -1, -1, -1, -1, false}
199199
#endif
200200
};
201201
#endif

docs/en/installing.rst

+15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ Before Installing
1010
We recommend you install the support using your favorite IDE, but other options are available depending on your operating system.
1111
To install Arduino-ESP32 support, you can use one of the following options.
1212

13+
.. note::
14+
Users in China might have troubles with connection and download speeds using GitHub. Please use our Jihulab mirror as the repository source:
15+
16+
``https://jihulab.com/esp-mirror/espressif/arduino-esp32.git``
17+
1318
Installing using Arduino IDE
1419
----------------------------
1520

@@ -32,6 +37,16 @@ This is the way to install Arduino-ESP32 directly from the Arduino IDE.
3237
https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json
3338

3439

40+
Users in China might have troubles with connection and download speeds using the links above. Please use our Jihulab mirror:
41+
42+
- Stable release link::
43+
44+
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_index_cn.json
45+
46+
- Development release link::
47+
48+
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_dev_index_cn.json
49+
3550
.. note::
3651
Starting with the Arduino IDE version 1.6.4, Arduino allows installation of third-party platform
3752
packages using Boards Manager. We have packages available for Windows, macOS, and Linux.

docs/en/troubleshooting.rst

+17
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,23 @@ Installing
1414

1515
Here are the common issues during the installation.
1616

17+
Slow or unstable downloads
18+
**************************
19+
20+
Users in China might have troubles with connection and download speeds using GitHub. Please use our Jihulab mirror as the repository source:
21+
22+
`https://jihulab.com/esp-mirror/espressif/arduino-esp32.git <https://jihulab.com/esp-mirror/espressif/arduino-esp32.git>`_
23+
24+
JSON files for the boards manager are available here:
25+
26+
- Stable release::
27+
28+
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_index_cn.json
29+
30+
- Development release::
31+
32+
https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_dev_index_cn.json
33+
1734
Building
1835
--------
1936

libraries/ESP32/examples/Serial/onReceiveExample/onReceiveExample.ino

+57-74
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55
void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout = false)
66
77
It is possible to register an UART callback function that will be called
8-
every time that UART receives data and an associated interrupt is generated.
8+
every time that UART receives data and an associated UART interrupt is generated.
99
10-
In summary, HardwareSerial::onReceive() works like an RX Interrupt callback, that can be adjusted
11-
using HardwareSerial::setRxFIFOFull() and HardwareSerial::setRxTimeout().
10+
In summary, HardwareSerial::onReceive() works like an RX Interrupt callback, that
11+
can be adjusted using HardwareSerial::setRxFIFOFull() and HardwareSerial::setRxTimeout().
1212
13-
OnReceive will be called, while receiving a stream of data, when every 120 bytes are received (default FIFO Full),
14-
which may not help in case that the application needs to get all data at once before processing it.
15-
Therefore, a way to make it work is by detecting the end of a stream transmission. This can be based on a protocol
16-
or based on timeout with the UART line in idle (no data received - this is the case of this example).
13+
In case that <onlyOnTimeout> is not changed or it is set to <false>, the callback function is
14+
executed whenever any event happens first (FIFO Full or RX Timeout).
15+
OnReceive will be called when every 120 bytes are received(default FIFO Full),
16+
or when RX Timeout occurs after 1 UART symbol by default.
1717
18-
In some cases, it is necessary to wait for receiving all the data before processing it and parsing the
19-
UART input. This example demonstrates a way to create a String with all data received from UART0 and
20-
signaling it using a Mutex for another task to process it. This example uses a timeout of 500ms as a way to
21-
know when the reception of data has finished.
18+
This example demonstrates a way to create a String with all data received from UART0 only
19+
after RX Timeout. This example uses an RX timeout of about 3.5 Symbols as a way to know
20+
when the reception of data has finished.
21+
In order to achieve it, the sketch sets <onlyOnTimeout> to <true>.
2222
2323
The onReceive() callback is called whenever the RX ISR is triggered.
2424
It can occur because of two possible events:
@@ -34,90 +34,73 @@
3434
3535
2- UART RX Timeout: it happens, based on a timeout equivalent to a number of symbols at
3636
the current baud rate. If the UART line is idle for this timeout, it will raise an interrupt.
37-
This time can be changed by HardwareSerial::setRxTimeout(uint8_t rxTimeout)
37+
This time can be changed by HardwareSerial::setRxTimeout(uint8_t rxTimeout).
38+
<rxTimeout> is bound to the clock source.
39+
In order to use it properly, ESP32 and ESP32-S2 shall set the UART Clock Source to APB.
3840
3941
When any of those two interrupts occur, IDF UART driver will copy FIFO data to its internal
4042
RingBuffer and then Arduino can read such data. At the same time, Arduino Layer will execute
4143
the callback function defined with HardwareSerial::onReceive().
4244
43-
<bool onlyOnTimeout> parameter (default false) can be used by the application to tell Arduino to
44-
only execute the callback when the second event above happens (Rx Timeout). At this time all
45-
received data will be available to be read by the Arduino application. But if the number of
46-
received bytes is higher than the FIFO space, it will generate an error of FIFO overflow.
47-
In order to avoid such problem, the application shall set an appropriate RX buffer size using
45+
<bool onlyOnTimeout> parameter can be used by the application to tell Arduino to only execute
46+
the callback when Rx Timeout happens, by setting it to <true>.
47+
At this time all received data will be available to be read by the Arduino application.
48+
The application shall set an appropriate RX buffer size using
4849
HardwareSerial::setRxBufferSize(size_t new_size) before executing begin() for the Serial port.
49-
*/
5050
51-
// this will make UART0 work in any case (using or not USB)
52-
#if ARDUINO_USB_CDC_ON_BOOT
53-
#define UART0 Serial0
54-
#else
55-
#define UART0 Serial
56-
#endif
51+
MODBUS timeout of 3.5 symbol is based on these documents:
52+
https://www.automation.com/en-us/articles/2012-1/introduction-to-modbus
53+
https://minimalmodbus.readthedocs.io/en/stable/serialcommunication.html
54+
*/
5755

5856
// global variable to keep the results from onReceive()
5957
String uart_buffer = "";
60-
// a pause of a half second in the UART transmission is considered the end of transmission.
61-
const uint32_t communicationTimeout_ms = 500;
62-
63-
// Create a mutex for the access to uart_buffer
64-
// only one task can read/write it at a certain time
65-
SemaphoreHandle_t uart_buffer_Mutex = NULL;
66-
67-
// UART_RX_IRQ will be executed as soon as data is received by the UART
68-
// This is a callback function executed from a high priority
69-
// task created when onReceive() is used
58+
// The Modbus RTU standard prescribes a silent period corresponding to 3.5 characters between each
59+
// message, to be able to figure out where one message ends and the next one starts.
60+
const uint32_t modbusRxTimeoutLimit = 4;
61+
const uint32_t baudrate = 19200;
62+
63+
// UART_RX_IRQ will be executed as soon as data is received by the UART and an RX Timeout occurs
64+
// This is a callback function executed from a high priority monitor task
65+
// All data will be buffered into RX Buffer, which may have its size set to whatever necessary
7066
void UART0_RX_CB() {
71-
// take the mutex, waits forever until loop() finishes its processing
72-
if (xSemaphoreTake(uart_buffer_Mutex, portMAX_DELAY)) {
73-
uint32_t now = millis(); // tracks timeout
74-
while ((millis() - now) < communicationTimeout_ms) {
75-
if (UART0.available()) {
76-
uart_buffer += (char)UART0.read();
77-
now = millis(); // reset the timer
78-
}
79-
}
80-
// releases the mutex for data processing
81-
xSemaphoreGive(uart_buffer_Mutex);
67+
while (Serial0.available()) {
68+
uart_buffer += (char)Serial0.read();
8269
}
8370
}
8471

8572
// setup() and loop() are functions executed by a low priority task
8673
// Therefore, there are 2 tasks running when using onReceive()
8774
void setup() {
88-
UART0.begin(115200);
89-
90-
// creates a mutex object to control access to uart_buffer
91-
uart_buffer_Mutex = xSemaphoreCreateMutex();
92-
if (uart_buffer_Mutex == NULL) {
93-
log_e("Error creating Mutex. Sketch will fail.");
94-
while (true) {
95-
UART0.println("Mutex error (NULL). Program halted.");
96-
delay(2000);
97-
}
98-
}
99-
100-
UART0.onReceive(UART0_RX_CB); // sets the callback function
101-
UART0.println("Send data to UART0 in order to activate the RX callback");
75+
// Using Serial0 will work in any case (using or not USB CDC on Boot)
76+
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
77+
// UART_CLK_SRC_APB will allow higher values of RX Timeout
78+
// default for ESP32 and ESP32-S2 is REF_TICK which limits the RX Timeout to 1
79+
// setClockSource() must be called before begin()
80+
Serial0.setClockSource(UART_CLK_SRC_APB);
81+
#endif
82+
// the amount of data received or waiting to be proessed shall not exceed this limit of 1024 bytes
83+
Serial0.setRxBufferSize(1024); // default is 256 bytes
84+
Serial0.begin(baudrate); // default pins and default mode 8N1 (8 bits data, no parity bit, 1 stopbit)
85+
// set RX Timeout based on UART symbols ~ 3.5 symbols of 11 bits (MODBUS standard) ~= 2 ms at 19200
86+
Serial0.setRxTimeout(modbusRxTimeoutLimit); // 4 symbols at 19200 8N1 is about 2.08 ms (40 bits)
87+
// sets the callback function that will be executed only after RX Timeout
88+
Serial0.onReceive(UART0_RX_CB, true);
89+
Serial0.println("Send data using Serial Monitor in order to activate the RX callback");
10290
}
10391

10492
uint32_t counter = 0;
10593
void loop() {
94+
// String <uart_buffer> is filled by the UART Callback whenever data is received and RX Timeout occurs
10695
if (uart_buffer.length() > 0) {
107-
// signals that the onReceive function shall not change uart_buffer while processing
108-
if (xSemaphoreTake(uart_buffer_Mutex, portMAX_DELAY)) {
109-
// process the received data from UART0 - example, just print it beside a counter
110-
UART0.print("[");
111-
UART0.print(counter++);
112-
UART0.print("] [");
113-
UART0.print(uart_buffer.length());
114-
UART0.print(" bytes] ");
115-
UART0.println(uart_buffer);
116-
uart_buffer = ""; // reset uart_buffer for the next UART reading
117-
// releases the mutex for more data to be received
118-
xSemaphoreGive(uart_buffer_Mutex);
119-
}
96+
// process the received data from Serial - example, just print it beside a counter
97+
Serial0.print("[");
98+
Serial0.print(counter++);
99+
Serial0.print("] [");
100+
Serial0.print(uart_buffer.length());
101+
Serial0.print(" bytes] ");
102+
Serial0.println(uart_buffer);
103+
uart_buffer = ""; // reset uart_buffer for the next UART reading
120104
}
121-
UART0.println("Sleeping for 1 second...");
122-
delay(1000);
105+
delay(1);
123106
}

0 commit comments

Comments
 (0)