* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-//debug print levels are err/warn/info/dbg/spew
#include <config.h>
#include <fcntl.h>
#include <glib.h>
#include "libsigrok-internal.h"
#include "protocol.h"
-//Baud rate is really a don't care because we run USB CDC, dtr must be 1.
-//flow should be zero since we don't
-//use xon/xoff
+/*Baud rate is really a don't care because we run USB CDC, dtr must be 1.
+flow should be zero since we don't use xon/xoff
+*/
#define SERIALCOMM "115200/8n1/dtr=1/rts=0/flow=0"
+/* Use the force_detect scan option as a way to pass user information to the device
+ the string must use only 0-9,a-z,A-Z,'.','=' and '-'* and be less than 60 characters */
static const uint32_t scanopts[] = {
- SR_CONF_CONN, //Required OS name for the port, i.e. /dev/ttyACM0
- SR_CONF_SERIALCOMM, //Optional config of the port, i.e. 115200/8n1
+ SR_CONF_CONN, /*Required OS name for the port, i.e. /dev/ttyACM0 */
+ SR_CONF_SERIALCOMM, /*Optional config of the port, i.e. 115200/8n1 */
+ SR_CONF_FORCE_DETECT
};
-//Sample rate can either provide a std_gvar_samplerates_steps or a std_gvar_samplerates.
-//The latter is just a long list of every supported rate.
-//For the steps, pulseview/pv/toolbars/mainbar.cpp will do a min,max,step. If step is
-//1 then it provides a 1,2,5,10 select otherwise it allows a spin box.
-//Going with the full list because while the spin box is more flexible, it is harder to read
+/*Sample rate can either provide a std_gvar_samplerates_steps or a std_gvar_samplerates.
+The latter is just a long list of every supported rate.
+For the steps, pulseview/pv/toolbars/mainbar.cpp will do a min,max,step. If step is
+1 then it provides a 1,2,5,10 select otherwise it allows a spin box.
+Going with the full list because while the spin box is more flexible, it is harder to read
+*/
static const uint64_t samplerates[] = {
SR_KHZ(5),
SR_KHZ(6),
SR_KHZ(100),
SR_KHZ(125),
SR_KHZ(150),
- SR_KHZ(160),//max rate of 3 ADC channels that has integer divisor/dividend
+ SR_KHZ(160),/*max rate of 3 ADC channels that has integer divisor/dividend*/
SR_KHZ(200),
- SR_KHZ(250), //max rate of 2 ADC channels
+ SR_KHZ(250), /*max rate of 2 ADC channels*/
SR_KHZ(300),
SR_KHZ(400),
SR_KHZ(500),
SR_KHZ(600),
SR_KHZ(800),
- //Give finer granularity near the thresholds of RLE effectiveness ~1-4Msps
- //Also use 1.2 and 2.4 as likely max values for ADC overclocking
+ /*Give finer granularity near the thresholds of RLE effectiveness ~1-4Msps
+ Also use 1.2 and 2.4 as likely max values for ADC overclocking */
SR_MHZ(1),
SR_MHZ(1.2),
SR_MHZ(1.5),
SR_MHZ(30),
SR_MHZ(40),
SR_MHZ(60),
- //The baseline 120Mhz PICO clock won't support an 80 or 100
- //with non fractional divisor, but an overclocked version or one
- //that modified sysclk could
+ /*The baseline 120Mhz PICO clock won't support an 80 or 100
+ with non fractional divisor, but an overclocked version or one
+ that modified sysclk could */
SR_MHZ(80),
SR_MHZ(100),
SR_MHZ(120),
- //These may not be practically useful, but someone might want to
- //try to make it work with overclocking
+ /*These may not be practically useful, but someone might want to
+ try to make it work with overclocking */
SR_MHZ(150),
SR_MHZ(200),
SR_MHZ(240)
SR_CONF_LOGIC_ANALYZER,
};
-//SW trigger requires this
static const int32_t trigger_matches[] = {
SR_TRIGGER_ZERO,
SR_TRIGGER_ONE,
static const uint32_t devopts[] = {
-//CLI prefers LIMIT_SAMPLES to be a list of high,low
SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
SR_CONF_TRIGGER_MATCH | SR_CONF_LIST,
SR_CONF_CAPTURE_RATIO | SR_CONF_GET | SR_CONF_SET,
-//pulseview needs a list return to allow sample rate setting
SR_CONF_SAMPLERATE | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
};
struct sr_channel *ch;
GSList *l;
int num_read;
- unsigned int i;
- const char *conn, *serialcomm;
+ int i;
+ const char *conn,*serialcomm,*force_detect;
char buf[32];
+ char ustr[64];
int len;
uint8_t num_a, num_d, a_size;
gchar *channel_name;
- conn = serialcomm = NULL;
+ conn = serialcomm = force_detect = NULL;
for (l = options; l; l = l->next) {
src = l->data;
switch (src->key) {
case SR_CONF_SERIALCOMM:
serialcomm = g_variant_get_string(src->data, NULL);
break;
+ case SR_CONF_FORCE_DETECT:
+ force_detect = g_variant_get_string(src->data, NULL);
+ sr_info("Force detect string %s",force_detect);
+ break;
}
}
if (!conn)
sr_info("Resetting device with *s at %s.", conn);
send_serial_char(serial, '*');
g_usleep(10000);
- //drain any inflight data
do {
sr_warn("Drain reads");
len = serial_read_blocking(serial, buf, 32, 100);
if (len)
sr_dbg("Dropping in flight serial data");
} while (len > 0);
-
-
- //Send identify
- num_read = send_serial_w_resp(serial, "i\n", buf, 17);
+ /*Send the user string with the identify */
+ if(force_detect
+ && (strlen(force_detect)<=60)){
+ sprintf(ustr,"i%s\n",force_detect);
+ sr_info("User string %s",ustr);
+ num_read = send_serial_w_resp(serial, ustr, buf, 17);
+ }else{
+ num_read = send_serial_w_resp(serial, "i\n", buf, 17);
+ }
if (num_read < 16) {
sr_err("1st identify failed");
serial_close(serial);
return NULL;
}
}
- //Expected ID response is SRPICO,AxxyDzz,VV
- //where xx are number of analog channels, y is bytes per analog sample
- //and zz is number of digital channels, and VV is two digit version# which must be 02
+ /*Expected ID response is SRPICO,AxxyDzz,VV
+ where xx are number of analog channels, y is bytes per analog sample (7 bits per byte)
+ and zz is number of digital channels, and VV is two digit version# which must be 02 */
if ((num_read < 16)
|| (strncmp(buf, "SRPICO,A", 8))
|| (buf[11] != 'D')
return NULL;
}
a_size = buf[10] - '0';
- buf[10] = '\0'; //Null to end the str for atois
- buf[14] = '\0'; //Null to end the str for atois
+ buf[10] = '\0'; /*Null to end the str for atois */
+ buf[14] = '\0';
num_a = atoi(&buf[8]);
num_d = atoi(&buf[12]);
}
devc = g_malloc0(sizeof(struct dev_context));
devc->a_size = a_size;
- //multiple bytes per analog sample not supported
- if ((num_a > 0) && (devc->a_size != 1)) {
- sr_err("Only Analog Size of 1 supported\n\r");
- return NULL;
- }
devc->num_a_channels = num_a;
devc->num_d_channels = num_d;
devc->a_chan_mask = ((1 << num_a) - 1);
devc->d_chan_mask = ((1 << num_d) - 1);
-//The number of bytes that each digital sample in the buffers sent to the session.
-//All logical channels are packed together, where a slice of N channels takes roundup(N/8) bytes
-//This never changes even if channels are disabled because PV expects disabled channels to still
-//be accounted for in the packing
+/*The number of bytes that each digital sample in the buffers sent to the session.
+All logical channels are packed together, where a slice of N channels takes roundup(N/8) bytes
+This never changes even if channels are disabled because PV expects disabled channels to still
+be accounted for in the packing */
devc->dig_sample_bytes = ((devc->num_d_channels + 7) / 8);
- //These are the slice sizes of the data on the wire
- //1 7 bit field per byte
+ /*These are the slice sizes of the data on the wire
+ 1 7 bit field per byte */
devc->bytes_per_slice = (devc->num_a_channels * devc->a_size);
if (devc->num_d_channels > 0) {
- // logic sent in groups of 7
+ /* logic sent in groups of 7*/
devc->bytes_per_slice += (devc->num_d_channels + 6) / 7;
}
sr_dbg("num channels a %d d %d bps %d dsb %d", num_a, num_d,
devc->bytes_per_slice, devc->dig_sample_bytes);
-//Each analog channel is it's own group
-//Digital are just channels
-//Grouping of channels is rather arbitrary as parameters like sample rate and number of samples
-//apply to all changes. Analog channels do have a scale and offset, but that is applied
-//without involvement of the session.
+/* Each analog channel is it's own group
+Digital are just channels
+Grouping of channels is rather arbitrary as parameters like sample rate and number of samples
+apply to all changes. Analog channels do have a scale and offset, but that is applied
+without involvement of the session.
+*/
devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group *) *
devc->num_a_channels);
for (i = 0; i < devc->num_a_channels; i++) {
channel_name = g_strdup_printf("A%d", i);
- //sdi, index, type, enabled,name
ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE,
channel_name);
devc->analog_groups[i] =
if (devc->num_d_channels > 0) {
for (i = 0; i < devc->num_d_channels; i++) {
- //Name digital channels starting at D2 to match pico board pin names
+ /*Name digital channels starting at D2 to match pico board pin names*/
channel_name = g_strdup_printf("D%d", i + 2);
sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE,
channel_name);
}
}
- //In large sample usages we get the call to receive with large transfers.
- //Since the CDC serial implemenation can silenty lose data as it gets close to full, allocate
- //storage for a half buffer which in a worst case scenario has 2x ratio of transmitted bytes
- // to storage bytes.
- //Note: The intent of making this buffer large is to prevent CDC serial buffer overflows.
- //However, it is likely that if the host is running slow (i.e. it's a raspberry pi model 3) that it becomes
- //compute bound and doesn't service CDC serial responses in time to not overflow the internal CDC buffers.
- //And thus no serial buffer is large enough. But, it's only 32K....
+ /*In large sample usages we get the call to receive with large transfers.
+ Since the CDC serial implemenation can silenty lose data as it gets close to full, allocate
+ storage for a half buffer which in a worst case scenario has 2x ratio of transmitted bytes
+ to storage bytes.
+ Note: The intent of making this buffer large is to prevent CDC serial buffer overflows.
+ However, it is likely that if the host is running slow (i.e. it's a raspberry pi model 3) that it becomes
+ compute bound and doesn't service CDC serial responses in time to not overflow the internal CDC buffers.
+ And thus no serial buffer is large enough. But, it's only 32K.... */
devc->serial_buffer_size = 32000;
devc->buffer = NULL;
sr_dbg("Setting serial buffer size: %i.",
devc->serial_buffer_size);
devc->cbuf_wrptr = 0;
- //While slices are sent as a group of one sample across all channels, sigrok wants analog
- //channel data sent as separate packets.
- //Logical trace values are packed together.
- //An RLE byte in normal mode can represent up to 1640 samples.
- //In D4 an RLE byte can represents up to 640 samples.
- //Rather than making the sample_buf_size 1640x the size of serial buff, we require that the process loops
- //push samples to the session as we get anywhere close to full.
+ /*While slices are sent as a group of one sample across all channels, sigrok wants analog
+ channel data sent as separate packets.
+ Logical trace values are packed together.
+ An RLE byte in normal mode can represent up to 1640 samples.
+ In D4 an RLE byte can represents up to 640 samples.
+ Rather than making the sample_buf_size 1640x the size of serial buff, we require that the process loops
+ push samples to the session as we get anywhere close to full.*/
devc->sample_buf_size = devc->serial_buffer_size;
for (i = 0; i < devc->num_a_channels; i++) {
devc->capture_ratio = 10;
devc->rxstate = RX_IDLE;
sdi->priv = devc;
- //Set an initial value as various code relies on an inital value.
+ /*Set an initial value as various code relies on an inital value.*/
devc->limit_samples = 1000;
if (raspberrypi_pico_get_dev_cfg(sdi) != SR_OK) {
-//Note that on the initial driver load we pull all values into local storage.
-//Thus gets can return local data, but sets have to issue commands to device.
+/*Note that on the initial driver load we pull all values into local storage.
+ Thus gets can return local data, but sets have to issue commands to device. */
static int config_set(uint32_t key, GVariant * data,
const struct sr_dev_inst *sdi,
const struct sr_channel_group *cg)
const struct sr_channel_group *cg)
{
(void) cg;
- //scan or device options are the only ones that can be called without a defined instance
+ /*scan or device options are the only ones that can be called without a defined instance*/
if ((key == SR_CONF_SCAN_OPTIONS)
|| (key == SR_CONF_DEVICE_OPTIONS)) {
return STD_CONFIG_LIST(key, data, sdi, cg, scanopts,
std_gvar_samplerates(ARRAY_AND_SIZE
(samplerates));
break;
-//This must be set to get SW trigger support
+ /*This must be set to get SW trigger support*/
case SR_CONF_TRIGGER_MATCH:
*data =
std_gvar_array_i32(ARRAY_AND_SIZE(trigger_matches));
break;
case SR_CONF_LIMIT_SAMPLES:
- //Really this limit is up to the memory capacity of the host,
- //and users that pick huge values deserve what they get.
- //But setting this limit to prevent really crazy things.
+ /*Really this limit is up to the memory capacity of the host,
+ and users that pick huge values deserve what they get.
+ But setting this limit to prevent really crazy things. */
*data = std_gvar_tuple_u64(1LL, 1000000000LL);
sr_dbg("sr_config_list limit samples ");
break;
sr_err("ERROR:serial buffer malloc fail");
return SR_ERR_MALLOC;
}
- //Get device in idle state
+ /*Get device in idle state*/
if (serial_drain(serial) != SR_OK) {
sr_err("Initial Drain Failed\n\r");
return SR_ERR;
} else {
}
- }//for all channels
- //ensure data channels are continuous
+ }/*for all channels*/
+ /*ensure data channels are continuous*/
int invalid = 0;
for (i = 0; i < 32; i++) {
if ((devc->d_chan_mask >> i) & 1) {
invalid = 1;
}
}
- //recalculate bytes_per_slice based on which analog channels are enabled
+ /*recalculate bytes_per_slice based on which analog channels are enabled */
devc->bytes_per_slice = (a_enabled * devc->a_size);
for (i = 0; i < devc->num_d_channels; i += 7) {
}
sr_dbg("bps %d\n", devc->bytes_per_slice);
- //Apply sample rate limits
- //While earlier versions forced a lower sample rate, the PICO seems to allow
- //ADC overclocking, and by not enforcing these limits it may support other devices.
- //Thus call sr_err to get something into the device logs, but allowing it to progress.
+ /*Apply sample rate limits
+ While earlier versions forced a lower sample rate, the PICO seems to allow
+ ADC overclocking, and by not enforcing these limits it may support other devices.
+ Thus call sr_err to get something into the device logs, but allowing it to progress.*/
if ((a_enabled == 3) && (devc->sample_rate > 160000)) {
sr_err
("WARN:3 channel ADC sample rate above 160khz");
sr_err
("WARN:1 channel ADC sample rate above 500khz");
}
- //Depending on channel configs, rates below 5ksps are possible
- //but such a low rate can easily stream and this eliminates a lot
- //of special cases.
+ /*Depending on channel configs, rates below 5ksps are possible
+ but such a low rate can easily stream and this eliminates a lot
+ of special cases. */
if (devc->sample_rate < 5000) {
sr_err("Sample rate override to min of 5ksps");
devc->sample_rate = 5000;
}
- //While PICO specs a max clock ~120-125Mhz, it does overclock in many cases
- //so leaving is a warning.
+ /*While PICO specs a max clock ~120-125Mhz, it does overclock in many cases
+ so leaving is a warning. */
if (devc->sample_rate > 120000000) {
sr_err("WARN: Sample rate above 120Msps");
}
- //It may take a very large number of samples to notice, but if digital and analog are enabled
- //and either PIO or ADC are fractional the samples will skew over time.
- //24Mhz is the max common divisor to the 120Mhz and 48Mhz ADC clock
- //so force an integer divisor to 24Mhz.
+ /*It may take a very large number of samples to notice, but if digital and analog are enabled
+ and either PIO or ADC are fractional the samples will skew over time.
+ 24Mhz is the max common divisor to the 120Mhz and 48Mhz ADC clock
+ so force an integer divisor to 24Mhz. */
if ((a_enabled > 0) && (d_enabled > 0)) {
if (24000000ULL % (devc->sample_rate)) {
uint32_t commondivint =
24000000ULL / (devc->sample_rate);
- //Always increment the divisor so that we go down in frequency to avoid max sample rate issues
+ /*Always increment the divisor so that we go down in frequency to avoid max sample rate issues */
commondivint++;
devc->sample_rate = 24000000ULL / commondivint;
- //Make sure the divisor increement didn't make use go too low.
+ /*Make sure the divisor increement didn't make use go too low. */
if (devc->sample_rate < 5000) {
devc->sample_rate = 50000;
}
}
}
- //If we are only digital or only analog print a warning that the
- //fractional divisors aren't a true PLL fractional feedback loop and thus
- //could have sample to sample variation.
- //These warnings of course assume that the device is programmed with the expected ratios
- //but non PICO implementations, or PICO implementations that use different divisors could avoid.
- //This generally won't be a problem because most of the sampe_rate pulldown values are integer divisors.
+ /*If we are only digital or only analog print a warning that the
+ fractional divisors aren't a true PLL fractional feedback loop and thus
+ could have sample to sample variation.
+ These warnings of course assume that the device is programmed with the expected ratios
+ but non PICO implementations, or PICO implementations that use different divisors could avoid.
+ This generally won't be a problem because most of the sampe_rate pulldown values are integer divisors. */
if (a_enabled > 0) {
if (48000000ULL % (devc->sample_rate * a_enabled)) {
sr_warn
sr_err("Sample limit to device failed");
return SR_ERR;
}
- //To support future devices that may allow the analog scale/offset to change, call get_dev_cfg again to get new values
+ /*To support future devices that may allow the analog scale/offset to change, call get_dev_cfg again to get new values */
if(raspberrypi_pico_get_dev_cfg(sdi) != SR_OK){
sr_err("get_dev_cfg failure on start");
return SR_ERR;
}
- //With all other params set, we use the final sample rate setting as an opportunity for the device
- //to communicate any errors in configuration.
- //A single "*" indicates success.
- //A "*" with subsequent data is success, but allows for the device to print something
- //to the error console without aborting.
- //A non "*" in the first character blocks the start
+ /*With all other params set, we use the final sample rate setting as an opportunity for the device
+ to communicate any errors in configuration.
+ A single "*" indicates success.
+ A "*" with subsequent data is success, but allows for the device to print something
+ to the error console without aborting.
+ A non "*" in the first character blocks the start */
sprintf(tmpstr, "R%llu\n", devc->sample_rate);
num_read = send_serial_w_resp(serial, tmpstr, buf, 30);
buf[num_read]=0;
}
devc->pretrig_entries =
(devc->capture_ratio * devc->limit_samples) / 100;
- //While the driver supports the passing of trigger info to the device
- //it has been found that the sw overhead of supporting triggering and
- //pretrigger buffer entries etc.. ends up slowing the cores down enough
- //that the effective continous sample rate isn't much higher than that of sending
- //untriggered samples across USB. Thus this code will remain but likely may
- //not be used by the device, unless HW based triggers are implemented
+ /*While the driver supports the passing of trigger info to the device
+ it has been found that the sw overhead of supporting triggering and
+ pretrigger buffer entries etc.. ends up slowing the cores down enough
+ that the effective continous sample rate isn't much higher than that of sending
+ untriggered samples across USB. Thus this code will remain but likely may
+ not be used by the device, unless HW based triggers are implemented */
if ((trigger = sr_session_trigger_get(sdi->session))) {
if (g_slist_length(trigger->stages) > 1)
return SR_ERR_NA;
val=-1;
}
sr_info("Trigger value idx %d match %d",idx,match->match);
- //Only set trigger on enabled channels
+ /*Only set trigger on enabled channels*/
if((val>=0) && ((devc->d_chan_mask>>idx)&1)){
sprintf(&tmpstr[0], "t%d%02d\n", val,idx+2);
if (send_serial_w_ack(serial, tmpstr) != SR_OK) {
("ERROR:Analog pretrigger buffer malloc failure, disabling");
devc->trigger_fired = TRUE;
}
- } //if chan_mask
- } //for num_a_channels
- } //if pre_trigger
+ }
+ }
+ }
sr_info("Entering sw triggered mode");
- //post the receive before starting the device to ensure we are ready to receive data ASAP
+ /*post the receive before starting the device to ensure we are ready to receive data ASAP*/
serial_source_add(sdi->session, serial, G_IO_IN, 200,
raspberrypi_pico_receive, (void *) sdi);
sprintf(tmpstr, "C\n");
if (devc->trigger_fired)
std_session_send_df_trigger(sdi);
- //Keep this at the end as we don't want to be RX_ACTIVE unless everything is ok
+ /*Keep this at the end as we don't want to be RX_ACTIVE unless everything is ok*/
devc->rxstate = RX_ACTIVE;
return SR_OK;
}
-//This function is called either by the protocol code if we reached all of the samples
-//or an error condition, and also by the user clicking stop in pulseview.
-//It must always be called for any acquistion that was started to free memory.
+/*This function is called either by the protocol code if we reached all of the samples
+or an error condition, and also by the user clicking stop in pulseview.
+It must always be called for any acquistion that was started to free memory. */
static int dev_acquisition_stop(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
serial = sdi->conn;
std_session_send_df_end(sdi);
- //If we reached this while still active it is likely because the stop button was pushed
- //in pulseview.
- //That is generally some kind of error condition, so we don't try to check the bytenct
+ /*If we reached this while still active it is likely because the stop button was pushed
+ in pulseview.
+ That is generally some kind of error condition, so we don't try to check the bytenct */
if (devc->rxstate == RX_ACTIVE) {
sr_err("Reached dev_acquisition_stop in RX_ACTIVE");
}
sr_err("Sending plus to stop device stream\n\r");
send_serial_char(serial, '+');
}
- //In case we get calls to receive force it to exit
+ /*In case we get calls to receive force it to exit */
devc->rxstate = RX_IDLE;
- //drain data from device so that it doesn't confuse subsequent commands
+ /*drain data from device so that it doesn't confuse subsequent commands*/
do {
len =
serial_read_blocking(serial, devc->buffer,
SR_PRIV int send_serial_str(struct sr_serial_dev_inst *serial, char *str)
{
int len = strlen(str);
- if ((len > 15) || (len < 1)) { //limit length to catch errant strings
+ if ((len > 15) || (len < 1)) {
sr_err("ERROR:Serial string len %d invalid ", len);
return SR_ERR;
}
- //100ms timeout. With USB CDC serial we can't define the timeout
- //based on link rate, so just pick something large as we shouldn't normally see them
+ /*100ms timeout. With USB CDC serial we can't define the timeout
+ based on link rate, so just pick something large as we shouldn't normally see them */
if (serial_write_blocking(serial, str, len, 100) != len) {
sr_err("ERROR:Serial str write failed");
return SR_ERR;
{
char buf[1];
buf[0] = ch;
- if (serial_write_blocking(serial, buf, 1, 100) != 1) { //100ms
+ if (serial_write_blocking(serial, buf, 1, 100) != 1) { /*100ms */
sr_err("ERROR:Serial char write failed");
return SR_ERR;
}
return SR_OK;
}
-//Issue a command that expects a string return that is less than 30 characters.
-//returns the length of string
+/* Issue a command that expects a string return that is less than 30 characters.
+ returns the length of string */
int send_serial_w_resp(struct sr_serial_dev_inst *serial, char *str,
char *resp, size_t cnt)
{
int num_read, i;
send_serial_str(serial, str);
- //Using the serial_read_blocking function when reading a response of unknown length requires
- //a long worst case timeout to always be taken. So, instead loop waiting for a first byte, and
- //then a final small delay for the rest.
- for (i = 0; i < 1000; i++) { //wait up to 1 second in ms increments
+ /*Using the serial_read_blocking function when reading a response of unknown length requires
+ a long worst case timeout to always be taken. So, instead loop waiting for a first byte, and
+ then a final small delay for the rest. */
+ for (i = 0; i < 1000; i++) { /* wait up to 1 second in ms increments */
num_read = serial_read_blocking(serial, resp, cnt, 1);
if (num_read > 0)
break;
}
- //Since the serial port is usb CDC we can't calculate timeouts based on baud rate but
- //even if the response is split between two USB transfers 10ms should be plenty.
+ /* Since the serial port is usb CDC we can't calculate timeouts based on baud rate but
+ even if the response is split between two USB transfers 10ms should be plenty. */
num_read +=
serial_read_blocking(serial, &(resp[num_read]), cnt - num_read,
10);
}
}
-//Issue a command that expects a single char ack
+/*Issue a command that expects a single char ack */
SR_PRIV int send_serial_w_ack(struct sr_serial_dev_inst *serial, char *str)
{
char buf[2];
int num_read;
- //In case we have left over transfer from the device, drain them
- //These should not exist in normal operation
+ /*In case we have left over transfer from the device, drain them
+ These should not exist in normal operation */
while ((num_read = serial_read_blocking(serial, buf, 2, 10))) {
sr_dbg("swack drops 2 bytes %d %d",buf[0],buf[1]);
}
send_serial_str(serial, str);
- //1000ms timeout
+ /*1000ms timeout */
num_read = serial_read_blocking(serial, buf, 1, 1000);
if ((num_read == 1) && (buf[0] == '*')) {
return SR_OK;
}
}
-//Process incoming data stream assuming it is optimized packing of 4 channels or less
-//Each byte is 4 channels of data and a 3 bit rle value, or a larger rle value, or a control signal.
-//This also checks for aborts and ends.
-//If an end is seen we stop processing but do not check the byte_cnt
-//The output is a set of samples fed to process group to perform sw triggering and sending of data to the session
-//as well as maintenance of the serial rx byte cnt.
-//Since we can get huge rle values we chop them up for processing into smaller groups
-//In this mode we can always consume all bytes because there are no cases where the processing of one
-//byte requires the one after it.
+/*Process incoming data stream assuming it is optimized packing of 4 channels or less
+Each byte is 4 channels of data and a 3 bit rle value, or a larger rle value, or a control signal.
+This also checks for aborts and ends.
+If an end is seen we stop processing but do not check the byte_cnt
+The output is a set of samples fed to process group to perform sw triggering and sending of data to the session
+as well as maintenance of the serial rx byte cnt.
+Since we can get huge rle values we chop them up for processing into smaller groups
+In this mode we can always consume all bytes because there are no cases where the processing of one
+byte requires the one after it.
+*/
void process_D4(struct sr_dev_inst *sdi, struct dev_context *d)
{
uint32_t j;
uint32_t rlecnt = 0;
while (d->ser_rdptr < d->bytes_avail) {
cbyte = d->buffer[(d->ser_rdptr)];
- //RLE only byte
+ /*RLE only byte */
if (cbyte >= 48 && cbyte <= 127) {
rlecnt += (cbyte - 47) * 8;
d->byte_cnt++;
- } else if (cbyte >= 0x80) { //sample with possible rle
+ } else if (cbyte >= 0x80) { /*sample with possible rle */
rlecnt += (cbyte & 0x70) >> 4;
if (rlecnt) {
- //On a value change, duplicate the previous values first.
+ /*On a value change, duplicate the previous values first.*/
rle_memset(d, rlecnt);
rlecnt = 0;
}
- //Finally add in the new values
+ /*Finally add in the new values*/
cval = cbyte & 0xF;
uint32_t didx=(d->cbuf_wrptr) * (d->dig_sample_bytes);
d->d_data_buf[didx] = cval;
- //pad in all other bytes since the sessions even wants disabled channels reported
+ /*pad in all other bytes since the sessions even wants disabled channels reported*/
for (j = 1; j < d->dig_sample_bytes; j++) {
d->d_data_buf[didx+j] = 0;
}
rlecnt = 0;
d->d_last[0] = cval;
}
- //Any other character ends parsing - it could be a frame error or a start of the final byte cnt
+ /*Any other character ends parsing - it could be a frame error or a start of the final byte cnt*/
else {
if (cbyte == '$') {
sr_info
d->byte_cnt);
d->rxstate = RX_ABORT;
}
- break; //break from while loop
+ break; /* break from while loop*/
}
(d->ser_rdptr)++;
- //To ensure we don't overflow the sample buffer, but still send it large chunks of data
- //(to make the packet sends to the session efficient) only call process group after
- //a large number of samples have been seen.
- //cbuf_wrptr counts slices, so shift right by 2 to create a worst case x4 multiple ratio of
- //cbuf_wrptr value to the depth of the sample buffer.
- //Likely we could use the max rle value of 640 but 1024 gives some extra room.
- //Also do a simple check of rlecnt>2000 since that is a reasonable minimal value to send to the session
+ /*To ensure we don't overflow the sample buffer, but still send it large chunks of data
+ (to make the packet sends to the session efficient) only call process group after
+ a large number of samples have been seen.
+ cbuf_wrptr counts slices, so shift right by 2 to create a worst case x4 multiple ratio of
+ cbuf_wrptr value to the depth of the sample buffer.
+ Likely we could use the max rle value of 640 but 1024 gives some extra room.
+ Also do a simple check of rlecnt>2000 since that is a reasonable minimal value to send to the session */
if ((rlecnt>=2000)
||((rlecnt + ((d->cbuf_wrptr)<<2))) > (d->sample_buf_size - 1024)) {
sr_spew("D4 preoverflow wrptr %d bufsize %d rlecnt %d\n\r",d->cbuf_wrptr,d->sample_buf_size,rlecnt);
rlecnt=0;
}
- }//while rdptr < wrptr
+ }/*while rdptr < wrptr*/
sr_spew("D4 while done rdptr %d", d->ser_rdptr);
- //If we reach the end of the serial input stream send any remaining values or rles to the session
+ /* If we reach the end of the serial input stream send any remaining values or rles to the session */
if (rlecnt) {
sr_spew("Residual D4 slice rlecnt %d", rlecnt);
rle_memset(d, rlecnt);
}
-} //Process_D4
+} /* Process_D4 */
-//Process incoming data stream and forward to trigger processing with process_group
-//The final value of ser_rdptr indicates how many bytes were processed.
-//This version handles all other enabled channel configurations that Process_D4 doesn't
+/*Process incoming data stream and forward to trigger processing with process_group
+The final value of ser_rdptr indicates how many bytes were processed.
+This version handles all other enabled channel configurations that Process_D4 doesn't */
void process_slice(struct sr_dev_inst *sdi, struct dev_context *devc)
{
int32_t i;
uint32_t tmp32;
uint8_t cbyte;
uint32_t cword;
- uint32_t slice_bytes; //number of bytes that have legal slice values including RLE
- //Only process legal data values for this mode which are 0x32-0x7F for RLE and 0x80 to 0xFF for data
+ uint32_t slice_bytes; /*number of bytes that have legal slice values including RLE
+ /*Only process legal data values for this mode which are 0x32-0x7F for RLE and 0x80 to 0xFF for data*/
for (slice_bytes = 1; (slice_bytes < devc->bytes_avail)
&& (devc->buffer[slice_bytes - 1] >= 0x30); slice_bytes++);
if (slice_bytes != devc->bytes_avail) {
cbyte = devc->buffer[slice_bytes - 1];
- slice_bytes--; //Don't process the ending character
+ slice_bytes--; /* Don't process the ending character */
if (cbyte == '$') {
sr_info
("Data stream stops with cbyte %d char %c rdidx %d sbytes %d cnt %llu",
devc->rxstate = RX_ABORT;
}
}
- //If the wrptr is non-zero due to a residual from the previous serial transfer don't double count it towards byte_cnt
+ /* If the wrptr is non-zero due to a residual from the previous serial transfer don't double count it towards byte_cnt*/
devc->byte_cnt += slice_bytes - (devc->wrptr);
sr_spew("process slice avail %d rdptr %d sb %d byte_cnt %" PRIu64 "",
devc->bytes_avail, devc->ser_rdptr, slice_bytes,
devc->byte_cnt);
- //Must have a full slice or one rle byte
+ /*Must have a full slice or one rle byte*/
while (((devc->ser_rdptr + devc->bytes_per_slice) <= slice_bytes)
||((devc->ser_rdptr < slice_bytes)&&(devc->buffer[devc->ser_rdptr] < 0x80))) {
}else{
cword = 0;
- //build up a word 7 bits at a time, using only enabled channels
+ /* build up a word 7 bits at a time, using only enabled channels */
for (i = 0; i < devc->num_d_channels; i += 7) {
if (((devc->d_chan_mask) >> i) & 0x7F) {
cword |=
(devc->ser_rdptr)++;
}
}
- //and then distribute 8 bits at a time to all possible channels
- //but first save of cword for rle
+ /*and then distribute 8 bits at a time to all possible channels
+ but first save of cword for rle */
devc->d_last[0]=cword&0xFF;
devc->d_last[1]=(cword>>8)&0xFF;
devc->d_last[2]=(cword>>16)&0xFF;
cword >>= 8;
}
- //Each analog value is a 7 bit value
+ /*Each analog value is one or more 7 bit values */
for (i = 0; i < devc->num_a_channels; i++) {
if ((devc->a_chan_mask >> i) & 1) {
- //a_size is depracted and must always be 1B
+
tmp32 =
devc->buffer[devc->ser_rdptr] - 0x80;
+ for(int a=1;a<devc->a_size;a++){
+ tmp32+=(devc->buffer[(devc->ser_rdptr)+a] - 0x80)<<(7*a);
+ }
devc->a_data_bufs[i][devc->cbuf_wrptr] =
((float) tmp32 * devc->a_scale[i]) +
devc->a_offset[i];
a_data_bufs[i][devc->cbuf_wrptr],
devc->cbuf_wrptr, devc->ser_rdptr,
devc->a_scale[i], devc->a_offset[i]);
- devc->ser_rdptr++;
- } //if channel enabled
- } //for num_a_channels
+ devc->ser_rdptr+=devc->a_size;
+ } /*if channel enabled*/
+ } /*for num_a_channels*/
devc->cbuf_wrptr++;
- }//Not an RLE
- //RLEs can create a large number of samples relative to the incoming serial buffer
- //To prevent overflow of the sample data buffer we call process_group.
- //cbuf_wrptr and sample_buf_size are both in terms of slices
- //2048 is more than needed for a max rle of 1640 on the next incoming character
+ }/*Not an RLE */
+ /*RLEs can create a large number of samples relative to the incoming serial buffer
+ To prevent overflow of the sample data buffer we call process_group.
+ cbuf_wrptr and sample_buf_size are both in terms of slices
+ 2048 is more than needed for a max rle of 1640 on the next incoming character */
if((devc->cbuf_wrptr +2048) > devc->sample_buf_size){
sr_spew("Drain large buff %d %d\n\r",devc->cbuf_wrptr,devc->sample_buf_size);
process_group(sdi, devc, devc->cbuf_wrptr);
}
- }//While another slice or RLE available
+ }/* While another slice or RLE available */
if (devc->cbuf_wrptr){
process_group(sdi, devc, devc->cbuf_wrptr);
}
}
-//Send the processed analog values to the session
+/* Send the processed analog values to the session */
int send_analog(struct sr_dev_inst *sdi, struct dev_context *devc,
uint32_t num_samples, uint32_t offset)
{
packet.payload = &analog;
sr_session_send(sdi, &packet);
g_slist_free(analog.meaning->channels);
- }//if enabled
- }//for channels
+ }/* if enabled */
+ }/* for channels */
return 0;
}
-//Send the ring buffer of pre-trigger analog samples.
-// The entire buffer is sent (as long as it filled once), but need send two payloads split at the
-// the writeptr
+/*Send the ring buffer of pre-trigger analog samples.
+ The entire buffer is sent (as long as it filled once), but need send two payloads split at the
+ the writeptr */
int send_analog_ring(struct sr_dev_inst *sdi, struct dev_context *devc,
uint32_t num_samples)
{
analog.meaning->mqflags = 0;
packet.type = SR_DF_ANALOG;
packet.payload = &analog;
- //First send what is after the write pointer because it is oldest
+ /*First send what is after the write pointer because it is oldest */
if (num_post) {
analog.num_samples = num_post;
analog.data =
}
g_slist_free(analog.meaning->channels);
sr_dbg("Sending A%d ring buffer done ", i);
- }//if enabled
- }//for channels
+ }/*if enabled */
+ }/* for channels */
return 0;
}
-//Given a chunk of slices forward to trigger check or session as appropriate and update state
-//these could be real slices or those generated by rles
+/* Given a chunk of slices forward to trigger check or session as appropriate and update state
+ these could be real slices or those generated by rles */
int process_group(struct sr_dev_inst *sdi, struct dev_context *devc,
uint32_t num_slices)
{
int trigger_offset;
int pre_trigger_samples;
- //These are samples sent to session and are less than num_slices if we reach limit_samples
+ /* These are samples sent to session and are less than num_slices if we reach limit_samples */
size_t num_samples;
struct sr_datafeed_logic logic;
struct sr_datafeed_packet packet;
int i;
size_t cbuf_wrptr_cpy;
cbuf_wrptr_cpy = devc->cbuf_wrptr;
- //regardless of whether we forward samples on or not (because we aren't triggered), always reset the
- //pointer into the device data buffers
+ /*regardless of whether we forward samples on or not (because we aren't triggered), always reset the
+ pointer into the device data buffers */
devc->cbuf_wrptr = 0;
- if (devc->trigger_fired) { //send directly to session
+ if (devc->trigger_fired) { /*send directly to session */
if (devc->limit_samples &&
num_slices >
devc->limit_samples - devc->sent_samples) {
if (devc->num_d_channels) {
packet.type = SR_DF_LOGIC;
packet.payload = &logic;
- //Size the number of bytes required to fit all of the channels
+ /*Size the number of bytes required to fit all of the channels */
logic.unitsize = devc->dig_sample_bytes;
- //The total length of the array sent
+ /*The total length of the array sent */
logic.length =
num_samples * logic.unitsize;
logic.data = devc->d_data_buf;
sr_session_send(sdi, &packet);
}
send_analog(sdi, devc, num_samples, 0);
- }//num_samples >0
+ }/*num_samples >0 */
devc->sent_samples += num_samples;
return 0;
- }//trigger_fired
+ }/* trigger_fired */
else {
size_t num_ring_samples;
size_t sptr;
size_t numtail;
size_t numwrap;
size_t srcptr;
- //The trigger_offset is -1 if no trigger is found, but if a trigger is found
- //then trigger_offset is the offset into the data buffer sent to it.
- //The pre_trigger_samples is the total number of samples before the trigger, but limited to
- //the size of the ring buffer set by the capture_ratio. So the pre_trigger_samples can include both the new samples
- //and the ring buffer, but trigger_offset is only in relation to the new samples
+ /*The trigger_offset is -1 if no trigger is found, but if a trigger is found
+ then trigger_offset is the offset into the data buffer sent to it.
+ The pre_trigger_samples is the total number of samples before the trigger, but limited to
+ the size of the ring buffer set by the capture_ratio. So the pre_trigger_samples can include both the new samples
+ and the ring buffer, but trigger_offset is only in relation to the new samples */
trigger_offset = soft_trigger_logic_check(devc->stl,
devc->d_data_buf,
num_slices *
devc->dig_sample_bytes,
&pre_trigger_samples);
- //A trigger offset >=0 indicates a trigger was seen. The stl will isue the trigger to the session
- //and will forward all pre trigger logic samples, but we must send any post trigger logic
- //and all pre and post trigger analog signals
+ /*A trigger offset >=0 indicates a trigger was seen. The stl will isue the trigger to the session
+ and will forward all pre trigger logic samples, but we must send any post trigger logic
+ and all pre and post trigger analog signals */
if (trigger_offset > -1) {
devc->trigger_fired = TRUE;
devc->sent_samples += pre_trigger_samples;
packet.type = SR_DF_LOGIC;
packet.payload = &logic;
num_samples = num_slices - trigger_offset;
-//Since we are in continuous mode for SW triggers it is possible to get more samples than limit_samples, so
-//once the trigger fires make sure we don't get beyond limit samples. At this point sent_samples should
-//be equal to pre_trigger_samples (just added above) because without being triggered we'd never increment
-//sent_samples.
-//This number is the number of post trigger logic samples to send to the session, the number of floats
-//is larger because of the analog ring buffer we track.
+/*Since we are in continuous mode for SW triggers it is possible to get more samples than limit_samples, so
+once the trigger fires make sure we don't get beyond limit samples. At this point sent_samples should
+be equal to pre_trigger_samples (just added above) because without being triggered we'd never increment
+sent_samples.
+This number is the number of post trigger logic samples to send to the session, the number of floats
+is larger because of the analog ring buffer we track. */
if (devc->limit_samples &&
num_samples >
devc->limit_samples - devc->sent_samples)
num_samples =
devc->limit_samples -
devc->sent_samples;
- //The soft trigger logic issues the trigger and sends packest for all logic data that was pretrigger
- //so only send what is left
+ /*The soft trigger logic issues the trigger and sends packest for all logic data that was pretrigger
+ so only send what is left */
if (num_samples > 0) {
sr_dbg
("Sending post trigger logical remainder of %d",
}
size_t new_start, new_end, new_samples,
ring_samples;
- //Figure out the analog data to send.
- //We might need to send:
- //-some or all of incoming data
- //-all of incoming data and some of ring buffer
- //-all of incoming data and all of ring buffer (and still might be short)
- //We don't need to compare to limit_samples because pretrig_entries can never be more than limit_samples
- //trigger offset indicatese where in the new samples the trigger was, but we need to go back pretrig_entries before it
+ /*Figure out the analog data to send.
+ We might need to send:
+ -some or all of incoming data
+ -all of incoming data and some of ring buffer
+ -all of incoming data and all of ring buffer (and still might be short)
+ We don't need to compare to limit_samples because pretrig_entries can never be more than limit_samples
+ trigger offset indicatese where in the new samples the trigger was, but we need to go back pretrig_entries before it */
new_start =
(trigger_offset >
(int) devc->pretrig_entries) ? trigger_offset
- devc->pretrig_entries : 0;
- //Note that we might not have gotten all the pre triggerstore data we were looking for. In such a case the sw trigger
- //logic seems to fill up to the limit_samples and thus the ratio is off, but we get the full number of samples
- //The number of entries in the ring buffer is pre_trigger_samples-trigger_offset so subtract that from limit samples
- //as a threshold
+ /*Note that we might not have gotten all the pre triggerstore data we were looking for. In such a case the sw trigger
+ logic seems to fill up to the limit_samples and thus the ratio is off, but we get the full number of samples
+ The number of entries in the ring buffer is pre_trigger_samples-trigger_offset so subtract that from limit samples
+ as a threshold */
new_end =
MIN(num_slices - 1,
devc->limit_samples -
(pre_trigger_samples - trigger_offset) -
1);
- //This includes pre and post trigger storage.
+ /*This includes pre and post trigger storage.*/
new_samples = new_end - new_start + 1;
- //pre_trigger_samples can never be greater than trigger_offset by more than the ring buffer depth (pretrig entries)
+ /* pre_trigger_samples can never be greater than trigger_offset by more than the ring buffer depth (pretrig entries) */
ring_samples =
(pre_trigger_samples >
trigger_offset) ? pre_trigger_samples -
new_start);
}
- } //if trigger_offset
- else { //We didn't trigger but need to copy to ring buffer
+ } /* if trigger_offset */
+ else { /* We didn't trigger but need to copy to ring buffer */
if ((devc->a_chan_mask) && (devc->pretrig_entries)) {
- //The incoming data buffer could be much larger than the ring buffer, so never copy more than
- //the size of the ring buffer
+ /*The incoming data buffer could be much larger than the ring buffer, so never copy more than
+ the size of the ring buffer */
num_ring_samples =
num_slices >
devc->
pretrig_entries ? devc->pretrig_entries
: num_slices;
- sptr = devc->pretrig_wr_ptr; //starting pointer to copy to
- //endptr can't go past the end
+ sptr = devc->pretrig_wr_ptr; /*starting pointer to copy to */
+ /*endptr can't go past the end */
eptr =
(sptr + num_ring_samples) >=
devc->
pretrig_entries ? devc->pretrig_entries
- 1 : sptr + num_ring_samples - 1;
- numtail = (eptr - sptr) + 1; //number of samples to copy to the tail of ring buffer without wrapping
+ numtail = (eptr - sptr) + 1; /*number of samples to copy to the tail of ring buffer without wrapping */
numwrap =
(num_ring_samples >
numtail) ? num_ring_samples -
numtail : 0;
- //cbuf_wrptr points to where the next write should go, not theactual write data
+ /* cbuf_wrptr points to where the next write should go, not the actual write data */
srcptr = cbuf_wrptr_cpy - num_ring_samples;
sr_spew("RNG num %zu sptr %zu eptr %zu ",
num_ring_samples, sptr, eptr);
for (i = 0; i < devc->num_a_channels; i++) {
if ((devc->a_chan_mask >> i) & 1) {
- //copy tail
+ /* copy tail */
for (uint32_t j = 0;
j < numtail; j++) {
devc->a_pretrig_bufs
devc->a_data_bufs
[i]
[srcptr + j];
- } //for j
- } //if chan_mask
- } //for channels
- //Copy wrap
+ }
+ }
+ }
+ /* Copy wrap */
srcptr += numtail;
for (i = 0; i < devc->num_a_channels; i++) {
if ((devc->a_chan_mask >> i) & 1) {
devc->a_data_bufs
[i]
[srcptr + j];
- } //for j
- } //if chan_mask
- } //for channels
+ }
+ }
+ }
devc->pretrig_wr_ptr =
(numwrap) ? numwrap : (eptr +
1) %
devc->pretrig_entries;
- } //if any analog channel enabled and pretrig_entries
- } //else (trigger not detected)
- } //trigger not set on function entry
+ } /*if any analog channel enabled and pretrig_entries */
+ } /*else (trigger not detected) */
+ } /*trigger not set on function entry */
return 0;
-} //process_group
+} /* process_group */
-//Duplicate previous sample values
-//This function relies on the caller to ensure d_data_buf has samples to handle the full value of the rle
+/*Duplicate previous sample values
+ This function relies on the caller to ensure d_data_buf has samples to handle the full value of the rle */
void rle_memset(struct dev_context *devc, uint32_t num_slices)
{
uint32_t j, k,didx;
sr_spew("rle_memset vals 0x%X, 0x%X, 0x%X slices %d dsb %d\n", devc->d_last[0],devc->d_last[1],devc->d_last[2],
num_slices, devc->dig_sample_bytes);
- //Even if a channel is disabled, PV expects the same location and size for the enabled
- // channels as if the channel were enabled.
+ /* Even if a channel is disabled, PV expects the same location and size for the enabled
+ channels as if the channel were enabled. */
for (j = 0; j < num_slices; j++) {
didx=devc->cbuf_wrptr*devc->dig_sample_bytes;
for (k = 0; k < devc->dig_sample_bytes; k++) {
devc->d_data_buf[didx + k] = devc->d_last[k];
}
- // cbuf_wrptr always counts slices/samples (and not the bytes in the buffer)
- // regardless of mode
+ /* cbuf_wrptr always counts slices/samples (and not the bytes in the buffer)
+ regardless of mode */
devc->cbuf_wrptr++;
}
}
-//This callback function is mapped from api.c with serial_source_add and is created after a capture
-//has been setup and is responsible for querying the device trigger status, downloading data
-//and forwarding packets
+/* This callback function is mapped from api.c with serial_source_add and is created after a capture
+has been setup and is responsible for querying the device trigger status, downloading data
+and forwarding packets */
SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data)
{
struct sr_dev_inst *sdi;
if (!(devc = sdi->priv))
return TRUE;
if (devc->rxstate != RX_ACTIVE) {
- //This condition is normal operation and expected to happen
- //but printed as information
+ /*This condition is normal operation and expected to happen
+ but printed as information */
sr_dbg("Reached non active state in receive %d",
devc->rxstate);
- //don't return - we may be waiting for a final bytecnt
+ /*don't return - we may be waiting for a final bytecnt*/
}
if (devc->rxstate == RX_IDLE) {
- //This is the normal end condition where we do one more receive
- //to make sure we get the full byte_cnt
+ /*This is the normal end condition where we do one more receive
+ to make sure we get the full byte_cnt */
sr_dbg("Reached idle state in receive %d", devc->rxstate);
return FALSE;
}
serial = sdi->conn;
- //return true if it is some kind of event we don't handle
+ /*return true if it is some kind of event we don't handle */
if (!(revents == G_IO_IN || revents == 0))
return TRUE;
- //Fill the buffer, note the end may have partial slices
+ /*Fill the buffer, note the end may have partial slices */
bytes_rem = devc->serial_buffer_size - devc->wrptr;
- //Read one byte less so that we can null it and print as a string
- //Do a small 10ms timeout, if we get nothing, we'll always come back again
+ /*Read one byte less so that we can null it and print as a string
+ Do a small 10ms timeout, if we get nothing, we'll always come back again*/
len =
serial_read_blocking(serial, &(devc->buffer[devc->wrptr]),
bytes_rem - 1, 10);
if (len > 0) {
devc->buffer[devc->wrptr + len] = 0;
- //Add the "#" so that spaces are clearly seen
+ /*Add the "#" so that spaces in the string are clearly seen */
sr_dbg("rx string %s#", devc->buffer);
devc->bytes_avail = (devc->wrptr + len);
sr_spew
sr_err("ERROR:Negative serial read code %d", len);
sdi->driver->dev_acquisition_stop(sdi);
return FALSE;
- }// if len>0
+ }/* if len>0 */
- //Process the serial read data
+ /* Process the serial read data */
devc->ser_rdptr = 0;
if (devc->rxstate == RX_ACTIVE) {
if ((devc->a_chan_mask == 0)
process_slice(sdi, devc);
}
}
- //process_slice/process_D4 increment ser_rdptr as bytes of the serial buffer are used
- //But they may not use all of it, and thus the residual unused bytes are shifted to the start of the buffer
- //for the next call.
+ /*process_slice/process_D4 increment ser_rdptr as bytes of the serial buffer are used
+ But they may not use all of it, and thus the residual unused bytes are shifted to the start of the buffer
+ for the next call. */
residual_bytes = devc->bytes_avail - devc->ser_rdptr;
if (residual_bytes) {
for (i = 0; i < residual_bytes; i++) {
sr_spew("Residual shift rdptr %u wrptr %u",
devc->ser_rdptr, devc->wrptr);
} else {
- //If there are no residuals shifted then zero the wrptr since all data is used
+ /* If there are no residuals shifted then zero the wrptr since all data is used */
devc->wrptr = 0;
}
- //ABORT ends immediately
+ /*ABORT ends immediately */
if (devc->rxstate == RX_ABORT) {
sr_err("Ending receive on abort");
sdi->driver->dev_acquisition_stop(sdi);
- return FALSE; //
+ return FALSE;
}
- //if stopped look for final '+' indicating the full byte_cnt is received
+ /*if stopped, look for final '+' indicating the full byte_cnt is received */
if (devc->rxstate == RX_STOPPED) {
sr_dbg("Stopped, checking byte_cnt");
if (devc->buffer[0] != '$') {
- //If this happens it means that we got a set of data that was not processed as
- //whole groups of slice bytes. So either we lost data or are not parsing it correctly.
+ /*If this happens it means that we got a set of data that was not processed as
+ whole groups of slice bytes. So either we lost data or are not parsing it correctly. */
sr_err("ERROR: Stop marker should be byte zero");
devc->rxstate = RX_ABORT;
sdi->driver->dev_acquisition_stop(sdi);
("ERROR: received %llu and counted %llu bytecnts don't match, data may be lost",
rxbytecnt, devc->byte_cnt);
}
- //Since we got the bytecnt we know the device is done sending data
+ /* Since we got the bytecnt we know the device is done sending data */
devc->rxstate = RX_IDLE;
- //We must always call acquisition_stop on all completed runs
+ /* We must always call acquisition_stop on all completed runs */
sdi->driver->dev_acquisition_stop(sdi);
return TRUE;
}
}
- //It's possible we need one more serial transfer to get the byte_cnt, so print that here
+ /*It's possible we need one more serial transfer to get the byte_cnt, so print that here */
sr_dbg("Haven't seen byte_cnt + yet");
- } //if RX_STOPPED
- //If at the sample limit, send a "+" in case we are in continuous mode and need
- //to stop the device. Not that even in non continous mode there might be cases where get an extra
- //sample or two...
+ } /*if RX_STOPPED*/
+ /*If at the sample limit, send a "+" in case we are in continuous mode and need
+ to stop the device. Not that even in non continous mode there might be cases where get an extra
+ sample or two... */
if ((devc->sent_samples >= devc->limit_samples)
&& (devc->rxstate == RX_ACTIVE)) {
("Receive function done: sent %u limit %llu wrptr %u len %d",
devc->sent_samples, devc->limit_samples, devc->wrptr, len);
return TRUE;
-} //raspberrypi_pico_receive
+}/* raspberrypi_pico_receive */
-//Read device specific information from the device
+/* Read device specific information from the device */
SR_PRIV int raspberrypi_pico_get_dev_cfg(const struct sr_dev_inst *sdi)
{
struct dev_context *devc;
("ERROR:No response from device for analog channel query");
return SR_ERR;
}
- //null end of string for strsplit
response[ret] = 0;
tokens = NULL;
tokens = g_strsplit(response, "x", 0);
sr_err
("ERROR:Ascale read c%d got unparseable response %s tokens %d",
i, response, num_tokens);
- //force a legal fixed value assuming a 3.3V scale
- //a failue in parsing the scale
+ /*force a legal fixed value assuming a 3.3V scale */
devc->a_scale[i] = 0.0257;
devc->a_offset[i] = 0.0;
}
g_strfreev(tokens);
g_free(cmd);
}
-
-
return SR_OK;
-
}
#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
-//This is used by sr_dbg/log etc to indicate where a printout came from
+/*This is used by sr_dbg/log etc to indicate where a printout came from*/
#define LOG_PREFIX "srpico"
- //number of bytes between markers
+/*/number of bytes between markers*/
#define MRK_STRIDE 128
-//These must be 32 or or less since many channel enable/disable masks and other elements may be only 32 bits wide.
-//Setting values larger than what a PICO can support to enable other devices, or possibly modes where
-//channels are created from internal values rather than external pins
+/*These must be 32 or or less since many channel enable/disable masks and other elements may be only 32 bits wide.
+Setting values larger than what a PICO can support to enable other devices, or possibly modes where
+channels are created from internal values rather than external pins */
#define MAX_ANALOG_CHANNELS 8
#define MAX_DIGITAL_CHANNELS 32
-//digits input to sr_analog_init
+/*digits input to sr_analog_init */
#define ANALOG_DIGITS 4
SR_PRIV int send_serial_str(struct sr_serial_dev_inst *serial, char *str);
char *str);
typedef enum rxstate {
- RX_IDLE = 0, //not receiving
- RX_ACTIVE = 1, //receiving data
- RX_STOPPED = 2, //received stop marker, waiting for byte cnt
- RX_ABORT = 3, //received aborted marker or other error
+ RX_IDLE = 0, /*not receiving */
+ RX_ACTIVE = 1, /*receiving data */
+ RX_STOPPED = 2, /*received stop marker, waiting for byte cnt */
+ RX_ABORT = 3, /*received aborted marker or other error */
} rxstate_t;
struct dev_context {
-//Configuration Parameters
- //It is up to the user to understand sample rates and serial download speed etc and
- // do the right thing. i.e. don't expect continuous streaming bandwidth greater
- //than serial link speed etc...
- //The number of samples the user expects to see.
- uint64_t limit_samples;
- uint64_t sample_rate;
- //Number of samples that have been received and processed
- uint32_t num_samples;
- //Initial Number of analog and digital channels.
- //This is set by initial device config. Channels can be disabled/enabled,
- //but can not be added/removed once driver is loaded.
- uint16_t num_a_channels;
- uint16_t num_d_channels;
- //Masks of enabled channels based on user input
- uint32_t a_chan_mask;
- uint32_t d_chan_mask;
- // Channel groups -each analog channel is it's own group
- struct sr_channel_group **analog_groups;
- struct sr_channel_group *digital_group;
- //Data size in bytes for each analog channel in bytes
- //must be 1 as only single byte samples are supported in this version
- uint8_t a_size;
- //Offset and scale for each analog channel to covert bytes to float
- float a_offset[MAX_ANALOG_CHANNELS];
- float a_scale[MAX_ANALOG_CHANNELS];
- // % ratio of pre-trigger to post trigger samples
- uint64_t capture_ratio;
- // total number of bytes of data sent for one sample across all channels
- uint16_t bytes_per_slice;
- //The number of bytes needed to store all channels for one sample in the device data buff
- uint32_t dig_sample_bytes;
-// Tracking/status once started
- //number of bytes in the current serial input stream
- uint32_t bytes_avail;
- //Samples sent to the session
- uint32_t sent_samples;
- //count total received bytes to detect lost info
- uint64_t byte_cnt;
- //For SW based triggering we put the device into continuous transmit and stop when
- // we detect a sample and capture all the samples we need. trigger_fired is thus set when
- // the sw trigger logic detects a trigger.
- //For non triggered modes we send a start and a number of samples and the device
- //transmits that much. trigger_fired is set immediately at the start.
- gboolean trigger_fired;
- //Has the device, via an "!" indicated it has stopped sending data, or has a marker
- //error been detected
- // gboolean device_stopped;
- rxstate_t rxstate;
-// Serial Related
- // Serial data buffer
- unsigned char *buffer;
- //Size of incoming serial buffer
- uint32_t serial_buffer_size;
- //Current byte in serial read stream that is being processed
- uint32_t ser_rdptr;
- //write pointer into the serial input buffer
- uint32_t wrptr;
-
-// Buffering Related
- // parsed serial read data is split into each channels dedicated buffer for analog
- float *a_data_bufs[MAX_ANALOG_CHANNELS];
- // digital samples are stored packed together since cli/pulseview want it that way
- uint8_t *d_data_buf;
- // write pointer for the the per channel data buffers
- uint32_t cbuf_wrptr;
- // size of packet data buffers for each channel
- uint32_t sample_buf_size;
-// RLE related
- // Previous sample values to duplicate for rle
- float a_last[MAX_ANALOG_CHANNELS];
- uint8_t d_last[4];
-
-// SW Trigger Related
- struct soft_trigger_logic *stl;
- //Maximum number of entries to store pre-trigger
- uint32_t pretrig_entries;
- // Analog pre-trigger storage for software based triggering
- // because sw based only has internal storage for logic
- float *a_pretrig_bufs[MAX_ANALOG_CHANNELS];
- uint32_t pretrig_wr_ptr;
+/* Configuration Parameters */
+ /* It is up to the user to understand sample rates and serial download speed etc and
+ do the right thing. i.e. don't expect continuous streaming bandwidth greater
+ than serial link speed etc...
+ The number of samples the user expects to see. */
+ uint64_t limit_samples;
+ uint64_t sample_rate;
+ /* Number of samples that have been received and processed */
+ uint32_t num_samples;
+ /* Initial Number of analog and digital channels.
+ This is set by initial device config. Channels can be disabled/enabled,
+ but can not be added/removed once driver is loaded. */
+ uint16_t num_a_channels;
+ uint16_t num_d_channels;
+ /* Masks of enabled channels based on user input*/
+ uint32_t a_chan_mask;
+ uint32_t d_chan_mask;
+ /* Channel groups -each analog channel is it's own group*/
+ struct sr_channel_group **analog_groups;
+ struct sr_channel_group *digital_group;
+ /* Data size in bytes for each analog channel in bytes
+ must be 1 as only single byte samples are supported in this version*/
+ uint8_t a_size;
+ /* Offset and scale for each analog channel to covert bytes to float*/
+ float a_offset[MAX_ANALOG_CHANNELS];
+ float a_scale[MAX_ANALOG_CHANNELS];
+ /* % ratio of pre-trigger to post trigger samples*/
+ uint64_t capture_ratio;
+ /* total number of bytes of data sent for one sample across all channels*/
+ uint16_t bytes_per_slice;
+ /* The number of bytes needed to store all channels for one sample in the device data buff*/
+ uint32_t dig_sample_bytes;
+
+/* Tracking/status once started */
+ /* number of bytes in the current serial input stream */
+ uint32_t bytes_avail;
+ /* Samples sent to the session */
+ uint32_t sent_samples;
+ /* count total received bytes to detect lost info*/
+ uint64_t byte_cnt;
+ /* For SW based triggering we put the device into continuous transmit and stop when
+ we detect a sample and capture all the samples we need. trigger_fired is thus set when
+ the sw trigger logic detects a trigger.
+ For non triggered modes we send a start and a number of samples and the device
+ transmits that much. trigger_fired is set immediately at the start. */
+ gboolean trigger_fired;
+ rxstate_t rxstate;
+
+/* Serial Related */
+ /* Serial data buffer */
+ unsigned char *buffer;
+ /* Size of incoming serial buffer*/
+ uint32_t serial_buffer_size;
+ /* Current byte in serial read stream that is being processed */
+ uint32_t ser_rdptr;
+ /* write pointer into the serial input buffer */
+ uint32_t wrptr;
+
+/* Buffering Related */
+ /* parsed serial read data is split into each channels dedicated buffer for analog */
+ float *a_data_bufs[MAX_ANALOG_CHANNELS];
+ /* digital samples are stored packed together since cli/pulseview want it that way */
+ uint8_t *d_data_buf;
+ /* write pointer for the the per channel data buffers */
+ uint32_t cbuf_wrptr;
+ /* size of packet data buffers for each channel */
+ uint32_t sample_buf_size;
+ /* RLE related*/
+ /* Previous sample values to duplicate for rle */
+ float a_last[MAX_ANALOG_CHANNELS];
+ uint8_t d_last[4];
+
+/* SW Trigger Related */
+ struct soft_trigger_logic *stl;
+ /* Maximum number of entries to store pre-trigger*/
+ uint32_t pretrig_entries;
+ /* Analog pre-trigger storage for software based triggering
+ because sw based only has internal storage for logic */
+ float *a_pretrig_bufs[MAX_ANALOG_CHANNELS];
+ uint32_t pretrig_wr_ptr;
};