1*503a627eSMilanka Ringwald# 2*503a627eSMilanka Ringwald 3*503a627eSMilanka RingwaldIn this section, we highlight the BTstack components that need to be 4*503a627eSMilanka Ringwaldadjusted for different hardware platforms. 5*503a627eSMilanka Ringwald 6*503a627eSMilanka Ringwald 7*503a627eSMilanka Ringwald## Time Abstraction Layer {#sec:timeAbstractionPorting} 8*503a627eSMilanka Ringwald 9*503a627eSMilanka RingwaldBTstack requires a way to learn about passing time. 10*503a627eSMilanka Ringwald*btstack_run_loop_embedded.c* supports two different modes: system ticks or a 11*503a627eSMilanka Ringwaldsystem clock with millisecond resolution. BTstack’s timing requirements 12*503a627eSMilanka Ringwaldare quite low as only Bluetooth timeouts in the second range need to be 13*503a627eSMilanka Ringwaldhandled. 14*503a627eSMilanka Ringwald 15*503a627eSMilanka Ringwald 16*503a627eSMilanka Ringwald### Tick Hardware Abstraction {#sec:tickAbstractionPorting} 17*503a627eSMilanka Ringwald 18*503a627eSMilanka Ringwald 19*503a627eSMilanka RingwaldIf your platform doesn’t require a system clock or if you already have a 20*503a627eSMilanka Ringwaldsystem tick (as it is the default with CMSIS on ARM Cortex devices), you 21*503a627eSMilanka Ringwaldcan use that to implement BTstack’s time abstraction in 22*503a627eSMilanka Ringwald*include/btstack/hal_tick.h\>*. 23*503a627eSMilanka Ringwald 24*503a627eSMilanka RingwaldFor this, you need to define *HAVE_EMBEDDED_TICK* in *btstack_config.h*: 25*503a627eSMilanka Ringwald 26*503a627eSMilanka Ringwald #define HAVE_EMBEDDED_TICK 27*503a627eSMilanka Ringwald 28*503a627eSMilanka RingwaldThen, you need to implement the functions *hal_tick_init* and 29*503a627eSMilanka Ringwald*hal_tick_set_handler*, which will be called during the 30*503a627eSMilanka Ringwaldinitialization of the run loop. 31*503a627eSMilanka Ringwald 32*503a627eSMilanka Ringwald void hal_tick_init(void); 33*503a627eSMilanka Ringwald void hal_tick_set_handler(void (*tick_handler)(void)); 34*503a627eSMilanka Ringwald int hal_tick_get_tick_period_in_ms(void); 35*503a627eSMilanka Ringwald 36*503a627eSMilanka RingwaldAfter BTstack calls *hal_tick_init()* and 37*503a627eSMilanka Ringwald*hal_tick_set_handler(tick_handler)*, it expects that the 38*503a627eSMilanka Ringwald*tick_handler* gets called every 39*503a627eSMilanka Ringwald*hal_tick_get_tick_period_in_ms()* ms. 40*503a627eSMilanka Ringwald 41*503a627eSMilanka Ringwald 42*503a627eSMilanka Ringwald### Time MS Hardware Abstraction {#sec:timeMSAbstractionPorting} 43*503a627eSMilanka Ringwald 44*503a627eSMilanka Ringwald 45*503a627eSMilanka RingwaldIf your platform already has a system clock or it is more convenient to 46*503a627eSMilanka Ringwaldprovide such a clock, you can use the Time MS Hardware Abstraction in 47*503a627eSMilanka Ringwald*include/btstack/hal_time_ms.h*. 48*503a627eSMilanka Ringwald 49*503a627eSMilanka RingwaldFor this, you need to define *HAVE_EMBEDDED_TIME_MS* in *btstack_config.h*: 50*503a627eSMilanka Ringwald 51*503a627eSMilanka Ringwald #define HAVE_EMBEDDED_TIME_MS 52*503a627eSMilanka Ringwald 53*503a627eSMilanka RingwaldThen, you need to implement the function *hal_time_ms()*, which will 54*503a627eSMilanka Ringwaldbe called from BTstack’s run loop and when setting a timer for the 55*503a627eSMilanka Ringwaldfuture. It has to return the time in milliseconds. 56*503a627eSMilanka Ringwald 57*503a627eSMilanka Ringwald uint32_t hal_time_ms(void); 58*503a627eSMilanka Ringwald 59*503a627eSMilanka Ringwald 60*503a627eSMilanka Ringwald## Bluetooth Hardware Control API {#sec:btHWControlPorting} 61*503a627eSMilanka Ringwald 62*503a627eSMilanka Ringwald 63*503a627eSMilanka RingwaldThe Bluetooth hardware control API can provide the HCI layer with a 64*503a627eSMilanka Ringwaldcustom initialization script, a vendor-specific baud rate change 65*503a627eSMilanka Ringwaldcommand, and system power notifications. It is also used to control the 66*503a627eSMilanka Ringwaldpower mode of the Bluetooth module, i.e., turning it on/off and putting 67*503a627eSMilanka Ringwaldto sleep. In addition, it provides an error handler *hw_error* that is 68*503a627eSMilanka Ringwaldcalled when a Hardware Error is reported by the Bluetooth module. The 69*503a627eSMilanka Ringwaldcallback allows for persistent logging or signaling of this failure. 70*503a627eSMilanka Ringwald 71*503a627eSMilanka RingwaldOverall, the struct *btstack_control_t* encapsulates common functionality 72*503a627eSMilanka Ringwaldthat is not covered by the Bluetooth specification. As an example, the 73*503a627eSMilanka Ringwald*btstack_chipset_cc256x_in-stance* function returns a pointer to a control 74*503a627eSMilanka Ringwaldstruct suitable for the CC256x chipset. 75*503a627eSMilanka Ringwald 76*503a627eSMilanka Ringwald 77*503a627eSMilanka Ringwald 78*503a627eSMilanka Ringwald## HCI Transport Implementation {#sec:hciTransportPorting} 79*503a627eSMilanka Ringwald 80*503a627eSMilanka Ringwald 81*503a627eSMilanka RingwaldOn embedded systems, a Bluetooth module can be connected via USB or an 82*503a627eSMilanka RingwaldUART port. BTstack implements three UART based protocols for carrying HCI 83*503a627eSMilanka Ringwaldcommands, events and data between a host and a Bluetooth module: HCI 84*503a627eSMilanka RingwaldUART Transport Layer (H4), H4 with eHCILL support, a lightweight 85*503a627eSMilanka Ringwaldlow-power variant by Texas Instruments, and the Three-Wire UART Transport Layer (H5). 86*503a627eSMilanka Ringwald 87*503a627eSMilanka Ringwald 88*503a627eSMilanka Ringwald### HCI UART Transport Layer (H4) {#sec:hciUARTPorting} 89*503a627eSMilanka Ringwald 90*503a627eSMilanka Ringwald 91*503a627eSMilanka RingwaldMost embedded UART interfaces operate on the byte level and generate a 92*503a627eSMilanka Ringwaldprocessor interrupt when a byte was received. In the interrupt handler, 93*503a627eSMilanka Ringwaldcommon UART drivers then place the received data in a ring buffer and 94*503a627eSMilanka Ringwaldset a flag for further processing or notify the higher-level code, i.e., 95*503a627eSMilanka Ringwaldin our case the Bluetooth stack. 96*503a627eSMilanka Ringwald 97*503a627eSMilanka RingwaldBluetooth communication is packet-based and a single packet may contain 98*503a627eSMilanka Ringwaldup to 1021 bytes. Calling a data received handler of the Bluetooth stack 99*503a627eSMilanka Ringwaldfor every byte creates an unnecessary overhead. To avoid that, a 100*503a627eSMilanka RingwaldBluetooth packet can be read as multiple blocks where the amount of 101*503a627eSMilanka Ringwaldbytes to read is known in advance. Even better would be the use of 102*503a627eSMilanka Ringwaldon-chip DMA modules for these block reads, if available. 103*503a627eSMilanka Ringwald 104*503a627eSMilanka RingwaldThe BTstack UART Hardware Abstraction Layer API reflects this design 105*503a627eSMilanka Ringwaldapproach and the underlying UART driver has to implement the following 106*503a627eSMilanka RingwaldAPI: 107*503a627eSMilanka Ringwald 108*503a627eSMilanka Ringwald void hal_uart_dma_init(void); 109*503a627eSMilanka Ringwald void hal_uart_dma_set_block_received(void (*block_handler)(void)); 110*503a627eSMilanka Ringwald void hal_uart_dma_set_block_sent(void (*block_handler)(void)); 111*503a627eSMilanka Ringwald int hal_uart_dma_set_baud(uint32_t baud); 112*503a627eSMilanka Ringwald void hal_uart_dma_send_block(const uint8_t *buffer, uint16_t len); 113*503a627eSMilanka Ringwald void hal_uart_dma_receive_block(uint8_t *buffer, uint16_t len); 114*503a627eSMilanka Ringwald 115*503a627eSMilanka Ringwald 116*503a627eSMilanka RingwaldThe main HCI H4 implementations for embedded system is 117*503a627eSMilanka Ringwald*hci_h4_transport-_dma* function. This function calls the following 118*503a627eSMilanka Ringwaldsequence: *hal_uart_dma_init*, *hal_uart_dma_set_block_received* 119*503a627eSMilanka Ringwaldand *hal_uart_dma_set_block_sent* functions. this sequence, the HCI 120*503a627eSMilanka Ringwaldlayer will start packet processing by calling 121*503a627eSMilanka Ringwald*hal_uart-_dma_receive_block* function. The HAL implementation is 122*503a627eSMilanka Ringwaldresponsible for reading the requested amount of bytes, stopping incoming 123*503a627eSMilanka Ringwalddata via the RTS line when the requested amount of data was received and 124*503a627eSMilanka Ringwaldhas to call the handler. By this, the HAL implementation can stay 125*503a627eSMilanka Ringwaldgeneric, while requiring only three callbacks per HCI packet. 126*503a627eSMilanka Ringwald 127*503a627eSMilanka Ringwald### H4 with eHCILL support 128*503a627eSMilanka Ringwald 129*503a627eSMilanka RingwaldWith the standard H4 protocol interface, it is not possible for either 130*503a627eSMilanka Ringwaldthe host nor the baseband controller to enter a sleep mode. Besides the 131*503a627eSMilanka Ringwaldofficial H5 protocol, various chip vendors came up with proprietary 132*503a627eSMilanka Ringwaldsolutions to this. The eHCILL support by Texas Instruments allows both 133*503a627eSMilanka Ringwaldthe host and the baseband controller to independently enter sleep mode 134*503a627eSMilanka Ringwaldwithout loosing their synchronization with the HCI H4 Transport Layer. 135*503a627eSMilanka RingwaldIn addition to the IRQ-driven block-wise RX and TX, eHCILL requires a 136*503a627eSMilanka Ringwaldcallback for CTS interrupts. 137*503a627eSMilanka Ringwald 138*503a627eSMilanka Ringwald void hal_uart_dma_set_cts_irq_handler(void(*cts_irq_handler)(void)); 139*503a627eSMilanka Ringwald void hal_uart_dma_set_sleep(uint8_t sleep); 140*503a627eSMilanka Ringwald 141*503a627eSMilanka Ringwald 142*503a627eSMilanka Ringwald### H5 143*503a627eSMilanka Ringwald 144*503a627eSMilanka RingwaldH5, makes use of the SLIP protocol to transmit a packet and can deal 145*503a627eSMilanka Ringwaldwith packet loss and bit-errors by retransmission. Since it can recover 146*503a627eSMilanka Ringwaldfrom packet loss, it's also possible for either side to enter sleep 147*503a627eSMilanka Ringwaldmode without loosing synchronization. 148*503a627eSMilanka Ringwald 149*503a627eSMilanka RingwaldThe use of hardware flow control in H5 is optional, however, since 150*503a627eSMilanka RingwaldBTstack uses hardware flow control to avoid packet buffers, it's 151*503a627eSMilanka Ringwaldrecommended to only use H5 with RTS/CTS as well. 152*503a627eSMilanka Ringwald 153*503a627eSMilanka RingwaldFor porting, the implementation follows the regular H4 protocol described above. 154*503a627eSMilanka Ringwald 155*503a627eSMilanka Ringwald## Persistent Storage APIs {#sec:persistentStoragePorting} 156*503a627eSMilanka Ringwald 157*503a627eSMilanka RingwaldOn embedded systems there is no generic way to persist data like link 158*503a627eSMilanka Ringwaldkeys or remote device names, as every type of a device has its own 159*503a627eSMilanka Ringwaldcapabilities, particularities and limitations. The persistent storage 160*503a627eSMilanka RingwaldAPIs provides an interface to implement concrete drivers for a particular 161*503a627eSMilanka Ringwaldsystem. 162*503a627eSMilanka Ringwald 163*503a627eSMilanka Ringwald### Link Key DB 164*503a627eSMilanka Ringwald 165*503a627eSMilanka RingwaldAs an example and for testing purposes, BTstack provides the 166*503a627eSMilanka Ringwaldmemory-only implementation *btstack_link_key_db_memory*. An 167*503a627eSMilanka Ringwaldimplementation has to conform to the interface in Listing [below](#lst:persistentDB). 168*503a627eSMilanka Ringwald 169*503a627eSMilanka Ringwald~~~~ {#lst:persistentDB .c caption="{Persistent storage interface.}"} 170*503a627eSMilanka Ringwald 171*503a627eSMilanka Ringwald typedef struct { 172*503a627eSMilanka Ringwald // management 173*503a627eSMilanka Ringwald void (*open)(); 174*503a627eSMilanka Ringwald void (*close)(); 175*503a627eSMilanka Ringwald 176*503a627eSMilanka Ringwald // link key 177*503a627eSMilanka Ringwald int (*get_link_key)(bd_addr_t bd_addr, link_key_t link_key); 178*503a627eSMilanka Ringwald void (*put_link_key)(bd_addr_t bd_addr, link_key_t key); 179*503a627eSMilanka Ringwald void (*delete_link_key)(bd_addr_t bd_addr); 180*503a627eSMilanka Ringwald } btstack_link_key_db_t; 181*503a627eSMilanka Ringwald~~~~ 182