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
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
Code:
#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;
}