From 6e951334cbf0a703c6a5a61972c9ed0de1fb4509 Mon Sep 17 00:00:00 2001 From: Giuseppe Roberti Date: Tue, 9 Aug 2022 10:17:09 +0200 Subject: [PATCH 1/4] Support BlueNRG-LP --- examples/Peripheral/ButtonLED/ButtonLED.ino | 13 +- keywords.txt | 2 +- src/utility/HCISpiTransport.cpp | 314 +++++++++++++++++--- src/utility/HCISpiTransport.h | 7 +- 4 files changed, 295 insertions(+), 41 deletions(-) diff --git a/examples/Peripheral/ButtonLED/ButtonLED.ino b/examples/Peripheral/ButtonLED/ButtonLED.ino index c3f777d4..f12adb50 100644 --- a/examples/Peripheral/ButtonLED/ButtonLED.ino +++ b/examples/Peripheral/ButtonLED/ButtonLED.ino @@ -6,7 +6,7 @@ represents the state of the button. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 You can use a generic BLE central app, like LightBlue (iOS and Android) or nRF Connect (Android), to interact with the services and characteristics @@ -17,7 +17,16 @@ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1); diff --git a/keywords.txt b/keywords.txt index 9214671b..e13de56d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -143,5 +143,5 @@ BLEUpdated LITERAL1 SPBTLE_RF LITERAL1 SPBTLE_1S LITERAL1 BLUENRG_M2SP LITERAL1 +BLUENRG_LP LITERAL1 BLEChip_t LITERAL1 - diff --git a/src/utility/HCISpiTransport.cpp b/src/utility/HCISpiTransport.cpp index a503b427..b2abddd4 100644 --- a/src/utility/HCISpiTransport.cpp +++ b/src/utility/HCISpiTransport.cpp @@ -33,6 +33,7 @@ HCISpiTransportClass::HCISpiTransportClass(SPIClass &spi, BLEChip_t ble_chip, ui _write_index = 0; _write_index_initial = 0; _initial_phase = 1; + _random_addr_done = false; } HCISpiTransportClass::~HCISpiTransportClass() @@ -66,7 +67,7 @@ int HCISpiTransportClass::begin() digitalWrite(_ble_rst, HIGH); delay(5); - if (_ble_chip == SPBTLE_RF || _ble_chip == BLUENRG_M0) { + if (_ble_chip == SPBTLE_RF || _ble_chip == BLUENRG_M0 || _ble_chip == BLUENRG_LP) { // Wait for Blue Initialize wait_for_blue_initialize(); } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { @@ -97,7 +98,7 @@ void HCISpiTransportClass::wait(unsigned long timeout) int HCISpiTransportClass::available() { - if (_ble_chip != SPBTLE_RF && _ble_chip != SPBTLE_1S && _ble_chip != BLUENRG_M2SP && _ble_chip != BLUENRG_M0) { + if (_ble_chip != SPBTLE_RF && _ble_chip != SPBTLE_1S && _ble_chip != BLUENRG_M2SP && _ble_chip != BLUENRG_M0 && _ble_chip != BLUENRG_LP) { return 0; } @@ -115,7 +116,7 @@ int HCISpiTransportClass::available() while (digitalRead(_spi_irq) == 1 && _write_index != BLE_MODULE_SPI_BUFFER_SIZE) { uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { detachInterrupt(_spi_irq); } @@ -172,7 +173,7 @@ int HCISpiTransportClass::available() } } } - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint16_t byte_count = (header_master[4] << 8) | header_master[3]; if (byte_count > 0) { @@ -222,13 +223,13 @@ int HCISpiTransportClass::available() _spi->endTransaction(); - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); } } if (ble_reset) { - if (_ble_chip == SPBTLE_RF || _ble_chip == BLUENRG_M0) { + if (_ble_chip == SPBTLE_RF || _ble_chip == BLUENRG_M0 || _ble_chip == BLUENRG_LP) { /* BLE chip was reset: we need to enable LL_ONLY */ enable_ll_only(); wait_for_enable_ll_only(); @@ -238,18 +239,32 @@ int HCISpiTransportClass::available() } /* Call Gatt Init and Gap Init to activate the random BLE address */ - aci_gatt_init(); - wait_for_aci_gatt_init(); - aci_gap_init(); - wait_for_aci_gap_init(); - /* Call Read Config Parameter to retrieve the random BLE address */ - aci_read_config_parameter(); - wait_for_aci_read_config_parameter(); - - /* Now we can update the write index and close the initial phase */ - _write_index = _write_index_initial; - _initial_phase = 0; - _write_index_initial = 0; + if (!_random_addr_done) { + aci_gatt_init(); + wait_for_aci_gatt_init(); + aci_gap_init(); + wait_for_aci_gap_init(); + /* Call Read Config Parameter to retrieve the random BLE address */ + aci_read_config_parameter(); + wait_for_aci_read_config_parameter(); + if (_ble_chip == BLUENRG_LP) { + hci_reset(); + _read_index = _write_index = _write_index_initial = 0; + _initial_phase = 1; + } else { + /* Now we can update the write index and close the initial phase */ + _write_index = _write_index_initial; + _initial_phase = 0; + _write_index_initial = 0; + } + } else { + set_address(); + wait_for_set_address(); + /* Now we can update the write index and close the initial phase */ + _write_index = _write_index_initial; + _initial_phase = 0; + _write_index_initial = 0; + } } if (_read_index != _write_index) { @@ -297,7 +312,7 @@ size_t HCISpiTransportClass::write(const uint8_t *data, size_t length) int result = 0; uint32_t tickstart = millis(); - if (_ble_chip != SPBTLE_RF && _ble_chip != SPBTLE_1S && _ble_chip != BLUENRG_M2SP && _ble_chip != BLUENRG_M0) { + if (_ble_chip != SPBTLE_RF && _ble_chip != SPBTLE_1S && _ble_chip != BLUENRG_M2SP && _ble_chip != BLUENRG_M0 && _ble_chip != BLUENRG_LP) { return 0; } @@ -332,7 +347,7 @@ size_t HCISpiTransportClass::write(const uint8_t *data, size_t length) result = -3; break; } - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint32_t tickstart_data_available = millis(); result = 0; @@ -406,7 +421,7 @@ void HCISpiTransportClass::wait_for_blue_initialize() while (digitalRead(_spi_irq) == 1) { uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { detachInterrupt(_spi_irq); } @@ -469,13 +484,38 @@ void HCISpiTransportClass::wait_for_blue_initialize() } } } + } else if (_ble_chip == BLUENRG_LP) { + uint8_t byte_count = (header_master[4] << 8) | header_master[3]; + + if (byte_count > 0) { + /* Read the response */ + if (byte_count == 7) { + for (int j = 0; j < byte_count; j++) { + event[j] = _spi->transfer(0xFF); + } + + if (event[0] == 0x82 && + event[1] == 0xFF && + event[2] == 0x03 && + event[3] == 0x00 && + event[4] == 0x01 && + event[5] == 0x00 && + event[6] == 0x01) { + event_blue_initialize = 1; + } + } else { + for (int j = 0; j < byte_count; j++) { + _spi->transfer(0xFF); + } + } + } } digitalWrite(_cs_pin, HIGH); _spi->endTransaction(); - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); } } @@ -498,7 +538,7 @@ void HCISpiTransportClass::wait_for_enable_ll_only() while (digitalRead(_spi_irq) == 1) { uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { detachInterrupt(_spi_irq); } @@ -534,7 +574,7 @@ void HCISpiTransportClass::wait_for_enable_ll_only() } } } - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint16_t byte_count = (header_master[4] << 8) | header_master[3]; if (byte_count > 0) { @@ -561,7 +601,7 @@ void HCISpiTransportClass::wait_for_enable_ll_only() _spi->endTransaction(); - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); } } @@ -601,7 +641,7 @@ void HCISpiTransportClass::enable_ll_only() digitalWrite(_cs_pin, HIGH); _spi->endTransaction(); - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint32_t tickstart_data_available = millis(); result = 0; @@ -660,7 +700,7 @@ void HCISpiTransportClass::wait_for_aci_gatt_init() while (digitalRead(_spi_irq) == 1) { uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { detachInterrupt(_spi_irq); } @@ -696,7 +736,7 @@ void HCISpiTransportClass::wait_for_aci_gatt_init() } } } - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint16_t byte_count = (header_master[4] << 8) | header_master[3]; if (byte_count > 0) { @@ -723,7 +763,7 @@ void HCISpiTransportClass::wait_for_aci_gatt_init() _spi->endTransaction(); - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); } } @@ -763,7 +803,7 @@ void HCISpiTransportClass::aci_gatt_init() digitalWrite(_cs_pin, HIGH); _spi->endTransaction(); - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint32_t tickstart_data_available = millis(); result = 0; @@ -822,7 +862,7 @@ void HCISpiTransportClass::wait_for_aci_gap_init() while (digitalRead(_spi_irq) == 1) { uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { detachInterrupt(_spi_irq); } @@ -858,7 +898,7 @@ void HCISpiTransportClass::wait_for_aci_gap_init() } } } - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint16_t byte_count = (header_master[4] << 8) | header_master[3]; if (byte_count > 0) { @@ -885,7 +925,7 @@ void HCISpiTransportClass::wait_for_aci_gap_init() _spi->endTransaction(); - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); } } @@ -896,6 +936,7 @@ void HCISpiTransportClass::aci_gap_init() { uint8_t header_master[5] = {0x0a, 0x00, 0x00, 0x00, 0x00}; uint8_t cmd[7] = {0x01, 0x8A, 0xFC, 0x03, 0x0F, 0x00, 0x00}; // ACI_GAP_INIT + uint8_t cmd_lp[8] = {0x01, 0x8A, 0xFC, 0x04, 0x0F, 0x00, 0x00, 0x00}; // ACI_GAP_INIT for BlueNRG-LP int result = 0; do { @@ -963,6 +1004,45 @@ void HCISpiTransportClass::aci_gap_init() _spi->endTransaction(); + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); + } else if (_ble_chip == BLUENRG_LP) { + uint32_t tickstart_data_available = millis(); + result = 0; + + detachInterrupt(_spi_irq); + + _spi->beginTransaction(_spiSettings); + + digitalWrite(_cs_pin, LOW); + + while (!(digitalRead(_spi_irq) == 1)) { + if ((millis() - tickstart_data_available) > 1000) { + result = -3; + break; + } + } + + if (result == -3) { + digitalWrite(_cs_pin, HIGH); + _spi->endTransaction(); + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); + break; + } + + /* Write the header */ + _spi->transfer(header_master, 5); + + if ((int)((((uint16_t)header_master[2]) << 8) | ((uint16_t)header_master[1])) >= 8) { + /* Write the data */ + _spi->transfer((void *)cmd_lp, 8); + } else { + result = -2; + } + + digitalWrite(_cs_pin, HIGH); + + _spi->endTransaction(); + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); } } while (result < 0); @@ -984,7 +1064,7 @@ void HCISpiTransportClass::wait_for_aci_read_config_parameter() while (digitalRead(_spi_irq) == 1) { uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { detachInterrupt(_spi_irq); } @@ -1021,7 +1101,7 @@ void HCISpiTransportClass::wait_for_aci_read_config_parameter() } } } - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint16_t byte_count = (header_master[4] << 8) | header_master[3]; if (byte_count > 0) { @@ -1040,6 +1120,7 @@ void HCISpiTransportClass::wait_for_aci_read_config_parameter() data[6] == 0x00) { memcpy(_random_addr, &data[8], 6); status = 1; + _random_addr_done = true; } } } @@ -1049,7 +1130,7 @@ void HCISpiTransportClass::wait_for_aci_read_config_parameter() _spi->endTransaction(); - if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); } } @@ -1089,7 +1170,7 @@ void HCISpiTransportClass::aci_read_config_parameter() digitalWrite(_cs_pin, HIGH); _spi->endTransaction(); - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint32_t tickstart_data_available = millis(); result = 0; @@ -1131,3 +1212,162 @@ void HCISpiTransportClass::aci_read_config_parameter() } } while (result < 0); } + +void HCISpiTransportClass::hci_reset() +{ + uint8_t header_master[5] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + uint8_t cmd[4] = {0x01, 0x03, 0x0C, 0x00}; // HCI_RESET + int result = 0; + + do { + if (_ble_chip == BLUENRG_LP) { + uint32_t tickstart_data_available = millis(); + result = 0; + + detachInterrupt(_spi_irq); + + _spi->beginTransaction(_spiSettings); + + digitalWrite(_cs_pin, LOW); + + while (!(digitalRead(_spi_irq) == 1)) { + if ((millis() - tickstart_data_available) > 1000) { + result = -3; + break; + } + } + + if (result == -3) { + digitalWrite(_cs_pin, HIGH); + _spi->endTransaction(); + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); + break; + } + + /* Write the header */ + _spi->transfer(header_master, 5); + + if ((int)((((uint16_t)header_master[2]) << 8) | ((uint16_t)header_master[1])) >= 4) { + /* Write the data */ + _spi->transfer((void *)cmd, 4); + } else { + result = -2; + } + + digitalWrite(_cs_pin, HIGH); + + _spi->endTransaction(); + + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); + } + } while (result < 0); +} + +void HCISpiTransportClass::set_address() +{ + uint8_t header_master[5] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + uint8_t cmd[10] = {0x01, 0x05, 0x20, 0x06}; // SET ADDR + int result = 0; + memcpy(&cmd[4], _random_addr, 6); + + do { + if (_ble_chip == BLUENRG_LP) { + uint32_t tickstart_data_available = millis(); + result = 0; + + detachInterrupt(_spi_irq); + + _spi->beginTransaction(_spiSettings); + + digitalWrite(_cs_pin, LOW); + + while (!(digitalRead(_spi_irq) == 1)) { + if ((millis() - tickstart_data_available) > 1000) { + result = -3; + break; + } + } + + if (result == -3) { + digitalWrite(_cs_pin, HIGH); + _spi->endTransaction(); + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); + break; + } + + /* Write the header */ + _spi->transfer(header_master, 5); + + if ((int)((((uint16_t)header_master[2]) << 8) | ((uint16_t)header_master[1])) >= 10) { + /* Write the data */ + _spi->transfer((void *)cmd, 10); + } else { + result = -2; + } + + digitalWrite(_cs_pin, HIGH); + + _spi->endTransaction(); + + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); + } + } while (result < 0); +} + +void HCISpiTransportClass::wait_for_set_address() +{ + uint8_t data[15]; + int status = 0; + + if (_ble_chip != BLUENRG_LP) return; + + do { + while (!data_avail); + + if (digitalRead(_spi_irq) == 0) { + continue; + } + + data_avail = 0; + while (digitalRead(_spi_irq) == 1) { + uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint16_t byte_count = 0; + + detachInterrupt(_spi_irq); + + _spi->beginTransaction(_spiSettings); + + digitalWrite(_cs_pin, LOW); + + /* Write the header */ + _spi->transfer(header_master, 5); + + byte_count = (header_master[4] << 8) | header_master[3]; + + if (byte_count > 0) { + /* Read the response */ + for (int j = 0; j < byte_count; j++) { + data[j] = _spi->transfer(0xFF); + } + + if (byte_count >= 7) { // 040E0401052000 + if (data[0] == 0x04 && + data[1] == 0x0E && + data[2] == 0x04 && + data[3] == 0x01 && + data[4] == 0x05 && + data[5] == 0x20 && + data[6] == 0x00) { + status = 1; + } + } + } + + digitalWrite(_cs_pin, HIGH); + + _spi->endTransaction(); + + attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); + } + } while (!status); +} diff --git a/src/utility/HCISpiTransport.h b/src/utility/HCISpiTransport.h index 9c3afc34..34af1aa9 100644 --- a/src/utility/HCISpiTransport.h +++ b/src/utility/HCISpiTransport.h @@ -27,7 +27,8 @@ typedef enum BLEChip_s { SPBTLE_RF, SPBTLE_1S, BLUENRG_M2SP, - BLUENRG_M0 + BLUENRG_M0, + BLUENRG_LP } BLEChip_t; #ifndef BLE_SPI_BYTE_ORDER @@ -61,6 +62,9 @@ class HCISpiTransportClass : public HCITransportInterface { void aci_gap_init(); void wait_for_aci_read_config_parameter(); void aci_read_config_parameter(); + void hci_reset(); + void set_address(); + void wait_for_set_address(); SPIClass *_spi; SPISettings _spiSettings; BLEChip_t _ble_chip; @@ -73,6 +77,7 @@ class HCISpiTransportClass : public HCITransportInterface { uint16_t _write_index_initial; uint8_t _initial_phase; uint8_t _random_addr[6]; + bool _random_addr_done; }; #endif /* _HCI_SPI_TRANSPORT_H_ */ From 9cf284f8ce05446b1e0064bff07fd4e83b0075f5 Mon Sep 17 00:00:00 2001 From: Giuseppe Roberti Date: Tue, 9 Aug 2022 13:34:06 +0200 Subject: [PATCH 2/4] Ugly fix delay --- src/utility/HCISpiTransport.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/utility/HCISpiTransport.cpp b/src/utility/HCISpiTransport.cpp index b2abddd4..eae96911 100644 --- a/src/utility/HCISpiTransport.cpp +++ b/src/utility/HCISpiTransport.cpp @@ -113,6 +113,11 @@ int HCISpiTransportClass::available() data_avail = 0; + // Wait for BlueNRG-LP to be ready (needs to be done after each HCI RESET) + if (_ble_chip == BLUENRG_LP && _initial_phase) { + delay(100); + } + while (digitalRead(_spi_irq) == 1 && _write_index != BLE_MODULE_SPI_BUFFER_SIZE) { uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; From 831e996f17f82efec25149e39ca8655f65dbdb05 Mon Sep 17 00:00:00 2001 From: Giuseppe Roberti Date: Tue, 9 Aug 2022 16:32:20 +0200 Subject: [PATCH 3/4] LP only differ in cmd, not procedure --- src/utility/HCISpiTransport.cpp | 61 ++++++++------------------------- 1 file changed, 15 insertions(+), 46 deletions(-) diff --git a/src/utility/HCISpiTransport.cpp b/src/utility/HCISpiTransport.cpp index eae96911..5c18083f 100644 --- a/src/utility/HCISpiTransport.cpp +++ b/src/utility/HCISpiTransport.cpp @@ -940,8 +940,16 @@ void HCISpiTransportClass::wait_for_aci_gap_init() void HCISpiTransportClass::aci_gap_init() { uint8_t header_master[5] = {0x0a, 0x00, 0x00, 0x00, 0x00}; - uint8_t cmd[7] = {0x01, 0x8A, 0xFC, 0x03, 0x0F, 0x00, 0x00}; // ACI_GAP_INIT - uint8_t cmd_lp[8] = {0x01, 0x8A, 0xFC, 0x04, 0x0F, 0x00, 0x00, 0x00}; // ACI_GAP_INIT for BlueNRG-LP + uint8_t cmd_lp[8] = {0x01, 0x8A, 0xFC, 0x04, 0x0F, 0x00, 0x00, 0x00}; // ACI_GAP_INIT + uint8_t cmd_others[7] = {0x01, 0x8A, 0xFC, 0x03, 0x0F, 0x00, 0x00}; // ACI_GAP_INIT + uint8_t *cmd, cmd_size; + if (_ble_chip == BLUENRG_LP) { + cmd = cmd_lp; + cmd_size = 8; + } else { + cmd = cmd_others; + cmd_size = 7; + } int result = 0; do { @@ -958,9 +966,9 @@ void HCISpiTransportClass::aci_gap_init() /* device is ready */ if (header_master[0] == 0x02) { /* Write the data */ - if (header_master[1] >= 7) { + if (header_master[1] >= cmd_size) { /* Write the data */ - _spi->transfer((void *)cmd, 7); + _spi->transfer((void *)cmd, cmd_size); } else { result = -2; } @@ -971,46 +979,7 @@ void HCISpiTransportClass::aci_gap_init() digitalWrite(_cs_pin, HIGH); _spi->endTransaction(); - } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP) { - uint32_t tickstart_data_available = millis(); - result = 0; - - detachInterrupt(_spi_irq); - - _spi->beginTransaction(_spiSettings); - - digitalWrite(_cs_pin, LOW); - - while (!(digitalRead(_spi_irq) == 1)) { - if ((millis() - tickstart_data_available) > 1000) { - result = -3; - break; - } - } - - if (result == -3) { - digitalWrite(_cs_pin, HIGH); - _spi->endTransaction(); - attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); - break; - } - - /* Write the header */ - _spi->transfer(header_master, 5); - - if ((int)((((uint16_t)header_master[2]) << 8) | ((uint16_t)header_master[1])) >= 7) { - /* Write the data */ - _spi->transfer((void *)cmd, 7); - } else { - result = -2; - } - - digitalWrite(_cs_pin, HIGH); - - _spi->endTransaction(); - - attachInterrupt(_spi_irq, SPI_Irq_Callback, RISING); - } else if (_ble_chip == BLUENRG_LP) { + } else if (_ble_chip == SPBTLE_1S || _ble_chip == BLUENRG_M2SP || _ble_chip == BLUENRG_LP) { uint32_t tickstart_data_available = millis(); result = 0; @@ -1037,9 +1006,9 @@ void HCISpiTransportClass::aci_gap_init() /* Write the header */ _spi->transfer(header_master, 5); - if ((int)((((uint16_t)header_master[2]) << 8) | ((uint16_t)header_master[1])) >= 8) { + if ((int)((((uint16_t)header_master[2]) << 8) | ((uint16_t)header_master[1])) >= cmd_size) { /* Write the data */ - _spi->transfer((void *)cmd_lp, 8); + _spi->transfer((void *)cmd, cmd_size); } else { result = -2; } From 93af438927ffc0119caf0b2b4d4c300da3dee364 Mon Sep 17 00:00:00 2001 From: Giuseppe Roberti Date: Tue, 30 Aug 2022 14:51:20 +0200 Subject: [PATCH 4/4] Enable STEVAL-MKBOXPRO support in examples --- examples/Central/LedControl/LedControl.ino | 13 +++++++++++-- .../PeripheralExplorer/PeripheralExplorer.ino | 13 +++++++++++-- examples/Central/Scan/Scan.ino | 13 +++++++++++-- examples/Central/ScanCallback/ScanCallback.ino | 13 +++++++++++-- .../Central/SensorTagButton/SensorTagButton.ino | 13 +++++++++++-- examples/Peripheral/CallbackLED/CallbackLED.ino | 13 +++++++++++-- examples/Peripheral/LED/LED.ino | 13 +++++++++++-- 7 files changed, 77 insertions(+), 14 deletions(-) diff --git a/examples/Central/LedControl/LedControl.ino b/examples/Central/LedControl/LedControl.ino index 2f64bc28..d0f73383 100644 --- a/examples/Central/LedControl/LedControl.ino +++ b/examples/Central/LedControl/LedControl.ino @@ -6,7 +6,7 @@ it will remotely control the BLE Peripheral's LED, when the button is pressed or released. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 You can use it with another board that is compatible with this library and the Peripherals -> LED example. @@ -16,7 +16,16 @@ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1); diff --git a/examples/Central/PeripheralExplorer/PeripheralExplorer.ino b/examples/Central/PeripheralExplorer/PeripheralExplorer.ino index e5461fa5..ea8b3b24 100644 --- a/examples/Central/PeripheralExplorer/PeripheralExplorer.ino +++ b/examples/Central/PeripheralExplorer/PeripheralExplorer.ino @@ -5,7 +5,7 @@ is found. Then connects, and discovers + prints all the peripheral's attributes. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 You can use it with another board that is compatible with this library and the Peripherals -> LED example. @@ -15,7 +15,16 @@ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1); diff --git a/examples/Central/Scan/Scan.ino b/examples/Central/Scan/Scan.ino index bf1bef5f..bd22c65e 100644 --- a/examples/Central/Scan/Scan.ino +++ b/examples/Central/Scan/Scan.ino @@ -5,14 +5,23 @@ address, local name, advertised service UUID's. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 This example code is in the public domain. */ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1); diff --git a/examples/Central/ScanCallback/ScanCallback.ino b/examples/Central/ScanCallback/ScanCallback.ino index 4d9bbc77..dbc2536e 100644 --- a/examples/Central/ScanCallback/ScanCallback.ino +++ b/examples/Central/ScanCallback/ScanCallback.ino @@ -7,14 +7,23 @@ reported for every single advertisement it makes. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 This example code is in the public domain. */ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1); diff --git a/examples/Central/SensorTagButton/SensorTagButton.ino b/examples/Central/SensorTagButton/SensorTagButton.ino index c6377f9f..1831b172 100644 --- a/examples/Central/SensorTagButton/SensorTagButton.ino +++ b/examples/Central/SensorTagButton/SensorTagButton.ino @@ -8,7 +8,7 @@ outputted to the Serial Monitor when one is pressed. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 - TI SensorTag This example code is in the public domain. @@ -16,7 +16,16 @@ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1); diff --git a/examples/Peripheral/CallbackLED/CallbackLED.ino b/examples/Peripheral/CallbackLED/CallbackLED.ino index 28bf40a8..363d804b 100644 --- a/examples/Peripheral/CallbackLED/CallbackLED.ino +++ b/examples/Peripheral/CallbackLED/CallbackLED.ino @@ -6,7 +6,7 @@ library are used. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 You can use a generic BLE central app, like LightBlue (iOS and Android) or nRF Connect (Android), to interact with the services and characteristics @@ -17,7 +17,16 @@ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1); diff --git a/examples/Peripheral/LED/LED.ino b/examples/Peripheral/LED/LED.ino index 2ea0e5ae..48de79d7 100644 --- a/examples/Peripheral/LED/LED.ino +++ b/examples/Peripheral/LED/LED.ino @@ -5,7 +5,7 @@ characteristic to control an LED. The circuit: - - STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 + - STEVAL-MKBOXPRO, STEVAL-MKSBOX1V1, B-L475E-IOT01A1, B_L4S5I_IOT01A, or a Nucleo board plus the X-NUCLEO-IDB05A2 or the X-NUCLEO-IDB05A1 or the X-NUCLEO-BNRG2A1 You can use a generic BLE central app, like LightBlue (iOS and Android) or nRF Connect (Android), to interact with the services and characteristics @@ -15,7 +15,16 @@ */ #include -#if defined(ARDUINO_STEVAL_MKSBOX1V1) +#if defined(ARDUINO_STEVAL_MKBOXPRO) +/* STEVAL-MKBOXPRO */ +SPIClass SpiHCI(PA7, PA6, PA5); +HCISpiTransportClass HCISpiTransport(SpiHCI, BLUENRG_LP, PA2, PB11, PD4, 1000000, SPI_MODE3); +#if !defined(FAKE_BLELOCALDEVICE) +BLELocalDevice BLEObj(&HCISpiTransport); +BLELocalDevice& BLE = BLEObj; +#endif +const int buttonPin = PC13; // set buttonPin to digital pin PC13 +#elif defined(ARDUINO_STEVAL_MKSBOX1V1) /* STEVAL-MKSBOX1V1 */ SPIClass SpiHCI(PC3, PD3, PD1); HCISpiTransportClass HCISpiTransport(SpiHCI, SPBTLE_1S, PD0, PD4, PA8, 1000000, SPI_MODE1);