Skip to content

Commit 2320ed7

Browse files
authored
Merge branch 'espressif:master' into master
2 parents 56cb759 + 23c6abc commit 2320ed7

File tree

13 files changed

+304
-74
lines changed

13 files changed

+304
-74
lines changed

.github/scripts/package_esptool.sh

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
# Check version argument
6+
if [[ $# -ne 3 ]]; then
7+
echo "Usage: $0 <version> <base_folder> <json_path>"
8+
echo "Example: $0 5.0.dev1 /tmp/esptool /tmp/esptool-5.0.dev1.json"
9+
exit 1
10+
fi
11+
12+
VERSION=$1
13+
BASE_FOLDER=$2
14+
JSON_PATH=$3
15+
16+
export COPYFILE_DISABLE=1
17+
18+
shopt -s nullglob # So for loop doesn't run if no matches
19+
20+
# Function to update JSON for a given host
21+
function update_json_for_host {
22+
local host=$1
23+
local archive=$2
24+
25+
# Extract the old url from the JSON for this host, then replace only the filename
26+
old_url=$(jq -r --arg host "$host" '
27+
.packages[].tools[] | select(.name == "esptool_py") | .systems[] | select(.host == $host) | .url // empty
28+
' "$tmp_json")
29+
if [[ -n "$old_url" ]]; then
30+
base_url="${old_url%/*}"
31+
url="$base_url/$archive"
32+
else
33+
echo "No old url found for $host"
34+
exit 1
35+
fi
36+
37+
archiveFileName="$archive"
38+
checksum="SHA-256:$(shasum -a 256 "$archive" | awk '{print $1}')"
39+
size=$(stat -f%z "$archive")
40+
41+
# Use jq to update the JSON
42+
jq --arg host "$host" \
43+
--arg url "$url" \
44+
--arg archiveFileName "$archiveFileName" \
45+
--arg checksum "$checksum" \
46+
--arg size "$size" \
47+
'
48+
.packages[].tools[]
49+
|= if .name == "esptool_py" then
50+
.systems = (
51+
((.systems // []) | map(select(.host != $host))) + [{
52+
host: $host,
53+
url: $url,
54+
archiveFileName: $archiveFileName,
55+
checksum: $checksum,
56+
size: $size
57+
}]
58+
)
59+
else
60+
.
61+
end
62+
' "$tmp_json" > "$tmp_json.new" && mv "$tmp_json.new" "$tmp_json"
63+
}
64+
65+
cd "$BASE_FOLDER"
66+
67+
# Delete all archives before starting
68+
rm -f esptool-*.tar.gz esptool-*.zip
69+
70+
for dir in esptool-*; do
71+
# Check if directory exists and is a directory
72+
if [[ ! -d "$dir" ]]; then
73+
continue
74+
fi
75+
76+
base="${dir#esptool-}"
77+
78+
# Add 'linux-' prefix if base doesn't contain linux/macos/win64
79+
if [[ "$base" != *linux* && "$base" != *macos* && "$base" != *win64* ]]; then
80+
base="linux-${base}"
81+
fi
82+
83+
if [[ "$dir" == esptool-win* ]]; then
84+
# Windows zip archive
85+
zipfile="esptool-v${VERSION}-${base}.zip"
86+
echo "Creating $zipfile from $dir ..."
87+
zip -r "$zipfile" "$dir"
88+
else
89+
# Non-Windows: set permissions and tar.gz archive
90+
tarfile="esptool-v${VERSION}-${base}.tar.gz"
91+
echo "Setting permissions and creating $tarfile from $dir ..."
92+
chmod -R u=rwx,g=rx,o=rx "$dir"
93+
tar -cvzf "$tarfile" "$dir"
94+
fi
95+
done
96+
97+
# After the for loop, update the JSON for each archive
98+
# Create a temporary JSON file to accumulate changes
99+
tmp_json="${JSON_PATH}.tmp"
100+
cp "$JSON_PATH" "$tmp_json"
101+
102+
for archive in esptool-v"${VERSION}"-*.tar.gz esptool-v"${VERSION}"-*.zip; do
103+
[ -f "$archive" ] || continue
104+
105+
echo "Updating JSON for $archive"
106+
107+
# Determine host from archive name
108+
case "$archive" in
109+
*linux-amd64*) host="x86_64-pc-linux-gnu" ;;
110+
*linux-armv7*) host="arm-linux-gnueabihf" ;;
111+
*linux-aarch64*) host="aarch64-linux-gnu" ;;
112+
*macos-amd64*) host="x86_64-apple-darwin" ;;
113+
*macos-arm64*) host="arm64-apple-darwin" ;;
114+
*win64*) hosts=("x86_64-mingw32" "i686-mingw32") ;;
115+
*) echo "Unknown host for $archive"; continue ;;
116+
esac
117+
118+
# For win64, loop over both hosts; otherwise, use a single host
119+
if [[ "$archive" == *win64* ]]; then
120+
for host in "${hosts[@]}"; do
121+
update_json_for_host "$host" "$archive"
122+
done
123+
else
124+
update_json_for_host "$host" "$archive"
125+
fi
126+
done
127+
128+
# After all archives are processed, move the temporary JSON to the final file
129+
mv "$tmp_json" "$JSON_PATH"

boards.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36051,12 +36051,12 @@ XIAO_ESP32S3_Plus.build.cdc_on_boot=1
3605136051
XIAO_ESP32S3_Plus.build.msc_on_boot=0
3605236052
XIAO_ESP32S3_Plus.build.dfu_on_boot=0
3605336053
XIAO_ESP32S3_Plus.build.f_cpu=240000000L
36054-
XIAO_ESP32S3_Plus.build.flash_size=8MB
36054+
XIAO_ESP32S3_Plus.build.flash_size=16MB
3605536055
XIAO_ESP32S3_Plus.build.flash_freq=80m
3605636056
XIAO_ESP32S3_Plus.build.flash_mode=dio
3605736057
XIAO_ESP32S3_Plus.build.boot=qio
3605836058
XIAO_ESP32S3_Plus.build.boot_freq=80m
36059-
XIAO_ESP32S3_Plus.build.partitions=default_8MB
36059+
XIAO_ESP32S3_Plus.build.partitions=ffat
3606036060
XIAO_ESP32S3_Plus.build.defines=
3606136061
XIAO_ESP32S3_Plus.build.loop_core=
3606236062
XIAO_ESP32S3_Plus.build.event_core=
@@ -36093,8 +36093,6 @@ XIAO_ESP32S3_Plus.menu.FlashMode.dio.build.boot=dio
3609336093
XIAO_ESP32S3_Plus.menu.FlashMode.dio.build.boot_freq=80m
3609436094
XIAO_ESP32S3_Plus.menu.FlashMode.dio.build.flash_freq=80m
3609536095

36096-
XIAO_ESP32S3_Plus.menu.FlashSize.8M=8MB (64Mb)
36097-
XIAO_ESP32S3_Plus.menu.FlashSize.8M.build.flash_size=8MB
3609836096
XIAO_ESP32S3_Plus.menu.FlashSize.16M=16MB (128Mb)
3609936097
XIAO_ESP32S3_Plus.menu.FlashSize.16M.build.flash_size=16MB
3610036098

cores/esp32/esp32-hal-spi.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ extern "C" {
3838
#define HSPI 2 //SPI 2 bus normally mapped to pins 12 - 15, but can be matrixed to any pins
3939
#define VSPI 3 //SPI 3 bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
4040
#else
41-
#define FSPI 0
42-
#define HSPI 1
41+
#define FSPI 0 // ESP32C2, C3, C6, H2, S3, P4 - SPI 2 bus
42+
#define HSPI 1 // ESP32S3, P4 - SPI 3 bus
4343
#endif
4444

4545
// This defines are not representing the real Divider of the ESP32

docs/en/guides/core_compatibility.rst

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,28 @@ Welcome to the compatibility guide for library developers aiming to support mult
99
Code Adaptations
1010
----------------
1111

12-
To ensure compatibility with both versions of the ESP32 Arduino core, developers should utilize conditional compilation directives in their code. Below is an example of how to conditionally include code based on the ESP32 Arduino core version::
12+
To ensure compatibility with both versions of the ESP32 Arduino core, developers should utilize conditional compilation directives in their code. Below is an example of how to conditionally include code based on the ESP32 Arduino core version:
1313

14-
.. code-block:: cpp
14+
.. code-block:: cpp
1515
16-
#ifdef ESP_ARDUINO_VERSION_MAJOR
17-
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
18-
// Code for version 3.x
19-
#else
20-
// Code for version 2.x
21-
#endif
22-
#else
23-
// Code for version 1.x
24-
#endif
16+
#ifdef ESP_ARDUINO_VERSION_MAJOR
17+
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
18+
// Code for version 3.x
19+
#else
20+
// Code for version 2.x
21+
#endif
22+
#else
23+
// Code for version 1.x
24+
#endif
2525
2626
Version Print
2727
-------------
2828

29-
To easily print the ESP32 Arduino core version at runtime, developers can use the `ESP_ARDUINO_VERSION_STR` macro. Below is an example of how to print the ESP32 Arduino core version::
29+
To easily print the ESP32 Arduino core version at runtime, developers can use the `ESP_ARDUINO_VERSION_STR` macro. Below is an example of how to print the ESP32 Arduino core version:
3030

31-
.. code-block:: cpp
31+
.. code-block:: cpp
3232
33-
Serial.printf(" ESP32 Arduino core version: %s\n", ESP_ARDUINO_VERSION_STR);
33+
Serial.printf(" ESP32 Arduino core version: %s\n", ESP_ARDUINO_VERSION_STR);
3434
3535
API Differences
3636
---------------

libraries/DNSServer/src/DNSServer.cpp

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,22 @@ void DNSServer::_handleUDP(AsyncUDPPacket &pkt) {
111111
// will reply with IP only to "*" or if domain matches without www. subdomain
112112
if (dnsHeader.OPCode == DNS_OPCODE_QUERY && requestIncludesOnlyOneQuestion(dnsHeader)
113113
&& (_domainName.isEmpty() || getDomainNameWithoutWwwPrefix(static_cast<const unsigned char *>(dnsQuestion.QName), dnsQuestion.QNameLength) == _domainName)) {
114-
replyWithIP(pkt, dnsHeader, dnsQuestion);
114+
115+
// Qtype = A (1) or ANY (255): send an A record otherwise an empty response
116+
if (ntohs(dnsQuestion.QType) == 1 || ntohs(dnsQuestion.QType) == 255) {
117+
replyWithIP(pkt, dnsHeader, dnsQuestion);
118+
} else {
119+
replyWithNoAnsw(pkt, dnsHeader, dnsQuestion);
120+
}
115121
return;
116122
}
117-
118123
// otherwise reply with custom code
119124
replyWithCustomCode(pkt, dnsHeader);
120125
}
121126

122127
bool DNSServer::requestIncludesOnlyOneQuestion(DNSHeader &dnsHeader) {
123-
return ntohs(dnsHeader.QDCount) == 1 && dnsHeader.ANCount == 0 && dnsHeader.NSCount == 0 && dnsHeader.ARCount == 0;
128+
dnsHeader.ARCount = 0; // We assume that if ARCount !=0 there is a EDNS OPT packet, just ignore
129+
return ntohs(dnsHeader.QDCount) == 1 && dnsHeader.ANCount == 0 && dnsHeader.NSCount == 0;
124130
}
125131

126132
String DNSServer::getDomainNameWithoutWwwPrefix(const unsigned char *start, size_t len) {
@@ -139,7 +145,6 @@ String DNSServer::getDomainNameWithoutWwwPrefix(const unsigned char *start, size
139145

140146
void DNSServer::replyWithIP(AsyncUDPPacket &req, DNSHeader &dnsHeader, DNSQuestion &dnsQuestion) {
141147
AsyncUDPMessage rpl;
142-
143148
// Change the type of message to a response and set the number of answers equal to
144149
// the number of questions in the header
145150
dnsHeader.QR = DNS_QR_RESPONSE;
@@ -187,3 +192,76 @@ void DNSServer::replyWithCustomCode(AsyncUDPPacket &req, DNSHeader &dnsHeader) {
187192
rpl.write(reinterpret_cast<const uint8_t *>(&dnsHeader), sizeof(DNSHeader));
188193
_udp.sendTo(rpl, req.remoteIP(), req.remotePort());
189194
}
195+
196+
void DNSServer::replyWithNoAnsw(AsyncUDPPacket &req, DNSHeader &dnsHeader, DNSQuestion &dnsQuestion) {
197+
198+
dnsHeader.QR = DNS_QR_RESPONSE;
199+
dnsHeader.ANCount = 0;
200+
dnsHeader.NSCount = htons(1);
201+
202+
AsyncUDPMessage rpl;
203+
rpl.write(reinterpret_cast<const uint8_t *>(&dnsHeader), sizeof(DNSHeader));
204+
205+
// Write the question
206+
rpl.write(dnsQuestion.QName, dnsQuestion.QNameLength);
207+
rpl.write((uint8_t *)&dnsQuestion.QType, 2);
208+
rpl.write((uint8_t *)&dnsQuestion.QClass, 2);
209+
210+
// An empty answer contains an authority section with a SOA,
211+
// We take the name of the query as the root of the zone for which the SOA is generated
212+
// and use a value of DNS_MINIMAL_TTL seconds in order to minimize negative caching
213+
// Write the authority section:
214+
// The SOA RR's ownername is set equal to the query name, and we use made up names for
215+
// the MNAME and RNAME - it doesn't really matter from a protocol perspective - as for
216+
// a no such QTYPE answer only the timing fields are used.
217+
// a protocol perspective - it
218+
// Use DNS name compression : instead of repeating the name in this RNAME occurrence,
219+
// set the two MSB of the byte corresponding normally to the length to 1. The following
220+
// 14 bits must be used to specify the offset of the domain name in the message
221+
// (<255 here so the first byte has the 6 LSB at 0)
222+
rpl.write((uint8_t)0xC0);
223+
rpl.write((uint8_t)DNS_OFFSET_DOMAIN_NAME);
224+
225+
// DNS type A : host address, DNS class IN for INternet, returning an IPv4 address
226+
uint16_t answerType = htons(DNS_TYPE_SOA), answerClass = htons(DNS_CLASS_IN);
227+
uint32_t Serial = htonl(DNS_SOA_SERIAL); // Date type serial based on the date this piece of code was written
228+
uint32_t Refresh = htonl(DNS_SOA_REFRESH); // These timers don't matter, we don't serve zone transfers
229+
uint32_t Retry = htonl(DNS_SOA_RETRY);
230+
uint32_t Expire = htonl(DNS_SOA_EXPIRE);
231+
uint32_t MinTTL = htonl(DNS_MINIMAL_TTL); // See RFC2308 section 5
232+
char MLabel[] = DNS_SOA_MNAME_LABEL;
233+
char RLabel[] = DNS_SOA_RNAME_LABEL;
234+
char PostFixLabel[] = DNS_SOA_POSTFIX_LABEL;
235+
236+
// 4 accounts for len fields and for both rname
237+
// and lname and their postfix labels and there are 5 32 bit fields
238+
239+
uint16_t RdataLength = htons((uint16_t)(strlen(MLabel) + strlen(RLabel) + 2 * strlen(PostFixLabel) + 4 + 5 * sizeof(Serial)));
240+
241+
rpl.write((unsigned char *)&answerType, 2);
242+
rpl.write((unsigned char *)&answerClass, 2);
243+
rpl.write((unsigned char *)&MinTTL, 4); // DNS Time To Live
244+
245+
rpl.write((unsigned char *)&RdataLength, 2);
246+
247+
rpl.write((uint8_t)strlen(MLabel));
248+
rpl.write((unsigned char *)&MLabel, strlen(MLabel));
249+
250+
rpl.write((unsigned char *)&PostFixLabel, strlen(PostFixLabel));
251+
rpl.write((uint8_t)0);
252+
// rpl.write((uint8_t)0xC0);
253+
// rpl.write((uint8_t)DNS_OFFSET_DOMAIN_NAME);
254+
255+
rpl.write((uint8_t)strlen(RLabel));
256+
rpl.write((unsigned char *)&RLabel, strlen(RLabel));
257+
rpl.write((unsigned char *)&PostFixLabel, strlen(PostFixLabel));
258+
rpl.write((uint8_t)0);
259+
260+
rpl.write((unsigned char *)&Serial, 4);
261+
rpl.write((unsigned char *)&Refresh, 4);
262+
rpl.write((unsigned char *)&Retry, 4);
263+
rpl.write((unsigned char *)&Expire, 4);
264+
rpl.write((unsigned char *)&MinTTL, 4);
265+
266+
_udp.sendTo(rpl, req.remoteIP(), req.remotePort());
267+
}

libraries/DNSServer/src/DNSServer.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,26 @@
99
#define DNS_OFFSET_DOMAIN_NAME DNS_HEADER_SIZE // Offset in bytes to reach the domain name labels in the DNS message
1010
#define DNS_DEFAULT_PORT 53
1111

12+
#define DNS_SOA_MNAME_LABEL "ns"
13+
#define DNS_SOA_RNAME_LABEL "esp32"
14+
// The POSTFIX_LABEL will be concatenated to the RName and MName Label label
15+
// do not use a multilabel name here. "local" is a good choice as it is reserved for
16+
// local use by IANA
17+
// The postfix label is defined as an array of characters that follows the
18+
// definition of RFC1035 3.1
19+
// for instance, a postfix of example.com would be defined as:
20+
// #define DNS_SOA_POSTFIX_LABEL {'\7', 'e', 'x', 'a', 'm', 'p', 'l', 'e', '\3', 'c', 'o', 'm', '\0'}
21+
#define DNS_SOA_POSTFIX_LABEL \
22+
{ '\5', 'l', 'o', 'c', 'a', 'l', '\0' }
23+
// From the following values only the MINIMAL_TTL has relevance
24+
// in the context of client-server protocol interactions.
25+
// The other values are arbitrary chosen as they are only relevant for
26+
// in a zone-transfer scenario.
27+
#define DNS_SOA_SERIAL 2025052900 // Arbitrary serial (format: YYYYMMDDnn)
28+
#define DNS_SOA_REFRESH 100000 // Arbitrary (seconds)
29+
#define DNS_SOA_RETRY 10000 // Arbitrary (seconds)
30+
#define DNS_SOA_EXPIRE 1000000 // Arbitrary (seconds)
31+
#define DNS_MINIMAL_TTL 5 // Time to live for negative answers RFC2308
1232
enum class DNSReplyCode : uint16_t {
1333
NoError = 0,
1434
FormError = 1,
@@ -179,5 +199,7 @@ class DNSServer {
179199
inline bool requestIncludesOnlyOneQuestion(DNSHeader &dnsHeader);
180200
void replyWithIP(AsyncUDPPacket &req, DNSHeader &dnsHeader, DNSQuestion &dnsQuestion);
181201
inline void replyWithCustomCode(AsyncUDPPacket &req, DNSHeader &dnsHeader);
202+
inline void replyWithNoAnsw(AsyncUDPPacket &req, DNSHeader &dnsHeader, DNSQuestion &dnsQuestion);
203+
182204
void _handleUDP(AsyncUDPPacket &pkt);
183205
};

libraries/OpenThread/src/OThread.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ void OpenThread::otPrintNetworkInformation(Stream &output) {
335335

336336
output.printf("Role: %s", otGetStringDeviceRole());
337337
output.println();
338+
output.printf("RLOC16: 0x%04x", otThreadGetRloc16(mInstance)); // RLOC16
339+
output.println();
338340
output.printf("Network Name: %s", otThreadGetNetworkName(mInstance));
339341
output.println();
340342
output.printf("Channel: %d", otLinkGetChannel(mInstance));

libraries/SPI/src/SPI.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ SPIClass::~SPIClass() {
6363
#endif
6464
}
6565

66-
void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss) {
66+
bool SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss) {
6767
if (_spi) {
68-
return;
68+
return true;
6969
}
7070

7171
if (!_div) {
@@ -74,7 +74,7 @@ void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss) {
7474

7575
_spi = spiStartBus(_spi_num, _div, SPI_MODE0, SPI_MSBFIRST);
7676
if (!_spi) {
77-
return;
77+
return false;
7878
}
7979

8080
if (sck == -1 && miso == -1 && mosi == -1 && ss == -1) {
@@ -110,10 +110,11 @@ void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss) {
110110
if (_mosi >= 0 && !spiAttachMOSI(_spi, _mosi)) {
111111
goto err;
112112
}
113-
return;
113+
return true;
114114

115115
err:
116116
log_e("Attaching pins to SPI failed.");
117+
return false;
117118
}
118119

119120
void SPIClass::end() {

0 commit comments

Comments
 (0)