XMC4500 SPI Master DMA transmit

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User15069
Level 1
Level 1
Hello

I tried to send some SPI-data using DMA but data transmission doest not work. I already tried different settings. Attached my code.
Maybe someone of you could give me a hint.


#include
#include
#include
#include "xmc_spi.h"
#include "xmc_dma.h"


// U1C1 for controlling of 4 SPI slave devices
#define SPI_MISO P0_0
#define SPI_MOSI P0_1
#define SPI_SS P0_9
#define SPI_SCLK P0_10

#define SPI_SSELO1 P3_3
#define SPI_SSELO2 P3_4
#define SPI_SSELO3 P3_5
#define SPI_SSELO4 P3_6

#define SPI1_SLAVE_0 0
#define SPI1_SLAVE_1 1
#define SPI1_SLAVE_2 2
#define SPI1_SLAVE_3 3
#define SPI1_STD_BAUDRATE_1MHZ 1000000UL


#define BUFFER_LENGTH 100
volatile uint8_t SPIOutData[BUFFER_LENGTH];

/**
* @brief SPI configuration structure
*/
XMC_SPI_CH_CONFIG_t spi_config =
{
.baudrate = SPI1_STD_BAUDRATE_1MHZ,
.bus_mode = XMC_SPI_CH_BUS_MODE_MASTER,
.selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS,
.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE
};



static XMC_DMA_CH_CONFIG_t U1C1_DMAChConfig =
{
.dst_addr = (uint32_t)&(XMC_USIC1_CH1->TBUF[0]),
.src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8,
.src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT,
.dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE,
.src_burst_length = XMC_DMA_CH_BURST_LENGTH_8,
.dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1,
.transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA,
.transfer_type = XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK,
.dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_HARDWARE,
.dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_0,
.enable_interrupt = true
};

void Init_SPI1(uint32_t baudrate)
{
if (baudrate != 0)
spi_config.baudrate = baudrate;
else
spi_config.baudrate = SPI1_STD_BAUDRATE_1MHZ; // use standard baudrate

/*Initialize and Start SPI*/
XMC_SPI_CH_Init(XMC_SPI1_CH1, &spi_config);

/*Input source selected*/
XMC_SPI_CH_SetInputSource(XMC_SPI1_CH1, XMC_SPI_CH_INPUT_DIN0, USIC1_C1_DX0_P0_0);
XMC_SPI_CH_Start(XMC_SPI1_CH1);

/*GPIO configuration*/
XMC_GPIO_SetMode(SPI_MOSI, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
XMC_GPIO_SetMode(SPI_SS, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
XMC_GPIO_SetMode(SPI_SCLK, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
XMC_GPIO_SetMode(SPI_MISO, XMC_GPIO_MODE_INPUT_TRISTATE);

XMC_GPIO_SetMode(SPI_SSELO1, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
XMC_GPIO_SetMode(SPI_SSELO2, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
XMC_GPIO_SetMode(SPI_SSELO3, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
XMC_GPIO_SetMode(SPI_SSELO4, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2);
}

void Init_SPI_DMA(uint8_t *Buffer, XMC_USIC_CH_t *USICChannel, uint8_t DMAChannel, XMC_DMA_CH_CONFIG_t *DMAChannelConfig)
{
// Init GPDMA0 using specified DMA config
XMC_DMA_CH_Init(XMC_DMA0, DMAChannel, DMAChannelConfig);

// Enable GPDMA channel event BLOCK_TRANSFER_COMPLETE
XMC_DMA_CH_EnableEvent(XMC_DMA0, DMAChannel, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE);

// Route interrupt vector to the handler routine and enable DMA event handling

NVIC_SetPriority(GPDMA0_0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 63, 0));
NVIC_EnableIRQ(GPDMA0_0_IRQn);

Init_SPI1(1000000);

XMC_SPI_CH_EnableEvent(USICChannel, XMC_SPI_CH_EVENT_TRANSMIT_BUFFER);

XMC_USIC_CH_SetInterruptNodePointer(USICChannel, XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER, 0);

XMC_SPI_CH_Start(USICChannel);

// Make DMA ready
XMC_USIC_CH_TriggerServiceRequest(USICChannel, 0);

XMC_DMA_CH_SetBlockSize(XMC_DMA0, DMAChannel, BUFFER_LENGTH);
XMC_DMA_CH_SetSourceAddress(XMC_DMA0, DMAChannel, (uint32_t)Buffer);

// Enable DMA Channel
XMC_DMA_CH_Enable(XMC_DMA0, DMAChannel);
}

void GPDMA0_0_IRQHandler(void)
{
const uint8_t U1C1DMAChannel = 0;

if (XMC_DMA_CH_GetEventStatus(XMC_DMA0, U1C1DMAChannel) == XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE)
{
XMC_DMA_CH_ClearEventStatus(XMC_DMA0, U1C1DMAChannel, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE);
printf("U1C1 DMA Done!\n");
}
}

// just as a test to check if SPI data transmission works
static void SPI1_Send_Byte(uint8_t Data)
{
XMC_SPI_CH_EnableSlaveSelect(XMC_SPI1_CH1, XMC_SPI_CH_SLAVE_SELECT_0); // enable slave select line 0
/* send a byte*/
XMC_SPI_CH_Transmit(XMC_SPI1_CH1, Data, XMC_SPI_CH_MODE_STANDARD);

/* wait till the byte has been transmitted*/
while((XMC_SPI_CH_GetStatusFlag(XMC_SPI1_CH1) & XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION) == 0U);
XMC_SPI_CH_ClearStatusFlag(XMC_SPI1_CH1, XMC_SPI_CH_STATUS_FLAG_TRANSMIT_SHIFT_INDICATION);

/* disable slave select line */
XMC_SPI_CH_DisableSlaveSelect(XMC_SPI1_CH1);
}



int main(void)
{
uint8_t n = 0;

for (n = 0; n < BUFFER_LENGTH; n++)
{
SPIOutData = n;
}

// Init General Purpose DMA 0
XMC_DMA_Init(XMC_DMA0);

Init_SPI_DMA(SPIOutData, XMC_USIC1_CH1, 0, &U1C1_DMAChConfig);

/* Placeholder for user application code. The while loop below can be replaced with user application code. */
while(1U)
{

}
}



Thank you
Geri
0 Likes
0 Replies