Skip to content

Commit 2ac6cff

Browse files
committed
BLE support added
1 parent d30ae07 commit 2ac6cff

File tree

8 files changed

+477
-2
lines changed

8 files changed

+477
-2
lines changed
Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
/*
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "CordioBLE.h"
18+
#include "CordioHCIDriver.h"
19+
#include "hci_defs.h"
20+
#include "hci_api.h"
21+
#include "hci_cmd.h"
22+
#include "hci_core.h"
23+
#include "bstream.h"
24+
#include "wsf_buf.h"
25+
#include <stdbool.h>
26+
#include "hci_mbed_os_adaptation.h"
27+
#include "H4TransportDriver.h"
28+
#include "OdinCordioInterface.h"
29+
30+
namespace ble {
31+
namespace vendor {
32+
namespace odin_w2 {
33+
34+
class HCIDriver : public cordio::CordioHCIDriver {
35+
36+
public:
37+
HCIDriver(cordio::CordioHCITransportDriver& transport_driver, PinName shutdown_name, PinName hci_rts_name) :
38+
cordio::CordioHCIDriver(transport_driver),
39+
shutdown(shutdown_name, 0),
40+
hci_rts(hci_rts_name, 0),
41+
service_pack_index(0),
42+
service_pack_transfered(false) {
43+
};
44+
45+
virtual void do_initialize();
46+
47+
virtual void do_terminate();
48+
49+
virtual void start_reset_sequence();
50+
51+
virtual void handle_reset_sequence(uint8_t *pMsg);
52+
53+
private:
54+
void start_service_pack_transfert(void) {
55+
service_pack_index = 0;
56+
service_pack_transfered = false;
57+
send_service_pack_command();
58+
}
59+
60+
void send_service_pack_command(void) {
61+
uint16_t cmd_len = OdinServicePack[service_pack_index + HCI_CMD_HDR_LEN];
62+
cmd_opcode_ack_expected = (OdinServicePack[service_pack_index + 2] << 8) | OdinServicePack[service_pack_index + 1];
63+
uint8_t *pBuf = hciCmdAlloc(cmd_opcode_ack_expected, cmd_len);
64+
if (pBuf) {
65+
memcpy(pBuf, OdinServicePack + service_pack_index + 1, cmd_len + HCI_CMD_HDR_LEN);
66+
hciCmdSend(pBuf);
67+
}
68+
else {
69+
printf("Error cannot allocate memory for the buffer");
70+
}
71+
}
72+
73+
void ack_service_pack_command(uint16_t opcode, uint8_t* msg) {
74+
/* check if response opcode is same as expected command opcode */
75+
MBED_ASSERT (cmd_opcode_ack_expected == opcode);
76+
77+
// update service pack index
78+
service_pack_index += (1 + HCI_CMD_HDR_LEN + OdinServicePack[service_pack_index + HCI_CMD_HDR_LEN]);
79+
80+
if (service_pack_index < service_pack_size) {
81+
send_service_pack_command();
82+
}
83+
else if (opcode == HCID_VS_WRITE_BD_ADDR) {
84+
/* send an HCI Reset command to start the sequence */
85+
HciResetCmd();
86+
service_pack_transfered = true;
87+
}
88+
else {
89+
/* send BT device hardware address write command */
90+
send_hci_vs_cmd(HCID_VS_WRITE_BD_ADDR);
91+
cmd_opcode_ack_expected = HCID_VS_WRITE_BD_ADDR;
92+
}
93+
}
94+
95+
void hciCoreReadResolvingListSize(void)
96+
{
97+
/* if LL Privacy is supported by Controller and included */
98+
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_PRIVACY) &&
99+
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_PRIVACY))
100+
{
101+
/* send next command in sequence */
102+
HciLeReadResolvingListSize();
103+
}
104+
else
105+
{
106+
hciCoreCb.resListSize = 0;
107+
108+
/* send next command in sequence */
109+
hciCoreReadMaxDataLen();
110+
}
111+
}
112+
113+
void hciCoreReadMaxDataLen(void)
114+
{
115+
/* if LE Data Packet Length Extensions is supported by Controller and included */
116+
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) &&
117+
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_DATA_LEN_EXT))
118+
{
119+
/* send next command in sequence */
120+
HciLeReadMaxDataLen();
121+
}
122+
else
123+
{
124+
/* send next command in sequence */
125+
HciLeRandCmd();
126+
}
127+
}
128+
129+
DigitalOut shutdown; // power/shutdown pin for bt device
130+
DigitalOut hci_rts; // request to sent pin
131+
size_t service_pack_index; // Index of command to be recently sent over hci
132+
bool service_pack_transfered; // Flag to notify if service pack is completely transferred or not
133+
uint16_t cmd_opcode_ack_expected; // Command against which acknowledgment is expected
134+
uint32_t service_pack_size; // size of service pack
135+
char* OdinServicePack ;
136+
vs_cmd_send_t send_hci_vs_cmd ;
137+
138+
};
139+
140+
} // namespace odin_w2
141+
} // namespace vendor
142+
} // namespace ble
143+
144+
void ble::vendor::odin_w2::HCIDriver::do_initialize()
145+
{
146+
cordio_callback_s callback;
147+
148+
hci_rts = 1; // Flow Control is OFF
149+
150+
shutdown = 0; // BT Power is OFF
151+
wait_ms(20);
152+
shutdown = 1; // BT Power is ON
153+
wait_ms(500);
154+
155+
hci_rts = 0; // Flow Control is ON
156+
157+
/* ODIN ble driver initialization function */
158+
cbCordio_Btinit(&callback);
159+
160+
OdinServicePack = callback.Service_pack;
161+
send_hci_vs_cmd = callback.vs_command_callback;
162+
service_pack_size = callback.service_pack_size;
163+
}
164+
165+
void ble::vendor::odin_w2::HCIDriver::do_terminate()
166+
{
167+
// TODO: ASRI
168+
}
169+
170+
void ble::vendor::odin_w2::HCIDriver::start_reset_sequence()
171+
{
172+
/* Update baudrate of BT to speed up setup time */
173+
send_hci_vs_cmd(HCID_VS_UPDATE_UART_BAUD_RATE);
174+
175+
}
176+
177+
void ble::vendor::odin_w2::HCIDriver::handle_reset_sequence(uint8_t *pMsg)
178+
{
179+
uint16_t opcode;
180+
static uint8_t randCnt;
181+
182+
/* if event is a command complete event */
183+
if (*pMsg == HCI_CMD_CMPL_EVT)
184+
{
185+
/* parse parameters */
186+
pMsg += HCI_EVT_HDR_LEN;
187+
pMsg++; /* skip num packets */
188+
BSTREAM_TO_UINT16(opcode, pMsg);
189+
pMsg++; /* skip status */
190+
191+
if (opcode == HCID_VS_UPDATE_UART_BAUD_RATE)
192+
{
193+
update_uart_baud_rate();
194+
start_service_pack_transfert();
195+
return;
196+
}
197+
198+
if (service_pack_transfered == false) {
199+
ack_service_pack_command(opcode, pMsg);
200+
return;
201+
}
202+
203+
/* decode opcode */
204+
switch (opcode) {
205+
206+
case HCI_OPCODE_RESET:
207+
/* Send (fast and slow) clock configuration command */
208+
send_hci_vs_cmd(HCID_VS_FAST_CLOCK_CONFIG_BTIP);
209+
break;
210+
211+
case HCID_VS_FAST_CLOCK_CONFIG_BTIP:
212+
/* Send deep-sleep behavior control command (setting retransmission, inactivity and rts pulse width for Bt) */
213+
send_hci_vs_cmd(HCID_VS_HCILL_PARS_CFG);
214+
break;
215+
216+
case HCID_VS_HCILL_PARS_CFG:
217+
/* Send sleep mode configuration command */
218+
send_hci_vs_cmd(HCID_VS_SLEEP_PROTOCOLS_CFG);
219+
break;
220+
221+
case HCID_VS_SLEEP_PROTOCOLS_CFG:
222+
/* initialize rand command count */
223+
randCnt = 0;
224+
225+
/* send next command in sequence */
226+
HciSetEventMaskCmd((uint8_t *)hciEventMask);
227+
break;
228+
229+
case HCI_OPCODE_SET_EVENT_MASK:
230+
/* send next command in sequence */
231+
HciLeSetEventMaskCmd((uint8_t *)hciLeEventMask);
232+
break;
233+
234+
case HCI_OPCODE_LE_SET_EVENT_MASK:
235+
/* send next command in sequence */
236+
HciSetEventMaskPage2Cmd((uint8_t *)hciEventMaskPage2);
237+
break;
238+
239+
case HCI_OPCODE_SET_EVENT_MASK_PAGE2:
240+
/* send next command in sequence */
241+
HciReadBdAddrCmd();
242+
break;
243+
244+
case HCI_OPCODE_READ_BD_ADDR:
245+
/* parse and store event parameters */
246+
BdaCpy(hciCoreCb.bdAddr, pMsg);
247+
248+
/* send next command in sequence */
249+
HciLeReadBufSizeCmd();
250+
break;
251+
252+
case HCI_OPCODE_LE_READ_BUF_SIZE:
253+
/* parse and store event parameters */
254+
BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg);
255+
BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg);
256+
257+
/* initialize ACL buffer accounting */
258+
hciCoreCb.availBufs = hciCoreCb.numBufs;
259+
260+
/* send next command in sequence */
261+
HciLeReadSupStatesCmd();
262+
break;
263+
264+
case HCI_OPCODE_LE_READ_SUP_STATES:
265+
/* parse and store event parameters */
266+
memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN);
267+
268+
/* send next command in sequence */
269+
HciLeReadWhiteListSizeCmd();
270+
break;
271+
272+
case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE:
273+
/* parse and store event parameters */
274+
BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg);
275+
276+
/* send next command in sequence */
277+
HciLeReadLocalSupFeatCmd();
278+
break;
279+
280+
case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT:
281+
/* parse and store event parameters */
282+
BSTREAM_TO_UINT16(hciCoreCb.leSupFeat, pMsg);
283+
284+
/* send next command in sequence */
285+
hciCoreReadResolvingListSize();
286+
break;
287+
288+
case HCI_OPCODE_LE_READ_RES_LIST_SIZE:
289+
/* parse and store event parameters */
290+
BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg);
291+
292+
/* send next command in sequence */
293+
hciCoreReadMaxDataLen();
294+
break;
295+
296+
case HCI_OPCODE_LE_READ_MAX_DATA_LEN:
297+
{
298+
uint16_t maxTxOctets;
299+
uint16_t maxTxTime;
300+
301+
BSTREAM_TO_UINT16(maxTxOctets, pMsg);
302+
BSTREAM_TO_UINT16(maxTxTime, pMsg);
303+
304+
/* use Controller's maximum supported payload octets and packet duration times
305+
* for transmission as Host's suggested values for maximum transmission number
306+
* of payload octets and maximum packet transmission time for new connections.
307+
*/
308+
HciLeWriteDefDataLen(maxTxOctets, maxTxTime);
309+
}
310+
break;
311+
312+
case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN:
313+
if (hciCoreCb.extResetSeq)
314+
{
315+
/* send first extended command */
316+
(*hciCoreCb.extResetSeq)(pMsg, opcode);
317+
}
318+
else
319+
{
320+
/* initialize extended parameters */
321+
hciCoreCb.maxAdvDataLen = 0;
322+
hciCoreCb.numSupAdvSets = 0;
323+
hciCoreCb.perAdvListSize = 0;
324+
325+
/* send next command in sequence */
326+
HciLeRandCmd();
327+
}
328+
break;
329+
330+
case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN:
331+
case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS:
332+
case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE:
333+
if (hciCoreCb.extResetSeq)
334+
{
335+
/* send next extended command in sequence */
336+
(*hciCoreCb.extResetSeq)(pMsg, opcode);
337+
}
338+
break;
339+
340+
case HCI_OPCODE_LE_RAND:
341+
/* check if need to send second rand command */
342+
if (randCnt < (HCI_RESET_RAND_CNT - 1))
343+
{
344+
randCnt++;
345+
HciLeRandCmd();
346+
}
347+
else
348+
{
349+
signal_reset_sequence_done();
350+
}
351+
break;
352+
353+
default:
354+
break;
355+
}
356+
}
357+
}
358+
359+
ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() {
360+
static ble::vendor::cordio::H4TransportDriver transport_driver (/* cbCFG_PIO_PIN_BT_HCI_TX */ PG_14,
361+
/* cbCFG_PIO_PIN_BT_HCI_RX */ PC_7,
362+
/* cbCFG_PIO_PIN_BT_HCI_CTS */ PG_15,
363+
/* cbCFG_PIO_PIN_BT_HCI_RTS */ PG_12,
364+
115200);
365+
static ble::vendor::odin_w2::HCIDriver hci_driver ( transport_driver,
366+
/* cbCFG_PIO_PIN_BT_ENABLE */ PG_7,
367+
/* cbCFG_PIO_PIN_BT_HCI_RTS */ PG_12);
368+
369+
return hci_driver;
370+
}

0 commit comments

Comments
 (0)