-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Explicitly Define HW SPI Interface Pins - MOSI & SLCK #377
Comments
First of all, let me note that ESP32 is not officially supported (or at least is not tested)
There is no protection, it is simply impossible for most of the uC to change the SPI/I2C lines. Notable exceptions include the ESP systems. For I2C (but not for SPI), there is already an u8g2 extension:
It is possible to add clock and data lines as optional arguments to the end of constructor. The official page does not at all allow you to use any other pins for I2C: However, there is an ESP8266 specific extension which is used by u8g2 in the special case of ESP8266 For SPI, no such extension is known to me and also not implemented. As a conclusion: U8g2 build on top of Wire.h and SPI.h. Both libs do not support pin numbers for any hardware communication. From this perspective, U8g2 just offers the same interface and capabilities like the standard official Arduino API. These is a extra feature for the ESP8266 board which has to be implemented as an extra feature to u8g2. Or even better, you should approach Arduino people to implement the same extension to the core libraries.
I assome this is some ESP32 specific thing. So i can not answer this question
For SW SPI i just use digitalWrite to communicate with the display. For this I require the pins to which the display is connected. For HW SPI I will use SPI.h which will use fixed pins.
Again I am the wrong person. I tried to add support for ESP32. At least as of now, there is no official board description for the Arduino IDE. Without that official board support it is difficult for me to add support for ESP32. Nevertheless, any Pull Requests are highly wellcome. Oliver |
Thank you for shedding some light on this.
It appears that the root of the issue is that other "Arduino Compatible" boards leverage the same Official Arduino API which was originally designed for officially Arduino boards only. I tried using the Espressif's Arduino "Compatible" implementation similar to the one you linked above but for ESP32 instead of ESP8266 as linked here: As new boards get added for Arduino API compatibility, it is only a matter of time when it won't be sufficient. ESP32 is a prime example of something way more complex and capable than Arduino boards (even compared to Arduino Due which is ARM based). The key point here is that Espressif is "Forced" to meet the Arduino API. I presume this is the case for any non standard Arduino boards that are vastly different from the original Arduino boards but still try to conform to the same old API. I was able to use U8g2 with @nkolban ESP32 HAL linked below: The problem now is that it is a purely ESP-IDF implementation and we lose the ease of use offered by Arduino API. It is also C based and I tried messing around with C++ and it gave me int to pointer assignement error. I haven't had a chance to delve in the details yet. I believe there is a need for a generic high level abstraction for Microcontrollers that enable rapid prototyping. Or perhaps there is an opportunity to decouple and expand the scope of Arduino core API to support a plethora of new boards. I think the latter might be easier to lobby for. Pinging @nkolban to see if he can shed some light on the ESP framework. |
not an official opinion... the burden of defining pins for hardware ports (no matter what) must be taken outside library, to implementation specific libraries and presented for interface as an arduino derived hardware interface. Like was implemented for 2nd serial port on some mcu's that support it. right? |
@nkolban reporting for duty. Use me as a source of assistance for all things ESP32 related. Is there a specific question that is in the ESP32 domain? |
@neilpanchal wow, i like your pictures. They exactly describe the current (bad?) situation. The standard Arduino Libraries reflect the situation for old 8-bit controller. If possible and if there is sufficient user request u8g2 can be modified to support extended library features like for the ESP8266. Drawback are several #ifdef's in the u8g2 code to separate between ESP and traditional Arduino boards. One good thing is this: Arduino project has unified hardware access more than any other library known to me. U8glib and U8g2 are also successful and widely used because of this compatibility. I agree that these Arduino libraries are restricted and maybe even some features of your favorite controller are not supported, but you can still build on a lot of existing libs. Anyhow, as soon as there is a official ESP32 support package for Arduino IDE (Ubuntu), I can start working for a ESP32 of the U8g2 lib with better support for moving hardware SPI/I2C pins. |
Agreed, for U8g2 pin numbers must be provided from extern (either via constructor or by writing your own callback functions). No other assumption is done on pin numbers. Infact this also makes the architecture of u8g2 a little bit complicated. The picture below shows the architecture starting at u8x8 API level (u8g2 is build on top of the u8x8 API) down to the Arduino Core library access. |
Howdy, https://github.com/espressif/arduino-esp32 Did I mis-understand some deeper story? |
I tried sometime back, but I failed due to the missing package description (json file). Is this available meanwhile? I guess i need to give it a try... |
I do my unit testing on Arduino IDE on Linux (Ubuntu) so will be delighted to assist you getting it up and running. I'm at your disposal. Quickest/easiest way (for me) is that when you are ready and have a Linux shell prompt/UI in front of you, ping me on skype (neil.kolban) and you can share your screen and I'll walk you through the steps (if needed). Shouldn't take 15 minutes. |
Nice offer, jet my hope was, that i can just fetch ESP32 Support from the Ardunio Board Manager. Is this possible meanwhile? |
I don't believe the Board Manager technology can be used to install the ESP32 support for the Arduino IDE. I have always followed the instructions found here: https://github.com/espressif/arduino-esp32#installation-instructions I have tested both Windows and Linux instructions and they have both worked for me. I'm in UTC-6. Our best hope for availability overlap will likely be weekend. |
ok, looks like the install instructions became more simpler compared to my last visit. Nevertheless also the json package file for the board manager seems to be on the way. I am not sure, when i find some time to work on this. |
Some good news here: I have EPS32 support within Arduino IDE working. I also successfully connected my Sparkfun ESP32 Thing. U8g2 works without problem, but HW I2C pinremapping was not supported until now, so this was the first improvement what I did:
Pin remapping triples time compared to digitalWrite/SW I2C bit banging:
|
I started to investigate the Arduino Libraries for the ESP32: There is no support for HSPI at the moment: See ~/Arduino/hardware/espressif/esp32/libraries/SPI/src/SPI.c @neilpanchal Update:
is required at the end of One additional line
is required for EDIT:
is required (typing mistake in my above statement) |
I have created a beta release: |
I made a typing mistake. The additional required line is:
|
Additional comment: I just had a discussion here #378 about ESP8266. It looks like they have removed the flexible pin assignment via SPI.begin() statement (instead they have added an extra statement for this). Update: I was wrong, the ESP8266 SPI lib has not been changed, but the ESP8266 as a complete different way to specify other pins for the SPI interface compared to ESP32. This means ESP8266 and ESP32 do not have the same interface for specifing the SPI pins. |
SPI Lib ESP8266: SPI Lib ESP32: Wire Lib ESP8266 Wire Lib ESP32 Conclusion:
Suggestions: From seeing the above differences my suggestion is to modify the ESP8266 project
|
Update: Moved this topic to #381 as it is kind of unrelated to the SPI pinouts and VSPI/HSPI modules. Thanks for investigating this. I am trying to validate the changes on my side but I've come across an interesting roadblock. Arduino-esp32 dictates 4 ways of using the Arduino API with ESP-IDF in the instructions/readme. Method 1One of those ways is to use Arduino API as an ESP-IDF component as described here. I managed to add Arduino API to ESP-IDF using this method. Next, I've added a component.mk file to @olikraus's U8g2_Arduino fork. Component.mk has the following options to add source directors and include files:
Now, U8g2 is a component of ESP-IDF and we can use the wonderful There is one problem. Usually, I am able to edit the SPI frequency in the u8x2_d_ssd1306_128x64_noname.c, however, no matter what frequency I set and upload to ESP32, I always get 8MHz as the clock freq. I've validated it using a scope. Method 2Another way to use ESP-IDF + Arduino API is to leverage the Platform IO ESP32 framework. So, I tried the same test as above and I changed the I am pretty sure I am missing something obvious here. Any ideas on what must be going on? Any chances I make to the |
I don't use Arduino IDE so I unzipped the file and added as a component to ESP IDF using component.mk. Then I added
at the end of
at the end of
If I remove the modifications to SPI.h and SPI.cpp, |
Looks like a conflict within ESP project. SPI1 is just a suggestion. It is used as secondary SPI device for other platfroms (like ATMega). |
@olikraus Hi, I was able to get rid of the error. I've added the additional lines at the end of SPI.c and SPI.h. SPIClass SPI(VSPI);
SPIClass SPIX(HSPI); What is the procedure to now actually create a U8g2 class and specifying whether I want to use I opened an issue (espressif/arduino-esp32#790) on esp32-arduino repo and the suggestion was to use the new SPI class. I am trying to now understand how does U8g2 create an SPI object in the library to initiate the communication. |
Ok, I think I understand now. So the SPI instance is created within the esp32-arduino library and then adding the I found where I think the SPI instance is used in the u8x8lib.cpp file: #if defined(ESP_PLATFORM) || defined(ARDUINO_ARCH_ESP32)
/* ESP32 has the following begin: SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t
* mosi=MOSI, int8_t ss=-1); */
/* not sure about ESP8266 */
if (u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE &&
u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE) {
/* SPI.begin(int8_t sck=SCK, int8_t miso=MISO, int8_t mosi=MOSI, int8_t ss=-1); */
/* actually MISO is not used, but what else could be used here??? */
SPI.begin(u8x8->pins[U8X8_PIN_I2C_CLOCK], MISO, u8x8->pins[U8X8_PIN_I2C_DATA]);
} else {
SPI.begin();
}
#else
SPI.begin();
#endif I am going to try to see if I can pass the pointer to the new SPIX instance from the main.cpp and modify the u8g2 lib accordingly. |
If the SPI object would be called SPI1 (instead of SPIX), you could use the U8g2 2nd SPI device: Then, we need to activate the 2nd spi device: Oh i just see, that there is an error. It should be SPI_INTERFACES_COUNT instead of WIRE_INTERFACES_COUNT |
Thank you @cbpdk !!! Your clean change made the trick neatly 🥇 I rephrased your change in this #1331 (comment) |
Hello, void setup(void) { void loop(void) { The monitor shows : rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) the RTCWDT_RTC_RESET is then repeated about every 8s. |
Looks like an issue with some Real Time Controller (RTC) Watch Dog Timeout (WDT). From my perspective this has nothing todo with u8g2. |
Thank you for your answer Olikraus. |
Using u8g2 procedures may cause and additional delay which then may cause the RTC watch dog timer to reach its timeout. |
Sorry to distrub you @olikraus. |
Hello. |
Thanks for the feedback. Maybe this is also useful for others. |
A short follow up. Since I first made the modification for using SPI1, I have not tested it until now. Switching to SPI using: The SD Card seems to work using SPI1 (HSPI) solving the problem using the display together with a SD Card. |
Hmmm the contrast should be independent from the communication layer. |
@ cbpdk @olikraus I encountered the same problem. When using stm32F401, it is also JLX12864G-08602/JLX12864G-086 display, which can be displayed, but the front is blank. I set various contrast and voltage parameters, and the result is the same. The pixels are all filled. Look at my code. void uc1701x_init(void) //设置屏幕spi引脚和延迿 |
@olikraus found that after commenting out this item, it can be displayed normally, but the contrast cannot be adjusted. I suspect that the SPI setting and contrast are not well matched. I use hardware SPI. #ifdef U8X8_WITH_SET_CONTRAST |
@olikraus Run to stm32f4xx_ hal_ At spi. c, the transmitted data is 1, and the contrast changes. /* Transmit data in 8 Bit mode */ |
I am not exactly sure, what the problem had been, but I am happy, that you found a solution. |
I've been dealing with a perplexing issue with U8G2 and custom SPI pins on an ESP32-S3. I'm using U8G2 with an SSD1309-based 128x64 OLED panel. It is worth noting that everything works perfectly fine with appropriate bit-banged "SW_SPI" constructor (if a little slow), with the following constructor defined: As there is not a constructor that provides the SPI pins, I did some digging around the source code. It turns out that the U8G2 source code has compiler #ifdefs for ESP32 and custom SPI pins--just there is no constructor provided to utilize this functionality. Lines 920 to 935 in 3d41860
(whoa...wait a minute...that's probably part of the problem! The lines use the I2C pin defs instead of the SPI pin defs! Bug alert! This error is also present in the "3wire_hw_spi" routine.) Digging into the code a bit further, I found that the only difference between the "u8x8_SetPin_4Wire_SW_SPI" software SPI setup, and the "u8x8_SetPin_4Wire_HW_SPI" hardware SPI setup...was that the HW setup doesn't provide means for setting the CLK/DAT pin definitions. This is significant, because the above "setup routine" checks these pin definitions to determine whether or not to use the custom SPI pins in the hardware SPI setup. In short, there is no way to access the custom SPI pin setup functions. Here is the software SPI pin definitions routine: Lines 1678 to 1685 in 3d41860
And the hardware SPI pin definitions routine: Lines 1734 to 1739 in 3d41860
Notice that literally the only difference is the omission of SPI_CLK and SPI_DATA on the HW_SPI routine.
....well, turns out once I get PlatformIO's head screwed on correctly, the above code does work if the aforementioned bugfixes are made to the U8x8lib.cpp file. The next level is slightly beyond U8G2's scope, and that's to allow specifying of the MISO SPI pin. I understand and know that U8G2 does not read back from display modules--BUT in the interests of being able to share the SPI bus with other devices that WILL talk back...yeah, that is important. But like I said, not in U8G2's scope. |
oooohhhhhh that seems to be a real bug... I will check further with #2123 |
The PR doesn't touch 3W SPI, so this is done with commit 9b20136 |
@WebDust21 and @kazetsukaimiko : Thanks a lot for your effort here. Excellent work. |
@WebDust21 Thank you very much for the instructions on how to use custom HW-SPI pins on the ESP32 S3 !! |
@olikraus looks like this is still an issue with a Esp32 s2 mini. Ssd1309 4Wire HW SPI on an Esp32 v1 when pin connect to D23 for data and D18 for clock There is no D23 on Esp32 S2 mini. Not seeing a way to set data(MOSI) and clock in the 4W SPI HW constructor. |
The PR/corrections did not change this. Use the custom constructor I detailed above, namely, using an HW constructor (so U8G2 uses HW SPI), but using the SW pin configuration function. Repeated here:
|
I'm trying to use alternative SPI pins on an ESP32S3 and found this issue, but I couldn't get it to work. Can you share a full example of how to use u8g2 using custom SPI pins? |
@sebastianmach |
Hello,
U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI display1(U8G2_R0, /* cs=*/ 5, /* dc=*/ 2, /* reset=*/ 4);
Doesn't allow the user to define the MOSI and SCLK pins in the constructor.
It is especially useful on boards with 2 or more SPI modules such as on the ESP32. I probed around with a scope and found out that the constructor selects VSPI as opposed to HSPI module.
A couple of questions to try to understand the rationality behind protecting the user from defining the pins themselves.
Is it possible to connect displays on both HSPI and VSPI lines? I understand that I can use the chip-select (CS) pin to select between displays, however, I am trying to avoid robbing clock cycles and therefore reducing the framerate (not sure how true my claim is...but I just want to try it out).
I am curious why there are some drivers whose constructors allow for data and clock pin definition and others whose constructors don't. I am using SSD1306.
Is this something that needs to be handled by the ESP32 HAL? I haven't had a chance to delve into the U8G2 code, or the ESP32 IDF and/or espressif32 for Arduino.
Thank you!
The text was updated successfully, but these errors were encountered: