pull/37/head
meexmachina 2022-12-12 17:42:22 +02:00
rodzic 3d26dc2aea
commit eee358d06a
38 zmienionych plików z 22981 dodań i 23753 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Plik diff jest za duży Load Diff

Plik binarny nie jest wyświetlany.

Plik diff jest za duży Load Diff

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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),

Wyświetl plik

@ -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 */
};

Wyświetl plik

@ -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>;
};
};
};

Wyświetl plik

@ -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)
{

Wyświetl plik

@ -98,7 +98,7 @@ typedef struct
{
// pinout
int reset_pin;
int irq_pin;
int soft_reset_pin;
int cs_pin;
// spi device

Wyświetl plik

@ -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)

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;}
/***************************************************************************/

Wyświetl plik

@ -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 {

Wyświetl plik

@ -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, &current_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, &current_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;
}

Wyświetl plik

@ -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;

Wyświetl plik

@ -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;

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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(&current_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;
}

Wyświetl plik

@ -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
}

Wyświetl plik

@ -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)
{

Wyświetl plik

@ -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

Wyświetl plik

@ -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 */
};

Wyświetl plik

@ -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[])
{

Wyświetl plik

@ -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)
{

Wyświetl plik

@ -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,

Wyświetl plik

@ -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);

Wyświetl plik

@ -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
}

Wyświetl plik

@ -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;

Wyświetl plik

@ -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)
{

Wyświetl plik

@ -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;

Wyświetl plik

@ -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)

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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