This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LAUNCHXL-CC2640R2:如果在 CC2640R2上使用 SPI、IOS v14.6无法发现服务

Guru**** 2526700 points
Other Parts Discussed in Thread: CC2640, CC2640R2L, BLE-STACK

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1029416/launchxl-cc2640r2-ios-v14-6-cannot-discover-services-if-using-spi-on-cc2640r2

器件型号:LAUNCHXL-CC2640R2
Thread 中讨论的其他器件:CC2640CC2640R2LBLE-STACK

您好!

我已经基于 ProjectZero 示例代码开发了一个定制应用程序。 我正面临一个非常具体的问题、我不确定导致问题的原因是什么。 在整个开发过程中、我使用 Android 手机上的 NRF 连接应用进行测试。 我想将设备与 iPhone 配合使用。

与相关的 e2e 线程非常相似、如果我在 CC2640上使用 SPI 外设、iPhone 无法发现服务。 在我注释所有对 SPI_init()、SPI_open (...)的调用后 和 SPI_TRANSACTION (...) iPhone 连接正确、能够识别 BLE 服务。 我已经使用具有和不具有 SPI 函数调用的相同固件测试了 LAUNCHXL_CC2640R2和 CC2640R2L 自定义电路板。 在这两种情况下、如果我有 SPI 函数调用、Android 设备工作正常、iPhone ->无法找到图像中所示的服务。 一旦我从固件中删除 SPI 函数调用、iPhone 就可以发现 BLE 服务、Android 设备也能正常工作。 由于评估板和定制板上的行为相同、因此这不应是硬件问题。

我的 Android 手机从未遇到过这样的问题。

图 1.尝试使用 SPI 功能通过 iPhone 上的 NRF 连接应用程序进行连接;显示无服务

图 2.尝试通过 iPhone 上的 NRF 连接应用程序进行连接而不使用 SPI 功能;正确显示服务

图 3.我正在使用的 iPhone 的详细信息;iOS 版本14.6、iPhone X

我假设 SDK 中的 BLE 堆栈存在一些限制。 请告诉我是什么导致了这个问题、以及如何解决这个问题。 谢谢。

我使用的是 Simplelink SDK 版本4.40和 TI 编译器版本20.2.3.LTS

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    请解释 SPI 的使用方法。 您是在单独的任务中访问它、还是在与 PROJECT_ZERO 相同的任务中访问它? 您使用的是阻塞操作还是回调操作?

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您的回复。 我使用的是同一个任务(PROJECT_ZERO 任务)。 我在阻塞模式下使用 SPI。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您使用 SPI 的方式对我来说不正确。
    它可能会阻止主任务的执行、从而导致您面临的问题。

    您最好考虑在回调模式下使用 SPI。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我认为是这样。 实际上、为了测试情况是否如此、我又尝试了一件事。 目前、在 SPI 库头文件中、我已对 SPI_Transfer 函数调用进行了注释、仅用于测试。 我还对 FLASH_init()函数进行了注释,该函数初始化引脚并设置 SPI 事务的 SPI 句柄。

    因此、到目前为止、不会在固件上执行 SPI 事务。 在初始化任务之前,我只在 main()函数中添加了一个 SPI_init()调用。 在一切开始之前,我还尝试了 ProjectZero_init()函数中的 SPI_init()调用。 我仍然看到相同的行为。 我无法从 iPhone 连接。

    在上述情况下、没有 SPI_OPEN (...) 或 SPI_TRANSACTION (...) 可能会阻止并导致 BLE 连接无法连接的呼叫。 我所做的就是调用 SPI_init()函数,并在 BLE 开始广播之前尝试在 init 函数中初始化 CC2640的 SPI 外设。 因此、SPI 的阻塞或回调模式不应导致此问题、因为它甚至尚未设置。

    因此,基本而言,启动时只有一个 SPI_init()调用导致此问题。 我已评论所有其他 SPI_open (...) 和 SPI_TRANSACTION (...) 调用。 如果我在开始时添加了 SPI_init()->无法连接到 iPhone。 我将其删除->能够与 iPhone 正确连接。

    这里可能会有什么问题?

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您的发现非常有趣。Project_Zero 利用外部闪存并通过 SPI 进行访问。  

    对 SPI_init()的调用似乎可以在其他地方完成,特别是在与非易失性存储器(NVS)相关的代码中。

    您是否可以像以前那样尝试不调用 SPI_init()然后访问驱动程序? 此外、请确保不要将相同的 SSI 模块用于 NVS 和您自己的需求(即使用 CC2640R2_LAUNCHXL_SPI1接口)。

    我希望它能有所帮助、

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    很抱歉、我昨天没收到您的回复。

    我在项目中找不到与非易失性存储(NVS)相关的任何代码。 它究竟应该在哪里?
    无论如何,我尝试了你建议的以下几点,以下是我的观察结果:

    1.我在没有调用 SPI_init()的情况下尝试运行代码。 所以,我刚刚注释掉了对 SPI_init()的调用,并尝试运行我的固件而不做任何其他更改。 代码如下:

    #define DF_CS_inactive  PIN_setOutputValue(spiPinHandle, Board_SPI_FLASH_CS, Board_FLASH_CS_OFF);
    #define DF_CS_active    PIN_setOutputValue(spiPinHandle, Board_SPI_FLASH_CS, Board_FLASH_CS_ON);
    
    ...
    
    void spi_init_pins(void)
    {
        spiPinHandle = PIN_open(&spiPinState, spiPinTable);
        if(!spiPinHandle)
        {
        Log_error0("Error initializing board CS pins");
        Task_exit();
        }
        DF_CS_active;
    //    SPI_init();   //TODO: commented for testing; undo later
        SPI_Params_init(&spi_param);
        spi_param.transferMode = SPI_MODE_BLOCKING;
        spi1 = SPI_open(Board_SPI_MASTER, NULL);
        if(spi1 == NULL)
        {
            Log_info0("Error initializing SPI0\n");
            while (1);
        }
        DF_CS_inactive;
    }
    
    void flash_init(void)
    {
            spi_init_pins();
            ...
    }

    flash_init()是我初始化外部 SPI 闪存的函数。 它调用 SPI_init_pines()函数,该函数设置 SPI 外设,然后向 IC 发送一些 SPI 闪存命令。

    如您所见,我尝试在 SPI_init_pines()函数中注释 spi_init(),但代码在第19行停止。

    spi1 = SPI_open(Board_SPI_MASTER, NULL);
    if(spi1 == NULL)
    {
        Log_info0("Error initializing SPI0\n");
        while (1);
    }

    它无法打开 SPI、并且未返回有效的 SPI 句柄。 因此,也许我在 SPI_init_pines()函数中对 SPI_init()的调用是在固件中初始化 SPI 所需的唯一调用。

    2、到目前为止、我使用 MYBOARD_SPI0连接闪存。 我使用 的是通过 blestack 用户指南中的此链接创建的定制板级配置文件 、这就是为什么名称 是 MYBOARD_SPI0的原因。 它类似于 CC2640R2_LAUNCHXL_SPI0。
    我更改了定义、现在我将 MYBOARD_SPI1用于闪存。

    #define Board_SPI_MASTER        MYBOARD_SPI1//MYBOARD_SPI0

    以上是 Board.h 文件中的更改。

    /* SPI Board */
    #define MYBOARD_SPI0_MISO             PIN_UNASSIGNED//IOID_8          /* RF1.20 */
    #define MYBOARD_SPI0_MOSI             PIN_UNASSIGNED//IOID_9          /* RF1.18 */
    #define MYBOARD_SPI0_CLK              PIN_UNASSIGNED//IOID_10         /* RF1.16 */
    #define MYBOARD_SPI0_CSN              PIN_UNASSIGNED
    #define MYBOARD_SPI1_MISO             IOID_8//PIN_UNASSIGNED
    #define MYBOARD_SPI1_MOSI             IOID_9//PIN_UNASSIGNED
    #define MYBOARD_SPI1_CLK              IOID_10//PIN_UNASSIGNED
    #define MYBOARD_SPI1_CSN              PIN_UNASSIGNED

    以上是 MYBOARD.h 文件中的更改。 我已验证 SPI 工作正常、引脚分配没有问题。 闪存读取/写入工作正常。 但是、我的板仍然无法连接到 iPhone。 它像以前一样正确连接到我的 Android 手机。 我在 Android 手机上使用了 NRF 连接应用程序来检查该应用程序、并在 iPhone 上使用 LightBlue 应用程序来检查它。

    此外、在 iPhone 上使用 LightBlue 应用时、会显示以下错误:

    "查询外设超时"。

    其他什么可能导致该问题? 或者如何在调试中取得进展?

    是否有办法与您联系、以便我可以向您展示错误并更清楚地解释问题?

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    在使用的 SPI 接口上进行更改后、观察到的误差与之前略有不同。 对吧?

    在这种情况下、您保持了 SPI_OPEN 和所有事务。 对吧? 如果是、请查看 SPI 阻塞调用是否可能是问题的根源。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    首先、观察到的误差是相同的。 前面我在原始问题中显示了在 iPhone 上使用 NRF 连接应用程序时出现的错误。 在最近的答复中、我在 iPhone 上的 LightBlue 应用中显示了错误。 只有这些应用程序显示错误的方式不同。 我仍在 iPhone 上的 NRF 连接应用程序上遇到错误、这在我发布的原始问题中有描述。

    其次、是的、我一直调用 SPI_open (...) 和 SPI_TRANSACTION (...) 并且只对对对 SPI_init()的调用进行了注释。 因为它在最新的帖子中、SPI_OPEN (...) 没有为我提供任何有效的 SPI 句柄以供我使用、以便在代码中继续操作并调用阻塞 SPI_TRANSACTION (...) 导致此问题的调用。 SPI_OPEN (...) 返回 NULL。 因此、代码会检查返回值是否为 NULL、并由于错误而在 while (1)中停止。 现在、我知道您可能希望我更改 spi_param.transferMode = spi_mode_blocking;将行更改为 spi_param.transferMode = spi_mode_callback;以便使用回调模式。 但是,即使这样,我也需要调用 spi_init(),否则我永远不会得到有效的 SPI 句柄,而且我会永远等待。

    此外,正如我在原来的问题中所解释,这个问题只发生在 iPhone 上,而不是在 Android 手机上。 在 Android 手机中、使用 NRF 连接应用程序时、我从未遇到过此问题。 如果这是由于阻止 SPI 呼叫导致的、那么也应该是我的 Android 手机上导致了此问题。 但 Android 上的 NRF 连接应用程序始终与器件连接、没有任何错误。

    显然、如果错误行为仅在 iPhone 上而不在 Android 上、则应由阻止 SPI 调用以外的其他行为引起。 在顶部的相关 e2e 线程链接中: https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/872176/ccs-cc2640-ios-13-can-t-discover-services-if-spi-is-using、 Marie H 说" 与 IOS 13存在互操作性问题"。 BLE-STACK 和 iOS 13有哪些问题? 这里是否会导致相同的问题? 如何解决这些问题?

    请告诉我。

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您是否使用其他 iOS 版本运行了一些测试?

    此致、

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Cl é ment、
    我意识到这实际上是一个内存问题。 显然、与我的 Android 手机通信相比、硬件与 iPhone 通信需要更多的动态 RAM。 因此、在 CC2640R2L 上可用的~17KB RAM 中(正如我在"Memory Allocation"窗口中看到的)、我使用了12.8KB 的 RAM、因为我几个月前注意到了 Android 上的 BLE 稳定性问题。

    但是现在、为了使它能够与 iPhone 配合使用、我只允许使用~12.3kB 的 RAM。 如果我以任何方式超越它、BLE 将无法与 iPhone 正常配合使用。 尽管如此、除非您使用的 RAM 大于12.8kB、否则它可以在 Android 中正常工作。

    我尝试从项目中添加 SPI_init()和删除 UART_init(),它开始使用 iPhone。 这是因为我之前的 RAM 用量为12.8kB、之后减少到了12.3kB、清楚地表明这是 RAM 问题。

    无论如何、CC2640R2L 中可用的 RAM 显然对于我们的应用来说太少了、因此我们将切换到另一个 MCU、以便将来用于该项目。

    感谢您的所有帮助。

    此致、