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

SAM7SE, реальный баг SDRAM контроллера

Всем доброго времени суток, коллеги!

 

Проблемка у меня, может быть кто-нибудь еще наблюдал подобное.

 

Запускаю плату на 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 в курсе, но уже три недели "отмораживается", поэтому я пребываю в некоторой неуверенности - следует ли мне дальше искать баг где-то у себя в системе (нельзя же такое в серию запускать), или это проблема более общая и кто-то еще с ней сталкивался?

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


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

А не мог бы уважаемый VslavX ответить на вопрос: реагирует ли Ваш AT91SAM7SE на сигнал сброса?

Собрал макет на AT91SAM7SE512 (пока без SDRAM), загрузил в FLASH простейшую программку (моргает светодиодом), а на сброс не реагирует. Это глюк контроллера, или я туплю?

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


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

А не мог бы уважаемый VslavX ответить на вопрос: реагирует ли Ваш AT91SAM7SE на сигнал сброса?

Собрал макет на AT91SAM7SE512 (пока без SDRAM), загрузил в FLASH простейшую программку (моргает светодиодом), а на сброс не реагирует. Это глюк контроллера, или я туплю?

Это не баг, а фича всех SAM'ов: Reset нужно включать программно. Смотрите описание Reset Controllera в DS.

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


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

А не мог бы уважаемый VslavX ответить на вопрос: реагирует ли Ваш AT91SAM7SE на сигнал сброса?

Собрал макет на AT91SAM7SE512 (пока без SDRAM), загрузил в FLASH простейшую программку (моргает светодиодом), а на сброс не реагирует. Это глюк контроллера, или я туплю?

Настроить Reset Controller надо правильно, как aaarrr уже отписал. Иначе ножка ~NRST будет работать выходом.

P.S. Дойдете до SDRAM, напишете о топиксабже?

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


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

Всем доброго времени суток, коллеги!

 

Проблемка у меня, может быть кто-нибудь еще наблюдал подобное.

 

Запускаю плату на 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;

// }

 

 

После такого шаманства зажужало

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


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

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 соответственно.

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


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

Скопировал из рабочего проекта, все работает как часы, частота 48 МГц ,использовал память SDRAM от SAMSUNG K4S641632K-UC75

Микросхема памяти немного другая, возможно у нее после сброса Mode Register по умолчанию становится в CAS=2. Попробуйте своим кодом настроить контроллер и память на CAS=3. Тогда будет точно видно что команда MRS по шине SDRAM проходит.

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

Помните о правильной замене эквивалентных ножек SDRAM при разводке

Спасибо, помним :)

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


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

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

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

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

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

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

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

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

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

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