bug_fixes_integration_tx
David Michaeli 2021-12-28 00:58:59 +02:00
rodzic b314b7a644
commit 880c561a10
37 zmienionych plików z 16153 dodań i 25420 usunięć

Wyświetl plik

@ -22,5 +22,5 @@ add_executable(caribou_dump1090
modes.c
)
target_link_libraries(caribou_dump1090 SoapySDR)
target_link_libraries(caribou_dump1090 SoapySDR iir_static)
#install(TARGETS caribou_dump1090 DESTINATION ${CMAKE_INSTALL_BINDIR})

Wyświetl plik

@ -39,6 +39,8 @@ sys/types.h
-
sys/stat.h
-
Iir.h
-
modes.h
/home/pi/projects/cariboulite/examples/cpp/modes.h

Wyświetl plik

@ -1 +1 @@
/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/caribou_dump1090.dir/dump1090.cpp.o CMakeFiles/caribou_dump1090.dir/modes.c.o -o caribou_dump1090 -lSoapySDR
/usr/bin/c++ -O3 -DNDEBUG CMakeFiles/caribou_dump1090.dir/dump1090.cpp.o CMakeFiles/caribou_dump1090.dir/modes.c.o -o caribou_dump1090 -lSoapySDR -liir_static

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -15,8 +15,10 @@
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <Iir.h>
#include "modes.h"
/***********************************************************************
* Print the banner
**********************************************************************/
@ -65,6 +67,33 @@ void onModeSMessage(mode_s_t *self, struct mode_s_msg *mm)
printf("Got message from flight %s at altitude %d\n", mm->flight, mm->altitude);
}
#define FILT_ORDER 6
Iir::Butterworth::LowPass<FILT_ORDER> filt;
void makeFilter(double fs, double cutoff)
{
try {filt.setup(fs, cutoff);}
catch (...) {printf("Filter Setup Exception!\n");}
}
// Turn I/Q samples pointed by `data` into the magnitude vector pointed by `mag`
void MagnitudeVector(short *data, uint16_t *mag, uint32_t size)
{
uint32_t k;
float ii, qq, i, q;
int t = 0;
for (k=0; k<size; k+=2, t++)
{
float i = data[k];
float q = data[k+1];
//ii = filt.filter(i);
//qq = filt.filter(q);
mag[t]=(uint16_t)sqrt(ii*ii + qq*qq);
}
}
void runSoapyProcess(
SoapySDR::Device *device,
SoapySDR::Stream *stream,
@ -74,14 +103,13 @@ void runSoapyProcess(
{
//allocate buffers for the stream read/write
const size_t numElems = device->getStreamMTU(stream);
std::vector<std::vector<char>> buffMem(numChans, std::vector<char>(elemSize*numElems));
std::vector<unsigned short> magMem(numElems);
std::vector<void *> buffs(numChans);
for (size_t i = 0; i < numChans; i++) buffs[i] = buffMem[i].data();
int16_t* buff = (int16_t*)malloc (2*sizeof(int16_t)*numElems); // complex 16 bit samples
uint16_t* mag = (uint16_t*)malloc(sizeof(uint16_t)*numElems);
// MODE-S Stuff
mode_s_t state;
mode_s_init(&state);
makeFilter(4e6, 50e3);
std::cout << "Starting stream loop, press Ctrl+C to exit..." << std::endl;
device->activateStream(stream);
@ -91,7 +119,7 @@ void runSoapyProcess(
int ret = 0;
int flags = 0;
long long timeUS = numElems;
ret = device->readStream(stream, buffs.data(), numElems, flags, timeUS);
ret = device->readStream(stream, (void* const*)&buff, numElems, flags, timeUS);
if (ret == SOAPY_SDR_TIMEOUT) continue;
if (ret == SOAPY_SDR_OVERFLOW)
@ -109,13 +137,17 @@ void runSoapyProcess(
std::cerr << "Unexpected stream error " << ret << std::endl;
break;
}
//totalSamples += ret;
// compute the magnitude of the signal
mode_s_compute_magnitude_vector((short*)(buffs[0]), magMem.data(), ret);
MagnitudeVector(buff, mag, ret);
for (int jjj = 0; jjj < numElems; jjj++)
{
printf("%d, ", buff[jjj*2]);
}
// detect Mode S messages in the signal and call on_msg with each message
mode_s_detect(&state, magMem.data(), ret, onModeSMessage);
mode_s_detect(&state, mag, ret, onModeSMessage);
}
device->deactivateStream(stream);
@ -132,6 +164,8 @@ int main(int argc, char *argv[])
std::vector<size_t> channels;
std::string argStr;
double fullScale = 0.0;
double freq = 1090.0e6;
//double freq = 1090e6;
printBanner();
//findDevices(argStr, false);
@ -145,8 +179,10 @@ int main(int argc, char *argv[])
// set the sample rate
device->setSampleRate(SOAPY_SDR_RX, channels[0], 4e6);
device->setBandwidth(SOAPY_SDR_RX, channels[0], 2500e3);
device->setGainMode(SOAPY_SDR_RX, channels[0], true);
device->setBandwidth(SOAPY_SDR_RX, channels[0], 2.5e6);
device->setGainMode(SOAPY_SDR_RX, channels[0], false);
device->setGain(SOAPY_SDR_RX, channels[0], 60);
device->setFrequency(SOAPY_SDR_RX, channels[0], freq);
//create the stream, use the native format
const auto format = device->getNativeStreamFormat(SOAPY_SDR_RX, channels.front(), fullScale);

Wyświetl plik

@ -492,29 +492,6 @@ void mode_s_decode(mode_s_t *self, struct mode_s_msg *mm, unsigned char *msg) {
mm->phase_corrected = 0; // Set to 1 by the caller if needed.
}
// Turn I/Q samples pointed by `data` into the magnitude vector pointed by `mag`
void mode_s_compute_magnitude_vector(short *data, uint16_t *mag, uint32_t size)
{
uint32_t j;
// Compute the magnitude vector. It's just SQRT(I^2 + Q^2), but we rescale
// to the 0-255 range to exploit the full resolution.
/*for (j = 0; j < size; j += 2) {
int i = data[j]-127;
int q = data[j+1]-127;
if (i < 0) i = -i;
if (q < 0) q = -q;
mag[j/2] = maglut[i*129+q];
}*/
for (j=0; j<size; j+=2)
{
int i = data[j];
int q = data[j+1];
mag[j/2]=sqrt(i*i + q*q);
}
}
// Return -1 if the message is out of fase left-side
// Return 1 if the message is out of fase right-size
// Return 0 if the message is not particularly out of phase.

Wyświetl plik

@ -82,7 +82,6 @@ struct mode_s_msg {
typedef void (*mode_s_callback_t)(mode_s_t *self, struct mode_s_msg *mm);
void mode_s_init(mode_s_t *self);
void mode_s_compute_magnitude_vector(short *data, uint16_t *mag, uint32_t size);
void mode_s_detect(mode_s_t *self, uint16_t *mag, uint32_t maglen, mode_s_callback_t);
void mode_s_decode(mode_s_t *self, struct mode_s_msg *mm, unsigned char *msg);

Wyświetl plik

@ -13,7 +13,7 @@ def setup_receiver(sdr, channel, freq_hz):
use_agc = False # Use or don't use the AGC
# The wide channel parameters
sdr.setGainMode(SOAPY_SDR_RX, channel, use_agc) # Set the gain mode
sdr.setGain(SOAPY_SDR_RX, channel, 50) # Set the gain
sdr.setGain(SOAPY_SDR_RX, channel, 0) # Set the gain
sdr.setFrequency(SOAPY_SDR_RX, channel, freq_hz) # Tune the LO
sdr.setBandwidth(SOAPY_SDR_RX, channel, 2.5e6)
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [channel]) # Setup data stream
@ -24,10 +24,10 @@ def update_receiver_freq(sdr, stream, channel, freq_hz):
# Data and Source Configuration
rx_chan = 1 # 6G = 1
rx_chan = 0 # 6G = 1
N = 16384 # Number of complex samples per transfer
rx_buff = np.empty(2 * N, np.int16) # Create memory buffer for data stream
freq = 915.6e6
freq = 915e6
# Initialize CaribouLite Soapy
sdr = SoapySDR.Device(dict(driver="Cariboulite")) # Create Cariboulite
@ -57,7 +57,7 @@ PSD_shifted = np.fft.fftshift(PSD_log)
center_freq = freq
f = np.arange(Fs/-2.0, Fs/2.0, Fs/N) # start, stop, step. centered around 0 Hz
f += center_freq # now add center frequency
#f += center_freq # now add center frequency
fig = plt.figure()
plt.plot(f, PSD_shifted)

Wyświetl plik

@ -11,7 +11,7 @@ build: top.bin
echo "Generating code blob"
../software/utils/generate_bin_blob ./top.bin cariboulite_firmware ./h-files/cariboulite_fpga_firmware.h
echo "Copying dtbo blob h-file to the code directory"
echo "Copying firmware blob to the software lib"
cp ./h-files/cariboulite_fpga_firmware.h ../software/libcariboulite/src/
prog: build

Wyświetl plik

@ -20,13 +20,15 @@ module lvds_rx
localparam
modem_i_sync = 3'b10,
modem_q_sync = 3'b01;
// modem_i_sync = 3'b01,
// modem_q_sync = 3'b10;
// Internal Registers
reg [1:0] r_state_if;
reg [2:0] r_phase_count;
reg [31:0] r_data;
reg r_push;
reg r_cnt;
reg [1:0] r_cnt;
assign o_debug_state = r_state_if;
@ -63,33 +65,38 @@ module lvds_rx
r_phase_count <= 3'b111;
r_push <= 1'b0;
r_data[3:2] <= 2'b11;
r_data[1:0] <= r_cnt;
end
state_i_phase: begin
if (r_phase_count == 3'b000) begin
if (i_ddr_data == modem_q_sync ) begin
r_phase_count <= 3'b110;
r_phase_count <= 3'b111;
r_state_if <= state_q_phase;
end else begin
r_state_if <= state_idle;
end
end else begin
r_phase_count <= r_phase_count - 1;
r_data <= {r_data[29:0], i_ddr_data};
end
r_data <= {r_data[29:0], i_ddr_data};
//r_data <= {r_data[29:0], i_ddr_data};
end
state_q_phase: begin
if (r_phase_count == 3'b000) begin
r_push <= ~i_fifo_full;
r_state_if <= state_idle;
o_fifo_data <= {r_data[29:0], i_ddr_data};
//o_fifo_data <= {r_data[29:0], i_ddr_data};
o_fifo_data <= r_data;
r_cnt <= r_cnt + 1;
end else begin
r_phase_count <= r_phase_count - 1;
r_data <= {r_data[29:0], i_ddr_data};
end
r_data <= {r_data[29:0], i_ddr_data};
//r_data <= {r_data[29:0], i_ddr_data};
end
endcase
end

Plik diff jest za duży Load Diff

Plik binarny nie jest wyświetlany.

Plik diff jest za duży Load Diff

Wyświetl plik

@ -224,12 +224,12 @@ module top(
.PIN_TYPE(6'b000000), // Input only, DDR mode (sample on both pos edge and
// negedge of the input clock)
.IO_STANDARD("SB_LVDS_INPUT"),// LVDS standard
.NEG_TRIGGER(1'b1) // The signal is negated in hardware
.NEG_TRIGGER(1'b0) // The signal is negated in hardware
) iq_rx_09 (
.PACKAGE_PIN(i_iq_rx_09_p),
.INPUT_CLK (lvds_clock_buf), // The I/O sampling clock with DDR
.D_IN_0 ( w_lvds_rx_09_d0 ), // the 0 deg data output
.D_IN_1 ( w_lvds_rx_09_d1 ) );// the 180 deg data output
.D_IN_0 ( w_lvds_rx_09_d1 ), // the 0 deg data output
.D_IN_1 ( w_lvds_rx_09_d0 ) );// the 180 deg data output
//=========================================================================
@ -264,7 +264,7 @@ module top(
// test reversed LSB / MSB
// -----------------------
.i_ddr_data ({w_lvds_rx_09_d1, w_lvds_rx_09_d0}),
//.i_ddr_data ({w_lvds_rx_09_d0, w_lvds_rx_09_d1}),
//.i_ddr_data ({w_lvds_rx_09_d0, w_lvds_rx_09_d1}),
.i_fifo_full (w_rx_09_fifo_full),
.o_fifo_write_clk (w_rx_09_fifo_write_clk),
@ -294,7 +294,7 @@ module top(
.empty_o (w_rx_09_fifo_empty)
);
lvds_rx lvds_rx_24_inst
/*lvds_rx lvds_rx_24_inst
(
.i_reset (w_soft_reset),
.i_ddr_clk (lvds_clock_buf),
@ -328,7 +328,7 @@ module top(
.rd_data_o (w_rx_24_fifo_pulled_data),
.full_o (w_rx_24_fifo_full),
.empty_o (w_rx_24_fifo_empty)
);
);*/
smi_ctrl smi_ctrl_ins
(

Wyświetl plik

@ -23,6 +23,7 @@ add_subdirectory(src/io_utils EXCLUDE_FROM_ALL)
add_subdirectory(src/rffc507x EXCLUDE_FROM_ALL)
add_subdirectory(src/cariboulite_config EXCLUDE_FROM_ALL)
add_subdirectory(src/cariboulite_eeprom EXCLUDE_FROM_ALL)
add_subdirectory(src/production_utils EXCLUDE_FROM_ALL)
add_subdirectory(src/zf_log EXCLUDE_FROM_ALL)
# Create the library LibCaribouLite
@ -37,10 +38,12 @@ target_link_libraries(cariboulite datatypes
io_utils
cariboulite_config
cariboulite_eeprom
production_utils
zf_log
rt
m
pthread)
pthread
iir_static)
target_include_directories(cariboulite PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_compile_options(-Wall -Wextra -Wno-unused-variable -Wno-missing-braces)
@ -84,14 +87,17 @@ SOAPY_SDR_MODULE_UTIL(
set(SOURCES_ICE40_PROGRAMMER test/ice40_programmer.c)
set(SOURCES_FPGA_COMM test/fpga_comm_test.c)
set(SOURCES_MAIN src/cariboulite.c)
set(SOURCES_PROD src/cariboulite_production.c)
add_executable(ice40programmer ${SOURCES_ICE40_PROGRAMMER})
add_executable(fpgacomm ${SOURCES_FPGA_COMM})
add_executable(cariboulite_app ${SOURCES_MAIN})
add_executable(cariboulite_prod ${SOURCES_PROD})
target_link_libraries(ice40programmer cariboulite)
target_link_libraries(fpgacomm cariboulite)
target_link_libraries(cariboulite_app cariboulite)
target_link_libraries(cariboulite_prod cariboulite)
set_target_properties( ice40programmer PROPERTIES RUNTIME_OUTPUT_DIRECTORY test)
set_target_properties( fpgacomm PROPERTIES RUNTIME_OUTPUT_DIRECTORY test)

Wyświetl plik

@ -250,7 +250,7 @@ int caribou_fpga_get_io_ctrl_mode (caribou_fpga_st* dev, uint8_t* debug_mode, ca
}
//--------------------------------------------------------------
int caribou_fpga_set_io_ctrl_dig (caribou_fpga_st* dev, int ldo, int led0, int led1)
int caribou_fpga_set_io_ctrl_dig (caribou_fpga_st* dev, int led0, int led1)
{
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_io_ctrl_dig");
@ -261,12 +261,12 @@ int caribou_fpga_set_io_ctrl_dig (caribou_fpga_st* dev, int ldo, int led0, int l
.ioc = IOC_IO_CTRL_DIG_PIN
};
uint8_t pins = (ldo << 2) | led1<<1 | led0<<0;
uint8_t pins = led1<<1 | led0<<0;
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &pins);
}
//--------------------------------------------------------------
int caribou_fpga_get_io_ctrl_dig (caribou_fpga_st* dev, int* ldo, int* led0, int* led1, int* btn, int* cfg)
int caribou_fpga_get_io_ctrl_dig (caribou_fpga_st* dev, int* led0, int* led1, int* btn, int* cfg)
{
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_get_io_ctrl_dig");
@ -281,7 +281,6 @@ int caribou_fpga_get_io_ctrl_dig (caribou_fpga_st* dev, int* ldo, int* led0, int
caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &pins);
if (led0) *led0 = (pins>>0)&0x01;
if (led1) *led1 = (pins>>1)&0x01;
if (ldo) *ldo = (pins>>2)&0x01;
if (cfg) *cfg = (pins>>3)&0x0F;
if (btn) *btn = (pins>>7)&0x01;

Wyświetl plik

@ -90,8 +90,8 @@ int caribou_fpga_get_errors (caribou_fpga_st* dev, uint8_t *err_map);
int caribou_fpga_set_io_ctrl_mode (caribou_fpga_st* dev, uint8_t debug_mode, caribou_fpga_io_ctrl_rfm_en rfm);
int caribou_fpga_get_io_ctrl_mode (caribou_fpga_st* dev, uint8_t *debug_mode, caribou_fpga_io_ctrl_rfm_en *rfm);
int caribou_fpga_set_io_ctrl_dig (caribou_fpga_st* dev, int ldo, int led0, int led1);
int caribou_fpga_get_io_ctrl_dig (caribou_fpga_st* dev, int *ldo, int *led0, int *led1, int *btn, int *cfg);
int caribou_fpga_set_io_ctrl_dig (caribou_fpga_st* dev, int led0, int led1);
int caribou_fpga_get_io_ctrl_dig (caribou_fpga_st* dev, int *led0, int *led1, int *btn, int *cfg);
int caribou_fpga_set_io_ctrl_pmod_dir (caribou_fpga_st* dev, uint8_t dir);
int caribou_fpga_get_io_ctrl_pmod_dir (caribou_fpga_st* dev, uint8_t *dir);

Wyświetl plik

@ -11,7 +11,6 @@ include_directories(${SUPER_DIR})
set(SOURCES_LIB caribou_smi.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 -pedantic -Werror)
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-missing-braces -O3)
#Generate the static library from the sources

Wyświetl plik

@ -348,9 +348,27 @@ static void set_realtime_priority(int priority_deter)
ZF_LOGI("Thread priority is %d", params.sched_priority);
}
int caribou_smi_search_offset(uint8_t *buff, int len)
{
bool succ = false;
int off = 0;
while (!succ)
{
if ( (buff[off + 0] & 0xC0) == 0xC0 &&
(buff[off + 4] & 0xC0) == 0xC0 &&
(buff[off + 8] & 0xC0) == 0xC0 &&
(buff[off + 12] & 0xC0) == 0xC0 )
return off;
off ++;
}
return -1;
}
//=========================================================================
void* caribou_smi_analyze_thread(void* arg)
{
//static int a = 0;
int current_data_size = 0;
pthread_t tid = pthread_self();
struct timeval tv_pre = {0};
@ -369,6 +387,7 @@ void* caribou_smi_analyze_thread(void* arg)
ZF_LOGD("Entered SMI analysis thread id %lu, running = %d", tid, st->read_analysis_thread_running);
set_realtime_priority(2);
int offset = 0;
while (st->read_analysis_thread_running)
{
pthread_mutex_lock(&st->read_analysis_lock);
@ -376,12 +395,24 @@ void* caribou_smi_analyze_thread(void* arg)
if (!st->read_analysis_thread_running) break;
offset = caribou_smi_search_offset(st->current_app_buffer, 16);
if (offset == -1)
{
ZF_LOGE("Offset error!");
for (int i = 0; i < 60; i+=4)
{
printf("%08X\n", *((uint32_t*)(st->current_app_buffer + i)));
}
}
current_data_size = st->read_ret_value;
if (offset != 0) current_data_size -= 4;
if (st->data_cb) st->data_cb(dev->cb_context,
st->service_context,
type,
ch,
st->read_ret_value,
st->current_app_buffer,
current_data_size,
st->current_app_buffer + offset,
st->batch_length);
gettimeofday(&tv_post, NULL);
@ -408,7 +439,7 @@ void* caribou_smi_analyze_thread(void* arg)
return NULL;
}
#define TIMING_PERF_SYNC (1)
#define TIMING_PERF_SYNC (0)
//=========================================================================
void* caribou_smi_thread(void *arg)
{

Wyświetl plik

@ -67,6 +67,13 @@ typedef enum
cariboulite_ext_ref_src_na = 3, // not applicable
} cariboulite_ext_ref_src_en;
typedef enum
{
cariboulite_sys_status_unintialized = 0,
cariboulite_sys_status_minimal_init = 1,
cariboulite_sys_status_minimal_full_init = 2,
} cariboulite_sys_status_en;
typedef struct
{
cariboulite_ext_ref_src_en src;
@ -102,6 +109,8 @@ typedef struct cariboulite_st_t
caribou_fpga_versions_st fpga_versions;
cariboulite_ext_ref_settings_st ext_ref_settings;
uint8_t fpga_error_status;
cariboulite_sys_status_en system_status;
int fpga_config_res_state;
} cariboulite_st;
int cariboulite_config_detect_board(cariboulite_board_info_st *info);

Wyświetl plik

@ -85,6 +85,7 @@ extern "C" {
.initialized = 0, \
}, \
.reset_fpga_on_startup = 1, \
.system_status = cariboulite_sys_status_unintialized,\
}
#ifdef __cplusplus

Wyświetl plik

@ -629,7 +629,7 @@ static int cariboulite_eeprom_contents_parse(cariboulite_eeprom_st *ee)
}
//===========================================================
static int cariboulite_eeprom_fill_in(cariboulite_eeprom_st *ee)
int cariboulite_eeprom_fill_in(cariboulite_eeprom_st *ee, int prod_id, int prod_ver)
{
struct atom_t *atom = NULL;
uint8_t *location = (uint8_t *)ee->eeprom_buffer_to_write;
@ -649,8 +649,8 @@ static int cariboulite_eeprom_fill_in(cariboulite_eeprom_st *ee)
atom = (struct atom_t*)location;
struct vendor_info_t* vinf = (struct vendor_info_t*)(location + ATOM_HEADER_SIZE);
vinf->pid = 1;
vinf->pver = 1;
vinf->pid = prod_id;
vinf->pver = prod_ver;
vinf->vslen = strlen("CaribouLabs.co");
vinf->pslen = strlen("CaribouLite RPI Hat");
strcpy(VENDOR_VSTR_POINT(vinf), "CaribouLabs.co");
@ -804,18 +804,25 @@ int cariboulite_eeprom_init(cariboulite_eeprom_st *ee)
ee->eeprom_initialized = cariboulite_eeprom_valid(ee);
cariboulite_eeprom_contents_parse(ee);
return 0;
}
//===========================================================
int cariboulite_eeprom_generate_write_config(cariboulite_eeprom_st *ee, int prod_id, int prod_ver)
{
if (!ee->eeprom_initialized)
{
ZF_LOGI("=======================================================");
ZF_LOGI("The EEPROM is not initialized or corrupted");
cariboulite_eeprom_fill_in(ee);
ZF_LOGI("Push the button on the board and hold, then press ENTER to continue...");
getchar();
//ZF_LOGI("=======================================================");
//ZF_LOGI("The EEPROM is not initialized or corrupted");
ZF_LOGI("Filling in EEPROM information");
cariboulite_eeprom_fill_in(ee, prod_id, prod_ver);
//ZF_LOGI("Push the button on the board and hold, then press ENTER to continue...");
//getchar();
ZF_LOGI("Writing into EEPROM");
write_eeprom(ee, ee->eeprom_buffer_to_write, ee->eeprom_buffer_to_write_used_size);
ZF_LOGI("EEPROM configuration Done");
ZF_LOGI("=======================================================");
//ZF_LOGI("EEPROM configuration Done");
//ZF_LOGI("=======================================================");
}
return 0;
}

Wyświetl plik

@ -139,6 +139,8 @@ typedef struct
int cariboulite_eeprom_init(cariboulite_eeprom_st *ee);
int cariboulite_eeprom_close(cariboulite_eeprom_st *ee);
int cariboulite_eeprom_fill_in(cariboulite_eeprom_st *ee, int prod_id, int prod_ver);
int cariboulite_eeprom_print(cariboulite_eeprom_st *ee);
int cariboulite_eeprom_generate_write_config(cariboulite_eeprom_st *ee, int prod_id, int prod_ver);
#endif // __CARIBOU_EEPROM_H__

Wyświetl plik

@ -1,3 +1,183 @@
#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 "CARIBOULITE Prod"
#include "zf_log/zf_log.h"
#include "cariboulite_setup.h"
#include "cariboulite_events.h"
#include "cariboulite.h"
#include "cariboulite_eeprom/cariboulite_eeprom.h"
#include "production_utils/production_utils.h"
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include "cariboulite_production.h"
struct sigaction act;
int program_running = 1;
int signal_shown = 0;
CARIBOULITE_CONFIG_DEFAULT(cariboulite_sys);
//=================================================
int stop_program ()
{
if (program_running) ZF_LOGD("program termination requested");
program_running = 0;
return 0;
}
//=================================================
void sighandler( struct cariboulite_st_t *sys,
void* context,
int signal_number,
siginfo_t *si)
{
if (signal_shown != signal_number)
{
ZF_LOGI("Received signal %d", signal_number);
signal_shown = signal_number;
}
switch (signal_number)
{
case SIGINT:
case SIGTERM:
case SIGABRT:
case SIGILL:
case SIGSEGV:
case SIGFPE: stop_program (); break;
default: return; break;
}
}
//=================================================
cariboulite_eeprom_st ee = { .i2c_address = 0x50, .eeprom_type = eeprom_type_24c32,};
int cariboulite_prod_eeprom_programming(cariboulite_st* sys, cariboulite_eeprom_st* eeprom)
{
int led0 = 0, led1 = 0, btn = 0, cfg = 0;
ZF_LOGI("==============================================");
ZF_LOGI("EEPROM CONFIG - PRESS AND HOLD BUTTON");
int c = 0;
while (1)
{
caribou_fpga_get_io_ctrl_dig (&sys->fpga, &led0, &led1, &btn, &cfg);
if (btn == 0) // pressed
{
ZF_LOGI(" <=== KEEP HOLDING THE BUTTON ====>");
caribou_fpga_set_io_ctrl_dig (&sys->fpga, 1, 1);
break;
}
if (c == 0) caribou_fpga_set_io_ctrl_dig (&sys->fpga, 0, 0);
else if (c == 1) caribou_fpga_set_io_ctrl_dig (&sys->fpga, 0, 1);
else if (c == 2) caribou_fpga_set_io_ctrl_dig (&sys->fpga, 1, 1);
else if (c == 3) caribou_fpga_set_io_ctrl_dig (&sys->fpga, 1, 0);
usleep(200000);
c = (c + 1) % 4;
}
cariboulite_system_type_en type = (cfg&0x1)?cariboulite_system_type_full:cariboulite_system_type_ism;
if (type == cariboulite_system_type_full) ZF_LOGI("Detected CaribouLite FULL Version");
else if (type == cariboulite_system_type_ism) ZF_LOGI("Detected CaribouLite ISM Version");
cariboulite_eeprom_generate_write_config(eeprom, (int)(type), 0x1);
sleep(1);
caribou_fpga_set_io_ctrl_dig (&sys->fpga, 0, 0);
ZF_LOGI(" <=== DONE - YOU CAN RELEASE BUTTON ====>");
return 0;
}
//=================================================
int main(int argc, char *argv[])
{
int ret = 0;
cariboulite_production_utils_rpi_leds_init(1);
cariboulite_production_utils_rpi_leds_blink_start_tests();
cariboulite_production_wifi_status_st wifi_stat;
cariboulite_production_check_wifi_state(&wifi_stat);
printf("Wifi Status: available: %d, wlan_id = %d, ESSID: %s, InternetAccess: %d\n",
wifi_stat.available, wifi_stat.wlan_id, wifi_stat.essid, wifi_stat.internet_access);
cariboulite_rpi_info_st rpi = {0};
cariboulite_production_get_rpi_info(&rpi);
printf("uname: %s, cpu: %s-R%s, sn: %s, model: %s\n", rpi.uname, rpi.cpu_name, rpi.cpu_revision, rpi.cpu_serial_number, rpi.model);
// init the minimal set of drivers and FPGA
cariboulite_board_info_st board_info = {0};
ret = cariboulite_init_driver_minimal(&cariboulite_sys, &board_info);
if (ret != 0)
{
switch(-ret)
{
case cariboulite_board_detection_failed:
ZF_LOGI("This is a new board - board detection failed");
break;
case cariboulite_signal_registration_failed:
cariboulite_production_utils_rpi_leds_blink_fatal_error();
ZF_LOGE("Internal RPI error: Signal registration failed");
break;
case cariboulite_io_setup_failed:
cariboulite_production_utils_rpi_leds_blink_fatal_error();
ZF_LOGE("Internal RPI error: I/O setup failed");
break;
case cariboulite_fpga_configuration_failed:
cariboulite_production_utils_rpi_leds_blink_fatal_error();
ZF_LOGE("FPGA error: couldn't program, read or write");
//set error at: cariboulite_test_en_fpga_programming
break;
default:
break;
}
}
else
{
ZF_LOGI("Driver init seccessfull - the board has already been initialized before");
}
// EEPROM programming
ZF_LOGI("Starting EEPROM programming sequence");
cariboulite_eeprom_init(&ee);
cariboulite_prod_eeprom_programming(&cariboulite_sys, &ee);
cariboulite_eeprom_close(&ee);
ZF_LOGI("Verifying EEPROM");
cariboulite_eeprom_init(&ee);
if (ee.eeprom_initialized == 0)
{
// report eeprom error
}
cariboulite_eeprom_print(&ee);
// Testing the system
///
// setup the signal handler
cariboulite_setup_signal_handler (&cariboulite_sys, sighandler, cariboulite_signal_handler_op_last, &cariboulite_sys);
// dummy loop
sleep(1);
while (program_running)
{
usleep(300000);
}
// close the driver and release resources
cariboulite_production_utils_rpi_leds_init(0);
cariboulite_release_driver(&cariboulite_sys);
return 0;
}

Wyświetl plik

@ -23,7 +23,6 @@ typedef enum
cariboulite_test_en_fpga_leds,
cariboulite_test_en_fpga_versions,
cariboulite_test_en_fpga_communication,
cariboulite_test_en_fpga_programming,
cariboulite_test_en_fpga_smi,
cariboulite_test_en_mixer_reset,
cariboulite_test_en_mixer_communication,
@ -45,13 +44,6 @@ typedef struct
char email[128];
} cariboulite_production_facility_st;
typedef struct
{
char uname[256]; // uname -a
char cpu_name[32]; // cat /proc/cpuinfo
char cpu_serial_number[32];
} cariboulite_rpi_info_st;
typedef struct
{
struct tm start_time_of_test;
@ -59,7 +51,7 @@ typedef struct
cariboulite_test_en test_type;
int test_serial_number;
char test_result[512];
char test_result_textual[512];
uint32_t test_pass;
} cariboulite_production_test_st;

Wyświetl plik

@ -657,7 +657,7 @@ int cariboulite_set_frequency( cariboulite_radios_st* radios,
{
// region #1 - UP CONVERSION
uint32_t modem_freq = CARIBOULITE_2G4_MAX;
if (f_rf > (CARIBOULITE_2G4_MAX/2 - 15e6) && f_rf < (CARIBOULITE_2G4_MAX/2 + 15e6)) modem_freq = CARIBOULITE_2G4_MIN;
//if (f_rf > (CARIBOULITE_2G4_MAX/2 - 15e6) && f_rf < (CARIBOULITE_2G4_MAX/2 + 15e6)) modem_freq = CARIBOULITE_2G4_MIN;
modem_act_freq = (double)at86rf215_setup_channel (&rad->cariboulite_sys->modem,
at86rf215_rf_channel_2400mhz,
modem_freq);
@ -694,11 +694,11 @@ int cariboulite_set_frequency( cariboulite_radios_st* radios,
(uint32_t)(CARIBOULITE_2G4_MIN));
uint32_t lo = f_rf + modem_act_freq;
if (f_rf > (CARIBOULITE_2G4_MIN*2 + CARIBOULITE_MIN_LO)) lo = f_rf - modem_act_freq;
//if (f_rf > (CARIBOULITE_2G4_MIN*2 + CARIBOULITE_MIN_LO)) lo = f_rf - modem_act_freq;
// setup mixer LO to according to actual modem frequency
lo_act_freq = rffc507x_set_frequency(&rad->cariboulite_sys->mixer, f_rf - modem_act_freq);
act_freq = lo_act_freq - modem_act_freq;
if (f_rf > (CARIBOULITE_2G4_MIN*2 + CARIBOULITE_MIN_LO)) act_freq = modem_act_freq + lo_act_freq;
act_freq = lo_act_freq + modem_act_freq;
//if (f_rf > (CARIBOULITE_2G4_MIN*2 + CARIBOULITE_MIN_LO)) act_freq = modem_act_freq + lo_act_freq;
// setup fpga RFFE <= downconvert (tx / rx)
conversion_direction = conversion_dir_down;

Wyświetl plik

@ -157,10 +157,14 @@ void cariboulite_sigaction_basehandler (int signo,
default: break;
}
//getchar();
if (run_last)
{
sigsys->signal_cb(sigsys, sigsys->singal_cb_context, signo, si);
}
exit(0);
}
//=======================================================================================
@ -302,16 +306,6 @@ int cariboulite_init_submodules (cariboulite_st* sys)
{
int res = 0;
ZF_LOGI("initializing submodules");
// FPGA Init
//------------------------------------------------------
ZF_LOGD("INIT FPGA SPI communication");
res = caribou_fpga_init(&sys->fpga, &sys->spi_dev);
if (res < 0)
{
ZF_LOGE("FPGA communication init failed");
goto cariboulite_init_submodules_fail;
}
// SMI Init
//------------------------------------------------------
@ -336,7 +330,6 @@ int cariboulite_init_submodules (cariboulite_st* sys)
// Configure modem
//------------------------------------------------------
ZF_LOGD("Configuring modem initial state");
//at86rf215_set_clock_output(&sys->modem, at86rf215_drive_current_4ma, at86rf215_clock_out_freq_26mhz);
at86rf215_setup_rf_irq(&sys->modem, 0, 1, at86rf215_drive_current_2ma);
at86rf215_radio_set_state(&sys->modem, at86rf215_rf_channel_900mhz, at86rf215_radio_state_cmd_trx_off);
at86rf215_radio_set_state(&sys->modem, at86rf215_rf_channel_2400mhz, at86rf215_radio_state_cmd_trx_off);
@ -375,20 +368,43 @@ int cariboulite_init_submodules (cariboulite_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);
// RFFC5072
//------------------------------------------------------
ZF_LOGD("INIT MIXER - RFFC5072");
res = rffc507x_init(&sys->mixer, &sys->spi_dev);
if (res < 0)
{
ZF_LOGE("Error initializing mixer 'rffc5072'");
goto cariboulite_init_submodules_fail;
}
switch (sys->board_info.sys_type)
{
case cariboulite_system_type_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;
sys->ext_ref_settings.freq_hz = 32000000;
cariboulite_setup_ext_ref (sys, cariboulite_ext_ref_32mhz);
break;
case cariboulite_system_type_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;
cariboulite_setup_ext_ref (sys, cariboulite_ext_ref_off);
default:
ZF_LOGE("Unknown board type - we sheuldn't get here");
break;
}
// Configure mixer
//------------------------------------------------------
//rffc507x_setup_reference_freq(&sys->mixer, 26e6);
rffc507x_calibrate(&sys->mixer);
// The mixer - only relevant to the full version
if (sys->board_info.sys_type == cariboulite_system_type_full)
{
// RFFC5072
//------------------------------------------------------
ZF_LOGD("INIT MIXER - RFFC5072");
res = rffc507x_init(&sys->mixer, &sys->spi_dev);
if (res < 0)
{
ZF_LOGE("Error initializing mixer 'rffc5072'");
goto cariboulite_init_submodules_fail;
}
// Configure mixer
//------------------------------------------------------
//rffc507x_setup_reference_freq(&sys->mixer, 26e6);
rffc507x_calibrate(&sys->mixer);
}
ZF_LOGI("Cariboulite submodules successfully initialized");
return 0;
@ -405,26 +421,6 @@ int cariboulite_self_test(cariboulite_st* sys, cariboulite_self_test_result_st*
memset(res, 0, sizeof(cariboulite_self_test_result_st));
int error_occured = 0;
//------------------------------------------------------
ZF_LOGI("Testing FPGA communication and versions...");
caribou_fpga_get_versions (&sys->fpga, &sys->fpga_versions);
caribou_fpga_get_errors (&sys->fpga, &sys->fpga_error_status);
ZF_LOGI("FPGA Versions: sys: %d, manu.id: %d, sys_ctrl_mod: %d, io_ctrl_mod: %d, smi_ctrl_mot: %d",
sys->fpga_versions.sys_ver,
sys->fpga_versions.sys_manu_id,
sys->fpga_versions.sys_ctrl_mod_ver,
sys->fpga_versions.io_ctrl_mod_ver,
sys->fpga_versions.smi_ctrl_mod_ver);
ZF_LOGI("FPGA Errors: %02X", sys->fpga_error_status);
if (sys->fpga_versions.sys_ver != 0x01 || sys->fpga_versions.sys_manu_id != 0x01)
{
ZF_LOGE("FPGA firmware didn't pass - sys_ver = %02X, manu_id = %02X",
sys->fpga_versions.sys_ver, sys->fpga_versions.sys_manu_id);
res->fpga_fail = 1;
error_occured = 1;
}
//------------------------------------------------------
ZF_LOGI("Testing modem communication and versions");
@ -437,16 +433,20 @@ int cariboulite_self_test(cariboulite_st* sys, cariboulite_self_test_result_st*
error_occured = 1;
}
//------------------------------------------------------
ZF_LOGI("Testing mixer communication and versions");
rffc507x_device_id_st dev_id;
rffc507x_readback_status(&sys->mixer, &dev_id, NULL);
if (dev_id.device_id != 0x1140 && dev_id.device_id != 0x11C0)
{
ZF_LOGE("The assembled mixer is not RFFC5071/2[A]");
res->mixer_fail = 1;
error_occured = 1;
}
//------------------------------------------------------
// Mixer only relevant to the full version
if (sys->board_info.sys_type == cariboulite_system_type_full)
{
ZF_LOGI("Testing mixer communication and versions");
rffc507x_device_id_st dev_id;
rffc507x_readback_status(&sys->mixer, &dev_id, NULL);
if (dev_id.device_id != 0x1140 && dev_id.device_id != 0x11C0)
{
ZF_LOGE("The assembled mixer is not RFFC5071/2[A]");
res->mixer_fail = 1;
error_occured = 1;
}
}
//------------------------------------------------------
ZF_LOGI("Testing smi communication");
@ -468,62 +468,41 @@ int cariboulite_release_submodules(cariboulite_st* sys)
{
int res = 0;
// SMI Module
//------------------------------------------------------
ZF_LOGD("CLOSE SMI");
caribou_smi_close(&sys->smi);
usleep(10000);
// AT86RF215
//------------------------------------------------------
ZF_LOGD("CLOSE MODEM - AT86RF215");
at86rf215_stop_iq_radio_receive (&sys->modem, at86rf215_rf_channel_900mhz);
at86rf215_stop_iq_radio_receive (&sys->modem, at86rf215_rf_channel_2400mhz);
at86rf215_close(&sys->modem);
// RFFC5072
//------------------------------------------------------
ZF_LOGD("CLOSE MIXER - RFFC5072");
rffc507x_release(&sys->mixer);
// FPGA Module
//------------------------------------------------------
ZF_LOGD("CLOSE FPGA communication");
res = caribou_fpga_close(&sys->fpga);
if (res < 0)
{
ZF_LOGE("FPGA communication release failed (%d)", res);
return -1;
}
return 0;
}
//=================================================
int cariboulite_version_dependent_config (cariboulite_st* sys)
{
ZF_LOGI("Performing version dependent configurations");
switch (sys->board_info.sys_type)
if (sys->system_status == cariboulite_sys_status_minimal_full_init)
{
case cariboulite_system_type_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;
sys->ext_ref_settings.freq_hz = 32000000;
cariboulite_setup_ext_ref (sys, cariboulite_ext_ref_32mhz);
break;
case cariboulite_system_type_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;
cariboulite_setup_ext_ref (sys, cariboulite_ext_ref_off);
break;
case cariboulite_system_type_unknown:
default:
ZF_LOGE("This board doesn't have a valid product ID.");
return 0;
break;
// SMI Module
//------------------------------------------------------
ZF_LOGD("CLOSE SMI");
caribou_smi_close(&sys->smi);
usleep(10000);
// AT86RF215
//------------------------------------------------------
ZF_LOGD("CLOSE MODEM - AT86RF215");
at86rf215_stop_iq_radio_receive (&sys->modem, at86rf215_rf_channel_900mhz);
at86rf215_stop_iq_radio_receive (&sys->modem, at86rf215_rf_channel_2400mhz);
at86rf215_close(&sys->modem);
//------------------------------------------------------
// RFFC5072 only relevant to the full version
if (sys->board_info.sys_type == cariboulite_system_type_full)
{
ZF_LOGD("CLOSE MIXER - RFFC5072");
rffc507x_release(&sys->mixer);
}
}
if (sys->system_status == cariboulite_sys_status_minimal_init)
{
// FPGA Module
//------------------------------------------------------
ZF_LOGD("CLOSE FPGA communication");
res = caribou_fpga_close(&sys->fpga);
if (res < 0)
{
ZF_LOGE("FPGA communication release failed (%d)", res);
return -1;
}
}
return 0;
@ -544,12 +523,20 @@ static int cariboulite_register_many_signals(int *sig_nos, int nsigs, struct sig
}
//=================================================
int cariboulite_init_driver(cariboulite_st *sys, cariboulite_board_info_st *info)
int cariboulite_init_driver_minimal(cariboulite_st *sys, cariboulite_board_info_st *info)
{
//zf_log_set_output_level(ZF_LOG_ERROR);
//zf_log_set_output_level(ZF_LOG_ERROR);
zf_log_set_output_level(ZF_LOG_VERBOSE);
ZF_LOGI("driver initializing");
if (sys->system_status != cariboulite_sys_status_unintialized)
{
ZF_LOGE("System is already initialized! returnig");
return 0;
}
// signals
ZF_LOGI("Initializing signals");
cariboulite_setup_signal_handler (sys, NULL, cariboulite_signal_handler_op_last, NULL);
int signals[] = {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV, SIGTERM};
@ -559,19 +546,72 @@ int cariboulite_init_driver(cariboulite_st *sys, cariboulite_board_info_st *info
sa.sa_sigaction = cariboulite_sigaction_basehandler;
sa.sa_flags |= SA_RESTART | SA_SIGINFO;
// RPI Internal Configurations
if(cariboulite_register_many_signals(signals, sizeof(signals)/sizeof(signals[0]), &sa) != 0)
{
ZF_LOGE("error signal list registration");
return -cariboulite_signal_registration_failed;
}
ZF_LOGI("driver initializing");
if (cariboulite_setup_io (sys) != 0)
{
return -cariboulite_io_setup_failed;
}
// External Configurations
// FPGA Init
//------------------------------------------------------
if (cariboulite_configure_fpga (sys, cariboulite_firmware_source_blob, NULL/*sys->firmware_path_operational*/) != 0)
{
cariboulite_release_io (sys);
return -cariboulite_fpga_configuration_failed;
}
ZF_LOGD("INIT FPGA SPI communication");
if (caribou_fpga_init(&sys->fpga, &sys->spi_dev) < 0)
{
ZF_LOGE("FPGA communication init failed");
cariboulite_release_io (sys);
return -cariboulite_fpga_configuration_failed;
}
ZF_LOGI("Testing FPGA communication and versions...");
caribou_fpga_get_versions (&sys->fpga, &sys->fpga_versions);
caribou_fpga_get_errors (&sys->fpga, &sys->fpga_error_status);
ZF_LOGI("FPGA Versions: sys: %d, manu.id: %d, sys_ctrl_mod: %d, io_ctrl_mod: %d, smi_ctrl_mot: %d",
sys->fpga_versions.sys_ver,
sys->fpga_versions.sys_manu_id,
sys->fpga_versions.sys_ctrl_mod_ver,
sys->fpga_versions.io_ctrl_mod_ver,
sys->fpga_versions.smi_ctrl_mod_ver);
ZF_LOGI("FPGA Errors: %02X", sys->fpga_error_status);
if (sys->fpga_versions.sys_ver != 0x01 || sys->fpga_versions.sys_manu_id != 0x01)
{
ZF_LOGE("FPGA firmware varsion error - sys_ver = %02X, manu_id = %02X",
sys->fpga_versions.sys_ver, sys->fpga_versions.sys_manu_id);
caribou_fpga_close(&sys->fpga);
cariboulite_release_io (sys);
return -cariboulite_fpga_configuration_failed;
}
// Now read the configuration from the FPGA (resistor set)
//caribou_fpga_set_io_ctrl_dig (&sys->fpga, int ldo, int led0, int led1);
int led0 = 0, led1 = 0, btn = 0, cfg = 0;
caribou_fpga_get_io_ctrl_dig (&sys->fpga, &led0, &led1, &btn, &cfg);
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;
ZF_LOGI("Detected Board Information:");
if (info == NULL)
{
int detected = cariboulite_config_detect_board(&sys->board_info);
if (!detected)
{
ZF_LOGE("The RPI HAT interface didn't detect any connected boards");
ZF_LOGW("The RPI HAT interface didn't detect any connected boards");
caribou_fpga_close(&sys->fpga);
cariboulite_release_io (sys);
return -cariboulite_board_detection_failed;
}
}
@ -579,39 +619,48 @@ int cariboulite_init_driver(cariboulite_st *sys, cariboulite_board_info_st *info
{
memcpy(&sys->board_info, info, sizeof(cariboulite_board_info_st));
}
ZF_LOGI("Detected Board Information:");
cariboulite_config_print_board_info(&sys->board_info);
if (cariboulite_setup_io (sys) != 0)
{
return -cariboulite_io_setup_failed;
}
if (cariboulite_configure_fpga (sys, cariboulite_firmware_source_blob, NULL/*sys->firmware_path_operational*/) != 0)
{
cariboulite_release_io (sys);
return -cariboulite_fpga_configuration_failed;
}
sys->system_status = cariboulite_sys_status_minimal_init;
return cariboulite_ok;
}
//=================================================
int cariboulite_init_driver(cariboulite_st *sys, cariboulite_board_info_st *info)
{
int ret = cariboulite_init_driver_minimal(sys, info);
if (ret < 0)
{
return ret;
}
if (sys->system_status == cariboulite_sys_status_minimal_full_init)
{
ZF_LOGE("System is already fully initialized! returnig");
return 0;
}
// INIT other sub-modules
if (cariboulite_init_submodules (sys) != 0)
{
caribou_fpga_close(&sys->fpga);
cariboulite_release_io (sys);
return -cariboulite_submodules_init_failed;
}
if (cariboulite_version_dependent_config(sys))
{
cariboulite_release_io (sys);
return -cariboulite_board_dependent_config_failed;
}
// Self-Test
cariboulite_self_test_result_st self_tes_res = {0};
if (cariboulite_self_test(sys, &self_tes_res) != 0)
{
caribou_fpga_close(&sys->fpga);
cariboulite_release_io (sys);
return -cariboulite_self_test_failed;
}
sys->system_status = cariboulite_sys_status_minimal_full_init;
return cariboulite_ok;
}
@ -634,9 +683,13 @@ int cariboulite_setup_signal_handler (cariboulite_st *sys,
void cariboulite_release_driver(cariboulite_st *sys)
{
ZF_LOGI("driver being released");
if (sys->system_status != cariboulite_sys_status_unintialized)
{
cariboulite_release_submodules(sys);
cariboulite_release_io (sys);
cariboulite_release_submodules(sys);
cariboulite_release_io (sys);
sys->system_status = cariboulite_sys_status_unintialized;
}
ZF_LOGI("driver released");
}

Wyświetl plik

@ -63,6 +63,7 @@ typedef enum
} cariboulite_ext_ref_freq_en;
int cariboulite_init_driver(cariboulite_st *sys, cariboulite_board_info_st *info);
int cariboulite_init_driver_minimal(cariboulite_st *sys, cariboulite_board_info_st *info);
int cariboulite_setup_signal_handler (cariboulite_st *sys,
caribou_signal_handler handler,
cariboulite_signal_handler_operation_en op,
@ -74,11 +75,9 @@ int cariboulite_setup_io (cariboulite_st* sys);
int cariboulite_release_io (cariboulite_st* sys);
int cariboulite_configure_fpga (cariboulite_st* sys, cariboulite_firmware_source_en src, char* fpga_bin_path);
int cariboulite_init_submodules (cariboulite_st* sys);
int cariboulite_version_dependent_config (cariboulite_st* sys);
int cariboulite_release_submodules(cariboulite_st* sys);
int cariboulite_self_test(cariboulite_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( cariboulite_st *sys,
cariboulite_channel_en ch,
cariboulite_channel_dir_en dir,

Wyświetl plik

@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.15)
project(cariboulite)
set(CMAKE_BUILD_TYPE Release)
#Bring the headers, such as Student.h into the project
set(SUPER_DIR ${PROJECT_SOURCE_DIR}/..)
include_directories(/.)
include_directories(${SUPER_DIR})
#However, the file(GLOB...) allows for wildcard additions:
set(SOURCES_LIB production_utils.c)
#add_compile_options(-Wall -Wextra -pedantic -Werror)
add_compile_options(-Wall -Wextra -Wno-missing-braces)
#Generate the static library from the sources
add_library(production_utils STATIC ${SOURCES_LIB})
target_include_directories(production_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

Wyświetl plik

@ -0,0 +1,217 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdbool.h>
#include <string.h>
#include <sys/wait.h>
#include "production_utils.h"
int cariboulite_production_utils_rpi_leds_init(int state)
{
FILE* trigger_green = fopen("/sys/class/leds/led0/trigger", "w");
if (trigger_green == NULL)
{
printf("Production Utils 'cariboulite_production_utils_rpi_leds_init' ERROR: couldn't open internal LED0\n");
return -1;
}
FILE* trigger_red = fopen("/sys/class/leds/led1/trigger", "w");
if (trigger_red == NULL)
{
printf("Production Utils 'cariboulite_production_utils_rpi_leds_init' ERROR: couldn't open internal LED1\n");
fclose(trigger_green);
return -1;
}
if (state == 1) // operation mode for gpio
{
fprintf(trigger_green, "gpio");
fprintf(trigger_red, "gpio");
}
else
{
fprintf(trigger_green, "mmc0");
fprintf(trigger_red, "actpwr");
}
fclose(trigger_red);
fclose(trigger_green);
return 0;
}
int cariboulite_production_utils_rpi_leds_set_state(int led_green, int led_red)
{
if (led_green != -1)
{
FILE* fid = fopen("/sys/class/leds/led0/brightness", "w");
if (fid == NULL)
{
printf("Production Utils 'cariboulite_production_utils_rpi_leds_set_state' error ctrling LED green\n");
return -1;
}
if (led_green > 0) led_green = 1;
fprintf(fid, "%d", led_green);
fclose(fid);
}
if (led_red != -1)
{
FILE* fid = fopen("/sys/class/leds/led1/brightness", "w");
if (fid == NULL)
{
printf("Production Utils 'cariboulite_production_utils_rpi_leds_set_state' error ctrling LED red\n");
return -1;
}
if (led_red > 0) led_red = 1;
fprintf(fid, "%d", led_red);
fclose(fid);
}
return 0;
}
void cariboulite_production_utils_rpi_leds_blink_start_tests(void)
{
int val = 0;
int N_cycles = 20;
cariboulite_production_utils_rpi_leds_set_state(0, 0);
usleep(1000000);
cariboulite_production_utils_rpi_leds_set_state(1, 1);
usleep(2000000);
for (int i = 0; i < N_cycles; i++)
{
cariboulite_production_utils_rpi_leds_set_state(val, -1);
usleep(50000);
cariboulite_production_utils_rpi_leds_set_state(-1, val);
usleep(50000);
cariboulite_production_utils_rpi_leds_set_state(-1, -1);
usleep(50000);
val = !val;
}
}
void cariboulite_production_utils_rpi_leds_blink_fatal_error(void)
{
int val = 1;
int N_cycles = 30;
for (int i = 0; i < N_cycles; i++)
{
cariboulite_production_utils_rpi_leds_set_state(val, val);
usleep(150000);
val = !val;
}
}
static int cariboulite_production_execute_command(char **argv)
{
pid_t pid;
int status;
if ((pid = fork()) < 0) { // fork a child process
printf("*** ERROR: forking child process failed\n");
exit(1);
}
else if (pid == 0) { // for the child process:
if (execvp(*argv, argv) < 0) { // execute the command
printf("*** ERROR: exec failed\n");
exit(1);
}
}
else { /* for the parent: */
while (wait(&status) != pid) /* wait for completion */
;
}
return status;
}
static int cariboulite_production_execute_command_read(char *cmd, char* res, int res_size)
{
int i = 0;
FILE *p = popen(cmd,"r");
if (p != NULL )
{
while (!feof(p) && (i < res_size) )
{
fread(&res[i++],1,1,p);
}
res[i] = 0;
//printf("%s",res);
pclose(p);
return 0;
}
else
{
return -1;
}
}
int cariboulite_production_check_wifi_state(cariboulite_production_wifi_status_st* wifi_stat)
{
char res[100] = {0};
cariboulite_production_execute_command_read("/usr/sbin/iwgetid", res, 99);
if (wifi_stat == NULL) return 0;
wifi_stat->internet_access = false;
if (strlen(res)<1)
{
wifi_stat->available = false;
wifi_stat->wlan_id = -1;
strcpy(wifi_stat->essid, "");
return -1;
}
else
{
wifi_stat->available = true;
char* wlan_id = strstr(res, "wlan");
char* essid = strstr(res, "ESSID:");
wifi_stat->wlan_id = atoi(wlan_id + strlen("wlan"));
strcpy(wifi_stat->essid, essid + strlen("ESSID:") + 1);
wifi_stat->essid[strlen(wifi_stat->essid)-2] = '\0';
}
cariboulite_production_execute_command_read("/usr/bin/curl -s -I https://linuxhint.com/", res, 99);
char* inter = strstr(res, "HTTP/2 200");
if (inter != NULL) wifi_stat->internet_access = true;
return 0;
}
int cariboulite_production_get_rpi_info(cariboulite_rpi_info_st* rpi)
{
char res[1024] = {0};
cariboulite_production_execute_command_read("/usr/bin/uname -a", rpi->uname, 255);
cariboulite_production_execute_command_read("/usr/bin/cat /proc/cpuinfo", res, 1023);
strtok(rpi->uname, "\n");
char* Serial = strstr(res, "Serial");
char* Model = strstr(res, "Model");
char* CPU = strstr(res, "Hardware");
char* Revision = strstr(res, "Revision");
Serial = strstr(Serial,": ") + 2; strtok(Serial, " \n");
Model = strstr(Model,": ") + 2; strtok(Model, "\n");
CPU = strstr(CPU,": ") + 2; strtok(CPU, " \n");
Revision = strstr(Revision,": ") + 2; strtok(Revision, " \n");
sprintf(rpi->cpu_revision, "%s", Revision);
sprintf(rpi->cpu_name, "%s", CPU);
sprintf(rpi->model, "%s", Model);
sprintf(rpi->cpu_serial_number, "%s", Serial);
return 0;
}

Wyświetl plik

@ -0,0 +1,38 @@
#ifndef __PRODUCTION_UTILS_H__
#define __PRODUCTION_UTILS_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
bool available;
int wlan_id;
char essid[512];
bool internet_access;
} cariboulite_production_wifi_status_st;
typedef struct
{
char uname[256]; // uname -a
char cpu_name[32]; // cat /proc/cpuinfo
char cpu_revision[32];
char model[64];
char cpu_serial_number[32];
} cariboulite_rpi_info_st;
int cariboulite_production_utils_rpi_leds_init(int state);
int cariboulite_production_utils_rpi_leds_set_state(int led_green, int led_red);
void cariboulite_production_utils_rpi_leds_blink_fatal_error(void);
void cariboulite_production_utils_rpi_leds_blink_start_tests(void);
int cariboulite_production_check_wifi_state(cariboulite_production_wifi_status_st* wifi_stat);
int cariboulite_production_get_rpi_info(cariboulite_rpi_info_st* rpi);
#ifdef __cplusplus
}
#endif
#endif //__PRODUCTION_UTILS_H__

Wyświetl plik

@ -149,8 +149,8 @@ int rffc507x_init( rffc507x_st* dev,
set_RFFC507X_P2CTV(dev, 12);
set_RFFC507X_P1CTV(dev, 12);
set_RFFC507X_RGBYP(dev, 1);
set_RFFC507X_P2MIXIDD(dev, 6);
set_RFFC507X_P1MIXIDD(dev, 6);
set_RFFC507X_P2MIXIDD(dev, 4);
set_RFFC507X_P1MIXIDD(dev, 4);
// Others
set_RFFC507X_LDEN(dev, 1);

Wyświetl plik

@ -382,17 +382,25 @@ static double convertTxBandwidth(at86rf215_radio_tx_cut_off_en bw_en)
//========================================================
void Cariboulite::setBandwidth( const int direction, const size_t channel, const double bw )
{
//printf("setBandwidth dir: %d, channel: %ld, bw: %.2f\n", direction, channel, bw);
int filt = 0;
double setbw = bw;
if (bw == 200000.0f) filt = 4;
else if (bw == 100000.0f) filt = 3;
else if (bw == 50000.0f) filt = 2;
else if (bw == 20000.0f) filt = 1;
if (setbw < 200000) setbw = 200000;
if (direction == SOAPY_SDR_RX)
{
cariboulite_set_rx_bandwidth(&radios,(cariboulite_channel_en)channel,
convertRxBandwidth(bw));
cariboulite_set_rx_bandwidth(&radios,(cariboulite_channel_en)channel, convertRxBandwidth(setbw));
if (channel == 0) sample_queues[2]->dig_filt = filt;
else if (channel == 1) sample_queues[3]->dig_filt = filt;
}
else if (direction == SOAPY_SDR_TX)
{
cariboulite_set_tx_bandwidth(&radios,(cariboulite_channel_en)channel,
convertTxBandwidth(bw));
convertTxBandwidth(setbw));
}
}
@ -424,6 +432,9 @@ std::vector<double> Cariboulite::listBandwidths( const int direction, const size
if (direction == SOAPY_SDR_RX)
{
float fact = BW_SHIFT_FACT;
options.push_back( 20000 );
options.push_back( 50000 );
options.push_back( 100000 );
options.push_back( 160000*fact );
options.push_back( 200000*fact );
options.push_back( 250000*fact );

Wyświetl plik

@ -13,6 +13,7 @@
#include <cstring>
#include <algorithm>
#include <atomic>
#include <Iir.h>
//#define ZF_LOG_LEVEL ZF_LOG_ERROR
#define ZF_LOG_LEVEL ZF_LOG_VERBOSE
@ -53,8 +54,8 @@ typedef struct
// associated with CS16 - total 4 bytes / element
typedef struct
{
int16_t i; // LSB
int16_t q; // MSB
int16_t i; // LSB
int16_t q; // MSB
} sample_complex_int16;
// associated with CS32 - total 8 bytes / element
@ -111,6 +112,7 @@ public:
int stream_channel;
int is_cw;
Cariboulite_Format chosen_format;
int dig_filt;
private:
tsqueue_st queue;
size_t mtu_size_bytes;
@ -119,6 +121,18 @@ private:
int partial_buffer_length;
sample_complex_int16 *interm_native_buffer;
#define FILT_ORDER 6
#define FILT_ORDER1 8
Iir::Butterworth::LowPass<FILT_ORDER> filt20_i;
Iir::Butterworth::LowPass<FILT_ORDER> filt20_q;
Iir::Butterworth::LowPass<FILT_ORDER> filt50_i;
Iir::Butterworth::LowPass<FILT_ORDER> filt50_q;
Iir::Butterworth::LowPass<FILT_ORDER> filt100_i;
Iir::Butterworth::LowPass<FILT_ORDER> filt100_q;
Iir::Butterworth::LowPass<FILT_ORDER> filt200_i;
Iir::Butterworth::LowPass<FILT_ORDER> filt200_q;
Iir::Butterworth::LowPass<FILT_ORDER1> filt2p5M_i;
Iir::Butterworth::LowPass<FILT_ORDER1> filt2p5M_q;
};
/***********************************************************************

Wyświetl plik

@ -1,6 +1,53 @@
#include "Cariboulite.hpp"
#include <Iir.h>
class CircFifo
{
private:
sample_complex_int16 *buffer;
uint32_t in;
uint32_t out;
uint32_t size;
public:
CircFifo(uint32_t _size)
{
if (!is_power_of_2(_size))
_size = roundup_power_of_2(_size);
buffer = new sample_complex_int16[_size];
in = 0;
out = 0;
size = _size;
}
~CircFifo()
{
delete []buffer;
}
uint32_t put(const uint8_t *data, uint32_t len)
{
len = min(len, size - in + out);
auto l = min(len, size - (in & (size - 1)));
memcpy(buffer + (in & (size - 1)), data, l);
memcpy(buffer, data + l, len - l);
in += len;
return len;
}
uint32_t get(uint8_t *data, uint32_t len)
{
len = min(len, in - out);
auto l = min(len, size - (out & (size - 1)));
memcpy(data, buffer + (out & (size - 1)), l);
memcpy(data + l, buffer, len - l);
out += len;
return len;
}
}
//==============================================
void print_iq(uint32_t* array, int len)
{
@ -36,11 +83,24 @@ SampleQueue::SampleQueue(int mtu_bytes, int num_buffers)
partial_buffer = new uint8_t[mtu_size_bytes];
partial_buffer_start = mtu_size_bytes;
partial_buffer_length = 0;
dig_filt = 0;
// a buffer for conversion betwen native and emulated formats
// the maximal size is the 2*(mtu_size in bytes)
interm_native_buffer = new sample_complex_int16[2*mtu_size_bytes];
is_cw = 0;
filt20_i.setup(4e6, 20e3/2);
filt50_i.setup(4e6, 50e3/2);
filt100_i.setup(4e6, 100e3/2);
filt200_i.setup(4e6, 200e3/2);
filt2p5M_i.setup(4e6, 2.5e6/2);
filt20_q.setup(4e6, 20e3/2);
filt50_q.setup(4e6, 50e3/2);
filt100_q.setup(4e6, 100e3/2);
filt200_q.setup(4e6, 200e3/2);
filt2p5M_q.setup(4e6, 2.5e6/2);
}
//=================================================================
@ -188,19 +248,25 @@ int SampleQueue::ReadSamples(sample_complex_int16* buffer, size_t num_elements,
// todo!!
return res;
}
/*if (once)
{
print_iq((uint32_t*) buffer, 5);
once--;
}*/
int tot_read_elements = res / sizeof(sample_complex_int16);
// shift q
//buffer[0].q = last_q;
for (int i = 1; i < tot_read_elements; i++)
/*for (int i = 1; i < tot_read_elements; i++)
{
buffer[i-1].q = buffer[i].q;
}
}*/
/*for (int i = 1; i < tot_read_elements; i+=2)
{
short t = buffer[i].i;
buffer[i].i = buffer[i+1].i;
buffer[i+1].i = t;
t = buffer[i].q;
buffer[i].q = buffer[i+1].q;
buffer[i+1].q = t;
}*/
/*for (int i = tot_read_elements-1; i >= 0; i--)
{
@ -217,12 +283,51 @@ int SampleQueue::ReadSamples(sample_complex_int16* buffer, size_t num_elements,
if (buffer[i].i >= (int16_t)0x1000) buffer[i].i -= (int16_t)0x2000;
if (buffer[i].q >= (int16_t)0x1000) buffer[i].q -= (int16_t)0x2000;
/*if (i<5)
{
printf("i: %d, q: %d\n", buffer[i].i, buffer[i].q);
}*/
}
return tot_read_elements;
if (dig_filt == 0)
{
for (int i = 0; i < res; i++)
{
buffer[i].i = (int16_t)filt2p5M_i.filter((float)buffer[i].i);
buffer[i].q = (int16_t)filt2p5M_q.filter((float)buffer[i].q);
}
}
else if (dig_filt == 1)
{
for (int i = 0; i < res; i++)
{
buffer[i].i = (int16_t)filt20_i.filter((float)buffer[i].i);
buffer[i].q = (int16_t)filt20_q.filter((float)buffer[i].q);
}
}
else if (dig_filt == 2)
{
for (int i = 0; i < res; i++)
{
buffer[i].i = (int16_t)filt50_i.filter((float)buffer[i].i);
buffer[i].q = (int16_t)filt50_q.filter((float)buffer[i].q);
}
}
else if (dig_filt == 3)
{
for (int i = 0; i < res; i++)
{
buffer[i].i = (int16_t)filt100_i.filter((float)buffer[i].i);
buffer[i].q = (int16_t)filt100_q.filter((float)buffer[i].q);
}
}
else if (dig_filt == 4)
{
for (int i = 0; i < res; i++)
{
buffer[i].i = (int16_t)filt200_i.filter((float)buffer[i].i);
buffer[i].q = (int16_t)filt200_q.filter((float)buffer[i].q);
}
}
return tot_read_elements;
}
@ -269,7 +374,7 @@ int SampleQueue::ReadSamples(sample_complex_float* buffer, size_t num_elements,
buffer[i].q -= sumQ;
}
double theta1 = 0.0;
/*double theta1 = 0.0;
double theta2 = 0.0;
double theta3 = 0.0;
for (int i = 0; i < res; i++)
@ -293,7 +398,7 @@ int SampleQueue::ReadSamples(sample_complex_float* buffer, size_t num_elements,
float qq = buffer[i].q;
buffer[i].i = c2 * ii;
buffer[i].q = c1 * ii + qq;
}
}*/
return res;
}