Skip to content

Commit 1945778

Browse files
authored
Fixes Serial Example and Adds a new std:func Serial Example (#8409)
* fixes example folder * adds new Serial std::func example
1 parent e7ceeb1 commit 1945778

File tree

2 files changed

+208
-75
lines changed

2 files changed

+208
-75
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,75 @@
1-
/*
2-
Simple Sketch for testing HardwareSerial with different CPU Frequencies
3-
Changing the CPU Frequency may affect peripherals and Wireless functionality
4-
In ESP32 Arduino, UART shall work correctly in order to let the user see DGB info
5-
and other application messages.
6-
7-
CPU Frequency is usually lowered in sleep modes
8-
and some other Low Power configurations
9-
10-
*/
11-
12-
int cpufreqs[6] = {240, 160, 80, 40, 20, 10};
13-
#define NUM_CPU_FREQS (sizeof(cpufreqs) / sizeof(int))
14-
15-
void setup() {
16-
17-
Serial.begin(115200);
18-
delay(1000);
19-
Serial.println("\n Starting...\n");
20-
Serial.flush();
21-
22-
// initial information
23-
uint32_t Freq = getCpuFrequencyMhz();
24-
Serial.print("CPU Freq = ");
25-
Serial.print(Freq);
26-
Serial.println(" MHz");
27-
Freq = getXtalFrequencyMhz();
28-
Serial.print("XTAL Freq = ");
29-
Serial.print(Freq);
30-
Serial.println(" MHz");
31-
Freq = getApbFrequency();
32-
Serial.print("APB Freq = ");
33-
Serial.print(Freq);
34-
Serial.println(" Hz");
35-
delay(500);
36-
37-
// ESP32-C3 and other RISC-V target may not support 240MHz
38-
#ifdef CONFIG_IDF_TARGET_ESP32C3
39-
uint8_t firstFreq = 1;
40-
#else
41-
uint8_t firstFreq = 0;
42-
#endif
43-
44-
// testing HardwareSerial for all possible CPU/APB Frequencies
45-
for (uint8_t i = firstFreq; i < NUM_CPU_FREQS; i++) {
46-
Serial.printf("\n------- Trying CPU Freq = %d ---------\n", cpufreqs[i]);
47-
Serial.flush(); // wait to empty the UART FIFO before changing the CPU Freq.
48-
setCpuFrequencyMhz(cpufreqs[i]);
49-
Serial.updateBaudRate(115200);
50-
51-
Freq = getCpuFrequencyMhz();
52-
Serial.print("CPU Freq = ");
53-
Serial.print(Freq);
54-
Serial.println(" MHz");
55-
Freq = getXtalFrequencyMhz();
56-
Serial.print("XTAL Freq = ");
57-
Serial.print(Freq);
58-
Serial.println(" MHz");
59-
Freq = getApbFrequency();
60-
Serial.print("APB Freq = ");
61-
Serial.print(Freq);
62-
Serial.println(" Hz");
63-
if (i < NUM_CPU_FREQS - 1) {
64-
Serial.println("Moving to the next frequency after a pause of 2 seconds.");
65-
delay(2000);
66-
}
67-
}
68-
Serial.println("\n-------------------\n");
69-
Serial.println("End of testing...");
70-
Serial.println("\n-------------------\n");
71-
}
72-
73-
void loop() {
74-
// Nothing here so far
75-
}
1+
/*
2+
Simple Sketch for testing HardwareSerial with different CPU Frequencies
3+
Changing the CPU Frequency may affect peripherals and Wireless functionality
4+
In ESP32 Arduino, UART shall work correctly in order to let the user see DGB info
5+
and other application messages.
6+
7+
CPU Frequency is usually lowered in sleep modes
8+
and some other Low Power configurations
9+
10+
*/
11+
12+
int cpufreqs[6] = {240, 160, 80, 40, 20, 10};
13+
#define NUM_CPU_FREQS (sizeof(cpufreqs) / sizeof(int))
14+
15+
void setup() {
16+
17+
Serial.begin(115200);
18+
delay(1000);
19+
Serial.println("\n Starting...\n");
20+
Serial.flush();
21+
22+
// initial information
23+
uint32_t Freq = getCpuFrequencyMhz();
24+
Serial.print("CPU Freq = ");
25+
Serial.print(Freq);
26+
Serial.println(" MHz");
27+
Freq = getXtalFrequencyMhz();
28+
Serial.print("XTAL Freq = ");
29+
Serial.print(Freq);
30+
Serial.println(" MHz");
31+
Freq = getApbFrequency();
32+
Serial.print("APB Freq = ");
33+
Serial.print(Freq);
34+
Serial.println(" Hz");
35+
delay(500);
36+
37+
// ESP32-C3 and other RISC-V target may not support 240MHz
38+
#ifdef CONFIG_IDF_TARGET_ESP32C3
39+
uint8_t firstFreq = 1;
40+
#else
41+
uint8_t firstFreq = 0;
42+
#endif
43+
44+
// testing HardwareSerial for all possible CPU/APB Frequencies
45+
for (uint8_t i = firstFreq; i < NUM_CPU_FREQS; i++) {
46+
Serial.printf("\n------- Trying CPU Freq = %d ---------\n", cpufreqs[i]);
47+
Serial.flush(); // wait to empty the UART FIFO before changing the CPU Freq.
48+
setCpuFrequencyMhz(cpufreqs[i]);
49+
Serial.updateBaudRate(115200);
50+
51+
Freq = getCpuFrequencyMhz();
52+
Serial.print("CPU Freq = ");
53+
Serial.print(Freq);
54+
Serial.println(" MHz");
55+
Freq = getXtalFrequencyMhz();
56+
Serial.print("XTAL Freq = ");
57+
Serial.print(Freq);
58+
Serial.println(" MHz");
59+
Freq = getApbFrequency();
60+
Serial.print("APB Freq = ");
61+
Serial.print(Freq);
62+
Serial.println(" Hz");
63+
if (i < NUM_CPU_FREQS - 1) {
64+
Serial.println("Moving to the next frequency after a pause of 2 seconds.");
65+
delay(2000);
66+
}
67+
}
68+
Serial.println("\n-------------------\n");
69+
Serial.println("End of testing...");
70+
Serial.println("\n-------------------\n");
71+
}
72+
73+
void loop() {
74+
// Nothing here so far
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* This is C++ example that demonstrates the usage of a std::function as OnReceive Callback function to all the UARTs
3+
* It basically defines a general onReceive function that receives an extra parameter, the Serial pointer that is
4+
* executing the callback.
5+
*
6+
* For each HardwareSerial object (Serial, Serial1, Serial2), it is necessary to set the callback with
7+
* the repective Serial pointer. It is done using lambda expression as a std::function.
8+
* Example:
9+
* Serial1.onReceive([]() { processOnReceiving(&Serial1); });
10+
*
11+
*/
12+
13+
// soc/soc_caps.h has information about each SoC target
14+
// in this example, we use SOC_UART_NUM that goes from 1 to 3,
15+
// depending on the number of available UARTs in the ESP32xx
16+
// This makes the code transparent to what SoC is used.
17+
#include "soc/soc_caps.h"
18+
19+
// In case that the target has USB CDC and it has being selected to be enable on boot,
20+
// the console output will into USB (Serial).
21+
// Otherwise the output will be sent to UART0 (Serial) and we have to redefine Serial0
22+
#ifndef ARDUINO_USB_CDC_ON_BOOT
23+
#define ARDUINO_USB_CDC_ON_BOOT 0
24+
#endif
25+
#if ARDUINO_USB_CDC_ON_BOOT == 0 // No USB CDC
26+
#define Serial0 Serial // redefine the symbol Serial0 to the default Arduino
27+
#endif
28+
29+
// This example shall use UART1 or UART2 for testing and UART0 for console messages
30+
// If UART0 is used for testing, it is necessary to manually send data to it, using the Serial Monitor/Terminal
31+
// In case that USB CDC is available, it may be used as console for messages.
32+
#define TEST_UART 1 // Serial# (0, 1 or 2) will be used for the loopback
33+
#define RXPIN 4 // GPIO 4 => RX for Serial1 or Serial2
34+
#define TXPIN 5 // GPIO 5 => TX for Serial1 or Serial2
35+
36+
// declare testingSerial (as reference) related to TEST_UART number defined above (only for Serial1 and Serial2)
37+
#if SOC_UART_NUM > 1 && TEST_UART == 1
38+
HardwareSerial &testingSerial = Serial1;
39+
#elif SOC_UART_NUM > 2 && TEST_UART == 2
40+
HardwareSerial &testingSerial = Serial2;
41+
#endif
42+
43+
// General callback function for any UART -- used with a lambda std::function within HardwareSerial::onReceive()
44+
void processOnReceiving(HardwareSerial &mySerial) {
45+
// detects which Serial# is being used here
46+
int8_t uart_num = -1;
47+
if (&mySerial == &Serial0) {
48+
uart_num = 0;
49+
#if SOC_UART_NUM > 1
50+
} else if (&mySerial == &Serial1) {
51+
uart_num = 1;
52+
#endif
53+
#if SOC_UART_NUM > 2
54+
} else if (&mySerial == &Serial2) {
55+
uart_num = 2;
56+
#endif
57+
}
58+
59+
//Prints some information on the current Serial (UART0 or USB CDC)
60+
if (uart_num == -1) {
61+
Serial.println("This is not a know Arduino Serial# object...");
62+
return;
63+
}
64+
Serial.printf("\nOnReceive Callback --> Received Data from UART%d\n", uart_num);
65+
Serial.printf("Received %d bytes\n", mySerial.available());
66+
Serial.printf("First byte is '%c' [0x%02x]\n", mySerial.peek(), mySerial.peek());
67+
uint8_t charPerLine = 0;
68+
while(mySerial.available()) {
69+
char c = mySerial.read();
70+
Serial.printf("'%c' [0x%02x] ", c, c);
71+
if (++charPerLine == 10) {
72+
charPerLine = 0;
73+
Serial.println();
74+
}
75+
}
76+
}
77+
78+
void setup() {
79+
// Serial can be the USB or UART0, depending on the settings and which SoC is used
80+
Serial.begin(115200);
81+
82+
// when data is received from UART0, it will call the general function
83+
// passing Serial0 as parameter for processing
84+
#if TEST_UART == 0
85+
Serial0.begin(115200); // keeps default GPIOs
86+
Serial0.onReceive([]() {
87+
processOnReceiving(Serial0);
88+
});
89+
#else
90+
// and so on for the other UARTs (Serial1 and Serial2)
91+
// Rx = 4, Tx = 5 will work for ESP32, S2, S3, C3, C6 and H2
92+
testingSerial.begin(115200, SERIAL_8N1, RXPIN, TXPIN);
93+
testingSerial.onReceive([]() {
94+
processOnReceiving(testingSerial);
95+
});
96+
#endif
97+
98+
// this helper function will connect TX pin (from TEST_UART number) to its RX pin
99+
// creating a loopback that will allow to write to TEST_UART number
100+
// and send it to RX with no need to physically connect both pins
101+
#if TEST_UART > 0
102+
uart_internal_loopback(TEST_UART, RXPIN);
103+
#else
104+
// when UART0 is used for testing, it is necessary to send data using the Serial Monitor/Terminal
105+
// Data must be sent by the CP2102, manually using the Serial Monitor/Terminal
106+
#endif
107+
108+
delay(500);
109+
Serial.printf("\nSend bytes to UART%d in order to\n", TEST_UART);
110+
Serial.println("see a single processing fuction display information about");
111+
Serial.println("the received data.\n");
112+
113+
}
114+
115+
void loop() {
116+
// All done by the UART callback functions
117+
// just write a random number of bytes into the testing UART
118+
char serial_data[24];
119+
size_t len = random(sizeof(serial_data) - 1) + 1; // at least 1 byte will be sent
120+
for (uint8_t i = 0; i < len; i++) serial_data[i] = 'A' + i;
121+
122+
#if TEST_UART > 0
123+
Serial.println("\n\n==================================");
124+
Serial.printf("Sending %d bytes to UART%d...\n", len, TEST_UART);
125+
testingSerial.write(serial_data, len);
126+
#else
127+
// when UART0 is used for testing, it is necessary to send data using the Serial Monitor/Terminal
128+
Serial.println("Use the Serial Monitor/Terminal to send data to UART0");
129+
#endif
130+
Serial.println("pausing for 15 seconds.");
131+
delay(15000);
132+
}
133+

0 commit comments

Comments
 (0)