From 7a8cc0243ffb7011d2100091025572bd73e3c5f2 Mon Sep 17 00:00:00 2001 From: Vincent Coubard Date: Wed, 4 Jul 2018 12:15:26 +0100 Subject: [PATCH 1/9] Cordio Documentation: Explain how to tests and what tools are available. --- .../targets/TARGET_CORDIO/doc/PortingGuide.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index 9f98386311..a25853150b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -489,6 +489,26 @@ ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() { } ``` +### Tests + +Greentea tests are bundled with the cordio port of BLE API to ensure that the transport driver works as expected as well as validate the cordio stack initialization. You can run them with the following command: + +``` +mbed test -t -m -n mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver,mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport +``` + +* mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport: Ensure that the transport is able to send an HCI reset command and receive the corresponding HCI status event. +* mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver: Runs the whole initialization process then ensure the cordio stack has been properly initialized by the HCI driver. + + +### Tools + +The application [mbed-os-cordio-hci-passthrough](https://github.com/ARMmbed/mbed-os-cordio-hci-passthrough) can be used to _proxify_ a Bluetooth controller connected to an mbed board. + +Bytes sent by the host over the board serial are forwarded to the controller with the help of the `HCITransportDriver` while bytes sent by the controller are sent back to the host through the board serial. + +This application can be used to validate the transport driver and debug the initialization process on a PC host. + From bae4c89d0f3076970acbe9036fad463f4f0b4ac4 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Mon, 9 Jul 2018 15:06:11 +0300 Subject: [PATCH 2/9] Remove shall, whole lotta other changes. Not done yet. --- .../targets/TARGET_CORDIO/doc/PortingGuide.md | 282 +++++++++--------- 1 file changed, 133 insertions(+), 149 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index a25853150b..27819eb55c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -1,91 +1,94 @@ -# Porting guide +# Porting guide -Enabling the mbed BLE Cordio port for a given target is a two step process: -* The target shall be configured to include Cordio BLE port and Cordio libraries -during the build process. -* An implementation of the `CordioHCIDriver` class targeting the bluetooth -controller used shall be provided. +There are two main steps to enable the Mbed BLE Cordio port for a given target: -## Target configuration +1. Configure the target to include Cordio BLE port and Cordio libraries +during the build process. -This step happens in the file defining all mbed os targets. The file is located -in `targets/target.json`. +1. Implement `CordioHCIDriver` class targeting the Bluetooth controller. -### Add BLE feature +[[[Do we want something like this at the beginning? Why not just give the steps, instead of summarizing them?]]] -First of all support for BLE has to be added to the target. This is achieved by -adding the string `BLE` in the list of `features` of the target. Once this -value has been added the sources of BLE api are added to the list of sources -compiled for the target. +## Configure the target -```json +Define all Mbed OS targets in the `targets/target.json` file: + +* Add BLE support to the target: + + * Add the string `BLE` to the target's list of `features`. This adds the BLE API sources to the list of sources compiled for the target. + +``` "TARGET_NAME": { "features": ["target features ...", "BLE"] } ``` -### Include Cordio BLE implementation +### Include Cordio BLE implementation -The target should also compile the sources of the BLE Cordio port. It is -achieved by adding the string `CORDIO` in the list of the `extra_labels` -property of the target. +* Compile the BLE Cordio port sources: -```json +[[[sources?]]] + + * Add the string `CORDIO` to the `extra_labels` property of the JSON file. + +``` "TARGET_NAME": { "extra_labels": ["target extra labels ...", "CORDIO"], "features": ["target features ...", "BLE"] } ``` -## CordioHCIDriver implementation: +## Implement CordioHCIDriver: -A port shall include an HCI driver for the BLE module used by the target and -a factory function which create the BLE instance used by the user of BLE API. +Include an HCI driver for the BLE module used by the target and a factory function which creates the BLE instance used by the user of the BLE API. -### Create source folder +### Create source folder -The port shall live in the folder of BLE API which host targets port : -`features/FEATURE_BLE/targets`. +Create a `TARGET_` folder. -To isolate the port code from other code a folder containing the port code has -to be created. The name of this folder shall start with `TARGET_` and end with +The port shall live in the folder of BLE API which host targets port : +`features/FEATURE_BLE/targets`. + +You need to create a folder containing the port code to isolate it from other code. Name + +To isolate the port code from other code, a folder containing the port code has +to be created. The name of this folder shall start with `TARGET_` and end with the target name in capital. ### Create the HCI driver -The HCI driver is split in two entities: one which handle HCI communication with -the Bluetooth module and the other handling the initialization, reset sequence +The HCI driver is split in two entities: one which handle HCI communication with +the Bluetooth module and the other handling the initialization, reset sequence and memory dedicated for the Bluetooth controller. -More information about the architecture can be found in the +More information about the architecture can be found in the [HCI abstraction architecture](HCIAbstraction.md) document. -#### HCITransport +#### HCITransport -> **Note:** If the Bluetooth controller uses an H4 communication interface and -the host exposes serial flow control in mbed then this step can be skipped and -the class `ble::vendor::cordio::H4TransportDriver` can be used as the transport -driver. +**Note:** If the Bluetooth controller uses an H4 communication interface and +the host exposes serial flow control in Mbed, then you can skip this step. Use the class `ble::vendor::cordio::H4TransportDriver` as the transport +driver. -An empty transport driver can be coded as: +You can code an empty transport driver as: -```c++ +``` #include "CordioHCITransportDriver.h" -namespace ble { +namespace ble { namespace vendor { -namespace target_name { +namespace target_name { -class TransportDriver : public cordio::CordioHCITransportDriver { -public: +class TransportDriver : public cordio::CordioHCITransportDriver { +public: TransportDriver(/* specific constructor arguments*/); virtual ~TransportDriver(); virtual void initialize(); - virtual void terminate(); - + virtual void terminate(); + virtual uint16_t write(uint8_t packet_type, uint16_t len, uint8_t *data); private: @@ -97,40 +100,42 @@ private: } // namespace ble ``` -It shall inherits publicly from the base class `CordioHCITransportDriver`. +It inherits publicly from the base class `CordioHCITransportDriver`. -* **Initialization/termination:** The functions `initialize` and `terminate` are -responsible for initializing and terminating the transport driver. It is not +[[[still don't know what this means]]] + +* **Initialization/termination:** The functions `initialize` and `terminate` are +responsible for initializing and terminating the transport driver. It is not necessary to initialize the transport in the constructor. -* **Sending data** The function `write` shall sends data in input to the -Bluetooth controller and return the number of bytes in the `data` buffer sent. -Depending on the type of transport being implemented, the packet `type` might +* **Sending data** The function `write` shall sends data in input to the +Bluetooth controller and return the number of bytes in the `data` buffer sent. +Depending on the type of transport being implemented, the packet `type` might have to be sent to the controller before the packet data. -* **Receiving data**: HCI data from the Bluetooth controller shall be injected -in the system by invoking the function `on_data_received`. This function is -a static one and is provided by the base class. Its prototype is: +* **Receiving data**: HCI data from the Bluetooth controller shall be injected +in the system by invoking the function `on_data_received` injects . This function is +a static one and is provided by the base class. Its prototype is: -```c++ +``` void on_data_received(uint8_t* data_received, uint16_t length_of_data_received); ``` -#### HCIDriver +#### HCIDriver -The skeleton of driver is: +The skeleton of driver is: -```c++ +``` #include "CordioHCIDriver.h" -namespace ble { +namespace ble { namespace vendor { -namespace target_name { +namespace target_name { -class HCIDriver : public cordio::CordioHCIDriver { -public: +class HCIDriver : public cordio::CordioHCIDriver { +public: HCIDriver( - cordio::CordioHCITransportDriver& transport_driver, + cordio::CordioHCITransportDriver& transport_driver, /* specific constructor arguments*/ ); @@ -144,7 +149,7 @@ public: virtual void start_reset_sequence(); - virtual void handle_reset_sequence(uint8_t *msg); + virtual void handle_reset_sequence(uint8_t \*msg); private: // private driver declarations }; @@ -154,21 +159,16 @@ private: } // namespace ble ``` -##### Initialization process +##### Initialization process -The initialization/termination process is achieved by the couple of functions -`do_initialize` and `do_terminate`. Those function manages the state of the -bluetooth controller. +The functions `do_initialize` and `do_terminate` handle initialization and termination processes. These functions manage the state of the Bluetooth controller. -> **Important:** It is unnecessary to initialize or terminate the hci transport -in those function because it is handled by the base class. The HCI transport is -initialized right before the call to `do_initialize` and is terminated right -after the call to `do_terminate`. +**Note:** It is unnecessary to initialize or terminate the HCI transport in those function because it is handled by the base class. The HCI transport is initialized right before the call to `do_initialize` and is terminated right +after the call to `do_terminate`. -##### Memory pool +##### Memory pool -The implementation of the function `get_buffer_pool_description` in the base -class will return a buffer of 1040 bytes divided in different memory pools: +The function `get_buffer_pool_description` in the base class returns a buffer of 1040 bytes divided in different memory pools: | Chunk size (bytes) | Number of chunks | |--------------------|------------------| @@ -178,11 +178,11 @@ class will return a buffer of 1040 bytes divided in different memory pools: | 128 | 2 | | 272 | 1 | -A port shall override this function if the memory provided by the base class -doesn't match what is required by the Bluetooth controller driven. +A port overrides this function if the memory provided by the base class +doesn't match what is required by the Bluetooth controller driver. -```c++ -buf_pool_desc_t CordioHCIDriver::get_buffer_pool_description() { +``` +buf_pool_desc_t CordioHCIDriver::get_buffer_pool_description() { static uint8_t buffer[/* buffer size */]; static const wsfBufPoolDesc_t pool_desc[] = { { /* chunk size */, /* number of chunks */ }, @@ -195,70 +195,70 @@ buf_pool_desc_t CordioHCIDriver::get_buffer_pool_description() { }; return buf_pool_desc_t(buffer, pool_desc); -} +} ``` -##### Reset sequence +##### Reset sequence -The reset sequence process is handled by three functions: +The reset sequence process is handled by three functions: -* `start_reset_sequence`: This function start the process. The basic -implementation sends an HCI reset command to the Bluetooth controller. The +* `start_reset_sequence`: This function start the process. The basic +implementation sends an HCI reset command to the Bluetooth controller. The function shall be overridden in the driver if the bluetooth controller requires -more than just sending the standard reset command. +more than just sending the standard reset command. * `handle_reset_sequence`: Entry point to the state machine handling the reset -process. Every time an HCI packet is received during the reset sequence, this -function is called with the HCI packet received. It's purpose is to prepare the +process. Every time an HCI packet is received during the reset sequence, this +function is called with the HCI packet received. Its purpose is to prepare the Bluetooth controller and set the parameters the stack needs to operate properly. This function can be overridden if necessary. -* `signal_reset_sequence_done`: This function shall be called once the reset +* `signal_reset_sequence_done`: This function shall be called once the reset sequence is achieved. It cannot be overridden. -###### Controller parameters to set +###### Controller parameters to set This instruct the controller which events are relevant for the stack. -The following parameters should be set in the controller (if supported): -* event mask: The reset sequence should issue the call +The following parameters should be set in the controller (if supported): +* event mask: The reset sequence should issue the call `HciSetEventMaskCmd((uint8_t *) hciEventMask)` -* LE event mask: The call `HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask)` +* LE event mask: The call `HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask)` should be issued. -* 2nd page of events mask: Can be achieved by invoking +* 2nd page of events mask: Can be achieved by invoking `HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2)`. ###### Stack runtime parameters -Some stack parameters shall be acquired at runtime from the controller: +Some stack parameters shall be acquired at runtime from the controller: -* Bluetooth address: Can be queried with `HciReadBdAddrCmd`. Response shall be +* Bluetooth address: Can be queried with `HciReadBdAddrCmd`. Response shall be copied into `hciCoreCb.bdAddr` with `BdaCpy`. -* Buffer size of the controller: Can be obtained by `HciLeReadBufSizeCmd`. The -return parameter *HC_ACL_Data_Packet_Length* shall be copied into -`hciCoreCb.bufSize` and the response parameter -`HC_Synchronous_Data_Packet_Length`shall be copied into `hciCoreCb.numBufs`. +* Buffer size of the controller: Can be obtained by `HciLeReadBufSizeCmd`. The +return parameter *HC_ACL_Data_Packet_Length* shall be copied into +`hciCoreCb.bufSize` and the response parameter +`HC_Synchronous_Data_Packet_Length` shall be copied into `hciCoreCb.numBufs`. The value of `hciCoreCb.availBufs` shall be initialized with `hciCoreCb.numBufs`. -* Supported state: Queried with `HciLeReadSupStatesCmd`, the response shall go +* Supported state: Queried with `HciLeReadSupStatesCmd`, the response shall go into `hciCoreCb.leStates`. * Whitelist size: Queried with `HciLeReadWhiteListSizeCmd` the response shall go into `hciCoreCb.whiteListSize`. -* LE features supported: Obtained with `HciLeReadLocalSupFeatCmd`. The response +* LE features supported: Obtained with `HciLeReadLocalSupFeatCmd`. The response shall be stored into `hciCoreCb.leSupFeat`. * Resolving list size: Obtained with `hciCoreReadResolvingListSize`. The response shall go into `hciCoreCb.resListSize`. * Max data length: Acquired with `hciCoreReadMaxDataLen`. The response parameter -`supportedMaxTxOctets` and `supportedMaxTxTime` shall be pass to the function +`supportedMaxTxOctets` and `supportedMaxTxTime` shall be pass to the function `HciLeWriteDefDataLen`. -The default implementation is: +The default implementation is: -```c++ -void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { - // only accept command complete event: - if (*pMsg != HCI_CMD_CMPL_EVT) { +``` +void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { + // only accept command complete event: + if (*pMsg != HCI_CMD_CMPL_EVT) { return; } @@ -277,30 +277,30 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { case HCI_OPCODE_RESET: /* initialize rand command count */ randCnt = 0; - // set the event mask to control which events are generated by the + // set the event mask to control which events are generated by the // controller for the host HciSetEventMaskCmd((uint8_t *) hciEventMask); break; case HCI_OPCODE_SET_EVENT_MASK: - // set the event mask to control which LE events are generated by + // set the event mask to control which LE events are generated by // the controller for the host HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask); break; case HCI_OPCODE_LE_SET_EVENT_MASK: - // set the event mask to control which events are generated by the + // set the event mask to control which events are generated by the // controller for the host (2nd page of flags ) HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2); break; case HCI_OPCODE_SET_EVENT_MASK_PAGE2: - // Ask the Bluetooth address of the controller + // Ask the Bluetooth address of the controller HciReadBdAddrCmd(); break; case HCI_OPCODE_READ_BD_ADDR: - // Store the Bluetooth address in the stack runtime parameter + // Store the Bluetooth address in the stack runtime parameter BdaCpy(hciCoreCb.bdAddr, pMsg); // Read the size of the buffer of the controller @@ -315,23 +315,23 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { /* initialize ACL buffer accounting */ hciCoreCb.availBufs = hciCoreCb.numBufs; - // read the states and state combinations supported by the link + // read the states and state combinations supported by the link // layer of the controller HciLeReadSupStatesCmd(); break; case HCI_OPCODE_LE_READ_SUP_STATES: - // store supported state and combination in the runtime parameters + // store supported state and combination in the runtime parameters // of the stack memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN); - // read the total of whitelist entries that can be stored in the + // read the total of whitelist entries that can be stored in the // controller. HciLeReadWhiteListSizeCmd(); break; case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE: - // store the number of whitelist entries in the stack runtime + // store the number of whitelist entries in the stack runtime // parameters BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg); @@ -343,17 +343,17 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { // Store the set of LE features supported by the controller BSTREAM_TO_UINT16(hciCoreCb.leSupFeat, pMsg); - // read the total number of address translation entries which can be + // read the total number of address translation entries which can be // stored in the controller resolving list. hciCoreReadResolvingListSize(); break; case HCI_OPCODE_LE_READ_RES_LIST_SIZE: - // store the number of address translation entries in the stack + // store the number of address translation entries in the stack // runtime parameter BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg); - // read the Controller’s maximum supported payload octets and packet + // read the Controller’s maximum supported payload octets and packet // duration times for transmission and reception hciCoreReadMaxDataLen(); break; @@ -392,11 +392,11 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { HciLeRandCmd(); } break; - + case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN: case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS: case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE: - // handle extended command + // handle extended command if (hciCoreCb.extResetSeq) { /* send next extended command in sequence */ @@ -462,21 +462,21 @@ static void hciCoreReadResolvingListSize(void) ### HCI accessor function -The HCI driver is injected in the `CordioBLE` class at construction site. -Given that the CordioBLE class doesn't know what class shall be used to -construct the driver nor it knows how to construct it, the port shall provide a -function returning a reference to the HCI driver. +The HCI driver is injected in the `CordioBLE` class at construction site. +Given that the CordioBLE class doesn't know what class shall be used to +construct the driver nor it knows how to construct it, the port shall provide a +function returning a reference to the HCI driver. -This function lives in the global namespace and its signature is: +This function lives in the global namespace and its signature is: -```c++ +``` ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver(); ``` -A common implementation might be: +A common implementation might be: -```c++ -ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() { +``` +ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() { static ble::vendor::target_name::TransportDriver transport_driver( /* transport parameters */ ); @@ -491,36 +491,20 @@ ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() { ### Tests -Greentea tests are bundled with the cordio port of BLE API to ensure that the transport driver works as expected as well as validate the cordio stack initialization. You can run them with the following command: +Greentea tests are bundled with the Cordio port of the BLE API so the transport driver works as expected as well as validate the Cordio stack initialization. You can run them with the following command: ``` mbed test -t -m -n mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver,mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport ``` -* mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport: Ensure that the transport is able to send an HCI reset command and receive the corresponding HCI status event. -* mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver: Runs the whole initialization process then ensure the cordio stack has been properly initialized by the HCI driver. +* `mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport`: Ensures that the transport is able to send an HCI reset command and receive the corresponding HCI status event. +* `mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver`: Runs the whole initialization process then ensure the Cordio stack has been properly initialized by the HCI driver. ### Tools -The application [mbed-os-cordio-hci-passthrough](https://github.com/ARMmbed/mbed-os-cordio-hci-passthrough) can be used to _proxify_ a Bluetooth controller connected to an mbed board. +The application [mbed-os-cordio-hci-passthrough](https://github.com/ARMmbed/mbed-os-cordio-hci-passthrough) can be used to _proxify_ a Bluetooth controller connected to an Mbed board. Bytes sent by the host over the board serial are forwarded to the controller with the help of the `HCITransportDriver` while bytes sent by the controller are sent back to the host through the board serial. This application can be used to validate the transport driver and debug the initialization process on a PC host. - - - - - - - - - - - - - - - - From f2c6d59c2331521792e753d39fb48e7e5c66ac49 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Fri, 10 Aug 2018 09:56:42 +0300 Subject: [PATCH 3/9] Further stylistic changes. Passive -> active --- .../targets/TARGET_CORDIO/doc/PortingGuide.md | 142 ++++++------------ 1 file changed, 45 insertions(+), 97 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index 27819eb55c..f58f4a2089 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -1,13 +1,10 @@ # Porting guide -There are two main steps to enable the Mbed BLE Cordio port for a given target: +There are two main steps to enable the Mbed BLE Cordio port: -1. Configure the target to include Cordio BLE port and Cordio libraries -during the build process. +1. Configure your target to include Cordio BLE port and Cordio libraries during the build process. -1. Implement `CordioHCIDriver` class targeting the Bluetooth controller. - -[[[Do we want something like this at the beginning? Why not just give the steps, instead of summarizing them?]]] +1. Implement the `CordioHCIDriver` class targeting the Bluetooth controller. ## Configure the target @@ -25,11 +22,9 @@ Define all Mbed OS targets in the `targets/target.json` file: ### Include Cordio BLE implementation -* Compile the BLE Cordio port sources: +Compile the BLE Cordio port sources: -[[[sources?]]] - - * Add the string `CORDIO` to the `extra_labels` property of the JSON file. +* Add the string `CORDIO` to the `extra_labels` property of the JSON file. ``` "TARGET_NAME": { @@ -40,37 +35,25 @@ Define all Mbed OS targets in the `targets/target.json` file: ## Implement CordioHCIDriver: -Include an HCI driver for the BLE module used by the target and a factory function which creates the BLE instance used by the user of the BLE API. +Include an HCI driver for the BLE module used by the target, and a factory function which creates the BLE instance you use. ### Create source folder -Create a `TARGET_` folder. +1. Navigate to the folder of the BLE API that hosts target port `features/FEATURE_BLE/targets`. -The port shall live in the folder of BLE API which host targets port : -`features/FEATURE_BLE/targets`. - -You need to create a folder containing the port code to isolate it from other code. Name - -To isolate the port code from other code, a folder containing the port code has -to be created. The name of this folder shall start with `TARGET_` and end with -the target name in capital. +1. Create a folder containing the port code to isolate it from other code. Begin this folder's name with `TARGET_` and the rest of the name in capital letters. ### Create the HCI driver -The HCI driver is split in two entities: one which handle HCI communication with -the Bluetooth module and the other handling the initialization, reset sequence -and memory dedicated for the Bluetooth controller. +The HCI driver is split in two entities: one which handle HCI communication with the Bluetooth module and the other handling the initialization, reset sequence and memory dedicated for the Bluetooth controller. -More information about the architecture can be found in the -[HCI abstraction architecture](HCIAbstraction.md) document. +More information about the architecture can be found in the [HCI abstraction architecture](HCIAbstraction.md) document. #### HCITransport -**Note:** If the Bluetooth controller uses an H4 communication interface and -the host exposes serial flow control in Mbed, then you can skip this step. Use the class `ble::vendor::cordio::H4TransportDriver` as the transport -driver. +**Note:** If the Bluetooth controller uses an H4 communication interface and the host exposes serial flow control in Mbed, then you can skip this step. Use the class `ble::vendor::cordio::H4TransportDriver` as the transport driver. -You can code an empty transport driver as: +To code an empty transport driver: ``` #include "CordioHCITransportDriver.h" @@ -102,20 +85,11 @@ private: It inherits publicly from the base class `CordioHCITransportDriver`. -[[[still don't know what this means]]] +* **Initialization/termination**: The functions `initialize` and `terminate` are responsible for initializing and terminating the transport driver. It is not necessary to initialize the transport in the constructor. -* **Initialization/termination:** The functions `initialize` and `terminate` are -responsible for initializing and terminating the transport driver. It is not -necessary to initialize the transport in the constructor. +* **Sending data**: The function `write` sends data in input to the Bluetooth controller and return the number of bytes in the `data` buffer sent. Depending on the type of transport you implement, you may need to send the packet `type` to the controller before the packet data. -* **Sending data** The function `write` shall sends data in input to the -Bluetooth controller and return the number of bytes in the `data` buffer sent. -Depending on the type of transport being implemented, the packet `type` might -have to be sent to the controller before the packet data. - -* **Receiving data**: HCI data from the Bluetooth controller shall be injected -in the system by invoking the function `on_data_received` injects . This function is -a static one and is provided by the base class. Its prototype is: +* **Receiving data**: Inject HCI data from the Bluetooth controller to the system by invoking the function `on_data_received`. This function is a static one and is provided by the base class: ``` void on_data_received(uint8_t* data_received, uint16_t length_of_data_received); @@ -123,7 +97,7 @@ void on_data_received(uint8_t* data_received, uint16_t length_of_data_received); #### HCIDriver -The skeleton of driver is: +The template for the driver is: ``` #include "CordioHCIDriver.h" @@ -163,8 +137,7 @@ private: The functions `do_initialize` and `do_terminate` handle initialization and termination processes. These functions manage the state of the Bluetooth controller. -**Note:** It is unnecessary to initialize or terminate the HCI transport in those function because it is handled by the base class. The HCI transport is initialized right before the call to `do_initialize` and is terminated right -after the call to `do_terminate`. +**Note:** It is unnecessary to initialize or terminate the HCI transport in those function because it is handled by the base class. The HCI transport is initialized right before the call to `do_initialize` and is terminated right after the call to `do_terminate`. ##### Memory pool @@ -178,8 +151,7 @@ The function `get_buffer_pool_description` in the base class returns a buffer of | 128 | 2 | | 272 | 1 | -A port overrides this function if the memory provided by the base class -doesn't match what is required by the Bluetooth controller driver. +Porting overrides this function if the memory provided by the base class doesn't match what is required by the Bluetooth controller driver. ``` buf_pool_desc_t CordioHCIDriver::get_buffer_pool_description() { @@ -200,60 +172,39 @@ buf_pool_desc_t CordioHCIDriver::get_buffer_pool_description() { ##### Reset sequence -The reset sequence process is handled by three functions: +Three functions handle the reset sequence process: -* `start_reset_sequence`: This function start the process. The basic -implementation sends an HCI reset command to the Bluetooth controller. The -function shall be overridden in the driver if the bluetooth controller requires -more than just sending the standard reset command. +* `start_reset_sequence`: This function starts the process. It sends an HCI reset command to the Bluetooth controller. You can override this function *if* the Bluetooth controller requires more than just sending the standard reset command. -* `handle_reset_sequence`: Entry point to the state machine handling the reset -process. Every time an HCI packet is received during the reset sequence, this -function is called with the HCI packet received. Its purpose is to prepare the -Bluetooth controller and set the parameters the stack needs to operate properly. -This function can be overridden if necessary. +* `handle_reset_sequence`: Entry point to the state machine handling the reset process. Every time an HCI packet is received during the reset sequence, this function is called with the HCI packet received. Its purpose is to prepare the Bluetooth controller and set the parameters the stack needs to operate properly. You can override this function if necessary. -* `signal_reset_sequence_done`: This function shall be called once the reset -sequence is achieved. It cannot be overridden. +* `signal_reset_sequence_done`: Once the reset sequence is finished, you can call this function. You cannot override it. ###### Controller parameters to set -This instruct the controller which events are relevant for the stack. +This step tells the controller which events are relevant to the stack. The following parameters should be set in the controller (if supported): -* event mask: The reset sequence should issue the call -`HciSetEventMaskCmd((uint8_t *) hciEventMask)` -* LE event mask: The call `HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask)` -should be issued. -* 2nd page of events mask: Can be achieved by invoking -`HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2)`. +* Event mask: Call `HciSetEventMaskCmd((uint8_t *) hciEventMask)`. + +* LE event mask: Call `HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask)`. + +* 2nd page of events mask: Call `HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2)`. ###### Stack runtime parameters -Some stack parameters shall be acquired at runtime from the controller: +At runtime, you can get some stack parameters from the controller: -* Bluetooth address: Can be queried with `HciReadBdAddrCmd`. Response shall be -copied into `hciCoreCb.bdAddr` with `BdaCpy`. -* Buffer size of the controller: Can be obtained by `HciLeReadBufSizeCmd`. The -return parameter *HC_ACL_Data_Packet_Length* shall be copied into -`hciCoreCb.bufSize` and the response parameter -`HC_Synchronous_Data_Packet_Length` shall be copied into `hciCoreCb.numBufs`. -The value of `hciCoreCb.availBufs` shall be initialized with `hciCoreCb.numBufs`. -* Supported state: Queried with `HciLeReadSupStatesCmd`, the response shall go -into `hciCoreCb.leStates`. -* Whitelist size: Queried with `HciLeReadWhiteListSizeCmd` the response shall go -into `hciCoreCb.whiteListSize`. -* LE features supported: Obtained with `HciLeReadLocalSupFeatCmd`. The response -shall be stored into `hciCoreCb.leSupFeat`. -* Resolving list size: Obtained with `hciCoreReadResolvingListSize`. The response -shall go into `hciCoreCb.resListSize`. -* Max data length: Acquired with `hciCoreReadMaxDataLen`. The response parameter -`supportedMaxTxOctets` and `supportedMaxTxTime` shall be pass to the function -`HciLeWriteDefDataLen`. +* Bluetooth address: Query this with `HciReadBdAddrCmd`. Copy the response into `hciCoreCb.bdAddr` with `BdaCpy`. +* Buffer size of the controller: Can be obtained by `HciLeReadBufSizeCmd`. The return parameter `HC_ACL_Data_Packet_Length` is copied to `hciCoreCb.bufSize`, and the response parameter `HC_Synchronous_Data_Packet_Length` shall be copied into `hciCoreCb.numBufs`. The value of `hciCoreCb.availBufs` shall be initialized with `hciCoreCb.numBufs`. -The default implementation is: +* Supported state: Query this with `HciLeReadSupStatesCmd`, and copy the response into `hciCoreCb.leStates`. +* Whitelist size: Query this with `HciLeReadWhiteListSizeCmd`, and copy the response into `hciCoreCb.whiteListSize`. +* LE features supported: Query this with `HciLeReadLocalSupFeatCmd`, and copy the response into `hciCoreCb.leSupFeat`. +* Resolving list size: Query this with `hciCoreReadResolvingListSize`, and copy the response into `hciCoreCb.resListSize`. +* Max data length: Query this with `hciCoreReadMaxDataLen`, and pass the response parameters `supportedMaxTxOctets` and `supportedMaxTxTime` to the function `HciLeWriteDefDataLen`: ``` void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { @@ -458,22 +409,19 @@ static void hciCoreReadResolvingListSize(void) } ``` - - ### HCI accessor function -The HCI driver is injected in the `CordioBLE` class at construction site. -Given that the CordioBLE class doesn't know what class shall be used to -construct the driver nor it knows how to construct it, the port shall provide a -function returning a reference to the HCI driver. +The HCI driver is injected to the `CordioBLE` class at manufacture. -This function lives in the global namespace and its signature is: +Given that the CordioBLE class doesn't know what class constructs the driver nor how to construct it, the port provides a function returning a reference to the HCI driver. + +This function is in the global namespace, and you can call it with: ``` ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver(); ``` -A common implementation might be: +**Example:** ``` ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() { @@ -491,20 +439,20 @@ ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() { ### Tests -Greentea tests are bundled with the Cordio port of the BLE API so the transport driver works as expected as well as validate the Cordio stack initialization. You can run them with the following command: +We bundle Greentea tests with the Cordio port of the BLE API, so the transport driver works, as well as validation of Cordio stack initialization. You can run these tests with the following command: ``` mbed test -t -m -n mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver,mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport ``` * `mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport`: Ensures that the transport is able to send an HCI reset command and receive the corresponding HCI status event. -* `mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver`: Runs the whole initialization process then ensure the Cordio stack has been properly initialized by the HCI driver. +* `mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver`: Runs the whole initialization process, then ensures the HCI driver has properly initialized the Cordio stack. ### Tools -The application [mbed-os-cordio-hci-passthrough](https://github.com/ARMmbed/mbed-os-cordio-hci-passthrough) can be used to _proxify_ a Bluetooth controller connected to an Mbed board. +You can use the application [mbed-os-cordio-hci-passthrough](https://github.com/ARMmbed/mbed-os-cordio-hci-passthrough) to proxify a Bluetooth controller connected to an Mbed board. -Bytes sent by the host over the board serial are forwarded to the controller with the help of the `HCITransportDriver` while bytes sent by the controller are sent back to the host through the board serial. +Bytes sent by the host over the board serial are forwarded to the controller with the help of the `HCITransportDriver`, while bytes sent by the controller are sent back to the host through the board serial. This application can be used to validate the transport driver and debug the initialization process on a PC host. From 739bd6605de10d42c457b6e16cc0000ffab03314 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Fri, 10 Aug 2018 11:01:38 +0300 Subject: [PATCH 4/9] grammatical and stylistic fixes, more passive -> active --- .../TARGET_CORDIO/doc/HCIAbstraction.md | 44 +++++----- .../targets/TARGET_CORDIO/doc/PortingGuide.md | 88 ++++++++++--------- 2 files changed, 68 insertions(+), 64 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/HCIAbstraction.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/HCIAbstraction.md index 1a69a0d44c..879fb01806 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/HCIAbstraction.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/HCIAbstraction.md @@ -1,44 +1,44 @@ # HCI abstraction architecture The HCI driver is split into two interfaces: -* `CordioHCIDriver`: It is the driver for a BLE controller. It contains -the primitive necessary to start and initialize the controller. -* `CordioHCITransport`: It is the transport interface which is used by the HCI +* `CordioHCIDriver`: It is the driver for a BLE controller. It contains +the primitive necessary to start and initialize the controller. +* `CordioHCITransport`: It is the transport interface which is used by the HCI driver to communicate with the controller. -A `CordioHCITransport` is injected into a `CordioHCIDriver` at construction +A `CordioHCITransport` is injected into a `CordioHCIDriver` at construction time. A `CordioHCIDriver` is also injected at construction time of a `BLECordio` -instance. +instance. -This can be summarized in the following diagram: +This can be summarized in the following diagram: ![](resources/architecture.png) ## CordioHCITransportDriver -The single responsabilities of this a driver is to handle the communication with -the Bluetooth module. Basically, sending and reading bytes. +The single responsibility of this driver is to handle the communication with +the Bluetooth module. Basically, sending and reading bytes. -Given that the Bluetooth specification define standard transport interface, an -implementation of the H4 interface is bundled in this port. It might be extended -in the future with an implementation of the H5 interface. However there is no +Given that the Bluetooth specification defines standard transport interface, an +implementation of the H4 interface is bundled in this port. It might be extended +in the future with an implementation of the H5 interface. However, there is no plan to provide the SDIO implementation at the moment. -This interface is defined in the header file +This interface is defined in the header file [CordioHCITransportDriver.h](../driver/CordioHCITransportDriver.h) ## CordioHCIDriver -The responsibilities of this driver are: -* Provide the memory which will used by the Bluetooth stack. -* Initialize the bluetooth controller. -* Handle the reset/startup sequence of the bluetooth controller. +The responsibilities of this driver are: +* Provide the memory which will used by the Bluetooth stack. +* Initialize the Bluetooth controller. +* Handle the reset/startup sequence of the Bluetooth controller. -This interface is defined in the header file +This interface is defined in the header file [CordioHCIDriver.h](../driver/CordioHCIDriver.h) -A partial implementation is present in the file -[CordioHCIDriver.cpp](../driver/CordioHCIDriver.cpp). It defines the function -delivering memory to the stack and a complete reset sequence. However it does -not define any initialization for the Bluetooth controller, this part being -specific to the controller used. +A partial implementation is present in the file +[CordioHCIDriver.cpp](../driver/CordioHCIDriver.cpp). It defines the function +delivering memory to the stack and a complete reset sequence. However, it does +not define any initialization for the Bluetooth controller, this part being +specific to the controller used. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index f58f4a2089..4bdcebe28e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -8,11 +8,11 @@ There are two main steps to enable the Mbed BLE Cordio port: ## Configure the target -Define all Mbed OS targets in the `targets/target.json` file: +1. Define all Mbed OS targets in the `targets/target.json` file: -* Add BLE support to the target: +1. Add BLE support to the target: - * Add the string `BLE` to the target's list of `features`. This adds the BLE API sources to the list of sources compiled for the target. + * Add the string `BLE` to the target's list of `features`. This adds the BLE API sources to the list of sources compiled for the target: ``` "TARGET_NAME": { @@ -24,7 +24,7 @@ Define all Mbed OS targets in the `targets/target.json` file: Compile the BLE Cordio port sources: -* Add the string `CORDIO` to the `extra_labels` property of the JSON file. +* Add the string `CORDIO` to the `extra_labels` property of the JSON file: ``` "TARGET_NAME": { @@ -39,7 +39,7 @@ Include an HCI driver for the BLE module used by the target, and a factory funct ### Create source folder -1. Navigate to the folder of the BLE API that hosts target port `features/FEATURE_BLE/targets`. +1. Navigate to the folder of the BLE API that hosts the target port `features/FEATURE_BLE/targets`. 1. Create a folder containing the port code to isolate it from other code. Begin this folder's name with `TARGET_` and the rest of the name in capital letters. @@ -47,7 +47,7 @@ Include an HCI driver for the BLE module used by the target, and a factory funct The HCI driver is split in two entities: one which handle HCI communication with the Bluetooth module and the other handling the initialization, reset sequence and memory dedicated for the Bluetooth controller. -More information about the architecture can be found in the [HCI abstraction architecture](HCIAbstraction.md) document. +More information about the architecture can be found in [HCI abstraction architecture](HCIAbstraction.md). #### HCITransport @@ -89,7 +89,9 @@ It inherits publicly from the base class `CordioHCITransportDriver`. * **Sending data**: The function `write` sends data in input to the Bluetooth controller and return the number of bytes in the `data` buffer sent. Depending on the type of transport you implement, you may need to send the packet `type` to the controller before the packet data. -* **Receiving data**: Inject HCI data from the Bluetooth controller to the system by invoking the function `on_data_received`. This function is a static one and is provided by the base class: +* **Receiving data**: Inject HCI data from the Bluetooth controller to the system by invoking the function `on_data_received`. This function is a static one and is provided by the base class. + +**Example:** ``` void on_data_received(uint8_t* data_received, uint16_t length_of_data_received); @@ -137,11 +139,11 @@ private: The functions `do_initialize` and `do_terminate` handle initialization and termination processes. These functions manage the state of the Bluetooth controller. -**Note:** It is unnecessary to initialize or terminate the HCI transport in those function because it is handled by the base class. The HCI transport is initialized right before the call to `do_initialize` and is terminated right after the call to `do_terminate`. +**Note:** It is unnecessary to initialize or terminate the HCI transport in these functions, because that is handled by the base class. The HCI transport is initialized right before the call to `do_initialize` and is terminated right after the call to `do_terminate`. ##### Memory pool -The function `get_buffer_pool_description` in the base class returns a buffer of 1040 bytes divided in different memory pools: +The function `get_buffer_pool_description` in the base class returns a buffer of 1040 bytes divided into different memory pools: | Chunk size (bytes) | Number of chunks | |--------------------|------------------| @@ -153,6 +155,8 @@ The function `get_buffer_pool_description` in the base class returns a buffer of Porting overrides this function if the memory provided by the base class doesn't match what is required by the Bluetooth controller driver. +**Example:** + ``` buf_pool_desc_t CordioHCIDriver::get_buffer_pool_description() { static uint8_t buffer[/* buffer size */]; @@ -194,17 +198,17 @@ The following parameters should be set in the controller (if supported): ###### Stack runtime parameters -At runtime, you can get some stack parameters from the controller: +At runtime, you can get stack parameters from the controller: * Bluetooth address: Query this with `HciReadBdAddrCmd`. Copy the response into `hciCoreCb.bdAddr` with `BdaCpy`. - -* Buffer size of the controller: Can be obtained by `HciLeReadBufSizeCmd`. The return parameter `HC_ACL_Data_Packet_Length` is copied to `hciCoreCb.bufSize`, and the response parameter `HC_Synchronous_Data_Packet_Length` shall be copied into `hciCoreCb.numBufs`. The value of `hciCoreCb.availBufs` shall be initialized with `hciCoreCb.numBufs`. - +* Buffer size of the controller: Query this with `HciLeReadBufSizeCmd`. The return parameter `HC_ACL_Data_Packet_Length` is copied to `hciCoreCb.bufSize`. Copy the response parameter `HC_Synchronous_Data_Packet_Length` into `hciCoreCb.numBufs`. The value of `hciCoreCb.availBufs` shall be initialized with `hciCoreCb.numBufs`. * Supported state: Query this with `HciLeReadSupStatesCmd`, and copy the response into `hciCoreCb.leStates`. * Whitelist size: Query this with `HciLeReadWhiteListSizeCmd`, and copy the response into `hciCoreCb.whiteListSize`. * LE features supported: Query this with `HciLeReadLocalSupFeatCmd`, and copy the response into `hciCoreCb.leSupFeat`. * Resolving list size: Query this with `hciCoreReadResolvingListSize`, and copy the response into `hciCoreCb.resListSize`. -* Max data length: Query this with `hciCoreReadMaxDataLen`, and pass the response parameters `supportedMaxTxOctets` and `supportedMaxTxTime` to the function `HciLeWriteDefDataLen`: +* Max data length: Query this with `hciCoreReadMaxDataLen`, and pass the response parameters `supportedMaxTxOctets` and `supportedMaxTxTime` to the function `HciLeWriteDefDataLen`. + +**Example:** ``` void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { @@ -228,90 +232,90 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { case HCI_OPCODE_RESET: /* initialize rand command count */ randCnt = 0; - // set the event mask to control which events are generated by the - // controller for the host + // Set the event mask to control which events are generated by the + // controller for the host. HciSetEventMaskCmd((uint8_t *) hciEventMask); break; case HCI_OPCODE_SET_EVENT_MASK: - // set the event mask to control which LE events are generated by - // the controller for the host + // Set the event mask to control which LE events are generated by + // the controller for the host. HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask); break; case HCI_OPCODE_LE_SET_EVENT_MASK: - // set the event mask to control which events are generated by the - // controller for the host (2nd page of flags ) + // Set the event mask to control which events are generated by the + // controller for the host (2nd page of flags). HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2); break; case HCI_OPCODE_SET_EVENT_MASK_PAGE2: - // Ask the Bluetooth address of the controller + // Ask the Bluetooth address of the controller. HciReadBdAddrCmd(); break; case HCI_OPCODE_READ_BD_ADDR: - // Store the Bluetooth address in the stack runtime parameter + // Store the Bluetooth address in the stack runtime parameter. BdaCpy(hciCoreCb.bdAddr, pMsg); - // Read the size of the buffer of the controller + // Read the size of the buffer of the controller. HciLeReadBufSizeCmd(); break; case HCI_OPCODE_LE_READ_BUF_SIZE: - // Store the buffer parameters in the stack runtime parameters + // Store the buffer parameters in the stack runtime parameters. BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg); BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg); /* initialize ACL buffer accounting */ hciCoreCb.availBufs = hciCoreCb.numBufs; - // read the states and state combinations supported by the link - // layer of the controller + // Read the states and state combinations supported by the link + // layer of the controller. HciLeReadSupStatesCmd(); break; case HCI_OPCODE_LE_READ_SUP_STATES: - // store supported state and combination in the runtime parameters - // of the stack + // Store supported state and combination in the runtime parameters + // of the stack. memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN); - // read the total of whitelist entries that can be stored in the + // Read the total of whitelist entries that can be stored in the // controller. HciLeReadWhiteListSizeCmd(); break; case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE: - // store the number of whitelist entries in the stack runtime - // parameters + // Store the number of whitelist entries in the stack runtime + // parameters. BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg); - // Read the LE features supported by the controller + // Read the LE features supported by the controller. HciLeReadLocalSupFeatCmd(); break; case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT: - // Store the set of LE features supported by the controller + // Store the set of LE features supported by the controller. BSTREAM_TO_UINT16(hciCoreCb.leSupFeat, pMsg); - // read the total number of address translation entries which can be + // Read the total number of address translation entries which can be // stored in the controller resolving list. hciCoreReadResolvingListSize(); break; case HCI_OPCODE_LE_READ_RES_LIST_SIZE: - // store the number of address translation entries in the stack - // runtime parameter + // Store the number of address translation entries in the stack + // runtime parameter. BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg); - // read the Controller’s maximum supported payload octets and packet - // duration times for transmission and reception + // Read the Controller’s maximum supported payload octets and packet + // duration times for transmission and reception. hciCoreReadMaxDataLen(); break; case HCI_OPCODE_LE_READ_MAX_DATA_LEN: { - // store payload definition in the runtime stack parameters. + // Store payload definition in the runtime stack parameters. uint16_t maxTxOctets; uint16_t maxTxTime; @@ -413,7 +417,7 @@ static void hciCoreReadResolvingListSize(void) The HCI driver is injected to the `CordioBLE` class at manufacture. -Given that the CordioBLE class doesn't know what class constructs the driver nor how to construct it, the port provides a function returning a reference to the HCI driver. +Given that the `CordioBLE` class doesn't know which class constructs the driver nor how to construct it, the port provides a function returning a reference to the HCI driver. This function is in the global namespace, and you can call it with: @@ -453,6 +457,6 @@ mbed test -t -m -n mbed-os-features-feature_ble-targets-tar You can use the application [mbed-os-cordio-hci-passthrough](https://github.com/ARMmbed/mbed-os-cordio-hci-passthrough) to proxify a Bluetooth controller connected to an Mbed board. -Bytes sent by the host over the board serial are forwarded to the controller with the help of the `HCITransportDriver`, while bytes sent by the controller are sent back to the host through the board serial. +The host sent bytes over the board serial, which the `HCITransport Driver` then forwards. Bytes sent by the controller go back to the host through the board serial. -This application can be used to validate the transport driver and debug the initialization process on a PC host. +This application can be used to validate the transport driver and debug the initialization process. From db8f36945b6150547695a1331a94f5d8d2dc2060 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Fri, 10 Aug 2018 11:17:32 +0300 Subject: [PATCH 5/9] Fixing colons and formatting --- .../FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index 4bdcebe28e..b15685c6b3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -35,7 +35,7 @@ Compile the BLE Cordio port sources: ## Implement CordioHCIDriver: -Include an HCI driver for the BLE module used by the target, and a factory function which creates the BLE instance you use. +Include an HCI driver for the BLE module used by the target, and a factory function that creates the BLE instance you use. ### Create source folder @@ -45,7 +45,7 @@ Include an HCI driver for the BLE module used by the target, and a factory funct ### Create the HCI driver -The HCI driver is split in two entities: one which handle HCI communication with the Bluetooth module and the other handling the initialization, reset sequence and memory dedicated for the Bluetooth controller. +The HCI driver is split in two entities. One handles HCI communication with the Bluetooth module. The other handles initialization, reset sequence, and memory dedicated to the Bluetooth controller. More information about the architecture can be found in [HCI abstraction architecture](HCIAbstraction.md). @@ -89,7 +89,7 @@ It inherits publicly from the base class `CordioHCITransportDriver`. * **Sending data**: The function `write` sends data in input to the Bluetooth controller and return the number of bytes in the `data` buffer sent. Depending on the type of transport you implement, you may need to send the packet `type` to the controller before the packet data. -* **Receiving data**: Inject HCI data from the Bluetooth controller to the system by invoking the function `on_data_received`. This function is a static one and is provided by the base class. +* **Receiving data**: Inject HCI data from the Bluetooth controller to the system by calling `on_data_received`. This is a static function provided by the base class. **Example:** @@ -99,7 +99,7 @@ void on_data_received(uint8_t* data_received, uint16_t length_of_data_received); #### HCIDriver -The template for the driver is: +The HCIDriver template is: ``` #include "CordioHCIDriver.h" From 1082724ac3a36a88269312d30d44036206273ec2 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Fri, 10 Aug 2018 11:39:02 +0300 Subject: [PATCH 6/9] formatting changes --- .../targets/TARGET_CORDIO/doc/PortingGuide.md | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index b15685c6b3..ee758a8bec 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -1,4 +1,4 @@ -# Porting guide +## Porting guide There are two main steps to enable the Mbed BLE Cordio port: @@ -6,7 +6,7 @@ There are two main steps to enable the Mbed BLE Cordio port: 1. Implement the `CordioHCIDriver` class targeting the Bluetooth controller. -## Configure the target +### Configure the target 1. Define all Mbed OS targets in the `targets/target.json` file: @@ -33,17 +33,17 @@ Compile the BLE Cordio port sources: } ``` -## Implement CordioHCIDriver: +### Implement CordioHCIDriver: Include an HCI driver for the BLE module used by the target, and a factory function that creates the BLE instance you use. -### Create source folder +#### Create source folder 1. Navigate to the folder of the BLE API that hosts the target port `features/FEATURE_BLE/targets`. 1. Create a folder containing the port code to isolate it from other code. Begin this folder's name with `TARGET_` and the rest of the name in capital letters. -### Create the HCI driver +#### Create the HCI driver The HCI driver is split in two entities. One handles HCI communication with the Bluetooth module. The other handles initialization, reset sequence, and memory dedicated to the Bluetooth controller. @@ -182,31 +182,38 @@ Three functions handle the reset sequence process: * `handle_reset_sequence`: Entry point to the state machine handling the reset process. Every time an HCI packet is received during the reset sequence, this function is called with the HCI packet received. Its purpose is to prepare the Bluetooth controller and set the parameters the stack needs to operate properly. You can override this function if necessary. -* `signal_reset_sequence_done`: Once the reset sequence is finished, you can call this function. You cannot override it. +* `signal_reset_sequence_done`: Once the reset sequence is completed, you can call this function. You cannot override it. ###### Controller parameters to set This step tells the controller which events are relevant to the stack. -The following parameters should be set in the controller (if supported): +You should set the following parameters in the controller (if supported): -* Event mask: Call `HciSetEventMaskCmd((uint8_t *) hciEventMask)`. +* **Event mask:** Call `HciSetEventMaskCmd((uint8_t *) hciEventMask)`. -* LE event mask: Call `HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask)`. +* **LE event mask:** Call `HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask)`. -* 2nd page of events mask: Call `HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2)`. +* **2nd page of events mask:** Call `HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2)`. ###### Stack runtime parameters At runtime, you can get stack parameters from the controller: -* Bluetooth address: Query this with `HciReadBdAddrCmd`. Copy the response into `hciCoreCb.bdAddr` with `BdaCpy`. -* Buffer size of the controller: Query this with `HciLeReadBufSizeCmd`. The return parameter `HC_ACL_Data_Packet_Length` is copied to `hciCoreCb.bufSize`. Copy the response parameter `HC_Synchronous_Data_Packet_Length` into `hciCoreCb.numBufs`. The value of `hciCoreCb.availBufs` shall be initialized with `hciCoreCb.numBufs`. -* Supported state: Query this with `HciLeReadSupStatesCmd`, and copy the response into `hciCoreCb.leStates`. -* Whitelist size: Query this with `HciLeReadWhiteListSizeCmd`, and copy the response into `hciCoreCb.whiteListSize`. -* LE features supported: Query this with `HciLeReadLocalSupFeatCmd`, and copy the response into `hciCoreCb.leSupFeat`. -* Resolving list size: Query this with `hciCoreReadResolvingListSize`, and copy the response into `hciCoreCb.resListSize`. -* Max data length: Query this with `hciCoreReadMaxDataLen`, and pass the response parameters `supportedMaxTxOctets` and `supportedMaxTxTime` to the function `HciLeWriteDefDataLen`. +* **Bluetooth address:** Query this with `HciReadBdAddrCmd`. Copy the response into `hciCoreCb.bdAddr` with `BdaCpy`. + +* **Buffer size of the controller:** Query this with `HciLeReadBufSizeCmd`. + * The return parameter `HC_ACL_Data_Packet_Length` is copied to `hciCoreCb.bufSize`. Copy the response parameter `HC_Synchronous_Data_Packet_Length` into `hciCoreCb.numBufs`. `hciCoreCb.numBufs` initializes the value of `hciCoreCb.availBufs`. + +* **Supported state:** Query this with `HciLeReadSupStatesCmd`, and copy the response into `hciCoreCb.leStates`. + +* **Whitelist size:** Query this with `HciLeReadWhiteListSizeCmd`, and copy the response into `hciCoreCb.whiteListSize`. + +* **LE features supported:** Query this with `HciLeReadLocalSupFeatCmd`, and copy the response into `hciCoreCb.leSupFeat`. + +* **Resolving list size:** Query this with `hciCoreReadResolvingListSize`, and copy the response into `hciCoreCb.resListSize`. + +* **Max data length:** Query this with `hciCoreReadMaxDataLen`, and pass the response parameters `supportedMaxTxOctets` and `supportedMaxTxTime` to the function `HciLeWriteDefDataLen`. **Example:** @@ -457,6 +464,6 @@ mbed test -t -m -n mbed-os-features-feature_ble-targets-tar You can use the application [mbed-os-cordio-hci-passthrough](https://github.com/ARMmbed/mbed-os-cordio-hci-passthrough) to proxify a Bluetooth controller connected to an Mbed board. -The host sent bytes over the board serial, which the `HCITransport Driver` then forwards. Bytes sent by the controller go back to the host through the board serial. +The host sent bytes over the board serial, which the `HCITransport Driver` forwards. Bytes sent by the controller go back to the host through the board serial. -This application can be used to validate the transport driver and debug the initialization process. +You can use this application to validate the transport driver and debug the initialization process. From 3b95202154b04deca0d53705bb8d7cd12e55afb8 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Tue, 14 Aug 2018 10:55:39 +0300 Subject: [PATCH 7/9] Final review and grammatical changes --- .../targets/TARGET_CORDIO/doc/PortingGuide.md | 43 ++++++++----------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index ee758a8bec..2b8c0abc3f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -41,17 +41,18 @@ Include an HCI driver for the BLE module used by the target, and a factory funct 1. Navigate to the folder of the BLE API that hosts the target port `features/FEATURE_BLE/targets`. -1. Create a folder containing the port code to isolate it from other code. Begin this folder's name with `TARGET_` and the rest of the name in capital letters. +1. Create a folder containing the port code to isolate it from other code. + * Begin this folder's name with `TARGET_` and the rest of the name in capital letters. #### Create the HCI driver -The HCI driver is split in two entities. One handles HCI communication with the Bluetooth module. The other handles initialization, reset sequence, and memory dedicated to the Bluetooth controller. +The HCI driver is split into two entities. One handles HCI communication with the Bluetooth module. The other handles the initialization, reset sequence, and memory dedicated to the Bluetooth controller. More information about the architecture can be found in [HCI abstraction architecture](HCIAbstraction.md). #### HCITransport -**Note:** If the Bluetooth controller uses an H4 communication interface and the host exposes serial flow control in Mbed, then you can skip this step. Use the class `ble::vendor::cordio::H4TransportDriver` as the transport driver. +**Note:** If the Bluetooth controller uses an H4 communication interface and the host exposes serial flow control in Mbed, you can skip this step. Use the class `ble::vendor::cordio::H4TransportDriver` as the transport driver. To code an empty transport driver: @@ -85,9 +86,11 @@ private: It inherits publicly from the base class `CordioHCITransportDriver`. +##### Functions + * **Initialization/termination**: The functions `initialize` and `terminate` are responsible for initializing and terminating the transport driver. It is not necessary to initialize the transport in the constructor. -* **Sending data**: The function `write` sends data in input to the Bluetooth controller and return the number of bytes in the `data` buffer sent. Depending on the type of transport you implement, you may need to send the packet `type` to the controller before the packet data. +* **Sending data**: The function `write` sends data as input to the Bluetooth controller and returns the number of bytes in the `data` buffer sent. Depending on the type of transport you implement, you may need to send the packet `type` to the controller before the packet data. * **Receiving data**: Inject HCI data from the Bluetooth controller to the system by calling `on_data_received`. This is a static function provided by the base class. @@ -239,20 +242,17 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { case HCI_OPCODE_RESET: /* initialize rand command count */ randCnt = 0; - // Set the event mask to control which events are generated by the - // controller for the host. + // Set the event mask to control which events are generated by the controller for the host. HciSetEventMaskCmd((uint8_t *) hciEventMask); break; case HCI_OPCODE_SET_EVENT_MASK: - // Set the event mask to control which LE events are generated by - // the controller for the host. + // Set the event mask to control which LE events are generated by the controller for the host. HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask); break; case HCI_OPCODE_LE_SET_EVENT_MASK: - // Set the event mask to control which events are generated by the - // controller for the host (2nd page of flags). + // Set the event mask to control which events are generated by the controller for the host (2nd page of flags). HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2); break; @@ -277,24 +277,20 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { /* initialize ACL buffer accounting */ hciCoreCb.availBufs = hciCoreCb.numBufs; - // Read the states and state combinations supported by the link - // layer of the controller. + // Read the states and state combinations supported by the link layer of the controller. HciLeReadSupStatesCmd(); break; case HCI_OPCODE_LE_READ_SUP_STATES: - // Store supported state and combination in the runtime parameters - // of the stack. + // Store supported state and combination in the runtime parameters of the stack. memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN); - // Read the total of whitelist entries that can be stored in the - // controller. + // Read the total of whitelist entries that can be stored in the controller. HciLeReadWhiteListSizeCmd(); break; case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE: - // Store the number of whitelist entries in the stack runtime - // parameters. + // Store the number of whitelist entries in the stack runtime parameters. BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg); // Read the LE features supported by the controller. @@ -305,18 +301,15 @@ void HCIDriver::handle_reset_sequence(uint8_t *pMsg) { // Store the set of LE features supported by the controller. BSTREAM_TO_UINT16(hciCoreCb.leSupFeat, pMsg); - // Read the total number of address translation entries which can be - // stored in the controller resolving list. + // Read the total number of address translation entries which can be stored in the controller resolving list. hciCoreReadResolvingListSize(); break; case HCI_OPCODE_LE_READ_RES_LIST_SIZE: - // Store the number of address translation entries in the stack - // runtime parameter. + // Store the number of address translation entries in the stack runtime parameter. BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg); - // Read the Controller’s maximum supported payload octets and packet - // duration times for transmission and reception. + // Read the Controller’s maximum supported payload octets and packet duration times for transmission and reception. hciCoreReadMaxDataLen(); break; @@ -450,7 +443,7 @@ ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() { ### Tests -We bundle Greentea tests with the Cordio port of the BLE API, so the transport driver works, as well as validation of Cordio stack initialization. You can run these tests with the following command: +We bundle Greentea tests with the Cordio port of the BLE API, so the transport driver and validation of Cordio stack initialization both work. You can run these tests with the following command: ``` mbed test -t -m -n mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-driver,mbed-os-features-feature_ble-targets-target_cordio-tests-cordio_hci-transport From c1e154b1cc35e1b3fca3eca3bd45a49c6dc72394 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Tue, 14 Aug 2018 16:26:30 +0300 Subject: [PATCH 8/9] removing \ --- features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index 2b8c0abc3f..9fbe4d6800 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -128,7 +128,7 @@ public: virtual void start_reset_sequence(); - virtual void handle_reset_sequence(uint8_t \*msg); + virtual void handle_reset_sequence(uint8_t *msg); private: // private driver declarations }; From 4a9570b252cdafa6e86d1a140a0a204817729653 Mon Sep 17 00:00:00 2001 From: Melinda Weed Date: Thu, 16 Aug 2018 14:46:07 +0300 Subject: [PATCH 9/9] function signature line --- features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md index 9fbe4d6800..0995c09475 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/doc/PortingGuide.md @@ -419,7 +419,7 @@ The HCI driver is injected to the `CordioBLE` class at manufacture. Given that the `CordioBLE` class doesn't know which class constructs the driver nor how to construct it, the port provides a function returning a reference to the HCI driver. -This function is in the global namespace, and you can call it with: +This function is in the global namespace, and its signature is: ``` ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver();