Memory controller (memory interface device)
If the address is in different ranges, different chip selection pins will be issued. In other words, different memory chips external to SOC will have different address ranges.
CPU unified addressing includes GPIO, various protocol interface controllers (UART, I2C...), memory device interface, and nand flash controller (nand flash chip itself is not subject to CPU unified addressing). The selectable address range space of each chip selection signal is 128M, and at least 27 address lines are required.
CPU sends 32 as address - > memory controller - > sends 27 as address signal and chip selection signal
Sequence diagram analysis
Programmable access cycle
2440 reading sequence diagram
Nor Flash chip timing chart
Modify various values in the timing chart according to the memory chip manual. The default values of chips are the safest, which can not give full play to the performance of cpu.
For simplicity, we set 2440 chip selection (CE #) read signal (OE #) address signal to be sent at the same time and maintained at 70nm
Memory controller related registers (Nor Flash)
Bus bit width and wait control register
Bank control register
Set Tacc[10:8] = 100
init.c
#include "s3c2440_soc.h" void bank0_tacc_set(int val) { BANKCON0 = val << 8; }
init.h
#ifndef _INIT_H #define _INIT_H void bank0_tacc_set(int val); #endif
uart.c
#include "s3c2440_soc.h" /* 115200,8n1 */ void uart0_init() { /* Set pin for serial port */ /* GPH2,3 For TxD0, RxD0 */ GPHCON &= ~((3<<4) | (3<<6)); GPHCON |= ((2<<4) | (2<<6)); GPHUP &= ~((1<<2) | (1<<3)); /* Enable internal pull-up */ /* set baud rate */ /* UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1 * UART clock = 50M * UBRDIVn = (int)( 50000000 / ( 115200 x 16) ) –1 = 26 */ UCON0 = 0x00000005; /* PCLK,Interrupt / query mode */ UBRDIV0 = 26; /* Format data */ ULCON0 = 0x00000003; /* 8n1: 8 Data bits, no comparison bit, 1 stop bit */ /* */ } int putchar(int c) { /* UTRSTAT0 */ /* UTXH0 */ while (!(UTRSTAT0 & (1<<2))); UTXH0 = (unsigned char)c; } int getchar(void) { while (!(UTRSTAT0 & (1<<0))); return URXH0; } int puts(const char *s) { while (*s) { putchar(*s); s++; } }
uart.h
#ifndef _UART_H #define _UART_H void uart0_init(); int putchar(int c); int getchar(void); int puts(const char *s); #endif
main.c
#include "s3c2440_soc.h" #include "uart.h" #include "init.h" int main(void) { unsigned char c; uart0_init(); puts("Enter the Tacc val: \n\r"); while(1) { c = getchar(); putchar(c); if (c >= '0' && c <= '7') { bank0_tacc_set(c - '0'); led_test(); } else { puts("Error, val should between 0~7\n\r"); puts("Enter the Tacc val: \n\r"); } } return 0; }
Set to burn the program to nor flash, set it to nor start, set different values with serial port, and observe the flashing of light.
SDRAM Basics
See this column "memory SDRAM"
2440 memory controller settings
Our SDRAM address is on Bnak6
- We use two 16 bit SDRAM chips to form a 32-bit physical bit width DW6[25:24] = 10.
- When the cpu sends a read-write signal, the chip is still not ready for data. You can send a wait signal to the cpu. We don't need it. WS6[26] = 0
- Whether the reading and writing is accurate to byte. No, read out a 32-bit data, and the memory controller can select byte. ST6[26] = 0
To set SDRAM, you only need to set MT[16:15], Trcd[3:2], and SCAN[1:0].
SCAN[1:0]: column address, check the chip manual and get 9 bits.
Trcd[3:2]: how long is the delay between row address and column address. 20ns when reading the chip manual
SDRAM needs to be refreshed continuously during use
Refresh register
Enable refresh, auto refresh
Refresh Counter[10:0] :
Check the chip manual and it can be counted as 1269
CL[6:4]:sdram will not return data until it receives the column address
SDRAM test procedure
Write a value in SDRAM and then read it to test whether it is correct.
init.c init.h
#include "s3c2440_soc.h" void sdram_init(void) { BWSCON = 0x22000000; BANKCON6 = 0x18001; BANKCON7 = 0x18001; REFRESH = 0x8404f5; BANKSIZE = 0xb1; MRSRB6 = 0x20; MRSRB7 = 0x20; } int sdram_test(void) { volatile unsigned char *p = (volatile unsigned char *)0x30000000; int i; // write sdram for (i = 0; i < 1000; i++) p[i] = 0x55; // read sdram for (i = 0; i < 1000; i++) if (p[i] != 0x55) return -1; return 0; }
#ifndef _INIT_H #define _INIT_H void sdram_init(void); int sdram_test(void); #endif
main.c
#include "s3c2440_soc.h" #include "uart.h" #include "init.h" int main(void) { uart0_init(); sdram_init(); if (sdram_test() == 0) led_test(); return 0; }