URI friendly Pmod Interface Library

Dependents:   MBD2PMD_WebServer ARD2PMD_WebServer

PmodInterface.cpp

Committer:
gsteiert
Date:
2014-05-10
Revision:
0:828bfd94972b

File content as of revision 0:828bfd94972b:

/* Pmod Interface Library
 *
 */

#include "mbed.h"
#include "PmodInterface.h"

PmodInterface::PmodInterface()
{
}

PmodInterface::~PmodInterface()
{
}

// Initialize PmodInterface
void PmodInterface::init(DigitalInOut **dio, I2C* i2c, MAX14661* mux, const int* mux_a, const int* mux_p)
{
    _pmd = dio;  // save pointer to digital IO
    _i2c = i2c;  // save pointer to I2C interface
    _mux = mux;  // save pointer to multiplexer
    _mux_a = mux_a;  // save pointer to mux micro LUT
    _mux_p = mux_p;  // save pointer to mux pmod LUT
}

/* Digital I/O
 * /d              read all
 * /d/[pin]        read from pin
 * /d/[pin]/[cfg]  write configuration to pin
 * /d/[cfg]/[cfg]/[cfg]/[cfg]/[cfg]/[cfg]/[cfg]/[cfg]
 * [pin] = number (from 0 to 7) of the pin to access
 * [cfg] = pin configuration command:
 *     bit 0 - pin state to write
 *     bit 1 - pin state write disable
 *     bit 2 - pin direction
 *     bit 3 - pin direction write enable
 *     bit 4 - pin pullup state
 *     bit 5 - pin pullup write enable
 */
void PmodInterface::fnc_dio(char* resp)
{
    int bdat;
    int bcnt;
    switch (_args[0]) {
        case 0:
            bdat = 0;
            for (bcnt = 0; bcnt < 8 ; bcnt++) {
                if ((*_pmd[bcnt]).read()) {
                    bdat += (1 << bcnt);
                }
            }
            sprintf(resp,"0x%02X", bdat);
            break;
        case 1:
            if (_args[1] > 7) {
                sprintf(resp, "!pin");
            } else {
                sprintf(resp,"%d", (*_pmd[_args[1]]).read());
            }
            break;
        case 2:
            if (_args[1] > 7) {
                sprintf(resp, "!pin");
            } else {
                if (!(_args[2] & DB_OWD)) {
                    if (_args[2] & DB_OUT) {
                        (*_pmd[_args[1]]).write(1);
                        sprintf(resp++, "H");
                    } else {
                        (*_pmd[_args[1]]).write(0);
                        sprintf(resp++, "L");
                    }
                }
                if (_args[2] & DB_DWE) {
                    if (_args[2] & DB_DIR) {
                        (*_pmd[_args[1]]).output();
                        sprintf(resp++, "O");
                    } else {
                        (*_pmd[_args[1]]).input();
                        sprintf(resp++, "I");
                    }
                }
                if (_args[2] & DB_PWE) {
                    if (_args[2] & DB_PU) {
                        (*_pmd[_args[1]]).mode(PullUp);
                        sprintf(resp++, "U");
                    } else {
                        (*_pmd[_args[1]]).mode(PullNone);
                        sprintf(resp++, "N");
                    }
                }
            }
            break;
        case 8:
            for (bcnt = 0; bcnt < 8 ; bcnt++) {
                bdat = _args[bcnt +1];
                if (!(bdat & DB_OWD)) {
                    if (bdat & DB_OUT) {
                        (*_pmd[bcnt]).write(1);
                        sprintf(resp++, "H");
                    } else {
                        (*_pmd[bcnt]).write(0);
                        sprintf(resp++, "L");
                    }
                }
                if (bdat & DB_DWE) {
                    if (bdat & DB_DIR) {
                        (*_pmd[bcnt]).output();
                        sprintf(resp++, "O");
                    } else {
                        (*_pmd[bcnt]).input();
                        sprintf(resp++, "I");
                    }
                }
                if (bdat & DB_PWE) {
                    if (bdat & DB_PU) {
                        (*_pmd[bcnt]).mode(PullUp);
                        sprintf(resp++, "U");
                    } else {
                        (*_pmd[bcnt]).mode(PullNone);
                        sprintf(resp++, "N");
                    }
                }
                sprintf(resp++, "/");
            }
            *(--resp) = '\0';
            break;
        default:
            sprintf(resp, "!args");
            break;
    }
}

/* I2C
 * /i/[even]/[data]...       write
 * /i/[odd]/[cnt]/[data]...  read
 * [even] = even I2C address used for writes
 * [odd]  = odd I2C address used for reads
 * [data] = data to be writen, if data is included with a read, the data
 *     will be written prior to the read to set the register address
 * [cnt]  = number of bytes to read
 */
void PmodInterface::fnc_i2c(char* resp)
{
    int dcnt=0;
    if (_args[IA_CNT] < 2) {
        sprintf(resp, "!args");
    } else {
        if (_args[IA_ADD] & 1) {
            if (_args[IA_CNT] > 2) {
                for (dcnt = 0; dcnt < (_args[IA_CNT] -2) ; dcnt++) {
                    _dbuf[dcnt] = _args[(dcnt +3)];
                }
                if ((*_i2c).write(_args[IA_ADD], _dbuf, dcnt, true) != 0) {
                    sprintf(resp, "!write");
                    resp +=6;
                }
            }
            if ((*_i2c).read(_args[IA_ADD], _dbuf, _args[IA_DATA])!=0) {
                sprintf(resp, "!read");
            } else {
                for (dcnt = 0; dcnt < _args[IA_DATA]; dcnt++) {
                    sprintf(resp,"0x%02X/", _dbuf[dcnt]);
                    resp +=5;
                }
                *(--resp) = '\0';
            }
        } else {
            for (dcnt = 0; dcnt < (_args[IA_CNT] -1) ; dcnt++) {
                _dbuf[dcnt] = _args[(dcnt +2)];
            }
            if ((*_i2c).write(_args[IA_ADD], _dbuf, dcnt) == 0) {
                sprintf(resp,"%d", dcnt);
            } else {
                sprintf(resp, "!write");
            }
        }
    }
}

/* Multiplexer
 * /m/[pa]/[ma]/[pb]/[mb]  Set multiplexer channels A and B
 * [pa][pb]  int from 0 to 7 representint pmod pin
 * [ma][mb]  int from 0 to 15 representing micro pin
 */
void PmodInterface::fnc_mux(char* resp)
{
    if (_args[0] !=4) {
        sprintf(resp, "0x%08X", (*_mux).read());
    } else {
        if ((_args[1] > 8)||(_args[1] < 0)) {
            _args[1] =8;
        }
        if ((_args[2] > 16)||(_args[2] < 0)) {
            _args[2] =16;
        }
        if ((_args[3] > 8)||(_args[3] < 0)) {
            _args[3] =8;
        }
        if ((_args[4] > 16)||(_args[4] < 0)) {
            _args[4] =16;
        }
        int chA = _mux_p[_args[1]] | _mux_a[_args[2]];
        int chB = _mux_p[_args[3]] | _mux_a[_args[4]];
        (*_mux).setAB(chA, chB);
        sprintf(resp, "A: 0x%04X, B: 0x%04X", chA, chB);
    }
}


/* SPI
 * TBD
 */
void PmodInterface::fnc_spi(char* resp)
{
    if (_args[0] < 1) {
        sprintf(resp, "!args");
    } else {
        sprintf(resp, "spi tbd");
    }
}

void PmodInterface::call(char* input, char* output)
{
    char cmd;
    _args[0] = 0;
    if (*input == '/') {
        input++;
        cmd = *input;
        input = strchr(input, '/');
        while (*input == '/') {
            input++;
            _args[(_args[0]+1)] = strtol(input, &input, 0);
            if (input) {
                _args[0]++;
            }
        }
        switch (cmd) {
            case 'd':
            case 'D':
                fnc_dio(output);
                break;
            case 'i':
            case 'I':
                fnc_i2c(output);
                break;
            case 'm':
            case 'M':
                fnc_mux(output);
                break;
            case 's':
            case 'S':
                fnc_spi(output);
                break;
            default:
                sprintf(output, "!commands:  dio i2c mux pwm spi");
                break;
        }
    } else {
        sprintf(output, "!format:  /cmd/arg1/arg2...");

    }
}