diff options
author | Javier Valenzuela <javier.valenzuela@ni.com> | 2021-09-29 10:04:04 -0500 |
---|---|---|
committer | Wade Fife <wade.fife@ettus.com> | 2022-01-25 10:18:47 -0700 |
commit | 38c549d1f7672e38773fc6624539cc166285a1df (patch) | |
tree | ca5d66868eec499c526aa11e8a616385412dba83 /fpga | |
parent | 9335939b9b3ab85cee5908ff3357f9e7819e3366 (diff) | |
download | uhd-38c549d1f7672e38773fc6624539cc166285a1df.tar.gz uhd-38c549d1f7672e38773fc6624539cc166285a1df.tar.bz2 uhd-38c549d1f7672e38773fc6624539cc166285a1df.zip |
fpga: x400: Add SPI bus support for GPIO ports
Diffstat (limited to 'fpga')
-rw-r--r-- | fpga/usrp3/top/x400/Makefile.x4xx.inc | 1 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/doc/X4XX_FPGA_left.htm | 18 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/doc/X4XX_FPGA_right.htm | 553 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/regmap/dig_ifc_regmap_utils.vh | 88 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/regmap/radio_dio_regmap_utils.vh | 5 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/x4xx_core.v | 1 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/x4xx_core_common.v | 194 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/x4xx_gpio_atr.v | 4 | ||||
-rw-r--r-- | fpga/usrp3/top/x400/x4xx_gpio_spi.v | 534 |
9 files changed, 1338 insertions, 60 deletions
diff --git a/fpga/usrp3/top/x400/Makefile.x4xx.inc b/fpga/usrp3/top/x400/Makefile.x4xx.inc index 2c6de75ec..fa6208088 100644 --- a/fpga/usrp3/top/x400/Makefile.x4xx.inc +++ b/fpga/usrp3/top/x400/Makefile.x4xx.inc @@ -74,6 +74,7 @@ x4xx_global_regs.v \ x4xx_versioning_regs.v \ x4xx_dio.v \ x4xx_gpio_atr.v \ +x4xx_gpio_spi.v \ rf/100m/rf_core_100m.v \ rf/200m/rf_core_200m.v \ rf/200m/rf_down_4to2.v \ diff --git a/fpga/usrp3/top/x400/doc/X4XX_FPGA_left.htm b/fpga/usrp3/top/x400/doc/X4XX_FPGA_left.htm index c302c2f9c..0a101710e 100644 --- a/fpga/usrp3/top/x400/doc/X4XX_FPGA_left.htm +++ b/fpga/usrp3/top/x400/doc/X4XX_FPGA_left.htm @@ -270,6 +270,21 @@ </div> </div> <p> + <span class="pm" id="pm_DIG_IFC_REGMAP" onclick="pm('DIG_IFC_REGMAP');">+</span> + <span class="regmap" id="a_DIG_IFC_REGMAP" onclick="a('DIG_IFC_REGMAP');">DIG_IFC_REGMAP</span> + </p> <div class="sh" id="div_DIG_IFC_REGMAP"> + <p> + <span class="pm" id="pm_DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS" onclick="pm('DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS');">+</span> + <span class="group" id="a_DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS" onclick="a('DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS');">SPI_OVER_GPIO_REGS</span> + </p> + <div class="sh" id="div_DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS"> + <p><span class="register" id="a_DIG_IFC_REGMAP|SPI_SLAVE_CONFIG" onclick="a('DIG_IFC_REGMAP|SPI_SLAVE_CONFIG');">SPI_SLAVE_CONFIG</span></p> + <p><span class="register" id="a_DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG" onclick="a('DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG');">SPI_TRANSACTION_CONFIG</span></p> + <p><span class="register" id="a_DIG_IFC_REGMAP|SPI_TRANSACTION_GO" onclick="a('DIG_IFC_REGMAP|SPI_TRANSACTION_GO');">SPI_TRANSACTION_GO</span></p> + <p><span class="register" id="a_DIG_IFC_REGMAP|SPI_STATUS" onclick="a('DIG_IFC_REGMAP|SPI_STATUS');">SPI_STATUS</span></p> + </div> + </div> + <p> <span class="pm" id="pm_DIO_REGMAP" onclick="pm('DIO_REGMAP');">+</span> <span class="regmap" id="a_DIO_REGMAP" onclick="a('DIO_REGMAP');">DIO_REGMAP</span> </p> <div class="sh" id="div_DIO_REGMAP"> @@ -579,7 +594,8 @@ </p> <div class="sh" id="div_RADIO_DIO_REGMAP|DIO_SOURCES"> <p><span class="register" id="a_RADIO_DIO_REGMAP|RADIO_GPIO_ATR_REGS" onclick="a('RADIO_DIO_REGMAP|RADIO_GPIO_ATR_REGS');">RADIO_GPIO_ATR_REGS</span></p> - <p><span class="register" id="a_RADIO_DIO_REGMAP|DIO_SOURCE_CONTROL" onclick="a('RADIO_DIO_REGMAP|DIO_SOURCE_CONTROL');">DIO_SOURCE_CONTROL</span></p> + <p><span class="register" id="a_RADIO_DIO_REGMAP|DIO_SOURCE_CONTROL" onclick="a('RADIO_DIO_REGMAP|DIO_SOURCE_CONTROL');">DIO_SOURCE_CONTROL</span></p> + <p><span class="register" id="a_RADIO_DIO_REGMAP|DIGITAL_IFC_REGS" onclick="a('RADIO_DIO_REGMAP|DIGITAL_IFC_REGS');">DIGITAL_IFC_REGS</span></p> </div> </div> <p> diff --git a/fpga/usrp3/top/x400/doc/X4XX_FPGA_right.htm b/fpga/usrp3/top/x400/doc/X4XX_FPGA_right.htm index 4e3b3c3a8..2827c1a93 100644 --- a/fpga/usrp3/top/x400/doc/X4XX_FPGA_right.htm +++ b/fpga/usrp3/top/x400/doc/X4XX_FPGA_right.htm @@ -3232,6 +3232,492 @@ Total Offset =</td></tr> </div> <div class="regmap"> + <a name="DIG_IFC_REGMAP"></a> + <h1 class="regmap">DIG_IFC_REGMAP</h1> + + <div class="group"><a name="DIG_IFC_REGMAP|SPI_OVER_GPIO_REGS"></a><h2 class="group">SPI_OVER_GPIO_REGS</h2> + + <div class="register"> + <a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG"></a> + +<h3 class="register">Offset 0x0000: SPI_SLAVE_CONFIG(3:0) Register Array (R|W)</h3> + + <a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_SLAVE_CONFIG_in')">(<span id="show_DIG_IFC_REGMAP|SPI_SLAVE_CONFIG_in">show</span> extended info)</a> + <div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_SLAVE_CONFIG_in"> + + <table class="extended_info"> + +<tr> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr> + <tr><td class="offset_info" align="right"> 0x00C000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr> + <tr><td class="offset_info" align="right"> 0x002000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right">SPI_SLAVE_CONFIG</td></tr> + <tr><td class="offset_info" align="right"> offset=0x0000 + i*4</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + +<tr><td class="offset_info"> + + +Cannot determine accessibility through this path</td></tr> +<tr><td class="offset_info"> +Total Offset =</td></tr> +<tr><td class="offset_info"> 0x00E000 + i*4 + +</td></tr> +</table> + +</td> + +</tr> + +</table><p/> + +<p class="reg_info"><B>Initial Values</B><BR/> +<table> + <tr><td>default</td><td>=></td><td>0x00000000</td></tr> +</table> +</p> + +<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.<BR/> +It uses RegType <b>SPI_SETUP</b> which is defined in HDL source file x4xx_gpio_spi.v.</p> + +</div> + +<div class="info"> + +Controls SPI Transaction<BR/> +Set of configuration registers for the supported slaves. + +</div> + + <table class="bitfields" border="0" cellspacing="0" cellpadding="0"> + <tr class="header"><td class="bits">Bits</td><td>Name</td></tr> + + <tr valign="top"> + <td class="bits">31..28</td> + <td> + <p><span class="name">Reserved</span><span class="attr"> </span></p> + <p></p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">27</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|MOSI_EDGE"></a>MOSI_EDGE</span><span class="attr"> (initialvalue=0)</span></p> + <p>Controls the edge in which the MOSI line is updated.</br> + 0 = falling edge of SCLK.</br> + 1 = rising edge of SCLK.</p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">26</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|MISO_EDGE"></a>MISO_EDGE</span><span class="attr"> (initialvalue=0)</span></p> + <p>Controls the edge in which the MISO line is latched.</br> + 0 = falling edge of SCLK.</br> + 1 = rising edge of SCLK.</p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">25..20</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SPI_LENGTH"></a>SPI_LENGTH</span><span class="attr"> (initialvalue=0)</span></p> + <p>Indicates the length of SPI transactions to this slave.</p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">19..15</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_CS"></a>SLAVE_CS</span><span class="attr"> (initialvalue=0)</span></p> + <p>Indicates which GPIO line to use for the CS signal.</br> + 0-11 : Port A GPIO</br> + 16-27: Port B GPIO</p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">14..10</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_MISO"></a>SLAVE_MISO</span><span class="attr"> (initialvalue=0)</span></p> + <p>Indicates which GPIO line to use for the MISO signal.</br> + 0-11 : Port A GPIO</br> + 16-27: Port B GPIO</p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">9..5</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_MOSI"></a>SLAVE_MOSI</span><span class="attr"> (initialvalue=0)</span></p> + <p>Indicates which GPIO line to use for the MOSI signal.</br> + 0-11 : Port A GPIO</br> + 16-27: Port B GPIO</p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">4..0</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_SLAVE_CONFIG|SLAVE_CLK"></a>SLAVE_CLK</span><span class="attr"> (initialvalue=0)</span></p> + <p>Indicates which GPIO line to use for the SCLK signal.</br> + 0-11 : Port A GPIO</br> + 16-27: Port B GPIO</p> + + </td> + </tr> + +</table> + +</div> + + <div class="register"> + <a name="DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG"></a> + +<h3 class="register">Offset 0x0010: SPI_TRANSACTION_CONFIG Register (R|W)</h3> + + <a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG_in')">(<span id="show_DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG_in">show</span> extended info)</a> + <div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG_in"> + + <table class="extended_info"> + +<tr> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr> + <tr><td class="offset_info" align="right"> 0x00C000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr> + <tr><td class="offset_info" align="right"> 0x002000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right">SPI_TRANSACTION_CONFIG</td></tr> + <tr><td class="offset_info" align="right"> offset=0x0010</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + +<tr><td class="offset_info"> + + +Total Offset =</td></tr> +<tr><td class="offset_info"> 0x00E010 + +</td></tr> +</table> + +</td> + +</tr> + +</table><p/> + +<p class="reg_info">Initial Value = 0x00000000 +</p> + +<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.</p> + +</div> + +<div class="info"> + +Controls clock rate and target for subsequent SPI transactions. + +</div> + + <table class="bitfields" border="0" cellspacing="0" cellpadding="0"> + <tr class="header"><td class="bits">Bits</td><td>Name</td></tr> + + <tr valign="top"> + <td class="bits">31..24</td> + <td> + <p><span class="name">Reserved</span><span class="attr"> </span></p> + <p></p> + + </td> + </tr> + + <tr class='byte' valign="top"> + <td class="bits">23..18</td> + <td> + <p><span class="name">Reserved</span><span class="attr"> </span></p> + <p></p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">17..16</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG|SPI_SLAVE_SELECT"></a>SPI_SLAVE_SELECT</span><span class="attr"> (initialvalue=0)</span></p> + <p></p> + + </td> + </tr> + + <tr class='byte' valign="top"> + <td class="bits">15..0</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_CONFIG|SPI_CLK_DIV"></a>SPI_CLK_DIV</span><span class="attr"> (initialvalue=0)</span></p> + <p>Controls the rate for subsequent SPI transactions. SCLK = DataClk/[(SPI_CLK_DIV+1)]</p> + + </td> + </tr> + +</table> + +</div> + + <div class="register"> + <a name="DIG_IFC_REGMAP|SPI_TRANSACTION_GO"></a> + +<h3 class="register">Offset 0x0014: SPI_TRANSACTION_GO Register (W)</h3> + + <a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_TRANSACTION_GO_in')">(<span id="show_DIG_IFC_REGMAP|SPI_TRANSACTION_GO_in">show</span> extended info)</a> + <div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_TRANSACTION_GO_in"> + + <table class="extended_info"> + +<tr> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr> + <tr><td class="offset_info" align="right"> 0x00C000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr> + <tr><td class="offset_info" align="right"> 0x002000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right">SPI_TRANSACTION_GO</td></tr> + <tr><td class="offset_info" align="right"> offset=0x0014</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + +<tr><td class="offset_info"> + + +Total Offset =</td></tr> +<tr><td class="offset_info"> 0x00E014 + +</td></tr> +</table> + +</td> + +</tr> + +</table><p/> + +<p class="reg_info">Initial Value = 0x00000000 +</p> + +<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.</p> + +</div> + +<div class="info"> + +Starts a SPI transaction + +</div> + + <table class="bitfields" border="0" cellspacing="0" cellpadding="0"> + <tr class="header"><td class="bits">Bits</td><td>Name</td></tr> + + <tr valign="top"> + <td class="bits">31..0w</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_TRANSACTION_GO|SPI_DATA"></a>SPI_DATA</span><span class="attr"> (initialvalue=0)</span></p> + <p>Payload to be sent for the SPI transaction. If the payload is shorter than 32 bits, + it must be aligned to the MSbs in this field. LSbs are ignored in this scenario.</p> + + </td> + </tr> + +</table> + +</div> + + <div class="register"> + <a name="DIG_IFC_REGMAP|SPI_STATUS"></a> + +<h3 class="register">Offset 0x0018: SPI_STATUS Register (R)</h3> + + <a class="sh_addrs" href="javascript:sa('DIG_IFC_REGMAP|SPI_STATUS_in')">(<span id="show_DIG_IFC_REGMAP|SPI_STATUS_in">show</span> extended info)</a> + <div class="sh_addrs" id="div_DIG_IFC_REGMAP|SPI_STATUS_in"> + + <table class="extended_info"> + +<tr> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr> + <tr><td class="offset_info" align="right"> 0x00C000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_DIO_REGMAP|DIGITAL_IFC_REGS">RADIO_DIO_REGMAP|DIGITAL_IFC_REGS</a></td></tr> + <tr><td class="offset_info" align="right"> 0x002000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right">SPI_STATUS</td></tr> + <tr><td class="offset_info" align="right"> offset=0x0018</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + +<tr><td class="offset_info"> + + +Total Offset =</td></tr> +<tr><td class="offset_info"> 0x00E018 + +</td></tr> +</table> + +</td> + +</tr> + +</table><p/> + +<p class="reg_info">Initial Value = 0x00000000 +</p> + +<p class="reg_info">This register is defined in HDL source file x4xx_gpio_spi.v.</p> + +</div> + +<div class="info"> + +Contains the status of the SPI engine. + +</div> + + <table class="bitfields" border="0" cellspacing="0" cellpadding="0"> + <tr class="header"><td class="bits">Bits</td><td>Name</td></tr> + + <tr valign="top"> + <td class="bits">31..25</td> + <td> + <p><span class="name">Reserved</span><span class="attr"> </span></p> + <p></p> + + </td> + </tr> + + <tr valign="top"> + <td class="bits">24</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_STATUS|SPI_READY"></a>SPI_READY</span><span class="attr"> (initialvalue=0)</span></p> + <p>Indicates the SPI engine is ready to start a new SPI transaction.</p> + + </td> + </tr> + + <tr class='byte' valign="top"> + <td class="bits">23..0</td> + <td> + <p><span class="name"><a name="DIG_IFC_REGMAP|SPI_STATUS|SPI_RESPONSE"></a>SPI_RESPONSE</span><span class="attr"> (initialvalue=0)</span></p> + <p>Records the response of the last completed SPI transaction.</p> + + </td> + </tr> + +</table> + +</div> + +</div> + +</div> + + <div class="regmap"> <a name="DIO_REGMAP"></a> <h1 class="regmap">DIO_REGMAP</h1> @@ -8020,7 +8506,7 @@ Total Offset =</td></tr> Controls whether GPIO lines use the TX and RX state of an RF channel (Classic ATR) or the daughterboard state the selector for the - @.GPIO_ATR_STATE. + <a href="#GPIO_ATR_REGMAP|ATR_STATE">ATR_STATE</a>. </div> @@ -8069,7 +8555,7 @@ Controls whether GPIO lines use the TX and RX state of an RF channel <p><span class="name"><a name="GPIO_ATR_REGMAP|ATR_OPTION_REGISTRER|ATR_OPTION"></a>ATR_OPTION</span><span class="attr"> (initialvalue=0)</span></p> <p>Sets the scheme in which RF states in the radio will control GPIO lines. 0 = DB state is used. RF states are combined and the - GPIO state is driven based on all 16 @.GPIO_ATR_STATE registers. + GPIO state is driven based on all 16 <a href="#GPIO_ATR_REGMAP|ATR_STATE">ATR_STATE</a> registers. 1 = Each RF channel has its separate ATR state(Classic ATR). Use register <a href="#GPIO_ATR_REGMAP|CLASSIC_ATR_CONFIG">CLASSIC_ATR_CONFIG</a> to indicate the RF channel to which each GPIO line responds to.</p> @@ -16324,6 +16810,69 @@ Window to access the DIO register map through the control port from the radio bl </div> + <div class="register"> + <a name="RADIO_DIO_REGMAP|DIGITAL_IFC_REGS"></a> + +<h3 class="register">Offset 0x2000: DIGITAL_IFC_REGS Window (R|W)</h3> +<p class="offset_info"> Target regmap = <a href="#DIG_IFC_REGMAP">DIG_IFC_REGMAP</a></p> + <a class="sh_addrs" href="javascript:sa('RADIO_DIO_REGMAP|DIGITAL_IFC_REGS_in')">(<span id="show_RADIO_DIO_REGMAP|DIGITAL_IFC_REGS_in">show</span> extended info)</a> + <div class="sh_addrs" id="div_RADIO_DIO_REGMAP|DIGITAL_IFC_REGS_in"> + + <table class="extended_info"> + +<tr> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right"><a href="#RADIO_CTRLPORT_REGMAP|DIO_WINDOW">RADIO_CTRLPORT_REGMAP|DIO_WINDOW</a></td></tr> + <tr><td class="offset_info" align="right"> 0x00C000</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + <tr><td class="offset_info" align="right">DIGITAL_IFC_REGS</td></tr> + <tr><td class="offset_info" align="right"> offset=0x2000</td></tr> + <tr><td class="offset_info" align="right"> size=0x1000 (4 Kbytes)</td></tr> +</table> + +</td> + +<td class="outercell" rowspan="1"> + +<table border="0" cellspacing="0" cellpadding="0"> + +<tr><td class="offset_info"> + + +Total Offset =</td></tr> +<tr><td class="offset_info"> 0x00E000 + +</td></tr> +</table> + +</td> + +</tr> + +</table><p/> + +<p class="reg_info">This window is defined in HDL source file x4xx_core_common.v.</p> + +</div> + +<div class="info"> + +Register space reserved for configuring a digital interface over the GPIO lines. + Currently, SPI is the only supported protocol. + +</div> + +</div> + </div> </div> diff --git a/fpga/usrp3/top/x400/regmap/dig_ifc_regmap_utils.vh b/fpga/usrp3/top/x400/regmap/dig_ifc_regmap_utils.vh new file mode 100644 index 000000000..7ead185d7 --- /dev/null +++ b/fpga/usrp3/top/x400/regmap/dig_ifc_regmap_utils.vh @@ -0,0 +1,88 @@ +// +// Copyright 2021 Ettus Research, A National Instruments Company +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: dig_ifc_regmap_utils.vh +// Description: +// The constants in this file are autogenerated by XmlParse. + +//=============================================================================== +// A numerically ordered list of registers and their HDL source files +//=============================================================================== + + // SPI_SLAVE_CONFIG : 0x0 (x4xx_gpio_spi.v) + // SPI_TRANSACTION_CONFIG : 0x10 (x4xx_gpio_spi.v) + // SPI_TRANSACTION_GO : 0x14 (x4xx_gpio_spi.v) + // SPI_STATUS : 0x18 (x4xx_gpio_spi.v) + +//=============================================================================== +// RegTypes +//=============================================================================== + + // SPI_SETUP Type (from x4xx_gpio_spi.v) + localparam SPI_SETUP_SIZE = 32; + localparam SPI_SETUP_MASK = 32'hFFFFFFF; + localparam SLAVE_CLK_SIZE = 5; //SPI_SETUP:SLAVE_CLK + localparam SLAVE_CLK_MSB = 4; //SPI_SETUP:SLAVE_CLK + localparam SLAVE_CLK = 0; //SPI_SETUP:SLAVE_CLK + localparam SLAVE_MOSI_SIZE = 5; //SPI_SETUP:SLAVE_MOSI + localparam SLAVE_MOSI_MSB = 9; //SPI_SETUP:SLAVE_MOSI + localparam SLAVE_MOSI = 5; //SPI_SETUP:SLAVE_MOSI + localparam SLAVE_MISO_SIZE = 5; //SPI_SETUP:SLAVE_MISO + localparam SLAVE_MISO_MSB = 14; //SPI_SETUP:SLAVE_MISO + localparam SLAVE_MISO = 10; //SPI_SETUP:SLAVE_MISO + localparam SLAVE_CS_SIZE = 5; //SPI_SETUP:SLAVE_CS + localparam SLAVE_CS_MSB = 19; //SPI_SETUP:SLAVE_CS + localparam SLAVE_CS = 15; //SPI_SETUP:SLAVE_CS + localparam SPI_LENGTH_SIZE = 6; //SPI_SETUP:SPI_LENGTH + localparam SPI_LENGTH_MSB = 25; //SPI_SETUP:SPI_LENGTH + localparam SPI_LENGTH = 20; //SPI_SETUP:SPI_LENGTH + localparam MISO_EDGE_SIZE = 1; //SPI_SETUP:MISO_EDGE + localparam MISO_EDGE_MSB = 26; //SPI_SETUP:MISO_EDGE + localparam MISO_EDGE = 26; //SPI_SETUP:MISO_EDGE + localparam MOSI_EDGE_SIZE = 1; //SPI_SETUP:MOSI_EDGE + localparam MOSI_EDGE_MSB = 27; //SPI_SETUP:MOSI_EDGE + localparam MOSI_EDGE = 27; //SPI_SETUP:MOSI_EDGE + +//=============================================================================== +// Register Group SPI_OVER_GPIO_REGS +//=============================================================================== + + // SPI_SLAVE_CONFIG Register (from x4xx_gpio_spi.v) + localparam SPI_SLAVE_CONFIG_COUNT = 4; // Number of elements in array + + // SPI_TRANSACTION_CONFIG Register (from x4xx_gpio_spi.v) + localparam SPI_TRANSACTION_CONFIG = 'h10; // Register Offset + localparam SPI_TRANSACTION_CONFIG_SIZE = 32; // register width in bits + localparam SPI_TRANSACTION_CONFIG_MASK = 32'h3FFFF; + localparam SPI_CLK_DIV_SIZE = 16; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV + localparam SPI_CLK_DIV_MSB = 15; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV + localparam SPI_CLK_DIV = 0; //SPI_TRANSACTION_CONFIG:SPI_CLK_DIV + localparam SPI_SLAVE_SELECT_SIZE = 2; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT + localparam SPI_SLAVE_SELECT_MSB = 17; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT + localparam SPI_SLAVE_SELECT = 16; //SPI_TRANSACTION_CONFIG:SPI_SLAVE_SELECT + + // SPI_TRANSACTION_GO Register (from x4xx_gpio_spi.v) + localparam SPI_TRANSACTION_GO = 'h14; // Register Offset + localparam SPI_TRANSACTION_GO_SIZE = 32; // register width in bits + localparam SPI_TRANSACTION_GO_MASK = 32'hFFFFFFFF; + localparam SPI_DATA_SIZE = 32; //SPI_TRANSACTION_GO:SPI_DATA + localparam SPI_DATA_MSB = 31; //SPI_TRANSACTION_GO:SPI_DATA + localparam SPI_DATA = 0; //SPI_TRANSACTION_GO:SPI_DATA + + // SPI_STATUS Register (from x4xx_gpio_spi.v) + localparam SPI_STATUS = 'h18; // Register Offset + localparam SPI_STATUS_SIZE = 32; // register width in bits + localparam SPI_STATUS_MASK = 32'h1FFFFFF; + localparam SPI_RESPONSE_SIZE = 24; //SPI_STATUS:SPI_RESPONSE + localparam SPI_RESPONSE_MSB = 23; //SPI_STATUS:SPI_RESPONSE + localparam SPI_RESPONSE = 0; //SPI_STATUS:SPI_RESPONSE + localparam SPI_READY_SIZE = 1; //SPI_STATUS:SPI_READY + localparam SPI_READY_MSB = 24; //SPI_STATUS:SPI_READY + localparam SPI_READY = 24; //SPI_STATUS:SPI_READY + + // Return the offset of an element of register array SPI_SLAVE_CONFIG + function integer SPI_SLAVE_CONFIG (input integer i); + SPI_SLAVE_CONFIG = (i * 'h4) + 'h0; + endfunction diff --git a/fpga/usrp3/top/x400/regmap/radio_dio_regmap_utils.vh b/fpga/usrp3/top/x400/regmap/radio_dio_regmap_utils.vh index 62de3d75e..6916dc79c 100644 --- a/fpga/usrp3/top/x400/regmap/radio_dio_regmap_utils.vh +++ b/fpga/usrp3/top/x400/regmap/radio_dio_regmap_utils.vh @@ -13,6 +13,7 @@ // RADIO_GPIO_ATR_REGS : 0x0 (x4xx_core_common.v) // DIO_SOURCE_CONTROL : 0x1000 (x4xx_core_common.v) + // DIGITAL_IFC_REGS : 0x2000 (x4xx_core_common.v) //=============================================================================== // RegTypes @@ -29,3 +30,7 @@ // DIO_SOURCE_CONTROL Window (from x4xx_core_common.v) localparam DIO_SOURCE_CONTROL = 'h1000; // Window Offset localparam DIO_SOURCE_CONTROL_SIZE = 'h1000; // size in bytes + + // DIGITAL_IFC_REGS Window (from x4xx_core_common.v) + localparam DIGITAL_IFC_REGS = 'h2000; // Window Offset + localparam DIGITAL_IFC_REGS_SIZE = 'h1000; // size in bytes diff --git a/fpga/usrp3/top/x400/x4xx_core.v b/fpga/usrp3/top/x400/x4xx_core.v index 4e944e335..609892581 100644 --- a/fpga/usrp3/top/x400/x4xx_core.v +++ b/fpga/usrp3/top/x400/x4xx_core.v @@ -249,6 +249,7 @@ module x4xx_core #( .PCIE_PRESENT (0) ) x4xx_core_common_i ( .radio_clk (radio_clk), + .radio_clk_2x (radio_clk_2x), .radio_rst (radio_rst), .rfnoc_chdr_clk (rfnoc_chdr_clk), .rfnoc_chdr_rst (rfnoc_chdr_rst), diff --git a/fpga/usrp3/top/x400/x4xx_core_common.v b/fpga/usrp3/top/x400/x4xx_core_common.v index 3dac18ad5..89dd49a49 100644 --- a/fpga/usrp3/top/x400/x4xx_core_common.v +++ b/fpga/usrp3/top/x400/x4xx_core_common.v @@ -38,6 +38,7 @@ module x4xx_core_common #( ) ( // Clocks and resets input wire radio_clk, + input wire radio_clk_2x, input wire radio_rst, input wire rfnoc_chdr_clk, @@ -234,16 +235,16 @@ module x4xx_core_common #( .s_ctrlport_resp_ack (m_resp_ack), .s_ctrlport_resp_status (m_resp_status), .s_ctrlport_resp_data (m_resp_data), - .m_ctrlport_req_wr ({timekeeper_req_wr, versioning_req_wr, global_regs_req_wr, dio_req_wr}), - .m_ctrlport_req_rd ({timekeeper_req_rd, versioning_req_rd, global_regs_req_rd, dio_req_rd}), - .m_ctrlport_req_addr ({timekeeper_req_addr, versioning_req_addr, global_regs_req_addr, dio_req_addr}), - .m_ctrlport_req_data ({timekeeper_req_data, versioning_req_data, global_regs_req_data, dio_req_data}), + .m_ctrlport_req_wr ({timekeeper_req_wr, versioning_req_wr, global_regs_req_wr, dio_req_wr}), + .m_ctrlport_req_rd ({timekeeper_req_rd, versioning_req_rd, global_regs_req_rd, dio_req_rd}), + .m_ctrlport_req_addr ({timekeeper_req_addr, versioning_req_addr, global_regs_req_addr, dio_req_addr}), + .m_ctrlport_req_data ({timekeeper_req_data, versioning_req_data, global_regs_req_data, dio_req_data}), .m_ctrlport_req_byte_en (), .m_ctrlport_req_has_time (), .m_ctrlport_req_time (), - .m_ctrlport_resp_ack ({timekeeper_resp_ack, versioning_resp_ack, global_regs_resp_ack, dio_resp_ack}), + .m_ctrlport_resp_ack ({timekeeper_resp_ack, versioning_resp_ack, global_regs_resp_ack, dio_resp_ack}), .m_ctrlport_resp_status ({timekeeper_resp_status, versioning_resp_status, global_regs_resp_status, dio_resp_status}), - .m_ctrlport_resp_data ({timekeeper_resp_data, versioning_resp_data, global_regs_resp_data, dio_resp_data}) + .m_ctrlport_resp_data ({timekeeper_resp_data, versioning_resp_data, global_regs_resp_data, dio_resp_data}) ); @@ -349,6 +350,7 @@ module x4xx_core_common #( // Radio CtrlPort Splitter //----------------------------------------------------------------------- + // Radio CtrlPort endpoints wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_req_wr; wire [ 1*NUM_DBOARDS-1:0] rf_ctrlport_req_rd; wire [ 20*NUM_DBOARDS-1:0] rf_ctrlport_req_addr; @@ -371,9 +373,36 @@ module x4xx_core_common #( wire [ 2*NUM_DBOARDS-1:0] radio_dio_resp_status; wire [ 32*NUM_DBOARDS-1:0] radio_dio_resp_data; + wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_wr; + wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_rd; + wire [ 20*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_addr; + wire [ 32*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_data; + wire [ 4*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_byte_en; + wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_has_time; + wire [ 64*NUM_DBOARDS-1:0] gpio_atr_ctrlport_req_time; + wire [ 1*NUM_DBOARDS-1:0] gpio_atr_ctrlport_resp_ack; + wire [ 2*NUM_DBOARDS-1:0] gpio_atr_ctrlport_resp_status; + wire [ 32*NUM_DBOARDS-1:0] gpio_atr_ctrlport_resp_data; + + wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_wr; + wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_rd; + wire [ 20*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_addr; + wire [ 32*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_data; + wire [ 4*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_byte_en; + wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_has_time; + wire [ 64*NUM_DBOARDS-1:0] gpio_spi_ctrlport_req_time; + wire [ 1*NUM_DBOARDS-1:0] gpio_spi_ctrlport_resp_ack; + wire [ 2*NUM_DBOARDS-1:0] gpio_spi_ctrlport_resp_status; + wire [ 32*NUM_DBOARDS-1:0] gpio_spi_ctrlport_resp_data; + + // GPIO control signals from radio ctrlport endpoints to + // x4xx_dio. wire [NUM_DBOARDS*32-1:0] atr_gpio_out; wire [NUM_DBOARDS*32-1:0] atr_gpio_ddr; + wire [NUM_DBOARDS*32-1:0] spi_gpio_out; + wire [NUM_DBOARDS*32-1:0] spi_gpio_ddr; + genvar db; generate for (db = 0; db < NUM_DBOARDS; db = db+1) begin : gen_radio_ctrlport @@ -385,67 +414,100 @@ module x4xx_core_common #( // This section takes the CtrlPort master from each radio block and splits it // into a CtrlPort bus for the associated daughter(m_radio_ctrlport_*), the // RFDC timing control (rf_ctrlport_*), the ATR GPIO control for the DB state - // the current radio(db) and DIO main control block(x4xx_dio). + // the current radio(db), the SPI controller of the radio, and DIO main + // control block(x4xx_dio). // Refer to diagram in the RADIO_CTRLPORT_REGMAP Register map for a // visual representation on how these interfaces are distributed. // Register space offset calculation localparam [19:0] DIO_SOURCE_CONTROL_OFFSET = DIO_WINDOW + DIO_SOURCE_CONTROL; localparam [19:0] RADIO_GPIO_ATR_OFFSET = DIO_WINDOW + RADIO_GPIO_ATR_REGS; + localparam [19:0] DIGITAL_IFC_OFFSET = DIO_WINDOW + DIGITAL_IFC_REGS; // Register space size calculation localparam [31:0] RFDC_TIMING_WINDOW_SIZE_W = $clog2(RFDC_TIMING_WINDOW_SIZE); localparam [31:0] DB_WINDOW_SIZE_W = $clog2(DB_WINDOW_SIZE); localparam [31:0] DIO_SOURCE_CONTROL_SIZE_W = $clog2(DIO_SOURCE_CONTROL_SIZE); localparam [31:0] RADIO_GPIO_ATR_SIZE_W = $clog2(RADIO_GPIO_ATR_REGS_SIZE); - - wire gpio_atr_ctrlport_req_wr; - wire gpio_atr_ctrlport_req_rd; - wire [19:0] gpio_atr_ctrlport_req_addr; - wire [31:0] gpio_atr_ctrlport_req_data; - wire [ 3:0] gpio_atr_ctrlport_req_byte_en; - wire gpio_atr_ctrlport_req_has_time; - wire [63:0] gpio_atr_ctrlport_req_time; - wire gpio_atr_ctrlport_resp_ack; - wire [ 1:0] gpio_atr_ctrlport_resp_status; - wire [31:0] gpio_atr_ctrlport_resp_data; - + localparam [31:0] DIGITAL_IFC_REGS_SIZE_W = $clog2(DIGITAL_IFC_REGS_SIZE); ctrlport_decoder_param #( - .NUM_SLAVES (4), - .PORT_BASE ({ DIO_SOURCE_CONTROL_OFFSET, + .NUM_SLAVES (5), + .PORT_BASE ({ DIGITAL_IFC_OFFSET, + DIO_SOURCE_CONTROL_OFFSET, RADIO_GPIO_ATR_OFFSET, RFDC_TIMING_WINDOW[19:0], DB_WINDOW[19:0] }), - .PORT_ADDR_W ({ DIO_SOURCE_CONTROL_SIZE_W, + .PORT_ADDR_W ({ DIGITAL_IFC_REGS_SIZE_W, + DIO_SOURCE_CONTROL_SIZE_W, RADIO_GPIO_ATR_SIZE_W, RFDC_TIMING_WINDOW_SIZE_W, DB_WINDOW_SIZE_W }) ) ctrlport_decoder_param_i ( - .ctrlport_clk (radio_clk), - .ctrlport_rst (radio_rst), - .s_ctrlport_req_wr (s_radio_ctrlport_req_wr [ 1*db+: 1]), - .s_ctrlport_req_rd (s_radio_ctrlport_req_rd [ 1*db+: 1]), - .s_ctrlport_req_addr (s_radio_ctrlport_req_addr [20*db+:20]), - .s_ctrlport_req_data (s_radio_ctrlport_req_data [32*db+:32]), - .s_ctrlport_req_byte_en (s_radio_ctrlport_req_byte_en [ 4*db+: 4]), - .s_ctrlport_req_has_time (s_radio_ctrlport_req_has_time [ 1*db+: 1]), - .s_ctrlport_req_time (s_radio_ctrlport_req_time [64*db+:64]), - .s_ctrlport_resp_ack (s_radio_ctrlport_resp_ack [ 1*db+: 1]), - .s_ctrlport_resp_status (s_radio_ctrlport_resp_status [ 2*db+: 2]), - .s_ctrlport_resp_data (s_radio_ctrlport_resp_data [32*db+:32]), - .m_ctrlport_req_wr ({ radio_dio_req_wr [ 1*db+: 1], gpio_atr_ctrlport_req_wr, rf_ctrlport_req_wr [ 1*db+: 1], m_radio_ctrlport_req_wr [ 1*db+: 1] }), - .m_ctrlport_req_rd ({ radio_dio_req_rd [ 1*db+: 1], gpio_atr_ctrlport_req_rd, rf_ctrlport_req_rd [ 1*db+: 1], m_radio_ctrlport_req_rd [ 1*db+: 1] }), - .m_ctrlport_req_addr ({ radio_dio_req_addr [20*db+:20], gpio_atr_ctrlport_req_addr, rf_ctrlport_req_addr [20*db+:20], m_radio_ctrlport_req_addr [20*db+:20] }), - .m_ctrlport_req_data ({ radio_dio_req_data [32*db+:32], gpio_atr_ctrlport_req_data, rf_ctrlport_req_data [32*db+:32], m_radio_ctrlport_req_data [32*db+:32] }), - .m_ctrlport_req_byte_en ({ radio_dio_req_byte_en [ 4*db+: 4], gpio_atr_ctrlport_req_byte_en, rf_ctrlport_req_byte_en [ 4*db+: 4], m_radio_ctrlport_req_byte_en [ 4*db+: 4] }), - .m_ctrlport_req_has_time ({ radio_dio_req_has_time [ 1*db+: 1], gpio_atr_ctrlport_req_has_time, rf_ctrlport_req_has_time [ 1*db+: 1], m_radio_ctrlport_req_has_time [ 1*db+: 1] }), - .m_ctrlport_req_time ({ radio_dio_req_time [64*db+:64], gpio_atr_ctrlport_req_time, rf_ctrlport_req_time [64*db+:64], m_radio_ctrlport_req_time [64*db+:64] }), - .m_ctrlport_resp_ack ({ radio_dio_resp_ack [ 1*db+: 1], gpio_atr_ctrlport_resp_ack, rf_ctrlport_resp_ack [ 1*db+: 1], m_radio_ctrlport_resp_ack [ 1*db+: 1] }), - .m_ctrlport_resp_status ({ radio_dio_resp_status [ 2*db+: 2], gpio_atr_ctrlport_resp_status, rf_ctrlport_resp_status [ 2*db+: 2], m_radio_ctrlport_resp_status [ 2*db+: 2] }), - .m_ctrlport_resp_data ({ radio_dio_resp_data [32*db+:32], gpio_atr_ctrlport_resp_data, rf_ctrlport_resp_data [32*db+:32], m_radio_ctrlport_resp_data [32*db+:32] }) + .ctrlport_clk ( radio_clk ), + .ctrlport_rst ( radio_rst ), + .s_ctrlport_req_wr ( s_radio_ctrlport_req_wr [ 1*db+: 1] ), + .s_ctrlport_req_rd ( s_radio_ctrlport_req_rd [ 1*db+: 1] ), + .s_ctrlport_req_addr ( s_radio_ctrlport_req_addr [20*db+:20] ), + .s_ctrlport_req_data ( s_radio_ctrlport_req_data [32*db+:32] ), + .s_ctrlport_req_byte_en ( s_radio_ctrlport_req_byte_en [ 4*db+: 4] ), + .s_ctrlport_req_has_time ( s_radio_ctrlport_req_has_time [ 1*db+: 1] ), + .s_ctrlport_req_time ( s_radio_ctrlport_req_time [64*db+:64] ), + .s_ctrlport_resp_ack ( s_radio_ctrlport_resp_ack [ 1*db+: 1] ), + .s_ctrlport_resp_status ( s_radio_ctrlport_resp_status [ 2*db+: 2] ), + .s_ctrlport_resp_data ( s_radio_ctrlport_resp_data [32*db+:32] ), + .m_ctrlport_req_wr ({ gpio_spi_ctrlport_req_wr [ 1*db+: 1], + radio_dio_req_wr [ 1*db+: 1], + gpio_atr_ctrlport_req_wr [ 1*db+: 1], + rf_ctrlport_req_wr [ 1*db+: 1], + m_radio_ctrlport_req_wr [ 1*db+: 1] }), + .m_ctrlport_req_rd ({ gpio_spi_ctrlport_req_rd [ 1*db+: 1], + radio_dio_req_rd [ 1*db+: 1], + gpio_atr_ctrlport_req_rd [ 1*db+: 1], + rf_ctrlport_req_rd [ 1*db+: 1], + m_radio_ctrlport_req_rd [ 1*db+: 1] }), + .m_ctrlport_req_addr ({ gpio_spi_ctrlport_req_addr [20*db+:20], + radio_dio_req_addr [20*db+:20], + gpio_atr_ctrlport_req_addr [20*db+:20], + rf_ctrlport_req_addr [20*db+:20], + m_radio_ctrlport_req_addr [20*db+:20] }), + .m_ctrlport_req_data ({ gpio_spi_ctrlport_req_data [32*db+:32], + radio_dio_req_data [32*db+:32], + gpio_atr_ctrlport_req_data [32*db+:32], + rf_ctrlport_req_data [32*db+:32], + m_radio_ctrlport_req_data [32*db+:32] }), + .m_ctrlport_req_byte_en ({ gpio_spi_ctrlport_req_byte_en [ 4*db+: 4], + radio_dio_req_byte_en [ 4*db+: 4], + gpio_atr_ctrlport_req_byte_en [ 4*db+: 4], + rf_ctrlport_req_byte_en [ 4*db+: 4], + m_radio_ctrlport_req_byte_en [ 4*db+: 4] }), + .m_ctrlport_req_has_time ({ gpio_spi_ctrlport_req_has_time [ 1*db+: 1], + radio_dio_req_has_time [ 1*db+: 1], + gpio_atr_ctrlport_req_has_time [ 1*db+: 1], + rf_ctrlport_req_has_time [ 1*db+: 1], + m_radio_ctrlport_req_has_time [ 1*db+: 1] }), + .m_ctrlport_req_time ({ gpio_spi_ctrlport_req_time [64*db+:64], + radio_dio_req_time [64*db+:64], + gpio_atr_ctrlport_req_time [64*db+:64], + rf_ctrlport_req_time [64*db+:64], + m_radio_ctrlport_req_time [64*db+:64] }), + .m_ctrlport_resp_ack ({ gpio_spi_ctrlport_resp_ack [ 1*db+: 1], + radio_dio_resp_ack [ 1*db+: 1], + gpio_atr_ctrlport_resp_ack [ 1*db+: 1], + rf_ctrlport_resp_ack [ 1*db+: 1], + m_radio_ctrlport_resp_ack [ 1*db+: 1] }), + .m_ctrlport_resp_status ({ gpio_spi_ctrlport_resp_status [ 2*db+: 2], + radio_dio_resp_status [ 2*db+: 2], + gpio_atr_ctrlport_resp_status [ 2*db+: 2], + rf_ctrlport_resp_status [ 2*db+: 2], + m_radio_ctrlport_resp_status [ 2*db+: 2] }), + .m_ctrlport_resp_data ({ gpio_spi_ctrlport_resp_data [32*db+:32], + radio_dio_resp_data [32*db+:32], + gpio_atr_ctrlport_resp_data [32*db+:32], + rf_ctrlport_resp_data [32*db+:32], + m_radio_ctrlport_resp_data [32*db+:32] }) ); // Compute ATR state for this radio @@ -459,19 +521,37 @@ module x4xx_core_common #( ) x4xx_gpio_atr_i ( .ctrlport_clk (radio_clk), .ctrlport_rst (radio_rst), - .s_ctrlport_req_wr (gpio_atr_ctrlport_req_wr), - .s_ctrlport_req_rd (gpio_atr_ctrlport_req_rd), - .s_ctrlport_req_addr (gpio_atr_ctrlport_req_addr), - .s_ctrlport_req_data (gpio_atr_ctrlport_req_data), - .s_ctrlport_resp_ack (gpio_atr_ctrlport_resp_ack), - .s_ctrlport_resp_status (gpio_atr_ctrlport_resp_status), - .s_ctrlport_resp_data (gpio_atr_ctrlport_resp_data), + .s_ctrlport_req_wr (gpio_atr_ctrlport_req_wr [ 1*db+: 1]), + .s_ctrlport_req_rd (gpio_atr_ctrlport_req_rd [ 1*db+: 1]), + .s_ctrlport_req_addr (gpio_atr_ctrlport_req_addr [20*db+:20]), + .s_ctrlport_req_data (gpio_atr_ctrlport_req_data [32*db+:32]), + .s_ctrlport_resp_ack (gpio_atr_ctrlport_resp_ack [ 1*db+: 1]), + .s_ctrlport_resp_status (gpio_atr_ctrlport_resp_status [ 2*db+: 2]), + .s_ctrlport_resp_data (gpio_atr_ctrlport_resp_data [32*db+:32]), .db_state (db_state), .gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a}), .gpio_out (atr_gpio_out[db*32+: 32]), .gpio_ddr (atr_gpio_ddr[db*32+: 32]) ); + x4xx_gpio_spi #( + .NUM_SLAVES (2) + ) x4xx_gpio_spi_i( + .ctrlport_clk (radio_clk), + .ctrlport_clk_2x (radio_clk_2x), + .ctrlport_rst (radio_rst), + .s_ctrlport_req_wr (gpio_spi_ctrlport_req_wr [ 1*db+: 1]), + .s_ctrlport_req_rd (gpio_spi_ctrlport_req_rd [ 1*db+: 1]), + .s_ctrlport_req_addr (gpio_spi_ctrlport_req_addr [20*db+:20]), + .s_ctrlport_req_data (gpio_spi_ctrlport_req_data [32*db+:32]), + .s_ctrlport_resp_ack (gpio_spi_ctrlport_resp_ack [ 1*db+: 1]), + .s_ctrlport_resp_status (gpio_spi_ctrlport_resp_status [ 2*db+: 2]), + .s_ctrlport_resp_data (gpio_spi_ctrlport_resp_data [32*db+:32]), + .gpio_out (spi_gpio_out[db*32+: 32]), + .gpio_ddr (spi_gpio_ddr[db*32+: 32]), + .gpio_in ({4'b0, gpio_in_b, 4'b0, gpio_in_a}) + ); + end endgenerate @@ -686,10 +766,10 @@ module x4xx_core_common #( .atr_gpio_ddr (atr_gpio_ddr), .ps_gpio_out ({4'b0, ps_gpio_out_b, 4'b0, ps_gpio_out_a}), .ps_gpio_ddr ({4'b0, ps_gpio_ddr_b, 4'b0, ps_gpio_ddr_a}), - .digital_ifc_gpio_out_radio0 (32'b0), - .digital_ifc_gpio_ddr_radio0 (32'b0), - .digital_ifc_gpio_out_radio1 (32'b0), - .digital_ifc_gpio_ddr_radio1 (32'b0), + .digital_ifc_gpio_out_radio0 (spi_gpio_out[31:0]), + .digital_ifc_gpio_ddr_radio0 (spi_gpio_ddr[31:0]), + .digital_ifc_gpio_out_radio1 (spi_gpio_out[63:32]), + .digital_ifc_gpio_ddr_radio1 (spi_gpio_ddr[63:32]), .user_app_in_a (gpio_in_fabric_a), .user_app_in_b (gpio_in_fabric_b), .user_app_out_a (gpio_out_fabric_a), @@ -771,6 +851,10 @@ endmodule // <window name="DIO_SOURCE_CONTROL" offset="0x1000" size="0x1000" targetregmap="DIO_REGMAP"> // <info>Window to access the DIO register map through the control port from the radio blocks.</info> // </window> +// <window name="DIGITAL_IFC_REGS" offset="0x2000" size="0x1000" targetregmap="DIG_IFC_REGMAP"> +// <info>Register space reserved for configuring a digital interface over the GPIO lines. +// Currently, SPI is the only supported protocol.</info> +// </window> // </group> //</regmap> diff --git a/fpga/usrp3/top/x400/x4xx_gpio_atr.v b/fpga/usrp3/top/x400/x4xx_gpio_atr.v index 98ba881f3..86e1a6afe 100644 --- a/fpga/usrp3/top/x400/x4xx_gpio_atr.v +++ b/fpga/usrp3/top/x400/x4xx_gpio_atr.v @@ -312,13 +312,13 @@ endmodule // <info> // Controls whether GPIO lines use the TX and RX state of an RF channel // (Classic ATR) or the daughterboard state the selector for the -// @.GPIO_ATR_STATE. +// @.ATR_STATE. // </info> // <bitfield name="ATR_OPTION" range="0" initialvalue="0"> // <info> // Sets the scheme in which RF states in the radio will control GPIO // lines. 0 = DB state is used. RF states are combined and the -// GPIO state is driven based on all 16 @.GPIO_ATR_STATE registers. +// GPIO state is driven based on all 16 @.ATR_STATE registers. // 1 = Each RF channel has its separate ATR state(Classic ATR). // Use register @.CLASSIC_ATR_CONFIG to indicate the RF channel // to which each GPIO line responds to. diff --git a/fpga/usrp3/top/x400/x4xx_gpio_spi.v b/fpga/usrp3/top/x400/x4xx_gpio_spi.v new file mode 100644 index 000000000..b5866f867 --- /dev/null +++ b/fpga/usrp3/top/x400/x4xx_gpio_spi.v @@ -0,0 +1,534 @@ +// +// Copyright 2021 Ettus Research, A National Instruments Brand +// +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: x4xx_gpio_spi +// +// Description: +// +// This block enables control of a SPI master engine via CtrlPort +// transactions. +// It also enables customization on how signals from the SPI buses +// connected to the master are mapped to the GPIO Ports. +// This block supports configuring communication to up to 4 SPI slaves. +// +// Parameters: +// +// NUM_SLAVES : Number of SPI slaves to be supported. Values from 1 to 4 +// are supported. SPI transfers can only target one slave +// at a time. +// BASE_ADDRESS : Start address for this register block. +// SIZE_ADDRESS : Size of the CtrlPort window to consider in this block. +// + +`default_nettype none + + +module x4xx_gpio_spi #( + parameter NUM_SLAVES = 4, + parameter [19:0] BASE_ADDRESS = 0, + parameter [19:0] SIZE_ADDRESS = 19'h20 +) ( + input wire ctrlport_clk, + input wire ctrlport_clk_2x, + input wire ctrlport_rst, + + // Request + input wire s_ctrlport_req_wr, + input wire s_ctrlport_req_rd, + input wire [19:0] s_ctrlport_req_addr, + input wire [31:0] s_ctrlport_req_data, + + // Response + output reg s_ctrlport_resp_ack = 1'b0, + output reg [ 1:0] s_ctrlport_resp_status = 2'b0, + output reg [31:0] s_ctrlport_resp_data = 32'b0, + + // GPIO control/status + output wire [31:0] gpio_out, + output wire [31:0] gpio_ddr, + input wire [31:0] gpio_in +); + + `include "../../lib/rfnoc/core/ctrlport.vh" + `include "regmap/dig_ifc_regmap_utils.vh" + + // Registers / wires for SPI core communication + reg [31:0] set_data = 0; + reg [ 7:0] set_addr = 0; + reg set_stb = 1'b0; + + wire [31:0] readback; + wire readback_stb; + wire readback_stb_extended; + + wire sclk; + wire mosi; + wire miso; + // This array is set to the maximum supported SPI slaves instead of + // the provided NUM_SLAVES to facilitate concurrent re-mapping. + // See section(GPIO Mapping) of this file. + wire [3:0] ss; + + // Auxiliary signals to compute which GPIO lines are outputs + reg [31:0] gpio_is_mosi = 32'b0; + reg [31:0] gpio_is_sclk = 32'b0; + reg [31:0] gpio_is_cs = 32'b0; + + // SPI-to-GPIO mapping signals. + // These arrays are set to the maximum supported SPI slaves instead of + // the provided NUM_SLAVES to facilitate concurrent re-mapping. + // See section(GPIO Mapping) of this file. + reg [ SLAVE_CLK_SIZE-1:0] sclk_mapping [3:0]; + reg [SLAVE_MOSI_SIZE-1:0] mosi_mapping [3:0]; + reg [SLAVE_MISO_SIZE-1:0] miso_mapping [3:0]; + reg [ SLAVE_CS_SIZE-1:0] ss_mapping [3:0]; + + //--------------------------------------------------------------------------- + // Address calculation + //--------------------------------------------------------------------------- + + wire address_in_range = + (s_ctrlport_req_addr >= BASE_ADDRESS) && + (s_ctrlport_req_addr < BASE_ADDRESS + SIZE_ADDRESS); + + // Check that address is targeting slave configuration. + wire address_is_slave = + (s_ctrlport_req_addr >= BASE_ADDRESS + SPI_SLAVE_CONFIG(0)) && + (s_ctrlport_req_addr <= BASE_ADDRESS + SPI_SLAVE_CONFIG(3)); + + // Decode the slave being addressed. + wire [1:0]slave_address = s_ctrlport_req_addr[3:2]; + + //--------------------------------------------------------------------------- + // Slave configuration signals + //--------------------------------------------------------------------------- + + // These settings are registered individually for each slave + reg [ NUM_SLAVES-1:0] data_in_edge = {NUM_SLAVES{1'b0}}; + reg [ NUM_SLAVES-1:0] data_out_edge = {NUM_SLAVES{1'b0}}; + reg [SPI_LENGTH_SIZE-1:0] slave_spi_length [NUM_SLAVES-1:0]; + + // One-hot encoding to indicate active slave + reg [NUM_SLAVES-1:0] slave_select = {NUM_SLAVES{1'b0}}; + + //--------------------------------------------------------------------------- + // FSM to handle transfers + //--------------------------------------------------------------------------- + + localparam IDLE = 3'd0; + localparam SET_DIVIDER = 3'd1; + localparam WRITE_SPI = 3'd2; + localparam CONFIG_TRANSFER = 3'd3; + localparam WAIT_SPI = 3'd4; + + localparam DIVIDER_ADDRESS = 8'd0; + localparam CTRL_ADDRESS = 8'd1; + localparam DATA_ADDRESS = 8'd2; + + reg [ 2:0] state = IDLE; + reg [ 31:0] data_cache; + reg [SPI_CLK_DIV_SIZE-1:0] divider; + reg [ 1:0] cs; + reg spi_go = 1'b0; + reg spi_ready = 1'b0; + + integer slave_i; + + //--------------------------------------------------------------------------- + // CtrlPort Register endpoints + //--------------------------------------------------------------------------- + + always @ (posedge ctrlport_clk) begin + + if (ctrlport_rst) begin + s_ctrlport_resp_ack <= 1'b0; + spi_go <= 1'b0; + spi_ready <= 1'b0; + divider <= {SPI_CLK_DIV_SIZE{1'b0}}; + cs <= 2'b0; + + // Assigned to unassigned mapping. This avoids overwriting + // signals with those from uninitialized slaves. + for (slave_i=0; slave_i<4; slave_i=slave_i+1) begin + sclk_mapping[slave_i] <= 5'h31; + mosi_mapping[slave_i] <= 5'h31; + miso_mapping[slave_i] <= 5'h31; + ss_mapping [slave_i] <= 5'h31; + end + + for (slave_i=0; slave_i<NUM_SLAVES; slave_i=slave_i+1) begin + slave_spi_length[slave_i] <= {SPI_LENGTH_SIZE{1'b0}}; + end + end else begin + + // Default assignments + s_ctrlport_resp_ack <= 1'b0; + spi_go <= 1'b0; + + // Requests appear + if (s_ctrlport_req_wr) begin + s_ctrlport_resp_ack <= 1'b1; + s_ctrlport_resp_data <= {32{1'bx}}; + s_ctrlport_resp_status <= CTRL_STS_OKAY; + + // Address spi configuration writes + if(address_is_slave) begin + // GPIO mapping + sclk_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_CLK_MSB:SLAVE_CLK]; + mosi_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_MOSI_MSB:SLAVE_MOSI]; + miso_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_MISO_MSB:SLAVE_MISO]; + ss_mapping [slave_address] <= s_ctrlport_req_data[SLAVE_CS_MSB:SLAVE_CS]; + // Transfer Configuration + slave_spi_length [slave_address] <= s_ctrlport_req_data[SPI_LENGTH_MSB:SPI_LENGTH]; + data_in_edge [slave_address] <= s_ctrlport_req_data[MISO_EDGE]; + data_out_edge [slave_address] <= s_ctrlport_req_data[MOSI_EDGE]; + end else begin + + case (s_ctrlport_req_addr) + BASE_ADDRESS + SPI_TRANSACTION_CONFIG: begin + divider <= s_ctrlport_req_data[SPI_CLK_DIV_MSB:SPI_CLK_DIV]; + cs <= s_ctrlport_req_data[SPI_SLAVE_SELECT_MSB:SPI_SLAVE_SELECT]; + end + + BASE_ADDRESS + SPI_TRANSACTION_GO: begin + spi_ready <= 1'b0; + spi_go <= 1'b1; + end + + // No register implementation for provided address + default: begin + // Acknowledge and provide error status if address is in range + if (address_in_range) begin + s_ctrlport_resp_status <= CTRL_STS_CMDERR; + + // No response if out of range + end else begin + s_ctrlport_resp_ack <= 1'b0; + end + end + + endcase + end + + end else if(s_ctrlport_req_rd) begin + // default assumption: valid request + s_ctrlport_resp_ack <= 1'b1; + s_ctrlport_resp_status <= CTRL_STS_OKAY; + s_ctrlport_resp_data <= {32{1'b0}}; + + case (s_ctrlport_req_addr) + BASE_ADDRESS + SPI_TRANSACTION_CONFIG: begin + s_ctrlport_resp_data[SPI_CLK_DIV_MSB:SPI_CLK_DIV] <= divider; + end + + BASE_ADDRESS + SPI_STATUS: begin + s_ctrlport_resp_data[SPI_READY] <= spi_ready; + s_ctrlport_resp_data[SPI_RESPONSE_MSB:SPI_RESPONSE] <= readback[SPI_RESPONSE_MSB:SPI_RESPONSE]; + end + + // No register implementation for provided address + default: begin + // Acknowledge and provide error status if address is in range + if (address_in_range) begin + s_ctrlport_resp_status <= CTRL_STS_CMDERR; + + // No response if out of range + end else begin + s_ctrlport_resp_ack <= 1'b0; + end + end + + endcase + end + + if (readback_stb_extended) begin + spi_ready <= 1'b1; + end + end + + end + + //--------------------------------------------------------------------------- + // SPI Control FSM + //--------------------------------------------------------------------------- + + always @ (posedge ctrlport_clk) begin + if (ctrlport_rst) begin + state <= IDLE; + set_stb <= 1'b0; + data_cache <= 32'h0; + end else begin + + // Default Assignments + set_stb <= 1'b0; + + case (state) + IDLE: begin + // Save data and address for further steps + data_cache <= s_ctrlport_req_data; + if (spi_go) begin + state <= CONFIG_TRANSFER; + + slave_select <= {NUM_SLAVES{1'b0}}; + slave_select[cs] <= 1'b1; + end + end + + // Set slave select + CONFIG_TRANSFER: begin + state <= SET_DIVIDER; + + set_stb <= 1'b1; + set_addr <= CTRL_ADDRESS; + set_data <= { data_out_edge[cs], // 1 bit + data_in_edge[cs], // 1 bit + slave_spi_length[cs], // 6 bits + {24-NUM_SLAVES{1'b0}}, // Padding for slaves + slave_select // NUM_SLAVES bits + }; + end + + // Write divider to SPI core + SET_DIVIDER: begin + state <= WRITE_SPI; + + set_stb <= 1'b1; + set_addr <= DIVIDER_ADDRESS; + set_data <= {16'b0, divider}; + end + + // Write data bits to SPI core (aligned to MSB) + WRITE_SPI: begin + state <= WAIT_SPI; + + set_stb <= 1'b1; + set_addr <= DATA_ADDRESS; + set_data <= data_cache; + end + + // Wait for transaction to complete and translate to ctrlport response + WAIT_SPI: begin + + if (readback_stb_extended) begin + state <= IDLE; + end + end + + default: begin + state <= IDLE; + end + endcase + + // Update Auxiliary signals + gpio_is_mosi <= 32'h0; + gpio_is_sclk <= 32'h0; + gpio_is_cs <= 32'h0; + + for (slave_i=0; slave_i<NUM_SLAVES; slave_i=slave_i+1) begin + gpio_is_mosi [mosi_mapping[slave_i]] <= 1'b1; + gpio_is_sclk [sclk_mapping[slave_i]] <= 1'b1; + gpio_is_cs [ ss_mapping[slave_i]] <= 1'b1; + end + + end + end + + + //--------------------------------------------------------------------------- + // SPI master + //--------------------------------------------------------------------------- + + // Register set_stb for use in 2x domain. + reg set_stb_2x = 1'b0; + reg ctrlport_clk_phase = 1'b0; + + always @ (posedge ctrlport_clk_2x) begin + // Assert strobe only during a single 2x cycle of the + // 1x pulse. + set_stb_2x <= ctrlport_clk_phase & set_stb; + ctrlport_clk_phase <= ~ctrlport_clk_phase; + end + + simple_spi_core #( + .BASE (0), + .WIDTH (NUM_SLAVES), + .CLK_IDLE (0), + .SEN_IDLE ({NUM_SLAVES{1'b1}}) + ) simple_spi_core_i ( + .clock (ctrlport_clk_2x), + .reset (ctrlport_rst), + .set_stb (set_stb_2x), + .set_addr (set_addr), + .set_data (set_data), + .readback (readback), + .readback_stb (readback_stb), + .ready (), + .sen (ss[NUM_SLAVES-1:0]), + .sclk (sclk), + .mosi (mosi), + .miso (miso), + .debug () + ); + + // Delay and extend signal for use in 1x domain. + reg readback_stb_dly = 1'b0; + + always @ (posedge ctrlport_clk_2x) begin + readback_stb_dly <= readback_stb; + end + + assign readback_stb_extended = readback_stb_dly | readback_stb; + + //--------------------------------------------------------------------------- + // GPIO Mapping + //--------------------------------------------------------------------------- + + wire [31:0] mosi_mux_out; + reg [31:0] mosi_mux_out_dlyd; + wire [31:0] ss_mux_out; + wire [31:0] gated_sclk; + reg [31:0] gated_sclk_dlyd; + reg [31:0] gpio_is_sclk_dlyd; + + genvar i; + generate + + for (i = 0; i < 32; i = i + 1) begin: dio_output_gen + + // Indicate which GPIO lines are outputs + assign gpio_ddr[i] = gpio_is_mosi[i] | gpio_is_sclk[i] | gpio_is_cs[i]; + + // CS re-mapping + assign ss_mux_out[i] = ( i == ss_mapping[0] ) ? ss[0] : + ( i == ss_mapping[1] ) ? ss[1] : + ( i == ss_mapping[2] ) ? ss[2] : + ( i == ss_mapping[3] ) ? ss[3] : + 1'b0; + + assign mosi_mux_out[i] = gpio_is_mosi[i] ? mosi : ss_mux_out[i]; + assign gated_sclk[i] = gpio_is_sclk[i] ? sclk : 1'b0; + + // register signals once remapping logic is resolved + always @ (posedge ctrlport_clk_2x) begin + mosi_mux_out_dlyd[i] <= mosi_mux_out[i]; + gpio_is_sclk_dlyd[i] <= gpio_is_sclk[i]; + gated_sclk_dlyd[i] <= gated_sclk[i]; + end + + // Choose between SCLK and MOSI/SS mux. + glitch_free_mux glitch_free_gpio_out ( + .select (gpio_is_sclk_dlyd[i]), + .signal0 (mosi_mux_out_dlyd[i]), + .signal1 (gated_sclk_dlyd[i]), + .muxed_signal (gpio_out[i]) + ); + + end + endgenerate + + assign miso = ( ~ss[0] ) ? gpio_in[miso_mapping[0]] : + ( ~ss[1] ) ? gpio_in[miso_mapping[1]] : + ( ~ss[2] ) ? gpio_in[miso_mapping[2]] : + ( ~ss[3] ) ? gpio_in[miso_mapping[3]] : + 1'b0; + + +endmodule + + +`default_nettype wire + +//XmlParse xml_on +//<regmap name="DIG_IFC_REGMAP" readablestrobes="false" generatevhdl="true" ettusguidelines="true"> +// <group name="SPI_OVER_GPIO_REGS"> +// <info> +// </info> +// <regtype name="SPI_SETUP" size="32"> +// <info> +// Controls SPI Transaction +// </info> +// <bitfield name="SLAVE_CLK" range="0..4" initialvalue="0"> +// <info> +// Indicates which GPIO line to use for the SCLK signal.</br> +// 0-11 : Port A GPIO</br> +// 16-27: Port B GPIO +// </info> +// </bitfield> +// <bitfield name="SLAVE_MOSI" range="5..9" initialvalue="0"> +// <info> +// Indicates which GPIO line to use for the MOSI signal.</br> +// 0-11 : Port A GPIO</br> +// 16-27: Port B GPIO +// </info> +// </bitfield> +// <bitfield name="SLAVE_MISO" range="10..14" initialvalue="0"> +// <info> +// Indicates which GPIO line to use for the MISO signal.</br> +// 0-11 : Port A GPIO</br> +// 16-27: Port B GPIO +// </info> +// </bitfield> +// <bitfield name="SLAVE_CS" range="15..19" initialvalue="0"> +// <info> +// Indicates which GPIO line to use for the CS signal.</br> +// 0-11 : Port A GPIO</br> +// 16-27: Port B GPIO +// </info> +// </bitfield> +// <bitfield name="SPI_LENGTH" range="20..25" initialvalue="0"> +// <info> +// Indicates the length of SPI transactions to this slave. +// </info> +// </bitfield> +// <bitfield name="MISO_EDGE" range="26" initialvalue="0"> +// <info> +// Controls the edge in which the MISO line is latched.</br> +// 0 = falling edge of SCLK.</br> +// 1 = rising edge of SCLK. +// </info> +// </bitfield> +// <bitfield name="MOSI_EDGE" range="27" initialvalue="0"> +// <info> +// Controls the edge in which the MOSI line is updated.</br> +// 0 = falling edge of SCLK.</br> +// 1 = rising edge of SCLK. +// </info> +// </bitfield> +// </regtype> +// <register name="SPI_SLAVE_CONFIG" typename="SPI_SETUP" offset="0x00" count="4" options="--step 4"> +// <info> Set of configuration registers for the supported slaves. </info> +// </register> +// <register name="SPI_TRANSACTION_CONFIG" offset="0x10" size="32"> +// <info> +// Controls clock rate and target for subsequent SPI transactions. +// </info> +// <bitfield name="SPI_CLK_DIV" range="0..15" initialvalue="0"> +// <info> Controls the rate for subsequent SPI transactions. SCLK = DataClk/[(SPI_CLK_DIV+1)]</info> +// </bitfield> +// <bitfield name="SPI_SLAVE_SELECT" range="16..17" initialvalue="0"/> +// </register> +// <register name="SPI_TRANSACTION_GO" offset="0x14" size="32" readable="false"> +// <info> +// Starts a SPI transaction +// </info> +// <bitfield name="SPI_DATA" range="0..31" initialvalue="0"> +// <info> Payload to be sent for the SPI transaction. If the payload is shorter than 32 bits, +// it must be aligned to the MSbs in this field. LSbs are ignored in this scenario.</info> +// </bitfield> +// </register> +// <register name="SPI_STATUS" offset="0x18" size="32" writable="false"> +// <info> +// Contains the status of the SPI engine. +// </info> +// <bitfield name="SPI_READY" range="24" initialvalue="0"> +// <info> Indicates the SPI engine is ready to start a new SPI transaction. </info> +// </bitfield> +// <bitfield name="SPI_RESPONSE" range="0..23" initialvalue="0"> +// <info> Records the response of the last completed SPI transaction. </info> +// </bitfield> +// </register> +// </group> +//</regmap> +//XmlParse xml_off |