150 lines
3.8 KiB
C
150 lines
3.8 KiB
C
|
|
||
|
#include <stdint.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <RP2040.h>
|
||
|
#include <system_RP2040.h>
|
||
|
#include <core_cm0plus.h>
|
||
|
|
||
|
#include <hardware/structs/iobank0.h>
|
||
|
#include <hardware/clocks.h>
|
||
|
#include <hardware/dma.h>
|
||
|
#include <hardware/gpio.h>
|
||
|
#include <hardware/irq.h>
|
||
|
#include <hardware/pio.h>
|
||
|
#include <hardware/pwm.h>
|
||
|
#include <pico/stdlib.h>
|
||
|
#include <pico/stdio_usb.h>
|
||
|
|
||
|
#include "trigctl.pio.h"
|
||
|
#include "uart_rx.pio.h"
|
||
|
|
||
|
#define PIN_TRIGGER 14
|
||
|
#define PIN_TRIGGER_POL glitch_positive
|
||
|
|
||
|
#define PIN_NMI 15
|
||
|
#define PIN_NMI_POL glitch_negative
|
||
|
|
||
|
#define PIN_ACK 16
|
||
|
#define PIN_UART 17
|
||
|
|
||
|
#define PIO_UNIT pio0
|
||
|
#define PIOSM_UART 0
|
||
|
#define PIOSM_TRIG 1
|
||
|
|
||
|
#define UART_BAUD 9600
|
||
|
|
||
|
static void init_gpio(void) {
|
||
|
const int func = GPIO_FUNC_PIO0;
|
||
|
|
||
|
// init trigger pin
|
||
|
sio_hw->gpio_oe_clr = 1u << PIN_TRIGGER;
|
||
|
hw_write_masked(&padsbank0_hw->io[PIN_TRIGGER]
|
||
|
, (PADS_BANK0_GPIO0_IE_BITS)
|
||
|
, (PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS)
|
||
|
| (PADS_BANK0_GPIO0_SCHMITT_BITS)
|
||
|
);
|
||
|
hw_write_masked(&iobank0_hw->io[PIN_TRIGGER].ctrl
|
||
|
, (func << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
|
||
|
| ((uint)(PIN_TRIGGER_POL ? GPIO_OVERRIDE_INVERT
|
||
|
: GPIO_OVERRIDE_NORMAL) << IO_BANK0_GPIO0_CTRL_INOVER_LSB)
|
||
|
, (IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS)
|
||
|
| (IO_BANK0_GPIO0_CTRL_INOVER_BITS)
|
||
|
);
|
||
|
|
||
|
sio_hw->gpio_clr = 1u << PIN_NMI;
|
||
|
sio_hw->gpio_oe_set = 1u << PIN_NMI;
|
||
|
hw_write_masked(&padsbank0_hw->io[PIN_NMI]
|
||
|
, PADS_BANK0_GPIO0_IE_BITS
|
||
|
| ((uint)GPIO_SLEW_RATE_FAST << PADS_BANK0_GPIO0_SLEWFAST_LSB)
|
||
|
| (PADS_BANK0_GPIO0_DRIVE_VALUE_12MA << PADS_BANK0_GPIO0_DRIVE_LSB)
|
||
|
, PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS
|
||
|
| PADS_BANK0_GPIO0_SLEWFAST_BITS | PADS_BANK0_GPIO0_DRIVE_BITS
|
||
|
);
|
||
|
hw_write_masked(&iobank0_hw->io[PIN_NMI].ctrl
|
||
|
, (func << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
|
||
|
| ((uint)(PIN_NMI_POL ? GPIO_OVERRIDE_INVERT
|
||
|
: GPIO_OVERRIDE_NORMAL) << IO_BANK0_GPIO0_CTRL_OUTOVER_LSB)
|
||
|
, IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS | IO_BANK0_GPIO0_CTRL_OUTOVER_BITS
|
||
|
);
|
||
|
|
||
|
sio_hw->gpio_clr = 1u << PIN_ACK;
|
||
|
sio_hw->gpio_oe_set = 1u << PIN_ACK;
|
||
|
gpio_init(PIN_ACK);
|
||
|
gpio_set_dir(PIN_ACK, GPIO_OUT);
|
||
|
gpio_set_function(PIN_ACK, GPIO_FUNC_SIO);
|
||
|
}
|
||
|
|
||
|
static uint off_uart, off_trig;
|
||
|
static void init_pio(void) {
|
||
|
off_uart = pio_add_program(PIO_UNIT, &uart_rx_program);
|
||
|
uart_rx_program_init(PIO_UNIT, PIOSM_UART, off_uart, PIN_UART, UART_BAUD);
|
||
|
|
||
|
off_trig = pio_add_program(PIO_UNIT, &trigctl_program);
|
||
|
trigctl_pio_init(PIO_UNIT, PIOSM_TRIG, off_trig,
|
||
|
trig_source_pin, PIN_NMI, PIN_TRIGGER, PIN_TRIGGER_POL,
|
||
|
PIN_NMI_POL, true, 125); // 1 MHz
|
||
|
|
||
|
const int irq = PIO0_IRQ_1;
|
||
|
irq_set_enabled(irq, false);
|
||
|
trigctl_ack_glitch_irq(PIO_UNIT, PIOSM_TRIG);
|
||
|
trigctl_set_glitch_irq_enabled(PIO_UNIT, PIOSM_TRIG, 1, true);
|
||
|
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
|
||
|
irq_set_enabled(irq, true);
|
||
|
}
|
||
|
|
||
|
static bool uart_poll_ch(uint8_t* ch) {
|
||
|
if (pio_sm_is_rx_fifo_empty(PIO_UNIT, PIOSM_UART)) return false;
|
||
|
|
||
|
// 8-bit read from the uppermost byte of the FIFO, as data is left-justified
|
||
|
io_rw_8 *rxfifo_shift = (io_rw_8*)&PIO_UNIT->rxf[PIOSM_UART] + 3;
|
||
|
*ch = *rxfifo_shift;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
stdio_init_all();
|
||
|
|
||
|
init_gpio();
|
||
|
init_pio();
|
||
|
|
||
|
while (!stdio_usb_connected());
|
||
|
|
||
|
uint32_t delay = 1;
|
||
|
const uint32_t len = 2;
|
||
|
|
||
|
while (true) {
|
||
|
if (pio_sm_is_tx_fifo_empty(PIO_UNIT, PIOSM_TRIG)) {
|
||
|
printf("push offlen\n");
|
||
|
trigctl_push_off_len(PIO_UNIT, PIOSM_TRIG, delay, len);
|
||
|
}
|
||
|
|
||
|
uint8_t ch;
|
||
|
if (uart_poll_ch(&ch)) {
|
||
|
printf("got cmd: %c\n", ch);
|
||
|
switch (ch) {
|
||
|
case '0': delay = 1; break;
|
||
|
case '+': ++delay; break;
|
||
|
case '-': --delay; break;
|
||
|
default: goto noack;
|
||
|
}
|
||
|
|
||
|
printf("send ack\n");
|
||
|
sio_hw->gpio_set = 1u << PIN_ACK;
|
||
|
busy_wait_us_32(50);
|
||
|
sio_hw->gpio_clr = 1u << PIN_ACK;
|
||
|
printf("sent ack\n");
|
||
|
|
||
|
noack:;
|
||
|
}
|
||
|
|
||
|
if (PIO_UNIT->irq & (1u << PIOSM_TRIG)) {
|
||
|
printf("sent nmi\n");
|
||
|
trigctl_ack_glitch_irq(PIO_UNIT, PIOSM_TRIG);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|