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

📄 tsc210x.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
    case 0x07:	/* AUX1 */    case 0x08:	/* AUX2 */    case 0x09:	/* TEMP1 */    case 0x0a:	/* TEMP2 */        return;    default:#ifdef TSC_VERBOSE        fprintf(stderr, "tsc2102_data_register_write: "                        "no such register: 0x%02x\n", reg);#endif    }}static void tsc2102_control_register_write(                struct tsc210x_state_s *s, int reg, uint16_t value){    switch (reg) {    case 0x00:	/* TSC ADC */        s->host_mode = value >> 15;        s->enabled = !(value & 0x4000);        if (s->busy && !s->enabled)            qemu_del_timer(s->timer);        s->busy &= s->enabled;        s->nextfunction = (value >> 10) & 0xf;        s->nextprecision = (value >> 8) & 3;        s->filter = value & 0xff;        return;    case 0x01:	/* Status */        s->pin_func = value >> 14;        return;    case 0x03:	/* Reference */        s->ref = value & 0x1f;        return;    case 0x04:	/* Reset */        if (value == 0xbb00) {            if (s->busy)                qemu_del_timer(s->timer);            tsc210x_reset(s);#ifdef TSC_VERBOSE        } else {            fprintf(stderr, "tsc2102_control_register_write: "                            "wrong value written into RESET\n");#endif        }        return;    case 0x05:	/* Configuration */        s->timing = value & 0x3f;#ifdef TSC_VERBOSE        if (value & ~0x3f)            fprintf(stderr, "tsc2102_control_register_write: "                            "wrong value written into CONFIG\n");#endif        return;    default:#ifdef TSC_VERBOSE        fprintf(stderr, "tsc2102_control_register_write: "                        "no such register: 0x%02x\n", reg);#endif    }}static void tsc2102_audio_register_write(                struct tsc210x_state_s *s, int reg, uint16_t value){    switch (reg) {    case 0x00:	/* Audio Control 1 */        s->audio_ctrl1 = value & 0x0f3f;#ifdef TSC_VERBOSE        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into Audio 1\n");#endif        tsc2102_audio_rate_update(s);        if (s->audio)            tsc2102_audio_output_update(s);        return;    case 0x01:#ifdef TSC_VERBOSE        if (value != 0xff00)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into reg 0x01\n");#endif        return;    case 0x02:	/* DAC Volume Control */        s->volume = value;        s->volume_change = qemu_get_clock(vm_clock);        return;    case 0x03:#ifdef TSC_VERBOSE        if (value != 0x8b00)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into reg 0x03\n");#endif        return;    case 0x04:	/* Audio Control 2 */        s->audio_ctrl2 = value & 0xf7f2;#ifdef TSC_VERBOSE        if (value & ~0xf7fd)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into Audio 2\n");#endif        return;    case 0x05:	/* Stereo DAC Power Control */        if ((value & ~s->dac_power) & (1 << 10))            s->powerdown = qemu_get_clock(vm_clock);        s->dac_power = value & 0x9543;#ifdef TSC_VERBOSE        if ((value & ~0x9543) != 0x2aa0)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into Power\n");#endif        tsc2102_audio_rate_update(s);        if (s->audio)            tsc2102_audio_output_update(s);        return;    case 0x06:	/* Audio Control 3 */        s->audio_ctrl3 &= 0x00c0;        s->audio_ctrl3 |= value & 0xf800;#ifdef TSC_VERBOSE        if (value & ~0xf8c7)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into Audio 3\n");#endif        if (s->audio)            tsc2102_audio_output_update(s);        return;    case 0x07:	/* LCH_BASS_BOOST_N0 */    case 0x08:	/* LCH_BASS_BOOST_N1 */    case 0x09:	/* LCH_BASS_BOOST_N2 */    case 0x0a:	/* LCH_BASS_BOOST_N3 */    case 0x0b:	/* LCH_BASS_BOOST_N4 */    case 0x0c:	/* LCH_BASS_BOOST_N5 */    case 0x0d:	/* LCH_BASS_BOOST_D1 */    case 0x0e:	/* LCH_BASS_BOOST_D2 */    case 0x0f:	/* LCH_BASS_BOOST_D4 */    case 0x10:	/* LCH_BASS_BOOST_D5 */    case 0x11:	/* RCH_BASS_BOOST_N0 */    case 0x12:	/* RCH_BASS_BOOST_N1 */    case 0x13:	/* RCH_BASS_BOOST_N2 */    case 0x14:	/* RCH_BASS_BOOST_N3 */    case 0x15:	/* RCH_BASS_BOOST_N4 */    case 0x16:	/* RCH_BASS_BOOST_N5 */    case 0x17:	/* RCH_BASS_BOOST_D1 */    case 0x18:	/* RCH_BASS_BOOST_D2 */    case 0x19:	/* RCH_BASS_BOOST_D4 */    case 0x1a:	/* RCH_BASS_BOOST_D5 */        s->filter_data[reg - 0x07] = value;        return;    case 0x1b:	/* PLL Programmability 1 */        s->pll[0] = value & 0xfffc;#ifdef TSC_VERBOSE        if (value & ~0xfffc)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into PLL 1\n");#endif        return;    case 0x1c:	/* PLL Programmability 2 */        s->pll[1] = value & 0xfffc;#ifdef TSC_VERBOSE        if (value & ~0xfffc)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into PLL 2\n");#endif        return;    case 0x1d:	/* Audio Control 4 */        s->softstep = !(value & 0x4000);#ifdef TSC_VERBOSE        if (value & ~0x4000)            fprintf(stderr, "tsc2102_audio_register_write: "                            "wrong value written into Audio 4\n");#endif        return;    default:#ifdef TSC_VERBOSE        fprintf(stderr, "tsc2102_audio_register_write: "                        "no such register: 0x%02x\n", reg);#endif    }}/* This handles most of the chip logic.  */static void tsc210x_pin_update(struct tsc210x_state_s *s){    int64_t expires;    int pin_state;    switch (s->pin_func) {    case 0:        pin_state = s->pressure;        break;    case 1:        pin_state = !!s->dav;        break;    case 2:    default:        pin_state = s->pressure && !s->dav;    }    if (!s->enabled)        pin_state = 0;    if (pin_state != s->irq) {        s->irq = pin_state;        qemu_set_irq(s->pint, !s->irq);    }    switch (s->nextfunction) {    case TSC_MODE_XY_SCAN:    case TSC_MODE_XYZ_SCAN:        if (!s->pressure)            return;        break;    case TSC_MODE_X:    case TSC_MODE_Y:    case TSC_MODE_Z:        if (!s->pressure)            return;        /* Fall through */    case TSC_MODE_BAT1:    case TSC_MODE_BAT2:    case TSC_MODE_AUX:    case TSC_MODE_TEMP1:    case TSC_MODE_TEMP2:        if (s->dav)            s->enabled = 0;        break;    case TSC_MODE_AUX_SCAN:    case TSC_MODE_PORT_SCAN:        break;    case TSC_MODE_NO_SCAN:    case TSC_MODE_XX_DRV:    case TSC_MODE_YY_DRV:    case TSC_MODE_YX_DRV:    default:        return;    }    if (!s->enabled || s->busy)        return;    s->busy = 1;    s->precision = s->nextprecision;    s->function = s->nextfunction;    expires = qemu_get_clock(vm_clock) + (ticks_per_sec >> 10);    qemu_mod_timer(s->timer, expires);}static uint16_t tsc210x_read(struct tsc210x_state_s *s){    uint16_t ret = 0x0000;    if (!s->command)        fprintf(stderr, "tsc210x_read: SPI underrun!\n");    switch (s->page) {    case TSC_DATA_REGISTERS_PAGE:        ret = tsc2102_data_register_read(s, s->offset);        break;    case TSC_CONTROL_REGISTERS_PAGE:        ret = tsc2102_control_register_read(s, s->offset);        break;    case TSC_AUDIO_REGISTERS_PAGE:        ret = tsc2102_audio_register_read(s, s->offset);        break;    default:        cpu_abort(cpu_single_env, "tsc210x_read: wrong memory page\n");    }    tsc210x_pin_update(s);    /* Allow sequential reads.  */    s->offset ++;    s->state = 0;    return ret;}static void tsc210x_write(struct tsc210x_state_s *s, uint16_t value){    /*     * This is a two-state state machine for reading     * command and data every second time.     */    if (!s->state) {        s->command = value >> 15;        s->page = (value >> 11) & 0x0f;        s->offset = (value >> 5) & 0x3f;        s->state = 1;    } else {        if (s->command)            fprintf(stderr, "tsc210x_write: SPI overrun!\n");        else            switch (s->page) {            case TSC_DATA_REGISTERS_PAGE:                tsc2102_data_register_write(s, s->offset, value);                break;            case TSC_CONTROL_REGISTERS_PAGE:                tsc2102_control_register_write(s, s->offset, value);                break;            case TSC_AUDIO_REGISTERS_PAGE:                tsc2102_audio_register_write(s, s->offset, value);                break;            default:                cpu_abort(cpu_single_env,                                "tsc210x_write: wrong memory page\n");            }        tsc210x_pin_update(s);        s->state = 0;    }}static void tsc210x_timer_tick(void *opaque){    struct tsc210x_state_s *s = opaque;    /* Timer ticked -- a set of conversions has been finished.  */    if (!s->busy)        return;    s->busy = 0;    s->dav |= mode_regs[s->function];    tsc210x_pin_update(s);}static void tsc210x_touchscreen_event(void *opaque,                int x, int y, int z, int buttons_state){    struct tsc210x_state_s *s = opaque;    int p = s->pressure;    if (buttons_state) {        s->x = x;        s->y = y;    }    s->pressure = !!buttons_state;    /*     * Note: We would get better responsiveness in the guest by     * signaling TS events immediately, but for now we simulate     * the first conversion delay for sake of correctness.     */    if (p != s->pressure)        tsc210x_pin_update(s);}static void tsc210x_i2s_swallow(struct tsc210x_state_s *s){    if (s->dac_voice[0])        tsc210x_out_flush(s, s->codec.out.len);    else        s->codec.out.len = 0;}static void tsc210x_i2s_set_rate(struct tsc210x_state_s *s, int in, int out){    s->i2s_tx_rate = out;    s->i2s_rx_rate = in;}static void tsc210x_save(QEMUFile *f, void *opaque){    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;    int64_t now = qemu_get_clock(vm_clock);    int i;    qemu_put_be16(f, s->x);    qemu_put_be16(f, s->y);    qemu_put_byte(f, s->pressure);    qemu_put_byte(f, s->state);    qemu_put_byte(f, s->page);    qemu_put_byte(f, s->offset);    qemu_put_byte(f, s->command);    qemu_put_byte(f, s->irq);    qemu_put_be16s(f, &s->dav);    qemu_put_timer(f, s->timer);    qemu_put_byte(f, s->enabled);    qemu_put_byte(f, s->host_mode);    qemu_put_byte(f, s->function);    qemu_put_byte(f, s->nextfunction);    qemu_put_byte(f, s->precision);    qemu_put_byte(f, s->nextprecision);    qemu_put_byte(f, s->filter);    qemu_put_byte(f, s->pin_func);    qemu_put_byte(f, s->ref);    qemu_put_byte(f, s->timing);    qemu_put_be32(f, s->noise);    qemu_put_be16s(f, &s->audio_ctrl1);    qemu_put_be16s(f, &s->audio_ctrl2);    qemu_put_be16s(f, &s->audio_ctrl3);    qemu_put_be16s(f, &s->pll[0]);    qemu_put_be16s(f, &s->pll[1]);    qemu_put_be16s(f, &s->volume);    qemu_put_be64(f, (uint64_t) (s->volume_change - now));    qemu_put_be64(f, (uint64_t) (s->powerdown - now));    qemu_put_byte(f, s->softstep);    qemu_put_be16s(f, &s->dac_power);    for (i = 0; i < 0x14; i ++)        qemu_put_be16s(f, &s->filter_data[i]);}static int tsc210x_load(QEMUFile *f, void *opaque, int version_id){    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;    int64_t now = qemu_get_clock(vm_clock);    int i;    s->x = qemu_get_be16(f);    s->y = qemu_get_be16(f);    s->pressure = qemu_get_byte(f);    s->state = qemu_get_byte(f);    s->page = qemu_get_byte(f);    s->offset = qemu_get_byte(f);    s->command = qemu_get_byte(f);    s->irq = qemu_get_byte(f);    qemu_get_be16s(f, &s->dav);    qemu_get_timer(f, s->timer);    s->enabled = qemu_get_byte(f);    s->host_mode = qemu_get_byte(f);    s->function = qemu_get_byte(f);    s->nextfunction = qemu_get_byte(f);    s->precision = qemu_get_byte(f);    s->nextprecision = qemu_get_byte(f);    s->filter = qemu_get_byte(f);    s->pin_func = qemu_get_byte(f);    s->ref = qemu_get_byte(f);    s->timing = qemu_get_byte(f);    s->noise = qemu_get_be32(f);    qemu_get_be16s(f, &s->audio_ctrl1);    qemu_get_be16s(f, &s->audio_ctrl2);    qemu_get_be16s(f, &s->audio_ctrl3);    qemu_get_be16s(f, &s->pll[0]);    qemu_get_be16s(f, &s->pll[1]);    qemu_get_be16s(f, &s->volume);    s->volume_change = (int64_t) qemu_get_be64(f) + now;    s->powerdown = (int64_t) qemu_get_be64(f) + now;    s->softstep = qemu_get_byte(f);    qemu_get_be16s(f, &s->dac_power);    for (i = 0; i < 0x14; i ++)        qemu_get_be16s(f, &s->filter_data[i]);    s->busy = qemu_timer_pending(s->timer);    qemu_set_irq(s->pint, !s->irq);    return 0;}static int tsc2102_iid = 0;struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio){    struct tsc210x_state_s *s;    s = (struct tsc210x_state_s *)            qemu_mallocz(sizeof(struct tsc210x_state_s));    memset(s, 0, sizeof(struct tsc210x_state_s));    s->x = 160;    s->y = 160;    s->pressure = 0;    s->precision = s->nextprecision = 0;    s->timer = qemu_new_timer(vm_clock, tsc210x_timer_tick, s);    s->pint = pint;    s->name = "tsc2102";    s->audio = audio;    s->chip.opaque = s;    s->chip.send = (void *) tsc210x_write;    s->chip.receive = (void *) tsc210x_read;    s->codec.opaque = s;    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;    s->codec.in.fifo = s->in_fifo;    s->codec.out.fifo = s->out_fifo;    tsc210x_reset(s);    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,                    "QEMU TSC2102-driven Touchscreen");    if (s->audio)        AUD_register_card(s->audio, s->name, &s->card);    qemu_register_reset((void *) tsc210x_reset, s);    register_savevm(s->name, tsc2102_iid ++, 0,                    tsc210x_save, tsc210x_load, s);    return &s->chip;}struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip){    struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;    return &s->codec;}

⌨️ 快捷键说明

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