This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1352P: Porting ProjectZero to custom board

Part Number: CC1352P

I have successfully loaded and operated Project Zero on the LaunchXL-CC1352P4 Evaluation Board. I am now tying to load it onto my own target hardware (with a CC1352P1F3 micro). The code is getting stuck in a while(1); loop in the Icall_abort() routine. The call stack is as follows:

ICall_abort() at icall.c:2,927 0x0001D874    

icall_directAPI() at icall.c:0 0x00014C02    

ProjectZero_init() at project_zero.c:569 0x0000015A    

ProjectZero_taskFxn() at project_zero.c:687 0x000000D2    

When single-stepping, I get to line marked with <<<<<<<< below


 

 /*******************************************************************************
 * @fn          icall_directAPI
 * see headers for details.
 */
uint32_t icall_directAPI( uint8_t service , icall_lite_id_t id, ... )
{
  va_list argp;
  uint32_t res;
  icallLiteMsg_t liteMsg;

  // The following will push all parameter in the runtime stack.
  // This need to be call before any other local declaration of variable....
  va_start(argp, id);

  // Test that the API is not called in a Hwi or Swi context
  {
    BIOS_ThreadType threadtype = BIOS_getThreadType();

    if (threadtype == BIOS_ThreadType_Hwi ||
        threadtype == BIOS_ThreadType_Swi)
    {
#ifdef HALNODEBUG
#else /* ! HALNODEBUG */
      ICall_abort();
#endif /* HALNODEBUG */
    }
  }

  // Todo - add string for every icall API function, instead of printing function address
  BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : icall_directAPI to BLE func=0x%x, status=%d\n", id, 0);
  // Create the message that will be send to the requested service..
  liteMsg.hdr.len = sizeof(icallLiteMsg_t);
  liteMsg.hdr.next = NULL;
  liteMsg.hdr.dest_id = ICALL_UNDEF_DEST_ID;
  liteMsg.msg.directAPI  = id;
  liteMsg.msg.pointerStack = (uint32_t*)(*((uint32_t*)(&argp)));
  ICall_sendServiceMsg(ICall_getEntityId(), service,
                       ICALL_MSG_FORMAT_DIRECT_API_ID, &(liteMsg.msg));

  // Since stack needs to always have a higher priority than the thread calling
  // the API, when we reach this point the API has been executed by the stack.
  // This implies the following:
  //  - API are not called in critical section or in section where task
  //    switching is disabled
  // It is possible that the stack is blocking on this API, in this case a
  // sync object needs to be used in order for this call to resume only when
  // the API has been process in full.
  {
    ICall_Errno errno;
    void *pCmdStatus = NULL;

    errno = ICall_waitMatch(ICALL_TIMEOUT_PREDEFINE, matchLiteCS, NULL, NULL,                                 <<<<<<<<<<<<<<<< routine times out inside the ICall_waitMatch() routine
                    (void **)&pCmdStatus);
    if (errno == ICALL_ERRNO_TIMEOUT)
    {
#ifdef HALNODEBUG
#elif  defined(EXT_HAL_ASSERT)
      HAL_ASSERT(HAL_ASSERT_CAUSE_ICALL_TIMEOUT);
#else /* !EXT_HAL_ASSERT */
      ICall_abort();
#endif /* EXT_HAL_ASSERT */
    }
    else if (errno == ICALL_ERRNO_SUCCESS)
    {
      if (pCmdStatus)
      {
        ICall_freeMsg(pCmdStatus);
      }
    }
    else
    {
#ifdef HALNODEBUG
#else /* ! HALNODEBUG */
      ICall_abort();
#endif /* HALNODEBUG */
    }
  }

  // The return parameter is set in the runtime stack, at the location of the
  // first parameter.
  res = liteMsg.msg.pointerStack[0];

  va_end(argp);

  return (res);
}

ICall_waitMatch(uint_least32_t milliseconds,
                ICall_MsgMatchFn matchFn,
                ICall_ServiceEnum *src,
                ICall_EntityID *dest,
                void **msg)
{
  Task_Handle taskhandle = Task_self();
  ICall_TaskEntry *taskentry = ICall_searchTask(taskhandle);
  ICall_MsgQueue prependQueue = NULL;
#ifndef ICALL_EVENTS
  uint_fast16_t consumedCount = 0;
#endif
  UInt timeout;
  uint_fast32_t timeoutStamp;
  ICall_Errno errno;

  {
    BIOS_ThreadType threadtype = BIOS_getThreadType();

    if (threadtype == BIOS_ThreadType_Hwi ||
        threadtype == BIOS_ThreadType_Swi)
    {
      /* Blocking call is not allowed from Hwi or Swi.
       * Note that though theoretically, Swi or lower priority Hwi may block
       * on an event to be generated by a higher priority Hwi, it is not a
       * safe practice and hence it is disabled.
       */
      return (ICALL_ERRNO_UNKNOWN_THREAD);
    }
  }

  if (!taskentry)
  {
    return (ICALL_ERRNO_UNKNOWN_THREAD);
  }
  /* Successful */
  if (milliseconds == 0)
  {
    timeout = BIOS_NO_WAIT;
  }
  else if (milliseconds == ICALL_TIMEOUT_FOREVER)
  {
    timeout = BIOS_WAIT_FOREVER;
  }
  else
  {
    /* Convert milliseconds to number of ticks */
    errno = ICall_msecs2Ticks(milliseconds, &timeout);
    if (errno != ICALL_ERRNO_SUCCESS)
    {
      return (errno);
    }
  }

  errno = ICALL_ERRNO_TIMEOUT;
  timeoutStamp = Clock_getTicks() + timeout;
#ifdef ICALL_LITE
  while(ICALL_SYNC_HANDLE_PEND_WM(taskentry->syncHandle, timeout))
#else /* !ICALL_LITE */
  while (ICALL_SYNC_HANDLE_PEND(taskentry->syncHandle, timeout))
#endif /* ICALL_LITE */
  {
    ICall_EntityID fetchSrc;
    ICall_EntityID fetchDst;
    ICall_ServiceEnum servId;
    void *fetchMsg;
    errno = ICall_fetchMsg(&fetchSrc, &fetchDst, &fetchMsg);
    if (errno == ICALL_ERRNO_SUCCESS)
    {
      if (ICall_primEntityId2ServiceId(fetchSrc, &servId) ==
            ICALL_ERRNO_SUCCESS)
      {
        if (matchFn(servId, fetchDst, fetchMsg))
        {
          /* Matching message found*/
          if (src != NULL)
          {
            *src = servId;
          }
          if (dest != NULL)
          {
            *dest = fetchDst;
          }
          *msg = fetchMsg;
          errno = ICALL_ERRNO_SUCCESS;
          break;
        }
      }
      /* Message was received but it wasn't expected one.
       * Add to the prepend queue */
      ICall_msgEnqueue(&prependQueue, fetchMsg);
#ifdef ICALL_EVENTS
    /* Event are binary semaphore, so if several messsages are posted while
     * we are processing one, it's possible that some of them are 'missed' and
     * not processed. Sending a event to ourself force this loop to run until
     * all the messages in the queue are processed.
     */
#ifdef ICALL_LITE
     ICALL_SYNC_HANDLE_POST_WM(taskentry->syncHandle);
#else /* !ICALL_LITE */
     ICALL_SYNC_HANDLE_POST(taskentry->syncHandle);
#endif /* ICALL_LITE*/
#endif /* ICALL_EVENTS */
    }

    /* Prepare for timeout exit */
    errno = ICALL_ERRNO_TIMEOUT;

#ifndef ICALL_EVENTS
    /* Keep the decremented semaphore count */
    consumedCount++;
#endif  /* ICALL_EVENTS */
    if (timeout != BIOS_WAIT_FOREVER &&
        timeout != BIOS_NO_WAIT)
    {
      /* Readjust timeout */
      UInt newTimeout = timeoutStamp - Clock_getTicks();
      if (newTimeout == 0 || newTimeout > timeout)
      {
        break;
      }
      timeout = newTimeout;
    }
  }

#ifdef ICALL_EVENTS
  /*
   * Because Events are binary semaphores, the task's queue must be checked for
   * any remaining messages.  If there are, the ICall event flag must be
   * re-posted due to it being cleared on the last pend.
   */
  ICall_primRepostSync();
#endif //ICALL_EVENTS

  /* Prepend retrieved irrelevant messages */
  ICall_msgPrepend(&taskentry->queue, prependQueue);
#ifndef ICALL_EVENTS
  /* Re-increment the consumed semaphores */
  for (; consumedCount > 0; consumedCount--)
  {
    Semaphore_post(taskentry->syncHandle);
  }
#endif /* ICALL_EVENTS */
  return (errno);
}

Looking for a message showing up when it's NOT supposed to is a lot easier to debug than looking for a message that's not showing up that IS supposed to.

Can anyone help?