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

ESP32 to SSD1331 HWSPI using correct default pin numbers? #8

Closed
gojimmypi opened this issue Jun 6, 2019 · 11 comments
Closed

ESP32 to SSD1331 HWSPI using correct default pin numbers? #8

gojimmypi opened this issue Jun 6, 2019 · 11 comments

Comments

@gojimmypi
Copy link

I am unable to get the SSD-1331 display working in HWSPI (fast) mode. I'm wondering if the SPI pins are connected the same as the default ESP-Dev-Module (WROOM-32). I'm thinking perhaps not.

I was able to get the ESP32 to use the SSD-1331 display in SWSPI (slow) mode. using these pin definitions and the passthru code loaded on the FPGA:

// ULX3S names in physical connector order:
#define oled_csn  17 // aka cs
#define oled_dc   16 // aka ds
#define oled_resn 25 // aka rst
#define oled_mosi 15 // aka mosi
#define oled_clk  14 // aka sclk

For the SWSPI, the option 1 in the Adafruit LCDGFXDemo example, the display is instantiated like this:

// Option 1: use any pins but a little slower
#pragma message "Using SWSPI"
Adafruit_SSD1331 display = Adafruit_SSD1331(oled_csn, oled_dc, oled_mosi, oled_clk, oled_resn);

For HWSPI, the display is instead instantiated like this:

#pragma message "Using HWSPI"
Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, oled_csn, oled_dc, oled_resn);

I have some addition notes in my SSD1331 Branch of Examples and duplicated here:

Arduino Implmentation Notes

This an Arduino-style solution, suitable for use with either the Ardunio IDE,
or Visual Micro. The display can be initialized either with this software SPI, which is
perhaps more flexible but a little slower:

Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);

... or the alternative is this hardware SPI instantiation (untested / not working at this time):

Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, cs, dc, rst);

Note the comments in the Adafruit code:

hwspi hardcodes those pins, no need to redefine them.

As the ULX3S appears to use different pins, is HWSPI even possible? The cs, dc, rst pins do not seem to be otherwise defined without the macros.

The &SPI is defined in %USERPROFILE%\Documents\Arduino\hardware\espressif\esp32\libraries\SPI\src\SPI.cpp of interest, is this initialization code:

    if(sck == -1 && miso == -1 && mosi == -1 && ss == -1) {
        _sck = (_spi_num == VSPI) ? SCK : 14;
        _miso = (_spi_num == VSPI) ? MISO : 12;
        _mosi = (_spi_num == VSPI) ? MOSI : 13;
        _ss = (_spi_num == VSPI) ? SS : 15;
    } else {
        _sck = sck;
        _miso = miso;
        _mosi = mosi;
        _ss = ss;
    }

We're looking for the defaults not explicitly stated in the declaration Adafruit_SSD1331(&SPI, oled_csn, oled_dc, oled_resn); specifically (MOSI and SCLK) - however here it appears MISO is pin 12 and SCK is 15 (we are expecting MOSI=15 and SCK=14) when _spi_num != VSPI.

TODO: where is _spi_num defined?

The last line of file SPI.cpp

SPIClass SPI(VSPI);

Note in MAIN_ESP32_HAL_SPI_H_ (.\Arduino\hardware\espressif\esp32\cores\esp32\esp32-hal-spi.h)

#define VSPI  3 //SPI bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
@emard
Copy link
Owner

emard commented Jun 6, 2019 via email

@gojimmypi
Copy link
Author

hello @emard and thank you for your prompt response.

yes, I saw your ESP32 web-JTAG project (looks very interesting, btw) ... but that's only the ESP32 part and not the small help of FPGA logic which I think may be the issue in my case. Does your standard passthru include the right pins for the HWSPI OLED display? If not - what specific small help of FGPA is needed? :)

Specifically, here's what (I believe) the passthru does:

N2 to N3 for oled_csn /CS  to wifi_gpio17 (GPIO17)
P1 to L1 for oled_dc /DC   to wifi_gpio16 (GPIO16)
P2 to E3 for oled_resn/RES to wifi_gpio25 (GPIO25)
P3 to J1 for oled_mosi/SDA to sd_cmd      (GPIO15)
P4 to H2 for oled_clk /SCL to sd_clk      (GPIO14)

I have more documentation on that in my WIP example here

Unfortunately, I've not been able to get your LibXSVF-ESP to compile. After chasing all the dependencies, I have this error on the tft.nop():

'class SSD_13XX' has no member named 'nop'

Are you using this one: https://github.com/sumotoy/SSD_13XX ?

Is this the line where you instantiate HWSPI for the display?

SSD_13XX tft = SSD_13XX(__CS_TFT, __DC_TFT);

it was my understanding that the ESP32 WROOM-32 device can use both the SD and OLED at the same time. The Adafruit code even has this comment:

// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
#pragma message "Using HWSPI"
Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, cs, dc, rst);

but let's see if I can simply get the HWSPI OLED working solo first.

thanks a lot for your help. :)

@emard
Copy link
Owner

emard commented Jun 6, 2019 via email

@gojimmypi
Copy link
Author

ah yes, your version of SSD_13XX. Indeed a bit difficult but I now have your websvf_sd compiled and working. Well, more specifically I see output on the serial port. The display is blank.

I instead then tried using your pre-compiled websf_sd - and in this case the display does seem to work - well, at least it is not blank: an IP address is shown. The question then: was the source for websvf_sd/websvf_sd.ino.partitions.bin using HWSPI? Clearly something is different between the working pre-compiled version and the source code.

If the pre-compiled version is using HWSPI, then I would assume that shows the FPGA properly configured, agreed?

For the version I compiled (non-working display), here are the pins being used:

__CS_SD =13
__MOSI_TFT =15
__MISO_TFT =2
__SCL_TFT =14
__DC_TFT =16
__CS_TFT =17
__RES_TFT =25

There's a note in the README

In ESP32 arduino support directory, edit file "SD.cpp"

// spi.begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
spi.begin(14, 12, 13, -1); // v1.7
spi.begin(14, 2, 15, -1); // v1.8 and higher

however my SD.cpp has only one instance of spi.begin() with no parameters.

bool SDFS::begin(uint8_t ssPin, SPIClass &spi, uint32_t frequency, const char * mountpoint)
{
    if(_pdrv != 0xFF) {
        return true;
    }

    spi.begin();

    _pdrv = sdcard_init(ssPin, &spi, frequency);
    if(_pdrv == 0xFF) {
        return false;
    }

    if(!sdcard_mount(_pdrv, mountpoint)){
        sdcard_unmount(_pdrv);
        sdcard_uninit(_pdrv);
        _pdrv = 0xFF;
        return false;
    }

    _impl->mountpoint(mountpoint);
    return true;
}

I've made no edits to my SD.cpp at this time.

@emard
Copy link
Owner

emard commented Jun 6, 2019 via email

@gojimmypi
Copy link
Author

It appears the HWSPI is using these values in SPIClass::begin found in the ESP32 SPI.cpp file:

// SPIClass _sck=18
// SPIClass _miso=19
// SPIClass _mosi=23

From the schematic, there's a note for VSPI using those same pins (is VSPI considered HWSPI?)

ESP32 VSPI pins
GPIO5: SS
GPIO18: SCK
GPIO19: MISO
GPIO23: MOSI

Those pins do not appear to be in the FPGA passthru, so I modified the passthru.v to include these lines in the module declaration:

	// HWSPI
	inout  wire wifi_gpio5, // GPIO5
	input  wire jtag_tck,   // GPIO18
	inout  wire jtag_tdo,   // GPIO19
	inout  wire jtag_tdi,   // GPIO23

and these assignment edits for clk and mosi:

	assign S_oled_csn = wifi_gpio5; // was wifi_gpio17;  
	assign oled_csn = S_oled_csn;
	assign oled_clk = jtag_tck; // GPIO18 was // sd_clk WiFi_GPIO14
	assign oled_mosi = jtag_tdi; // GPIO23;  was //  WiFi GPIO15

I didn't know what to do with GPIO19 (JTAG_TDO) for MISO as there's only a MOSI connector on the display.

I left the other assignment the same:

#define oled_csn  5 // aka cs was 17
#define oled_dc   16 // aka ds
#define oled_resn 25 // aka rst
#define oled_mosi 23 // aka mosi was 15
#define oled_clk  18 // aka sclk was 14

And still, the HWSPI display does not work. With the non-modified passthru, I can get the slower SWSPI working. Any other tips for HWSPI? Thanks

@emard
Copy link
Owner

emard commented Jun 7, 2019 via email

@gojimmypi
Copy link
Author

I believe I have determined why my ULX3S SSD1331 display does not work with the Adafruit Arduino library when attempting to instantiate hardware SPI (aka HWSPI) communication.

According to the comments in the Espressif example:

The ESP32 has four SPi buses, however as of right now only two of
them are available to use, HSPI and VSPI. Simply using the SPI API
as illustrated in Arduino examples will use VSPI, leaving HSPI unused.

The default hardware SPI is the VSPI using these pins:

  //initialise vspi with default pins
  //SCLK = 18, MISO = 19, MOSI = 23, SS = 5

Alternatively, the other hardware SPI is the HSPI, using different pins:

//initialise hspi with default pins
//SCLK = 14, MISO = 12, MOSI = 13, SS = 15

The current passthru implementation is using the HSPI pins:

  S_oled_csn <= wifi_gpio17;
  oled_csn <= S_oled_csn;
  oled_clk <= sd_clk; -- wifi_gpio14
  oled_mosi <= sd_cmd; -- wifi_gpio15
  oled_dc <= wifi_gpio16;
  oled_resn <= gp(11); -- wifi_gpio25

Note also the inconsistency on MOSI - GPIOS15 (in passthru) vs GPIO13 HSPI MOSI default.

Further exacerbating my problem, is that when making the changes to the FPGA passthru (mentioned above) to use the default VSPI pins to prove and fix this, I had not noticed these warnings in Lattice Diamond:

WARNING - Specified location site name "T5" is not valid for jtag_tck. Location directive ignored.

WARNING - Specified location site name "R5" is not valid for jtag_tdi. Location directive ignored.

WARNING - Semantic error in "LOCATE COMP "jtag_tck" SITE "T5" ;": Unable to find site T5 in the device. This preference has been disabled.
WARNING - Semantic error in "LOCATE COMP "jtag_tdi" SITE "R5" ;": Unable to find site R5 in the device. This preference has been disabled.

Here's the JTAG section of the constraint file with the desired pins uncommented:

## JTAG ESP-32 "usb" sheet
# connected to FT231X and ESP-32
# commented out because those are dedicated pins, not directly useable as GPIO
# but could be used by some vendor-specific JTAG bridging (boundary scan) module
LOCATE COMP "jtag_tdi" SITE "R5"; # FTDI_nRI   FPGA receives
#LOCATE COMP "jtag_tdo" SITE "V4"; # FTDI_nCTS  FPGA transmits
LOCATE COMP "jtag_tck" SITE "T5"; # FTDI_nDSR  FPGA receives
#LOCATE COMP "jtag_tms" SITE "U5"; # FTDI_nDCD  FPGA receives
IOBUF PORT "jtag_tdi" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
#IOBUF PORT "jtag_tdo" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
IOBUF PORT "jtag_tck" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
#IOBUF PORT "jtag_tms" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;

Admittedly, I'm a FPGA newbie, and I have no idea why Diamond is complaining about these pin locations. If you can provide some tips on how to passthru to use SCLK = 18, MISO = 19, MOSI = 23, SS = 5 for the VSPI default, I can work on this further.

Here's my ECP5 setting:

image

I do have another SSD-1331 display that should arrive later today to test with a stand-alone ESP32 WROOM-32 board.

In the meantime, although I agree that as you said:

It is absolutely possible to get hardware SPI working with OLED using default passthru

(but with other code, but not with the Arduino libraries expecting VSPI default)

What do you think? Do you agree? What I suggest is that the passthru perhaps be modified to use the VSPI pins instead?

@gojimmypi
Copy link
Author

I forgot to add that regarding changing esp32arduino's SPI sources - that's not very practical. The only option for the end user would be to add conditional board type... the ULX3S? It's not really - as it is actually the ESP32 board.

I'm also curious about the FPGA JTAG cannot be used for anything else but JTAG comment. Can you provide more details?

@emard
Copy link
Owner

emard commented Jun 9, 2019 via email

@emard
Copy link
Owner

emard commented Jul 15, 2019

As hardware SPI from ESP32 works to SD card and OLED in my firmware
I will close this issue. ULX3S is wired correctly to allow hardware SPI with ESP32
and to discuss firmware issues it is more fruitful to refer to ESP32 related gits and forums

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

No branches or pull requests

2 participants