diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index 706ccb4c..a5cfe26b 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -35,26 +35,41 @@ jobs: platforms: | - name: arduino:samd artifact-name-suffix: arduino-samd-mkrwifi1010 + type: nina - fqbn: arduino:samd:nano_33_iot platforms: | - name: arduino:samd artifact-name-suffix: arduino-samd-nano_33_iot + type: nina - fqbn: arduino:megaavr:uno2018:mode=on platforms: | - name: arduino:megaavr artifact-name-suffix: arduino-megaavr-uno2018 + type: nina - fqbn: arduino:mbed_nano:nano33ble platforms: | - name: arduino:mbed_nano artifact-name-suffix: arduino-mbed_nano-nano33ble + type: nina - fqbn: arduino:mbed_nano:nanorp2040connect platforms: | - name: arduino:mbed_nano artifact-name-suffix: arduino-mbed_nano-nanorp2040connect + type: nina - fqbn: arduino:renesas_uno:unor4wifi platforms: | - name: arduino:renesas_uno artifact-name-suffix: arduino-renesas_uno-unor4wifi + type: unor4wifi + + include: + - board: + type: nina + libraries: | + - name: WiFiNINA + - board: + type: unor4wifi + libraries: steps: - name: Checkout repository @@ -69,6 +84,7 @@ jobs: libraries: | # Install the library from the local path. - source-path: ./ + ${{ matrix.libraries }} sketch-paths: | - examples enable-deltas-report: true @@ -83,7 +99,7 @@ jobs: build-for-esp32: runs-on: ubuntu-latest - + strategy: matrix: fqbn: @@ -101,6 +117,8 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} fqbn: ${{ matrix.fqbn }} + libraries: | + ${{ matrix.libraries }} platforms: | - name: esp32:esp32 source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json diff --git a/library.properties b/library.properties index 543998b7..4196e767 100644 --- a/library.properties +++ b/library.properties @@ -8,3 +8,4 @@ category=Communication url=https://www.arduino.cc/en/Reference/ArduinoBLE architectures=samd,megaavr,mbed,apollo3,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_giga,renesas,renesas_portenta,mbed_opta,renesas_uno,silabs includes=ArduinoBLE.h +depends=WiFiNINA diff --git a/src/local/BLELocalDevice.cpp b/src/local/BLELocalDevice.cpp index 5792353f..7c2ae2c7 100644 --- a/src/local/BLELocalDevice.cpp +++ b/src/local/BLELocalDevice.cpp @@ -50,26 +50,7 @@ BLELocalDevice::~BLELocalDevice() int BLELocalDevice::begin() { -#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_NANO_RP2040_CONNECT) - // reset the NINA in BLE mode - pinMode(SPIWIFI_SS, OUTPUT); - pinMode(NINA_RESETN, OUTPUT); - - digitalWrite(SPIWIFI_SS, LOW); -#endif - -#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_AVR_UNO_WIFI_REV2) - digitalWrite(NINA_RESETN, HIGH); - delay(100); - digitalWrite(NINA_RESETN, LOW); - delay(750); -#elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_NANO_RP2040_CONNECT) - // inverted reset - digitalWrite(NINA_RESETN, LOW); - delay(100); - digitalWrite(NINA_RESETN, HIGH); - delay(750); -#elif defined(PORTENTA_H7_PINS) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_GIGA) || defined(ARDUINO_OPTA) +#if defined(PORTENTA_H7_PINS) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_GIGA) || defined(ARDUINO_OPTA) // BT_REG_ON -> HIGH pinMode(BT_REG_ON, OUTPUT); digitalWrite(BT_REG_ON, LOW); @@ -182,10 +163,10 @@ int BLELocalDevice::begin() // } // Serial.println(); - // // save this + // // save this // uint8_t zeros[16]; // for(int k=0; k<16; k++) zeros[15-k] = 0; - + // // HCI.leAddResolvingAddress((*BADDR_Type)[i],(*BADDRs)[i],(*IRKs)[i], zeros); // delete[] (*BADDRs)[i]; @@ -197,7 +178,7 @@ int BLELocalDevice::begin() // delete BADDRs; // delete[] (*IRKs); // delete IRKs; - + // memcheck = new uint8_t[1]; // Serial.print("nIRK location: 0x"); // Serial.println((int)memcheck,HEX); @@ -216,15 +197,9 @@ void BLELocalDevice::end() HCI.end(); -#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_AVR_UNO_WIFI_REV2) - // disable the NINA - digitalWrite(NINA_RESETN, HIGH); -#elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_NANO_RP2040_CONNECT) - // disable the NINA - digitalWrite(NINA_RESETN, LOW); -#elif defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_GIGA) || defined(ARDUINO_OPTA) +#if defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_GIGA) || defined(ARDUINO_OPTA) digitalWrite(BT_REG_ON, LOW); -#endif +#endif _advertisingData.clear(); _scanResponseData.clear(); } @@ -310,7 +285,7 @@ bool BLELocalDevice::setManufacturerData(const uint16_t companyId, const uint8_t bool BLELocalDevice::setLocalName(const char *localName) { - return _scanResponseData.setLocalName(localName); + return _scanResponseData.setLocalName(localName); } void BLELocalDevice::setAdvertisingData(BLEAdvertisingData& advertisingData) @@ -355,7 +330,7 @@ int BLELocalDevice::advertise() { _advertisingData.updateData(); _scanResponseData.updateData(); - return GAP.advertise( _advertisingData.data(), _advertisingData.dataLength(), + return GAP.advertise( _advertisingData.data(), _advertisingData.dataLength(), _scanResponseData.data(), _scanResponseData.dataLength()); } diff --git a/src/utility/HCINinaSpiTransport.cpp b/src/utility/HCINinaSpiTransport.cpp new file mode 100644 index 00000000..4eeb90f3 --- /dev/null +++ b/src/utility/HCINinaSpiTransport.cpp @@ -0,0 +1,65 @@ +/* + This file is part of the ArduinoBLE library. + + Copyright (c) 2024 Arduino SA + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#if defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(TARGET_NANO_RP2040_CONNECT) +#include "HCINinaSpiTransport.h" +#include "spi_drv.h" +#include "ble_drv.h" + +int HCINinaSpiTransportClass::begin() +{ + SpiDrv::begin(); + return BleDrv::bleBegin(); +} + +void HCINinaSpiTransportClass::end() +{ + BleDrv::bleEnd(); +} + +void HCINinaSpiTransportClass::wait(unsigned long timeout) +{ + for (unsigned long start = millis(); (millis() - start) < timeout;) { + if (available()) { + break; + } + } +} + +int HCINinaSpiTransportClass::available() +{ + return BleDrv::bleAvailable(); +} + +int HCINinaSpiTransportClass::peek() +{ + int res=-1; + BleDrv::blePeek((uint8_t*)&res, 1); // read a single byte, if nothing is returned we return -1 + + return res; +} + +int HCINinaSpiTransportClass::read() +{ + int res=-1; + BleDrv::bleRead((uint8_t*)&res, 1); // read a single byte, if nothing is returned we return -1 + + return res; +} + +size_t HCINinaSpiTransportClass::write(const uint8_t* data, size_t length) +{ + return BleDrv::bleWrite(data, length); +} + +HCINinaSpiTransportClass HCINinaSpiTransport; +HCITransportInterface& HCITransport = HCINinaSpiTransport; + +#endif diff --git a/src/utility/HCINinaSpiTransport.h b/src/utility/HCINinaSpiTransport.h new file mode 100644 index 00000000..55cb1068 --- /dev/null +++ b/src/utility/HCINinaSpiTransport.h @@ -0,0 +1,32 @@ +/* + This file is part of the ArduinoBLE library. + + Copyright (c) 2024 Arduino SA + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#ifndef _HCI_NINA_SPI_TRANSPORT_H_ +#define _HCI_NINA_SPI_TRANSPORT_H_ + +#include "HCITransport.h" + +class HCINinaSpiTransportClass : public HCITransportInterface { +public: + HCINinaSpiTransportClass() {} + + virtual int begin(); + virtual void end(); + + virtual void wait(unsigned long timeout); + + virtual int available(); + virtual int peek(); + virtual int read(); + + virtual size_t write(const uint8_t* data, size_t length); +}; + +#endif diff --git a/src/utility/HCIUartTransport.cpp b/src/utility/HCIUartTransport.cpp index 191811a7..606c8148 100644 --- a/src/utility/HCIUartTransport.cpp +++ b/src/utility/HCIUartTransport.cpp @@ -17,24 +17,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) && !defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_WIFI) || defined(TARGET_NANO_RP2040_CONNECT) //|| defined(CORE_CM4) +#if defined(ARDUINO_PORTENTA_C33) #include "HCIUartTransport.h" -#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_AVR_UNO_WIFI_REV2) -#define SerialHCI Serial2 -#elif defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_NANO_RP2040_CONNECT) -// SerialHCI is already defined in the variant -#elif defined(ARDUINO_PORTENTA_H7_M4) -// SerialHCI is already defined in the variant -#elif defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) -#define SerialHCI Serial2 -#elif defined(ARDUINO_OPTA) -#define SerialHCI Serial3 -#elif defined(ARDUINO_PORTENTA_C33) +#if defined(ARDUINO_PORTENTA_C33) #define SerialHCI Serial5 -#elif defined(ARDUINO_GIGA) -arduino::UART SerialHCI(CYBSP_BT_UART_TX, CYBSP_BT_UART_RX, CYBSP_BT_UART_RTS, CYBSP_BT_UART_CTS); #else #error "Unsupported board selected!" #endif diff --git a/src/utility/ble_drv.cpp b/src/utility/ble_drv.cpp new file mode 100644 index 00000000..22e16ba6 --- /dev/null +++ b/src/utility/ble_drv.cpp @@ -0,0 +1,153 @@ + +#include +#include +#include + +#include "Arduino.h" +#include +#include "utility/ble_drv.h" + + +extern "C" { +#include "utility/ble_spi.h" +} + + +int BleDrv::bleBegin() { + WAIT_FOR_SLAVE_SELECT(); + + SpiDrv::sendCmd(BLE_BEGIN, PARAM_NUMS_0); + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + uint8_t len = 1; + uint8_t result = 0; + SpiDrv::waitResponseCmd(BLE_BEGIN, PARAM_NUMS_1, (uint8_t*)&result, &len); + SpiDrv::spiSlaveDeselect(); + + return result == 0; +} + +void BleDrv::bleEnd() { + WAIT_FOR_SLAVE_SELECT(); + + SpiDrv::sendCmd(BLE_END, PARAM_NUMS_0); + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + uint8_t len = 1; + uint8_t result = 0; + SpiDrv::waitResponseCmd(BLE_END, PARAM_NUMS_1, (uint8_t*)&result, &len); + SpiDrv::spiSlaveDeselect(); +} + +int BleDrv::bleAvailable() { + WAIT_FOR_SLAVE_SELECT(); + uint16_t result = 0; + + SpiDrv::sendCmd(BLE_AVAILABLE, PARAM_NUMS_0); + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + uint8_t len = 2; + SpiDrv::waitResponseCmd(BLE_AVAILABLE, PARAM_NUMS_1, (uint8_t*)&result, &len); + SpiDrv::spiSlaveDeselect(); + + return result; +} + +int BleDrv::bleRead(uint8_t data[], size_t length) { + WAIT_FOR_SLAVE_SELECT(); + + SpiDrv::sendCmd(BLE_READ, PARAM_NUMS_1); + + int commandSize = 7; // 4 for the normal command length + 3 for the parameter + uint16_t param = length; // TODO check length doesn't exceed 2^16 + SpiDrv::sendParam((uint8_t*)¶m, sizeof(param), LAST_PARAM); + + // pad to multiple of 4 + while (commandSize % 4 != 0) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + uint16_t res_len = 0; + SpiDrv::waitResponseData16(BLE_READ, data, (uint16_t*)&res_len); + + SpiDrv::spiSlaveDeselect(); + + return res_len; +} + +int BleDrv::blePeek(uint8_t data[], size_t length) { + WAIT_FOR_SLAVE_SELECT(); + + SpiDrv::sendCmd(BLE_PEEK, PARAM_NUMS_1); + + int commandSize = 7; // 4 for the normal command length + 3 for the parameter + uint16_t param = length; // TODO check length doesn't exceed 2^16 + SpiDrv::sendParam((uint8_t*)¶m, sizeof(param), LAST_PARAM); + + // pad to multiple of 4 + while (commandSize % 4 != 0) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + uint16_t res_len = 0; + SpiDrv::waitResponseData16(BLE_READ, data, (uint16_t*)&res_len); + + SpiDrv::spiSlaveDeselect(); + + return res_len; +} + +size_t BleDrv::bleWrite(const uint8_t* data, size_t len) { + WAIT_FOR_SLAVE_SELECT(); + + int commandSize = 4; + SpiDrv::sendCmd(BLE_WRITE, PARAM_NUMS_1); + + SpiDrv::sendBuffer((uint8_t*)data, len, LAST_PARAM); + commandSize += len+2; + + // pad to multiple of 4 + while (commandSize % 4 != 0) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + uint8_t res_len = 1; + uint16_t res = 0; + SpiDrv::waitResponseCmd(BLE_WRITE, PARAM_NUMS_1, (uint8_t*)&res, &res_len); + SpiDrv::spiSlaveDeselect(); + + return res; +} + + +BleDrv bleDrv; \ No newline at end of file diff --git a/src/utility/ble_drv.h b/src/utility/ble_drv.h new file mode 100644 index 00000000..8eeab162 --- /dev/null +++ b/src/utility/ble_drv.h @@ -0,0 +1,20 @@ + +#pragma once + +#include + + + +class BleDrv +{ +public: + static int bleBegin(); + static void bleEnd(); + static int bleAvailable(); + static int bleRead(uint8_t data[], size_t length); + static int blePeek(uint8_t data[], size_t length); + static size_t bleWrite(const uint8_t* data, size_t length); + +}; + +extern BleDrv bleDrv; diff --git a/src/utility/ble_spi.h b/src/utility/ble_spi.h new file mode 100644 index 00000000..486a22c5 --- /dev/null +++ b/src/utility/ble_spi.h @@ -0,0 +1,13 @@ +#pragma once + +enum { + + + BLE_BEGIN = 0x4A, + BLE_END = 0x4B, + BLE_AVAILABLE = 0x4C, + BLE_PEEK = 0x4D, + BLE_READ = 0x4E, + BLE_WRITE = 0x4F, + +}; \ No newline at end of file