SPC music playback tools for real snes apu

Dependencies:   mbed

gpio.cpp

Committer:
akkera102
Date:
2017-01-11
Revision:
2:62e6e22f8be2
Parent:
0:5bd52e196edb

File content as of revision 2:62e6e22f8be2:

#include "gpio.h"
#include "mbed.h"

// mbed LPC1768
DigitalInOut d[] = {
    p5,       // A7
    p6,       // A6
    p7,       // A0
    p8,       // A1
    p9,       // WR
    p10,      // RD

    p11,      // D0
    p12,
    p13,
    p14,
    p15,
    p16,
    p17,
    p18,      // D7

    p19,      // ICL
};

static void gpio_set_pin(int pin, bool high);
static void gpio_set_dir(int pin, bool write);
static unsigned char gpio_swap_bits(unsigned char c);

void gpio_init(void)
{
    gpio_set_pin(GPIO_A0, false);
    gpio_set_pin(GPIO_A1, false);
    gpio_set_pin(GPIO_A6, true);
    gpio_set_pin(GPIO_A7, false);
    gpio_set_pin(GPIO_WR, true);
    gpio_set_pin(GPIO_RD, true);
    gpio_set_pin(GPIO_ICL, true);

    gpio_set_dir(GPIO_A0, true);
    gpio_set_dir(GPIO_A1, true);
    gpio_set_dir(GPIO_A6, true);
    gpio_set_dir(GPIO_A7, true);
    gpio_set_dir(GPIO_WR, true);
    gpio_set_dir(GPIO_RD, true);
    gpio_set_dir(GPIO_ICL, true);

    gpio_set_pin(GPIO_A0, false);
    gpio_set_pin(GPIO_A1, false);
    gpio_set_pin(GPIO_A6, true);
    gpio_set_pin(GPIO_A7, false);
    gpio_set_pin(GPIO_WR, true);
    gpio_set_pin(GPIO_RD, true);
    gpio_set_pin(GPIO_ICL, true);
}

void gpio_reset(void)
{
    gpio_set_pin(GPIO_A0, false);
    gpio_set_pin(GPIO_A1, false);
    gpio_set_pin(GPIO_A6, true);
    gpio_set_pin(GPIO_A7, false);
    gpio_set_pin(GPIO_WR, true);
    gpio_set_pin(GPIO_RD, true);
    gpio_set_pin(GPIO_ICL, false);
    wait_us(50 * 1000);

    gpio_set_pin(GPIO_ICL, true);
    wait_us(50 * 1000);
}

void gpio_write(int address, unsigned char data)
{
    gpio_set_pin(GPIO_A0, ((address & 1) != 0));
    gpio_set_pin(GPIO_A1, ((address & 2) != 0));
    gpio_set_pin(GPIO_RD, true);
    gpio_set_pin(GPIO_WR, false);

    for(int i=6; i<6+8; i++)
    {
        d[i].output();
        d[i] = data & 0x1;
        data >>= 1;
    }
    wait_us(1);

    gpio_set_pin(GPIO_WR, true);
}

unsigned char gpio_read(int address)
{
    gpio_set_pin(GPIO_A0, ((address & 1) != 0));
    gpio_set_pin(GPIO_A1, ((address & 2) != 0));
    gpio_set_pin(GPIO_WR, true);
    gpio_set_pin(GPIO_RD, false);

    unsigned char ret = 0;

    wait_us(1);
    for(int i=6; i<6+8; i++)
    {
        d[i].input();
        ret <<= 1;
        ret |= d[i];
    }

    gpio_set_pin(GPIO_RD, true);

    return gpio_swap_bits(ret);
}

static void gpio_set_pin(int pin, bool high)
{
    d[pin] = high ? 1 : 0;
}

static void gpio_set_dir(int pin, bool write)
{
    if(write)
    {
        d[pin].output();
    }
    else
    {
        d[pin].input();
    }
}

static unsigned char gpio_swap_bits(unsigned char c)
{
    unsigned char r = 0;

    if(c & 0x01) r |= 0x80;
    if(c & 0x02) r |= 0x40;
    if(c & 0x04) r |= 0x20;
    if(c & 0x08) r |= 0x10;
    if(c & 0x10) r |= 0x08;
    if(c & 0x20) r |= 0x04;
    if(c & 0x40) r |= 0x02;
    if(c & 0x80) r |= 0x01;

    return r;
}