AnsweredAssumed Answered

Basic SPI Operations with K64F or KSDK

Question asked by photonflux on Dec 9, 2018
Latest reply on Dec 14, 2018 by photonflux

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 ;
}

Outcomes