{"id":1615,"date":"2020-12-29T20:19:05","date_gmt":"2020-12-29T20:19:05","guid":{"rendered":"http:\/\/box2281.temp.domains\/~ganzwork\/?page_id=1615"},"modified":"2022-01-29T19:37:19","modified_gmt":"2022-01-29T19:37:19","slug":"i2c-master-for-nesmini-controller","status":"publish","type":"page","link":"https:\/\/ganslermike.com\/?page_id=1615","title":{"rendered":"I2C Master for NESMini Controller"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This FPGA project communicates with a Nintendo Classic Mini Controller by implementing an <a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/\" target=\"_blank\">I2C<\/a> master device in <a rel=\"noreferrer noopener\" href=\"https:\/\/www.chipverify.com\/verilog\/verilog-tutorial\" target=\"_blank\">Verilog<\/a>.  <\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"Retro Nintendo Classic Mini controller comm with FPGA over I2C\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/zHz0d-TQWGw?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Preview of some waveforms discussed in detail further below:<\/p>\n\n\n\n<figure class=\"wp-block-gallery aligncenter has-nested-images columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"125\" data-id=\"1938\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=640%2C125&#038;ssl=1\" alt=\"\" class=\"wp-image-1938\" srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=1024%2C200&amp;ssl=1 1024w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=300%2C58&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=768%2C150&amp;ssl=1 768w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=1536%2C299&amp;ssl=1 1536w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?w=1914&amp;ssl=1 1914w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption>No buttons pressed (bytes 4,5=0xFF,0xFF)<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"125\" data-id=\"1939\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=640%2C125&#038;ssl=1\" alt=\"\" class=\"wp-image-1939\" srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=1024%2C200&amp;ssl=1 1024w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=300%2C58&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=768%2C150&amp;ssl=1 768w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=1536%2C299&amp;ssl=1 1536w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?w=1914&amp;ssl=1 1914w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption>&#8216;A&#8217; button pressed (bytes 4,5=0xFF,0xEF)<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"which-controller\">Which Controller?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The controller I used this project looks like the original NES controller (up\/down\/left\/right, select, start, A, and B only) but has a <strong>Wii-style connector<\/strong>.   This controller is fundamentally different than the similar-looking USB controllers.    NES Classic Mini retro controllers with the Wii connector communicate over an <a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/\" target=\"_blank\">I2C<\/a> interface, which is necessary for this project.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s a pic of the controller I purchased:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-old-school-controller.jpg?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-old-school-controller.jpg?w=400&#038;ssl=1\" alt=\"\" class=\"wp-image-1927\" \/><\/a><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">I developed this on a <a rel=\"noreferrer noopener\" href=\"https:\/\/www.terasic.com.tw\/cgi-bin\/page\/archive.pl?Language=English&amp;No=1021\" target=\"_blank\">Terasic DE10-Lite board<\/a> using the <a rel=\"noreferrer noopener\" href=\"https:\/\/fpgasoftware.intel.com\/?edition=lite\" target=\"_blank\">Quartus Prime 20.1, Light Edition<\/a> toolchain.  Nothing about the Verilog code is very specific to this board or its Altera <a rel=\"noreferrer noopener\" href=\"https:\/\/www.intel.com\/content\/www\/us\/en\/products\/programmable\/fpga\/max-10.html\" target=\"_blank\">MAX10<\/a> FPGA, so it should be easy to adapt to other boards.  <strong>The source code is well commented and is the best place to understand the assumptions and limitations.  Additional <a href=\"#caveats-jump\" data-type=\"internal\" data-id=\"#caveats-jump\">Caveats<\/a> are also in a separate section below.<\/strong><\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"why\">Why?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I made this to support another project which is an FPGA-based 80\u2019s retro video game.  The game is all FPGA, i.e. no <a rel=\"noreferrer noopener\" href=\"https:\/\/people.ece.cornell.edu\/land\/courses\/ece5760\/DE1_SOC\/HPS_INTRO_54001.pdf\" target=\"_blank\">HPS<\/a>, no <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Soft_microprocessor\" target=\"_blank\">soft MCU<\/a>, no <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Framebuffer\" target=\"_blank\">frame buffer<\/a>, just on-the-fly generation of a <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Video_Graphics_Array\" target=\"_blank\">VGA<\/a> signal 800\u00d7600 at 60 Hz (40MHz pixel clock) and gameplay also implemented in the FPGA. A fun example of what FPGAs can do. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The game uses two instantiations of the code from this NES controller project.  That provides fully independent communication with two controllers for the game&#8217;s two players.  The fact that the off-the-shelf controllers have the same slave device address is no issue, since the two instantiations create completely separate I2C buses.  The magic of FPGAs&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">See more detail on that project here &#8211; <a href=\"https:\/\/ganslermike.com\/?page_id=2177\">Ganzvaders<\/a>.<\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"some-i2c-musings\">Some I2C Musings<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Nintendo Classic Mini controller acts as an <a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/\" target=\"_blank\">I2C<\/a> slave device, so my Verilog code implements an <a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/\" target=\"_blank\">I2C<\/a> master device.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.i2c-bus.org\/\">I2C<\/a> is a bidirectional, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Open_collector\">open-drain<\/a>, synchronous serial protocol that&#8217;s used mostly on PCBs between IC&#8217;s, but as in this case, sometimes it&#8217;s also used with offboard devices.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is not intended to be a full I2C tutorial.  Many other sites online provide great detail on I2C, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/\" target=\"_blank\">i2c-bus.org<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.ti.com\/lit\/slva704\" target=\"_blank\">App Note slva704 from TI<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/I%C2%B2C\" target=\"_blank\">Wikipedia&#8217;s I2C page<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/learn.sparkfun.com\/tutorials\/i2c\" target=\"_blank\">Sparkfun<\/a><\/li><\/ul>\n\n\n\n<div style=\"height:23px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Please check out those sites above for if you&#8217;re new to <a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/\" target=\"_blank\">I2C<\/a>.  I won&#8217;t go in all the details they do, but will mention a few highlights:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>I2C physically consists of a data line (SDA) and a clock line (SCL).<\/li><li>Typical data rates are 100 KHz and 400 KHz, though faster speeds exist but are fairly rare.  This project uses 100 KHz.<\/li><li>SDA and SCL are both <a href=\"https:\/\/en.wikipedia.org\/wiki\/Open_collector\">open-drain<\/a>, meaning that devices drive the lines to ground for a LOW, but HIGH values are expressed by releasing the line and allowing pull-up resistors to bring it to the positive voltage rail.  This makes bidirectional data straightforward, but the weak drive capability of the pull-up resistors also makes it difficult to run long distances.<\/li><li>I2C is synchronous, unlike a <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Universal_asynchronous_receiver-transmitter\" target=\"_blank\">UART<\/a>, and transactions are paced by the SCL (clock) line.<\/li><li>A I2C bus has at least one master device, who controls SCL, and one or more slave devices.  Technically, a bus can have multiple masters and a slave device can control the clock under a special circumstance called &#8220;<a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/clock-stretching\/\" target=\"_blank\">clock stretching<\/a>&#8220;, but let&#8217;s keep it simple for now.<\/li><li>All communication is between a master device and a slave device.  Slave devices cannot directly communicate with each other.<\/li><li>There are special conditions on the bus to indicate the beginning and end of a transaction called START and STOP conditions. These are the only time when SDA changes while the SCL is HIGH, allowing devices to easily detect these conditions<\/li><li>The master device controls all transactions, and begins each with a START condition, followed by an address indicating which slave device&#8217;s turn it is to talk on the bus.<\/li><li>Each slave device has its own 7 bit unique <a rel=\"noreferrer noopener\" href=\"https:\/\/www.i2c-bus.org\/addressing\/\" target=\"_blank\">address<\/a> on the bus.  (10 bit address modes do exist, but are less common.)<\/li><li>When the slave device address is transmitted, it is always appended with an additional bit (making an 8 bit byte).  That extra bit, the R\/*W bit, indicates whether the master device is writing to the slave device or reading from the slave device<\/li><li>After some number of byte transfers between the master device and the slave device, the master creates a STOP condition on the bus, ending the transaction.<\/li><\/ul>\n\n\n\n<div style=\"height:24px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"caveats-jump\">Caveats<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A few caveats about my implementation:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>my code <strong><span class=\"has-inline-color has-black-color\"><span style=\"text-decoration: underline;\">does not check for ACK\/NACKs from the slave device<\/span><\/span><\/strong> &#8211; if you want error checking you will have to add it!!<\/li><li>my code <strong><span class=\"has-inline-color has-black-color\"><span style=\"text-decoration: underline;\">does not support clock stretching<\/span><\/span><\/strong><\/li><li>I2C depends on <a href=\"https:\/\/en.wikipedia.org\/wiki\/Open_collector\">open-drain<\/a> connections for the SCL and SDA lines.  To achieve this, the Verilog code <a rel=\"noreferrer noopener\" href=\"https:\/\/www.nandland.com\/articles\/inference-vs-instantiation-vs-gui.html\" target=\"_blank\">infers<\/a> <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Three-state_logic\" target=\"_blank\">tristate drivers<\/a> on the toolchain and board mentioned above.  If there are issues with other tools or FPGAs, verifying the driver for these lines may be necessary<\/li><li>if this code is used in a scenario where clock domain crossing is done, additional care naturally will be needed to manage that<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The limitations above were not an issue in this NES controller application.  See the source code for more details.<\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"protocol\">Protocol<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As mentioned above, the Nintendo Classic Mini controller is the slave device, which means the Verilog code must implement a master device to communicate with it.  In order to obtain the switch states from the controller, a sequences of writes and reads are necessary.  The FPGA first writes to the controller, essentially saying &#8220;I&#8217;m ready for data&#8221;, then the FPGA reverses the direction of data on the I2C bus, and reads 6 bytes from the controller.  Those bytes contains the button states.  This set of transactions is defined by the firmware in the controller itself and is summarized on many websites, including Albert Gonzalez&#8217;s page <a rel=\"noreferrer noopener\" href=\"http:\/\/albertgonzalez.coffee\/projects\/snes_mini_arduino\/\" target=\"_blank\">here<\/a>.<\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"verilog-code-lower-layer\">Verilog Code &#8211; Lower Layer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As mentioned above, my code has two main layers &#8211; a lower level that performs fundamental I2C operations and a higher level that sequences the set of transactions specific to this type of controller.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The lower-level can perform any of the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>generate an I2C start condition<\/li><li>generate an I2C stop condition<\/li><li>transmit a byte from master to slave<\/li><li>receive a byte from slave to master<\/li><\/ul>\n\n\n\n<div style=\"height:26px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">This is done in module <strong>gI2C_low_level_tx_rx.v<\/strong> and is implemented by a small <a href=\"https:\/\/en.wikipedia.org\/wiki\/Finite-state_machine\" target=\"_blank\" rel=\"noreferrer noopener\">finite state machine<\/a>, seen below.  <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-driver-level-cropped-1.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"458\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-driver-level-cropped-1.png?resize=640%2C458&#038;ssl=1\" alt=\"\" class=\"wp-image-2082\" srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-driver-level-cropped-1.png?w=933&amp;ssl=1 933w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-driver-level-cropped-1.png?resize=300%2C214&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-driver-level-cropped-1.png?resize=768%2C549&amp;ssl=1 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption>      gI2C_low_level_tx.v state machine<\/figcaption><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Once the low level driver module (<strong>gI2C_low_level_tx_rx.v<\/strong>) has completed the commanded operation, it indicates this to the caller and returns to the IDLE state.  <\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><span style=\"text-decoration: underline;\">Header and I\/O interface for gI2C_low_level_tx_rx.v (full code on <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ganz125\/gI2C_mini_master\" target=\"_blank\">GitHub<\/a>):<\/span><\/strong><\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #888888\">\/\/  ------------------------------------------------------------------------------<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  gI2C_low_level_tx_rx.v -- low level I2C comm for Nintendo Class Mini controller<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Copyright (C) 2020 Michael Gansler<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This program is free software: you can redistribute it and\/or modify<\/span>\n<span style=\"color: #888888\">\/\/  it under the terms of the GNU General Public License as published by<\/span>\n<span style=\"color: #888888\">\/\/  the Free Software Foundation, either version 3 of the License, or<\/span>\n<span style=\"color: #888888\">\/\/  (at your option) any later version.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This program is distributed in the hope that it will be useful,<\/span>\n<span style=\"color: #888888\">\/\/  but WITHOUT ANY WARRANTY; without even the implied warranty of<\/span>\n<span style=\"color: #888888\">\/\/  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<\/span>\n<span style=\"color: #888888\">\/\/  GNU General Public License for more details.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  You should have received a copy of the GNU General Public License<\/span>\n<span style=\"color: #888888\">\/\/  along with this program.  If not, see &lt;https:\/\/www.gnu.org\/licenses\/&gt;.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  ------------------------------------------------------------------------------<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Module:       gI2C_low_leveL_tx_rx.v<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Objective:    Performs basic low-level I2C Master operations to <\/span>\n<span style=\"color: #888888\">\/\/                support communications witha Nintendo Class Mini controller.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Assumptions:  - 40 MHz input clock<\/span>\n<span style=\"color: #888888\">\/\/                  Altera MAX10 FPGA<\/span>\n<span style=\"color: #888888\">\/\/                - Does not check for ACK's from slave<\/span>\n<span style=\"color: #888888\">\/\/                - Does not perform clock stretching<\/span>\n<span style=\"color: #888888\">\/\/                - Development done on Terasic DE10-Lite board with <\/span>\n<span style=\"color: #888888\">\/\/                - No clock domain crossings accomodated.  If this module <\/span>\n<span style=\"color: #888888\">\/\/                  were used in an actual situation with clock domain <\/span>\n<span style=\"color: #888888\">\/\/                  crossings or asynchronous inputs, more attention <\/span>\n<span style=\"color: #888888\">\/\/                  (i.e. code changes) would be necessary to manage the <\/span>\n<span style=\"color: #888888\">\/\/                  situation.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Notes:<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This module performs a number of low-level I2C Master activities.  The<\/span>\n<span style=\"color: #888888\">\/\/  intention is that a higher level module coordinates the overall<\/span>\n<span style=\"color: #888888\">\/\/  transaction, while this module is commanded by that module <\/span>\n<span style=\"color: #888888\">\/\/  to perform any of the following operations:<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/    1.  create a start condtion<\/span>\n<span style=\"color: #888888\">\/\/    2.  create a stop condtion<\/span>\n<span style=\"color: #888888\">\/\/    3.  transmit a byte from master to slave<\/span>\n<span style=\"color: #888888\">\/\/    4.  receive a byte from slave to master<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Note that clock stretching is not implemented since this<\/span>\n<span style=\"color: #888888\">\/\/  appeared to not be necessary for the the Nintendo Classic Mini <\/span>\n<span style=\"color: #888888\">\/\/  retro controller interfacing application.  Likewise, ACKs\/NACKs<\/span>\n<span style=\"color: #888888\">\/\/  from the slave are not evaluated.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  The diagram below shows typical  I2C SDA and SCL waverforms:<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/      START                                                STOP <\/span>\n<span style=\"color: #888888\">\/\/      COND                                                 COND<\/span>\n<span style=\"color: #888888\">\/\/      ____       __  __  __  __  __  __  __  __  __         ___<\/span>\n<span style=\"color: #888888\">\/\/  SDA     |_____\/A6\\\/A5\\\/A4\\\/A3\\\/A2\\\/A1\\\/A0\\\/RW\\\/AK\\_______|<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/                  ^   ^   ^   ^   ^   ^   ^   ^   ^<\/span>\n<span style=\"color: #888888\">\/\/      ______       _   _   _   _   _   _   _   _   _      _____<\/span>\n<span style=\"color: #888888\">\/\/  SCL       |_____| |_| |_| |_| |_| |_| |_| |_| |_| |____|<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/ ^'s show SCL rising edge, where receiver samples SDA.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/ The above shows the case of TX'ing the Address (7 bits) and the<\/span>\n<span style=\"color: #888888\">\/\/ R\/*W bit followed by receiving an ACK from the receiver.  <\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/ Data byte transfers in the opposite direction are analogous, <\/span>\n<span style=\"color: #888888\">\/\/ 8 bits of data + an ACK\/NACK bit.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #003366; font-weight: bold\">`default_nettype<\/span> none            <span style=\"color: #888888\">\/\/ Require all nets to be declared before used.<\/span>\n                                 <span style=\"color: #888888\">\/\/ --&gt; typo'd net names get trapped<\/span>\n\n<span style=\"color: #008800; font-weight: bold\">module<\/span> gI2C_low_level_tx_rx\n#(\n   <span style=\"color: #008800; font-weight: bold\">parameter<\/span> <span style=\"color: #003366; font-weight: bold\">TICKS_PER_I2C_CLK_PERIOD<\/span> <span style=\"color: #333333\">=<\/span> <span style=\"color: #005588; font-weight: bold\">400<\/span>   <span style=\"color: #888888\">\/\/ Ticks of input clock per I2C SCL period (10 usec).<\/span>\n)\n(\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #888888\">\/\/ INPUTS<\/span>\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">input<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span>       clk,         <span style=\"color: #888888\">\/\/ Input clock, tested with 40 MHz<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">input<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span>       rst,         <span style=\"color: #888888\">\/\/ Reset input<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">input<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span> [<span style=\"color: #005588; font-weight: bold\">2<\/span><span style=\"color: #333333\">:<\/span><span style=\"color: #005588; font-weight: bold\">0<\/span>] command,     <span style=\"color: #888888\">\/\/ Input command for which I2C operation to create<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">input<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span> [<span style=\"color: #005588; font-weight: bold\">7<\/span><span style=\"color: #333333\">:<\/span><span style=\"color: #005588; font-weight: bold\">0<\/span>] tx_byte,     <span style=\"color: #888888\">\/\/ Byte to transmit from master to slave (if requested)<\/span>\n\n   <span style=\"color: #008800; font-weight: bold\">input<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span>       <span style=\"color: #003366; font-weight: bold\">ACK<\/span>,         <span style=\"color: #888888\">\/\/ 1=Master ACKs after slave read, 0=Master NACKs<\/span>\n   \n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #888888\">\/\/ OUTPUTS<\/span>\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span> [<span style=\"color: #005588; font-weight: bold\">7<\/span><span style=\"color: #333333\">:<\/span><span style=\"color: #005588; font-weight: bold\">0<\/span>] read_byte,   <span style=\"color: #888888\">\/\/ Byte read from slave (if requested)<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>       busy,        <span style=\"color: #888888\">\/\/ Indicates that this module is busy performing a sequence of actions<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>       data_valid,  <span style=\"color: #888888\">\/\/ Indicates that a byte has been read from the slave and is available<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>       done,        <span style=\"color: #888888\">\/\/ Indicates that requested action is complete.<\/span>\n   \n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #888888\">\/\/ I2C I\/O<\/span>\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">input<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span>       i_sda,       <span style=\"color: #888888\">\/\/ Input from tristate driver output, connected externally to SDA line   <\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>       o_sda,       <span style=\"color: #888888\">\/\/ Output from this module indicating how to drive I2C SDA externally<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>       o_scl        <span style=\"color: #888888\">\/\/ Output from this module indicating how to drive I2C SCL externally<\/span>\n);\n<\/pre><\/div>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"verilog-code-top-layer\">Verilog Code &#8211; Top Layer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The higher level module (<strong>gI2C_mini_nes_read.v<\/strong>) sequences the specific transactions for this controller.  This consists of a sort of command and response, where a byte is written to the controller, then 6 bytes are read from the controller.  Sequencing of these controller-specific transactions is performed in this module by another <a href=\"https:\/\/en.wikipedia.org\/wiki\/Finite-state_machine\" target=\"_blank\" rel=\"noreferrer noopener\">finite state machine<\/a>, seen below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-top-level-cropped.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-top-level-cropped.png?w=640&#038;ssl=1\" alt=\"\" class=\"wp-image-1933\"  srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-top-level-cropped.png?w=841&amp;ssl=1 841w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-top-level-cropped.png?resize=300%2C257&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-state-diagram-top-level-cropped.png?resize=768%2C658&amp;ssl=1 768w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><figcaption>gI2C_mini_nes_read.v state machine<\/figcaption><\/figure><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The higher level module (<strong>gI2C_mini_nes_read.v<\/strong>) instantiates the low-level Verilog module (<strong>gI2C_low_level_tx_rx.v<\/strong>).  It then sends commands to the lower level module for each I2C action, and parses the responses from the controller.  Button states are provided as individual flags and as a packed word.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Details of how this is implemented is documented in the Verilog source code.  <\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><span style=\"text-decoration: underline;\">Header and I\/O interface for gI2C_mini_nes_read.v (full code on <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ganz125\/gI2C_mini_master\" target=\"_blank\">GitHub<\/a>):<\/span><\/strong><\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #ffffff; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #888888\">\/\/  ------------------------------------------------------------------------------<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  gI2C_mini_nes_read.v -- I2C comm with Nintendo Class Mini controller<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Copyright (C) 2020 Michael Gansler<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This program is free software: you can redistribute it and\/or modify<\/span>\n<span style=\"color: #888888\">\/\/  it under the terms of the GNU General Public License as published by<\/span>\n<span style=\"color: #888888\">\/\/  the Free Software Foundation, either version 3 of the License, or<\/span>\n<span style=\"color: #888888\">\/\/  (at your option) any later version.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This program is distributed in the hope that it will be useful,<\/span>\n<span style=\"color: #888888\">\/\/  but WITHOUT ANY WARRANTY; without even the implied warranty of<\/span>\n<span style=\"color: #888888\">\/\/  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<\/span>\n<span style=\"color: #888888\">\/\/  GNU General Public License for more details.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  You should have received a copy of the GNU General Public License<\/span>\n<span style=\"color: #888888\">\/\/  along with this program.  If not, see &lt;https:\/\/www.gnu.org\/licenses\/&gt;.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  ------------------------------------------------------------------------------<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Module:       gI2C_mini_nes_read.v<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Objective:    Performs basic I2C Master operations to communicate with<\/span>\n<span style=\"color: #888888\">\/\/                a Nintendo Class Mini controller and read all buttons.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Assumptions:  - 40 MHz input clock<\/span>\n<span style=\"color: #888888\">\/\/                - Development done on Terasic DE10-Lite board with <\/span>\n<span style=\"color: #888888\">\/\/                  Altera MAX10 FPGA<\/span>\n<span style=\"color: #888888\">\/\/                - No clock domain crossings accomodated.  If this module <\/span>\n<span style=\"color: #888888\">\/\/                  were used in an actual situation with clock domain <\/span>\n<span style=\"color: #888888\">\/\/                  crossings or asynchronous inputs, more attention <\/span>\n<span style=\"color: #888888\">\/\/                  (i.e. code changes) would be necessary to manage the <\/span>\n<span style=\"color: #888888\">\/\/                  situation.<\/span>\n<span style=\"color: #888888\">\/\/  Notes:<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This module communicates as a Master over an I2C bus and decodes <\/span>\n<span style=\"color: #888888\">\/\/  button press status from a NES Classi Mini retro controller.  This is <\/span>\n<span style=\"color: #888888\">\/\/  the sort of controller that looks like an original NES controller<\/span>\n<span style=\"color: #888888\">\/\/  (up\/down\/left\/right\/select\/start\/A\/B), but has a completely different<\/span>\n<span style=\"color: #888888\">\/\/  interface than the original.  This updated retro controller has a Wii<\/span>\n<span style=\"color: #888888\">\/\/  style connector and an I2C bus.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  The high-level module in this file coordinates the sequences of starts,<\/span>\n<span style=\"color: #888888\">\/\/  stops, transmits and reads for a full transaction with the controller.  <\/span>\n<span style=\"color: #888888\">\/\/  This obtains the status of all of the buttons: up, down, left, right,<\/span>\n<span style=\"color: #888888\">\/\/  select, start, A, and B.  Since this controller is a rendition of the <\/span>\n<span style=\"color: #888888\">\/\/  original NES controller, this is the full set of buttons on the device.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This module also instantiates a lower level I2c module which handles <\/span>\n<span style=\"color: #888888\">\/\/  the bit by bit signaling of each I2C operation.  The sequence of these<\/span>\n<span style=\"color: #888888\">\/\/  operations is coordinated by this upper level module, sending a<\/span>\n<span style=\"color: #888888\">\/\/  number of commands to the lower level driver for each operation, <\/span>\n<span style=\"color: #888888\">\/\/  resulting in one full transaction with the device.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Once transaction consists of the following operations:<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/   - generate start condition<\/span>\n<span style=\"color: #888888\">\/\/   - transmit address to slave, write mode<\/span>\n<span style=\"color: #888888\">\/\/   - write 0x00 to slave<\/span>\n<span style=\"color: #888888\">\/\/   - generate stop condition<\/span>\n<span style=\"color: #888888\">\/\/   - generate start condition<\/span>\n<span style=\"color: #888888\">\/\/   - transmit address to slave, read mode<\/span>\n<span style=\"color: #888888\">\/\/   - read 6 bytes from slave (the last two bytes contain the button data)<\/span>\n<span style=\"color: #888888\">\/\/   - generate a stop condition<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  This complete transaction requires less than 1.5 msec, allowing high<\/span>\n<span style=\"color: #888888\">\/\/  polling rates of the buttons, if needed.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  The input clock used for testing and development was 40 MHz since this <\/span>\n<span style=\"color: #888888\">\/\/  module was intended for a VGA project that has a 40 MHz pixel clock).  <\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #888888\">\/\/  Parameterization was done to allow other clock frequencies.  Comments are<\/span>\n<span style=\"color: #888888\">\/\/  included describing areas to be mindful of when changing the clock. <\/span>\n<span style=\"color: #888888\">\/\/  The main concern is the counter in the lower-level module (ctr) that <\/span>\n<span style=\"color: #888888\">\/\/  regulates SCL bit timing.  Make sure it has sufficient width if a <\/span>\n<span style=\"color: #888888\">\/\/  faster input clock is used.<\/span>\n<span style=\"color: #888888\">\/\/<\/span>\n<span style=\"color: #003366; font-weight: bold\">`default_nettype<\/span> none                    <span style=\"color: #888888\">\/\/ Require all nets to be declared before used.<\/span>\n                                         <span style=\"color: #888888\">\/\/ --&gt; typo'd net names get trapped<\/span>\n\n<span style=\"color: #008800; font-weight: bold\">module<\/span> gI2C_mini_nes_read\n#( \n   <span style=\"color: #008800; font-weight: bold\">parameter<\/span> <span style=\"color: #003366; font-weight: bold\">SLAVE_ADDR<\/span> <span style=\"color: #333333\">=<\/span> <span style=\"color: #005588; font-weight: bold\">7'h52<\/span>,         <span style=\"color: #888888\">\/\/ This is the I2C address of the NES mini controller<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">parameter<\/span> <span style=\"color: #003366; font-weight: bold\">TICKS_PER_I2C_CLK<\/span> <span style=\"color: #333333\">=<\/span> <span style=\"color: #005588; font-weight: bold\">400<\/span>     <span style=\"color: #888888\">\/\/ For 40 MHz clock -&gt; 400.   <\/span>\n                                         <span style=\"color: #888888\">\/\/ 10 is useful for simulation.<\/span>\n                                         <span style=\"color: #888888\">\/\/ Note: standard I2C is 100 KHz which means 10 usec\/bit.  <\/span>\n                                         <span style=\"color: #888888\">\/\/ Therefore, if input clk is 40 MHz, then:<\/span>\n                                         <span style=\"color: #888888\">\/\/ TICKS_PER_I2C_CLK = 40MHz*10usec = 400 counts.<\/span>\n)\n(\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #888888\">\/\/ INPUTS <\/span>\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">input<\/span>  <span style=\"color: #333399; font-weight: bold\">wire<\/span>          clk_40,          <span style=\"color: #888888\">\/\/ Input clock.  Tested with 40 MHz clock<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">input<\/span>  <span style=\"color: #333399; font-weight: bold\">wire<\/span>          rst,             <span style=\"color: #888888\">\/\/ Active high reset line.<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">input<\/span>  <span style=\"color: #333399; font-weight: bold\">wire<\/span>          request_data,    <span style=\"color: #888888\">\/\/ Pulse this high to initiate full data transfer sequence<\/span>\n                                         <span style=\"color: #888888\">\/\/ which includes all Starts, Stops, Master Writes, and Master Reads<\/span>\n                                         <span style=\"color: #888888\">\/\/ to obtain data from the controller.<\/span>\n   \n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #888888\">\/\/ OUTPUTS<\/span>\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           data_valid,      <span style=\"color: #888888\">\/\/ Pulse that indicates controller_data was updated with new data.<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           busy,            <span style=\"color: #888888\">\/\/ Module is busy, i.e. transaction in progress<\/span>\n\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_none,        <span style=\"color: #888888\">\/\/ <\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_up,          <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_down,        <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_left,        <span style=\"color: #888888\">\/\/   Button states decoded from the<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_right,       <span style=\"color: #888888\">\/\/   NES mini controller I2C data (bytes 4 and 5).<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_select,      <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_start,       <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_B,           <span style=\"color: #888888\">\/\/            <\/span>\n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>           btn_A,           <span style=\"color: #888888\">\/\/ <\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">output<\/span> <span style=\"color: #333399; font-weight: bold\">reg<\/span>  [<span style=\"color: #005588; font-weight: bold\">8<\/span><span style=\"color: #333333\">:<\/span><span style=\"color: #005588; font-weight: bold\">0<\/span>]    buttons,         <span style=\"color: #888888\">\/\/ Same button state info as above, but as a packed word<\/span>\n   \n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #888888\">\/\/ BIDIRECTIONAL<\/span>\n   <span style=\"color: #888888\">\/\/<\/span>\n   <span style=\"color: #008800; font-weight: bold\">inout<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span>           io_sda,          <span style=\"color: #888888\">\/\/ SDA line to outside world (implements a tristate driver)<\/span>\n   \n   <span style=\"color: #008800; font-weight: bold\">inout<\/span> <span style=\"color: #333399; font-weight: bold\">wire<\/span>           io_scl           <span style=\"color: #888888\">\/\/ SCL line to outside world (implements a tristate driver)<\/span>\n);\n<\/pre><\/div>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"protocol-examples\">Protocol Examples<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Two examples of the full sequence of transactions are included below:  <\/p>\n\n\n\n<figure class=\"wp-block-gallery aligncenter has-nested-images columns-1 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"125\" data-id=\"1938\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=640%2C125&#038;ssl=1\" alt=\"\" class=\"wp-image-1938\" srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=1024%2C200&amp;ssl=1 1024w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=300%2C58&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=768%2C150&amp;ssl=1 768w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?resize=1536%2C299&amp;ssl=1 1536w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?w=1914&amp;ssl=1 1914w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption>No buttons pressed (bytes 4,5=0xFF,0xFF)<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"125\" data-id=\"1939\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=640%2C125&#038;ssl=1\" alt=\"\" class=\"wp-image-1939\" srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=1024%2C200&amp;ssl=1 1024w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=300%2C58&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=768%2C150&amp;ssl=1 768w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?resize=1536%2C299&amp;ssl=1 1536w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?w=1914&amp;ssl=1 1914w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-A-button.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption>&#8216;A&#8217; button pressed (bytes 4,5=0xFF,0xEF)<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In these diagrams, green circles show the START conditions and red squares show the STOP conditions.  The slave device address (0x52) is seen after each START condition &#8211; the first time with the LSB LOW to indicate write mode, the second time with the LSB HIGH to indicate read mode.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first transaction is a write of a single byte (0x00) from master device to slave device.  The master device then creates a STOP condition, followed by another START condition to begin a second transaction but in the opposite direction &#8211; data flowing from slave device to master device.  The next element is the slave device address (0x52) again, but with the R\/W bit HIGH to indicate read mode.  This follows with the master device reading 6 bytes from the slave device.  This is the data that we want from the controller.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bytes 0-3 of the 6 data bytes are not relevant for this controller, so they are discarded.  Bytes 4 and 5 have the states for the 8 buttons on this controller (up\/down\/left\/right, select, start, A, and B).  The exact format is seen in the source code comments of <strong>gI2C_mini_nes_read.v<\/strong>.  Once these transactions are complete, the high level code extracts the button information from these bytes and provides them as output.<\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"simulation-stuff\">Simulation Stuff<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For development, I used ModelSim (free with Quartus Prime) to run a <a rel=\"noreferrer noopener\" href=\"https:\/\/www.nandland.com\/articles\/what-is-a-testbench-fpga.html\" target=\"_blank\">test bench<\/a> I created that pings the top level module for one full transaction.  Files on the <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ganz125\/gI2C_mini_master\" target=\"_blank\">GitHub<\/a> site, and simulation waveform output below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?w=640&#038;ssl=1\" alt=\"\" class=\"wp-image-2258\"  srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?resize=1024%2C287&amp;ssl=1 1024w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?resize=300%2C84&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?resize=768%2C215&amp;ssl=1 768w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?resize=1536%2C430&amp;ssl=1 1536w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?w=1859&amp;ssl=1 1859w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-modelsim-waveforms.png?w=1280&amp;ssl=1 1280w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><\/figure><\/div>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"tests-on-the-hardware\">Tests on the Hardware<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once I had the basics working in simulation, I also created a synthesizable wrapper to request data ~19 Hz.  This wrapper instantiates the higher-level module (<strong>gI2C_mini_nes_read.v<\/strong>) in a Quartus schematic and pings it using some Quartus timer and compare functions.  This allowed me to do real tests on hardware with the Nintendo controller connected and communicating on the I2C bus.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Higher update rates than 19 Hz are possible since the I2C transactions only take about 1.5 msec total.  Quartus files are up on <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ganz125\/gI2C_mini_master\" target=\"_blank\">GitHub<\/a>.  Wrapper schematic seen below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/nes-mini-i2c-schematic.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"234\" src=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/nes-mini-i2c-schematic.png?resize=640%2C234&#038;ssl=1\" alt=\"\" class=\"wp-image-1935\" srcset=\"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/nes-mini-i2c-schematic.png?resize=1024%2C375&amp;ssl=1 1024w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/nes-mini-i2c-schematic.png?resize=300%2C110&amp;ssl=1 300w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/nes-mini-i2c-schematic.png?resize=768%2C281&amp;ssl=1 768w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/nes-mini-i2c-schematic.png?w=1499&amp;ssl=1 1499w, https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/nes-mini-i2c-schematic.png?w=1280&amp;ssl=1 1280w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/figure><\/div>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"initialization-notes\">Initialization Notes<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Some websites mention a need to send some additional initialization bytes to the Nintendo Mini Class controller, while others say they are not necessary.  I did not send any initialization bytes other than the 0x00 described above, since that worked fine with the controller I hand on hand for testing.<\/p>\n\n\n\n<div style=\"height:18px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"source-code\">Source Code<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The full Quartus project is on my <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/ganz125\/gI2C_mini_master\" target=\"_blank\">GitHub<\/a> site.  The source code is well commented and is the best place to understand the assumptions and limitations. Additional <a href=\"#caveats-jump\" data-type=\"internal\" data-id=\"#caveats-jump\">Caveats<\/a> are also in a separate section above.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This FPGA project communicates with a Nintendo Classic Mini Controller by implementing an I2C master device in Verilog. Preview of some waveforms discussed in detail further below: Which Controller? The controller I used this project looks like the original NES controller (up\/down\/left\/right, select, start, A, and B only) but has<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"nf_dc_page":"","footnotes":""},"class_list":["post-1615","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>I2C Master for NESMini Controller - ganslermike.com<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ganslermike.com\/?page_id=1615\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"I2C Master for NESMini Controller - ganslermike.com\" \/>\n<meta property=\"og:description\" content=\"This FPGA project communicates with a Nintendo Classic Mini Controller by implementing an I2C master device in Verilog. Preview of some waveforms discussed in detail further below: Which Controller? The controller I used this project looks like the original NES controller (up\/down\/left\/right, select, start, A, and B only) but has\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ganslermike.com\/?page_id=1615\" \/>\n<meta property=\"og:site_name\" content=\"ganslermike.com\" \/>\n<meta property=\"article:modified_time\" content=\"2022-01-29T19:37:19+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons-1024x200.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615\",\"url\":\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615\",\"name\":\"I2C Master for NESMini Controller - ganslermike.com\",\"isPartOf\":{\"@id\":\"http:\\\/\\\/ganslermike.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ganslermike.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/gI2C-logic-analyzer-no-buttons-1024x200.png\",\"datePublished\":\"2020-12-29T20:19:05+00:00\",\"dateModified\":\"2022-01-29T19:37:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/ganslermike.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/gI2C-logic-analyzer-no-buttons.png?fit=1914%2C373&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/ganslermike.com\\\/wp-content\\\/uploads\\\/2021\\\/01\\\/gI2C-logic-analyzer-no-buttons.png?fit=1914%2C373&ssl=1\",\"width\":1914,\"height\":373},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ganslermike.com\\\/?page_id=1615#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"http:\\\/\\\/ganslermike.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"I2C Master for NESMini Controller\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\\\/\\\/ganslermike.com\\\/#website\",\"url\":\"http:\\\/\\\/ganslermike.com\\\/\",\"name\":\"ganslermike.com\",\"description\":\"electronics, flightsim, robots, and stuff\",\"publisher\":{\"@id\":\"http:\\\/\\\/ganslermike.com\\\/#\\\/schema\\\/person\\\/032aad67c31c143c210499ce1b84aa9e\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\\\/\\\/ganslermike.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"http:\\\/\\\/ganslermike.com\\\/#\\\/schema\\\/person\\\/032aad67c31c143c210499ce1b84aa9e\",\"name\":\"mike.t.gansler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g\",\"caption\":\"mike.t.gansler\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"I2C Master for NESMini Controller - ganslermike.com","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ganslermike.com\/?page_id=1615","og_locale":"en_US","og_type":"article","og_title":"I2C Master for NESMini Controller - ganslermike.com","og_description":"This FPGA project communicates with a Nintendo Classic Mini Controller by implementing an I2C master device in Verilog. Preview of some waveforms discussed in detail further below: Which Controller? The controller I used this project looks like the original NES controller (up\/down\/left\/right, select, start, A, and B only) but has","og_url":"https:\/\/ganslermike.com\/?page_id=1615","og_site_name":"ganslermike.com","article_modified_time":"2022-01-29T19:37:19+00:00","og_image":[{"url":"http:\/\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons-1024x200.png","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/ganslermike.com\/?page_id=1615","url":"https:\/\/ganslermike.com\/?page_id=1615","name":"I2C Master for NESMini Controller - ganslermike.com","isPartOf":{"@id":"http:\/\/ganslermike.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ganslermike.com\/?page_id=1615#primaryimage"},"image":{"@id":"https:\/\/ganslermike.com\/?page_id=1615#primaryimage"},"thumbnailUrl":"https:\/\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons-1024x200.png","datePublished":"2020-12-29T20:19:05+00:00","dateModified":"2022-01-29T19:37:19+00:00","breadcrumb":{"@id":"https:\/\/ganslermike.com\/?page_id=1615#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ganslermike.com\/?page_id=1615"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ganslermike.com\/?page_id=1615#primaryimage","url":"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?fit=1914%2C373&ssl=1","contentUrl":"https:\/\/i0.wp.com\/ganslermike.com\/wp-content\/uploads\/2021\/01\/gI2C-logic-analyzer-no-buttons.png?fit=1914%2C373&ssl=1","width":1914,"height":373},{"@type":"BreadcrumbList","@id":"https:\/\/ganslermike.com\/?page_id=1615#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http:\/\/ganslermike.com\/"},{"@type":"ListItem","position":2,"name":"I2C Master for NESMini Controller"}]},{"@type":"WebSite","@id":"http:\/\/ganslermike.com\/#website","url":"http:\/\/ganslermike.com\/","name":"ganslermike.com","description":"electronics, flightsim, robots, and stuff","publisher":{"@id":"http:\/\/ganslermike.com\/#\/schema\/person\/032aad67c31c143c210499ce1b84aa9e"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/ganslermike.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"http:\/\/ganslermike.com\/#\/schema\/person\/032aad67c31c143c210499ce1b84aa9e","name":"mike.t.gansler","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g","caption":"mike.t.gansler"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/da4019a2041637d5c64d000774fccc108efe76eb985bf03f6fdae3985bf4e273?s=96&d=mm&r=g"}}]}},"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ganslermike.com\/index.php?rest_route=\/wp\/v2\/pages\/1615","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ganslermike.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ganslermike.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ganslermike.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ganslermike.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1615"}],"version-history":[{"count":5,"href":"https:\/\/ganslermike.com\/index.php?rest_route=\/wp\/v2\/pages\/1615\/revisions"}],"predecessor-version":[{"id":4042,"href":"https:\/\/ganslermike.com\/index.php?rest_route=\/wp\/v2\/pages\/1615\/revisions\/4042"}],"wp:attachment":[{"href":"https:\/\/ganslermike.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}