The tests of the COMM PCB are:
-
- LoRa Communication
- 1.1. Transmit
- 1.2. Receive
-
- CAN communication
- 2.1 Check mode ✅
- 2.2 Check enable ✅
- 2.3 Transmit ✅
- 2.4. Receive ✅
-
- 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
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.
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
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
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:
but here it is defined
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.