IPS(Interpreter for Process Structures) for mbed

Dependencies:   ConfigFile FATFileSystem mbed

IPS port from linux/unix version.

mbed_blinky.ips

0 VAR led1
" LED1 " DigitalOut led1 !
: main
    ANFANG
    1 JA?
      1 led1 @ write
      200 wait_ms
      0 led1 @ write
      200 wait_ms
    DANN/NOCHMAL
;
main

mbedAPI.cpp

Committer:
va009039
Date:
2015-05-23
Revision:
2:908338b1151a
Child:
4:b62b40563944

File content as of revision 2:908338b1151a:

// mbedAPI.cpp 2015/5/22
#include <algorithm>
#include "mbed.h"
#include "mbedAPI.h"
#include "PinNameTable.h"

// $MBEDAPI
#define mbed_wait           1
#define mbed_wait_ms        2
#define mbed_DigitalOut     3
#define mbed_DigitalIn      4
#define mbed_DigitalInOut   5
#define mbed_Timer          6
#define mbed_RawSerial      7
#define mbed_read           8
#define mbed_write          9
#define mbed_putc           10
#define mbed_getc           11
#define mbed_readable       12
#define mbed_baud           13
#define mbed_SPI            14
#define mbed_I2C            15
#define mbed_start          16
#define mbed_stop           17
#define mbed_reset          18
#define mbed_read_ms        19
#define mbed_read_us        20
#define mbed_PwmOut         21
#define mbed_period_ms      22
#define mbed_period_us      23
#define mbed_pulsewidth_ms  24
#define mbed_pulsewidth_us  25
#define mbed_AnalogIn       26
#define mbed_read_u16       27

void mbedAPI::code() {
    int f = ips.pull_ps();
    uint16_t a1;
    switch(f) {
        case mbed_wait_ms:
            a1 = ips.pull_ps();
            wait_ms(a1);
            break;
        case mbed_Timer:
            init<Timer>(f);
            break;
        case mbed_DigitalOut:
            init<DigitalOut, PinName>(f);
            break;
        case mbed_DigitalIn:
            init<DigitalIn, PinName>(f);
            break;
        case mbed_DigitalInOut:
            init<DigitalInOut, PinName>(f);
            break;
        case mbed_AnalogIn:
            init<AnalogIn, PinName>(f);
            break;
        case mbed_PwmOut:
            init<PwmOut, PinName>(f);
            break;
        case mbed_RawSerial:
            init<RawSerial, PinName, PinName>(f);
            break;
        case mbed_SPI:
            init<SPI, PinName, PinName, PinName>(f);
            break;
        case mbed_I2C:
            init<I2C, PinName, PinName>(f);
            break;
        default:
            code_method(f);
            break;
    }
}

void mbedAPI::code_method(int f) {
    mbedObj obj = pull_ps_obj();
    uint16_t a1;
    switch(obj.ct) {
        case mbed_DigitalOut:
            switch(f) {
                case mbed_write:
                    method<DigitalOut, int, &DigitalOut::write>(obj.p);
                    break;
                case mbed_read:
                    method<int, DigitalOut, &DigitalOut::read>(obj.p);
                    break;
                default:
                    break;
            }
            break;
        case mbed_DigitalInOut:
            switch(f) {
                case mbed_write:
                    method<DigitalInOut, int, &DigitalInOut::write>(obj.p);
                    break;
                case mbed_read:
                    method<int, DigitalInOut, &DigitalInOut::read>(obj.p);
                    break;
                default:
                    break;
            }
            break;
        case mbed_AnalogIn:
            switch(f) {
                case mbed_read_u16:
                    method<unsigned short, AnalogIn, &AnalogIn::read_u16>(obj.p);
                    break;
                default:
                    error("%s %d", __LINE__, f);
                    break;
            }
            break;
        case mbed_PwmOut:
            switch(f) {
                case mbed_period_ms:
                    method<PwmOut, int, &PwmOut::period_ms>(obj.p);
                    break;
                case mbed_period_us:
                    method<PwmOut, int, &PwmOut::period_us>(obj.p);
                    break;
                case mbed_pulsewidth_ms:
                    method<PwmOut, int, &PwmOut::pulsewidth_ms>(obj.p);
                    break;
                case mbed_pulsewidth_us:
                    method<PwmOut, int, &PwmOut::pulsewidth_us>(obj.p);
                    break;
                default:
                    error("%s %d", __LINE__, f);
                    break;
            }
            break;
        case mbed_Timer:
            switch(f) {
                case mbed_start:
                    method<Timer, &Timer::start>(obj.p);
                    break;
                case mbed_stop:
                    method<Timer, &Timer::stop>(obj.p);
                    break;
                case mbed_reset:
                    method<Timer, &Timer::reset>(obj.p);
                    break;
                case mbed_read_ms:
                    method<int, Timer, &Timer::read_ms>(obj.p);
                    break;
                case mbed_read_us:
                    method<int, Timer, &Timer::read_us>(obj.p);
                    break;
                default:
                    error("%s %d", __LINE__, f);
                    break;
            }
            break;
        case mbed_DigitalIn:
            switch(f) {
                case mbed_read:
                    method<int, DigitalIn, &DigitalIn::read>(obj.p);
                    break;
                default:
                    error("%s %d", __LINE__, f);
                    break;
            }
            break;
        case mbed_SPI:
            switch(f) {
                case mbed_write:
                    method<int, SPI, int, &SPI::write>(obj.p);
                    break;
                default:
                    error("%s %d", __LINE__, f);
                    break;
            }
            break;
        case mbed_I2C:
            code_method_I2C(f, obj);
            break;
        case mbed_RawSerial:
            switch(f) {
                case mbed_putc:
                    a1 = ips.pull_ps();
                    reinterpret_cast<RawSerial*>(obj.p)->putc(a1);
                    break;
                case mbed_getc:
                    method<int, RawSerial, &RawSerial::getc>(obj.p);
                    break;
                case mbed_readable:
                    ips.push_ps(reinterpret_cast<RawSerial*>(obj.p)->readable());
                    break;
                case mbed_baud:
                    a1 = ips.pull_ps();
                    reinterpret_cast<RawSerial*>(obj.p)->baud(a1);
                    break;
                default:
                    error("%s %d", __LINE__, f);
                    break;
            }
            break;
        default:
            break;
    }
}

void mbedAPI::code_method_I2C(int f, mbedObj& obj) {
    if (f == mbed_read) {
        uint16_t a3 = ips.pull_ps(); // addr
        uint16_t a2 = ips.pull_ps(); // data length
        uint16_t a1 = ips.pull_ps(); // data pointer
        char buf[a2];
        reinterpret_cast<I2C*>(obj.p)->read(a3, buf, a1);
        for(int i = 0; i < a2; i++) {
            ips.pokeB(a1 + i, buf[i]);
        }
    } else if (f == mbed_write) {
        uint16_t a3 = ips.pull_ps(); // addr
        uint16_t a2 = ips.pull_ps(); // data length
        uint16_t a1 = ips.pull_ps(); // data pointer
        char buf[a2];
        for(int i = 0; i < a2; i++) {
            buf[i] = ips.peekB(a1 + i);
        }
        reinterpret_cast<I2C*>(obj.p)->write(a3, buf, a1);
    } else {
        error("%s %d", __LINE__, f);
    }
}

template<>
PinName mbedAPI::pull_ps<PinName>() {
    char buf[64];
    pull_ps_string(buf, sizeof(buf));
    return findPinName(buf);
}

mbedObj mbedAPI::pull_ps_obj() {
    int i = ips.pull_ps();
    return objs[i];
}

void mbedAPI::pull_ps_string(char* buf, size_t size) {
    size_t s_len = ips.pull_ps();
    int s_start = ips.pull_ps();
    s_len = std::min(s_len, size-1);
    for(size_t i = 0; i < s_len; i++) {
        buf[i] = ips.peekB(s_start + i);
    }
    buf[s_len] = '\0';
}

PinName mbedAPI::findPinName(const char* name) const {
    int imin = 0;
    int imax = sizeof(pinname_table) / sizeof(pinNameStr) - 1;
    while(imax >= imin) {
        int i = (imin + imax) / 2;
        int c = strcmp(name, pinname_table[i].name);
        if (c == 0) {
            return pinname_table[i].pin;
        } else if (c > 0) {
            imin = i + 1;
        } else {
            imax = i - 1;
        }
    }
    return NC;
}

void mbedAPI::push_ps_obj(void* p, int ct) {
    mbedObj obj;
    obj.p = p;
    obj.ct = ct;
    objs.push_back(obj);
    uint16_t r1 = objs.size() - 1;
    ips.push_ps(r1);
}