Skip to content

Commit

Permalink
Add Sensor API
Browse files Browse the repository at this point in the history
  • Loading branch information
zuckschwerdt committed May 19, 2019
1 parent b0203fd commit 147f82a
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 0 deletions.
166 changes: 166 additions & 0 deletions PlutoSDR_Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,172 @@ bool SoapyPlutoSDR::getFullDuplex( const int direction, const size_t channel ) c
return(true);
}


/*******************************************************************
* Sensor API
******************************************************************/

bool SoapyPlutoSDR::is_sensor_channel(struct iio_channel *chn) const
{
return (!iio_channel_is_output(chn) &&
(iio_channel_find_attr(chn, "raw") ||
iio_channel_find_attr(chn, "input")));
}

double SoapyPlutoSDR::get_sensor_value(struct iio_channel *chn) const
{
char *old_locale;
char buf[32];
double val = 0.0;

old_locale = strdup(setlocale(LC_NUMERIC, NULL));
setlocale(LC_NUMERIC, "C");

if (iio_channel_find_attr(chn, "input")) {
if (iio_channel_attr_read(chn, "input", buf, sizeof(buf)) > 0)
val = strtod(buf, NULL);
} else {
if (iio_channel_attr_read(chn, "raw", buf, sizeof(buf)) > 0)
val = strtod(buf, NULL);

if (iio_channel_find_attr(chn, "offset")) {
if (iio_channel_attr_read(chn, "offset", buf, sizeof(buf)) > 0)
val += strtod(buf, NULL);
}

if (iio_channel_find_attr(chn, "scale")) {
if (iio_channel_attr_read(chn, "scale", buf, sizeof(buf)) > 0)
val *= strtod(buf, NULL);
}
}

setlocale(LC_NUMERIC, old_locale);
free(old_locale);

return val / 1000.0;
}

const char *SoapyPlutoSDR::id_to_unit(const char *id) const
{
static struct {
const char *id;
const char *unit;
} map[] = {
{ "current", "A" },
{ "power", "W" },
{ "temp", "C" },
{ "voltage", "V" },
{ 0, },
};

unsigned int i;

for (i = 0; map[i].id; ++i) {
if (!strncmp(id, map[i].id, strlen(map[i].id)))
return map[i].unit;
}

return "";
}

std::vector<std::string> SoapyPlutoSDR::listSensors(void) const
{
/*
iio:device2: xadc
10 channels found:
temp0: (input)
voltage0: vccint (input)
voltage1: vccaux (input)
voltage2: vccbram (input)
voltage3: vccpint (input)
voltage4: vccpaux (input)
voltage5: vccoddr (input)
voltage6: vrefp (input)
voltage7: vrefn (input)
voltage8: (input)
iio:device0: adm1177
2 channels found:
current0: (input)
voltage0: (input)
iio:device1: ad9361-phy
9 channels found:
temp0: (input)
voltage2: (input)
*/
std::vector<std::string> sensors;

sensors.push_back("xadc_temp0");
sensors.push_back("xadc_voltage0");
sensors.push_back("xadc_voltage1");
sensors.push_back("xadc_voltage2");
sensors.push_back("xadc_voltage3");
sensors.push_back("xadc_voltage4");
sensors.push_back("xadc_voltage5");
sensors.push_back("xadc_voltage6");
sensors.push_back("xadc_voltage7");
sensors.push_back("xadc_voltage8");
sensors.push_back("adm1177_current0");
sensors.push_back("adm1177_voltage0");
sensors.push_back("ad9361-phy_temp0");
sensors.push_back("ad9361-phy_voltage2");

return sensors;
}

SoapySDR::ArgInfo SoapyPlutoSDR::getSensorInfo(const std::string &key) const
{
SoapySDR::ArgInfo info;

std::size_t dash = key.find("_");
if (dash < std::string::npos)
{
std::string deviceStr = key.substr(0, dash);
std::string channelStr = key.substr(dash + 1);

iio_device *dev = iio_context_find_device(ctx, deviceStr.c_str());
if (!dev)
return info;
iio_channel *chn = iio_device_find_channel(dev, channelStr.c_str(), false);
if (!chn)
return info;

const char *name = iio_channel_get_name(chn);
info.key = key;
if (name)
info.name = name;
info.type = SoapySDR::ArgInfo::FLOAT;
info.value = "0.0";
info.units = id_to_unit(channelStr.c_str());
}

return info;
}

std::string SoapyPlutoSDR::readSensor(const std::string &key) const
{
std::string sensorValue;

std::size_t dash = key.find("_");
if (dash < std::string::npos)
{
std::string deviceStr = key.substr(0, dash);
std::string channelStr = key.substr(dash + 1);

iio_device *dev = iio_context_find_device(ctx, deviceStr.c_str());
if (!dev)
return sensorValue;
iio_channel *chn = iio_device_find_channel(dev, channelStr.c_str(), false);
if (!chn)
return sensorValue;

double value = get_sensor_value(chn);
sensorValue.assign(std::to_string(value));
}

return sensorValue;
}


/*******************************************************************
* Settings API
******************************************************************/
Expand Down
15 changes: 15 additions & 0 deletions SoapyPlutoSDR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ class SoapyPlutoSDR : public SoapySDR::Device{
);


/*******************************************************************
* Sensor API
******************************************************************/

std::vector<std::string> listSensors(void) const;

SoapySDR::ArgInfo getSensorInfo(const std::string &key) const;

std::string readSensor(const std::string &key) const;


/*******************************************************************
* Settings API
******************************************************************/
Expand Down Expand Up @@ -292,6 +303,10 @@ class SoapyPlutoSDR : public SoapySDR::Device{
bool IsValidRxStreamHandle(SoapySDR::Stream* handle) const;
bool IsValidTxStreamHandle(SoapySDR::Stream* handle);

bool is_sensor_channel(struct iio_channel *chn) const;
double get_sensor_value(struct iio_channel *chn) const;
const char *id_to_unit(const char *id) const;

iio_device *dev;
iio_device *rx_dev;
iio_device *tx_dev;
Expand Down

0 comments on commit 147f82a

Please sign in to comment.