-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HW Trigger #22
Comments
Tracking this here: |
If you are interested, I have implemented some kind of auto trigger for my sigrok-pico module. Auto triggering works til 1/7 of system clock, on my probe these are 24MHz. See here: https://github.com/rgrr/yapicoprobe, especially https://github.com/rgrr/yapicoprobe/blob/master/src/pico-sigrok/sigrok.pio Code fragment to switch between the generated fetch and the above: /**
* Setup PIO operation.
* PIO is configured, so that it reads input in \a sr_dev.pin_count chunks and writes the data in 32bit words.
* That means, that 4bit reads require 8 samples to do one 32bit write and so on.
*
* \note
* used PIO is \a SIGROK_PIO.
*
* \pre
* - sr_dev.d_mask != 0
* - sr_dev.pin_count (4/8/16/32) and sr_dev.sample_rate must be set
* - sr_dev.sample_rate must be a multiple of 1000
*
* \post
* - PIO is configured but not started
* - unused pins within pincount are pulled down to prevent those lines from false triggers
*/
static void setup_pio(void)
{
const uint32_t trigger_delay = 7; // see sigrok.pio
uint32_t sample_rate_khz = 0;
pio_sm_config pio_conf;
uint offset;
uint32_t f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS);
assert(sr_dev.d_mask != 0);
assert(sr_dev.pin_count == 4 || sr_dev.pin_count == 8 || sr_dev.pin_count == 16 || sr_dev.pin_count == 32);
pio_clear_instruction_memory(SIGROK_PIO);
if (sr_dev.sample_rate / 1000 <= f_clk_sys / trigger_delay && sr_dev.a_mask == 0) {
//
// Auto triggering for 4/8/16bit: acquisition is triggered if there are changes on the enabled input lines
// TODO currently no auto trigger with analog/digital signal mix
//
Dprintf("Capturing with auto trigger\n");
if (sr_dev.pin_count == 4) {
offset = pio_add_program(SIGROK_PIO, &sigrok_d4_triggered_program);
pio_conf = sigrok_d4_triggered_program_get_default_config(offset);
sample_rate_khz = (trigger_delay * sr_dev.sample_rate) / 1000;
}
else if (sr_dev.pin_count == 8) {
offset = pio_add_program(SIGROK_PIO, &sigrok_1b_triggered_program);
pio_conf = sigrok_1b_triggered_program_get_default_config(offset);
sample_rate_khz = (trigger_delay * sr_dev.sample_rate) / 1000;
}
else if (sr_dev.pin_count == 16) {
offset = pio_add_program(SIGROK_PIO, &sigrok_2b_triggered_program);
pio_conf = sigrok_2b_triggered_program_get_default_config(offset);
sample_rate_khz = (trigger_delay * sr_dev.sample_rate) / 1000;
}
}
if (sample_rate_khz == 0) {
//
// this is too fast for auto triggering: just do sampling of the input
//
uint16_t capture_prog_instr;
Dprintf("Fast immediate capturing\n");
capture_prog_instr = pio_encode_in(pio_pins, sr_dev.pin_count);
struct pio_program capture_prog = {
.instructions = &capture_prog_instr,
.length = 1,
.origin = -1
};
offset = pio_add_program(SIGROK_PIO, &capture_prog);
// Configure state machine to loop over this `in` instruction forever,
// with autopush enabled.
pio_conf = pio_get_default_sm_config();
sm_config_set_wrap(&pio_conf, offset, offset);
sample_rate_khz = sr_dev.sample_rate / 1000;
}
uint32_t div_256 = (256 * f_clk_sys + sample_rate_khz / 2) / sample_rate_khz;
uint32_t div_int = div_256 >> 8;
uint32_t div_frac = div_256 & 0xff;
if (div_int == 0) {
div_int = 1;
div_frac = 0;
}
else if (div_int > 0xffff) {
div_int = 0xffff;
div_frac = 0xff;
}
Dprintf("PIO sample clk %lukHz / (%lu + %lu/256) = %lukHz, requested %lukHz\n",
f_clk_sys, div_int, div_frac, sample_rate_khz, sr_dev.sample_rate / 1000);
sm_config_set_clkdiv_int_frac(&pio_conf, div_int, div_frac);
sm_config_set_in_pins(&pio_conf, SR_BASE_D_CHAN); // start at SR_BASE_D_CHAN
// enable pull-down on unused pins within pin_count
for (int i = 0; i < (sr_dev.pin_count < SR_NUM_D_CHAN ? sr_dev.pin_count : SR_NUM_D_CHAN); ++i) {
if ((sr_dev.d_mask & (1 << i)) == 0) {
// pull down seems to be less noise sensitive
gpio_pull_down(SR_BASE_D_CHAN + i);
}
}
sm_config_set_in_shift(&pio_conf, true, true, 32); // shift right, autopush, threshold=32
sm_config_set_fifo_join(&pio_conf, PIO_FIFO_JOIN_RX);
pio_sm_init(SIGROK_PIO, SIGROK_SM, offset, &pio_conf);
pio_sm_set_enabled(SIGROK_PIO, SIGROK_SM, false);
pio_sm_clear_fifos(SIGROK_PIO, SIGROK_SM);
pio_sm_restart(SIGROK_PIO, SIGROK_SM);
} // setup_pio And in the CMakeLists.txt one has to add: pico_generate_pio_header(picoprobe ${CMAKE_CURRENT_LIST_DIR}/src/pico-sigrok/sigrok.pio) |
This project seems to have a very smart implementation of HW trigger that's using PIO code to handle many triggering conditions in only 2 cycles (so 100Msps is achievable).
The text was updated successfully, but these errors were encountered: