LPC55S69 SPI DMA Slave : MOSI works but MISO doesn't work

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

LPC55S69 SPI DMA Slave : MOSI works but MISO doesn't work

332 Views
Loïc
Contributor II

Hello,

I have a similar problem. I'm using the SPI DMA example for the LPC55S69 as a Slave but I can't succeed answering to the master (SPI DMA Master LPC55S36).

I tried with the example without modification but nothing happens.

After that, I tried with a little bit of modification ( the communication is in the while and the master try to communicate with the slave every loop) and I manage to have the MOSI working but not the MISO. It seems that the DMA Tx Slave doesn't work.

The slave code :

 

 

/*
 * Copyright  2017 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_debug_console.h"
#include "fsl_device_registers.h"
#include "fsl_spi.h"
#include "fsl_spi_dma.h"
#include "fsl_dma.h"
#include "pin_mux.h"
#include "board.h"
#include <stdbool.h>
#include "fsl_power.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define EXAMPLE_SPI_SLAVE            SPI8
#define EXAMPLE_SPI_SLAVE_IRQ        LSPI_HS_IRQn
#define EXAMPLE_SPI_SSEL             1
#define EXAMPLE_DMA                  DMA0
#define EXAMPLE_SPI_SLAVE_RX_CHANNEL 2
#define EXAMPLE_SPI_SLAVE_TX_CHANNEL 3
#define EXAMPLE_SLAVE_SPI_SPOL       kSPI_SpolActiveAllLow
#define TRANSFER_SIZE 4U /*! Transfer dataSize */

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
static void SPI_SlaveUserCallback(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData);
static void EXAMPLE_SlaveInit(void);
static void EXAMPLE_SlaveDMASetup(void);
static void EXAMPLE_SlaveStartDMATransfer(void);
static void EXAMPLE_TransferDataCheck(void);

/*******************************************************************************
 * Variables
 ******************************************************************************/
uint8_t slaveRxData[TRANSFER_SIZE] = {0U};
uint8_t slaveTxData[TRANSFER_SIZE] = {0U};

dma_handle_t slaveTxHandle;
dma_handle_t slaveRxHandle;

spi_dma_handle_t slaveHandle;

volatile bool isTransferCompleted = false;

/*******************************************************************************
 * Code
 ******************************************************************************/
static void SPI_SlaveUserCallback(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData)
{
    if (status == kStatus_Success)
    {
        isTransferCompleted = true;
    }
}

/*!
 * @brief Main function
 */
int main(void)
{
    /* Initialzie board setting. */
    /* set BOD VBAT level to 1.65V */
    POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
    /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

    CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true);
    CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 3U, false);

    /* attach 50 MHz clock to HSLSPI */
    CLOCK_AttachClk(kPLL0_DIV_to_HSLSPI);

    /* reset FLEXCOMM for SPI */
    RESET_PeripheralReset(kHSLSPI_RST_SHIFT_RSTn);

    /* Print project information. */
    PRINTF("This is SPI DMA transfer slave example.\r\n");
    PRINTF("This example will communicate with another master SPI on the other board.\r\n");
    PRINTF("Slave board is working...!\r\n");

    /* Initialize the SPI slave instance. */
    EXAMPLE_SlaveInit();

    /* Configure DMA for slave SPI. */
    EXAMPLE_SlaveDMASetup();

    /* Start SPI DMA transfer. */
    EXAMPLE_SlaveStartDMATransfer();


    /* De-intialize the SPI instance. */
//    SPI_Deinit(EXAMPLE_SPI_SLAVE);

    while (1)
    {
    /* Waiting for transmission complete and check if all data matched. */
    EXAMPLE_TransferDataCheck();
    }
}

static void EXAMPLE_SlaveInit(void)
{
    spi_slave_config_t slaveConfig;

    /* Get default Slave configuration. */
    SPI_SlaveGetDefaultConfig(&slaveConfig);

    /* Initialize the SPI slave. */
    slaveConfig.sselPol = (spi_spol_t)EXAMPLE_SLAVE_SPI_SPOL;
//    slaveConfig.direction = kSPI_LsbFirst;
    SPI_SlaveInit(EXAMPLE_SPI_SLAVE, &slaveConfig);
}

static void EXAMPLE_SlaveDMASetup(void)
{
    /* DMA init */
    DMA_Init(EXAMPLE_DMA);

    /* configure channel/priority and create handle for TX and RX. */
    DMA_EnableChannel(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_TX_CHANNEL);
    DMA_EnableChannel(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_RX_CHANNEL);
    DMA_SetChannelPriority(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_TX_CHANNEL, kDMA_ChannelPriority0);
    DMA_SetChannelPriority(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_RX_CHANNEL, kDMA_ChannelPriority1);
    DMA_CreateHandle(&slaveTxHandle, EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_TX_CHANNEL);
    DMA_CreateHandle(&slaveRxHandle, EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_RX_CHANNEL);
}

static void EXAMPLE_SlaveStartDMATransfer(void)
{
    uint32_t i = 0U;

    /* Initialzie the transfer data */
    for (i = 0U; i < TRANSFER_SIZE; i++)
    {
        slaveTxData[i] = 0U;
        slaveRxData[i] = 0U;
    }

//    /* Create handle for slave instance. */
//    SPI_SlaveTransferCreateHandleDMA(EXAMPLE_SPI_SLAVE, &slaveHandle, SPI_SlaveUserCallback, NULL, &slaveTxHandle,
//                                     &slaveRxHandle);

}

static void EXAMPLE_TransferDataCheck(void)
{
	static status_t state = kStatus_Success;
    uint32_t i = 0U, errorCount = 0U;
    spi_transfer_t slaveXfer;
	static bool aborted = false;

    /* Create handle for slave instance. */
    SPI_SlaveTransferCreateHandleDMA(EXAMPLE_SPI_SLAVE, &slaveHandle, SPI_SlaveUserCallback, NULL, &slaveTxHandle,
                                     &slaveRxHandle);

    /* Initialzie the transfer data */
    for (i = 0U; i < TRANSFER_SIZE; i++)
    {
		if(state != kStatus_Success)
		{
			slaveTxData[i] = 0x55;
		}
		else
		{
			slaveTxData[i] = 0x88/*slaveRxData[i]*/;
		}
    }

    slaveXfer.txData   = (uint8_t *)&slaveTxData;
    slaveXfer.rxData   = (uint8_t *)&slaveRxData;
    slaveXfer.dataSize = TRANSFER_SIZE * sizeof(slaveTxData[0]);
    slaveXfer.configFlags = kSPI_FrameAssert;

    /* Start transfer, when transmission complete, the SPI_SlaveUserCallback will be called. */
    state = SPI_SlaveTransferDMA(EXAMPLE_SPI_SLAVE, &slaveHandle, &slaveXfer);
//	isTransferCompleted = false;
    if (kStatus_Success != state)
    {
        PRINTF("There is an error when start SPI_SlaveTransferDMA \r\n");
        SPI_MasterTransferAbortDMA(EXAMPLE_SPI_SLAVE, &slaveHandle);
        aborted = true;
    }
    else
    {
    	aborted = false;
    }
    if(!aborted)
    {
		/* Wait until transfer completed */
		while (!isTransferCompleted)
		{
		}

		PRINTF("\r\nThe received data are now:");
		/*Check if the data is right*/
		for (i = 0; i < TRANSFER_SIZE; i++)
		{
			/* Print 16 numbers in a line */
			if ((i & 0x0FU) == 0U)
			{
				PRINTF("\r\n  ");
			}
			PRINTF("  0x%02X", slaveRxData[i]);
			/* Check if data matched. */
			if (slaveTxData[i] != slaveRxData[i])
			{
				errorCount++;
			}
		}
		if (errorCount == 0)
		{
			PRINTF("\r\nSPI transfer all data matched! \r\n");
		}
		else
		{
			PRINTF("\r\nError occurred in SPI transfer ! \r\n");
		}
	    isTransferCompleted = false;
    }
}

 

 

I've tried a lot of thing but nothing works.

At one time, it was working, and the next day without any modification the code stopped working.

I am using SDK_2.16.000 for LPC55S69 (2024/07/12) and SDK_2.16.000 for LPC55S36 (2024/07/15).

 

I tried with the example that @diego_charles give in this topic :

https://community.nxp.com/t5/LPC-Microcontrollers/LPC55S69-Continuous-Data-reception-using-SPI-with-...

But still doesn't work.

 

Best regards,

Loïc

0 Kudos
Reply
0 Replies