this is the question, a few days ago I bought the FPGA Cyclone II development board from altera (I am a big fan of arduino and I have a variety of modules and others) at first I started studying Verilog, I provided some led onboards to learn how The clock works and others, but now I want to try something a little more difficult, an LCD. I saw several forums / pages but they use the LCD without the I2C interface and I want to use it with I2C for two reasons, first because that way I will also learn how to use the I2C protocol for other sensors, and second, I don't want to desolder the module. If anyone can give me some piece of code or website / forum where I can learn how to use this and show a little text, I would appreciate it. Greetings!
-
\$\begingroup\$ IMO an I2C controller for an LCD might be a difficult task for a beginner. What I suggest you do first is use your Arduino to interface with the LCD via I2C. Learn and understand the I2C commands that you need to send to the LCD to make it do what you want. Like turn on and print 'Hello World' for instance. Then after you have a firm understanding, design your I2C controller on the FPGA to do the same thing. Which LCD and development board do you have? \$\endgroup\$– mrbeanApr 10, 2021 at 5:52
-
\$\begingroup\$ @mrbean, I understood the LCD is soldered onto the FPGA board, so connecting it to the Arduino would be difficult -- also, the Arduino hides the I2C protocol from the programmer, so there is little knowledge to be gained that way. \$\endgroup\$– Simon RichterApr 10, 2021 at 5:54
-
\$\begingroup\$ Which LCD is on the board? My suggestion is to start with the 'high-level' approach first. Like turn on the LCD and print characters. This sounds easy but sometimes it's more complicated than you think. Then when you're ready, drill down into the details using the FPGA. I am speaking from experience when I first started out. \$\endgroup\$– mrbeanApr 10, 2021 at 5:55
-
\$\begingroup\$ I say this because the documentation for the LCD's is sometimes not good. It's going to be quicker to program a microcontroller and try things out than to fumble with the FPGA. Especially if you don't know how to build a testbench and run a simulation. \$\endgroup\$– mrbeanApr 10, 2021 at 6:03
-
\$\begingroup\$ Which dev board it is? There is a good chance that normal 16x2 char LCDs are not even used via I2C. \$\endgroup\$– JustmeApr 10, 2021 at 10:04
1 Answer
You'd implement a block for the low-level parts of the I2C protocol, and a block that schedules the data transfers, and then evolve from there.
I2C has a gated clock and a bidirectional data pin, these are your first steps on the low level block, and both are great learning experiences as well:
The clock isn't very fast, so you can in theory generate the clock as a normal signal by dividing a faster clock, but that is messy to get right since you also need to drive the data line synchronously to that.
So step 1 is to generate an I2C clock with a PLL, you can find the PLL interface in the IP Catalog.
Check that the clock works, then build a gated clock output.
This is typically done by instantiating a DDR output driver (also in the IP Catalog) that outputs the gate signal while the clock is high, and 0
while the clock is low.
The third thing you want (also from the IP Catalog) is a bidirectional IO driver for the data line.
Then, implement a state machine that performs a single transfer over the I2C bus using these primitives, ideally some hardcoded command that is immediately visible on the LCD, and then extend from there.
Connecting that to the rest of the design will later require either a rework of clocking the I2C part of the design to use a faster clock and pulses from a divisor that advance the I2C state machine, or a clock domain crossing mechanism, that will be another great learning opportunity. :)
-
1\$\begingroup\$ Use a counter to divide the clock down. Not a PLL. SCL of I2C is < 100 kHz/400kHz/1MHz typically. A PLL is typically not used to create low speed clocks like this in an FPGA. Also, using a gated clock on an FPGA is typically bad design practice. \$\endgroup\$– mrbeanApr 10, 2021 at 6:12
-
\$\begingroup\$ @mrbean, in principle I agree that the divider is the better choice, but it runs into issues if you try to actually use the divider output as a clock, so there's a big step on the learning curve here that I would not want to put first. \$\endgroup\$ Apr 10, 2021 at 6:30
-
\$\begingroup\$ Yes, you can use a divider clock as an output clock. What issues are you refering to specifically? Dividing a clock input down via a counter and driving an IO pin as a serial clock is very common. This is used for I2C, SPI, etc... on FPGA's all the time. You'll need to be more specific what issues you are referring to. A PLL is typically not used for this purpose. \$\endgroup\$– mrbeanApr 10, 2021 at 7:01
-
\$\begingroup\$ @mrbean, as an output, yes, but clocking other logic will give warnings because it's no longer a clock net, so you'd have to generate an enable pulse synchronous to the real clock, and use that in the I2C logic. Totally doable and the best approach, but needs more upfront explanation and is harder to debug, which is why I preferred the PLL approach for didactic purposes and mentioned the "proper" way to do it only in the last paragraph as an optimization. \$\endgroup\$ Apr 10, 2021 at 9:31
-
\$\begingroup\$ It sounds like you've never actually done an I2C master in an FPGA. In fact, as far as the FPGA is concerned, SCL is just an ordinary signal -- it is never used as a clock in the logic. And there's nothing "messy" about dealing with SCL and SDA, since there is never any need for simultaneous edges on the two signals. \$\endgroup\$ Apr 10, 2021 at 13:43