Sunday, June 4, 2023

Drawing on the LCD screen to test functions I need - part 2

ODDITIES OF THE COMMUNICATION WITH THE LCD MODULE

The link between the DE10-Nano (as well as the Raspberry Pi Nano for which it was originally developed) may use Serial Peripheral Interface (SPI) protocol from the processor side but the hardware on the module itself is a mix of I2C protocol devices and some improvised shift register logic. The controller for the LCD screen is set up in parallel mode, not using a serial protocol, thus the shift register logic was added.

The shift register is reset when the Slave Select line is high. When it goes low, the clock transitions on the SCLK line activate shifting of the 16 bit serial-in, parallel out shift register. The MOSI line of SPI is what is shifted into the register. When Slave Select returns to high, the parallel output of the shift register is passed to the LCD controller chip along with a strobe signal, causing the controller to read the 16 bit parallel data. 

If more than 16 bits are transmitted over the SPI link without the slave select being activated, a counter chip will also strobe the LCD controller and reset the register. Thus, sending a stream of 16 bit words under one slave select session is the same as if individual 16 bit words were transmitted each with its own slave select boundary.

Commands to the LCD controller are indicated by the state of the LCD Command/Data signal, but use the same 16 bit parallel input path. The controller only looks at the first 8 bits for a command code, thus if the processor sends only one byte then deactivates slave select, it still causes the register to strobe the controller and pass along the initial 8 bits plus zeros for the rest of the 16 bit parallel word. This means the Raspberry Pi Nano could send only a byte of command and it would still be received properly, while in data mode it has to send a full 16 bit word (or multiple). 

This is not canonical SPI protocol at all. The schematic for the module even uses I2C labels for the clock and input bit line, rather than SPI labels. It is actually neither, just a Rube Goldberg mechanism that successfully handles the communications signals coming from the processor and the code library provided with the module. 

DESIGN DECISION TO INTERFACE STANDARD SPI MASTER WITH THIS MODULE

Upon reflection I chose to return my setup to vanilla SPI operating in mode 0, that is with clock polarity 0 and clock phase 0. I set the word length for SPI to 16 bits which will ensure the slave select behavior intended for the most prevalent transfers, data words going to the LCD module. 

The library sends just a single byte for transmissions of commands, but that won't complete in standard SPI of 16 bit words. I will therefore take the library function called to write commands and pack the 8 bit command twice in a 16 bit word. The controller will pick off the 8 bits it wants from the 16 parallel lines and all should be good. 

This would be the least involved modification of the library from this point forward. Of course I had considerable hacking to do as I ported it from the Raspberry Pi Nano to the Cyclone V chip running Linux, but that is all behind me. Except, of course, for all the testing to make sure it works as intended. 

WIRED UP AND COMMENCING TESTING WITH THIS APPROACH

I hooked up the LCD Module and its wires to the FPGA sides GPIO connector 0. The test program was readied with the intent of seeing the screen erased and a few lines of text written to help me validate the addressing logic on the screen. The application ran to completion but nothing showed up on the screen.

I slowed down the SPI link rate to 2.5MHz, in part because of a note I read that suggested that the touch controller needed to  operate that slowly, but also in case the shift register and counter chips were having a problem at 25MHz as I originally ran the link.

At the same time I looked over my code and discovered that in fact I failed to toggle the LCD Reset line because of a typo in my code. I fixed that and when I ran my initial testing program I was rewarded with a white screen but none of the text I tried to display was visible on the screen. This is either a sign that I initialized the display properly but had issues in my subsequent writing of text, or that the initialization itself didn't happen correctly and the white screen was simply the result of the LCD reset. 

To discriminate between these cases rapidly, I inserted a pause between when I reset the LCD module and when I called for the initialization stream to be written. The white screen definitely occurs after initialization. Good so far.

Then I inserted a call to clear the screen and set it to cyan from white. That executed without making any impact at all on the screen. At this point I guess I will be debugging the initialization and use of the LCD module since I do appear to be communicating with it. There is an outside chance that it is receiving gibberish because my SPI link is still not correct, which might produce the results I see.

I will address this debugging with a mix of signal inspection via oscilloscope and careful review of the initialization sequence and other porting to be certain that I have not introduced this bug myself.  The scope will look for correct polarity and phase of the SPI lines, proper operation of the LCD command/data signal and after that I might verify that some words were properly sent. 

No comments:

Post a Comment