From: AC0BI Date: Fri, 13 Jan 2023 14:36:44 +0000 (-0700) Subject: raspberrypi-pico: Formatting; support force_detect, analog sizes X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=dbf599ec68f2a932ec011eb574dd41553fe1a950;p=libsigrok.git raspberrypi-pico: Formatting; support force_detect, analog sizes --- diff --git a/src/hardware/raspberrypi-pico/api.c b/src/hardware/raspberrypi-pico/api.c index e6b03648..9e134149 100644 --- a/src/hardware/raspberrypi-pico/api.c +++ b/src/hardware/raspberrypi-pico/api.c @@ -16,7 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -//debug print levels are err/warn/info/dbg/spew #include #include #include @@ -29,20 +28,24 @@ #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), @@ -57,16 +60,16 @@ static const uint64_t samplerates[] = { 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), @@ -83,14 +86,14 @@ static const uint64_t samplerates[] = { 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) @@ -101,7 +104,6 @@ static const uint32_t drvopts[] = { SR_CONF_LOGIC_ANALYZER, }; -//SW trigger requires this static const int32_t trigger_matches[] = { SR_TRIGGER_ZERO, SR_TRIGGER_ONE, @@ -112,11 +114,9 @@ static const int32_t trigger_matches[] = { 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, }; @@ -132,14 +132,15 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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) { @@ -149,6 +150,10 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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) @@ -167,7 +172,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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); @@ -175,10 +179,15 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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); @@ -197,9 +206,9 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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') @@ -209,8 +218,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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]); @@ -234,39 +243,34 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) } 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] = @@ -281,7 +285,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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); @@ -289,26 +293,26 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) } } - //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++) { @@ -320,7 +324,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) 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) { @@ -339,8 +343,8 @@ static GSList *scan(struct sr_dev_driver *di, GSList * options) -//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) @@ -413,7 +417,7 @@ static int config_list(uint32_t key, GVariant ** data, 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, @@ -432,15 +436,15 @@ static int config_list(uint32_t key, GVariant ** data, 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; @@ -473,7 +477,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) 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; @@ -515,8 +519,8 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) } 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) { @@ -530,7 +534,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) 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) { @@ -544,10 +548,10 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) } 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"); @@ -560,30 +564,30 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) 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; } @@ -593,12 +597,12 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) } } - //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 @@ -620,18 +624,18 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) 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; @@ -680,12 +684,12 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) } 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; @@ -719,7 +723,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) 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) { @@ -754,11 +758,11 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) ("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"); @@ -781,15 +785,15 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) 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; @@ -800,9 +804,9 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) 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"); } @@ -810,9 +814,9 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) 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, diff --git a/src/hardware/raspberrypi-pico/protocol.c b/src/hardware/raspberrypi-pico/protocol.c index 99971ed0..d724545a 100644 --- a/src/hardware/raspberrypi-pico/protocol.c +++ b/src/hardware/raspberrypi-pico/protocol.c @@ -34,12 +34,12 @@ 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; @@ -52,30 +52,30 @@ SR_PRIV int send_serial_char(struct sr_serial_dev_inst *serial, char ch) { 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); @@ -87,18 +87,18 @@ int send_serial_w_resp(struct sr_serial_dev_inst *serial, char *str, } } -//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; @@ -113,15 +113,16 @@ SR_PRIV int send_serial_w_ack(struct sr_serial_dev_inst *serial, char *str) } } -//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; @@ -130,22 +131,22 @@ void process_D4(struct sr_dev_inst *sdi, struct dev_context *d) 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; } @@ -158,7 +159,7 @@ void process_D4(struct sr_dev_inst *sdi, struct dev_context *d) 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 @@ -173,16 +174,16 @@ void process_D4(struct sr_dev_inst *sdi, struct dev_context *d) 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); @@ -191,9 +192,9 @@ void process_D4(struct sr_dev_inst *sdi, struct dev_context *d) 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); @@ -204,24 +205,24 @@ void process_D4(struct sr_dev_inst *sdi, struct dev_context *d) } -} //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", @@ -236,12 +237,12 @@ void process_slice(struct sr_dev_inst *sdi, struct dev_context *devc) 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))) { @@ -262,7 +263,7 @@ void process_slice(struct sr_dev_inst *sdi, struct dev_context *devc) }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 |= @@ -271,8 +272,8 @@ void process_slice(struct sr_dev_inst *sdi, struct dev_context *devc) (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; @@ -289,12 +290,15 @@ void process_slice(struct sr_dev_inst *sdi, struct dev_context *devc) 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;aa_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]; @@ -307,28 +311,28 @@ void process_slice(struct sr_dev_inst *sdi, struct dev_context *devc) 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) { @@ -361,15 +365,15 @@ int send_analog(struct sr_dev_inst *sdi, struct dev_context *devc, 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) { @@ -404,7 +408,7 @@ int send_analog_ring(struct sr_dev_inst *sdi, struct dev_context *devc, 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 = @@ -435,30 +439,30 @@ int send_analog_ring(struct sr_dev_inst *sdi, struct dev_context *devc, } 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) { @@ -474,19 +478,19 @@ int process_group(struct sr_dev_inst *sdi, struct dev_context *devc, 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; @@ -494,39 +498,39 @@ int process_group(struct sr_dev_inst *sdi, struct dev_context *devc, 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", @@ -543,29 +547,29 @@ int process_group(struct sr_dev_inst *sdi, struct dev_context *devc, } 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 - @@ -582,35 +586,35 @@ int process_group(struct sr_dev_inst *sdi, struct dev_context *devc, 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 @@ -618,10 +622,10 @@ int process_group(struct sr_dev_inst *sdi, struct dev_context *devc, 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) { @@ -632,44 +636,44 @@ int process_group(struct sr_dev_inst *sdi, struct dev_context *devc, 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; @@ -687,27 +691,27 @@ SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data) 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); @@ -716,7 +720,7 @@ SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data) 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 @@ -729,9 +733,9 @@ SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data) 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) @@ -741,9 +745,9 @@ SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data) 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++) { @@ -755,21 +759,21 @@ SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data) 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); @@ -788,19 +792,19 @@ SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data) ("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)) { @@ -815,9 +819,9 @@ SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data) ("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; @@ -838,7 +842,6 @@ SR_PRIV int raspberrypi_pico_get_dev_cfg(const struct sr_dev_inst *sdi) ("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); @@ -856,16 +859,12 @@ SR_PRIV int raspberrypi_pico_get_dev_cfg(const struct sr_dev_inst *sdi) 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; - } diff --git a/src/hardware/raspberrypi-pico/protocol.h b/src/hardware/raspberrypi-pico/protocol.h index 8bbfe3aa..683ce2c4 100644 --- a/src/hardware/raspberrypi-pico/protocol.h +++ b/src/hardware/raspberrypi-pico/protocol.h @@ -25,17 +25,17 @@ #include #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); @@ -46,93 +46,92 @@ SR_PRIV int send_serial_w_ack(struct sr_serial_dev_inst *serial, 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; };