Friday, June 2, 2023

On to plan F - abandoning LTC connector, abandoning GPIO links, leveraging an HPS to FPGA bridge

BLOODIED BUT NOT DEFEATED

I could not get the five signals I needed directly connected to the Linux processor (HPS), nor even four if I went back to tacking the power fail wire onto the HPS side pushbutton. Two signals would be reflected in GPIO ports, with two pins each for the two signals due to the internal connectivity of the LTC section. Two other pins did not change GPIO bits, thus are effectively dead.  Another pin would oddly change both of the GPIO signals simultaneously. This worried me, even if I had only needed the two ,pins that worked.

Selecting the GPIO mux entries in the Platform Designer routes the HPS internal Cyclone V pin to the GPIO registers, but that still doesn't give me a way to inject signals to that internal pin. I was unable to find any way to get this to do what I wanted, which is to use the FPGA side GPIO (same name, not the same at all as the GPIO in the HPS side) to send signals into the HPS side where I could read them from the HPS GPIO registers. 

FALLBACK PLAN F - THE PIO FUNCTION TO THE RESCUE

Altera/Intel provides an intellectual property (IP) block called a PIO that is designed to hook external (and internal) FPGA signals including the FPGA GPIO connector to the bridge that transfers data between the HPS and the FPGA. It is a memory mapped device with four to six words that are accessed from the Linux side by simply reading or writing those memory addresses. 

This device supports up to 32 FPGA pins, allowing us to read or write those pins based on what data we write or read from the defined memory addresses. It can set each of those pins to in, out, inout or bidirectional mode. It can be set to trigger an interrupt when certain pins are active. It can watch for edge transitions and remember them even if the original event is past when we read the edgedetector word. 

In fact this is ideal for my purposes. I instantiated one of these for the two output signals I use to clear the LCD and to indicate to the LCD controller whether an SPI transfer is a command or a data word. This is a very simple output only use. I instantiated a second for the three input signals - power fail, touch pad interrupt and pick (heads loaded on the physical disk drive). I want to watch for the edge to show when a touch has occurred on the touch screen, whereas I only care about the current state for the other two input signals.

I am already using the HPS to FPGA lightweight bridge (H2FLW) for my commands and status between my FPGA logic and the controlling program under Linux. I am able to easily add these other two blocks, input and output PIO, because I can set the address ranges within the H2FLW bridge. 

That bridge has a 10 bit address range, thus we can read or write to any word inside that span from the Linux (HPS) side. The way I designed the connections, addresses in the range of 0 to 7 within the H2FLW will be routed to my existing command/status processing logic. I don't actually care about the address when a read or write comes to that logic, so this still works fine. The input PIO is at address x100 to x107 and the output PIO is at address x200 to 203. 

If I write or read to x100 I set the bits to output from the FPGA GPIO pins wired here or read the state of those pins. If I write or read to x101, I can set the direction of the pin to input or output but this should all be input. Address x103 is the edge capture register which will tell me if the touch interrupt edge was seen. Address x102 is for interrupts which I am not using. Any other address in this range is ignored. 

Using addresses between x100 to x107 causes the read/write requests to be routed only to this input PIO, while addresses between x200 to x203 are routed to the output PIO. Addresses from x000 to x007 are routed to my existing command/status logic. Very clean and neat way of working with the signals. 

INTEGRATING THIS INTO THE DESIGN

My programs on the HPS side that check the input conditions pick, touch interrupt and power fail need to reference the proper addresses in memory - the ranges inside the H2FLW bridge span. This is the same kind of code I used, just with different base and offset addresses. 

My programs to control the LCD had been manipulating the SPI slave select signals 3 and 4, so the mechanism is more different now that the reset and command/data lines make use of the output PIO, but it is not a very difficult change. 

I have already cleanly generated the FPGA and system wide configuration file using the two PIO blocks. A few additional lines will connect them to the FPGA GPIO connector pins for the five signals. 

Finally I have to set up the edge detection configuration for the falling edge that indicates a new touch on the screen and update my application so that it checks the edge and resets the captured edge properly. Again, not very difficult at all. I expect to have a test application to prove out the functioning of the five signals and my access methodology after which I can roll on to getting the SPI communications to the LCD and touch controllers working properly. 

No comments:

Post a Comment