Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 27 additions & 20 deletions .github/workflows/build_and_publish_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,38 @@ jobs:
sudo apt-get install doxygen graphviz texlive-full pandoc
pip install -r doc/requirements.txt

- name: Build Documentation
- name: Build Documentation (HTML)
run: |
cd doc
# ignore if the following command fails
build-docs -bs html -t esp32 -l en --project-path ../ --source-dir ./ --doxyfile_dir ./ || true
mkdir -p ../docs
cp -r _build/en/esp32/html/* ../docs/.
# go to the latex output
cd _build/en/esp32/latex/
# use xelatex because the generated docs include Unicode characters
# that pdflatex cannot render reliably
xelatex -interaction=batchmode refman || true
# build again to make sure page numbers and refs and such work (ignore if command fails)
xelatex -interaction=batchmode refman || true
if [ -f refman.pdf ]; then
mv refman.pdf espp_documentation.pdf
if [ -d _build/en/esp32/html ]; then
build_dir_from_doc=_build/en/esp32
build_dir_root=doc/_build/en/esp32
elif [ -d ../_build/en/esp32/html ]; then
build_dir_from_doc=../_build/en/esp32
build_dir_root=_build/en/esp32
else
echo "Unable to find generated documentation output directory." >&2
exit 1
fi
# set a variable to indicate whether the PDF was generated successfully
if [ -f espp_documentation.pdf ]; then
echo "DOC_BUILD_DIR_FROM_DOC=${build_dir_from_doc}" >> $GITHUB_ENV
echo "DOC_BUILD_DIR_ROOT=${build_dir_root}" >> $GITHUB_ENV
# copy the generated HTML files to the docs directory for GitHub Pages
mkdir -p ../docs
cp -r "${build_dir_from_doc}/html/"* ../docs/.

- name: Build Documentation (PDF)
run: |
cd doc
if sh ./build_latex_pdf.sh "${DOC_BUILD_DIR_FROM_DOC}/latex"; then
echo "PDF_GENERATED=true" >> $GITHUB_ENV
echo "Success: PDF documentation generated successfully."
else
rm -f "${DOC_BUILD_DIR_FROM_DOC}/latex/refman.pdf"
rm -f "${DOC_BUILD_DIR_FROM_DOC}/latex/espp_documentation.pdf"
echo "PDF_GENERATED=false" >> $GITHUB_ENV
fi
# warn if the PDF was not generated successfully
if [ "$PDF_GENERATED" = "false" ]; then
# warn if the PDF was not generated successfully
echo "Warning: PDF documentation was not generated successfully."
fi

Expand All @@ -65,15 +72,15 @@ jobs:
publish_dir: ./docs
force_orphan: true

- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v5
if: env.PDF_GENERATED == 'true'
with:
name: espp_documentation.pdf
path: doc/_build/en/esp32/latex/espp_documentation.pdf
path: ${{ env.DOC_BUILD_DIR_ROOT }}/latex/espp_documentation.pdf

- name: Attach files to release
uses: softprops/action-gh-release@v2
if: ${{ github.event.release && github.event.action == 'published' && env.PDF_GENERATED == 'true' }}
with:
files: |
doc/_build/en/esp32/latex/espp_documentation.pdf
${{ env.DOC_BUILD_DIR_ROOT }}/latex/espp_documentation.pdf
8 changes: 4 additions & 4 deletions components/cobs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The COBS component provides efficient encoding and decoding for the Consistent O
## Features

- **Zero-byte elimination**: Removes all zero bytes from data, using them as packet delimiters
- **Consistent overhead**: Maximum overhead of n/254 + 1 bytes per packet
- **Consistent overhead**: Maximum overhead of ceil(n/254) + 1 bytes per packet
- **Simple framing**: Uses zero bytes as reliable packet delimiters
- **Streaming support**: Handle fragmented data streams and batch multiple packets
- **Thread-safe**: Streaming classes are thread-safe with internal locking
Expand Down Expand Up @@ -170,7 +170,7 @@ decoder.clear();


**Buffer Size Formulas:**
- **`max_encoded_size(payload_len)`**: `payload_len + payload_len/254 + 2`
- **`max_encoded_size(payload_len)`**: `payload_len + ceil(payload_len/254) + 2`
- **`max_decoded_size(encoded_len)`**: `encoded_len - 1` (accounts for delimiter)

## COBS Algorithm Details
Expand All @@ -179,7 +179,7 @@ COBS works by:
1. **Eliminating zeros**: All zero bytes are removed from the data
2. **Adding overhead bytes**: Each block of non-zero data gets a length prefix
3. **Using zero as delimiter**: A single zero byte marks the end of each packet
4. **Consistent overhead**: Maximum overhead is n/254 + 1 bytes per packet
4. **Consistent overhead**: Maximum overhead is ceil(n/254) + 1 bytes per packet

### Example Encoding
```
Expand All @@ -197,7 +197,7 @@ Output: [0x03, 0x01, 0x02, 0x02, 0x03, 0x04, 0x00]

## Performance Characteristics

- **Encoding overhead**: At most n/254 + 1 bytes per packet
- **Encoding overhead**: At most ceil(n/254) + 1 bytes per packet
- **Decoding complexity**: O(n) where n is packet size
- **Speed**: Optimized for embedded systems with minimal overhead
- **Large packet support**: Tested and verified with packets up to 1000+ bytes
Expand Down
3 changes: 2 additions & 1 deletion components/cobs/include/cobs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ namespace espp {
*
* Provides single-packet encoding and decoding using the COBS algorithm
* with 0 as the delimiter.
* COBS encoding can add at most ⌈n/254⌉ + 1 bytes overhead. Plus 1 byte for the delimiter
* COBS encoding can add at most ceil(n/254) + 1 bytes overhead, plus 1 byte
* for the delimiter.
* COBS changes the size of the packet by at least 1 byte, so it's not possible to encode in
* place. MAX_BLOCK_SIZE = 254 is the maximum number of non-zero bytes in an encoded block.
*
Expand Down
12 changes: 6 additions & 6 deletions components/color/include/color.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ class Hsv;
*/
class Rgb {
public:
float r{0}; ///< Red value [0, 1]
float g{0}; ///< Green value [0, 1]
float b{0}; ///< Blue value [0, 1]
float r{0}; ///< Red value in [0, 1]
float g{0}; ///< Green value in [0, 1]
float b{0}; ///< Blue value in [0, 1]

Rgb() = default;

Expand Down Expand Up @@ -106,9 +106,9 @@ class Rgb {
*/
class Hsv {
public:
float h{0}; ///< Hue [0, 360]
float s{0}; ///< Saturation [0, 1]
float v{0}; ///< Value [0, 1]
float h{0}; ///< Hue in [0, 360]
float s{0}; ///< Saturation in [0, 1]
float v{0}; ///< Value in [0, 1]

Hsv() = default;

Expand Down
4 changes: 2 additions & 2 deletions components/rx8130ce/example/main/rx8130ce_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ extern "C" void app_main(void) {

// Check alarm
if (rtc.is_alarm_triggered(ec) && !ec) {
logger.info("🚨 ALARM TRIGGERED!");
logger.info("ALARM TRIGGERED!");
rtc.clear_alarm_flag(ec);
}

// Check timer
if (rtc.is_timer_expired(ec) && !ec) {
logger.info("TIMER EXPIRED!");
logger.info("TIMER EXPIRED!");
rtc.clear_timer_flag(ec);

// Restart timer for another 5 seconds
Expand Down
22 changes: 10 additions & 12 deletions components/tabulate/example/main/tabulate_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ extern "C" void app_main(void) {
Table universal_constants;

universal_constants.add_row({"Quantity", "Value"});
universal_constants.add_row({"Characteristic impedance of vacuum", "376.730 313 461... Ω"});
universal_constants.add_row({"Characteristic impedance of vacuum", "376.730 313 461... Ohm"});
universal_constants.add_row(
{"Electric constant (permittivity of free space)", "8.854 187 817... × 10⁻¹²F·m⁻¹"});
{"Electric constant (permittivity of free space)", "8.854 187 817... x 10^-12 F*m^-1"});
universal_constants.add_row({"Magnetic constant (permeability of free space)",
"4π × 10⁻⁷ N·A⁻² = 1.2566 370 614... × 10⁻⁶ N·A⁻²"});
"4*pi x 10^-7 N*A^-2 = 1.2566 370 614... x 10^-6 N*A^-2"});
universal_constants.add_row({"Gravitational constant (Newtonian constant of gravitation)",
"6.6742(10) × 10⁻¹¹m³·kg⁻¹·s⁻²"});
universal_constants.add_row({"Planck's constant", "6.626 0693(11) × 10⁻³⁴ J·s"});
universal_constants.add_row({"Dirac's constant", "1.054 571 68(18) × 10⁻³⁴ J·s"});
universal_constants.add_row({"Speed of light in vacuum", "299 792 458 m·s⁻¹"});
"6.6742(10) x 10^-11 m^3*kg^-1*s^-2"});
universal_constants.add_row({"Planck's constant", "6.626 0693(11) x 10^-34 J*s"});
universal_constants.add_row({"Dirac's constant", "1.054 571 68(18) x 10^-34 J*s"});
universal_constants.add_row({"Speed of light in vacuum", "299 792 458 m*s^-1"});

universal_constants.format()
.font_style({FontStyle::bold})
Expand Down Expand Up @@ -99,7 +99,7 @@ extern "C" void app_main(void) {
Table readme;
readme.format().border_color(Color::yellow);

readme.add_row(Row_t{"🔥tabulate for Modern C++🔥"});
readme.add_row(Row_t{"tabulate for Modern C++"});
readme[0].format().font_align(FontAlign::center).font_color(Color::yellow);

readme.add_row(Row_t{"https://github.com/p-ranav/tabulate"});
Expand Down Expand Up @@ -182,9 +182,7 @@ extern "C" void app_main(void) {

readme[9].format().hide_border_top().border_color(Color::white).font_color(Color::yellow);

readme.add_row(Row_t{"ᚠ ᚡ ᚢ ᚣ ᚤ ᚥ ᚦ ᚧ ᚨ ᚩ ᚪ ᚫ ᚬ ᚭ ᚮ ᚯ ᚰ ᚱ ᚲ ᚳ ᚴ ᚵ ᚶ ᚷ ᚸ ᚹ ᚺ "
"ᚻ ᚼ ᚽ ᚾ ᚿ ᛀ ᛁ ᛂ ᛃ ᛄ ᛅ ᛆ ᛇ "
"ᛈ ᛉ ᛊ ᛋ ᛌ ᛍ ᛎ ᛏ ᛐ ᛑ ᛒ ᛓ"});
readme.add_row(Row_t{"Multi-byte sample text rendered in a PDF-friendly ASCII form."});
readme[10]
.format()
.font_background_color(Color::red)
Expand Down Expand Up @@ -301,7 +299,7 @@ extern "C" void app_main(void) {
chart[8][17].set_text("This one's yellow and right-aligned");
chart[8][17].format().color(Color::yellow).font_align(FontAlign::right);

chart[9][17].set_text("This one's on 🔥🔥🔥");
chart[9][17].set_text("This one's on fire!");

std::cout << chart;
std::cout << legend << "\n\n";
Expand Down
2 changes: 1 addition & 1 deletion components/thermistor/example/main/thermistor_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ extern "C" void app_main(void) {
// https://product.tdk.com/system/files/dam/doc/product/sensor/ntc/chip-ntc-thermistor/catalog/tpd_commercial_ntc-thermistor_ntcg_en.pdf
// From the table (page 7):
// clang-format off
// Part Number. | R25(Ω) | Tolerance | B25/50(Κ) | B25/75(Κ) | B25/85(Κ) | B25/100(K) | Current (mA) | Operating Temp Range
// Part Number. | R25(Ohm) | Tolerance | B25/50(K) | B25/75(K) | B25/85(K) | B25/100(K) | Current (mA) | Operating Temp Range
// NTCG103JF103FT1 | 10,000 | +/–1% | 3380 | 3422 | 3435 | 3453 +/–1% | 0.31 | –40 to 152
// clang-format on
espp::Thermistor thermistor({.divider_config = espp::Thermistor::ResistorDividerConfig::UPPER,
Expand Down
6 changes: 5 additions & 1 deletion doc/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ PROJECT_NAME = "Espressif++ (ESPP), an ESP C++ Library"
##
QUIET = YES

INLINE_SOURCES = YES
# Keep inline sources out of the generated LaTeX/PDF output. Some example/source
# listings contain rich Unicode that is fine in code and HTML, but makes the
# standalone Doxygen PDF build unreliable.
INLINE_SOURCES = NO


# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
Expand Down
59 changes: 59 additions & 0 deletions doc/build_latex_pdf.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/bin/sh
set -eu

if [ "$#" -ne 1 ]; then
echo "usage: build_latex_pdf.sh <latex_dir>" >&2
exit 2
fi

latex_dir=$1
if [ ! -d "$latex_dir" ]; then
echo "latex directory not found: $latex_dir" >&2
exit 1
fi
latex_dir=$(
CDPATH= cd -- "$latex_dir" && pwd
)

script_dir=$(
CDPATH= cd -- "$(dirname -- "$0")" && pwd
)

success=0
cleanup() {
if [ "$success" -ne 1 ]; then
rm -f "$latex_dir/refman.pdf" "$latex_dir/espp_documentation.pdf"
fi
}
trap cleanup EXIT HUP INT TERM

rm -f \
"$latex_dir/refman.pdf" \
"$latex_dir/espp_documentation.pdf" \
"$latex_dir/refman.aux" \
"$latex_dir/refman.fdb_latexmk" \
"$latex_dir/refman.fls" \
"$latex_dir/refman.idx" \
"$latex_dir/refman.ilg" \
"$latex_dir/refman.ind" \
"$latex_dir/refman.log" \
"$latex_dir/refman.lof" \
"$latex_dir/refman.lot" \
"$latex_dir/refman.out" \
"$latex_dir/refman.synctex.gz" \
"$latex_dir/refman.toc"

python3 "$script_dir/patch_doxygen_latex.py" "$latex_dir"

cd "$latex_dir"
pdflatex -interaction=batchmode -halt-on-error refman.tex
python3 "$script_dir/patch_doxygen_latex.py" "$latex_dir"
pdflatex -interaction=batchmode -halt-on-error refman.tex

if [ ! -s refman.pdf ]; then
echo "refman.pdf was not generated" >&2
exit 1
fi

cp refman.pdf espp_documentation.pdf
success=1
6 changes: 0 additions & 6 deletions doc/conf_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,3 @@

idf_targets = ['esp32', 'esp32s2', 'esp32c3']
languages = ['en']

# The generated API/README content includes Unicode characters such as Ω, π,
# emoji, and other symbols that pdflatex cannot handle reliably. Use xelatex so
# the PDF docs build stays aligned with the HTML sources instead of requiring
# per-character LaTeX escape maintenance.
latex_engine = 'xelatex'
2 changes: 1 addition & 1 deletion doc/en/cobs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Overhead Byte Stuffing algorithm, a packet framing protocol that ensures reliabl
packet boundaries in communication streams.

Key features:
* Zero-byte elimination with consistent overhead (max n/254 + 1 bytes)
* Zero-byte elimination with consistent overhead (max ceil(n/254) + 1 bytes)
* Single packet API for basic encoding/decoding
* Streaming API with thread-safe encoder/decoder classes
* Support for fragmented data streams and packet batching
Expand Down
Loading
Loading