20

IMXRT学习记录 – FlexIO

 4 years ago
source link: https://www.taterli.com/7030/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在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提供了很多配置代码.

3ARZvuj.png!web

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK