Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increase I2C Buffer Length or Provide Configurable Interface #2728

Closed
umeiko opened this issue Jan 1, 2025 · 6 comments
Closed

Increase I2C Buffer Length or Provide Configurable Interface #2728

umeiko opened this issue Jan 1, 2025 · 6 comments
Labels
enhancement New feature or request

Comments

@umeiko
Copy link

umeiko commented Jan 1, 2025

Hello,

I have encountered some issues while using the arduino-pico library, particularly when porting libraries based on ESP32. The I2C implementation in ESP32 does not have a strict buffer length limitation, whereas the arduino-pico library limits the I2C buffer length to 256 bytes. This limitation makes it difficult to port some ESP32-based libraries to arduino-pico, especially when sensors or devices return data exceeding 256 bytes in a single transaction.

Suggestions:

  • Increase I2C Buffer Length: Increase the default I2C buffer length to a larger value, such as 512 bytes or more, to better accommodate devices that require large data transfers.
  • Provide Configurable Interface: Provide an interface that allows users to customize the buffer length during I2C initialization. This would enable users to adjust the buffer size according to their specific application needs, enhancing flexibility and compatibility.
@earlephilhower earlephilhower added the enhancement New feature or request label Jan 1, 2025
@earlephilhower
Copy link
Owner

It sounds like you have a need and an idea how to make it work. Want to do a PR adding the ESP32's setBuffer method to let apps define a non-standard size? I think it's pretty straightforward...

@umeiko
Copy link
Author

umeiko commented Jan 2, 2025

But I found a strange thing that, I copyed Wire.h and Wire.cpp into my code space, using #include "Wire.h" rather than #include<Wire.h>to include them, then made a modification #define WIRE_BUFFER_SIZE 315。 but, I am encountering an issue with the TwoWire::requestFrom function:

size_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) {
    if (!_running || _txBegun || !quantity || (quantity > sizeof(_buff))) {
        return 0;
    }

    _buffLen = i2c_read_blocking_until(_i2c, address, _buff, quantity, !stopBit, make_timeout_time_ms(_timeout));
    if ((_buffLen == PICO_ERROR_GENERIC) || (_buffLen == PICO_ERROR_TIMEOUT)) {
        if (_buffLen == PICO_ERROR_TIMEOUT) {
            _handleTimeout(_reset_with_timeout);
        }
        _buffLen = 0;
    }
    _buffOff = 0;
    return _buffLen;
}
}

when requesting data from a sensor that returns more than 255 bytes. Specifically, I have a sensor that returns 258 bytes of data. When I set the quantity to values between 1 and 255, everything works as expected. However,

  • when quantity set to 256, the function returns 0;
  • when quantity set to 257, it returns 1;
  • when quantity set to 258, it returns 2.
    seems like data was still cut off at 255, though sizeof(_buff) is alreally 315

@umeiko
Copy link
Author

umeiko commented Jan 3, 2025

int i2c_read_blocking_until (i2c_inst_t * i2c, uint8_t addr, uint8_t * dst, size_t len, bool nostop, absolute_time_t until)

The size_t data type should be able to represent sizes larger than 255, but the function seems to have an implicit limit. Seems only uint8_t was accepted

@earlephilhower
Copy link
Owner

FWIW, we use the plain SDK code. To me it doesn't seem to have any limitations baked in...it just uses polling to fill ilen bytes from the FIFO:

https://github.com/raspberrypi/pico-sdk/blob/95ea6acad131124694cda1c162c52cd30e0aece0/src/rp2_common/hardware_i2c/i2c.c#L268-L315

The datasheet doesn't talk about any limitations either (there's only a 10 byte FIFO but that's busy polled in the SDK).

For sanity you might want to Serial.printf("%lu\n", len); in the start of your modified function just to see if somehow things are being truncated by the object call?

@umeiko
Copy link
Author

umeiko commented Jan 7, 2025

okay, seems like my sensor has some problem, since i changed another one, everything works good. i will make a pr to provide a method to adjustment the buffer size of i2c

@earlephilhower
Copy link
Owner

It's been years since I implemented the code so I completely forgot that this capability already exists (taken from the ESP8266 side). Just define the new size in your platform.local.txt or P.IO INI file and you can set it to any size needed:

#ifndef WIRE_BUFFER_SIZE
#define WIRE_BUFFER_SIZE 256
#endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants