【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)

【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)

MMWave API(位置处于BSS)可以被DSS和MSS调用
通过Mailbox进行数据通信
毫米波雷达接口

#include < ti/control/mmwave/mmwave.h>
#include 

MMWave工作原理

首先搞清楚 mmwave时雷达射频整体 每秒发送很多frame(帧)
frame下面有chirp 比如96个chirp
所以当发送开始时 会连续发送96个chirps 然后接收数据 再处理
如图为chirp的时序图
【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)_第1张图片
雷达工作原理是上电-发送chirps-帧结束-处理-上电循环
一个Frame,首先是信号发送,比如96个chirp就顺次发出去,然后接收回来,混频滤波,ADC采样,这些都是射频模块的东西。射频完成之后,FFT,CFAR,DOA这些就是信号处理的东西。然后输出给那个结构体,就是当前帧获得的点云了。
在这里插入图片描述
在射频发送阶段 一个frame发送若干个chirp 也就是上图左上角
第一个绿色点为frame start 第二个绿色点为frame end
其中发送若干chirps(小三角形)
chirps的个数称为numLoops(代码中 rlFrameCfg_t结构体)
在mmwave studio上位机中 则称为 no of chirp loops

frame end 到 周期结束的时间为计算时间 称为inter frame period
在这里插入图片描述
frame start到循环结束的时间称为framePeriodicity(代码中 rlFrameCfg_t结构体)
在mmwave studio上位机中 则称为 Periodicity

如下图frame配置部分
在这里插入图片描述
在inter frame Periodicity时间内(比如这里整个周期是55ms)
就是用于计算和处理的时间 一定比55ms要小
如果chirps很多的话 那么计算时间就会减小

如果是处理点云数据 则只需要每一帧计算一次点云即可
计算出当前帧的xyz坐标和速度 以及保存时间戳

雷达上电

 /* Wait for BSS powerup */
if (SOC_waitBSSPowerUp(socHandle, &errCode) < 0)
{
    /* Debug Message: */
    System_printf ("Debug: SOC_waitBSSPowerUp failed with Error [%d]\n", errCode);
    return 0;
}

Mailbox_init(MAILBOX_TYPE_MSS);

除了初始化SOC外 还需要调用SOC_waitBSSPowerUpMailbox_init

配置流程

1. 初始化模块:MMWave_init

配置结构体 MMWave_InitCfg
domain指定运行位置

MMWave_InitCfg      initCfg;
initCfg.domain                  = MMWave_Domain_MSS;
initCfg.socHandle               = MMWave_Global_Params.handle.socHandle;
initCfg.eventFxn                = MMWave_eventFxnCallback;  //事件回调
initCfg.linkCRCCfg.useCRCDriver = 0U;           //1开启CRC 0关闭CRC
initCfg.linkCRCCfg.crcChannel   = CRC_Channel_CH1;      //CRC通道1
initCfg.cfgMode                 = MMWave_ConfigurationMode_FULL;  //全部模式 也可以设置成最小全部模式
initCfg.executionMode           = MMWave_ExecutionMode_ISOLATION;  //MSS和DSS不通讯 如果需要 则换个模式

//以下全是回调
initCfg.cooperativeModeCfg.cfgFxn   = MMWave_cfgFxnCallback;
initCfg.cooperativeModeCfg.closeFxn = MMWave_closeFxnCallback;
initCfg.cooperativeModeCfg.openFxn  = MMWave_openFxnCallback;
initCfg.cooperativeModeCfg.startFxn = MMWave_startFxnCallback;
initCfg.cooperativeModeCfg.stopFxn  = MMWave_stopFxnCallback;

/* Initialize and setup the MMWave Control module */
MMWave_Global_Params.handle.MMWave_handle = MMWave_init (&initCfg, &errCode);
if (MMWave_Global_Params.handle.MMWave_handle == NULL)
{
    /* Error: Unable to initialize the MMWave control module */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: MMWave Control Initialization failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    return;
}

在MSS+DSS协作模式下工作时,毫米波同时在MSS和DSS上执行。每个域都注册一个回调函数,如果对等域执行等效操作,则由毫米波模块调用该函数。
【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)_第2张图片
这样在配置时 会自动进行传参 使两个部分同步

2. 同步模块:MMWave_sync

/* Synchronization: This will synchronize the execution of the control module
     * between the domains. This is a prerequiste and always needs to be invoked. */
    //同步
    if (MMWave_sync (MMWave_Global_Params.handle.MMWave_handle, &errCode) < 0)
    {
        /* Error: Unable to synchronize the MMWave control module */
        MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
        System_printf ("Error: MMWave Control Synchronization failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
        return;
    }

直接调用MMWave_sync

3. 执行毫米波模块:MMWave_execute

在执行上面两步以后需要调用MMWave_execute
这个函数需要在上下文一直调用 所以建立一个死循环线程

这里priority 越大 优先级越高 越先响应

/*****************************************************************************
    * Launch the MMWave control execution task
    * - This should have a higher priroity than any other task which uses the
    *   MMWave control API
    *****************************************************************************/
    //这里是开了一个线程循环调用
    Task_Params_init(&taskParams);
    taskParams.priority  = 5;
    taskParams.stackSize = 3*1024;
    MMWave_Global_Params.task.MMWaveCtrl = Task_create(Ctrl_MMWave, &taskParams, NULL);
void Ctrl_MMWave(UArg arg0, UArg arg1)
{
    int32_t errCode;
    MMWave_ErrorLevel   errorLevel;
    int16_t             mmWaveErrorCode;
    int16_t             subsysErrorCode;

    while (1)
    {
        /* Execute the MMWave control module: */
        if (MMWave_execute (MMWave_Global_Params.handle.MMWave_handle, &errCode) < 0)
        {
            MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
            System_printf ("Error: MMWave control execution failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
        }
    }
}

4. 打开模块:MMWave_open

MMWave_OpenCfg      openCfg;

openCfg.freqLimitLow  = 600U;   //低频限制
openCfg.freqLimitHigh = 640U;   //高频限制

openCfg.chCfg.rxChannelEn = 0x000F;  //开启四个RX
openCfg.chCfg.txChannelEn = 0x0007;  //开启四个TX
openCfg.chCfg.cascading   = 0x0000;  //不开启级联
openCfg.chCfg.cascadingPinoutCfg = 0;  //直接给0

openCfg.lowPowerMode.lpAdcMode = 0x0000; //Regular ADC mode

openCfg.adcOutCfg.fmt.b2AdcBits = 2; //16bit
openCfg.adcOutCfg.fmt.b8FullScaleReducFctr = 0; //16bit只能为0
openCfg.adcOutCfg.fmt.b2AdcOutFmt = 2;  //Complex with Image band

openCfg.defaultAsyncEventHandler    = MMWave_DefaultAsyncEventHandler_MSS;

openCfg.disableFrameStartAsyncEvent = false;
openCfg.disableFrameStopAsyncEvent  = false;

openCfg.useCustomCalibration        = false;  // 无自定义校准 false表示默认启用所有校准
openCfg.customCalibrationEnableMask = 0x0;

openCfg.calibMonTimeUnit            = 1;   //一帧一次校准

/*
MMWave_CalibrationData      calibrationData;
memset ((void*)&calibrationCfg, 0 , sizeof(MMWave_CalibrationCfg));

calibrationData.ptrCalibData->calibChunk
calibrationData.ptrPhaseShiftCalibData->PhShiftcalibChunk
*/

/* Open the mmWave module: */
if (MMWave_open (MMWave_Global_Params.handle.MMWave_handle, &openCfg, NULL, &errCode) < 0)
{
    /* Error: decode and Report the error */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Open failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
}

这里是配置频段 RX、TX使能个数、采样位数等
对应mmwave studio:
【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)_第3张图片
【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)_第4张图片

5. 模块的配置:MMWave_config

这里是配置frame

MMWave_CtrlCfg      ctrlCfg;

ctrlCfg.dfeDataOutputMode = MMWave_DFEDataOutputMode_FRAME;

ctrlCfg.u.frameCfg.profileHandle[0]=MMWave_Global_Params.handle.profileHandle[0];
ctrlCfg.u.frameCfg.profileHandle[1]=NULL;
ctrlCfg.u.frameCfg.profileHandle[2]=NULL;
ctrlCfg.u.frameCfg.profileHandle[3]=NULL;

ctrlCfg.u.frameCfg.frameCfg.chirpStartIdx = 0;
ctrlCfg.u.frameCfg.frameCfg.chirpEndIdx = 2;
ctrlCfg.u.frameCfg.frameCfg.numLoops = 96;
ctrlCfg.u.frameCfg.frameCfg.numFrames = 0;
ctrlCfg.u.frameCfg.frameCfg.numAdcSamples = 96;
ctrlCfg.u.frameCfg.frameCfg.framePeriodicity = 11000000;  //55ms
ctrlCfg.u.frameCfg.frameCfg.triggerSelect = 0x0001; //软件API触发

ctrlCfg.u.frameCfg.frameCfg.numDummyChirpsAtEnd = 0;
ctrlCfg.u.frameCfg.frameCfg.frameTriggerDelay = 0;

/*
//frame模式不用配
ctrlCfg.u.continuousModeCfg.cfg.startFreqConst
ctrlCfg.u.continuousModeCfg.cfg.txOutPowerBackoffCode
ctrlCfg.u.continuousModeCfg.cfg.txPhaseShifter
ctrlCfg.u.continuousModeCfg.cfg.digOutSampleRate
ctrlCfg.u.continuousModeCfg.cfg.hpfCornerFreq1
ctrlCfg.u.continuousModeCfg.cfg.hpfCornerFreq2
ctrlCfg.u.continuousModeCfg.cfg.rxGain
ctrlCfg.u.continuousModeCfg.cfg.vcoSelect
ctrlCfg.u.continuousModeCfg.dataTransSize
*/
//ctrlCfg.u.advancedFrameCfg.profileHandle = //NULL;  //frame模式不用配

/* Configure the mmWave module: */
if (MMWave_config (MMWave_Global_Params.handle.MMWave_handle, &ctrlCfg, &errCode) < 0)
{
    /* Error: Report the error */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Config failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
}

对应:
【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)_第5张图片

配置profile和chirp

如果需要配置profile和chirp 则需要调用MMWave_addProfileMMWave_addChirp

注意 chirp是在profile之下的 而profile是在mmwave之下的(就像mmwave的句柄在soc之下)

所以配置frame时:

ctrlCfg.u.frameCfg.profileHandle[0]=MMWave_Global_Params.handle.profileHandle[0];

这里的profile句柄就是MMWave_addProfile返回的 而chirp的句柄在MMWave_addChirp的返回中
并且MMWave_addChirp的第一个参数就是MMWave_addProfile的返回值(profile的句柄)
MMWave_addProfile的第一个参数则为MMWave_init的返回值(mmwave的句柄)
那么配置的先后关系就可以列出来了(其实不用在意 只要配了就行 另外 句柄要用全局变量 但是按顺序配置可以方便从上往下读代码)

rlProfileCfg_t  profileCfg;
rlChirpCfg_t    chirpCfg;
memset ((void*)&profileCfg, 0 , sizeof(rlProfileCfg_t));
memset ((void*)&chirpCfg, 0 , sizeof(rlChirpCfg_t));

profileCfg.profileId = 0;
profileCfg.pfVcoSelect = 0x02;  //内置 VCO2 选择60-64GHz
profileCfg.pfCalLutUpdate = 0x00;  //校准
profileCfg.startFreqConst = 0x58E3A1CD;  //60GHz
profileCfg.idleTimeConst = 0x2710;  //100us
profileCfg.adcStartTimeConst = 0x258;  //6us
profileCfg.rampEndTime = 0x1770;  //60us
profileCfg.txOutPowerBackoffCode = 0;  //全为0
profileCfg.txPhaseShifter = 0;  //全为0
profileCfg.freqSlopeConst = 0x05E7;  //54.713 MHz/us
profileCfg.txStartTime = 0;  //0us
profileCfg.numAdcSamples = 96;  //96
profileCfg.digOutSampleRate = 0x0B86;  //2950ksps
profileCfg.hpfCornerFreq1 = 0;  //175K
profileCfg.hpfCornerFreq2 = 0;  //350K
profileCfg.txCalibEnCfg = 0xFFFF;  //不适用于IWR6843 ES 1.0
profileCfg.rxGain = 0x68; //40dB/34dB

MMWave_Global_Params.handle.profileHandle[0] = MMWave_addProfile(MMWave_Global_Params.handle.MMWave_handle,&profileCfg,&errCode);
if(MMWave_Global_Params.handle.profileHandle[0] == NULL)
{
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave profileCfg failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
}

chirpCfg.chirpStartIdx=0;
chirpCfg.chirpEndIdx=0;
chirpCfg.profileId=0;
chirpCfg.startFreqVar=0;
chirpCfg.freqSlopeVar=0;
chirpCfg.idleTimeVar=0;
chirpCfg.adcStartTimeVar=0;
chirpCfg.txEnable=(1<<0);

//TDM模式 用for循环配置三次 每次的chirpStartIdx chirpEndIdx均不同 分别为00 11 22 另外 打开的TX也不同 分别为TX0 TX1 TX2
//这三个chirp配置都属于同一个profileHandle下
for(i=0;i<3;i++)
{
    chirpCfg.chirpStartIdx=i;
    chirpCfg.chirpEndIdx=i;
    chirpCfg.txEnable=(1<<i);
    MMWave_Global_Params.handle.chirpHandle[i] = MMWave_addChirp(MMWave_Global_Params.handle.profileHandle[0],&chirpCfg,&errCode);
    if(MMWave_Global_Params.handle.chirpHandle[i] == NULL)
    {
        MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
        System_printf ("Error: mmWave chirpCfg %d failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    }
}

//然后下面再是MMWave_config 函数和配置

然后下面再是MMWave_config 函数和配置

对应的就是这一大块
【TI毫米波雷达笔记】MMwave毫米波雷达API配置及驱动(以IWR6843AOP为例)_第6张图片

6. 启动毫米波:MMWave_start

这里就是开启测量了 同时定义了校准和运行模式

MMWave_CalibrationCfg       calibrationCfg;
memset ((void *)&calibrationCfg, 0, sizeof(MMWave_CalibrationCfg));

calibrationCfg.dfeDataOutputMode = MMWave_DFEDataOutputMode_FRAME;

calibrationCfg.u.chirpCalibrationCfg.enableCalibration = true;
calibrationCfg.u.chirpCalibrationCfg.enablePeriodicity = true;
calibrationCfg.u.chirpCalibrationCfg.periodicTimeInFrames = 10;  //每10帧一次校准

//calibrationCfg.u.contCalibrationCfg.enableOneShotCalibration  //frame模式不用配

/* Start the mmWave module: The configuration has been applied successfully. */
if (MMWave_start(MMWave_Global_Params.handle.MMWave_handle, &calibrationCfg, &errCode) < 0)
{
    /* Error/Warning: Unable to start the mmWave module */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Start failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    /* datapath has already been moved to start state; so either we initiate a cleanup of start sequence or
       assert here and re-start from the beginning. For now, choosing the latter path */
}

错误代码

毫米波雷达错误代码可以用MMWave_decodeError函数来获取
传入的第一个参数为errCode 而后面三个其实都是返回值
比如:

int32_t         errCode;
MMWave_ErrorLevel   errorLevel;
int16_t             mmWaveErrorCode;
int16_t             subsysErrorCode;
if (MMWave_start(MMWave_Global_Params.handle.MMWave_handle, &calibrationCfg, &errCode) < 0)
{
    /* Error/Warning: Unable to start the mmWave module */
    MMWave_decodeError (errCode, &errorLevel, &mmWaveErrorCode, &subsysErrorCode);
    System_printf ("Error: mmWave Start failed [Error Level: %d Error code: %d Subsystem: %d]\n",errorLevel,mmWaveErrorCode, subsysErrorCode);
    /* datapath has already been moved to start state; so either we initiate a cleanup of start sequence or
       assert here and re-start from the beginning. For now, choosing the latter path */
}

最后皆可以通过mmWaveErrorCode来获取调用函数的问题

其他模块的错误代码基本地址不一样 但是也大同小异 查其他模块的手册就可以了

你可能感兴趣的:(TI毫米波雷达笔记,笔记,单片机,毫米波雷达,嵌入式硬件)