mirror of https://github.com/PentHertz/srsLTE.git
Radio: channel map includes device mapping, unmapped Rx uses dummy buffers
This commit is contained in:
parent
74fde5597f
commit
51c6e8d1a6
|
@ -59,7 +59,7 @@ public:
|
|||
low_freq = low_freq_;
|
||||
high_freq = high_freq_;
|
||||
}
|
||||
bool contains(float freq)
|
||||
bool contains(float freq) const
|
||||
{
|
||||
if (low_freq == 0 && high_freq == 0) {
|
||||
return true;
|
||||
|
@ -67,8 +67,8 @@ public:
|
|||
return freq >= low_freq && freq <= high_freq;
|
||||
}
|
||||
}
|
||||
float get_low() { return low_freq; }
|
||||
float get_high() { return high_freq; }
|
||||
float get_low() const { return low_freq; }
|
||||
float get_high() const { return high_freq; }
|
||||
|
||||
private:
|
||||
float low_freq = 0;
|
||||
|
@ -82,6 +82,19 @@ public:
|
|||
uint32_t carrier_idx;
|
||||
} channel_cfg_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t carrier_idx; // Physical channel index of all channels
|
||||
uint32_t device_idx; // RF Device index
|
||||
uint32_t channel_idx; // Channel index in the RF Device
|
||||
} device_mapping_t;
|
||||
|
||||
/**
|
||||
* Sets the number of the RF device channels and antennas per carrier
|
||||
* @param nof_channels_x_dev_ Number of RF channels per device
|
||||
* @param nof_antennas_ number of antennas per carrrier
|
||||
*/
|
||||
void set_config(const uint32_t& nof_channels_x_dev_, const uint32_t& nof_antennas_);
|
||||
|
||||
/**
|
||||
* Sets the channel configuration. If no channels are configured no physical channels can be allocated
|
||||
* @param channels_
|
||||
|
@ -105,14 +118,14 @@ public:
|
|||
bool release_freq(const uint32_t& logical_ch);
|
||||
|
||||
/**
|
||||
* Obtains the carrier index configured in set_channels() in the radio to which the logical channel logical_ch has
|
||||
* been mapped to
|
||||
* Obtains the physical information configured in set_channels() in the radio to which the logical channel logical_ch
|
||||
* has been mapped to
|
||||
* @param logical_ch logical channel index
|
||||
* @return <0 if logical_ch is not allocated, true otherwise
|
||||
* @return A device mapping structure carrying the mapping information
|
||||
*
|
||||
* @see channel_cfg_t
|
||||
*/
|
||||
int get_carrier_idx(const uint32_t& logical_ch);
|
||||
device_mapping_t get_device_mapping(const uint32_t& logical_ch, const uint32_t& antenna_idx = 0) const;
|
||||
|
||||
/**
|
||||
* Checks if the channel has been allocated using allocate_freq()
|
||||
|
@ -120,12 +133,20 @@ public:
|
|||
* @param logical_ch logical channel index
|
||||
* @return true if the channel is allocated, false otherwise
|
||||
*/
|
||||
bool is_allocated(const uint32_t& logical_ch);
|
||||
bool is_allocated(const uint32_t& logical_ch) const;
|
||||
|
||||
/**
|
||||
* Represents the channel mapping into a string
|
||||
* @return a string representing the current channel mapping
|
||||
*/
|
||||
std::string to_string() const;
|
||||
|
||||
private:
|
||||
std::list<channel_cfg_t> available_channels = {};
|
||||
std::map<uint32_t, channel_cfg_t> allocated_channels = {};
|
||||
std::mutex mutex = {};
|
||||
mutable std::mutex mutex = {};
|
||||
uint32_t nof_antennas = 1;
|
||||
uint32_t nof_channels_x_dev = 1;
|
||||
};
|
||||
|
||||
} // namespace srslte
|
||||
|
|
|
@ -103,6 +103,8 @@ private:
|
|||
srslte::logger* logger = nullptr;
|
||||
phy_interface_radio* phy = nullptr;
|
||||
cf_t* zeros = nullptr;
|
||||
cf_t* buffer = nullptr;
|
||||
std::array<cf_t*, SRSLTE_MAX_CHANNELS> dummy_buffers;
|
||||
|
||||
rf_timestamp_t end_of_burst_time = {};
|
||||
bool is_start_of_burst = false;
|
||||
|
@ -191,7 +193,7 @@ private:
|
|||
* @param radio_buffers Actual physical radio buffer
|
||||
* @return It returns true if the mapping was successful, otherwise it returns false.
|
||||
*/
|
||||
bool map_channels(channel_mapping& map,
|
||||
bool map_channels(const channel_mapping& map,
|
||||
uint32_t device_idx,
|
||||
uint32_t sample_offset,
|
||||
const rf_buffer_interface& buffer,
|
||||
|
|
|
@ -21,9 +21,16 @@
|
|||
|
||||
#include "srslte/radio/channel_mapping.h"
|
||||
#include "srslte/phy/utils/debug.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace srslte {
|
||||
|
||||
void channel_mapping::set_config(const uint32_t& nof_channels_x_dev_, const uint32_t& nof_antennas_)
|
||||
{
|
||||
nof_channels_x_dev = nof_channels_x_dev_;
|
||||
nof_antennas = nof_antennas_;
|
||||
}
|
||||
|
||||
bool channel_mapping::allocate_freq(const uint32_t& logical_ch, const float& freq)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
@ -40,10 +47,11 @@ bool channel_mapping::allocate_freq(const uint32_t& logical_ch, const float& fre
|
|||
if (c->band.contains(freq)) {
|
||||
allocated_channels[logical_ch] = *c;
|
||||
available_channels.erase(c);
|
||||
printf("-- Current mapping: %s\n", to_string().c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ERROR("allocate_freq: No channels available for frequency=%.1f\n", freq);
|
||||
ERROR("allocate_freq: No channels available for frequency=%.1f %s\n", freq, to_string().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -58,19 +66,38 @@ bool channel_mapping::release_freq(const uint32_t& logical_ch)
|
|||
return false;
|
||||
}
|
||||
|
||||
int channel_mapping::get_carrier_idx(const uint32_t& logical_ch)
|
||||
channel_mapping::device_mapping_t channel_mapping::get_device_mapping(const uint32_t& logical_ch,
|
||||
const uint32_t& antenna_idx) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
if (allocated_channels.count(logical_ch)) {
|
||||
return allocated_channels[logical_ch].carrier_idx;
|
||||
if (allocated_channels.count(logical_ch) > 0) {
|
||||
uint32_t carrier_idx = allocated_channels.at(logical_ch).carrier_idx;
|
||||
uint32_t channel_idx = carrier_idx * nof_antennas + antenna_idx;
|
||||
return {carrier_idx, channel_idx / nof_channels_x_dev, channel_idx % nof_channels_x_dev};
|
||||
}
|
||||
return -1;
|
||||
return {UINT32_MAX, UINT32_MAX, UINT32_MAX};
|
||||
}
|
||||
|
||||
bool channel_mapping::is_allocated(const uint32_t& logical_ch)
|
||||
bool channel_mapping::is_allocated(const uint32_t& logical_ch) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
return allocated_channels.count(logical_ch) > 0;
|
||||
}
|
||||
|
||||
std::string channel_mapping::to_string() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "[";
|
||||
for (const auto& c : allocated_channels) {
|
||||
uint32_t carrier_idx = allocated_channels.at(c.first).carrier_idx;
|
||||
uint32_t channel_idx = carrier_idx * nof_antennas;
|
||||
ss << "{carrier: " << c.first << ", device: " << channel_idx / nof_channels_x_dev
|
||||
<< ", channel: " << channel_idx % nof_channels_x_dev
|
||||
<< ", center_freq: " << (c.second.band.get_low() + c.second.band.get_high()) / 2e6 << " MHz },";
|
||||
}
|
||||
ss << "]";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace srslte
|
|
@ -32,12 +32,19 @@ radio::radio(srslte::log_filter* log_h_) : logger(nullptr), log_h(log_h_), zeros
|
|||
{
|
||||
zeros = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX);
|
||||
srslte_vec_cf_zero(zeros, SRSLTE_SF_LEN_MAX);
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) {
|
||||
dummy_buffers[i] = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX);
|
||||
srslte_vec_cf_zero(dummy_buffers[i], SRSLTE_SF_LEN_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
radio::radio(srslte::logger* logger_) : logger(logger_), log_h(nullptr), zeros(nullptr)
|
||||
{
|
||||
zeros = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX);
|
||||
srslte_vec_cf_zero(zeros, SRSLTE_SF_LEN_MAX);
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) {
|
||||
dummy_buffers[i] = srslte_vec_cf_malloc(SRSLTE_SF_LEN_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
radio::~radio()
|
||||
|
@ -46,6 +53,13 @@ radio::~radio()
|
|||
free(zeros);
|
||||
zeros = nullptr;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) {
|
||||
if (dummy_buffers[i]) {
|
||||
free(dummy_buffers[i]);
|
||||
dummy_buffers[i] = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int radio::init(const rf_args_t& args, phy_interface_radio* phy_)
|
||||
|
@ -115,6 +129,9 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_)
|
|||
rf_info.resize(device_args_list.size());
|
||||
rx_offset_n.resize(device_args_list.size());
|
||||
|
||||
tx_channel_mapping.set_config(nof_channels_x_dev, nof_antennas);
|
||||
rx_channel_mapping.set_config(nof_channels_x_dev, nof_antennas);
|
||||
|
||||
// Init and start Radios
|
||||
for (uint32_t device_idx = 0; device_idx < (uint32_t)device_args_list.size(); device_idx++) {
|
||||
if (not open_dev(device_idx, args.device_name, device_args_list[device_idx])) {
|
||||
|
@ -267,6 +284,12 @@ bool radio::rx_dev(const uint32_t& device_idx, const rf_buffer_interface& buffer
|
|||
double* frac_secs = rxd_time ? &rxd_time->frac_secs : nullptr;
|
||||
|
||||
void* radio_buffers[SRSLTE_MAX_CHANNELS] = {};
|
||||
|
||||
// Discard channels not allocated, need to point to valid buffer
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) {
|
||||
radio_buffers[i] = dummy_buffers[i];
|
||||
}
|
||||
|
||||
if (not map_channels(rx_channel_mapping, device_idx, 0, buffer, radio_buffers)) {
|
||||
log_h->error("Mapping logical channels to physical channels for transmission\n");
|
||||
return false;
|
||||
|
@ -437,6 +460,12 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons
|
|||
srslte_timestamp_add(&end_of_burst_time[device_idx], 0, (double)nof_samples / cur_tx_srate);
|
||||
|
||||
void* radio_buffers[SRSLTE_MAX_CHANNELS] = {};
|
||||
|
||||
// Discard channels not allocated, need to point to valid buffer
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) {
|
||||
radio_buffers[i] = zeros;
|
||||
}
|
||||
|
||||
if (not map_channels(tx_channel_mapping, device_idx, sample_offset, buffer, radio_buffers)) {
|
||||
log_h->error("Mapping logical channels to physical channels for transmission\n");
|
||||
return false;
|
||||
|
@ -484,31 +513,28 @@ void radio::set_rx_freq(const uint32_t& carrier_idx, const double& freq)
|
|||
|
||||
// Map carrier index to physical channel
|
||||
if (rx_channel_mapping.allocate_freq(carrier_idx, freq)) {
|
||||
uint32_t physical_channel_idx = rx_channel_mapping.get_carrier_idx(carrier_idx);
|
||||
log_h->info("Mapping RF channel %d to logical carrier %d on f_rx=%.1f MHz\n",
|
||||
physical_channel_idx * nof_antennas,
|
||||
channel_mapping::device_mapping_t device_mapping = rx_channel_mapping.get_device_mapping(carrier_idx);
|
||||
log_h->info("Mapping RF channel %d (device=%d, channel=%d) to logical carrier %d on f_rx=%.1f MHz\n",
|
||||
device_mapping.carrier_idx,
|
||||
device_mapping.device_idx,
|
||||
device_mapping.channel_idx,
|
||||
carrier_idx,
|
||||
freq / 1e6);
|
||||
if (cur_rx_freqs[physical_channel_idx] != freq) {
|
||||
if ((physical_channel_idx + 1) * nof_antennas <= nof_channels) {
|
||||
cur_rx_freqs[physical_channel_idx] = freq;
|
||||
if (cur_rx_freqs[device_mapping.carrier_idx] != freq) {
|
||||
if ((device_mapping.carrier_idx + 1) * nof_antennas <= nof_channels) {
|
||||
cur_rx_freqs[device_mapping.carrier_idx] = freq;
|
||||
for (uint32_t i = 0; i < nof_antennas; i++) {
|
||||
uint32_t phys_antenna_idx = physical_channel_idx * nof_antennas + i;
|
||||
|
||||
// From channel number deduce RF device index and channel
|
||||
uint32_t rf_device_idx = phys_antenna_idx / nof_channels_x_dev;
|
||||
uint32_t rf_channel_idx = phys_antenna_idx % nof_channels_x_dev;
|
||||
|
||||
srslte_rf_set_rx_freq(&rf_devices[rf_device_idx], rf_channel_idx, freq + freq_offset);
|
||||
channel_mapping::device_mapping_t dm = rx_channel_mapping.get_device_mapping(carrier_idx, 0);
|
||||
srslte_rf_set_rx_freq(&rf_devices[dm.device_idx], dm.channel_idx, freq + freq_offset);
|
||||
}
|
||||
} else {
|
||||
log_h->error("set_rx_freq: physical_channel_idx=%d for %d antennas exceeds maximum channels (%d)\n",
|
||||
physical_channel_idx,
|
||||
device_mapping.carrier_idx,
|
||||
nof_antennas,
|
||||
nof_channels);
|
||||
}
|
||||
} else {
|
||||
log_h->info("RF channel %d already on freq\n", physical_channel_idx * nof_antennas);
|
||||
log_h->info("RF Rx channel %d already on freq\n", device_mapping.carrier_idx);
|
||||
}
|
||||
} else {
|
||||
log_h->error("set_rx_freq: Could not allocate frequency %.1f MHz to carrier %d\n", freq / 1e6, carrier_idx);
|
||||
|
@ -547,19 +573,15 @@ void radio::set_rx_srate(const double& srate)
|
|||
|
||||
void radio::set_channel_rx_offset(uint32_t ch, int32_t offset_samples)
|
||||
{
|
||||
int physical_channel_idx = rx_channel_mapping.get_carrier_idx(ch);
|
||||
uint32_t device_idx = rx_channel_mapping.get_device_mapping(ch, 0).device_idx;
|
||||
|
||||
// Return if invalid index
|
||||
if (physical_channel_idx < SRSLTE_SUCCESS) {
|
||||
if (device_idx >= rf_devices.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate device index
|
||||
uint32_t device_idx = (nof_antennas * (uint32_t)physical_channel_idx) / nof_channels_x_dev;
|
||||
|
||||
// Skip correction if device matches the first logical channel
|
||||
int main_physical_channel_idx = rx_channel_mapping.get_carrier_idx(0);
|
||||
uint32_t main_device_idx = (nof_antennas * (uint32_t)main_physical_channel_idx) / nof_channels_x_dev;
|
||||
uint32_t main_device_idx = rx_channel_mapping.get_device_mapping(0, 0).device_idx;
|
||||
if (device_idx == main_device_idx) {
|
||||
return;
|
||||
}
|
||||
|
@ -588,31 +610,29 @@ void radio::set_tx_freq(const uint32_t& carrier_idx, const double& freq)
|
|||
|
||||
// Map carrier index to physical channel
|
||||
if (tx_channel_mapping.allocate_freq(carrier_idx, freq)) {
|
||||
uint32_t physical_channel_idx = tx_channel_mapping.get_carrier_idx(carrier_idx);
|
||||
log_h->info("Mapping RF channel %d to logical carrier %d on f_tx=%.1f MHz\n",
|
||||
physical_channel_idx * nof_antennas,
|
||||
channel_mapping::device_mapping_t device_mapping = tx_channel_mapping.get_device_mapping(carrier_idx);
|
||||
log_h->info("Mapping RF channel %d (device=%d, channel=%d) to logical carrier %d on f_tx=%.1f MHz\n",
|
||||
device_mapping.carrier_idx,
|
||||
device_mapping.device_idx,
|
||||
device_mapping.channel_idx,
|
||||
carrier_idx,
|
||||
freq / 1e6);
|
||||
if (cur_tx_freqs[physical_channel_idx] != freq) {
|
||||
if ((physical_channel_idx + 1) * nof_antennas <= nof_channels) {
|
||||
cur_tx_freqs[physical_channel_idx] = freq;
|
||||
if (cur_tx_freqs[device_mapping.carrier_idx] != freq) {
|
||||
if ((device_mapping.carrier_idx + 1) * nof_antennas <= nof_channels) {
|
||||
cur_tx_freqs[device_mapping.carrier_idx] = freq;
|
||||
for (uint32_t i = 0; i < nof_antennas; i++) {
|
||||
uint32_t phys_antenna_idx = physical_channel_idx * nof_antennas + i;
|
||||
device_mapping = tx_channel_mapping.get_device_mapping(carrier_idx, i);
|
||||
|
||||
// From channel number deduce RF device index and channel
|
||||
uint32_t rf_device_idx = phys_antenna_idx / nof_channels_x_dev;
|
||||
uint32_t rf_channel_idx = phys_antenna_idx % nof_channels_x_dev;
|
||||
|
||||
srslte_rf_set_tx_freq(&rf_devices[rf_device_idx], rf_channel_idx, freq + freq_offset);
|
||||
srslte_rf_set_tx_freq(&rf_devices[device_mapping.device_idx], device_mapping.channel_idx, freq + freq_offset);
|
||||
}
|
||||
} else {
|
||||
log_h->error("set_tx_freq: physical_channel_idx=%d for %d antennas exceeds maximum channels (%d)\n",
|
||||
physical_channel_idx,
|
||||
device_mapping.carrier_idx,
|
||||
nof_antennas,
|
||||
nof_channels);
|
||||
}
|
||||
} else {
|
||||
log_h->info("RF channel %d already on freq\n", physical_channel_idx * nof_antennas);
|
||||
log_h->info("RF Tx channel %d already on freq\n", device_mapping.carrier_idx);
|
||||
}
|
||||
} else {
|
||||
log_h->error("set_tx_freq: Could not allocate frequency %.1f MHz to carrier %d\n", freq / 1e6, carrier_idx);
|
||||
|
@ -835,16 +855,12 @@ void radio::rf_msg_callback(void* arg, srslte_rf_error_t error)
|
|||
}
|
||||
}
|
||||
|
||||
bool radio::map_channels(channel_mapping& map,
|
||||
bool radio::map_channels(const channel_mapping& map,
|
||||
uint32_t device_idx,
|
||||
uint32_t sample_offset,
|
||||
const rf_buffer_interface& buffer,
|
||||
void* radio_buffers[SRSLTE_MAX_CHANNELS])
|
||||
{
|
||||
// Discard channels not allocated, need to point to valid buffer
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CHANNELS; i++) {
|
||||
radio_buffers[i] = zeros;
|
||||
}
|
||||
// Conversion from safe C++ std::array to the unsafe C interface. We must ensure that the RF driver implementation
|
||||
// accepts up to SRSLTE_MAX_CHANNELS buffers
|
||||
for (uint32_t i = 0; i < nof_carriers; i++) {
|
||||
|
@ -853,25 +869,17 @@ bool radio::map_channels(channel_mapping& map,
|
|||
continue;
|
||||
}
|
||||
|
||||
// Get physical channel
|
||||
uint32_t physical_idx = map.get_carrier_idx(i);
|
||||
|
||||
// Map each antenna
|
||||
for (uint32_t j = 0; j < nof_antennas; j++) {
|
||||
channel_mapping::device_mapping_t physical_idx = map.get_device_mapping(i, j);
|
||||
|
||||
// Detect mapping out-of-bounds
|
||||
if (physical_idx * nof_antennas + j >= SRSLTE_MAX_CHANNELS) {
|
||||
if (physical_idx.channel_idx >= nof_channels_x_dev) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate actual physical port index
|
||||
uint32_t phys_chan_idx = physical_idx * nof_antennas + j;
|
||||
|
||||
// Deduce physical device and port
|
||||
uint32_t rf_device_idx = phys_chan_idx / nof_channels_x_dev;
|
||||
uint32_t rf_channel_idx = phys_chan_idx % nof_channels_x_dev;
|
||||
|
||||
// Set pointer if device index matches
|
||||
if (rf_device_idx == device_idx) {
|
||||
if (physical_idx.device_idx == device_idx) {
|
||||
cf_t* ptr = buffer.get(i, j, nof_antennas);
|
||||
|
||||
// Add sample offset only if it is a valid pointer
|
||||
|
@ -879,7 +887,7 @@ bool radio::map_channels(channel_mapping& map,
|
|||
ptr += sample_offset;
|
||||
}
|
||||
|
||||
radio_buffers[rf_channel_idx] = ptr;
|
||||
radio_buffers[physical_idx.channel_idx] = ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue