SPI使用参考


1. 概述

1.1. SPI概述

本文介绍了主SPI(MSPI)控制器。 MSPI是一个同步串行接口,可以连接各种外部设备。

1.2. MSPI特点

  • 具有半双工的通用SPI协议。

  • 支持Motorola SPI兼容时序。(CPHA / CPOL)

  • 8字节读写缓冲区。

  • 字节传输1位到8位可配置位宽度。

  • 最多支持8个从设备选择信号。

  • 支持3线模式。

  • 支持内部RIU(寄存器接口单元)接口。 RIU是SigmaStar的内部协议。

1.3. MSPI框图

图1-1


2. SPI控制

2.1. SPI控制概述

本节对启用MSPI前寄存器的初始化、MSPI的触发以及MSPI状态检查进行介绍。

2.2. 寄存器初始化

MSPI可配置参数如下图所示:

图2-1

  1. 直流时序设置

    “tr_start”: SCZ有效设置时间(相对于SCK)

    “tr_end”: SCZ有效保持时间(相对于SCK)

    “tb” : 帧传输之间的延迟周期

    “trw”: 最后一次写入和第一次读取之间的延迟周期。 (读取回转周期)

  2. 写入/读取帧长度设置 (0x111098, 0x11109C)

    帧长:0~8 Bytes

  3. 每帧读/写位长度设置 (0x111098, 0x11109C)

    位长: 1~ 8 bit

  4. 时钟和相位控制 (0x111092)

    时钟设置:

    3'b000: CPU_CLOCK/2  
    3'b001: CPU_CLOCK/4  
    3'b010: CPU_CLOCK/8  
    3'b011: CPU_CLOCK/16  
    3'b100: CPU_CLOCK/32  
    3'b101: CPU_CLOCK/64  
    3'b110: CPU_CLOCK/128  
    3'b111: CPU_CLOCK/256
    

    Bit[7]: Clock Polarity, CPOL.

    空闲状态下,SCK电平设置

    0: 设为0时是低电平

    1: 设为1时是高电平

    Bit[6]: Clock Phase, CPHA

    0: SCK启用时对日期进行采样。

    1: SCK回到待机状态时对日期进行采样

  5. 重置并启用 (0x111092)

    Bit[2]: 使能MSPI中断

    0: 禁用

    1: 启用

    Bit[1]: 重置

    0: 重置

    1: 保持

    Bit[0]: 启用MSPI

    0: 禁用

    1: 启用

  6. 启用芯片选择 (0x1110BE)

    SPI Device1的芯片选择

    0: 启用

    1: 禁用

2.3. MSPI触发

MSPI触发 (0x1110BE, Bit[0])

  • bit设置为1时,MSPI控制器触发。

  • bit为write-clear寄存器

2.4. MSPI状态

MSPI完成标志 (0x08B6, Bit[0])

  1. MSPI操作完成后,在开始之前硬件将此位置高电平,到下一次数据传输时,SW需要通过(0x80B8,Bit [0])清除该位。

  2. 当MSPI操作完成时,MSPI向CPU、SW发出中断通过(0x08B8,位[0])清除中断。

2.5. MSPI读取数据端口

MSPI操作完成后,SW可以从以下读取端口获取数据

0x111088

0x11108A

0x11108C

0x11108E


3. 示例说明

3.1. SPI操作示例

本节描述了MSPI操作的示例。

(0)初始化

(1)CS变低电平

(2)写入2 Bytes数据

(3)读取1 Bytes的数据

(4)CS变高电平

图3-1

WREG[0x111092] = 0x07  //启用MSPI,不复位,启用INT  
//CPOL =0, CPHA=0

WREG[0x111093] = 0x00                       //MSPI clock = CPU Clock/2  
WREG[0x111094] = 0x00                       //tr_start = 1 Cycle  
WREG[0x111095] = 0x00                       //tr_end = 1 Cycle  
WREG[0x111096] = 0x00                       //tb = 0 cycle  
WREG[0x111097] = 0x00                       //trw = 0 Cycle  
WREG[0x111080] = DATA0                      //Write buffer0  
WREG[0x111081] = DATA1                      //Write buffer1  
WREG[0x111090] = 0x02                       //Write length = 2  
WREG[0x111091] = 0x01                       //Read length = 1  
WREG[0x111098], BIT[2:0] = 3b111            //Bit length=8Bit for write buffer0  
            BIT[5:3] = 3b111            //Bit length=8Bit for write buffer1  
WREG[0x11109c], BIT[2:0] = 3b111            //Bit length=8Bit for read buffer0  
WREG[0x1110BE], BIT[0] = 1b0                //Select cs0  
WREG[0x1110B4], BIT[0] = 1b1                //Trigger MSPI operation  
Done = RREG[0x08B6, Bit[0]]                //Polling MSPI done flag Or interrupt  
WREG[0x1110B8], BIT[0] = 1b1               //Clear done flag or clear interrupt  
WREG[0x1110BE], BIT[0] = 1b1               //Disable cs0

3.2. MSPI Connect to Incense 示例代码

  • Register Write to Incense: WREG[0x5a] = 16’h5555

    WREG[0x111092] = 0x07                       //Enable MSPI, Not Reset, Enable INT                           //CPOL =0, CPHA=0  
    WREG[0x111093] = 0x00                       //MSPI clock = CPU Clock/2  
    WREG[0x111094] = 0x00                       //tr_start = 1 Cycle  
    WREG[0x111095] = 0x01                       //tr_end = 2 Cycle  
    WREG[0x111096] = 0x00                       //tb = 0 cycle  
    WREG[0x111097] = 0x00                       //trw = 0 Cycle  
    WREG[0x111080] = 0x03 (CMD)                 //Write buffer0  
    WREG[0x111081] = 0x5A (ADR)                 //Write buffer1  
    WREG[0x111090] = 0x02                       //Write length = 2  
    WREG[0x111098], BIT[2:0] = 3’b111            //Bit length=8Bit for write buffer0  
    BIT[5:3] = 3’b000            //Bit length=1Bit for write buffer1  
    WREG[0x1110BE], BIT[0] = 1’b0                //Select cs0  
    WREG[0x1110B4], BIT[0] = 1’b1                //Trigger MSPI operation  
    Done = RREG[0x1110B6, Bit[0]]                //Polling MSPI done flag Or interrupt  
    WREG[0x1110B8], BIT[0] = 1’b1               //Clear done flag or clear interrupt  
    WREG[0x1110BE], BIT[0] = 1’b1               //Disable cs0  
    ADR = ADR << 1;  
    WREG[0x111080] = ADR                     //Write buffer0  
    WREG[0x111081] = 0x55(DATA0)             //Write buffer1  
    WREG[0x111082] = 0x55(DATA1)             //Write buffer2  
    WREG[0x111090] = 0x03                    //Write length = 3  
    WREG[0x111098], BIT[2:0] = 3’b110            //Bit length=7Bit for write buffer0  
    BIT[5:3] = 3’b111            //Bit length=8Bit for write buffer1  
    BIT[8:6] = 3’b111            //Bit length=8Bit for write buffer2  
    WREG[0x1110BE], BIT[0] = 1’b0                //Select cs0  
    WREG[0x1110B4], BIT[0] = 1’b1                //Trigger MSPI operation  
    Done = RREG[0x1110B6, Bit[0]]                //Polling MSPI done flag Or interrupt  
    WREG[0x1110B8], BIT[0] = 1’b1               //Clear done flag or clear interrupt  
    WREG[0x1110BE], BIT[0] = 1’b1               //Disable cs0
    
  • Register Read from Incense: RREG[0x5a]

    WREG[0x111092] = 0x07                       //Enable MSPI, Not Reset, Enable INT  
                                            //CPOL =0, CPHA=0  
    WREG[0x111093] = 0x00                       //MSPI clock = CPU Clock/2  
    WREG[0x111094] = 0x00                       //tr_start = 1 Cycle  
    WREG[0x111095] = 0x01                       //tr_end = 2 Cycle  
    WREG[0x111096] = 0x00                       //tb = 0 cycle  
    WREG[0x111097] = 0x00                       //trw = 0 Cycle  
    WREG[0x111080] = 0x06 (CMD)                 //Write buffer0  
    WREG[0x111081] = 0x5A (ADR)                 //Write buffer1  
    WREG[0x111090] = 0x02                       //Write length = 2  
    WREG[0x111098], BIT[2:0] = 3b111            //Bit length=8Bit for write buffer0  
    BIT[5:3] = 3b000            //Bit length=1Bit for write buffer1  
    WREG[0x1110BE], BIT[0] = 1b0                //Select cs0  
    WREG[0x1110B4], BIT[0] = 1b1                //Trigger MSPI operation  
    Done = RREG[0x1110B6, Bit[0]]                //Polling MSPI done flag Or inte rrupt  
    WREG[0x1110B8], BIT[0] = 1b1               //Clear done flag or clear interrupt  
    WREG[0x1110BE], BIT[0] = 1b1               //Disable cs0
    
    ADR = ADR << 1;  
    WREG[0x111080] = ADR                       //Write buffer0  
    WREG[0x111090] = 0x01                      //Write length = 1  
    WREG[0x111098], BIT[2:0] = 3b110            //Bit length=7Bit for write buffer0  
    WREG[0x1110BE], BIT[0] = 1b0                //Select cs0  
    WREG[0x1110B4], BIT[0] = 1b1                //Trigger MSPI operation  
    Done = RREG[0x1110B6, Bit[0]]                //Polling MSPI done flag Or interrupt  
    WREG[0x1110B8], BIT[0] = 1b1               //Clear done flag or clear interrupt
    
    WREG[0x111092], BIT[7:6]= 2b01              //CPOL =0, CPHA=1  
                                            //Change mode for read data  
    WREG[0x111094] = 0x08                       //tr_start = 8 Cycle  
                                                //In this case trw = tr_start  
    WREG[0x111090] = 0x00                       //Write length = 0  
    WREG[0x111091] = 0x02                       //Read length = 2  
    WREG[0x1110B4], BIT[0] = 1b1                //Trigger MSPI operation  
    Done = RREG[0x1110B6, Bit[0]]                //Polling MSPI done flag Or interrupt  
    WREG[0x1110B8], BIT[0] = 1b1               //Clear done flag or clear interrupt  
    WREG[0x1110BE], BIT[0] = 1b1               //Disable cs0
    
    WREG[0x111091] = 0x01                       //Read length = 1  
                                            //Dummy read  
    WREG[0x11109c], BIT[2:0] = 3b000            //Bit length=1Bit for read buffer0  
    WREG[0x1110B4], BIT[0] = 1b1                //Trigger MSPI operation  
    Done = RREG[0x1110B6, Bit[0]]                //Polling MSPI done flag Or interrupt  
    WREG[0x1110B8], BIT[0] = 1b1               //Clear done flag or clear interrupt