x300: add front-panel GPIO source control
Adds a ZPU register to control the FP GPIO source. These are 2bits
per GPIO pin, totalling 24 bits. 0 corresponds to RF-A, 1 corresponds
to RF-B. The following Python code will control the upper 6 bits of the
front-panel GPIO from the B-side radio on an X300:
>>> import uhd
>>> U = uhd.usrp.MultiUSRP("type=x300")
>>> U.get_gpio_src_banks()
['FP0']
>>> U.get_gpio_src("FP0")
['RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA',
'RFA', 'RFA']
>>> U.set_gpio_src("FP0", ['RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA',
'RFB', 'RFB', 'RFB', 'RFB', 'RFB', 'RFB'])
>>> U.get_gpio_src("FP0")
['RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFA', 'RFB', 'RFB', 'RFB', 'RFB',
'RFB', 'RFB']
>>> # Make all GPIOs outputs:
>>> U.set_gpio_attr("FP0A", "DDR", 0xFFF)
>>> U.set_gpio_attr("FP0B", "DDR", 0xFFF)
>>> # Control all GPIOs from software (not ATR):
>>> U.set_gpio_attr("FP0A", "CTRL", 0x000)
>>> U.set_gpio_attr("FP0B", "CTRL", 0x000)
>>> # Bottom 3 pins go high from radio A
>>> U.set_gpio_attr("FP0A", "OUT", 0x007)
>>> # Top 3 pins go high from radio B
>>> U.set_gpio_attr("FP0B", "OUT", 0xE00)
Amends the gpio.cpp example to allow switching the source.
Co-authored-by: Brent Stapleton <brent.stapleton@ettus.com>
Original-commit: d7304cc724de43b0d61d5b9d61a528d58898f004
This commit is contained in:
committed by
atrnati
co-authored by
Brent Stapleton
parent
59adae6252
commit
f51c7aa780
+12
-1
@@ -45,6 +45,8 @@ module bus_int #(
|
|||||||
input SFPP0_ModAbs, input SFPP0_TxFault, input SFPP0_RxLOS, inout SFPP0_RS0, inout SFPP0_RS1,
|
input SFPP0_ModAbs, input SFPP0_TxFault, input SFPP0_RxLOS, inout SFPP0_RS0, inout SFPP0_RS1,
|
||||||
// SFP+ 1
|
// SFP+ 1
|
||||||
input SFPP1_ModAbs, input SFPP1_TxFault, input SFPP1_RxLOS, inout SFPP1_RS0, inout SFPP1_RS1,
|
input SFPP1_ModAbs, input SFPP1_TxFault, input SFPP1_RxLOS, inout SFPP1_RS0, inout SFPP1_RS1,
|
||||||
|
// Front-panel GPIO source
|
||||||
|
output [23:0] fp_gpio_src,
|
||||||
// Clock control and status
|
// Clock control and status
|
||||||
input [7:0] clock_status, output [7:0] clock_control, output [31:0] ref_freq, output ref_freq_changed,
|
input [7:0] clock_status, output [7:0] clock_control, output [31:0] ref_freq, output ref_freq_changed,
|
||||||
// SFP+ 0 data stream
|
// SFP+ 0 data stream
|
||||||
@@ -153,7 +155,7 @@ module bus_int #(
|
|||||||
localparam SR_SPI = 8'd32;
|
localparam SR_SPI = 8'd32;
|
||||||
localparam SR_ETHINT0 = 8'd40;
|
localparam SR_ETHINT0 = 8'd40;
|
||||||
localparam SR_ETHINT1 = 8'd56;
|
localparam SR_ETHINT1 = 8'd56;
|
||||||
//localparam SR_NEXT_ADDR = 8'd72;
|
localparam SR_FP_GPIO_SRC = 8'd72;
|
||||||
localparam SR_BASE_TIME = 8'd100;
|
localparam SR_BASE_TIME = 8'd100;
|
||||||
|
|
||||||
localparam RB_COUNTER = 8'd00;
|
localparam RB_COUNTER = 8'd00;
|
||||||
@@ -169,6 +171,7 @@ module bus_int #(
|
|||||||
localparam RB_GIT_HASH = 8'd10;
|
localparam RB_GIT_HASH = 8'd10;
|
||||||
localparam RB_XADC_VALS = 8'd11;
|
localparam RB_XADC_VALS = 8'd11;
|
||||||
localparam RB_NUM_TIMEKEEPERS = 8'd12;
|
localparam RB_NUM_TIMEKEEPERS = 8'd12;
|
||||||
|
localparam RB_FP_GPIO_SRC = 8'd13;
|
||||||
|
|
||||||
localparam COMPAT_MAJOR = 16'h0026;
|
localparam COMPAT_MAJOR = 16'h0026;
|
||||||
localparam COMPAT_MINOR = 16'h0000;
|
localparam COMPAT_MINOR = 16'h0000;
|
||||||
@@ -433,6 +436,7 @@ module bus_int #(
|
|||||||
`endif
|
`endif
|
||||||
RB_GIT_HASH: rb_data = `GIT_HASH;
|
RB_GIT_HASH: rb_data = `GIT_HASH;
|
||||||
RB_XADC_VALS: rb_data = xadc_readback;
|
RB_XADC_VALS: rb_data = xadc_readback;
|
||||||
|
RB_FP_GPIO_SRC: rb_data = fp_gpio_src;
|
||||||
SR_BASE_TIME: begin
|
SR_BASE_TIME: begin
|
||||||
rb_data = radio_time[31:0];
|
rb_data = radio_time[31:0];
|
||||||
radio_time_hi_ld = 1'b1;
|
radio_time_hi_ld = 1'b1;
|
||||||
@@ -604,6 +608,13 @@ module bus_int #(
|
|||||||
assign SFPP1_RS0 = sfpp1_ctrl[0] ? 1'b0 : 1'bz;
|
assign SFPP1_RS0 = sfpp1_ctrl[0] ? 1'b0 : 1'bz;
|
||||||
assign SFPP1_RS1 = sfpp1_ctrl[1] ? 1'b0 : 1'bz;
|
assign SFPP1_RS1 = sfpp1_ctrl[1] ? 1'b0 : 1'bz;
|
||||||
|
|
||||||
|
|
||||||
|
// Front-panel GPIO source - Each pin is allocated 2 bits
|
||||||
|
setting_reg #(.my_addr(SR_FP_GPIO_SRC), .awidth(SR_AWIDTH), .width(24)) set_fp_gpio_src
|
||||||
|
(.clk(clk), .rst(reset),
|
||||||
|
.strobe(set_stb), .addr(set_addr), .in(set_data),
|
||||||
|
.out(fp_gpio_src));
|
||||||
|
|
||||||
// ////////////////////////////////////////////////////////////////
|
// ////////////////////////////////////////////////////////////////
|
||||||
// ETH interfaces
|
// ETH interfaces
|
||||||
|
|
||||||
|
|||||||
+33
-6
@@ -1,6 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2014 Ettus Research LLC
|
// Copyright 2014 Ettus Research LLC
|
||||||
// Copyright 2017 Ettus Research, a National Instruments Company
|
// Copyright 2017 Ettus Research, a National Instruments Company
|
||||||
|
// Copyright 2020 Ettus Research, a National Instruments Brand
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
//
|
//
|
||||||
@@ -21,7 +22,7 @@ module x300_core #(
|
|||||||
// Radio 0
|
// Radio 0
|
||||||
input [31:0] rx0, output [31:0] tx0,
|
input [31:0] rx0, output [31:0] tx0,
|
||||||
input [31:0] db0_gpio_in, output [31:0] db0_gpio_out, output [31:0] db0_gpio_ddr,
|
input [31:0] db0_gpio_in, output [31:0] db0_gpio_out, output [31:0] db0_gpio_ddr,
|
||||||
input [31:0] fp_gpio_in, output [31:0] fp_gpio_out, output [31:0] fp_gpio_ddr,
|
input [31:0] fp_gpio_in, output reg [31:0] fp_gpio_out, output reg [31:0] fp_gpio_ddr,
|
||||||
output [7:0] sen0, output sclk0, output mosi0, input miso0,
|
output [7:0] sen0, output sclk0, output mosi0, input miso0,
|
||||||
output [2:0] radio_led0,
|
output [2:0] radio_led0,
|
||||||
output reg [31:0] radio0_misc_out, input [31:0] radio0_misc_in,
|
output reg [31:0] radio0_misc_out, input [31:0] radio0_misc_in,
|
||||||
@@ -311,6 +312,8 @@ module x300_core #(
|
|||||||
// SFP 1
|
// SFP 1
|
||||||
.SFPP1_ModAbs(SFPP1_ModAbs),.SFPP1_TxFault(SFPP1_TxFault),.SFPP1_RxLOS(SFPP1_RxLOS),
|
.SFPP1_ModAbs(SFPP1_ModAbs),.SFPP1_TxFault(SFPP1_TxFault),.SFPP1_RxLOS(SFPP1_RxLOS),
|
||||||
.SFPP1_RS0(SFPP1_RS0), .SFPP1_RS1(SFPP1_RS1),
|
.SFPP1_RS0(SFPP1_RS0), .SFPP1_RS1(SFPP1_RS1),
|
||||||
|
// Front-panel GPIO source
|
||||||
|
.fp_gpio_src(sr_fp_gpio_src),
|
||||||
//clocky locky misc
|
//clocky locky misc
|
||||||
.clock_status({misc_clock_status, pps_detect, LMK_Holdover, LMK_Lock, LMK_Status}),
|
.clock_status({misc_clock_status, pps_detect, LMK_Holdover, LMK_Lock, LMK_Status}),
|
||||||
.clock_control({1'b0, clock_misc_opt[1:0], pps_out_enb, pps_select[1:0], clock_ref_sel[1:0]}),
|
.clock_control({1'b0, clock_misc_opt[1:0], pps_out_enb, pps_select[1:0], clock_ref_sel[1:0]}),
|
||||||
@@ -528,6 +531,7 @@ module x300_core #(
|
|||||||
wire [31:0] db_gpio_in[0:NUM_DBOARDS-1], db_gpio_out[0:NUM_DBOARDS-1], db_gpio_ddr[0:NUM_DBOARDS-1];
|
wire [31:0] db_gpio_in[0:NUM_DBOARDS-1], db_gpio_out[0:NUM_DBOARDS-1], db_gpio_ddr[0:NUM_DBOARDS-1];
|
||||||
wire [31:0] misc_outs[0:NUM_DBOARDS-1];
|
wire [31:0] misc_outs[0:NUM_DBOARDS-1];
|
||||||
reg [31:0] misc_ins[0:NUM_DBOARDS-1];
|
reg [31:0] misc_ins[0:NUM_DBOARDS-1];
|
||||||
|
wire [24:0] sr_fp_gpio_src, fp_gpio_src;
|
||||||
wire [7:0] sen[0:NUM_DBOARDS-1];
|
wire [7:0] sen[0:NUM_DBOARDS-1];
|
||||||
wire sclk[0:NUM_DBOARDS-1], mosi[0:NUM_DBOARDS-1], miso[0:NUM_DBOARDS-1];
|
wire sclk[0:NUM_DBOARDS-1], mosi[0:NUM_DBOARDS-1], miso[0:NUM_DBOARDS-1];
|
||||||
wire rx_running[0:NUM_CHANNELS-1], tx_running[0:NUM_CHANNELS-1];
|
wire rx_running[0:NUM_CHANNELS-1], tx_running[0:NUM_CHANNELS-1];
|
||||||
@@ -601,6 +605,34 @@ module x300_core #(
|
|||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
|
//------------------------------------
|
||||||
|
// Front-Panel GPIO Source Mux
|
||||||
|
//------------------------------------
|
||||||
|
// Number of FP GPIO Pins
|
||||||
|
localparam FP_GPIO_WIDTH = 12;
|
||||||
|
|
||||||
|
// Bring FP GPIO controls into radio clk domain
|
||||||
|
synchronizer #(.WIDTH(24)) fp_gpio_sync (
|
||||||
|
.clk(radio_clk), .rst(radio_rst), .in(sr_fp_gpio_src), .out(fp_gpio_src)
|
||||||
|
);
|
||||||
|
|
||||||
|
// For each bit in the front-panel GPIO, mux the output and the direction
|
||||||
|
// control bit based on the fp_gpio_src register. The fp_gpio_src register
|
||||||
|
// holds 2 bits per GPIO pin, which selects which source to use for GPIO
|
||||||
|
// control. Currently, only daughter board 0 and daughter board 1 are
|
||||||
|
// supported.
|
||||||
|
for (i=0; i<FP_GPIO_WIDTH; i=i+1) begin : gen_fp_gpio_mux
|
||||||
|
always @(posedge radio_clk) begin
|
||||||
|
fp_gpio_out[i] <= fp_gpio_r_out[fp_gpio_src[2*i +: 2] == 0 ? 0 : 1][i];
|
||||||
|
fp_gpio_ddr[i] <= fp_gpio_r_ddr[fp_gpio_src[2*i +: 2] == 0 ? 0 : 1][i];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Front-panel GPIO inputs are routed to all daughter boards
|
||||||
|
for (i=0; i<NUM_DBOARDS; i=i+1) begin : gen_fp_gpio_inputs
|
||||||
|
assign fp_gpio_r_in[i] = fp_gpio_in;
|
||||||
|
end
|
||||||
|
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
// Radio to ADC,DAC and IO Mapping
|
// Radio to ADC,DAC and IO Mapping
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
@@ -653,11 +685,6 @@ module x300_core #(
|
|||||||
assign db0_gpio_ddr = db_gpio_ddr[0];
|
assign db0_gpio_ddr = db_gpio_ddr[0];
|
||||||
assign db1_gpio_ddr = db_gpio_ddr[1];
|
assign db1_gpio_ddr = db_gpio_ddr[1];
|
||||||
|
|
||||||
//Front-panel board GPIO
|
|
||||||
assign {fp_gpio_r_in[1], fp_gpio_r_in[0]} = {32'b0, fp_gpio_in};
|
|
||||||
assign fp_gpio_out = fp_gpio_r_out[0]; //fp_gpio_r_out[1] unused
|
|
||||||
assign fp_gpio_ddr = fp_gpio_r_ddr[0]; //fp_gpio_ddr[1] unused
|
|
||||||
|
|
||||||
//SPI
|
//SPI
|
||||||
assign {sen0, sclk0, mosi0} = {sen[0], sclk[0], mosi[0]};
|
assign {sen0, sclk0, mosi0} = {sen[0], sclk[0], mosi[0]};
|
||||||
assign miso[0] = miso0;
|
assign miso[0] = miso0;
|
||||||
|
|||||||
Reference in New Issue
Block a user