Smart External Memory Controller functions (SOMRT1061, MODRT1171).
#include< semc.h>
SEMC Overview
The Smart External Memory Controller (SEMC) provides a flexible interface for connecting external parallel memory devices to the i.MX RT1061 and RT1171 processors. The SEMC supports various memory types including SRAM, PSRAM, NOR Flash, and other parallel bus devices.
Key Features
- Multiple chip select support (CS0-CS3)
- Configurable data bus widths (8-bit, 16-bit)
- Asynchronous and synchronous clock modes
- Burst transfer support (1, 2, 4, 8, 16, 32, 64 beats)
- Multiplexed and non-multiplexed addressing modes
- Independent timing configuration per chip select
- Memory-mapped access via standard pointers
- Address range: 0x80000000 - 0x9FFFFFFF
Memory Address Map
Memory Region Layout:
+---------------------+ 0x9FFFFFFF
| |
| Available SEMC |
| Address Space |
| (512 MB total) |
| |
+---------------------+ 0x80000000 <-- SEMC_Base[]
| |
| Other Memory |
| |
+---------------------+ 0x00000000
Basic Usage Workflow
+------------------+
| 1. Initialize |
| System | Call
init() in UserMain()
+--------+---------+
|
v
+--------+---------+
| 2. Configure |
+--------+---------+
|
v
+--------+---------+
| 3. Set Timing |
| Parameters | Configure timing based on device datasheet
+--------+---------+
|
v
+--------+---------+
| 4. Call |
+--------+---------+
|
v
+--------+---------+
| 5. Access |
| Memory | Use standard pointers to
read/
write
+------------------+
int read(int fd, char *buf, int nbytes)
Read data from a file descriptor (fd).
int write(int fd, const char *buf, int nbytes)
Write data to the stream associated with a file descriptor (fd). Can be used to write data to stdio,...
void ConfigureSEMC(uint32_t baseAddr, uint32_t siz, SEMC_cfg_t &&cfg)
Configure a Chip Select for the external data bus with rvalue reference configuration.
void init()
System initialization. Ideally called at the beginning of all applications, since the easiest Recover...
Configuration structure for SEMC (Smart External Memory Controller) interface.
Definition MIMXRT10xx/include/semc.h:799
Operating Modes
Asynchronous Mode (SEMC_ClkMode_t::Async)
Timing Diagram (
Async Read):
CS_SETUP RD_EN_LO RD_EN_HI CS_HOLD
+------+ +-------+ +--------+ +------+
| | | | | | | |
CS\______/ | | | | \______/
\| | | |/
RD \_______________________/
| | | |
ADDR ------<==============================>------
| | | |
DATA ------+-+-----+-+---<========>-------------
| | | | | |
<-+-----+-> = Setup Time
<-+--+--------> = Access Time
@ Async
Asynchronous mode. Timing based on fixed delays. No clock synchronization required....
Definition MIMXRT10xx/include/semc.h:608
Synchronous Mode (SEMC_ClkMode_t::Sync)
Timing Diagram (
Sync Burst Read):
CLK __/--\__/--\__/--\__/--\__/--\__/--\__/--\_
| | | | | | | | | | | | | |
CS ___/--------------------------------------\_____
| | | | | | | | | | | | | |
ADDR ---<ADDR>---------------------------------
| | | | | | | | | | | | | |
DATA ---+--+--+--+--<D0><D1><D2><D3>-----------
| | | | | | | | | | | | | |
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | | | | | | | |
Setup | | Latency | Burst Transfer |
| | | |
Address| First Last
Valid Data Data
@ Sync
Synchronous mode. All signals synchronized to SEMC clock. Supports burst transfers....
Definition MIMXRT10xx/include/semc.h:609
Addressing Modes
Multiplexed Mode (SEMC_AddrMux_t::Mux)
Address and Data share the same bus pins:
AD_BUS[15:0] <ADDRESS> <======= DATA =======>
CS \________/------------------------
ADV \________/---------
- Reduces pin count
- Address latched by ADV signal
- Common for SRAM and PSRAM devices
Non-Multiplexed Mode (SEMC_AddrMux_t::Bus)
Separate Address and Data buses:
ADDR[n:0] <========== ADDRESS ===========>
DATA[15:0] <============ DATA ============>
CS \______________________________/
- Faster access times
- More pins required
- Better for high-performance applications
Timing Calculation
All timing values are specified in SEMC clock cycles. The actual time depends on the SEMC clock frequency configured in your system.
Example: SEMC Clock = 100 MHz (10 ns per cycle)
If device datasheet specifies:
- Address Setup Time: 15 ns minimum
- Read Enable Low: 30 ns minimum
- Read Enable High: 50 ns minimum
Calculate cycles needed:
addr_setup = ceil(15 ns / 10 ns) - 1 = 2 - 1 = 1
rd_en_lo = ceil(30 ns / 10 ns) - 1 = 3 - 1 = 2
rd_en_hi = ceil(50 ns / 10 ns) - 1 = 5 - 1 = 4
Note: Many timing parameters are (n+1) cycles, so subtract 1
from the calculated value.
Configuration Structure
The SEMC_cfg_t structure uses unions to provide both hardware register access and structured field access:
Memory Layout:
+------------------+ CR0 (Control Register 0)
| busWidth :1|
Bus width selection
| RESERVED :2|
| burstLen :3| Burst length
| RESERVED :1|
| muxMode :2| Address multiplexing mode
| advPol :1| ADV signal polarity
| advHoldLvl :1| ADV hold level
| colAddrWidth :4| Column address width
+------------------+
+------------------+ CR1 (Control Register 1)
| addr_setup :4| Address setup
time (n+1)
| addr_hold :4| Address hold
time
| wr_en_lo :4| Write enable low
time (n+1)
| wr_en_hi :4| Write enable high
time (n+1)
| rd_en_lo :4| Read enable low
time (n+1)
| rd_en_hi :4| Read enable high
time (n+1)
+------------------+
+------------------+ CR2 (Control Register 2)
| wr_dat_setup :4| Write data setup (n+1)
| wr_dat_hold :4| Write data hold (n)
| addr_wr_hold :4| Address
write hold (n+1)
| turnaround :4| Turnaround
time (n)
| latency :4| Read latency (n)
| rd_cycle :4| Read cycle
time (n+1)
| cs_min_intv :4| CS minimum interval (n+1)
| rd_hold :4| Read hold
time (n)
+------------------+
+------------------+
| clkPin (
PinIO) | Clock pin assignment
+------------------+
+------------------+
+------------------+
GPIO Pin Class.
Definition coldfire/cpu/MCF5441X/include/cpu_pins.h:44
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, unsigned long timeout)
Wait for events to occur on one or more I/O resources associated with a set of file descriptors (fds)...
Definition iosys.h:648
time_t time(time_t *pt)
Gets the current system GMT time.
@ Bus
Non-multiplexed bus mode (write only). Separate address and data buses. Reads are performed as AD-Mux...
Definition MIMXRT10xx/include/semc.h:517
Multiple Chip Select Configuration
Memory Map Example with Multiple CS:
+---------------------+ 0x9FFFFFFF
| Unused Space |
+---------------------+ 0x80180000
| |
| Flash (512 KB) |
| |
+---------------------+ 0x80100000
| |
| SRAM (512 KB) |
| |
+---------------------+ 0x80080000
| |
| PSRAM (512 KB) |
| |
+---------------------+ 0x80000000 <-- SEMC_Base[]
Requirements:
- Base addresses must be aligned to size boundary
- Memory regions must not overlap
- Each CS can have independent timing configuration
- Different CS pins must be used for each region
Common Configuration Examples
Typical Async SRAM Configuration:
Device Type: IS61WV51216BLL (512K x 16-bit SRAM)
Access Time: 10ns
SEMC Clock: 100 MHz
.cs_setup = 1,
.cs_hold_min = 1,
.addr_setup = 1,
.addr_hold = 1,
.wr_en_lo = 2,
.wr_en_hi = 2,
.rd_en_lo = 2,
.rd_en_hi = 4,
};
@ Mux
Multiplexed address/data mode. Address and data share the same pins. Requires ADV signal to latch add...
Definition MIMXRT10xx/include/semc.h:515
@ Width_16
16-bit data bus (D[15:0]). Suitable for 16-bit memory devices. Provides 2x throughput compared to 8-b...
Definition MIMXRT10xx/include/semc.h:493
@ Burst_1
Single-beat transfer. No burst mode. Each access requires full address cycle. Use for random access o...
Definition MIMXRT10xx/include/semc.h:661
@ Width_0
No column addressing. Do not configure address pins for column mode. Use for simple SRAM/NOR Flash wi...
Definition MIMXRT10xx/include/semc.h:558
Typical Sync Burst PSRAM Configuration:
Device Type: IS66/67WVE4M16EBLL (Synchronous PSRAM)
Clock: 100 MHz
Latency: 3 cycles
.cs_setup = 2,
.cs_hold_min = 2,
.addr_setup = 1,
.addr_hold = 1,
.wr_dat_setup = 1,
.wr_dat_hold = 0,
.latency = 3,
.rd_cycle = 5,
.cs_min_intv = 1,
.rd_hold = 1,
};
@ Burst_8
8-beat burst transfer. Address once, transfer 8 consecutive data words. Optimal for cache line fills ...
Definition MIMXRT10xx/include/semc.h:664
@ Width_8
8-bit column address (A[7:0]). Common for smaller SDRAM and burst-capable PSRAM.
Definition MIMXRT10xx/include/semc.h:551
Memory Access Patterns
Direct Memory Access:
uint8_t *bytePtr = (uint8_t *)0x80000000;
uint16_t *wordPtr = (uint16_t *)0x80000000;
uint32_t *dwordPtr = (uint32_t *)0x80000000;
bytePtr[0] = 0x42;
uint8_t value = bytePtr[0];
wordPtr[0] = 0x1234;
uint16_t word = wordPtr[0];
dwordPtr[0] = 0xDEADBEEF;
uint32_t dword = dwordPtr[0];
Bulk Data Transfer:
uint8_t *extMem = (uint8_t *)0x80000000;
uint8_t buffer[1024];
memcpy(extMem, buffer, sizeof(buffer));
memcpy(buffer, extMem, sizeof(buffer));
memset(extMem, 0xFF, 1024);
Structure Access:
struct DataRecord {
uint32_t id;
uint16_t value;
uint8_t status;
uint8_t flags;
};
DataRecord *records = (DataRecord *)0x80000000;
records[0].id = 1234;
records[0].value = 0x5678;
records[0].status = 0x01;
for (int i = 0; i < 100; i++) {
records[i].id = i;
records[i].value = i * 2;
}
Troubleshooting Guide
Common Issues and Solutions:
Issue: Data corruption or incorrect reads
+------------------------------------------+
| Check: |
| 1. Timing parameters match datasheet |
| 2. SEMC clock frequency is correct |
| 3. Setup/hold times meet minimum specs |
| 4. Signal integrity (scope waveforms) |
| 5. Power supply stability |
+------------------------------------------+
Issue: System crashes when accessing memory
+------------------------------------------+
| Check: |
| 1. Base address within valid range |
| 2. Size is power of 2 and aligned |
| 3. No address overlap with other CS |
| 5. Pins configured correctly |
+------------------------------------------+
Issue: Intermittent failures
+------------------------------------------+
| Check: |
| 1. Add margin to timing parameters |
| 2. Check turnaround
time settings |
| 3. Verify CS hold
time adequate |
| 4. Temperature effects on device |
| 5.
Bus contention with other devices |
+------------------------------------------+
Best Practices
- Always add timing margin (10-20%) beyond minimum datasheet specifications
- Initialize SEMC during system startup, before any memory access
- Verify timing calculations against datasheet at your SEMC clock frequency
- Use const for read-only data stored in external Flash memory
- Consider cache implications for frequently accessed data
- Test memory thoroughly after configuration changes
- Document the specific memory device part number and timing calculations
- Use volatile keyword when hardware registers might change externally
- Align data structures to natural boundaries for best performance
- Implement error detection/correction if data integrity is critical
Performance Considerations
Access Performance Comparison (approximate):
+------------------------+----------------+-------------+
| Memory Type | Typical Access | Throughput |
+------------------------+----------------+-------------+
| Internal SRAM | 1 cycle |
Maximum |
| External SRAM (
Async) | 5-10 cycles | Medium |
| External SRAM (
Sync) | 3-6 cycles | High |
| External Flash (
Async) | 10-20 cycles | Low |
+------------------------+----------------+-------------+
Burst Mode Benefits:
- First access: Full latency
- Subsequent accesses: 1 cycle each
- Best for sequential data access
- Up to 8x performance for burst-8 mode
@ Maximum
Highest priority currently unused, 0->OS_LO_PRIO.
Definition nbrtos.h:2375
Memory Region Symbols
The linker provides symbols for SEMC memory regions:
extern uint8_t SEMC_Base[];
extern uint8_t _s_data_bus[];
extern uint8_t _e_data_bus[];
Usage example:
void CheckSEMCRegion(void *ptr) {
uintptr_t addr = (uintptr_t)ptr;
uintptr_t base = (uintptr_t)SEMC_Base;
if (addr >= base && addr < (base + 0x20000000)) {
iprintf("Address is in SEMC region\n");
}
}
- Note
- For detailed timing parameter descriptions, see SEMC_cfg_t structure documentation.
-
Consult your external memory device datasheet for specific timing requirements.
-
SEMC configuration should be done early in UserMain() before accessing external memory.
- See also
- ConfigureSEMC()
-
SEMC_cfg_t