- Muchas notas - Fran Acién

20230525 - Errors Edusat COMM PCB

The tests of the COMM PCB are:

    1. LoRa Communication
    • 1.1. Transmit
    • 1.2. Receive
    1. CAN communication
    • 2.1 Check mode ✅
    • 2.2 Check enable ✅
    • 2.3 Transmit ✅
    • 2.4. Receive ✅
    1. Why the JTAG interface is not working?

1

I used this source to transmit and receive. In the other end I had the arduino with lora, that is using another library. And the result was that they were not able to communicate to each other.

2.1 2.2

I checked the enable in the multimeter, and I forgot that is necessary to enable the transceiver by code. It is placed on the GPIO16.

2.4

I am able to receive packets using the library from esp, but the serial is stucked and is all the time reading the same message. The code is next one:

/* ESP32 TWAI receive example.
  Receive messages and sends them over serial.

  Connect a CAN bus transceiver to the RX/TX pins.
  For example: SN65HVD230

  TWAI_MODE_LISTEN_ONLY is used so that the TWAI controller will not influence the bus.

  The API gives other possible speeds and alerts:
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html

  Example output from a can bus message:
  -> Message received
  -> Message is in Standard Format
  -> ID: 604
  -> Byte: 0 = 00, 1 = 0f, 2 = 13, 3 = 02, 4 = 00, 5 = 00, 6 = 08, 7 = 00

  Example output with alerts:
  -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
  -> Bus error count: 171
  -> Alert: The RX queue is full causing a received frame to be lost.
  -> RX buffered: 4  RX missed: 46 RX overrun 0

  created 05-11-2022 by Stephan Martin (designer2k2)
*/

#include "driver/twai.h"

// Pins used to connect to CAN bus transceiver:
#define RX_PIN 15
#define TX_PIN 14

#define CAN_EN_PIN 16

// Intervall:
#define POLLING_RATE_MS 1000

static bool driver_installed = false;

void setup() {
  // Start Serial:
  Serial.begin(115200);

  pinMode(CAN_EN_PIN, OUTPUT);
  digitalWrite(CAN_EN_PIN, HIGH);

  // Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_LISTEN_ONLY);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }

  // Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }

  // Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states
  uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
    return;
  }

  // TWAI driver is now successfully installed and started
  driver_installed = true;
}

static void handle_rx_message(twai_message_t& message) {
  // Process received message
  if (message.extd) {
    Serial.println("Message is in Extended Format");
  } else {
    Serial.println("Message is in Standard Format");
  }
  Serial.printf("ID: %x\nByte:", message.identifier);
  if (!(message.rtr)) {
    for (int i = 0; i < message.data_length_code; i++) {
      Serial.printf(" %d = %02x,", i, message.data[i]);
    }
    Serial.println("");
  }
}

void loop() {
  if (!driver_installed) {
    // Driver not installed
    delay(1000);
    return;
  }
  // Check if alert happened
  uint32_t alerts_triggered;
  twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS));
  twai_status_info_t twaistatus;
  twai_get_status_info(&twaistatus);

  // Handle alerts
  if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
    Serial.println("Alert: TWAI controller has become error passive.");
  }
  if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
    Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
    Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count);
  }
  if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
    Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
    Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx);
    Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count);
    Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count);
  }

  // Check if message is received
  if (alerts_triggered & TWAI_ALERT_RX_DATA) {
    // One or more messages received. Handle all.
    twai_message_t message;
    while (twai_receive(&message, 0) == ESP_OK) {
      handle_rx_message(message);
    }
  }
}

The conclusion is that, there is no CAN library that works correctly on the ESP32S3, or at least I have not found it.

The solutions are:

  • Make the official driver to work on ESP32S3
  • Adapt the library I know is working to ESP32S3
  • Modify the PCB to use the previous ESP, and use the libraries I know are working

I tried to send messages with the official driver on the esp32 dev kit, and it is stucked reading a message from the queue, it is not updated correctly. I tried to use esp32_can without much success.

ESP CAN TWAI Self test

d1d7e0c34a6009e4cb180fe5a7e6dd30.png

The steps were to upload the twai self test with the transceiver connecter. The output is that is working. I needed to short the enable pin directly to VCC

CAN test now is working

After doing the short in the enable pin.… it works. Why? Not sure. But I am able to receive.

CAN TRANSMISSION WORKING

I removed the wire from CAN_EN, and is working. It is strange, but somehow now is working.

/* ESP32 TWAI receive example.
  Receive messages and sends them over serial.

  Connect a CAN bus transceiver to the RX/TX pins.
  For example: SN65HVD230

  TWAI_MODE_LISTEN_ONLY is used so that the TWAI controller will not influence the bus.

  The API gives other possible speeds and alerts:
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html

  Example output from a can bus message:
  -> Message received
  -> Message is in Standard Format
  -> ID: 604
  -> Byte: 0 = 00, 1 = 0f, 2 = 13, 3 = 02, 4 = 00, 5 = 00, 6 = 08, 7 = 00

  Example output with alerts:
  -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
  -> Bus error count: 171
  -> Alert: The RX queue is full causing a received frame to be lost.
  -> RX buffered: 4  RX missed: 46 RX overrun 0

  created 05-11-2022 by Stephan Martin (designer2k2)
*/

#include "driver/twai.h"

// Pins used to connect to CAN bus transceiver:
#define RX_PIN 15
#define TX_PIN 14

#define CAN_EN_PIN 16

// Intervall:
#define POLLING_RATE_MS 1000

static bool driver_installed = false;

void setup() {
  // Start Serial:
  Serial.begin(115200);

  pinMode(CAN_EN_PIN, OUTPUT);
  digitalWrite(CAN_EN_PIN, HIGH);

  // Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_NORMAL);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }

  // Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }

  // Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states
  uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
    return;
  }

  // TWAI driver is now successfully installed and started
  driver_installed = true;
}

static void handle_rx_message(twai_message_t& message) {
  // Process received message
  if (message.extd) {
    Serial.println("Message is in Extended Format");
  } else {
    Serial.println("Message is in Standard Format");
  }
  Serial.printf("ID: %x\nByte:", message.identifier);
  if (!(message.rtr)) {
    for (int i = 0; i < message.data_length_code; i++) {
      Serial.printf(" %d = %02x,", i, message.data[i]);
    }
    Serial.println("");
  }
}


void loop() {
  if (!driver_installed) {
    // Driver not installed
    delay(1000);
    return;
  }
  // Check if alert happened
  uint32_t alerts_triggered;
  twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS));
  twai_status_info_t twaistatus;
  twai_get_status_info(&twaistatus);

  // Handle alerts
  if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
    Serial.println("Alert: TWAI controller has become error passive.");
  }
  if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
    Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
    Serial.printf("Bus error count: %d\n", twaistatus.bus_error_count);
  }
  if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
    Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
    Serial.printf("RX buffered: %d\t", twaistatus.msgs_to_rx);
    Serial.printf("RX missed: %d\t", twaistatus.rx_missed_count);
    Serial.printf("RX overrun %d\n", twaistatus.rx_overrun_count);
  }

  // Check if message is received
  if (alerts_triggered & TWAI_ALERT_RX_DATA) {
    // One or more messages received. Handle all.
    twai_message_t message;
    while (twai_receive(&message, 0) == ESP_OK) {
      handle_rx_message(message);
    }
  }
}

/*
void loop(){
  if (!driver_installed) {
    // Driver not installed
    delay(1000);
    return;
  }

  //Configure message to transmit
  twai_message_t message;
  message.identifier = 0xAAAA;
  message.extd = 1;
  message.data_length_code = 4;
  for (int i = 0; i < 4; i++) {
      message.data[i] = 0;
  }

  //Queue message for transmission
  if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
      printf("Message queued for transmission\n");
  } else {
      printf("Failed to queue message for transmission\n");
  }

  delay(2000);
}
*/

Uploading code tests

Test 1

Source: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/linux-macos-setup.html

Connected with the ESP-Prog with both interfaces, the jtag and the program interface.

Then I did:

$ sudo apt-get install git wget flex bison gperf python3 python3-venv cmake ninja-build ccache libffi-dev libss
l-dev dfu-util libusb-1.0-0\n
$ cd esp-idf-v5.0.1
$ ./install.sh esp32s3
$ chmod 755 export.sh
$ . ./export.sh
$ cd examples/get-started/hello_world
$ idf.py set-target esp32s3\n
$ idf.py build\n
$ idf.py -p /dev/ttyUSB1 flash
$ screen /dev/ttyUSB1 115200

While flashing it is necessary to press the boot button.

Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
Restarting in 4 seconds...
Restarting in 3 seconds...
Restarting in 2 seconds...
Restarting in 1 seconds...
Restarting in 0 seconds...
Restarting now.
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40375625
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3810,len:0x164c
load:0x403c9700,len:0xbe0
load:0x403cc700,len:0x2ef8
entry 0x403c9900
I (29) boot: ESP-IDF v5.0.1-dirty 2nd stage bootloader
I (29) boot: compile time 13:24:59
I (29) boot: chip revision: v0.1
I (32) boot.esp32s3: Boot SPI Speed : 80MHz
I (36) boot.esp32s3: SPI Mode       : DIO
I (41) boot.esp32s3: SPI Flash Size : 2MB
I (46) boot: Enabling RNG early entropy source...
I (51) boot: Partition Table:
I (55) boot: ## Label            Usage          Type ST Offset   Length
I (62) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (70) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (77) boot:  2 factory          factory app      00 00 00010000 00100000
I (85) boot: End of partition table
I (89) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=08c84h ( 35972) map
I (104) esp_image: segment 1: paddr=00018cac vaddr=3fc91000 size=02318h (  8984) load
I (107) esp_image: segment 2: paddr=0001afcc vaddr=40374000 size=0504ch ( 20556) load
I (119) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=195f4h (103924) map
I (141) esp_image: segment 4: paddr=0003961c vaddr=4037904c size=07f1ch ( 32540) load
I (154) boot: Loaded app from partition at offset 0x10000
I (154) boot: Disabling RNG early entropy source...
I (165) cpu_start: Pro cpu up.
I (166) cpu_start: Starting app cpu, entry point is 0x40375168
I (0) cpu_start: App cpu up.
I (180) cpu_start: Pro cpu start user code
I (180) cpu_start: cpu freq: 160000000 Hz
I (180) cpu_start: Application information:
I (183) cpu_start: Project name:     hello_world
I (188) cpu_start: App version:      v5.0.1-dirty
I (194) cpu_start: Compile time:     May 25 2023 13:24:52
I (200) cpu_start: ELF file SHA256:  0e14337c73093a5d...
I (206) cpu_start: ESP-IDF:          v5.0.1-dirty
I (211) cpu_start: Min chip rev:     v0.0
I (216) cpu_start: Max chip rev:     v0.99
I (221) cpu_start: Chip rev:         v0.1
I (226) heap_init: Initializing. RAM available for dynamic allocation:
I (233) heap_init: At 3FC93D38 len 000559D8 (342 KiB): D/IRAM
I (239) heap_init: At 3FCE9710 len 00005724 (21 KiB): STACK/DRAM
I (246) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (252) heap_init: At 600FE010 len 00001FF0 (7 KiB): RTCRAM
I (259) spi_flash: detected chip: gd
I (263) spi_flash: flash io: dio
W (267) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (280) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
Hello world!
This is esp32s3 chip with 2 CPU core(s), WiFi/BLE, silicon revision v0.1, 2MB external flash
Minimum free heap size: 391944 bytes
Restarting in 10 seconds...
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
Restarting in 4 seconds...
Restarting in 3 seconds...

Test 2 - Upload code from arduino

The board in arduino ide is ESP32S3. Connect the 2 cables to the esp-prog. While uploading is necessary to press boot button.

A sample code is:

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(36, OUTPUT);
  Serial.begin(9600);
}

// the loop function runs over and over again forever
void loop() {
  Serial.println("asdf");
  digitalWrite(36, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(36, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                      // wait for a second
}

Test 3 - Upload code from vscode platform io

Same setup

[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
board_build.mcu = esp32s3
framework = arduino
debug_tool = esp-prog

Using the same code as arduino. Remember to press boot when uploading code.

Test 4 - Debugger

By default the JTAG interface is disabled, that is why is necessary to change something in the software.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/tips-and-quirks.html#jtag-and-esp32-wroom-32-at-firmware-compatibility-issue

I have not been able to fix the debugger. It seems that is not detecting it -.-

EDIT: With the code that comes it is disable the jtag, but as soon as you program it will change.

Test Lora communication

79dc7d0ef07410209ea7b36d3fa97527.png

It works. The setup is 2 pcbs sending messages.

KNOW ERRORS V0.1

  • The JTAG is not working, the debugger is not working. I am able to upload code but with the serial interface.
  • The mode is set to low power mode, it would be appreciated to put a solderbridge to select the mode
  • The transceiver is controlled by a pin. It would be nice to put a solderbridge to change the behaviour in testing.
  • The reset button sometimes is working and others not. When you press it, it freezes the board. Only when using arduino ide, then on platform io it works perfectly.
  • CAN_EN needs to be connected to VCC with a wire, otherwise is doing strange things.
  • The through hole pins are very narrow, it is not good for desoldering.
  • If you break the solderbridge SB1, then you need to push the prog button of the ESP-Prog while programming it.

CAN Library not working

d41846a3a40c9d0128481cb5571ccea8.png

It is not declared this variable on ESP32S3: https://github.com/sandeepmistry/arduino-CAN/blob/a1cd3017c840942a7a4eeed0e44460e5df796e65/src/ESP32SJA1000.cpp#L56

In esp32s2 is defined here https://github.com/espressif/esp-idf/blob/d00e7b5af897cc5fafe51fae19c57f0313b81edf/components/soc/esp32s2/include/soc/system_reg.h#L411

The source of the problem is that in the arduino framework it is not defined:

https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/esp32s3/include/soc/esp32s3/include/soc/system_reg.h

but here it is defined

https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/esp32s2/include/soc/esp32s2/include/soc/system_reg.h

Basically the problem is that the framework on arduino is not prepared yet, so there are some missing registers.

However I noticed that in the examples of ESP32S3 there is one for CAN.