WORD SIZE FOR SPI VERSUS WHAT IS SENT TO LCD AND TOUCH CONTROLLERS
The LCD controller chip is sent one of three sequences of bits - a single byte as a command, a 16 bit word, and a sequence of contiguous 16 bit words. These are delimited by the slave select line which is active at the beginning and then deasserted after 8, 16 or n*16 bits. The touch controller always has 24 bits in a transmission, delimited by slave select active at the start and switched off after the 24th bit.
This means that we should be using 8 bit transmissions at the SPI master in my board. We right justify the 8 bits in a 16 bit register to send or receive data. To send 16 we would write two bytes sequentially right justifying each, 2*n for n 16 bit words. The touch screen would have three bytes sequentially pushed into the register, right justified.
Parenthetically, the LCD controller only uses all 16 bits of a word when it is loading data as pixel values to display. When taking commands or parameters to commands, it only looks at the bottom 8 bits of what is transmitted. For commands, we send only 8 and drop select, but for the parameters we send 16 bits, the actual 8 bit value right justified in that word, then drop select.
This is done for code compatibility for when we are sending pixel data. Pixels are transmitted one 16 bit word each, with five bits of red level, six bits of green level and five bits of blue level in that word. For convenience they transmitted parameters as 16 bits but it would have worked fine, I believe, to send just 8 bits and drop select. I can only assume other devices supported by this library may have used more than 8 bits for parameters otherwise this design choice doesn't make sense.
SLAVE SELECT CONTROL TO MEET NEEDS OF CONTROLLERS
The challenge is that our SPI master will insist on dropping slave select after every byte is transmitted. That will NOT work with the shift register approach for the LCD controller nor with the touch controller. The solution is to manually control the slave select lines, ignoring the signals generated by the SPI master.
To do this, I added two signals to the PIO output block in my FPGA. By sending a 0 to bit positions 2 or 3, I can assert the slave select line for the LCD and touch controller respectively. Sending a 1 turns off the slave select once we sent our 8, 16, n*16 or 24 bit transmission.
TESTING THE COMMUNICATIONS CORRECTNESS
I will modify the programs so that I do a minimal transmission of each length to the appropriate controller chip, choosing a sequence that will give me confirmation of successful reception. I have a command for the LCD controller chip which returns some device identifying data - this is a good first test. The touch controller can be asked to send various types of data back, which I can view to determine that it worked properly.
A transaction which returns the ID of the LCD controller chip:
- turn on slave select
- set the Command/Data signal to command
- transmit xD3 to the LCD controller chip
- set the Command/Data signal to data
- send two16 bit words of x0000
- drop slave select
What will be returned is four bytes during the data transfer. The first byte is dummy and can be ignored. The next three bytes returned should be x00, x94 and x88 in order to believe we have a good communication path with the LCD controller.
If I send a command of x90 to the touch controller followed by two bytes of x00, it will return the 12 bit ADC value during parts of the second and third byte transfers. This value will be the Y value of where the stylus is touching on the screen. By moving the stylus I can be certain that the communications with the touch controller is working properly.
The final test will be sending a single command byte to turn off the display, once it is initialized to all pixels on by the existing code. This is done by:
- turn on slave select
- set Command/Data to command (value 0)
- send x22
- turn off slave select
When this works, we will have tested all the modes and can move on to debugging the specific codes we are transmitting to the two controllers.
RESULTS OF THE TEST
First I reran the existing test application after switching over to the 8 bit word frame and manual slave select scheme. I hung up trying to write to the LCD controller which I realized was due to my failure to turn on both the actual slave select of the SPI module as well as the manual one I control through PIOout bits.
I can see that I am transferring data with the SPI master showing appropriate status as I write an 8 bit word frame. The LCD panel did not light up but I am feeling signs of progress and will keep testing from this point until I get everything debugged.
One potential issue would be the shift out and in order between the SPI master and the slave devices. If I don't get a good response to one of the simple tests below, I might try sending the same stream with the bits flipped end for end.
I then whipped up the three simple tests described above and executed the two of them that I could - the single command to blank pixels is predicated on the screen having been lit up. I was however able to send the sequences to interrogate the LCD controller ID and to measure the Y coordinate of a touch.
Whether I sent to the touch controller or the LCD controller, whether I reversed the bits or not, I always got back zeros but the SPI master believed it was correctly transmitting what I sent. Time to devise some deeper experiments and diagnostic output to help me figure this out.