[BACK]Return to gpio7seg.c CVS log [TXT][DIR] Up to [local] / funnyos / arch / sam7s64 / dev

Annotation of funnyos/arch/sam7s64/dev/gpio7seg.c, Revision 1.1

1.1     ! nbrk        1: /*
        !             2:  * $Id$
        !             3:  */
        !             4: #include <sys/types.h>
        !             5: #include <sys/device.h>
        !             6: #include <sys/gpio.h>
        !             7: #include <sys/devctl.h>
        !             8:
        !             9: #include <arch/sam7s64/dev/gpio7segvar.h>
        !            10: #include <libkern/printf.h>
        !            11: /*
        !            12:  * Driver for 7-segment LED indicator.
        !            13:  *
        !            14:  * Well known way to describe segments is:
        !            15:  *   _a_
        !            16:  * f|   |b
        !            17:  *  |_g_|
        !            18:  * e|   |c
        !            19:  *  |_d_|
        !            20:  *
        !            21:  * XXX: There is no way to associate pin to a segment but to hardcode that.
        !            22:  * TODO: Maybe this all gpio stuff should go into MI part.
        !            23:  */
        !            24:
        !            25: /* hardcode segments to lines (PA{23, 26-31} in my case) */
        !            26: #define GPIO7SEG_PINA  26
        !            27: #define GPIO7SEG_PINB  28
        !            28: #define GPIO7SEG_PINC  31
        !            29: #define GPIO7SEG_PIND  29
        !            30: #define GPIO7SEG_PINE  30
        !            31: #define GPIO7SEG_PINF  27
        !            32: #define GPIO7SEG_PING  23
        !            33:
        !            34:
        !            35: int    gpio7seg_attach(struct device *, uint32_t, uint8_t);
        !            36: int    gpio7seg_devctl(struct device *self, uint32_t ctlcmd, void *ctldata);
        !            37: uint8_t        gpio7seg_digit(uint8_t digit);
        !            38: void   gpio7seg_update(struct gpio7seg_dd *ddp);
        !            39:
        !            40:
        !            41: struct driver gpio7seg_dr = {
        !            42:        sizeof(struct gpio7seg_dd),
        !            43:        gpio7seg_attach,
        !            44:        NULL,
        !            45:        NULL
        !            46: };
        !            47:
        !            48:
        !            49: int
        !            50: gpio7seg_attach(struct device *self, uint32_t loc, uint8_t flags)
        !            51: {
        !            52:        struct gpio7seg_dd *ddp = self->dv_devdata;
        !            53:        uint8_t i;
        !            54:
        !            55:        /* grab parent's gpio_controller */
        !            56:        ddp->gs_gcp = self->dv_parent->dv_aux;
        !            57:
        !            58:        /*
        !            59:         * Configure pins.
        !            60:         */
        !            61:        /* assign hardcoded pin numbers */
        !            62:        ddp->gs_pins[0].gp_pinno = GPIO7SEG_PINA;
        !            63:        ddp->gs_pins[1].gp_pinno = GPIO7SEG_PINB;
        !            64:        ddp->gs_pins[2].gp_pinno = GPIO7SEG_PINC;
        !            65:        ddp->gs_pins[3].gp_pinno = GPIO7SEG_PIND;
        !            66:        ddp->gs_pins[4].gp_pinno = GPIO7SEG_PINE;
        !            67:        ddp->gs_pins[5].gp_pinno = GPIO7SEG_PINF;
        !            68:        ddp->gs_pins[6].gp_pinno = GPIO7SEG_PING;
        !            69:
        !            70:        /* set all lines to output, value 1 means 'off' */
        !            71:        for(i = 0; i < 7; i++) {
        !            72:                ddp->gs_pins[i].gp_pio = 1;
        !            73:                ddp->gs_pins[i].gp_flags = GPIO_PIN_OUTPUT;
        !            74:                ddp->gs_pins[i].gp_value = 1; /* OFF by default */
        !            75:
        !            76:                /* talk to gpio controller */
        !            77:                ddp->gs_gcp->gc_pinset(ddp->gs_gcp->gc_selfdd, ddp->gs_pins[i]);
        !            78:        }
        !            79:
        !            80:        printf("p64 onboard 7-segment LED\n");
        !            81:
        !            82:
        !            83:        devctl_register(self, gpio7seg_devctl);
        !            84:
        !            85:        return(0);
        !            86: }
        !            87:
        !            88:
        !            89: int
        !            90: gpio7seg_devctl(struct device *self, uint32_t ctlcmd, void *ctldata)
        !            91: {
        !            92:        struct gpio7seg_dd *ddp;
        !            93:        uint8_t digit;
        !            94:
        !            95:        ddp = self->dv_devdata;
        !            96:
        !            97:        switch(ctlcmd) {
        !            98:                case(DCGPIO7SEG_OFF):
        !            99:                        /*
        !           100:                         * Switch all segments off.
        !           101:                         */
        !           102:                        ddp->gs_mask &= ~(1 << 7);
        !           103:                        gpio7seg_update(ddp);
        !           104:
        !           105:                        break;
        !           106:
        !           107:                case(DCGPIO7SEG_ON):
        !           108:                        /*
        !           109:                         * Switch all segments on.
        !           110:                         */
        !           111:                        ddp->gs_mask |= 1 << 7;
        !           112:                        gpio7seg_update(ddp);
        !           113:
        !           114:                        break;
        !           115:
        !           116:                case(DCGPIO7SEG_SETMASK):
        !           117:                        /*
        !           118:                         * Manually set indicator mask and update ourselves.
        !           119:                         */
        !           120:                        ddp->gs_mask = *(uint8_t *)ctldata;
        !           121:                        gpio7seg_update(ddp);
        !           122:
        !           123:                        break;
        !           124:
        !           125:                case(DCGPIO7SEG_SETDIGIT):
        !           126:                        /*
        !           127:                         * Draw given digit. Valid digits are 0..15 (where 10 will be 'A').
        !           128:                         */
        !           129:                        digit = *(uint8_t *)ctldata;
        !           130:
        !           131:                        if (digit > 15)
        !           132:                                /* overflow */
        !           133:                                return(-1);
        !           134:
        !           135:                        /* modify mask to determine which segments represent given digit */
        !           136:                        ddp->gs_mask = gpio7seg_digit(digit);
        !           137:
        !           138:                        /* update */
        !           139:                        gpio7seg_update(ddp);
        !           140:
        !           141:                default:
        !           142:                        break;
        !           143:        }
        !           144:
        !           145:        return(0);
        !           146: }
        !           147:
        !           148:
        !           149: uint8_t
        !           150: gpio7seg_digit(uint8_t digit)
        !           151: {
        !           152:        /*
        !           153:         * Return bitmask representing given digit.
        !           154:         * Nothing special: this is well-know way.
        !           155:         */
        !           156:        switch (digit) {
        !           157:                case 0:
        !           158:                        return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E | GPIO7SEG_F);
        !           159:                case 1:
        !           160:                        return(GPIO7SEG_B | GPIO7SEG_C);
        !           161:                case 2:
        !           162:                        return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_G | GPIO7SEG_E | GPIO7SEG_D);
        !           163:                case 3:
        !           164:                        return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_G | GPIO7SEG_C | GPIO7SEG_D);
        !           165:                case 4:
        !           166:                        return(GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_B | GPIO7SEG_C);
        !           167:                case 5:
        !           168:                        return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_C | GPIO7SEG_D);
        !           169:                case 6:
        !           170:                        return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E);
        !           171:                case 7:
        !           172:                        return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C);
        !           173:                case 8:
        !           174:                        return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E | GPIO7SEG_F | GPIO7SEG_G);
        !           175:                case 9:
        !           176:                        return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_B | GPIO7SEG_C);
        !           177:                case 10:
        !           178:                        /* 'A' */
        !           179:                        return(GPIO7SEG_E | GPIO7SEG_F | GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_G);
        !           180:                case 11:
        !           181:                        /* 'b' */
        !           182:                        return(GPIO7SEG_F | GPIO7SEG_E | GPIO7SEG_D | GPIO7SEG_C | GPIO7SEG_G);
        !           183:                case 12:
        !           184:                        /* 'C' */
        !           185:                        return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_E | GPIO7SEG_D);
        !           186:                case 13:
        !           187:                        /* 'd' */
        !           188:                        return(GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E | GPIO7SEG_G);
        !           189:                case 14:
        !           190:                        /* 'E' */
        !           191:                        return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_E | GPIO7SEG_D);
        !           192:                case 15:
        !           193:                        /* 'F' */
        !           194:                        return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_E);
        !           195:        }
        !           196:
        !           197:        /* XXX else return 'OFF' mask */
        !           198:        return(GPIO7SEG_OFF);
        !           199: }
        !           200:
        !           201:
        !           202: void
        !           203: gpio7seg_update(struct gpio7seg_dd *ddp)
        !           204: {
        !           205:        /*
        !           206:         * Update gpio controller based on our mask.
        !           207:         */
        !           208:        uint8_t i;
        !           209:
        !           210:        /* see if GPIO7SEG_OFF is given */
        !           211:        if (ddp->gs_mask & GPIO7SEG_OFF) {
        !           212:                /* TODO */
        !           213:                return;
        !           214:        }
        !           215:
        !           216:        for(i = 0; i < 7; i++) {
        !           217:                if (ddp->gs_mask & (1 << i)) {
        !           218:                        /* corresponding bit is set */
        !           219:                        ddp->gs_pins[i].gp_value = 0;
        !           220:                } else ddp->gs_pins[i].gp_value = 1;
        !           221:
        !           222:        /* kick pio controller */
        !           223:        ddp->gs_gcp->gc_pinset(ddp->gs_gcp->gc_selfdd, ddp->gs_pins[i]);
        !           224:        }
        !           225:
        !           226: }
        !           227:

CVSweb