• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012-2023 NXP
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 _PHNXPUCIHAL_H_
18 #define _PHNXPUCIHAL_H_
19 
20 #include <thread>
21 
22 #include "hal_nxpuwb.h"
23 #include "NxpUwbChip.h"
24 #include "phNxpUciHal_Adaptation.h"
25 #include "phNxpUciHal_utils.h"
26 #include "phTmlUwb.h"
27 #include "uci_defs.h"
28 
29 /********************* Definitions and structures *****************************/
30 #define MAX_RETRY_COUNT 0x05
31 #define UCI_MAX_DATA_LEN 4200 // maximum data packet size
32 #define UCI_MAX_PAYLOAD_LEN 4200
33 #define UCI_MAX_CONFIG_PAYLOAD_LEN 0xFF
34 // #define UCI_RESPONSE_STATUS_OFFSET 0x04
35 #define UCI_PKT_HDR_LEN 0x04
36 #define UCI_PKT_PAYLOAD_STATUS_LEN 0x01
37 #define UCI_PKT_NUM_CAPS_LEN 0x01
38 #define UCI_PKT_UCI_GENERIC 0x09
39 #define UWB_CHANNELS 0x0E
40 #define CCC_UWB_CHANNELS 0xA3
41 #define COUNTRY_CODE_TAG 0x00
42 #define UWB_ENABLE_TAG 0x01
43 #define CHANNEL_5_TAG 0x02
44 #define CHANNEL_9_TAG 0x03
45 #define TX_POWER_TAG 0x05
46 #define CHANNEL_5_MASK 0xFE
47 #define CHANNEL_9_MASK 0xF7
48 #define CHANNEL_NUM_5 0x05
49 #define CHANNEL_NUM_9 0x09
50 #define CCC_CHANNEL_INFO_BIT_MASK 0x03
51 
52 #define MAX_RESPONSE_STATUS 0x0C
53 
54 #define UCI_MT_MASK 0xE0
55 #define UCI_PBF_MASK 0x10
56 #define UCI_GID_MASK 0x0F
57 #define UCI_OID_MASK 0x3F
58 #define UCI_OID_RANGE_DATA_NTF 0x00
59 
60 #define UCI_NTF_PAYLOAD_OFFSET 0x04
61 #define NORMAL_MODE_LENGTH_OFFSET 0x03
62 #define EXTENDED_MODE_LEN_OFFSET 0x02
63 #define EXTENDED_MODE_LEN_SHIFT 0x08
64 #define EXTND_LEN_INDICATOR_OFFSET 0x01
65 #define EXTND_LEN_INDICATOR_OFFSET_MASK 0x80
66 #define UCI_SESSION_ID_OFFSET 0x04
67 #define FWD_MAX_RETRY_COUNT 0x05
68 
69 #define USER_FW_BOOT_MODE 0x01
70 #define FW_VERSION_PARAM_ID 0x01
71 
72 #define FW_BOOT_MODE_PARAM_ID 0x63
73 
74 #define CCC_SUPPORTED_PROTOCOL_VERSIONS_ID 0xA4
75 
76 /* Low power mode */
77 #define LOW_POWER_MODE_TAG_ID 0x01
78 #define LOW_POWER_MODE_LENGTH 0x01
79 
80 /* AOA support handling */
81 #define AOA_SUPPORT_TAG_ID 0x13
82 #define ANTENNA_RX_PAIR_DEFINE_TAG_ID 0xE4
83 #define ANTENNA_RX_PAIR_DEFINE_SUB_TAG_ID 0x62
84 
85 #define DEVICE_NAME_PARAM_ID 0x00
86 
87 /* Mem alloc. with 8 byte alignment */
88 #define nxp_malloc(x) malloc(((x - 1) | 7) + 1)
89 
90 /* UCI Message set application config specific parameters*/
91 #define UCI_CMD_NUM_CONFIG_PARAM_LENGTH 1
92 #define UCI_CMD_NUM_CONFIG_PARAM_BYTE 8
93 #define UCI_CMD_LENGTH_PARAM_BYTE1 3
94 #define UCI_CMD_LENGTH_PARAM_BYTE2 2
95 #define UCI_CMD_TAG_BYTE_LENGTH 1
96 #define UCI_CMD_PARAM_SIZE_BYTE_LENGTH 1
97 #define UCI_CMD_PAYLOAD_BYTE_LENGTH 1
98 
99 /* FW debug and crash log path */
100 inline constexpr const char debug_log_path[] = "/data/vendor/uwb/";
101 
102 // Device file
103 inline constexpr const char uwb_dev_node[] = "/dev/srxxx";
104 
105 /* UCI Data */
106 #define NXP_MAX_CONFIG_STRING_LEN 2052
107 typedef struct uci_data {
108   uint16_t len;
109   uint8_t p_data[UCI_MAX_DATA_LEN];
110 } uci_data_t;
111 
112 typedef enum {
113   HAL_STATUS_CLOSE = 0,
114   HAL_STATUS_OPEN
115 } phNxpUci_HalStatus;
116 
117 typedef enum {
118   UWB_DEVICE_INIT = 0,
119   UWB_DEVICE_READY,
120   UWB_DEVICE_BUSY,
121   UWB_DEVICE_STATE_UNKNOWN = 0XA0,
122   UWB_DEVICE_ERROR = 0xFF
123 }phNxpUci_UwbcState;
124 
125 typedef enum {
126   UWB_DEVICE_NOT_BOUND = 0,
127   UWB_DEVICE_BOUND_UNLOCKED,
128   UWB_DEVICE_BOUND_LOCKED,
129   UWB_DEVICE_UNKNOWN
130 } phNxpUci_UwbBindingStatus;
131 
132 typedef enum {
133   HAL_STATE_CLOSE = 0,
134   HAL_STATE_CORE_INIT,
135   HAL_STATE_OPEN,
136   HAL_STATE_READ_BINDING_NTF
137 } phNxpUci_HalState;
138 
139 /* Macros to enable and disable extensions */
140 #define HAL_ENABLE_EXT() (nxpucihal_ctrl.hal_ext_enabled = 1)
141 #define HAL_DISABLE_EXT() (nxpucihal_ctrl.hal_ext_enabled = 0)
142 
143 typedef struct {
144   uint8_t
145       validation; /* indicates on which platform validation is done like SR100*/
146   uint8_t android_version; /* android version */
147   uint8_t major_version;   /* major version of the MW */
148   uint8_t minor_version;   /* Minor Version of MW */
149   uint8_t rc_version;      /* RC version */
150   uint8_t mw_drop;         /* MW early drops */
151 } phNxpUciHal_MW_Version_t;
152 
153 typedef struct {
154   uint8_t major_version;  /* major */
155   uint8_t minor_version;  /* minor/maintenance */
156   uint8_t rc_version;     /* patch */
157 } phNxpUciHal_FW_Version_t;
158 
159 typedef struct {
160   uint16_t restricted_channel_mask;
161   bool uwb_enable;
162   short tx_power_offset;    // From UWB_COUNTRY_CODE_CAPS
163 } phNxpUciHal_Runtime_Settings_t;
164 
165 // From phNxpUciHal_process_ext_cmd_rsp(),
166 // For checking CMD/RSP turn around matching.
167 class CmdRspCheck {
168 public:
CmdRspCheck()169   CmdRspCheck() { }
170 
StartCmd(uint8_t gid,uint8_t oid)171   void StartCmd(uint8_t gid, uint8_t oid) {
172     if (sem_ != nullptr) {
173       NXPLOG_UCIHAL_E("CMD/RSP turnaround is already ongoing!");
174     } else {
175       sem_ = std::make_shared<UciHalSemaphore>();
176       gid_ = gid;
177       oid_ = oid;
178     }
179   }
180 
181   // CMD writer waits for the corresponding RSP
Wait(long timeout_ms)182   tHAL_UWB_STATUS Wait(long timeout_ms) {
183     auto sem = GetSemaphore();
184     if (sem == nullptr) {
185       NXPLOG_UCIHAL_E("Wait CMD/RSP for non-existed turnaround!");
186       return UCI_STATUS_FAILED;
187     }
188     sem->wait_timeout_msec(timeout_ms);
189     auto ret = sem->getStatus();
190     ReleaseSemaphore();
191     return ret;
192   }
193 
194   // Reset the state, this shouldn't be called while
195   // Someone is waiting from WaitRsp().
Cancel()196   void Cancel() {
197     ReleaseSemaphore();
198   }
199 
200   // Wakes up the user thread when RSP packet is matched.
Wakeup(uint8_t gid,uint8_t oid)201   void Wakeup(uint8_t gid, uint8_t oid) {
202     auto sem = GetSemaphore();
203     if (sem == nullptr) {
204       NXPLOG_UCIHAL_E("Wakeup CMD/RSP while no one is waiting for CMD/RSP!");
205       return;
206     }
207     if (gid_ != gid || oid_ != oid) {
208       NXPLOG_UCIHAL_E(
209         "Received incorrect response of GID:%x OID:%x, expected GID:%x OID:%x",
210         gid, oid, gid_, oid_);
211       sem->post(UWBSTATUS_COMMAND_RETRANSMIT);
212     } else {
213       sem->post(UWBSTATUS_SUCCESS);
214     }
215   }
216 
217   // Wakes up the user thread with error status code.
WakeupError(tHAL_UWB_STATUS status)218   void WakeupError(tHAL_UWB_STATUS status) {
219     auto sem = GetSemaphore();
220     if (sem == nullptr) {
221       NXPLOG_UCIHAL_V("Got error while no one is waiting for CMD/RSP!");
222       return;
223     }
224     sem->post(status);
225   }
226 
227 private:
GetSemaphore()228   std::shared_ptr<UciHalSemaphore> GetSemaphore() {
229     return sem_;
230   }
ReleaseSemaphore()231   void ReleaseSemaphore() {
232     sem_ = nullptr;
233   }
234   std::shared_ptr<UciHalSemaphore> sem_;
235   uint8_t gid_;
236   uint8_t oid_;
237 };
238 
239 /* UCI Control structure */
240 typedef struct phNxpUciHal_Control {
241   phNxpUci_HalStatus halStatus; /* Indicate if hal is open or closed */
242   std::thread client_thread;    /* Integration thread handle */
243 
244   // a main message queue on the "client" thread.
245   std::shared_ptr<MessageQueue<phLibUwb_Message>> pClientMq;
246 
247   std::unique_ptr<NxpUwbChip> uwb_chip;
248 
249   /* libuwb-uci callbacks */
250   uwb_stack_callback_t* p_uwb_stack_cback;
251   uwb_stack_data_callback_t* p_uwb_stack_data_cback;
252 
253   /* HAL extensions */
254   uint8_t hal_ext_enabled;
255 
256   /* Waiting semaphore */
257   CmdRspCheck cmdrsp;
258 
259   /* CORE_DEVICE_INFO_RSP cache */
260   bool isDevInfoCached;
261   uint8_t dev_info_resp[256];
262 
263   phNxpUciHal_FW_Version_t fw_version;
264   device_type_t device_type;
265   uint8_t fw_boot_mode;
266   bool_t fw_dwnld_mode;
267 
268   // Per-country settings
269   phNxpUciHal_Runtime_Settings_t rt_settings;
270 
271   // AOA support handling
272   int numberOfAntennaPairs;
273 
274   // Extra calibration
275   // Antenna Definitions for extra calibration, b0=Antenna1, b1=Antenna2, ...
276   uint8_t cal_rx_antenna_mask;
277   uint8_t cal_tx_antenna_mask;
278 
279   bool_t recovery_ongoing;
280   bool_t uwb_device_initialized;
281 
282   // Current country code
283   uint8_t country_code[2];
284 } phNxpUciHal_Control_t;
285 
286 // RX packet handler
287 struct phNxpUciHal_RxHandler;
288 
289 /* Internal messages to handle callbacks */
290 #define UCI_HAL_OPEN_CPLT_MSG 0x411
291 #define UCI_HAL_CLOSE_CPLT_MSG 0x412
292 #define UCI_HAL_INIT_CPLT_MSG 0x413
293 #define UCI_HAL_ERROR_MSG 0x415
294 
295 #define UCIHAL_CMD_CODE_LEN_BYTE_OFFSET (2U)
296 #define UCIHAL_CMD_CODE_BYTE_LEN (3U)
297 
298 #define NXP_CHIP_SR100 1
299 #define NXP_CHIP_SR200 2
300 #define NXP_ANDROID_VERSION (14U)     /* Android version */
301 #define UWB_NXP_MW_VERSION_MAJ (0x00) /* MW major version */
302 #define UWB_NXP_MW_VERSION_MIN                                                 \
303   (0x00) /* MS Nibble is MW minor version and LS Nibble is Test Object/Patch*/
304 #define UWB_NXP_ANDROID_MW_RC_VERSION (0x02)   /* Android MW RC Version */
305 #define UWB_NXP_ANDROID_MW_DROP_VERSION (0x07) /* Android MW early drops */
306 /******************** UCI HAL exposed functions *******************************/
307 tHAL_UWB_STATUS phNxpUciHal_hw_init();
308 void phNxpUciHal_hw_deinit();
309 
310 void phNxpUciHal_hw_suspend();
311 void phNxpUciHal_hw_resume();
312 
313 tHAL_UWB_STATUS phNxpUciHal_write_unlocked(size_t cmd_len, const uint8_t* p_cmd);
314 void phNxpUciHal_read_complete(void* pContext, phTmlUwb_ReadTransactInfo* pInfo);
315 
316 // Report UCI packet to upper layer
317 void report_uci_message(const uint8_t* buffer, size_t len);
318 
319 tHAL_UWB_STATUS phNxpUciHal_uwb_reset();
320 tHAL_UWB_STATUS phNxpUciHal_process_ext_cmd_rsp(size_t cmd_len, const uint8_t *p_cmd);
321 void phNxpUciHal_send_dev_error_status_ntf();
322 bool phNxpUciHal_parse(size_t* data_len, uint8_t *p_data);
323 
324 // RX packet handler
325 // handler should returns true if the packet is handled and
326 // shouldn't report it to the upper layer.
327 
328 using RxHandlerCallback = std::function<bool(size_t packet_len, const uint8_t *packet)>;
329 
330 std::shared_ptr<phNxpUciHal_RxHandler> phNxpUciHal_rx_handler_add(
331   uint8_t mt, uint8_t gid, uint8_t oid,
332   bool run_once,
333   RxHandlerCallback callback);
334 void phNxpUciHal_rx_handler_del(std::shared_ptr<phNxpUciHal_RxHandler> handler);
335 
336 // Helper class for rx handler with run_once=false
337 // auto-unregistered from destructor
338 
339 class UciHalRxHandler {
340 public:
UciHalRxHandler()341   UciHalRxHandler() {}
UciHalRxHandler(uint8_t mt,uint8_t gid,uint8_t oid,RxHandlerCallback callback)342   UciHalRxHandler(uint8_t mt, uint8_t gid, uint8_t oid,
343                   RxHandlerCallback callback) {
344     handler_ = phNxpUciHal_rx_handler_add(mt, gid, oid, false, callback);
345   }
346   UciHalRxHandler& operator=(UciHalRxHandler &&handler) {
347     Unregister();
348     handler_ = std::move(handler.handler_);
349     return *this;
350   }
351 
352   UciHalRxHandler(const UciHalRxHandler&) = delete;
353   UciHalRxHandler& operator=(const UciHalRxHandler& handler) = delete;
354 
~UciHalRxHandler()355   ~UciHalRxHandler() {
356     Unregister();
357   }
358 private:
Unregister()359   void Unregister() {
360     if (handler_) {
361       phNxpUciHal_rx_handler_del(handler_);
362       handler_.reset();
363     }
364   }
365   std::shared_ptr<phNxpUciHal_RxHandler> handler_;
366 };
367 
368 #endif /* _PHNXPUCIHAL_H_ */
369