Skip to content

Commit fefde9d

Browse files
authored
Merge pull request #2832 from jeremybrodt/max326xx_updates
Updates to Maxim Integrated targets.
2 parents f9ee683 + b4e2339 commit fefde9d

File tree

80 files changed

+7846
-366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+7846
-366
lines changed
Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
/*******************************************************************************
2+
* Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included
12+
* in all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
18+
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+
* OTHER DEALINGS IN THE SOFTWARE.
21+
*
22+
* Except as contained in this notice, the name of Maxim Integrated
23+
* Products, Inc. shall not be used except as stated in the Maxim Integrated
24+
* Products, Inc. Branding Policy.
25+
*
26+
* The mere transfer of this software does not imply any licenses
27+
* of trade secrets, proprietary technology, copyrights, patents,
28+
* trademarks, maskwork rights, or any other form of intellectual
29+
* property whatsoever. Maxim Integrated Products, Inc. retains all
30+
* ownership rights.
31+
*******************************************************************************
32+
*/
33+
34+
#include "mbed.h"
35+
#include "us_ticker_api.h"
36+
#include "MaximBLE.h"
37+
#include "wsf_types.h"
38+
#include "wsf_msg.h"
39+
#include "wsf_os.h"
40+
#include "wsf_buf.h"
41+
#include "wsf_sec.h"
42+
#include "wsf_timer.h"
43+
#include "hci_handler.h"
44+
#include "dm_handler.h"
45+
#include "l2c_handler.h"
46+
#include "att_handler.h"
47+
#include "smp_handler.h"
48+
#include "l2c_api.h"
49+
#include "att_api.h"
50+
#include "smp_api.h"
51+
#include "hci_drv.h"
52+
#include "hci_vs.h"
53+
54+
/* Number of WSF buffer pools */
55+
#define WSF_BUF_POOLS 4
56+
57+
/*! Free memory for pool buffers. */
58+
static uint8_t mainBufMem[768];
59+
60+
/*! Default pool descriptor. */
61+
static wsfBufPoolDesc_t mainPoolDesc[WSF_BUF_POOLS] =
62+
{
63+
{ 16, 8 },
64+
{ 32, 4 },
65+
{ 64, 2 },
66+
{ 128, 2 }
67+
};
68+
69+
/*! WSF handler ID */
70+
wsfHandlerId_t maximHandlerId;
71+
static volatile int reset_complete;
72+
73+
/* Current mbed SPI API does not support HW slave selects. Configured in HCI driver. */
74+
static DigitalOut _csn(HCI_CSN, 1);
75+
static SPI _spi(HCI_MOSI, HCI_MISO, HCI_SCK, HCI_CSN);
76+
static DigitalOut _rst(HCI_RST, 0);
77+
static InterruptIn _irq(HCI_IRQ);
78+
79+
/**
80+
* The singleton which represents the MaximBLE transport for the BLE.
81+
*/
82+
static MaximBLE deviceInstance;
83+
84+
/**
85+
* BLE-API requires an implementation of the following function in order to
86+
* obtain its transport handle.
87+
*/
88+
BLEInstanceBase *createBLEInstance(void)
89+
{
90+
return (&deviceInstance);
91+
}
92+
93+
MaximBLE::MaximBLE(void) : initialized(false), instanceID(BLE::DEFAULT_INSTANCE)
94+
{
95+
}
96+
97+
MaximBLE::~MaximBLE(void)
98+
{
99+
}
100+
101+
const char *MaximBLE::getVersion(void)
102+
{
103+
static char versionString[32];
104+
105+
strncpy(versionString, "unknown", sizeof(versionString));
106+
107+
return versionString;
108+
}
109+
110+
static void DmCback(dmEvt_t *pDmEvt)
111+
{
112+
dmEvt_t *pMsg;
113+
114+
if ((pMsg = (dmEvt_t*)WsfMsgAlloc(sizeof(dmEvt_t))) != NULL)
115+
{
116+
memcpy(pMsg, pDmEvt, sizeof(dmEvt_t));
117+
WsfMsgSend(maximHandlerId, pMsg);
118+
}
119+
}
120+
121+
static void maximHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
122+
{
123+
if (pMsg != NULL)
124+
{
125+
switch(pMsg->event)
126+
{
127+
case DM_RESET_CMPL_IND:
128+
reset_complete = 1;
129+
break;
130+
case DM_ADV_START_IND:
131+
break;
132+
case DM_ADV_STOP_IND:
133+
MaximGap::getInstance().advertisingStopped();
134+
break;
135+
case DM_SCAN_REPORT_IND:
136+
{
137+
hciLeAdvReportEvt_t *scanReport = (hciLeAdvReportEvt_t*)pMsg;
138+
MaximGap::getInstance().processAdvertisementReport( scanReport->addr,
139+
scanReport->rssi,
140+
(scanReport->eventType == DM_ADV_SCAN_RESPONSE) ? true : false,
141+
(GapAdvertisingParams::AdvertisingType_t)scanReport->eventType,
142+
scanReport->len,
143+
scanReport->pData);
144+
}
145+
break;
146+
case DM_CONN_OPEN_IND:
147+
{
148+
hciLeConnCmplEvt_t *connOpen = (hciLeConnCmplEvt_t*)pMsg;
149+
MaximGap::getInstance().setConnectionHandle(connOpen->handle);
150+
Gap::ConnectionParams_t params = { connOpen->connInterval, connOpen->connInterval, connOpen->connLatency, connOpen->supTimeout };
151+
Gap::AddressType_t ownAddrType;
152+
Gap::Address_t ownAddr;
153+
MaximGap::getInstance().getAddress(&ownAddrType, ownAddr);
154+
MaximGap::getInstance().processConnectionEvent(connOpen->handle,
155+
Gap::PERIPHERAL,
156+
(Gap::AddressType_t)connOpen->addrType,
157+
connOpen->peerAddr,
158+
ownAddrType,
159+
ownAddr,
160+
&params);
161+
}
162+
break;
163+
case DM_CONN_CLOSE_IND:
164+
{
165+
hciDisconnectCmplEvt_t *connClose = (hciDisconnectCmplEvt_t*)pMsg;
166+
MaximGap::getInstance().setConnectionHandle(DM_CONN_ID_NONE);
167+
MaximGap::getInstance().processDisconnectionEvent(connClose->handle, (Gap::DisconnectionReason_t)connClose->reason);
168+
}
169+
break;
170+
case DM_HW_ERROR_IND:
171+
{
172+
hciHwErrorEvt_t *error = (hciHwErrorEvt_t*)pMsg;
173+
printf("HCI Hardware Error 0x%02x occurred\n", error->code);
174+
}
175+
break;
176+
default:
177+
break;
178+
}
179+
}
180+
}
181+
182+
static void AppServerConnCback(dmEvt_t *pDmEvt)
183+
{
184+
dmConnId_t connId = (dmConnId_t)pDmEvt->hdr.param;
185+
186+
switch (pDmEvt->hdr.event)
187+
{
188+
case DM_CONN_OPEN_IND:
189+
/* set up CCC table with uninitialized (all zero) values */
190+
AttsCccInitTable(connId, NULL);
191+
break;
192+
case DM_CONN_CLOSE_IND:
193+
/* clear CCC table on connection close */
194+
AttsCccClearTable(connId);
195+
break;
196+
default:
197+
break;
198+
}
199+
}
200+
201+
ble_error_t MaximBLE::init(BLE::InstanceID_t instanceID, FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> initCallback)
202+
{
203+
wsfHandlerId_t handlerId;
204+
205+
/* init OS subsystems */
206+
WsfTimerInit(1);
207+
WsfBufInit(sizeof(mainBufMem), mainBufMem, WSF_BUF_POOLS, mainPoolDesc);
208+
WsfSecInit();
209+
210+
/* init stack */
211+
handlerId = WsfOsSetNextHandler(HciHandler);
212+
HciHandlerInit(handlerId);
213+
214+
handlerId = WsfOsSetNextHandler(DmHandler);
215+
DmAdvInit();
216+
DmScanInit();
217+
DmConnInit();
218+
DmConnSlaveInit();
219+
DmSecInit();
220+
DmHandlerInit(handlerId);
221+
222+
handlerId = WsfOsSetNextHandler(L2cSlaveHandler);
223+
L2cSlaveHandlerInit(handlerId);
224+
L2cInit();
225+
L2cMasterInit();
226+
L2cSlaveInit();
227+
228+
handlerId = WsfOsSetNextHandler(AttHandler);
229+
AttHandlerInit(handlerId);
230+
AttsInit();
231+
AttsIndInit();
232+
AttcInit();
233+
234+
handlerId = WsfOsSetNextHandler(SmpHandler);
235+
SmpHandlerInit(handlerId);
236+
SmpiInit();
237+
SmprInit();
238+
239+
/* store handler ID */
240+
maximHandlerId = WsfOsSetNextHandler(maximHandler);
241+
242+
/* init HCI */
243+
_irq.disable_irq();
244+
_irq.rise(hciDrvIsr);
245+
_irq.fall(NULL);
246+
hciDrvInit(HCI_CSN, HCI_RST, HCI_IRQ);
247+
248+
/* Register for stack callbacks */
249+
DmRegister(DmCback);
250+
DmConnRegister(DM_CLIENT_ID_APP, DmCback);
251+
AttConnRegister(AppServerConnCback);
252+
253+
/* Reset the device */
254+
reset_complete = 0;
255+
DmDevReset();
256+
257+
while (!reset_complete) {
258+
callDispatcher();
259+
}
260+
261+
initialized = true;
262+
BLE::InitializationCompleteCallbackContext context = {
263+
BLE::Instance(instanceID),
264+
BLE_ERROR_NONE
265+
};
266+
initCallback.call(&context);
267+
return BLE_ERROR_NONE;
268+
}
269+
270+
ble_error_t MaximBLE::shutdown(void)
271+
{
272+
return BLE_ERROR_NOT_IMPLEMENTED;
273+
}
274+
275+
void MaximBLE::waitForEvent(void)
276+
{
277+
static LowPowerTimeout nextTimeout;
278+
timestamp_t nextTimestamp;
279+
bool_t pTimerRunning;
280+
281+
callDispatcher();
282+
283+
if (wsfOsReadyToSleep()) {
284+
// setup an mbed timer for the next Wicentric timeout
285+
nextTimestamp = (timestamp_t)WsfTimerNextExpiration(&pTimerRunning) * 1000;
286+
if (pTimerRunning) {
287+
nextTimeout.attach_us(timeoutCallback, nextTimestamp);
288+
}
289+
290+
// go to sleep
291+
if (hciDrvReadyToSleep()) {
292+
// go to deep sleep
293+
deepsleep();
294+
hciDrvResume();
295+
}
296+
else {
297+
sleep();
298+
}
299+
}
300+
}
301+
302+
void MaximBLE::processEvents()
303+
{
304+
callDispatcher();
305+
}
306+
307+
void MaximBLE::timeoutCallback(void)
308+
{
309+
// do nothing. just an interrupt for wake up.
310+
}
311+
312+
void MaximBLE::callDispatcher(void)
313+
{
314+
static uint32_t lastTimeUs = us_ticker_read();
315+
uint32_t currTimeUs, deltaTimeMs;
316+
317+
// Update the current Wicentric time
318+
currTimeUs = us_ticker_read();
319+
deltaTimeMs = (currTimeUs - lastTimeUs) / 1000;
320+
if (deltaTimeMs > 0) {
321+
WsfTimerUpdate(deltaTimeMs);
322+
lastTimeUs += deltaTimeMs * 1000;
323+
}
324+
325+
wsfOsDispatcher();
326+
}

0 commit comments

Comments
 (0)