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

📄 stellaris.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* * Luminary Micro Stellaris preipherals * * Copyright (c) 2006 CodeSourcery. * Written by Paul Brook * * This code is licenced under the GPL. */#include "hw.h"#include "arm-misc.h"#include "primecell.h"#include "devices.h"#include "qemu-timer.h"#include "i2c.h"#include "net.h"#include "sd.h"#include "sysemu.h"#include "boards.h"#define GPIO_A 0#define GPIO_B 1#define GPIO_C 2#define GPIO_D 3#define GPIO_E 4#define GPIO_F 5#define GPIO_G 6#define BP_OLED_I2C  0x01#define BP_OLED_SSI  0x02#define BP_GAMEPAD   0x04typedef const struct {    const char *name;    uint32_t did0;    uint32_t did1;    uint32_t dc0;    uint32_t dc1;    uint32_t dc2;    uint32_t dc3;    uint32_t dc4;    uint32_t peripherals;} stellaris_board_info;/* General purpose timer module.  */typedef struct gptm_state {    uint32_t config;    uint32_t mode[2];    uint32_t control;    uint32_t state;    uint32_t mask;    uint32_t load[2];    uint32_t match[2];    uint32_t prescale[2];    uint32_t match_prescale[2];    uint32_t rtc;    int64_t tick[2];    struct gptm_state *opaque[2];    uint32_t base;    QEMUTimer *timer[2];    /* The timers have an alternate output used to trigger the ADC.  */    qemu_irq trigger;    qemu_irq irq;} gptm_state;static void gptm_update_irq(gptm_state *s){    int level;    level = (s->state & s->mask) != 0;    qemu_set_irq(s->irq, level);}static void gptm_stop(gptm_state *s, int n){    qemu_del_timer(s->timer[n]);}static void gptm_reload(gptm_state *s, int n, int reset){    int64_t tick;    if (reset)        tick = qemu_get_clock(vm_clock);    else        tick = s->tick[n];    if (s->config == 0) {        /* 32-bit CountDown.  */        uint32_t count;        count = s->load[0] | (s->load[1] << 16);        tick += (int64_t)count * system_clock_scale;    } else if (s->config == 1) {        /* 32-bit RTC.  1Hz tick.  */        tick += ticks_per_sec;    } else if (s->mode[n] == 0xa) {        /* PWM mode.  Not implemented.  */    } else {        cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",                  s->mode[n]);    }    s->tick[n] = tick;    qemu_mod_timer(s->timer[n], tick);}static void gptm_tick(void *opaque){    gptm_state **p = (gptm_state **)opaque;    gptm_state *s;    int n;    s = *p;    n = p - s->opaque;    if (s->config == 0) {        s->state |= 1;        if ((s->control & 0x20)) {            /* Output trigger.  */	    qemu_irq_raise(s->trigger);	    qemu_irq_lower(s->trigger);        }        if (s->mode[0] & 1) {            /* One-shot.  */            s->control &= ~1;        } else {            /* Periodic.  */            gptm_reload(s, 0, 0);        }    } else if (s->config == 1) {        /* RTC.  */        uint32_t match;        s->rtc++;        match = s->match[0] | (s->match[1] << 16);        if (s->rtc > match)            s->rtc = 0;        if (s->rtc == 0) {            s->state |= 8;        }        gptm_reload(s, 0, 0);    } else if (s->mode[n] == 0xa) {        /* PWM mode.  Not implemented.  */    } else {        cpu_abort(cpu_single_env, "TODO: 16-bit timer mode 0x%x\n",                  s->mode[n]);    }    gptm_update_irq(s);}static uint32_t gptm_read(void *opaque, target_phys_addr_t offset){    gptm_state *s = (gptm_state *)opaque;    offset -= s->base;    switch (offset) {    case 0x00: /* CFG */        return s->config;    case 0x04: /* TAMR */        return s->mode[0];    case 0x08: /* TBMR */        return s->mode[1];    case 0x0c: /* CTL */        return s->control;    case 0x18: /* IMR */        return s->mask;    case 0x1c: /* RIS */        return s->state;    case 0x20: /* MIS */        return s->state & s->mask;    case 0x24: /* CR */        return 0;    case 0x28: /* TAILR */        return s->load[0] | ((s->config < 4) ? (s->load[1] << 16) : 0);    case 0x2c: /* TBILR */        return s->load[1];    case 0x30: /* TAMARCHR */        return s->match[0] | ((s->config < 4) ? (s->match[1] << 16) : 0);    case 0x34: /* TBMATCHR */        return s->match[1];    case 0x38: /* TAPR */        return s->prescale[0];    case 0x3c: /* TBPR */        return s->prescale[1];    case 0x40: /* TAPMR */        return s->match_prescale[0];    case 0x44: /* TBPMR */        return s->match_prescale[1];    case 0x48: /* TAR */        if (s->control == 1)            return s->rtc;    case 0x4c: /* TBR */        cpu_abort(cpu_single_env, "TODO: Timer value read\n");    default:        cpu_abort(cpu_single_env, "gptm_read: Bad offset 0x%x\n", (int)offset);        return 0;    }}static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value){    gptm_state *s = (gptm_state *)opaque;    uint32_t oldval;    offset -= s->base;    /* The timers should be disabled before changing the configuration.       We take advantage of this and defer everything until the timer       is enabled.  */    switch (offset) {    case 0x00: /* CFG */        s->config = value;        break;    case 0x04: /* TAMR */        s->mode[0] = value;        break;    case 0x08: /* TBMR */        s->mode[1] = value;        break;    case 0x0c: /* CTL */        oldval = s->control;        s->control = value;        /* TODO: Implement pause.  */        if ((oldval ^ value) & 1) {            if (value & 1) {                gptm_reload(s, 0, 1);            } else {                gptm_stop(s, 0);            }        }        if (((oldval ^ value) & 0x100) && s->config >= 4) {            if (value & 0x100) {                gptm_reload(s, 1, 1);            } else {                gptm_stop(s, 1);            }        }        break;    case 0x18: /* IMR */        s->mask = value & 0x77;        gptm_update_irq(s);        break;    case 0x24: /* CR */        s->state &= ~value;        break;    case 0x28: /* TAILR */        s->load[0] = value & 0xffff;        if (s->config < 4) {            s->load[1] = value >> 16;        }        break;    case 0x2c: /* TBILR */        s->load[1] = value & 0xffff;        break;    case 0x30: /* TAMARCHR */        s->match[0] = value & 0xffff;        if (s->config < 4) {            s->match[1] = value >> 16;        }        break;    case 0x34: /* TBMATCHR */        s->match[1] = value >> 16;        break;    case 0x38: /* TAPR */        s->prescale[0] = value;        break;    case 0x3c: /* TBPR */        s->prescale[1] = value;        break;    case 0x40: /* TAPMR */        s->match_prescale[0] = value;        break;    case 0x44: /* TBPMR */        s->match_prescale[0] = value;        break;    default:        cpu_abort(cpu_single_env, "gptm_write: Bad offset 0x%x\n", (int)offset);    }    gptm_update_irq(s);}static CPUReadMemoryFunc *gptm_readfn[] = {   gptm_read,   gptm_read,   gptm_read};static CPUWriteMemoryFunc *gptm_writefn[] = {   gptm_write,   gptm_write,   gptm_write};static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger){    int iomemtype;    gptm_state *s;    s = (gptm_state *)qemu_mallocz(sizeof(gptm_state));    s->base = base;    s->irq = irq;    s->trigger = trigger;    s->opaque[0] = s->opaque[1] = s;    iomemtype = cpu_register_io_memory(0, gptm_readfn,                                       gptm_writefn, s);    cpu_register_physical_memory(base, 0x00001000, iomemtype);    s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);    s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);    /* ??? Save/restore.  */}/* System controller.  */typedef struct {    uint32_t base;    uint32_t pborctl;    uint32_t ldopctl;    uint32_t int_status;    uint32_t int_mask;    uint32_t resc;    uint32_t rcc;    uint32_t rcgc[3];    uint32_t scgc[3];    uint32_t dcgc[3];    uint32_t clkvclr;    uint32_t ldoarst;    uint32_t user0;    uint32_t user1;    qemu_irq irq;    stellaris_board_info *board;} ssys_state;static void ssys_update(ssys_state *s){  qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);}static uint32_t pllcfg_sandstorm[16] = {    0x31c0, /* 1 Mhz */    0x1ae0, /* 1.8432 Mhz */    0x18c0, /* 2 Mhz */    0xd573, /* 2.4576 Mhz */    0x37a6, /* 3.57954 Mhz */    0x1ae2, /* 3.6864 Mhz */    0x0c40, /* 4 Mhz */    0x98bc, /* 4.906 Mhz */    0x935b, /* 4.9152 Mhz */    0x09c0, /* 5 Mhz */    0x4dee, /* 5.12 Mhz */    0x0c41, /* 6 Mhz */    0x75db, /* 6.144 Mhz */    0x1ae6, /* 7.3728 Mhz */    0x0600, /* 8 Mhz */    0x585b /* 8.192 Mhz */};static uint32_t pllcfg_fury[16] = {    0x3200, /* 1 Mhz */    0x1b20, /* 1.8432 Mhz */    0x1900, /* 2 Mhz */    0xf42b, /* 2.4576 Mhz */    0x37e3, /* 3.57954 Mhz */    0x1b21, /* 3.6864 Mhz */    0x0c80, /* 4 Mhz */    0x98ee, /* 4.906 Mhz */    0xd5b4, /* 4.9152 Mhz */    0x0a00, /* 5 Mhz */    0x4e27, /* 5.12 Mhz */    0x1902, /* 6 Mhz */    0xec1c, /* 6.144 Mhz */    0x1b23, /* 7.3728 Mhz */    0x0640, /* 8 Mhz */    0xb11c /* 8.192 Mhz */};static uint32_t ssys_read(void *opaque, target_phys_addr_t offset){    ssys_state *s = (ssys_state *)opaque;    offset -= s->base;    switch (offset) {    case 0x000: /* DID0 */        return s->board->did0;    case 0x004: /* DID1 */        return s->board->did1;    case 0x008: /* DC0 */        return s->board->dc0;    case 0x010: /* DC1 */        return s->board->dc1;    case 0x014: /* DC2 */        return s->board->dc2;    case 0x018: /* DC3 */        return s->board->dc3;    case 0x01c: /* DC4 */        return s->board->dc4;    case 0x030: /* PBORCTL */        return s->pborctl;    case 0x034: /* LDOPCTL */        return s->ldopctl;    case 0x040: /* SRCR0 */        return 0;    case 0x044: /* SRCR1 */        return 0;

⌨️ 快捷键说明

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