Where to find ESP32S2 bare chip reference schematic?

If you are not using the ESP32S2 as a module but as a chip, you need a reference schematic to check if you have errors in a schematic.

A good place to start is by checking out the schematic of the ESP32S2-MINI, which you can find on page 19 & 20 of the module datasheet.

Posted by Uli Köhler in Allgemein

What is SYS_STARTUP_FN() on the ESP32?

SYS_STARTUP_FN() is being called at the end of call_start_cpu0() during the app startup process (after the bootloader has already finished executing).

It essentially just calls the function pointer g_startup_fn for the current core:

#define SYS_STARTUP_FN()  ((*g_startup_fn[(cpu_hal_get_core_id())])())
g_startup_fn, in turn, is defined to basically start_cpu0 and start_cpu1 in this rather convoluted but still conceptually easy code.

 

Posted by Uli Köhler in Embedded, ESP8266/ESP32

Where is esp_startup_start_app_common() started on the ESP32 (ESP-IDF)?

esp_startup_start_app_common() is called in start_cpu0_default(), which is located in components/esp_system/startup.c
Note that start_cpu0_default() is a weak alias for start_cpu0().

For version 4.4.1 of the ESP-IDF, this is the link to the location where it is called.

Posted by Uli Köhler in Embedded, ESP8266/ESP32

Where is esp_startup_start_app_common() started on the ESP32 (ESP-IDF)?

esp_startup_start_app_common() is called in esp_startup_start_app(), which is a function specific to the architecture (xtensa or riscv).

For version 4.4.1 of the ESP-IDF, this is the link to the location where it is called for the xtensa port.

Posted by Uli Köhler in Embedded, ESP8266/ESP32

Where is the bootloader_init() source code for the ESP32?

In the ESP32 bootloader_start.c, you can see that bootloader_init() is called during bootloader startup:

if (bootloader_init() != ESP_OK) {
    bootloader_reset();
}

The implementation of bootloader_init() is sightly harder to find because it is not located in components/bootloader but components/bootloader_support, within a specific platform-specific subdirectory, for example in components/bootloader_support/src/esp32s2/bootloader_esp32s2.c for the ESP32S2 – Github link to the v4.4.1 source code.

 

 

Posted by Uli Köhler in Embedded, ESP8266/ESP32

Where is main_task() started on the ESP32 (ESP-IDF)?

The FreeRTOS main taskmain_task() (which in turn starts app_main()) is  started in esp_startup_start_app_common():

portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main",
                                            ESP_TASK_MAIN_STACK, NULL,
                                            ESP_TASK_MAIN_PRIO, NULL, ESP_TASK_MAIN_CORE);

 

For version 4.4.1 of the ESP-IDF, this is the link to the location where it is called.

Posted by Uli Köhler in Embedded, ESP8266/ESP32

What are the default UART0 RX/TX pins for the ESP32S2?

As shown in the ESP32S2 datasheet:

  • U0TXD (UART 0 transmit) is GPIO43, which is pin 48 in the QFN56 package#
  • U0RXD is GPIO44, which is pin 49 in the QFN56 package
Posted by Uli Köhler in Embedded, ESP8266/ESP32

What is SPI flash manufacturer C2 / Device 2016

Flash manufacturer C2 is Macronix.

I have seen Manufacturer C2 / device ID 2016 via esptool.py flash_id in a Macronix MX25L3233FM1I-08Q 32-Mbit (4MByte) QSPI flash.

Posted by Uli Köhler in Electronics

What is SPI flash manufacturer 20 / Device ID 4016

I have seen Manufacturer 20, device 4016 via esptool.py flash_id in a SOICW-8 flash device in a ESP8266 module. It is labeled XMC and P50H32C

It is a 32Mbit (4Mbyte) flash device.

Posted by Uli Köhler in Embedded

Which pins are USB D+/D- on the ESP32S2?

As listed in the ESP32S2 datasheet,

  • GPIO19 is USB-D-
  • GPIO20 is USB-D+
Posted by Uli Köhler in Electronics, Embedded, ESP8266/ESP32

How to fix VFS: cifs_mount failed w/return code = -22

Problem:

When trying to mount a CIFS/SMB share, you see the following error log in dmesg:

[  139.680974] CIFS: Attempting to mount \\10.10.10.10\test
[  139.686714] CIFS: VFS: cifs_mount failed w/return code = -22

Solution:

This is a currently a bug in Samba or the Kernel but you can easily work around it by adding vers=2.0to the mount options, either in /etc/fstab or if using mount manually, by using the -o vers=2.0 option. This forces Samba to use SMB version 2.0 which does not have the bug.

Posted by Uli Köhler in Linux, Networking

How to fix PlatformIO No such file or directory bootloader__80m.bin/bootloader__40m.bin

Problem:

While trying to upload/flash an ESP32(S2/S3) project using PlatformIO with a platformio.ini like this:

[env:esp32-s2-saola-1]
platform = espressif32
board = esp32-s2-saola-1
framework = arduino

you see an error message like

esptool write_flash: error: argument <address> <filename>: [Errno 2] No such file or directory: '/home/uli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32s2/bin/bootloader__80m.bin'
*** [upload] Error 2

or

esptool write_flash: error: argument <address> <filename>: [Errno 2] No such file or directory: '/home/uli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/bin/bootloader__40m.bin'

Solution:

This is a bug in version 2.0.4 of the arduino-espressif32 framework. In order to work around it, use version 2.0.3 until this bux is fixed. You can do this by appending

platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.3

to platformio.ini. Full example:

[env:esp32dev]
platform = espressif32
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.3
board = esp32dev
framework = arduino

 

Posted by Uli Köhler in Arduino, ESP8266/ESP32, PlatformIO

Minimal boost::asio::serial_port read (read_some) example

The following example shows how to initialize a boost::asio serial_port , set its baud rate, parity & stop bits and then read data from it in a loop, printing the data to stdout as-is.

#include <boost/asio.hpp>
#include <iostream>

#define BUFSIZE 256

int main() {
    boost::asio::io_service io;
    // Open serial port
    boost::asio::serial_port serial(io, "/dev/ttyUSB0");

    // Configure basic serial port parameters: 115.2kBaud, 8N1
    serial.set_option(boost::asio::serial_port_base::baud_rate(115200));
    serial.set_option(boost::asio::serial_port_base::character_size(8 /* data bits */));
    serial.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none));
    serial.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));

    // Read data in a loop and copy to stdout
    while(true) {
        char data[BUFSIZE];
        size_t n = serial.read_some(boost::asio::buffer(data, BUFSIZE));
        // Write data to stdout
        std::cout.write(data, n);
    }
}

For a more complete example that also shows how to open the serial port, see How to open & initialize boost::asio::serial_port

Posted by Uli Köhler in Boost, C/C++

How to set baud rate & parity on boost::asio::serial_port

This example shows how to baudrate, parity & stop bits:

// Configure serial port parameters: 115.2kBaud, 8N1
serial.set_option(boost::asio::serial_port_base::baud_rate(115200));
serial.set_option(boost::asio::serial_port_base::character_size(8 /* data bits */));
serial.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none));
serial.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));

For a more complete example that also shows how to open the serial port, see How to open & initialize boost::asio::serial_port or our Minimal boost::asio::serial_port read (read_some) example

Posted by Uli Köhler in Boost, C/C++

How to open & initialize boost::asio::serial_port

This example shows how to open a boost serial port and how to set the baudrate, parity & stop bits:

boost::asio::io_service io;
// Open serial port
boost::asio::serial_port serial(io, "/dev/ttyUSB0");

// Configure basic serial port parameters: 115.2kBaud, 8N1
serial.set_option(boost::asio::serial_port_base::baud_rate(115200));
serial.set_option(boost::asio::serial_port_base::character_size(8 /* data bits */));
serial.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none));
serial.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));

Also see our Minimal boost::asio::serial_port read (read_some) example

Posted by Uli Köhler in Boost, C/C++

How to initialize struct sockaddr_in using initializer lists

This way of initializing a struct sockaddr_in uses modern C and avoids all the raw of days that should long be forgotten, at least for most applications. I use this approach successfully e.g. for ESP32 microcontrollers.

struct sockaddr_in server_addr = {
    .sin_family = AF_INET,
    .sin_port = htons(46118),
    .sin_addr = {.s_addr = htonl(INADDR_ANY)}
};

 

Posted by Uli Köhler in C/C++, ESP8266/ESP32, PlatformIO

ESP32 Filesystem initialization code example (LittleFS)

This example code takes care of mounting the filesystem, or creating a filesystem if none is present.

#pragma once
#include <stddef.h>

// InitFilesystem() sets this to true if the filesystem is available.
extern volatile bool filesystemOK;

void InitFilesystem();
#include "FS.h"
#include "LittleFS.h"

volatile bool filesystemOK = false;

void InitFilesystem() {
  // Initialize LittleFS
  if (!LittleFS.begin(false /* false: Do not format if mount failed */)) {
    Serial.println("Failed to mount LittleFS");
    if (!LittleFS.begin(true /* true: format */)) {
      Serial.println("Failed to format LittleFS");
    } else {
      Serial.println("LittleFS formatted successfully");
      filesystemOK = true;
    }
  } else { // Initial mount success
    filesystemOK = true;
  }
}

 

Posted by Uli Köhler in C/C++, ESP8266/ESP32

What AC coupling capacitors value should you use for 100Base-FX (SFP)?

Using either 10 nF capacitors or 100 nF capacitors. My recommendation is to go with 10 nF unless you have a specific reason to use 10 nF caps. The argument to use lower value capacitors is to reject more lower-frequency common mode noise which might be overlaid on the high speed signal.

Note that many SFP modules already contain AC coupling capacitors.

X5R or X7R capacitors should be fine, you don’t need to use NP0/C0G for this.

Sources:
Marvell 88E3015/88E3018 datasheet, section 6.2, figure 34: 10nF

Microchip application note, page 14 reference schematic: 100nF

Posted by Uli Köhler in Electronics, Networking

How to connect 100Base-FX transceiver to SFP module (schematic)

Also see my post on selecting a suitable 100Base-FX Ethernet PHY.

Note that sometimes the capacitors and the 100 Ohm termination resistor is integrated in the specific SFP module in use! In that case, replace the capacitors by 0 Ohm resistors and omit the 100 Ohm resistor. My recommendation is to check out the datasheet of the SFP module or just try it out with the capacitors & termination if you don’t know.

100Base-FX transceivers are pretty easy to connect to the PHY, but you have to terminate the high speed interface correctly. Since PECL logic is used, the termination scheme is somewhat difference.

PECL & AC termination

The first thing is understand is that while all SFP modules are equal (i.e. subject to the SFP multi-source agreement), some are more equal than others.

More specifically, some of them include termination resistors, some of them include AC coupling capacitors, some of them include both and some of them include none. My recommendation is to assume that the SFP module contains both AC coupling caps and the transmit termination, but have spare component footprints in case you need to add them. Similar strategies are recommended

What you absolutely need is:

  • A 50 Ohm differential trace between the SFP and the PHY
  • Some termination scheme on the PHY side
  • You 100% absolutely need to checkout your PHY’s datasheet, or ask the manufacturer for reference schematics!
  • Short traces – the shorter the traces, the less headache you’ll get from debugging. You don’t want more headache than neccessary, believe me.

What you might or might not need, depending on SFP, PHY and board layout is:

  • Additional terminations (if you add those while other termination is already in place, this will approximately half your signal amplitude.
  • AC coupling capacitors (doesn’t hurt all too much to include them even if they are redundant)
  • Pullup resistors for the PHY driver

Variant 1: Microchip

The following information is based on Microchip’s application note for the LAN93xx series. The basic termination strategy is to use a 100R differential transmit termination, included with the note that some transceivers already contain the termination resistor inside them and using an extra termination resistor.

Note that in one of the schematics Microchip swapped the termination resistors. The 130 Ohm resistor should go toward 3.3V and not toward ground.

Furthermore, Microchip requires 50 Ohm (read: 49.9 Ohm) pull-up resistors to be fitted to the transmit lines. These resistors are required for the Microchip drivers, but not required for all drivers.

Variant 2: Marvell

In Marvell’s 88E3015/88E3018 datasheet, a slightly different termination scheme is implemented which omits the differential 100R termination resistor in favour of a pair of

Note that the Marvell device does not specify 50R pullup resistors. As far as I could find out SFP modules never appear to require these pullups, but some PHYs do. The only safe variant is to include these pullups into the schematic and do not populated them.

Combining the variants

A good idea with high speed signals, especially with different transceivers is to include all possible options and then just try out what works best.

Download KiCAD schematic

My recommendations on what to start with are as follows:

  • All resistors shown with NA values: Do not populate, populate only if needed experimentally
  • Since most SFP receivers already include AC coupling capacitors, these are not needed, but they typically do not hurt either
  • Try to keep the traces between the PHY and the SFP module short. This will solve most signal integrity problems without having to test-fit resistors etc.

In addition to the high speed data connection from the SFP module to the PHY, you want to find the LOS (loss of signal) pin, sometimes called signal detect or link detect and also connect it directly from the SFP module to the PHY (no termination or pullups required).

Regarding the layout, as usual with high speed connections, ensure that the components are placed near to the relevant components and try to place the PHY and the SFP module as close together as possible.

Posted by Uli Köhler in Electronics, KiCAD, Networking
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPTPrivacy &amp; Cookies Policy