kopia lustrzana https://github.com/cariboulabs/cariboulite
firmware update - syncs, ioctrl, smi_ctrl(dir and channel)
fpga driver update smi_stream_driver update thanks to @matteoserva great workgr-cariboulite_tag_samples
rodzic
80faa75c1f
commit
96828b4bcc
|
@ -152,6 +152,7 @@ static const char *const ioctl_names[] =
|
|||
static void write_smi_reg(struct bcm2835_smi_instance *inst, u32 val, unsigned reg)
|
||||
{
|
||||
writel(val, inst->smi_regs_ptr + reg);
|
||||
mb();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -211,46 +212,50 @@ static inline int smi_is_active(struct bcm2835_smi_instance *inst)
|
|||
return read_smi_reg(inst, SMICS) & SMICS_ACTIVE;
|
||||
}
|
||||
|
||||
static long set_state(smi_stream_state_en new_state)
|
||||
static int set_state(smi_stream_state_en new_state)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned int new_address = calc_address_from_state(new_state);
|
||||
|
||||
if (inst == NULL) return 0;
|
||||
dev_info(inst->dev, "Set STREAMING_STATUS = %d, cur_addr = %d", new_state, new_address);
|
||||
|
||||
spin_lock(&inst->state_lock);
|
||||
|
||||
if(new_state == inst->state)
|
||||
|
||||
// in any case if we want to change the state
|
||||
// then stop the current transfer and update the new state.
|
||||
if(new_state != inst->state)
|
||||
{
|
||||
spin_unlock(&inst->state_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_info(inst->dev, "Set STREAMING_STATUS = %d, cur_addr = %d", new_state, new_address);
|
||||
|
||||
if(inst->state != smi_stream_idle)
|
||||
{
|
||||
//exiting from current state
|
||||
if (inst->state == smi_stream_tx_channel)
|
||||
{
|
||||
transfer_thread_stop(inst);
|
||||
}
|
||||
else
|
||||
{
|
||||
transfer_thread_stop(inst);
|
||||
}
|
||||
// stop the transter
|
||||
transfer_thread_stop(inst);
|
||||
|
||||
if(smi_is_active(inst->smi_inst))
|
||||
{
|
||||
spin_unlock(&inst->state_lock);
|
||||
return -EAGAIN;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
// update the state from current state
|
||||
inst->state = smi_stream_idle;
|
||||
bcm2835_smi_set_address(inst->smi_inst, calc_address_from_state(smi_stream_idle));
|
||||
bcm2835_smi_set_address(inst->smi_inst, calc_address_from_state(smi_stream_idle));
|
||||
|
||||
ret = 0;
|
||||
//now state is idle
|
||||
}
|
||||
//now state is idle
|
||||
|
||||
if(new_state != smi_stream_idle)
|
||||
// else if the state is the same, do nothing
|
||||
else
|
||||
{
|
||||
int ret = -1;
|
||||
bcm2835_smi_set_address(inst->smi_inst, new_address);
|
||||
spin_unlock(&inst->state_lock);
|
||||
dev_info(inst->dev, "State is the same as before");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Only if the new state is not idle (rx0, rx1 ot tx) setup a new transfer
|
||||
if(new_state != smi_stream_idle)
|
||||
{
|
||||
bcm2835_smi_set_address(inst->smi_inst, new_address);
|
||||
|
||||
if (new_state == smi_stream_tx_channel)
|
||||
{
|
||||
ret = transfer_thread_init(inst,DMA_MEM_TO_DEV,stream_smi_write_dma_callback);
|
||||
|
@ -260,21 +265,24 @@ static long set_state(smi_stream_state_en new_state)
|
|||
ret = transfer_thread_init(inst,DMA_DEV_TO_MEM,stream_smi_read_dma_callback);
|
||||
}
|
||||
|
||||
if(!ret)
|
||||
// if starting the transfer succeeded update the state
|
||||
if (!ret)
|
||||
{
|
||||
inst->state = new_state;
|
||||
inst->state = new_state;
|
||||
}
|
||||
// if failed, go back to idle
|
||||
else
|
||||
{
|
||||
bcm2835_smi_set_address(inst->smi_inst, calc_address_from_state(smi_stream_idle));
|
||||
inst->state = smi_stream_idle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
mb();
|
||||
|
||||
spin_unlock(&inst->state_lock);
|
||||
return 0;
|
||||
|
||||
// return the success
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -297,25 +305,26 @@ static inline int smi_enabled(struct bcm2835_smi_instance *inst)
|
|||
|
||||
static int smi_disable_sync(struct bcm2835_smi_instance *smi_inst)
|
||||
{
|
||||
int smics_temp;
|
||||
int smics_temp = 0;
|
||||
int success = 0;
|
||||
int errors = 0;
|
||||
dev_info(inst->dev, "smi disable sync enter");
|
||||
//dev_info(inst->dev, "smi disable sync enter");
|
||||
|
||||
/* Disable the peripheral: */
|
||||
smics_temp = read_smi_reg(smi_inst, SMICS) & ~(SMICS_ENABLE | SMICS_WRITE);
|
||||
write_smi_reg(smi_inst, smics_temp, SMICS);
|
||||
|
||||
// wait for the ENABLE to go low
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_enabled(smi_inst), 1000000U, success);
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_enabled(smi_inst), 100000U, success);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
dev_info(inst->dev, "errore disable. %u %08X",smi_enabled(smi_inst),read_smi_reg(smi_inst, SMICS));
|
||||
//dev_info(inst->dev, "error disable sync. %u %08X", smi_enabled(smi_inst), read_smi_reg(smi_inst, SMICS));
|
||||
errors = -1;
|
||||
}
|
||||
|
||||
print_smil_registers();
|
||||
dev_info(inst->dev, "smi disable sync exit");
|
||||
//print_smil_registers();
|
||||
//dev_info(inst->dev, "smi disable sync exit");
|
||||
|
||||
return errors;
|
||||
|
||||
|
@ -323,7 +332,7 @@ static int smi_disable_sync(struct bcm2835_smi_instance *smi_inst)
|
|||
|
||||
static void smi_refresh_dma_command(struct bcm2835_smi_instance *smi_inst, int num_transfers)
|
||||
{
|
||||
int smics_temp;
|
||||
int smics_temp = 0;
|
||||
//print_smil_registers_ext("refresh 1");
|
||||
write_smi_reg(smi_inst, SMI_TRANSFER_MULTIPLIER*num_transfers, SMIL); //to avoid stopping and restarting
|
||||
//print_smil_registers_ext("refresh 2");
|
||||
|
@ -339,34 +348,38 @@ static void smi_refresh_dma_command(struct bcm2835_smi_instance *smi_inst, int n
|
|||
/***************************************************************************/
|
||||
static int smi_init_programmed_transfer(struct bcm2835_smi_instance *smi_inst, enum dma_transfer_direction dma_dir,int num_transfers)
|
||||
{
|
||||
int smics_temp;
|
||||
int smics_temp = 0;
|
||||
int success = 0;
|
||||
|
||||
dev_info(inst->dev, "smi_init_programmed_read");
|
||||
dev_info(inst->dev, "smi_init_programmed_transfer");
|
||||
print_smil_registers_ext("init 1");
|
||||
|
||||
write_smi_reg(inst->smi_inst, 0, SMIL);
|
||||
write_smi_reg(inst->smi_inst, 0x0, SMIL);
|
||||
|
||||
print_smil_registers_ext("init 2");
|
||||
smics_temp = read_smi_reg(smi_inst, SMICS);
|
||||
|
||||
/* Program the transfer count: */
|
||||
write_smi_reg(smi_inst, num_transfers, SMIL);
|
||||
print_smil_registers_ext("init 3");
|
||||
|
||||
print_smil_registers_ext("init 3");
|
||||
|
||||
/* re-enable and start: */
|
||||
smics_temp |= SMICS_CLEAR;
|
||||
smics_temp |= SMICS_ENABLE;
|
||||
if(dma_dir == DMA_MEM_TO_DEV)
|
||||
{
|
||||
smics_temp |= SMICS_WRITE;
|
||||
smics_temp |= SMICS_WRITE;
|
||||
}
|
||||
|
||||
write_smi_reg(smi_inst, smics_temp, SMICS);
|
||||
print_smil_registers_ext("init 4");
|
||||
|
||||
print_smil_registers_ext("init 4");
|
||||
|
||||
/* IO barrier - to be sure that the last request have
|
||||
been dispatched in the correct order
|
||||
*/
|
||||
mb();
|
||||
|
||||
// busy wait as long as the transaction is active (taking place)
|
||||
BUSY_WAIT_WHILE_TIMEOUT(smi_is_active(smi_inst), 1000000U, success);
|
||||
if (!success)
|
||||
|
@ -379,6 +392,7 @@ print_smil_registers_ext("init 4");
|
|||
// Clear the FIFO (reset it to zero contents)
|
||||
write_smi_reg(smi_inst, smics_temp, SMICS);
|
||||
print_smil_registers_ext("init 5");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -570,7 +584,7 @@ static void stream_smi_read_dma_callback(void *param)
|
|||
}
|
||||
else
|
||||
{
|
||||
inst->counter_missed++;
|
||||
inst->counter_missed++;
|
||||
}
|
||||
|
||||
if(!(inst->current_read_chunk % 100 ))
|
||||
|
@ -594,17 +608,18 @@ static void stream_smi_check_and_restart(struct bcm2835_smi_dev_instance *inst)
|
|||
int i;
|
||||
for(i = 0; i < 1000; i++)
|
||||
{
|
||||
if(!smi_is_active(smi_inst))
|
||||
break;
|
||||
udelay(1);
|
||||
if(!smi_is_active(smi_inst))
|
||||
{
|
||||
break;
|
||||
}
|
||||
udelay(1);
|
||||
}
|
||||
if(i == 1000)
|
||||
{
|
||||
print_smil_registers_ext("write dma callback errore 1000");
|
||||
print_smil_registers_ext("write dma callback error 1000");
|
||||
}
|
||||
|
||||
smi_refresh_dma_command(smi_inst, DMA_BOUNCE_BUFFER_SIZE/4);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -685,13 +700,14 @@ int transfer_thread_init(struct bcm2835_smi_dev_instance *inst, enum dma_transfe
|
|||
int ret;
|
||||
int success;
|
||||
|
||||
dev_info(inst->dev, "Enterred reader thread");
|
||||
dev_info(inst->dev, "Starting cyclic transfer");
|
||||
inst->reader_thread_running = true;
|
||||
|
||||
/* Disable the peripheral: */
|
||||
if(smi_disable_sync(inst->smi_inst))
|
||||
{
|
||||
return -1;
|
||||
dev_err(inst->smi_inst->dev, "smi_disable_sync failed");
|
||||
return -1;
|
||||
}
|
||||
write_smi_reg(inst->smi_inst, 0, SMIL);
|
||||
|
||||
|
@ -702,14 +718,13 @@ int transfer_thread_init(struct bcm2835_smi_dev_instance *inst, enum dma_transfe
|
|||
if (ret != 0)
|
||||
{
|
||||
spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
dev_err(inst->smi_inst->dev, "smi_init_programmed_read returned %d", ret);
|
||||
dev_err(inst->smi_inst->dev, "smi_init_programmed_transfer returned %d", ret);
|
||||
smi_disable_sync(inst->smi_inst);
|
||||
return -2;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
}
|
||||
inst->current_read_chunk = 0;
|
||||
inst->counter_missed = 0;
|
||||
|
@ -738,18 +753,18 @@ int transfer_thread_init(struct bcm2835_smi_dev_instance *inst, enum dma_transfe
|
|||
|
||||
void transfer_thread_stop(struct bcm2835_smi_dev_instance *inst)
|
||||
{
|
||||
int errors = 0;
|
||||
dev_info(inst->dev, "Reader state became idle, terminating dma %u %u", (inst->address_changed) ,errors);
|
||||
//int errors = 0;
|
||||
//dev_info(inst->dev, "Reader state became idle, terminating dma %u %u", (inst->address_changed) ,errors);
|
||||
print_smil_registers_ext("thread stop 0");
|
||||
spin_lock(&inst->smi_inst->transaction_lock);
|
||||
dmaengine_terminate_sync(inst->smi_inst->dma_chan);
|
||||
spin_unlock(&inst->smi_inst->transaction_lock);
|
||||
|
||||
dev_info(inst->dev, "Reader state became idle, terminating smi transaction");
|
||||
//dev_info(inst->dev, "Reader state became idle, terminating smi transaction");
|
||||
smi_disable_sync(inst->smi_inst);
|
||||
bcm2835_smi_set_regs_from_settings(inst->smi_inst);
|
||||
|
||||
dev_info(inst->dev, "Left reader thread");
|
||||
//dev_info(inst->dev, "Left reader thread");
|
||||
inst->reader_thread_running = false;
|
||||
inst->reader_waiting_sema = false;
|
||||
return ;
|
||||
|
@ -802,8 +817,6 @@ static int smi_stream_open(struct inode *inode, struct file *file)
|
|||
// when file is being openned, stream state is still idle
|
||||
set_state(smi_stream_idle);
|
||||
|
||||
|
||||
|
||||
inst->address_changed = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -845,7 +858,7 @@ static ssize_t smi_stream_read_file_fifo(struct file *file, char __user *buf, si
|
|||
int ret = 0;
|
||||
unsigned int copied = 0;
|
||||
|
||||
if (buf == NULL)
|
||||
if (buf == NULL)
|
||||
{
|
||||
//dev_info(inst->dev, "Flushing internal rx_kfifo");
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
|
@ -858,22 +871,13 @@ static ssize_t smi_stream_read_file_fifo(struct file *file, char __user *buf, si
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (kfifo_is_empty(&inst->rx_fifo))
|
||||
{
|
||||
int ret = wait_event_interruptible(inst->poll_event, !kfifo_is_empty(&inst->rx_fifo) );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
if (mutex_lock_interruptible(&inst->read_lock))
|
||||
{
|
||||
return -EINTR;
|
||||
}
|
||||
ret = kfifo_to_user(&inst->rx_fifo, buf, count, &copied);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
return -EINTR;
|
||||
}
|
||||
ret = kfifo_to_user(&inst->rx_fifo, buf, count, &copied);
|
||||
mutex_unlock(&inst->read_lock);
|
||||
|
||||
return ret < 0 ? ret : (ssize_t)copied;
|
||||
}
|
||||
|
||||
|
@ -896,9 +900,7 @@ static ssize_t smi_stream_write_file(struct file *f, const char __user *user_ptr
|
|||
{
|
||||
mutex_unlock(&inst->write_lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// check how many bytes are available in the tx fifo
|
||||
|
|
|
@ -5,7 +5,7 @@ pcf_file = ./io.pcf
|
|||
top.bin:
|
||||
yosys -p 'synth_ice40 -top top -json $(filename).json -blif $(filename).blif' -p 'ice40_opt' -p 'fsm_opt' $(filename).v
|
||||
#nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc
|
||||
nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 64 --parallel-refine --opt-timing --timing-allow-fail
|
||||
nextpnr-ice40 --lp1k --package qn84 --json $(filename).json --pcf $(pcf_file) --asc $(filename).asc --freq 80 --parallel-refine --opt-timing --seed 1 --timing-allow-fail
|
||||
#nextpnr-ice40 --json blinky.json --pcf blinky.pcf --asc blinky.asc --gui
|
||||
icepack $(filename).asc $(filename).bin
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -15,7 +15,7 @@ module io_ctrl
|
|||
input [3:0] i_config,
|
||||
output o_led0,
|
||||
output o_led1,
|
||||
output [7:0] o_pmod,
|
||||
output [3:0] o_pmod,
|
||||
|
||||
// Analog interfaces
|
||||
output o_mixer_fm,
|
||||
|
@ -26,7 +26,7 @@ module io_ctrl
|
|||
output o_tr_vc2,
|
||||
output o_shdn_tx_lna,
|
||||
output o_shdn_rx_lna,
|
||||
output o_mixer_en
|
||||
output o_mixer_en
|
||||
);
|
||||
|
||||
|
||||
|
@ -73,7 +73,7 @@ module io_ctrl
|
|||
reg led0_state;
|
||||
reg led1_state;
|
||||
reg [7:0] pmod_dir_state;
|
||||
reg [7:0] pmod_state;
|
||||
reg [3:0] pmod_state;
|
||||
reg [7:0] rf_pin_state;
|
||||
reg mixer_en_state;
|
||||
|
||||
|
@ -146,7 +146,8 @@ module io_ctrl
|
|||
|
||||
//----------------------------------------------
|
||||
ioc_pmod_val: begin
|
||||
o_data_out <= pmod_state;
|
||||
o_data_out[3:0] <= pmod_state;
|
||||
o_data_out[7:4] <= 4'b0000;
|
||||
end
|
||||
|
||||
//----------------------------------------------
|
||||
|
@ -191,7 +192,7 @@ module io_ctrl
|
|||
|
||||
//----------------------------------------------
|
||||
ioc_pmod_val: begin
|
||||
pmod_state <= i_data_in;
|
||||
pmod_state[3:0] <= i_data_in[3:0];
|
||||
end
|
||||
|
||||
//----------------------------------------------
|
||||
|
|
|
@ -29,7 +29,7 @@ module smi_ctrl
|
|||
output o_smi_write_req,
|
||||
input i_smi_test,
|
||||
output o_channel,
|
||||
output o_dir,
|
||||
output o_dir,
|
||||
|
||||
// TX CONDITIONAL
|
||||
output reg o_cond_tx,
|
||||
|
|
|
@ -16,6 +16,16 @@ module sys_ctrl
|
|||
output o_debug_smi_test,
|
||||
output o_debug_loopback_tx,
|
||||
output [3:0] o_tx_sample_gap,
|
||||
|
||||
output o_rx_sync_type09,
|
||||
output o_rx_sync_type24,
|
||||
output o_tx_sync_type09,
|
||||
output o_tx_sync_type24,
|
||||
|
||||
output o_rx_sync_09,
|
||||
output o_rx_sync_24,
|
||||
output o_tx_sync_09,
|
||||
output o_tx_sync_24,
|
||||
);
|
||||
|
||||
// MODULE SPECIFIC IOC LIST
|
||||
|
@ -26,7 +36,8 @@ module sys_ctrl
|
|||
ioc_manu_id = 5'b00010, // read only
|
||||
ioc_error_state = 5'b00011, // read only
|
||||
ioc_debug_modes = 5'b00101, // write only
|
||||
ioc_tx_sample_gap = 5'b00110; // read / write
|
||||
ioc_tx_sample_gap = 5'b00110, // read / write
|
||||
ioc_soft_sync = 5'b00111; // write only
|
||||
|
||||
// MODULE SPECIFIC PARAMS
|
||||
// ----------------------
|
||||
|
@ -40,12 +51,32 @@ module sys_ctrl
|
|||
reg debug_fifo_push;
|
||||
reg debug_fifo_pull;
|
||||
reg debug_smi_test;
|
||||
reg debug_loopback_tx;
|
||||
reg [3:0] tx_sample_gap;
|
||||
reg debug_loopback_tx;
|
||||
reg [3:0] tx_sample_gap;
|
||||
|
||||
reg rx_sync_type09;
|
||||
reg rx_sync_type24;
|
||||
reg tx_sync_type09;
|
||||
reg tx_sync_type24;
|
||||
|
||||
reg rx_sync_09;
|
||||
reg rx_sync_24;
|
||||
reg tx_sync_09;
|
||||
reg tx_sync_24;
|
||||
|
||||
assign o_debug_fifo_push = debug_fifo_push;
|
||||
assign o_debug_fifo_pull = debug_fifo_pull;
|
||||
assign o_debug_smi_test = debug_smi_test;
|
||||
assign o_rx_sync_type09 = rx_sync_type09;
|
||||
assign o_tx_sync_type09 = tx_sync_type09;
|
||||
assign o_rx_sync_type24 = rx_sync_type24;
|
||||
assign o_tx_sync_type24 = tx_sync_type24;
|
||||
|
||||
assign o_rx_sync_09 = rx_sync_09;
|
||||
assign o_tx_sync_09 = tx_sync_09;
|
||||
assign o_rx_sync_24 = rx_sync_24;
|
||||
assign o_tx_sync_24 = tx_sync_24;
|
||||
|
||||
|
||||
// MODULE MAIN PROCESS
|
||||
// -------------------
|
||||
|
@ -58,6 +89,17 @@ module sys_ctrl
|
|||
debug_smi_test <= 1'b0;
|
||||
debug_loopback_tx <= 1'b0;
|
||||
tx_sample_gap <= 4'd0;
|
||||
|
||||
rx_sync_type09 <= 1'b0;
|
||||
rx_sync_type24 <= 1'b0;
|
||||
tx_sync_type09 <= 1'b0;
|
||||
tx_sync_type24 <= 1'b0;
|
||||
|
||||
rx_sync_09 <= 1'b0;
|
||||
tx_sync_09 <= 1'b0;
|
||||
rx_sync_24 <= 1'b0;
|
||||
tx_sync_24 <= 1'b0;
|
||||
|
||||
end else if (i_cs == 1'b1) begin
|
||||
//=============================================
|
||||
// READ OPERATIONS
|
||||
|
@ -70,7 +112,10 @@ module sys_ctrl
|
|||
//----------------------------------------------
|
||||
ioc_tx_sample_gap: begin
|
||||
o_data_out[3:0] <= tx_sample_gap;
|
||||
o_data_out[7:4] <= 4'd0;
|
||||
o_data_out[4] <= rx_sync_type09;
|
||||
o_data_out[5] <= rx_sync_type24;
|
||||
o_data_out[6] <= tx_sync_type09;
|
||||
o_data_out[7] <= tx_sync_type24;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
@ -89,6 +134,17 @@ module sys_ctrl
|
|||
//----------------------------------------------
|
||||
ioc_tx_sample_gap: begin
|
||||
tx_sample_gap <= i_data_in[3:0];
|
||||
rx_sync_type09 <= i_data_in[4];
|
||||
rx_sync_type24 <= i_data_in[5];
|
||||
tx_sync_type09 <= i_data_in[6];
|
||||
tx_sync_type24 <= i_data_in[7];
|
||||
end
|
||||
//----------------------------------------------
|
||||
ioc_soft_sync: begin
|
||||
rx_sync_09 <= i_data_in[0];
|
||||
tx_sync_09 <= i_data_in[1];
|
||||
rx_sync_24 <= i_data_in[2];
|
||||
tx_sync_24 <= i_data_in[3];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
|
21799
firmware/top.asc
21799
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.
7117
firmware/top.blif
7117
firmware/top.blif
Plik diff jest za duży
Load Diff
35367
firmware/top.json
35367
firmware/top.json
Plik diff jest za duży
Load Diff
|
@ -50,27 +50,28 @@ module top (
|
|||
//
|
||||
// RPI PIN | FPGA TOP-LEVEL SIGNAL
|
||||
// ------------------------------------------------------------------------
|
||||
// GPIO2_SA3 | i_smi_a[2] - RX09 / RX24 channel select
|
||||
// GPIO3_SA2 | i_smi_a[1] - Tx SMI (0) / Rx SMI (1) select
|
||||
// GPIO4_SA1 | i_smi_a[0] - used as a sys async reset (GBIN1)
|
||||
// GPIO2_SA3 | i_smi_a3 - RX09 / RX24 channel select
|
||||
// GPIO3_SA2 | i_smi_a2 - Tx SMI (0) / Rx SMI (1) select
|
||||
// GPIO4_SA1 | i_rst_b - used as a sys async reset (GBIN1)
|
||||
// GPIO5_SA0 | Not connected to FPGA (MixerRst)
|
||||
//
|
||||
// In order to perform SMI data bus direction selection (highZ / PushPull)
|
||||
// signal a[0] was chosen, while the '0' level (default) denotes RPI => FPGA
|
||||
// direction, and the DATA bus is highZ (recessive mode).
|
||||
// The signal a[2] selects the RX source (900 MHZ or 2.4GHz)
|
||||
// The signal a[1] can be used in the future for other purposes
|
||||
// The signal i_smi_a2 selects Tx(0) or Rx(1) direction
|
||||
// The signal i_smi_a3 selects the RX source (900 MHZ or 2.4GHz)
|
||||
|
||||
//
|
||||
// Description | a[2] (SA3)| a[1] (SA2) |
|
||||
// -------------|------------|---------------|
|
||||
// | 0 | 0 |
|
||||
// TX |------------| RPI => FPGA |
|
||||
// | 1 | Data HighZ |
|
||||
// -------------|------------|---------------|
|
||||
// RX09 | 0 | 1 |
|
||||
// -------------|------------| FPGA => RPI |
|
||||
// RX24 | 1 | Data PushPull |
|
||||
// -------------|------------|---------------|
|
||||
// Description | a2 (SA2) | a3 (SA3) |
|
||||
// -------------|---------------|------------|
|
||||
// | 0 | 0 |
|
||||
// TX | RPI => FPGA |------------|
|
||||
// | Data HighZ | 1 |
|
||||
// -------------|---------------|------------|
|
||||
// RX09 | 1 | 0 |
|
||||
// -------------| FPGA => RPI |------------|
|
||||
// RX24 | Data PushPull | 1 |
|
||||
// -------------|---------------|------------|
|
||||
input i_smi_a2,
|
||||
input i_smi_a3,
|
||||
|
||||
|
@ -105,6 +106,26 @@ module top (
|
|||
wire [7:0] w_tx_data_io;
|
||||
wire [7:0] w_tx_data_smi;
|
||||
|
||||
wire w_rx_sync_type_09;
|
||||
wire w_rx_sync_type_24;
|
||||
wire w_tx_sync_type_09;
|
||||
wire w_tx_sync_type_24;
|
||||
|
||||
wire w_rx_sync_09;
|
||||
wire w_rx_sync_24;
|
||||
wire w_tx_sync_09;
|
||||
wire w_tx_sync_24;
|
||||
|
||||
wire w_rx_sync_input_09;
|
||||
wire w_rx_sync_input_24;
|
||||
wire w_tx_sync_input_09;
|
||||
wire w_tx_sync_input_24;
|
||||
|
||||
assign w_rx_sync_input_09 = (w_rx_sync_type_09) ? io_pmod[7] : w_rx_sync_09;
|
||||
assign w_rx_sync_input_24 = (w_rx_sync_type_24) ? io_pmod[6] : w_rx_sync_24;
|
||||
assign w_tx_sync_input_09 = (w_tx_sync_type_09) ? io_pmod[5] : w_tx_sync_09;
|
||||
assign w_tx_sync_input_24 = (w_tx_sync_type_24) ? io_pmod[4] : w_tx_sync_24;
|
||||
|
||||
//=========================================================================
|
||||
// INSTANCES
|
||||
//=========================================================================
|
||||
|
@ -138,11 +159,22 @@ module top (
|
|||
.i_cs(w_cs[0]),
|
||||
.i_fetch_cmd(w_fetch),
|
||||
.i_load_cmd(w_load),
|
||||
|
||||
.o_debug_fifo_push(),
|
||||
.o_debug_fifo_pull(),
|
||||
.o_debug_smi_test(),
|
||||
.o_debug_loopback_tx(w_debug_lb_tx),
|
||||
.o_tx_sample_gap(tx_sample_gap),
|
||||
|
||||
.o_rx_sync_type09(w_rx_sync_type_09),
|
||||
.o_rx_sync_type24(w_rx_sync_type_24),
|
||||
.o_tx_sync_type09(w_tx_sync_type_09),
|
||||
.o_tx_sync_type24(w_tx_sync_type_24),
|
||||
|
||||
.o_rx_sync_09(w_rx_sync_09),
|
||||
.o_rx_sync_24(w_rx_sync_24),
|
||||
.o_tx_sync_09(w_tx_sync_09),
|
||||
.o_tx_sync_24(w_tx_sync_24)
|
||||
);
|
||||
|
||||
wire w_debug_fifo_push;
|
||||
|
@ -167,7 +199,7 @@ module top (
|
|||
.i_config(i_config),
|
||||
.o_led0 (/*o_led0*/),
|
||||
.o_led1 (/*o_led1*/),
|
||||
.o_pmod (),
|
||||
.o_pmod (io_pmod[3:0]),
|
||||
|
||||
// Analog interfaces
|
||||
.o_mixer_fm(/*o_mixer_fm*/),
|
||||
|
@ -266,7 +298,7 @@ module top (
|
|||
|
||||
// Non-inverting, P-side of pair
|
||||
SB_IO #(
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_INPUT_REGISTER }
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_OUTPUT_REGISTER }
|
||||
.IO_STANDARD("SB_LVCMOS"),
|
||||
) iq_tx_p (
|
||||
.PACKAGE_PIN(o_iq_tx_p),
|
||||
|
@ -277,7 +309,7 @@ module top (
|
|||
|
||||
// Inverting, N-side of pair
|
||||
SB_IO #(
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_INPUT_REGISTER }
|
||||
.PIN_TYPE (6'b010000), // {PIN_OUTPUT_DDR, PIN_OUTPUT_REGISTER }
|
||||
.IO_STANDARD("SB_LVCMOS"),
|
||||
) iq_tx_n (
|
||||
.PACKAGE_PIN(o_iq_tx_n),
|
||||
|
@ -318,7 +350,7 @@ module top (
|
|||
.o_fifo_push(w_rx_09_fifo_push),
|
||||
|
||||
.o_fifo_data (w_rx_09_fifo_data),
|
||||
.i_sync_input (1'b0),
|
||||
.i_sync_input (w_rx_sync_input_09),
|
||||
.o_debug_state()
|
||||
);
|
||||
|
||||
|
@ -333,7 +365,7 @@ module top (
|
|||
.o_fifo_push(w_rx_24_fifo_push),
|
||||
|
||||
.o_fifo_data (w_rx_24_fifo_data),
|
||||
.i_sync_input (1'b0),
|
||||
.i_sync_input (w_rx_sync_input_24),
|
||||
.o_debug_state()
|
||||
);
|
||||
|
||||
|
@ -344,9 +376,6 @@ module top (
|
|||
wire [31:0] w_rx_fifo_pulled_data;
|
||||
wire w_rx_fifo_full;
|
||||
wire w_rx_fifo_empty;
|
||||
wire channel;
|
||||
|
||||
//assign channel = i_smi_a3;
|
||||
|
||||
complex_fifo #(
|
||||
.ADDR_WIDTH(10), // 1024 samples
|
||||
|
@ -382,12 +411,12 @@ module top (
|
|||
.i_fifo_data(w_tx_fifo_pulled_data),
|
||||
.i_sample_gap(tx_sample_gap),
|
||||
.i_tx_state(~w_smi_data_direction),
|
||||
.i_sync_input(1'b0),
|
||||
.i_sync_input(w_tx_sync_input_09),
|
||||
.i_debug_lb(w_debug_lb_tx),
|
||||
.o_tx_state_bit(),
|
||||
.o_sync_state_bit(),
|
||||
);
|
||||
|
||||
|
||||
wire w_tx_fifo_full;
|
||||
wire w_tx_fifo_empty;
|
||||
wire w_tx_fifo_read_clk;
|
||||
|
@ -418,6 +447,11 @@ module top (
|
|||
.debug_push(1'b0)
|
||||
);
|
||||
|
||||
wire channel;
|
||||
wire w_smi_data_direction;
|
||||
//assign channel = i_smi_a3;
|
||||
//assign w_smi_data_direction = i_smi_a2;
|
||||
|
||||
smi_ctrl smi_ctrl_ins (
|
||||
.i_rst_b(i_rst_b),
|
||||
.i_sys_clk(w_clock_sys),
|
||||
|
@ -446,7 +480,7 @@ module top (
|
|||
.o_smi_read_req(w_smi_read_req),
|
||||
.o_smi_write_req(w_smi_write_req),
|
||||
.o_channel(channel),
|
||||
.o_dir (/*w_smi_data_direction*/),
|
||||
.o_dir (w_smi_data_direction),
|
||||
.i_smi_test(1'b0/*w_debug_smi_test*/),
|
||||
.o_cond_tx(),
|
||||
.o_address_error()
|
||||
|
@ -456,7 +490,6 @@ module top (
|
|||
wire [7:0] w_smi_data_input;
|
||||
wire w_smi_read_req;
|
||||
wire w_smi_write_req;
|
||||
wire w_smi_data_direction;
|
||||
|
||||
// the "Writing" flag indicates that the data[7:0] direction (inout)
|
||||
// from the FPGA's SMI module should be "output". This happens when the
|
||||
|
@ -464,7 +497,6 @@ module top (
|
|||
// The address has the MSB '1' when in RX mode. otherwise (when IDLE or TX)
|
||||
// the data is high-z, which is the more "recessive" mode
|
||||
|
||||
assign w_smi_data_direction = i_smi_a2;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b1010_01),
|
||||
.PULLUP (1'b0)
|
||||
|
@ -538,8 +570,6 @@ module top (
|
|||
.D_IN_0(w_smi_data_input[7])
|
||||
);
|
||||
|
||||
// We need the 'o_smi_write_req' to be 1 only when the direction is TX
|
||||
// (w_smi_data_direction == 0) and the write fifo is not full
|
||||
assign o_smi_read_req = (w_smi_data_direction) ? w_smi_read_req : w_smi_write_req;
|
||||
assign o_smi_write_req = 1'bZ;
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ public:
|
|||
void StartReceiving();
|
||||
void StartReceivingInternal(size_t samples_per_chunk);
|
||||
void StopReceiving(void);
|
||||
void StartTransmitting(std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> on_data_request, size_t samples_per_chunk);
|
||||
void StartTransmitting(void);
|
||||
void StartTransmittingLo(void);
|
||||
void StartTransmittingCw(void);
|
||||
void StopTransmitting(void);
|
||||
|
@ -198,6 +198,7 @@ private:
|
|||
const CaribouLite* _device;
|
||||
const RadioType _type;
|
||||
|
||||
// Rx information
|
||||
bool _rx_thread_running;
|
||||
bool _rx_is_active;
|
||||
std::thread *_rx_thread;
|
||||
|
@ -209,14 +210,12 @@ private:
|
|||
RxCbType _rxCallbackType;
|
||||
ApiType _api_type;
|
||||
|
||||
bool _tx_thread_running;
|
||||
// Tx information
|
||||
bool _tx_is_active;
|
||||
std::thread *_tx_thread;
|
||||
std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> _on_data_request;
|
||||
size_t _tx_samples_per_chunk;
|
||||
|
||||
// buffers
|
||||
cariboulite_sample_complex_int16 *_read_samples;
|
||||
std::complex<short> *_write_samples;
|
||||
cariboulite_sample_meta* _read_metadata;
|
||||
|
||||
private:
|
||||
|
|
|
@ -132,7 +132,32 @@ int CaribouLiteRadio::ReadSamples(std::complex<short>* samples, size_t num_to_re
|
|||
//==================================================================
|
||||
int CaribouLiteRadio::WriteSamples(std::complex<float>* samples, size_t num_to_write)
|
||||
{
|
||||
return 0;
|
||||
// fill in the _write_samples internal buffer
|
||||
size_t written_so_far = 0;
|
||||
size_t left_to_write = num_to_write;
|
||||
size_t mtu_size = GetNativeMtuSample();
|
||||
|
||||
while (written_so_far < num_to_write)
|
||||
{
|
||||
size_t current_write = left_to_write;
|
||||
size_t k = written_so_far;
|
||||
if (current_write > mtu_size) current_write = mtu_size;
|
||||
|
||||
for (size_t i = 0; i < current_write; i++, k++)
|
||||
{
|
||||
_write_samples[i].real((uint16_t)(samples[k].real() * 4096));
|
||||
_write_samples[i].imag((uint16_t)(samples[k].imag() * 4096));
|
||||
}
|
||||
int ret = WriteSamples(_write_samples, current_write);
|
||||
if (ret <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
written_so_far += ret;
|
||||
left_to_write -= ret;
|
||||
}
|
||||
|
||||
return written_so_far;
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
|
@ -143,20 +168,6 @@ int CaribouLiteRadio::WriteSamples(std::complex<short>* samples, size_t num_to_w
|
|||
num_to_write);
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
void CaribouLiteRadio::CaribouLiteTxThread(CaribouLiteRadio* radio)
|
||||
{
|
||||
while (radio->_tx_thread_running)
|
||||
{
|
||||
if (!radio->_tx_is_active)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(4));
|
||||
continue;
|
||||
}
|
||||
// TBD
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
CaribouLiteRadio::CaribouLiteRadio( const cariboulite_radio_state_st* radio,
|
||||
RadioType type,
|
||||
|
@ -164,25 +175,26 @@ CaribouLiteRadio::CaribouLiteRadio( const cariboulite_radio_state_st* radio,
|
|||
const CaribouLite* parent)
|
||||
: _radio(radio), _device(parent), _type(type), _rxCallbackType(RxCbType::None), _api_type(api_type)
|
||||
{
|
||||
size_t mtu_size = GetNativeMtuSample();
|
||||
if (_api_type == Async)
|
||||
{
|
||||
//printf("Creating Radio Type %d ASYNC\n", type);
|
||||
_rx_thread_running = true;
|
||||
_rx_thread = new std::thread(CaribouLiteRadio::CaribouLiteRxThread, this);
|
||||
|
||||
_tx_thread_running = true;
|
||||
_tx_thread = new std::thread(CaribouLiteRadio::CaribouLiteTxThread, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("Creating Radio Type %d SYNC\n", type);
|
||||
_read_samples = NULL;
|
||||
_read_metadata = NULL;
|
||||
size_t mtu_size = GetNativeMtuSample();
|
||||
|
||||
// allocate internal buffers
|
||||
_read_samples = new cariboulite_sample_complex_int16[mtu_size];
|
||||
_read_samples = new cariboulite_sample_complex_int16[mtu_size];
|
||||
_read_metadata = new cariboulite_sample_meta[mtu_size];
|
||||
}
|
||||
|
||||
_write_samples = NULL;
|
||||
_write_samples = new std::complex<short>[mtu_size];
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
|
@ -197,18 +209,18 @@ CaribouLiteRadio::~CaribouLiteRadio()
|
|||
_rx_thread_running = false;
|
||||
_rx_thread->join();
|
||||
if (_rx_thread) delete _rx_thread;
|
||||
|
||||
_tx_thread_running = false;
|
||||
_tx_thread->join();
|
||||
if (_tx_thread) delete _tx_thread;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_read_samples) delete [] _read_samples;
|
||||
_read_samples = NULL;
|
||||
|
||||
if (_read_metadata) delete [] _read_metadata;
|
||||
_read_metadata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (_write_samples) delete [] _write_samples;
|
||||
_write_samples = NULL;
|
||||
}
|
||||
|
||||
// Gain
|
||||
|
@ -596,11 +608,9 @@ void CaribouLiteRadio::StopReceiving()
|
|||
}
|
||||
|
||||
//==================================================================
|
||||
void CaribouLiteRadio::StartTransmitting(std::function<void(CaribouLiteRadio*, std::complex<float>*, const bool*, size_t*)> on_data_request, size_t samples_per_chunk)
|
||||
void CaribouLiteRadio::StartTransmitting()
|
||||
{
|
||||
_rx_is_active = false;
|
||||
_on_data_request = on_data_request;
|
||||
_tx_samples_per_chunk = samples_per_chunk;
|
||||
cariboulite_radio_activate_channel((cariboulite_radio_state_st*)_radio, cariboulite_channel_dir_rx, false);
|
||||
cariboulite_radio_set_cw_outputs((cariboulite_radio_state_st*)_radio, false, false);
|
||||
cariboulite_radio_activate_channel((cariboulite_radio_state_st*)_radio, cariboulite_channel_dir_tx, true);
|
||||
|
|
|
@ -90,10 +90,6 @@ typedef enum
|
|||
at86rf215_radio_rx_bw_BW1250KHZ_IF2000KHZ = 0x9, // at86rf215_radio_rx_f_cut_0_75_half_fs
|
||||
at86rf215_radio_rx_bw_BW1600KHZ_IF2000KHZ = 0xA, // at86rf215_radio_rx_f_cut_half_fs
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IF2000KHZ = 0xB, // at86rf215_radio_rx_f_cut_half_fs
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFCCKHZ = 0xC, // **
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFDDHZ = 0xD, // **
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFEEKHZ = 0xE, // **
|
||||
at86rf215_radio_rx_bw_BW2000KHZ_IFFFKHZ = 0xF, // **
|
||||
} at86rf215_radio_rx_bw_en;
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -13,13 +13,14 @@
|
|||
//--------------------------------------------------------------
|
||||
// Static Definitions
|
||||
//--------------------------------------------------------------
|
||||
#define IOC_MOD_VER 0
|
||||
#define IOC_SYS_CTRL_SYS_VERSION 1
|
||||
#define IOC_SYS_CTRL_MANU_ID 2
|
||||
#define IOC_SYS_CTRL_SYS_ERR_STAT 3
|
||||
#define IOC_SYS_CTRL_SYS_SOFT_RST 4
|
||||
#define IOC_SYS_CTRL_DEBUG_MODES 5
|
||||
#define IOC_SYS_CTRL_SYS_TX_SAMPLE_GAP 6
|
||||
#define IOC_MOD_VER 0
|
||||
#define IOC_SYS_CTRL_SYS_VERSION 1
|
||||
#define IOC_SYS_CTRL_MANU_ID 2
|
||||
#define IOC_SYS_CTRL_SYS_ERR_STAT 3
|
||||
#define IOC_SYS_CTRL_SYS_SOFT_RST 4
|
||||
#define IOC_SYS_CTRL_DEBUG_MODES 5
|
||||
#define IOC_SYS_CTRL_TX_SAMPLE_GAP 6
|
||||
#define IOC_SYS_CTRL_SOFT_SYNC 7
|
||||
|
||||
#define IOC_IO_CTRL_MODE 1
|
||||
#define IOC_IO_CTRL_DIG_PIN 2
|
||||
|
@ -31,7 +32,7 @@
|
|||
|
||||
#define IOC_SMI_CTRL_FIFO_STATUS 1
|
||||
#define IOC_SMI_CHANNEL_SELECT 2
|
||||
#define IOC_SMI_CTRL_DIR_SELECT 3
|
||||
#define IOC_SMI_CTRL_DIR_SELECT 3
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Internal Data-Types
|
||||
|
@ -380,21 +381,42 @@ int caribou_fpga_get_errors (caribou_fpga_st* dev, uint8_t *err_map)
|
|||
.ioc = IOC_SYS_CTRL_SYS_ERR_STAT
|
||||
};
|
||||
|
||||
*err_map = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), err_map);
|
||||
if (err_map)
|
||||
{
|
||||
*err_map = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), err_map);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_set_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t gap)
|
||||
{
|
||||
uint8_t actual_val = 0;
|
||||
uint8_t actual_gap = 0;
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_sys_ctrl_tx_sample_gap");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_write,
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_SYS_TX_SAMPLE_GAP,
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP,
|
||||
};
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &gap);
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_val);
|
||||
if (ret != 0) return -1;
|
||||
|
||||
actual_gap = actual_val & 0xF;
|
||||
actual_val &= 0xF0;
|
||||
|
||||
if (gap != actual_gap)
|
||||
{
|
||||
// only if change is needed
|
||||
oc.rw = caribou_fpga_rw_write;
|
||||
actual_val |= (gap & 0xF);
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -406,14 +428,104 @@ int caribou_fpga_get_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t *gap)
|
|||
{
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_SYS_TX_SAMPLE_GAP
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP
|
||||
};
|
||||
|
||||
*gap = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), gap);
|
||||
uint8_t actual_gap = 0;
|
||||
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_gap);
|
||||
|
||||
if (gap) *gap = actual_gap & 0xF;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_set_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en rx_09,
|
||||
caribou_fpga_sync_source_en rx_24,
|
||||
caribou_fpga_sync_source_en tx_09,
|
||||
caribou_fpga_sync_source_en tx_24)
|
||||
{
|
||||
uint8_t actual_val = 0;
|
||||
uint8_t temp = 0;
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_sys_ctrl_sync_source");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP,
|
||||
};
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &actual_val);
|
||||
if (ret != 0) return -1;
|
||||
|
||||
temp = actual_val & 0xF;
|
||||
uint8_t cur_rx_09 = (actual_val >> 4) & 0x1;
|
||||
uint8_t cur_rx_24 = (actual_val >> 5) & 0x1;
|
||||
uint8_t cur_tx_09 = (actual_val >> 6) & 0x1;
|
||||
uint8_t cur_tx_24 = (actual_val >> 7) & 0x1;
|
||||
|
||||
if (rx_09 != caribou_fpga_sync_src_no_change) cur_rx_09 = rx_09 & 0x1;
|
||||
if (rx_24 != caribou_fpga_sync_src_no_change) cur_rx_24 = rx_24 & 0x1;
|
||||
if (tx_09 != caribou_fpga_sync_src_no_change) cur_tx_09 = tx_09 & 0x1;
|
||||
if (tx_24 != caribou_fpga_sync_src_no_change) cur_tx_24 = tx_24 & 0x1;
|
||||
|
||||
temp |= cur_rx_09 << 4;
|
||||
temp |= cur_rx_24 << 5;
|
||||
temp |= cur_tx_09 << 6;
|
||||
temp |= cur_tx_24 << 7;
|
||||
|
||||
oc.rw = caribou_fpga_rw_write;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &temp);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_get_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en *rx_09,
|
||||
caribou_fpga_sync_source_en *rx_24,
|
||||
caribou_fpga_sync_source_en *tx_09,
|
||||
caribou_fpga_sync_source_en *tx_24)
|
||||
{
|
||||
uint8_t temp = 0;
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_get_sys_ctrl_sync_source");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_read,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_TX_SAMPLE_GAP,
|
||||
};
|
||||
int ret = caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &temp);
|
||||
if (ret != 0) return -1;
|
||||
|
||||
if (rx_09) *rx_09 = (temp >> 4) & 0x1;
|
||||
if (rx_24) *rx_24 = (temp >> 5) & 0x1;
|
||||
if (tx_09) *tx_09 = (temp >> 6) & 0x1;
|
||||
if (tx_24) *tx_24 = (temp >> 7) & 0x1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
int caribou_fpga_set_sys_ctrl_soft_sync_value (caribou_fpga_st* dev, uint8_t rx_09,
|
||||
uint8_t rx_24,
|
||||
uint8_t tx_09,
|
||||
uint8_t tx_24)
|
||||
{
|
||||
uint8_t temp = (rx_09 & 0xf) | ((tx_09 & 0xf) << 1) | ((rx_24 & 0xf) << 2) | ((tx_24 & 0xf) << 3);
|
||||
CARIBOU_FPGA_CHECK_DEV(dev,"caribou_fpga_set_sys_ctrl_soft_sync_value");
|
||||
|
||||
// read before write
|
||||
caribou_fpga_opcode_st oc =
|
||||
{
|
||||
.rw = caribou_fpga_rw_write,
|
||||
.mid = caribou_fpga_mid_sys_ctrl,
|
||||
.ioc = IOC_SYS_CTRL_SOFT_SYNC,
|
||||
};
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &temp);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// I/O Controller
|
||||
int caribou_fpga_set_io_ctrl_mode (caribou_fpga_st* dev, uint8_t debug_mode, caribou_fpga_io_ctrl_rfm_en rfm)
|
||||
{
|
||||
|
@ -445,8 +557,8 @@ int caribou_fpga_get_io_ctrl_mode (caribou_fpga_st* dev, uint8_t* debug_mode, ca
|
|||
uint8_t mode = 0;
|
||||
caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), &mode);
|
||||
|
||||
*debug_mode = mode & 0x3;
|
||||
*rfm = (mode >> 2) & 0x7;
|
||||
if (debug_mode) *debug_mode = mode & 0x3;
|
||||
if (rfm) *rfm = (mode >> 2) & 0x7;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -512,8 +624,12 @@ int caribou_fpga_get_io_ctrl_pmod_dir (caribou_fpga_st* dev, uint8_t *dir)
|
|||
.mid = caribou_fpga_mid_io_ctrl,
|
||||
.ioc = IOC_IO_CTRL_PMOD_DIR
|
||||
};
|
||||
*dir = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), dir);
|
||||
if (dir)
|
||||
{
|
||||
*dir = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), dir);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -540,8 +656,12 @@ int caribou_fpga_get_io_ctrl_pmod_val (caribou_fpga_st* dev, uint8_t *val)
|
|||
.mid = caribou_fpga_mid_io_ctrl,
|
||||
.ioc = IOC_IO_CTRL_PMOD_VAL
|
||||
};
|
||||
*val = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), val);
|
||||
if (val)
|
||||
{
|
||||
*val = 0;
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), val);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -568,8 +688,12 @@ int caribou_fpga_get_io_ctrl_rf_state (caribou_fpga_st* dev, caribou_fpga_rf_pin
|
|||
.mid = caribou_fpga_mid_io_ctrl,
|
||||
.ioc = IOC_IO_CTRL_RF_PIN
|
||||
};
|
||||
memset(pins, 0, sizeof(caribou_fpga_rf_pin_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)pins);
|
||||
if (pins)
|
||||
{
|
||||
memset(pins, 0, sizeof(caribou_fpga_rf_pin_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)pins);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
@ -583,8 +707,12 @@ int caribou_fpga_get_smi_ctrl_fifo_status (caribou_fpga_st* dev, caribou_fpga_sm
|
|||
.mid = caribou_fpga_mid_smi_ctrl,
|
||||
.ioc = IOC_SMI_CTRL_FIFO_STATUS
|
||||
};
|
||||
memset(status, 0, sizeof(caribou_fpga_smi_fifo_status_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)status);
|
||||
if (status)
|
||||
{
|
||||
memset(status, 0, sizeof(caribou_fpga_smi_fifo_status_st));
|
||||
return caribou_fpga_spi_transfer (dev, (uint8_t*)(&oc), (uint8_t*)status);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
|
|
@ -98,6 +98,20 @@ typedef enum
|
|||
caribou_fpga_smi_channel_1 = 1,
|
||||
} caribou_fpga_smi_channel_en;
|
||||
|
||||
/**
|
||||
* @brief Syncronization bit (metadata) source. Either software
|
||||
* setting using "caribou_fpga_set_sys_ctrl_soft_sync_value"
|
||||
* or by using an external pulse on the PMOD 6/7 pins.
|
||||
* If no change is needed on a specific sync source,
|
||||
* "caribou_fpga_sync_src_no_change" should be used
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
caribou_fpga_sync_src_soft = 0,
|
||||
caribou_fpga_sync_src_pmod = 1,
|
||||
caribou_fpga_sync_src_no_change = 2,
|
||||
} caribou_fpga_sync_source_en;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/**
|
||||
|
@ -154,6 +168,19 @@ int caribou_fpga_set_debug_modes (caribou_fpga_st* dev, bool dbg_fifo_push, bool
|
|||
int caribou_fpga_set_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t gap);
|
||||
int caribou_fpga_get_sys_ctrl_tx_sample_gap (caribou_fpga_st* dev, uint8_t *gap);
|
||||
|
||||
int caribou_fpga_set_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en rx_09,
|
||||
caribou_fpga_sync_source_en rx_24,
|
||||
caribou_fpga_sync_source_en tx_09,
|
||||
caribou_fpga_sync_source_en tx_24);
|
||||
int caribou_fpga_get_sys_ctrl_sync_source (caribou_fpga_st* dev, caribou_fpga_sync_source_en *rx_09,
|
||||
caribou_fpga_sync_source_en *rx_24,
|
||||
caribou_fpga_sync_source_en *tx_09,
|
||||
caribou_fpga_sync_source_en *tx_24);
|
||||
|
||||
int caribou_fpga_set_sys_ctrl_soft_sync_value (caribou_fpga_st* dev, uint8_t rx_09,
|
||||
uint8_t rx_24,
|
||||
uint8_t tx_09,
|
||||
uint8_t tx_24);
|
||||
// I/O Controller
|
||||
int caribou_fpga_set_io_ctrl_mode (caribou_fpga_st* dev, uint8_t debug_mode, caribou_fpga_io_ctrl_rfm_en rfm);
|
||||
int caribou_fpga_get_io_ctrl_mode (caribou_fpga_st* dev, uint8_t *debug_mode, caribou_fpga_io_ctrl_rfm_en *rfm);
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -18,12 +18,13 @@
|
|||
#include "cariboulite_events.h"
|
||||
#include "cariboulite_setup.h"
|
||||
|
||||
|
||||
#define GET_MODEM_CH(rad_ch) ((rad_ch)==cariboulite_channel_s1g ? at86rf215_rf_channel_900mhz : at86rf215_rf_channel_2400mhz)
|
||||
#define GET_SMI_CH(rad_ch) ((rad_ch)==cariboulite_channel_s1g ? caribou_smi_channel_900 : caribou_smi_channel_2400)
|
||||
|
||||
static float sample_rate_middles[] = {3000, 1666, 1166, 900, 733, 583, 450};
|
||||
static float rx_bandwidth_middles[] = {225, 281, 356, 450, 562, 706, 893, 1125, 1406, 1781, 2250};
|
||||
static float tx_bandwidth_middles[] = {90, 112, 142, 180, 225, 282, 357, 450, 562, 712, 900};
|
||||
static float sample_rate_middles[] = {3000e3, 1666e3, 1166e3, 900e3, 733e3, 583e3, 450e3};
|
||||
static float rx_bandwidth_middles[] = {225e3, 281e3, 356e3, 450e3, 562e3, 706e3, 893e3, 1125e3, 1406e3, 1781e3, 2250e3};
|
||||
static float tx_bandwidth_middles[] = {90e3, 112e3, 142e3, 180e3, 225e3, 282e3, 357e3, 450e3, 562e3, 712e3, 900e3};
|
||||
|
||||
|
||||
//=========================================================================
|
||||
|
@ -187,8 +188,30 @@ int cariboulite_radio_set_rx_bandwidth(cariboulite_radio_state_st* radio,
|
|||
cariboulite_radio_rx_bw_en rx_bw)
|
||||
{
|
||||
cariboulite_radio_f_cut_en fcut = cariboulite_radio_rx_f_cut_half_fs;
|
||||
|
||||
/*if (rx_bw == cariboulite_radio_rx_bw_2500KHz || rx_bw == cariboulite_radio_rx_bw_2000KHz)
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_half_fs; // 2MHz cuttof
|
||||
}
|
||||
else if (rx_bw == cariboulite_radio_rx_bw_1562KHz ||
|
||||
rx_bw == cariboulite_radio_rx_bw_1250KHz ||
|
||||
rx_bw == cariboulite_radio_rx_bw_1000KHz)
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_0_75_half_fs; // 1.5MHz cuttof
|
||||
}
|
||||
else if (rx_bw == cariboulite_radio_rx_bw_787KHz ||
|
||||
rx_bw == cariboulite_radio_rx_bw_625KHz)
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_0_5_half_fs; // 1MHz cuttof
|
||||
}
|
||||
else
|
||||
{
|
||||
fcut = cariboulite_radio_rx_f_cut_0_25_half_fs; // 500kHz cuttof
|
||||
}*/
|
||||
|
||||
|
||||
radio->rx_fcut = fcut;
|
||||
|
||||
|
||||
at86rf215_radio_set_rx_bw_samp_st cfg =
|
||||
{
|
||||
.inverter_sign_if = 0,
|
||||
|
@ -197,8 +220,8 @@ int cariboulite_radio_set_rx_bandwidth(cariboulite_radio_state_st* radio,
|
|||
// to channel scheme. This increases the IF frequency to max 2.5MHz
|
||||
// thus places the internal LO fasr away from the signal => lower noise
|
||||
.bw = (at86rf215_radio_rx_bw_en)rx_bw,
|
||||
.fcut = (at86rf215_radio_f_cut_en)radio->rx_fcut, // keep the same
|
||||
.fs = (at86rf215_radio_sample_rate_en)radio->rx_fs, // keep the same
|
||||
.fcut = (at86rf215_radio_f_cut_en)radio->rx_fcut,
|
||||
.fs = (at86rf215_radio_sample_rate_en)radio->rx_fs,
|
||||
};
|
||||
at86rf215_radio_set_rx_bandwidth_sampling(&radio->sys->modem, GET_MODEM_CH(radio->type), &cfg);
|
||||
radio->rx_bw = rx_bw;
|
||||
|
@ -1053,12 +1076,11 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
|
||||
// then deactivate the modem's stream
|
||||
cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_trx_off);
|
||||
ret = caribou_smi_set_driver_streaming_state(&radio->sys->smi, smi_stream_idle);
|
||||
|
||||
// DEACTIVATION
|
||||
if (!activate)
|
||||
{
|
||||
// if we deactivate, first shut off the smi stream
|
||||
ret = caribou_smi_set_driver_streaming_state(&radio->sys->smi, smi_stream_idle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1088,14 +1110,7 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
// Activate the channel according to the configurations
|
||||
// RX on both channels looks the same
|
||||
if (radio->channel_direction == cariboulite_channel_dir_rx)
|
||||
{
|
||||
// Setup the IQ stream properties
|
||||
smi_stream_state_en smi_state = smi_stream_idle;
|
||||
if (radio->smi_channel_id == caribou_smi_channel_900)
|
||||
smi_state = smi_stream_rx_channel_0;
|
||||
else if (radio->smi_channel_id == caribou_smi_channel_2400)
|
||||
smi_state = smi_stream_rx_channel_1;
|
||||
|
||||
{
|
||||
at86rf215_iq_interface_config_st modem_iq_config = {
|
||||
.loopback_enable = radio->tx_loopback_anabled,
|
||||
.drv_strength = at86rf215_iq_drive_current_4ma,
|
||||
|
@ -1105,11 +1120,29 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
.radio24_mode = at86rf215_iq_if_mode,
|
||||
.clock_skew = at86rf215_iq_clock_data_skew_4_906ns,
|
||||
};
|
||||
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
|
||||
|
||||
|
||||
// Setup the IQ stream properties
|
||||
smi_stream_state_en smi_state = smi_stream_idle;
|
||||
if (radio->smi_channel_id == caribou_smi_channel_900)
|
||||
{
|
||||
modem_iq_config.radio09_mode = at86rf215_iq_if_mode;
|
||||
modem_iq_config.radio24_mode = at86rf215_baseband_mode;
|
||||
modem_iq_config.clock_skew = at86rf215_iq_clock_data_skew_4_906ns;
|
||||
smi_state = smi_stream_rx_channel_0;
|
||||
}
|
||||
else if (radio->smi_channel_id == caribou_smi_channel_2400)
|
||||
{
|
||||
modem_iq_config.radio09_mode = at86rf215_baseband_mode;
|
||||
modem_iq_config.radio24_mode = at86rf215_iq_if_mode;
|
||||
modem_iq_config.clock_skew = at86rf215_iq_clock_data_skew_2_906ns;
|
||||
smi_state = smi_stream_rx_channel_1;
|
||||
}
|
||||
|
||||
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
|
||||
|
||||
// configure FPGA with the correct rx channel
|
||||
caribou_fpga_set_smi_channel (&radio->sys->fpga, radio->type == cariboulite_channel_s1g? caribou_fpga_smi_channel_0 : caribou_fpga_smi_channel_1);
|
||||
//caribou_fpga_set_io_ctrl_dig (&radio->sys->fpga, radio->type == cariboulite_channel_s1g? 0 : 1, 0);
|
||||
caribou_fpga_set_smi_ctrl_data_direction(&radio->sys->fpga, 1);
|
||||
|
||||
// turn on the modem RX
|
||||
cariboulite_radio_set_modem_state(radio, cariboulite_radio_state_cmd_rx);
|
||||
|
@ -1135,7 +1168,7 @@ int cariboulite_radio_activate_channel(cariboulite_radio_state_st* radio,
|
|||
.tx_control_with_iq_if = !radio->cw_output,
|
||||
.radio09_mode = at86rf215_iq_if_mode,
|
||||
.radio24_mode = at86rf215_iq_if_mode,
|
||||
.clock_skew = at86rf215_iq_clock_data_skew_4_906ns,
|
||||
.clock_skew = at86rf215_iq_clock_data_skew_2_906ns,
|
||||
};
|
||||
at86rf215_setup_iq_if(&radio->sys->modem, &modem_iq_config);
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ int rffc507x_init( rffc507x_st* dev,
|
|||
set_RFFC507X_CTMAX(dev, 127);
|
||||
set_RFFC507X_P2CTV(dev, 12);
|
||||
set_RFFC507X_FULLD(dev, 0);*/
|
||||
set_RFFC507X_P2MIXIDD(dev, 4);
|
||||
set_RFFC507X_P2MIXIDD(dev, 5);
|
||||
|
||||
// Others
|
||||
set_RFFC507X_LDEN(dev, 1);
|
||||
|
|
Ładowanie…
Reference in New Issue