XMC4800 Relax: Dataflash example (SPI)

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

cross mob
User14604
Level 4
Level 4
First solution authored
Hello,

I tried to access the local data flash N25Q03 built into XMC4800 Relax board. Because there's no example for the 4800, I created a new SPI Master application with DAVE, then copied the required N25Q03 routines from the XMC4500 example to my project.

Works fine when running with low SPI clock speeds up to ~75 kHz. Everything above makes the dataflash chip return all zero bits on every attempt to read any data from it (e.g. device ID). Looked at the signals, but both MOSI, CLK and MISO signals look fine. Also, my example is using SPI in polled mode (no FIFO, no interrupts).
Is there something I should be aware of? Maybe performance of polled mode is too low to access the flash?

Attached you'll find the DAVE-generated SPI configuration.

Best regards,
Ernie



#include "spi_master.h"



static SPI_MASTER_STATUS_t SPI_MASTER_0_lInit(void);
/* Data Transmit pin from SPI_MASTER */
const SPI_MASTER_GPIO_t SPI_MASTER_0_MOSI =
{
.port = (XMC_GPIO_PORT_t *)PORT4_BASE,
.pin = (uint8_t)7
};

SPI_MASTER_GPIO_CONFIG_t SPI_MASTER_0_MOSI_Config =
{
.port_config =
{
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE
},
.hw_control = XMC_GPIO_HWCTRL_DISABLED
};

/* Data Receive pin for SPI_MASTER */
const SPI_MASTER_GPIO_t SPI_MASTER_0_MISO =
{
.port = (XMC_GPIO_PORT_t *)PORT4_BASE,
.pin = (uint8_t)6
};

SPI_MASTER_GPIO_CONFIG_t SPI_MASTER_0_MISO_Config =
{
.port_config =
{
.mode = XMC_GPIO_MODE_INPUT_TRISTATE,
},

};

const SPI_MASTER_GPIO_t SPI_MASTER_0_SCLKOUT =
{
.port = (XMC_GPIO_PORT_t *)PORT4_BASE,
.pin = (uint8_t)2
};

const SPI_MASTER_GPIO_CONFIG_t SPI_MASTER_0_SCLKOUT_Config =
{
.port_config =
{
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE
}
};

const SPI_MASTER_GPIO_t SPI_MASTER_0_SS_0 =
{
.port = (XMC_GPIO_PORT_t *)PORT4_BASE,
.pin = (uint8_t)3
};

const SPI_MASTER_GPIO_CONFIG_t SPI_MASTER_0_SS_0_Config =
{
.port_config =
{
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT1,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_MEDIUM_EDGE
},
.slave_select_ch = XMC_SPI_CH_SLAVE_SELECT_2
};

XMC_SPI_CH_CONFIG_t SPI_MASTER_0_Channel_Config =
{
.baudrate = 19200U,
.bus_mode = (XMC_SPI_CH_BUS_MODE_t)XMC_SPI_CH_BUS_MODE_MASTER,
.selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS,
.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE
};


const SPI_MASTER_CONFIG_t SPI_MASTER_0_Config =
{
.channel_config = &SPI_MASTER_0_Channel_Config,
.fptr_spi_master_config = SPI_MASTER_0_lInit,
/* FIFO configuration */
.tx_fifo_size = (XMC_USIC_CH_FIFO_SIZE_t)XMC_USIC_CH_FIFO_DISABLED,
.rx_fifo_size = (XMC_USIC_CH_FIFO_SIZE_t)XMC_USIC_CH_FIFO_DISABLED,
/* Clock Settings */
.shift_clk_passive_level = XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_DISABLED,
.slave_select_lines = (uint8_t)1,
.leading_trailing_delay = (uint8_t)2,
.spi_master_config_mode = XMC_SPI_CH_MODE_STANDARD, /* spi master initial mode configured mode */
.transmit_mode = SPI_MASTER_TRANSFER_MODE_DIRECT,
.receive_mode = SPI_MASTER_TRANSFER_MODE_DIRECT,

.tx_cbhandler = NULL,
.rx_cbhandler = NULL,
.parity_cbhandler = NULL,
.mosi_0_pin = &SPI_MASTER_0_MOSI, /*!< mosi0 pin pointer*/
.mosi_0_pin_config = &SPI_MASTER_0_MOSI_Config,
.mosi_1_pin = &SPI_MASTER_0_MISO,
.mosi_1_pin_config = &SPI_MASTER_0_MISO_Config,
.mosi_2_pin = NULL,
.mosi_2_pin_config = NULL,
.mosi_3_pin = NULL,
.mosi_3_pin_config = NULL,
.sclk_out_pin_config = &SPI_MASTER_0_SCLKOUT_Config,
.sclk_out_pin = &SPI_MASTER_0_SCLKOUT,
.slave_select_pin = {&SPI_MASTER_0_SS_0, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL
},
.slave_select_pin_config = {&SPI_MASTER_0_SS_0_Config, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL
},

.tx_sr = (SPI_MASTER_SR_ID_t)SPI_MASTER_SR_ID_0,
.rx_sr = (SPI_MASTER_SR_ID_t)SPI_MASTER_SR_ID_0,
};

SPI_MASTER_RUNTIME_t SPI_MASTER_0_runtime =
{
.spi_master_mode = XMC_SPI_CH_MODE_STANDARD, /* spi master transmission mode */
.word_length = 8U,


.dx0_input = SPI_MASTER_INPUT_E,
.dx0_input_half_duplex = SPI_MASTER_INPUT_INVALID,

.tx_data_dummy = false,
.rx_data_dummy = true,
.tx_busy = false,
.rx_busy = false
};

SPI_MASTER_t SPI_MASTER_0 =
{
.channel = XMC_SPI2_CH1, /* USIC channel */
.config = &SPI_MASTER_0_Config, /* spi master configuration structure pointer */
.runtime = &SPI_MASTER_0_runtime,
};

/*
* @brief Configure the port registers and data input registers of SPI channel
*
* @param[in] handle Pointer to an object of SPI_MASTER configuration
*/
static SPI_MASTER_STATUS_t SPI_MASTER_0_lInit(void)
{
SPI_MASTER_STATUS_t status;
status = SPI_MASTER_STATUS_SUCCESS; // TODO: remove status
/* LLD initialization */
XMC_SPI_CH_Init(XMC_SPI2_CH1, &SPI_MASTER_0_Channel_Config);

XMC_SPI_CH_DisableFEM(XMC_SPI2_CH1);

XMC_SPI_CH_SetBitOrderMsbFirst(XMC_SPI2_CH1);

XMC_SPI_CH_SetWordLength(XMC_SPI2_CH1, (uint8_t)8);

XMC_SPI_CH_SetFrameLength(XMC_SPI2_CH1, (uint8_t)64);

/* Configure the clock polarity and clock delay */
XMC_SPI_CH_ConfigureShiftClockOutput(XMC_SPI2_CH1,
XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_DISABLED,
XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);
/* Configure Leading/Trailing delay */
XMC_SPI_CH_SetSlaveSelectDelay(XMC_SPI2_CH1, 2U);


/* Configure the input pin properties */
XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT4_BASE, (uint8_t)6, &SPI_MASTER_0_MISO_Config.port_config);

/* Configure the data input line selected */
XMC_SPI_CH_SetInputSource(XMC_SPI2_CH1, XMC_SPI_CH_INPUT_DIN0, (uint8_t)SPI_MASTER_INPUT_E);
/* Start the SPI_Channel */
XMC_SPI_CH_Start(XMC_SPI2_CH1);

/* Configure the output pin properties */
XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT4_BASE, (uint8_t)7, &SPI_MASTER_0_MOSI_Config.port_config);

/* Initialize SPI SCLK out pin */
XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT4_BASE, (uint8_t)2, &SPI_MASTER_0_SCLKOUT_Config.port_config);

/* Configure the pin properties */
XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT4_BASE, (uint8_t)3, &SPI_MASTER_0_SS_0_Config.port_config);
XMC_SPI_CH_EnableSlaveSelect(XMC_SPI2_CH1, XMC_SPI_CH_SLAVE_SELECT_2);

XMC_USIC_CH_SetInterruptNodePointer(XMC_SPI2_CH1,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL,
(uint32_t)SPI_MASTER_SR_ID_0);

return status;
}

0 Likes
2 Replies
User14604
Level 4
Level 4
First solution authored
Below are osci shots with low speed 76800 Baud (working) and higher speed 115200 Baud (not working). It seems the XMC has some auto-chip select feature, which kicks in with higher speeds and de-selects the device.

The transfer is sending 4 bytes (0x9e 0xFF 0xFF 0xFF), so you can see 32 clock cycles (blue). The violet signal is chip select, the yellow one the XMC MISO.

76800 Baud:
3246.attach

115200 Baud de-selects after the first byte (0x9E), then keeps chip selected until all 3 bytes have been received.
3247.attach

Can anyone point me into the correct direction?

Thanks,
Ernie
0 Likes
User14604
Level 4
Level 4
First solution authored
The problem was in configuration routine. Following line

XMC_SPI_CH_DisableFEM(XMC_SPI2_CH1);

needs to be replaced by

XMC_SPI_CH_EnableFEM(XMC_SPI_CH_EnableFEM);


To set "Frame End Mode" to 1, which prevents the XMC from de-selecting the CS line if TDV (transmit register) runs empty.

Case closed.
0 Likes