skripach 6 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба С НОВЫМ ГОДОМ! :santa2: Хочу использовать внутреннее ОЗУ как ROM, а SDRAM(внешнее озу) как RAM. Не понятно куда вставить код инициализации контроллера SDRAM, очевидно что где-то перед "__iar_program_start". Вообще такое можно сделать? Или это делается как-то иначе? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба Вообще такое можно сделать? Или это делается как-то иначе? С Новым Годом! Поскольку код инициализации SDRAM контроллера не может использовать переменные, размещенные в "ОЗУ" (т.е. в SDRAM), то не следует использовать язык программирования высокого уровня. Сделать инициализацию контроллера на асме (только контроллера памяти). После этого можно использовать переменные на языке Си/Си++. Типа BIOS))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба Поскольку код инициализации SDRAM контроллера не может использовать переменные, размещенные в "ОЗУ" (т.е. в SDRAM), то не следует использовать язык программирования высокого уровня. Сделать инициализацию контроллера на асме (только контроллера памяти). После этого можно использовать переменные на языке Си/Си++. Типа BIOS))) Может использовать, а может и не использовать. Так что если контролировать в дизассемблере генерируемый код, то всё получится. Но на ассемблере успех гарантирован, конечно. Добавлю, что инициализацию SDRAM следует делать в функции __low_level_init(). Она вызывается самой первой, и ОЗУ (стек) при вызове не используется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба Может использовать, а может и не использовать. Ну раньше было ключевое слово register. Хотя и это не гарантирует, что компилятор разместит переменную в регистрах. следует делать в функции __low_level_init(). Это для какого компилятора? Я использую Code Sourcery. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба Это для какого компилятора? Я использую Code Sourcery. Это я для топикстартера написал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 6 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба инициализацию 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" ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба Я так понимаю перед "EXTERN __iar_program_start" надо вставить свою "EXTERN __SDRAM_init" ? Можно перед, или после или вообще не вставлять. Смотрите в EWARM_DevelopmentGuide.ENU.pdf пункт Customizing system initialization. Там описано про функцию low_level_init. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба нет у меня такой функции. (IAR 6.30). Ошибаетесь, она есть. Если интересно, в какой момент она вызывается, просто пройдитесь по шагам в симуляторе с самого начала. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 6 2 января, 2013 Опубликовано 2 января, 2013 · Жалоба Смотрите в EWARM_DevelopmentGuide.ENU.pdf пункт Customizing system initialization. Там описано про функцию low_level_init. Ошибаетесь, она есть. Если интересно, в какой момент она вызывается, просто пройдитесь по шагам в симуляторе с самого начала. ja ja naturlich, спасибо, буду пробовать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 5 января, 2013 Опубликовано 5 января, 2013 · Жалоба Поскольку код инициализации SDRAM контроллера не может использовать переменные, размещенные в "ОЗУ" (т.е. в SDRAM), то не следует использовать язык программирования высокого уровня. Сделать инициализацию контроллера на асме (только контроллера памяти). После этого можно использовать переменные на языке Си/Си++. Типа BIOS))) Инициализировать можно на каком угодно языке. Управлять размещением выходных секций кода/данных компилятора надо через линковщик. В IAR это шса-файл. Размещаете необходимые для кода инициализации секции во внутреннем ОЗУ/флеш и спокойно работаете. нет у меня такой функции. (IAR 6.30). Есть файл startup: После старта CPU у вас управление очевидно передаётся на метку Reset_Handler. С неё и начинается код инициализации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 6 16 января, 2013 Опубликовано 16 января, 2013 · Жалоба Не создаю новую тему. :) Увеличил частоту ядра(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 памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 16 января, 2013 Опубликовано 16 января, 2013 · Жалоба Если раскоментировать for(volatile uint32_t er=0; er < 3000; er++); то тест проходит без ошибок, иначе в error_array 85-95 первых адресов SDRAM. Менял задержки в инициализации контроллера SDRAM, но не заработало. Надеюсь на гуру SDRAM памяти. Тайминги надо менять, у вас идет последовательная запись, а потом последовательное чтение если нет задержки между переходом все слетает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 6 17 января, 2013 Опубликовано 17 января, 2013 (изменено) · Жалоба Тайминги надо менять, у вас идет последовательная запись, а потом последовательное чтение если нет задержки между переходом все слетает. Не понимаю полностью логику работы 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? Изменено 17 января, 2013 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться