Перейти к содержанию
    

LPC43XX + SDRAM

 

 

Господа, если кто имел дело с китом LPC4357-EVB (мэйд "ELEMENT 14") или просто цеплял SDRAM к LPX43xx - помогите.

Сначала я пытался запустить  LPX4337 + MT48LC4M16A на своей плате. Драйвер EMC  взял из примера, идущего с выше означенным китом. Получилось не совсем понятное для меня поведение: запись по адресам SDRAM отрабатывает нормально, а при считывании  на 4 байте камень уходит в ступор: если программа выполнялась под отладкой, то выдается сообщение, что невозможно остановить CPU. Если без отладки, то она просто перестает работать, по крайней мере, цикл main не крутится и светодиод по таймеру  не мигает. Раньше с SDRAM как-то не приходилось работать, да и LPX43xx только осваиваю, по этому такое поведение не совсем понятно. Ну, не работает память, тайминги не те или сопля в плате, ну, читается от туда мусор, а виснет-то почему? :) . Посмотрел осциллографом сигналы на ногах SDRAM во время цикла записи, все в наличии, уровни нормальные, задержка клока правильная, по tset - thold проходит с запасом (частота всего 100 Мгц).

Ладно, на моей плате не работает, решил на ките запустить его родной пример  (по крайней мере, скачанный с сайта производителя кита) . Выяснилось, что настройки драйвера EMC расчитаны на память  4М16, а запаяна 16М16, пришлось поменять пару параметров.  Но все рано не заработало, точно такое-же поведение - виснет при считывании!   Получается, производитель не особо старался, допиливая софт под свою плату? На всякий случай выкладываю листинг драйвера и хедер к нему.

lpc4350_db1_emc.h

#define __CRYSTAL        (12000000UL)    /* Crystal Oscillator frequency          */
#define __PLLMULT		 (16)
#define __PLLOUTHZ		 (__CRYSTAL * __PLLMULT)
#define __EMCDIV		 (2)
#define __EMCHZ			 (__PLLOUTHZ / __EMCDIV)

void MemoryPinInit(void);
void EMCFlashInit(void);

/* SDRAM Address Base for DYCS0*/
#define SDRAM_BASE_ADDR 0x28000000
#define FLASH_BASE_ADDR 0x1C000000

#define EMC_SDRAM_WIDTH_8_BITS		0
#define EMC_SDRAM_WIDTH_16_BITS		1
#define EMC_SDRAM_WIDTH_32_BITS		2

#define EMC_SDRAM_SIZE_16_MBITS		0
#define EMC_SDRAM_SIZE_64_MBITS		1
#define EMC_SDRAM_SIZE_128_MBITS	2
#define EMC_SDRAM_SIZE_256_MBITS	3
#define EMC_SDRAM_SIZE_512_MBITS	4

#define EMC_SDRAM_DATA_BUS_16_BITS	0
#define EMC_SDRAM_DATA_BUS_32_BITS	1

#define EMC_B_ENABLE 					(1 << 19)
#define EMC_ENABLE 						(1 << 0)
#define EMC_CE_ENABLE 					(1 << 0)
#define EMC_CS_ENABLE 					(1 << 1)
#define EMC_CLOCK_DELAYED_STRATEGY 		(0 << 0)
#define EMC_COMMAND_DELAYED_STRATEGY 	(1 << 0)
#define EMC_COMMAND_DELAYED_STRATEGY2 	(2 << 0)
#define EMC_COMMAND_DELAYED_STRATEGY3 	(3 << 0)
#define EMC_INIT(i) 					((i) << 7)
#define EMC_NORMAL 						(0)
#define EMC_MODE 						(1)
#define EMC_PRECHARGE_ALL 				(2)
#define EMC_NOP 						(3)

/* The Hitex LPC18xx Evaluation board contains a 64Mb SDRAM with a 16-bit data bus */
#define SDRAM_SIZE_BYTES		(1024UL * 1024UL * 8UL)
#define SDRAM_WIDTH			EMC_SDRAM_WIDTH_16_BITS
#define SDRAM_SIZE_MBITS		EMC_SDRAM_SIZE_256_MBITS//EMC_SDRAM_SIZE_64_MBITS
#define SDRAM_DATA_BUS_BITS		EMC_SDRAM_DATA_BUS_16_BITS			
#define SDRAM_COL_ADDR_BITS		9//8		
#define CLK0_DELAY                      5
/*
// 48LC4M32B2-7 on Diolan LPC-4350-DB1 demodoard 
#define SDRAM_SIZE_BYTES		(1024UL * 1024UL * 16UL)
#define SDRAM_WIDTH			EMC_SDRAM_WIDTH_32_BITS
#define SDRAM_SIZE_MBITS		EMC_SDRAM_SIZE_128_MBITS
#define SDRAM_DATA_BUS_BITS		EMC_SDRAM_DATA_BUS_32_BITS
#define SDRAM_COL_ADDR_BITS		8		
#define CLK0_DELAY              5*/


#define EMCSRDRAMInit( )        vEMC_InitSRDRAM(SDRAM_BASE_ADDR, SDRAM_WIDTH, SDRAM_SIZE_MBITS, SDRAM_DATA_BUS_BITS, SDRAM_COL_ADDR_BITS);

void vEMC_InitSRDRAM(uint32_t u32BaseAddr, uint32_t u32Width, uint32_t u32Size, uint32_t u32DataBus, uint32_t u32ColAddrBits);
void emc_WaitUS(volatile uint32_t us);
void emc_WaitMS(uint32_t ms);

lpc4350_db1_emc.с

void MemoryPinInit(void)
{
  /* select correct functions on the GPIOs */

#if 1
  /* DATA LINES 0..31 > D0..D31 */
  	/* P1_7 - EXTBUS_D0 — External memory data line 0 */
    scu_pinmux(0x1,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_7: D0 (function 0) errata */
    scu_pinmux(0x1,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_8: D1 (function 0) errata */
    scu_pinmux(0x1,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_9: D2 (function 0) errata */
    scu_pinmux(0x1,  10, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_10: D3 (function 0) errata */
    scu_pinmux(0x1,  11, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_11: D4 (function 0) errata */
    scu_pinmux(0x1,  12, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_12: D5 (function 0) errata */
    scu_pinmux(0x1,  13, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_13: D6 (function 0) errata */
    scu_pinmux(0x1,  14, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_14: D7 (function 0) errata */
    scu_pinmux(0x5,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_4: D8 (function 0) errata */
    scu_pinmux(0x5,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_5: D9 (function 0) errata */
    scu_pinmux(0x5,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_6: D10 (function 0) errata */
    scu_pinmux(0x5,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_7: D11 (function 0) errata */
    scu_pinmux(0x5,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_0: D12 (function 0) errata */
    scu_pinmux(0x5,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_1: D13 (function 0) errata */
    scu_pinmux(0x5,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_2: D14 (function 0) errata */
    scu_pinmux(0x5,  3,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* P5_3: D15 (function 0) errata */
#if SDRAM32
    scu_pinmux(0xD,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_2: D16 (function 0) errata */
    scu_pinmux(0xD,  3,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_3: D17 (function 0) errata */
    scu_pinmux(0xD,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_4: D18 (function 0) errata */
    scu_pinmux(0xD,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_5: D19 (function 0) errata */
    scu_pinmux(0xD,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_6: D20 (function 0) errata */
    scu_pinmux(0xD,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_7: D21 (function 0) errata */
    scu_pinmux(0xD,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_8: D22 (function 0) errata */
    scu_pinmux(0xD,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_9: D23 (function 0) errata */
    scu_pinmux(0xE,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_5: D24 (function 0) errata */
    scu_pinmux(0xE,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_6: D25 (function 0) errata */
    scu_pinmux(0xE,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_7: D26 (function 0) errata */
    scu_pinmux(0xE,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_8: D27 (function 0) errata */
    scu_pinmux(0xE,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_9: D28 (function 0) errata */
    scu_pinmux(0xE, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_10: D29 (function 0) errata */
    scu_pinmux(0xE, 11,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_11: D30 (function 0) errata */
    scu_pinmux(0xE, 12,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_12: D31 (function 0) errata */
#endif

  /* ADDRESS LINES A0..A11 > A0..A11 */
	scu_pinmux(0x2,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P2_9 - EXTBUS_A0 — External memory address line 0 */
	scu_pinmux(0x2, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P2_10 - EXTBUS_A1 — External memory address line 1 */	
	scu_pinmux(0x2, 11,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P2_11 - EXTBUS_A2 — External memory address line 2 */	
	scu_pinmux(0x2, 12,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P2_12 - EXTBUS_A3 — External memory address line 3 */
	scu_pinmux(0x2, 13,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P2_13 - EXTBUS_A4 — External memory address line 4 */	
	scu_pinmux(0x1,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* P1_0 - EXTBUS_A5 — External memory address line 5 */
	scu_pinmux(0x1,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* P1_1 - EXTBUS_A6 — External memory address line 6 */	
	scu_pinmux(0x1,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* P1_2 - EXTBUS_A7 — External memory address line 7 */	
	scu_pinmux(0x2,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P2_8 - EXTBUS_A8 — External memory address line 8 */
	scu_pinmux(0x2,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P2_7 - EXTBUS_A9 — External memory address line 9 */	
	scu_pinmux(0x2,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* P2_6 - EXTBUS_A10 — External memory address line 10 */
	scu_pinmux(0x2,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* P2_2 - EXTBUS_A11 — External memory address line 11 */
	scu_pinmux(0x2,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* P2_1 - EXTBUS_A12 — External memory address line 12 */
	scu_pinmux(0x2,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* P2_0 - EXTBUS_A13 — External memory address line 13 */	
	scu_pinmux(0x6,  8,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1);	/* P6_8 - EXTBUS_A14 — External memory address line 14 */
	scu_pinmux(0x6,  7,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1);	/* P6_7 - EXTBUS_A15 — External memory address line 15 */	
	scu_pinmux(0xD, 16,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* PD_16 - EXTBUS_A16 — External memory address line 16 */
	scu_pinmux(0xD, 15,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* PD_15 - EXTBUS_A17 — External memory address line 17 */	
	scu_pinmux(0xE,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* PE_0 - EXTBUS_A18 — External memory address line 18 */
	scu_pinmux(0xE,  1,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* PE_1 - EXTBUS_A19 — External memory address line 19 */
	scu_pinmux(0xE,  2,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* PE_2 - EXTBUS_A20 — External memory address line 20 */
	scu_pinmux(0xE,  3,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* PE_3 - EXTBUS_A21 — External memory address line 21 */
	scu_pinmux(0xE,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* PE_4 - EXTBUS_A22 — External memory address line 22 */	
	scu_pinmux(0xA,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* PA_4 - EXTBUS_A23 — External memory address line 23 */

  /* BYTE ENABLES */
	//scu_pinmux(0x1,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);	/* P1_4 - EXTBUS_BLS0 — LOW active Byte Lane select signal 0 */
	//scu_pinmux(0x6,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1);	/* P6_6 - EXTBUS_BLS1 — LOW active Byte Lane select signal 1 */	
	//scu_pinmux(0xD, 13,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* PD_13 - EXTBUS_BLS2 — LOW active Byte Lane select signal 2 */
	//scu_pinmux(0xD, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);	/* PD_10 - EXTBUS_BLS3 — LOW active Byte Lane select signal 3 */		

    scu_pinmux(0x6,  9,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_9: EXTBUS_DYCS0  (function 0) > CS# errata */
    scu_pinmux(0x1,  6,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P1_6: WE (function 0) errata */
    scu_pinmux(0x6,  4,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_4: CAS  (function 0) > CAS# errata */
    scu_pinmux(0x6,  5,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_5: RAS  (function 0) > RAS# errata */

    LPC_SCU_CLK(0) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK0: EXTBUS_CLK0  (function 0, from datasheet) > CLK ds */
    //LPC_SCU_CLK(1) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK1: EXTBUS_CLK1  (function 2, from datasheet) */
    //LPC_SCU_CLK(2) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK2: EXTBUS_CLK2  (function 2, from datasheet) */
    //LPC_SCU_CLK(3) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK3: EXTBUS_CLK3  (function 2, from datasheet) */

    scu_pinmux(0x6, 11,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_11: CKEOUT0  (function 0) > CKE errata */
    scu_pinmux(0x6, 12,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_12: DQMOUT0  (function 0) > DQM0 errata */
    scu_pinmux(0x6, 10,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* P6_10: DQMOUT1  (function 0) > DQM1 errata */
    //scu_pinmux(0xD,  0,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2);  /* PD_0: DQMOUT2  (function 2, from datasheet) > DQM2 errata */
    //scu_pinmux(0xE, 13,  (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3);  /* PE_13: DQMOUT3  (function 3, from datasheet) > DQM3 errata */

	scu_pinmux(	1	,	3	,	MD_PLN_FAST	,	3	);	//OE
	scu_pinmux(	1	,	4	,	MD_PLN_FAST	,	3	);	//BLS0
	scu_pinmux(	1	,	5	,	MD_PLN_FAST	,	3	);	//CS0
	scu_pinmux(	1	,	6	,	MD_PLN_FAST	,	3	);	//WE

#endif
}

void EMCFlashInit(void)
{
	// Hitex board SST39VF3201B Flash
	// Read Cycle Time 70 nS minimum
	// Chip Enable Access Time 70 ns maximum
	// Address Access Time 70 ns max
	// Toe 35 ns max
	// CE/OE high to inactive output 16 ns

	/* Set up EMC Controller */
	LPC_EMC->STATICWAITRD0 = DELAYCYCLES(70)+1;

	LPC_EMC->STATICWAITPAG0 = DELAYCYCLES(70)+1;


	LPC_EMC->CONTROL = 0x01;
	LPC_EMC->STATICCONFIG0 = (1UL<<7) | (1UL);
	LPC_EMC->STATICWAITOEN0 = DELAYCYCLES(35)+1;

    /*Enable Buffer for External Flash*/
    LPC_EMC->STATICCONFIG0 |= 1<<19;
}

/* SDRAM refresh time to 16 clock num */
#define EMC_SDRAM_REFRESH(freq,time)  \
  (((uint64_t)((uint64_t)time * freq)/16000000000ull)+1)

void vEMC_InitSRDRAM(uint32_t u32BaseAddr, uint32_t u32Width, uint32_t u32Size, uint32_t u32DataBus, uint32_t u32ColAddrBits)
{
   // adjust the CCU delaye for EMI (default to zero)

	// Move all clock delays together
	LPC_SCU->EMCDELAYCLK = ((CLK0_DELAY)
				|  (CLK0_DELAY << 4)
				|  (CLK0_DELAY << 8)
				|  (CLK0_DELAY << 12));

   /* Initialize EMC to interface with SDRAM */
	LPC_EMC->CONTROL 			= 0x00000001;   /* Enable the external memory controller */	
	LPC_EMC->CONFIG 			= 0;

	LPC_EMC->DYNAMICCONFIG0 	= ((u32Width << 7) | (u32Size << 9)/* | (1UL << 12)*/ | (u32DataBus << 14));
	LPC_EMC->DYNAMICCONFIG2 	= ((u32Width << 7) | (u32Size << 9)/* | (1UL << 12)*/ | (u32DataBus << 14));

        LPC_EMC->DYNAMICRASCAS0 	= (3 << 0) | (3 << 8);      // aem
        LPC_EMC->DYNAMICRASCAS2 	= (3 << 0) | (3 << 8);  // aem
	
	LPC_EMC->DYNAMICREADCONFIG	= EMC_COMMAND_DELAYED_STRATEGY;
	
	LPC_EMC->DYNAMICRP 		= 2;    // calculated from xls sheet for 120 MHz
	LPC_EMC->DYNAMICRAS 		= 5;
	LPC_EMC->DYNAMICSREX 		= 8;
	LPC_EMC->DYNAMICAPR 		= 1;
	LPC_EMC->DYNAMICDAL 		= 5;
	LPC_EMC->DYNAMICWR 		= 1;
	LPC_EMC->DYNAMICRC 		= 8;
	LPC_EMC->DYNAMICRFC 		= 8;
	LPC_EMC->DYNAMICXSR 		= 8;
	LPC_EMC->DYNAMICRRD 		= 1;
	LPC_EMC->DYNAMICMRD 		= 1;

	LPC_EMC->DYNAMICCONTROL 	= EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_NOP);
	emc_WaitUS(100);
	
	LPC_EMC->DYNAMICCONTROL 	= EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_PRECHARGE_ALL);

	LPC_EMC->DYNAMICREFRESH 	= 2;
	emc_WaitUS(100);
	

        LPC_EMC->DYNAMICREFRESH 	= 118;
	
	LPC_EMC->DYNAMICCONTROL 	= EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_MODE);

	if(u32DataBus == 0)   // burst size 8, CAS3
	{
		*((volatile uint32_t *)(u32BaseAddr | ((3UL | (3UL << 4)) << (u32ColAddrBits + 2 + 1))));
	}
	else   // burst size 4, CAS3
	{
		*((volatile uint32_t *)(u32BaseAddr | ((2UL | (3UL << 4)) << (u32ColAddrBits + 2 + 2))));
	}

	LPC_EMC->DYNAMICCONTROL 	= 0; // EMC_CE_ENABLE | EMC_CS_ENABLE;
	LPC_EMC->DYNAMICCONFIG0 	= ((u32Width << 7) | (u32Size << 9)/* | (1UL << 12)*/ | (u32DataBus << 14)) | EMC_B_ENABLE;
	LPC_EMC->DYNAMICCONFIG1 	= ((u32Width << 7) | (u32Size << 9)/* | (1UL << 12)*/ | (u32DataBus << 14)) | EMC_B_ENABLE;
	LPC_EMC->DYNAMICCONFIG2 	= ((u32Width << 7) | (u32Size << 9)/* | (1UL << 12)*/ | (u32DataBus << 14)) | EMC_B_ENABLE;
	LPC_EMC->DYNAMICCONFIG3 	= ((u32Width << 7) | (u32Size << 9)/* | (1UL << 12)*/ | (u32DataBus << 14)) | EMC_B_ENABLE;
}

В какую сторону копать?  Какие ошибки в инициализации EMC могут привести к  таким симптомам?  Может кто поделится рабочим исходником для инициализации?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

35 минут назад, b-volkov сказал:

В какую сторону копать?  Какие ошибки в инициализации EMC могут привести к  таким симптомам?  Может кто поделится рабочим исходником для инициализации?

1) Сделать обработку fault-ов.

2) Периферийные блоки у NXP совместимы во многих семействах. Так что можно попробовать примеры инициализации SDRAM из других семейств, например LPC17xx. Или сделать самостоятельно, по даташиту.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, разобрался. Точнее - нашел ответ на Сахаре. 

Оказывается, надо все выходы CLKx переключать в режим ЕМС, а не только используемый (в моем случае CLK0).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Столкнулся еще с одной проблемой. Если заполнить SDRAM 32-битными словами (0х00000000,0х00000001... и т.д), а потом СРАЗУ начать теме же словами  считывать и сравнивать, то может обнаруживаться  несколько ошибок (1-4шт). Все эти ошибки располагаются в самом начале памяти, в районе первых 0хFF ячеек.  Ошибки возникают именно в записи, поскольку их потом видно в дампе памяти.

 Если записывать и считывать по 8 или 16 бит, то ни каких ошибок не возникает.  

Но самое интересное, если между циклом записи и чтения воткнуть небольшую задержку (пустой for на 1000 итераций), то ошибки пропадают.

Получается, что SDRAM или  контроллер не может  мгновенно перестроится с записи на чтение?

Может быть надо "подкрутить" какие-нибудь  параметры?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 hours ago, b-volkov said:

Спасибо, разобрался. Точнее - нашел ответ на Сахаре. 

Оказывается, надо все выходы CLKx переключать в режим ЕМС, а не только используемый (в моем случае CLK0).

Да, там подстава. Другие CLK нельзя использовать в качестве GPIO и прочих других функций... Сам однажды с этим столкнулся. Причём в документации это не так просто найти. А память портилась очень коварно, долго не обнаруживалась проблема.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, b-volkov said:

Столкнулся еще с одной проблемой. Если заполнить SDRAM 32-битными словами (0х00000000,0х00000001... и т.д), а потом СРАЗУ начать теме же словами  считывать и сравнивать, то может обнаруживаться  несколько ошибок (1-4шт). Все эти ошибки располагаются в самом начале памяти, в районе первых 0хFF ячеек.  Ошибки возникают именно в записи, поскольку их потом видно в дампе памяти.

 Если записывать и считывать по 8 или 16 бит, то ни каких ошибок не возникает.  

Но самое интересное, если между циклом записи и чтения воткнуть небольшую задержку (пустой for на 1000 итераций), то ошибки пропадают.

Получается, что SDRAM или  контроллер не может  мгновенно перестроится с записи на чтение?

Может быть надо "подкрутить" какие-нибудь  параметры?

Он может "мгновенно" перестроиться с записи на чтение. Имейте в виду, что между шиной и SDRAM находятся буфера (кэши). Хотя это не ваш случай. Подозреваю, что только тайминги виноваты. Либо разрядность и организация памяти заданы контроллеру ошибочно.

 

Для меня - одно из самых неприятных - настраивать EMC. Обычно старался взять пример для похожей SDRAM, и поправить настройки банков, таймингов и т.д. и т.п.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, b-volkov сказал:

Ошибки возникают именно в записи, поскольку их потом видно в дампе памяти.

Не факт. Такая ошибка может быть и из-за чтения. Когда-то давно сталкивался с подобной проблемой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дальше больше.  Если EMC_CCLK  =  BASE_M4_CLK /2, то в какой-то момент времени ,в процессе записи в память CPU улетает  в HardFault :(  Без делителя SDRAM стабильно работает вплоть до 167МГц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пример работы с SDRAM идущий в комплекте с вашей LPC4357-EVB не работает?

Или у вас своя плата?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, подкинули мне идею, куда двигаться дальше.  

Проблема оказалась в моей плате. Та же программа (с учетом разных параметров конфигурации SDRAM) замечательно работает на ките.  Ни каких выше перечисленных  глюков не наблюдается.

Различия: кит  - LPC4357 в BGA256 + MT48LC16M16, моя плата - LPC4337 в TQFP144+ MT48LC4M16

Не думаю, что дело  в разводке памяти, иначе не работала бы она на 167Мгц часами. Скорее всего, проблема "системного " характера. В пользу этой версии говорит то, что с самого начала работы на своей плате  я заметил некоторые "особенности". Например, если  при работе под отладчиком (среда IAR) открыто окно просмотра регистров на закладке модуля CCU1 , то значения  его регистров не отображаются, одни прочерки и дальнейшая работа под отладчиком невозможна, через несколько шагов отладчик отваливается. На тот момент   я отнес это к особенностям работы CCU и не предал особого значения, просто не открывал  эту самую закладку. Были и другие похожие случаи, когда по непонятным причинам виснет отладка или программа " ускакивает" в какие-то непотребные адреса, деталей уже не помню. Но на китовой плате ничего подобного нет! Содержимое CCU1 нормально отображается и отладчик не вылетает.

Пока у меня 3 версии:

1. Для 37-го камня требуется какая-то иная начальная инициализация, по сравнения 57-м.

2. Некорректное "включение":  не подал на нужную ногу нужный уровень.

3. Полуживой камень по причине перегрева при пайке, статики или брака.

Буду благодарен за любые идеи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, b-volkov said:

Например, если  при работе под отладчиком (среда IAR) открыто окно просмотра регистров на закладке модуля CCU1 , то значения  его регистров не отображаются, одни прочерки и дальнейшая работа под отладчиком невозможна, через несколько шагов отладчик отваливается. На тот момент   я отнес это к особенностям работы CCU и не предал особого значения, просто не открывал  эту самую закладку. Были и другие похожие случаи, когда по непонятным причинам виснет отладка или программа " ускакивает" в какие-то непотребные адреса, деталей уже не помню. Но на китовой плате ничего подобного нет! Содержимое CCU1 нормально отображается и отладчик не вылетает. 

Есть регистры чтение которых приводит к сбросу тех или иных бит, соответственно когда отладчик читает регистры это может влиять на работу програмы. В схеме есть отличия от кита в части подключения памяти? адреса/данные мешали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 10/5/2018 at 8:23 PM, skripach said:

Есть регистры чтение которых приводит к сбросу тех или иных бит

Именно на это я сначала и списал "глюки". Но на китовой плате те-же регистры с теми-же  битами, а все нормально.

На шине данных у меня и вправду по ошибке перепутаны два разряда D2 и D3. Но,насколько я понимаю, ни при инициализации регистра MODE , ни при формировании команд шина данных не используется. Опять же, повторюсь, за исключение двух вышеуказанных случаев память работает нормально. Взять хотя бы ситуацию с делителем клока: независимо от того, EMC_CCLK  =  BASE_M4_CLK = 100МГц или BASE_M4_CLK = 200 МГц, EMC_CCLK  =  BASE_M4_CLK /2 = 100МГц на шине SDRAM  те-же самые диаграммы с теми же временами. Но во втором случае "HardFault". У меня ощущение, что проблемы на внутренней шине LPC или с контроллером SDRAM.

Конечно, если ничего лучше не придет в голову, порежу плату и исправлю ошибку...  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...