rl_driver.c
1 /****************************************************************************************
2  * FileName : rl_driver.c
3  *
4  * Description : This file implements the mmwave radar Host Communication
5  * Protocol
6  *
7  ****************************************************************************************
8  * (C) Copyright 2014, Texas Instruments Incorporated. - TI web address www.ti.com
9  *---------------------------------------------------------------------------------------
10  *
11  * Redistribution and use in source and binary forms, with or without modification,
12  * are permitted provided that the following conditions are met:
13  *
14  * Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  *
17  * Redistributions in binary form must reproduce the above copyright notice,
18  * this list of conditions and the following disclaimer in the documentation
19  * and/or other materials provided with the distribution.
20  *
21  * Neither the name of Texas Instruments Incorporated nor the names of its
22  * contributors may be used to endorse or promote products derived from this
23  * software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38  /*
39  ****************************************************************************************
40  * Revision History :
41  *---------------------------------------------------------------------------------------
42  * Version Date Author Defect No Description
43  *---------------------------------------------------------------------------------------
44  * 0.1.0 12May2015 Kaushal Kukkar - Initial Version
45  *
46  * 0.5.2 23Sep2016 Kaushal Kukkar AUTORADAR-541 xWR1642 Support
47  *
48  * 0.6.0 15Nov2016 Kaushal Kukkar AUTORADAR-666 Logging Feature
49  * Kaushal Kukkar AUTORADAR-716 Cascade API change
50  *
51  * 0.7.0 11May2017 Kaushal Kukkar MMWSDK-362 LDRA static analysis Issue Fix
52  *
53  * 0.8.6 24Jul2017 Jitendra Gupta MMWL-25 Support for 2K Message size
54  * Kaushal Kukkar MMWL-23 Big Endian Support
55  *
56  * 0.9.1 - Jitendra Gupta MMWL-5 Code size optimization
57  *
58  * 1.2.2 14Feb2019 Pavan Penikalapati MMWL-159 Fixed log prints in rlDeviceAddDevices
59  *
60  * 1.2.5.15 15Jul2019 Pavan Penikalapati MMWL-217 Flush mechanism fix, when SYNC for ACK
61  * corrupted.
62  ****************************************************************************************
63  */
64 
65 /******************************************************************************
66  * INCLUDE FILES
67  ******************************************************************************
68  */
69 #include <stdlib.h>
70 #include <string.h>
71 #include <ti/control/mmwavelink/mmwavelink.h>
72 #include <ti/control/mmwavelink/include/rl_driver.h>
73 #include <ti/control/mmwavelink/include/rl_messages.h>
74 #include <ti/control/mmwavelink/include/rl_controller.h>
75 #include <ti/control/mmwavelink/include/rl_protocol.h>
76 #include <ti/control/mmwavelink/include/rl_trace.h>
77 
78 /****************************************************************************************
79 * MACRO DEFINITIONS
80 ****************************************************************************************
81 */
82 /* Check if Interrupt is pending */
83 #define RL_PENDING_RX_MSG(driverData, index) \
84  (((driverData)->rxIrqCnt[(index)]) != ((driverData)->rxDoneCnt[(index)]))
85 
86 /* mmwave radar Communication Interface Read/Write */
87 #define RL_IF_WRITE(fd,pBuff,len) \
88  rl_driverData.clientCtx.comIfCb.rlComIfWrite((fd),(pBuff),(len))
89 #define RL_IF_READ(fd,pBuff,len) \
90  rl_driverData.clientCtx.comIfCb.rlComIfRead((fd),(pBuff),(len))
91 
92 
93 /* mmwave radar Communication Interface Read/Write Error Check */
94 #define RL_IF_WRITE_CHECK(fd,pBuff,len) \
95  {\
96  if (((rlInt32_t)(len)) != RL_IF_WRITE((fd), (pBuff), (len)))\
97  {\
98  return RL_RET_CODE_RADAR_IF_ERROR;\
99  }\
100  }
101 #define RL_IF_READ_CHECK(fd,pBuff,len) \
102  {\
103  if (((rlInt32_t)(len)) != RL_IF_READ((fd), (pBuff), (len)))\
104  {\
105  return RL_RET_CODE_RADAR_IF_ERROR;\
106  }\
107  }
108 
109 /* MAX Retry of SYNC Match */
110 #define RL_SYNC_SCAN_THRESHOLD (252U)
111 
112 /* mmWaveLink Header Opcode Class */
113 #define RL_RHCP_HDR_OPCODE_CLASS(ptr) \
114  (rlUInt8_t) (((rlProtHeader_t *)(ptr))->opcode.b2MsgType)
115 
116 /* mmWaveLink Header Payload */
117 #define RL_RHCP_HDR_PL_LENGTH(ptr) (((rlProtHeader_t *)(ptr))->len)
118 
119 #define PATTERN_NOT_MATCHED ((rlInt32_t)0x0)
120 #define SYNC_PATTERN_MATCHED ((rlInt32_t)0x1)
121 #define CNYS_PATTERN_MATCHED ((rlInt32_t)0x2)
122 
123 /* Protocol SYNC Patterns */
124 #define D2H_SYNC_PATTERN_1 (0xDCBAU)
125 #define D2H_SYNC_PATTERN_2 (0xABCDU)
126 #define H2D_SYNC_PATTERN_1 (0x1234U)
127 #define H2D_SYNC_PATTERN_2 (0x4321U)
128 #define H2D_CNYS_PATTERN_1 (0x5678U)
129 #define H2D_CNYS_PATTERN_2 (0x8765U)
130 
131 /******************************************************************************
132  * GLOBAL VARIABLES/DATA-TYPES DEFINITIONS
133  ******************************************************************************
134  */
135 
136 /* mmwave radar Driver global structure */
137 #ifdef ccs
138 #pragma DATA_ALIGN(rl_driverData, 4);
139 #endif
140 static rlDriverData_t rl_driverData = {0};
141 
142 /* mmwave radar Driver Command/Response Buffer */
143 #ifdef ccs
144 #pragma DATA_ALIGN(rl_txMsg, 8);
145 #endif
146 rlRhcpMsg_t rl_txMsg[RL_CASCADE_NUM_DEVICES] = {0};
147 #ifdef ccs
148 #pragma DATA_ALIGN(rl_rxMsg, 8);
149 #endif
150 rlRhcpMsg_t rl_rxMsg[RL_CASCADE_NUM_DEVICES] = {0};
151 
152 /******************************************************************************
153  * FUNCTION PROTOTYPES
154  ******************************************************************************
155  */
156 static rlReturnVal_t rlDriverOriginDirCheck(rlUInt8_t deviceRunId, rlUInt8_t dataDir);
157 static rlUInt8_t rlDriverReceiveSync(rlComIfHdl_t comIfHdl, rlUInt8_t syncBuf[],
158  rlInt32_t *syncType);
159 static rlReturnVal_t rlDriverClientCbCheck(rlClientCbs_t clientCb);
160 static rlReturnVal_t rlDriverOsiCbCheck(rlClientCbs_t clientCb);
161 static rlReturnVal_t rlDriverCmdWriter(rlUInt8_t devIndex, rlDriverMsg_t* outMsg);
162 
163 
164 /******************************************************************************
165  * FUNCTION DEFINITIONS
166  ******************************************************************************
167  */
168 
176 /* SourceId : */
177 /* DesignId : */
178 /* Requirements : */
179 void rlDriverShiftDWord(rlUInt8_t buf[])
180 {
181  rlUInt8_t shiftIdx;
182 
183  /* shift each byte in recevied byte array */
184  for (shiftIdx = 0U; shiftIdx < 7U; shiftIdx++)
185  {
186  /* overwritting each data byte with next data byte of array */
187  buf[shiftIdx] = buf[shiftIdx + 1U];
188  }
189 
190  /* set last byte to zero */
191  buf[7U] = 0U;
192 }
193 
207 /* DesignId : */
208 /* Requirements : AUTORADAR_REQ-774 */
209 rlReturnVal_t rlDriverCalCRC(rlUInt8_t* data, rlUInt16_t dataLen,
210  rlUInt8_t crcType, rlUInt8_t crc[RL_CRC_LEN_MAX])
211 {
212  rlReturnVal_t retVal;
213 
214  RL_LOGV_ARG0("rlDriverCalCRC starts...\n");
215 
216  /* check if API is defined by the application during powerOn */
217  if (rl_driverData.clientCtx.crcCb.rlComputeCRC != NULL)
218  {
219  /* compute CRC on given data */
220  retVal = rl_driverData.clientCtx.crcCb.rlComputeCRC(data, dataLen, crcType, &crc[0U]);
221  }
222  else
223  {
224  /* set error code if CRC compute API is not set by Application */
225  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
226  }
227  RL_LOGV_ARG0("rlDriverCalCRC ends...\n");
228 
229  return retVal;
230 }
231 
246 /* DesignId : */
247 /* Requirements : AUTORADAR_REQ-780 */
248 rlReturnVal_t rlDriverVerifyCRC(rlUInt8_t* data, rlUInt16_t dataLen,
249  rlUInt8_t crcType, rlUInt8_t crc[RL_CRC_LEN_MAX])
250 {
251  rlUInt8_t indx;
252  rlUInt8_t crcByte[RL_CRC_LEN_MAX];
253  rlReturnVal_t retVal = RL_RET_CODE_OK;
254 
255  RL_LOGV_ARG0("rlDriverVerifyCRC starts...\n");
256 
257  /* compute CRC on given data */
258  if (RL_RET_CODE_OK != rl_driverData.clientCtx.crcCb.rlComputeCRC(data, dataLen, \
259  crcType, &crcByte[0U]))
260  {
261  /* set error code if CRC callback returns non-zero */
262  retVal += RL_RET_CODE_RADAR_IF_ERROR;
263  }
264  else
265  {
266  /* compare computed and received CRC value */
267  for (indx = 0U; indx < (2U << crcType); indx++)
268  {
269  if (crcByte[indx] != crc[indx])
270  {
271  /* set error code if computed and received CRC value mismatched */
272  retVal += RL_RET_CODE_CRC_FAILED;
273  break;
274  }
275  }
276  }
277  RL_LOGV_ARG0("rlDriverVerifyCRC ends...\n");
278 
279  return retVal;
280 }
281 
294 /* DesignId : */
295 /* Requirements : AUTORADAR_REQ-774, AUTORADAR_REQ-777 */
296 rlReturnVal_t rlDriverCalChkSum(rlProtHeader_t* hdrData, rlUInt8_t len,
297  rlUInt16_t* checksum)
298 {
299  /* TBD - MISRA compliant Checksum code */
300  rlUInt32_t checkSumVal = 0U;
301  rlUInt8_t *localGenHdr = (rlUInt8_t *)hdrData;
302  rlReturnVal_t retVal;
303 
304  RL_LOGV_ARG0("rlDriverCalChkSum starts...\n");
305 
306  /* if received data pointer is not NULL */
307  if (localGenHdr != RL_NULL_PTR)
308  {
309  /* if length is 2 or more bytes */
310  while (len > 1U)
311  {
312  /* AR_CODE_REVIEW MR:R.11.2 <APPROVED> "Pointer conversion
313  * from data array
314  * to calculate Checksum" */
315  /*LDRA_INSPECTED 94 S */
316  /*LDRA_INSPECTED 95 S */
317  checkSumVal += *((rlUInt16_t*) localGenHdr);
318  localGenHdr += 2U;
319 
320  /* If high order bit set, fold */
321  if ((checkSumVal & 0x80000000U) != 0U)
322  {
323  checkSumVal = (checkSumVal & 0xFFFFU) + (checkSumVal >> 16U);
324  }
325  /* decrement length by 2 as checkSum is calculated on each 2 bytes */
326  len -= 2U;
327  }
328  /* Take care of left over byte */
329  if (len > 0U)
330  {
331  checkSumVal += (rlUInt32_t) (*((rlUInt8_t *)localGenHdr));
332  }
333  /* Add all half words to calcuated SUM */
334  while ((checkSumVal >> 16U) != 0U)
335  {
336  checkSumVal = (checkSumVal & 0xFFFFU) + (checkSumVal >> 16U);
337  }
338  RL_LOGV_ARG1("Final checksum 0x%X\n", *checksum);
339 
340  /* Calculate Checksum as compliment of the SUM */
341  *(checksum) = (rlUInt16_t)~checkSumVal;
342  retVal = RL_RET_CODE_OK;
343  }
344  else
345  {
346  retVal = RL_RET_CODE_FATAL_ERROR;
347  }
348 
349  RL_LOGV_ARG0("rlDriverCalChkSum ends...\n");
350 
351  return retVal;
352 }
353 
354 
364 /* DesignId : */
365 /* Requirements : AUTORADAR_REQ-777 */
366 rlReturnVal_t rlDriverValidateHdr(rlProtHeader_t protHdr)
367 {
368  rlReturnVal_t retVal;
369  rlUInt16_t checkSum = 0U;
370 
371  /* Calculate checksum*/
372  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Checksum is getting updated in called function" */
373  /*LDRA_INSPECTED 8 D */
374  if (RL_RET_CODE_OK != rlDriverCalChkSum(&protHdr, ((rlUInt8_t)(RHCP_HEADER_LEN - 2U)),
375  &checkSum))
376  {
377  /* Set error code if checksum callback returns non-zero value */
378  retVal = RL_RET_CODE_RADAR_IF_ERROR;
379  }
380  else
381  {
382  /* Compare calcualted and received checksum*/
383  if (protHdr.chksum != checkSum)
384  {
385  /* Checksum doesn't match, return error*/
386  retVal = RL_RET_CODE_CHKSUM_FAILED;
387  RL_LOGE_ARG0("Checksum validation failed for header\n");
388  }
389  else
390  {
391  /* checksum successfully matched */
392  RL_LOGD_ARG0("Checksum validation is successful\n");
393  retVal= RL_RET_CODE_OK;
394  }
395  }
396 
397  return retVal;
398 }
399 
410 /* DesignId : */
411 /* Requirements : */
412 rlUInt8_t rlDeviceIdentifyCmdDir(rlUInt16_t msgId, rlUInt8_t platform)
413 {
414  rlUInt8_t cmdDir;
415 
416  RL_LOGV_ARG0("rlDeviceIdentifyCmdDir starts...\n");
417 
418  /* if MsgId is for radarSS */
419  if ((RL_RF_RESP_ERROR_MSG < msgId) && (RL_RF_ASYNC_EVENT_MSG > msgId))
420  {
421  /* if mmWaveLink is running on MSS */
422  if (RL_PLATFORM_MSS == platform)
423  {
424  cmdDir = RL_API_DIR_MSS_TO_BSS;
425  }
426  /* if mmWaveLink is running on Host */
427  else if (RL_PLATFORM_HOST == platform)
428  {
429  cmdDir = RL_API_DIR_HOST_TO_BSS;
430  }
431  /* if mmWaveLink is running on DSS */
432  else
433  {
434  cmdDir = RL_API_DIR_DSS_TO_BSS;
435  }
436  RL_LOGV_ARG1("cmdDir for radarSS = %d (1:host2Bss, 10:dss2Bss, 8:mss2bss)\n",\
437  cmdDir);
438  }
439  /* if MsgId is for MSS */
440  else if ((RL_DEV_POWERUP_MSG <= msgId) && (RL_DEV_ASYNC_EVENT_MSG > msgId))
441  {
442  /* if mmWaveLink is running on Host */
443  if (RL_PLATFORM_HOST == platform)
444  {
445  /* MsgId for MSS need not send to MSS itself */
446  cmdDir = RL_API_DIR_HOST_TO_MSS;
447  }
448  else
449  {
450  /* If MSS wants to configure these MsgID to DSS */
451  cmdDir = RL_API_DIR_MSS_TO_DSS;
452  }
453  RL_LOGV_ARG1("cmdDir for MSS = %d (5:host2Mss, 12:dss2Mss)\n", cmdDir);
454  }
455  /* if msgId is for DSS */
456  else if ((RL_DSP_RESERVED0_MSG <= msgId) && (RL_DSP_ASYNC_EVENT_MSG > msgId))
457  {
458  /* MsgId for DSS need not send to DSS itself */
459 
460  /* if mmWaveLink is running on MSS */
461  if (RL_PLATFORM_MSS == platform)
462  {
463  /* set direction MSS_TO_DSS */
464  cmdDir = RL_API_DIR_MSS_TO_DSS;
465  }
466  /* if mmWaveLink is running on Host */
467  else
468  {
469  /* set direction HOST_TO_DSS */
470  cmdDir = RL_API_DIR_HOST_TO_DSS;
471  }
472  RL_LOGV_ARG1("cmdDir for DSS = %d (11:Mss2Dss, 3:hostDss)\n", cmdDir);
473  }
474  else
475  {
476  /* set direction INVALID */
477  cmdDir = RL_API_DIR_INVALID;
478  RL_LOGE_ARG1("rlDeviceIdentifyCmdDir: Invalid cmd, platform: [%d]\n", platform);
479  }
480  RL_LOGV_ARG0("rlDeviceIdentifyCmdDir ends...\n");
481 
482  return cmdDir;
483 }
484 
498 /* DesignId : */
499 /* Requirements : AUTORADAR_REQ-783 */
500 rlReturnVal_t rlDriverAsyncEventHandler(rlUInt8_t devIndex,
501  rlUInt16_t nsbc, rlUInt8_t *payload,
502  rlUInt16_t payloadLen)
503 {
504  rlUInt16_t indx;
505  rlUInt16_t sbLen = 0U;
506  rlUInt16_t sbcId = 0U;
507  rlUInt16_t recSbsLen = 0U;
508  rlReturnVal_t retVal = RL_RET_CODE_OK;
509  rlUInt8_t *payldAddr = payload;
510 
511  RL_LOGV_ARG0("rlDriverAsyncEventHandler starts...\n");
512 
513  /* Lood for all the Events Sub Block and call event handler */
514  for (indx = 0U; indx < nsbc; indx++)
515  {
516  /* check for payload pointer for NULL */
517  if ((payldAddr == RL_NULL_PTR) || (recSbsLen > payloadLen))
518  {
519  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Error value set on top of default value" */
520  /*LDRA_INSPECTED 8 D */
521  retVal = RL_RET_CODE_FATAL_ERROR;
522  break;
523  }
524  /* Read Sub Block Id */
525  rlGetSubBlockId(payldAddr, &sbcId);
526 
527  /* Read Sub Block Len */
528  rlGetSubBlockLen(payldAddr, &sbLen);
529 
530  /* Call Application registered callback to indicate event*/
531  if (RL_NULL_PTR != rl_driverData.clientCtx.eventCb.rlAsyncEvent)
532  {
533  /* Call event handler and pass event payload */
534  /* AR_CODE_REVIEW MR:R.18.1,R.18.4 <APPROVED> "pointer arithmetic required" */
535  /*LDRA_INSPECTED 567 S */
536  /*LDRA_INSPECTED 87 S */
537  rl_driverData.clientCtx.eventCb.rlAsyncEvent(devIndex, sbcId, \
538  ((rlUInt16_t)(sbLen - RL_MIN_SBC_LEN)),\
539  (payldAddr + RL_SBC_PL_INDEX));
540  /* Increase received payload length*/
541  recSbsLen += (sbLen);
542 
543  /* increment payload address */
544  payldAddr += sbLen;
545  }
546  }
547  RL_LOGV_ARG0("rlDriverAsyncEventHandler ends...\n");
548 
549  return retVal;
550 }
551 
563 /* DesignId : */
564 /* Requirements : AUTORADAR_REQ-777 */
565 void rlDriverHostIrqHandler(rlUInt8_t deviceIndex, void *pValue)
566 {
567  rlUInt8_t tempVar;
568  /* get rlDriver global structure pointer */
569  rlDriverData_t* rlDrvData = rlDriverGetHandle();
570 
571  RL_LOGV_ARG0("rlDriverHostIrqHandler starts...\n");
572 
573  /* check for NULL pointer */
574  if (pValue == RL_NULL_PTR)
575  {
576  /* No Argument Passed */
577  RL_LOGD_ARG0("rlDriverHostIrqHandler Input arg is NULL\n");
578  }
579 
580  /* Mask the Interrupt - Required if interrupt is Level triggered*/
581  /* AR_CODE_REVIEW MR:D.4.1,D.4.14 <APPROVED> "rlDrvData is pointer to a global strcture,
582  can't be NULL" */
583  /*LDRA_INSPECTED 45 D */
584  if ((RL_NULL_PTR != rlDrvData->clientCtx.devCtrlCb.rlDeviceMaskHostIrq)\
585  && ((rlComIfHdl_t)RL_NULL_PTR != rlDrvData->commDevIdx.comIfHdl[deviceIndex]))
586  {
587  /* Mask Host IRQ */
588  rlDrvData->clientCtx.devCtrlCb.rlDeviceMaskHostIrq((rlComIfHdl_t) \
589  rlDrvData->commDevIdx.comIfHdl[deviceIndex]);
590  RL_LOGD_ARG0("rlDriverHostIrqHandler Mask the Interrupt\n");
591  }
592 
593  /* Increment the Irq count*/
594  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "storing incremented value to global structure" */
595  /*LDRA_INSPECTED 105 D */
596  rlDrvData->rxIrqCnt[deviceIndex] = (rlDrvData->rxIrqCnt[deviceIndex] + 1U);
597 
598  /* store deviceIndex in Global */
599  rlDrvData->commDevIdx.rlDevIndex[deviceIndex] = deviceIndex;
600 
601  tempVar = (rlDrvData->isCmdRespWaited[deviceIndex] | \
602  rlDrvData->isRespWriteWaited[deviceIndex]);
603  /* Check if command transaction is in progress*/
604  if (RL_TRUE == tempVar)
605  {
606  /* Release command response wait semaphore to unblock command thread*/
607  (void)rlDrvData->clientCtx.osiCb.sem.rlOsiSemSignal(
608  &rlDrvData->cmdSem[deviceIndex]);
609  RL_LOGD_ARG0("rlDriverHostIrqHandler Release command response \n");
610  }
611  else
612  {
613  /* No response is expected, Add to the Spawn queue to be hanled
614  * in different context*/
615  (void)rlDrvData->clientCtx.osiCb.queue.rlOsiSpawn(
616  (RL_P_OSI_SPAWN_ENTRY)rlDriverMsgReadSpawnCtx,
617  &rlDrvData->commDevIdx.rlDevIndex[deviceIndex], 0);
618  RL_LOGD_ARG0("rlDriverHostIrqHandler No response is expected \n");
619  }
620 
621  RL_LOGV_ARG0("rlDriverHostIrqHandler ends...\n");
622 
623  return;
624 }
625 
636 rlReturnVal_t rlDriverProcRdMsg(rlUInt8_t devIdx, rlReturnVal_t inVal)
637 {
638  /* get rlDriver global structure pointer */
639  rlDriverData_t* rlDrvData = rlDriverGetHandle();
640  rlReturnVal_t retVal;
641 
642  /* Increment IRQ done IR*/
643  /* AR_CODE_REVIEW MR:D.4.1,D.4.14 <APPROVED> "rlDrvData is pointer to a global strcture,
644  can't be NULL" */
645  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "storing incremented value to global structure" */
646  /*LDRA_INSPECTED 105 D */
647  /*LDRA_INSPECTED 45 D */
648  rlDrvData->rxDoneCnt[devIdx] = (rlDrvData->rxDoneCnt[devIdx] + 1U);
649 
650  /* Check received message class*/
651  switch (rlDrvData->funcParams[devIdx].rxMsgClass)
652  {
653  case RL_API_CLASS_ASYNC:
654  /* If CRC check passed then only parse Async Event */
655  if (inVal == RL_RET_CODE_OK)
656  {
657  /* parse received Async Event Message */
658  /*LDRA_INSPECTED 95 S */
659  retVal = rlDriverAsyncEventHandler(devIdx,\
660  rlDrvData->funcParams[devIdx].asyncEvt.evtMsg.hdr.nsbc,\
661  (rlUInt8_t *)&rlDrvData->funcParams[devIdx].asyncEvt.evtMsg.payload[0],\
662  (rlUInt16_t)(rlDrvData->funcParams[devIdx].asyncEvt.evtMsg.hdr.len - \
663  RHCP_HEADER_LEN));
664  }
665  else
666  {
667  rlUInt16_t errPayload[RL_MIN_SBC_LEN + 4U];
668  /* Generate local payload containing [SBID+SBLEN+error value] */
669  errPayload[0] = ((RL_MMWL_ASYNC_EVENT_MSG * RL_MAX_SB_IN_MSG) +\
670  RL_MMWL_AE_MISMATCH_REPORT);
671  errPayload[1] = (RL_MIN_SBC_LEN + 4U);
672 
673  /* Copy last return value[error] to payload of this async event msg */
674  (void)memcpy(&errPayload[2], (rlUInt8_t*) &inVal, sizeof(rlReturnVal_t));
675 
676  /* Send error Async Event message to application containing error value */
677  /* AR_CODE_REVIEW MR:R.10.3 <INSPECTED> "All param types are matching to function
678  argument type. LDRA tool issue." */
679  /*LDRA_INSPECTED 458 S */
680  retVal = rlDriverAsyncEventHandler(devIdx, 1U,\
681  (rlUInt8_t *)&errPayload[0],\
682  (rlUInt16_t)(RL_MIN_SBC_LEN + 4U));
683  }
684  break;
685  case RL_API_CLASS_NACK:
686  /* These types are legal in this context. Do nothing */
687  retVal = RL_RET_CODE_OK;
688  break;
689  case RL_API_CLASS_RSP:
690  /* Command response is illegal in this context. */
691  retVal = RL_RET_CODE_OK;
692  break;
693  /* if mmWaveLink is running on MSS/DSS and receives command from other Core/HOST */
694  case RL_API_CLASS_CMD:
695  case RL_API_CLASS_BYPASS:
696  {
697  /* Check if command parser API callback is assigned by the application */
698  if (rl_driverData.clientCtx.cmdParserCb.rlCmdParser != RL_NULL_PTR)
699  {
700  /* invoke callback to parse the received command packet */
701  (void)rl_driverData.clientCtx.cmdParserCb.rlCmdParser(
702  rlDrvData->funcParams[devIdx].rxMsgClass, inVal);
703  }
704  else
705  {
706  /* do nothing */
707  }
708  retVal = RL_RET_CODE_OK;
709  }
710  break;
711  case RL_API_CLASS_MAX:
712  /* do nothing */
713  retVal = RL_RET_CODE_OK;
714  break;
715  default:
716  /* set error code */
717  retVal = RL_RET_CODE_PROTOCOL_ERROR;
718  RL_LOGE_ARG0("rlDriverProcRdMsg, Rl protocol error\n");
719  break;
720  }
721 
722  return retVal;
723 }
724 
734 /* DesignId : */
735 /* Requirements : AUTORADAR_REQ-782, AUTORADAR_REQ-1038 */
736 rlReturnVal_t rlDriverMsgReadSpawnCtx(const void *pValue)
737 {
738  rlReturnVal_t retVal, msgRdRetVal;
739  rlUInt8_t deviceIndex;
740  rlUInt8_t lclRxIrqCnt, lclRxDoneCnt;
741  /* get rlDriver global structure pointer */
742  rlDriverData_t* rlDrvData = rlDriverGetHandle();
743 
744  RL_LOGV_ARG0("rlDriverMsgReadSpawnCtx starts...\n");
745 
746  /* check for NULL pointer */
747  if (pValue == RL_NULL_PTR)
748  {
749  /* No Argument Passed */
750  deviceIndex = 0U;
751  RL_LOGE_ARG0("rlDriverMsgReadSpawnCtx Input arg is NULL\n");
752  }
753  else
754  {
755  /* argument passed is Device Index */
756  deviceIndex = *(const rlUInt8_t*)pValue;
757  }
758 
759  /* This function pointer is always being checked on powerOn and mmwavelink
760  fails poweron with error return value, in this failure case no API call is allowed */
761 
762  /* AR_CODE_REVIEW MR:D.4.1,D.4.14 <APPROVED> "rlDrvData is pointer to a global strcture,
763  can't be NULL" */
764  /*LDRA_INSPECTED 45 D */
765  if (RL_RET_CODE_OK != rlDrvData->clientCtx.osiCb.mutex.rlOsiMutexLock
766  (&rlDrvData->devMutex[deviceIndex], (rlOsiTime_t)RL_OSI_WAIT_FOREVER))
767  {
768  rlUInt16_t errPayload[RL_MIN_SBC_LEN + 4U];
769  rlReturnVal_t inVal;
770  rlReturnVal_t* ptrData;
771 
772  /* Generate local payload containing [SBID+SBLEN+error value] */
773  errPayload[0] = ((RL_MMWL_ASYNC_EVENT_MSG * RL_MAX_SB_IN_MSG) +\
774  RL_MMWL_AE_INTERNALERR_REPORT);
775  errPayload[1] = (RL_MIN_SBC_LEN + 4U);
776 
777  /* If MutexLock returns non-zero then treat this as error and set error code to inVal */
778  inVal = RL_RET_CODE_RADAR_OSIF_ERROR;
779 
780  ptrData = &inVal;
781  if (RL_NULL_PTR != ptrData)
782  {
783  /* Copy last return value[error] to payload of this async event msg */
784  /* AR_CODE_REVIEW MR:R.21.17 <INSPECTED> "Local variable and array can't be null.
785  LDRA tool issue." */
786  /*LDRA_INSPECTED 140 D */
787  (void)memcpy((void*)&errPayload[2], (void*)ptrData, sizeof(rlReturnVal_t));
788  }
789 
790  /* Send error Async Event message to application containing error value */
791  /* AR_CODE_REVIEW MR:R.10.3 <INSPECTED> "All param types are matching to function
792  argument type. LDRA tool issue." */
793  /*LDRA_INSPECTED 458 S */
794  retVal = rlDriverAsyncEventHandler(deviceIndex, 1U,\
795  (rlUInt8_t *)&errPayload[0],\
796  (rlUInt16_t)(RL_MIN_SBC_LEN + 4U));
797  }
798  else
799  {
800  /* Messages might have been read by CmdResp context. Therefore after getting LockObj,
801  check again where the Pending Rx Msg is still present. */
802  lclRxIrqCnt = rlDrvData->rxIrqCnt[deviceIndex];
803  lclRxDoneCnt = rlDrvData->rxDoneCnt[deviceIndex];
804 
805  /* unlock Mutex if all Received IRQ are handled i.e. DONE */
806  if (lclRxIrqCnt == lclRxDoneCnt)
807  {
808  (void)rlDrvData->clientCtx.osiCb.mutex.rlOsiMutexUnLock(
809  &rlDrvData->devMutex[deviceIndex]);
810  RL_LOGD_ARG0("rlDriverMsgReadSpawnCtx, RxIrqCnt is equal to RxDoneCnt\n");
811  retVal = RL_RET_CODE_OK;
812  }
813  else
814  {
815  /* Receive data over communication channel*/
816  /* AR_CODE_REVIEW MR:D.4.7,R.17.7 <APPROVED> "variable is used in next function
817  call" */
818  /*LDRA_INSPECTED 91 D */
819  msgRdRetVal = rlDriverMsgRead(rlDrvData, deviceIndex);
820  /* process received message */
821  retVal = rlDriverProcRdMsg(deviceIndex, msgRdRetVal);
822 
823  /* Unlock Global Mutex */
824  (void)rlDrvData->clientCtx.osiCb.mutex.rlOsiMutexUnLock
825  (&rlDrvData->devMutex[deviceIndex]);
826  }
827  }
828  RL_LOGV_ARG0("rlDriverMsgReadSpawnCtx ends...\n");
829 
830  return retVal;
831 }
832 
845 rlReturnVal_t rlDriverMsgCmdReply(rlDriverData_t* rlDrvData, rlUInt8_t devIndex)
846 {
847  rlReturnVal_t retVal, retStatus;
848  rlUInt8_t tempVar;
849 
850  RL_LOGV_ARG0("rlDriverMsgCmdReply starts...\n");
851 
852  /* Receive data over communication channel */
853  retStatus = rlDriverMsgRead(rlDrvData, devIndex);
854 
855  /* Data received successfully */
856  rlDrvData->rxDoneCnt[devIndex]++;
857 
858  if (RL_RET_CODE_OK != (rlInt32_t)retStatus)
859  {
860  /* If Async event message has some issue then notify to the
861  * application with the error value */
862  if (RL_API_CLASS_ASYNC == rlDrvData->funcParams[devIndex].rxMsgClass)
863  {
864  rlUInt16_t errPayload[RL_MIN_SBC_LEN + 4U];
865  /* Generate local payload with [SBID+SBLEN+Error_value] */
866  errPayload[0] = ((RL_MMWL_ASYNC_EVENT_MSG * RL_MAX_SB_IN_MSG) +\
867  RL_MMWL_AE_MISMATCH_REPORT);
868  errPayload[1] = (RL_MIN_SBC_LEN + 4U);
869 
870  (void)memcpy(&errPayload[2], (rlUInt8_t*)&retStatus, sizeof(rlReturnVal_t));
871 
872  /* Send error Async Event message to application containing error value */
873  /* AR_CODE_REVIEW MR:R.10.3 <INSPECTED> "All param types are matching to function
874  argument type. LDRA tool issue." */
875  /*LDRA_INSPECTED 458 S */
876  (void)rlDriverAsyncEventHandler(devIndex, 1U,\
877  (rlUInt8_t *)&errPayload[0],\
878  (rlUInt16_t)(RL_MIN_SBC_LEN + 4U));
879 
880  if (retStatus == RL_RET_CODE_CRC_FAILED)
881  {
882  /* In case CRC failed for the actual async event
883  then in the CMD context wait for response msg */
884  retStatus = RL_RET_CODE_OK;
885  }
886  }
887 
888  /* Error in received data, return error */
889  retVal = retStatus;
890  RL_LOGE_ARG0("Error in received data\n");
891  }
892  else
893  {
894  /* Check received message class */
895  if (RL_API_CLASS_RSP == rlDrvData->funcParams[devIndex].rxMsgClass)
896  {
897  /* Command response received, clear the Wait flag to exit loop */
898  tempVar = RL_FALSE;
899  rlDrvData->isCmdRespWaited[devIndex] = tempVar;
900 
901  /* check if received msg-ID doesn't match with CMD msg-ID */
902  if (rl_rxMsg[devIndex].hdr.opcode.b10MsgId != rl_txMsg[devIndex].hdr.opcode.b10MsgId)
903  {
904  /* set error code if MsgId of response doesn't match with CMD msg ID */
905  retVal = RL_RET_CODE_MSGID_MISMATCHED;
906  RL_LOGE_ARG0("Msg id is mis-matched\n");
907  }
908  else
909  {
910  if (rl_rxMsg[devIndex].hdr.flags.b4SeqNum != rl_txMsg[devIndex].hdr.flags.b4SeqNum)
911  {
912  retVal = RL_RET_CODE_RX_SEQ_NUM_NOT_MATCH;
913  RL_LOGV_ARG0("ACK sequence number is not matching with CMD sequence number\n");
914  }
915  else
916  {
917  /* response sequence number matches with CMD sequence number */
918  retVal = RL_RET_CODE_OK;
919  }
920  }
921 
922  /* In case CmdResp has been read without waiting on cmdSem that */
923  /* Sem object. That to prevent old signal to be processed. */
924  /* Clear the Semaphore */
925  rlDrvData->clientCtx.osiCb.sem.rlOsiSemWait
926  (&(rlDrvData->cmdSem[devIndex]), (rlOsiTime_t)RL_OSI_NO_WAIT);
927  }
928  else if (RL_API_CLASS_ASYNC == rlDrvData->funcParams[devIndex].rxMsgClass)
929  {
930  /* Async event received when command response is awaited,
931  Handle the event and keep waiting for the response*/
932  /* AR_CODE_REVIEW MR:R.10.3 <APPROVED> "All parameter types are matching to function
933  argument type. LDRA tool issue." */
934  /*LDRA_INSPECTED 458 S */
935  /*LDRA_INSPECTED 95 S */
936  (void)rlDriverAsyncEventHandler(devIndex, \
937  rlDrvData->funcParams[devIndex].asyncEvt.evtMsg.hdr.nsbc, \
938  (rlUInt8_t *)&rlDrvData->funcParams[devIndex].asyncEvt.evtMsg.payload[0],
939  (rlUInt16_t)(rlDrvData->funcParams[devIndex].asyncEvt.evtMsg.hdr.len - \
940  RHCP_HEADER_LEN));
941  retVal = RL_RET_CODE_OK;
942 
943  /* If CRC check fails, the Async Event is Ignored */
944  }
945  else if (RL_API_CLASS_NACK == rlDrvData->funcParams[devIndex].rxMsgClass)
946  {
947  /* If NACK received for the CMD sent, set CMD Response Wait TAG to FALSE */
948  tempVar = RL_FALSE;
949  rlDrvData->isCmdRespWaited[devIndex] = tempVar;
950  /* set error code to CRC Failed */
951  retVal = RL_RET_CODE_NACK_ERROR;
952  RL_LOGE_ARG0("CMD CRC check fails, device sends NACK\n");
953  }
954  else
955  {
956  /* Invalid Class*/
957  retVal = RL_RET_CODE_INVALID_STATE_ERROR;
958  RL_LOGE_ARG0("Invalid Class\n");
959  }
960  }
961  RL_LOGV_ARG0("rlDriverMsgCmdReply ends...\n");
962 
963  return retVal;
964 }
965 
966 
977 /* DesignId : MMWL_DesignId_102 */
978 /* Requirements : AUTORADAR_REQ-782, AUTORADAR_REQ-1038 */
979 rlReturnVal_t rlDriverMsgReadCmdCtx(rlUInt8_t devIndex)
980 {
981  rlReturnVal_t retVal;
982  rlDriverData_t* rlDrvData = rlDriverGetHandle();
983 
984  RL_LOGV_ARG0("rlDriverMsgReadCmdCtx starts...\n");
985  /* check for NULL pointer */
986  if (RL_NULL_PTR == rlDrvData)
987  {
988  retVal = RL_RET_CODE_FATAL_ERROR;
989  }
990  else
991  {
992  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Return value is being set under different
993  conditions, where it's set with default value first" */
994  /*LDRA_INSPECTED 8 D */
995 
996  retVal = RL_RET_CODE_OK;
997  /* after command response is received and isCmdRespWaited flag is set FALSE, it is
998  necessary to read out all Async messages in Commands context, because slave device
999  could have dispatched some Async messages before receiving the command */
1000 
1001  /* AR_CODE_REVIEW MR:D.2.1 <APPROVED> "This is function must loop till
1002  * command response is received successfully or retry timer expires ,
1003  * if any Hw hang then WDT reset recovers from this error" */
1004  /*LDRA_INSPECTED 28 D */
1005  while ((RL_TRUE == rlDrvData->isCmdRespWaited[devIndex]) && (RL_RET_CODE_OK == retVal))
1006  {
1007  if (RL_PENDING_RX_MSG(rlDrvData, devIndex))
1008  {
1009  /* init to illegal value and verify it's overwritten with the
1010  * valid one */
1011  rlDrvData->funcParams[devIndex].rxMsgClass = RL_API_CLASS_MAX;
1012 
1013  /* Receive data over communication channel */
1014  retVal += rlDriverMsgCmdReply(rlDrvData, devIndex);
1015  }
1016  /* AR_CODE_REVIEW MR:D.2.1 <APPROVED> "This is function must loop till
1017  * command response is received successfully or retry timer expires,
1018  * if any Hw hang then WDT reset recovers from this error" */
1019  /*LDRA_INSPECTED 28 D */
1020  else
1021  {
1022  /* cmdSem will be signaled by IRQ */
1023  if (RL_RET_CODE_OK != rlDrvData->clientCtx.osiCb.sem.rlOsiSemWait(
1024  &(rlDrvData->cmdSem[devIndex]),
1025  (rlOsiTime_t)rlDrvData->clientCtx.ackTimeout))
1026  {
1027  /* setCmd Response Wait Tag to False when timer expires */
1028  rlDrvData->isCmdRespWaited[devIndex] = RL_FALSE;
1029 
1030  RL_LOGE_ARG0("CmdSem should be signaled by IRQ but respTimeout\n");
1031  retVal += RL_RET_CODE_RESP_TIMEOUT;
1032  break;
1033  }
1034  }
1035  }
1036 
1037  /* if any Rx Msg is pending to process and ACK Timout error hasn't happend */
1038  if (RL_PENDING_RX_MSG(rlDrvData, devIndex) && (retVal != RL_RET_CODE_FATAL_ERROR) \
1039  && (rlDrvData->isCmdRespWaited[devIndex] == RL_FALSE))
1040  {
1041  /* Spawn a thread/task to read pending Rx Msg */
1042  if (rlDrvData->clientCtx.osiCb.queue.rlOsiSpawn
1043  ((RL_P_OSI_SPAWN_ENTRY)rlDriverMsgReadSpawnCtx, \
1044  &rlDrvData->commDevIdx.rlDevIndex[devIndex], 0U) != RL_RET_CODE_OK)
1045  {
1046  retVal = RL_RET_CODE_RADAR_OSIF_ERROR;
1047  }
1048  }
1049  }
1050  RL_LOGV_ARG0("rlDriverMsgReadCmdCtx ends...\n");
1051 
1052  return retVal;
1053 }
1054 
1068 /* DesignId : */
1069 /* Requirements : */
1070 static rlReturnVal_t rlDriverOriginDirCheck(rlUInt8_t deviceRunId,
1071  rlUInt8_t dataDir)
1072 {
1073  rlReturnVal_t retVal;
1074 
1075  RL_LOGV_ARG0("rlDriverOriginDirCheck starts...\n");
1076 
1077  switch (deviceRunId)
1078  {
1079  /* if mmWaveLink instance is running on Host */
1080  case RL_PLATFORM_HOST:
1081  if ((RL_API_DIR_BSS_TO_HOST == dataDir) ||
1082  (RL_API_DIR_MSS_TO_HOST == dataDir) ||
1083  (RL_API_DIR_DSS_TO_HOST == dataDir))
1084  {
1085  /* set OK to return value, i.e. requested DataDir is correct
1086  as per running instance of mmWaveLink */
1087  retVal = RL_RET_CODE_OK;
1088  }
1089  else
1090  {
1091  /* request DataDir is invalid as per running instance of mmWaveLink */
1092  retVal = RL_RET_CODE_INVALID_INPUT;
1093  }
1094  break;
1095  /* if mmWaveLink instance is running on MSS */
1096  case RL_PLATFORM_MSS:
1097  if ((RL_API_DIR_BSS_TO_MSS == dataDir) ||
1098  (RL_API_DIR_DSS_TO_MSS == dataDir) ||
1099  (RL_API_DIR_HOST_TO_MSS == dataDir))
1100  {
1101  /* set OK to return value, i.e. requested DataDir is correct
1102  as per running instance of mmWaveLink */
1103  retVal = RL_RET_CODE_OK;
1104  }
1105  else
1106  {
1107  /* request DataDir is invalid as per running instance of mmWaveLink */
1108  retVal = RL_RET_CODE_INVALID_INPUT;
1109  }
1110  break;
1111  /* if mmWaveLink instance is running on DSS */
1112  case RL_PLATFORM_DSS:
1113  /* if Data direction is towards DSS */
1114  if ((RL_API_DIR_BSS_TO_DSS == dataDir) ||
1115  (RL_API_DIR_MSS_TO_DSS == dataDir) ||
1116  (RL_API_DIR_HOST_TO_DSS == dataDir))
1117  {
1118  /* set OK to return value, i.e. requested DataDir is correct
1119  as per running instance of mmWaveLink */
1120  retVal = RL_RET_CODE_OK;
1121  }
1122  else
1123  {
1124  /* request DataDir is invalid as per running instance of mmWaveLink */
1125  retVal = RL_RET_CODE_INVALID_INPUT;
1126  }
1127  break;
1128  default:
1129  /* Invalid: set error code */
1130  retVal = RL_RET_CODE_INVALID_INPUT;
1131  RL_LOGE_ARG2("Unknown platform %d, retVal = %d\n", \
1132  dataDir, retVal);
1133  break;
1134  }
1135  RL_LOGV_ARG0("rlDriverOriginDirCheck ends...\n");
1136 
1137  return retVal;
1138 }
1139 
1140 rlReturnVal_t rlDriverRdVerifyMsg(rlReadBuf_t readBuf, rlUInt8_t devIndex)
1141 {
1142  rlUInt16_t rxLengthRecv;
1143  rlReturnVal_t retVal, readRetVal;
1144  rlUInt16_t payloadLen, msgCrcLen, msgCrcType;
1145  rlUInt8_t isCrcPresent;
1146 
1147  /* get Received Message length excluding SYNC */
1148  rxLengthRecv = RL_RHCP_HDR_PL_LENGTH(&(readBuf.syncHeader.protHdr));
1149 
1150  /* check if received msg length is under valid Msg size */
1151  if (rxLengthRecv >= (RL_MAX_SIZE_MSG - SYNC_PATTERN_LEN))
1152  {
1153  retVal = RL_RET_CODE_PROTOCOL_ERROR;
1154  }
1155  else
1156  {
1157  rlRhcpMsg_t *rhcpMsg;
1158 
1159  /* Get Rx Message Class from received buffer header */
1160  /* Process Header Here - Verify each field */
1161  rl_driverData.funcParams[devIndex].rxMsgClass =
1162  RL_RHCP_HDR_OPCODE_CLASS(&(readBuf.syncHeader.protHdr));
1163 
1164  /* get the Payload Value removing Header length from Rx Msg Length */
1165  payloadLen = rxLengthRecv - (rlUInt16_t)RHCP_HEADER_LEN;
1166 
1167  if (RL_API_CLASS_ASYNC == rl_driverData.funcParams[devIndex].rxMsgClass)
1168  {
1169  /* Get RHCP message structure pointer */
1170  /* AR_CODE_REVIEW MR:D.4.1,D.4.14 <APPROVED> "rlDrvData is pointer to a global
1171  structure, can't be NULL" */
1172  /*LDRA_INSPECTED 45 D */
1173  rhcpMsg = &rl_driverData.funcParams[devIndex].asyncEvt.evtMsg;
1174  }
1175  else
1176  {
1177  /* Get RHCP message structure pointer */
1178  rhcpMsg = &rl_rxMsg[devIndex];
1179  }
1180 
1181  /* copy header to global structure */
1182  rhcpMsg->hdr = readBuf.syncHeader.protHdr;
1183  /* Copy SYNC from Communication Channel*/
1184  rhcpMsg->syncPattern = readBuf.syncHeader.syncPattern;
1185 
1186  /* Check whether CRC is present*/
1187  if (rhcpMsg->hdr.flags.b2Crc != 0U)
1188  {
1189  /* if CRC is not present in Msg the reset crc variables */
1190  isCrcPresent = RL_FALSE;
1191  msgCrcLen = 0U;
1192  msgCrcType = 0U;
1193  }
1194  else
1195  {
1196  isCrcPresent = RL_TRUE;
1197  /* It may be size 2/4/8 based on 16/32/64 bit */
1198  msgCrcType = rhcpMsg->hdr.flags.b2CrcLen;
1199  /* set CRC length in bytes based on CRC Type */
1200  msgCrcLen = (2U << (msgCrcType & 0x3U));
1201  }
1202  /* Calculate payload length from header legnth*/
1203  payloadLen = ((isCrcPresent == RL_TRUE) ? (payloadLen - msgCrcLen) : payloadLen);
1204 
1205  /* This is an Response/AsyncEvent message. Read the rest of it. */
1206  if (payloadLen > 0U)
1207  {
1208  if (RL_IF_READ(rl_driverData.commDevIdx.comIfHdl[devIndex],
1209  &rhcpMsg->payload[0U], payloadLen) != (rlInt32_t)payloadLen)
1210  {
1211  /* If Read from Communication channel failed then set Error code */
1212  readRetVal = RL_RET_CODE_RADAR_IF_ERROR;
1213  }
1214  else
1215  {
1216  readRetVal = RL_RET_CODE_OK;
1217  }
1218  }
1219  else
1220  {
1221  readRetVal = RL_RET_CODE_OK;
1222  }
1223 
1224  /* If CRC is present - Read and verify*/
1225  if ((isCrcPresent == RL_TRUE) && (readRetVal == RL_RET_CODE_OK))
1226  {
1227  /* Read the CRC Bytes */
1228  if (RL_IF_READ(rl_driverData.commDevIdx.comIfHdl[devIndex],
1229  rl_driverData.funcParams[devIndex].msgCRC,
1230  msgCrcLen) != (rlInt32_t)msgCrcLen)
1231  {
1232  /* Set the error code if read data fails */
1233  retVal = RL_RET_CODE_RADAR_IF_ERROR;
1234  }
1235  else
1236  {
1237  (void)memcpy(&rhcpMsg->payload[payloadLen], \
1238  &rl_driverData.funcParams[devIndex].msgCRC[0U], msgCrcLen);
1239  /* Check if CRC is enabled from the application and it's type
1240  matched with received MSG CRC type */
1241  if ((rl_driverData.clientCtx.crcType != (rlUInt8_t)RL_CRC_TYPE_NO_CRC) && \
1242  (rl_driverData.clientCtx.crcType == (rlUInt8_t)msgCrcType))
1243  {
1244  /* Validate CRC first as Opcode might be corrupt as well */
1245  /* AR_CODE_REVIEW MR:R.10.3 <APPROVED> "All parameter types are matching to
1246  function argument type. LDRA tool issue." */
1247  /*LDRA_INSPECTED 458 S */
1248  retVal = rlDriverVerifyCRC((rlUInt8_t*)&rhcpMsg->hdr, (rxLengthRecv - \
1249  msgCrcLen), (rlUInt8_t)(msgCrcType), \
1250  rl_driverData.funcParams[devIndex].msgCRC);
1251  }
1252  else
1253  {
1254  retVal = RL_RET_CODE_OK;
1255  }
1256  }
1257  }
1258  else
1259  {
1260  retVal = RL_RET_CODE_OK;
1261  }
1262  }
1263 
1264  return retVal;
1265 }
1266 
1278 /* DesignId : MMWL_DesignId_026 */
1279 /* Requirements : AUTORADAR_REQ-777, AUTORADAR_REQ-779 */
1280 rlReturnVal_t rlDriverMsgRead(rlDriverData_t* rlDrvData, rlUInt8_t devIndex)
1281 {
1282  rlReturnVal_t retVal, hdrRetVal;
1283  rlReadBuf_t readBuf = {0};
1284  rlUInt16_t payloadLen;
1285 
1286  RL_LOGV_ARG0("rlDriverMsgRead starts...\n");
1287  /* check for NULL pointer */
1288  if (RL_NULL_PTR == rlDrvData)
1289  {
1290  /* set error code */
1291  retVal = RL_RET_CODE_FATAL_ERROR;
1292  }
1293  else
1294  {
1295  rlReturnVal_t hdrType;
1296 
1297  /* Read message Header from given device index */
1298  hdrType = rlDriverRxHdrRead(readBuf.tempBuf,
1299  rlDrvData->commDevIdx.comIfHdl[devIndex]);
1300  RL_LOGV_ARG1("rlDriverRxHdrRead return val = %d\n", hdrType);
1301 
1302  /* if it's not CNYS pattern then calculate checksum before consuming or
1303  * forwarding to other core */
1304  if (SYNC_PATTERN_MATCHED == (rlInt32_t)(hdrType))
1305  {
1306  /* Verify Checksum, return value 0/-7 (RL_RET_CODE_CHKSUM_FAILED) */
1307  hdrRetVal = rlDriverValidateHdr(readBuf.syncHeader.protHdr);
1308 
1309  /* Received msg can be command/response/async_event
1310  * and it is destined to the same device where this mmWaveLink ir running
1311  */
1312  if ((RL_RET_CODE_OK == hdrRetVal) && (RL_RET_CODE_OK == \
1313  rlDriverOriginDirCheck(rlDrvData->clientCtx.platform,
1314  (rlUInt8_t)readBuf.syncHeader.protHdr.opcode.b4Direction)))
1315  {
1316  retVal = rlDriverRdVerifyMsg(readBuf, devIndex);
1317  }
1318  else if (RL_RET_CODE_OK == hdrRetVal)
1319  {
1320  rlDrvData->funcParams[devIndex].rxMsgClass = RL_API_CLASS_BYPASS;
1321  /* if rcvd data is not meant for the device where mmWaveLink is running,
1322  * Then pass data to intended destination; Assumption: byPass of
1323  * Data will happening in MSS only
1324  */
1325  rl_rxMsg[devIndex].syncPattern = readBuf.syncHeader.syncPattern;
1326  rl_rxMsg[devIndex].hdr = readBuf.syncHeader.protHdr;
1327 
1328  /* this length includes the CRC field also */
1329  payloadLen = readBuf.syncHeader.protHdr.len - (rlUInt16_t)RHCP_HEADER_LEN;
1330 
1331  /* read full data before writing to destination COMM handle */
1332  if (RL_IF_READ(rlDrvData->commDevIdx.comIfHdl[devIndex], \
1333  &rl_rxMsg[devIndex].payload[0], payloadLen) != (rlInt32_t)payloadLen)
1334  {
1335  /* Set error code if read is failed */
1336  retVal = RL_RET_CODE_RADAR_IF_ERROR;
1337  }
1338  else
1339  {
1340  /* Set as passed if data read returns zero */
1341  retVal = RL_RET_CODE_OK;
1342  }
1343  }
1344  /* If checksum mismatched of the received message and link is running on
1345  Host then it needs to flush the AWR device's MibSPI RAM so that MSS
1346  can re-sync its buffer pointer */
1347  else if ((RL_RET_CODE_CHKSUM_FAILED == hdrRetVal) && \
1348  (rl_driverData.clientCtx.platform == RL_PLATFORM_HOST))
1349  {
1350  rlUInt16_t dummyToFlushSpi[8U] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
1351  0xFFFF, 0xFFFF, 0xFFFF};
1352  rlUInt16_t readCnt;
1353  /* Get the CRC Length what is configured */
1354  rlUInt16_t msgCrcLen = (2U << (rl_driverData.clientCtx.crcType & 0x3U));
1355 
1356  /* Read 240 bytes from SPI buff to allign MSS SPI_RX DMA with HOST TX buff */
1357  for (readCnt = 1U; readCnt < (SYNC_PATTERN_LEN + RHCP_HEADER_LEN); readCnt++)
1358  {
1359  (void)RL_IF_READ(rlDrvData->commDevIdx.comIfHdl[devIndex],
1360  (rlUInt8_t*)&dummyToFlushSpi[0U], (SYNC_PATTERN_LEN + \
1361  RHCP_HEADER_LEN));
1362  }
1363 
1364  /* Check whether CRC is present read it from MibSPI buff */
1365  if (rl_txMsg[devIndex].hdr.flags.b2Crc == 0U)
1366  {
1367  /* Read remaining data to clear SPI buffer */
1368  (void)RL_IF_READ(rlDrvData->commDevIdx.comIfHdl[devIndex],
1369  (rlUInt8_t*)&dummyToFlushSpi[0U], msgCrcLen);
1370  }
1371  /* In case Checksum of header is corrupted MMWL will create internal Async event
1372  message to Notify the application about checksum failure */
1373  rl_driverData.funcParams[devIndex].rxMsgClass = RL_API_CLASS_ASYNC;
1374 
1375  /* Set header Validate function return value to retVal */
1376  retVal = hdrRetVal;
1377  }
1378  else
1379  {
1380  /* Set header Validate function return value to retVal */
1381  retVal = hdrRetVal;
1382  /* In case CRC/Checksum is corrupted then store RxMsg Class with Async event */
1383  rl_driverData.funcParams[devIndex].rxMsgClass =
1384  RL_RHCP_HDR_OPCODE_CLASS(&(readBuf.syncHeader.protHdr));
1385  }
1386  }
1387  /* In case mmWaveLink instance is running on MSS, it may receive CNYS from Host Over SPI */
1388  else if (CNYS_PATTERN_MATCHED == (rlInt32_t)(hdrType))
1389  {
1390  /* Check callback is assigned by the application */
1391  if (rl_driverData.clientCtx.cmdParserCb.rlPostCnysStep != RL_NULL_PTR)
1392  {
1393  /* invoke function to complete the task required after receiving CNYS */
1394  retVal = rl_driverData.clientCtx.cmdParserCb.rlPostCnysStep(devIndex);
1395  }
1396  else
1397  {
1398  /* Set error code if callback is NULL */
1399  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1400  }
1401  }
1402  else
1403  {
1404  retVal = hdrType;
1405  /* If timeout for HostIRQ down then notify this to Host via AsyncEvent */
1406  if (hdrType == RL_RET_CODE_HOSTIRQ_TIMEOUT)
1407  {
1408  rl_driverData.funcParams[devIndex].rxMsgClass = RL_API_CLASS_ASYNC;
1409  }
1410  else
1411  {
1412  /* In case CRC/Checksum is corrupted then store RxMsg Class with Async event */
1413  rl_driverData.funcParams[devIndex].rxMsgClass =
1414  RL_RHCP_HDR_OPCODE_CLASS(&(readBuf.syncHeader.protHdr));
1415  }
1416  }
1417 
1418  /* Unmask Interrupt call */
1419  if ((RL_NULL_PTR != rlDrvData->clientCtx.devCtrlCb.rlDeviceUnMaskHostIrq) &&\
1420  (retVal != RL_RET_CODE_FATAL_ERROR))
1421  {
1422  /* Un Mask Interrupt */
1424  rlDrvData->commDevIdx.comIfHdl[devIndex]);
1425  RL_LOGD_ARG0("rlDriverMsgRead Unmask Interrupt call\n");
1426  }
1427  }
1428 
1429  RL_LOGV_ARG0("rlDriverMsgRead ends...\n");
1430 
1431  return retVal;
1432 }
1433 
1446 /* DesignId : MMWL_DesignId_025 */
1447 /* Requirements : AUTORADAR_REQ_772, AUTORADAR_REQ-774 */
1448 rlReturnVal_t rlDriverMsgWrite(rlDriverData_t* rlDrvData, rlUInt8_t devIndex,
1449  rlComIfHdl_t comIfHdl)
1450 {
1451  rlReturnVal_t retVal;
1452 
1453  RL_LOGV_ARG0("rlDriverMsgWrite starts...\n");
1454 
1455  /* check for NULL pointer */
1456  if (((rlComIfHdl_t)RL_NULL != comIfHdl) && (rlDrvData != RL_NULL_PTR))
1457  {
1458  rlUInt16_t checkSum = 0U, msgCrcLen;
1459  rlUInt16_t payloadLen;
1460  rlUInt16_t tempLen;
1461  /* Calculate Checksum */
1462  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Checksum is getting updated in called function" */
1463  /*LDRA_INSPECTED 8 D */
1464  (void)rlDriverCalChkSum(&rl_txMsg[devIndex].hdr, ((rlUInt8_t)(RHCP_HEADER_LEN - 2U)),
1465  &checkSum);
1466  rl_txMsg[devIndex].hdr.chksum = checkSum;
1467 
1468  /* get Payload length removing Header length from Msg Length */
1469  payloadLen = rl_txMsg[devIndex].hdr.len - (rlUInt16_t)RHCP_HEADER_LEN;
1470  RL_LOGV_ARG1("API Dir = %d \n", rl_txMsg[devIndex].hdr.opcode.b4Direction);
1471 
1472  /* check for Data Direction to choose Sync Pattern */
1473  if ((RL_API_DIR_DSS_TO_HOST == rl_txMsg[devIndex].hdr.opcode.b4Direction) || \
1474  (RL_API_DIR_MSS_TO_HOST == rl_txMsg[devIndex].hdr.opcode.b4Direction) || \
1475  (RL_API_DIR_DSS_TO_MSS == rl_txMsg[devIndex].hdr.opcode.b4Direction))
1476  {
1477  /* set device to Host Sync Pattern */
1478  rl_txMsg[devIndex].syncPattern.sync1 = D2H_SYNC_PATTERN_1;
1479  rl_txMsg[devIndex].syncPattern.sync2 = D2H_SYNC_PATTERN_2;
1480  }
1481  else
1482  {
1483  /* set Host to device Sync Pattern */
1484  rl_txMsg[devIndex].syncPattern.sync1 = H2D_SYNC_PATTERN_1;
1485  rl_txMsg[devIndex].syncPattern.sync2 = H2D_SYNC_PATTERN_2;
1486  }
1487 
1488  /* Check if CRC is enabled, Calculate and update payload length*/
1489  if (rl_txMsg[devIndex].hdr.flags.b2Crc == RL_HDR_FLAG_CRC)
1490  {
1491  /* It may be size 2/4/8 based on 16/32/64 bit */
1492  msgCrcLen = (2U << (rlDrvData->clientCtx.crcType & 0x3U));
1493  /* compute CRC */
1494  /* AR_CODE_REVIEW MR:R.10.3 <INSPECTED> "All param types are matching to function
1495  argument type. LDRA tool issue." */
1496  /*LDRA_INSPECTED 458 S */
1497  (void)rlDriverCalCRC((rlUInt8_t *)&rl_txMsg[devIndex].hdr,\
1498  (rl_txMsg[devIndex].hdr.len - msgCrcLen),
1499  (rlUInt8_t)rlDrvData->clientCtx.crcType,
1500  &rlDrvData->funcParams[devIndex].msgCRC[0]);
1501  /* copy computed CRC to Tx Msg buffer */
1502  (void)memcpy((rlUInt8_t*)(&rl_txMsg[devIndex].payload[payloadLen - msgCrcLen]),
1503  (rlUInt8_t*)&(rlDrvData->funcParams[devIndex].msgCRC[0]), msgCrcLen);
1504  }
1505  tempLen = ((rlUInt16_t)(SYNC_PATTERN_LEN + RHCP_HEADER_LEN) + payloadLen);
1506 
1507  /* write Tx Msg to destination either over Mailbox internal to
1508  mmWave device or to External Host Over SPI */
1509  if (RL_IF_WRITE(comIfHdl, ((rlUInt8_t *)&rl_txMsg[devIndex]), \
1510  tempLen) != (rlInt32_t)tempLen)
1511  {
1512  /* set error code */
1513  retVal = RL_RET_CODE_RADAR_IF_ERROR;
1514  }
1515  else
1516  {
1517  /* set Error code as OK */
1518  retVal = RL_RET_CODE_OK;
1519  }
1520  }
1521  else
1522  {
1523  /* set error code if pointers are NULL */
1524  retVal = RL_RET_CODE_FATAL_ERROR;
1525  }
1526  RL_LOGV_ARG0("rlDriverMsgWrite ends...\n");
1527 
1528  return retVal;
1529 }
1530 
1544 /* DesignId : */
1545 /* Requirements : AUTORADAR_REQ-777 */
1546 static rlUInt8_t rlDriverReceiveSync(rlComIfHdl_t comIfHdl, rlUInt8_t syncBuf[],
1547  rlInt32_t *syncType)
1548 {
1549  rlUInt8_t count = 0;
1550  rlInt32_t retVal;
1551  rlSyncPattern_t recSyncPattern = {0U, 0U};
1552  rlReturnVal_t errVal;
1553 
1554  RL_LOGV_ARG0("rlDriverReceiveSync starts...\n");
1555 
1556  /* check for NULL pointer */
1557  if (syncType != (rlInt32_t*)RL_NULL)
1558  {
1559  /* Read 4 bytes SYNC Pattern) */
1560  if (RL_IF_READ(comIfHdl, &syncBuf[0U], (rlUInt16_t)SYNC_PATTERN_LEN) != \
1561  (rlInt32_t)SYNC_PATTERN_LEN)
1562  {
1563  /* set error code */
1564  errVal = RL_RET_CODE_RADAR_IF_ERROR;
1565  }
1566  else
1567  {
1568  /* if SYNC pattern has been read properly then copy it */
1569  (void)memcpy(&recSyncPattern, &syncBuf[0U], SYNC_PATTERN_LEN);
1570  errVal = RL_RET_CODE_OK;
1571  }
1572  retVal = PATTERN_NOT_MATCHED;
1573 
1574  /* Wait for SYNC_PATTERN from the device (when mmWaveLink is running on Ext Host*/
1575  while (((retVal) == (rlInt32_t)PATTERN_NOT_MATCHED) && (errVal == RL_RET_CODE_OK))
1576  {
1577  /* check if matched with SYNC pattern Host-to-device or device-to-Host */
1578  if (((recSyncPattern.sync1 == H2D_SYNC_PATTERN_1) &&
1579  (recSyncPattern.sync2 == H2D_SYNC_PATTERN_2) ) || \
1580  ((recSyncPattern.sync1 == D2H_SYNC_PATTERN_1) &&
1581  (recSyncPattern.sync2 == D2H_SYNC_PATTERN_2)))
1582  {
1583  /* set to SYNC Matched flag if H2D or D2H SYNC pattern is matching
1584  for big/little endian data */
1585  retVal = SYNC_PATTERN_MATCHED;
1586  }
1587  else
1588  {
1589  /* if mmwavelink running on device and connect to Host over SPI then
1590  it may recieve CNYS to send data */
1591  if ((recSyncPattern.sync1 == H2D_CNYS_PATTERN_1) &&
1592  (recSyncPattern.sync2 == H2D_CNYS_PATTERN_2))
1593  {
1594  /* set to CNYS Matched flag if H2D CNYS pattern is matching
1595  for big/little endian data */
1596  retVal = CNYS_PATTERN_MATCHED;
1597  }
1598  /* check if count is beyond SYNC Scan threshold */
1599  else if (count >= (rlUInt16_t)RL_SYNC_SCAN_THRESHOLD)
1600  {
1601  rlUInt16_t crcLen = (2U << (rl_driverData.clientCtx.crcType & 0x3U));
1602  /* If pattern not found then read few extra bytes (CRC Len) to make
1603  whole read count [4n+CRCLen] aligned */
1604  if (RL_IF_READ(comIfHdl, &syncBuf[SYNC_PATTERN_LEN], (rlUInt16_t)crcLen) != \
1605  (rlInt32_t)crcLen)
1606  {
1607  /* Set error code to terminate this loop */
1608  errVal += RL_RET_CODE_RADAR_IF_ERROR;
1609  }
1610  else
1611  {
1612  /* Set error code to terminate this loop */
1613  errVal += RL_RET_CODE_PROTOCOL_ERROR;
1614  }
1615  }
1616  else
1617  {
1618  /* Read next 4 bytes to Low 4 bytes of buffer */
1619  if (0 == (count % SYNC_PATTERN_LEN))
1620  {
1621  /* Read 4 bytes SYNC Pattern) */
1622  if (RL_IF_READ(comIfHdl, &syncBuf[SYNC_PATTERN_LEN],\
1623  (rlUInt16_t)SYNC_PATTERN_LEN) != \
1624  (rlInt32_t)SYNC_PATTERN_LEN)
1625  {
1626  /* Set error code to terminate this loop */
1627  errVal += RL_RET_CODE_RADAR_IF_ERROR;
1628  break;
1629  }
1630  }
1631  /* Shift Buffer Up for checking if the sync is shifted */
1632  rlDriverShiftDWord(syncBuf);
1633  /* copy data to recv sync pattern to compare further */
1634  (void)memcpy(&recSyncPattern, &syncBuf[0U], SYNC_PATTERN_LEN);
1635  /* increment read counter */
1636  count++;
1637  }
1638  }
1639  }
1640 
1641  if (errVal == RL_RET_CODE_OK)
1642  {
1643  *(syncType) = retVal;
1644  }
1645  else
1646  {
1647  *(syncType) = errVal;
1648  }
1649  }
1650  count %= SYNC_PATTERN_LEN;
1651  RL_LOGV_ARG1("rlDriverReceiveSync, count = %d\n", count);
1652  RL_LOGV_ARG0("rlDriverReceiveSync ends...\n");
1653 
1654  return count;
1655 }
1656 
1667 /* DesignId : */
1668 /* Requirements : AUTORADAR_REQ-777 */
1669 /*AR_CODE_REVIEW MR:R.2.2 <APPROVED> "errVal is re initialized under different
1670  if else conditions based on what the error is" */
1671 /*LDRA_INSPECTED 8 D */
1672 rlReturnVal_t rlDriverRxHdrRead(rlUInt8_t hdrBuf[RHCP_HEADER_LEN], rlComIfHdl_t comIfHdl)
1673 {
1674  /* syncBuf: it should be 2/4 byte aligned, as in the application where
1675  * it uses DMA to Rd/Wr DMA might have limitation of src/dest address
1676  * alignement
1677  */
1678  rlUInt8_t syncBuf[SYNC_PATTERN_LEN * 2] = {0U};
1679  /* This buffer contains CNYS pattern (4Bytes) and 12Bytes of dummy sequence.
1680  Host writes this buffer in response to Host-IRQ raised by AWR device to indicate
1681  that device can now write response/async event data to its SPI buffer which will
1682  be read by Host.
1683  */
1684  rlUInt16_t cnysBuf[8U] = {H2D_CNYS_PATTERN_1, H2D_CNYS_PATTERN_2,
1685  0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU, 0xFFFFU};
1686  rlInt32_t syncType = PATTERN_NOT_MATCHED;
1687  rlUInt8_t syncCnt;
1688  rlInt32_t errVal;
1689 
1690  RL_LOGV_ARG0("rlDriverRxHdrRead starts...\n");
1691 
1692  /* check for NULL pointer */
1693  if ((rlComIfHdl_t)RL_NULL == comIfHdl)
1694  {
1695  errVal = RL_RET_CODE_FATAL_ERROR;
1696  syncType += errVal;
1697  }
1698  else
1699  {
1700  /* If mmWaveLink is running on Ext Host */
1701  if (rl_driverData.clientCtx.platform == RL_PLATFORM_HOST)
1702  {
1703  /* Write CNYS pattern to mmWave Radar */
1704  if (RL_IF_WRITE(comIfHdl,
1705  (rlUInt8_t*)&cnysBuf[0U], (rlUInt16_t)(SYNC_PATTERN_LEN+ RHCP_HEADER_LEN)) !=\
1706  (rlInt32_t)(SYNC_PATTERN_LEN + RHCP_HEADER_LEN))
1707  {
1708  /* Set error code if data write function fails to write SYNC pattern */
1709  errVal = RL_RET_CODE_RADAR_IF_ERROR;
1710  }
1711  else
1712  {
1713  errVal = RL_RET_CODE_OK;
1714  }
1715 
1716  RL_LOGV_ARG2("Platform = %d, delay = %d \n",\
1717  rl_driverData.clientCtx.platform, \
1718  rl_driverData.clientCtx.timerCb.rlDelay);
1719  /* Need to wait till host Irq is down */
1720  /* Check if Host Irq Status can be polled, else use fixed delay */
1721  if ((rl_driverData.clientCtx.devCtrlCb.rlDeviceWaitIrqStatus != NULL) &&
1722  (rl_driverData.clientCtx.devCtrlCb.rlDeviceWaitIrqStatus(comIfHdl,
1723  0U) != RL_RET_CODE_OK) && (errVal == RL_RET_CODE_OK))
1724  {
1725  /* If IRQ polling timed out then re-write the CNYS pattern to mmwave Radar */
1726  if (RL_IF_WRITE(comIfHdl,
1727  (rlUInt8_t*)&cnysBuf[0U], (rlUInt16_t)(SYNC_PATTERN_LEN+ RHCP_HEADER_LEN)) !=\
1728  (rlInt32_t)(SYNC_PATTERN_LEN + RHCP_HEADER_LEN))
1729  {
1730  /* Set error code if data write function fails to write SYNC pattern */
1731  errVal += RL_RET_CODE_RADAR_IF_ERROR;
1732  }
1733  else
1734  {
1735  if (rl_driverData.clientCtx.devCtrlCb.rlDeviceWaitIrqStatus(comIfHdl, 0U) != 0)
1736  {
1737  errVal += RL_RET_CODE_HOSTIRQ_TIMEOUT;
1738  }
1739  }
1740  }
1741  else
1742  {
1743  /* Check if Delay callback is present and invoke */
1744  if (rl_driverData.clientCtx.timerCb.rlDelay != RL_NULL_PTR)
1745  {
1746  /* add 1 mSec delay */
1747  (void)rl_driverData.clientCtx.timerCb.rlDelay(1U);
1748  }
1749  }
1750  }
1751  else
1752  {
1753  errVal = RL_RET_CODE_OK;
1754  }
1755 
1756  if (errVal == RL_RET_CODE_OK)
1757  {
1758  /* AR_CODE_REVIEW MR:D.4.7 <APPROVED> "syncCnt is used when pattern is matched to
1759  copy and read data" */
1760  /*LDRA_INSPECTED 91 D */
1761  syncCnt = rlDriverReceiveSync(comIfHdl, &syncBuf[0U], &syncType);
1762  RL_LOGV_ARG1("syncType = %d \n", syncType);
1763 
1764  if ((CNYS_PATTERN_MATCHED == syncType) || (SYNC_PATTERN_MATCHED == syncType))
1765  {
1766  rlUInt16_t tempLen;
1767  rlUInt8_t* payloadBuf;
1768  /* copying shifted data to hdrBuf */
1769  payloadBuf = &syncBuf[0U];
1770  if (RL_NULL_PTR != payloadBuf)
1771  {
1772  /* AR_CODE_REVIEW MR:R.21.17 <INSPECTED> "Local array can't be null.
1773  LDRA tool issue." */
1774  /*LDRA_INSPECTED 140 D */
1775  (void)memcpy(&hdrBuf[0], payloadBuf, (SYNC_PATTERN_LEN + syncCnt));
1776  }
1777  tempLen = RHCP_HEADER_LEN - (0x00FFU & syncCnt);
1778  /* Here we've read Sync Pattern. Read the remaining header */
1779  if (RL_IF_READ(comIfHdl, (&hdrBuf[(SYNC_PATTERN_LEN + syncCnt)]), \
1780  tempLen) != (rlInt32_t)tempLen)
1781  {
1782  syncType += RL_RET_CODE_RADAR_IF_ERROR;
1783  }
1784  }
1785  else
1786  {
1787  /* do nothing */
1788  RL_LOGD_ARG0("do nothing ");
1789  }
1790  }
1791  else
1792  {
1793  syncType += errVal;
1794  }
1795 
1796  }
1797 
1798  RL_LOGV_ARG0("rlDriverRxHdrRead ends...\n");
1799 
1800  return syncType;
1801 }
1802 
1811 /* DesignId : MMWL_DesignId_002 */
1812 /* Requirements : AUTORADAR_REQ-784 */
1813 rlReturnVal_t rlDriverOsiInit(void)
1814 {
1815  rlReturnVal_t retVal;
1816  rlInt32_t funcRetVal = RL_RET_CODE_OK;
1817  rlUInt8_t index;
1818  rlInt8_t CmdSemStr[9] = "CmdSem_";
1819  rlInt8_t devMutexStr[11] = "devMutex_";
1820 
1821  for (index = 0U; index < RL_CASCADE_NUM_DEVICES; index++)
1822  {
1823  /* Create Command Semaphore */
1824  /* AR_CODE_REVIEW MR:R.10.8 <INSPECTED> "conversion required" */
1825  /*LDRA_INSPECTED 444 S */
1826  CmdSemStr[7] = (rlInt8_t)(index+48U);
1827  /* AR_CODE_REVIEW MR:R.18.1 <INSPECTED> "Array size not exceeded. Tool issue" */
1828  /*LDRA_INSPECTED 69 X */
1829  CmdSemStr[8] = (rlInt8_t)'\0';
1830  funcRetVal += rl_driverData.clientCtx.osiCb.sem.rlOsiSemCreate(
1831  &rl_driverData.cmdSem[index], CmdSemStr);
1832 
1833  /* Create Command Mutex */
1834  /* AR_CODE_REVIEW MR:R.10.8 <INSPECTED> "conversion required" */
1835  /*LDRA_INSPECTED 444 S */
1836  devMutexStr[9] = (rlInt8_t)(index+48U);
1837  /* AR_CODE_REVIEW MR:R.18.1 <INSPECTED> "Array size not exceeded. Tool issue" */
1838  /*LDRA_INSPECTED 69 X */
1839  devMutexStr[10] = (rlInt8_t)'\0';
1840  funcRetVal += rl_driverData.clientCtx.osiCb.mutex.rlOsiMutexCreate(
1841  &rl_driverData.devMutex[index], devMutexStr);
1842  }
1843 
1844  /* check for above function call return value */
1845  if (funcRetVal != RL_RET_CODE_OK)
1846  {
1847  /* set error code */
1848  retVal = RL_RET_CODE_RADAR_OSIF_ERROR;
1849  }
1850  else
1851  {
1852  retVal = RL_RET_CODE_OK;
1853  }
1854 
1855  return retVal;
1856 }
1857 
1858 static rlReturnVal_t rlDriverOsiCbCheck(rlClientCbs_t clientCb)
1859 {
1860  rlReturnVal_t retVal;
1861 
1862  /* Check if application has passed mutex interace functions */
1863  if ((RL_NULL_PTR == clientCb.osiCb.mutex.rlOsiMutexCreate) ||
1864  (RL_NULL_PTR == clientCb.osiCb.mutex.rlOsiMutexLock ) ||
1865  (RL_NULL_PTR == clientCb.osiCb.mutex.rlOsiMutexUnLock) ||
1866  (RL_NULL_PTR == clientCb.osiCb.mutex.rlOsiMutexDelete))
1867  {
1868  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1869  }
1870  /* Check if application has passed semaphore interface functions */
1871  else if ((RL_NULL_PTR == clientCb.osiCb.sem.rlOsiSemCreate) ||
1872  (RL_NULL_PTR == clientCb.osiCb.sem.rlOsiSemWait ) ||
1873  (RL_NULL_PTR == clientCb.osiCb.sem.rlOsiSemSignal) ||
1874  (RL_NULL_PTR == clientCb.osiCb.sem.rlOsiSemDelete))
1875  {
1876  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1877  }
1878  /* Check if application has passed communication interface functions */
1879  else if ((RL_NULL_PTR == (void*)clientCb.comIfCb.rlComIfOpen ) ||
1880  (RL_NULL_PTR == clientCb.comIfCb.rlComIfClose) ||
1881  (RL_NULL_PTR == clientCb.comIfCb.rlComIfRead ) ||
1882  (RL_NULL_PTR == clientCb.comIfCb.rlComIfWrite))
1883  {
1884  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1885  }
1886  else
1887  {
1888  /* if no error then set return value as OK */
1889  retVal = RL_RET_CODE_OK;
1890  }
1891 
1892  return retVal;
1893 }
1894 
1904 static rlReturnVal_t rlDriverClientCbCheck(rlClientCbs_t clientCb)
1905 {
1906  rlReturnVal_t retVal;
1907 
1908  if (RL_RET_CODE_OK != rlDriverOsiCbCheck(clientCb))
1909  {
1910  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1911  }
1912  /* Check if application has passed device interace functions */
1913  else if ((RL_NULL_PTR == clientCb.eventCb.rlAsyncEvent ) ||
1914  (RL_NULL_PTR == clientCb.devCtrlCb.rlDeviceDisable ) ||
1915  (RL_NULL_PTR == clientCb.devCtrlCb.rlDeviceEnable ) ||
1916  (RL_NULL_PTR == clientCb.devCtrlCb.rlDeviceMaskHostIrq ))
1917  {
1918  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1919  }
1920  /* When mmWaveLink instance is running on HOST, check for interface for IRQ and delay */
1921  else if (((clientCb.platform == RL_PLATFORM_HOST) &&
1922  (((RL_NULL_PTR == clientCb.devCtrlCb.rlDeviceWaitIrqStatus) &&
1923  (RL_NULL_PTR == clientCb.timerCb.rlDelay)))) ||
1924  (RL_NULL_PTR == clientCb.osiCb.queue.rlOsiSpawn))
1925  {
1926  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1927  }
1928  /* If CRC is enabled from application then check for CRC compute interface function */
1929  else if ((RL_NULL_PTR == clientCb.devCtrlCb.rlDeviceUnMaskHostIrq) ||
1930  (RL_NULL_PTR == clientCb.devCtrlCb.rlRegisterInterruptHandler) ||
1931  ((RL_CRC_TYPE_NO_CRC != clientCb.crcType) &&
1932  (RL_NULL_PTR == clientCb.crcCb.rlComputeCRC)))
1933  {
1934  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
1935  }
1936  else
1937  {
1938  retVal = RL_RET_CODE_OK;
1939  }
1940 
1941  return retVal;
1942 }
1943 
1955 /* DesignId : MMWL_DesignId_003 */
1956 /* Requirements : AUTORADAR_REQ-707 */
1957 rlReturnVal_t rlDriverInit(rlUInt8_t deviceMap, rlClientCbs_t clientCb)
1958 {
1959  rlReturnVal_t retVal, cbCheck;
1960  rlUInt8_t index = 0U;
1961 
1962  /* check for all interface APIs passed by the Application */
1963  cbCheck = rlDriverClientCbCheck(clientCb);
1964 
1965  if (RL_RET_CODE_OK != cbCheck)
1966  {
1967  retVal = cbCheck;
1968  }
1969  /* Initialize Driver Global Data */
1970  else if (deviceMap <= ((1U << RL_DEVICE_CONNECTED_MAX) - 0x1U))
1971  {
1972  /* Initialize Driver Global Data */
1973  for (; index < RL_DEVICE_CONNECTED_MAX; index++)
1974  {
1975  rl_driverData.isCmdRespWaited[index] = RL_FALSE;
1976  rl_driverData.isRespWriteWaited[index] = RL_FALSE;
1977  rl_driverData.rxDoneCnt[index] = 0U;
1978  rl_driverData.rxIrqCnt[index] = 0U;
1979  }
1980  /* Initialize Tx/Rx message pointers */
1981  for (index = 0U; index < RL_CASCADE_NUM_DEVICES; index++)
1982  {
1983  rl_driverData.txMsgPtr[index] = &rl_txMsg[index];
1984  rl_driverData.rxMsgPtr[index] = &rl_rxMsg[index];
1985  }
1986 
1987  /*Copy Client Context Info*/
1988  rl_driverData.clientCtx = clientCb;
1989  /* Store deviceMap */
1990  rl_driverData.deviceMap = deviceMap;
1991  /* Set command retry count */
1992  rl_driverData.retryCount = RL_API_CMD_RETRY_COUNT;
1993 
1994  /* intialize and stitch all OS interfaces */
1995  retVal = rlDriverOsiInit();
1996 
1997 #if !(RL_DISABLE_LOGGING)
1998  if (RL_RET_CODE_OK == retVal)
1999  {
2000  /*All callback copied in global strcuture, Init log parameter */
2001  retVal += rlLogInit();
2002  RL_LOGV_ARG0("Logging is enabled \n");
2003  }
2004 #endif
2005  index = 0U;
2006 
2007  do
2008  {
2009  /* If deviceIndex is set in devceMap requested by application */
2010  if (((deviceMap & (1U << index)) != 0U) && (retVal == RL_RET_CODE_OK))
2011  {
2012  /* reset to zero sequence number for that deviceIndex */
2013  rl_driverData.cmdSeqNum[index] = 0U;
2014  /* store the deviceIndex in a global structure */
2015  rl_driverData.commDevIdx.rlDevIndex[index] = index;
2016  /* Open communication interface handle */
2017  rl_driverData.commDevIdx.comIfHdl[index] =
2018  rl_driverData.clientCtx.comIfCb.rlComIfOpen(index, 0U);
2019 
2020  /* check for NULL pointer */
2021  if ((rlComIfHdl_t)RL_NULL_PTR == rl_driverData.commDevIdx.comIfHdl[index])
2022  {
2023  retVal += RL_RET_CODE_RADAR_IF_ERROR;
2024  }
2025  else
2026  {
2027  /* Register Host Interrupt Handler */
2028  if (rl_driverData.clientCtx.devCtrlCb.rlRegisterInterruptHandler(\
2029  index, (RL_P_EVENT_HANDLER)rlDriverHostIrqHandler, \
2030  (void*)RL_NULL) != RL_RET_CODE_OK)
2031  {
2032  retVal +=RL_RET_CODE_RADAR_IF_ERROR;
2033  }
2034  }
2035  /* Get next Device Map based on index */
2036  deviceMap &= ~(1U << index);
2037 
2038  /* check for any error */
2039  if (retVal != RL_RET_CODE_OK)
2040  {
2041  /* If error occured then break from this loop */
2042  break;
2043  }
2044  }
2045  /* increment Device Index */
2046  index++;
2047  }
2048  while ((deviceMap != 0U) && (index < RL_DEVICE_CONNECTED_MAX));
2049  }
2050  else
2051  {
2052  retVal = RL_RET_CODE_INVALID_INPUT;
2053  RL_LOGE_ARG0("Invaid input argument\n");
2054  }
2055 
2056  /* If no error during deviceInit then set the flag to 1 */
2057  if (retVal == RL_RET_CODE_OK)
2058  {
2059  rl_driverData.isDriverInitialized = 1U;
2060  RL_LOGD_ARG0("Driver init flag is set\n");
2061  }
2062  else
2063  {
2064  RL_LOGE_ARG0("rlDriverInit, Init failed\n");
2065  }
2066  return retVal;
2067 }
2068 
2079 /* DesignId : */
2080 /* Requirements : */
2081 rlReturnVal_t rlDriverAddDevice(rlUInt8_t deviceMap)
2082 {
2083  rlReturnVal_t retVal;
2084  rlUInt8_t index = 0U;
2085 
2086  RL_LOGV_ARG0("rlDriverAddDevice starts\n");
2087 
2088  if ((rl_driverData.isDriverInitialized != (rlUInt8_t)0U) && \
2089  (deviceMap <= ((1U << RL_DEVICE_CONNECTED_MAX) - 0x1U)))
2090  {
2091  /* Add to the global device map */
2092  rl_driverData.deviceMap |= deviceMap;
2093 
2094  do
2095  {
2096  /* If deviceIndex is set in devceMap requested by application */
2097  if ((deviceMap & (1U << index)) != 0U)
2098  {
2099  /* reset to zero sequence number for that deviceIndex */
2100  rl_driverData.cmdSeqNum[index] = 0U;
2101  /* store the deviceIndex in a global structure */
2102  rl_driverData.commDevIdx.rlDevIndex[index] = index;
2103  /* Open communication interface handle */
2104  rl_driverData.commDevIdx.comIfHdl[index] = \
2105  rl_driverData.clientCtx.comIfCb.rlComIfOpen(index, 0U);
2106 
2107  if ((rlComIfHdl_t)RL_NULL_PTR != rl_driverData.commDevIdx.comIfHdl[index])
2108  {
2109  /* register Interrupt handler */
2110  if ((rl_driverData.clientCtx.devCtrlCb.rlRegisterInterruptHandler(\
2111  index, (RL_P_EVENT_HANDLER)rlDriverHostIrqHandler, \
2112  (void*)RL_NULL) != RL_RET_CODE_OK) ||
2113  (rl_driverData.clientCtx.devCtrlCb.rlDeviceEnable(index) < 0))
2114  {
2115  /* set the error code */
2116  retVal = RL_RET_CODE_RADAR_IF_ERROR;
2117  }
2118  else
2119  {
2120  retVal = RL_RET_CODE_OK;
2121  }
2122  }
2123  else
2124  {
2125  retVal =RL_RET_CODE_RADAR_IF_ERROR;
2126  }
2127  deviceMap &= ~(1U << index);
2128  }
2129  else
2130  {
2131  retVal = RL_RET_CODE_OK;
2132  }
2133 
2134  /* break the loop if any error occured during above callbacks */
2135  if (RL_RET_CODE_OK != retVal)
2136  {
2137  break;
2138  }
2139  /* increment device index */
2140  index++;
2141  }
2142  while ((deviceMap != 0U) && (index < RL_DEVICE_CONNECTED_MAX));
2143  }
2144  else
2145  {
2146  if (deviceMap > ((1U << RL_DEVICE_CONNECTED_MAX) - 0x1U))
2147  {
2148  retVal = RL_RET_CODE_INVALID_INPUT;
2149  RL_LOGE_ARG0("Invalid input argument\n");
2150  }
2151  else
2152  {
2153  retVal = RL_RET_CODE_INVALID_STATE_ERROR;
2154  RL_LOGE_ARG0("rlDriverAddDevice, Invalid state \n");
2155  }
2156  }
2157  RL_LOGV_ARG0("rlDriverAddDevice completes\n");
2158 
2159  return retVal;
2160 }
2161 
2172 /* DesignId : */
2173 /* Requirements : */
2174 rlReturnVal_t rlDriverRemoveDevices(rlUInt8_t deviceMap)
2175 {
2176  rlUInt8_t index;
2177  rlReturnVal_t retVal = RL_RET_CODE_OK;
2178 
2179  RL_LOGV_ARG0("rlDriverRemoveDevices starts...\n");
2180 
2181  /* Clear the device map from driver data */
2182  rl_driverData.deviceMap &= ~deviceMap;
2183 
2184  for (index = 0U; ((deviceMap != 0U) && (index < RL_DEVICE_CONNECTED_MAX));\
2185  index++)
2186  {
2187  if ((deviceMap & (1U << index)) != 0U)
2188  {
2189  /* Close mmwave radar device communication Channel */
2190  if (rl_driverData.commDevIdx.comIfHdl[index] != RL_NULL_PTR)
2191  {
2192  retVal += rl_driverData.clientCtx.comIfCb.rlComIfClose( \
2193  rl_driverData.commDevIdx.comIfHdl[index]);
2194  rl_driverData.commDevIdx.comIfHdl[index] = RL_NULL_PTR;
2195  }
2196 
2197  /* Un Register Interrupt Handler */
2198  (void)rl_driverData.clientCtx.devCtrlCb.rlRegisterInterruptHandler(
2199  index, RL_NULL, RL_NULL);
2200 
2201  deviceMap &= ~(1U << index);
2202  }
2203  }
2204  RL_LOGV_ARG0("rlDriverRemoveDevices completes\n");
2205  return retVal;
2206 }
2207 
2217 /* DesignId : */
2218 /* Requirements : AUTORADAR_REQ-711 */
2219 rlReturnVal_t rlDriverDeInit(void)
2220 {
2221  rlUInt8_t index, devCnt;
2222  rlUInt8_t deviceMap = rl_driverData.deviceMap;
2223  rlReturnVal_t retVal = RL_RET_CODE_OK;
2224 
2225  RL_LOGV_ARG0("rlDriverDeInit starts...\n");
2226 
2227  for (index = 0U; ((deviceMap != 0U) && (index < RL_DEVICE_CONNECTED_MAX));\
2228  index++)
2229  {
2230  if ((deviceMap & (1U << index)) != 0U)
2231  {
2232  /* Close mmwave radar device communication Channel */
2233  if (rl_driverData.commDevIdx.comIfHdl[index] != RL_NULL_PTR)
2234  {
2235  retVal += rl_driverData.clientCtx.comIfCb.rlComIfClose( \
2236  rl_driverData.commDevIdx.comIfHdl[index]);
2237  rl_driverData.commDevIdx.comIfHdl[index] = RL_NULL_PTR;
2238  }
2239 
2240  /* Un Register Interrupt Handler */
2241  (void)rl_driverData.clientCtx.devCtrlCb.rlRegisterInterruptHandler(
2242  index, RL_NULL, RL_NULL);
2243 
2244  deviceMap &= ~(1U << index);
2245  }
2246  }
2247  /* Destroy per command mutexes */
2248  for (devCnt = 0U; devCnt < RL_CASCADE_NUM_DEVICES; devCnt++)
2249  {
2250  /* AR_CODE_REVIEW MR:D.4.1 <REVIEWED> "function Pointer is being checked
2251  in rlDriverOsiCbCheck " */
2252  /*LDRA_INSPECTED 128 D */
2253  retVal += rl_driverData.clientCtx.osiCb.mutex.rlOsiMutexDelete(
2254  &rl_driverData.devMutex[devCnt]);
2255  rl_driverData.devMutex[devCnt] = RL_NULL_PTR;
2256 
2257  RL_LOGD_ARG0("Destroy Per CMD Mutex\n");
2258 
2259  /* Destroy Command Semaphore */
2260  if (rl_driverData.cmdSem[devCnt] != RL_NULL_PTR)
2261  {
2262  retVal += rl_driverData.clientCtx.osiCb.sem.rlOsiSemDelete(\
2263  &rl_driverData.cmdSem[devCnt]);
2264  rl_driverData.cmdSem[devCnt] = RL_NULL_PTR;
2265  RL_LOGD_ARG0("Destroy Command Semaphore\n");
2266  }
2267  }
2268 
2269  rl_driverData.deviceMap = 0U;
2270  rl_driverData.isDriverInitialized = 0U;
2271  RL_LOGV_ARG0("rlDriverDeInit ends...\n");
2272 
2273  return retVal;
2274 }
2275 
2284 /* DesignId : */
2285 /* Requirements : */
2287 {
2288  /* return driverData pointer/handle */
2289  return (&rl_driverData);
2290 }
2291 
2300 /* DesignId : */
2301 /* Requirements : */
2302 rlUInt8_t rlDriverGetPlatformId(void)
2303 {
2304  RL_LOGV_ARG0("rlDriverGetPlatformId is called \n");
2305  /* return platform ID */
2306  return (rl_driverData.clientCtx.platform);
2307 }
2308 
2309 
2318 /* DesignId : */
2319 /* Requirements : */
2321 {
2322  RL_LOGV_ARG0("rlDriverGetArDeviceType is called \n");
2323  /* return AWR device Type */
2324  return (rl_driverData.clientCtx.arDevType);
2325 }
2326 
2337 /* DesignId : */
2338 /* Requirements : */
2339 rlReturnVal_t rlDriverIsDeviceMapValid(rlUInt8_t deviceMap)
2340 {
2341  rlUInt8_t storedDevMap;
2342  rlReturnVal_t retVal;
2343 
2344  RL_LOGV_ARG0("rlDriverIsDeviceMapValid starts \n");
2345 
2346  /* get the no. of connected device */
2347  storedDevMap = rl_driverData.deviceMap;
2348 
2349  if ((storedDevMap & deviceMap) != 0U)
2350  {
2351  /* set return value to success */
2352  retVal = 0;
2353  }
2354  else
2355  {
2356  /* set return value to failure */
2357  retVal = -1;
2358  RL_LOGE_ARG0("Device map is In-valid \n");
2359  }
2360  RL_LOGV_ARG0("rlDriverIsDeviceMapValid ends \n");
2361 
2362  return retVal;
2363 }
2364 
2377 /* DesignId : MMWL_DesignId_024 */
2378 /* Requirements : AUTORADAR_REQ-774 */
2379 /*AR_CODE_REVIEW MR:R.2.2 <APPROVED> "payloadLen is re initialized after each pass to the
2380  rlGetSubBlock fucntion as it is passed again to the function" */
2381 /*LDRA_INSPECTED 8 D */
2382 rlReturnVal_t rlDriverWaitForResponse(rlUInt8_t devIndex,
2383  rlDriverMsg_t* outMsg)
2384 {
2385  rlUInt16_t rspChunks;
2386  rlPayloadSb_t errorSB;
2387  rlReturnVal_t retVal, retVal1;
2388  rlUInt16_t indx;
2389  rlUInt8_t payloadLen = 0U;
2390 
2391  RL_LOGV_ARG0("rlDriverWaitForResponse starts... \n");
2392 
2393  do
2394  {
2395  /* Wait for Host Interrupt and Read the Response */
2396  retVal1 = rlDriverMsgReadCmdCtx(devIndex);
2397  if (RL_RET_CODE_OK == retVal1)
2398  {
2399  /* Get number of chunks in the response */
2400  rspChunks = rl_rxMsg[devIndex].hdr.remChunks;
2401 
2402  /* Check if Number of Sub Block doesn't exceed expected number */
2403  if (outMsg->opcode.nsbc >= rl_rxMsg[devIndex].hdr.nsbc)
2404  {
2405  outMsg->opcode.nsbc = rl_rxMsg[devIndex].hdr.nsbc;
2406  /* Loop for number of chunks and copy payload */
2407  for (indx = 0U; indx < (outMsg->opcode.nsbc); indx++)
2408  {
2409  /* Copy Payload to output variable*/
2410  /* AR_CODE_REVIEW MR:R.18.4 <APPROVED> "pointer arithmetic required" */
2411  /*LDRA_INSPECTED 87 S */
2412  (void)rlGetSubBlock(rl_rxMsg[devIndex].payload + payloadLen,
2413  &(outMsg->subblocks[indx].sbid),
2414  &(outMsg->subblocks[indx].len),
2415  outMsg->subblocks[indx].pSblkData);
2416  payloadLen += (rlUInt8_t)(outMsg->subblocks[indx].len);
2417 
2418  }
2419  }
2420  retVal = retVal1;
2421  }
2422  else if (RL_RET_CODE_MSGID_MISMATCHED == retVal1)
2423  {
2424  /* Number of Sub Block is unexpected. Error Case */
2425  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Values are used by called function.
2426  LDRA Tool Issue" */
2427  /*LDRA_INSPECTED 105 D */
2428  rlErrorResp_t errMsgSbData = {(rlSysNRespType_t)0U, (rlUInt16_t)0U};
2429  /* Initialize with zero which will set with valid value in next function call */
2430  errorSB.sbid = 0U;
2431  errorSB.len = 0U;
2432  errorSB.pSblkData = (rlUInt8_t* )&errMsgSbData;
2433 
2434  /* Copy Payload to local variable*/
2435  /* AR_CODE_REVIEW MR:R.18.4 <APPROVED> "pointer arithmetic required" */
2436  /*LDRA_INSPECTED 87 S */
2437  (void)rlGetSubBlock(rl_rxMsg[devIndex].payload + payloadLen,
2438  &(errorSB.sbid), &(errorSB.len),
2439  errorSB.pSblkData);
2440 
2441  /* Return Error to indicate command failure */
2442  retVal = (rlReturnVal_t)(errMsgSbData.errorType);
2443  rspChunks = 0U;
2444 
2445  RL_LOGE_ARG0("msg id mis-match, command failure\n");
2446 
2447  }
2448  else
2449  {
2450  /* Timeout in receiving response*/
2451  rspChunks = 0U;
2452  retVal = retVal1;
2453  RL_LOGE_ARG0("Timeout in receiving response\n");
2454  }
2455  }
2456  while (rspChunks > 0U);
2457 
2458  RL_LOGV_ARG0("rlDriverWaitForResponse ends... \n");
2459 
2460  return retVal;
2461 }
2462 
2463 static rlReturnVal_t rlDriverCmdWriter(rlUInt8_t devIndex, rlDriverMsg_t* outMsg)
2464 {
2465  rlReturnVal_t retVal;
2466  rlUInt8_t retryCount = 0U;
2467  rlDriverData_t *rlDrvData = rlDriverGetHandle();
2468  rlUInt8_t isPayloadValid = RL_FALSE, isNackRetry = RL_FALSE;
2469 
2470  do
2471  {
2472  if ((retryCount != 0U) && (isNackRetry == RL_FALSE))
2473  {
2474  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Global variable is used by
2475  other function" */
2476  /*LDRA_INSPECTED 105 D */
2477  /* AR_CODE_REVIEW MR:D.4.1,D.4.14 <APPROVED> "rlDrvData Can't be NULL" */
2478  /*LDRA_INSPECTED 45 D */
2479  rlDrvData->txMsgPtr[devIndex]->hdr.flags.b2RetryFlag = RL_HDR_FLAG_RETRY;
2480  }
2481  retryCount++;
2482 
2483  if ( rlDrvData->clientCtx.ackTimeout != 0U)
2484  {
2485  /* Set flag to true and check for it in Host IRQ handler routine*/
2486  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Global variable is used by
2487  other function" */
2488  /*LDRA_INSPECTED 105 D */
2489  rlDrvData->isCmdRespWaited[devIndex] = RL_TRUE;
2490  }
2491  /* send the command to mmWave Radar device */
2492  retVal = rlDriverMsgWrite(rlDrvData, devIndex, rlDrvData->commDevIdx.comIfHdl[devIndex]);
2493 
2494  if (RL_RET_CODE_OK == retVal)
2495  {
2496  /* Check if It needs to wait for ACK*/
2497  if (rlDrvData->clientCtx.ackTimeout != 0U)
2498  {
2499  /* wait for respond */
2500  retVal += rlDriverWaitForResponse(devIndex, outMsg);
2501  RL_LOGD_ARG0("rlDriverCmdWriter, wait for respond\n");
2502  }
2503 
2504  /* Response received Successfully */
2505  if ((RL_RET_CODE_OK == retVal) || \
2506  ((RL_RET_CODE_CRC_FAILED != retVal) && \
2507  (RL_RET_CODE_RESP_TIMEOUT != retVal)))
2508  {
2509  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Global variable is used by
2510  other function" */
2511  /*LDRA_INSPECTED 105 D */
2512  rlDrvData->isCmdRespWaited[devIndex] = RL_FALSE;
2513  /* Increment the Sequence Number */
2514  rlDrvData->cmdSeqNum[devIndex]++;
2515  /* If device sends NACK then mmWaveLink needs to resend same
2516  command with incremented seqNum but no RETRY-Flag */
2517  if (RL_RET_CODE_NACK_ERROR == retVal)
2518  {
2519  /* Set the flag */
2520  isNackRetry = RL_TRUE;
2521  /* Modulo on cmdSeqNum (4Bits field) and fill Command Sequence Number */
2522  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Global variable is used
2523  by other function" */
2524  /*LDRA_INSPECTED 105 D */
2525  /*LDRA_INSPECTED 8 D */
2526  rlDrvData->txMsgPtr[devIndex]->hdr.flags.b4SeqNum =
2527  rlDrvData->cmdSeqNum[devIndex] % 16U;
2528  }
2529  else
2530  {
2531  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Set to TRUE for valid payload" */
2532  /*LDRA_INSPECTED 8 D */
2533  isPayloadValid = RL_TRUE;
2534  /* Reset the flag */
2535  isNackRetry = RL_FALSE;
2536  }
2537  }
2538  else
2539  {
2540  /* if return value is not NACK_ERROR then reset this flag */
2541  isNackRetry = RL_FALSE;
2542  }
2543  }
2544  else
2545  {
2546  /* Error in command message write */
2547  if (rlDrvData->clientCtx.ackTimeout != 0U)
2548  {
2549  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Global variable is used by
2550  other function" */
2551  /*LDRA_INSPECTED 105 D */
2552  rlDrvData->isCmdRespWaited[devIndex] = RL_FALSE;
2553  }
2554  RL_LOGE_ARG0("rlDriverCmdWriter, Error in cmd msg write\n");
2555  break;
2556  }
2557  }
2558  while ((retryCount < (rl_driverData.retryCount + 1U)) && (isPayloadValid == RL_FALSE));
2559 
2560  return retVal;
2561 }
2562 
2574 /* DesignId : MMWL_DesignId_023 */
2575 /* Requirements : AUTORADAR_REQ-772, AUTORADAR_REQ-774, AUTORADAR_REQ-775, AUTORADAR_REQ-778,\
2576  AUTORADAR_REQ-781 */
2577 rlReturnVal_t rlDriverCmdSendRetry(rlUInt8_t devIndex, rlDriverMsg_t* outMsg)
2578 {
2579  rlReturnVal_t retVal;
2580  rlDriverData_t *rlDrvData = rlDriverGetHandle();
2581 
2582  if ((rlDrvData == RL_NULL))
2583  {
2584  retVal = RL_RET_CODE_FATAL_ERROR;
2585  }
2586  else
2587  {
2588  retVal = RL_RET_CODE_OK;
2589  }
2590 
2591  /* Send Command to Device connected and wait for response one by one */
2592  /* AR_CODE_REVIEW MR:D.2.1 <APPROVED> "This loop terminates when it sends commands to all
2593  * connected devices or when any of devices returns -ve response" */
2594  /*LDRA_INSPECTED 28 D */
2595  /* Fill Command Sequence Number */
2596  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Global variable is used by other function" */
2597  /*LDRA_INSPECTED 105 D */
2598  /*LDRA_INSPECTED 8 D */
2599  rlDrvData->txMsgPtr[devIndex]->hdr.flags.b4SeqNum =
2600  rlDrvData->cmdSeqNum[devIndex] % 16U;
2601 
2602  /* Write command to slave device */
2603  retVal += rlDriverCmdWriter(devIndex, outMsg);
2604 
2605  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Global variable is used by other function" */
2606  /*LDRA_INSPECTED 105 D */
2607  rlDrvData->isCmdRespWaited[devIndex] = RL_FALSE;
2608 
2609  return retVal;
2610 }
2611 
2622 /* DesignId : MMWL_DesignId_023 */
2623 /* Requirements : AUTORADAR_REQ-772, AUTORADAR_REQ-774, AUTORADAR_REQ-776 */
2624 static void rlDriverAppendDummyByte(rlUInt8_t devIndex)
2625 {
2626  rlUInt8_t protAlignSize;
2627  rlUInt16_t msgCrcLen;
2628 
2629  rl_txMsg[devIndex].hdr.flags.b2CrcLen = rl_driverData.clientCtx.crcType;
2630 
2631  /* It may be size 2/4/8 based on 16/32/64 bit */
2632  msgCrcLen = (2U << (rl_driverData.clientCtx.crcType & 0x3U));
2633 
2634  protAlignSize = (rl_driverData.clientCtx.crcType < RL_CRC_TYPE_64BIT_ISO) ? \
2635  RL_PAYLOAD_MSG_4BYTE_MULT : RL_PAYLOAD_MSG_8BYTE_MULT;
2636 
2637  /* cmd pointer is assigned to rl_rxMsg, which can't be NULL as it's global structure. */
2638  if (rl_driverData.txMsgPtr[devIndex] != RL_NULL_PTR)
2639  {
2640  /* Add Padding Byte to payload - This is required before CRC calculation*/
2641  if ((rl_driverData.txMsgPtr[devIndex]->hdr.len % protAlignSize) != 0U)
2642  {
2643  /* AR_CODE_REVIEW MR:R.18.1,R.18.4 <APPROVED> "pointer arithmetic required" */
2644  /*LDRA_INSPECTED 567 S */
2645  /* AR_CODE_REVIEW MR:R.10.3 <APPROVED> "All parameter types are matching to
2646  function argument type. LDRA tool issue." */
2647  /*LDRA_INSPECTED 458 S */
2648  /*LDRA_INSPECTED 87 S */
2649  /* AR_CODE_REVIEW MR:R.11.1 <INSPECTED> "Conversion required." */
2650  /*LDRA_INSPECTED 95 S */
2651  /*LDRA_INSPECTED 440 S */
2652  /*LDRA_INSPECTED 93 S */
2653  (void)rlAppendDummy((rlUInt8_t*)(((rlUInt8_t*)rl_driverData.txMsgPtr[devIndex]) + \
2654  rl_driverData.txMsgPtr[devIndex]->hdr.len + SYNC_PATTERN_LEN), \
2655  (rlUInt8_t)(protAlignSize - \
2656  (rlUInt8_t)(rl_driverData.txMsgPtr[devIndex]->hdr.len % protAlignSize)));
2657  rl_driverData.txMsgPtr[devIndex]->hdr.len += (rlUInt16_t)(protAlignSize - \
2658  (rlUInt16_t)(rl_driverData.txMsgPtr[devIndex]->hdr.len % protAlignSize));
2659  }
2660  /* add on crc length to header length field */
2661  rl_driverData.txMsgPtr[devIndex]->hdr.len += msgCrcLen;
2662  }
2663  return;
2664 }
2665 
2682 /* DesignId : MMWL_DesignId_023 */
2683 /* Requirements : AUTORADAR_REQ-772, AUTORADAR_REQ-774, AUTORADAR_REQ-776 */
2684 rlReturnVal_t rlDriverCmdInvoke(rlUInt8_t deviceMap, rlDriverMsg_t inMsg,
2685  rlDriverMsg_t* outMsg)
2686 {
2687  rlReturnVal_t retVal = RL_RET_CODE_OK;
2688  rlUInt8_t devIndex = 0U;
2689  rlUInt16_t indx;
2690  rlUInt16_t payloadLen;
2691 
2692  RL_LOGV_ARG0("rlDriverCmdInvoke starts... \n");
2693 
2694  if (rl_driverData.isDriverInitialized != (rlUInt8_t)0U)
2695  {
2696  /* AR_CODE_REVIEW MR:R.2.1 <APPROVED> "This loop terminates when it sends commands to all
2697  * connected devices or when any of devices returns -ve response" */
2698  /*LDRA_INSPECTED 28 D */
2699  while ((deviceMap != 0U) && (RL_RET_CODE_OK == retVal))
2700  {
2701  if ((deviceMap & (1U << devIndex)) != 0U)
2702  {
2703  /* If Mutex lock is failed then return with error code */
2704  if (RL_RET_CODE_OK != rl_driverData.clientCtx.osiCb.mutex.rlOsiMutexLock
2705  (&(rl_driverData.devMutex[devIndex]), (rlOsiTime_t)RL_OSI_WAIT_FOREVER))
2706  {
2707  /* If MutexLock returns non-zero then treat this as error and
2708  set error code to retVal */
2709  retVal = RL_RET_CODE_RADAR_OSIF_ERROR;
2710  }
2711  else
2712  {
2713  rlReturnVal_t retVal1 = RL_RET_CODE_OK;
2714 
2715  payloadLen = 0U;
2716  /* Fill Command Header */
2717  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Some of variables are re-assigned based
2718  on different conditions."*/
2719  /*LDRA_INSPECTED 8 D */
2720  rl_txMsg[devIndex].hdr.opcode.b4Direction = inMsg.opcode.dir;
2721  rl_txMsg[devIndex].hdr.opcode.b2MsgType = inMsg.opcode.msgType;
2722  rl_txMsg[devIndex].hdr.opcode.b10MsgId = \
2723  ((rl_txMsg[devIndex].hdr.opcode.b10MsgId & 0x000U)|\
2724  (inMsg.opcode.msgId & 0x3FFU));
2725  rl_txMsg[devIndex].hdr.remChunks = inMsg.remChunks;
2726  rl_txMsg[devIndex].hdr.nsbc = inMsg.opcode.nsbc;
2727  rl_txMsg[devIndex].hdr.flags.b2AckFlag = 0U;
2728  rl_txMsg[devIndex].hdr.flags.b2Crc = 0U;
2729  rl_txMsg[devIndex].hdr.flags.b2CrcLen = 0U;
2730  rl_txMsg[devIndex].hdr.flags.b2RetryFlag = 0U;
2731  rl_txMsg[devIndex].hdr.flags.b4SeqNum = 0U;
2732  rl_txMsg[devIndex].hdr.flags.b4Version = 0U;
2733 
2734  /* Fill Payload */
2735  for (indx = 0U; indx < inMsg.opcode.nsbc; indx++)
2736  {
2737  /* append all subblock len, id and data to one global structure */
2738  retVal1 += rlAppendSubBlock(&rl_txMsg[devIndex].payload[payloadLen],
2739  inMsg.subblocks[indx].sbid,
2740  inMsg.subblocks[indx].len,
2741  inMsg.subblocks[indx].pSblkData);
2742  /* increment payload length as appending each sub-block data in a
2743  message */
2744  payloadLen += inMsg.subblocks[indx].len + \
2745  (rlUInt16_t)(RL_SBC_ID_SIZE + RL_SBC_LEN_SIZE);
2746  if (RL_RET_CODE_OK != retVal1)
2747  {
2748  break;
2749  }
2750  }
2751 
2752  /* if above for loop is not terminated due to any error */
2753  if (indx == inMsg.opcode.nsbc)
2754  {
2755  rl_txMsg[devIndex].hdr.len = RHCP_HEADER_LEN + payloadLen;
2756 
2757  /* Check if ACK is Requested*/
2758  if (rl_driverData.clientCtx.ackTimeout == 0U)
2759  {
2760  /* No ACK Requested */
2761  rl_txMsg[devIndex].hdr.flags.b2AckFlag = RL_HDR_FLAG_NO_ACK;
2762  }
2763 
2764  /* Check if CRC is required to be sent*/
2765  if (rl_driverData.clientCtx.crcType == RL_CRC_TYPE_NO_CRC)
2766  {
2767  /* CRC Not Included */
2768  rl_txMsg[devIndex].hdr.flags.b2Crc = RL_HDR_FLAG_NO_CRC;
2769  }
2770 
2771  /* Append Dummy Bytes if CRC is present */
2772  if (rl_txMsg[devIndex].hdr.flags.b2Crc == RL_HDR_FLAG_CRC)
2773  {
2774  rlDriverAppendDummyByte(devIndex);
2775  }
2776 
2777  retVal = rlDriverCmdSendRetry(devIndex, outMsg);
2778  /* Release the per CMD Mutex */
2779  (void)rl_driverData.clientCtx.osiCb.mutex.rlOsiMutexUnLock(\
2780  &(rl_driverData.devMutex[devIndex]));
2781  }
2782  else
2783  {
2784  retVal = retVal1;
2785  }
2786  }
2787  deviceMap &= ~(1U << devIndex);
2788  } /* End if */
2789  devIndex++;
2790  } /* End while */
2791  }
2792  else
2793  {
2794  retVal = RL_RET_CODE_INVALID_STATE_ERROR;
2795  RL_LOGE_ARG0("rlDriverCmdInvoke, Invalid input \n");
2796  }
2797 
2798  RL_LOGV_ARG0("rlDriverCmdInvoke ends... \n");
2799 
2800  return retVal;
2801 }
2802 
2812 rlReturnVal_t rlDriverConfigureCrc(rlCrcType_t crcType)
2813 {
2814  rlReturnVal_t retVal;
2815 
2816  RL_LOGV_ARG0("rlDriverConfigureCrc starts... \n");
2817  /* Check if driver is initialized */
2818  if (rl_driverData.isDriverInitialized == 1U)
2819  {
2820  /* Set CRC Type to global structure */
2821  rl_driverData.clientCtx.crcType = crcType;
2822  RL_LOGD_ARG0("rlDriverConfigureCrc is success\n");
2823  retVal = RL_RET_CODE_OK;
2824  }
2825  else
2826  {
2827  /* if driver is not initialized then return and error value */
2828  retVal = RL_RET_CODE_INVALID_STATE_ERROR;
2829  }
2830  RL_LOGV_ARG0("rlDriverConfigureCrc ends... \n");
2831 
2832  return retVal;
2833 }
2834 
2844 /* DesignId : */
2845 /* Requirements : */
2846 rlReturnVal_t rlDriverConfigureAckTimeout(rlUInt32_t ackTimeout)
2847 {
2848  rlReturnVal_t retVal;
2849 
2850  RL_LOGV_ARG0("rlDriverConfigureAckTimeout starts... \n");
2851  /* Check if driver is initialized */
2852  if (rl_driverData.isDriverInitialized == 1U)
2853  {
2854  /* set ACK timeout to global structure */
2855  rl_driverData.clientCtx.ackTimeout = ackTimeout;
2856  RL_LOGD_ARG0("rlDriverConfigureAckTimeout is success\n");
2857  retVal = RL_RET_CODE_OK;
2858  }
2859  else
2860  {
2861  /* if driver is not initialized then return and error value */
2862  retVal = RL_RET_CODE_INVALID_STATE_ERROR;
2863  }
2864  RL_LOGV_ARG0("rlDriverConfigureAckTimeout ends... \n");
2865 
2866  return retVal;
2867 }
2868 
2879 /* DesignId : */
2880 /* Requirements : */
2881 rlPrintFptr rlGetLogFptr(rlUInt8_t dbgLevel)
2882 {
2883  rlPrintFptr retFuncPtr;
2884  if (dbgLevel > 0U)
2885  {
2886  /* If debug level is valid the set debug function pointer */
2887  retFuncPtr = rl_driverData.logObj.rlPrintAr[dbgLevel - (rlUInt8_t)1U];
2888  }
2889  else
2890  {
2891  /* If debug level is valid the set debug function pointer to NULL */
2892  retFuncPtr = RL_NULL_PTR;
2893  }
2894 
2895  return retFuncPtr;
2896 }
2897 
2907 /* DesignId : MMWL_DesignId_031 */
2908 /* Requirements : AUTORADAR_REQ-712 */
2909 rlReturnVal_t rlLogInit(void)
2910 {
2911  rlReturnVal_t retVal;
2912  rlDriverData_t* rlDrvData = &rl_driverData;
2913  rlPrintFptr fPtr;
2914  rlUInt8_t level, idx;
2915  /* store debug level to local variable */
2916  level = rlDrvData->clientCtx.dbgCb.dbgLevel;
2917  /* store Function pointer to local variable */
2918  fPtr = rlDrvData->clientCtx.dbgCb.rlPrint;
2919 
2920  /* check for Function pointer for NON-NULL */
2921  if (fPtr != RL_NULL_PTR)
2922  {
2923  switch (level)
2924  {
2925  case RL_DBG_LEVEL_VERBOSE :
2926  case RL_DBG_LEVEL_DEBUG :
2927  case RL_DBG_LEVEL_INFO :
2928  case RL_DBG_LEVEL_WARNING :
2929  case RL_DBG_LEVEL_ERROR :
2930  for (idx = level; idx > RL_DBG_LEVEL_NONE; idx--)
2931  {
2932  rlDrvData->logObj.rlPrintAr[idx - 1U] = fPtr;
2933  }
2934  break;
2935  case RL_DBG_LEVEL_NONE :
2936  {
2937  (void)fPtr("INFO: MMWAVELINK Logging is disabled\n");
2938  /* reset all function pointers to NULL */
2939  (void)memset(&rlDrvData->logObj.rlPrintAr[0], 0U, sizeof(rlLogCtx_t));
2940  break;
2941  }
2942  default :
2943  {
2944  (void)fPtr("INFO: Invalid MMWAVELINK Logging, hence disbled\n");
2945  /* if dbgLevel is set beyond expected value then assign NONE */
2946  rlDrvData->clientCtx.dbgCb.dbgLevel = RL_DBG_LEVEL_NONE;
2947 
2948  /* reset all function pointers to NULL */
2949  (void)memset(&rlDrvData->logObj.rlPrintAr[0], 0U, sizeof(rlLogCtx_t));
2950  break;
2951  }
2952  }
2953  retVal = RL_RET_CODE_OK;
2954  }
2955  else
2956  {
2957  /* reset all function pointers to NULL */
2958  (void)memset(&rlDrvData->logObj.rlPrintAr[0], 0U, sizeof(rlLogCtx_t));
2959  retVal = RL_RET_CODE_INTERFACE_CB_NULL;
2960  }
2961 
2962  return retVal;
2963 }
2964 
2977 void rlDriverConstructInMsg(rlUInt16_t msgId, rlDriverMsg_t* inMsg, rlPayloadSb_t* payloadPtr)
2978 {
2979  /* check for NULL pointer */
2980  if (inMsg != NULL)
2981  {
2982  rlUInt8_t cmdDir;
2983  /* Set Command Header Opcode */
2984  inMsg->opcode.nsbc = 1U;
2985  inMsg->opcode.msgType = RL_API_CLASS_CMD;
2986  inMsg->opcode.msgId = msgId;
2987  inMsg->remChunks = 0U;
2988  /* get command direction based on requested MsgId */
2989  cmdDir = rlDeviceIdentifyCmdDir(msgId, rlDriverGetPlatformId());
2990  inMsg->opcode.dir = cmdDir;
2991  inMsg->subblocks = payloadPtr;
2992  }
2993  else
2994  {
2995  /* Error: iutMsg is sent as NULL */
2996  RL_LOGV_ARG0("rlDriverConstructInMsg construct InMsg failed!!!\n");
2997  }
2998 }
2999 
3012 void rlDriverConstructOutMsg(rlUInt16_t numSblk, rlDriverMsg_t* outMsg,
3013  rlPayloadSb_t* payloadPtr)
3014 {
3015  /* check for NULL pointer */
3016  if (outMsg != NULL)
3017  {
3018  /* Set num of sub-block to outMsg Opcode field */
3019  outMsg->opcode.nsbc = numSblk;
3020  /* assign payload pointer to subblock ot outMsg */
3021  outMsg->subblocks = payloadPtr;
3022  }
3023  else
3024  {
3025  /* Error: outMsg is sent as NULL */
3026  RL_LOGV_ARG0("rlDriverConstructOutMsg construct OutMsg failed!!!\n");
3027  }
3028 }
3029 
3043 void rlDriverFillPayload(rlUInt16_t msgId, rlUInt16_t sbcID, rlPayloadSb_t* payloadPtr,
3044  rlUInt8_t* data, rlUInt16_t inLen)
3045 {
3046  /* check for NULL pointer */
3047  if (payloadPtr != NULL)
3048  {
3049  /* get Unique Sub-Block ID and asign it to Command Sub Block */
3050  payloadPtr->sbid = (rlUInt16_t)RL_GET_UNIQUE_SBID(msgId, sbcID);
3051 
3052  /* set Command Sub-block length to sizeof command strcuture type */
3053  payloadPtr->len = inLen;
3054  /* set sub-block data pointer to payload structure */
3055  payloadPtr->pSblkData = data;
3056  }
3057  else
3058  {
3059  RL_LOGV_ARG0("rlDriverFillPayload data fill failed!!!\n");
3060  }
3061 }
3062 
3076 rlReturnVal_t rlDriverExecuteGetApi(rlUInt8_t deviceMap, rlUInt16_t msgId,
3077  rlUInt16_t sbcID, rlUInt8_t *msgData, rlUInt16_t inLen)
3078 {
3079  /*LDRA waiver 8 D - DD data flow anomalies found- */
3080  rlReturnVal_t retVal;
3081  /* Initialize Command and Response Sub Blocks */
3082  /* Initialize in-message structure to zero */
3083  rlDriverMsg_t inMsg = {0};
3084  /* Initialize out-message structure to zero */
3085  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Values are used by called function. LDRA Tool Issue" */
3086  /*LDRA_INSPECTED 105 D */
3087  rlDriverMsg_t outMsg = {0};
3088  /* Initialize in-payload sub-block structure to zero */
3089  rlPayloadSb_t inPayloadSb = {0};
3090  /* Initialize out-payload sub-block structure to zero */
3091  rlPayloadSb_t outPayloadSb = {0};
3092 
3093  /* Construct command packet */
3094  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Values are used by called function. LDRA Tool Issue" */
3095  /*LDRA_INSPECTED 8 D */
3096  rlDriverConstructInMsg(msgId, &inMsg, &inPayloadSb);
3097 
3098  /* Fill in-message Payload */
3099  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Values are used by called function. LDRA Tool Issue" */
3100  /*LDRA_INSPECTED 105 D */
3101  rlDriverFillPayload(msgId, sbcID, &inPayloadSb, NULL , 0U);
3102 
3103  /* Construct response packet */
3104  rlDriverConstructOutMsg(1U, &outMsg, &outPayloadSb);
3105 
3106  /* Fill out-message Payload */
3107  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Values are used by called function. LDRA Tool Issue" */
3108  /*LDRA_INSPECTED 105 D */
3109  rlDriverFillPayload(0U, 0U, &outPayloadSb, msgData, inLen);
3110 
3111  /* Send Command to mmWave Radar Device */
3112  /* AR_CODE_REVIEW MR:D.4.1,D.4.14 <APPROVED> "Can't be NULL" */
3113  /*LDRA_INSPECTED 45 D */
3114  retVal = rlDriverCmdInvoke(deviceMap, inMsg, &outMsg);
3115 
3116  return retVal;
3117 }
3118 
3132 rlReturnVal_t rlDriverExecuteSetApi(rlUInt8_t deviceMap, rlUInt16_t msgId,
3133  rlUInt16_t sbcID, rlUInt8_t *msgData, rlUInt16_t inLen)
3134 {
3135  /*LDRA waiver 8 D - DD data flow anomalies found- */
3136  rlReturnVal_t retVal;
3137  /* Initialize in-message structure to zero */
3138  rlDriverMsg_t inMsg = {0};
3139  /* Initialize out-message structure to zero */
3140  rlDriverMsg_t outMsg = {0};
3141  /* Initialize in-payload sub-block structure to zero */
3142  rlPayloadSb_t inPayloadSb = {0};
3143 
3144  /* Construct command packet */
3145  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Values are updated in other function.
3146  LDRA Tool Issue" */
3147  /*LDRA_INSPECTED 8 D */
3148  rlDriverConstructInMsg(msgId, &inMsg, &inPayloadSb);
3149 
3150  /* Fill in-message Payload */
3151  /* AR_CODE_REVIEW MR:R.2.2 <APPROVED> "Values are used by called function.
3152  LDRA Tool Issue" */
3153  /*LDRA_INSPECTED 105 D */
3154  rlDriverFillPayload(msgId, sbcID, &inPayloadSb, msgData, inLen);
3155 
3156  /* Send Command to mmWave Radar Device */
3157  /* AR_CODE_REVIEW MR:D.4.1,D.4.14 <APPROVED> "Can't be NULL" */
3158  /*LDRA_INSPECTED 45 D */
3159  retVal = rlDriverCmdInvoke(deviceMap, inMsg, &outMsg);
3160 
3161  return retVal;
3162 }
3163 
3174 rlReturnVal_t rlDriverSetRetryCount(rlUInt8_t retryCnt)
3175 {
3176  rlReturnVal_t retVal;
3177 
3178  RL_LOGV_ARG0("rlDriverSetRetryCount starts... \n");
3179  /* Check if driver is initialized */
3180  if (rl_driverData.isDriverInitialized == 1U)
3181  {
3182  if (retryCnt <= RL_API_CMD_RETRY_COUNT)
3183  {
3184  /* set command retry count to global structure */
3185  rl_driverData.retryCount = retryCnt;
3186  RL_LOGD_ARG0("rlDriverSetRetryCount is success\n");
3187  retVal = RL_RET_CODE_OK;
3188  }
3189  else
3190  {
3191  /* Retry count can be set to max pre-defined value,
3192  * else return an error
3193  */
3194  retVal = RL_RET_CODE_INVALID_INPUT;
3195  }
3196  }
3197  else
3198  {
3199  /* if driver is not initialized then return and error value */
3200  retVal = RL_RET_CODE_INVALID_STATE_ERROR;
3201  }
3202  RL_LOGV_ARG0("rlDriverSetRetryCount ends... \n");
3203 
3204  return retVal;
3205 }
3206 
3207 /*
3208  * END OF rl_driver.c FILE
3209  */
rlReturnVal_t rlDriverMsgWrite(rlDriverData_t *rlDrvData, rlUInt8_t devIndex, rlComIfHdl_t comIfHdl)
Write command header and payload data over communication channel.
Definition: rl_driver.c:1448
rlReturnVal_t rlDriverMsgReadCmdCtx(rlUInt8_t devIndex)
Wait and handle command response.
Definition: rl_driver.c:979
rlUInt16_t b2MsgType
Msg Type.
Definition: rl_protocol.h:108
rlUInt16_t b2Crc
00 - CRC present, 11 - CRC not Present
Definition: rl_protocol.h:157
rlOsiCbs_t osiCb
Operating System Callback.
Definition: mmwavelink.h:1482
mmWaveLink client callback structure
Definition: mmwavelink.h:1473
volatile rlUInt8_t isCmdRespWaited[RL_DEVICE_CONNECTED_MAX]
Driver Command Wait Flag.
Definition: rl_driver.h:252
rlUInt8_t dir
Message Direction.
Definition: rl_driver.h:331
rlRhcpMsg_t * txMsgPtr[RL_CASCADE_NUM_DEVICES]
Tx message buffer pointer.
Definition: rl_driver.h:301
rlInt32_t(* rlDeviceEnable)(rlUInt8_t deviceIndex)
Bring mmWave radar device out of Reset.
Definition: mmwavelink.h:1348
rlReturnVal_t rlDriverMsgCmdReply(rlDriverData_t *rlDrvData, rlUInt8_t devIndex)
Wait and handle command response.
Definition: rl_driver.c:845
rlUInt8_t rlDeviceIdentifyCmdDir(rlUInt16_t msgId, rlUInt8_t platform)
Get the direction of command packet based on MsgID and platform.
Definition: rl_driver.c:412
rlReturnVal_t rlDriverConfigureCrc(rlCrcType_t crcType)
Configures the CRC Type in mmwavelink Driver.
Definition: rl_driver.c:2812
rlUInt8_t platform
0x0: mmWaveLink runs on Ext Host, 0x1: mmWaveLink runs on MSS, 0x2: mmWaveLink runs on DSS
Definition: mmwavelink.h:1519
rlOpcode_t opcode
rlUInt16_t, rlApiActionType,rlApiGetSetType
Definition: rl_protocol.h:214
volatile rlUInt8_t rxIrqCnt[RL_DEVICE_CONNECTED_MAX]
Driver Host Interrupt count.
Definition: rl_driver.h:260
rlUInt8_t msgType
Message Class.
Definition: rl_driver.h:335
void rlDriverConstructOutMsg(rlUInt16_t numSblk, rlDriverMsg_t *outMsg, rlPayloadSb_t *payloadPtr)
: Construct command packet based on given message-ID and payload
Definition: rl_driver.c:3012
rlUInt8_t rlDevIndex[RL_DEVICE_CONNECTED_MAX]
stores device Index
Definition: rl_driver.h:221
rlUInt32_t ackTimeout
ACK wait timeout in Milliseconds, 0 - No ACK Configuration of the timeout should consider interrupt l...
Definition: mmwavelink.h:1513
rlUInt16_t msgId
Message Id.
Definition: rl_driver.h:339
rlUInt16_t cmdSeqNum[RL_DEVICE_CONNECTED_MAX]
Driver command sequnce number.
Definition: rl_driver.h:268
rlOsiMsgQCbs_t queue
OS message queue/Spawn callback functions.
Definition: mmwavelink.h:1259
rlUInt8_t rlDriverGetPlatformId(void)
Returns RL Platform ID (i.e. where mmWaveLink is executing)
Definition: rl_driver.c:2302
volatile rlUInt8_t rxDoneCnt[RL_DEVICE_CONNECTED_MAX]
Driver serviced Host Interrupt count.
Definition: rl_driver.h:264
rlUInt16_t b2CrcLen
Length of CRC appended to the message 00 16-bit CRC 01 32-bit CRC 10 64-bit CRC 11 Reserved.
Definition: rl_protocol.h:165
rlLogCtx_t logObj
As per debug level callback functions will be assinged.
Definition: rl_driver.h:292
rlUInt8_t isRespWriteWaited[RL_DEVICE_CONNECTED_MAX]
if writing a data waits for Host IRQ
Definition: rl_driver.h:256
rlReturnVal_t rlDriverCalCRC(rlUInt8_t *data, rlUInt16_t dataLen, rlUInt8_t crcType, rlUInt8_t crc[RL_CRC_LEN_MAX])
Calculates 16bit/32bit/64bit CRC.
Definition: rl_driver.c:209
rlComIfCbs_t comIfCb
Comunication Interface Callback.
Definition: mmwavelink.h:1478
rlOsiSemCbs_t sem
Semaphore callback functions.
Definition: mmwavelink.h:1255
rlRhcpMsg_t * rxMsgPtr[RL_CASCADE_NUM_DEVICES]
Rx message buffer pointer.
Definition: rl_driver.h:305
rlReturnVal_t rlDriverValidateHdr(rlProtHeader_t protHdr)
Validates the header by comparing Checksum.
Definition: rl_driver.c:366
rlOsiMutexCbs_t mutex
Mutex callback functions.
Definition: mmwavelink.h:1251
rlDbgCb_t dbgCb
Debug Callback, required to receive Debug information.
Definition: mmwavelink.h:1528
rlUInt16_t b4SeqNum
Sequence Number.
Definition: rl_protocol.h:169
rlUInt8_t arDevType
xWR1243/AWR2243 + HOST = 0x0, xWR1443 MSS = 0x1, xWR1642 MSS/DSS = 0x2, xWR1843 MSS/DSS = 0x3,...
Definition: mmwavelink.h:1524
rlUInt16_t b2AckFlag
00- ACK requested, 11 - No ACK Requested
Definition: rl_protocol.h:149
rlInt32_t(* rlComIfRead)(rlComIfHdl_t fd, rlUInt8_t *pBuff, rlUInt16_t len)
Read Data from Communication interface.
Definition: mmwavelink.h:1053
rlOsiSemHdl_t cmdSem[RL_CASCADE_NUM_DEVICES]
Driver Command Wait Semaphore.
Definition: rl_driver.h:280
void rlDriverConstructInMsg(rlUInt16_t msgId, rlDriverMsg_t *inMsg, rlPayloadSb_t *payloadPtr)
: Construct command packet (inMsg) based on given message-ID and payload
Definition: rl_driver.c:2977
mmwave radar Driver Global Structure
Definition: rl_driver.h:235
rlReturnVal_t rlDriverCmdSendRetry(rlUInt8_t devIndex, rlDriverMsg_t *outMsg)
: Send command and wait for response
Definition: rl_driver.c:2577
rlComIfHdl_t comIfHdl[RL_DEVICE_CONNECTED_MAX]
Communication Interface Handles.
Definition: rl_driver.h:217
rlUInt8_t isDriverInitialized
Driver Status.
Definition: rl_driver.h:244
rlReturnVal_t rlDriverMsgRead(rlDriverData_t *rlDrvData, rlUInt8_t devIndex)
Receive and validate protocol header and payload.
Definition: rl_driver.c:1280
rlUInt16_t nsbc
Number of Sub Blocks in Payload.
Definition: rl_driver.h:343
rlInt32_t(* rlComIfClose)(rlComIfHdl_t fd)
Close the Communication interface.
Definition: mmwavelink.h:1081
mmwave Logging functions
Definition: rl_driver.h:227
rlUInt16_t b4Direction
Direction.
Definition: rl_protocol.h:104
rlEventCbs_t eventCb
Event Callback, required to receive notification.
Definition: mmwavelink.h:1486
rlComIfHdl_t(* rlComIfOpen)(rlUInt8_t deviceIndex, rlUInt32_t flags)
Open Communication interface.
Definition: mmwavelink.h:1038
rlReturnVal_t rlDriverExecuteGetApi(rlUInt8_t deviceMap, rlUInt16_t msgId, rlUInt16_t sbcID, rlUInt8_t *msgData, rlUInt16_t inLen)
: Construct get message and invoke command.
Definition: rl_driver.c:3076
rlUInt8_t dbgLevel
User needs to set debug level such as error, warning, debug, verbose.
Definition: mmwavelink.h:1467
rlReturnVal_t rlDriverSetRetryCount(rlUInt8_t retryCnt)
: Set the retry count for re-sending command
Definition: rl_driver.c:3174
rlReturnVal_t rlDriverRxHdrRead(rlUInt8_t hdrBuf[RHCP_HEADER_LEN], rlComIfHdl_t comIfHdl)
Read SYNC and Header from communication channel.
Definition: rl_driver.c:1672
rlUInt8_t rlDriverGetArDeviceType(void)
Returns AR device type which mmWavelink is communicating.
Definition: rl_driver.c:2320
mmwave radar Driver Protocol header read buffer
Definition: rl_driver.h:317
rlOsiMutexHdl_t devMutex[RL_CASCADE_NUM_DEVICES]
Driver Global Lock Mutex.
Definition: rl_driver.h:276
rlReturnVal_t rlDriverDeInit(void)
De Initializes the mmwave radar Driver.
Definition: rl_driver.c:2219
void(* rlDeviceMaskHostIrq)(rlComIfHdl_t fd)
Masks Host Interrupt.
Definition: mmwavelink.h:1374
rlDriverData_t * rlDriverGetHandle(void)
Returns mmwave radar Driver Global Structure.
Definition: rl_driver.c:2286
void rlDriverHostIrqHandler(rlUInt8_t deviceIndex, void *pValue)
Interrupt Service Routine to handle host interrupt from mmwave radar device.
Definition: rl_driver.c:565
rlReturnVal_t rlDriverAsyncEventHandler(rlUInt8_t devIndex, rlUInt16_t nsbc, rlUInt8_t *payload, rlUInt16_t payloadLen)
Handles asynchronous response/error from mmwave radar device.
Definition: rl_driver.c:500
RHCP Payload Structure.
Definition: rl_driver.h:155
rlReturnVal_t rlDriverCmdInvoke(rlUInt8_t deviceMap, rlDriverMsg_t inMsg, rlDriverMsg_t *outMsg)
Invokes a command to mmwave radar Device. Implements mmwave radar Host Communication Protocol(RHCP)
Definition: rl_driver.c:2684
RHCP protocol header structure.
Definition: rl_protocol.h:209
mmwave radar Driver Payload
Definition: rl_driver.h:349
rlTimerCbs_t timerCb
Timer Callback, required when ACK is enabled.
Definition: mmwavelink.h:1494
rlCrcCbs_t crcCb
CRC Callback, required when CRC is enabled.
Definition: mmwavelink.h:1503
void rlDriverFillPayload(rlUInt16_t msgId, rlUInt16_t sbcID, rlPayloadSb_t *payloadPtr, rlUInt8_t *data, rlUInt16_t inLen)
: Fill payload based on given message-ID, sub-block ID and data.
Definition: rl_driver.c:3043
rlUInt16_t b2RetryFlag
00- No Retry, 11 - Retry
Definition: rl_protocol.h:145
rlReturnVal_t rlDriverConfigureAckTimeout(rlUInt32_t ackTimeout)
Configures the Acknowledgement timeout in mmwavelink Driver.
Definition: rl_driver.c:2846
void(* rlAsyncEvent)(rlUInt8_t devIndex, rlUInt16_t subId, rlUInt16_t subLen, rlUInt8_t *payload)
Reports Asynchronous events from mmwave radar device such as device status, exceptions etc.
Definition: mmwavelink.h:1282
rlReturnVal_t rlDriverOsiInit(void)
Initializes the OSI layer abstraction for mmwavelink.
Definition: rl_driver.c:1813
rlUInt16_t b10MsgId
Message ID.
Definition: rl_protocol.h:112
rlReturnVal_t rlDriverVerifyCRC(rlUInt8_t *data, rlUInt16_t dataLen, rlUInt8_t crcType, rlUInt8_t crc[RL_CRC_LEN_MAX])
Compares received CRC with Calculated CRC.
Definition: rl_driver.c:248
rlReturnVal_t rlDriverRemoveDevices(rlUInt8_t deviceMap)
Disconnects the mmwave radar devices.
Definition: rl_driver.c:2174
rlFunctionParams_t funcParams[RL_CASCADE_NUM_DEVICES]
Current API parameters.
Definition: rl_driver.h:240
rlInt32_t(* rlComIfWrite)(rlComIfHdl_t fd, rlUInt8_t *pBuff, rlUInt16_t len)
Write Data over Communication interface.
Definition: mmwavelink.h:1068
rlInt32_t(* rlDeviceDisable)(rlUInt8_t deviceIndex)
Power off mmWave radar device.
Definition: mmwavelink.h:1362
void(* rlDeviceUnMaskHostIrq)(rlComIfHdl_t fd)
Unmask Host Interrupt.
Definition: mmwavelink.h:1386
rlSysNRespType_t errorType
Definition: rl_protocol.h:74
rlUInt8_t retryCount
Retry count for re-sending command if device doesn't send response within timeout or device sends NAC...
Definition: rl_driver.h:297
rlClientCbs_t clientCtx
Client context.
Definition: rl_driver.h:288
rlDeviceCtrlCbs_t devCtrlCb
Device Control Callback.
Definition: mmwavelink.h:1490
rlReturnVal_t rlDriverAddDevice(rlUInt8_t deviceMap)
Adds mmwave radar device.
Definition: rl_driver.c:2081
RHCP message structure.
Definition: rl_protocol.h:225
mmWaveLink API Error Sub block structure
Definition: rl_protocol.h:69
rlCrcType_t crcType
CRC Types rlCrcType_t 16/32/64.
Definition: mmwavelink.h:1507
rlReturnVal_t rlDriverWaitForResponse(rlUInt8_t devIndex, rlDriverMsg_t *outMsg)
: Wait for Device's response
Definition: rl_driver.c:2382
rlUInt8_t deviceMap
Bitmap of devices connected radarSS/DSS Mailbox in case of 16xx autonomous.
Definition: rl_driver.h:248
rlUInt16_t b4Version
0000 - Invalid, 0001 - 1111 - Valid Range
Definition: rl_protocol.h:153
rlReturnVal_t rlDriverProcRdMsg(rlUInt8_t devIdx, rlReturnVal_t inVal)
Process received message for Async event message.
Definition: rl_driver.c:636
RHCP SYNC Pattern Structure.
Definition: rl_protocol.h:85
rlComDevInx_t commDevIdx
Communication handle and device-index for deifferent devices connected to Host.
Definition: rl_driver.h:272
void rlDriverShiftDWord(rlUInt8_t buf[])
Shifts one byte in the byte array.
Definition: rl_driver.c:179
rlCmdParserCbs_t cmdParserCb
Call back for parsing the Command received at MSS from the Host TI Internal Use only.
Definition: mmwavelink.h:1499
rlReturnVal_t rlDriverExecuteSetApi(rlUInt8_t deviceMap, rlUInt16_t msgId, rlUInt16_t sbcID, rlUInt8_t *msgData, rlUInt16_t inLen)
: Construct set message and invoke command.
Definition: rl_driver.c:3132
rlReturnVal_t rlDriverIsDeviceMapValid(rlUInt8_t deviceMap)
Checks if given deviecMap is valid wrt to global DeviceMap set to mmWaveLink.
Definition: rl_driver.c:2339
rlInt32_t(* rlDeviceWaitIrqStatus)(rlComIfHdl_t fd, rlUInt8_t highLow)
Polls Host Interrupt Status.
Definition: mmwavelink.h:1405

Copyright 2020, Texas Instruments Incorporated