示例#1
0
void HostCommunication::packetSent(int index, const Message &m) {
    const Component *src = m.sender;
    MicroFlo::PortId srcPort = m.senderPort;
    if (!src) {
        return;
    }

    uint8_t cmd[MICROFLO_CMD_SIZE] = { GraphCmdPacketSent, src->id(), (uint8_t)srcPort, m.target->id(),
                                        (uint8_t)m.targetPort, (uint8_t)m.pkg.type(), 0, 0 };

    if (m.pkg.isData()) {
        if (m.pkg.isBool()) {
            cmd[6] = m.pkg.asBool();
        } else if (m.pkg.isNumber()){
            // FIXME: truncates
            const int i = m.pkg.asInteger();
            cmd[6] = i>>0;
            cmd[7] = i>>8;
        } else if (m.pkg.isVoid()) {
            // Nothing needs doing
        } else {
            // FIXME: support all types
            MICROFLO_DEBUG(this, DebugLevelError, DebugNotImplemented);
        }
    }
示例#2
0
void HostCommunication::setup(Network *net, HostTransport *t) {
    network = net;
    transport = t;

    MICROFLO_DEBUG(this, DebugLevelInfo, DebugProgramStart);
    network->setNotificationHandler(this);
}
示例#3
0
void Network::connectSubgraph(bool isOutput,
                              MicroFlo::NodeId subgraphNode, MicroFlo::PortId subgraphPort,
                              MicroFlo::NodeId childNode, MicroFlo::PortId childPort) {
#ifdef MICROFLO_ENABLE_SUBGRAPHS

    MICROFLO_RETURN_IF_FAIL(MICROFLO_VALID_NODEID(subgraphNode) && MICROFLO_VALID_NODEID(childNode),
                    notificationHandler, DebugLevelError, DebugSubGraphConnectInvalidNodes);

    Component *comp = nodes[subgraphNode];
    Component *child = nodes[childNode];
    MICROFLO_ASSERT(comp->component() == MicroFlo::IdSubGraph && child->parentNodeId >= Network::firstNodeId,
                    notificationHandler, DebugLevelError, DebugSubGraphConnectNotASubgraph);

    SubGraph *subgraph = (SubGraph *)comp;
    if (isOutput) {
        subgraph->connectOutport(subgraphPort, child, childPort);
    } else {
        subgraph->connectInport(subgraphPort, child, childPort);
    }
    if (notificationHandler) {
        notificationHandler->subgraphConnected(isOutput, subgraphNode, subgraphPort, childNode, childPort);
    }
#else
    MICROFLO_DEBUG(this, DebugLevelError, DebugNotSupported);
#endif
}
示例#4
0
    virtual void PinSetPullup(MicroFlo::PinId pin, IO::PullupMode mode) {
        if (mode == IO::PullNone) {

        } else {
            MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
        }
    }
示例#5
0
 // Timer
 virtual long TimerCurrentMs() {
     timespec current_time;
     if (clock_gettime(CLOCK_MONOTONIC, &current_time) != 0) {
         MICROFLO_DEBUG(debug, DebugLevelError, DebugIoFailure);
     }
     timespec since_start = timespec_diff(start_time, current_time);
     return (since_start.tv_sec*1000)+(since_start.tv_nsec/1000000);
 }
示例#6
0
 virtual void PinSetPullup(MicroFlo::PinId pin, IO::PullupMode mode) {
     if (mode == IO::PullNone) {
         digitalWrite(pin, LOW);
     } else if (mode == IO::PullUp) {
         digitalWrite(pin, HIGH);
     } else {
         MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
     }
 }
示例#7
0
 // Assumes GPIO is set up as input
 bool gpio_read(int number){
     std::string path = SYS_GPIO_BASE + "gpio" + std::to_string(number) + "/value";
     std::string res = read_sys_file(path);
     if (res.empty()) {
         MICROFLO_DEBUG(debug, DebugLevelError, DebugIoFailure);
     }
     res = rtrim(res);
     return res == "1";
 }
示例#8
0
    // Pin config
    virtual void PinSetMode(MicroFlo::PinId pin, IO::PinMode mode) {
        if (!write_sys_file(SYS_GPIO_BASE+"export", std::to_string(pin))) {
            MICROFLO_DEBUG(debug, DebugLevelError, DebugIoFailure);
            return;
        }

        if (mode == IO::InputPin) {
            if (!write_sys_file(SYS_GPIO_BASE+"gpio"+std::to_string(pin)+"/direction", "in")) {
                MICROFLO_DEBUG(debug, DebugLevelError, DebugIoFailure);
            }
        } else if (mode == IO::OutputPin) {
            if (write_sys_file(SYS_GPIO_BASE+"gpio"+std::to_string(pin)+"/direction", "out")) {
                MICROFLO_DEBUG(debug, DebugLevelError, DebugIoFailure);
            }
        } else {
            MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
        }
    }
示例#9
0
void HostCommunication::parseByte(char b) {

    buffer[currentByte++] = b;

    if (state == ParseHeader) {
        MICROFLO_DEBUG(this, DebugLevelVeryDetailed, DebugParseHeader);
        if (currentByte == sizeof(MICROFLO_GRAPH_MAGIC)) {

            if (memcmp(buffer, MICROFLO_GRAPH_MAGIC, sizeof(MICROFLO_GRAPH_MAGIC)) == 0) {
                MICROFLO_DEBUG(this, DebugLevelDetailed, DebugMagicMatched);
                const uint8_t cmd[] = { GraphCmdCommunicationOpen };
                transport->sendCommand(cmd, sizeof(cmd));
                state = ParseCmd;
            } else {
                MICROFLO_DEBUG(this, DebugLevelError, DebugMagicMismatch);
                state = Invalid;
            }
            currentByte = 0;
        }
    } else if (state == ParseCmd) {
        MICROFLO_DEBUG(this, DebugLevelVeryDetailed, DebugParseCommand);
        if (currentByte == MICROFLO_CMD_SIZE) {
            if (memcmp(buffer, MICROFLO_GRAPH_MAGIC, sizeof(MICROFLO_GRAPH_MAGIC)) == 0) {
                MICROFLO_DEBUG(this, DebugLevelDetailed, DebugMagicMatched);
                const uint8_t cmd[] = { GraphCmdCommunicationOpen };
                transport->sendCommand(cmd, sizeof(cmd));
                // already in ParseCmd state
            } else {
                parseCmd();
            }
            currentByte = 0;
        }
    } else if (state == LookForHeader) {
        MICROFLO_DEBUG(this, DebugLevelVeryDetailed, DebugParseLookForHeader);
        if (b == MICROFLO_GRAPH_MAGIC[0]) {
            state = ParseHeader;
            buffer[0] = b;
            currentByte = 1;
        } else {
            currentByte = 0;
        }

    } else if (state == Invalid) {
        MICROFLO_DEBUG(this, DebugLevelError, DebugParserInvalidState);
        // try to recover
        currentByte = 0;
        state = LookForHeader;
    } else {
        MICROFLO_DEBUG(this, DebugLevelError,DebugParserUnknownState);
        // try to recover
        currentByte = 0;
        state = LookForHeader;
    }
}
示例#10
0
    // Pin config
    virtual void PinSetMode(MicroFlo::PinId pin, IO::PinMode mode) {

        MAP_SysCtlPeripheralEnable(peripheral(pin));
        if (mode == IO::InputPin) {
            MAP_GPIOPinTypeGPIOInput(portBase(pin), pinMask(pin));
        } else if (mode == IO::OutputPin) {
            MAP_GPIOPinTypeGPIOOutput(portBase(pin), pinMask(pin));
        } else {
            MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
        }
    }
示例#11
0
 virtual void setIoValue(const uint8_t *buf, uint8_t len) {
     IoType type = (IoType)buf[1];
     if (type == IoTypeAnalog) {
         // TEMP: implement
         MICROFLO_DEBUG(debug, DebugLevelError, DebugUnknownIoType);
     } else if (type == IoTypeDigital) {
         const uint8_t pin = buf[2];
         const bool val = buf[3];
         if (pin < DIGITAL_PINS) {
             digitalInputs[pin] = val;
             const uint8_t b[] = { GraphCmdSetIoValueCompleted, buf[1], buf[2], buf[3], buf[4] };
             transport->sendCommand(b, sizeof(b));
         } else {
             MICROFLO_DEBUG(debug, DebugLevelError, DebugIoInvalidValueSet);
         }
     } else if (type == IoTypeTimeMs) {
         // Perhaps also support incrementing?
         timeMs = readLong(buf+2);
         const uint8_t b[] = { GraphCmdSetIoValueCompleted, buf[1], buf[2], buf[3], buf[4] };
         transport->sendCommand(b, sizeof(b));
     } else {
         MICROFLO_DEBUG(debug, DebugLevelError, DebugUnknownIoType);
     }
 }
示例#12
0
 LinuxIO() {
     if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0) {
         MICROFLO_DEBUG(debug, DebugLevelError, DebugIoFailure);
     }
 }
示例#13
0
 // Assumes GPIO is set up as output
 void gpio_write(int number, bool value){
     std::string path = SYS_GPIO_BASE + "gpio" + std::to_string(number) + "/value";
     if (!write_sys_file(path, value ? "1" : "0")) {
         MICROFLO_DEBUG(debug, DebugLevelError, DebugIoFailure);
     }
 }
示例#14
0
 virtual void AttachExternalInterrupt(uint8_t interrupt, IO::Interrupt::Mode mode,
                                     IOInterruptFunction func, void *user) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
 }
示例#15
0
文件: io.hpp 项目: microflo/microflo
 // Timer
 virtual long TimerCurrentMs() {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
     return 0;
 }
示例#16
0
 virtual void PwmWrite(MicroFlo::PinId pin, long dutyPercent) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
 }
示例#17
0
文件: io.hpp 项目: microflo/microflo
 // Digital
 virtual void DigitalWrite(MicroFlo::PinId pin, bool val) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
 }
示例#18
0
 virtual unsigned char SerialRead(uint8_t serialDevice) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
     return '\0';
 }
示例#19
0
 // Serial
 // TODO: support serial
 virtual void SerialBegin(uint8_t serialDevice, int baudrate) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
 }
示例#20
0
void HostCommunication::parseCmd() {

    GraphCmd cmd = (GraphCmd)buffer[0];
    if (cmd == GraphCmdEnd) {
        MICROFLO_DEBUG(this, DebugLevelDetailed, DebugEndOfTransmission);
        const uint8_t cmd[] = { GraphCmdTransmissionEnded };
        transport->sendCommand(cmd, sizeof(cmd));
        state = LookForHeader;
    } else if (cmd == GraphCmdReset) {
        network->reset();
    } else if (cmd == GraphCmdStartNetwork) {
        network->start();
    } else if (cmd == GraphCmdCreateComponent) {
        MICROFLO_DEBUG(this, DebugLevelDetailed, DebugComponentCreateStart);
        Component *c = createComponent((MicroFlo::ComponentId)buffer[1]);
        MICROFLO_DEBUG(this, DebugLevelDetailed, DebugComponentCreateEnd);
        network->addNode(c, buffer[2]);
    } else if (cmd == GraphCmdConnectNodes) {
        MICROFLO_DEBUG(this, DebugLevelDetailed, DebugConnectNodesStart);
        network->connect(buffer[1], buffer[3], buffer[2], buffer[4]);
    } else if (cmd == GraphCmdSendPacket) {
        const Msg packetType = (Msg)buffer[3];
        Packet p;
        if (packetType == MsgBracketStart || packetType == MsgBracketEnd
                || packetType == MsgVoid) {
            p = Packet(packetType);
        } else if (packetType == MsgInteger) {
            const long val = buffer[4] + ((long)(buffer[5])<<8) + ((long)(buffer[6])<<16) + ((long)(buffer[7])<<24);
            p = Packet(val);
        } else if (packetType == MsgByte) {
            p = Packet(buffer[4]);
        } else if (packetType == MsgBoolean) {
            p = Packet(!(buffer[4] == 0));
        }

        if (p.isValid()) {
            network->sendMessageId(buffer[1], buffer[2], p);
            const uint8_t cmd[] = { GraphCmdSendPacketDone, buffer[1], buffer[2], (uint8_t)packetType };
            transport->sendCommand(cmd, sizeof(cmd));
        } else {
            MICROFLO_DEBUG(this, DebugLevelError, DebugParserUnknownPacketType);
        }
    } else if (cmd == GraphCmdConfigureDebug) {
        network->setDebugLevel((DebugLevel)buffer[1]);
    } else if (cmd == GraphCmdSubscribeToPort) {
        network->subscribeToPort(buffer[1], buffer[2], (bool)buffer[3]);
    } else if (cmd == GraphCmdConnectSubgraphPort) {
#ifdef MICROFLO_ENABLE_SUBGRAPHS
        // FIXME: validate
        const bool isOutput = (unsigned int)buffer[1];
        const int subgraphNode = (unsigned int)buffer[2];
        const int subgraphPort = (unsigned int)buffer[3];
        const int childNode = (unsigned int)buffer[4];
        const int childPort = (unsigned int)buffer[5];
        network->connectSubgraph(isOutput, subgraphNode, subgraphPort, childNode, childPort);
#else
        MICROFLO_DEBUG(this, DebugLevelError, DebugNotSupported);
#endif
    } else if (cmd == GraphCmdPing) {
        const uint8_t cmd[] = { GraphCmdPong, cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7] };
        transport->sendCommand(cmd, sizeof(cmd));
    } else if (cmd == GraphCmdSetIoValue) {
        network->setIoValue(buffer, MICROFLO_CMD_SIZE);
    } else if (cmd >= GraphCmdInvalid) {
        MICROFLO_ASSERT(memcmp(buffer, MICROFLO_GRAPH_MAGIC, sizeof(MICROFLO_GRAPH_MAGIC)) == 0,
                        this, DebugLevelError, DebugParserInvalidCommand);
    } else {
        MICROFLO_DEBUG(this, DebugLevelError, DebugParserUnknownCommand);
    }
}
示例#21
0
 virtual long SerialDataAvailable(uint8_t serialDevice) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
     return 0;
 }
示例#22
0
 virtual bool DigitalRead(MicroFlo::PinId pin) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
     return false;
 }
示例#23
0
 virtual void SerialWrite(uint8_t serialDevice, unsigned char b) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
 }
示例#24
0
 virtual void PinSetPullup(MicroFlo::PinId pin, IO::PullupMode mode) {
     // TODO: support pullup/pulldown config on common boards like RPi
     // Not exposed in sysfs, need to prod registers directly.
     // http://elinux.org/RPi_Low-level_peripherals#GPIO_Pull_Up.2FPull_Down_Register_Example
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
 }
示例#25
0
 // Analog
 virtual long AnalogRead(MicroFlo::PinId pin) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
     return 0;
 }
示例#26
0
文件: io.hpp 项目: microflo/microflo
 // Pin config
 virtual void PinSetMode(MicroFlo::PinId pin, IO::PinMode mode) {
     MICROFLO_DEBUG(debug, DebugLevelError, DebugIoOperationNotImplemented);
 }