SPI1 with DMA on K22 - BUG

cancel
Showing results for 
Search instead for 
Did you mean: 

SPI1 with DMA on K22 - BUG

489 Views
brunoalbrecht
Contributor III

Greetings,

I just found another bug on NXP's SDK 2.3.0 (maybe on older versions as well, haven't tested it), this time on the driver for SPI over DMA (master) when using SPI instance 1 on a Kinetis microcontroller model MK22FN512VLH12.

My environment:

* Win 10 Pro 1709

* KDS 3.2

* SDK 2.3.0 for FRDM-K22F

* Dev Board FRDM-K22F

Using the demo application under SDK folder\boards\frdmk22f\driver_examples\dspi\edma_b2b_transfer\master\

First test: Original application (SPI0):

* Transfer Size: 64 Bytes (original)

spi0-64B.png

* Transfer Size: 32 Bytes

spi0-32B.png

* Transfer Size: 4 Bytes

spi0-4B.png

Second Test: Application changed to SPI1:

pin_mux.c:

void BOARD_InitPins(void)
{
    /* Port C Clock Gate Control: Clock enabled */
    CLOCK_EnableClock(kCLOCK_PortC);
    /* Port D Clock Gate Control: Clock enabled */
    CLOCK_EnableClock(kCLOCK_PortD);
    /* Port E Clock Gate Control: Clock enabled */
    CLOCK_EnableClock(kCLOCK_PortE);

    /* PORTC4 (pin 49) is configured as SPI0_PCS0 */
    PORT_SetPinMux(PORTC, 4U, kPORT_MuxAlt2);
    /* PORTD4 (pin 61) is configured as SPI1_PCS0 */
    PORT_SetPinMux(PORTD, 4U, kPORT_MuxAlt7);

    /* PORTC5 (pin 50) is configured as SPI0_SCK */
    PORT_SetPinMux(PORTC, 5U, kPORT_MuxAlt2);
    /* PORTD5 (pin 62) is configured as SPI1_SCK */
    PORT_SetPinMux(PORTD, 5U, kPORT_MuxAlt7);

    /* PORTC6 (pin 51) is configured as SPI0_SOUT */
    PORT_SetPinMux(PORTC, 6U, kPORT_MuxAlt2);
    /* PORTD6 (pin 63) is configured as SPI1_SOUT */
    PORT_SetPinMux(PORTD, 6U, kPORT_MuxAlt7);

    /* PORTC7 (pin 52) is configured as SPI0_SIN */
    PORT_SetPinMux(PORTC, 7U, kPORT_MuxAlt2);
    /* PORTD7 (pin 64) is configured as SPI1_SIN */
    PORT_SetPinMux(PORTD, 7U, kPORT_MuxAlt7);

    /* PORTE0 (pin 1) is configured as UART1_TX */
    PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3);

    /* PORTE1 (pin 2) is configured as UART1_RX */
    PORT_SetPinMux(PORTE, 1U, kPORT_MuxAlt3);

    SIM->SOPT5 = ((SIM->SOPT5 &
                   /* Mask bits to zero which are setting */
                   (~(SIM_SOPT5_UART1TXSRC_MASK)))

                  /* UART 1 transmit data source select: UART1_TX pin. */
                  | SIM_SOPT5_UART1TXSRC(SOPT5_UART1TXSRC_UART_TX));
}

dspi_edma_b2b_transfer_master.c:

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define EXAMPLE_DSPI_MASTER_BASEADDR SPI1
#define EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR DMAMUX
#define EXAMPLE_DSPI_MASTER_DMA_BASEADDR DMA0
#define EXAMPLE_DSPI_MASTER_DMA_RX_REQUEST_SOURCE kDmaRequestMux0SPI1
#define EXAMPLE_DSPI_MASTER_DMA_TX_REQUEST_SOURCE kDmaRequestMux0SPI1
#define DSPI_MASTER_CLK_SRC DSPI1_CLK_SRC
#define DSPI_MASTER_CLK_FREQ CLOCK_GetFreq(DSPI1_CLK_SRC)
#define EXAMPLE_DSPI_MASTER_PCS_FOR_INIT kDSPI_Pcs0
#define EXAMPLE_DSPI_MASTER_PCS_FOR_TRANSFER kDSPI_MasterPcs0
#define EXAMPLE_DSPI_DEALY_COUNT 0xfffffU
#define TRANSFER_SIZE 64U         /* Transfer dataSize */
#define TRANSFER_BAUDRATE 500000U /* Transfer baudrate - 500k */‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

* Transfer Size: 64 Bytes (original)

spi1-64B.png

* Transfer Size: 32 Bytes

spi1-32B.png

* Transfer Size: 4 Bytes

spi1-4B.png

As can be seen, not only the amount of data to transfer is not transferred, the first 2 Bytes are wrong (instead of send '1' and '2', it sends '1' then '0').

Has any one had this problem and solved it? Anything that I'm doing wrong?

Best regards,

Bruno

2 Replies

180 Views
gerardo_rodriguez
NXP Employee
NXP Employee

Hi Bruno,

The SPI1 instance has a shared DMA request for RX/TX and the DSPI EDMA driver expects only the RX DMA channel to be triggered by the RX request and the RX channel and will then link to the TX channel.

 

So in your code, you should remove the EXAMPLE_DSPI_MASTER_DMA_TX_REQUEST_SOURCE macro definition, this way the following code will be disabled by the preprocessor:

 

#if (defined EXAMPLE_DSPI_MASTER_DMA_TX_REQUEST_SOURCE)
    DMAMUX_SetSource(EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR, masterTxChannel,
                     (uint8_t)EXAMPLE_DSPI_MASTER_DMA_TX_REQUEST_SOURCE);
    DMAMUX_EnableChannel(EXAMPLE_DSPI_MASTER_DMA_MUX_BASEADDR, masterTxChannel);
#endif

 

Let me know if this solves your issue.

Best regards,

Gerardo

180 Views
brunoalbrecht
Contributor III

Sorry for the late reply and thank you for your message. Indeed the proposed change solves the problem.

From what I understood, the same request source was being assigned to two different DMAMUX channels, which was confusing the peripheral, so to say.

This topic can be closed.