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