mspbsldump/nmigen/main.c

150 lines
3.8 KiB
C
Raw Normal View History

#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);
}
}
}