SEMC read unexpected behaviour

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

SEMC read unexpected behaviour

966 Views
nickwallis
Senior Contributor I

Hi,

I am observing some unexpected behaviour when reading data from an FPGA that is attached to the SEMC interface.

I have the SEMC configured in SRAM mode to connect to an external FPGA. The connections between the two are a 16-bit data bus, /CS and /OE. The MCU only ever reads from the FPGA, there are no writes. The MCU is always reading the same register, so effectively there is one fixed address although in practice there is no need for any address decoding as there is nothing else on the same bus.

What I am seeing is, when I read from the SEMC in my code, I see an unexpected number of /CS and /OE strobes on the oscilloscope. I expect just one /CS and /OE for each read, when in fact I see 16. Why might this be please? I have setup the SEMC using ADMUX mode, ASYNC mode, port size = 16 bits and burst length = 1. The code is really simple:

volatile uint16_t *fpga_data  = (uint16_t *)0xa0000000;
volatile uint16_t data;
volatile uint32_t i;

while (1)
{
data = fpga_data[0];
PRINTF("%x\r\n", data);

for(i=0;i<0x2ffffff;i++) // this loop approx. 1 second
{
	__asm volatile ("nop");
	__asm volatile ("nop");
	__asm volatile ("nop");
	__asm volatile ("nop");
	__asm volatile ("nop");
}

}

 

I know that in an older build of code, this used to work as expected (i.e. I saw just one /CS and /OE strobe for each SEMC read), but now it is behaving differently and I don't know why.

Can anyone help please?

thanks

-Nick 

0 Kudos
6 Replies

918 Views
nickwallis
Senior Contributor I

Hi @jeremyzhou 

I tried the SDK driver for SEMC, and the behaviour is the same. I checked the SEMC registers in a debug session, and they are the same (as expected) no matter which driver I use.

I also compared all of the SEMC registers between the code which gives just 1 x CS and OE for each access (as expected), and the code that gives 16 x CS and OE for each access (definitely not as expected), and the SEMC registers are the same in both cases.

So I am really at a loss to explain this behaviour, but I did notice that someone else has observed similar behaviour (see this post https://community.nxp.com/t5/i-MX-RT/Are-there-any-known-issues-with-using-multiple-SEMC-device/m-p/...)

I also checked the register for the clock sources for the SEMC module in both cases (CCM-ANALOG-PFD-528 and CCM-CBCDR) and they also are the same in both cases.

Clearly, there is something obscure and not obvious that is causing this behaviour.

@jeremyzhou please can you contact an SEMC module expert who might be able to help?

thanks and regards

-Nick

0 Kudos

909 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thanks for your reply.
According to your description, the older and new code SEMC demo is almost the same, however, their behaviors are different, it doesn't make sense.
So I was wondering if you can share these two demo codes, as I'd like to replicate the phenomenon on my site.
Looking forward to your reply.
Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

 

0 Kudos

899 Views
nickwallis
Senior Contributor I

thanks @jeremyzhou 

I am happy to share the code, please can you PM me so we can do that.

But, I think you might struggle to reproduce in hardware, because the NXP EVK board uses SDRAM which means the signals we are using (CS# and OE#) are used for other SDRAM signals on that board.

(We are using GPIO_EMC_20 for OE# and GPIO_EMC_41 for CSX0#)

-Nick

0 Kudos

950 Views
nickwallis
Senior Contributor I

I captured some oscilloscope traces showing this.

1st capture below shows the unexpected behaviour on the scope, when the code reads from the SEMC interface I see 16 x CS# and 16 x OE#, when I expect just one. Top trace is CS#, bottom one OE#.

semc_bad_16.png

2nd capture below is the system working as expected, when the code reads from the SEMC interface I see on the scope one CS# pulse and one #OE pulse. The timebase is the same as above, 1us/div, so the scale is the same.

semc_good_1.png

Last one is a zoom of the above, showing the 1 x CS# and 1 x OE#. The OE# pulse width is what I expected, 16 clocks of 163.86MHz = 98 ns.

semc_good_1_zoom.png

Here is the code that sets up the clock source for the SEMC module (PLL2):

	// Set the PLL2 PFD divider to ÷ 29,
	// so the output frequency is now 528MHz * [18/29] = 327MHz
	CLOCK_InitSysPfd(kCLOCK_Pfd2, 29);

	// Set PLL2 as the clock source for the SEMC module
	CLOCK_SetMux(kCLOCK_SemcMux, 1);

	// Set the AXI_PODF (a.k.a. SEMC_PODF) divider in CBCDR to ÷2,
	// so the actual SEMC module clock is 327MHz ÷ 2 = 163.86MHz
	CLOCK_SetDiv(kCLOCK_SemcDiv, 1);

	InitSemc(); //NJW

And lastly here is the contents of the InitSemc() function.

void InitSemc(void)
{

	// enable SEMC clocks
	CLOCK_EnableClock(kCLOCK_Semc);
	CLOCK_EnableClock(kCLOCK_SemcExsc);

	// initialise all the SEMC base registers to zero
	SEMC->BR[0] = 0;
	SEMC->BR[1] = 0;
	SEMC->BR[2] = 0;
	SEMC->BR[3] = 0;
	SEMC->BR[4] = 0;
	SEMC->BR[5] = 0;

	// Base Register 6 (For PSRAM device 0) (BR6)
	// High position 20 bits of SoC level Base Address = 0xA0000000;
	// Memory size = 4 KB
	// VALID = 1
	SEMC->BR[6] = 0xa0000001;

	SEMC->BR[7] = 0;
	SEMC->BR[8] = 0;

	// reset the SEMC module
	SEMC->MCR = SEMC_MCR_SWRST_MASK;
	while((SEMC->MCR & (uint32_t)SEMC_MCR_SWRST_MASK) != 0U)
	{
		;
	}

	// disable the SEMC module
	SEMC->MCR |= SEMC_MCR_MDIS_MASK;

	// setup register MCR, but keep the SEMC module disabled for now
	// BTO = 0x1f
	// DQSMD = 1
	// MDIS = 1
	SEMC->MCR = 0x1f000006;

	// weight settings for ARM AXI bus memory access
	// For now, values are taken from previous working SEMC example
	SEMC->BMCR0 = 0x00104085;
	SEMC->BMCR1 = 0x40602485;

	// setup IOCR
	// MUX_CSX0 = PSRAM CE#
	SEMC->IOCR = 0x00000030;

	// setup SRAMCR0
	// Column Address bit width = 12 bits
	// ADV# is high during address hold state
	// ADV# is active low
	// Address/Data MUX mode (ADMUX)
	// Burst Length = 1
	// ASYNC mode is enabled
	// Port Size = 16 bits
	SEMC->SRAMCR0 = 0x0000f001;

	// setup SRAMCR1
	// RE high time = 16 clocks of 163.86MHz = 98 ns
	// RE low time = 16 clocks of 163.86MHz = 98 ns
//	SEMC->SRAMCR1 = 0x66666633;
	SEMC->SRAMCR1 = 0xffffffff;

	// setup SRAMCR2
	// CE# interval minimum time is 9 clock cycles
	// Address to write data hold time is 6 clock cycles
	// Turnaround time is 7 clock cycles
	SEMC->SRAMCR2 = 0x08006600; //NEW, other bits should only apply to SYNC mode!
//	SEMC->SRAMCR2 = 0x08f0660f; //OLD

	// enable the SEMC module
	SEMC->MCR &= ~SEMC_MCR_MDIS_MASK;

}

I am struggling to explain this behaviour, what might be causing there to be 16x CS# and OE# pulses for one read?

This worked OK in an older version of software, so there must be a difference somewhere but I don't know where.

-Nick

0 Kudos

946 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
Regarding your question, firstly, I'd like to suggest you figure out the difference of the configuration of either SEMC or pin between the older and current code version.
Next, after having a brief review of your code, I've not found anything wrong, so I'd like to suggest you can try to use the SEMC driver to configure the SEMC module, and you can find the driver in the attachment.
Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

941 Views
nickwallis
Senior Contributor I

Hi @jeremyzhou 

Thank you, I will try your driver but I don't see any attachment? Please can you send it?

Yes I have compared the old and new code, and in the debugger compared the registers, but so far I did not spot any differences that would explain this behaviour.

regards

-Nick

0 Kudos