//
// SQUARE WAVE CLOCK SIGNAL, WITH INTERRUPTS FOR MEMORY ACCESS
// PIN_CLK is monitored in Wokwi Logic Analyzer and resulting VCD file viewed in PulseView
//
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/irq.h" //
#include "hardware/pio.h" //
#include "hardware/clocks.h"
#include "cpu6502.h"
#include "PIO_test.pio.h"
uint16_t cpu_addr; // 65C02 address (program counter)
uint8_t cpu_data; // 65C02 data
bool cpu_rw; // 65C02 Read/Write pin state
static PIO PIO_O; // PIO object
static uint SM; // PIO state machine index
static uint PIO_IRQ; // NVIC ARM CPU interrupt number
//
// INIT
//
void init() {
stdio_init_all();
printf("Pi Pico TEST : clock and interrupts\n\n");
cpu6502_init();
}
//
// PIO INTERRUPT SERVICE ROUTINE
// Still not entirely sure of timing requirements
// Timing diags indicate address OK as PHI2 goes low
//
void pio_irq_handler() {
gpio_put(_NMI_PIN, 1); // SET TEST PIN FOR ANALYSER
gpio_put(_NMI_PIN, 0); // Just using NMI since it's not in use
if (gpio_get(_CLOCK_PIN) == 0) // Low, get address
cpu6502_get_address();
else
cpu6502_get_data(); // else get data from bus
pio_interrupt_clear(PIO_O, 0);
}
void test_IRQ_PIO() {
PIO_O = pio0;
PIO_IRQ = PIO0_IRQ_0;
uint offset = pio_add_program(PIO_O, &pioIRQ_program);
// TODO
float SM_CLK_FREQ = 1000000;
// Find a free state machine on our chosen PIO
SM = pio_claim_unused_sm(PIO_O, true);
pioIRQ_program_init(PIO_O, SM, offset, _CLOCK_PIN, SM_CLK_FREQ);
pio_set_irq0_source_enabled(PIO_O, pis_interrupt0, true); // sets IRQ0
irq_set_exclusive_handler(PIO_IRQ, pio_irq_handler); //Set the handler in the NVIC
irq_set_enabled(PIO_IRQ, true); // Enabling the PIO
}
//
// MAIN
//
int main() {
init();
test_IRQ_PIO();
printf("PIO: %d, SM: %d, PIO_IRQ_num: %d \n", pio_get_index(PIO_O), SM, PIO_IRQ);
while (true) {
printf("."); // Show something happening
sleep_ms(200);
}
}