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/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/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); 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..5c18083f 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; } @@ -112,10 +113,15 @@ 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}; - 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 +178,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 +228,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 +244,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 +317,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 +352,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 +426,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 +489,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 +543,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 +579,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 +606,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 +646,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 +705,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 +741,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 +768,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 +808,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 +867,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 +903,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 +930,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); } } @@ -895,7 +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 + 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 { @@ -912,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; } @@ -925,7 +979,7 @@ void HCISpiTransportClass::aci_gap_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; @@ -952,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])) >= 7) { + if ((int)((((uint16_t)header_master[2]) << 8) | ((uint16_t)header_master[1])) >= cmd_size) { /* Write the data */ - _spi->transfer((void *)cmd, 7); + _spi->transfer((void *)cmd, cmd_size); } else { result = -2; } @@ -984,7 +1038,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 +1075,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 +1094,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 +1104,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 +1144,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 +1186,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_ */