summaryrefslogtreecommitdiffstats
path: root/src/modchipfw/utglitcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/modchipfw/utglitcher.c')
-rw-r--r--src/modchipfw/utglitcher.c158
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