Porównaj commity

...

4 Commity

Autor SHA1 Wiadomość Data
matteo serva c7efd74bb9 merging changes from dev branch 2024-04-23 12:20:35 +02:00
matteo serva d0805f51c9 improved example tx code 2024-04-23 12:17:02 +02:00
matteo serva 461226602f updating fpga binary blob 2024-04-23 12:15:55 +02:00
matteo serva 788d08e6f4 firmware: using 16 bit buffers to simplify routing and use fpga resources more efficiently 2024-04-23 12:10:28 +02:00
14 zmienionych plików z 2914 dodań i 4806 usunięć

Wyświetl plik

@ -1,3 +1,20 @@
# MODIFIED CARIBOULITE
This is a non-official branch of cariboulite.
Features:
- performance upgrades
- transmission of arbitrary waveforms
The guide on how to use this version is in docs/notes/tutorial.txt
___
_
___
_
___
_
# CaribouLite
CaribouLite is an affordable, educational, open-source SDR evaluation platform and a HAT for the Raspberry-Pi family of boards (40-pin versions only). It is built for makers, hackers, and researchers and was designed to complement the current SDR (Software Defined Radio) eco-systems offering with a scalable, standalone dual-channel software-defined radio.

Wyświetl plik

@ -3,10 +3,12 @@ filename = top
pcf_file = ./io.pcf
SOURCES := $(wildcard *.v)
top.bin: $(SOURCES)
yosys -p 'synth_ice40 -abc2 -top top -json $(filename).json -blif $(filename).blif' -p 'opt' -p 'ice40_opt' -p 'fsm_opt' $(filename).v | grep -i warning
#nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc
false; while [ $$? != 0 ]; do nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 64 --opt-timing; done
#false; while [ $$? != 0 ]; do nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 64 --opt-timing; done
nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 80 --parallel-refine --opt-timing --seed 5
#nextpnr-ice40 --json blinky.json --pcf blinky.pcf --asc blinky.asc --gui
icepack $(filename).asc $(filename).bin

Wyświetl plik

@ -6,13 +6,13 @@ module lvds_rx (
input i_fifo_full,
output o_fifo_write_clk,
output o_fifo_push,
output reg [31:0] o_fifo_data,
output [15:0] o_fifo_data,
input i_sync_input,
output [ 1:0] o_debug_state
);
// Internal FSM States
localparam state_idle = 2'b00, state_i_phase = 2'b01, state_q_phase = 2'b11;
localparam state_idle = 2'b00, state_i_phase = 2'b01, state_q_sync = 2'b10, state_q_phase = 2'b11;
// Modem sync symbols
localparam modem_i_sync = 2'b10, modem_q_sync = 2'b01;
@ -34,52 +34,64 @@ module lvds_rx (
assign o_fifo_write_clk = i_ddr_clk;
assign o_debug_state = r_state_if;
reg [35:0] r_fifo_data;
always @(posedge i_ddr_clk) begin
r_fifo_data <= {r_fifo_data[33:0], i_ddr_data};;
end
assign o_fifo_data = r_fifo_data[19:4];
reg fifo_push2;
// Main Process
always @(posedge i_ddr_clk or negedge i_rst_b) begin
if (i_rst_b == 1'b0) begin
r_state_if <= state_idle;
r_fifo_push <= 1'b0;
r_phase_count <= 3'b111;
r_phase_count <= 3'b000;
r_sync_input <= 1'b0;
fifo_push2 <= 1'b0;
end else begin
r_phase_count <= r_phase_count + 1;
case (r_state_if)
state_idle: begin
if (i_ddr_data == modem_i_sync) begin
if (r_fifo_data[1:0] == modem_i_sync) begin
r_state_if <= state_i_phase;
o_fifo_data <= {30'b000000000000000000000000000000, i_ddr_data};
r_sync_input <= i_sync_input; // mark the sync input for this sample
end
r_phase_count <= 3'b111;
end
r_phase_count <= 3'b001;
r_fifo_push <= 1'b0;
if(fifo_push2) begin
r_fifo_push <= 1'b1;
fifo_push2 <= 1'b0;
end
end
state_i_phase: begin
if (r_phase_count == 3'b000) begin
if (i_ddr_data == modem_q_sync) begin
r_phase_count <= 3'b110;
r_state_if <= state_q_phase;
end else begin
r_state_if <= state_idle;
end
end else begin
r_phase_count <= r_phase_count - 1;
if (r_phase_count == 3'b111) begin
r_state_if <= state_q_sync;
end
r_fifo_push <= 1'b0;
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data};
end
state_q_phase: begin
if (r_phase_count == 3'b000) begin
r_fifo_push <= ~i_fifo_full;
r_state_if <= state_idle;
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data[1], r_sync_input};
state_q_sync: begin
if (r_fifo_data[1:0] == modem_q_sync) begin
r_state_if <= state_q_phase;
r_fifo_push <= ~i_fifo_full;
fifo_push2 <= ~i_fifo_full;
end else begin
r_fifo_push <= 1'b0;
r_phase_count <= r_phase_count - 1;
o_fifo_data <= {o_fifo_data[29:0], i_ddr_data};
r_state_if <= state_idle;
end
end
state_q_phase: begin
if (r_phase_count == 3'b111) begin
r_state_if <= state_idle;
end
r_fifo_push <= 1'b0;
end
endcase
end

Wyświetl plik

@ -14,7 +14,7 @@ module lvds_tx (
input i_fifo_empty,
output o_fifo_read_clk,
output o_fifo_pull,
input [31:0] i_fifo_data,
input [15:0] i_fifo_data,
input [3:0] i_sample_gap,
input i_tx_state,
input i_sync_input,
@ -28,8 +28,10 @@ module lvds_tx (
// STATES and PARAMS
localparam
tx_state_init = 4'b0000,
tx_state_sync = 4'b0001,
tx_state_pretx = 4'b0010,
tx_state_tx = 4'b0100,
tx_state_debugtx = 4'b1000;
localparam sync_duration_frames = 8'd10; // at least 2.5usec
@ -116,14 +118,18 @@ module lvds_tx (
// SYNC AND MANAGEMENT
always @(posedge i_ddr_clk) begin
if (lvds_ready_syncd == 1'b0) begin
r_state <= tx_state_sync;
r_pulled <= !i_fifo_empty;
r_state <= tx_state_init;
r_pulled <= 1'b0;
r_fifo_data <= zero_frame;
r_sync_count <= 8'd200;
end else begin
r_pulled <= 1'b0;
case (r_state)
tx_state_init:
if( !i_fifo_empty) begin
r_pulled <= i_fifo_data[0];
r_state <= tx_state_sync;
end
tx_state_sync:
begin
r_fifo_data <= zero_frame;
@ -141,10 +147,16 @@ module lvds_tx (
tx_state_pretx:
begin
r_state <= tx_state_debugtx;
r_sync_count <= {4'd0,i_sample_gap};
r_fifo_data <= ( {2'b00, i_fifo_data[31:2]} & data_mask) | (sync_frame);
r_state <= tx_state_tx;
r_fifo_data[31:16] <= ({2'b00, i_fifo_data[15:2]} & data_mask[31:16]) | (sync_frame[31:16]);
r_pulled <= 1'b1;
end
tx_state_tx:
begin
r_state <= tx_state_debugtx;
r_fifo_data[15:0] <= ({2'b00, i_fifo_data[15:2]} & data_mask[15:0]) | (sync_frame[15:0]);
r_pulled <= 1'b0;
end
tx_state_debugtx:
@ -154,7 +166,7 @@ module lvds_tx (
if (w_data_sbe_ddr) begin
r_state <= tx_state_sync;
end
r_sync_count <= {4'd0,i_sample_gap};
end

Wyświetl plik

@ -12,11 +12,11 @@ module smi_ctrl
// FIFO INTERFACE
output o_rx_fifo_pull,
input [31:0] i_rx_fifo_pulled_data,
input [15:0] i_rx_fifo_pulled_data,
input i_rx_fifo_empty,
output o_tx_fifo_push,
output reg [31:0] o_tx_fifo_pushed_data,
output reg [15:0] o_tx_fifo_pushed_data,
input i_tx_fifo_full,
output o_tx_fifo_clock,
@ -111,6 +111,7 @@ module smi_ctrl
reg [7:0] r_smi_test_count;
reg r_fifo_pull;
reg r_fifo_pull_1;
reg r_fifo_pull_2;
reg w_fifo_pull_trigger;
reg r_channel;
reg r_dir;
@ -119,8 +120,10 @@ module smi_ctrl
wire soe_and_reset;
assign soe_and_reset = i_rst_b & i_smi_soe_se;
assign o_smi_read_req = (!i_rx_fifo_empty) || i_smi_test;
assign o_rx_fifo_pull = !r_fifo_pull_1 && r_fifo_pull && !i_rx_fifo_empty;
assign o_rx_fifo_pull = (r_fifo_pull_1 ^ r_fifo_pull) && !i_rx_fifo_empty;
reg [7:0] r_rx_fifo_pulled_data;
always @(negedge soe_and_reset)
begin
if (i_rst_b == 1'b0) begin
@ -129,9 +132,31 @@ module smi_ctrl
r_fifo_pulled_data <= 32'h00000000;
end else begin
w_fifo_pull_trigger <= (int_cnt_rx == 5'd24) && !i_smi_test;
int_cnt_rx <= int_cnt_rx + 8;
o_smi_data_out <= i_rx_fifo_pulled_data[int_cnt_rx+7:int_cnt_rx];
case (int_cnt_rx[1:0])
2'b00: begin
o_smi_data_out <= i_rx_fifo_pulled_data[7:0];
w_fifo_pull_trigger <= 1'b1;
r_rx_fifo_pulled_data <= i_rx_fifo_pulled_data[15:8];
end
2'b01: begin
o_smi_data_out <= r_rx_fifo_pulled_data;
end
2'b10: begin
o_smi_data_out <= i_rx_fifo_pulled_data[7:0];
w_fifo_pull_trigger <= 1'b0;
r_rx_fifo_pulled_data <= i_rx_fifo_pulled_data[15:8];
end
default: begin
o_smi_data_out <= r_rx_fifo_pulled_data;
end
endcase
int_cnt_rx <= int_cnt_rx + 1;
@ -143,9 +168,11 @@ module smi_ctrl
if (i_rst_b == 1'b0) begin
r_fifo_pull <= 1'b0;
r_fifo_pull_1 <= 1'b0;
end else begin
r_fifo_pull <= w_fifo_pull_trigger;
r_fifo_pull_1 <= r_fifo_pull;
r_fifo_pull_2 <= r_fifo_pull_1;
end
end
@ -159,7 +186,7 @@ module smi_ctrl
tx_state_fourth = 2'b11;
reg [4:0] int_cnt_tx;
reg [31:0] r_fifo_pushed_data;
reg [7:0] r_fifo_pushed_data;
reg [1:0] tx_reg_state;
reg modem_tx_ctrl;
reg cond_tx_ctrl;
@ -169,7 +196,7 @@ module smi_ctrl
wire swe_and_reset;
assign o_smi_write_req = !i_tx_fifo_full;
assign o_tx_fifo_push = !r_fifo_push_1 && r_fifo_push && !i_tx_fifo_full;
assign o_tx_fifo_push = (r_fifo_push_1 ^ r_fifo_push) && !i_tx_fifo_full;
assign swe_and_reset = i_rst_b & i_smi_swe_srw;
assign o_tx_fifo_clock = i_sys_clk;
@ -192,7 +219,6 @@ module smi_ctrl
modem_tx_ctrl <= i_smi_data_in[6];
cond_tx_ctrl <= i_smi_data_in[5];
tx_reg_state <= tx_state_second;
w_fifo_push_trigger <= 1'b0;
end else begin
// if from some reason we are in the first byte stage and we got
// a byte without '1' on its MSB, that means that we are not synced
@ -205,32 +231,31 @@ module smi_ctrl
tx_state_second:
begin
r_fifo_pushed_data[15:8] <= i_smi_data_in[7:0];
o_tx_fifo_pushed_data <= {i_smi_data_in[7:0],r_fifo_pushed_data};
tx_reg_state <= tx_state_third;
w_fifo_push_trigger <= 1'b0;
w_fifo_push_trigger <= 1'b1;
end
//----------------------------------------------
tx_state_third:
begin
if (i_smi_data_in[0] == 1'b0) begin
r_fifo_pushed_data[23:16] <= i_smi_data_in[7:0];
r_fifo_pushed_data <= i_smi_data_in[7:0];
tx_reg_state <= tx_state_fourth;
end else begin
tx_reg_state <= tx_state_first;
w_fifo_push_trigger <= 1'b0;
end
w_fifo_push_trigger <= 1'b0;
end
//----------------------------------------------
tx_state_fourth:
begin
o_tx_fifo_pushed_data <= {i_smi_data_in[7:0],r_fifo_pushed_data[23:0] };
w_fifo_push_trigger <= 1'b1;
o_tx_fifo_pushed_data <= {i_smi_data_in[7:0],r_fifo_pushed_data};
w_fifo_push_trigger <= 1'b0;
o_cond_tx <= cond_tx_ctrl;
tx_reg_state <= tx_state_first;
tx_reg_state <= tx_state_first;
end
endcase
end
@ -247,4 +272,4 @@ module smi_ctrl
end
end
endmodule // smi_ctrl
endmodule // smi_ctrl

Wyświetl plik

@ -16,6 +16,7 @@ module sys_ctrl
output o_debug_smi_test,
output o_debug_loopback_tx,
output [3:0] o_tx_sample_gap,
output [7:0] o_tx_control_word,
);
// MODULE SPECIFIC IOC LIST
@ -26,7 +27,8 @@ module sys_ctrl
ioc_manu_id = 5'b00010, // read only
ioc_error_state = 5'b00011, // read only
ioc_debug_modes = 5'b00101, // write only
ioc_tx_sample_gap = 5'b00110; // read / write
ioc_tx_sample_gap = 5'b00110, // read / write
ioc_tx_control_word = 5'b00011; // read only
// MODULE SPECIFIC PARAMS
// ----------------------
@ -40,14 +42,15 @@ module sys_ctrl
reg debug_fifo_push;
reg debug_fifo_pull;
reg debug_smi_test;
reg debug_loopback_tx;
reg [3:0] tx_sample_gap;
reg debug_loopback_tx;
reg [3:0] tx_sample_gap;
reg [7:0] r_tx_control_word;
assign o_debug_fifo_push = debug_fifo_push;
assign o_debug_fifo_pull = debug_fifo_pull;
assign o_debug_smi_test = debug_smi_test;
assign o_tx_sample_gap = tx_sample_gap;
assign o_tx_sample_gap = tx_sample_gap;
assign o_tx_control_word = r_tx_control_word;
// MODULE MAIN PROCESS
// -------------------
always @(posedge i_sys_clk or negedge i_rst_b)
@ -59,6 +62,7 @@ module sys_ctrl
debug_smi_test <= 1'b0;
debug_loopback_tx <= 1'b0;
tx_sample_gap <= 4'd0;
r_tx_control_word <=8'd0;
end else if (i_cs == 1'b1) begin
//=============================================
// READ OPERATIONS
@ -91,9 +95,13 @@ module sys_ctrl
ioc_tx_sample_gap: begin
tx_sample_gap <= i_data_in[3:0];
end
ioc_tx_control_word: begin
r_tx_control_word <= i_data_in;
end
endcase
end
end
end
endmodule // sys_ctrl
endmodule // sys_ctrl

Wyświetl plik

@ -6,6 +6,11 @@
`include "lvds_tx.v"
`include "async_fifo_fwft.v"
`include "sync_fifo_fwft.v"
`include "samples_fifo_fwft.v"
`include "pin_holder.v"
`include "smi_rx.v"
module top (
input i_glob_clock,
input i_rst_b,
@ -104,7 +109,10 @@ module top (
wire [7:0] w_tx_data_sys;
wire [7:0] w_tx_data_io;
wire [7:0] w_tx_data_smi;
wire debug_led1;
wire [7:0] debug_word;
wire [7:0] w_tx_control_word;
//=========================================================================
// INSTANCES
//=========================================================================
@ -154,6 +162,7 @@ module top (
.o_debug_smi_test(),
.o_debug_loopback_tx(w_debug_lb_tx),
.o_tx_sample_gap(tx_sample_gap),
.o_tx_control_word(w_tx_control_word),
);
wire w_debug_fifo_push;
@ -200,7 +209,12 @@ module top (
//and requires global buffering. For example, a users logic-generated clock.
.USER_SIGNAL_TO_GLOBAL_BUFFER (r_counter),
.GLOBAL_BUFFER_OUTPUT ( w_clock_sys) );
/* sysclock_gen sysclock_gen_inst (
.clock_in (i_glob_clock),
.clock_out(w_clock_sys),
.locked(),
);*/
//=========================================================================
// CLOCK AND DATA-FLOW
//=========================================================================
@ -209,12 +223,17 @@ module top (
r_counter <= 1'b0;
end else begin
r_counter <= !r_counter;
end
end
always @(posedge w_clock_sys) begin
begin
case (w_cs)
4'b0001: r_tx_data <= w_tx_data_sys;
4'b0010: r_tx_data <= w_tx_data_io;
4'b0100: r_tx_data <= w_tx_data_smi;
4'b1000: r_tx_data <= 8'b10100101; // 0xA5: reserved
4'b1000: r_tx_data <= debug_word; // 0xA5: reserved
4'b0000: r_tx_data <= 8'b00000000; // no module selected
endcase
end
@ -339,11 +358,11 @@ module top (
// RX FIFO Internals
wire w_rx_09_fifo_write_clk;
wire w_rx_09_fifo_push;
wire [31:0] w_rx_09_fifo_data;
wire [15:0] w_rx_09_fifo_data;
wire w_rx_24_fifo_write_clk;
wire w_rx_24_fifo_push;
wire [31:0] w_rx_24_fifo_data;
wire [15:0] w_rx_24_fifo_data;
lvds_rx lvds_rx_09_inst (
.i_rst_b (i_rst_b),
@ -375,31 +394,53 @@ module top (
wire w_rx_fifo_write_clk = lvds_clock_buf; //(channel == 1'b0) ? w_rx_09_fifo_write_clk : w_rx_24_fifo_write_clk;
wire w_rx_fifo_push = (channel == 1'b0) ? w_rx_09_fifo_push : w_rx_24_fifo_push;
wire [31:0] w_rx_fifo_data = (channel == 1'b0) ? w_rx_09_fifo_data : w_rx_24_fifo_data;
wire [15:0] w_rx_fifo_data = (channel == 1'b0) ? w_rx_09_fifo_data : w_rx_24_fifo_data;
wire w_rx_fifo_pull;
wire [31:0] w_rx_fifo_pulled_data;
wire [15:0] w_rx_fifo_pulled_data;
wire w_rx_fifo_full;
wire w_rx_fifo_empty;
wire channel;
//assign channel = i_smi_a3;
async_fifo_fwft #(
.ADDR_WIDTH(8), // 1024 samples
wire [15:0] rxbuf_data;
wire rxbuf_full;
wire rxbuf_empty;
wire rxbuf_beat = (~rxbuf_full) & (~rxbuf_empty);
samples_fifo_fwft #(
.ADDR_WIDTH(11), // 1024 samples
.DATA_WIDTH(16), // 2x16 for I and Q
) rx_fifo (
.wr_rst_b_i(i_rst_b),
.wr_clk_i(w_rx_fifo_write_clk),
.wr_en_i(w_rx_fifo_push),
.wr_data_i(w_rx_fifo_data),
.full_o(w_rx_fifo_full),
.rd_rst_b_i(i_rst_b),
.rd_clk_i(w_clock_sys),
/* .rd_en_i(rxbuf_beat),
.rd_data_o(rxbuf_data),
.empty_o(rxbuf_empty),
);
sync_fifo_fwft #(
.ADDR_WIDTH(8), // 1024 samples
.DATA_WIDTH(16), // 2x16 for I and Q
) sys_rx_fifo (
.reset_n(i_rst_b),
.clk(w_clock_sys),
.wr_en_i(rxbuf_beat),
.wr_data_i(rxbuf_data),
.full_o(rxbuf_full),
*/
.rd_en_i(w_rx_fifo_pull),
.rd_data_o(w_rx_fifo_pulled_data),
.full_o(w_rx_fifo_full),
.empty_o(w_rx_fifo_empty),
.debug_pull(1'b0/*w_debug_fifo_pull*/),
.debug_push(1'b0/*w_debug_fifo_push*/)
.empty_o(w_rx_fifo_empty)
);
//=========================================================================
@ -420,9 +461,12 @@ module top (
.i_sample_gap(tx_sample_gap),
.i_tx_state(~w_smi_data_direction),
.i_sync_input(1'b0),
.i_debug_lb(w_debug_lb_tx),
.i_debug_lb(1'b1 /*w_debug_lb_tx*/),
.o_tx_state_bit(),
.o_sync_state_bit(),
.o_heartbeat(debug_led1),
.o_debug_word(debug_word),
.i_tx_control_word(w_tx_control_word),
);
wire w_tx_fifo_full;
@ -430,12 +474,12 @@ module top (
wire w_tx_fifo_read_clk;
wire w_tx_fifo_push;
wire w_tx_fifo_clock;
wire [31:0] w_tx_fifo_data;
wire [15:0] w_tx_fifo_data;
wire w_tx_fifo_pull;
wire [31:0] w_tx_fifo_pulled_data;
wire [15:0] w_tx_fifo_pulled_data;
async_fifo_fwft #(
.ADDR_WIDTH(8), // 1024 samples
samples_fifo_fwft #(
.ADDR_WIDTH(11), // 1024 samples
.DATA_WIDTH(16), // 2x16 for I and Q
) tx_fifo (
// smi clock is writing
@ -471,17 +515,17 @@ module top (
.i_rx_fifo_empty(w_rx_fifo_empty),
// FIFO TX
.o_tx_fifo_push(w_tx_fifo_push),
.o_tx_fifo_pushed_data(w_tx_fifo_data),
.i_tx_fifo_full(w_tx_fifo_full),
.o_tx_fifo_clock(w_tx_fifo_clock),
.o_tx_fifo_push(),
.o_tx_fifo_pushed_data(),
.i_tx_fifo_full(1'b1),
.o_tx_fifo_clock(),
.i_smi_soe_se(i_smi_soe_se),
.i_smi_swe_srw(i_smi_swe_srw),
.i_smi_swe_srw(1'b1),
.o_smi_data_out(w_smi_data_output),
.i_smi_data_in(w_smi_data_input),
.o_smi_read_req(w_smi_read_req),
.o_smi_write_req(w_smi_write_req),
.o_smi_write_req(),
.o_channel(channel),
.o_dir (control_smi_data_direction),
.i_smi_test(1'b0/*w_debug_smi_test*/),
@ -489,6 +533,21 @@ module top (
.o_address_error()
);
smi_rx smi_rx_ins (
.i_rst_b(i_rst_b),
.i_sys_clk(w_clock_sys),
// FIFO TX
.o_tx_fifo_push(w_tx_fifo_push),
.o_tx_fifo_pushed_data(w_tx_fifo_data),
.i_tx_fifo_full(w_tx_fifo_full),
.o_tx_fifo_clock(w_tx_fifo_clock),
.i_smi_swe_srw(i_smi_swe_srw),
.i_smi_data_in(w_smi_data_input),
.o_smi_write_req(w_smi_write_req),
);
wire [7:0] w_smi_data_output;
wire [7:0] w_smi_data_input;
wire w_smi_read_req;
@ -496,12 +555,10 @@ module top (
wire w_smi_data_direction;
wire w_smi_data_output_enable;
// the "Writing" flag indicates that the data[7:0] direction (inout)
// from the FPGA's SMI module should be "output". This happens when the
// SMI is in the READ mode - data flows from the FPGA to the RPI (RX mode)
// The address has the MSB '1' when in RX mode. otherwise (when IDLE or TX)
// the data is high-z, which is the more "recessive" mode
/*
* SMI I/O PINS
*/
assign w_smi_data_direction = i_smi_a2;
assign w_smi_data_output_enable = i_smi_a2 & !i_smi_soe_se;
@ -517,7 +574,7 @@ module top (
.D_OUT_0(w_smi_data_output[k]),
.D_IN_0(w_smi_data_input[k])
);
end
endgenerate
@ -538,7 +595,7 @@ module top (
.D_IN_0()
);
assign o_led0 = w_smi_data_direction;
assign o_led1 = channel;
assign o_led0 = control_smi_data_direction ^ debug_led1;
assign o_led1 = w_smi_data_direction;
endmodule // top

Wyświetl plik

@ -20,6 +20,7 @@
#define IOC_SYS_CTRL_SYS_SOFT_RST 4
#define IOC_SYS_CTRL_DEBUG_MODES 5
#define IOC_SYS_CTRL_SYS_TX_SAMPLE_GAP 6
#define IOC_SYS_CTRL_SYS_CTRL_WORD 3
#define IOC_IO_CTRL_MODE 1
#define IOC_IO_CTRL_DIG_PIN 2
@ -384,6 +385,21 @@ int caribou_fpga_get_errors (caribou_fpga_st* dev, uint8_t *err_map)
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), err_map);
}
int caribou_fpga_get_debug (caribou_fpga_st* dev, uint8_t *err_map)
{
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_get_errors");
CARIBOU_FPGA_CHECK_PTR_NOT_NULL(err_map,"caribou_fpga_get_errors","err_map");
caribou_fpga_opcode_st oc =
{
.rw = caribou_fpga_rw_read,
.mid = caribou_fpga_mid_res,
.ioc = IOC_SYS_CTRL_SYS_ERR_STAT
};
*err_map = 0;
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), err_map);
}
//--------------------------------------------------------------
int caribou_fpga_set_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t gap)
{
@ -397,6 +413,18 @@ int caribou_fpga_set_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t gap)
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &gap);
}
int caribou_fpga_set_sys_ctrl_tx_control_word (caribou_fpga_st* dev, uint8_t word)
{
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_sys_ctrl_tx_control_word");
caribou_fpga_opcode_st oc =
{
.rw = caribou_fpga_rw_write,
.mid = caribou_fpga_mid_sys_ctrl,
.ioc = IOC_SYS_CTRL_SYS_CTRL_WORD,
};
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &word);
}
//--------------------------------------------------------------
int caribou_fpga_get_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t *gap)
{

Wyświetl plik

@ -153,6 +153,7 @@ int caribou_fpga_set_debug_modes (caribou_fpga_st* dev, bool dbg_fifo_push, bool
int caribou_fpga_set_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t gap);
int caribou_fpga_get_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t *gap);
int caribou_fpga_set_sys_ctrl_tx_control_word (caribou_fpga_st* dev, uint8_t word);
// I/O Controller
int caribou_fpga_set_io_ctrl_mode (caribou_fpga_st* dev, uint8_t debug_mode, caribou_fpga_io_ctrl_rfm_en rfm);
@ -175,6 +176,8 @@ int caribou_fpga_get_smi_ctrl_fifo_status (caribou_fpga_st* dev, caribou_fpga_sm
int caribou_fpga_set_smi_channel (caribou_fpga_st* dev, caribou_fpga_smi_channel_en channel);
int caribou_fpga_set_smi_ctrl_data_direction (caribou_fpga_st* dev, uint8_t dir);
int caribou_fpga_get_debug (caribou_fpga_st* dev, uint8_t *err_map);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -25,6 +25,7 @@ static float sample_rate_middles[] = {3000, 1666, 1166, 900, 733, 583, 450};
static float rx_bandwidth_middles[] = {225, 281, 356, 450, 562, 706, 893, 1125, 1406, 1781, 2250};
static float tx_bandwidth_middles[] = {90, 112, 142, 180, 225, 282, 357, 450, 562, 712, 900};
int cariboulite_radio_set_modem_state(cariboulite_radio_state_st* radio, cariboulite_radio_state_cmd_en state);
void cariboulite_radio_debug(cariboulite_radio_state_st* radio)
{
@ -34,8 +35,8 @@ void cariboulite_radio_debug(cariboulite_radio_state_st* radio)
at86rf215_iq_interface_config_st cfg;
at86rf215_get_iq_if_cfg(&radio->sys->modem,&cfg,1);
uint8_t debug_word = 0;
//caribou_fpga_get_debug (&radio->sys->fpga, &debug_word);
uint8_t debug_word;
caribou_fpga_get_debug (&radio->sys->fpga, &debug_word);
printf("debug word vale %02X\n",(int)debug_word);
}
@ -1080,7 +1081,7 @@ static int cariboulite_radio_tx_prep(cariboulite_radio_state_st* radio)
int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
cariboulite_channel_dir_en dir,
bool activate)
{
{
int ret = 0;
radio->channel_direction = dir;
radio->active = activate;
@ -1088,6 +1089,7 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
ZF_LOGD("Activating channel %d, dir = %s, activate = %d", radio->type, radio->channel_direction==cariboulite_channel_dir_rx?"RX":"TX", activate);
// then deactivate the modem's stream
cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_trx_off);
@ -1163,8 +1165,9 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
.radio24_mode = at86rf215_iq_if_mode,
.clock_skew = at86rf215_iq_clock_data_skew_4_906ns,
};
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
// if its an LO frequency output from the mixer - no need for modem output
// LO applicable only to the channel with the mixer
if (radio->lo_output &&
@ -1195,7 +1198,7 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
1, 0x3F);
// transition to state TX
cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_tx);
//cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_tx);
}
else
{
@ -1212,11 +1215,21 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
// apply the state
caribou_smi_set_driver_streaming_state(&radio->sys->smi, smi_stream_tx_channel);
// ACTIVATION STEPS
//caribou_fpga_set_sys_ctrl_tx_control_word(&radio->sys->fpga, 0x0); // send zero frames to the radio
if(cariboulite_radio_tx_prep(radio))
{
return -1;
}
}
usleep(100); // wait at least tx_start_delay
caribou_fpga_set_sys_ctrl_tx_control_word(&radio->sys->fpga, 0x01);
}
}
return 0;

Wyświetl plik

@ -381,10 +381,17 @@ int main(int argc, char *argv[])
uint8_t* buffer = (uint8_t*) state.buffer;
for(int i = 0; i < len; i+=4)
{
buffer[i] = (sample_val>>9) & 0xff;
buffer[i+1] = (sample_val>>17) & 0xff;
buffer[i+2] = (sample_val>>9) & 0xff;
buffer[i+3] = (sample_val>>17) & 0xff;
uint32_t val = sample_val % 4;
val |= (val << 2);
val |= val << 4;
val |= val << 8;
val |= val << 16;
val = 0xAABB99cc;
uint32_t* dest = (uint32_t*) &buffer[i];
*dest = val;
sample_val = (sample_val + 1) % 4000001;
}
sample_val ++;