X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fraspberrypi-pico%2Fprotocol.h;h=45a8a2a3ff94b4c37d87753869ce9a2127f8d50a;hb=1711287ee9e5e4d37cab1cf9fcda5c98f732a137;hp=4c096375b0277fcfe2c6941862a40453cbb4d424;hpb=dc90146ef360d8f4e7bdf8df5b46b40e9eef3197;p=libsigrok.git diff --git a/src/hardware/raspberrypi-pico/protocol.h b/src/hardware/raspberrypi-pico/protocol.h index 4c096375..45a8a2a3 100644 --- a/src/hardware/raspberrypi-pico/protocol.h +++ b/src/hardware/raspberrypi-pico/protocol.h @@ -1,7 +1,7 @@ /* * This file is part of the libsigrok project. * - * Copyright (C) 2022 AC0BI + * Copyright (C) 2022 Shawn Walker * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,11 +25,138 @@ #include #include "libsigrok-internal.h" -#define LOG_PREFIX "raspberrypi-pico" +/* This is used by sr_dbg/log etc to indicate where a printout came from */ +#define LOG_PREFIX "srpico" + +/* 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 */ +#define MAX_ANALOG_CHANNELS 8 +#define MAX_DIGITAL_CHANNELS 32 + +/* Digits input to sr_analog_init */ +#define ANALOG_DIGITS 4 + +SR_PRIV int send_serial_str(struct sr_serial_dev_inst *serial, char *str); +SR_PRIV int send_serial_char(struct sr_serial_dev_inst *serial, char ch); +int send_serial_w_resp(struct sr_serial_dev_inst *serial, char *str, + char *resp, size_t cnt); +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 */ +} 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 its 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 buffer */ + 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; }; -SR_PRIV int raspberrypi_pico_receive_data(int fd, int revents, void *cb_data); +SR_PRIV int raspberrypi_pico_receive(int fd, int revents, void *cb_data); +SR_PRIV int raspberrypi_pico_get_dev_cfg(const struct sr_dev_inst *sdi); + +void process_D4(struct sr_dev_inst *sdi, struct dev_context *d); +void process_slice(struct sr_dev_inst *sdi, struct dev_context *devc); + +int send_analog(struct sr_dev_inst *sdi, struct dev_context *devc, + uint32_t num_samples, uint32_t offset); +int send_analog_ring(struct sr_dev_inst *sdi, struct dev_context *devc, + uint32_t num_samples); + +int process_group(struct sr_dev_inst *sdi, struct dev_context *devc, + uint32_t num_slices); +void rle_memset(struct dev_context *devc, uint32_t num_slices); +SR_PRIV int check_marker(struct dev_context *d, int *len); + #endif