mspbsldump/nmigen/main.c

221 lines
5.7 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 PIN_ACT 18
#define PIN_STAT 19
#define PIO_UNIT pio0
#define PIOSM_UART 0
#define PIOSM_TRIG 1
#define UART_BAUD 9600
/*static void act_irq(uint gpio, uint32_t ev) {
if (gpio != PIN_ACT) return;
//printf("ev: 0x%lx\n", ev);
if (ev & GPIO_IRQ_EDGE_FALL) {
if (ev & GPIO_IRQ_EDGE_RISE) {
//printf("wut\n");
} else {
//printf("fall\n");
//gpio_set_function(PIN_NMI, GPIO_FUNC_NULL);
const uint func = GPIO_FUNC_NULL;
hw_write_masked(&iobank0_hw->io[PIN_NMI].ctrl
, (func << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
, IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS
);
}
} else if (ev & GPIO_IRQ_EDGE_RISE) {
//printf("rise\n");
//gpio_set_function(PIN_NMI, GPIO_FUNC_PIO0);
const uint func = GPIO_FUNC_PIO0;
hw_write_masked(&iobank0_hw->io[PIN_NMI].ctrl
, (func << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
, IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS
);
}
}*/
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_NORMAL//INVERT
/*: GPIO_OVERRIDE_NORMAL*/) << IO_BANK0_GPIO0_CTRL_OUTOVER_LSB)
, IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS | IO_BANK0_GPIO0_CTRL_OUTOVER_BITS
);
gpio_set_outover(PIN_NMI, GPIO_OVERRIDE_INVERT);
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);
sio_hw->gpio_oe_clr = 1u << PIN_ACT;
gpio_init(PIN_ACT);
gpio_set_dir(PIN_ACT, GPIO_IN);
gpio_set_function(PIN_ACT, GPIO_FUNC_SIO);
sio_hw->gpio_set = 1u << PIN_STAT;
sio_hw->gpio_oe_set = 1u << PIN_STAT;
gpio_init(PIN_STAT);
gpio_put(PIN_STAT, true);
gpio_set_dir(PIN_STAT, GPIO_OUT);
gpio_set_function(PIN_STAT, GPIO_FUNC_SIO);
const int irq = PIO0_IRQ_1;
irq_set_enabled(irq, false);
irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY);
irq_set_enabled(irq, true);
}
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, 5); // 25 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;
}
static void flush_pio_fifo(void) {
PIO pio = PIO_UNIT;
const uint sm = PIOSM_TRIG;
pio_sm_set_enabled(pio, sm, false);
pio_sm_clear_fifos(pio, sm);
pio_sm_restart(pio, sm);
pio_sm_clkdiv_restart(pio, sm);
pio_sm_exec(pio, sm, pio_encode_jmp(off_trig));
pio_sm_set_enabled(pio, sm, true);
}
int main() {
stdio_init_all();
init_pio();
init_gpio();
/*gpio_set_irq_enabled_with_callback(PIN_ACT,
GPIO_IRQ_EDGE_RISE|GPIO_IRQ_EDGE_FALL, true, act_irq);*/
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
gpio_put(LED_PIN, true);
//while (!stdio_usb_connected());
uint32_t delay = 1;
const uint32_t len = 16;
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*25, len*25);
}
uint8_t ch;
if (uart_poll_ch(&ch)) {
//printf("got cmd: %c\n", ch);
switch (ch) {
case '0':
delay = 1;
flush_pio_fifo();
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);
}
}
}