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

LPC43xx, RAM только в SDRAM.

С НОВЫМ ГОДОМ! :santa2:

Хочу использовать внутреннее ОЗУ как ROM, а SDRAM(внешнее озу) как RAM. Не понятно куда вставить код инициализации контроллера SDRAM, очевидно что где-то перед "__iar_program_start".

Вообще такое можно сделать? Или это делается как-то иначе?

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


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

Вообще такое можно сделать? Или это делается как-то иначе?

С Новым Годом!

 

Поскольку код инициализации SDRAM контроллера не может использовать переменные, размещенные в "ОЗУ" (т.е. в SDRAM), то не следует использовать язык программирования высокого уровня. Сделать инициализацию контроллера на асме (только контроллера памяти). После этого можно использовать переменные на языке Си/Си++. Типа BIOS)))

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


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

Поскольку код инициализации SDRAM контроллера не может использовать переменные, размещенные в "ОЗУ" (т.е. в SDRAM), то не следует использовать язык программирования высокого уровня. Сделать инициализацию контроллера на асме (только контроллера памяти). После этого можно использовать переменные на языке Си/Си++. Типа BIOS)))

Может использовать, а может и не использовать. Так что если контролировать в дизассемблере генерируемый код, то всё получится. Но на ассемблере успех гарантирован, конечно.

Добавлю, что инициализацию SDRAM следует делать в функции __low_level_init(). Она вызывается самой первой, и ОЗУ (стек) при вызове не используется.

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


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

Может использовать, а может и не использовать.

Ну раньше было ключевое слово register. Хотя и это не гарантирует, что компилятор разместит переменную в регистрах.

следует делать в функции __low_level_init().

Это для какого компилятора? Я использую Code Sourcery.

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


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

инициализацию SDRAM следует делать в функции __low_level_init().

нет у меня такой функции. (IAR 6.30). Есть файл startup:

        MODULE  ?cstartup

       ;; Forward declaration of sections.
        SECTION CSTACK:DATA:NOROOT(3)

        SECTION .intvec:CODE:NOROOT(2)

        EXTERN  __iar_program_start
        EXTERN  SystemInit
        PUBLIC  __vector_table
        PUBLIC  __vector_table_0x1c
        PUBLIC  __Vectors
        PUBLIC  __Vectors_End
        PUBLIC  __Vectors_Size

        DATA

Sign_Value        EQU        0x5A5A5A5A

__vector_table
        DCD     sfe(CSTACK)
        DCD     Reset_Handler

        DCD     NMI_Handler
        DCD     HardFault_Handler

Я так понимаю перед "EXTERN __iar_program_start" надо вставить свою "EXTERN __SDRAM_init" ?

 

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


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

Я так понимаю перед "EXTERN __iar_program_start" надо вставить свою "EXTERN __SDRAM_init" ?

Можно перед, или после или вообще не вставлять.

Смотрите в EWARM_DevelopmentGuide.ENU.pdf пункт Customizing system initialization. Там описано про функцию low_level_init.

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


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

нет у меня такой функции. (IAR 6.30).

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

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


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

Смотрите в EWARM_DevelopmentGuide.ENU.pdf пункт Customizing system initialization. Там описано про функцию low_level_init.

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

ja ja naturlich, спасибо, буду пробовать.

 

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


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

Поскольку код инициализации SDRAM контроллера не может использовать переменные, размещенные в "ОЗУ" (т.е. в SDRAM), то не следует использовать язык программирования высокого уровня. Сделать инициализацию контроллера на асме (только контроллера памяти). После этого можно использовать переменные на языке Си/Си++. Типа BIOS)))

Инициализировать можно на каком угодно языке. Управлять размещением выходных секций кода/данных компилятора надо через линковщик. В IAR это шса-файл. Размещаете необходимые для кода инициализации секции во внутреннем ОЗУ/флеш и спокойно работаете.

 

нет у меня такой функции. (IAR 6.30). Есть файл startup:

После старта CPU у вас управление очевидно передаётся на метку Reset_Handler. С неё и начинается код инициализации.

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


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

Не создаю новую тему. :)

Увеличил частоту ядра(SDRAM), всё стало периодически "падать".

Память у меня 32МБайта, 16бит шина. Сделал простенький тест памяти:

uint32_t error_array[100];
uint32_t *ramdata;
uint32_t i;  

for(;;)
{
  error_counter=0;
  ramdata = (uint32_t *)SDRAM_ADDR_BASE;
  for(i=0;i<SDRAM_SIZE/4;i++)
  {
    *ramdata = i;
    ramdata++;
  }
  //for(volatile uint32_t er=0; er < 3000; er++);
  ramdata = (uint32_t *)SDRAM_ADDR_BASE;
  for(i=0;i<SDRAM_SIZE/4;i++)
  {
    if(*ramdata != i)
    {
      error_array[error_counter]=(uint32_t)ramdata;
      error_counter++;
    }
  ramdata++;
}

Если раскоментировать for(volatile uint32_t er=0; er < 3000; er++); то тест проходит без ошибок, иначе в error_array 85-95 первых адресов SDRAM.

Менял задержки в инициализации контроллера SDRAM, но не заработало. Надеюсь на гуру SDRAM памяти.

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


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

Если раскоментировать for(volatile uint32_t er=0; er < 3000; er++); то тест проходит без ошибок, иначе в error_array 85-95 первых адресов SDRAM.

Менял задержки в инициализации контроллера SDRAM, но не заработало. Надеюсь на гуру SDRAM памяти.

Тайминги надо менять, у вас идет последовательная запись, а потом последовательное чтение

если нет задержки между переходом все слетает.

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


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

Тайминги надо менять, у вас идет последовательная запись, а потом последовательное чтение

если нет задержки между переходом все слетает.

Не понимаю полностью логику работы SDRAM поэтому не знаю что менять, пробовал добавить по 10-20 нс в разных местах - изменений не увидел. Память MT48LC16M16A2P-75. Код:

#include "lpc43xx.h"
#include "lpc_types.h"
#include "lpc43xx_scu.h"
#include "lpc43xx_timer.h"
#include "lpc43xx_cgu.h"
#include "SDRAM_drv.h"


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

/*********************************************************************
* @brief		Calculate EMC Clock from nano second
* @param[in]	freq - frequency of EMC Clk
* @param[in]	time - nano second
* @return 		None
**********************************************************************/
uint32_t NS2CLK(uint32_t freq,uint32_t time){
return (((uint64_t)time*freq/1000000000));
}
/*********************************************************************
* @brief		Init the EMC Controller to connect ex SDRAM
* @param[in]	None
* @return 		None
**********************************************************************/
void SDRAM_Init(void) 
{
uint32_t pclk, temp;
uint64_t tmpclk;
TIM_TIMERCFG_Type TIM_ConfigStruct;
LPC_SCU->EMCDELAYCLK=0x7777;
/* Set up EMC pin */
scu_pinmux(	1, 7	,	MD_PLN_FAST	,	3	);//D0
scu_pinmux(	1, 8	,	MD_PLN_FAST	,	3	);//D1
scu_pinmux(	1, 9	,	MD_PLN_FAST	,	3	);//D2
scu_pinmux(	1, 10	,	MD_PLN_FAST	,	3	);//D3
scu_pinmux(	1, 11	,	MD_PLN_FAST	,	3	);//D4
scu_pinmux(	1, 12	,	MD_PLN_FAST	,	3	);//D5
scu_pinmux(	1, 13	,	MD_PLN_FAST	,	3	);//D6
scu_pinmux(	1, 14	,	MD_PLN_FAST	,	3	);//D7
	scu_pinmux(	5, 4	,	MD_PLN_FAST	,	2	);//D8
scu_pinmux(	5, 5	,	MD_PLN_FAST	,	2	);//D9
scu_pinmux(	5, 6	,	MD_PLN_FAST	,	2	);//D10
scu_pinmux(	5, 7	,	MD_PLN_FAST	,	2	);//D11   
scu_pinmux(	5, 0	,	MD_PLN_FAST	,	2	);//D12
scu_pinmux(	5, 1	,	MD_PLN_FAST	,	2	);//D13
scu_pinmux(	5, 2	,	MD_PLN_FAST	,	2	);//D14
scu_pinmux(	5, 3	,	MD_PLN_FAST	,	2	);//D15

scu_pinmux(	2, 9	,	MD_PLN_FAST	,	3	);//A0
scu_pinmux(	2, 10	,	MD_PLN_FAST	,	3	);//A1
scu_pinmux(	2, 11	,	MD_PLN_FAST	,	3	);//A2
scu_pinmux(	2, 12	,	MD_PLN_FAST	,	3	);//A3
scu_pinmux(	2, 13	,	MD_PLN_FAST	,	3	);//A4	
scu_pinmux(	1, 0	,	MD_PLN_FAST	,	2	);//A5
scu_pinmux(	1, 1	,	MD_PLN_FAST	,	2	);//A6
scu_pinmux(	1, 2	,	MD_PLN_FAST	,	2	);//A7
scu_pinmux(	2, 8	,	MD_PLN_FAST	,	3	);//A8  
scu_pinmux(	2, 7	,	MD_PLN_FAST	,	3	);//A9
scu_pinmux(	2, 6	,	MD_PLN_FAST	,	2	);//A10
scu_pinmux(	2, 2	,	MD_PLN_FAST	,	2	);//A11
scu_pinmux(	2, 1	,	MD_PLN_FAST	,	2	);//A12
scu_pinmux(	2, 0	,	MD_PLN_FAST	,	2	);//A13
scu_pinmux(	6, 8	,	MD_PLN_FAST	,	1	);//A14  

	scu_pinmux(	6, 9	,	MD_PLN_FAST	,	3	);//DYCS0
	scu_pinmux(	6, 10	,	MD_PLN_FAST	,	3	);//DQMOUT1
	scu_pinmux(	6, 11	,	MD_PLN_FAST	,	3	);//CKEOUT0
	scu_pinmux(	6, 12	,	MD_PLN_FAST	,	3	);//DQMOUT0
	scu_pinmux(	6, 4	,	MD_PLN_FAST	,	3	);//CAS
scu_pinmux(	6, 5	,	MD_PLN_FAST	,	3	);//RAS
	scu_pinmux(	1, 6	,	MD_PLN_FAST	,	3	);//WE

/* Select EMC clock-out */
LPC_SCU->SFSCLK_0 = MD_PLN_FAST;
LPC_SCU->SFSCLK_1 = MD_PLN_FAST;
LPC_SCU->SFSCLK_2 = MD_PLN_FAST;
LPC_SCU->SFSCLK_3 = MD_PLN_FAST;

TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
TIM_ConfigStruct.PrescaleValue	= 1;

// Set configuration for Tim_config and Tim_MatchConfig
TIM_Init(LPC_TIMER0, TIM_TIMER_MODE,&TIM_ConfigStruct);

LPC_EMC->CONTROL 	= 0x00000001;
LPC_EMC->CONFIG	  = 0x00000000;
LPC_EMC->DYNAMICCONFIG0 = 3<<9 | 1<<7; /* 256 Mb (16Mx16), 4 banks, row length = 13, column length = 9 */

pclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);

LPC_EMC->DYNAMICRASCAS0	= 0x00000303; /* 3 RAS, 3 CAS latency */
LPC_EMC->DYNAMICREADCONFIG = 0x00000001; /* Command delayed strategy, using EMCCLKDELAY */

LPC_EMC->DYNAMICRP		 = NS2CLK(pclk, 20);  // min 20 ns
LPC_EMC->DYNAMICRAS		= NS2CLK(pclk, 44);  // min 44 max 120 ns 
LPC_EMC->DYNAMICSREX	   = NS2CLK(pclk, 75);  // min 75 ns
LPC_EMC->DYNAMICAPR		= 0x00000005;
LPC_EMC->DYNAMICDAL		= 0x00000005;		// 5 ck
LPC_EMC->DYNAMICWR		 = 2;				 // 2 ck
LPC_EMC->DYNAMICRC		 = NS2CLK(pclk, 66);  // min 66 ns
LPC_EMC->DYNAMICRFC		= NS2CLK(pclk, 66);  // min 66 ns
LPC_EMC->DYNAMICXSR		= NS2CLK(pclk, 75);  // min 75 ns
LPC_EMC->DYNAMICRRD		= NS2CLK(pclk, 15);  // min 15 ns
LPC_EMC->DYNAMICMRD		= 0x00000002;		// 2 ck

TIM_Waitus(100);						   /* wait 100ms */
LPC_EMC->DYNAMICCONTROL	= 0x00000183; /* Issue NOP command */

TIM_Waitus(200);						   /* wait 200ms */
LPC_EMC->DYNAMICCONTROL	= 0x00000103; /* Issue PALL command */

LPC_EMC->DYNAMICREFRESH	= EMC_SDRAM_REFRESH(pclk,66); /* ( n * 16 ) -> 32 clock cycles */

TIM_Waitus(200);						   /* wait 200ms */

tmpclk = (uint64_t)15625*(uint64_t)pclk/1000000000/16;
LPC_EMC->DYNAMICREFRESH	= tmpclk; /* ( n * 16 ) -> 736 clock cycles -> 15.330uS at 48MHz <= 15.625uS ( 64ms / 4096 row ) */
LPC_EMC->DYNAMICCONTROL	= 0x00000083; /* Issue MODE command */

//Timing for 48/60/72MHZ Bus
temp = *((volatile uint32_t *)(SDRAM_ADDR_BASE | (3<<4 | 3)<<12)); /* 4 burst, 3 CAS latency */
temp = temp;
LPC_EMC->DYNAMICCONTROL	= 0x00000000; /* Issue NORMAL command */

//[re]enable buffers
LPC_EMC->DYNAMICCONFIG0	|= 1<<19;
}

И ещё интересный момент если uint32_t *ramdata; uint32_t i; обьявить глобальными(во внутренней памяти), а не в стеке(компилятор помещает в регистры), то тест тоже проходит без ошибок.

Может кто делал свой контроллер SDRAM на FPGA?

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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