Files
CHJ/user/MCU/lhl_xlink.c
2026-03-20 21:19:53 +08:00

122 lines
5.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "../main/SystemInclude.h"
//void XLINK_Init(XLINK0_INPUT_SOURCE_t input_src , XLINK0_OUTPUT_PORT_t output_src)
/**------------------------------------------------------------------------
* @brief 配置 LPTIM 通过 XLINK 触发 ADC 转换
* @param lptimer_x: LPTIM 实例 (LPTIM1 或 LPTIM2)
* @param ADCx: ADC 实例 (ADC_0 或 ADC_1)
* @note 该函数将指定 LPTIM 的中断输出信号通过 XLINK0 直接路由到 ADC 硬件触发输入端。
* 配置后,每当 LPTIM 产生中断事件时,将自动触发 ADC 启动一次单次转换。
* @example:
* XLINK_LPTIM_To_ADC_Trigger(LPTIM1, ADC_0); // LPTIM1 触发 ADC0
* XLINK_LPTIM_To_ADC_Trigger(LPTIM2, ADC_1); // LPTIM2 触发 ADC1
**/
void XLINK_LPTIM_To_ADC_Trigger(LPTIM_TypeDef *lptimer_x, ADC_ID_t ADCx)
{
uint32_t input_src, output_src;
XLINK_InitTypeDef XLINK_InitStructure;
/* 参数合法性检查 */
if (lptimer_x != LPTIM1 && lptimer_x != LPTIM2) return;
if (ADCx != ADC_0 && ADCx != ADC_1) return;
/* 1. 根据LPTIMER选择输入源 */
/* 2. 根据ADC选择输出源 */
// if(lptimer_x == LPTIM1) input_src = XLINK0_INPUT_LPTIM1_INT; //XLINK0_INPUT_LPTIM1_INT XLINK0_INPUT_XB_IN2
// else if(lptimer_x == LPTIM2) input_src = XLINK0_INPUT_LPTIM2_INT;
// else return;
// if(ADCx == ADC_0) output_src = XLINK0_OUTPUT_ADC0_TRIG;
// else if(ADCx == ADC_1) output_src = XLINK0_OUTPUT_ADC1_TRIG;
// else return;
/* 根据 LPTIM 选择 XLINK0 输入源 */
input_src = (lptimer_x == LPTIM1) ? XLINK0_INPUT_LPTIM1_INT : XLINK0_INPUT_LPTIM2_INT;
/* 根据 ADC 选择 XLINK0 输出源 */
output_src = (ADCx == ADC_0) ? XLINK0_OUTPUT_ADC0_TRIG : XLINK0_OUTPUT_ADC1_TRIG;
/* 3. 配置XLINK路由 */ // XLINK0_INPUT_PMU
XLINK_InitStructure.XLink_0_Input = input_src;
XLINK_InitStructure.XLink_0_Output = output_src;
LHL_XLINK_Init(&XLINK_InitStructure);
}
/**------------------------------------------------------------------------
* @brief 配置 RTC 闹钟通过 XLINK 触发 ADC 转换
* @param ADCx: ADC 实例 (ADC_0 或 ADC_1)
* @note 该函数将 RTC 闹钟信号通过 XLINK0 直接路由到 ADC 硬件触发输入端。
* 配置后,每当 RTC 闹钟事件发生时,将自动触发 ADC 启动一次单次转换。
* @example:
* XLINK_RTC_ALARM_To_ADC_Trigger(ADC_0); // RTC 闹钟触发 ADC0
* XLINK_RTC_ALARM_To_ADC_Trigger(ADC_1); // RTC 闹钟触发 ADC1
**/
void XLINK_RTC_ALARM_To_ADC_Trigger(ADC_ID_t ADCx)
{
uint32_t input_src, output_src;
XLINK_InitTypeDef XLINK_InitStructure;
/* 参数合法性检查 */
if (ADCx != ADC_0 && ADCx != ADC_1) return;
/* 1. 选择输入源 */
input_src = XLINK0_INPUT_RTC_ALARM;
/* 2. 根据ADC选择输出源 */
output_src = (ADCx == ADC_0) ? XLINK0_OUTPUT_ADC0_TRIG : XLINK0_OUTPUT_ADC1_TRIG;
/* 3. 配置XLINK路由 */
XLINK_InitStructure.XLink_0_Input = input_src;
XLINK_InitStructure.XLink_0_Output = output_src;
LHL_XLINK_Init(&XLINK_InitStructure);
}
/**------------------------------------------------------------------------
* @brief 配置 GPIO 引脚通过 XLINK 触发 ADC支持取反
* @param GPIOx: GPIO 端口 (pGPIO0/pGPIO1/pGPIO2)
* @param pin_pos: 引脚位置 (0~3仅支持 XB_IN 功能的引脚)
* @param ADCx: ADC_0 或 ADC_1
* @param invert: ENABLE 取反DISABLE 不取反
* @note
* - 不取反时:将 GPIO 的 XB_IN 信号直接通过 XLINK0 路由到 ADC 触发。
* - 取反时:先通过 XLINK1 将信号取反输出到 LU_OUT0再通过 XLINK0 路由到 ADC 触发。
* 取反可用于改变信号边沿(如下降沿转上升沿)以匹配 ADC 触发要求。
* @example:
* XLINK_GPIO_To_ADC_Trigger(pGPIO0, 3, ADC_1, ENABLE); // P0.3 取反触发 ADC1
* XLINK_GPIO_To_ADC_Trigger(pGPIO0, 3, ADC_1, DISABLE); // 直接触发 ADC1
**/
void XLINK_GPIO_To_ADC_Trigger(GPIO_TypeDef *GPIOx, uint8_t pin_pos, ADC_ID_t ADCx, FunctionalState invert)
{
/* 仅支持引脚 0~3 */
if (pin_pos > 3) return;
/* 计算 XLINK 输入源(基于连续枚举) */
uint32_t xlink0_input = XLINK0_INPUT_XB_IN0 + pin_pos;
uint32_t xlink1_input = XLINK1_INPUT_XB_IN0 + pin_pos;
/* 初始化 GPIO 为输入,复用为 XB_INAF 值固定为 6 */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = (1 << pin_pos);
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.SchmittTrigger = ENABLE;
GPIO_InitStructure.Alternate = 6; // 所有 XB_IN 的 AF 值均为 6 : GPIO0_1_AF_XB_IN1 GPIO0_2_AF_XB_IN2 GPIO0_3_AF_XB_IN3 GPIO1_0_AF_XB_IN0 .....
LHL_GPIO_Init(GPIOx, &GPIO_InitStructure);
if (invert == ENABLE) {
/* 取反路径XLINK1 取反 -> LU_OUT0 */
LHL_XLINK_InvertSingal((XLINK1_INPUT_SOURCE_t)xlink1_input, XLINK1_OUTPUT_LU_OUT0);
/* XLINK0 路由 LU_OUT0 到 ADC 触发 */
XLINK_InitTypeDef XLINK_InitStructure;
XLINK_InitStructure.XLink_0_Input = XLINK0_INPUT_LU_OUT0;
XLINK_InitStructure.XLink_0_Output = (ADCx == ADC_0) ? XLINK0_OUTPUT_ADC0_TRIG : XLINK0_OUTPUT_ADC1_TRIG;
LHL_XLINK_Init(&XLINK_InitStructure);
} else {
/* 直接路径XLINK0 路由 XB_IN 到 ADC 触发 */
XLINK_InitTypeDef XLINK_InitStructure;
XLINK_InitStructure.XLink_0_Input = xlink0_input;
XLINK_InitStructure.XLink_0_Output = (ADCx == ADC_0) ? XLINK0_OUTPUT_ADC0_TRIG : XLINK0_OUTPUT_ADC1_TRIG;
LHL_XLINK_Init(&XLINK_InitStructure);
}
}