#include #include "pico/stdlib.h" #include "hardware/uart.h" #include "hardware/gpio.h" #include "hardware/pio.h" #include "hardware/clocks.h" #include "hardware/vreg.h" #include "pulsegen.pio.h" #define PIN_NRST 7 #define PIN_TRIG 6 #define PIN_PULSE 0 #define PIN_CAPS 1 #define PIN_LED1 16 #define PIN_LED2 17 int main() { /* * For some reason the serial communication fails after some time when running at 200MHz * For me everything worked fine at 250 MHz without changing the core voltage (vreg_set_voltage) */ set_sys_clock_khz(250000, true); stdio_init_all(); // GPIO initialisation. gpio_init(PIN_NRST); gpio_init(PIN_TRIG); gpio_init(PIN_PULSE); gpio_init(PIN_CAPS); gpio_init(PIN_LED1); gpio_init(PIN_LED2); gpio_set_dir(PIN_NRST, GPIO_OUT); gpio_set_dir(PIN_TRIG, GPIO_IN); gpio_set_dir(PIN_PULSE, GPIO_OUT); gpio_set_dir(PIN_CAPS, GPIO_OUT); gpio_set_dir(PIN_LED1, GPIO_OUT); gpio_set_dir(PIN_LED2, GPIO_OUT); gpio_set_pulls(PIN_CAPS, true, false); gpio_set_drive_strength(PIN_PULSE, GPIO_DRIVE_STRENGTH_12MA); gpio_set_drive_strength(PIN_CAPS, GPIO_DRIVE_STRENGTH_12MA); gpio_set_slew_rate(PIN_PULSE, GPIO_SLEW_RATE_FAST); // Setup PIO PIO pio = pio0; uint32_t sm = pio_claim_unused_sm(pio, true); uint32_t pio_offset = pio_add_program(pio, &pulsegen_program); pulsegen_program_init(pio, sm, pio_offset, PIN_TRIG, PIN_PULSE, PIN_CAPS); // Wait for serial connection while (!stdio_usb_connected()) { sleep_ms(500); } gpio_put(PIN_LED1, true); gpio_put(PIN_NRST, false); char cmd; uint32_t pulse_offset = 0; uint32_t pulse_width = 0; uint32_t trig_edges = 1; uint32_t gpio_states = 0; uint8_t gpio_pin = 0; uint8_t gpio_state = 0; while (true) { cmd = getchar(); switch (cmd) { // Enable glitch SM case 'A': gpio_put(PIN_LED2, true); pio_sm_put_blocking(pio, sm, trig_edges); pio_sm_put_blocking(pio, sm, pulse_offset); pio_sm_put_blocking(pio, sm, pulse_width); gpio_put(PIN_NRST, true); sleep_ms(46); // Delay to make sure all UT signals are stable pio_sm_set_enabled(pio, sm, true); printf("A\n"); break; // Wait for trigger case 'B': while(!pio_interrupt_get(pio0, 0)) { cmd = getchar_timeout_us(1); if (cmd == 'D') break; // Disarm }; pio_sm_set_enabled(pio, sm, false); pio_interrupt_clear(pio, 0); pio_sm_clear_fifos(pio, sm); pio_sm_drain_tx_fifo(pio, sm); pio_sm_restart(pio, sm); pio_sm_set_enabled(pio, sm, false); pio_sm_exec_wait_blocking(pio, sm, pio_encode_set(pio_x, pio_offset)); pio_sm_exec_wait_blocking(pio, sm, pio_encode_mov(pio_pc, pio_x)); printf("T\n"); gpio_put(PIN_LED2, false); break; // Set the number of edges before inserting a pulse case 'E': fread(&trig_edges, 1, 4, stdin); printf("%d\n", trig_edges); break; // Set the pulse offset case 'O': fread(&pulse_offset, 1, 4, stdin); printf("%d\n", pulse_offset); break; // Set the pulse width case 'W': fread(&pulse_width, 1, 4, stdin); printf("%d\n", pulse_width); break; // print the current pulse offset and width case 'S': printf("PulseGenerator offset: %d, width: %d, edges: %d\n", pulse_offset, pulse_width, trig_edges); break; // control a gpio pin, can be expanded to handle multiple pins case 'G': fread(&gpio_pin, 1, 1, stdin); fread(&gpio_state, 1, 1, stdin); if (gpio_pin == PIN_NRST) { if (gpio_state == 0) { gpio_put(PIN_NRST, false); } else { gpio_put(PIN_NRST, true); } } printf("G\n"); break; // Read state of GPIOs case 'R': gpio_states = gpio_get_all(); printf("%d\n", gpio_states); break; default: break; } } return 0; }