1 /**
2 ******************************************************************************
3 * @file shci.c
4 * @author MCD Application Team
5 * @brief HCI command for the system channel
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2018-2021 STMicroelectronics.
10 * All rights reserved.
11 *
12 * This software is licensed under terms that can be found in the LICENSE file
13 * in the root directory of this software component.
14 * If no LICENSE file comes with this software, it is provided AS-IS.
15 *
16 ******************************************************************************
17 */
18
19
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32_wpan_common.h"
22
23 #include "shci_tl.h"
24 #include "shci.h"
25 #include "stm32wbxx.h"
26
27 /* Private typedef -----------------------------------------------------------*/
28 /* Private defines -----------------------------------------------------------*/
29 /* Private macros ------------------------------------------------------------*/
30 /* Private variables ---------------------------------------------------------*/
31 /* Global variables ----------------------------------------------------------*/
32 /* Private function prototypes -----------------------------------------------*/
33 /* Local Functions Definition ------------------------------------------------------*/
34 /* Public Functions Definition ------------------------------------------------------*/
35
36 /**
37 * C2 COMMAND
38 * These commands are sent to the CPU2
39 */
SHCI_C2_FUS_GetState(SHCI_FUS_GetState_ErrorCode_t * p_error_code)40 uint8_t SHCI_C2_FUS_GetState( SHCI_FUS_GetState_ErrorCode_t *p_error_code )
41 {
42 /**
43 * Buffer is large enough to hold command complete with payload
44 */
45 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE + 1];
46 TL_EvtPacket_t * p_rsp;
47
48 p_rsp = (TL_EvtPacket_t *)local_buffer;
49
50 shci_send( SHCI_OPCODE_C2_FUS_GET_STATE,
51 0,
52 0,
53 p_rsp );
54
55 if(p_error_code != 0)
56 {
57 *p_error_code = (SHCI_FUS_GetState_ErrorCode_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[1]);
58 }
59
60 return (((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
61 }
62
SHCI_C2_FUS_FwUpgrade(uint32_t fw_src_add,uint32_t fw_dest_add)63 SHCI_CmdStatus_t SHCI_C2_FUS_FwUpgrade( uint32_t fw_src_add, uint32_t fw_dest_add )
64 {
65 /**
66 * TL_BLEEVT_CC_BUFFER_SIZE is 16 bytes so it is large enough to hold the 8 bytes of command parameters
67 * Buffer is large enough to hold command complete without payload
68 */
69 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
70 TL_EvtPacket_t * p_rsp;
71 uint32_t *p_cmd;
72 uint8_t cmd_length;
73
74 p_cmd = (uint32_t*)local_buffer;
75 cmd_length = 0;
76
77 if(fw_src_add != 0)
78 {
79 *p_cmd = fw_src_add;
80 cmd_length += 4;
81 }
82
83 if(fw_dest_add != 0)
84 {
85 *(p_cmd+1) = fw_dest_add;
86 cmd_length += 4;
87 }
88
89 p_rsp = (TL_EvtPacket_t *)local_buffer;
90
91 shci_send( SHCI_OPCODE_C2_FUS_FW_UPGRADE,
92 cmd_length,
93 local_buffer,
94 p_rsp );
95
96 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
97 }
98
SHCI_C2_FUS_FwDelete(void)99 SHCI_CmdStatus_t SHCI_C2_FUS_FwDelete( void )
100 {
101 /**
102 * Buffer is large enough to hold command complete without payload
103 */
104 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
105 TL_EvtPacket_t * p_rsp;
106
107 p_rsp = (TL_EvtPacket_t *)local_buffer;
108
109 shci_send( SHCI_OPCODE_C2_FUS_FW_DELETE,
110 0,
111 0,
112 p_rsp );
113
114 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
115 }
116
SHCI_C2_FUS_UpdateAuthKey(SHCI_C2_FUS_UpdateAuthKey_Cmd_Param_t * pParam)117 SHCI_CmdStatus_t SHCI_C2_FUS_UpdateAuthKey( SHCI_C2_FUS_UpdateAuthKey_Cmd_Param_t *pParam )
118 {
119 /**
120 * Buffer is large enough to hold command complete without payload
121 */
122 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
123 TL_EvtPacket_t * p_rsp;
124
125 p_rsp = (TL_EvtPacket_t *)local_buffer;
126
127 shci_send( SHCI_OPCODE_C2_FUS_UPDATE_AUTH_KEY,
128 sizeof( SHCI_C2_FUS_UpdateAuthKey_Cmd_Param_t ),
129 (uint8_t*)pParam,
130 p_rsp );
131
132 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
133 }
134
SHCI_C2_FUS_LockAuthKey(void)135 SHCI_CmdStatus_t SHCI_C2_FUS_LockAuthKey( void )
136 {
137 /**
138 * Buffer is large enough to hold command complete without payload
139 */
140 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
141 TL_EvtPacket_t * p_rsp;
142
143 p_rsp = (TL_EvtPacket_t *)local_buffer;
144
145 shci_send( SHCI_OPCODE_C2_FUS_LOCK_AUTH_KEY,
146 0,
147 0,
148 p_rsp );
149
150 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
151 }
152
SHCI_C2_FUS_StoreUsrKey(SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t * pParam,uint8_t * p_key_index)153 SHCI_CmdStatus_t SHCI_C2_FUS_StoreUsrKey( SHCI_C2_FUS_StoreUsrKey_Cmd_Param_t *pParam, uint8_t *p_key_index )
154 {
155 /**
156 * Buffer is large enough to hold command complete with payload
157 */
158 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE + 1];
159 TL_EvtPacket_t * p_rsp;
160 uint8_t local_payload_len;
161
162 if(pParam->KeyType == KEYTYPE_ENCRYPTED)
163 {
164 /**
165 * When the key is encrypted, the 12 bytes IV Key is included in the payload as well
166 * The IV key is always 12 bytes
167 */
168 local_payload_len = pParam->KeySize + 2 + 12;
169 }
170 else
171 {
172 local_payload_len = pParam->KeySize + 2;
173 }
174
175 p_rsp = (TL_EvtPacket_t *)local_buffer;
176
177 shci_send( SHCI_OPCODE_C2_FUS_STORE_USR_KEY,
178 local_payload_len ,
179 (uint8_t*)pParam,
180 p_rsp );
181
182 *p_key_index = (((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[1]);
183
184 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
185 }
186
SHCI_C2_FUS_LoadUsrKey(uint8_t key_index)187 SHCI_CmdStatus_t SHCI_C2_FUS_LoadUsrKey( uint8_t key_index )
188 {
189 /**
190 * Buffer is large enough to hold command complete without payload
191 */
192 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
193 TL_EvtPacket_t * p_rsp;
194
195 p_rsp = (TL_EvtPacket_t *)local_buffer;
196
197 local_buffer[0] = key_index;
198
199 shci_send( SHCI_OPCODE_C2_FUS_LOAD_USR_KEY,
200 1,
201 local_buffer,
202 p_rsp );
203
204 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
205 }
206
SHCI_C2_FUS_StartWs(void)207 SHCI_CmdStatus_t SHCI_C2_FUS_StartWs( void )
208 {
209 /**
210 * Buffer is large enough to hold command complete without payload
211 */
212 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
213 TL_EvtPacket_t * p_rsp;
214
215 p_rsp = (TL_EvtPacket_t *)local_buffer;
216
217 shci_send( SHCI_OPCODE_C2_FUS_START_WS,
218 0,
219 0,
220 p_rsp );
221
222 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
223 }
224
SHCI_C2_FUS_LockUsrKey(uint8_t key_index)225 SHCI_CmdStatus_t SHCI_C2_FUS_LockUsrKey( uint8_t key_index )
226 {
227 /**
228 * Buffer is large enough to hold command complete without payload
229 */
230 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
231 TL_EvtPacket_t * p_rsp;
232
233 p_rsp = (TL_EvtPacket_t *)local_buffer;
234
235 local_buffer[0] = key_index;
236
237 shci_send( SHCI_OPCODE_C2_FUS_LOCK_USR_KEY,
238 1,
239 local_buffer,
240 p_rsp );
241
242 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
243 }
244
SHCI_C2_FUS_UnloadUsrKey(uint8_t key_index)245 SHCI_CmdStatus_t SHCI_C2_FUS_UnloadUsrKey( uint8_t key_index )
246 {
247 /**
248 * Buffer is large enough to hold command complete without payload
249 */
250 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
251 TL_EvtPacket_t * p_rsp;
252
253 p_rsp = (TL_EvtPacket_t *)local_buffer;
254
255 local_buffer[0] = key_index;
256
257 shci_send( SHCI_OPCODE_C2_FUS_UNLOAD_USR_KEY,
258 1,
259 local_buffer,
260 p_rsp );
261
262 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
263 }
264
SHCI_C2_FUS_ActivateAntiRollback(void)265 SHCI_CmdStatus_t SHCI_C2_FUS_ActivateAntiRollback( void )
266 {
267 /**
268 * Buffer is large enough to hold command complete without payload
269 */
270 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
271 TL_EvtPacket_t * p_rsp;
272
273 p_rsp = (TL_EvtPacket_t *)local_buffer;
274
275 shci_send( SHCI_OPCODE_C2_FUS_ACTIVATE_ANTIROLLBACK,
276 0,
277 0,
278 p_rsp );
279
280 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
281 }
282
SHCI_C2_BLE_Init(SHCI_C2_Ble_Init_Cmd_Packet_t * pCmdPacket)283 SHCI_CmdStatus_t SHCI_C2_BLE_Init( SHCI_C2_Ble_Init_Cmd_Packet_t *pCmdPacket )
284 {
285 /**
286 * Buffer is large enough to hold command complete without payload
287 */
288 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
289 TL_EvtPacket_t * p_rsp;
290
291 p_rsp = (TL_EvtPacket_t *)local_buffer;
292
293 shci_send( SHCI_OPCODE_C2_BLE_INIT,
294 sizeof( SHCI_C2_Ble_Init_Cmd_Param_t ),
295 (uint8_t*)&pCmdPacket->Param,
296 p_rsp );
297
298 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
299 }
300
SHCI_C2_THREAD_Init(void)301 SHCI_CmdStatus_t SHCI_C2_THREAD_Init( void )
302 {
303 /**
304 * Buffer is large enough to hold command complete without payload
305 */
306 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
307 TL_EvtPacket_t * p_rsp;
308
309 p_rsp = (TL_EvtPacket_t *)local_buffer;
310
311 shci_send( SHCI_OPCODE_C2_THREAD_INIT,
312 0,
313 0,
314 p_rsp );
315
316 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
317 }
318
SHCI_C2_LLDTESTS_Init(uint8_t param_size,uint8_t * p_param)319 SHCI_CmdStatus_t SHCI_C2_LLDTESTS_Init( uint8_t param_size, uint8_t * p_param )
320 {
321 /**
322 * Buffer is large enough to hold command complete without payload
323 */
324 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
325 TL_EvtPacket_t * p_rsp;
326
327 p_rsp = (TL_EvtPacket_t *)local_buffer;
328
329 shci_send( SHCI_OPCODE_C2_LLD_TESTS_INIT,
330 param_size,
331 p_param,
332 p_rsp );
333
334 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
335 }
336
SHCI_C2_BLE_LLD_Init(uint8_t param_size,uint8_t * p_param)337 SHCI_CmdStatus_t SHCI_C2_BLE_LLD_Init( uint8_t param_size, uint8_t * p_param )
338 {
339 /**
340 * Buffer is large enough to hold command complete without payload
341 */
342 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
343 TL_EvtPacket_t * p_rsp;
344
345 p_rsp = (TL_EvtPacket_t *)local_buffer;
346
347 shci_send( SHCI_OPCODE_C2_BLE_LLD_INIT,
348 param_size,
349 p_param,
350 p_rsp );
351
352 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
353 }
354
SHCI_C2_ZIGBEE_Init(void)355 SHCI_CmdStatus_t SHCI_C2_ZIGBEE_Init( void )
356 {
357 /**
358 * Buffer is large enough to hold command complete without payload
359 */
360 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
361 TL_EvtPacket_t * p_rsp;
362
363 p_rsp = (TL_EvtPacket_t *)local_buffer;
364
365 shci_send( SHCI_OPCODE_C2_ZIGBEE_INIT,
366 0,
367 0,
368 p_rsp );
369
370 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
371 }
372
SHCI_C2_DEBUG_Init(SHCI_C2_DEBUG_Init_Cmd_Packet_t * pCmdPacket)373 SHCI_CmdStatus_t SHCI_C2_DEBUG_Init( SHCI_C2_DEBUG_Init_Cmd_Packet_t *pCmdPacket )
374 {
375 /**
376 * Buffer is large enough to hold command complete without payload
377 */
378 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
379 TL_EvtPacket_t * p_rsp;
380
381 p_rsp = (TL_EvtPacket_t *)local_buffer;
382
383 shci_send( SHCI_OPCODE_C2_DEBUG_INIT,
384 sizeof( SHCI_C2_DEBUG_init_Cmd_Param_t ),
385 (uint8_t*)&pCmdPacket->Param,
386 p_rsp );
387
388 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
389 }
390
SHCI_C2_FLASH_EraseActivity(SHCI_EraseActivity_t erase_activity)391 SHCI_CmdStatus_t SHCI_C2_FLASH_EraseActivity( SHCI_EraseActivity_t erase_activity )
392 {
393 /**
394 * Buffer is large enough to hold command complete without payload
395 */
396 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
397 TL_EvtPacket_t * p_rsp;
398
399 p_rsp = (TL_EvtPacket_t *)local_buffer;
400
401 local_buffer[0] = erase_activity;
402
403 shci_send( SHCI_OPCODE_C2_FLASH_ERASE_ACTIVITY,
404 1,
405 local_buffer,
406 p_rsp );
407
408 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
409 }
410
SHCI_C2_CONCURRENT_SetMode(SHCI_C2_CONCURRENT_Mode_Param_t Mode)411 SHCI_CmdStatus_t SHCI_C2_CONCURRENT_SetMode( SHCI_C2_CONCURRENT_Mode_Param_t Mode )
412 {
413 /**
414 * Buffer is large enough to hold command complete without payload
415 */
416 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
417 TL_EvtPacket_t * p_rsp;
418
419 p_rsp = (TL_EvtPacket_t *)local_buffer;
420
421 local_buffer[0] = Mode;
422
423 shci_send( SHCI_OPCODE_C2_CONCURRENT_SET_MODE,
424 1,
425 local_buffer,
426 p_rsp );
427
428 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
429 }
430
SHCI_C2_CONCURRENT_GetNextBleEvtTime(SHCI_C2_CONCURRENT_GetNextBleEvtTime_Param_t * pParam)431 SHCI_CmdStatus_t SHCI_C2_CONCURRENT_GetNextBleEvtTime( SHCI_C2_CONCURRENT_GetNextBleEvtTime_Param_t *pParam )
432 {
433 /**
434 * Buffer is large enough to hold command complete with payload
435 */
436 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE+4];
437 TL_EvtPacket_t * p_rsp;
438
439 p_rsp = (TL_EvtPacket_t *)local_buffer;
440
441 shci_send( SHCI_OPCODE_C2_CONCURRENT_GET_NEXT_BLE_EVT_TIME,
442 0,
443 0,
444 p_rsp );
445
446 memcpy((void*)&(pParam->relative_time), (void*)&((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[1], sizeof(pParam->relative_time));
447
448 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
449 }
450
SHCI_C2_CONCURRENT_EnableNext_802154_EvtNotification(void)451 SHCI_CmdStatus_t SHCI_C2_CONCURRENT_EnableNext_802154_EvtNotification( void )
452 {
453 /**
454 * Buffer is large enough to hold command complete without payload
455 */
456 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
457 TL_EvtPacket_t * p_rsp;
458
459 p_rsp = (TL_EvtPacket_t *)local_buffer;
460
461 shci_send( SHCI_OPCODE_C2_CONCURRENT_ENABLE_NEXT_802154_EVT_NOTIFICATION,
462 0,
463 0,
464 p_rsp );
465
466 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
467 }
468
SHCI_C2_FLASH_StoreData(SHCI_C2_FLASH_Ip_t Ip)469 SHCI_CmdStatus_t SHCI_C2_FLASH_StoreData( SHCI_C2_FLASH_Ip_t Ip )
470 {
471 /**
472 * Buffer is large enough to hold command complete without payload
473 */
474 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
475 TL_EvtPacket_t * p_rsp;
476
477 p_rsp = (TL_EvtPacket_t *)local_buffer;
478
479 local_buffer[0] = Ip;
480
481 shci_send( SHCI_OPCODE_C2_FLASH_STORE_DATA,
482 1,
483 local_buffer,
484 p_rsp );
485
486 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
487 }
488
SHCI_C2_FLASH_EraseData(SHCI_C2_FLASH_Ip_t Ip)489 SHCI_CmdStatus_t SHCI_C2_FLASH_EraseData( SHCI_C2_FLASH_Ip_t Ip )
490 {
491 /**
492 * Buffer is large enough to hold command complete without payload
493 */
494 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
495 TL_EvtPacket_t * p_rsp;
496
497 p_rsp = (TL_EvtPacket_t *)local_buffer;
498
499 local_buffer[0] = Ip;
500
501 shci_send( SHCI_OPCODE_C2_FLASH_ERASE_DATA,
502 1,
503 local_buffer,
504 p_rsp );
505
506 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
507 }
508
SHCI_C2_RADIO_AllowLowPower(SHCI_C2_FLASH_Ip_t Ip,uint8_t FlagRadioLowPowerOn)509 SHCI_CmdStatus_t SHCI_C2_RADIO_AllowLowPower( SHCI_C2_FLASH_Ip_t Ip,uint8_t FlagRadioLowPowerOn)
510 {
511 /**
512 * Buffer is large enough to hold command complete without payload
513 */
514 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
515 TL_EvtPacket_t * p_rsp;
516
517 p_rsp = (TL_EvtPacket_t *)local_buffer;
518
519 local_buffer[0] = Ip;
520 local_buffer[1] = FlagRadioLowPowerOn;
521
522 shci_send( SHCI_OPCODE_C2_RADIO_ALLOW_LOW_POWER,
523 2,
524 local_buffer,
525 p_rsp );
526
527 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
528 }
529
SHCI_C2_MAC_802_15_4_Init(void)530 SHCI_CmdStatus_t SHCI_C2_MAC_802_15_4_Init( void )
531 {
532 /**
533 * Buffer is large enough to hold command complete without payload
534 */
535 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
536 TL_EvtPacket_t * p_rsp;
537
538 p_rsp = (TL_EvtPacket_t *)local_buffer;
539
540 shci_send( SHCI_OPCODE_C2_MAC_802_15_4_INIT,
541 0,
542 0,
543 p_rsp );
544
545 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
546 }
547
SHCI_C2_Reinit(void)548 SHCI_CmdStatus_t SHCI_C2_Reinit( void )
549 {
550 /**
551 * Buffer is large enough to hold command complete without payload
552 */
553 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
554 TL_EvtPacket_t * p_rsp;
555
556 p_rsp = (TL_EvtPacket_t *)local_buffer;
557
558 shci_send( SHCI_OPCODE_C2_REINIT,
559 0,
560 0,
561 p_rsp );
562
563 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
564 }
565
SHCI_C2_ExtpaConfig(uint32_t gpio_port,uint16_t gpio_pin_number,uint8_t gpio_polarity,uint8_t gpio_status)566 SHCI_CmdStatus_t SHCI_C2_ExtpaConfig(uint32_t gpio_port, uint16_t gpio_pin_number, uint8_t gpio_polarity, uint8_t gpio_status)
567 {
568 /**
569 * TL_BLEEVT_CC_BUFFER_SIZE is 16 bytes so it is large enough to hold the 8 bytes of command parameters
570 * Buffer is large enough to hold command complete without payload
571 */
572 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
573 TL_EvtPacket_t * p_rsp;
574
575 p_rsp = (TL_EvtPacket_t *)local_buffer;
576
577 ((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_port = gpio_port;
578 ((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_pin_number = gpio_pin_number;
579 ((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_polarity = gpio_polarity;
580 ((SHCI_C2_EXTPA_CONFIG_Cmd_Param_t*)local_buffer)->gpio_status = gpio_status;
581
582 shci_send( SHCI_OPCODE_C2_EXTPA_CONFIG,
583 8,
584 local_buffer,
585 p_rsp );
586
587 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
588 }
589
SHCI_C2_SetFlashActivityControl(SHCI_C2_SET_FLASH_ACTIVITY_CONTROL_Source_t Source)590 SHCI_CmdStatus_t SHCI_C2_SetFlashActivityControl(SHCI_C2_SET_FLASH_ACTIVITY_CONTROL_Source_t Source)
591 {
592 /**
593 * TL_BLEEVT_CC_BUFFER_SIZE is 16 bytes so it is large enough to hold the 1 byte of command parameter
594 * Buffer is large enough to hold command complete without payload
595 */
596 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
597 TL_EvtPacket_t * p_rsp;
598
599 p_rsp = (TL_EvtPacket_t *)local_buffer;
600
601 local_buffer[0] = (uint8_t)Source;
602
603 shci_send( SHCI_OPCODE_C2_SET_FLASH_ACTIVITY_CONTROL,
604 1,
605 local_buffer,
606 p_rsp );
607
608 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
609 }
610
SHCI_C2_Config(SHCI_C2_CONFIG_Cmd_Param_t * pCmdPacket)611 SHCI_CmdStatus_t SHCI_C2_Config(SHCI_C2_CONFIG_Cmd_Param_t *pCmdPacket)
612 {
613 /**
614 * Buffer is large enough to hold command complete without payload
615 */
616 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
617 TL_EvtPacket_t * p_rsp;
618
619 p_rsp = (TL_EvtPacket_t *)local_buffer;
620
621 shci_send( SHCI_OPCODE_C2_CONFIG,
622 sizeof(SHCI_C2_CONFIG_Cmd_Param_t),
623 (uint8_t*)pCmdPacket,
624 p_rsp );
625
626 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
627 }
628
SHCI_C2_802_15_4_DeInit(void)629 SHCI_CmdStatus_t SHCI_C2_802_15_4_DeInit( void )
630 {
631 /**
632 * Buffer is large enough to hold command complete without payload
633 */
634 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
635 TL_EvtPacket_t * p_rsp;
636
637 p_rsp = (TL_EvtPacket_t *)local_buffer;
638
639 shci_send( SHCI_OPCODE_C2_802_15_4_DEINIT,
640 0,
641 0,
642 p_rsp );
643
644 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
645 }
646
SHCI_C2_SetSystemClock(SHCI_C2_SET_SYSTEM_CLOCK_Cmd_Param_t clockSel)647 SHCI_CmdStatus_t SHCI_C2_SetSystemClock( SHCI_C2_SET_SYSTEM_CLOCK_Cmd_Param_t clockSel )
648 {
649 /**
650 * Buffer is large enough to hold command complete without payload
651 */
652 uint8_t local_buffer[TL_BLEEVT_CC_BUFFER_SIZE];
653 TL_EvtPacket_t * p_rsp;
654
655 p_rsp = (TL_EvtPacket_t *)local_buffer;
656
657 local_buffer[0] = (uint8_t)clockSel;
658
659 shci_send( SHCI_OPCODE_C2_SET_SYSTEM_CLOCK,
660 1,
661 local_buffer,
662 p_rsp );
663
664 return (SHCI_CmdStatus_t)(((TL_CcEvt_t*)(p_rsp->evtserial.evt.payload))->payload[0]);
665 }
666
667 /**
668 * Local System COMMAND
669 * These commands are NOT sent to the CPU2
670 */
671
SHCI_GetWirelessFwInfo(WirelessFwInfo_t * pWirelessInfo)672 SHCI_CmdStatus_t SHCI_GetWirelessFwInfo( WirelessFwInfo_t* pWirelessInfo )
673 {
674 uint32_t ipccdba = 0;
675 MB_RefTable_t * p_RefTable = NULL;
676 uint32_t wireless_firmware_version = 0;
677 uint32_t wireless_firmware_memorySize = 0;
678 uint32_t wireless_firmware_infoStack = 0;
679 MB_FUS_DeviceInfoTable_t * p_fus_device_info_table = NULL;
680 uint32_t fus_version = 0;
681 uint32_t fus_memorySize = 0;
682
683 ipccdba = READ_BIT( FLASH->IPCCBR, FLASH_IPCCBR_IPCCDBA );
684
685 /**
686 * The Device Info Table mapping depends on which firmware is running on CPU2.
687 * If the FUS is running on CPU2, FUS_DEVICE_INFO_TABLE_VALIDITY_KEYWORD shall be written in the table.
688 * Otherwise, it means the Wireless Firmware is running on the CPU2
689 */
690 p_fus_device_info_table = (MB_FUS_DeviceInfoTable_t*)(*(uint32_t*)((ipccdba<<2) + SRAM2A_BASE));
691
692 if(p_fus_device_info_table->DeviceInfoTableState == FUS_DEVICE_INFO_TABLE_VALIDITY_KEYWORD)
693 {
694 /* The FUS is running on CPU2 */
695 /**
696 * Retrieve the WirelessFwInfoTable
697 * This table is stored in RAM at startup during the TL (transport layer) initialization
698 */
699 wireless_firmware_version = p_fus_device_info_table->WirelessStackVersion;
700 wireless_firmware_memorySize = p_fus_device_info_table->WirelessStackMemorySize;
701 wireless_firmware_infoStack = p_fus_device_info_table->WirelessFirmwareBleInfo;
702
703 /**
704 * Retrieve the FusInfoTable
705 * This table is stored in RAM at startup during the TL (transport layer) initialization
706 */
707 fus_version = p_fus_device_info_table->FusVersion;
708 fus_memorySize = p_fus_device_info_table->FusMemorySize;
709 }
710 else
711 {
712 /* The Wireless Firmware is running on CPU2 */
713 p_RefTable = (MB_RefTable_t*)((ipccdba<<2) + SRAM2A_BASE);
714
715 /**
716 * Retrieve the WirelessFwInfoTable
717 * This table is stored in RAM at startup during the TL (transport layer) initialization
718 */
719 wireless_firmware_version = p_RefTable->p_device_info_table->WirelessFwInfoTable.Version;
720 wireless_firmware_memorySize = p_RefTable->p_device_info_table->WirelessFwInfoTable.MemorySize;
721 wireless_firmware_infoStack = p_RefTable->p_device_info_table->WirelessFwInfoTable.InfoStack;
722
723 /**
724 * Retrieve the FusInfoTable
725 * This table is stored in RAM at startup during the TL (transport layer) initialization
726 */
727 fus_version = p_RefTable->p_device_info_table->FusInfoTable.Version;
728 fus_memorySize = p_RefTable->p_device_info_table->FusInfoTable.MemorySize;
729 }
730
731 /**
732 * Retrieve the WirelessFwInfoTable
733 * This table is stored in RAM at startup during the TL (transport layer) initialization
734 */
735 pWirelessInfo->VersionMajor = ((wireless_firmware_version & INFO_VERSION_MAJOR_MASK) >> INFO_VERSION_MAJOR_OFFSET);
736 pWirelessInfo->VersionMinor = ((wireless_firmware_version & INFO_VERSION_MINOR_MASK) >> INFO_VERSION_MINOR_OFFSET);
737 pWirelessInfo->VersionSub = ((wireless_firmware_version & INFO_VERSION_SUB_MASK) >> INFO_VERSION_SUB_OFFSET);
738 pWirelessInfo->VersionBranch = ((wireless_firmware_version & INFO_VERSION_BRANCH_MASK) >> INFO_VERSION_BRANCH_OFFSET);
739 pWirelessInfo->VersionReleaseType = ((wireless_firmware_version & INFO_VERSION_TYPE_MASK) >> INFO_VERSION_TYPE_OFFSET);
740
741 pWirelessInfo->MemorySizeSram2B = ((wireless_firmware_memorySize & INFO_SIZE_SRAM2B_MASK) >> INFO_SIZE_SRAM2B_OFFSET);
742 pWirelessInfo->MemorySizeSram2A = ((wireless_firmware_memorySize & INFO_SIZE_SRAM2A_MASK) >> INFO_SIZE_SRAM2A_OFFSET);
743 pWirelessInfo->MemorySizeSram1 = ((wireless_firmware_memorySize & INFO_SIZE_SRAM1_MASK) >> INFO_SIZE_SRAM1_OFFSET);
744 pWirelessInfo->MemorySizeFlash = ((wireless_firmware_memorySize & INFO_SIZE_FLASH_MASK) >> INFO_SIZE_FLASH_OFFSET);
745
746 pWirelessInfo->StackType = ((wireless_firmware_infoStack & INFO_STACK_TYPE_MASK) >> INFO_STACK_TYPE_OFFSET);
747
748 /**
749 * Retrieve the FusInfoTable
750 * This table is stored in RAM at startup during the TL (transport layer) initialization
751 */
752 pWirelessInfo->FusVersionMajor = ((fus_version & INFO_VERSION_MAJOR_MASK) >> INFO_VERSION_MAJOR_OFFSET);
753 pWirelessInfo->FusVersionMinor = ((fus_version & INFO_VERSION_MINOR_MASK) >> INFO_VERSION_MINOR_OFFSET);
754 pWirelessInfo->FusVersionSub = ((fus_version & INFO_VERSION_SUB_MASK) >> INFO_VERSION_SUB_OFFSET);
755
756 pWirelessInfo->FusMemorySizeSram2B = ((fus_memorySize & INFO_SIZE_SRAM2B_MASK) >> INFO_SIZE_SRAM2B_OFFSET);
757 pWirelessInfo->FusMemorySizeSram2A = ((fus_memorySize & INFO_SIZE_SRAM2A_MASK) >> INFO_SIZE_SRAM2A_OFFSET);
758 pWirelessInfo->FusMemorySizeFlash = ((fus_memorySize & INFO_SIZE_FLASH_MASK) >> INFO_SIZE_FLASH_OFFSET);
759
760 return (SHCI_Success);
761 }
762
763