1 /*******************************************************************************
2  * @file  rsi_common_apis.c
3  *******************************************************************************
4  * # License
5  * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
6  *******************************************************************************
7  *
8  * SPDX-License-Identifier: Zlib
9  *
10  * The licensor of this software is Silicon Laboratories Inc.
11  *
12  * This software is provided 'as-is', without any express or implied
13  * warranty. In no event will the authors be held liable for any damages
14  * arising from the use of this software.
15  *
16  * Permission is granted to anyone to use this software for any purpose,
17  * including commercial applications, and to alter it and redistribute it
18  * freely, subject to the following restrictions:
19  *
20  * 1. The origin of this software must not be misrepresented; you must not
21  *    claim that you wrote the original software. If you use this software
22  *    in a product, an acknowledgment in the product documentation would be
23  *    appreciated but is not required.
24  * 2. Altered source versions must be plainly marked as such, and must not be
25  *    misrepresented as being the original software.
26  * 3. This notice may not be removed or altered from any source distribution.
27  *
28  ******************************************************************************/
29 
30 #include "rsi_common.h"
31 
32 #include "rsi_ble.h"
33 
34 #include "sl_si91x_status.h"
35 
36 /*
37   Global Variables
38  * */
39 rsi_driver_cb_t *rsi_driver_cb = NULL;
40 
41 int32_t rsi_driver_memory_estimate(void);
42 
43 /** @addtogroup COMMON
44 * @{
45 */
46 /*==============================================*/
47 /**
48  *
49  * @brief      Provide the memory required by the application. This is a non-blocking API.
50  * @param[in]  Void
51  * @return     Driver pool size
52  *
53  */
54 
rsi_driver_memory_estimate(void)55 int32_t rsi_driver_memory_estimate(void)
56 {
57   uint32_t actual_length = 0;
58 
59   // Calculate the Memory length of the application
60   actual_length += RSI_DRIVER_POOL_SIZE;
61   return actual_length;
62 }
63 
64 /*==============================================*/
65 /**
66  *
67  * @brief      Initialize WiSeConnect ble driver.  This is a non-blocking API.
68  *             Designate memory to all driver components from the buffer provided by the application.
69  * @param[in]  buffer      -    Pointer to buffer from application. \n Driver uses this buffer to hold driver control for its operation.
70  * @param[in]  length      -    Length of the buffer.
71  * @return     **Success** -    Returns the memory used, which is less than or equal to buffer length provided. \n
72  *             **Failure** -    Non-Zero values\n
73  *
74  *             			**RSI_ERROR_TIMEOUT**         -    If UART initialization fails in SPI / UART mode   \n
75  */
76 
77 /** @} */
78 uint8_t *buffer_addr = NULL;
rsi_ble_driver_init(uint8_t * buffer,uint32_t length)79 int32_t rsi_ble_driver_init(uint8_t *buffer, uint32_t length)
80 {
81   uint32_t actual_length = 0;
82 
83   if (((uintptr_t)buffer & 3) != 0) // To avoid compiler warning, replace uint32_t with uintptr_t
84   {
85     // Making buffer 4 byte aligned
86     // Length -= (4 - ((uint32_t)buffer & 3));
87     // To avoid compiler warning, replace uint32_t with uintptr_t
88     length -= (4 - ((uintptr_t)buffer & 3));
89     buffer = (uint8_t *)(((uintptr_t)buffer + 3) & ~3);
90   }
91 
92   // Memset user buffer
93   memset(buffer, 0, length);
94 
95   actual_length += rsi_driver_memory_estimate();
96   // If length is not sufficient
97   if (length < actual_length) {
98     return actual_length;
99   }
100   buffer_addr = buffer;
101 
102   // Store length minus any alignment bytes to first 32-bit address in buffer.
103   *(uint32_t *)buffer = length;
104   buffer += sizeof(uint32_t);
105 
106   // Designate memory for driver cb
107   rsi_driver_cb = (rsi_driver_cb_t *)buffer;
108   buffer += sizeof(rsi_driver_cb_t);
109 
110 #ifdef SL_SI91X_ENABLE_LITTLE_ENDIAN
111   rsi_driver_cb->endian = IS_LITTLE_ENDIAN;
112 #else
113   rsi_driver_cb->endian = IS_BIG_ENDIAN;
114 #endif
115 
116 #if defined(SL_SI91X_PRINT_DBG_LOG)
117   // Creates debug prints mutex
118   rsi_driver_cb->debug_prints_mutex = osMutexNew(NULL);
119 #endif
120 
121   // Designate memory for bt_common_cb
122   rsi_driver_cb->bt_common_cb = (rsi_bt_cb_t *)buffer;
123   buffer += ((sizeof(rsi_bt_cb_t) + 3) & ~3);
124 
125   // Initialize bt_common_cb
126   rsi_bt_cb_init(rsi_driver_cb->bt_common_cb, RSI_PROTO_BT_COMMON);
127 
128   // Save the expected response type for BLE card ready event from NWP
129   rsi_driver_cb->bt_common_cb->expected_response_type = RSI_BT_EVENT_CARD_READY;
130   rsi_driver_cb->bt_common_cb->sync_rsp               = 1;
131 
132   // Designate memory for ble_cb
133   rsi_driver_cb->ble_cb = (rsi_bt_cb_t *)buffer;
134   buffer += ((sizeof(rsi_bt_cb_t) + 3) & ~3);
135 
136   // Initialize ble_cb
137   rsi_bt_cb_init(rsi_driver_cb->ble_cb, RSI_PROTO_BLE);
138 
139   // Designate memory for bt_common_cb
140   rsi_driver_cb->bt_global_cb = (rsi_bt_global_cb_t *)buffer;
141   buffer += sizeof(rsi_bt_global_cb_t);
142 
143   // Fill in bt_global_cb
144   buffer += rsi_bt_global_cb_init(rsi_driver_cb, buffer);
145 
146   if (length < (uint32_t)(buffer - buffer_addr)) {
147     SL_PRINTF(SL_DRIVER_INIT_INSUFFICIENT_BUFFER_2, COMMON, LOG_ERROR, "length: %4x", (uint32_t)(buffer - buffer_addr));
148     return buffer - buffer_addr;
149   }
150 
151   // Update state
152   rsi_driver_cb->device_state = RSI_DRIVER_INIT_DONE;
153 
154   SL_PRINTF(SL_DRIVER_INIT_EXIT, COMMON, LOG_INFO, "actual_length=%4x", actual_length);
155   return actual_length;
156 }
157 
158 //======================================================
159 /**
160  *
161  * @brief       De-Initialize driver components. Clear all the memory given for driver operations in \ref rsi_ble_driver_init() API.
162  * In OS case,  User need to take care of OS variables initialized in \ref rsi_ble_driver_init(). This is a non-blocking API.
163  * This API must be called by the thread/task/Master thread that it is not dependent on.
164  * OS variables allocated/initialized in \ref rsi_ble_driver_init() API.
165  * @pre 		Need to call after the driver initialization
166  * @param[in]   Void
167  * @return      0              - Success \n
168  *              Non-Zero Value - Failure
169  */
170 
rsi_ble_driver_deinit(void)171 int32_t rsi_ble_driver_deinit(void)
172 {
173   SL_PRINTF(SL_DRIVER_DEINIT_ENTRY, COMMON, LOG_INFO);
174 
175   if (rsi_driver_cb->device_state < RSI_DRIVER_INIT_DONE) {
176     // Command given in wrong state
177     return RSI_ERROR_COMMAND_GIVEN_IN_WRONG_STATE;
178   }
179   // Check if buffer is enough for driver components
180   if (buffer_addr == NULL) {
181     return RSI_FAILURE;
182   }
183 
184 #if defined(SL_SI91X_PRINT_DBG_LOG)
185   if (rsi_driver_cb->debug_prints_mutex) {
186     osMutexDelete(rsi_driver_cb->debug_prints_mutex);
187   }
188 #endif
189 
190   // Delete BT semaphore
191   if (rsi_driver_cb->bt_common_cb->bt_cmd_sem) {
192     osSemaphoreDelete(rsi_driver_cb->bt_common_cb->bt_cmd_sem);
193   }
194 
195   if (rsi_driver_cb->bt_common_cb->bt_sem) {
196     osSemaphoreDelete(rsi_driver_cb->bt_common_cb->bt_sem);
197   }
198 
199   if (rsi_driver_cb->ble_cb->bt_cmd_sem) {
200     osSemaphoreDelete(rsi_driver_cb->ble_cb->bt_cmd_sem);
201   }
202 
203   if (rsi_driver_cb->ble_cb->bt_sem) {
204     osSemaphoreDelete(rsi_driver_cb->ble_cb->bt_sem);
205   }
206 
207   rsi_driver_cb->device_state = RSI_DEVICE_STATE_NONE;
208   SL_PRINTF(SL_DRIVER_DEINIT_SEMAPHORE_DESTROY_FAILED_26, COMMON, LOG_INFO);
209   return RSI_SUCCESS;
210 }
211 
212 /** @} */
213