kopia lustrzana https://github.com/cariboulabs/cariboulite
update
rodzic
3d26dc2aea
commit
eee358d06a
Plik diff jest za duży
Load Diff
|
@ -34,6 +34,7 @@ set_frequency lvds_clock_buf 64
|
|||
|
||||
# CLOCK
|
||||
set_io i_glob_clock A29
|
||||
set_io i_rst_b A43
|
||||
|
||||
# PMOD
|
||||
set_io io_pmod[0] B24
|
||||
|
@ -80,7 +81,6 @@ set_io o_led1 A39
|
|||
# SMI TO RPI
|
||||
set_io o_smi_write_req A19
|
||||
set_io o_smi_read_req B19
|
||||
set_io i_smi_a1 A43
|
||||
set_io i_smi_a2 A48
|
||||
set_io i_smi_a3 A47
|
||||
|
||||
|
|
|
@ -48,18 +48,6 @@ module smi_ctrl ( input i_rst_b,
|
|||
localparam
|
||||
module_version = 8'b00000001;
|
||||
|
||||
// SMI ADDRESS DEFS
|
||||
// ----------------
|
||||
localparam
|
||||
smi_address_idle = 3'b000,
|
||||
smi_address_write_900 = 3'b001,
|
||||
smi_address_write_2400 = 3'b010,
|
||||
smi_address_write_res2 = 3'b011,
|
||||
smi_address_read_res1 = 3'b100,
|
||||
smi_address_read_900 = 3'b101,
|
||||
smi_address_read_2400 = 3'b110,
|
||||
smi_address_read_res = 3'b111;
|
||||
|
||||
always @(posedge i_sys_clk)
|
||||
begin
|
||||
if (i_rst_b == 1'b0) begin
|
||||
|
@ -114,7 +102,7 @@ module smi_ctrl ( input i_rst_b,
|
|||
w_fifo_09_pull_trigger <= (int_cnt_09 == 5'd7) && !i_smi_test;
|
||||
w_fifo_24_pull_trigger <= (int_cnt_24 == 5'd7) && !i_smi_test;
|
||||
|
||||
if (i_smi_a == smi_address_read_900) begin
|
||||
if (i_smi_a[2] == 1'b0) begin
|
||||
if ( i_smi_test ) begin
|
||||
o_smi_data_out <= r_smi_test_count_09;
|
||||
r_smi_test_count_09 <= {((r_smi_test_count_09[2] ^ r_smi_test_count_09[3]) & 1'b1), r_smi_test_count_09[7:1]};
|
||||
|
@ -123,7 +111,7 @@ module smi_ctrl ( input i_rst_b,
|
|||
o_smi_data_out <= i_fifo_09_pulled_data[int_cnt_09:int_cnt_09-7];
|
||||
end
|
||||
|
||||
end else if (i_smi_a == smi_address_read_2400) begin
|
||||
end else if (i_smi_a[2] == 1'b1) begin
|
||||
if ( i_smi_test ) begin
|
||||
o_smi_data_out <= r_smi_test_count_24;
|
||||
r_smi_test_count_24 <= {((r_smi_test_count_24[2] ^ r_smi_test_count_24[3]) & 1'b1), r_smi_test_count_24[7:1]};
|
||||
|
@ -157,6 +145,34 @@ module smi_ctrl ( input i_rst_b,
|
|||
|
||||
assign o_fifo_09_pull = !r_fifo_09_pull_1 && r_fifo_09_pull && !i_fifo_09_empty;
|
||||
assign o_fifo_24_pull = !r_fifo_24_pull_1 && r_fifo_24_pull && !i_fifo_24_empty;
|
||||
assign o_smi_writing = i_smi_a[2];
|
||||
|
||||
// SMI Addressing description
|
||||
// ==========================
|
||||
// In CaribouLite, the SMI addresses are connected as follows:
|
||||
//
|
||||
// RPI PIN | FPGA TOP-LEVEL SIGNAL
|
||||
// ------------------------------------------------------------------------
|
||||
// GPIO2_SA3 | i_smi_a[2] - RX09 / RX24 channel select
|
||||
// GPIO3_SA2 | i_smi_a[1] - Tx SMI (0) / Rx SMI (1) select
|
||||
// GPIO4_SA1 | i_smi_a[0] - used as a sys async reset (GBIN1)
|
||||
// GPIO5_SA0 | Not connected to FPGA (MixerRst)
|
||||
//
|
||||
// In order to perform SMI data bus direction selection (highZ / PushPull)
|
||||
// signal a[0] was chosen, while the '0' level (default) denotes RPI => FPGA
|
||||
// direction, and the DATA bus is highZ (recessive mode).
|
||||
// The signal a[2] selects the RX source (900 MHZ or 2.4GHz)
|
||||
// The signal a[1] can be used in the future for other purposes
|
||||
//
|
||||
// Description | a[2] | a[1] |
|
||||
// -------------|-----------|---------------|
|
||||
// | 0 | 0 |
|
||||
// TX |-----------| RPI => FPGA |
|
||||
// | 1 | Data HighZ |
|
||||
// -------------|-----------|---------------|
|
||||
// RX09 | 0 | 1 |
|
||||
// -------------|-----------| FPGA => RPI |
|
||||
// RX24 | 1 | Data PushPull |
|
||||
// -------------|-----------|---------------|
|
||||
assign o_smi_writing = i_smi_a[1];
|
||||
|
||||
endmodule // smi_ctrl
|
|
@ -10,7 +10,6 @@ module sys_ctrl
|
|||
input i_fetch_cmd,
|
||||
input i_load_cmd,
|
||||
|
||||
output reg o_soft_reset,
|
||||
input [7:0] i_error_list,
|
||||
|
||||
// controls output
|
||||
|
@ -26,7 +25,6 @@ module sys_ctrl
|
|||
ioc_system_version = 5'b00001, // read only
|
||||
ioc_manu_id = 5'b00010, // read only
|
||||
ioc_error_state = 5'b00011, // read only
|
||||
ioc_soft_reset = 5'b00100, // write only
|
||||
ioc_debug_modes = 5'b00101; // write only
|
||||
|
||||
// MODULE SPECIFIC PARAMS
|
||||
|
@ -74,14 +72,12 @@ module sys_ctrl
|
|||
//=============================================
|
||||
else if (i_load_cmd == 1'b1) begin
|
||||
case (i_ioc)
|
||||
//----------------------------------------------
|
||||
ioc_debug_modes: begin
|
||||
debug_fifo_push <= i_data_in[0];
|
||||
debug_fifo_pull <= i_data_in[1];
|
||||
debug_smi_test <= i_data_in[2];
|
||||
end
|
||||
//----------------------------------------------
|
||||
ioc_soft_reset: begin reset_cmd <= 1'b1; end
|
||||
//----------------------------------------------
|
||||
ioc_debug_modes: begin
|
||||
debug_fifo_push <= i_data_in[0];
|
||||
debug_fifo_pull <= i_data_in[1];
|
||||
debug_smi_test <= i_data_in[2];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin
|
||||
|
@ -89,21 +85,4 @@ module sys_ctrl
|
|||
end
|
||||
end
|
||||
|
||||
// Reset state process
|
||||
always @(posedge i_sys_clk)
|
||||
begin
|
||||
if (reset_cmd) begin
|
||||
reset_count <= 0;
|
||||
end else begin
|
||||
if (reset_count < 4'd15) begin
|
||||
reset_count <= reset_count + 1'b1;
|
||||
o_soft_reset <= 1'b0;
|
||||
end else if (reset_count == 4'd15) begin
|
||||
reset_count <= reset_count;
|
||||
o_soft_reset <= 1'b1;
|
||||
end else begin
|
||||
reset_count <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule // sys_ctrl
|
18932
firmware/top.asc
18932
firmware/top.asc
Plik diff jest za duży
Load Diff
BIN
firmware/top.bin
BIN
firmware/top.bin
Plik binarny nie jest wyświetlany.
3880
firmware/top.blif
3880
firmware/top.blif
Plik diff jest za duży
Load Diff
17168
firmware/top.json
17168
firmware/top.json
Plik diff jest za duży
Load Diff
|
@ -6,7 +6,8 @@
|
|||
`include "complex_fifo.v"
|
||||
|
||||
module top( input i_glob_clock,
|
||||
|
||||
input i_rst_b,
|
||||
|
||||
// RF FRONT-END PATH
|
||||
output o_rx_h_tx_l,
|
||||
output o_rx_h_tx_l_b,
|
||||
|
@ -41,8 +42,33 @@ module top( input i_glob_clock,
|
|||
output o_led0,
|
||||
output o_led1,
|
||||
|
||||
// SMI TO RPI
|
||||
input i_smi_a1,
|
||||
// SMI Addressing description
|
||||
// ==========================
|
||||
// In CaribouLite, the SMI addresses are connected as follows:
|
||||
//
|
||||
// RPI PIN | FPGA TOP-LEVEL SIGNAL
|
||||
// ------------------------------------------------------------------------
|
||||
// GPIO2_SA3 | i_smi_a[2] - RX09 / RX24 channel select
|
||||
// GPIO3_SA2 | i_smi_a[1] - Tx SMI (0) / Rx SMI (1) select
|
||||
// GPIO4_SA1 | i_smi_a[0] - used as a sys async reset (GBIN1)
|
||||
// GPIO5_SA0 | Not connected to FPGA (MixerRst)
|
||||
//
|
||||
// In order to perform SMI data bus direction selection (highZ / PushPull)
|
||||
// signal a[0] was chosen, while the '0' level (default) denotes RPI => FPGA
|
||||
// direction, and the DATA bus is highZ (recessive mode).
|
||||
// The signal a[2] selects the RX source (900 MHZ or 2.4GHz)
|
||||
// The signal a[1] can be used in the future for other purposes
|
||||
//
|
||||
// Description | a[2] | a[1] |
|
||||
// -------------|-----------|---------------|
|
||||
// | 0 | 0 |
|
||||
// TX |-----------| RPI => FPGA |
|
||||
// | 1 | Data HighZ |
|
||||
// -------------|-----------|---------------|
|
||||
// RX09 | 0 | 1 |
|
||||
// -------------|-----------| FPGA => RPI |
|
||||
// RX24 | 1 | Data PushPull |
|
||||
// -------------|-----------|---------------|
|
||||
input i_smi_a2,
|
||||
input i_smi_a3,
|
||||
|
||||
|
@ -71,21 +97,11 @@ module top( input i_glob_clock,
|
|||
wire [3:0] w_cs;
|
||||
wire w_fetch;
|
||||
wire w_load;
|
||||
reg r_reset;
|
||||
wire w_soft_reset;
|
||||
|
||||
wire [7:0] w_tx_data_sys;
|
||||
wire [7:0] w_tx_data_io;
|
||||
wire [7:0] w_tx_data_smi;
|
||||
|
||||
//=========================================================================
|
||||
// INITIAL STATE
|
||||
//=========================================================================
|
||||
initial begin
|
||||
r_counter = 1'b0;
|
||||
r_reset = 1'b1;
|
||||
end
|
||||
|
||||
//=========================================================================
|
||||
// INSTANCES
|
||||
//=========================================================================
|
||||
|
@ -93,7 +109,7 @@ module top( input i_glob_clock,
|
|||
// SPI
|
||||
spi_if spi_if_ins
|
||||
(
|
||||
.i_rst_b (w_soft_reset),
|
||||
.i_rst_b (i_rst_b),
|
||||
.i_sys_clk (w_clock_sys),
|
||||
.o_ioc (w_ioc),
|
||||
.o_data_in (w_rx_data),
|
||||
|
@ -115,7 +131,7 @@ module top( input i_glob_clock,
|
|||
// SYSTEM CTRL
|
||||
sys_ctrl sys_ctrl_ins
|
||||
(
|
||||
.i_rst_b (r_reset),
|
||||
.i_rst_b (i_rst_b),
|
||||
.i_sys_clk (w_clock_sys),
|
||||
.i_ioc (w_ioc),
|
||||
.i_data_in (w_rx_data),
|
||||
|
@ -123,7 +139,6 @@ module top( input i_glob_clock,
|
|||
.i_cs (w_cs[0]),
|
||||
.i_fetch_cmd (w_fetch),
|
||||
.i_load_cmd (w_load),
|
||||
.o_soft_reset (w_soft_reset),
|
||||
|
||||
.i_error_list ({o_address_error, 7'b0000000}),
|
||||
.o_debug_fifo_push (w_debug_fifo_push),
|
||||
|
@ -138,7 +153,7 @@ module top( input i_glob_clock,
|
|||
// IO CTRL
|
||||
io_ctrl io_ctrl_ins
|
||||
(
|
||||
.i_rst_b (w_soft_reset),
|
||||
.i_rst_b (i_rst_b),
|
||||
.i_sys_clk (w_clock_sys),
|
||||
.i_ioc (w_ioc),
|
||||
.i_data_in (w_rx_data),
|
||||
|
@ -173,15 +188,19 @@ module top( input i_glob_clock,
|
|||
|
||||
always @(posedge i_glob_clock)
|
||||
begin
|
||||
r_counter <= !r_counter;
|
||||
if (i_rst_b == 1'b0) begin
|
||||
r_counter <= 1'b0;
|
||||
end else begin
|
||||
r_counter <= !r_counter;
|
||||
|
||||
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'b0000: r_tx_data <= 8'b00000000; // no module selected
|
||||
endcase
|
||||
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'b0000: r_tx_data <= 8'b00000000; // no module selected
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//=========================================================================
|
||||
|
@ -250,7 +269,7 @@ module top( input i_glob_clock,
|
|||
|
||||
lvds_rx lvds_rx_09_inst
|
||||
(
|
||||
.i_rst_b (w_soft_reset),
|
||||
.i_rst_b (i_rst_b),
|
||||
.i_ddr_clk (lvds_clock_buf),
|
||||
|
||||
.i_ddr_data ({w_lvds_rx_09_d1, w_lvds_rx_09_d0}),
|
||||
|
@ -268,7 +287,7 @@ module top( input i_glob_clock,
|
|||
|
||||
lvds_rx lvds_rx_24_inst
|
||||
(
|
||||
.i_rst_b (w_soft_reset),
|
||||
.i_rst_b (i_rst_b),
|
||||
.i_ddr_clk (lvds_clock_buf),
|
||||
|
||||
.i_ddr_data ({!w_lvds_rx_24_d1, !w_lvds_rx_24_d0}),
|
||||
|
@ -285,11 +304,11 @@ module top( input i_glob_clock,
|
|||
);
|
||||
|
||||
complex_fifo rx_09_fifo(
|
||||
.wr_rst_b_i (w_soft_reset),
|
||||
.wr_rst_b_i (i_rst_b),
|
||||
.wr_clk_i (w_rx_09_fifo_write_clk),
|
||||
.wr_en_i (w_rx_09_fifo_push),
|
||||
.wr_data_i (w_rx_09_fifo_data),
|
||||
.rd_rst_b_i (w_soft_reset),
|
||||
.rd_rst_b_i (i_rst_b),
|
||||
.rd_clk_i (w_clock_sys),
|
||||
.rd_en_i (w_rx_09_fifo_pull),
|
||||
.rd_data_o (w_rx_09_fifo_pulled_data),
|
||||
|
@ -300,11 +319,11 @@ module top( input i_glob_clock,
|
|||
);
|
||||
|
||||
complex_fifo rx_24_fifo(
|
||||
.wr_rst_b_i (w_soft_reset),
|
||||
.wr_rst_b_i (i_rst_b),
|
||||
.wr_clk_i (w_rx_24_fifo_write_clk),
|
||||
.wr_en_i (w_rx_24_fifo_push),
|
||||
.wr_data_i (w_rx_24_fifo_data),
|
||||
.rd_rst_b_i (w_soft_reset),
|
||||
.rd_rst_b_i (i_rst_b),
|
||||
.rd_clk_i (w_clock_sys),
|
||||
.rd_en_i (w_rx_24_fifo_pull),
|
||||
.rd_data_o (w_rx_24_fifo_pulled_data),
|
||||
|
@ -316,7 +335,7 @@ module top( input i_glob_clock,
|
|||
|
||||
smi_ctrl smi_ctrl_ins
|
||||
(
|
||||
.i_rst_b (w_soft_reset),
|
||||
.i_rst_b (i_rst_b),
|
||||
.i_sys_clk (w_clock_sys),
|
||||
.i_fast_clk (i_glob_clock),
|
||||
.i_ioc (w_ioc),
|
||||
|
|
|
@ -17,15 +17,15 @@ extern "C" {
|
|||
|
||||
/*
|
||||
* Time tagging of the module through the 'struct tm' structure
|
||||
* Date: 2022-11-21
|
||||
* Time: 23:30:06
|
||||
* Date: 2022-12-12
|
||||
* Time: 14:33:16
|
||||
*/
|
||||
struct tm cariboulite_dtbo_date_time = {
|
||||
.tm_sec = 6,
|
||||
.tm_min = 30,
|
||||
.tm_hour = 23,
|
||||
.tm_mday = 21,
|
||||
.tm_mon = 10, /* +1 */
|
||||
.tm_sec = 16,
|
||||
.tm_min = 33,
|
||||
.tm_hour = 14,
|
||||
.tm_mday = 12,
|
||||
.tm_mon = 11, /* +1 */
|
||||
.tm_year = 122, /* +1900 */
|
||||
};
|
||||
|
||||
|
|
|
@ -25,15 +25,15 @@
|
|||
smi_pins: smi_pins {
|
||||
/* Don't configure the top two address bits, as these are already used as ID_SD and ID_SC */
|
||||
/*brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25>; <= original */
|
||||
brcm,pins = <2 3 4 6 7 8 9 10 11 12 13 14 15 24 25>;
|
||||
brcm,pins = <2 3 6 7 8 9 10 11 12 13 14 15 24 25>;
|
||||
|
||||
/* Alt 1: SMI */
|
||||
/*brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5>; <= original */
|
||||
brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5 5>;
|
||||
brcm,function = <5 5 5 5 5 5 5 5 5 5 5 5 5 5>;
|
||||
|
||||
/* /CS, /WE and /OE are pulled high, as they are generally active low signals */
|
||||
/*brcm,pull = <2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>; <= original */
|
||||
brcm,pull = <2 2 2 2 2 0 0 0 0 0 0 0 0 0 0>;
|
||||
brcm,pull = <2 2 2 2 0 0 0 0 0 0 0 0 0 0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -115,10 +115,10 @@ int caribou_fpga_init(caribou_fpga_st* dev, io_utils_spi_st* io_spi)
|
|||
ZF_LOGI("configuring reset and irq pins");
|
||||
// Configure GPIO pins
|
||||
io_utils_setup_gpio(dev->reset_pin, io_utils_dir_output, io_utils_pull_up);
|
||||
io_utils_setup_gpio(dev->irq_pin, io_utils_dir_input, io_utils_pull_up);
|
||||
|
||||
io_utils_setup_gpio(dev->soft_reset_pin, io_utils_dir_output, io_utils_pull_up);
|
||||
|
||||
// set to known state
|
||||
//io_utils_write_gpio(dev->reset_pin, 1);
|
||||
io_utils_write_gpio(dev->soft_reset_pin, 1);
|
||||
|
||||
ZF_LOGI("Initializing io_utils_spi");
|
||||
io_utils_hard_spi_st hard_dev_fpga = { .spi_dev_id = dev->spi_dev,
|
||||
|
@ -127,15 +127,6 @@ int caribou_fpga_init(caribou_fpga_st* dev, io_utils_spi_st* io_spi)
|
|||
io_utils_spi_chip_type_fpga_comm,
|
||||
&hard_dev_fpga);
|
||||
|
||||
if (io_utils_setup_interrupt(dev->irq_pin, caribou_fpga_interrupt_handler, dev) < 0)
|
||||
{
|
||||
ZF_LOGE("interrupt registration for irq_pin (%d) failed", dev->irq_pin);
|
||||
io_utils_setup_gpio(dev->reset_pin, io_utils_dir_input, io_utils_pull_up);
|
||||
io_utils_setup_gpio(dev->irq_pin, io_utils_dir_input, io_utils_pull_up);
|
||||
io_utils_spi_remove_chip(dev->io_spi, dev->io_spi_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Init FPGA programming
|
||||
if (caribou_prog_init(&dev->prog_dev, dev->io_spi) < 0)
|
||||
{
|
||||
|
@ -241,15 +232,10 @@ int caribou_fpga_close(caribou_fpga_st* dev)
|
|||
int caribou_fpga_soft_reset(caribou_fpga_st* dev)
|
||||
{
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_soft_reset");
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_write,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_SYS_SOFT_RST
|
||||
};
|
||||
|
||||
uint8_t res = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &res);
|
||||
io_utils_write_gpio_with_wait(dev->soft_reset_pin, 0, 1000);
|
||||
io_utils_write_gpio_with_wait(dev->soft_reset_pin, 1, 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -304,7 +290,6 @@ int caribou_fpga_get_versions (caribou_fpga_st* dev, caribou_fpga_versions_st* v
|
|||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_set_debug_modes (caribou_fpga_st* dev, bool dbg_fifo_push, bool dbg_fifo_pull, bool dbg_smi)
|
||||
{
|
||||
|
|
|
@ -98,7 +98,7 @@ typedef struct
|
|||
{
|
||||
// pinout
|
||||
int reset_pin;
|
||||
int irq_pin;
|
||||
int soft_reset_pin;
|
||||
int cs_pin;
|
||||
|
||||
// spi device
|
||||
|
|
|
@ -10,7 +10,7 @@ include_directories(/.)
|
|||
include_directories(${SUPER_DIR})
|
||||
|
||||
# allows for wildcard additions:
|
||||
set(SOURCES_LIB caribou_smi.c utils.c caribou_smi_modules.c)
|
||||
set(SOURCES_LIB caribou_smi.c smi_stream.c utils.c caribou_smi_modules.c)
|
||||
set(SOURCES ${SOURCES_LIB} test_caribou_smi.c)
|
||||
set(EXTERN_LIBS ${SUPER_DIR}/io_utils/build/libio_utils.a ${SUPER_DIR}/zf_log/build/libzf_log.a -lpthread)
|
||||
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-missing-braces -Wno-unused-function -O3)
|
||||
|
|
|
@ -47,46 +47,6 @@ static void caribou_smi_setup_settings (caribou_smi_st* dev, struct smi_settings
|
|||
static int caribou_smi_init_stream(caribou_smi_st* dev, caribou_smi_stream_type_en type, caribou_smi_channel_en ch);
|
||||
|
||||
|
||||
#define TIMING_PERF_SYNC (0)
|
||||
|
||||
#if (TIMING_PERF_SYNC)
|
||||
#define TIMING_PERF_SYNC_VARS \
|
||||
struct timeval tv_pre = {0}; \
|
||||
struct timeval tv_post = {0}; \
|
||||
long long total_samples = 0,last_total_samples = 0; \
|
||||
double time_pre = 0, batch_time = 0, sample_rate = 0; \
|
||||
double time_post = 0, process_time = 0; \
|
||||
double temp_pre; \
|
||||
double num_samples = 0, num_samples_avg = 0;
|
||||
|
||||
#define TIMING_PERF_SYNC_TICK \
|
||||
gettimeofday(&tv_pre, NULL);
|
||||
|
||||
#define TIMING_PERF_SYNC_TOCK \
|
||||
gettimeofday(&tv_post, NULL); \
|
||||
num_samples = (double)(st->read_ret_value) / 4.0; \
|
||||
num_samples_avg = num_samples_avg*0.1 + num_samples*0.9; \
|
||||
temp_pre = tv_pre.tv_sec + ((double)(tv_pre.tv_usec)) / 1e6; \
|
||||
time_post = tv_post.tv_sec + ((double)(tv_post.tv_usec)) / 1e6; \
|
||||
batch_time = temp_pre - time_pre; \
|
||||
sample_rate = sample_rate*0.1 + (num_samples / batch_time) * 0.9; \
|
||||
process_time = process_time*0.1 + (time_post - temp_pre)*0.9; \
|
||||
time_pre = temp_pre; \
|
||||
total_samples += st->read_ret_value; \
|
||||
if ((total_samples - last_total_samples) > 4000000*4) \
|
||||
{ \
|
||||
last_total_samples = total_samples; \
|
||||
ZF_LOGD("sample_rate = %.2f SPS, process_time = %.2f usec" \
|
||||
", num_samples_avg = %.1f", \
|
||||
sample_rate, process_time * 1e6, num_samples_avg); \
|
||||
}
|
||||
#else
|
||||
#define TIMING_PERF_SYNC_VARS
|
||||
#define TIMING_PERF_SYNC_TICK
|
||||
#define TIMING_PERF_SYNC_TOCK
|
||||
#endif
|
||||
|
||||
|
||||
//=========================================================================
|
||||
char* caribou_smi_get_error_string(caribou_smi_error_en err)
|
||||
{
|
||||
|
@ -167,7 +127,8 @@ int caribou_smi_init(caribou_smi_st* dev, caribou_smi_error_callback error_cb, v
|
|||
|
||||
ZF_LOGD("Current SMI Settings:");
|
||||
caribou_smi_print_smi_settings(dev, &settings);
|
||||
|
||||
|
||||
// Debug options
|
||||
caribou_smi_set_debug_mode(dev, false, false, false);
|
||||
|
||||
// initialize streams (TODO: add error check)
|
||||
|
@ -279,13 +240,6 @@ again:
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
uint8_t caribou_smi_lfsr(uint8_t n)
|
||||
{
|
||||
uint8_t bit = ((n >> 2) ^ (n >> 3)) & 1;
|
||||
return (n >> 1) | (bit << 7);
|
||||
}
|
||||
|
||||
|
||||
double caribou_smi_analyze_data(uint8_t *buffer,
|
||||
size_t length_bytes,
|
||||
caribou_smi_sample_complex_int16* cmplx_vec,
|
||||
|
@ -314,10 +268,10 @@ double caribou_smi_analyze_data(uint8_t *buffer,
|
|||
//int last_error = -1;
|
||||
static double error_rate = 0;
|
||||
|
||||
//dump_hex(buffer, 12);
|
||||
//smi_utils_dump_hex(buffer, 12);
|
||||
for (size_t i = 0; i < length_bytes; i++)
|
||||
{
|
||||
if (buffer[i] != caribou_smi_lfsr(last_correct_byte) || buffer[i] == 0)
|
||||
if (buffer[i] != smi_utils_lfsr(last_correct_byte) || buffer[i] == 0)
|
||||
{
|
||||
if (first_error == -1) first_error = i;
|
||||
//last_error = i;
|
||||
|
@ -343,7 +297,7 @@ double caribou_smi_analyze_data(uint8_t *buffer,
|
|||
|
||||
if (pull_debug_mode || push_debug_mode)
|
||||
{
|
||||
//dump_hex(buffer, 64);
|
||||
//smi_utils_dump_hex(buffer, 64);
|
||||
uint32_t *values = (uint32_t*)buffer;
|
||||
uint32_t num_values = length_bytes / 4;
|
||||
static uint32_t error_accum_counter = 0;
|
||||
|
@ -371,11 +325,11 @@ double caribou_smi_analyze_data(uint8_t *buffer,
|
|||
|
||||
// check data offset
|
||||
unsigned int offs = 0;
|
||||
//dump_bin(buffer, 16);
|
||||
//smi_utils_dump_bin(buffer, 16);
|
||||
for (offs = 0; offs<8; offs++)
|
||||
{
|
||||
uint32_t s = __builtin_bswap32(*((uint32_t*)(&buffer[offs])));
|
||||
//print_bin(s);
|
||||
//smi_utils_print_bin(s);
|
||||
if ((s & 0xC001C000) == 0x80004000) break;
|
||||
//if ((s & 0xC000C000) == 0x80004000) break;
|
||||
}
|
||||
|
@ -421,7 +375,7 @@ void* caribou_smi_analyze_thread(void* arg)
|
|||
caribou_smi_channel_en ch = (caribou_smi_channel_en)(st->stream_id & 0x1);
|
||||
|
||||
ZF_LOGD("Entered SMI analysis thread id %lu, running = %d", tid, st->read_analysis_thread_running);
|
||||
set_realtime_priority(2);
|
||||
smi_utils_set_realtime_priority(2);
|
||||
|
||||
// ****************************************
|
||||
// MAIN LOOP
|
||||
|
@ -470,7 +424,7 @@ void* caribou_smi_thread(void *arg)
|
|||
caribou_smi_channel_en ch = (caribou_smi_channel_en)(st->stream_id & 0x1);
|
||||
|
||||
ZF_LOGD("Entered thread id %lu, running = %d, Perf-Verbosity = %d", tid, st->running, TIMING_PERF_SYNC);
|
||||
set_realtime_priority(0);
|
||||
smi_utils_set_realtime_priority(0);
|
||||
|
||||
// create the analysis thread and mutexes
|
||||
if (pthread_mutex_init(&st->read_analysis_lock, NULL) != 0)
|
||||
|
@ -596,7 +550,7 @@ int caribou_smi_setup_stream(caribou_smi_st* dev,
|
|||
caribou_smi_set_driver_streaming_state(dev, 0);
|
||||
|
||||
// allocate the buffer vector
|
||||
if (allocate_buffer_vec(&st->buffers, st->num_of_buffers, st->batch_length) != 0)
|
||||
if (smi_utils_allocate_buffer_vec(&st->buffers, st->num_of_buffers, st->batch_length) != 0)
|
||||
{
|
||||
ZF_LOGE("read buffer-vector allocation failed");
|
||||
return -1;
|
||||
|
@ -608,7 +562,7 @@ int caribou_smi_setup_stream(caribou_smi_st* dev,
|
|||
if (st->app_cmplx_vec == NULL)
|
||||
{
|
||||
ZF_LOGE("application complex buffer allocation failed");
|
||||
release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||
smi_utils_release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -617,7 +571,7 @@ int caribou_smi_setup_stream(caribou_smi_st* dev,
|
|||
if (st->app_meta_vec == NULL)
|
||||
{
|
||||
ZF_LOGE("application meta-data buffer allocation failed");
|
||||
release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||
smi_utils_release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||
free(st->app_cmplx_vec);
|
||||
return -1;
|
||||
}
|
||||
|
@ -634,7 +588,7 @@ int caribou_smi_setup_stream(caribou_smi_st* dev,
|
|||
if (ret != 0)
|
||||
{
|
||||
ZF_LOGE("read stream thread creation failed");
|
||||
release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||
smi_utils_release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||
free(st->app_cmplx_vec);
|
||||
free(st->app_meta_vec);
|
||||
st->buffers = NULL;
|
||||
|
@ -726,7 +680,7 @@ int caribou_smi_destroy_stream(caribou_smi_st* dev, int id)
|
|||
ZF_LOGE("Killed with pthread_cancel");
|
||||
}
|
||||
|
||||
release_buffer_vec(dev->streams[id].buffers, dev->streams[id].num_of_buffers, dev->streams[id].batch_length);
|
||||
smi_utils_release_buffer_vec(dev->streams[id].buffers, dev->streams[id].num_of_buffers, dev->streams[id].batch_length);
|
||||
free(dev->streams[id].app_cmplx_vec);
|
||||
free(dev->streams[id].app_meta_vec);
|
||||
|
||||
|
|
|
@ -57,14 +57,20 @@
|
|||
|
||||
#include "smi_stream_dev.h"
|
||||
|
||||
|
||||
#define FIFO_SIZE_MULTIPLIER 12
|
||||
#define FIFO_SIZE_MULTIPLIER (14)
|
||||
#define ADDR_DIR_OFFSET (2) // GPIO3_SA2 (fpga i_smi_a[1]) - Tx SMI (0) / Rx SMI (1) select
|
||||
#define ADDR_CH_OFFSET (3) // GPIO2_SA3 (fpga i_smi_a[2]) - RX09 / RX24 channel select
|
||||
|
||||
struct bcm2835_smi_dev_instance
|
||||
{
|
||||
struct device *dev;
|
||||
struct bcm2835_smi_instance *smi_inst;
|
||||
|
||||
// address related
|
||||
smi_stream_direction_en dir;
|
||||
smi_stream_channel_en channel;
|
||||
unsigned int cur_address;
|
||||
|
||||
struct task_struct *reader_thread;
|
||||
struct task_struct *writer_thread;
|
||||
struct kfifo rx_fifo;
|
||||
|
@ -101,8 +107,6 @@ static const char *const ioctl_names[] =
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
static void write_smi_reg(struct bcm2835_smi_instance *inst, u32 val, unsigned reg)
|
||||
{
|
||||
|
@ -115,6 +119,21 @@ static u32 read_smi_reg(struct bcm2835_smi_instance *inst, unsigned reg)
|
|||
return readl(inst->smi_regs_ptr + reg);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
static void set_address_direction(smi_stream_direction_en)
|
||||
{
|
||||
inst->cur_address &= ~(1<<ADDR_DIR_OFFSET)
|
||||
bcm2835_smi_get_address(inst->smi_inst, &cur_addr);
|
||||
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
static void set_address_channel(smi_stream_direction_en)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define BUSY_WAIT_WHILE_TIMEOUT(C,T,R) {int t = (T); while ((C) && t>0){t--;} (R)=t>0;}
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -51,6 +51,17 @@
|
|||
#define DRIVER_NAME "smi-stream-dev"
|
||||
#define DEVICE_MINOR 0
|
||||
|
||||
typedef enum
|
||||
{
|
||||
smi_stream_dir_smi_to_device = 0, // device data-bus is highZ
|
||||
smi_stream_dir_device_to_smi = 1, // device data-bus is push-pull
|
||||
} smi_stream_direction_en;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
smi_stream_channel_0 = 0, // channel 900 MHz (RX)
|
||||
smi_stream_channel_1 = 1, // channel 2400 MHz (RX)
|
||||
} smi_stream_channel_en;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
struct bcm2835_smi_instance {
|
||||
|
|
|
@ -22,6 +22,7 @@ extern "C" {
|
|||
|
||||
#include "zf_log/zf_log.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "smi_stream.h"
|
||||
|
||||
//=========================================================================
|
||||
|
@ -33,62 +34,228 @@ static int smi_stream_get_native_buffer_length(int filedesc)
|
|||
return len;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
static int smi_stream_set_address(int filedesc, int address)
|
||||
{
|
||||
int ret = ioctl(filedesc, BCM2835_SMI_IOC_ADDRESS, address);
|
||||
if (ret != 0)
|
||||
{
|
||||
ZF_LOGE("failed setting smi address (%d) to device", address);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
static int smi_stream_poll(smi_stream_st* st, uint32_t timeout_num_millisec, smi_stream_direction_en dir)
|
||||
{
|
||||
// Calculate the timeout
|
||||
struct timeval timeout = {0};
|
||||
int num_sec = timeout_num_millisec / 1000;
|
||||
timeout.tv_sec = num_sec;
|
||||
timeout.tv_usec = (timeout_num_millisec - num_sec * 1000) * 1000;
|
||||
|
||||
// Poll setting
|
||||
fd_set set;
|
||||
FD_ZERO(&set); // clear the set mask
|
||||
FD_SET(st->filedesc, &set); // add only our file descriptor to the set
|
||||
|
||||
again:
|
||||
int rv = 0;
|
||||
if (dir == smi_stream_dir_rx) rv = select(st->filedesc + 1, &set, NULL, NULL, &timeout);
|
||||
else if ((dir == smi_stream_dir_tx) rv = select(st->filedesc + 1, NULL, &set, NULL, &timeout);
|
||||
else return -1;
|
||||
|
||||
if(rv == -1)
|
||||
{
|
||||
int error = errno;
|
||||
switch(error)
|
||||
{
|
||||
case EBADF: // An invalid file descriptor was given in one of the sets.
|
||||
// (Perhaps a file descriptor that was already closed, or one on which an error has occurred.)
|
||||
ZF_LOGE("SMI filedesc select error - invalid file descriptor in one of the sets");
|
||||
break;
|
||||
case EINTR: // A signal was caught.
|
||||
ZF_LOGD("SMI filedesc select error - caught an interrupting signal");
|
||||
goto again;
|
||||
break;
|
||||
case EINVAL: // nfds is negative or the value contained within timeout is invalid.
|
||||
ZF_LOGE("SMI filedesc select error - nfds is negative or invalid timeout");
|
||||
break;
|
||||
case ENOMEM: // unable to allocate memory for internal tables.
|
||||
ZF_LOGE("SMI filedesc select error - internal tables allocation failed");
|
||||
break;
|
||||
default: break;
|
||||
};
|
||||
|
||||
return -1;
|
||||
}
|
||||
else if(rv == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return FD_ISSET(st->filedesc, &set);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
static int smi_stream_timeout_write(smi_stream_st* st,
|
||||
uint8_t* buffer,
|
||||
size_t len,
|
||||
uint32_t timeout_num_millisec)
|
||||
{
|
||||
// Set the address
|
||||
smi_stream_set_address(st->filedesc, st->stream_addr)
|
||||
|
||||
int res = smi_stream_poll(st, timeout_num_millisec, smi_stream_dir_tx);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
ZF_LOGD("select error");
|
||||
return -1;
|
||||
}
|
||||
else if (res == 0) // timeout
|
||||
{
|
||||
ZF_LOGD("smi write fd timeout");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return write(st->filedesc, buffer, len);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
static int smi_stream_timeout_read(smi_stream_st* st,
|
||||
uint8_t* buffer,
|
||||
size_t len,
|
||||
uint32_t timeout_num_millisec)
|
||||
{
|
||||
// Set the address
|
||||
smi_stream_set_address(st->filedesc, st->stream_addr)
|
||||
|
||||
int res = smi_stream_poll(st, timeout_num_millisec, smi_stream_dir_rx);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
ZF_LOGD("select error");
|
||||
return -1;
|
||||
}
|
||||
else if (res == 0) // timeout
|
||||
{
|
||||
ZF_LOGD("smi read fd timeout");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return read(st->filedesc, buffer, len);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
static void smi_stream_swap_buffers(smi_stream_st* st, smi_stream_direction_en dir)
|
||||
{
|
||||
uint8_t * temp = NULL;
|
||||
|
||||
if (dir == smi_stream_dir_rx)
|
||||
{
|
||||
temp = st->smi_read_point;
|
||||
st->smi_read_point = st->app_read_point;
|
||||
st->app_read_point = temp;
|
||||
}
|
||||
else if (dir == smi_stream_dir_rx)
|
||||
{
|
||||
temp = st->smi_write_point;
|
||||
st->smi_write_point = st->app_write_point;
|
||||
st->app_write_point = temp;
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
static void* smi_stream_reader_thread(void* arg)
|
||||
{
|
||||
int current_data_size = 0;
|
||||
smi_stream_st* st = (smi_stream_st*)arg;
|
||||
pthread_t tid = pthread_self();
|
||||
TIMING_PERF_SYNC_VARS;
|
||||
smi_utils_set_realtime_priority(2);
|
||||
|
||||
// performance
|
||||
struct timeval current_time = {0,0};
|
||||
|
||||
caribou_smi_stream_st* st = (caribou_smi_stream_st*)arg;
|
||||
caribou_smi_st* dev = (caribou_smi_st*)st->parent_dev;
|
||||
caribou_smi_stream_type_en type = (caribou_smi_stream_type_en)(st->stream_id>>1 & 0x1);
|
||||
caribou_smi_channel_en ch = (caribou_smi_channel_en)(st->stream_id & 0x1);
|
||||
|
||||
ZF_LOGD("Entered SMI analysis thread id %lu, running = %d", tid, st->read_analysis_thread_running);
|
||||
set_realtime_priority(2);
|
||||
ZF_LOGD("Entered SMI reader thread id %lu", tid);
|
||||
|
||||
// ****************************************
|
||||
// MAIN LOOP
|
||||
// ****************************************
|
||||
while (st->read_analysis_thread_running)
|
||||
while (st->active)
|
||||
{
|
||||
pthread_mutex_lock(&st->read_analysis_lock);
|
||||
TIMING_PERF_SYNC_TICK;
|
||||
if (!st->read_analysis_thread_running) break;
|
||||
|
||||
current_data_size = st->read_ret_value;
|
||||
//if (offset != 0) current_data_size -= 4;
|
||||
|
||||
dev-> rx_bitrate_mbps = caribou_smi_analyze_data(st->current_app_buffer,
|
||||
current_data_size,
|
||||
st->app_cmplx_vec,
|
||||
st->app_meta_vec,
|
||||
dev->smi_debug, dev->fifo_push_debug, dev->fifo_pull_debug);
|
||||
dev-> rx_bitrate_mbps /= 1e6;
|
||||
|
||||
if (st->data_cb) st->data_cb(dev->cb_context,
|
||||
st->service_context,
|
||||
type,
|
||||
caribou_smi_event_type_data,
|
||||
ch,
|
||||
current_data_size / 4,
|
||||
st->app_cmplx_vec,
|
||||
st->app_meta_vec,
|
||||
st->batch_length / 4);
|
||||
|
||||
TIMING_PERF_SYNC_TOCK;
|
||||
pthread_mutex_lock(&st->reader_lock);
|
||||
if (!st->active) break;
|
||||
|
||||
int ret = smi_stream_timeout_read(st, st->smi_read_point, st->buffer_length, 200);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (st->event_cb) dev->event_cb(st->stream_addr, smi_stream_error, NULL, st->context);
|
||||
break;
|
||||
}
|
||||
else if (ret == 0) // timeout
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Swap the buffers
|
||||
smi_stream_swap_buffers(st, smi_stream_dir_rx);
|
||||
|
||||
// Notify app
|
||||
if (st->data_cb) st->data_cb(st->stream_addr, smi_stream_dir_rx, st->app_read_point, ret, st->context);
|
||||
|
||||
// Performance
|
||||
st->rx_bitrate_mbps = smi_calculate_performance(ret, ¤t_time, st->rx_bitrate_mbps);
|
||||
}
|
||||
|
||||
ZF_LOGD("Leaving SMI analysis thread id %lu, running = %d", tid, st->read_analysis_thread_running);
|
||||
ZF_LOGD("Leaving SMI reader thread id %lu", tid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
static void* smi_stream_writer_thread(void* arg)
|
||||
{
|
||||
smi_stream_st* st = (smi_stream_st*)arg;
|
||||
pthread_t tid = pthread_self();
|
||||
smi_utils_set_realtime_priority(2);
|
||||
|
||||
return NULL;
|
||||
// performance
|
||||
struct timeval current_time = {0,0};
|
||||
|
||||
ZF_LOGD("Entered SMI writer thread id %lu", tid);
|
||||
|
||||
// ****************************************
|
||||
// MAIN LOOP
|
||||
// ****************************************
|
||||
while (st->active)
|
||||
{
|
||||
pthread_mutex_lock(&st->writer_lock);
|
||||
if (!st->active) break;
|
||||
|
||||
int ret = smi_stream_timeout_write(st, st->smi_write_point, st->buffer_length, 200);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (st->event_cb) dev->event_cb(st->stream_addr, smi_stream_error, NULL, st->context);
|
||||
break;
|
||||
}
|
||||
else if (ret == 0) // timeout
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Swap the buffers
|
||||
smi_stream_swap_buffers(st, smi_stream_dir_tx);
|
||||
|
||||
// Notify app
|
||||
if (st->data_cb) st->data_cb(st->stream_addr, smi_stream_dir_tx, st->app_read_point, ret, st->context);
|
||||
|
||||
// Performance
|
||||
st->tx_bitrate_mbps = smi_calculate_performance(ret, ¤t_time, st->tx_bitrate_mbps);
|
||||
}
|
||||
|
||||
ZF_LOGD("Leaving SMI writer thread id %lu", tid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
|
@ -120,17 +287,17 @@ int smi_stream_init(smi_stream_st* st,
|
|||
|
||||
// Buffers allocation
|
||||
// -------------------------------------------------------
|
||||
int buf_len = smi_stream_get_native_buffer_length(st->filedesc);
|
||||
if (buf_len < 0)
|
||||
st->buffer_length = smi_stream_get_native_buffer_length(st->filedesc);
|
||||
if (st->buffer_length < 0)
|
||||
{
|
||||
ZF_LOGE("Reading smi stream native buffer length failed, setting default");
|
||||
buf_len = DMA_BOUNCE_BUFFER_SIZE;
|
||||
st->buffer_length = DMA_BOUNCE_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
st->smi_read_buffers[i] = malloc(buf_len);
|
||||
st->smi_write_buffers[i] = malloc(buf_len);
|
||||
st->smi_read_buffers[i] = malloc(st->buffer_length);
|
||||
st->smi_write_buffers[i] = malloc(st->buffer_length);
|
||||
if (st->smi_read_buffers[i] == NULL || st->smi_write_buffers[i] == NULL)
|
||||
{
|
||||
ZF_LOGE("SMI stream allocation of buffers failed");
|
||||
|
@ -209,4 +376,3 @@ int smi_stream_release(smi_stream_st* st)
|
|||
st->initialized = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,17 @@ typedef enum
|
|||
smi_stream_event_type_start = 1,
|
||||
smi_stream_event_type_end = 2,
|
||||
smi_stream_released = 3,
|
||||
smi_stream_error = 4,
|
||||
} smi_stream_event_type_en;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
smi_stream_dir_rx = 0,
|
||||
smi_stream_dir_tx = 1,
|
||||
} smi_stream_direction_en;
|
||||
|
||||
typedef void (*smi_stream_data_callback)(int stream_addr,
|
||||
smi_stream_direction_en dir,
|
||||
uint8_t* data,
|
||||
size_t data_length,
|
||||
void* context);
|
||||
|
@ -37,6 +45,7 @@ typedef struct
|
|||
bool initialized; // is this stream initialized
|
||||
|
||||
// Buffers
|
||||
size_t buffer_length;
|
||||
uint8_t *smi_read_buffers[2];
|
||||
uint8_t *smi_read_point; // the buffer that is currently in the SMI DMA
|
||||
uint8_t *app_read_point; // the buffer that is currently analyzed / written by the application callback
|
||||
|
@ -45,6 +54,10 @@ typedef struct
|
|||
uint8_t *smi_write_point; // the buffer that is currently in the SMI DMA
|
||||
uint8_t *app_write_point; // the buffer that is currently analyzed / written by the application callback
|
||||
|
||||
// Performance
|
||||
float rx_bitrate_mbps;
|
||||
float tx_bitrate_mbps;
|
||||
|
||||
// Threads
|
||||
pthread_t reader_thread;
|
||||
pthread_mutex_t reader_lock;
|
||||
|
|
|
@ -152,7 +152,7 @@ int main_single_read()
|
|||
caribou_smi_init(&dev, caribou_smi_error_event, program_name);
|
||||
|
||||
caribou_smi_timeout_read(&dev, address, b8, read_count*sizeof(uint32_t), 1000);
|
||||
dump_hex(b8, read_count*sizeof(uint32_t));
|
||||
smi_utils_dump_hex(b8, read_count*sizeof(uint32_t));
|
||||
print_iq(buffer, read_count);
|
||||
caribou_smi_close (&dev);
|
||||
return 0;
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t lfsr(uint8_t n)
|
||||
{
|
||||
uint8_t bit = ((n >> 2) ^ (n >> 3)) & 1;
|
||||
return (n >> 1) | (bit << 7);
|
||||
}
|
||||
|
||||
int main1()
|
||||
{
|
||||
uint8_t b = 0;
|
||||
uint8_t vec[131072] = {0};
|
||||
for (int i = 0; i < 131072; i++)
|
||||
{
|
||||
vec[i] = b;
|
||||
b += 251;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < 131072; i++)
|
||||
{
|
||||
if (vec[i] != b)
|
||||
count ++;
|
||||
b += 251;
|
||||
}
|
||||
|
||||
printf("num errors %d\n", count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main2()
|
||||
{
|
||||
int b = 0x56;
|
||||
uint8_t vec[131072] = {0};
|
||||
for (int i = 0; i < 131072; i++)
|
||||
{
|
||||
vec[i] = b;
|
||||
b = lfsr(b);
|
||||
printf("%02X\n", b);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < 131072; i++)
|
||||
{
|
||||
if (vec[i] != b)
|
||||
count ++;
|
||||
|
||||
b = lfsr(b);
|
||||
}
|
||||
printf("num errors %d\n", count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
return main2();
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
|
||||
//=========================================================================
|
||||
void set_realtime_priority(int priority_deter)
|
||||
void smi_utils_set_realtime_priority(int priority_deter)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -57,7 +57,7 @@ void set_realtime_priority(int priority_deter)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
void dump_hex(const void* data, size_t size)
|
||||
void smi_utils_dump_hex(const void* data, size_t size)
|
||||
{
|
||||
char ascii[17];
|
||||
size_t i, j;
|
||||
|
@ -98,7 +98,7 @@ void dump_hex(const void* data, size_t size)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
void dump_bin(const uint8_t* data, size_t size)
|
||||
void smi_utils_dump_bin(const uint8_t* data, size_t size)
|
||||
{
|
||||
char str[16] = {0};
|
||||
|
||||
|
@ -119,7 +119,7 @@ void dump_bin(const uint8_t* data, size_t size)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
void print_bin(uint32_t v)
|
||||
void smi_utils_print_bin(uint32_t v)
|
||||
{
|
||||
char str[48] = {0};
|
||||
int i = 0;
|
||||
|
@ -133,7 +133,7 @@ void print_bin(uint32_t v)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
int allocate_buffer_vec(uint8_t*** mat, int num_buffers, int buffer_size)
|
||||
int smi_utils_allocate_buffer_vec(uint8_t*** mat, int num_buffers, int buffer_size)
|
||||
{
|
||||
ZF_LOGI("Allocating buffer vectors");
|
||||
(*mat) = (uint8_t**) malloc( num_buffers * sizeof(uint8_t*) );
|
||||
|
@ -172,7 +172,7 @@ int allocate_buffer_vec(uint8_t*** mat, int num_buffers, int buffer_size)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
void release_buffer_vec(uint8_t** mat, int num_buffers, int buffer_size)
|
||||
void smi_utils_release_buffer_vec(uint8_t** mat, int num_buffers, int buffer_size)
|
||||
{
|
||||
ZF_LOGI("Releasing buffer vectors");
|
||||
if (mat == NULL)
|
||||
|
@ -187,7 +187,7 @@ void release_buffer_vec(uint8_t** mat, int num_buffers, int buffer_size)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
int search_offset_in_buffer(uint8_t *buff, int len)
|
||||
int smi_utils_search_offset_in_buffer(uint8_t *buff, int len)
|
||||
{
|
||||
bool succ = false;
|
||||
int off = 0;
|
||||
|
@ -204,8 +204,22 @@ int search_offset_in_buffer(uint8_t *buff, int len)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
uint8_t caribou_smi_lfsr(uint8_t n)
|
||||
uint8_t smi_utils_lfsr(uint8_t n)
|
||||
{
|
||||
uint8_t bit = ((n >> 2) ^ (n >> 3)) & 1;
|
||||
return (n >> 1) | (bit << 7);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
double smi_calculate_performance(size_t bytes, struct timeval *old_time, double old_mbps)
|
||||
{
|
||||
struct timeval current_time = {0,0};
|
||||
|
||||
gettimeofday(¤t_time, NULL);
|
||||
|
||||
double elapsed_us = (current_time.tv_sec - old_time->tv_sec) + ((double)(current_time.tv_usec - old_time.tv_usec)) / 1000000.0;
|
||||
double speed_mbps = (double)(bytes * 8) / elapsed_us / 1e6;
|
||||
old_time->tv_sec = current_time.tv_sec;
|
||||
old_time->tv_usec = current_time.tv_usec;
|
||||
return old_mbps * 0.98 + speed_mbps * 0.02;
|
||||
}
|
||||
|
|
|
@ -8,13 +8,55 @@ extern "C" {
|
|||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void set_realtime_priority(int priority_deter);
|
||||
void dump_hex(const void* data, size_t size);
|
||||
void dump_bin(const uint8_t* data, size_t size);
|
||||
void print_bin(const uint32_t v);
|
||||
int allocate_buffer_vec(uint8_t*** mat, int num_buffers, int buffer_size);
|
||||
void release_buffer_vec(uint8_t** mat, int num_buffers, int buffer_size);
|
||||
int search_offset_in_buffer(uint8_t *buff, int len);
|
||||
#define TIMING_PERF_SYNC (0)
|
||||
|
||||
#if (TIMING_PERF_SYNC)
|
||||
#define TIMING_PERF_SYNC_VARS \
|
||||
struct timeval tv_pre = {0}; \
|
||||
struct timeval tv_post = {0}; \
|
||||
long long total_samples = 0,last_total_samples = 0; \
|
||||
double time_pre = 0, batch_time = 0, sample_rate = 0; \
|
||||
double time_post = 0, process_time = 0; \
|
||||
double temp_pre; \
|
||||
double num_samples = 0, num_samples_avg = 0;
|
||||
|
||||
#define TIMING_PERF_SYNC_TICK \
|
||||
gettimeofday(&tv_pre, NULL);
|
||||
|
||||
#define TIMING_PERF_SYNC_TOCK \
|
||||
gettimeofday(&tv_post, NULL); \
|
||||
num_samples = (double)(st->read_ret_value) / 4.0; \
|
||||
num_samples_avg = num_samples_avg*0.1 + num_samples*0.9; \
|
||||
temp_pre = tv_pre.tv_sec + ((double)(tv_pre.tv_usec)) / 1e6; \
|
||||
time_post = tv_post.tv_sec + ((double)(tv_post.tv_usec)) / 1e6; \
|
||||
batch_time = temp_pre - time_pre; \
|
||||
sample_rate = sample_rate*0.1 + (num_samples / batch_time) * 0.9; \
|
||||
process_time = process_time*0.1 + (time_post - temp_pre)*0.9; \
|
||||
time_pre = temp_pre; \
|
||||
total_samples += st->read_ret_value; \
|
||||
if ((total_samples - last_total_samples) > 4000000*4) \
|
||||
{ \
|
||||
last_total_samples = total_samples; \
|
||||
ZF_LOGD("sample_rate = %.2f SPS, process_time = %.2f usec" \
|
||||
", num_samples_avg = %.1f", \
|
||||
sample_rate, process_time * 1e6, num_samples_avg); \
|
||||
}
|
||||
#else
|
||||
#define TIMING_PERF_SYNC_VARS
|
||||
#define TIMING_PERF_SYNC_TICK
|
||||
#define TIMING_PERF_SYNC_TOCK
|
||||
#endif
|
||||
|
||||
|
||||
void smi_utils_set_realtime_priority(int priority_deter);
|
||||
void smi_utils_dump_hex(const void* data, size_t size);
|
||||
void smi_utils_dump_bin(const uint8_t* data, size_t size);
|
||||
void smi_utils_print_bin(const uint32_t v);
|
||||
int smi_utils_allocate_buffer_vec(uint8_t*** mat, int num_buffers, int buffer_size);
|
||||
void smi_utils_release_buffer_vec(uint8_t** mat, int num_buffers, int buffer_size);
|
||||
int smi_utils_search_offset_in_buffer(uint8_t *buff, int len);
|
||||
uint8_t smi_utils_lfsr(uint8_t n);
|
||||
double smi_calculate_performance(size_t bytes, struct timeval *current);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -65,12 +65,12 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
// setup the signal handler
|
||||
cariboulite_setup_signal_handler (&cariboulite_sys, sighandler, cariboulite_signal_handler_op_last, &cariboulite_sys);
|
||||
cariboulite_setup_signal_handler (&cariboulite_sys, sighandler, signal_handler_op_last, &cariboulite_sys);
|
||||
|
||||
sleep(1);
|
||||
while (program_running)
|
||||
{
|
||||
int ret = app_menu(&hermonsdr_sys);
|
||||
int ret = app_menu(&cariboulite_sys);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "cariboulite_config.h"
|
||||
#include "config/config.h"
|
||||
|
||||
// PINOUT SPI
|
||||
#define CARIBOULITE_SPI_DEV 1
|
||||
|
@ -13,11 +13,12 @@ extern "C" {
|
|||
#define CARIBOULITE_SCK 21
|
||||
#define CARIBOULITE_MISO 19
|
||||
|
||||
// PINOUT FPGA - ICE40
|
||||
// PINOUT FPGA
|
||||
#define CARIBOULITE_FPGA_SPI_CHANNEL 0
|
||||
#define CARIBOULITE_FPGA_SS 18
|
||||
#define CARIBOULITE_FPGA_CDONE 27
|
||||
#define CARIBOULITE_FPGA_CRESET 26
|
||||
#define CARIBOULITE_FPGA_SOFT_RESET 4
|
||||
|
||||
// PINOUT AT86 - AT86RF215
|
||||
#define CARIBOULITE_MODEM_SPI_CHANNEL 1
|
||||
|
@ -34,7 +35,7 @@ extern "C" {
|
|||
// SYSTEM DEFINITIONS & CONFIGURATIONS
|
||||
//=======================================================================================
|
||||
#define CARIBOULITE_CONFIG_DEFAULT(a) \
|
||||
cariboulite_st(a)={ \
|
||||
sys_st(a)={ \
|
||||
.board_info = {0}, \
|
||||
.spi_dev = \
|
||||
{ \
|
||||
|
@ -51,20 +52,19 @@ extern "C" {
|
|||
{ \
|
||||
.initialized = 0, \
|
||||
}, \
|
||||
.ice40 = \
|
||||
{ \
|
||||
.cs_pin = CARIBOULITE_FPGA_SS, \
|
||||
.cdone_pin = CARIBOULITE_FPGA_CDONE, \
|
||||
.reset_pin = CARIBOULITE_FPGA_CRESET, \
|
||||
.verbose = 1, \
|
||||
.initialized = 0, \
|
||||
}, \
|
||||
.fpga = \
|
||||
{ \
|
||||
.reset_pin = CARIBOULITE_FPGA_CRESET, \
|
||||
.soft_reset_pin = CARIBOULITE_FPGA_SOFT_RESET, \
|
||||
.cs_pin = CARIBOULITE_FPGA_SS, \
|
||||
.spi_dev = CARIBOULITE_SPI_DEV, \
|
||||
.spi_channel = CARIBOULITE_FPGA_SPI_CHANNEL, \
|
||||
.prog_dev = \
|
||||
{ \
|
||||
.cs_pin = CARIBOULITE_FPGA_SS, \
|
||||
.cdone_pin = CARIBOULITE_FPGA_CDONE, \
|
||||
.reset_pin = CARIBOULITE_FPGA_CRESET, \
|
||||
}, \
|
||||
.initialized = 0, \
|
||||
}, \
|
||||
.modem = \
|
||||
|
@ -85,7 +85,7 @@ extern "C" {
|
|||
.initialized = 0, \
|
||||
}, \
|
||||
.reset_fpga_on_startup = 1, \
|
||||
.system_status = cariboulite_sys_status_unintialized,\
|
||||
.system_status = sys_status_unintialized, \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -17,15 +17,15 @@ extern "C" {
|
|||
|
||||
/*
|
||||
* Time tagging of the module through the 'struct tm' structure
|
||||
* Date: 2022-11-21
|
||||
* Time: 23:30:06
|
||||
* Date: 2022-12-12
|
||||
* Time: 14:33:16
|
||||
*/
|
||||
struct tm cariboulite_dtbo_date_time = {
|
||||
.tm_sec = 6,
|
||||
.tm_min = 30,
|
||||
.tm_hour = 23,
|
||||
.tm_mday = 21,
|
||||
.tm_mon = 10, /* +1 */
|
||||
.tm_sec = 16,
|
||||
.tm_min = 33,
|
||||
.tm_hour = 14,
|
||||
.tm_mday = 12,
|
||||
.tm_mon = 11, /* +1 */
|
||||
.tm_year = 122, /* +1900 */
|
||||
};
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -101,7 +101,7 @@ typedef enum
|
|||
|
||||
//================================================================
|
||||
// TEST FUNCTIONS
|
||||
static int cariboulite_test_hat_parameters(void* context, void* test_context);
|
||||
static int cariboulite_test_parameters(void* context, void* test_context);
|
||||
static int cariboulite_test_hat_eeprom(void* context, void* test_context);
|
||||
static int cariboulite_test_fpga_programming(void* context, void* test_context);
|
||||
static int cariboulite_test_fpga_communication(void* context, void* test_context);
|
||||
|
@ -131,35 +131,35 @@ static int cariboulite_test_rf_tx_power(void* context, void* test_context);
|
|||
// TEST DEFINITIONS
|
||||
production_test_st tests[] =
|
||||
{
|
||||
{.test_name = "parameters", .group = 0, .test_number = cariboulite_test_en_rpi_params, .func = cariboulite_test_hat_parameters, },
|
||||
{.test_name = "hat eeprom", .group = 0, .test_number = cariboulite_test_en_rpi_id_eeprom, .func = cariboulite_test_hat_eeprom, },
|
||||
{.test_name = "fpga programming", .group = 1, .test_number = cariboulite_test_en_fpga_programming, .func = cariboulite_test_fpga_programming, },
|
||||
{.test_name = "fpga communication", .group = 1, .test_number = cariboulite_test_en_fpga_communication, .func = cariboulite_test_fpga_communication, },
|
||||
{.test_name = "fpga communication", .group = 1, .test_number = cariboulite_test_en_fpga_id_resistors, .func = cariboulite_test_fpga_id_resistors, },
|
||||
{.test_name = "fpga soft reset", .group = 1, .test_number = cariboulite_test_en_fpga_reset, .func = cariboulite_test_fpga_soft_reset, },
|
||||
{.test_name = "fpga pmod", .group = 1, .test_number = cariboulite_test_en_fpga_pmod, .func = cariboulite_test_fpga_pmod, },
|
||||
{.test_name = "fpga switch", .group = 1, .test_number = cariboulite_test_en_fpga_switch, .func = cariboulite_test_fpga_switch, },
|
||||
{.test_name = "fpga leds", .group = 1, .test_number = cariboulite_test_en_fpga_leds, .func = cariboulite_test_fpga_leds, },
|
||||
{.test_name = "fpga smi", .group = 1, .test_number = cariboulite_test_en_fpga_smi, .func = cariboulite_test_fpga_smi, },
|
||||
{.test_name = "mixer reset", .group = 2, .test_number = cariboulite_test_en_mixer_reset, .func = cariboulite_test_mixer_reset, },
|
||||
{.test_name = "mixer communication", .group = 2, .test_number = cariboulite_test_en_mixer_communication, .func = cariboulite_test_mixer_communication, },
|
||||
{.test_name = "mixer version id", .group = 2, .test_number = cariboulite_test_en_mixer_versions, .func = cariboulite_test_mixer_versions, },
|
||||
{.test_name = "modem reset", .group = 3, .test_number = cariboulite_test_en_modem_reset, .func = cariboulite_test_modem_reset, },
|
||||
{.test_name = "modem communication", .group = 3, .test_number = cariboulite_test_en_modem_communication, .func = cariboulite_test_modem_communication, },
|
||||
{.test_name = "modem version", .group = 3, .test_number = cariboulite_test_en_modem_versions, .func = cariboulite_test_modem_version, },
|
||||
{.test_name = "modem leds", .group = 3, .test_number = cariboulite_test_en_modem_leds, .func = cariboulite_test_modem_leds, },
|
||||
{.test_name = "modem interrupt", .group = 3, .test_number = cariboulite_test_en_modem_interrupt, .func = cariboulite_test_modem_interrupt, },
|
||||
{.test_name = "current system", .group = 4, .test_number = cariboulite_test_en_current_system, .func = cariboulite_test_current_system, },
|
||||
{.test_name = "current modem rx", .group = 4, .test_number = cariboulite_test_en_current_modem_rx, .func = cariboulite_test_current_modem_rx, },
|
||||
{.test_name = "current modem tx", .group = 4, .test_number = cariboulite_test_en_current_modem_tx, .func = cariboulite_test_current_modem_tx, },
|
||||
{.test_name = "current mixer", .group = 4, .test_number = cariboulite_test_en_current_mixer, .func = cariboulite_test_current_mixer, },
|
||||
{.test_name = "system smi data", .group = 5, .test_number = cariboulite_test_en_system_smi_data, .func = cariboulite_test_smi_data, },
|
||||
{.test_name = "system rf loopback", .group = 5, .test_number = cariboulite_test_en_system_rf_loopback, .func = cariboulite_test_rf_loopback, },
|
||||
{.test_name = "system rf tx power", .group = 5, .test_number = cariboulite_test_en_system_rf_tx_power, .func = cariboulite_test_rf_tx_power, },
|
||||
{.test_name = "parameters", .group = 0, .test_number = cariboulite_test_en_rpi_params, .func = cariboulite_test_parameters, },
|
||||
{.test_name = "hat_eeprom", .group = 0, .test_number = cariboulite_test_en_rpi_id_eeprom, .func = cariboulite_test_hat_eeprom, },
|
||||
{.test_name = "fpga_programming", .group = 1, .test_number = cariboulite_test_en_fpga_programming, .func = cariboulite_test_fpga_programming, },
|
||||
{.test_name = "fpga_communication", .group = 1, .test_number = cariboulite_test_en_fpga_communication, .func = cariboulite_test_fpga_communication, },
|
||||
{.test_name = "fpga_id_resistors", .group = 1, .test_number = cariboulite_test_en_fpga_id_resistors, .func = cariboulite_test_fpga_id_resistors, },
|
||||
{.test_name = "fpga_soft_reset", .group = 1, .test_number = cariboulite_test_en_fpga_reset, .func = cariboulite_test_fpga_soft_reset, },
|
||||
{.test_name = "fpga_pmod", .group = 1, .test_number = cariboulite_test_en_fpga_pmod, .func = cariboulite_test_fpga_pmod, },
|
||||
{.test_name = "fpga_switch", .group = 1, .test_number = cariboulite_test_en_fpga_switch, .func = cariboulite_test_fpga_switch, },
|
||||
{.test_name = "fpga_leds", .group = 1, .test_number = cariboulite_test_en_fpga_leds, .func = cariboulite_test_fpga_leds, },
|
||||
{.test_name = "fpga_smi", .group = 1, .test_number = cariboulite_test_en_fpga_smi, .func = cariboulite_test_fpga_smi, },
|
||||
{.test_name = "mixer_reset", .group = 2, .test_number = cariboulite_test_en_mixer_reset, .func = cariboulite_test_mixer_reset, },
|
||||
{.test_name = "mixer_communication", .group = 2, .test_number = cariboulite_test_en_mixer_communication, .func = cariboulite_test_mixer_communication, },
|
||||
{.test_name = "mixer_version_id", .group = 2, .test_number = cariboulite_test_en_mixer_versions, .func = cariboulite_test_mixer_versions, },
|
||||
{.test_name = "modem_reset", .group = 3, .test_number = cariboulite_test_en_modem_reset, .func = cariboulite_test_modem_reset, },
|
||||
{.test_name = "modem_communication", .group = 3, .test_number = cariboulite_test_en_modem_communication, .func = cariboulite_test_modem_communication, },
|
||||
{.test_name = "modem_version", .group = 3, .test_number = cariboulite_test_en_modem_versions, .func = cariboulite_test_modem_version, },
|
||||
{.test_name = "modem_leds", .group = 3, .test_number = cariboulite_test_en_modem_leds, .func = cariboulite_test_modem_leds, },
|
||||
{.test_name = "modem_interrupt", .group = 3, .test_number = cariboulite_test_en_modem_interrupt, .func = cariboulite_test_modem_interrupt, },
|
||||
{.test_name = "current_system", .group = 4, .test_number = cariboulite_test_en_current_system, .func = cariboulite_test_current_system, },
|
||||
{.test_name = "current_modem rx", .group = 4, .test_number = cariboulite_test_en_current_modem_rx, .func = cariboulite_test_current_modem_rx, },
|
||||
{.test_name = "current_modem tx", .group = 4, .test_number = cariboulite_test_en_current_modem_tx, .func = cariboulite_test_current_modem_tx, },
|
||||
{.test_name = "current_mixer", .group = 4, .test_number = cariboulite_test_en_current_mixer, .func = cariboulite_test_current_mixer, },
|
||||
{.test_name = "system_smi_data", .group = 5, .test_number = cariboulite_test_en_system_smi_data, .func = cariboulite_test_smi_data, },
|
||||
{.test_name = "system_rf_loopback", .group = 5, .test_number = cariboulite_test_en_system_rf_loopback, .func = cariboulite_test_rf_loopback, },
|
||||
{.test_name = "system_rf_tx_power", .group = 5, .test_number = cariboulite_test_en_system_rf_tx_power, .func = cariboulite_test_rf_tx_power, },
|
||||
};
|
||||
|
||||
//=================================================
|
||||
int cariboulite_test_hat_parameters(void *context, void* test_context)
|
||||
int cariboulite_test_parameters(void *context, void* test_context)
|
||||
{
|
||||
sys_st* sys = (sys_st*)context;
|
||||
production_sequence_st* tests = (production_sequence_st*)test_context;
|
||||
|
@ -413,7 +413,7 @@ void hat_powermon_event(void* context, hat_powermon_state_st* state)
|
|||
}
|
||||
|
||||
//=================================================
|
||||
int cariboulite_production_init(cariboulite_production_sequence_st* prod)
|
||||
int cariboulite_production_init(void)
|
||||
{
|
||||
production_utils_rpi_leds_init(1);
|
||||
production_utils_rpi_leds_blink_start_tests();
|
||||
|
@ -438,24 +438,6 @@ int cariboulite_production_init(cariboulite_production_sequence_st* prod)
|
|||
return hat_powermon_init(&prod->powermon, HAT_POWER_MON_ADDRESS, hat_powermon_event, prod);
|
||||
}
|
||||
|
||||
//=================================================
|
||||
int cariboulite_production_close(cariboulite_production_sequence_st* prod)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//=================================================
|
||||
int cariboulite_production_start_tests(cariboulite_production_sequence_st* prod)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//=================================================
|
||||
int cariboulite_production_generate_report(cariboulite_production_sequence_st* prod, char* path)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//=================================================
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
|
|
@ -58,7 +58,7 @@ static int add_entropy(uint8_t byte)
|
|||
}
|
||||
|
||||
//======================================================================
|
||||
int cariboulite_init_radios(cariboulite_radios_st* radios, cariboulite_st *sys)
|
||||
int cariboulite_init_radios(cariboulite_radios_st* radios, sys_st *sys)
|
||||
{
|
||||
memset (radios, 0, sizeof(cariboulite_radios_st));
|
||||
|
||||
|
@ -133,6 +133,31 @@ int cariboulite_dispose_radios(cariboulite_radios_st* radios)
|
|||
caribou_fpga_set_io_ctrl_mode (&rad_6g->cariboulite_sys->fpga, 0, caribou_fpga_io_ctrl_rfm_low_power);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================================
|
||||
int cariboulite_setup_ext_ref ( sys_st *sys, cariboulite_ext_ref_freq_en ref)
|
||||
{
|
||||
switch(ref)
|
||||
{
|
||||
case cariboulite_ext_ref_26mhz:
|
||||
ZF_LOGD("Setting ext_ref = 26MHz");
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_2ma, at86rf215_clock_out_freq_26mhz);
|
||||
rffc507x_setup_reference_freq(&sys->mixer, 26e6);
|
||||
break;
|
||||
case cariboulite_ext_ref_32mhz:
|
||||
ZF_LOGD("Setting ext_ref = 32MHz");
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_2ma, at86rf215_clock_out_freq_32mhz);
|
||||
rffc507x_setup_reference_freq(&sys->mixer, 32e6);
|
||||
break;
|
||||
case cariboulite_ext_ref_off:
|
||||
ZF_LOGD("Setting ext_ref = OFF");
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_2ma, at86rf215_clock_out_freq_off);
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
int cariboulite_sync_radio_information(cariboulite_radios_st* radios)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,6 @@ extern "C" {
|
|||
#include "config/config.h"
|
||||
#include "at86rf215/at86rf215.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cariboulite_channel_dir_rx = 0,
|
||||
|
@ -21,6 +20,13 @@ typedef enum
|
|||
cariboulite_channel_6g = 1,
|
||||
} cariboulite_channel_en;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cariboulite_ext_ref_off = 0,
|
||||
cariboulite_ext_ref_26mhz = 26,
|
||||
cariboulite_ext_ref_32mhz = 32,
|
||||
} cariboulite_ext_ref_freq_en;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cariboulite_channel_en type;
|
||||
|
@ -64,7 +70,6 @@ typedef struct
|
|||
at86rf215_radio_f_cut_en tx_fcut;
|
||||
at86rf215_radio_sample_rate_en tx_fs;
|
||||
|
||||
// at86rf215_radio_energy_detection_st rx_energy_detection;
|
||||
float rx_energy_detection_value;
|
||||
float rx_rssi;
|
||||
|
||||
|
@ -99,8 +104,13 @@ typedef struct
|
|||
cariboulite_radio_state_st radio_6g;
|
||||
} cariboulite_radios_st;
|
||||
|
||||
|
||||
|
||||
// API
|
||||
int cariboulite_init_radios(cariboulite_radios_st* radios, sys_st *sys);
|
||||
int cariboulite_dispose_radios(cariboulite_radios_st* radios);
|
||||
int cariboulite_setup_ext_ref (sys_st *sys, cariboulite_ext_ref_freq_en ref);
|
||||
|
||||
int cariboulite_sync_radio_information(cariboulite_radios_st* radios);
|
||||
|
||||
int cariboulite_get_mod_state (cariboulite_radios_st* radios,
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
#include "cariboulite_events.h"
|
||||
#include "cariboulite_fpga_firmware.h"
|
||||
|
||||
|
||||
// Global system object for signals
|
||||
sys_st* sigsys = NULL;
|
||||
|
||||
//=================================================================
|
||||
void print_siginfo(siginfo_t *si)
|
||||
{
|
||||
printf("Signal [%d] caught, with the following information: \n", si->si_signo);
|
||||
|
@ -110,12 +115,8 @@ void print_siginfo(siginfo_t *si)
|
|||
|
||||
}
|
||||
|
||||
sys_st* sigsys = NULL;
|
||||
|
||||
//=======================================================================================
|
||||
void cariboulite_sigaction_basehandler (int signo,
|
||||
siginfo_t *si,
|
||||
void *ucontext)
|
||||
void cariboulite_sigaction_basehandler (int signo, siginfo_t *si, void *ucontext)
|
||||
{
|
||||
int run_first = 0;
|
||||
int run_last = 0;
|
||||
|
@ -123,7 +124,6 @@ void cariboulite_sigaction_basehandler (int signo,
|
|||
// store the errno
|
||||
int internal_errno = errno;
|
||||
|
||||
|
||||
if (sigsys->signal_cb)
|
||||
{
|
||||
switch(sigsys->sig_op)
|
||||
|
@ -172,6 +172,31 @@ void cariboulite_sigaction_basehandler (int signo,
|
|||
exit(0);
|
||||
}
|
||||
|
||||
//=================================================
|
||||
static int cariboulite_setup_signals(sys_st *sys)
|
||||
{
|
||||
cariboulite_setup_signal_handler (sys, NULL, signal_handler_op_last, NULL);
|
||||
int signals[] = {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV, SIGTERM};
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigsys = sys;
|
||||
sa.sa_sigaction = cariboulite_sigaction_basehandler;
|
||||
sa.sa_flags |= SA_RESTART | SA_SIGINFO;
|
||||
|
||||
int nsigs = sizeof(signals)/sizeof(signals[0]);
|
||||
|
||||
for (int i = 0; i < nsigs; i++)
|
||||
{
|
||||
if(sigaction(signals[i], &sa, NULL) != 0)
|
||||
{
|
||||
ZF_LOGE("error sigaction() [%d] signal registration", signals[i]);
|
||||
return -cariboulite_signal_registration_failed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================================
|
||||
int cariboulite_setup_io (sys_st* sys)
|
||||
{
|
||||
|
@ -227,11 +252,11 @@ int cariboulite_configure_fpga (sys_st* sys, cariboulite_firmware_source_en src,
|
|||
switch (src)
|
||||
{
|
||||
case cariboulite_firmware_source_file:
|
||||
return hermon_fpga_program_to_fpga_from_file(&sys->fpga, fpga_bin_path, sys->force_fpga_reprogramming);
|
||||
return caribou_fpga_program_to_fpga_from_file(&sys->fpga, fpga_bin_path, sys->force_fpga_reprogramming);
|
||||
break;
|
||||
|
||||
case cariboulite_firmware_source_blob:
|
||||
return hermon_fpga_program_to_fpga(&sys->fpga, hermonsdr_firmware, sizeof(hermonsdr_firmware), sys->force_fpga_reprogramming);
|
||||
return caribou_fpga_program_to_fpga(&sys->fpga, cariboulite_firmware, sizeof(cariboulite_firmware), sys->force_fpga_reprogramming);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -241,30 +266,6 @@ int cariboulite_configure_fpga (sys_st* sys, cariboulite_firmware_source_en src,
|
|||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================================
|
||||
int cariboulite_setup_ext_ref ( sys_st *sys, cariboulite_ext_ref_freq_en ref)
|
||||
{
|
||||
switch(ref)
|
||||
{
|
||||
case cariboulite_ext_ref_26mhz:
|
||||
ZF_LOGD("Setting ext_ref = 26MHz");
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_2ma, at86rf215_clock_out_freq_26mhz);
|
||||
rffc507x_setup_reference_freq(&sys->mixer, 26e6);
|
||||
break;
|
||||
case cariboulite_ext_ref_32mhz:
|
||||
ZF_LOGD("Setting ext_ref = 32MHz");
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_2ma, at86rf215_clock_out_freq_32mhz);
|
||||
rffc507x_setup_reference_freq(&sys->mixer, 32e6);
|
||||
break;
|
||||
case cariboulite_ext_ref_off:
|
||||
ZF_LOGD("Setting ext_ref = OFF");
|
||||
at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_2ma, at86rf215_clock_out_freq_off);
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================================
|
||||
int cariboulite_init_submodules (sys_st* sys)
|
||||
{
|
||||
|
@ -335,10 +336,10 @@ int cariboulite_init_submodules (sys_st* sys)
|
|||
at86rf215_radio_setup_external_settings(&sys->modem, at86rf215_rf_channel_900mhz, &ext_ctrl);
|
||||
at86rf215_radio_setup_external_settings(&sys->modem, at86rf215_rf_channel_2400mhz, &ext_ctrl);
|
||||
|
||||
switch (sys->board_info.sys_type)
|
||||
switch (sys->board_info.numeric_product_id)
|
||||
{
|
||||
//---------------------------------------------------
|
||||
case cariboulite_system_type_full:
|
||||
case system_type_cariboulite_full:
|
||||
ZF_LOGD("This board is a Full version CaribouLite - setting ext_ref: modem, 32MHz");
|
||||
// by default the ext_ref for the mixer - from the modem, 32MHz
|
||||
sys->ext_ref_settings.src = cariboulite_ext_ref_src_modem;
|
||||
|
@ -347,7 +348,7 @@ int cariboulite_init_submodules (sys_st* sys)
|
|||
break;
|
||||
|
||||
//---------------------------------------------------
|
||||
case cariboulite_system_type_ism:
|
||||
case system_type_cariboulite_ism:
|
||||
ZF_LOGD("This board is a ISM version CaribouLite - setting ext_ref: OFF");
|
||||
sys->ext_ref_settings.src = cariboulite_ext_ref_src_na;
|
||||
sys->ext_ref_settings.freq_hz = 0;
|
||||
|
@ -360,7 +361,7 @@ int cariboulite_init_submodules (sys_st* sys)
|
|||
}
|
||||
|
||||
// The mixer - only relevant to the full version
|
||||
if (sys->board_info.sys_type == cariboulite_system_type_full)
|
||||
if (sys->board_info.numeric_product_id == system_type_cariboulite_full)
|
||||
{
|
||||
// RFFC5072
|
||||
//------------------------------------------------------
|
||||
|
@ -407,7 +408,7 @@ int cariboulite_self_test(sys_st* sys, cariboulite_self_test_result_st* res)
|
|||
|
||||
//------------------------------------------------------
|
||||
// Mixer only relevant to the full version
|
||||
if (sys->board_info.sys_type == cariboulite_system_type_full)
|
||||
if (sys->board_info.numeric_product_id == system_type_cariboulite_full)
|
||||
{
|
||||
ZF_LOGI("Testing mixer communication and versions");
|
||||
rffc507x_device_id_st dev_id;
|
||||
|
@ -440,7 +441,7 @@ int cariboulite_release_submodules(sys_st* sys)
|
|||
{
|
||||
int res = 0;
|
||||
|
||||
if (sys->system_status == sys_status_minimal_full_init)
|
||||
if (sys->system_status == sys_status_full_init)
|
||||
{
|
||||
// SMI Module
|
||||
//------------------------------------------------------
|
||||
|
@ -457,7 +458,7 @@ int cariboulite_release_submodules(sys_st* sys)
|
|||
|
||||
//------------------------------------------------------
|
||||
// RFFC5072 only relevant to the full version
|
||||
if (sys->board_info.sys_type == cariboulite_system_type_full)
|
||||
if (sys->board_info.numeric_product_id == system_type_cariboulite_full)
|
||||
{
|
||||
ZF_LOGD("CLOSE MIXER - RFFC5072");
|
||||
rffc507x_release(&sys->mixer);
|
||||
|
@ -480,24 +481,9 @@ int cariboulite_release_submodules(sys_st* sys)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//=================================================
|
||||
static int cariboulite_register_signals(int *sig_nos, int nsigs, struct sigaction *sa)
|
||||
{
|
||||
for (int i = 0; i < nsigs; i++)
|
||||
{
|
||||
if(sigaction(sig_nos[i], sa, NULL) != 0)
|
||||
{
|
||||
ZF_LOGE("error sigaction() [%d] signal registration", sig_nos[i]);
|
||||
return -cariboulite_signal_registration_failed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=================================================
|
||||
int cariboulite_init_driver_minimal(sys_st *sys, hat_board_info_st *info)
|
||||
{
|
||||
//zf_log_set_output_level(ZF_LOG_ERROR);
|
||||
zf_log_set_output_level(ZF_LOG_VERBOSE);
|
||||
ZF_LOGI("driver initializing");
|
||||
|
||||
|
@ -509,17 +495,7 @@ int cariboulite_init_driver_minimal(sys_st *sys, hat_board_info_st *info)
|
|||
|
||||
// signals
|
||||
ZF_LOGI("Initializing signals");
|
||||
cariboulite_setup_signal_handler (sys, NULL, signal_handler_op_last, NULL);
|
||||
|
||||
int signals[] = {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV, SIGTERM};
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigsys = sys;
|
||||
sa.sa_sigaction = cariboulite_sigaction_basehandler;
|
||||
sa.sa_flags |= SA_RESTART | SA_SIGINFO;
|
||||
|
||||
// RPI Internal Configurations
|
||||
if(cariboulite_register_signals(signals, sizeof(signals)/sizeof(signals[0]), &sa) != 0)
|
||||
if(cariboulite_setup_signals(sys) != 0)
|
||||
{
|
||||
ZF_LOGE("error signal list registration");
|
||||
return -cariboulite_signal_registration_failed;
|
||||
|
@ -531,10 +507,9 @@ int cariboulite_init_driver_minimal(sys_st *sys, hat_board_info_st *info)
|
|||
return -cariboulite_io_setup_failed;
|
||||
}
|
||||
|
||||
// External Configurations
|
||||
// FPGA Init and Programming
|
||||
ZF_LOGD("Initializing FPGA");
|
||||
if (hermon_fpga_init(&sys->fpga, &sys->spi_dev) < 0)
|
||||
if (caribou_fpga_init(&sys->fpga, &sys->spi_dev) < 0)
|
||||
{
|
||||
ZF_LOGE("FPGA communication init failed");
|
||||
cariboulite_release_io (sys);
|
||||
|
@ -561,7 +536,7 @@ int cariboulite_init_driver_minimal(sys_st *sys, hat_board_info_st *info)
|
|||
|
||||
ZF_LOGD("FPGA Digital Values: led0: %d, led1: %d, btn: %d, CFG[0..3]: [%d,%d,%d,%d]",
|
||||
led0, led1, btn, (cfg >> 0) & 0x1, (cfg >> 1) & 0x1, (cfg >> 2) & 0x1, (cfg >> 3) & 0x1);
|
||||
sys->fpga_config_res_state = cfg;
|
||||
sys->fpga_config_resistor_state = cfg;
|
||||
|
||||
ZF_LOGI("Detected Board Information:");
|
||||
if (info == NULL)
|
||||
|
@ -596,9 +571,9 @@ int cariboulite_init_driver(sys_st *sys, hat_board_info_st *info)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (sys->system_status == sys_status_minimal_full_init)
|
||||
if (sys->system_status == sys_status_full_init)
|
||||
{
|
||||
ZF_LOGE("System is already fully initialized! returnig");
|
||||
ZF_LOGE("System is already fully initialized!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -619,7 +594,7 @@ int cariboulite_init_driver(sys_st *sys, hat_board_info_st *info)
|
|||
return -cariboulite_self_test_failed;
|
||||
}
|
||||
|
||||
sys->system_status = sys_status_minimal_full_init;
|
||||
sys->system_status = sys_status_full_init;
|
||||
|
||||
return cariboulite_ok;
|
||||
}
|
||||
|
@ -640,10 +615,10 @@ int cariboulite_setup_signal_handler (sys_st *sys,
|
|||
}
|
||||
|
||||
//=================================================
|
||||
void cariboulite_release_driver(cariboulite_st *sys)
|
||||
void cariboulite_release_driver(sys_st *sys)
|
||||
{
|
||||
ZF_LOGI("driver being released");
|
||||
if (sys->system_status != cariboulite_sys_status_unintialized)
|
||||
if (sys->system_status != sys_status_unintialized)
|
||||
{
|
||||
//caribou_fpga_set_io_ctrl_mode (&sys->fpga, false, ...);
|
||||
cariboulite_release_submodules(sys);
|
||||
|
|
|
@ -7,7 +7,6 @@ extern "C" {
|
|||
|
||||
|
||||
#include "cariboulite_radios.h"
|
||||
|
||||
#include "caribou_fpga/caribou_fpga.h"
|
||||
#include "at86rf215/at86rf215.h"
|
||||
#include "rffc507x/rffc507x.h"
|
||||
|
@ -55,13 +54,6 @@ typedef enum
|
|||
cariboulite_signal_registration_failed = 7,
|
||||
} cariboulite_errors_en;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cariboulite_ext_ref_off = 0,
|
||||
cariboulite_ext_ref_26mhz = 26,
|
||||
cariboulite_ext_ref_32mhz = 32,
|
||||
} cariboulite_ext_ref_freq_en;
|
||||
|
||||
int cariboulite_init_driver(sys_st *sys, hat_board_info_st *info);
|
||||
int cariboulite_init_driver_minimal(sys_st *sys, hat_board_info_st *info);
|
||||
int cariboulite_setup_signal_handler (sys_st *sys,
|
||||
|
@ -77,11 +69,6 @@ int cariboulite_release_io (sys_st* sys);
|
|||
int cariboulite_init_submodules (sys_st* sys);
|
||||
int cariboulite_release_submodules(sys_st* sys);
|
||||
int cariboulite_self_test(sys_st* sys, cariboulite_self_test_result_st* res);
|
||||
int cariboulite_setup_ext_ref ( cariboulite_st *sys, cariboulite_ext_ref_freq_en ref);
|
||||
int cariboulite_setup_frequency( sys_st *sys,
|
||||
cariboulite_channel_en ch,
|
||||
cariboulite_channel_dir_en dir,
|
||||
double *freq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <linux/limits.h> // for file system path max length
|
||||
#include "caribou_programming/caribou_prog.h"
|
||||
#include "caribou_fpga/caribou_fpga.h"
|
||||
#include "rffc507x/rffc507x.h"
|
||||
|
@ -19,8 +19,6 @@ extern "C" {
|
|||
#include "ustimer/ustimer.h"
|
||||
|
||||
// GENERAL SETTINGS
|
||||
#define MAX_PATH_LEN 512
|
||||
|
||||
struct sys_st_t;
|
||||
|
||||
typedef void (*signal_handler)( struct sys_st_t *sys, // the current cariboulite low-level management struct
|
||||
|
@ -30,9 +28,9 @@ typedef void (*signal_handler)( struct sys_st_t *sys, // the current carib
|
|||
|
||||
typedef enum
|
||||
{
|
||||
cariboulite_signal_handler_op_last = 0, // The curtom sighandler operates (if present) after the default sig handler
|
||||
cariboulite_signal_handler_op_first = 1, // The curtom sighandler operates (if present) before the default sig handler
|
||||
cariboulite_signal_handler_op_override = 2, // The curtom sighandler operates (if present) instead of the default sig handler
|
||||
signal_handler_op_last = 0, // The curtom sighandler operates (if present) after the default sig handler
|
||||
signal_handler_op_first = 1, // The curtom sighandler operates (if present) before the default sig handler
|
||||
signal_handler_op_override = 2, // The curtom sighandler operates (if present) instead of the default sig handler
|
||||
} signal_handler_operation_en;
|
||||
|
||||
typedef enum
|
||||
|
@ -54,7 +52,7 @@ typedef enum
|
|||
{
|
||||
sys_status_unintialized = 0,
|
||||
sys_status_minimal_init = 1,
|
||||
sys_status_minimal_full_init = 2,
|
||||
sys_status_full_init = 2,
|
||||
} sys_status_en;
|
||||
|
||||
typedef struct
|
||||
|
@ -63,7 +61,7 @@ typedef struct
|
|||
double freq_hz;
|
||||
} cariboulite_ext_ref_settings_st;
|
||||
|
||||
typedef struct cariboulite_st_t
|
||||
typedef struct sys_st_t
|
||||
{
|
||||
hat_board_info_st board_info;
|
||||
system_type_en sys_type;
|
||||
|
@ -81,19 +79,17 @@ typedef struct cariboulite_st_t
|
|||
// Configuration
|
||||
int reset_fpga_on_startup;
|
||||
int force_fpga_reprogramming;
|
||||
char firmware_path_operational[MAX_PATH_LEN];
|
||||
char firmware_path_testing[MAX_PATH_LEN];
|
||||
int fpga_config_resistor_state;
|
||||
char firmware_path_operational[PATH_MAX];
|
||||
char firmware_path_testing[PATH_MAX];
|
||||
|
||||
// Signals
|
||||
signal_handler signal_cb;
|
||||
void* singal_cb_context;
|
||||
signal_handler_operation_en sig_op;
|
||||
|
||||
// Management
|
||||
caribou_fpga_versions_st fpga_versions;
|
||||
// External clock source
|
||||
cariboulite_ext_ref_settings_st ext_ref_settings;
|
||||
uint8_t fpga_error_status;
|
||||
int fpga_config_res_state;
|
||||
|
||||
// Initialization
|
||||
sys_status_en system_status;
|
||||
|
|
|
@ -10,7 +10,13 @@
|
|||
#include <time.h>
|
||||
#include "zf_log/zf_log.h"
|
||||
#include "io_utils_sys_info.h"
|
||||
#include "io_utils_fs.h"
|
||||
|
||||
//=====================================================================
|
||||
static int io_utils_get_rpi_serial_number(char* serial, int len)
|
||||
{
|
||||
return io_utils_read_string_from_file("/sys/firmware/devicetree/base/", "serial-number", serial, len);
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
static void io_utils_fill_sys_info(io_utils_sys_info_st *sys_info)
|
||||
|
@ -54,9 +60,10 @@ static void io_utils_fill_sys_info(io_utils_sys_info_st *sys_info)
|
|||
else if (!strcmp(sys_info->ram, "2G")) sys_info->ram_size_mbytes = 2000;
|
||||
else if (!strcmp(sys_info->ram, "4G")) sys_info->ram_size_mbytes = 4000;
|
||||
else if (!strcmp(sys_info->ram, "8G")) sys_info->ram_size_mbytes = 8000;
|
||||
|
||||
io_utils_get_rpi_serial_number(sys_info->serial_number, 31);
|
||||
}
|
||||
|
||||
|
||||
//=====================================================================
|
||||
int io_utils_get_rpi_info(io_utils_sys_info_st *info)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@ typedef struct
|
|||
char *processor;
|
||||
char *type;
|
||||
char revision[1024];
|
||||
char serial_number[32];
|
||||
|
||||
io_utils_processor_type_en processor_type;
|
||||
uint32_t ram_size_mbytes;
|
||||
|
|
|
@ -9,7 +9,7 @@ include_directories(${SUPER_DIR})
|
|||
|
||||
#However, the file(GLOB...) allows for wildcard additions:
|
||||
set(SOURCES lcd.c test_lcd.c)
|
||||
set(SOURCES_LIB production_utils.c hat_powermon.c lcd.c)
|
||||
set(SOURCES_LIB production_utils.c hat_powermon.c lcd.c production_testing.c)
|
||||
#add_compile_options(-Wall -Wextra -pedantic -Werror)
|
||||
add_compile_options(-Wall -Wextra -Wno-missing-braces)
|
||||
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
#ifndef ZF_LOG_LEVEL
|
||||
#define ZF_LOG_LEVEL ZF_LOG_VERBOSE
|
||||
#endif
|
||||
#define ZF_LOG_DEF_SRCLOC ZF_LOG_SRCLOC_LONG
|
||||
#define ZF_LOG_TAG "PRODUCTION_TESTING"
|
||||
#include "zf_log/zf_log.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "production_testing.h"
|
||||
|
||||
//===================================================================
|
||||
void production_testing_lcd_key_callback(void* context, int key1, int key2)
|
||||
{
|
||||
printf("%d, %d\n", key1, key2);
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
void production_testing_powermon_callback(void* context, hat_powermon_state_st* state)
|
||||
{
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
int production_init(production_sequence_st* prod, production_test_st* tests, int num_tests, void* context)
|
||||
{
|
||||
memset(prod, 0, sizeof(production_sequence_st));
|
||||
|
||||
if (lcd_init(&prod->lcd, production_testing_lcd_key_callback, prod) != 0)
|
||||
{
|
||||
ZF_LOGE("LCD init failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
io_utils_get_rpi_info(&prod->tester.rpi_info);
|
||||
|
||||
prod->context = context;
|
||||
prod->tests = tests;
|
||||
prod->number_of_tests = num_tests;
|
||||
prod->current_test_number = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
int production_close(production_sequence_st* prod)
|
||||
{
|
||||
lcd_close(&prod->lcd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define PROD_GET_TIME(T) {time_t time_now; time(&time_now); memcpy(&(T),gmtime(&time_now),sizeof(struct tm));}
|
||||
|
||||
//===================================================================
|
||||
int production_start_tests(production_sequence_st* prod)
|
||||
{
|
||||
prod->current_tests_pass = true;
|
||||
|
||||
for ( prod->current_test_number = 0;
|
||||
prod->current_test_number < prod->number_of_tests;
|
||||
prod->current_test_number ++ )
|
||||
{
|
||||
production_test_st* current_test = &prod->tests[prod->current_test_number];
|
||||
ZF_LOGI("Starting test No. %d ['%s']", prod->current_test_number, current_test->test_name);
|
||||
|
||||
current_test->test_number = prod->current_test_number;
|
||||
|
||||
PROD_GET_TIME(current_test->start_time_of_test);
|
||||
current_test->started = true;
|
||||
|
||||
if (current_test->func != NULL)
|
||||
{
|
||||
current_test->test_pass = current_test->func(prod->context, prod);
|
||||
|
||||
if (!current_test->test_pass)
|
||||
{
|
||||
prod->current_tests_pass = false;
|
||||
}
|
||||
}
|
||||
|
||||
current_test->finished = true;
|
||||
PROD_GET_TIME(current_test->end_time_of_test);
|
||||
ZF_LOGI("Finished test No. %d ['%s'] => %s", prod->current_test_number, current_test->test_name,
|
||||
current_test->test_pass ? "PASS" : "FAIL");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
int production_generate_report(production_sequence_st* prod, char* path, uint64_t serial_number)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
char filename[256] = {0};
|
||||
char date1[128] = {0};
|
||||
char date[256] = {0};
|
||||
strftime(date1, 128, "%Y_%m_%d__%H_%M_%S", &prod->tests[0].start_time_of_test);
|
||||
strftime(date, 256, "%d/%m/%Y %H:%M:%S", &prod->tests[0].start_time_of_test);
|
||||
sprintf(filename, "%s/%llu__%s.yml", path, serial_number, date1);
|
||||
|
||||
FILE* fid = fopen(filename, "w");
|
||||
if (fid == NULL)
|
||||
{
|
||||
ZF_LOGE("File opening failed for results generation");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(fid, "version: 1\n");
|
||||
fprintf(fid, "file_type: cariboulite_test_results\n");
|
||||
fprintf(fid, "date: %s\n", date);
|
||||
fprintf(fid, "product_name: %s\n", "cariboulite_full_r2.8"); // <====
|
||||
fprintf(fid, "rpi_serial_number: %s\n", prod->tester.rpi_info.serial_number);
|
||||
fprintf(fid, "summary_test_results: %s\n", prod->current_tests_pass?"PASS":"FAIL");
|
||||
fprintf(fid, "test_results:\n");
|
||||
|
||||
for (i = 0; i < prod->number_of_tests; i++)
|
||||
{
|
||||
fprintf(fid, "\t%s: %s\n", prod->tests[i].test_name, prod->tests[i].test_result_textual);
|
||||
}
|
||||
|
||||
fclose(fid);
|
||||
return 0;
|
||||
}
|
|
@ -14,6 +14,7 @@ extern "C" {
|
|||
#include "io_utils/io_utils_sys_info.h"
|
||||
|
||||
typedef int (*test_function)(void* context, void* tests);
|
||||
#define PROD_TESTING_PWR_MON_ADDR (0x25)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -32,7 +33,7 @@ typedef struct
|
|||
|
||||
// timing
|
||||
struct tm start_time_of_test;
|
||||
struct tm end_time_of_test
|
||||
struct tm end_time_of_test;
|
||||
|
||||
// outputs
|
||||
void* test_result_context;
|
||||
|
@ -45,19 +46,21 @@ typedef struct
|
|||
{
|
||||
lcd_st lcd;
|
||||
production_tester_st tester;
|
||||
hat_board_info_st board_info;
|
||||
hat_power_monitor_st powermon;
|
||||
|
||||
production_test_st *tests;
|
||||
uint32_t number_of_tests;
|
||||
void* context;
|
||||
|
||||
// state
|
||||
uint32_t current_test_number;
|
||||
bool current_tests_pass;
|
||||
} production_sequence_st;
|
||||
|
||||
|
||||
int cariboulite_production_init(production_sequence_st* prod, production_test_st* tests, int num_tests);
|
||||
int cariboulite_production_close(production_sequence_st* prod);
|
||||
int cariboulite_production_start_tests(production_sequence_st* prod);
|
||||
int cariboulite_production_generate_report(production_sequence_st* prod, char* path);
|
||||
int production_init(production_sequence_st* prod, production_test_st* tests, int num_tests, void* context);
|
||||
int production_close(production_sequence_st* prod);
|
||||
int production_start_tests(production_sequence_st* prod);
|
||||
int production_generate_report(production_sequence_st* prod, char* path, uint64_t serial_number);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
Ładowanie…
Reference in New Issue