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.

AWR1243: DFP mmwl_powerOnMaster fails

Part Number: AWR1243

Hi,

When I run the DFP function mmwl_powerOnMaster I get a time out error. The following functions are called before I get the error:

rlOsiMutexCreate Callback is called by mmWaveLink
rlOsiSyncObjCreate Callback is called by mmWaveLink
rlComIfOpen Callback Called for Device Index [0]
rlRegisterInterruptHandler Callback is called by mmWaveLink
rlDeviceEnable Callback is called by mmWaveLink for Device Index [0]
rlDeviceMaskHostIrq Callback is called by mmWaveLink
rlOsiMutexCreate Callback is called by mmWaveLink
mmWave Device Power on failed for deviceMap 1 with error -8

It seems to call the interrupt function, but never calls the asynchronous event handler?

Also I'm not running an OS so all my Mutex and Semaphore functions are dummy functions. Is that what should be done for no OS implementation?

Thanks,

Daniel

  • HI,

    An OS is not required to run mmWave link APIs.

    Have you run the example provided in the dfp release?

    C:\ti\mmwave_dfp_01_02_00_01\ti\example\mmwavelink_example

    Thank you
    Cesar
  • Cesar,

    I'm not running on widows. I ported the mmwavelink_example to different platform. I followed the porting guide and implemented all all the callback functions as instructed. I have no OS. Again what to do about the Mutex/Semaphore functions? And from my output above what could be the problem that it never calls the async event handler?

    Thanks,

    Daniel

  • Hi Deniel,
    you need to define mutex/semaphore callbacks (Non-OS equivalent) even though you are not using any OS with your Host application. mmwavelink uses these callbacks for communication protocol flow.

    You can refer on of TI-Rex application Non-OS mmw demo
    dev.ti.com/.../node

    Checkout src\common\mmw_link.c and osi_nonos.c files which will help you to implement mmwavelink with non-OS environment.


    Regards,
    Jitendra
  • Jitendar,

    I don't have the files mmw_link.c and osi_nonos.c. Where can I find them?

    Thanks,

    Daniel

  • These files are available under Non-OS mmw demo on TI-Rex (follow the link given in the previous reply).

    Regards,
    Jitendra
  • Jitendra,

    I have now implanted the mutex/semaphore callbacks from the TI non-os example code you linked. I'm still getting a timeout error and it now calls the following functions:

    Debug: Launched the mmwaveLink Management Task
    rlOsiMutexCreate Callback is called by mmWaveLink
    rlOsiSemCreate Callback is called by mmWaveLink
    rlComIfOpen Callback Called for Device Index [0]
    rlRegisterInterruptHandler Callback is called by mmWaveLink
    rlDeviceEnable Callback is called by mmWaveLink for Device Index [0]
    rlDeviceMaskHostIrq Callback is called by mmWaveLink
    rlOsiSpawn Callback is called by mmWaveLink
    mmWave Device Power on failed for deviceMap 1 with error -8

    It sill doesn't call the asynchronous event handler? I'm using the MMWL_asyncEventHandler function from the dfp example code. But I don't understand how this function would be ever called?

    Thanks,

    Daniel 

  • Any input regarding my post above?

    Thanks, Daniel

  • Hi Daniel,
    Could you check if your GPIO interrupt handler is getting triggered when AWR device raises HostIRQ?

    As I mentioned earlier, HostIRQ of AWR device should connect to one of GPIO of Host Processor and it needs to register interrupt (GPIOIntHandler) of GPIO raising high.

    While rlDevicePowerOn call, Host should have passed the rlRegisterInterruptHandler callback function which is implemented in the application.


    rlClientCbs_t RlApp_ClientCtx;
    RlApp_ClientCtx.devCtrlCb.rlRegisterInterruptHandler = MmwaveLink_registerInterruptHandler;
    /* Initialize the Asynchronous Event Handler: */
    RlApp_ClientCtx.eventCb.rlAsyncEvent = MmwaveLink_asyncEventHandler;
    /* Power on the Device: */
    if (rlDevicePowerOn(1U, RlApp_ClientCtx) != 0) {.... }


    static rlInt32_t MmwaveLink_registerInterruptHandler(rlUInt8_t deviceIndex, RL_P_EVENT_HANDLER pHandler, void* pValue)
    {
    g_MailboxInterruptFunc = pHandler;
    return 0;
    }


    Now in the GPIOIntHandler function, you need to check if it active High (i.e. HostIRQ raised from AWR).

    void GPIOIntHandler(...)
    {
    if(GPIO_HIGH)
    {
    g_MailboxInterruptFunc(0, NULL);
    /* this call goes to rlDriverHostIrqHandler of mmwavelink which spawn a function [rlDriverMsgReadSpawnCtx] to read the Async Event Message and forward that message to application layer [MmwaveLink_asyncEventHandler] */
    }
    }
    -----------------------------------------------------------------------------


    So now with your condition, when mmwavelink spawns a function, in the application while waiting for async-evnt message you need to invoke that spawned function manually (as you are using Non-OS).

    retVal = rlDevicePowerOn(1U, RlApp_ClientCtx);
    while (mmwl_bInitComp == 0U)
    {
    rlNonOsMainLoopTask(); /* implemented in rl_nonos.c file which you can find in nonOS mmw demo from TIRex dev.ti.com/.../node */
    rlAppSleep(1);
    timeOutCnt++;
    if (timeOutCnt > MMWL_API_INIT_TIMEOUT)
    {
    retVal = RL_RET_CODE_RESP_TIMEOUT;
    break;
    }
    }

    void MMWL_asyncEventHandler(rlUInt8_t deviceIndex, rlUInt16_t sbId,
    rlUInt16_t sbLen, rlUInt8_t *payload)
    {
    unsigned int deviceMap = 0;
    rlUInt16_t msgId = sbId / RL_MAX_SB_IN_MSG;
    rlUInt16_t asyncSB = RL_GET_SBID_FROM_MSG(sbId, msgId);

    /* Host can receive Async Event from RADARSS/MSS */
    switch (msgId)
    {

    /* Async Event from MSS */
    case RL_DEV_ASYNC_EVENT_MSG:
    {
    switch (asyncSB)
    {
    case RL_DEV_AE_MSSPOWERUPDONE_SB:
    {
    mmwl_bInitComp = 1U;
    }
    break;
    case RL_DEV_AE_MSS_BOOTERRSTATUS_SB:
    {
    mmwl_bInitComp = 1U;
    }
    ....................
    }

    Regards,

    Jitendra

  • Jitendra,

    I download the nonOS mmw demo into Code Composer, but I can't find the file rl_nonos.c anywhere?

    Thanks,

    Daniel

     

  • Hi Daniel,

    Sorry for the confusion. Here is code reference for rl_nonos.c

    
    #include <ti/control/mmwavelink/mmwavelink.h>
    
    #define NONOS_WAIT_FOREVER                               0x7FFF
    #define NONOS_NO_WAIT                                    0x00
    
    #define NONOS_RET_OK                            (0)
    #define NONOS_RET_ERR                           (0xFF)
    #define OSI_OK  NONOS_RET_OK
    
    #define NON_OS_SYNC_OBJ_CLEAR_VALUE                0x11
    #define NON_OS_SYNC_OBJ_SIGNAL_VALUE                0x22
    #define NON_OS_LOCK_OBJ_UNLOCK_VALUE                0x33
    #define NON_OS_LOCK_OBJ_LOCK_VALUE                0x44
    #define NONOS_MAX_SPAWN_ENTRIES     5
    
    typedef rlInt8_t rlNonOsRetVal_t;
    typedef rlInt32_t rlNonOsTime_t;
    typedef rlInt8_t rlNonOsSemObj_t;
    typedef void (*rlSpawnEntryFunc_t)(void* pValue);
    
    typedef struct
    {
        rlSpawnEntryFunc_t         pEntry;
        void*                       pValue;
    }rlNonOsSpawnEntry_t;
    
    typedef struct
    {
        rlNonOsSpawnEntry_t    SpawnEntries[NONOS_MAX_SPAWN_ENTRIES];
    }rlNonOsCB_t;
    
    rlNonOsCB_t rl_nonOsCB;
    
    rlNonOsRetVal_t rlNonOsSemSet(rlNonOsSemObj_t* pSemObj, rlNonOsSemObj_t Value)
    {
    	*pSemObj = Value;
    	return NONOS_RET_OK;
    }
    
    rlNonOsRetVal_t rlNonOsSemGet(rlNonOsSemObj_t* pSyncObj, rlNonOsSemObj_t WaitValue, rlNonOsSemObj_t SetValue, rlNonOsTime_t Timeout)
    {
    	volatile rlNonOsSemObj_t *tempVal = pSyncObj;
    
    	while (Timeout>0)
    	{
    		if (WaitValue == *tempVal)
    		{
    			*pSyncObj = SetValue;
    			break;
    		}
    		if (Timeout != NONOS_WAIT_FOREVER)
    		{
    			Timeout--;
    		}
    	}
    
    	if (0 == Timeout)
    	{
    		return NONOS_RET_ERR;
    	}
    	else
    	{
    		return NONOS_RET_OK;
    	}
    }
    rlNonOsRetVal_t rlNonOsSpawn(rlSpawnEntryFunc_t pEntry, void* pValue, rlUInt32_t flags)
    {
    	rlInt8_t i = 0;
    
    	for (i = 0; i<NONOS_MAX_SPAWN_ENTRIES; i++)
    	{
    		rlNonOsSpawnEntry_t* pE = &rl_nonOsCB.SpawnEntries[i];
    
    		if (NULL == pE->pEntry)
    		{
    			pE->pValue = pValue;
    			pE->pEntry = pEntry;
    			break;
    		}
    	}
    	return NONOS_RET_OK;
    }
    
    rlInt32_t rlSpawn(rlSpawnEntryFunc_t pEntry, void* pValue, rlUInt32_t flags)
    {
    	return rlNonOsSpawn(pEntry, pValue, flags);
    }
    
    rlInt32_t rlLockObjCreate(rlOsiMutexHdl_t* mutexHdl, rlInt8_t* name)
    {
        rlNonOsRetVal_t retVal;
        retVal = rlNonOsSemSet((rlNonOsSemObj_t*)mutexHdl, NON_OS_LOCK_OBJ_UNLOCK_VALUE);
        return ((rlInt32_t)retVal);
    }
    
    rlInt32_t rlLockObjDelete(rlOsiMutexHdl_t* mutexHdl)
    {
        rlNonOsRetVal_t retVal;
        retVal = rlNonOsSemSet((rlNonOsSemObj_t*)mutexHdl, 0);
        return ((rlInt32_t)retVal);
    }
    
    rlInt32_t rlLockObjLock(rlOsiMutexHdl_t* mutexHdl, rlOsiTime_t timeout)
    {
        rlNonOsRetVal_t retVal;
        retVal = rlNonOsSemGet((rlNonOsSemObj_t*)mutexHdl, NON_OS_LOCK_OBJ_UNLOCK_VALUE, NON_OS_LOCK_OBJ_LOCK_VALUE, timeout);
        return ((rlInt32_t)retVal);
    }
    
    rlInt32_t rlLockObjUnlock(rlOsiMutexHdl_t* mutexHdl)
    {
        rlNonOsRetVal_t retVal;
        retVal =rlNonOsSemSet((rlNonOsSemObj_t*)mutexHdl, NON_OS_LOCK_OBJ_UNLOCK_VALUE);
        return ((rlInt32_t)retVal);
    }
    
    rlInt32_t rlSyncObjCreate(rlOsiSemHdl_t* semHdl, rlInt8_t* name)
    {
        rlNonOsRetVal_t retVal;
        retVal = rlNonOsSemSet((rlNonOsSemObj_t*) semHdl, NON_OS_SYNC_OBJ_CLEAR_VALUE);
        return ((rlInt32_t)retVal);
    }
    
    rlInt32_t rlSyncObjDelete(rlOsiSemHdl_t* semHdl)
    {
        rlNonOsRetVal_t retVal;
        retVal = rlNonOsSemSet((rlNonOsSemObj_t*) semHdl, 0);
        return ((rlInt32_t)retVal);
    }
    
    rlInt32_t rlSyncObjSignal(rlOsiSemHdl_t* semHdl)
    {
        rlNonOsRetVal_t retVal;
        retVal = rlNonOsSemSet((rlNonOsSemObj_t*) semHdl, NON_OS_SYNC_OBJ_SIGNAL_VALUE);
        return ((rlInt32_t)retVal);
    }
    
    rlInt32_t rlSyncObjWait(rlOsiSemHdl_t* semHdl, rlOsiTime_t timeout)
    {
    	rlNonOsRetVal_t retVal;
    	retVal = rlNonOsSemGet((rlNonOsSemObj_t*)semHdl, NON_OS_SYNC_OBJ_SIGNAL_VALUE, NON_OS_SYNC_OBJ_CLEAR_VALUE, timeout);
    	return ((rlInt32_t)retVal);
    }
    
    rlNonOsRetVal_t rlNonOsMainLoopTask(void)
    {
        rlInt8_t i=0;
        for (i=0 ; i<NONOS_MAX_SPAWN_ENTRIES ; i++)
        {
            rlNonOsSpawnEntry_t* pE = &rl_nonOsCB.SpawnEntries[i];
            rlSpawnEntryFunc_t         pF = pE->pEntry;
    
            if (NULL != pF)
            {
    
                pF(pE->pValue); /* (pValue) */
    
                pE->pEntry = NULL;
                pE->pValue = NULL;
            }
        }
        return NONOS_RET_OK;
    }
    
    
    rlInt32_t rlAppSleep(rlUInt32_t delay)
    {
    	rlUInt32_t i;
    /* need to change the for count based on processor clock speed */ for(i=0; i< delay*10000; i++); return 0; }

    And here the all the Mutex and Semaphore calbacks which are needed to connect with mmwavelink

    clientCtx.osiCb.mutex.rlOsiMutexCreate = rlLockObjCreate;
    clientCtx.osiCb.mutex.rlOsiMutexLock = rlLockObjLock;
    clientCtx.osiCb.mutex.rlOsiMutexUnLock = rlLockObjUnlock;
    clientCtx.osiCb.mutex.rlOsiMutexDelete = rlLockObjDelete;

    /* Semaphore */
    clientCtx.osiCb.sem.rlOsiSemCreate = rlSyncObjCreate;
    clientCtx.osiCb.sem.rlOsiSemWait = rlSyncObjWait;
    clientCtx.osiCb.sem.rlOsiSemSignal = rlSyncObjSignal;
    clientCtx.osiCb.sem.rlOsiSemDelete = rlSyncObjDelete;

    /* Spawn Task */
    clientCtx.osiCb.queue.rlOsiSpawn = (RL_P_OS_SPAWN_FUNC_PTR)rlSpawn;

    /* Sleep/Delay Callback*/
    clientCtx.timerCb.rlDelay = (RL_P_OS_DELAY_FUNC_PTR)rlAppSleep;

    Regards,

    Jitendra