kopia lustrzana https://github.com/cariboulabs/cariboulite
updates
rodzic
b314b7a644
commit
880c561a10
|
@ -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})
|
||||
|
|
|
@ -39,6 +39,8 @@ sys/types.h
|
|||
-
|
||||
sys/stat.h
|
||||
-
|
||||
Iir.h
|
||||
-
|
||||
modes.h
|
||||
/home/pi/projects/cariboulite/examples/cpp/modes.h
|
||||
|
||||
|
|
|
@ -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.
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -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
|
||||
|
|
18113
firmware/top.asc
18113
firmware/top.asc
Plik diff jest za duży
Load Diff
BIN
firmware/top.bin
BIN
firmware/top.bin
Plik binarny nie jest wyświetlany.
16761
firmware/top.json
16761
firmware/top.json
Plik diff jest za duży
Load Diff
|
@ -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
|
||||
(
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -85,6 +85,7 @@ extern "C" {
|
|||
.initialized = 0, \
|
||||
}, \
|
||||
.reset_fpga_on_startup = 1, \
|
||||
.system_status = cariboulite_sys_status_unintialized,\
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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__
|
Plik diff jest za duży
Load Diff
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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})
|
|
@ -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;
|
||||
}
|
|
@ -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__
|
|
@ -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);
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue