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.

[参考译文] CC1352P7:项目中有2个 SPI 实例。 如何正确使用?

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1347522/cc1352p7-2-spi-instances-in-project-how-to-use-properly

器件型号:CC1352P7
Thread 中讨论的其他器件:SysBiosSysConfig

/*
 * File: led_strip.c
 *
 *  Created on: Aug 8, 2023
 *      Author: 
 */
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>

/* POSIX Header files */
#include <semaphore.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/SPI.h>

/* Driver Configuration */
#include <ti/common/cc26xx/uartlog/UartLog.h>
#include "ti_drivers_config.h"

#define LED_START_FRAME     0x00000000
#define LED_STOP_FRAME      0xFFFFFFFF
#define LED_DEFAULT         0xE70FC008
#define LED_OFF             0xE7000000
                            //RGB
#define LED_YELLOW          0x414100E7
#define LED_BLUE            0xE7410000
#define LED_GREEN           0xE7006100
#define LED_RED             0xE7000061

#define LED_STRIP_LEN       5
#define LED_FRAME_SIZE      (LED_STRIP_LEN + 2) // 1 - start and 1 -stop frame

static SPI_Handle ledSpiHandle;
static SPI_Params ledSpiParams;
static SPI_Transaction transaction;
static bool isCompleted = false;

void led_strip_flush_ua_flag(void);
void led_strip_off(void);
void spiCb(SPI_Handle handle, SPI_Transaction *transaction);

void spiCb(SPI_Handle handle, SPI_Transaction *transaction)
{
    if (transaction->status == SPI_TRANSFER_COMPLETED) {
        isCompleted = true;
    }
}

void led_strip_init(void)
{
    SPI_init();
    /* Open SPI as controller (default) */
    SPI_Params_init(&ledSpiParams);
    ledSpiParams.frameFormat = SPI_POL0_PHA0;
    ledSpiParams.mode = SPI_CONTROLLER;
    /* See device-specific technical reference manual for supported speeds */
    ledSpiParams.bitRate = 4000000;
    ledSpiParams.dataSize = 8; // bit
    ledSpiParams.transferMode = SPI_MODE_BLOCKING;
//    ledSpiParams.transferCallbackFxn = spiCb;

    ledSpiHandle = SPI_open(CONFIG_SPI_1, &ledSpiParams);

    if (ledSpiHandle == NULL)
    {
        Log_error0("SPI handle NULL");
        while(1) {};
    }
}

void led_strip_flush_ua_flag(void)
{
    if (ledSpiHandle == NULL)
    {
        Log_error0("SPI handle NULL");
        while(1) {};
    }

    bool transferOK;
    uint32_t strip_data[LED_FRAME_SIZE] = {};

    // Fill strip
    strip_data[0] = LED_START_FRAME;
    for (int i = 1; i <= LED_STRIP_LEN/2; i++)
    {
        strip_data[i] = LED_YELLOW;
    }

    for (int i = 3; i <= LED_STRIP_LEN; i++)
    {
        strip_data[i] = LED_BLUE;
    }

    strip_data[LED_FRAME_SIZE-1] = LED_STOP_FRAME;

    // Init transaction
    transaction.count = sizeof(strip_data);
    transaction.txBuf = (void *)strip_data;
    transaction.rxBuf = (void *)NULL;
    transferOK = SPI_transfer(ledSpiHandle, &transaction);

    if (!transferOK)
    {
        while(1) {};
    }
}

void led_strip_off(void)
{
    if (ledSpiHandle == NULL)
    {
        Log_error0("SPI handle NULL");
        while(1) {};
    }

    uint32_t strip_data[LED_FRAME_SIZE] = {};
    // Fill strip
    strip_data[0] = LED_START_FRAME;
    for (int i = 1; i <= LED_STRIP_LEN; i++)
    {
        strip_data[i] = LED_OFF;
    }

    strip_data[LED_FRAME_SIZE-1] = LED_STOP_FRAME;

    // Init transaction
    transaction.count = sizeof(strip_data);
    transaction.txBuf = (void *)strip_data;
    transaction.rxBuf = (void *)NULL;

    isCompleted = false;
    bool transferOK = SPI_transfer(ledSpiHandle, &transaction);

    if (!transferOK)
    {
        while(1) {};
    }

//    while (!isCompleted) {
////        Task_sleep(10);
//    }
}


/////////////////////////////////////////////////////////////
/// USE CASE when it hangs //////////////////////////////////
/// File cr4.cpp
void periphInit()
{
    setPinStates();
    buttonInit();
    setCmdHandlerCb(cmdHandler);
    led_strip_init();
    led_strip_off(); // Hang here
    sleep(1);
    flashTest();
}

extern "C" Task_Handle* createMainTask() {
    Task_Params taskParams;
    // Configure task
    Task_Params_init(&taskParams);
    taskParams.stack = sMainTaskStack;
    taskParams.stackSize = 2048;
    taskParams.priority = 1;

    Task_construct(&sMainTask, (ti_sysbios_knl_Task_FuncPtr)mainTask, &taskParams, NULL);

    sMainTaskHandle = Task_handle(&sMainTask);
    return &sMainTaskHandle;
}

/*
 *  ======== mainThread ========
 */
void mainTask(void *arg0)
{
    /* Call driver init functions */
    periphInit();
    m_ext = Extender::getInstance();

    while (1) {
        handleExtInputs();
        handleButton();
        Task_sleep(10);
    }
}

大家好! 此类设置存在问题:

CCS Studio 版本:12.6.0.00008  
SysConfig:v1.16.2
SimpleLink CC13xx SDK:v7.10.2.23
操作系统:TI-RTOS7
编译器:Clang3.2.1 LTS
定做电路板

使用的硬件:
SPI_1 -由 APA102C LED 驱动器使用(4个串联)。 未使用 POCI 引脚、但 SYSCfg 需要该引脚
SPI_2 -由 SPI 串行闪存使用

使用了以下引脚(在 SYSCFG 工具中):
#define CONFIG_GPIO_SPI_2_SCLK 28
#define CONFIG_GPIO_SPI_2_POCI 14
#define CONFIG_GPIO_SPI_2_PICO 15

#define CONFIG_GPIO_SPI_1_SCLK 6
#define CONFIG_GPIO_SPI_1_POCI 30
#define CONFIG_GPIO_SPI_1_PICO 5

SYSCFG 截图:




即使在轮询中从 SPI_1进行传输时也会出现问题、这会给我这个故障。 当我将实例 SSI0更改为 SSI1时、一个外设(在这种情况下为 LED)开始工作、但另一个在发送时挂起。


是否有人举过在任务上下文中使用2个单独实例的例子?

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

    伊凡、您好!

    当 SPI 实例未使用时、您是否能够独立使用该实例?

    此致、
    SID

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

    嗨、Sid、很遗憾不能。
    即使在使用实例后使用 spi_close()时也是如此。

    此外,在关闭实例(它始终为 nullptr)后,我无法通过 spi_Open()获取 handle。

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

    伊凡、您好!

    可能是 SPI 参数设置不正确。 请尝试注释掉另一个 SPI 实例代码、并且一次只能打开一个、并确保两个 SPI 实例实际上都可以正常工作

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

    感谢您的帮助!
    两个正常工作的实例、UartLog.c 模块在某种程度上影响了 SPI 事务。 在禁用该模块后、两个实例开始独立工作。

    假设这里的 UART 也用于阻塞模式、但在空闲状态下刷新 UART 缓冲区。
    如果所有操作都使用阻塞驱动程序、您是否有关于正确记录的指南?
    BTW、我知道系统 printf 也是阻塞的。

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

    伊凡、您好!

    遗憾的是,我们没有这样的指南。 但我看到 Uartlog.c 模块只是采用现有的 UART 实例句柄进行初始化。  

    您是否检查过您是否可以将非阻塞的 UART 实例传递给此实例?

    此致、

    SID

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

    谢谢! 将 UART 参数初始化为这样之后、UART 开始使用两个实例。 在阻塞模式之前、SPI 驱动程序无法打开第二个实例(handle == nullptr)

    UART2_Params params;
    UART2_Params_init(&params);
    params.writeMode = UART2_Mode_NONBLOCKING;
    // Open the UART
    UartLog_init(UART2_open(CONFIG_DISPLAY_UART, &params));
    Log_info1("Reset reason: %u", SysCtrlResetSourceGet());