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 
647 /**
648  *  Local System COMMAND
649  *  These commands are NOT sent to the CPU2
650  */
651 
SHCI_GetWirelessFwInfo(WirelessFwInfo_t * pWirelessInfo)652 SHCI_CmdStatus_t SHCI_GetWirelessFwInfo( WirelessFwInfo_t* pWirelessInfo )
653 {
654   uint32_t ipccdba = 0;
655   MB_RefTable_t * p_RefTable = NULL;
656   uint32_t wireless_firmware_version = 0;
657   uint32_t wireless_firmware_memorySize = 0;
658   uint32_t wireless_firmware_infoStack = 0;
659   MB_FUS_DeviceInfoTable_t * p_fus_device_info_table = NULL;
660   uint32_t fus_version = 0;
661   uint32_t fus_memorySize = 0;
662 
663   ipccdba = READ_BIT( FLASH->IPCCBR, FLASH_IPCCBR_IPCCDBA );
664 
665   /**
666    * The Device Info Table mapping depends on which firmware is running on CPU2.
667    * If the FUS is running on CPU2, FUS_DEVICE_INFO_TABLE_VALIDITY_KEYWORD shall be written in the table.
668    * Otherwise, it means the Wireless Firmware is running on the CPU2
669    */
670   p_fus_device_info_table = (MB_FUS_DeviceInfoTable_t*)(*(uint32_t*)((ipccdba<<2) + SRAM2A_BASE));
671 
672   if(p_fus_device_info_table->DeviceInfoTableState == FUS_DEVICE_INFO_TABLE_VALIDITY_KEYWORD)
673   {
674     /* The FUS is running on CPU2 */
675     /**
676      *  Retrieve the WirelessFwInfoTable
677      *  This table is stored in RAM at startup during the TL (transport layer) initialization
678      */
679     wireless_firmware_version =  p_fus_device_info_table->WirelessStackVersion;
680     wireless_firmware_memorySize =  p_fus_device_info_table->WirelessStackMemorySize;
681     wireless_firmware_infoStack =  p_fus_device_info_table->WirelessFirmwareBleInfo;
682 
683     /**
684      *  Retrieve the FusInfoTable
685      *  This table is stored in RAM at startup during the TL (transport layer) initialization
686      */
687     fus_version =  p_fus_device_info_table->FusVersion;
688     fus_memorySize =  p_fus_device_info_table->FusMemorySize;
689   }
690   else
691   {
692     /* The Wireless Firmware is running on CPU2 */
693     p_RefTable = (MB_RefTable_t*)((ipccdba<<2) + SRAM2A_BASE);
694 
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_RefTable->p_device_info_table->WirelessFwInfoTable.Version;
700     wireless_firmware_memorySize =  p_RefTable->p_device_info_table->WirelessFwInfoTable.MemorySize;
701     wireless_firmware_infoStack =  p_RefTable->p_device_info_table->WirelessFwInfoTable.InfoStack;
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_RefTable->p_device_info_table->FusInfoTable.Version;
708     fus_memorySize =  p_RefTable->p_device_info_table->FusInfoTable.MemorySize;
709   }
710 
711   /**
712    *  Retrieve the WirelessFwInfoTable
713    *  This table is stored in RAM at startup during the TL (transport layer) initialization
714    */
715   pWirelessInfo->VersionMajor       = ((wireless_firmware_version & INFO_VERSION_MAJOR_MASK) >> INFO_VERSION_MAJOR_OFFSET);
716   pWirelessInfo->VersionMinor       = ((wireless_firmware_version & INFO_VERSION_MINOR_MASK) >> INFO_VERSION_MINOR_OFFSET);
717   pWirelessInfo->VersionSub         = ((wireless_firmware_version & INFO_VERSION_SUB_MASK) >> INFO_VERSION_SUB_OFFSET);
718   pWirelessInfo->VersionBranch      = ((wireless_firmware_version & INFO_VERSION_BRANCH_MASK) >> INFO_VERSION_BRANCH_OFFSET);
719   pWirelessInfo->VersionReleaseType = ((wireless_firmware_version & INFO_VERSION_TYPE_MASK) >> INFO_VERSION_TYPE_OFFSET);
720 
721   pWirelessInfo->MemorySizeSram2B   = ((wireless_firmware_memorySize & INFO_SIZE_SRAM2B_MASK) >> INFO_SIZE_SRAM2B_OFFSET);
722   pWirelessInfo->MemorySizeSram2A   = ((wireless_firmware_memorySize & INFO_SIZE_SRAM2A_MASK) >> INFO_SIZE_SRAM2A_OFFSET);
723   pWirelessInfo->MemorySizeSram1    = ((wireless_firmware_memorySize & INFO_SIZE_SRAM1_MASK) >> INFO_SIZE_SRAM1_OFFSET);
724   pWirelessInfo->MemorySizeFlash    = ((wireless_firmware_memorySize & INFO_SIZE_FLASH_MASK) >> INFO_SIZE_FLASH_OFFSET);
725 
726   pWirelessInfo->StackType          = ((wireless_firmware_infoStack & INFO_STACK_TYPE_MASK) >> INFO_STACK_TYPE_OFFSET);
727 
728   /**
729    *  Retrieve the FusInfoTable
730    *  This table is stored in RAM at startup during the TL (transport layer) initialization
731    */
732   pWirelessInfo->FusVersionMajor       = ((fus_version & INFO_VERSION_MAJOR_MASK) >> INFO_VERSION_MAJOR_OFFSET);
733   pWirelessInfo->FusVersionMinor       = ((fus_version & INFO_VERSION_MINOR_MASK) >> INFO_VERSION_MINOR_OFFSET);
734   pWirelessInfo->FusVersionSub         = ((fus_version & INFO_VERSION_SUB_MASK) >> INFO_VERSION_SUB_OFFSET);
735 
736   pWirelessInfo->FusMemorySizeSram2B   = ((fus_memorySize & INFO_SIZE_SRAM2B_MASK) >> INFO_SIZE_SRAM2B_OFFSET);
737   pWirelessInfo->FusMemorySizeSram2A   = ((fus_memorySize & INFO_SIZE_SRAM2A_MASK) >> INFO_SIZE_SRAM2A_OFFSET);
738   pWirelessInfo->FusMemorySizeFlash    = ((fus_memorySize & INFO_SIZE_FLASH_MASK) >> INFO_SIZE_FLASH_OFFSET);
739 
740   return (SHCI_Success);
741 }
742 
743