pio.c

来自「《嵌入式固件开发》一书的源码」· C语言 代码 · 共 272 行

C
272
字号
/* pio.c:    Support the basic ability to configure and set/clear parallel IO pins.    General notice:    This code is part of a boot-monitor package developed as a generic base    platform for embedded system designs.  As such, it is likely to be    distributed to various projects beyond the control of the original    author.  Please notify the author of any enhancements made or bugs found    so that all may benefit from the changes.  In addition, notification back    to the author will allow the new user to pick up changes that may have    been made by other users after this version of the code was distributed.    Author: Ed Sutter    email:  esutter@lucent.com      (home: lesutter@worldnet.att.net)    phone:  908-582-2351            (home: 908-889-5161)*/#include "config.h"#include "cpuio.h"#include "ctype.h"#include "genlib.h"#include "stddefs.h"#define PIO_IN  1#define PIO_OUT 2#define PIO_GP  3#define PIO_DED 4/* Pio():    Display/Configure/Modify 68307 PIO pins.    Syntax    pio [options] {A|B} {bit #} [0|1]      For port A, bit # range = 0-7      For port B, bit # range = 0-15      Options:        -i  configure as in        -o  configure as out        -g  configure as gpio        -d  configure as dedicated*/#if INCLUDE_PIOchar *PioHelp[] = {    "Programmable IO Interface",    "-[iogdw] {A|B} {bit #} [0|1]",    " -i   input",    " -o   output",    " -g   gpio",    " -d   dedicated",    " -w   waitonbit",    0,};void pioshow(void);intPio(int argc,char *argv[]){    int opt, bitnum, val, config, portAorB, waitonbit;    if (argc == 1) {        pioshow();        return(0);    }    config = 0;    waitonbit = 0;    while((opt=getopt(argc,argv,"iogdw")) != -1) {        switch(opt) {        case 'o':            config = PIO_OUT;            break;        case 'g':            config = PIO_GP;            break;        case 'd':            config = PIO_DED;            break;        case 'i':            config = PIO_IN;            break;        case 'w':            waitonbit = 1;            break;        default:            return(0);        }    }    if (argc < (optind+2))        return(-1);    portAorB = tolower(argv[optind][0]);    bitnum = (int)strtol(argv[optind+1],(char **)0,0);    if (portAorB == 'a') {        if (bitnum > 15)  {            printf("Bit # out of range\n");            return(0);        }    }    else if (portAorB == 'b') {        if (bitnum > 11) {            printf("Bit # out of range\n");            return(0);        }    }    else        return(-1);    if (waitonbit) {        if (argc != (optind+3)) {            printf("-w requires port, bit and value\n");            return(-1);        }        val = argv[optind+2][0] & 1;        if (portAorB == 'a') {            while(1) {                if ((val == 1) &&                    (*(ushort *)PADAT&(ushort)~(0x01<<bitnum)))                    break;                else if ((val == 0) &&                    !(*(ushort *)PADAT&(ushort)~(0x01<<bitnum)))                    break;            }        }        else {            while(1) {                if ((val == 1) &&                    (*(ushort *)PBDAT&(ushort)~(0x0001<<bitnum)))                    break;                else if ((val == 0) &&                    !(*(ushort *)PBDAT&(ushort)~(0x0001<<bitnum)))                    break;            }        }        return(0);    }    /* If config, then set up direction or control */    if (config) {        if (argc != (optind+2))            return(-1);        if (portAorB == 'a') {            switch(config) {            case PIO_OUT:                *(ushort *)PADDR |= (ushort)(0x01 << bitnum);                break;            case PIO_IN:                *(ushort *)PADDR &= (ushort)~(0x01 << bitnum);                break;            case PIO_GP:                *(ushort *)PACNT &= (ushort)~(0x01 << bitnum);                break;            case PIO_DED:                *(ushort *)PACNT |= (ushort)(0x01 << bitnum);                break;            }        }        else {            switch(config) {            case PIO_OUT:                *(ushort *)PBDDR |= (ushort)(0x0001 << bitnum);                break;            case PIO_IN:                *(ushort *)PBDDR &= (ushort)~(0x0001 << bitnum);                break;            case PIO_GP:                *(ushort *)PBCNT &= (ushort)~(0x0001 << bitnum);                break;            case PIO_DED:                *(ushort *)PBCNT |= (ushort)(0x0001 << bitnum);                break;            }        }        return(0);    }    /* If config is not set, then it must be a read or write request... */    /* If third arg is present, then write; else read. */    if (argc == optind+3) {        val = argv[optind+2][0] & 1;        if (portAorB == 'a') {            if (val)                *(ushort *)PADAT |= (ushort)(0x01 << bitnum);                else                *(ushort *)PADAT &= (ushort)~(0x01 << bitnum);        }        else {            if (val)                *(ushort *)PBDAT |= (ushort)(0x0001 << bitnum);                else                *(ushort *)PBDAT &= (ushort)~(0x0001 << bitnum);        }    }    else {          /* Read a pio bit */        if (portAorB == 'a') {            printf("PA%d = %d\n",bitnum,                (*(ushort *)PADAT & (ushort)(0x01 << bitnum)) ? 1:0);        }        else {            printf("PB%d = %d\n",bitnum,                (*(ushort *)PBDAT & (ushort)(0x0001 << bitnum)) ? 1:0);        }    }    return(0);}voidpioshow(void){    int i;    ushort  mask;    printf("PORTA bits 0-15...\n");    printf("PACNT: 0x%04x, PADDR: 0x%04x, PADAT: 0x%04x\n",        *(ushort*)PACNT, *(ushort *)PADDR, *(ushort *)PADAT);    for (mask=1,i=0;i<16;i++,mask <<= 1) {        printf("  PA%02d: %s %s %d\n",i,            (*(ushort *)PACNT & mask) ? "dedicated" : "gpio",            (*(ushort *)PADDR & mask) ? "output" : "input",            (*(ushort *)PADAT & mask) ? 1 : 0);    }    printf("\nPORTB bits 0-11...\n");    printf("PBCNT: 0x%04x, PBDDR: 0x%04x, PBDAT: 0x%04x\n",        *(ushort*)PBCNT, *(ushort *)PBDDR, *(ushort *)PBDAT);    for (mask=1,i=0;i<12;i++,mask <<= 1) {        printf("  PB%02d: %s %s %d\n",i,            (*(ushort *)PBCNT & mask) ? "dedicated" : "gpio",            (*(ushort *)PBDDR & mask) ? "output" : "input",            (*(ushort *)PBDAT & mask) ? 1 : 0);    }}#endifintpioget(char port,int bitnum){    port = tolower(port);    if (port == 'a')        return((*(ushort *)PADAT & (ushort)(0x01 << bitnum)) ? 1:0);    else if (port == 'b')        return((*(ushort *)PBDAT & (ushort)(0x0001 << bitnum)) ? 1:0);    else        printf("pioget port error\n");    return(-1);}voidpioclr(char port,int bitnum){    port = tolower(port);    if (port == 'a')        *(ushort *)PADAT &= (ushort)~(0x01 << bitnum);    else if (port == 'b')        *(ushort *)PBDAT &= (ushort)~(0x0001 << bitnum);    else        printf("pioclr port error\n");}voidpioset(char port,int bitnum){    port = tolower(port);    if (port == 'a')        *(ushort *)PADAT |= (ushort)(0x01 << bitnum);    else if (port == 'b')        *(ushort *)PBDAT |= (ushort)(0x0001 << bitnum);    else        printf("pioset port error\n");}

⌨️ 快捷键说明

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