VslavX 0 22 ноября, 2007 Опубликовано 22 ноября, 2007 · Жалоба Всем доброго времени суток, коллеги! Проблемка у меня, может быть кто-нибудь еще наблюдал подобное. Запускаю плату на SAM7SE512 + SDRAM, установлен чип Samsung K4S561632H-UC75. Частота 48 МГц - четко проконтроллировано на выходе SCLK, waitstate для флэшей настроено правильно. Все работает как часы, ни в какие исключения не сваливается, все жужжит как нужно. SAM-BA не используется. Код инициализации SDRAM для начала выдрал из примера на сайте Атмела. Начинаю обращаться к SDRAM - пишу/читаю одно двойное слово - лезет ерунда. После ряда экспериментов выясняется, что при чтении чип памяти пытается работать на CAS latency 1. То есть буквально на следующий такт после CAS пытаются начать вылазить данные. Лезем дальше, доходим до операции Mode Register Set - явно не работает. Изучаем разные аппноты и примеры кодов - в месте ывполнения MRS в разных источниках написаны варианты - и все - разные и не соответствуют документации. :07: OK, верим в здравый смысл и запускаем такой циклик (все выводы PIO настроенны правильно на SDRAM контроллер) #define SDRAM_BASE 0x20000000 while(TRUE) { *((volatile unsigned int*)0xFFFFFFB0) = 0x10; // NORM *((volatile unsigned int*)(SDRAM_BASE)) = 0; *((volatile unsigned int*)0xFFFFFFB0) = 0x11; // NOP *((volatile unsigned int*)(SDRAM_BASE)) = 0; *((volatile unsigned int*)0xFFFFFFB0) = 0x12; // PRE *((volatile unsigned int*)(SDRAM_BASE)) = 0; *((volatile unsigned int*)0xFFFFFFB0) = 0x13; // MRS *((volatile unsigned int*)(SDRAM_BASE+0x50)) = 0x0000FFFF; } И везде вместо выполнения заказанных операций на осциллографе видны простые записи! Запускал в цикле только один MRS - "все равно олень" - не видно на осциллографе одновременных CAS+RAS которые нужны для MRS - идут обычные записи, от есть видим и ~CAS и ~RAS , но - по-отдельности. Хорошо, допустим "сам дурак" - какие-то траблы с железом - плата всего лишь двухслойка, (хотя это далеко не первая моя двухслойная плата с SDRAM, да и сигналы все в норме). Берем evaluation kit для SAM7SE, запускаем тот же самый код (тот же бинарник) - работает. Оба! Подметаю вырванные волосы :) и начинаю думать - а чип-то на EK другой - Микрон. Выкидываю из инициализации контроллера операцию MRS совсем, прошиваю, power-cycling - а оно все равно работает! То есть, похоже, чипу Микрон вообще не нужна инициализация - по умолчанию работает CL=2, BL=1. Восстанавливаю в инициализации код MRS - прописываю CL=3, BL=8 (нерабочие условия для контроллера SAM7SE), а чип Микрона все равно работает - левая инициализация-то по шине не проходит - настройки остаются правильными. В итоге выкрутился, запрограммировал выходы как PIO, кроме SDRAM ~CS. Выставил ~CAS + ~RAS + на шине адреса нужное значение MRS и выполнил чтение - для генерации ~CS в течение такта. И Самсунг тоже нормально заработал! Кстати, вот ориентировочная производительность при чтении 36-байтовыми блоками (ldm инструкция): Exernal SDRAM: 69.3MBps Internal Flash: 78.0 MBps Internal SRAM: 132.2MBps Очень сильно зависит от оптимизации кода процедуры считывания - основной тормоз это код во флэш. Атмел о проблеме SDRAM в курсе, но уже три недели "отмораживается", поэтому я пребываю в некоторой неуверенности - следует ли мне дальше искать баг где-то у себя в системе (нельзя же такое в серию запускать), или это проблема более общая и кто-то еще с ней сталкивался? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
afad 0 22 ноября, 2007 Опубликовано 22 ноября, 2007 · Жалоба А не мог бы уважаемый VslavX ответить на вопрос: реагирует ли Ваш AT91SAM7SE на сигнал сброса? Собрал макет на AT91SAM7SE512 (пока без SDRAM), загрузил в FLASH простейшую программку (моргает светодиодом), а на сброс не реагирует. Это глюк контроллера, или я туплю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 22 ноября, 2007 Опубликовано 22 ноября, 2007 · Жалоба А не мог бы уважаемый VslavX ответить на вопрос: реагирует ли Ваш AT91SAM7SE на сигнал сброса? Собрал макет на AT91SAM7SE512 (пока без SDRAM), загрузил в FLASH простейшую программку (моргает светодиодом), а на сброс не реагирует. Это глюк контроллера, или я туплю? Это не баг, а фича всех SAM'ов: Reset нужно включать программно. Смотрите описание Reset Controllera в DS. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VslavX 0 22 ноября, 2007 Опубликовано 22 ноября, 2007 · Жалоба А не мог бы уважаемый VslavX ответить на вопрос: реагирует ли Ваш AT91SAM7SE на сигнал сброса? Собрал макет на AT91SAM7SE512 (пока без SDRAM), загрузил в FLASH простейшую программку (моргает светодиодом), а на сброс не реагирует. Это глюк контроллера, или я туплю? Настроить Reset Controller надо правильно, как aaarrr уже отписал. Иначе ножка ~NRST будет работать выходом. P.S. Дойдете до SDRAM, напишете о топиксабже? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryM 0 17 апреля, 2008 Опубликовано 17 апреля, 2008 · Жалоба Всем доброго времени суток, коллеги! Проблемка у меня, может быть кто-нибудь еще наблюдал подобное. Запускаю плату на SAM7SE512 + SDRAM, установлен чип Samsung K4S561632H-UC75. Частота 48 МГц - четко проконтроллировано на выходе SCLK, waitstate для флэшей настроено правильно. Все работает как часы, ни в какие исключения не сваливается, все жужжит как нужно. SAM-BA не используется. Код инициализации SDRAM для начала выдрал из примера на сайте Атмела. Начинаю обращаться к SDRAM - пишу/читаю одно двойное слово - лезет ерунда. Вот мои разборки с SDRAM K4S561632H: // Open PIO for SDRAM PMC_EnablePeriphClock( (1<<4) | (1<<3) | (1<<2) ); PIOx_CfgPereferiya( 0, 0, (1<<29 | 1<<28 | 1<<27 | 1<<26 | 1<<24 | 1<<23) ); //Enable PIOA29:23 -> Perif B // PIOx_CfgPereferiya( 0, 0, (1<<29 | 1<<28 | 1<<27 | 1<<25 | 1<<26 | 1<<24 | 1<<23) ); //Enable PIOA29:23 -> Perif B //Здесь SDCKE High, а должно быть Low, поэтому PIOx_CfgInOut( 0, 0, 1<<25 ); //Enable SDCKE as PIO PIOA_Clear( 1<<25 ); //Clear SDCKE PIOx_CfgPereferiya( 1, 0, 0x3FFFF ); //Enable PIOB17:0 -> Perif B -> Addres Bus PIOx_CfgPereferiya( 2, 0x7FFFF, 0 ); //Enable PIOC18:0 -> Perif A -> Data Bus addr = start; s = ADDR_EBI; s->EBI_CSA = ( s->EBI_CSA ) | 2 ; tmp = s->EBI_CSA; ss = ADDR_SDRAMC; ss->SDRAMC_CR = 0x2188C159; ss->SDRAMC_MR = 0x11; // NOP Mode DataBusWidth = 16 *addr = 0; // Только здесь появляется SDCK, а должно быть раньше вообще-то // дополнительно смотри режим'с, для MR=0x10 SDCK не появляется for( i = 0; i < 100; i++); // wait 200us minimum PIOx_CfgPereferiya( 0, 0, 1<<25 ); //Enable PIOA25=SDCKE -> Perif B -> SDCKE->HIGH // NOP Mode ss->SDRAMC_MR = 0x11; *addr = 0; // All Precharge Mode ss->SDRAMC_MR = 0x12; *addr = 0; // Refresh Mode ss->SDRAMC_MR = 0x14; for ( i = 0; i < 8; i++){ *addr++ = 0; } // MRS Mode ss->SDRAMC_MR = 0x13; *(addr + 0x80) = 0; // Здесь адрес по барабану, все равно контроллер выставляет свой зашитый // Normal Mode ss->SDRAMC_MR = 0x10; *addr = 0; ss->SDRAMC_TR = 0x800; // } После такого шаманства зажужало Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Genius_80 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба SDRAM.c //* ---------------------------------------------------------------------------- //* ATMEL Microcontroller Software Support - ROUSSET - //* ---------------------------------------------------------------------------- //* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR //* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF //* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE //* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, //* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT //* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, //* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING //* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, //* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //*---------------------------------------------------------------------------- //* File Name : SDRAM.c //* Object : Init MT48LC16M16A2 Features Definition File //* 1.0 21/DEC/06 WG : Creation //*---------------------------------------------------------------------------- // Include Standard files #include "project.h" #include "SDRAM.h" #include <string.h> #include <math.h> #ifdef __cplusplus extern "C" { #endif void Multi_Transfer (unsigned int Size, unsigned int Read_Address, unsigned int Write_Address); #ifdef __cplusplus } #endif void SDRAM_Low_Power(void) { int dummy = *AT91C_SDRAM_BASE; AT91PS_SDRC psdrc = AT91C_BASE_SDRC; psdrc->SDRC_LPR = AT91C_SDRC_LPCB; // Low-Power Enable *AT91C_SDRAM_BASE = dummy; } void SDRAM_Self_Refresh(void) { AT91PS_SDRC psdrc = AT91C_BASE_SDRC; psdrc->SDRC_LPR = 0; psdrc->SDRC_SRR = AT91C_SDRC_SRCB; } void SDRAM_Normal_Mode(void) { int dummy = *AT91C_SDRAM_BASE; AT91PS_SDRC psdrc = AT91C_BASE_SDRC; psdrc->SDRC_LPR = 0; *AT91C_SDRAM_BASE = dummy; } //*---------------------------------------------------------------------------- //* \fn AT91F_EBI_SDRAM_CfgPIO //* \brief Configure the PIO for SDRAM check pinout connection //*---------------------------------------------------------------------------- void AT91F_EBI_SDRAM_CfgPIO(void) { // Configure PIOA controller to periph mode AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA, // PIO controller base address 0, // Peripheral A ((unsigned int) AT91C_PA23_NWR1_NBS1_CFIOR_NUB) | ((unsigned int) AT91C_PA24_SDA10 ) | ((unsigned int) AT91C_PA25_SDCKE ) | ((unsigned int) AT91C_PA26_NCS1_SDCS) | ((unsigned int) AT91C_PA27_SDWE ) | ((unsigned int) AT91C_PA28_CAS ) | ((unsigned int) AT91C_PA29_RAS ) ); // Peripheral B // Configure PIOB controller to periph mode AT91F_PIO_CfgPeriph( AT91C_BASE_PIOB, // PIO controller base address 0, // Peripheral A //((unsigned int) AT91C_PB1_A1_NBS2 ) | ((unsigned int) AT91C_PB16_A16_BA0 ) | ((unsigned int) AT91C_PB0_A0_NBS0 ) | ((unsigned int) AT91C_PB2_A2 ) | ((unsigned int) AT91C_PB3_A3 ) | ((unsigned int) AT91C_PB4_A4 ) | ((unsigned int) AT91C_PB10_A10 ) | ((unsigned int) AT91C_PB5_A5 ) | ((unsigned int) AT91C_PB11_A11 ) | ((unsigned int) AT91C_PB6_A6 ) | ((unsigned int) AT91C_PB12_A12 ) | ((unsigned int) AT91C_PB7_A7 ) | ((unsigned int) AT91C_PB13_A13 ) | ((unsigned int) AT91C_PB8_A8 ) | //((unsigned int) AT91C_PB14_A14 ) | ((unsigned int) AT91C_PB9_A9 ) | //((unsigned int) AT91C_PB15_A15 ) | ((unsigned int) AT91C_PB17_A17_BA1 )); // Peripheral B // Configure PIOC controller to periph mode AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, // PIO controller base address ((unsigned int) AT91C_PC10_D10 ) | ((unsigned int) AT91C_PC11_D11 ) | ((unsigned int) AT91C_PC12_D12 ) | ((unsigned int) AT91C_PC13_D13 ) | ((unsigned int) AT91C_PC14_D14 ) | ((unsigned int) AT91C_PC15_D15 ) | ((unsigned int) AT91C_PC0_D0 ) | ((unsigned int) AT91C_PC1_D1 ) | ((unsigned int) AT91C_PC2_D2 ) | ((unsigned int) AT91C_PC3_D3 ) | ((unsigned int) AT91C_PC4_D4 ) | ((unsigned int) AT91C_PC5_D5 ) | ((unsigned int) AT91C_PC6_D6 ) | ((unsigned int) AT91C_PC7_D7 ) | ((unsigned int) AT91C_PC8_D8 ) | ((unsigned int) AT91C_PC9_D9 ) , // Peripheral A 0); // Peripheral B } //*---------------------------------------------------------------------------- //* \fn AT91F_InitSdram //* \brief Init EBI and SDRAM controller for K4S641632K //*---------------------------------------------------------------------------- int AT91F_InitSdram (int master_clock) { if ((master_clock < 1000000) || (master_clock > 200000000)) return(-1); AT91PS_SDRC psdrc = AT91C_BASE_SDRC; // Init the EBI for SDRAM AT91C_BASE_EBI -> EBI_CSA = AT91C_EBI_CS1A_SDRAMC; // Chip Select is assigned to SDRAM controller //Configure PIO for EBI CS1 AT91F_EBI_SDRAM_CfgPIO(); // OPERATING AC PARAMETER for SAMSUNG K4S641632K unsigned int SDRC_TWR = 0x2; // 2 CLC unsigned int SDRC_TRC = (65 * (master_clock / 1000) + 999999) / 1000000; // 65 ns if (SDRC_TRC < 2) SDRC_TRC = 2; unsigned int SDRC_TRP = (20 * (master_clock / 1000) + 999999) / 1000000; // 20 ns if (SDRC_TRP < 2) SDRC_TRP = 2; unsigned int SDRC_TRCD = SDRC_TRP; // 20 ns unsigned int SDRC_TRAS = (45 * (master_clock / 1000) + 999999) / 1000000; // 45 ns - 100 us if (SDRC_TRAS < 2) SDRC_TRAS = 2; //unsigned int SDRC_TXSR = 2 + SDRC_TRP; // 2 CLK + tRP [+0.5 CLK] unsigned int SDRC_TXSR = (75 * (master_clock / 1000) + 999999) / 1000000; // 75 ns if (SDRC_TXSR < 2) SDRC_TXSR = 2; unsigned int SDRC_TR_TIME = 64 * (master_clock / 1000) / 4096; // 64ms //SDRC_TWR += 2; SDRC_TWR <<= 7; //SDRC_TRC += 2; SDRC_TRC <<= 11; //SDRC_TRP += 2; SDRC_TRP <<= 15; //SDRC_TRCD += 2; SDRC_TRCD <<= 19; //SDRC_TRAS += 2; SDRC_TRAS <<= 23; //SDRC_TXSR += 2; SDRC_TXSR <<= 27; //SDRC_TR_TIME >>= 1; //*** Step 1 *** // Set Configuration Register psdrc->SDRC_CR = AT91C_SDRC_NC_8 | // 8 bits Column Addressing: 256 (A0-A7) AT91C_SDRC_NC_8 AT91C_SDRC_NR_12 | // 12 bits Row Addressing: 4K (A0-A11) AT91C_SDRC_NR_12 AT91C_SDRC_CAS_2 | // SAMSUNG K4S641632K CAS 2 AT91C_SDRC_NB_4_BANKS | // 4 banks SDRC_TWR | // 2 CLK or (below 100MHz) 1CLK SDRC_TRC | // 65 ns SDRC_TRP | // 20 ns SDRC_TRCD | // 20 ns SDRC_TRAS | // 45 ns - 100 us SDRC_TXSR ; // 2CLK + TRP or (below 100MHz) 1CLK + 20ns //*** Step 2 *** // Wait 200us (not needed since the system starts on slow clock) for (int i = 0; i < (master_clock / 1000); i++); // ~1 ms (minimum) //*** Step 3 *** // NOP Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_NOP_CMD; // Set NOP *AT91C_SDRAM_BASE = 0x00000000; // Perform NOP //*** Step 4 *** //All Banks Precharge Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_PRCGALL_CMD; // Set PRCHG AL *AT91C_SDRAM_BASE = 0x00000000; // Perform PRCHG //*** Step 5 *** //8 Refresh Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS |AT91C_SDRC_MODE_RFSH_CMD; // Set 1st CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS |AT91C_SDRC_MODE_RFSH_CMD; // Set 2nd CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS |AT91C_SDRC_MODE_RFSH_CMD; // Set 3rd CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS |AT91C_SDRC_MODE_RFSH_CMD; // Set 4th CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS |AT91C_SDRC_MODE_RFSH_CMD; // Set 5th CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_RFSH_CMD; // Set 6th CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_RFSH_CMD; // Set 7th CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_RFSH_CMD; // Set 8th CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR //*** Step 6 *** //Mode Register Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_LMR_CMD; // Set LMR operation *AT91C_SDRAM_BASE = 0x00000000; // Perform LMR burst=1, lat=2 //*** Step 7 *** //Normal Mode Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_NORMAL_CMD; // Set Normal mode // 16 bits *AT91C_SDRAM_BASE = 0x00000000; // Perform Normal mode //*** Step 8 *** // Set Refresh Timer psdrc->SDRC_TR = SDRC_TR_TIME; return(0); } int Test_SDRAM(unsigned int offset_index, unsigned int size) { int res = 0; volatile char *ptr = (volatile char*)AT91C_SDRAM_BASE; ptr += offset_index; for (int i = 0; i < size; i++) { ptr[i] = 0; } for (int i = 0; i < size; i++) ptr[i] = i; for (int i = 0; i < size; i++) { if (ptr[i] != (char)i) { res = (-1); break; } } return(res); } #pragma location="ICODE" void InitSDRAM(int master_clock) { AT91PS_SDRC psdrc = AT91C_BASE_SDRC; // Init the EBI for SDRAM AT91C_BASE_EBI -> EBI_CSA = AT91C_EBI_CS1A_SDRAMC; // Chip Select is assigned to SDRAM controller //Configure PIO for EBI CS1 //AT91F_EBI_SDRAM_CfgPIO(); //pPio->PIO_ASR = periphAEnable; //pPio->PIO_BSR = periphBEnable; //pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode unsigned int tmp = ((unsigned int) AT91C_PA23_NWR1_NBS1_CFIOR_NUB) | ((unsigned int) AT91C_PA24_SDA10 ) | ((unsigned int) AT91C_PA25_SDCKE ) | ((unsigned int) AT91C_PA26_NCS1_SDCS) | ((unsigned int) AT91C_PA27_SDWE ) | ((unsigned int) AT91C_PA28_CAS ) | ((unsigned int) AT91C_PA29_RAS ); AT91C_BASE_PIOA->PIO_ASR = 0; AT91C_BASE_PIOA->PIO_BSR = tmp; AT91C_BASE_PIOA->PIO_PDR = tmp; tmp = //((unsigned int) AT91C_PB1_A1_NBS2 ) | ((unsigned int) AT91C_PB16_A16_BA0 ) | ((unsigned int) AT91C_PB0_A0_NBS0 ) | ((unsigned int) AT91C_PB2_A2 ) | ((unsigned int) AT91C_PB3_A3 ) | ((unsigned int) AT91C_PB4_A4 ) | ((unsigned int) AT91C_PB10_A10 ) | ((unsigned int) AT91C_PB5_A5 ) | ((unsigned int) AT91C_PB11_A11 ) | ((unsigned int) AT91C_PB6_A6 ) | ((unsigned int) AT91C_PB12_A12 ) | ((unsigned int) AT91C_PB7_A7 ) | ((unsigned int) AT91C_PB13_A13 ) | ((unsigned int) AT91C_PB8_A8 ) | //((unsigned int) AT91C_PB14_A14 ) | ((unsigned int) AT91C_PB9_A9 ) | //((unsigned int) AT91C_PB15_A15 ) | ((unsigned int) AT91C_PB17_A17_BA1 ); // Peripheral B AT91C_BASE_PIOB->PIO_ASR = 0; AT91C_BASE_PIOB->PIO_BSR = tmp; AT91C_BASE_PIOB->PIO_PDR = tmp; tmp = ((unsigned int) AT91C_PC10_D10 ) | ((unsigned int) AT91C_PC11_D11 ) | ((unsigned int) AT91C_PC12_D12 ) | ((unsigned int) AT91C_PC13_D13 ) | ((unsigned int) AT91C_PC14_D14 ) | ((unsigned int) AT91C_PC15_D15 ) | ((unsigned int) AT91C_PC0_D0 ) | ((unsigned int) AT91C_PC1_D1 ) | ((unsigned int) AT91C_PC2_D2 ) | ((unsigned int) AT91C_PC3_D3 ) | ((unsigned int) AT91C_PC4_D4 ) | ((unsigned int) AT91C_PC5_D5 ) | ((unsigned int) AT91C_PC6_D6 ) | ((unsigned int) AT91C_PC7_D7 ) | ((unsigned int) AT91C_PC8_D8 ) | ((unsigned int) AT91C_PC9_D9 ); // Peripheral A AT91C_BASE_PIOC->PIO_ASR = tmp; AT91C_BASE_PIOC->PIO_BSR = 0; AT91C_BASE_PIOC->PIO_PDR = tmp; // OPERATING AC PARAMETER for SAMSUNG K4S641632K unsigned int SDRC_TWR = 0x2; // 2 CLC unsigned int SDRC_TRC = (((70 * (master_clock >> 10)) >> 19) + 1) >> 1; // 65 ns if (SDRC_TRC < 2) SDRC_TRC = 2; unsigned int SDRC_TRP = (((21 * (master_clock >> 10)) >> 19) + 1) >> 1; // 20 ns if (SDRC_TRP < 2) SDRC_TRP = 2; unsigned int SDRC_TRCD = SDRC_TRP; // 20 ns unsigned int SDRC_TRAS = (((48 * (master_clock >> 10)) >> 19) + 1) >> 1; // 45 ns - 100 us if (SDRC_TRAS < 2) SDRC_TRAS = 2; //unsigned int SDRC_TXSR = 2 + SDRC_TRP; // 2 CLK + tRP [+0.5 CLK] unsigned int SDRC_TXSR = (((81 * (master_clock >> 10)) >> 19) + 1) >> 1; // 75 ns if (SDRC_TXSR < 2) SDRC_TXSR = 2; unsigned int SDRC_TR_TIME = ((66 * (master_clock >> 10) >> 11) + 1) >> 1; // 64ms //SDRC_TWR += 2; SDRC_TWR <<= 7; //SDRC_TRC += 2; SDRC_TRC <<= 11; //SDRC_TRP += 2; SDRC_TRP <<= 15; //SDRC_TRCD += 2; SDRC_TRCD <<= 19; //SDRC_TRAS += 2; SDRC_TRAS <<= 23; //SDRC_TXSR += 2; SDRC_TXSR <<= 27; //SDRC_TR_TIME >>= 1; //*** Step 1 *** // Set Configuration Register psdrc->SDRC_CR = AT91C_SDRC_NC_8 | // 8 bits Column Addressing: 256 (A0-A7) AT91C_SDRC_NC_8 AT91C_SDRC_NR_12 | // 12 bits Row Addressing: 4K (A0-A11) AT91C_SDRC_NR_12 AT91C_SDRC_CAS_2 | // SAMSUNG K4S641632K CAS 2 AT91C_SDRC_NB_4_BANKS | // 4 banks SDRC_TWR | // 2 CLK or (below 100MHz) 1CLK SDRC_TRC | // 65 ns SDRC_TRP | // 20 ns SDRC_TRCD | // 20 ns SDRC_TRAS | // 45 ns - 100 us SDRC_TXSR ; // 2CLK + TRP or (below 100MHz) 1CLK + 20ns //*** Step 2 *** // Wait 200us (not needed since the system starts on slow clock) for (int i = 0; i < (master_clock >> 10); i++); // ~1 ms (minimum) //*** Step 3 *** // NOP Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_NOP_CMD; // Set NOP *AT91C_SDRAM_BASE = 0x00000000; // Perform NOP //*** Step 4 *** //All Banks Precharge Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_PRCGALL_CMD; // Set PRCHG AL *AT91C_SDRAM_BASE = 0x00000000; // Perform PRCHG //*** Step 5 *** //8 Refresh Command for (int i = 0; i < 8; i++) { psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS |AT91C_SDRC_MODE_RFSH_CMD; // Set CBR *AT91C_SDRAM_BASE = 0x00000000; // Perform CBR } //*** Step 6 *** //Mode Register Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_LMR_CMD; // Set LMR operation *AT91C_SDRAM_BASE = 0x00000000; // Perform LMR burst=1, lat=2 //*** Step 7 *** //Normal Mode Command psdrc->SDRC_MR = AT91C_SDRC_DBW_16_BITS | AT91C_SDRC_MODE_NORMAL_CMD; // Set Normal mode // 16 bits *AT91C_SDRAM_BASE = 0x00000000; // Perform Normal mode //*** Step 8 *** // Set Refresh Timer psdrc->SDRC_TR = SDRC_TR_TIME; int dummy = *AT91C_SDRAM_BASE; psdrc->SDRC_LPR = 0; *AT91C_SDRAM_BASE = dummy; } // memcpy __ramfunc int memcpy_int(int *data_write, int *data_read, unsigned int size) { while((size--) > 0) *(data_write++) = *(data_read++); return(size); } __ramfunc int memcpy_short(short *data_write, short *data_read, unsigned int size) { while((size--) > 0) *(data_write++) = *(data_read++); return(size); } __ramfunc int memcpy_char(char *data_write, char *data_read, unsigned int size) { while((size--) > 0) *(data_write++) = *(data_read++); return(size); } int memcpy_16(char *data_write, char *data_read, unsigned int size) { Multi_Transfer((size >> 2), (unsigned int)data_read, (unsigned int)data_write); return(size); } SDRAM.h // ---------------------------------------------------------------------------- // ATMEL Microcontroller Software Support - ROUSSET - // ---------------------------------------------------------------------------- // DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE // DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ---------------------------------------------------------------------------- // File Name : SDRAM.h // Object : SAMSUNG K4S641632K Features Definition File // 1.0 11/FEB/08 WG : Creation // ---------------------------------------------------------------------------- #ifndef SDRAM_H #define SDRAM_H #define AT91C_SDRAM_BASE ((char *)0x20000000) //* Data bus definition K4S641632K AT91SA7SE #define DQ0 (unsigned int) AT91C_PC0_D0 #define DQ1 (unsigned int) AT91C_PC1_D1 #define DQ2 (unsigned int) AT91C_PC2_D2 #define DQ3 (unsigned int) AT91C_PC3_D3 #define DQ4 (unsigned int) AT91C_PC4_D4 #define DQ5 (unsigned int) AT91C_PC5_D5 #define DQ6 (unsigned int) AT91C_PC6_D6 #define DQ7 (unsigned int) AT91C_PC7_D7 #define DQ8 (unsigned int) AT91C_PC8_D8 #define DQ9 (unsigned int) AT91C_PC9_D9 #define DQ10 (unsigned int) AT91C_PC10_D10 #define DQ11 (unsigned int) AT91C_PC11_D11 #define DQ12 (unsigned int) AT91C_PC12_D12 #define DQ13 (unsigned int) AT91C_PC13_D13 #define DQ14 (unsigned int) AT91C_PC14_D14 #define DQ15 (unsigned int) AT91C_PC15_D15 //* Address bus definition K4S641632K AT91SA7SE //* 16 bits data interface unur 4 banks #define DQML (unsigned int) AT91C_PB0_A0_NBS0 #define DQMLH (unsigned int) AT91C_PA23_NWR1_NBS1_CFIOR_NUB #define DA0 (unsigned int) AT91C_PB2_A2 #define DA1 (unsigned int) AT91C_PB3_A3 #define DA2 (unsigned int) AT91C_PB4_A4 #define DA3 (unsigned int) AT91C_PB5_A5 #define DA4 (unsigned int) AT91C_PB6_A6 #define DA5 (unsigned int) AT91C_PB7_A7 #define DA6 (unsigned int) AT91C_PB8_A8 #define DA7 (unsigned int) AT91C_PB9_A9 #define DA8 (unsigned int) AT91C_PB10_A10 #define DA9 (unsigned int) AT91C_PB11_A11 #define DA10 (unsigned int) AT91C_PA24_SDA10 // PIO A #define DA11 (unsigned int) AT91C_PB13_A13 #define DA12 (unsigned int) AT91C_PB14_A14 #define BA0 (unsigned int) AT91C_PB16_A16_BA0 #define BA1 (unsigned int) AT91C_PB17_A17_BA1 //* Control bus definition K4S641632K AT91SA7SE #define CKE (unsigned int) AT91C_PA25_SDCKE #define SDWE (unsigned int) AT91C_PA27_SDWE #define CAS (unsigned int) AT91C_PA28_CAS #define RAS (unsigned int) AT91C_PA29_RAS //* SDRAM Configuration K4S641632K // Sdram Size 1M x 16Bit x 4Banks = 8 MBytes = 2 MWords ( 4 bytes) #define AT91C_SDRAM_SIZE (SDRAM_SIZE_Byte/4) // 2 MWords (Unsigned int) // Refresh time for 48MHz (TR= 15.6 * F ) 15.6 µs per row is a typical value // Refresh period (4096 rows) // Time 64ms 4096 row Refresh period µs 15,625 nb cycles 750,00 //*---------------------------------------------------------------------------- //* External function prototype //*---------------------------------------------------------------------------- void AT91F_EBI_SDRAM_CfgPIO(void); int AT91F_InitSdram (int master_clock); void SDRAM_Low_Power(void); void SDRAM_Self_Refresh(void); void SDRAM_Normal_Mode(void); int Test_SDRAM(unsigned int offset_index, unsigned int size); __ramfunc int memcpy_int(int *data_write, int *data_read, unsigned int size); __ramfunc int memcpy_short(short *data_write, short *data_read, unsigned int size); __ramfunc int memcpy_char(char *data_write, char *data_read, unsigned int size); int memcpy_16(char *data_write, char *data_read, unsigned int size); void InitSDRAM(int master_clock); #endif // SDRAM_H Custom_Functions.s79 ;------------------------------------------------------------------------------ ;- ATMEL Microcontroller Software Support - ROUSSET - ;------------------------------------------------------------------------------ ;- DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR ;- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ;- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE ;- DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, ;- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ;- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, ;- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ;- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ;- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, ;- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;------------------------------------------------------------------------------ ;- File source : Custom_Functions.s79 ;- Object : User functions ;- 1.0 21/DEC/06 WG : Creation ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ PROGRAM ?Custom ;- Begins a program module RSEG CODE:CODE (2) ;- Begins a relocatable segment ;- corresponding address is 32-bit aligned CODE32 ;- ARM mode ;------------------------------------------------------------------------------ ;- Custom Functions ;extern void Multi_Transfer (unsigned int Size,unsigned int Read_Address,unsigned Write_Address) ; return in interworking and AAPCS ; return in R0 ;R0 = Size ;R1 = Read_Address ;R2 = Write_Address ;------------------------------------------------------------------------------ PUBLIC Multi_Transfer Multi_Transfer stmfd sp!, {r4-r7} ; Save R4, R5, R6 and R7 in User Stack loop ldmia r1!,{r4-r7} ; R4=*R1, R5=*(R1+4), R6=*(R1+8), R7=*(R1+12) stmia r2!,{r4-r7} ; R2=R4, *(R2+4)=R5, *(R2+8)=R6, *(R2+12)=R7 subs r0,r0,#4 ; R0=R0-4 (4 address locations transfered at once) bne loop ; If R0 != #0 goto loop ldmia sp!, {r4-r7} ; Restore R4, R5, R6 and R7 registers from User Stack bx r14 ; If R0 == #0 return ENDMOD ; Terminates the assembly of the current module END ; Terminates the assembly of the last module in a file ;------------------------------------------------------------------------------ Скопировал из рабочего проекта, все работает как часы, частота 48 МГц ,использовал память SDRAM от SAMSUNG K4S641632K-UC75 Помните о правильной замене эквивалентных ножек SDRAM при разводке. Замена была следующая: адреса оставил на своих местах, младшую возьмерку данных от процессора подключил к старшей восьмерке SDRAM и инвертировал последовательность, старшую восьмерку данных процессора подключил к младшей восьмерке SDRAM, DQM0->UDQM, DQM1->DQML соответственно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VslavX 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба Скопировал из рабочего проекта, все работает как часы, частота 48 МГц ,использовал память SDRAM от SAMSUNG K4S641632K-UC75 Микросхема памяти немного другая, возможно у нее после сброса Mode Register по умолчанию становится в CAS=2. Попробуйте своим кодом настроить контроллер и память на CAS=3. Тогда будет точно видно что команда MRS по шине SDRAM проходит. Всем спасибо за ответы, сейчас пока проект на SAM7SE неактуален - вот и не доходят руки проверить предложенный код. Но у меня появился неплохой логический анализатор, появится время - можно будет еще тесты погонять. Помните о правильной замене эквивалентных ножек SDRAM при разводке Спасибо, помним :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться