BES2300YP - SPI接口

目录

GPIO Pin Mux

Pin Mux相关的代码

Hal_spi.c/h的几组api

hal_iomux_set_spilcd

我的测试代码


GPIO Pin Mux

SPI的调试需要考虑GPIO的选择和复用设定, 

最开始的时候我拿到的是GPIO Pin Mux的Excel, 整理如下:

后面的研究发现这里有坑

Pin Mux相关的代码

hal_iomux_best2300p.c文件中pin_func_map函数定义了每个引脚所支持的各种复用功能,

我们可以注意到上节所说的坑, 因为这里的定义和上节的excel是对应不上的, 解决方法:应该采用SPILCD而不是SPI的相关接口.

至于SPI接口, 因为我的2300YP没有P04~07,所以用不上, 如果换成其他芯片和封装, 可以具体再研究下

其定义如下:

// 为方便阅读, 和针对2300yp, 部分无效引脚的代码删除

static const enum HAL_IOMUX_FUNCTION_T pin_func_map[HAL_IOMUX_PIN_NUM][IOMUX_ALT_FUNC_NUM] = {
    // P0_0
    { HAL_IOMUX_FUNC_I2S0_SDI0, HAL_IOMUX_FUNC_UART2_RX, HAL_IOMUX_FUNC_PCM_DI, HAL_IOMUX_FUNC_SPILCD_DI0,
      HAL_IOMUX_FUNC_PDM0_CK, HAL_IOMUX_FUNC_SPILCD_DCN, },
    // P0_1
    { HAL_IOMUX_FUNC_I2S0_SDO, HAL_IOMUX_FUNC_UART2_TX, HAL_IOMUX_FUNC_PCM_DO, HAL_IOMUX_FUNC_SPILCD_DIO,
      HAL_IOMUX_FUNC_PDM0_D, HAL_IOMUX_FUNC_NONE, },
    // P0_2
    { HAL_IOMUX_FUNC_I2S0_WS, HAL_IOMUX_FUNC_I2C_M1_SCL, HAL_IOMUX_FUNC_PCM_FSYNC, HAL_IOMUX_FUNC_SPILCD_CS0,
      HAL_IOMUX_FUNC_PDM1_D, HAL_IOMUX_FUNC_NONE, },
    // P0_3
    { HAL_IOMUX_FUNC_I2S0_SCK, HAL_IOMUX_FUNC_I2C_M1_SDA, HAL_IOMUX_FUNC_PCM_CLK, HAL_IOMUX_FUNC_SPILCD_CLK,
      HAL_IOMUX_FUNC_PDM2_D, HAL_IOMUX_FUNC_NONE, },
   


    // P1_0
    { HAL_IOMUX_FUNC_SDMMC_DATA2, HAL_IOMUX_FUNC_I2S1_SCK, HAL_IOMUX_FUNC_SPILCD_CLK, HAL_IOMUX_FUNC_SPI_CS1,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },
    // P1_1
    { HAL_IOMUX_FUNC_SDMMC_DATA3, HAL_IOMUX_FUNC_I2S1_WS, HAL_IOMUX_FUNC_SPILCD_CS0, HAL_IOMUX_FUNC_SPI_CS2,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },
    // P1_2
    { HAL_IOMUX_FUNC_SDMMC_CMD, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPILCD_CS1, HAL_IOMUX_FUNC_SPI_CS3,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },
    // P1_3
    { HAL_IOMUX_FUNC_SDMMC_CLK, HAL_IOMUX_FUNC_I2S0_MCLK, HAL_IOMUX_FUNC_SPILCD_DCN, HAL_IOMUX_FUNC_CLK_OUT,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },
    // P1_4
    { HAL_IOMUX_FUNC_SDMMC_DATA0, HAL_IOMUX_FUNC_I2S1_SDI0, HAL_IOMUX_FUNC_SPILCD_DI0, HAL_IOMUX_FUNC_NONE,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },
    // P1_5
    { HAL_IOMUX_FUNC_SDMMC_DATA1, HAL_IOMUX_FUNC_I2S1_SDO, HAL_IOMUX_FUNC_SPILCD_DIO, HAL_IOMUX_FUNC_I2S0_MCLK,
      HAL_IOMUX_FUNC_CLK_OUT, HAL_IOMUX_FUNC_NONE, },


    // P1_6
    { HAL_IOMUX_FUNC_UART0_RX, HAL_IOMUX_FUNC_I2C_M0_SCL, HAL_IOMUX_FUNC_BT_UART_RX, HAL_IOMUX_FUNC_NONE,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },
    // P1_7
    { HAL_IOMUX_FUNC_UART0_TX, HAL_IOMUX_FUNC_I2C_M0_SDA, HAL_IOMUX_FUNC_BT_UART_TX, HAL_IOMUX_FUNC_NONE,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },

    // P2_2
    { HAL_IOMUX_FUNC_I2C_M1_SCL, HAL_IOMUX_FUNC_UART2_RX, HAL_IOMUX_FUNC_UART1_CTS, HAL_IOMUX_FUNC_BT_UART_CTS,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_I2S0_MCLK, },
    // P2_3
    { HAL_IOMUX_FUNC_I2C_M1_SDA, HAL_IOMUX_FUNC_UART2_TX, HAL_IOMUX_FUNC_UART1_RTS, HAL_IOMUX_FUNC_BT_UART_RTS,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_CLK_OUT, },


    // P2_5
    { HAL_IOMUX_FUNC_PWM1, HAL_IOMUX_FUNC_CLK_REQ_IN, HAL_IOMUX_FUNC_SPI_CS3, HAL_IOMUX_FUNC_NONE,
      HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_NONE, },
    // P2_6
    { HAL_IOMUX_FUNC_PWM2, HAL_IOMUX_FUNC_SPILCD_DI1, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPDIF0_DI,
      HAL_IOMUX_FUNC_CLK_32K_IN, HAL_IOMUX_FUNC_NONE, },
    // P2_7
    { HAL_IOMUX_FUNC_PWM3, HAL_IOMUX_FUNC_SPILCD_CS1, HAL_IOMUX_FUNC_NONE, HAL_IOMUX_FUNC_SPDIF0_DO,
      HAL_IOMUX_FUNC_CLK_OUT, HAL_IOMUX_FUNC_NONE, },
};

在hal_iomux_set_function函数中会基于pin_func_map来将功能序号转为寄存器掩码值,

这段代码如下:

// Other func values: 0 -> gpio, 6 -> rf_ana, 7 -> jtag/btdm, 9 -> clk_req, 10 -> ana_test
static const uint8_t index_to_func_val[IOMUX_ALT_FUNC_NUM] = { 1, 2, 3, 4, 5, 8, };

if (func == HAL_IOMUX_FUNC_GPIO) {
    val = IOMUX_FUNC_VAL_GPIO;
}
else
{
    for (i = 0; i < IOMUX_ALT_FUNC_NUM; i++)
    {
        if (pin_func_map[pin][i] == func)
        {
            break;
        }
    }

    if (i == IOMUX_ALT_FUNC_NUM) {
        return 3;
    }
    val = index_to_func_val[i];
}

reg = &iomux->REG_004 + pin / 8;
shift = (pin % 8) * 4;

*reg = (*reg & ~(0xF << shift)) | (val << shift);

Hal_spi.c/h的几组api

Hal_spi.c/h中有几组不同的api, 每组api有不同的原语(这个词我可能用的不合适)实现, 总结如下:

粗略的喵了一下, 这几组api只是用不同SPI_id调用一组后缀带_id的函数

所以这里我们应该可以忽略spi和spilcd的差别, 使用spilcd来替代本来预期的spi模块

hal_iomux_set_spilcd

这两个函数在hal_iomux_best2300p.c中定义, 是用来将GPIO的功能设定为用于SPILCD的.

他依赖于宏来控制所用的引脚, 以及SPI接口类型(3线或4线)

我的宏定义如下

#define SPILCD_IOMUX_4WIRE

// 使用GPIO 00~03时
#define SPILCD_IOMUX_DI0_INDEX 0

// 使用GPIO 10,11,14,15时
#define SPILCD_IOMUX_INDEX 10
#define SPILCD_IOMUX_DI0_INDEX 14

如果实在不放心, 请用以下函数

#define USE_GPIO_0_FOR_SPI

void my_iomux_set_spi()
{
    #ifdef USE_GPIO_0_FOR_SPI
    static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spi_4wire[4] = {
        {HAL_IOMUX_PIN_P0_3, HAL_IOMUX_FUNC_SPILCD_CLK, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
        {HAL_IOMUX_PIN_P0_2, HAL_IOMUX_FUNC_SPILCD_CS0,  HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
        {HAL_IOMUX_PIN_P0_1, HAL_IOMUX_FUNC_SPILCD_DIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
        {HAL_IOMUX_PIN_P0_0, HAL_IOMUX_FUNC_SPILCD_DI0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
    };
    #else // USE_GPIO_0_FOR_SPI
    static const struct HAL_IOMUX_PIN_FUNCTION_MAP pinmux_spi_4wire[4] = {
        {HAL_IOMUX_PIN_P1_0, HAL_IOMUX_FUNC_SPILCD_CLK, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
        {HAL_IOMUX_PIN_P1_1, HAL_IOMUX_FUNC_SPILCD_CS0,  HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
        {HAL_IOMUX_PIN_P1_5, HAL_IOMUX_FUNC_SPILCD_DIO, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
        {HAL_IOMUX_PIN_P1_4, HAL_IOMUX_FUNC_SPILCD_DI0, HAL_IOMUX_PIN_VOLTAGE_VIO, HAL_IOMUX_PIN_NOPULL},
    };
    #endif //USE_GPIO_0_FOR_SPI

    hal_iomux_init(pinmux_spi_4wire, ARRAY_SIZE(pinmux_spi_4wire));
}

我的测试代码


#include "hal_spi.h"

#define SPI_DMA_SEND  hal_spilcd_dma_send
#define SPI_DMA_RECV  hal_spilcd_dma_recv
#define SPI_ENABLE_AND_SEND  hal_spilcd_enable_and_send
#define SPI_ENABLE_AND_RECV  hal_spilcd_enable_and_recv
#define SPI_OPEN  hal_spilcd_open
extern void hal_iomux_set_spilcd(void);
#define IOMUX_SET_SPI hal_iomux_set_spilcd

static const struct HAL_SPI_CFG_T _spi_cfg_default =
{
    .rate = 200000,
    .clk_delay_half = true,
    .clk_polarity = true,
    .slave = false,
    .dma_rx = true,
    .dma_tx = true,
    .rx_sep_line = true,
    .cs = 0,
    .tx_bits = 32,
    .rx_bits = 32,
    .rx_frame_bits = 0,
};

static struct HAL_SPI_CTRL_T _spi_ctrl_8bit;

void spi_test()
{
    TRACE(1,"spi_test start!");
    IOMUX_SET_SPI();
    // my_iomux_set_spi();
    int32_t ret = SPI_OPEN(&_spi_cfg_default);
    TRACE(3,"%s, spi open failed! ret = %d", __func__, ret);

    while(1)
    {
        uint8_t cmd[4];    
        cmd[0] = 0XAA;
        cmd[1] = 0X55;
        cmd[2] = 0XAA;
        cmd[3] = 0X55;

        ret = SPI_ENABLE_AND_SEND(&_spi_ctrl_8bit, cmd, sizeof(cmd));
        TRACE(3,"%s, spi 1 send, ret = %d", __func__, ret);
        osDelay(10);

        ret = SPI_DMA_SEND(cmd, sizeof(cmd), NULL);
        TRACE(3,"%s, spi dma send, ret = %d", __func__, ret);
        osDelay(10);
    }

    TRACE(1,"spi_test done !");
}

// 测试时, 在app_init之前调用了spi_test

欢迎阅读更多 BES专栏文章

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: BEs2500iUC是一种高效能的电子产品,具有多项创新技术和功能。该型号的产品规格表提供了详细的信息,以下是针对该规格表的回答: BEs2500iUC的规格表包含了以下几个方面的信息:设备概述、主要性能指标、功能特点、尺寸和重量、电气参数、工作环境等。 设备概述部分介绍了BEs2500iUC的用途和适用领域。它是一款高效能的电子产品,适用于各种需要稳定电源的场合,如家庭、办公室、工业制造等。 主要性能指标方面,该规格表列出了BEs2500iUC的额定容量、工作电压范围、输出电压稳定度等重要参数。这些指标对于用户了解产品的使用限制和性能表现非常有帮助。 功能特点部分介绍了BEs2500iUC的主要特点和创新技术。例如,它可能具有智能电池管理系统,能够自动充电和保护电池寿命,还可能具备高效能的逆变器技术,提供稳定的交流输出。 尺寸和重量方面,规格表给出了BEs2500iUC的外形尺寸和重量,这对于用户在购买或使用过程中考虑产品的空间占用和搬运便利性非常重要。 电气参数方面,规格表提供了BEs2500iUC的输入功率、输出效率、电池容量等重要电气指标。这些参数反映了产品的能耗和使用性能,用户可以根据这些数据来选择适合自己需求的电源产品。 工作环境方面,规格表列出了BEs2500iUC的工作温度、湿度等环境要求。用户可以根据这些条件来选择产品适用的工作环境,确保产品的正常运行和安全使用。 综上所述,BEs2500iUC的规格表是一个包含了该产品各个方面详细信息的参考文档,用户可以通过阅读规格表来了解产品的性能和技术特点,以便做出正确的购买和使用决策。 ### 回答2: bes2500iuc是一款产品的型号,具体的详细信息可以在其数据手册(datasheet)中找到。数据手册是厂商为了方便用户了解产品的规格、特性和功能而提供的一份文档。 在bes2500iuc的数据手册中,一般会包含以下内容: 1. 产品概述:介绍bes2500iuc的基本信息,包括型号、尺寸、重量、供电要求等。 2. 规格参数:列出bes2500iuc的主要规格参数,如输入电压范围、输出功率、频率响应等。 3. 功能特性:详细描述bes2500iuc的功能和特性,比如电路保护功能、通信接口、控制方式等。 4. 机械图纸:提供bes2500iuc的机械图纸,包括安装尺寸、连接口布局等。 5. 电气连接图:展示bes2500iuc的电气连接图,包括输入输出接口、信号线连接等。 6. 使用说明:给出使用bes2500iuc的注意事项、操作步骤和维护方法等相关信息。 7. 典型应用案例:列出一些典型的使用bes2500iuc的应用场景,比如工业自动化、电力设备等。 总之,bes2500iuc datasheet提供了关于该产品的全面信息,让用户了解其规格和功能,从而确定是否适合自己的需求,以便做出正确的决策和应用。 ### 回答3: bes2500iuc是一款数据表,该数据表详细介绍了bes2500iuc产品的特点和技术规格。以下是对bes2500iuc datasheet的简要描述: bes2500iuc是一款高性能的集成电路,通常用于嵌入式系统和通信设备中。该产品具有多种特点和功能,使其成为许多应用领域的理想选择。 首先,bes2500iuc采用了先进的制造工艺和设计技术,具有高度的集成度和性能优势。它采用高速时钟和低功耗设计,能够在低功耗下提供卓越的性能和稳定性。 其次,bes2500iuc具有丰富的接口和通信能力。它支持多种通信标准和协议,包括以太网、USB、SPI和I2C等等。这使得它能够与其他外部设备和系统进行高效稳定的数据传输和交互。 此外,bes2500iuc还具有强大的处理能力和数据存储能力。它配备了高性能的CPU和内存,可以处理和存储大量的数据和信息。同时,它支持多种操作系统和开发工具,为用户提供了丰富的软件开发和应用定制的可能性。 最后,bes2500iuc还具备可靠性和安全性方面的特点。它采用了多种安全机制和数据保护措施,可以有效防止数据泄露和恶意攻击。同时,它具备可靠的故障监测和处理能力,可以提高系统的可靠性和稳定性。 总的来说,bes2500iuc是一款高性能、多功能、可靠的集成电路产品,适用于各种嵌入式系统和通信设备。它具备高度集成度、丰富的接口和通信能力、强大的处理能力和数据存储能力,以及可靠性和安全性方面的特点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值