NMI signal genration bullshit, impl is for tomorrow
This commit is contained in:
parent
c36b0e08b0
commit
a528472828
|
@ -0,0 +1 @@
|
|||
build/
|
|
@ -0,0 +1,29 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
# initialize the SDK based on PICO_SDK_PATH
|
||||
# note: this must happen before project()
|
||||
include(pico_sdk_import.cmake)
|
||||
set(PROJECT nmigen)
|
||||
project(${PROJECT})
|
||||
|
||||
pico_sdk_init()
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/trigctl.pio)
|
||||
pico_generate_pio_header(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/uart_rx.pio)
|
||||
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
main.c
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} PRIVATE pico_stdlib hardware_pwm hardware_pio
|
||||
hardware_dma pico_multicore cmsis_core
|
||||
pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror=implicit-function-declaration -Werror=return-type")
|
||||
|
||||
# enable usb output, disable uart output
|
||||
pico_enable_stdio_usb(${PROJECT} 1)
|
||||
pico_enable_stdio_uart(${PROJECT} 0)
|
|
@ -0,0 +1,149 @@
|
|||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
|
||||
|
||||
# This can be dropped into an external project to help locate this SDK
|
||||
# It should be include()ed prior to project()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
|
||||
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
|
||||
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
|
||||
endif ()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
|
||||
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
|
||||
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
|
||||
endif ()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
|
||||
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
|
||||
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
|
||||
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
|
||||
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
|
||||
|
||||
if (NOT PICO_SDK_PATH)
|
||||
if (PICO_SDK_FETCH_FROM_GIT)
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||
if (PICO_SDK_FETCH_FROM_GIT_PATH)
|
||||
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
endif ()
|
||||
FetchContent_Declare(
|
||||
pico_sdk
|
||||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||
GIT_TAG master
|
||||
)
|
||||
if (NOT pico_sdk)
|
||||
message("Downloading Raspberry Pi Pico SDK")
|
||||
FetchContent_Populate(pico_sdk)
|
||||
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
|
||||
endif ()
|
||||
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
if (NOT EXISTS ${PICO_SDK_PATH})
|
||||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
|
||||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
|
||||
|
||||
include(${PICO_SDK_INIT_CMAKE_FILE})
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
.program trigctl
|
||||
|
||||
; autopull should be on, depth 32
|
||||
;
|
||||
; input pin 0: trigger input
|
||||
;
|
||||
; set pin 0: glitch output
|
||||
;
|
||||
; irq 0 rel: PIO->CM0 "has glitched" signal
|
||||
; irq 1 rel: CM0->PIO "do a glitch now" signal
|
||||
|
||||
public _start:
|
||||
out x, 32 ; offset
|
||||
out y, 32 ; length
|
||||
|
||||
irq clear 0 rel
|
||||
|
||||
public waitinsn:
|
||||
wait 1 pin 0 ; or "wait irq 1 rel"
|
||||
|
||||
offloop:
|
||||
jmp x-- offloop
|
||||
|
||||
set pins, 1
|
||||
|
||||
lenloop:
|
||||
jmp y-- lenloop
|
||||
|
||||
set pins, 0
|
||||
|
||||
irq set 0 rel
|
||||
|
||||
public wait2:
|
||||
wait 0 pin 0 ; or "nop"
|
||||
|
||||
% c-sdk {
|
||||
|
||||
enum glitch_polarity {
|
||||
glitch_positive = 0,
|
||||
glitch_negative = 1
|
||||
};
|
||||
enum trigctl_source {
|
||||
trig_source_pin,
|
||||
trig_source_irq
|
||||
};
|
||||
|
||||
static inline void trigctl_pio_init(PIO pio, uint sm, uint prog_offs,
|
||||
enum trigctl_source trigsrc, uint glitch_pin, uint trig_pin,
|
||||
enum glitch_polarity trig_in_pol, enum glitch_polarity glitch_out_pol
|
||||
, bool enable, int divider) {
|
||||
pio_sm_set_enabled(pio, sm, false);
|
||||
|
||||
if (trigsrc == trig_source_irq) {
|
||||
pio->instr_mem[prog_offs + trigctl_offset_waitinsn] =
|
||||
pio_encode_wait_irq(true, true, 1);
|
||||
pio->instr_mem[prog_offs + trigctl_offset_wait2] =
|
||||
pio_encode_nop();
|
||||
} else {
|
||||
pio->instr_mem[prog_offs + trigctl_offset_waitinsn] =
|
||||
pio_encode_wait_pin(true, 0);
|
||||
pio->instr_mem[prog_offs + trigctl_offset_wait2] =
|
||||
pio_encode_wait_pin(false, 0);
|
||||
}
|
||||
|
||||
pio_sm_config c = trigctl_program_get_default_config(prog_offs);
|
||||
sm_config_set_set_pins(&c, glitch_pin, 1);
|
||||
sm_config_set_in_pins(&c, trig_pin/*, 1*/);
|
||||
sm_config_set_out_shift(&c, false, true, 32);
|
||||
sm_config_set_in_shift(&c, false, true, 32);
|
||||
sm_config_set_clkdiv(&c, divider);
|
||||
|
||||
if (trigsrc == trig_source_irq) {
|
||||
sm_config_set_wrap(&c, prog_offs + trigctl_wrap_target,
|
||||
prog_offs + trigctl_wrap - 1);
|
||||
}
|
||||
|
||||
pio_sm_init(pio, sm, prog_offs, &c);
|
||||
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, glitch_pin, 1, true );
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, trig_pin , 1, false);
|
||||
pio_sm_set_pins_with_mask(pio, sm, 0, 1u << glitch_pin);
|
||||
|
||||
pio_sm_set_enabled(pio, sm, enable);
|
||||
pio_gpio_init(pio, glitch_pin);
|
||||
pio_gpio_init(pio, trig_pin);
|
||||
}
|
||||
|
||||
// ony use "use_wfi" when the corresponding IRQ is enabled in the NVIC
|
||||
static inline void trigctl_wait_glitch_irq(PIO pio, uint sm, bool use_wfi) {
|
||||
uint mask = 1u << ((sm + 0) & 3);
|
||||
if (use_wfi) {
|
||||
while (!(pio->irq & mask)) __WFE();
|
||||
} else {
|
||||
while (!(pio->irq & mask)) ;
|
||||
}
|
||||
}
|
||||
static inline void trigctl_ack_glitch_irq(PIO pio, uint sm) {
|
||||
hw_set_bits(&pio->irq, 1 << ((sm + 0) & 3));
|
||||
}
|
||||
// nvic_irqno: corresponding NVIC IRQ will be PIO${pio}_IRQ_${nvic_irqno}
|
||||
static inline void trigctl_set_glitch_irq_enabled(PIO pio, uint sm, uint nvic_irqno, bool en) {
|
||||
pio_set_irqn_source_enabled(pio, nvic_irqno, (sm + 0) & 3, en);
|
||||
}
|
||||
|
||||
/*static inline void trigctl_send_trig_irq(PIO pio, uint sm) {
|
||||
pio->irq_force = 1 << ((sm + 1) & 3);
|
||||
}*/
|
||||
|
||||
static inline void trigctl_push_off_len(PIO pio, uint sm, uint32_t off, uint32_t len) {
|
||||
while (pio_sm_is_tx_fifo_full(pio, sm)) ;
|
||||
pio->txf[sm] = off;
|
||||
while (pio_sm_is_tx_fifo_full(pio, sm)) ;
|
||||
pio->txf[sm] = len;
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
;
|
||||
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
;
|
||||
; SPDX-License-Identifier: BSD-3-Clause
|
||||
;
|
||||
|
||||
.program uart_rx_mini
|
||||
|
||||
; Minimum viable 8n1 UART receiver. Wait for the start bit, then sample 8 bits
|
||||
; with the correct timing.
|
||||
; IN pin 0 is mapped to the GPIO used as UART RX.
|
||||
; Autopush must be enabled, with a threshold of 8.
|
||||
|
||||
wait 0 pin 0 ; Wait for start bit
|
||||
set x, 7 [10] ; Preload bit counter, delay until eye of first data bit
|
||||
bitloop: ; Loop 8 times
|
||||
in pins, 1 ; Sample data
|
||||
jmp x-- bitloop [6] ; Each iteration is 8 cycles
|
||||
|
||||
% c-sdk {
|
||||
#include "hardware/clocks.h"
|
||||
#include "hardware/gpio.h"
|
||||
|
||||
static inline void uart_rx_mini_program_init(PIO pio, uint sm, uint offset, uint pin, uint baud) {
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
|
||||
pio_gpio_init(pio, pin);
|
||||
gpio_pull_up(pin);
|
||||
|
||||
pio_sm_config c = uart_rx_mini_program_get_default_config(offset);
|
||||
sm_config_set_in_pins(&c, pin); // for WAIT, IN
|
||||
// Shift to right, autopush enabled
|
||||
sm_config_set_in_shift(&c, true, true, 8);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
|
||||
// SM transmits 1 bit per 8 execution cycles.
|
||||
float div = (float)clock_get_hz(clk_sys) / (8 * baud);
|
||||
sm_config_set_clkdiv(&c, div);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
%}
|
||||
|
||||
.program uart_rx
|
||||
|
||||
; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
|
||||
; break conditions more gracefully.
|
||||
; IN pin 0 and JMP pin are both mapped to the GPIO used as UART RX.
|
||||
|
||||
start:
|
||||
wait 0 pin 0 ; Stall until start bit is asserted
|
||||
set x, 7 [10] ; Preload bit counter, then delay until halfway through
|
||||
bitloop: ; the first data bit (12 cycles incl wait, set).
|
||||
in pins, 1 ; Shift data bit into ISR
|
||||
jmp x-- bitloop [6] ; Loop 8 times, each loop iteration is 8 cycles
|
||||
jmp pin good_stop ; Check stop bit (should be high)
|
||||
|
||||
irq 4 rel ; Either a framing error or a break. Set a sticky flag,
|
||||
wait 1 pin 0 ; and wait for line to return to idle state.
|
||||
jmp start ; Don't push data if we didn't see good framing.
|
||||
|
||||
good_stop: ; No delay before returning to start; a little slack is
|
||||
push ; important in case the TX clock is slightly too fast.
|
||||
|
||||
|
||||
% c-sdk {
|
||||
static inline void uart_rx_program_init(PIO pio, uint sm, uint offset, uint pin, uint baud) {
|
||||
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
|
||||
pio_gpio_init(pio, pin);
|
||||
gpio_pull_up(pin);
|
||||
|
||||
pio_sm_config c = uart_rx_program_get_default_config(offset);
|
||||
sm_config_set_in_pins(&c, pin); // for WAIT, IN
|
||||
sm_config_set_jmp_pin(&c, pin); // for JMP
|
||||
// Shift to right, autopush disabled
|
||||
sm_config_set_in_shift(&c, true, false, 32);
|
||||
// Deeper FIFO as we're not doing any TX
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
|
||||
// SM transmits 1 bit per 8 execution cycles.
|
||||
float div = (float)clock_get_hz(clk_sys) / (8 * baud);
|
||||
sm_config_set_clkdiv(&c, div);
|
||||
|
||||
pio_sm_init(pio, sm, offset, &c);
|
||||
pio_sm_set_enabled(pio, sm, true);
|
||||
}
|
||||
|
||||
static inline char uart_rx_program_getc(PIO pio, uint sm) {
|
||||
// 8-bit read from the uppermost byte of the FIFO, as data is left-justified
|
||||
io_rw_8 *rxfifo_shift = (io_rw_8*)&pio->rxf[sm] + 3;
|
||||
while (pio_sm_is_rx_fifo_empty(pio, sm))
|
||||
tight_loop_contents();
|
||||
return (char)*rxfifo_shift;
|
||||
}
|
||||
|
||||
%}
|
58
src/main.c
58
src/main.c
|
@ -24,11 +24,41 @@ static void setup_io(void) {
|
|||
P2SEL0 &= ~(BIT0 | BIT1); // port 2.[01] to eUSCI_A0
|
||||
P2SEL1 |= BIT0 | BIT1;
|
||||
|
||||
P1OUT &= ~(BIT0|BIT1|BIT2|BIT3); // P1.[0-3]: status LED and LA trigger debug stuff
|
||||
P1DIR |= (BIT0|BIT1|BIT2|BIT3);
|
||||
// BIT4: trigger for pico-controlled NMI
|
||||
P1OUT &= ~(BIT0|BIT1|BIT2|BIT3|BIT4); // P1.[0-3]: status LED and LA trigger debug stuff
|
||||
P1DIR |= (BIT0|BIT1|BIT2|BIT3|BIT4);
|
||||
// BIT5: ack from pico
|
||||
P1OUT &= ~BIT5;
|
||||
P1DIR &= ~BIT5;
|
||||
P1SEL0 &= ~BIT5;
|
||||
P2SEL0 &= ~BIT5;
|
||||
|
||||
// uart to pico (eUSCI_A3)
|
||||
P6OUT = BIT0;
|
||||
P6REN = BIT0;
|
||||
P6DIR = 0xff;
|
||||
P6SEL1 = ~(BIT0|BIT1);
|
||||
P6SEL0 = BIT0|BIT1 ;
|
||||
|
||||
PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
|
||||
// to activate previously configured port settings
|
||||
|
||||
// uart A3 to pico
|
||||
UCA3CTLW0 = UCSWRST;
|
||||
UCA3CTLW0 |= UCSSEL__SMCLK | (0<<9/*UART*/) | (0<<3/*dormant rx*/);
|
||||
UCA3BRW = 6; // 9600ish baud
|
||||
UCA3MCTLW |= UCOS16 | UCBRF_1 | 0x2080;
|
||||
UCA3IE &= ~(UCTXIE|UCRXIE);
|
||||
UCA3CTLW0 &= ~UCSWRST;
|
||||
}
|
||||
|
||||
static void pico_send_cmd(char cmd) {
|
||||
while (!(UCA3IFG & UCTXIFG)) ;
|
||||
UCA3TXBUF = cmd;
|
||||
}
|
||||
static void pico_wait_ack(void) {
|
||||
while (!(P1IN & BIT5)) ;
|
||||
while ( (P1IN & BIT5)) ;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
@ -288,15 +318,17 @@ __attribute__((__interrupt__(UNMI_VECTOR)))
|
|||
void NMI_ISR(void) {
|
||||
SFRIFG1 &= ~NMIIE;
|
||||
SYSUNIV = 0;
|
||||
++P1OUT;
|
||||
//++P1OUT;
|
||||
P1OUT = ((P1OUT+1) & 15) | (P1OUT & 0xF0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
setup_io();
|
||||
setup_clocks();
|
||||
stdio_msp_init();
|
||||
//SFRIE1 = NMIIE;
|
||||
//SFRRPCR = SYSRSTRE__ENABLE | SYSRSTUP__PULLUP | SYSNMIIES__FALLING | SYSNMI__NMI;
|
||||
SFRIE1 = NMIIE;
|
||||
SFRRPCR = SYSRSTRE__ENABLE | SYSRSTUP__PULLUP | SYSNMIIES__FALLING | SYSNMI__NMI;
|
||||
// NOTE: RST/#NMI == SBWTDIO
|
||||
|
||||
memset(regbak, 0, sizeof regbak);
|
||||
|
||||
|
@ -319,7 +351,19 @@ int main(void) {
|
|||
puts("hello world!\r\n");
|
||||
|
||||
done_irq = 0;
|
||||
do_trace();
|
||||
__builtin_unreachable();
|
||||
|
||||
pico_send_cmd(0);
|
||||
while (true) {
|
||||
P1OUT |= BIT4; // send trig
|
||||
__delay_cycles(10);
|
||||
P1OUT &= ~BIT4;
|
||||
|
||||
pico_send_cmd('+');
|
||||
pico_wait_ack();
|
||||
__delay_cycles(10000);
|
||||
}
|
||||
|
||||
/*do_trace();
|
||||
__builtin_unreachable();*/
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue