Basic SPI Operations with K64F or KSDK

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Basic SPI Operations with K64F or KSDK

1,618 Views
photonflux
Contributor I

Background

  • New to NXP microcontrollers, unfamiliar with KSDK.
  • Non-expert in C.

Documentation Referenced:

  1. Kinetis SDK 2.0 API Reference Manual - DSPI Driver
  2. K66 Sub-Family Reference Manual with Addendum [PDF]
  3. KSDK SPI Master-Slave with FRDM-K64F [PDF]

Hardware:

  • FRDM-K64F

Software:

  • MCU Xpresso v10.2.1 [2018-7-25]
  • KSDK 2.x_FRDM-K64F, Version 2.4.2, Manifest Version 3.3.0

Problem:

Unable to get SPI peripheral to function with SPI device.

Aforementioned documents have been read. Unable to decipher the SDK API reference manual in part. 

  1. srcClock_Hz = CLOCK_GetFreq(xxx); Does not appear to function with SPI0_CLK_SRC, etc. Unable to determine how to get this to function. Documentation I have read appears to state that the only clock source available to SPI is the bus clock. 
  2. DSPI is the only driver included. The SPI documentation does not compile on the device. Is this intentional? e.g. not sure if I am using the correct driver.

Note: Hardware is functional using mbed program, so hardware has been ruled out.

Goal:

  • Perform basic SPI communication operation. Read first 4 bytes of device register (send 0x00 4 times, print newline for each result)
  • Write to register, should be simple once basic read is done (sent register address, read output)

Code:

/*
 * Copyright 2016-2018 NXP Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o 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.
 *
 * o Neither the name of NXP Semiconductor, Inc. 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 HOLDER 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.
 */
 
/**
 * @file    MK64FN1M0xxx12_Project
 * @brief   Application entry point.
 */
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MK64F12.h"
#include "fsl_debug_console.h"

/* TODO: insert other include files here. */
/* Including the SPI drivers, clock */
#include "fsl_dspi.h"
#include "fsl_clock.h"

/* TODO: insert other definitions and declarations here. */
#define baudrate 115200


/*
 * @brief   Application entry point.
 */


int main(void) {

       /* Init board hardware. */
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitBootPeripherals();
       /* Init FSL debug console. */
    BOARD_InitDebugConsole();

    /* Init SPI */
    dspi_master_handle_t g_m_handle; //global variable
    dspi_master_config_t masterConfig;
    dspi_transfer_t     masterXfer = {0};

    masterConfig.whichCtar                                             = kDSPI_Ctar0;
    masterConfig.ctarConfig.baudRate                              = baudrate;
    masterConfig.ctarConfig.bitsPerFrame                         = 8;
    masterConfig.ctarConfig.cpol                                   = kDSPI_ClockPolarityActiveHigh;
    masterConfig.ctarConfig.cpha                                   = kDSPI_ClockPhaseFirstEdge;
    masterConfig.ctarConfig.direction                              = kDSPI_MsbFirst;
    masterConfig.ctarConfig.pcsToSckDelayInNanoSec               = 1000000000 / baudrate;
    masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec          = 1000000000 / baudrate;
    masterConfig.ctarConfig.betweenTransferDelayInNanoSec     = 1000000000 / baudrate;

    /* Chip Select Configuration */
    masterConfig.whichPcs                                             = kDSPI_Pcs0;
    masterConfig.pcsActiveHighOrLow                                   = kDSPI_PcsActiveLow;
    masterConfig.enableContinuousSCK                              = false;
    masterConfig.enableRxFifoOverWrite                              = false;
    masterConfig.enableModifiedTimingFormat                         = false;
    masterConfig.samplePoint                                        = kDSPI_SckToSin0Clock;

    /* Init SPI HW */
    int srcClock_Hz = CLOCK_GetFreq(kCLOCK_BusClk);
    DSPI_MasterInit(SPI0, &masterConfig, srcClock_Hz);

    DSPI_MasterTransferCreateHandle(SPI0, &g_m_handle, NULL, NULL);
    /* Declare Buffers, data */
//    uint8_t masterSendBuffer      = 0;
//    uint8_t masterReceiveBuffer = 0;
//    volatile size_t transfer_dataSize = 0;

    masterXfer.txData           = 0;
    masterXfer.rxData           = 0;
    masterXfer.dataSize      = 0;
    masterXfer.configFlags     = kDSPI_MasterCtar0 | kDSPI_MasterPcs0;


    masterXfer.txData = 0x00;
    DSPI_MasterTransferBlocking(SPI0, &masterXfer);
    PRINTF("Data Received: %d\n",masterXfer.rxData);
    DSPI_MasterTransferBlocking(SPI0, &masterXfer);
    PRINTF("Data Received: %d\n",masterXfer.rxData);


    /* Running main program now */
    PRINTF("Hello World\n");

    /* Force the counter to be placed into memory. */
    volatile static int i = 0 ;
    /* Enter an infinite loop, just incrementing a counter. */
    while(1) {
        i++ ;
    }
    return 0 ;
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Tags (2)
0 Kudos
2 Replies

995 Views
photonflux
Contributor I

I was able to get SPI working to send messages, however, I cannot receive any messages. 

It appears the chip select is going high before the empty 0b00000000 command is sent. How do I keep the chip select from toggling or must I toggle the CS pin manually? If so can you please provide an example code snippet?

Thank you.

0 Kudos

995 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

1. In fsl_clock.h line 289 you can see:

#define BUS_CLK kCLOCK_BusClk

#define I2C0_CLK_SRC BUS_CLK
#define I2C1_CLK_SRC BUS_CLK
#define I2C2_CLK_SRC BUS_CLK
#define DSPI0_CLK_SRC BUS_CLK

After you compiled the code, browse information is established. You can use F3 key to search the define link.

2. What do you mean of SPI documentation? Yes, you used correct driver (fsl_dspi.h).

I'm not sure if you have tested those examples in FRDM-K64F\boards\frdmk64f\driver_examples\dspi. They are useful.

Regards,

Jing

0 Kudos