Skip to content

Commit 63946d5

Browse files
author
Cruz Monrreal
authored
Merge pull request #8452 from u-blox/ublox_odin_driver_os_5_v3.5.0_rc1
ble: update ODIN drivers to v3.5.0 RC1
2 parents 01f864e + 9854c1b commit 63946d5

File tree

8 files changed

+458
-2
lines changed

8 files changed

+458
-2
lines changed
Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
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+
public:
36+
HCIDriver(cordio::CordioHCITransportDriver &transport_driver, PinName shutdown_name, PinName hci_rts_name) :
37+
cordio::CordioHCIDriver(transport_driver),
38+
shutdown(shutdown_name, 0),
39+
hci_rts(hci_rts_name, 0),
40+
service_pack_index(0),
41+
service_pack_transfered(false) {
42+
};
43+
44+
virtual void do_initialize();
45+
46+
virtual void do_terminate();
47+
48+
virtual void start_reset_sequence();
49+
50+
virtual void handle_reset_sequence(uint8_t *pMsg);
51+
52+
private:
53+
void start_service_pack_transfer(void)
54+
{
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+
{
62+
uint16_t cmd_len = odin_service_pack[service_pack_index + HCI_CMD_HDR_LEN];
63+
cmd_opcode_ack_expected = (odin_service_pack[service_pack_index + 2] << 8) | odin_service_pack[service_pack_index + 1];
64+
uint8_t *pBuf = hciCmdAlloc(cmd_opcode_ack_expected, cmd_len);
65+
if (pBuf) {
66+
memcpy(pBuf, odin_service_pack + service_pack_index + 1, cmd_len + HCI_CMD_HDR_LEN);
67+
hciCmdSend(pBuf);
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+
{
75+
/* check if response opcode is same as expected command opcode */
76+
MBED_ASSERT (cmd_opcode_ack_expected == opcode);
77+
78+
/* update service pack index */
79+
service_pack_index += (1 + HCI_CMD_HDR_LEN + odin_service_pack[service_pack_index + HCI_CMD_HDR_LEN]);
80+
81+
if (service_pack_index < service_pack_size)
82+
send_service_pack_command();
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+
} else {
88+
/* send BT device hardware address write command */
89+
send_hci_vs_cmd(HCID_VS_WRITE_BD_ADDR);
90+
cmd_opcode_ack_expected = HCID_VS_WRITE_BD_ADDR;
91+
}
92+
}
93+
94+
void hci_read_resolving_list_size(void)
95+
{
96+
/* if LL Privacy is supported by Controller and included */
97+
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_PRIVACY) &&
98+
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_PRIVACY)) {
99+
/* send next command in sequence */
100+
HciLeReadResolvingListSize();
101+
} else {
102+
hciCoreCb.resListSize = 0;
103+
104+
/* send next command in sequence */
105+
hci_read_max_data_len();
106+
}
107+
}
108+
109+
void hci_read_max_data_len(void)
110+
{
111+
/* if LE Data Packet Length Extensions is supported by Controller and included */
112+
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) &&
113+
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_DATA_LEN_EXT)) {
114+
/* send next command in sequence */
115+
HciLeReadMaxDataLen();
116+
} else {
117+
/* send next command in sequence */
118+
HciLeRandCmd();
119+
}
120+
}
121+
122+
DigitalOut shutdown; // power/shutdown pin for bt device
123+
DigitalOut hci_rts; // request to sent pin
124+
size_t service_pack_index; // Index of command to be recently sent over hci
125+
bool service_pack_transfered; // Flag to notify if service pack is completely transferred or not
126+
uint16_t cmd_opcode_ack_expected; // Command against which acknowledgment is expected
127+
uint32_t service_pack_size; // size of service pack
128+
char *odin_service_pack ; // Service pack needs to be provided by driver
129+
vs_cmd_send_t send_hci_vs_cmd ; // callback function to call vendor specific call handler
130+
131+
};
132+
133+
} // namespace odin_w2
134+
} // namespace vendor
135+
} // namespace ble
136+
137+
void ble::vendor::odin_w2::HCIDriver::do_initialize()
138+
{
139+
cordio_callback_s callback;
140+
141+
hci_rts = 1; // Flow Control is OFF
142+
143+
shutdown = 0; // BT Power is OFF
144+
wait_ms(20);
145+
shutdown = 1; // BT Power is ON
146+
wait_ms(500);
147+
148+
hci_rts = 0; // Flow Control is ON
149+
150+
/* ODIN ble driver initialization function */
151+
cbCordio_Btinit(&callback);
152+
153+
odin_service_pack = callback.Service_pack;
154+
send_hci_vs_cmd = callback.vs_command_callback;
155+
service_pack_size = callback.service_pack_size;
156+
}
157+
158+
void ble::vendor::odin_w2::HCIDriver::do_terminate()
159+
{
160+
161+
}
162+
163+
void ble::vendor::odin_w2::HCIDriver::start_reset_sequence()
164+
{
165+
/* Update baudrate of ble to speed up setup time */
166+
send_hci_vs_cmd(HCID_VS_UPDATE_UART_BAUD_RATE);
167+
168+
}
169+
170+
void ble::vendor::odin_w2::HCIDriver::handle_reset_sequence(uint8_t *pMsg)
171+
{
172+
uint16_t opcode;
173+
static uint8_t randCnt;
174+
175+
/* if event is a command complete event */
176+
if (*pMsg == HCI_CMD_CMPL_EVT) {
177+
/* parse parameters */
178+
pMsg += HCI_EVT_HDR_LEN;
179+
pMsg++; /* skip num packets */
180+
BSTREAM_TO_UINT16(opcode, pMsg);
181+
pMsg++; /* skip status */
182+
183+
if (opcode == HCID_VS_UPDATE_UART_BAUD_RATE) {
184+
update_uart_baud_rate();
185+
start_service_pack_transfer();
186+
return;
187+
}
188+
189+
if (service_pack_transfered == false) {
190+
ack_service_pack_command(opcode, pMsg);
191+
return;
192+
}
193+
194+
/* decode opcode */
195+
switch (opcode) {
196+
197+
case HCI_OPCODE_RESET:
198+
/* Send (fast and slow) clock configuration command */
199+
send_hci_vs_cmd(HCID_VS_FAST_CLOCK_CONFIG_BTIP);
200+
break;
201+
202+
case HCID_VS_FAST_CLOCK_CONFIG_BTIP:
203+
/* Send deep-sleep behavior control command (setting retransmission, inactivity and rts pulse width for Bt) */
204+
send_hci_vs_cmd(HCID_VS_HCILL_PARS_CFG);
205+
break;
206+
207+
case HCID_VS_HCILL_PARS_CFG:
208+
/* Send sleep mode configuration command */
209+
send_hci_vs_cmd(HCID_VS_SLEEP_PROTOCOLS_CFG);
210+
break;
211+
212+
case HCID_VS_SLEEP_PROTOCOLS_CFG:
213+
/* initialize rand command count */
214+
randCnt = 0;
215+
216+
/* send next command in sequence */
217+
HciSetEventMaskCmd((uint8_t *)hciEventMask);
218+
break;
219+
220+
case HCI_OPCODE_SET_EVENT_MASK:
221+
/* send next command in sequence */
222+
HciLeSetEventMaskCmd((uint8_t *)hciLeEventMask);
223+
break;
224+
225+
case HCI_OPCODE_LE_SET_EVENT_MASK:
226+
/* send next command in sequence */
227+
HciSetEventMaskPage2Cmd((uint8_t *)hciEventMaskPage2);
228+
break;
229+
230+
case HCI_OPCODE_SET_EVENT_MASK_PAGE2:
231+
/* send next command in sequence */
232+
HciReadBdAddrCmd();
233+
break;
234+
235+
case HCI_OPCODE_READ_BD_ADDR:
236+
/* parse and store event parameters */
237+
BdaCpy(hciCoreCb.bdAddr, pMsg);
238+
239+
/* send next command in sequence */
240+
HciLeReadBufSizeCmd();
241+
break;
242+
243+
case HCI_OPCODE_LE_READ_BUF_SIZE:
244+
/* parse and store event parameters */
245+
BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg);
246+
BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg);
247+
248+
/* initialize ACL buffer accounting */
249+
hciCoreCb.availBufs = hciCoreCb.numBufs;
250+
251+
/* send next command in sequence */
252+
HciLeReadSupStatesCmd();
253+
break;
254+
255+
case HCI_OPCODE_LE_READ_SUP_STATES:
256+
/* parse and store event parameters */
257+
memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN);
258+
259+
/* send next command in sequence */
260+
HciLeReadWhiteListSizeCmd();
261+
break;
262+
263+
case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE:
264+
/* parse and store event parameters */
265+
BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg);
266+
267+
/* send next command in sequence */
268+
HciLeReadLocalSupFeatCmd();
269+
break;
270+
271+
case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT:
272+
/* parse and store event parameters */
273+
BSTREAM_TO_UINT16(hciCoreCb.leSupFeat, pMsg);
274+
275+
/* send next command in sequence */
276+
hci_read_resolving_list_size();
277+
break;
278+
279+
case HCI_OPCODE_LE_READ_RES_LIST_SIZE:
280+
/* parse and store event parameters */
281+
BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg);
282+
283+
/* send next command in sequence */
284+
hci_read_max_data_len();
285+
break;
286+
287+
case HCI_OPCODE_LE_READ_MAX_DATA_LEN:
288+
uint16_t maxTxOctets;
289+
uint16_t maxTxTime;
290+
291+
BSTREAM_TO_UINT16(maxTxOctets, pMsg);
292+
BSTREAM_TO_UINT16(maxTxTime, pMsg);
293+
294+
/* use Controller's maximum supported payload octets and packet duration times
295+
* for transmission as Host's suggested values for maximum transmission number
296+
* of payload octets and maximum packet transmission time for new connections.
297+
*/
298+
HciLeWriteDefDataLen(maxTxOctets, maxTxTime);
299+
break;
300+
301+
case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN:
302+
if (hciCoreCb.extResetSeq) {
303+
/* send first extended command */
304+
(*hciCoreCb.extResetSeq)(pMsg, opcode);
305+
} else {
306+
/* initialize extended parameters */
307+
hciCoreCb.maxAdvDataLen = 0;
308+
hciCoreCb.numSupAdvSets = 0;
309+
hciCoreCb.perAdvListSize = 0;
310+
311+
/* send next command in sequence */
312+
HciLeRandCmd();
313+
}
314+
break;
315+
316+
case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN:
317+
case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS:
318+
case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE:
319+
if (hciCoreCb.extResetSeq) {
320+
/* send next extended command in sequence */
321+
(*hciCoreCb.extResetSeq)(pMsg, opcode);
322+
}
323+
break;
324+
325+
case HCI_OPCODE_LE_RAND:
326+
/* check if need to send second rand command */
327+
if (randCnt < (HCI_RESET_RAND_CNT - 1)) {
328+
randCnt++;
329+
HciLeRandCmd();
330+
} else {
331+
signal_reset_sequence_done();
332+
}
333+
break;
334+
335+
default:
336+
break;
337+
}
338+
}
339+
}
340+
341+
ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver() {
342+
static ble::vendor::cordio::H4TransportDriver transport_driver (/* cbCFG_PIO_PIN_BT_HCI_TX */ PG_14,
343+
/* cbCFG_PIO_PIN_BT_HCI_RX */ PC_7,
344+
/* cbCFG_PIO_PIN_BT_HCI_CTS */ PG_15,
345+
/* cbCFG_PIO_PIN_BT_HCI_RTS */ PG_12,
346+
115200);
347+
static ble::vendor::odin_w2::HCIDriver hci_driver ( transport_driver,
348+
/* cbCFG_PIO_PIN_BT_ENABLE */ PG_7,
349+
/* cbCFG_PIO_PIN_BT_HCI_RTS */ PG_12);
350+
351+
return hci_driver;
352+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017-2017 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+
#ifndef ODIN_CORDIO_INTF_H
18+
#define ODIN_CORDIO_INTF_H
19+
20+
#include <stdio.h>
21+
#include "cb_main.h"
22+
23+
/*------------------------------------------------------------------------------
24+
* Vendor specific commands opcode
25+
* ------------------------------------------------------------------------------
26+
*/
27+
28+
/* Command to write hardware address to BT device */
29+
#define HCID_VS_WRITE_BD_ADDR 0xFC06
30+
31+
/* It configures clk parameters for fast and slow clock */
32+
#define HCID_VS_FAST_CLOCK_CONFIG_BTIP 0xFD1C
33+
34+
/* Command to configure stand-by behavior */
35+
#define HCID_VS_HCILL_PARS_CFG 0xFD2B
36+
37+
/* Command to configures the sleep mode */
38+
#define HCID_VS_SLEEP_PROTOCOLS_CFG 0xFD0C
39+
40+
/* Command to Update BT device baudrate */
41+
#define HCID_VS_UPDATE_UART_BAUD_RATE 0xFF36
42+
43+
#define HCI_RESET_RAND_CNT 4
44+
45+
#endif /* ODIN_CORDIO_INTF_H */

0 commit comments

Comments
 (0)