mirror of
https://github.com/V2RetroComputing/analog.git
synced 2024-11-22 11:33:26 +00:00
89 lines
3.4 KiB
C
89 lines
3.4 KiB
C
#include <string.h>
|
|
#include <hardware/pio.h>
|
|
#include "common/config.h"
|
|
#include "common/abus.h"
|
|
#include "abus.pio.h"
|
|
|
|
#if CONFIG_PIN_APPLEBUS_PHI0 != PHI0_GPIO
|
|
#error CONFIG_PIN_APPLEBUS_PHI0 and PHI0_GPIO must be set to the same pin
|
|
#endif
|
|
|
|
|
|
#define CARD_SELECT ((value & (1u << CONFIG_PIN_APPLEBUS_DEVSEL-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)
|
|
#define CARD_DEVSEL ((address & 0xcf80) == 0xc080)
|
|
#define CARD_IOSEL (((address & 0xcf00) >= 0xc100) && ((address & 0xcf00) < 0xc700))
|
|
#define CARD_IOSTROBE ((address & 0xc800) == 0xc800)
|
|
|
|
|
|
static void abus_device_read_setup(PIO pio, uint sm) {
|
|
uint program_offset = pio_add_program(pio, &abus_device_read_program);
|
|
pio_sm_claim(pio, sm);
|
|
|
|
pio_sm_config c = abus_device_read_program_get_default_config(program_offset);
|
|
|
|
// set the "device selected" pin as the jump pin
|
|
sm_config_set_jmp_pin(&c, CONFIG_PIN_APPLEBUS_DEVSEL);
|
|
|
|
// map the OUT pin group to the data signals
|
|
sm_config_set_out_pins(&c, CONFIG_PIN_APPLEBUS_DATA_BASE, 8);
|
|
|
|
// map the SET pin group to the Data transceiver control signals
|
|
sm_config_set_set_pins(&c, CONFIG_PIN_APPLEBUS_CONTROL_BASE, 2);
|
|
|
|
pio_sm_init(pio, sm, program_offset, &c);
|
|
|
|
// All the GPIOs are shared and setup by the main program
|
|
}
|
|
|
|
static void abus_main_setup(PIO pio, uint sm) {
|
|
uint program_offset = pio_add_program(pio, &abus_program);
|
|
pio_sm_claim(pio, sm);
|
|
|
|
pio_sm_config c = abus_program_get_default_config(program_offset);
|
|
|
|
// set the bus R/W pin as the jump pin
|
|
sm_config_set_jmp_pin(&c, CONFIG_PIN_APPLEBUS_RW);
|
|
|
|
// map the IN pin group to the data signals
|
|
sm_config_set_in_pins(&c, CONFIG_PIN_APPLEBUS_DATA_BASE);
|
|
|
|
// map the SET pin group to the bus transceiver enable signals
|
|
sm_config_set_set_pins(&c, CONFIG_PIN_APPLEBUS_CONTROL_BASE+1, 3);
|
|
|
|
// configure left shift into ISR & autopush every 26 bits
|
|
sm_config_set_in_shift(&c, false, true, 26);
|
|
|
|
pio_sm_init(pio, sm, program_offset, &c);
|
|
|
|
// configure the GPIOs
|
|
// Ensure all transceivers will start disabled, with Data transceiver direction set to 'in'
|
|
pio_sm_set_pins_with_mask(pio, sm,
|
|
(uint32_t)0xe << CONFIG_PIN_APPLEBUS_CONTROL_BASE,
|
|
(uint32_t)0xf << CONFIG_PIN_APPLEBUS_CONTROL_BASE);
|
|
pio_sm_set_pindirs_with_mask(pio, sm,
|
|
(0xf << CONFIG_PIN_APPLEBUS_CONTROL_BASE),
|
|
(1 << CONFIG_PIN_APPLEBUS_PHI0) | (0xf << CONFIG_PIN_APPLEBUS_CONTROL_BASE) | (0x3ff << CONFIG_PIN_APPLEBUS_DATA_BASE));
|
|
|
|
// Disable input synchronization on input pins that are sampled at known stable times
|
|
// to shave off two clock cycles of input latency
|
|
pio->input_sync_bypass |= (0x3ff << CONFIG_PIN_APPLEBUS_DATA_BASE);
|
|
|
|
pio_gpio_init(pio, CONFIG_PIN_APPLEBUS_PHI0);
|
|
gpio_set_pulls(CONFIG_PIN_APPLEBUS_PHI0, false, false);
|
|
for(int pin=CONFIG_PIN_APPLEBUS_CONTROL_BASE; pin < CONFIG_PIN_APPLEBUS_CONTROL_BASE+4; pin++) {
|
|
pio_gpio_init(pio, pin);
|
|
}
|
|
for(int pin=CONFIG_PIN_APPLEBUS_DATA_BASE; pin < CONFIG_PIN_APPLEBUS_DATA_BASE+10; pin++) {
|
|
pio_gpio_init(pio, pin);
|
|
gpio_set_pulls(pin, false, false);
|
|
}
|
|
}
|
|
|
|
|
|
void abus_init() {
|
|
abus_device_read_setup(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM);
|
|
abus_main_setup(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
|
|
|
pio_enable_sm_mask_in_sync(CONFIG_ABUS_PIO, (1 << ABUS_MAIN_SM) | (1 << ABUS_DEVICE_READ_SM));
|
|
}
|