Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Ben
@bzeeman
how does one go about such things?
Mike Dunston
@atanisoft

set your framework line as:

framework=espidf, arduino

note the space after the comma it is required...

add sdkconfig.h to your src tree and press compile :)
Ben
@bzeeman
then can I use ULP
Mike Dunston
@atanisoft
start with https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/config/sdkconfig.h as your sdkconfig.h file and tweak if you need to
Ben
@bzeeman
I am on the wrong computer…
Mike Dunston
@atanisoft
you can use ULP macros in arduino today
but not ULP assembly code
Ben
@bzeeman
maybe i should look into the macros… I got a lot of the assembly logic written, but can’t seem to figure out the right way to read in GPIO
IIRC GPIO reading is simply loading a memory address
Ben
@bzeeman
Thats what I understand too, but something is not making sense to me.
Now PIO will generate a sdkconfig for me if I just have a blank one right?
Mike Dunston
@atanisoft
it should if you don't have one
but it may be different than the arduino one
Ben
@bzeeman
hmmm. With he Arduino one, that should let me configure custom partitions right? I think that was one of the problems I ran into when trying to convert my project over before.
Mike Dunston
@atanisoft
yup
it isn't tied to teh sdkconfig
Ben
@bzeeman
compiling now.
it's NOT happy haha.
Mike Dunston
@atanisoft
hmm
Ben
@bzeeman
sorry I just vanished, my dog jumped the fence
hreintke
@hreintke

Hi,
I see unexpected timings on serial, made a SerialTest to show it, baudrate in this is 19200.
My application on ESP32 communicates to ATMega328P via Serial1 connection, ESP32 sends message, AtMega replies.
For the testing I write all incoming ATmega characters to Serial2, on a char by char base, not waiting for the full message to arrive.
I also toggle pin 25 to know the timing.

Full test app is

#include "Arduino.h"

void setup()
{
    Serial.begin(115200);
    Serial1.begin(19200, SERIAL_8N1, 16, 17);
    Serial2.begin(19200, SERIAL_8N1, 23, 19);
    pinMode(25,OUTPUT);
    digitalWrite(25,LOW);
}

uint8_t msg[] = {0xAA,0x3A,0x24,0x08,0x01,0x72};

void loop()
{
    if (Serial.available()) // Initiate one message to ATMega
    {
        uint8_t c = Serial.read();
        Serial1.write(msg,6);
    }
    if (Serial1.available()) // ATMega reply is coming in
    {
        uint8_t c = Serial1.read();
        Serial2.write(c);   // Write to Serial2 for debugging.
        digitalWrite(25,!digitalRead(25));
    }
}

What happens is :
ESP32 sends message
ATMega replies immediately, first character start coming in after 120 us, first char complete in after 625 us.
But the Serial1.read() only returns true 3200 us after first char complete -> This is what I do not understand, I expected it a very short period after complete.
The timing is shown in the logic analyzer output.
White : Serial1 from ESP to ATmega
Green : Serial1 from ATMega to ESP
Brown : Serial2 from ESP
Grey : Pin25 (toggle)

esp32serial.JPG
chuck todd
@stickbreaker

@hreintke The Serial() driver code uses the 128 byte hardware fifo's of the UART. There are two case that trigger the emptying of the Fifo.:

  • The UART hardware receives 112 or more bytes.
  • Or, if the UART sees the receive pin inactive for two byte periods it triggers an interrupt to empty the fifo.

The Serial() object only sees the receive queue. So until either of those two cases happen, the data is only in the hardware Fifo.

chuck todd
@stickbreaker

You can change this behavior by adjusting the trigger points and recompiling. in cores\esp32\esp32-hal-uart.c line 102:

void uartEnableInterrupt(uart_t* uart)
{
    UART_MUTEX_LOCK();
    uart->dev->conf1.rxfifo_full_thrhd = 112;
    uart->dev->conf1.rx_tout_thrhd = 2;
    uart->dev->conf1.rx_tout_en = 1;
    uart->dev->int_ena.rxfifo_full = 1;
    uart->dev->int_ena.frm_err = 1;
    uart->dev->int_ena.rxfifo_tout = 1;
    uart->dev->int_clr.val = 0xffffffff;

    esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle);
    UART_MUTEX_UNLOCK();
}

reduce the trigger thresholduart->dev->conf1.rxfifo_full_thrhd = 112; it needs to be above zero.

ben-mkiv
@ben-mkiv
shouldnt HardwareSerial do the job, too?
lbernstone
@lbernstone
Serial. is a HardwareSerial object
Is 112 arbitrary, or is there a reason for that number?
Me No Dev
@me-no-dev
it's about as high as you can go before you start missing bytes at very high bitrates, because by the time the ISR got triggered and your code got to the point of reading, the FIFO got overflow. The other reason is to minimise the time between interrupts. In reality it should be connected to the baudrate in one way or another, so you do not have to wait a lot for long 9600bps messages
hreintke
@hreintke
@lbernstone Thx for info and link.
Expected to get Serial.available() as soon as first char was in the buffer.
Will play around with the config values. Found info on these in uart_struct.h
Me No Dev
@me-no-dev
you are getting it then :) just that the first byte in the buffer and the first byte in the fifo are two different things
if you want to get it at the moment it enters the fifo, set fifo full thresh to 1, but that will trigger ISR too often and you might not like the result
hreintke
@hreintke
You are right, should be careful with the wording.
Do you know in what units the
uint32_t rx_tout_thrhd: 7; /*This register is used to configure the timeout value for uart receiver receiving a byte.*/
needs to be set ?
Me No Dev
@me-no-dev
a value of 2 is generally OK
2 means that it will wait 2 byte times after the last byte to trigger TOUT (or end of the message)
if you set fifo full to 1 though, you do not need TOUT at all, because you will get interrupt each byte anyway
chuck todd
@stickbreaker
@hreintke unit is byte period. length of serial byte stream, (Start bit, 8 data bits, 1 stop) so baud/10.
@hreintke since rx_tout_thrhd is defined as a seven bit value max range is 127, min it zero, but 1 is actually lower range.
Ben
@bzeeman
So I tried switching from straight up arduino to PIO with platform =espidf, arduino and I think I finally got my custom partition working.. ish. It looks like I am successfully creating the file, but then if I try to open the file again it does not exist. Anyone seen this?
I am also seeing this now...
Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.
Mike Dunston
@atanisoft
That should be just a warning but you can fix it in sdkconfig.h
Me No Dev
@me-no-dev
@bzeeman you can have custom partitions in your sketch in ArduinoIDE also
hreintke
@hreintke

@lbernstone @me-no-dev
Based on the info from you yesterday I am looking into the serial/serial interrupts.
Still working on that but I noticed that static void IRAM_ATTR _uart_isr(void *arg) is always called twice.
Does not have a functional influence but don't know if that is expected/intentional.

Sketch :

#include "Arduino.h"

void setup()
{
    pinMode(25,OUTPUT);
    digitalWrite(25,LOW);
    pinMode(26,OUTPUT);
    digitalWrite(26,LOW);
    Serial.begin(115200);
}

void loop()
{
  if (Serial.available())
  {
    Serial.write(Serial.read());
  }
}

Added two pin toggles to _usart_isr

static void IRAM_ATTR _uart_isr(void *arg)
{
    uint8_t i, c;
    BaseType_t xHigherPriorityTaskWoken;
    uart_t* uart;

    digitalWrite(25,HIGH);   // ----> Brown toggle
    for(i=0;i<3;i++){
        uart = &_uart_bus_array[i];
        if(uart->intr_handle == NULL){
            continue;
        }
        uart->dev->int_clr.rxfifo_full = 1;
        uart->dev->int_clr.frm_err = 1;
        uart->dev->int_clr.rxfifo_tout = 1;
        while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {

            digitalWrite(26,HIGH); // ----> Grey toggle
            c = uart->dev->fifo.rw_byte;
            if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
                xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
            }
            digitalWrite(26,LOW); // ----> Grey toggle
        }
    }
    digitalWrite(25,LOW);    // ----> Brown toggle
    if (xHigherPriorityTaskWoken) {
        portYIELD_FROM_ISR();
    }
}

In the Logicanalyzer :
White : Serial Receive
Green : Serial Transmit
Brown : Pulse on _usart_isr
Grey : Pulse on char transfer from fifo to queue

Picture 1 : Receive and transmit of one char
Picture 2 : Detail of usart_isr + start of transmit

SerialInterrupt.JPG
SerialDetail.JPG
Ben
@bzeeman
@me-no-dev Yes, I have been using custom partitions in the Arduino IDE. The issue I am trying to solve right now is a combination of wanting a good debugging interface with the ESP-PROG, and getting some ULP programming done. I know I can do the ULP in Arduino IDE too, but something isn't working right for me, it's probably my own brain, but it still leaves me with getting a good debug interface working.
@me-no-dev so currently the only problem I am having in PIO with arduino + espidf is that I seem to be able to successfully open/write a new file, but once I close it it doesn't show up as saved.
I am using FFAT