SPI接口协议的学习5

SPI接口打开函数说明:
/*
 * @brief 打开spi
 * @parm spi  spi句柄
 * @return 0 成功,< 0 失败
 */
int spi_open(spi_dev spi)//打开spi
{
    int err;
    u8 id = spi_get_info_id(spi);//获取SPI的ID
    u8 port = spi_get_info_port(spi);//获取port
    u8 mode = spi_get_info_mode(spi);//获取mode
    u8 role = spi_get_info_role(spi);//获取role
    u32 clock = spi_get_info_clock(spi);//获取时钟

pSPI_IOMC_CONFIGid;//配置IO映射

spi_set_bit_mode(spi, mode);//设置bit模式
    spi_cs_dis(spi_regs[id]);//禁止片选
    if (role == SPI_ROLE_MASTER) {//如果是主机
        spi_role_master(spi_regs[id]);//配置为主机
    } else if (role == SPI_ROLE_SLAVE) {//如果是从机
        spi_role_slave(spi_regs[id]);//配置为从机
    }
    spi_smp_edge_fall(spi_regs[id]);//在 SPICK 的下降沿采样数据
    spi_ud_edge_fall(spi_regs[id]);//在 SPICK 的下降沿更新数据
    spi_cs_idle_h(spi_regs[id]);// SPICS 空闲时为 1 电平
    spi_clk_idle_l(spi_regs[id]);//SPICK 空闲时为 0 电平
    spi_clr_pnd(spi_regs[id]);//写入‘1’将清除 PND 中断请求标志
    if ((err = spi_set_baud(spi, clock))) {//配置波特率
        log_error(“invalid spi baudrate”);
        /* return 0; */
    }
    spi_w_reg_buf(spi_regs[id], 0);//设定spi初始化后DO口默认电平为低
    spi_enable(spi_regs[id]);//使能SPI

#if 0//调试打印信息
    printf(“spi%d port    = ‘%c’\n”, id, port);
    printf(“spi%d clk     = %d\n”, id, clock);
    printf(“spi%d mode    = %d\n”, id, mode);
    printf(“spi%d role    = %d\n”, id, role);
    printf(“spi%d di_pin  = %d\n”, id, spi_io_map[id].io[port - ‘A’].di_pin);
    printf(“spi%d clk_pin = %d\n”, id, spi_io_map[id].io[port - ‘A’].clk_pin);
    printf(“spi%d do_pin  = %d\n”, id, spi_io_map[id].io[port - ‘A’].do_pin);
    printf(“spi%d d2_pin  = %d\n”, id, spi_io_map[id].io[port - ‘A’].d2_pin);
    printf(“spi%d d3_pin  = %d\n”, id, spi_io_map[id].io[port - ‘A’].d3_pin);
    printf(“spi%d CON     = %04x\n”, id, spi_r_reg_con(spi_regs[id]));
    printf(“spi%d IOMC1   = %08x\n”, id, JL_IOMAP->CON1);
#endif
    return 0;
}

SPI接口的关闭:
/*
 * @brief 关闭spi
 * @parm spi  spi句柄
 * @return null
 */
void spi_close(spi_dev spi)//关闭spi
{
    u8 id = spi_get_info_id(spi);//获取ID
    u8 port = spi_get_info_port(spi);//获取port
    u8 mode = spi_get_info_mode(spi);//获取模式

port -= ‘A’;
    if (id == SPI2 && port + ‘A’ == ‘B’) {//如果是SPI2的B组
        spi_io_port_uninit(spi_io_map[id].io[port].di_pin);//复位DP和DM引脚配置
        JL_USB_IO->CON0 |= BIT(2);  //DP DIR IN
        JL_USB_IO->CON0 |= BIT(3);  //DM DIR IN
        JL_USB_IO->CON0 &= ~BIT(9);  //DP 1.2V digital input dis
        JL_USB_IO->CON0 &= ~BIT(10);  //DM 1.2V digital input dis
    } else {
        spi_io_port_uninit(spi_io_map[id].io[port].clk_pin);//CLK、DO、DI引脚复位
        spi_io_port_uninit(spi_io_map[id].io[port].do_pin);
        if (mode == SPI_MODE_BIDIR_1BIT) {
            spi_io_port_uninit(spi_io_map[id].io[port].di_pin);
        } else if (mode == SPI_MODE_UNIDIR_2BIT) {
            spi_io_port_uninit(spi_io_map[id].io[port].di_pin);
        } else if (mode == SPI_MODE_UNIDIR_4BIT) {
            spi_io_port_uninit(spi_io_map[id].io[port].di_pin);
            spi_io_port_uninit(spi_io_map[id].io[port].d2_pin);
            spi_io_port_uninit(spi_io_map[id].io[port].d3_pin);
        }
    }
    spi_disable(spi_regs[id]);//禁能SPI
}

以下SPI DMA相关函数配置:
/*
 * @brief spi dma接收
 * @parm spi  spi句柄
 * @parm buf  接收缓冲区基地址
 * @parm len  期望接收长度
 * @return 实际接收长度,< 0表示失败
 */
int spi_dma_recv(spi_dev spi, void *buf, u32 len)//spi dma接收
{
    u8 id = spi_get_info_id(spi);//获取ID

/* ASSERT((u32)buf % 4 == 0, “spi dma addr need 4-aligned”); */
    spi_dir_in(spi_regs[id]);//配置为接收数据
    spi_w_reg_dma_addr(spi_regs[id], (u32)buf);//配置DMA地址
    spi_w_reg_dma_cnt(spi_regs[id], len);//配置DMA接收数量
    asm(“csync”);
    if (__spi_wait_ok(spi, len)) {
        return -EFAULT;
    }
    return len;
}

/*
 * @brief spi dma发送
 * @parm spi  spi句柄
 * @parm buf  发送缓冲区基地址
 * @parm len  期望发送长度
 * @return 实际发送长度,< 0表示失败
 */
int spi_dma_send(spi_dev spi, const void *buf, u32 len)//spi dma发送
{
    u8 id = spi_get_info_id(spi);//获取ID

/* ASSERT((u32)buf % 4 == 0, “spi dma addr need 4-aligned”); */
    spi_dir_out(spi_regs[id]);//配置为输出方向
    spi_w_reg_dma_addr(spi_regs[id], (u32)buf);//写入地址
    spi_w_reg_dma_cnt(spi_regs[id], len);//写入长度
    asm(“csync”);
    if (__spi_wait_ok(spi, len)) {//等待发送完成
        return -EFAULT;
    }
    return len;
}

/*
 * @brief spi 配置dma,不等待pnd,用于中断
 * @parm spi  spi句柄
 * @parm buf  缓冲区基地址
 * @parm len  期望长度
 * @parm rw  1 接收 / 0 发送
 * @return null
 */
void spi_dma_set_addr_for_isr(spi_dev spi, void *buf, u32 len, u8 rw)//spi 配置dma,不等待pnd,用于中断
{
    u8 id = spi_get_info_id(spi);//获取ID

/* ASSERT((u32)buf % 4 == 0, “spi dma addr need 4-aligned”); */
    rw ? spi_dir_in(spi_regs[id]) : spi_dir_out(spi_regs[id]);//根据rw标志,配置输出或输入
    spi_w_reg_dma_addr(spi_regs[id], (u32)buf);//写地址
    spi_w_reg_dma_cnt(spi_regs[id], len);//写长度
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值