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