diff options
Diffstat (limited to '')
-rw-r--r-- | src/modchipfw/utglitcher.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/modchipfw/utglitcher.c b/src/modchipfw/utglitcher.c new file mode 100644 index 0000000..5ba5c94 --- /dev/null +++ b/src/modchipfw/utglitcher.c @@ -0,0 +1,158 @@ +#include <stdio.h> +#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; +}
\ No newline at end of file |