IMX6ULL裸机-3-SPI控制器

发布时间:2024-07-03  

1 IMX6ULL SPI控制器

NXP的6ull参考手册第Chapter 20介绍了SPI控制器,Enhanced Configurable SPI (ECSPI) 。

1.1 特点

①、全双工同步串行接口。 ②、可配置的主/从模式。 ③、四个硬件片选信号,支持多从机。 ④、发送和接收都有一个 32x64 的 FIFO。 ⑤、片选信号 SS/CS,时钟信号 SCLK 的极性相位(CPOL,CPHA)可配置。 ⑥、支持 DMA ⑦、SCK最高可以到输入参考时钟高达60Mhz

1.2 框图


最右边是引脚,SCLK,MISO,MOSI等,上面是外围总线,通过APB总线进行寄存器读写,INTREG,CONREG等等。TXDATA和TXDATA寄存器存放了要发送的数据和接收的收据。 时钟源来自Reference Clock or Low Frequency Clock。可选时钟源如下:这里选用ecspi_clk_root。


① CSCDR2的ECSPI_CLK_SEL位设置为0,选择出PLL3_SW_CLK 进行8分频作为 ECSPI 根时钟源。PLL3_SW_CLK=480MHz,8分频就是60MHz。 ② CSCDR2 的 ECSPI_CLK_PODF位再次进行分频,ECSPI_CLK_PODF位设置成0,表示2^0分频,也就是1分频。 ③ 最后ECSPI_CLK_ROOT就为60MHz

1.3 时序

CPOL时钟极性 和CPHA时钟相位组合成了4种模式:

CPOL:表示SPI CLK的初始电平(空闲状态时电平),0为低电平,1为高电平
CPHA:表示相位,即第一个还是第二个时钟沿采样数据,0为第一个时钟沿,1为第二个时钟沿



2 IMX6ULL SPI控制器寄存器描述

控制器初始化流程: CONREG[EN]:复位,0表示复位 CCM开启ECSPI时钟 CONREG[EN]:复位,1表示反选复位

RXDATA寄存器:接收数据寄存器,RR位的状态决定接受数据是否就绪

TXDATA寄存器:发送数据寄存器,实际传输的位数由相应SPI控制寄存器的BURST_LENGTH位来决定。


CONREG寄存器:控制寄存器

EN:使能位,1为使能 SMC:为1表示当数据写入TXFIFO时,立即启动SPI突发;这里使用该模式 CHANNEL_MODE:硬件片选模式选择,bit[7:4]分别表示通道3到通道0,这里采用通道0设定为Master mode.因此bit[7:4]配置成1 POST_DIVIDER:后分频,0到15表示2^n次方分频,比如0就是1分频,15就是2^15分频 PRE_DIVIDER:前分频,0到15表示1到16分频 前面spi clk的时钟源为ECSPI_CLK_ROOT 60MHz,这里我们用6MHz,因此可以设置POST_DIVIDER=0,PRE_DIVIDER=9,表示10分频。 CHANNEL_SELECT:通道选择,也就是硬件片选SS选择,这里选择SS0,通道0 BURST_LENGTH:突发访问长度,这里我们用一次突发8bit, 配置成0x7

CONFIGREG寄存器:配置寄存器

SCLK_PHA:时钟相位,SCLK_PHA[3:0]分别对应通道3~0,设置为0表示第一个时钟沿采集数据,设置成1表示第二个时钟沿采集数据。(同POL组成4种模式) SCLK_POL:时钟极性,表示时钟初始空闲时的电平,0为低电平,1为高电平。(同PHA组成4种模式) SS_CTL:硬件片选的wave form select,这个用不上设置成0 SS_POL:硬件片选的极性选择,用不上设置成0 DATA_CTL:数据线空闲时电平状态,我们设置成0表示高电平 SCLK_CTL:时钟线空闲时电平状态,我们设置成0表示低电平(POL设置了时钟初始空闲时的电平为低电平) HT_LENGTH: HT Mode不用,无需配置

STATREG寄存器:状态寄存器

TE:TXFIFO empty, 为1表示TXFIFO为空,0表示TXFIFO还没空,因此往TXDATA发送数据时,需要先等待TXFIFO为空。 RR: RXFIFO Ready,1表示有数据,0表示数据还没ready.读取RXDATA需要等RXFIFO先ready。

PERIODREG寄存器:采样周期寄存器

SAMPLE_ PERIOD:突发访问时的等待周期,表示等待多少个时钟周期后进行一下次突发访问。我们设置为0x2000。

CSRC: 等待周期的单位,0表示以SPI clk为单位, 1表示以low-frequency reference clk 32.768KHz为单位。 CSD_CTL:硬件片选延时,表示片选后多少个时钟周期才可以进行数据传输。(这里不用,我们用软件片选)

3 IMX6ULL SPI控制器代码编写

void spi_init(ECSPI_Type *base)

{

    /* 配置CONREG寄存器

     * bit0 :       1   使能ECSPI

     * bit3 :       1   当向TXFIFO写入数据以后立即开启SPI突发。

     * bit[7:4] :   0001 SPI通道0主模式,根据实际情况选择,

     *                  开发板上的ICM-20608接在SS0上,所以设置通道0为主模式

     * bit[19:18]:  00  选中通道0(其实不需要,因为片选信号我们我们自己控制)

     * bit[31:20]:  0x7 突发长度为8个bit。 

     */

    base->CONREG = 0; /* 先清除控制寄存器 */

    base->CONREG |= (1 << 0) | (1 << 3) | (1 << 4) | (7 << 20); /* 配置CONREG寄存器 */


    /*

     * ECSPI通道0设置,即设置CONFIGREG寄存器

     * bit0:    0 通道0 PHA为0

     * bit4:    0 通道0 SCLK高电平有效

     * bit8:    0 通道0片选信号 当SMC为1的时候此位无效

     * bit12:   0 通道0 POL为0

     * bit16:   0 通道0 数据线空闲时高电平

     * bit20:   0 通道0 时钟线空闲时低电平

     */

    base->CONFIGREG = 0;        /* 设置通道寄存器 */


    /*  

     * ECSPI通道0设置,设置采样周期

     * bit[14:0] :  0X2000  采样等待周期,比如当SPI时钟为10MHz的时候

     *              0X2000就等于1/10000 * 0X2000 = 0.8192ms,也就是连续

     *              读取数据的时候每次之间间隔0.8ms

     * bit15     :  0  采样时钟源为SPI CLK

     * bit[21:16]:  0  片选延时,可设置为0~63

     */

    base->PERIODREG = 0X2000;       /* 设置采样周期寄存器 */


    /*

     * ECSPI的SPI时钟配置,SPI的时钟源来源于pll3_sw_clk/8=480/8=60MHz

     * 通过设置CONREG寄存器的PER_DIVIDER(bit[11:8])和POST_DIVEDER(bit[15:12])来

     * 对SPI时钟源分频,获取到我们想要的SPI时钟:

     * SPI CLK = (SourceCLK / PER_DIVIDER) / (2^POST_DIVEDER)

     * 比如我们现在要设置SPI时钟为6MHz,那么PER_DIVEIDER和POST_DEIVIDER设置如下:

     * PER_DIVIDER = 0X9。

     * POST_DIVIDER = 0X0。

     * SPI CLK = 60000000/(0X9 + 1) = 60000000=6MHz

     */

    base->CONREG &= ~((0XF << 12) | (0XF << 8));    /* 清除PER_DIVDER和POST_DIVEDER以前的设置 */

    base->CONREG |= (0X9 << 12);                    /* 设置SPI CLK = 6MHz */

}


/*

 * @description     : SPI通道0发送/接收一个字节的数据

 * @param - base    : 要使用的SPI

 * @param - txdata  : 要发送的数据

 * @return          : 无

 */

unsigned char spich0_readwrite_byte(ECSPI_Type *base, unsigned char txdata)

    uint32_t  spirxdata = 0;

    uint32_t  spitxdata = txdata;


    /* 选择通道0 */

    base->CONREG &= ~(3 << 18);

    base->CONREG |= (0 << 18);


    while((base->STATREG & (1 << 0)) == 0){} /* 等待发送FIFO为空 */

        base->TXDATA = spitxdata;


    while((base->STATREG & (1 << 3)) == 0){} /* 等待接收FIFO有数据 */

        spirxdata = base->RXDATA;

    return spirxdata;

}


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>