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

📄 max7310.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
字号:
/* * MAX7310 8-port GPIO expansion chip. * * Copyright (c) 2006 Openedhand Ltd. * Written by Andrzej Zaborowski <balrog@zabor.org> * * This file is licensed under GNU GPL. */#include "hw.h"#include "i2c.h"struct max7310_s {    i2c_slave i2c;    int i2c_command_byte;    int len;    uint8_t level;    uint8_t direction;    uint8_t polarity;    uint8_t status;    uint8_t command;    qemu_irq handler[8];    qemu_irq *gpio_in;};void max7310_reset(i2c_slave *i2c){    struct max7310_s *s = (struct max7310_s *) i2c;    s->level &= s->direction;    s->direction = 0xff;    s->polarity = 0xf0;    s->status = 0x01;    s->command = 0x00;}static int max7310_rx(i2c_slave *i2c){    struct max7310_s *s = (struct max7310_s *) i2c;    switch (s->command) {    case 0x00:	/* Input port */        return s->level ^ s->polarity;        break;    case 0x01:	/* Output port */        return s->level & ~s->direction;        break;    case 0x02:	/* Polarity inversion */        return s->polarity;    case 0x03:	/* Configuration */        return s->direction;    case 0x04:	/* Timeout */        return s->status;        break;    case 0xff:	/* Reserved */        return 0xff;    default:#ifdef VERBOSE        printf("%s: unknown register %02x\n", __FUNCTION__, s->command);#endif        break;    }    return 0xff;}static int max7310_tx(i2c_slave *i2c, uint8_t data){    struct max7310_s *s = (struct max7310_s *) i2c;    uint8_t diff;    int line;    if (s->len ++ > 1) {#ifdef VERBOSE        printf("%s: message too long (%i bytes)\n", __FUNCTION__, s->len);#endif        return 1;    }    if (s->i2c_command_byte) {        s->command = data;        s->i2c_command_byte = 0;        return 0;    }    switch (s->command) {    case 0x01:	/* Output port */        for (diff = (data ^ s->level) & ~s->direction; diff;                        diff &= ~(1 << line)) {            line = ffs(diff) - 1;            if (s->handler[line])                qemu_set_irq(s->handler[line], (data >> line) & 1);        }        s->level = (s->level & s->direction) | (data & ~s->direction);        break;    case 0x02:	/* Polarity inversion */        s->polarity = data;        break;    case 0x03:	/* Configuration */        s->level &= ~(s->direction ^ data);        s->direction = data;        break;    case 0x04:	/* Timeout */        s->status = data;        break;    case 0x00:	/* Input port - ignore writes */	break;    default:#ifdef VERBOSE        printf("%s: unknown register %02x\n", __FUNCTION__, s->command);#endif        return 1;    }    return 0;}static void max7310_event(i2c_slave *i2c, enum i2c_event event){    struct max7310_s *s = (struct max7310_s *) i2c;    s->len = 0;    switch (event) {    case I2C_START_SEND:        s->i2c_command_byte = 1;        break;    case I2C_FINISH:        if (s->len == 1)#ifdef VERBOSE            printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len);#endif        break;    default:        break;    }}static void max7310_save(QEMUFile *f, void *opaque){    struct max7310_s *s = (struct max7310_s *) opaque;    qemu_put_be32(f, s->i2c_command_byte);    qemu_put_be32(f, s->len);    qemu_put_8s(f, &s->level);    qemu_put_8s(f, &s->direction);    qemu_put_8s(f, &s->polarity);    qemu_put_8s(f, &s->status);    qemu_put_8s(f, &s->command);    i2c_slave_save(f, &s->i2c);}static int max7310_load(QEMUFile *f, void *opaque, int version_id){    struct max7310_s *s = (struct max7310_s *) opaque;    s->i2c_command_byte = qemu_get_be32(f);    s->len = qemu_get_be32(f);    qemu_get_8s(f, &s->level);    qemu_get_8s(f, &s->direction);    qemu_get_8s(f, &s->polarity);    qemu_get_8s(f, &s->status);    qemu_get_8s(f, &s->command);    i2c_slave_load(f, &s->i2c);    return 0;}static int max7310_iid = 0;static void max7310_gpio_set(void *opaque, int line, int level){    struct max7310_s *s = (struct max7310_s *) opaque;    if (line >= sizeof(s->handler) / sizeof(*s->handler) || line  < 0)        hw_error("bad GPIO line");    if (level)        s->level |= s->direction & (1 << line);    else        s->level &= ~(s->direction & (1 << line));}/* MAX7310 is SMBus-compatible (can be used with only SMBus protocols), * but also accepts sequences that are not SMBus so return an I2C device.  */struct i2c_slave *max7310_init(i2c_bus *bus){    struct max7310_s *s = (struct max7310_s *)            i2c_slave_init(bus, 0, sizeof(struct max7310_s));    s->i2c.event = max7310_event;    s->i2c.recv = max7310_rx;    s->i2c.send = max7310_tx;    s->gpio_in = qemu_allocate_irqs(max7310_gpio_set, s,                    sizeof(s->handler) / sizeof(*s->handler));    max7310_reset(&s->i2c);    register_savevm("max7310", max7310_iid ++, 0,                    max7310_save, max7310_load, s);    return &s->i2c;}qemu_irq *max7310_gpio_in_get(i2c_slave *i2c){    struct max7310_s *s = (struct max7310_s *) i2c;    return s->gpio_in;}void max7310_gpio_out_set(i2c_slave *i2c, int line, qemu_irq handler){    struct max7310_s *s = (struct max7310_s *) i2c;    if (line >= sizeof(s->handler) / sizeof(*s->handler) || line  < 0)        hw_error("bad GPIO line");    s->handler[line] = handler;}

⌨️ 快捷键说明

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