Ejemplo n.º 1
0
// GPIO interface
// Sets the mode of a GPIO ( digital in= 0, digital out = 1, analog = 2 )
// Returns true on successful setup.
uint8_t Sodaq_RN2483::pinMode(uint8_t gpio, pinModes mode) {
	//sanitize inputs,
	//GPIO4 does not do analog
	debugPrintLn("setting GPIO pin");
	if (mode == analog) {
		if (gpio==4) {
			return false;
			debugPrintLn("GPIO4 does not support analog");
		}
	}
	// only handle GPIO0-13
	if (gpio >13) {
		return false;
		debugPrintLn("GPIO out of bounds : 0-13 only");
	}
	// sys set pinmode <pinname> <pinFunc>
	this->loraStream->print(STR_SYS_SET);
	this->loraStream->print(STR_GPIO_MODE);
	this->loraStream->print(STR_GPIO);
	this->loraStream->print(gpio);
	if (mode == digitalIn) {
		this->loraStream->print(STR_GPIO_MODE_DIGIN);
	}
	else if (mode == digitalOut){
		this->loraStream->print(STR_GPIO_MODE_DIGOUT);
	}
	else {
		this->loraStream->print(STR_GPIO_MODE_ANA);
	}
	this->loraStream->print(CRLF);

	// parse response
	return expectOK();
}
Ejemplo n.º 2
0
/**
* @brief Sends the command together with the given, paramValue (optional)
* @param Command should include a trailing space if paramValue is set. Refer to RN2483 command ref
* @param Command Parameter to send
* @return Returns true on success or false if invalid.
*/
bool RN2483::sendCommand(const char* command, uint8_t paramValue)
{
    _RN2483.printf(command);
    _RN2483.printf("%u",paramValue);
    _RN2483.printf(CRLF);

    return expectOK();
}
Ejemplo n.º 3
0
/**
* @brief Sends a join command to the network
* @param Type of join, OTAA or ABP
* @return Returns true on success or false if fail.
*/
bool RN2483::joinNetwork(const char* type)
{
    _RN2483.printf(STR_CMD_JOIN);
    _RN2483.printf(type);
    _RN2483.printf(CRLF);

    return expectOK() && expectString(STR_ACCEPTED, 30000);
}
Ejemplo n.º 4
0
/**
* @brief Sends the command together with the given, paramValue (optional)
* @param Command should include a trailing space if paramValue is set. Refer to RN2483 command ref
* @param Command Parameter to send
* @return Returns true on success or false if invalid.
*/
bool RN2483::sendCommand(const char* command, const char* paramValue)
{
    _RN2483.printf(command);
    if (paramValue != NULL) {
        _RN2483.printf(paramValue);
    }
    _RN2483.printf(CRLF);
    return expectOK();
}
Ejemplo n.º 5
0
/**
* @brief Sends the command together with the given paramValue (optional)
* @param MAC param should include a trailing space if paramValue is set. Refer to RN2483 command ref.
* @param Param value to send
* @return Returns true on success or false if invalid.
*/
bool RN2483::setMacParam(const char* paramName, const char* paramValue)
{
    _RN2483.printf(STR_CMD_SET);
    _RN2483.printf(paramName);
    _RN2483.printf(paramValue);
    _RN2483.printf(CRLF);

    return expectOK();
}
Ejemplo n.º 6
0
bool Sodaq_RN2483::macSave()
{
	debugPrint("[macSave] ");
    
    this->loraStream->print(STR_CMD_SAVE);
    this->loraStream->print(CRLF);

    return expectOK();
	
}
Ejemplo n.º 7
0
// Sends a join network command to the device and waits for the response (or timeout).
// Returns true on success.
bool Sodaq_RN2483::joinNetwork(const char* type)
{
    debugPrintLn("[joinNetwork]");

    this->loraStream->print(STR_CMD_JOIN);
    this->loraStream->print(type);
    this->loraStream->print(CRLF);

    return expectOK() && expectString(STR_ACCEPTED, 10000);
}
Ejemplo n.º 8
0
/**
* @brief Sends the command together with the given, paramValue (optional)
* @param Command should include a trailing space if paramValue is set. Refer to RN2483 command ref
* @param Command Parameter to send
* @param Size of param buffer
* @return Returns true on success or false if invalid.
*/
bool RN2483::sendCommand(const char* command, const uint8_t* paramValue, uint16_t size)
{
    _RN2483.printf(command);

    for (uint16_t i = 0; i < size; ++i) {
        _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(paramValue[i]))));
        _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(paramValue[i]))));
    }

    _RN2483.printf(CRLF);

    return expectOK();
}
Ejemplo n.º 9
0
// Sends the given mac command together with the given paramValue
// to the device and awaits for the response.
// Returns true on success.
// NOTE: paramName should include a trailing space
bool Sodaq_RN2483::setMacParam(const char* paramName, const char* paramValue)
{
    debugPrint("[setMacParam] ");
    debugPrint(paramName);
    debugPrint("= ");
    debugPrintLn(paramValue);

    this->loraStream->print(STR_CMD_SET);
    this->loraStream->print(paramName);
    this->loraStream->print(paramValue);
    this->loraStream->print(CRLF);

    return expectOK();
}
Ejemplo n.º 10
0
uint8_t Sodaq_RN2483::macTransmit(const char* type, uint8_t port, const uint8_t* payload, uint8_t size)
{
    debugPrintLn("[macTransmit]");

    this->loraStream->print(STR_CMD_MAC_TX);
    this->loraStream->print(type);
    this->loraStream->print(port);
    this->loraStream->print(" ");

    for (int i = 0; i < size; ++i) {
        this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(payload[i]))));
        this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(payload[i]))));
    }

    this->loraStream->print(CRLF);

    if (!expectOK()) {
        return lookupMacTransmitError(this->inputBuffer); // inputBuffer still has the last line read
    }

    this->packetReceived = false; // prepare for receiving a new packet

    debugPrint("Waiting for server response");
    unsigned long timeout = millis() + RECEIVE_TIMEOUT; // hard timeout
    while (millis() < timeout) {
        sodaq_wdt_reset();
        debugPrint(".");
        if (readLn() > 0) {
            debugPrintLn(".");debugPrint("(");debugPrint(this->inputBuffer);debugPrintLn(")");

            if (strstr(this->inputBuffer, " ") != NULL) // to avoid double delimiter search
            {
                // there is a splittable line -only case known is mac_rx
                debugPrintLn("Splittable response found");
                return onMacRX();
            } else if (strstr(this->inputBuffer, STR_RESULT_MAC_TX_OK)) {
                // done
                debugPrintLn("Received mac_tx_ok");
                return NoError;
            } else {
                // lookup the error message
                debugPrintLn("Some other string received (error)");
                return lookupMacTransmitError(this->inputBuffer);
            }
        }
    }

    debugPrintLn("Timed-out waiting for a response!");
    return Timeout;
}
Ejemplo n.º 11
0
/**
* @brief Sends the command together with the given paramValue (optional)
* @param MAC param should include a trailing space if paramValue is set. Refer to RN2483 command ref.
* @param Param value to send
* @param Size of Param buffer
* @return Returns true on success or false if invalid.
*/
bool RN2483::setMacParam(const char* paramName, const uint8_t* paramValue, uint16_t size)
{
    printf("RN2483: Set MAC param: %s\n");
    _RN2483.printf(STR_CMD_SET);
    _RN2483.printf(paramName);

    for (uint16_t i = 0; i < size; ++i) {
        _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(paramValue[i]))));
        _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(paramValue[i]))));
    }

    _RN2483.printf(CRLF);

    return expectOK();
}
Ejemplo n.º 12
0
// Sends the given mac command together with the given paramValue
// to the device and awaits for the response.
// Returns true on success.
// NOTE: paramName should include a trailing space
bool Sodaq_RN2483::setMacParam(const char* paramName, const uint8_t* paramValue, uint16_t size)
{
    debugPrint("[setMacParam] "); debugPrint(paramName); debugPrint("= [array]");

    this->loraStream->print(STR_CMD_SET);
    this->loraStream->print(paramName);

    for (uint16_t i = 0; i < size; ++i) {
        this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(paramValue[i]))));
        this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(paramValue[i]))));
    }

    this->loraStream->print(CRLF);

    return expectOK();
}
Ejemplo n.º 13
0
    //! Read the contents of the MT SBD message buffer.
    //! @param[in] data buffer to hold binary data.
    //! @param[in] data_size size of binary data buffer.
    //! @return number of bytes read.
    unsigned
    readBufferMT(uint8_t* data, unsigned data_size)
    {
        ReadMode saved_read_mode = getReadMode();
        Counter<double> timer(getTimeout());
        uint8_t bfr[2] = {0};
        uint8_t ccsum[2] = {0};
        unsigned length = 0;

        try
        {
            // Prepare to read raw data.
            setReadMode(READ_MODE_RAW);

            // Send command.
            sendAT("+SBDRB");

            // Read incoming data length.
            length = getBufferSizeMT(timer);
            getTask()->spew("reading %u bytes of SBD binary data", length);

            // Read data.
            if (length > data_size)
                throw BufferTooSmall(data_size, length);

            if (length > 0)
            {
                readRaw(timer, data, length);
                computeChecksum(data, length, ccsum);
            }

            // Read and validate.
            readRaw(timer, bfr, 2);
            if ((bfr[0] != ccsum[0]) || (bfr[1] != ccsum[1]))
                throw Hardware::InvalidChecksum(bfr, ccsum);

            setReadMode(saved_read_mode);
            expectOK();
        }
        catch (...)
        {
            setReadMode(saved_read_mode);
            throw;
        }

        return length;
    }
Ejemplo n.º 14
0
/**
* @brief Enables all the channels that belong to the given Frequency Sub-Band (FSB)
* disables the rest.
* @param FSB is [1, 8] or 0 to enable all channels.
* @return Returns true if all channels were set successfully.
*/
bool RN2483::setFsbChannels(uint8_t fsb)
{
    uint8_t first125kHzChannel = fsb > 0 ? (fsb - 1) * 8 : 0;
    uint8_t last125kHzChannel = fsb > 0 ? first125kHzChannel + 7 : 71;
    uint8_t fsb500kHzChannel = fsb + 63;

    bool allOk = true;
    for (uint8_t i = 0; i < 72; i++) {
        _RN2483.printf(STR_CMD_SET_CHANNEL_STATUS);
        _RN2483.printf("%u",i);
        _RN2483.printf(" ");
        _RN2483.printf(BOOL_TO_ONOFF(((i == fsb500kHzChannel) || (i >= first125kHzChannel && i <= last125kHzChannel))));
        _RN2483.printf(CRLF);

        allOk &= expectOK();
    }

    return allOk;
}
Ejemplo n.º 15
0
/**
* @brief Sends a a payload and blocks until there is a response back,
* or the receive windows have closed or the hard timeout has passed.
* @param Transmit type
* @param Port to use for transmit
* @param Payload buffer
* @param Size of payload buffer
* @return Returns if sucessfull or if a MAC transmit error.
*/
uint8_t RN2483::macTransmit(const char* type, uint8_t port, const uint8_t* payload, uint8_t size)
{
    _RN2483.printf(STR_CMD_MAC_TX);
    _RN2483.printf(type);
    _RN2483.printf("%u",port);
    _RN2483.printf(" ");

    for (int i = 0; i < size; ++i) {
        _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(payload[i]))));
        _RN2483.putc(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(payload[i]))));
    }

    _RN2483.printf(CRLF);

    if (!expectOK()) {
        return lookupMacTransmitError(this->inputBuffer); // inputBuffer still has the last line read
    }

    this->packetReceived = false; // prepare for receiving a new packet
    Timer t;
    t.start();
    int timeout = t.read_ms() + RECEIVE_TIMEOUT; // hard timeouts
    while (t.read_ms() < timeout) {
        if (readLn() > 0) {
            if (strstr(this->inputBuffer, " ") != NULL) { // to avoid double delimiter search
                // there is a splittable line -only case known is mac_rx
                t.stop();
                return onMacRX();
            } else if (strstr(this->inputBuffer, STR_RESULT_MAC_TX_OK)) {
                // done
                t.stop();
                return NoError;
            } else {
                // lookup the error message
                t.stop();
                return lookupMacTransmitError(this->inputBuffer);
            }
        }
    }
    t.stop();
    return Timedout;
}
Ejemplo n.º 16
0
// Enables all the channels that belong to the given Frequency Sub-Band (FSB)
// and disables the rest.
// fsb is [1, 8] or 0 to enable all channels.
// Returns true if all channels were set successfully.
bool Sodaq_RN2483::setFsbChannels(uint8_t fsb)
{
    debugPrintLn("[setFsbChannels]");

    uint8_t first125kHzChannel = fsb > 0 ? (fsb - 1) * 8 : 0;
    uint8_t last125kHzChannel = fsb > 0 ? first125kHzChannel + 7 : 71;
    uint8_t fsb500kHzChannel = fsb + 63;
    
    bool allOk = true;
    for (uint8_t i = 0; i < 72; i++) {
        this->loraStream->print(STR_CMD_SET_CHANNEL_STATUS);
        this->loraStream->print(i);
        this->loraStream->print(" ");
        this->loraStream->print(BOOL_TO_ONOFF(((i == fsb500kHzChannel) || (i >= first125kHzChannel && i <= last125kHzChannel))));
        this->loraStream->print(CRLF);

        allOk &= expectOK();
    }

    return allOk;
}
Ejemplo n.º 17
0
// Sets the digital state of a pin
// Returns true on successful setting.
uint8_t Sodaq_RN2483::digitalWrite(uint8_t gpio, uint8_t state) {
	//sanitize inputs,
	// only handle GPIO0-13
	debugPrintLn("digitalWrite");
	if (gpio >13) {
		return false;
		debugPrintLn("GPIO out of bounds : 0-13 only");
	}
	// sys set pindig <pinname> <pinstate>
	// example: sys set pindig GPIO5 1
	this->loraStream->print(STR_SYS_SET);
	this->loraStream->print(STR_GPIO_DIG);
	this->loraStream->print(STR_GPIO);
	this->loraStream->print(gpio);
	this->loraStream->print(" ");
	this->loraStream->print(state);
	this->loraStream->print(CRLF);

	// parse response 
	return expectOK();
}