Fixes Serial Example and Adds a new std:func Serial Example (#8409)

* fixes example folder

* adds new Serial std::func example
This commit is contained in:
Rodrigo Garcia 2023-07-17 06:50:41 -03:00 committed by GitHub
parent e7ceeb1b04
commit 1945778e82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 208 additions and 75 deletions

View File

@ -1,75 +1,75 @@
/*
Simple Sketch for testing HardwareSerial with different CPU Frequencies
Changing the CPU Frequency may affect peripherals and Wireless functionality
In ESP32 Arduino, UART shall work correctly in order to let the user see DGB info
and other application messages.
CPU Frequency is usually lowered in sleep modes
and some other Low Power configurations
*/
int cpufreqs[6] = {240, 160, 80, 40, 20, 10};
#define NUM_CPU_FREQS (sizeof(cpufreqs) / sizeof(int))
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n Starting...\n");
Serial.flush();
// initial information
uint32_t Freq = getCpuFrequencyMhz();
Serial.print("CPU Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getXtalFrequencyMhz();
Serial.print("XTAL Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getApbFrequency();
Serial.print("APB Freq = ");
Serial.print(Freq);
Serial.println(" Hz");
delay(500);
// ESP32-C3 and other RISC-V target may not support 240MHz
#ifdef CONFIG_IDF_TARGET_ESP32C3
uint8_t firstFreq = 1;
#else
uint8_t firstFreq = 0;
#endif
// testing HardwareSerial for all possible CPU/APB Frequencies
for (uint8_t i = firstFreq; i < NUM_CPU_FREQS; i++) {
Serial.printf("\n------- Trying CPU Freq = %d ---------\n", cpufreqs[i]);
Serial.flush(); // wait to empty the UART FIFO before changing the CPU Freq.
setCpuFrequencyMhz(cpufreqs[i]);
Serial.updateBaudRate(115200);
Freq = getCpuFrequencyMhz();
Serial.print("CPU Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getXtalFrequencyMhz();
Serial.print("XTAL Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getApbFrequency();
Serial.print("APB Freq = ");
Serial.print(Freq);
Serial.println(" Hz");
if (i < NUM_CPU_FREQS - 1) {
Serial.println("Moving to the next frequency after a pause of 2 seconds.");
delay(2000);
}
}
Serial.println("\n-------------------\n");
Serial.println("End of testing...");
Serial.println("\n-------------------\n");
}
void loop() {
// Nothing here so far
}
/*
Simple Sketch for testing HardwareSerial with different CPU Frequencies
Changing the CPU Frequency may affect peripherals and Wireless functionality
In ESP32 Arduino, UART shall work correctly in order to let the user see DGB info
and other application messages.
CPU Frequency is usually lowered in sleep modes
and some other Low Power configurations
*/
int cpufreqs[6] = {240, 160, 80, 40, 20, 10};
#define NUM_CPU_FREQS (sizeof(cpufreqs) / sizeof(int))
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n Starting...\n");
Serial.flush();
// initial information
uint32_t Freq = getCpuFrequencyMhz();
Serial.print("CPU Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getXtalFrequencyMhz();
Serial.print("XTAL Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getApbFrequency();
Serial.print("APB Freq = ");
Serial.print(Freq);
Serial.println(" Hz");
delay(500);
// ESP32-C3 and other RISC-V target may not support 240MHz
#ifdef CONFIG_IDF_TARGET_ESP32C3
uint8_t firstFreq = 1;
#else
uint8_t firstFreq = 0;
#endif
// testing HardwareSerial for all possible CPU/APB Frequencies
for (uint8_t i = firstFreq; i < NUM_CPU_FREQS; i++) {
Serial.printf("\n------- Trying CPU Freq = %d ---------\n", cpufreqs[i]);
Serial.flush(); // wait to empty the UART FIFO before changing the CPU Freq.
setCpuFrequencyMhz(cpufreqs[i]);
Serial.updateBaudRate(115200);
Freq = getCpuFrequencyMhz();
Serial.print("CPU Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getXtalFrequencyMhz();
Serial.print("XTAL Freq = ");
Serial.print(Freq);
Serial.println(" MHz");
Freq = getApbFrequency();
Serial.print("APB Freq = ");
Serial.print(Freq);
Serial.println(" Hz");
if (i < NUM_CPU_FREQS - 1) {
Serial.println("Moving to the next frequency after a pause of 2 seconds.");
delay(2000);
}
}
Serial.println("\n-------------------\n");
Serial.println("End of testing...");
Serial.println("\n-------------------\n");
}
void loop() {
// Nothing here so far
}

View File

@ -0,0 +1,133 @@
/*
* This is C++ example that demonstrates the usage of a std::function as OnReceive Callback function to all the UARTs
* It basically defines a general onReceive function that receives an extra parameter, the Serial pointer that is
* executing the callback.
*
* For each HardwareSerial object (Serial, Serial1, Serial2), it is necessary to set the callback with
* the repective Serial pointer. It is done using lambda expression as a std::function.
* Example:
* Serial1.onReceive([]() { processOnReceiving(&Serial1); });
*
*/
// soc/soc_caps.h has information about each SoC target
// in this example, we use SOC_UART_NUM that goes from 1 to 3,
// depending on the number of available UARTs in the ESP32xx
// This makes the code transparent to what SoC is used.
#include "soc/soc_caps.h"
// In case that the target has USB CDC and it has being selected to be enable on boot,
// the console output will into USB (Serial).
// Otherwise the output will be sent to UART0 (Serial) and we have to redefine Serial0
#ifndef ARDUINO_USB_CDC_ON_BOOT
#define ARDUINO_USB_CDC_ON_BOOT 0
#endif
#if ARDUINO_USB_CDC_ON_BOOT == 0 // No USB CDC
#define Serial0 Serial // redefine the symbol Serial0 to the default Arduino
#endif
// This example shall use UART1 or UART2 for testing and UART0 for console messages
// If UART0 is used for testing, it is necessary to manually send data to it, using the Serial Monitor/Terminal
// In case that USB CDC is available, it may be used as console for messages.
#define TEST_UART 1 // Serial# (0, 1 or 2) will be used for the loopback
#define RXPIN 4 // GPIO 4 => RX for Serial1 or Serial2
#define TXPIN 5 // GPIO 5 => TX for Serial1 or Serial2
// declare testingSerial (as reference) related to TEST_UART number defined above (only for Serial1 and Serial2)
#if SOC_UART_NUM > 1 && TEST_UART == 1
HardwareSerial &testingSerial = Serial1;
#elif SOC_UART_NUM > 2 && TEST_UART == 2
HardwareSerial &testingSerial = Serial2;
#endif
// General callback function for any UART -- used with a lambda std::function within HardwareSerial::onReceive()
void processOnReceiving(HardwareSerial &mySerial) {
// detects which Serial# is being used here
int8_t uart_num = -1;
if (&mySerial == &Serial0) {
uart_num = 0;
#if SOC_UART_NUM > 1
} else if (&mySerial == &Serial1) {
uart_num = 1;
#endif
#if SOC_UART_NUM > 2
} else if (&mySerial == &Serial2) {
uart_num = 2;
#endif
}
//Prints some information on the current Serial (UART0 or USB CDC)
if (uart_num == -1) {
Serial.println("This is not a know Arduino Serial# object...");
return;
}
Serial.printf("\nOnReceive Callback --> Received Data from UART%d\n", uart_num);
Serial.printf("Received %d bytes\n", mySerial.available());
Serial.printf("First byte is '%c' [0x%02x]\n", mySerial.peek(), mySerial.peek());
uint8_t charPerLine = 0;
while(mySerial.available()) {
char c = mySerial.read();
Serial.printf("'%c' [0x%02x] ", c, c);
if (++charPerLine == 10) {
charPerLine = 0;
Serial.println();
}
}
}
void setup() {
// Serial can be the USB or UART0, depending on the settings and which SoC is used
Serial.begin(115200);
// when data is received from UART0, it will call the general function
// passing Serial0 as parameter for processing
#if TEST_UART == 0
Serial0.begin(115200); // keeps default GPIOs
Serial0.onReceive([]() {
processOnReceiving(Serial0);
});
#else
// and so on for the other UARTs (Serial1 and Serial2)
// Rx = 4, Tx = 5 will work for ESP32, S2, S3, C3, C6 and H2
testingSerial.begin(115200, SERIAL_8N1, RXPIN, TXPIN);
testingSerial.onReceive([]() {
processOnReceiving(testingSerial);
});
#endif
// this helper function will connect TX pin (from TEST_UART number) to its RX pin
// creating a loopback that will allow to write to TEST_UART number
// and send it to RX with no need to physically connect both pins
#if TEST_UART > 0
uart_internal_loopback(TEST_UART, RXPIN);
#else
// when UART0 is used for testing, it is necessary to send data using the Serial Monitor/Terminal
// Data must be sent by the CP2102, manually using the Serial Monitor/Terminal
#endif
delay(500);
Serial.printf("\nSend bytes to UART%d in order to\n", TEST_UART);
Serial.println("see a single processing fuction display information about");
Serial.println("the received data.\n");
}
void loop() {
// All done by the UART callback functions
// just write a random number of bytes into the testing UART
char serial_data[24];
size_t len = random(sizeof(serial_data) - 1) + 1; // at least 1 byte will be sent
for (uint8_t i = 0; i < len; i++) serial_data[i] = 'A' + i;
#if TEST_UART > 0
Serial.println("\n\n==================================");
Serial.printf("Sending %d bytes to UART%d...\n", len, TEST_UART);
testingSerial.write(serial_data, len);
#else
// when UART0 is used for testing, it is necessary to send data using the Serial Monitor/Terminal
Serial.println("Use the Serial Monitor/Terminal to send data to UART0");
#endif
Serial.println("pausing for 15 seconds.");
delay(15000);
}