Abstract
上个文档描述的是整个项目的创建原因, 工程创建
, 工程导入
.
这个文档是进行具体的项目的配置, 根据原理图进行引脚信息, 从代码进行梳理, 一步一步确认引脚, 以及代码框架
我们需要配置的项:
- uart
- spi
- ldo
- RST
- IRQ
编译该工程注意路径中不能有空格!!!!!
Referance
rbb7 原理图文件: RBB_MCU7_V2.2-schematics.pdf
安森美 LDO dataSheet TI Level Shifter dataSheet:
UART 配置
这里的 uart 预留的是PD24
和PD25
, 我们芯片的该引脚也配置为如图的Rx
和Tx
.
进入到可视化配置界面, 搜索选择usart
, add
进行调整引脚, , 选择uart2
配置到PD25
和 PD26
需要调整的位置
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 |
在项目中的配置是按照如下代码部分进行配置的, MCU7
是Legacy
版本, 所以对应的是两个链接器. debug 和代码中显示的都是两个, 链接器, HatvanPlus 只有一个 LDO. ( 代码中的注释有点迷惑, 一直以为是 HatvanPlus
其实是 Legacy
)
按照如下配置进行配置雷达的驱动引脚配置, 就是没问题的. 调整 mcu 也只需调整这几个配置即可.
// detect board type
const bool isHatvanLegacy = Board_isHatvanLegacy();
if (isHatvanLegacy)
{
= &ShieldConnectorDefinitionHatvanLegacy[0];
ShieldConnectorDefinition = &BoardSpiDefinitionHatvanLegacy[0];
BoardSpiDefinition = &BoardRadarPinsConfigAvianHatvanLegacy[0];
BoardRadarPinsConfigAvian = ARRAY_SIZE(ShieldConnectorDefinitionHatvanLegacy);
m_shieldConnectorCount }
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
)其实都是打开的, 只不过没有数据通路.
(BoardSpiDefinition, m_shieldConnectorCount);
PlatformSpi_initialize
--> inter PlatformSpi_initialize :
for (unsigned int i = 0; i < m_count; i++)
{
*device = &m_definition[i];
PlatformSpiDefinition_t
return E_SUCCESS;
接下来就是对LED
的常规设置
// initialize LedSequence to be used for potential error signaling during detection
();
LedSequence_Constructor(LED_STATUS_OPERATING); LedSequence_setStatus
再往后就是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:
(RBB_ERROR_HARDWARE_CONNECTED_WRONG);
LedSequence_setRbbStatusreturn E_NOT_POSSIBLE;
break;
case E_NOT_SUPPORTED:
(RBB_ERROR_HARDWARE_NOT_SUPPORTED);
LedSequence_setRbbStatusreturn E_NOT_SUPPORTED;
break;
default:
(RBB_ERROR_HARDWARE_INTERNAL_ERROR);
LedSequence_setRbbStatusreturn detection;
break;
}
// power-up shield and configure its level shifters
(&ShieldConnectorDefinition[shieldId], shieldId, true);
ShieldConnector_enable}
return E_SUCCESS;
}
shield
没有问题利用所有配置创建雷达对象,
= Board_detectRadar(gpio, spi, i2c, &m_data); radar
下面是具体雷达对象创建
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)
{
(&m_avian, &DataAvian, gpio, spi, &BoardRadarConfigAvian[shieldId], &BoardRadarPinsConfigAvian[shieldId]);
Avian_Constructor(Board_acquisitionStatusCallback);
DataAvian_Constructor(BoardRadarConfigAvian[shieldId].dataIndex, m_dataBuffer, DATA_BUFFER_SIZE);
DataAvian_setBuffer(BoardRadarConfigAvian[shieldId].dataIndex, &BoardIrqPinsConfigAvian[shieldId]);
DataAvian_registerInterrupt*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 型号判断
如果无法判断型号是 HatvanLegacy
和 HatvanPlus
时可以使能ldo_en
引脚, 这里是个人提供的方案.
官方方案是
使能LDO2
然后检测PA8引脚是否拉高来判断是否为Legacy
version | LDO_en |
---|---|
HatvanLegacy | C31 |
HatvanPlus | C30 |
connector.h
然后到connecter
测量电压, 电平转换默认是正确配置, 查看是否能够检测到 LDO 电源(最好使能前后对比测量
).