SPI

简要说明

SPI(Serial Peripheral Interface)是一种高速的、全双工、同步的通信总线。SPI以主从方式工作,通常有一个主设备和一个或多个从设备。

SPI 控制器的信号线描述如下:

  • MISO:主设备数据输入,从设备数据输出;
  • MOSI:主设备数据输出,从设备数据输入;
  • SCLK: 时钟信号,由主设备产生;
  • SS:从设备使能信号,由主设备控制。这个信号可以是SPI外设的一部分,也可用GPIO引脚实现。

SPI 典型接线方式如下:

SPI总线支持的四种工作方式,取决于串行同步时钟极性(CPOL)和串行同步时钟相位CPHA的组合。

四种工作方式时序描述如下:

CPOL是用来决定SCLK时钟信号空闲时的电平,CPOL=0,空闲电平为低电平,CPOL=1时,空闲电平为高电平。CPHA是用来决定采样时刻的,CPHA=0,在每个周期的第一个时钟沿采样,第二个时钟沿数据输出;CPHA=1,在每个周期的第二个时钟沿采样,第一个时钟沿数据输出。SPI主模块和与之通信的外设时钟相位和极性应该一致。

接口描述

csi_spi_initialize

spi_handle_t csi_spi_initialize(int32_t idx, spi_event_cb_t cb_event)
  • 功能描述:

    • 通过设备号初始化对应的spi实例,返回spi实例的句柄。
  • 参数:

    • idx: 设备号。

    • cb_event: spi实例的事件回调函数(一般在中断上下文执行)。回调函数原型定义见spi_event_cb_t。

      回调函数类型iic_event_cb_t定义如下:

      typedef void (*spi_event_cb_t)(int32_t idx, spi_event_e event);
      

      其中idx为设备号,event 为传给回调函数的事件类型,spi 回调事件枚举类型 spi_event_e

  • 返回值:

    • NULL: 初始化失败。
    • 其它: 实例句柄。

spi_event_e:

名字 定义 备注
SPI_EVENT_TRANSFER_COMPLETE 传输完成事件
SPI_EVENT_TX_COMPLETE 发送完成事件
SPI_EVENT_RX_COMPLETE 接收完成事件
SPI_EVENT_DATA_LOST 数据丢失事件
SPI_EVENT_MODE_FAULT 模式错误事件

csi_spi_uninitialize

int32_t csi_spi_uninitialize(spi_handle_t handle)
  • 功能描述:

    • spi实例反初始化。该接口会停止spi
    • 实例正在进行的传输(如果有),并且释放相关的软硬件资源。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 错误码。

csi_spi_get_capabilities

spi_capabilities_t csi_spi_get_capabilities(int32_t idx)
  • 功能描述:

    • 获取spi实例支持的能力。
  • 参数:

    • idx: 设备号。
  • 返回值:

    • 描述spi能力的结构体,spi 的能力定义见
    • spi_capabilities_t定义。

spi_capabilities_t:

名字 定义 备注
simplex :1 支持单向传输模式,即半双工模式(主模式或从模式)
ti_ssi :1 支持同步串行接口(SSI)工业通信接口
microwire :1 支持Microwire串行接口
event_mode_fault :1 信号模式故障事件

csi_spi_send

int32_t csi_spi_send(spi_handle_t handle, const void *data, uint32_t num)
  • 功能描述:

    • spi启动数据发送。
  • 参数:

    • handle: 实例句柄。
    • data: 待发送数据的缓冲区地址。
    • num: 待发送数据的长度。
  • 返回值:

    • 错误码。

csi_spi_receive

int32_t csi_spi_receive(spi_handle_t handle, void *data, uint32_t num)
  • 功能描述:

    • spi启动数据接收。
  • 参数:

    • handle: 实例句柄。
    • data: 待接收数据的缓冲区地址。
    • num: 待接收数据的长度。
  • 返回值:

    • 错误码。

csi_spi_transfer

int32_t csi_spi_transfer(spi_handle_t handle, const void *data_out, void *data_in, uint32_t num_out, uint32_t num_in)
  • 功能描述:

    • spi启动数据传输。
  • 参数:

    • handle: 实例句柄。
    • data_out: 待发送数据的缓冲区地址。
    • data_in: 待接收数据的缓冲区地址。
    • num_out: 待发送数据的长度。
    • num_in: 待接收数据的长度。
  • 返回值:

    • 错误码。

csi_spi_abort_transfer

int32_t csi_spi_abort_transfer(spi_handle_t handle)
  • 功能描述:

    • spi数据传输终止。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 错误码。

csi_spi_get_status

spi_status_t csi_spi_get_status(spi_handle_t handle)
  • 功能描述:

    • 获取当前时刻spi的状态。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • spi状态的结构体,spi的状态定义见 spi_status_t的定义。

spi_status_t:

名字 定义 备注
busy : 1 传输或发送忙状态位
data_lost : 1 数据丢失
mode_fault : 1 模式错误

csi_spi_config_mode

int32_t csi_spi_config_mode(spi_handle_t handle, spi_mode_e  mode)
  • 功能描述:

    • 配置spi 实例的主从工作模式。
  • 参数:

    • handle: 实例句柄。
    • mode: spi的主从模式,参看spi_mode_e的定义。
  • 返回值:

    • 错误码。

spi_mode_e:

名字 定义 备注
SPI_MODE_INACTIVE spi闲置
SPI_MODE_MASTER spi全双工主模式
SPI_MODE_SLAVE spi全双工从模式
SPI_MODE_MASTER_SIMPLEX spi半双工主模式
SPI_MODE_SLAVE_SIMPLEX spi半双工从模式

csi_spi_config_block_mode

int32_t csi_spi_config_block_mode(spi_handle_t handle, int32_t flag)
  • 功能描述:

    • 配置spi 实例的阻塞模式。
  • 参数:

    • handle: 实例句柄。
    • flag: 1:开启block模式;0:关闭block模式
  • 返回值:

    • 错误码。

csi_spi_config_baudrate

int32_t csi_spi_config_baudrate(spi_handle_t handle, uint32_t baud)
  • 功能描述:

    • 配置spi 实例的速率。
  • 参数:

    • handle: 实例句柄。
    • baud: spi的波特率。
  • 返回值:

    • 错误码。

csi_spi_config_bit_order

int32_t csi_spi_config_bit_order(spi_handle_t handle, spi_bit_order_e order)
  • 功能描述:

    • 配置spi 实例的数据传输模式。
  • 参数:

    • handle: 实例句柄。
    • order: spi的数据传输模式,参看spi_bit_order_e的定义。
  • 返回值:

    • 错误码。

spi_bit_order_e:

名字 定义 备注
SPI_ORDER_MSB2LSB 高位(MSB)在前,低位(LSB)在后
SPI_ORDER_LSB2MSB 低位(LSB)在前,高位(MSB)在后

csi_spi_config_datawidth

int32_t csi_spi_config_datawidth(spi_handle_t handle, uint32_t datawidth)
  • 功能描述:

    • 配置spi 实例的工作模式。
  • 参数:

    • handle: 实例句柄。
    • datawidth: spi的数据位宽。
  • 返回值:

    • 错误码。

csi_spi_config_format

int32_t csi_spi_config_format(spi_handle_t handle, spi_format_e format)
  • 功能描述:

    • 配置spi 实例的极性和相位模式。
  • 参数:

    • handle: 实例句柄。
    • format: spi的工作模式,参看 spi_format_e的定义。
  • 返回值:

    • 错误码。

spi_format_e:

名字 定义 备注
SPI_FORMAT_CPOL0_CPHA0 空闲电平为低电平,第1个时钟沿采样
SPI_FORMAT_CPOL0_CPHA1 空闲电平为低电平,第2个时钟沿采样
SPI_FORMAT_CPOL1_CPHA0 空闲电平为高电平,第1个时钟沿采样
SPI_FORMAT_CPOL0_CPHA1 空闲电平为高电平,第2个时钟沿采样

csi_spi_config_ss_mode

int32_t csi_spi_config_ss_mode(spi_handle_t handle, spi_ss_mode_e ss_mode)
  • 功能描述:

    • 配置spi 实例的从设备选择模式。
  • 参数:

    • handle: 实例句柄。
    • ss_mode: spi的从设备使能模式,参看:spi_ss_mode_e的定义。
  • 返回值:

    • 错误码。

spi_ss_mode_e:

名字 定义 备注
SPI_SS_MASTER_UNUSED 从设备使能主模式未使能
SPI_SS_MASTER_SW 从设备使能主模式软件模式
SPI_SS_MASTER_HW_OUTPUT 从设备使能主模式硬件输出模式
SPI_SS_MASTER_HW_INPUT 从设备使能主模式硬件输入模式
SPI_SS_SLAVE_HW 从设备使能从模式硬件模式
SPI_SS_SLAVE_SW 从设备使能从模式软件模式

csi_spi_get_data_count

uint32_t csi_spi_get_data_count(spi_handle_t handle)
  • 功能描述:

    • 获取设备实例的上一次传输的数据个数。
  • 参数:

    • handle: 实例句柄。
  • 返回值:

    • 上一次传输的数据个数。

csi_spi_power_control

int32_t csi_spi_power_control(spi_handle_t handle, csi_power_stat_e state)
  • 功能描述:

    • 配置设备实例的功耗模式。
  • 参数:

    • handle: 实例句柄。
    • state: 设备实例的功耗模式,参看
    • csi_power_stat_e \<csi_power_stat_e\ * 的定义。
  • 返回值:

    • 错误码。

csi_spi_ss_control

int32_t csi_spi_ss_control(spi_handle_t handle, spi_ss_stat_e stat)
  • 功能描述:

    • 控制从设备实例的选择信号状态。
  • 参数:

    • handle: 实例句柄。
    • stat: 设备选择信号状态,见 spi_ss_stat_e定义。
  • 返回值:

    • 错误码。

spi_ss_stat_e:

名字 定义 备注
SPI_SS_INACTIVE 从设备选择信号无效
SPI_SS_ACTIVE 从设备选择信号有效

示例

SPI示例1

static spi_handle_t spi_handle;

static void spi_event_cb_fun(int32_t idx, spi_event_e event)
{
    //do your job here according to event
}

void example_main(void)
{
    spi_capabilities_t cap;
    int32_t ret;
    uint8_t send_buf[8] ={0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8};
    uint8_t recv_buf[8];
    uint8_t i;

    spi_handle = csi_spi_initialize(1,spi_event_cb_fun);
    if (spi_handle == NULL) {
        //fail
        return;
    }

    ret = csi_spi_power_control(spi_handle, DRV_POWER_FULL);
    if (ret < 0) {
       // power control failed
        return;
    }

    //get spi capabilities
    cap = csi_spi_get_capabilities(1);
    printf("spi %s simplex mode\n",cap.simplex==1 ? "supports":"not supports");
    printf("spi %s TI Synchronous Serial Interface\n",cap.ti_ssi==1 ? "supports":
           "not supports");
    printf("spi %s Microwire Interface\n",cap.microwire==1 ? "supports":"not supports");
    printf("spi %s signal mode fault event\n",cap.event_mode_fault==1 ? "have":
           "have not");

    //config spi as: baud 115200,master mode ,mode= 0,MSB2LSB, 7bit
    ret = csi_spi_config_mode(spi_handle, SPI_MODE_MASTER);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_block_mode(spi_handle, 1);
        if (ret < 0) {
            //config fail
        return ;
    }

    ret = csi_spi_config_baudrate(spi_handle, 115200);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_datawidth(spi_handle, 8);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_bit_order(spi_handle, SPI_ORDER_MSB2LSB);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_format(spi_handle, SPI_FORMAT_CPOL0_CPHA0);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_send(spi_handle, send_buf, sizeof(send_buf));
    if (ret < 0) {
        //send data failed
        return;
    }
    //check send result here
    ret = csi_spi_receive(spi_handle, recv_buf, sizeof(recv_buf));
    if (ret < 0) {
        //receive data failed
        return;
    }
    //check receive result here

    for (i = 0; i < sizeof(send_buf); i++) {
        if (send_buf[i] != recv_buf[i]) {
            // send and receive data failed
            return;
        }
    }

    ret = csi_spi_power_control(spi_handle, DRV_POWER_OFF);
    if (ret < 0) {
       // power control failed
        return;
    }

    //uninitialize spi 
    ret = csi_spi_uninitialize(spi_handle);
    if (ret != 0) {
       //failed
    }
}

SPI示例2

static spi_handle_t spi_handle;

static void spi_event_cb_fun(int32_t idx, spi_event_e event)
{
    //do your job here according to event
}

void example_main(void)
{
    int32_t ret;
    uint8_t send_buf[8] ={0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8};
    uint8_t recv_buf[8];
    uint8_t i;

    spi_handle = csi_spi_initialize(1, spi_event_cb_fun);
    if (spi_handle == NULL) {
        //failed
        return;
    }

    ret = csi_spi_power_control(spi_handle, DRV_POWER_FULL);
    if (ret < 0) {
       // power control failed
        return;
    }

    //config spi as: baud 115200,master mode ,mode= 0,MSB2LSB, 7bit
    ret = csi_spi_config_mode(spi_handle, SPI_MODE_MASTER);
        if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_block_mode(spi_handle, 1);
        if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_baudrate(spi_handle, 115200);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_datawidth(spi_handle, 8);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_bit_order(spi_handle, SPI_ORDER_MSB2LSB);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_config_format(spi_handle, SPI_FORMAT_CPOL0_CPHA0);
    if (ret < 0) {
        //config fail
        return ;
    }

    ret = csi_spi_transfer(spi_handle, send_buf, recv_buf, sizeof(send_buf), sizeof(recv_buf));
    if (ret < 0) {
        //spi transfer failed
        return;
    }

    for (i = 0; i < sizeof(send_buf); i++) {
        if (send_buf[i] == recv_buf[i]) {
            // send and receive data should not same
            break;
        }
    }

    ret = csi_spi_power_control(spi_handle, DRV_POWER_OFF);
    if (ret < 0) {
        // power control failed
        return;
    }

    //uninitialize spi
    ret = csi_spi_uninitialize(spi_handle);
        if (ret != 0) {
        //failed
    }
}

results matching ""

    No results matching ""