diff --git a/src/helpers/AutoDiscoverRTCClock.cpp b/src/helpers/AutoDiscoverRTCClock.cpp index 5c3a4f1cc..49a72893d 100644 --- a/src/helpers/AutoDiscoverRTCClock.cpp +++ b/src/helpers/AutoDiscoverRTCClock.cpp @@ -1,6 +1,7 @@ #include "AutoDiscoverRTCClock.h" #include "RTClib.h" #include +#include "RTC_RX8130CE.h" static RTC_DS3231 rtc_3231; static bool ds3231_success = false; @@ -11,9 +12,13 @@ static bool rv3028_success = false; static RTC_PCF8563 rtc_8563; static bool rtc_8563_success = false; +static RTC_RX8130CE rtc_8130; +static bool rtc_8130_success = false; + #define DS3231_ADDRESS 0x68 #define RV3028_ADDRESS 0x52 #define PCF8563_ADDRESS 0x51 +#define RX8130CE_ADDRESS 0x32 bool AutoDiscoverRTCClock::i2c_probe(TwoWire& wire, uint8_t addr) { wire.beginTransmission(addr); @@ -25,22 +30,32 @@ void AutoDiscoverRTCClock::begin(TwoWire& wire) { if (i2c_probe(wire, DS3231_ADDRESS)) { ds3231_success = rtc_3231.begin(&wire); } + if (i2c_probe(wire, RV3028_ADDRESS)) { rtc_rv3028.initI2C(wire); - rtc_rv3028.writeToRegister(0x35, 0x00); - rtc_rv3028.writeToRegister(0x37, 0xB4); // Direct Switching Mode (DSM): when VDD < VBACKUP, switchover occurs from VDD to VBACKUP - rtc_rv3028.set24HourMode(); // Set the device to use the 24hour format (default) instead of the 12 hour format + rtc_rv3028.writeToRegister(0x35, 0x00); + rtc_rv3028.writeToRegister(0x37, 0xB4); // Direct Switching Mode (DSM): when VDD < VBACKUP, switchover occurs from VDD to VBACKUP + rtc_rv3028.set24HourMode(); // Set the device to use the 24hour format (default) instead of the 12 hour format rv3028_success = true; } - if(i2c_probe(wire,PCF8563_ADDRESS)){ + + if (i2c_probe(wire, PCF8563_ADDRESS)) { rtc_8563_success = rtc_8563.begin(&wire); } + + if (i2c_probe(wire, RX8130CE_ADDRESS)) { + MESH_DEBUG_PRINTLN("RX8130CE: Found"); + rtc_8130.begin(&wire); + rtc_8130_success = true; + MESH_DEBUG_PRINTLN("RX8130CE: Initialized"); + } } uint32_t AutoDiscoverRTCClock::getCurrentTime() { if (ds3231_success) { return rtc_3231.now().unixtime(); } + if (rv3028_success) { return DateTime( rtc_rv3028.getYear(), @@ -51,9 +66,16 @@ uint32_t AutoDiscoverRTCClock::getCurrentTime() { rtc_rv3028.getSecond() ).unixtime(); } - if(rtc_8563_success){ + + if (rtc_8563_success) { return rtc_8563.now().unixtime(); } + + if (rtc_8130_success) { + MESH_DEBUG_PRINTLN("RX8130CE: Reading time"); + return rtc_8130.now().unixtime(); + } + return _fallback->getCurrentTime(); } @@ -66,6 +88,9 @@ void AutoDiscoverRTCClock::setCurrentTime(uint32_t time) { rtc_rv3028.setTime(dt.year(), dt.month(), weekday, dt.day(), dt.hour(), dt.minute(), dt.second()); } else if (rtc_8563_success) { rtc_8563.adjust(DateTime(time)); + } else if (rtc_8130_success) { + MESH_DEBUG_PRINTLN("RX8130CE: Setting time"); + rtc_8130.adjust(DateTime(time)); } else { _fallback->setCurrentTime(time); } diff --git a/src/helpers/RTC_RX8130CE.cpp b/src/helpers/RTC_RX8130CE.cpp new file mode 100644 index 000000000..8aa2b1ff3 --- /dev/null +++ b/src/helpers/RTC_RX8130CE.cpp @@ -0,0 +1,197 @@ +#include "RTC_RX8130CE.h" +#include "RTClib.h" + + +bool RTC_RX8130CE::stop(bool stop) { + write_register(0x1E, stop ? 0x040 : 0x00); + return true; +} + +bool RTC_RX8130CE::begin(TwoWire *wire) { + if (i2c_dev) { + delete i2c_dev; + } + + i2c_dev = new Adafruit_I2CDevice(this->_addr, wire); + if (!i2c_dev->begin()) { + return false; + } + + /* + * Digital offset register: + * [7] DET: 0 -> disabled + * [6:0] L7-L1: 0 -> no offset + */ + write_register(0x30, 0x00); + + /* + * Extension Register register: + * [7:6] FSEL: 0 -> 0 + * [5] USEL: 0 -> 0 + * [4] TE: 0 -> + * [3] WADA: 0 -> 0 + * [2-0] TSEL: 0 -> 0 + */ + write_register(0x1C, 0x00); + + /* + * Flag Register register: + * [7] VBLF: 0 -> 0 + * [6] 0: 0 -> + * [5] UF: 0 -> + * [4] TF: 0 -> + * [3] AF: 0 -> 0 + * [2] RSF: 0 -> 0 + * [1] VLF: 0 -> 0 + * [0] VBFF: 0 -> 0 + */ + write_register(0x1D, 0x00); + + /* + * Control Register0 register: + * [7] TEST: 0 -> 0 + * [6] STOP: 0 -> + * [5] UIE: 0 -> + * [4] TIE: 0 -> + * [3] AIE: 0 -> 0 + * [2] TSTP: 0 -> 0 + * [1] TBKON: 0 -> 0 + * [0] TBKE: 0 -> 0 + */ + write_register(0x1E, 0x00); + + /* + * Control Register1 register: + * [7-6] SMPTSEL: 0 -> 0 + * [5] CHGEN: 0 -> + * [4] INIEN: 0 -> + * [3] 0: 0 -> + * [2] RSVSEL: 0 -> 0 + * [1-0] BFVSEL: 0 -> 0 + */ + write_register(0x1F, 0x00); + + this->stop(false); // clear STOP bit + + /* + * Function register: + * [7] 100TH: 0 -> disabled + * [6:5] Periodic interrupt: 0 -> no periodic interrupt + * [4] RTCM: 0 -> real-time clock mode + * [3] STOPM: 0 -> RTC stop is controlled by STOP bit only + * [2:0] Clock output frequency: 000 (Default value) + */ + write_register(0x28, 0x00); + + // Battery switch register + write_register(0x26, 0x00); // enable battery switch feature + + return true; +} + +bool RTC_RX8130CE::setTime(struct tm *t) { + uint8_t buf[8]; + buf[0] = 0x10; + buf[1] = bin2bcd(t->tm_sec) & 0x7F; + buf[2] = bin2bcd(t->tm_min) & 0x7F; + buf[3] = bin2bcd(t->tm_hour) & 0x3F; + buf[4] = bin2bcd(t->tm_wday) & 0x07; + buf[5] = bin2bcd(t->tm_mday) & 0x3F; + buf[6] = bin2bcd(t->tm_mon + 1) & 0x1F; + buf[7] = bin2bcd((t->tm_year - 100)); + + this->stop(true); + i2c_dev->write(buf, sizeof(buf)); + this->stop(false); + + return true; +} + +void RTC_RX8130CE::adjust(DateTime dt) { + struct tm *atv; + time_t utime; + + utime = (time_t)dt.unixtime(); + atv = gmtime(&utime); + + this->setTime(atv); +} + +DateTime RTC_RX8130CE::now() { + struct tm atv; + this->getTime(&atv); + + return DateTime((uint32_t)mktime(&atv)); +} + +uint32_t RTC_RX8130CE::unixtime() { + struct tm atv; + this->getTime(&atv); + + return (uint32_t)mktime(&atv); +} + +bool RTC_RX8130CE::getTime(struct tm *t) { + uint8_t buff[7]; + + buff[0] = 0x10; + + i2c_dev->write_then_read(buff, 1, buff, 7); + + t->tm_sec = bcd2bin(buff[0] & 0x7F); + t->tm_min = bcd2bin(buff[1] & 0x7F); + t->tm_hour = bcd2bin(buff[2] & 0x3F); + t->tm_wday = bcd2bin(buff[3] & 0x07); + t->tm_mday = bcd2bin(buff[4] & 0x3F); + t->tm_mon = bcd2bin(buff[5] & 0x1F) - 1; + t->tm_year = bcd2bin(buff[6]) + 100; + + return true; +} + +bool RTC_RX8130CE::writeRAM(uint8_t address, uint8_t value) { + return this->writeRAM(address, &value, 1); +} + +size_t RTC_RX8130CE::writeRAM(uint8_t address, uint8_t *value, size_t len) { + uint8_t buf[len + 1]; + + if (address > 3) { + return 0; + } + + if ((address + len) > 3) { + len = 3 - address; + } + + buf[0] = 0x20 + address; + + for (int i = 1; i <= len + 1; i++) { + buf[i] = value[i - 1]; + } + + i2c_dev->write(buf, len + 1); + + return len; +} + +bool RTC_RX8130CE::readRAM(uint8_t address, uint8_t *value, size_t len) { + uint8_t real_address = 0x20 + address; + + if (address > 3) { // Oversize of 64-bytes RAM + return false; + } + + if ((address + len) > 3) { // Data size over RAM size + len = 3 - address; + } + + i2c_dev->write_then_read(&real_address, 1, value, len); + return true; +} + +uint8_t RTC_RX8130CE::readRAM(uint8_t address) { + uint8_t value = 0xFF; + this->readRAM(address, &value, 1); + return value; +} diff --git a/src/helpers/RTC_RX8130CE.h b/src/helpers/RTC_RX8130CE.h new file mode 100644 index 000000000..1cf148a9f --- /dev/null +++ b/src/helpers/RTC_RX8130CE.h @@ -0,0 +1,33 @@ +#ifndef __RTC_RX8130CE_H__ +#define __RTC_RX8130CE_H__ + +#include +#include +#include +#include "RTClib.h" + +class RTC_RX8130CE : RTC_I2C { + private: + const uint8_t _addr = 0x32; + + bool stop(bool stop); + + protected: + + public: + bool begin(TwoWire *wire); + bool setTime(struct tm *t); + bool getTime(struct tm *t); + void adjust(DateTime t); + + DateTime now(); + uint32_t unixtime(); + + bool writeRAM(uint8_t address, uint8_t value); + size_t writeRAM(uint8_t address, uint8_t *value, size_t len); + bool readRAM(uint8_t address, uint8_t *value, size_t len); + uint8_t readRAM(uint8_t address); + +}; + +#endif diff --git a/variants/muziworks_r1_neo/R1NeoBoard.cpp b/variants/muziworks_r1_neo/R1NeoBoard.cpp new file mode 100644 index 000000000..616d255a8 --- /dev/null +++ b/variants/muziworks_r1_neo/R1NeoBoard.cpp @@ -0,0 +1,66 @@ +#include +#include + +#include "R1NeoBoard.h" + +#ifdef NRF52_POWER_MANAGEMENT +// Static configuration for power management +// Values set in variant.h defines +const PowerMgtConfig power_config = { + .lpcomp_ain_channel = PWRMGT_LPCOMP_AIN, + .lpcomp_refsel = PWRMGT_LPCOMP_REFSEL, + .voltage_bootlock = PWRMGT_VOLTAGE_BOOTLOCK +}; + +void R1NeoBoard::initiateShutdown(uint8_t reason) { + // Disable LoRa module power before shutdown + MESH_DEBUG_PRINTLN("R1Neo: shutting down"); + digitalWrite(SX126X_POWER_EN, LOW); + + if (reason == SHUTDOWN_REASON_LOW_VOLTAGE || + reason == SHUTDOWN_REASON_BOOT_PROTECT) { + configureVoltageWake(power_config.lpcomp_ain_channel, power_config.lpcomp_refsel); + } + + enterSystemOff(reason); +} +#endif // NRF52_POWER_MANAGEMENT + +void R1NeoBoard::begin() { + // R1 Neo peculiarity: tell DCDC converter to stay powered. + // Must be done as soon as practical during boot. + + pinMode(PIN_DCDC_EN_MCU_HOLD, OUTPUT); + digitalWrite(PIN_DCDC_EN_MCU_HOLD, HIGH); + + // R1 Neo peculiarity: Tell I/O Controller device is on + // Enables passthrough of buttons and LEDs + + pinMode(PIN_SOFT_SHUTDOWN, OUTPUT); + digitalWrite(PIN_SOFT_SHUTDOWN, HIGH); + + NRF52BoardDCDC::begin(); + + // button is active high and passed through from I/O controller + pinMode(PIN_USER_BTN, INPUT); + + pinMode(PIN_BUZZER, OUTPUT); + digitalWrite(PIN_BUZZER, LOW); + + // battery pins + pinMode(PIN_BAT_CHG, INPUT); + pinMode(PIN_VBAT_READ, INPUT); + + Wire.setPins(PIN_WIRE_SDA, PIN_WIRE_SCL); + + Wire.begin(); + + pinMode(SX126X_POWER_EN, OUTPUT); +#ifdef NRF52_POWER_MANAGEMENT + // Boot voltage protection check (may not return if voltage too low) + // We need to call this after we configure SX126X_POWER_EN as output but before we pull high + checkBootVoltage(&power_config); +#endif + digitalWrite(SX126X_POWER_EN, HIGH); + delay(10); // give sx1262 some time to power up +} diff --git a/variants/muziworks_r1_neo/R1NeoBoard.h b/variants/muziworks_r1_neo/R1NeoBoard.h new file mode 100644 index 000000000..c27ea2321 --- /dev/null +++ b/variants/muziworks_r1_neo/R1NeoBoard.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include +#include "NullDisplayDriver.h" +#include "MomentaryButton.h" + +#define DISPLAY_CLASS NullDisplayDriver + +class R1NeoBoard : public NRF52BoardDCDC { +protected: +#ifdef NRF52_POWER_MANAGEMENT + void initiateShutdown(uint8_t reason) override; +#endif + +public: + R1NeoBoard() : NRF52Board("R1NEO_OTA") {} + void begin(); + +#if defined(P_LORA_TX_LED) + void onBeforeTransmit() override { + digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on + #if defined(LED_BLUE) + // turn off that annoying blue LED before transmitting + digitalWrite(LED_BLUE, LOW); + #endif + } + void onAfterTransmit() override { + digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off + #if defined(LED_BLUE) + // do it after transmitting too, just in case + digitalWrite(LED_BLUE, LOW); + #endif + } +#endif + + #define BATTERY_SAMPLES 8 + + uint16_t getBattMilliVolts() override { + MESH_DEBUG_PRINTLN("R1Neo: Sampling battery"); + analogReadResolution(12); + + uint32_t raw = 0; + for (int i = 0; i < BATTERY_SAMPLES; i++) { + raw += analogRead(PIN_VBAT_READ); + } + raw = raw / BATTERY_SAMPLES; + + return (ADC_MULTIPLIER * raw) / 4096; + } + + const char* getManufacturerName() const override { + return "muzi works R1 Neo"; + } +}; diff --git a/variants/muziworks_r1_neo/platformio.ini b/variants/muziworks_r1_neo/platformio.ini new file mode 100644 index 000000000..39ef8728f --- /dev/null +++ b/variants/muziworks_r1_neo/platformio.ini @@ -0,0 +1,132 @@ +[R1Neo] +extends = nrf52_base +board = rak4631 +board_check = true +build_flags = ${nrf52_base.build_flags} + ${sensor_base.build_flags} + -I variants/muziworks_r1_neo + -I src/helpers/ui + -D R1Neo + -D NRF52_POWER_MANAGEMENT + -D RADIO_CLASS=CustomSX1262 + -D WRAPPER_CLASS=CustomSX1262Wrapper + -D LORA_TX_POWER=22 + -D SX126X_CURRENT_LIMIT=140 + -D SX126X_RX_BOOSTED_GAIN=1 + -D PIN_BUZZER=3 + -D PIN_USER_BTN=26 + -D USER_BTN_PRESSED=HIGH + -D PIN_GPS_TX=25 + -D PIN_GPS_RX=24 + -D PIN_GPS_EN=33 +build_src_filter = ${nrf52_base.build_src_filter} + +<../variants/muziworks_r1_neo> + + + + + + +lib_deps = + ${nrf52_base.lib_deps} + ${sensor_base.lib_deps} + sparkfun/SparkFun u-blox GNSS Arduino Library@^2.2.27 + +[env:R1Neo_repeater] +extends = R1Neo +build_flags = + ${R1Neo.build_flags} + -D ADVERT_NAME='"R1 Neo Repeater"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${R1Neo.build_src_filter} + +<../examples/simple_repeater> + +[env:R1Neo_room_server] +extends = R1Neo +build_flags = + ${R1Neo.build_flags} + -D ADVERT_NAME='"R1 Neo Test Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${R1Neo.build_src_filter} + +<../examples/simple_room_server> + +[env:R1Neo_companion_radio_usb] +extends = R1Neo +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_flags = + ${R1Neo.build_flags} + -I examples/companion_radio/ui-orig + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 +; NOTE: DO NOT ENABLE --> -D MESH_PACKET_LOGGING=1 +; NOTE: DO NOT ENABLE --> -D MESH_DEBUG=1 +build_src_filter = ${R1Neo.build_src_filter} + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-orig/*.cpp> +lib_deps = + ${R1Neo.lib_deps} + densaugeo/base64 @ ~1.4.0 + end2endzone/NonBlockingRTTTL@^1.3.0 + +[env:R1Neo_companion_radio_ble] +extends = R1Neo +board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld +board_upload.maximum_size = 712704 +build_flags = + ${R1Neo.build_flags} + -I examples/companion_radio/ui-orig + -D ENV_INCLUDE_GPS=1 + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D BLE_PIN_CODE=123456 + -D BLE_DEBUG_LOGGING=1 + -D OFFLINE_QUEUE_SIZE=256 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${R1Neo.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-orig/*.cpp> +lib_deps = + ${R1Neo.lib_deps} + ${rak4631.lib_deps} + densaugeo/base64 @ ~1.4.0 + end2endzone/NonBlockingRTTTL@^1.3.0 + +[env:R1Neo_terminal_chat] +extends = R1Neo +build_flags = + ${R1Neo.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = ${R1Neo.build_src_filter} + +<../examples/simple_secure_chat/main.cpp> +lib_deps = + ${R1Neo.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:R1Neo_sensor] +extends = R1Neo +build_flags = + ${R1Neo.build_flags} + -D DISPLAY_CLASS=SSD1306Display + -D ADVERT_NAME='"R1 Neo Sensor"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' +; -D MESH_PACKET_LOGGING=1 + -D MESH_DEBUG=1 +build_src_filter = ${R1Neo.build_src_filter} + +<../examples/simple_sensor> diff --git a/variants/muziworks_r1_neo/target.cpp b/variants/muziworks_r1_neo/target.cpp new file mode 100644 index 000000000..7b0cb5bff --- /dev/null +++ b/variants/muziworks_r1_neo/target.cpp @@ -0,0 +1,47 @@ +#include +#include "target.h" +#include + +R1NeoBoard board; + +DISPLAY_CLASS display; + +RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); + +WRAPPER_CLASS radio_driver(radio, board); + +VolatileRTCClock fallback_clock; +AutoDiscoverRTCClock rtc_clock(fallback_clock); + +#if ENV_INCLUDE_GPS + #include + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); + EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else + EnvironmentSensorManager sensors; +#endif + +bool radio_init() { + rtc_clock.begin(Wire); + return radio.std_init(&SPI); +} + +uint32_t radio_get_rng_seed() { + return radio.random(0x7FFFFFFF); +} + +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { + radio.setFrequency(freq); + radio.setSpreadingFactor(sf); + radio.setBandwidth(bw); + radio.setCodingRate(cr); +} + +void radio_set_tx_power(uint8_t dbm) { + radio.setOutputPower(dbm); +} + +mesh::LocalIdentity radio_new_identity() { + RadioNoiseListener rng(radio); + return mesh::LocalIdentity(&rng); // create new random identity +} diff --git a/variants/muziworks_r1_neo/target.h b/variants/muziworks_r1_neo/target.h new file mode 100644 index 000000000..346e8741a --- /dev/null +++ b/variants/muziworks_r1_neo/target.h @@ -0,0 +1,22 @@ +#pragma once + +#define RADIOLIB_STATIC_ONLY 1 +#include +#include +#include +#include +#include +#include + +extern R1NeoBoard board; +extern WRAPPER_CLASS radio_driver; +extern AutoDiscoverRTCClock rtc_clock; +extern EnvironmentSensorManager sensors; +extern DISPLAY_CLASS display; +extern MomentaryButton user_btn; + +bool radio_init(); +uint32_t radio_get_rng_seed(); +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); +void radio_set_tx_power(uint8_t dbm); +mesh::LocalIdentity radio_new_identity(); diff --git a/variants/muziworks_r1_neo/variant.cpp b/variants/muziworks_r1_neo/variant.cpp new file mode 100644 index 000000000..bb3d1fdd4 --- /dev/null +++ b/variants/muziworks_r1_neo/variant.cpp @@ -0,0 +1,92 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" +#include "wiring_constants.h" +#include "wiring_digital.h" +#include "nrf.h" + +const uint32_t g_ADigitalPinMap[] = +{ + // P0 + 0, // P0.00 (NC) (XTAL) + 1, // P0.01 (NC) (XTAL) + 2, // P0.02 (30) GPS_PPS + 3, // P0.03 (29) BUZZER_DRIVE + 4, // P0.04 (41) NC + 5, // P0.05 (40) NC + 6, // P0.06 (NC) NOT_PRESENT + 7, // P0.07 (NC) (TRACECLK) + 8, // P0.08 (NC) NOT_PRESENT + 9, // P0.09 (13) NC + 10, // P0.10 (12) NC + 11, // P0.11 (NC) NOT_PRESENT + 12, // P0.12 (NC) NOT_PRESENT + 13, // P0.13 (04) DCDC_EN_MCU_HOLD + 14, // P0.14 (05) NC + 15, // P0.15 (06) NC + 16, // P0.16 (07) NC + 17, // P0.17 (08) NC + 18, // P0.18 (17) !RESET + 19, // P0.19 (09) RTC_SDA + 20, // P0.20 (10) RTC_SCL + 21, // P0.21 (11) NC + 22, // P0.22 (NC) NOT_PRESENT + 23, // P0.23 (NC) NOT_PRESENT + 24, // P0.24 (23) UART_GPS_RX + 25, // P0.25 (24) UART_GPS_TX + 26, // P0.26 (26) BTN_OK/USR_BTN_PROCESSED + 27, // P0.27 (NC) NOT_PRESENT + 28, // P0.28 (31) BLU_LED_RAK + 29, // P0.29 (32) SOFT_SHUTDOWN_SIGNAL + 30, // P0.30 (33) MCU_SIGNAL + 31, // P0.31 (39) ADC_VBAT + + // P1 + 32, // P1.00 (NC) NOT_PRESENT + 33, // P1.01 (25) GPS_EN + 34, // P1.02 (26) BAT_CHG_STATUS + 35, // P1.03 (27) NC + 36, // P1.04 (28) GRN_LED_RAK + 37, // P1.05 (SX) SX126X_POWER_EN + 38, // P1.06 (SX) P_LORA_RESET + 39, // P1.07 (NC) NOT_PRESENT + 40, // P1.08 (NC) NOT_PRESENT + 41, // P1.09 (NC) NOT_PRESENT + 42, // P1.10 (SX) P_LORA_NSS + 43, // P1.11 (SX) P_LORA_SCLK + 44, // P1.12 (SX) P_LORA_MOSI + 45, // P1.13 (SX) P_LORA_MISO + 46, // P1.14 (SX) P_LORA_BUSY + 47 // P1.15 (SX) P_LORA_DIO_1 +}; + + +void initVariant() +{ + // Red & Green LEDs - enable & turn off + pinMode(LED_GREEN, OUTPUT); + ledOff(LED_GREEN); + + pinMode(LED_BLUE, OUTPUT); + ledOff(LED_BLUE); + + pinMode(PIN_GPS_EN, OUTPUT); +} diff --git a/variants/muziworks_r1_neo/variant.h b/variants/muziworks_r1_neo/variant.h new file mode 100644 index 000000000..92046d61a --- /dev/null +++ b/variants/muziworks_r1_neo/variant.h @@ -0,0 +1,183 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_R1NEO_ +#define _VARIANT_R1NEO_ + +#define RAK4630 + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +#define USE_LFXO // Board uses 32khz crystal for LF +// define USE_LFRC // Board uses RC for LF + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/* Number of pins defined in PinDescription array */ +#define PINS_COUNT (48) +#define NUM_DIGITAL_PINS (48) +#define NUM_ANALOG_INPUTS (8) +#define NUM_ANALOG_OUTPUTS (0) + +/* R1Neo peculiarities */ +#define PIN_DCDC_EN_MCU_HOLD (13) // P0.13 (04) DCDC_EN_MCU_HOLD +#define PIN_SOFT_SHUTDOWN (29) // P0.29 (32) SOFT_SHUTDOWN_SIGNAL +#define PIN_MCU_SIGNAL (30) // P0.30 (33) MCU_SIGNAL + +/* R1Neo LoRa Radio */ +// RAK4630/4631 pins + +#define P_LORA_DIO_1 (47) // P1.15 (SX) +#define P_LORA_NSS (42) // P1.10 (SX) +#define P_LORA_RESET RADIOLIB_NC // P1.06 (SX) -- 38 +#define P_LORA_BUSY (46) // P1.14 (SX) +#define P_LORA_SCLK (43) // P1.11 (SX) +#define P_LORA_MISO (45) // P1.13 (SX) +#define P_LORA_MOSI (44) // P1.12 (SX) +#define SX126X_POWER_EN (37) // P1.05 (SX) + +#define SX126X_DIO2_AS_RF_SWITCH true +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 + +/* R1Neo peripherals */ +/* GPS */ +#define GPS_RX (24) // P0.24 (23) UART_GPS_RX +#define GPS_TX (25) // P0.25 (24) UART_GPS_TX +#define GPS_EN (33) // P1.01 (25) GPS_EN +#define GPS_PPS (2) // P0.02 (30) GPS_PPS + +#define PIN_GPS_1PPS GPS_PPS +#define GPS_BAUD_RATE 9600 + +/* RTC */ +#define RTC_SDA (19) // P0.19 (9) RTC_SDA +#define RTC_SCL (20) // P0.20 (10) RTC_SCL + +/* LEDs */ +#define LED_GREEN (36) // P1.04 (28) GRN_LED_RAK +#define LED_BLUE (28) // P0.28 (31) BLU_LED_RAK + +#define LED_BUILTIN (0xFF) + +#ifndef P_LORA_TX_LED + #define P_LORA_TX_LED LED_GREEN +#endif + +#define LED_STATE_ON 1 // State when LED is lit + +/* Buttons */ +#define PIN_USER_BTN (26) + +/* Buzzer */ +#define PIN_BUZZER (3) + +/* Analog pins */ +// Arduino makes me angry +#define PIN_A0 (0xFF) // NOT_PRESENT +#define PIN_A1 (0xFF) // NOT_PRESENT +#define PIN_A2 (4) // P0.04 (41) NC +#define PIN_A3 (5) // P0.05 (40) NC +#define PIN_A4 (0xFF) // NOT_PRESENT +#define PIN_A5 (0xFF) // NOT_PRESENT +#define PIN_A6 (0xFF) // NOT_PRESENT +#define PIN_A7 (31) // P0.31 (39) ADC_VBAT + + static const uint8_t A0 = PIN_A0; + static const uint8_t A1 = PIN_A1; + static const uint8_t A2 = PIN_A2; + static const uint8_t A3 = PIN_A3; + static const uint8_t A4 = PIN_A4; + static const uint8_t A5 = PIN_A5; + static const uint8_t A6 = PIN_A6; + static const uint8_t A7 = PIN_A7; +#define ADC_RESOLUTION 14 + +// Other pins +#define PIN_AREF (0xFF) // No analog reference + + static const uint8_t AREF = PIN_AREF; + +/* Serial interfaces */ +#define PIN_GPS_TX (GPS_TX) +#define PIN_GPS_RX (GPS_RX) +#define PIN_GPS_EN (GPS_EN) + +#define PIN_SERIAL1_TX (PIN_GPS_TX) +#define PIN_SERIAL1_RX (PIN_GPS_RX) + +/* SPI Interfaces */ +// unused pins - define anyways +#define SPI_INTERFACES_COUNT 1 +#define PIN_SPI_MOSI (9) // P0.09 (13) NC +#define PIN_SPI_MISO (10) // P0.10 (12) NC +#define PIN_SPI_SCK (21) // P0.21 (11) NC + +/* I2C Interfaces */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (RTC_SDA) +#define PIN_WIRE_SCL (RTC_SCL) + +/* QSPI Pins */ +// interface occupied by peripherals, define anyways +#define PIN_QSPI_SCK (3) // P0.03 (29) BUZZER +#define PIN_QSPI_CS (26) // P0.26 (34) USER_BUTTON +#define PIN_QSPI_IO0 (30) // P0.30 (33) MCU_SIGNAL +#define PIN_QSPI_IO1 (29) // P0.29 (32) SOFT_SHUTDOWN +#define PIN_QSPI_IO2 (28) // P0.28 (31) BLU_LED_RAK +#define PIN_QSPI_IO3 (2) // P0.02 (30) GPS_PPS + +/* On-board QSPI Flash */ +// No QSPI (define anyways) +#define EXTERNAL_FLASH_DEVICES IS25LP080D +#define EXTERNAL_FLASH_USE_QSPI + +/* Battery */ +#define PIN_VBAT_READ (31) // P0.31 (39) ADC_VBAT +#define PIN_BAT_CHG (34) // P1.02 (26) BAT_CHG_STATUS + +#define ADC_MULTIPLIER (3 * 1.73 * 1.187 * 1000) + +// Power management boot protection threshold (millivolts) +// Set to 0 to disable boot protection +// disabled for now until I can figure this out +#define PWRMGT_VOLTAGE_BOOTLOCK 0 // Won't boot below this voltage (mV) +// LPCOMP wake configuration (voltage recovery from SYSTEMOFF) +// AIN3 = P0.05 = PIN_A0 / PIN_VBAT_READ +#define PWRMGT_LPCOMP_AIN 5 +#define PWRMGT_LPCOMP_REFSEL 4 // 5/8 VDD (~3.13-3.44V) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif