diff --git a/LoRa.cpp b/LoRa.cpp index df50cfc..1ce035d 100644 --- a/LoRa.cpp +++ b/LoRa.cpp @@ -6,6 +6,20 @@ #include "LoRa.h" +#if LIBRARY_TYPE == LIBRARY_C + // We need sleep() to use instead of yield() + #include + // And we need to use the filesystem and IOCTLs instead of an SPI global + #include + // And we need to be able to report errors + #include + #include + // And we need IO formatting functions for the C++-stream dumpRegisters() + #include +#endif + + + #if MCU_VARIANT == MCU_ESP32 #include "soc/rtc_wdt.h" #define ISR_VECT IRAM_ATTR @@ -72,18 +86,26 @@ LoRaClass::LoRaClass() : _implicitHeaderMode(0), _onReceive(NULL) { +#if LIBRARY_TYPE == LIBRARY_ARDUINO // overide Stream timeout value setTimeout(0); +#elif LIBRARY_TYPE == LIBRARY_C + _fd = 0; +#endif } int LoRaClass::begin(long frequency) { - // setup pins - pinMode(_ss, OUTPUT); - // set SS high - digitalWrite(_ss, HIGH); + +#if LIBRARY_TYPE == LIBRARY_ARDUINO + // setup pins + pinMode(_ss, OUTPUT); + // set SS high + digitalWrite(_ss, HIGH); +#endif if (_reset != -1) { +#if LIBRARY_TYPE == LIBRARY_ARDUINO pinMode(_reset, OUTPUT); // perform reset @@ -91,11 +113,21 @@ int LoRaClass::begin(long frequency) delay(10); digitalWrite(_reset, HIGH); delay(10); +#endif + // TODO: No reset pin hooked up on BOARD_SPIDEV } +#if LIBRARY_TYPE == LIBRARY_ARDUINO // start SPI SPI.begin(); - +#elif LIBRARY_TYPE == LIBRARY_C + _fd = open("/dev/spidev0.0", O_RDWR); + if (_fd < 0) { + perror("could not open SPI device"); + exit(1); + } +#endif + // check version uint8_t version = readRegister(REG_VERSION); if (version != 0x12) { @@ -103,7 +135,7 @@ int LoRaClass::begin(long frequency) } // put in sleep mode - sleep(); + this->sleep(); // set frequency setFrequency(frequency); @@ -130,10 +162,17 @@ int LoRaClass::begin(long frequency) void LoRaClass::end() { // put in sleep mode - sleep(); + this->sleep(); +#if LIBRARY_TYPE == LIBRARY_ARDUINO // stop SPI SPI.end(); +#elif LIBRARY_TYPE == LIBRARY_C + if (_fd >= 0) { + close(_fd); + _fd = -1; + } +#endif } int LoRaClass::beginPacket(int implicitHeader) @@ -161,7 +200,11 @@ int LoRaClass::endPacket() // wait for TX done while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) { +#if LIBRARY_TYPE == LIBRARY_ARDUINO yield(); +#elif LIBRARY_TYPE == LIBRARY_C + ::sleep(1); +#endif } // clear IRQ's @@ -253,13 +296,13 @@ float ISR_VECT LoRaClass::packetSnr() { long LoRaClass::packetFrequencyError() { int32_t freqError = 0; - freqError = static_cast(readRegister(REG_FREQ_ERROR_MSB) & B111); + freqError = static_cast(readRegister(REG_FREQ_ERROR_MSB) & 0b111); freqError <<= 8L; freqError += static_cast(readRegister(REG_FREQ_ERROR_MID)); freqError <<= 8L; freqError += static_cast(readRegister(REG_FREQ_ERROR_LSB)); - if (readRegister(REG_FREQ_ERROR_MSB) & B1000) { // Sign bit is on + if (readRegister(REG_FREQ_ERROR_MSB) & 0b1000) { // Sign bit is on freqError -= 524288; // B1000'0000'0000'0000'0000 } @@ -337,17 +380,26 @@ void LoRaClass::onReceive(void(*callback)(int)) _onReceive = callback; if (callback) { +#if LIBRARY_TYPE == LIBRARY_ARDUINO pinMode(_dio0, INPUT); +#endif writeRegister(REG_DIO_MAPPING_1, 0x00); + +#if LIBRARY_TYPE == LIBRARY_ARDUINO #ifdef SPI_HAS_NOTUSINGINTERRUPT SPI.usingInterrupt(digitalPinToInterrupt(_dio0)); #endif attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING); +#endif + // TODO: What do we do if we want to use C library with a board that + // actually has dio0 connected? } else { +#if LIBRARY_TYPE == LIBRARY_ARDUINO detachInterrupt(digitalPinToInterrupt(_dio0)); #ifdef SPI_HAS_NOTUSINGINTERRUPT SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0)); +#endif #endif } } @@ -554,6 +606,7 @@ void LoRaClass::setSPIFrequency(uint32_t frequency) _spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); } +#if LIBRARY_TYPE == LIBRARY_ARDUINO void LoRaClass::dumpRegisters(Stream& out) { for (int i = 0; i < 128; i++) { @@ -563,6 +616,16 @@ void LoRaClass::dumpRegisters(Stream& out) out.println(readRegister(i), HEX); } } +#elif LIBRARY_TYPE == LIBRARY_C +void LoRaClass::dumpRegisters(std::ostream& out) +{ + for (int i = 0; i < 128; i++) { + out << "0x" << std::hex << i << ": 0x" << std::hex << readRegister(i) << std::endl; + } + out << std::dec; +} +#endif + void LoRaClass::explicitHeaderMode() { @@ -618,7 +681,8 @@ void LoRaClass::writeRegister(uint8_t address, uint8_t value) uint8_t ISR_VECT LoRaClass::singleTransfer(uint8_t address, uint8_t value) { uint8_t response; - + +#if LIBRARY_TYPE == LIBRARY_ARDUINO digitalWrite(_ss, LOW); SPI.beginTransaction(_spiSettings); @@ -627,6 +691,11 @@ uint8_t ISR_VECT LoRaClass::singleTransfer(uint8_t address, uint8_t value) SPI.endTransaction(); digitalWrite(_ss, HIGH); +#elif LIBRARY_TYPE == LIBRARY_C + +#else + #error "SPI transfer not implemented for library type" +#endif return response; } diff --git a/LoRa.h b/LoRa.h index 42bc116..5793337 100644 --- a/LoRa.h +++ b/LoRa.h @@ -15,7 +15,25 @@ #elif LIBRARY_TYPE == LIBRARY_C #include #include - #include "ArduinoOnLinux/Stream.h" + #include + + // Arduino Stream is not available, but not actually needed. + class Stream {}; + + typedef unsigned char byte; + + // Arduino SPI is not available. + #define MSBFIRST 0 + #define SPI_MODE0 0 + class SPISettings { + public: + inline SPISettings(int frequency, int bitness, int mode) : frequency(frequency), bitness(bitness), mode(mode) {}; + SPISettings& operator=(const SPISettings& other) = default; + int frequency; + int bitness; + int mode; + }; + #endif #define LORA_DEFAULT_SS_PIN 10 @@ -81,8 +99,12 @@ public: void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN); void setSPIFrequency(uint32_t frequency); - + +#if LIBRARY_TYPE == LIBRARY_ARDUINO void dumpRegisters(Stream& out); +#elif LIBRARY_TYPE == LIBRARY_C + void dumpRegisters(std::ostream& out); +#endif private: void explicitHeaderMode(); @@ -107,6 +129,9 @@ private: int _packetIndex; int _implicitHeaderMode; void (*_onReceive)(int); + #if LIBRARY_TYPE == LIBRARY_C + int _fd; + #endif }; extern LoRaClass LoRa; diff --git a/RNode_Firmware.ino b/RNode_Firmware.ino index ea1c90c..b0b0873 100644 --- a/RNode_Firmware.ino +++ b/RNode_Firmware.ino @@ -864,3 +864,12 @@ void serial_interrupt_init() { buffer_serial(); } #endif + +#if PLATFORM == PLATFORM_LINUX + int main(int argc, char** argv) { + setup(); + while (true) { + loop(); + } + } +#endif