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.

RTOS/CC2650: SPI Example Code

Part Number: CC2650
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Hi, 

I have been looking around to see if there are any SPI example codes of CC2650 launch pad. 

I did not find any in the resource explorer. 

 

Could anyone direct me to a right place to get a SPI example code? 

I would really appreciate it. 

  • I know display example uses SPI driver. You can try to refer to display example at dev.ti.com/.../
  • Hi,
    I did take a look at the display example code. but it does not use SPI.

    /*
    * Copyright (c) 2016, Texas Instruments Incorporated
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the distribution.
    *
    * * Neither the name of Texas Instruments Incorporated nor the names of
    * its contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */

    /*
    * ======== display.c ========
    */
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/PIN.h>
    #include <ti/mw/display/Display.h>
    #include <ti/mw/display/DisplayExt.h>

    /* Board Header files */
    #include "Board.h"

    /* Example GrLib image */
    #include "splash_image.h"

    #define TASKSTACKSIZE 768

    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];

    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;

    /*
    * Application LED pin configuration table:
    * - All LEDs board LEDs are off.
    */
    PIN_Config ledPinTable[] = {
    Board_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    PIN_TERMINATE
    };

    /*
    * ======== taskFxn ========
    * Toggle the Board_LED0. The Task_sleep is determined by arg0 which
    * is configured for the heartBeat Task instance.
    */
    Void taskFxn(UArg arg0, UArg arg1)
    {
    unsigned int ledPinValue;

    /* Initialize display and try to open both UART and LCD types of display. */
    Display_Params params;
    Display_Params_init(&params);
    params.lineClearMode = DISPLAY_CLEAR_BOTH;

    /* Open both an available LCD display and an UART display.
    * Whether the open call is successful depends on what is present in the
    * Display_config[] array of the board file.
    *
    * Note that for SensorTag evaluation boards combined with the SHARP96x96
    * Watch DevPack, there is a pin conflict with UART such that one must be
    * excluded, and UART is preferred by default. To display on the Watch
    * DevPack, add the precompiler define BOARD_DISPLAY_EXCLUDE_UART.
    */
    Display_Handle hDisplayLcd = Display_open(Display_Type_LCD, &params);
    Display_Handle hDisplaySerial = Display_open(Display_Type_UART, &params);

    /* Check if the selected Display type was found and successfully opened */
    if (hDisplaySerial) {
    Display_print0(hDisplaySerial, 0, 0, "Hello Serial!");
    }

    /* Check if the selected Display type was found and successfully opened */
    if (hDisplayLcd) {
    Display_print0(hDisplayLcd, 5, 3, "Hello LCD!");

    /* Wait a while so text can be viewed. */
    Task_sleep(1000 * (1000/Clock_tickPeriod));

    /*
    * Use the GrLib extension to get the GraphicsLib context object of the
    * LCD, if it is supported by the display type.
    */
    tContext *pContext = DisplayExt_getGrlibContext(hDisplayLcd);

    /* It's possible that no compatible display is available. */
    if (pContext) {
    /* Draw splash */
    GrImageDraw(pContext, &splashImage, 0, 0);
    GrFlush(pContext);
    }
    else {
    /* Not all displays have a GraphicsLib back-end */
    Display_print0(hDisplayLcd, 0, 0, "Display driver");
    Display_print0(hDisplayLcd, 1, 0, "is not");
    Display_print0(hDisplayLcd, 2, 0, "GrLib capable!");
    }

    /* Wait for a bit, then clear */
    Task_sleep(5000 * (1000/Clock_tickPeriod));
    Display_clear(hDisplayLcd);
    }

    /* Loop forever, alternating LED state and Display output. */
    while (1) {
    ledPinValue = PIN_getOutputValue(Board_LED0);

    if (hDisplayLcd) {
    /* Print to LCD and clear alternate lines if the LED is on or not. */
    Display_clearLine(hDisplayLcd, ledPinValue ? 0:1);
    Display_print1(hDisplayLcd, ledPinValue ? 1:0, 0, "LED: %s",
    (!ledPinValue) ? "On!":"Off!");
    }

    if (hDisplaySerial) {
    /* Print to UART */
    Display_print1(hDisplaySerial, 0, 0, "LED: %s",
    (!ledPinValue)?"On!":"Off!");
    }

    /* Toggle LED */
    PIN_setOutputValue(ledPinHandle, Board_LED0,
    !PIN_getOutputValue(Board_LED0));

    Task_sleep((UInt)arg0);
    }
    }

    /*
    * ======== main ========
    */
    int main(void)
    {
    Task_Params taskParams;

    /* Call board init functions */
    Board_initGeneral();

    /* Construct heartBeat Task thread */
    Task_Params_init(&taskParams);
    taskParams.arg0 = 1000000 / Clock_tickPeriod;
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL);


    /* Open LED pins */
    ledPinHandle = PIN_open(&ledPinState, ledPinTable);
    if(!ledPinHandle) {
    System_abort("Error initializing board LED pins\n");
    }

    PIN_setOutputValue(ledPinHandle, Board_LED0, 1);

    System_printf("Starting the example\nSystem provider is set to SysMin. "
    "Halt the target to view any SysMin contents in ROV.\n");

    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

    /* Start BIOS */
    BIOS_start();

    return (0);
    }

    There is no SPI init or SPI open in the code. I am not sure how it uses SPI.
  • Hi, I do not think Disply example uses SPI. In the code, it neither use SPI init or SPI_open.
  • Another example is BIM in BLE Stack 2.2.1, it uses SPI to access external flash.
  • Hey, I saw an example code here.

    But I am not sure how they define chip select pin, since DIO11, DIO13 and DIO14 can all be chip select pin.

    Here is the example code for SPI init.

    SPI_Transaction spiTransaction;
    uint8_t transmitBuffer[BUFSIZE];
    uint8_t receiveBuffer[BUFSIZE];
    bool transferOK;
    SPI_Params_init(&spiParams);
    spiParams.dataSize = 6;
    spi = SPI_open(Board_SPI0, &spiParams);
    ...
    spiTransaction.count = someIntegerValue;
    spiTransaction.txBuf = transmitBuffer;
    spiTransaction.rxBuf = receiveBuffer;
    ret = SPI_transfer(spi, &spiTransaction);
    if (!transferOK) {
    // Unsuccessful SPI transfer
    }

    and the website is : software-dl.ti.com/.../_s_p_i_8h.html
  • SPI pins should be defined in your board file.
  • But when i initialized it, i didnt see any clock signal (SCLK) from pin 10.

    uint8_t x;
    uint8_t y;
    uint8_t z;

    SPI_Handle spi;
    SPI_Params params;


    SPI_init(); // Initialize the SPI driver

    SPI_Params_init(&params);

    // spiParams.dataSize = 12; // 12-bit data size
    spi = SPI_open(Board_SPI0, &params);

    //from ADXL362 Driver
    ADXL362_Init();
    ADXL362_SoftwareReset();
    ADXL362_SetPowerMode(1);

    while (1){
    ADXL362_GetXyz(x,y,z);
    System_printf("x= %d, y= %d, z= %d", x, y, z);

    System_flush();
    }
  • Try to check if you get correct SPI handle after you call “spi = SPI_open(Board_SPI0, &params);”
  • Hi
    I checked the handle, it's good.

    I think the driver that I used is not compatible with cc2650.

    and I changed my code as following:
    PIN_setOutputValue(ledPinHandle, IOID_13, 0);
    transmitBuffer[0] = 0x0B;
    spiTransaction.count = 1;
    spiTransaction.txBuf = transmitBuffer;
    //spiTransaction.rxBuf = receiveBuffer;
    SPI_transfer(spi, &spiTransaction);
    PIN_setOutputValue(ledPinHandle, IOID_13, 1);

    but I am stuck in the SPI_transfer function and never go through.
  • If you use scope to check SPI SCLk Pin, do you see clock signal when you call “SPI_transfer“?
  • When I checked it on the scope.
    I didn't see the clock signal.
    But my WPI_OPEN did gives me a valid (non null) value.
  • Are you sure you check correct pin?
  • What would go wrong if there is no clock signal? 

    1. wrong pin?

    2. is there anything that would cause the SCLK has no signal?

  • If your SPI_open return correct handle, I would say it would be something wrong with your SCLK pin assignment.