IMXRT学习记录 – FlexIO

在i.MX上有很多Flex的外设,他们都非常的Flexable,其中最为变态的应该是FlexIO,因为他什么协议都能做,发生个I2C,SPI,PWM,8080刷屏当然很轻松,驱动WS2812之类的也不在话下.

  • 具有发送,接收和数据匹配模式的32位移位寄存器阵列
  • 双缓冲区实现连续数据传输
  • 支持大量数据传输
  • 自动启动/停止位生成
  • 支持并行或1,2,4,8,16,32位串行操作
  • 中断,DMA或轮询收发操作
  • 独立时钟,STOP模式下依然可以工作
  • 高度灵活的16位定时器,支持各种触发
  • 可编程状态机,8状态8输出3输入

如果之前接触过NXP家族的SGPIO,会发现,这是多么惊人的相似.

实际上,FlexIO是配置两个函数,一个是时基,一个是特定时刻需要发生的事情.

FLEXIO_SetShifterConfig和FLEXIO_SetTimerConfig 函数,对应两个关键结构体flexio_shifter_config_t和flexio_timer_config_t.

/*! @brief Define FlexIO timer configuration structure. */
typedef struct _flexio_timer_config
{
    /* Trigger. */
    uint32_t triggerSelect;                          //触发源选择,即满足触发条件定时器开始工作(Pin/移位寄存器/定时器)
    flexio_timer_trigger_polarity_t triggerPolarity; //触发极性(高/低)
    flexio_timer_trigger_source_t triggerSource;     //触发源 (内部/外部)
    /* Pin. */
    flexio_pin_config_t pinConfig;     //FlexIO 类型(禁止输出/开漏输出/双向输出/推挽输出)
    uint32_t pinSelect;                //FlexIO 位号(0-31)
    flexio_pin_polarity_t pinPolarity; //FlexIO 极性(*正极性/负极性)
    /* Timer. */
    flexio_timer_mode_t timerMode;                  //定时器工作模式(禁用/双8位波特模式/双八位PWM模式/单16位模式)
    flexio_timer_output_t timerOutput;              //定时器初始状态(逻辑1,并且不受计时器重置的影响/逻辑0,并且不受计时器重置的影响/在启动和重置时为逻辑1/在启动和重置时为逻辑0)
    flexio_timer_decrement_source_t timerDecrement; //配置定时器递减源(FlexIO时钟,移位时钟等于计时器输出/触发输入,移位时钟等于计时器输出/Pin输入,移位时钟等于管脚输入/触发输入,移位时钟等于触发器输入)
    flexio_timer_reset_condition_t timerReset;      //定时器复位条件(禁用/定时器引脚等于定时器输出时/定时器触发器等于定时器输出时/定时器Pin上升沿/触发源上升沿/触发上升或下降缘)
    flexio_timer_disable_condition_t timerDisable;  //定时器失能条件(禁用/定时器N-1禁用/定时器比较匹配/定时器比较匹配和触发低/Pin上升或下降沿/触发高且Pin上升或下降缘/触发下降沿)
    flexio_timer_enable_condition_t timerEnable;    //定时器使能条件(始终启动/定时器N-1启动/触发高/触发高且Pin高/Pin上升沿/Pin上升沿并触发高/触发上升沿/触发上升或下降缘)
    flexio_timer_stop_bit_condition_t timerStop;    //定时器停止位生成(禁用/定时器比较匹配时/定时器失能时/定时器比较匹配或失能时)
    flexio_timer_start_bit_condition_t timerStart;  //定时器开始位生成(禁用/启用)
    uint32_t timerCompare;                          //定时器比较器源(N)
} flexio_timer_config_t;

/*! @brief Define FlexIO shifter configuration structure. */
typedef struct _flexio_shifter_config
{
    /* Timer. */
    uint32_t timerSelect;                          //选中时钟计数器(0-3)时钟源
    flexio_shifter_timer_polarity_t timerPolarity; //时钟极性(在时钟的 低电平/高电平 进行写入读取)
    /* Pin. */
    flexio_pin_config_t pinConfig;     //FlexIO 类型(禁止输出/开漏输出/双向输出/推挽输出)
    uint32_t pinSelect;                //FlexIO 位号(0-31)
    flexio_pin_polarity_t pinPolarity; //FlexIO 极性(*正极性/负极性)
    /* Shifter. */
    flexio_shifter_mode_t shifterMode; //定义位移器工作模式(禁用/接收/发送/匹配存储/匹配连续)
#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH
    uint32_t parallelWidth;                    //并行模式带宽
#endif                                         /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */
    flexio_shifter_input_source_t inputSource; //选择移位器的输入源 (从引脚输入/从移位器输入)
    flexio_shifter_stop_bit_t shifterStop;     //移位器停止条件(禁用/逻辑低电平/逻辑高电平)
    flexio_shifter_start_bit_t shifterStart;   //移位器开始条件(禁用移位器启动位,发送器在启动时加载数据/禁用移位器启动位,发射机在第一次移位时加载数据/逻辑低电平/逻辑高电平)
} flexio_shifter_config_t;

不过,如果要使用FlexIO实现标准协议,不需要记得上面的配置,因为fsl_flex_*.c提供了很多配置代码.

从这里已经可以扩展很多,比如说WS2812可以理解成是特殊波特率的SPI,PWM可以理解成FlexIO定时器比较输出,归零重置.

发表评论

电子邮件地址不会被公开。 必填项已用*标注