⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pxa2xx.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
{    struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque;    addr -= s->base;    switch (addr) {    case ICR:        return s->control;    case ISR:        return s->status | (i2c_bus_busy(s->bus) << 2);    case ISAR:        return s->slave.address;    case IDBR:        return s->data;    case IBMR:        if (s->status & (1 << 2))            s->ibmr ^= 3;	/* Fake SCL and SDA pin changes */        else            s->ibmr = 0;        return s->ibmr;    default:        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);        break;    }    return 0;}static void pxa2xx_i2c_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque;    int ack;    addr -= s->base;    switch (addr) {    case ICR:        s->control = value & 0xfff7;        if ((value & (1 << 3)) && (value & (1 << 6))) {	/* TB and IUE */            /* TODO: slave mode */            if (value & (1 << 0)) {			/* START condition */                if (s->data & 1)                    s->status |= 1 << 0;		/* set RWM */                else                    s->status &= ~(1 << 0);		/* clear RWM */                ack = !i2c_start_transfer(s->bus, s->data >> 1, s->data & 1);            } else {                if (s->status & (1 << 0)) {		/* RWM */                    s->data = i2c_recv(s->bus);                    if (value & (1 << 2))		/* ACKNAK */                        i2c_nack(s->bus);                    ack = 1;                } else                    ack = !i2c_send(s->bus, s->data);            }            if (value & (1 << 1))			/* STOP condition */                i2c_end_transfer(s->bus);            if (ack) {                if (value & (1 << 0))			/* START condition */                    s->status |= 1 << 6;		/* set ITE */                else                    if (s->status & (1 << 0))		/* RWM */                        s->status |= 1 << 7;		/* set IRF */                    else                        s->status |= 1 << 6;		/* set ITE */                s->status &= ~(1 << 1);			/* clear ACKNAK */            } else {                s->status |= 1 << 6;			/* set ITE */                s->status |= 1 << 10;			/* set BED */                s->status |= 1 << 1;			/* set ACKNAK */            }        }        if (!(value & (1 << 3)) && (value & (1 << 6)))	/* !TB and IUE */            if (value & (1 << 4))			/* MA */                i2c_end_transfer(s->bus);        pxa2xx_i2c_update(s);        break;    case ISR:        s->status &= ~(value & 0x07f0);        pxa2xx_i2c_update(s);        break;    case ISAR:        i2c_set_slave_address(&s->slave, value & 0x7f);        break;    case IDBR:        s->data = value & 0xff;        break;    default:        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);    }}static CPUReadMemoryFunc *pxa2xx_i2c_readfn[] = {    pxa2xx_i2c_read,    pxa2xx_i2c_read,    pxa2xx_i2c_read,};static CPUWriteMemoryFunc *pxa2xx_i2c_writefn[] = {    pxa2xx_i2c_write,    pxa2xx_i2c_write,    pxa2xx_i2c_write,};static void pxa2xx_i2c_save(QEMUFile *f, void *opaque){    struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque;    qemu_put_be16s(f, &s->control);    qemu_put_be16s(f, &s->status);    qemu_put_8s(f, &s->ibmr);    qemu_put_8s(f, &s->data);    i2c_bus_save(f, s->bus);    i2c_slave_save(f, &s->slave);}static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id){    struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque;    qemu_get_be16s(f, &s->control);    qemu_get_be16s(f, &s->status);    qemu_get_8s(f, &s->ibmr);    qemu_get_8s(f, &s->data);    i2c_bus_load(f, s->bus);    i2c_slave_load(f, &s->slave);    return 0;}struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,                qemu_irq irq, uint32_t page_size){    int iomemtype;    struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *)            i2c_slave_init(i2c_init_bus(), 0, sizeof(struct pxa2xx_i2c_s));    s->base = base;    s->irq = irq;    s->slave.event = pxa2xx_i2c_event;    s->slave.recv = pxa2xx_i2c_rx;    s->slave.send = pxa2xx_i2c_tx;    s->bus = i2c_init_bus();    iomemtype = cpu_register_io_memory(0, pxa2xx_i2c_readfn,                    pxa2xx_i2c_writefn, s);    cpu_register_physical_memory(s->base & ~page_size, page_size, iomemtype);    register_savevm("pxa2xx_i2c", base, 0,                    pxa2xx_i2c_save, pxa2xx_i2c_load, s);    return s;}i2c_bus *pxa2xx_i2c_bus(struct pxa2xx_i2c_s *s){    return s->bus;}/* PXA Inter-IC Sound Controller */static void pxa2xx_i2s_reset(struct pxa2xx_i2s_s *i2s){    i2s->rx_len = 0;    i2s->tx_len = 0;    i2s->fifo_len = 0;    i2s->clk = 0x1a;    i2s->control[0] = 0x00;    i2s->control[1] = 0x00;    i2s->status = 0x00;    i2s->mask = 0x00;}#define SACR_TFTH(val)	((val >> 8) & 0xf)#define SACR_RFTH(val)	((val >> 12) & 0xf)#define SACR_DREC(val)	(val & (1 << 3))#define SACR_DPRL(val)	(val & (1 << 4))static inline void pxa2xx_i2s_update(struct pxa2xx_i2s_s *i2s){    int rfs, tfs;    rfs = SACR_RFTH(i2s->control[0]) < i2s->rx_len &&            !SACR_DREC(i2s->control[1]);    tfs = (i2s->tx_len || i2s->fifo_len < SACR_TFTH(i2s->control[0])) &&            i2s->enable && !SACR_DPRL(i2s->control[1]);    pxa2xx_dma_request(i2s->dma, PXA2XX_RX_RQ_I2S, rfs);    pxa2xx_dma_request(i2s->dma, PXA2XX_TX_RQ_I2S, tfs);    i2s->status &= 0xe0;    if (i2s->fifo_len < 16 || !i2s->enable)        i2s->status |= 1 << 0;			/* TNF */    if (i2s->rx_len)        i2s->status |= 1 << 1;			/* RNE */    if (i2s->enable)        i2s->status |= 1 << 2;			/* BSY */    if (tfs)        i2s->status |= 1 << 3;			/* TFS */    if (rfs)        i2s->status |= 1 << 4;			/* RFS */    if (!(i2s->tx_len && i2s->enable))        i2s->status |= i2s->fifo_len << 8;	/* TFL */    i2s->status |= MAX(i2s->rx_len, 0xf) << 12;	/* RFL */    qemu_set_irq(i2s->irq, i2s->status & i2s->mask);}#define SACR0	0x00	/* Serial Audio Global Control register */#define SACR1	0x04	/* Serial Audio I2S/MSB-Justified Control register */#define SASR0	0x0c	/* Serial Audio Interface and FIFO Status register */#define SAIMR	0x14	/* Serial Audio Interrupt Mask register */#define SAICR	0x18	/* Serial Audio Interrupt Clear register */#define SADIV	0x60	/* Serial Audio Clock Divider register */#define SADR	0x80	/* Serial Audio Data register */static uint32_t pxa2xx_i2s_read(void *opaque, target_phys_addr_t addr){    struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;    addr -= s->base;    switch (addr) {    case SACR0:        return s->control[0];    case SACR1:        return s->control[1];    case SASR0:        return s->status;    case SAIMR:        return s->mask;    case SAICR:        return 0;    case SADIV:        return s->clk;    case SADR:        if (s->rx_len > 0) {            s->rx_len --;            pxa2xx_i2s_update(s);            return s->codec_in(s->opaque);        }        return 0;    default:        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);        break;    }    return 0;}static void pxa2xx_i2s_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;    uint32_t *sample;    addr -= s->base;    switch (addr) {    case SACR0:        if (value & (1 << 3))				/* RST */            pxa2xx_i2s_reset(s);        s->control[0] = value & 0xff3d;        if (!s->enable && (value & 1) && s->tx_len) {	/* ENB */            for (sample = s->fifo; s->fifo_len > 0; s->fifo_len --, sample ++)                s->codec_out(s->opaque, *sample);            s->status &= ~(1 << 7);			/* I2SOFF */        }        if (value & (1 << 4))				/* EFWR */            printf("%s: Attempt to use special function\n", __FUNCTION__);        s->enable = ((value ^ 4) & 5) == 5;		/* ENB && !RST*/        pxa2xx_i2s_update(s);        break;    case SACR1:        s->control[1] = value & 0x0039;        if (value & (1 << 5))				/* ENLBF */            printf("%s: Attempt to use loopback function\n", __FUNCTION__);        if (value & (1 << 4))				/* DPRL */            s->fifo_len = 0;        pxa2xx_i2s_update(s);        break;    case SAIMR:        s->mask = value & 0x0078;        pxa2xx_i2s_update(s);        break;    case SAICR:        s->status &= ~(value & (3 << 5));        pxa2xx_i2s_update(s);        break;    case SADIV:        s->clk = value & 0x007f;        break;    case SADR:        if (s->tx_len && s->enable) {            s->tx_len --;            pxa2xx_i2s_update(s);            s->codec_out(s->opaque, value);        } else if (s->fifo_len < 16) {            s->fifo[s->fifo_len ++] = value;            pxa2xx_i2s_update(s);        }        break;    default:        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);    }}static CPUReadMemoryFunc *pxa2xx_i2s_readfn[] = {    pxa2xx_i2s_read,    pxa2xx_i2s_read,    pxa2xx_i2s_read,};static CPUWriteMemoryFunc *pxa2xx_i2s_writefn[] = {    pxa2xx_i2s_write,    pxa2xx_i2s_write,    pxa2xx_i2s_write,};static void pxa2xx_i2s_save(QEMUFile *f, void *opaque){    struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;    qemu_put_be32s(f, &s->control[0]);    qemu_put_be32s(f, &s->control[1]);    qemu_put_be32s(f, &s->status);    qemu_put_be32s(f, &s->mask);    qemu_put_be32s(f, &s->clk);    qemu_put_be32(f, s->enable);    qemu_put_be32(f, s->rx_len);    qemu_put_be32(f, s->tx_len);    qemu_put_be32(f, s->fifo_len);}static int pxa2xx_i2s_load(QEMUFile *f, void *opaque, int version_id){    struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;    qemu_get_be32s(f, &s->control[0]);    qemu_get_be32s(f, &s->control[1]);    qemu_get_be32s(f, &s->status);    qemu_get_be32s(f, &s->mask);    qemu_get_be32s(f, &s->clk);    s->enable = qemu_get_be32(f);    s->rx_len = qemu_get_be32(f);    s->tx_len = qemu_get_be32(f);    s->fifo_len = qemu_get_be32(f);    return 0;}static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx){    struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;    uint32_t *sample;    /* Signal FIFO errors */    if (s->enable && s->tx_len)        s->status |= 1 << 5;		/* TUR */    if (s->enable && s->rx_len)        s->status |= 1 << 6;		/* ROR */    /* Should be tx - MIN(tx, s->fifo_len) but we don't really need to     * handle the cases where it makes a difference.  */    s->tx_len = tx - s->fifo_len;    s->rx_len = rx;    /* Note that is s->codec_out wasn't set, we wouldn't get called.  */    if (s->enable)        for (sample = s->fifo; s->fifo_len; s->fifo_len --, sample ++)            s->codec_out(s->opaque, *sample);    pxa2xx_i2s_update(s);}static struct pxa2xx_i2s_s *pxa2xx_i2s_init(target_phys_addr_t base,                qemu_irq irq, struct pxa2xx_dma_state_s *dma){    int iomemtype;    struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *)            qemu_mallocz(sizeof(struct pxa2xx_i2s_s));    s->base = base;    s->irq = irq;    s->dma = dma;    s->data_req = pxa2xx_i2s_data_req;    pxa2xx_i2s_reset(s);    iomemtype = cpu_register_io_memory(0, pxa2xx_i2s_readfn,                    pxa2xx_i2s_writefn, s);    cpu_register_physical_memory(s->base & 0xfff00000, 0x100000, iomemtype);    register_savevm("pxa2xx_i2s", base, 0,                    pxa2xx_i2s_save, pxa2xx_i2s_load, s);    return s;}/* PXA Fast Infra-red Communications Port */struct pxa2xx_fir_s {    target_phys_addr_t base;    qemu_irq irq;    struct pxa2xx_dma_state_s *dma;    int enable;    CharDriverState *chr;    uint8_t control[3];    uint8_t status[2];    int rx_len;    int rx_start;    uint8_t rx_fifo[64];};static void pxa2xx_fir_reset(struct pxa2xx_fir_s *s){    s->control[0] = 0x00;    s->control[1] = 0x00;    s->control[2] = 0x00;    s->status[0] = 0x00;    s->status[1] = 0x00;    s->enable = 0;}static inline void pxa2xx_fir_update(struct pxa2xx_fir_s *s){    static const int tresh[4] = { 8, 16, 32, 0 };    int intr = 0;    if ((s->control[0] & (1 << 4)) &&			/* RXE */                    s->rx_len >= tresh[s->control[2] & 3])	/* TRIG */        s->status[0] |= 1 << 4;				/* RFS */    else        s->status[0] &= ~(1 << 4);			/* RFS */    if (s->control[0] & (1 << 3))			/* TXE */        s->status[0] |= 1 << 3;				/* TFS */    else        s->status[0] &= ~(1 << 3);			/* TFS */    if (s->rx_len)        s->status[1] |= 1 << 2;				/* RNE */    else        s->status[1] &= ~(1 << 2);			/* RNE */    if (s->control[0] & (1 << 4))			/* RXE */        s->status[1] |= 1 << 0;				/* RSY */    else        s->status[1] &= ~(1 << 0);			/* RSY */    intr |= (s->control[0] & (1 << 5)) &&		/* RIE */            (s->status[0] & (1 << 4));			/* RFS */    intr |= (s->control[0] & (1 << 6)) &&		/* TIE */            (s->status[0] & (1 << 3));			/* TFS */    intr |= (s->control[2] & (1 << 4)) &&		/* TRAIL */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -