infineon radar usecase (RBB7 Demo)

infineon
atmel
microChip
Author

dd21

Published

December 13, 2022

Abstract

上个文档描述的是整个项目的创建原因, 工程创建, 工程导入.

这个文档是进行具体的项目的配置, 根据原理图进行引脚信息, 从代码进行梳理, 一步一步确认引脚, 以及代码框架

我们需要配置的项:

  • uart
  • spi
  • ldo
  • RST
  • IRQ

编译该工程注意路径中不能有空格!!!!!

Referance

rbb7 原理图文件: RBB_MCU7_V2.2-schematics.pdf

安森美 LDO dataSheet TI Level Shifter dataSheet:

UART 配置

这里的 uart 预留的是PD24PD25, 我们芯片的该引脚也配置为如图的RxTx.

进入到可视化配置界面, 搜索选择usart, add

进行调整引脚, , 选择uart2配置到PD25PD26

需要调整的位置

USART_Sync

  • 阻塞型

USART_Async

  • 中断型

配置 SPI

Spi Key Word MISO : Master In Slave Out MOSI : Master Out Slave In CS: Chip Select

SPI 的几种模式

mode description
SPI_Master_Sync 同步模式下的串行外设接口 (SPI) 主机通信
SPI_Slave_Sync 同步模式下的串行外设接口 (SPI)从机通信
SPI_Master_Async 中断的异步模式下串行外设接口(SPI)主机通信
SPI_Slave_Async 中断的异步模式下的串行外设接口(SPI)从机通信
SPI_Master_DMA DMA 模式下的串行外设接口 (SPI) 主机通信
SPI_Master_RTOS 支持 RTOS模式下串行外设接口 (SPI) 主机通信

SPI 分配

rbb7代码中的QSPI是原理图上的S1_SPI, 代码中的SPI1是原理图的S2_SPI, 代码中的SPI2是原理图中的 SPI0 分配如下.

代码 原理图
Qspi S1_SPI
spi1 S2_SPI
spi2 SPI0

在项目中的配置是按照如下代码部分进行配置的, MCU7Legacy版本, 所以对应的是两个链接器. debug 和代码中显示的都是两个, 链接器, HatvanPlus 只有一个 LDO. ( 代码中的注释有点迷惑, 一直以为是 HatvanPlus 其实是 Legacy )

按照如下配置进行配置雷达的驱动引脚配置, 就是没问题的. 调整 mcu 也只需调整这几个配置即可.

 // detect board type
    const bool isHatvanLegacy = Board_isHatvanLegacy();
    if (isHatvanLegacy)
    {
        ShieldConnectorDefinition = &ShieldConnectorDefinitionHatvanLegacy[0];
        BoardSpiDefinition        = &BoardSpiDefinitionHatvanLegacy[0];
        BoardRadarPinsConfigAvian = &BoardRadarPinsConfigAvianHatvanLegacy[0];
        m_shieldConnectorCount    = ARRAY_SIZE(ShieldConnectorDefinitionHatvanLegacy);
    }

Hatvan Legacy Board Connector Definition, 我们这个是对HatvanLegacy的连接器做配置.

ShieldConnectorDefinition_t ShieldConnectorDefinitionHatvanLegacy[] = {
    [0] = {
        .en_ldo      = GPIO_ID('C', 30),
        .ls_spi_oe   = GPIO_ID('D', 24),
        .ls_gpio_oe  = GPIO_ID('D', 14),
        .ls_gpio_dir = GPIO_ID('D', 18),
        .oc_led      = GPIO_ID('C', 1),
        .oc1         = GPIO_ID('D', 16),
        .oc2         = GPIO_ID('C', 9),
        .oc3         = GPIO_ID('C', 28),
        .oc4         = GPIO_ID('A', 27),
    },  
    [1] = {
        .en_ldo      = GPIO_ID('C', 31),
        .ls_spi_oe   = GPIO_ID('C', 3),
        .ls_gpio_oe  = GPIO_ID('A', 1),
        .ls_gpio_dir = GPIO_ID('C', 10),
        .oc_led      = GPIO_ID('C', 2),
        .oc1         = GPIO_ID('A', 22),
        .oc2         = GPIO_ID('D', 10),
        .oc3         = GPIO_ID('C', 29),
        .oc4         = GPIO_ID('D', 15),
    },

spi配置

PlatformSpiDefinition_t BoardSpiDefinitionHatvanLegacy[] = {
    [0] = {
        .peripheral_id   = ID_QSPI,
        .baudrate        = 50000000,
        .setup_interface = setup_qspi,

        .addr = {
            .peripheral = QSPI,
            .tdr        = (uint32_t)&QSPI->QSPI_TDR,
            .rdr        = (uint32_t)&QSPI->QSPI_RDR,
        },
        .pins = {
            .csn        = PIO_PA11_IDX,
            .clk        = PIO_PA14_IDX,
            .clk_flags  = IOPORT_MODE_MUX_A,
            .miso       = PIO_PA12_IDX,
            .miso_flags = IOPORT_MODE_MUX_A,
            .mosi       = PIO_PA13_IDX,
            .mosi_flags = IOPORT_MODE_MUX_A,
        },
        .dma = {
            .tx_dma_channel = HV_DMA_HW_CH_TX_1,
            .tx_dma_hw_id   = HV_DMA_HW_INTF_TX_1,
            .rx_dma_channel = HV_DMA_HW_CH_RX_1,
            .rx_dma_hw_id   = HV_DMA_HW_INTF_RX_1,
        },
    },
    [1] = {
        .peripheral_id   = ID_SPI1,
        .baudrate        = 50000000,
        .setup_interface = setup_spi,

        .addr = {
            .peripheral = SPI1,
            .tdr        = (uint32_t)&SPI1->SPI_TDR,
            .rdr        = (uint32_t)&SPI1->SPI_RDR,
        },
        .pins = {
            .csn        = PIO_PC25_IDX,
            .clk        = PIO_PC24_IDX,
            .clk_flags  = IOPORT_MODE_MUX_C,
            .miso       = PIO_PC26_IDX,
            .miso_flags = IOPORT_MODE_MUX_C,
            .mosi       = PIO_PC27_IDX,
            .mosi_flags = IOPORT_MODE_MUX_C,
        },
        .dma = {
            .tx_dma_channel = HV_DMA_HW_CH_TX_2,
            .tx_dma_hw_id   = HV_DMA_HW_INTF_TX_2,
            .rx_dma_channel = HV_DMA_HW_CH_RX_2,
            .rx_dma_hw_id   = HV_DMA_HW_INTF_RX_2,
        },
    },
};

中断和复位设置

static const IPinsAvianConfig_t BoardRadarPinsConfigAvianHatvanLegacy[] = {
    [0] = {
        .gpioReset = GPIO_ID('A', 0),
        .gpioIrq   = GPIO_ID('C', 6),
    },
    [1] = {
        .gpioReset = GPIO_ID('A', 17),
        .gpioIrq   = GPIO_ID('C', 11),
    },
};

平台初始化, 这里有点迷惑, 通常初始化都是按照上面的配置进行初始化, 但是这里的init是将所有的spi, ldo , LevelShifter, connector都初始化. 就是全都配置出来, 没有连接的那边的引脚(另外一个connector)其实都是打开的, 只不过没有数据通路.

PlatformSpi_initialize(BoardSpiDefinition, m_shieldConnectorCount);

--> inter  PlatformSpi_initialize :
 for (unsigned int i = 0; i < m_count; i++)
    {
        PlatformSpiDefinition_t *device = &m_definition[i];



    return E_SUCCESS;

接下来就是对LED的常规设置

// initialize LedSequence to be used for potential error signaling during detection
    LedSequence_Constructor();
    LedSequence_setStatus(LED_STATUS_OPERATING);

再往后就是shield的错误检测, 如果shield没有错误就把LDO打开, 电平转换打开(使能connector)

static sr_t Board_detectShields(void)
{
    /* Checks both connectors for unsupported or wrongly connected shields.
     * In case no errors are detected, both connectors will be enabled,
     * in order to allow radar device detection.
     */
    for (uint8_t shieldId = 0; shieldId < m_shieldConnectorCount; shieldId++)
    {
        // detect the presence of a shield by probing the I2C lines
        const sr_t detection = ShieldConnector_detect(&ShieldConnectorDefinition[shieldId], shieldId);
        switch (detection)
        {
            case E_NOT_AVAILABLE:  // allow shields without I2C bus
                /*  no break */
            case E_SUCCESS:
                break;
            case E_NOT_POSSIBLE:
                LedSequence_setRbbStatus(RBB_ERROR_HARDWARE_CONNECTED_WRONG);
                return E_NOT_POSSIBLE;
                break;
            case E_NOT_SUPPORTED:
                LedSequence_setRbbStatus(RBB_ERROR_HARDWARE_NOT_SUPPORTED);
                return E_NOT_SUPPORTED;
                break;
            default:
                LedSequence_setRbbStatus(RBB_ERROR_HARDWARE_INTERNAL_ERROR);
                return detection;
                break;
        }

        // power-up shield and configure its level shifters
        ShieldConnector_enable(&ShieldConnectorDefinition[shieldId], shieldId, true);
    }

    return E_SUCCESS;
}

shield没有问题利用所有配置创建雷达对象,

 radar = Board_detectRadar(gpio, spi, i2c, &m_data);

下面是具体雷达对象创建

static IRadar *Board_detectRadar(IGpio *gpio, ISpi *spi, II2c *i2c, IData **data)
{
   // 遍历所有shield
    for (uint8_t shieldId = 0; shieldId < m_shieldConnectorCount; shieldId++)
    {
        // 如果要是第二个shield, 就交换配置, 将配置交换到第一个配置位置
        if (m_shieldConnectorCount == 2)
        {
            if (shieldId == 1)
            {
                PlatformInterfaces_swapI2cIds();
                Board_swapSpiIds();
            }
        }

        const sr_t avianDetection = Avian_Detect(spi, gpio, &BoardRadarConfigAvian[shieldId], &BoardRadarPinsConfigAvian[shieldId]);
        if (avianDetection == E_SUCCESS)
        {
            Avian_Constructor(&m_avian, &DataAvian, gpio, spi, &BoardRadarConfigAvian[shieldId], &BoardRadarPinsConfigAvian[shieldId]);
            DataAvian_Constructor(Board_acquisitionStatusCallback);
            DataAvian_setBuffer(BoardRadarConfigAvian[shieldId].dataIndex, m_dataBuffer, DATA_BUFFER_SIZE);
            DataAvian_registerInterrupt(BoardRadarConfigAvian[shieldId].dataIndex, &BoardIrqPinsConfigAvian[shieldId]);
            *data = &DataAvian;

            // 如果这里第一次配置成功就直接跳出该函数了, 就不会执行shield2 的配置.
            return (IRadar *)&m_avian;
        }

到此所有的脚位配置信息完成


接下来进行定制配置项目的构建.

  • 构建的部分包括uart, LDO, SPI, IRQ,Rst
  • 使用S2_SPI 所以需要配置LDO2

所需要的引脚配置如下

option PIn
UART_RX PD25
UART_TX PD26
LDO_2 PC31
IRQ PC11 (LOW)
RST PA17 (LOW)
S2_SPI_CLK PC24
S2_SPI_CS PC25(LOW)
S2_SPI_ MOSI PC27
S2_SPI_ MISO PC26

下面进行相关的配置部分.

S2_SPI 原理图

LDO 配置

Chip enable: Applying VEN < 0.4 V disables the regulator, Pulling VEN > 1.2 V enables the LDO

将 LDO 打开, 将输出的电源给到levelShifter, 进行下一步操作.

level enable
Low False
High True

根据原理图进行 LDO 引脚设置, LDO 的设置, 直接配置成默认拉高使能.

电平转化配置(Level Shifter Config)

电平转换, 的功能是将 mcu 的 3.3v 电平转换为 1.8v 电平和 radar 芯片的 spi 进行通信.

但是对于SN74AVC4T245RSVR这款电源芯片需要等待电平稳定后再输出, 所以使能LDO将电源提供给LevelShifter之后, 等待一段时间后再使能电平转换芯片.

对于该款电平转换芯片, 不仅有使能引脚 ( 控制开关) , 默认状态下是low (打开)

Sx_SPI_OEn level enable
high False
low True

还有方向控制引脚 ( 控制转换方向 ), 默认状态下是High(MCU → sensor)

Sx_SPI_DIR level direction
high MCU → sensor
low MCU ← sensor

从此往下的内容, 是没有调试工具的时候的代码猜测, 不需要关注


shield 型号判断

如果无法判断型号是 HatvanLegacyHatvanPlus 时可以使能ldo_en 引脚, 这里是个人提供的方案.

官方方案是使能LDO2然后检测PA8引脚是否拉高来判断是否为Legacy

version LDO_en
HatvanLegacy C31
HatvanPlus C30

connector.h

然后到connecter 测量电压, 电平转换默认是正确配置, 查看是否能够检测到 LDO 电源(最好使能前后对比测量).