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 instances in project. How to use properly?

Part Number: CC1352P7
Other Parts Discussed in Thread: SYSBIOS, SYSCONFIG

/*
 * 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);
    }
}

Hi all! Have an issue with such setup:

CCS Studio Version: 12.6.0.00008 
SysConfig: v1.16.2
SimpleLink CC13xx SDK: v7.10.2.23
OS: Ti-RTOS7
Compiler: Clang3.2.1 LTS
Custom-made board

Hardware used:
SPI_1 - used by APA102C led driver (4Leds in series). POCI pin not used, but needed by syscfg
SPI_2 - used by SPI Serial Flash Memory

Used such pins (in SysCfg tool):
#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 screenshots:




Have problem even when transmitting from SPI_1 in polling, which gives me this fault. When I am changing instances SSI0 to SSI1, one periph (LED in that case) starts to work, but another hangs out on transmit.


Have anyone an example of using 2 separate instances in task context?

  • Hi Ivan,

    Have you been able to use the SPI instances independently, when the other instance is not in use?

    Regards,
    Sid

  • Hi Sid, unfortunately no.
    Even when using SPI_Close() after using the instance.

    Moreover, I cannot get handle by SPI_Open() after closing the instance (it is always nullptr).

  • Hi Ivan,

    It could be that the SPI parameters is not set up correctly. Please can you try commenting out the other SPI instance code and only open one at a time and make sure both SPI instances actually work

  • Thanks for help!
    Two instances working, UartLog.c module somehow affected on SPI transactions. After disabling that module two instances started to work independently.

    Have assumption that UART here is used in blocking mode too, but flushing uart buffer performed in IDLE state..
    Have you some guide for proper logging in case when all periph using blocking drivers?
    BTW, system printf as I know is blocking too..

  • Hi Ivan,

    Unfortunately we do not have such a guide. But I see that Uartlog.c module, simply takes an existing UART instance handle for initialization. 

    Have you checked if you could pass a non blocking UART instance to this?

    Regards,

    Sid

  • Thanks! After initialising uart params as that, uart start to work with two instances. Before in blocking mode SPI driver cannot open 2nd instance (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());