Smart External Memory Controller functions (SOMRT1061)
More...
|
| struct | SEMC_cfg_t |
| | Configuration structure for SEMC (Smart External Memory Controller) interface. More...
|
| |
|
| enum class | SEMC_BusWidth_t : uint8_t { SEMC_BusWidth_t::Width_8 = 0
, SEMC_BusWidth_t::Width_16 = 1
} |
| | Data bus width configuration for SEMC interface. More...
|
| |
| enum class | SEMC_AddrMux_t : uint8_t { SEMC_AddrMux_t::Mux = 0
, SEMC_AddrMux_t::AdvMux = 1
, SEMC_AddrMux_t::Bus = 2
} |
| | Address multiplexing mode configuration. More...
|
| |
| enum class | SEMC_ColAddrWidth_t : uint8_t {
SEMC_ColAddrWidth_t::Width_12 = 0
, SEMC_ColAddrWidth_t::Width_11 = 1
, SEMC_ColAddrWidth_t::Width_10 = 2
, SEMC_ColAddrWidth_t::Width_9 = 3
,
SEMC_ColAddrWidth_t::Width_8 = 4
, SEMC_ColAddrWidth_t::Width_7 = 5
, SEMC_ColAddrWidth_t::Width_6 = 6
, SEMC_ColAddrWidth_t::Width_5 = 7
,
SEMC_ColAddrWidth_t::Width_4 = 8
, SEMC_ColAddrWidth_t::Width_3 = 9
, SEMC_ColAddrWidth_t::Width_2 = 10
, SEMC_ColAddrWidth_t::Width_0 = 12
} |
| | Column address width configuration for memory devices. More...
|
| |
| enum class | SEMC_ClkMode_t : uint8_t { SEMC_ClkMode_t::Async = 0
, SEMC_ClkMode_t::Sync = 1
} |
| | Clock mode configuration for SEMC interface. More...
|
| |
| enum class | SEMC_Burst_t : uint8_t {
SEMC_Burst_t::Burst_1 = 0
, SEMC_Burst_t::Burst_2 = 1
, SEMC_Burst_t::Burst_4 = 2
, SEMC_Burst_t::Burst_8 = 3
,
SEMC_Burst_t::Burst_16 = 4
, SEMC_Burst_t::Burst_32 = 5
, SEMC_Burst_t::Burst_64 = 6
} |
| | Burst transfer length configuration. More...
|
| |
|
| 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 | ConfigureSEMC (uint32_t baseAddr, uint32_t siz, SEMC_cfg_t &cfg) |
| | Configure a Chip Select for the external data bus with lvalue reference configuration.
|
| |
Smart External Memory Controller functions (SOMRT1061)
#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 processor. 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 semc.h:796
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....
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....
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:15
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)...
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...
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...
@ Width_16
16-bit data bus (D[15:0]). Suitable for 16-bit memory devices. Provides 2x throughput compared to 8-b...
@ Burst_1
Single-beat transfer. No burst mode. Each access requires full address cycle. Use for random access o...
@ Width_0
No column addressing. Do not configure address pins for column mode. Use for simple SRAM/NOR Flash wi...
SEMC_BusWidth_t busWidth
Definition semc.h:806
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 ...
@ Width_8
8-bit column address (A[7:0]). Common for smaller SDRAM and burst-capable PSRAM.
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
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
◆ SEMC_AddrMux_t
#include <semc.h>
Address multiplexing mode configuration.
Determines how address signals are presented on the bus interface. The mode affects pin usage, timing characteristics, and compatibility with different memory devices.
- Note
- Multiplexed modes reduce pin count by sharing address and data pins.
-
Non-multiplexed mode provides fastest access but requires separate address pins.
-
Consult your memory device datasheet for supported addressing modes.
- Warning
- Bus mode (non-multiplexed) performs reads as AD-Mux due to hardware limitation.
- See also
- SEMC_cfg_t::muxMode
| Enumerator |
|---|
| Mux | Multiplexed address/data mode. Address and data share the same pins. Requires ADV signal to latch address.
|
| AdvMux | Advanced multiplexed mode. Enhanced multiplexing with additional control signals for complex timing.
|
| Bus | Non-multiplexed bus mode (write only). Separate address and data buses. Reads are performed as AD-Mux. Best for write-heavy applications.
|
◆ SEMC_Burst_t
#include <semc.h>
Burst transfer length configuration.
Specifies the number of data beats (words) transferred in a single burst operation. Burst transfers improve throughput for sequential memory accesses by eliminating address overhead after the first access.
- Note
- Burst mode is most effective in synchronous clock mode (SEMC_ClkMode_t::Sync).
-
The external memory device must support the selected burst length.
-
Larger burst sizes provide better performance for sequential access patterns.
-
Single-beat (Burst_1) effectively disables burst mode.
Burst Performance Example (
Sync Mode, 100 MHz SEMC Clock):
+-------+-------+-------+-------+
| Addr | Data | Addr | Data | = 4 cycles for 2 words
+-------+-------+-------+-------+
Throughput: 50 million words/sec
Burst-4 Access:
+-------+-------+-------+-------+-------+
| Addr | Data0 | Data1 | Data2 | Data3 | = 5 cycles for 4 words
+-------+-------+-------+-------+-------+
Throughput: 80 million words/sec (1.6x faster)
Burst-8 Access:
+-------+-------+-----+-------+
| Addr | Data0 | ... | Data7 | = 9 cycles for 8 words
+-------+-------+-----+-------+
Throughput: 88.9 million words/sec (1.78x faster)
Performance Improvement:
-
Burst_2: ~1.3x faster than single
-
Burst_4: ~1.6x faster than single
-
Burst_8: ~1.8x faster than single
@ Burst_32
32-beat burst transfer. Address once, transfer 32 consecutive data words. Maximum sequential performa...
@ Burst_4
4-beat burst transfer. Address once, transfer 4 consecutive data words. Common burst length for many ...
@ Burst_16
16-beat burst transfer. Address once, transfer 16 consecutive data words. High-performance sequential...
@ Burst_2
2-beat burst transfer. Address once, transfer 2 consecutive data words. Minimal burst mode.
- Warning
- Verify your memory device supports the selected burst length before use.
-
Some devices may have alignment requirements for burst addresses.
- See also
- SEMC_cfg_t::burstLen
-
SEMC_ClkMode_t::Sync
| Enumerator |
|---|
| Burst_1 | Single-beat transfer. No burst mode. Each access requires full address cycle. Use for random access or non-burst devices.
|
| Burst_2 | 2-beat burst transfer. Address once, transfer 2 consecutive data words. Minimal burst mode.
|
| Burst_4 | 4-beat burst transfer. Address once, transfer 4 consecutive data words. Common burst length for many devices.
|
| Burst_8 | 8-beat burst transfer. Address once, transfer 8 consecutive data words. Optimal for cache line fills (32 bytes with 16-bit bus).
|
| Burst_16 | 16-beat burst transfer. Address once, transfer 16 consecutive data words. High-performance sequential access.
|
| Burst_32 | 32-beat burst transfer. Address once, transfer 32 consecutive data words. Maximum sequential performance.
|
| Burst_64 | 64-beat burst transfer. Address once, transfer 64 consecutive data words. Extreme burst length for specialized applications.
|
◆ SEMC_BusWidth_t
#include <semc.h>
Data bus width configuration for SEMC interface.
Specifies the width of the data bus connecting the processor to the external memory device. The bus width must match the physical memory device's data interface width.
- Note
- 16-bit bus width provides higher throughput but requires more pins.
-
8-bit bus width uses fewer pins but requires more bus cycles for wide data transfers.
-
Verify your hardware PCB design supports the selected bus width.
- See also
- SEMC_cfg_t::busWidth
| Enumerator |
|---|
| Width_8 | 8-bit data bus (D[7:0]). Suitable for 8-bit memory devices or low pin-count designs.
|
| Width_16 | 16-bit data bus (D[15:0]). Suitable for 16-bit memory devices. Provides 2x throughput compared to 8-bit.
|
◆ SEMC_ClkMode_t
#include <semc.h>
Clock mode configuration for SEMC interface.
Determines whether the memory interface operates in asynchronous or synchronous mode. This affects timing requirements, performance characteristics, and which timing parameters in SEMC_cfg_t are used.
- Note
- Asynchronous mode is simpler and works with most SRAM and NOR Flash devices.
-
Synchronous mode provides better performance with SDRAM and synchronous PSRAM.
-
Different timing parameters apply depending on the selected mode.
Mode Comparison:
+----------------+----------------------+---------------------+
+----------------+----------------------+---------------------+
| Timing | Fixed delays | Clock-synchronized |
| Performance | Moderate | Higher |
| Burst Support | Limited | Full support |
| Device Types | SRAM, NOR Flash | SDRAM,
Sync PSRAM |
| Complexity | Simple | More complex |
+----------------+----------------------+---------------------+
Timing Parameters Used:
- cs_setup, cs_hold_min
- addr_setup, addr_hold
- wr_en_lo, wr_en_hi
- rd_en_lo, rd_en_hi
- addr_wr_hold
- turnaround
- cs_setup, cs_hold_min
- addr_setup, addr_hold
- wr_dat_setup, wr_dat_hold
- latency
- rd_cycle
- rd_hold
- See also
- SEMC_cfg_t::clkMode
-
SEMC_cfg_t (for timing parameter details)
| Enumerator |
|---|
| Async | Asynchronous mode. Timing based on fixed delays. No clock synchronization required. Best for SRAM and asynchronous NOR Flash devices.
|
| Sync | Synchronous mode. All signals synchronized to SEMC clock. Supports burst transfers. Best for SDRAM and synchronous PSRAM devices.
|
◆ SEMC_ColAddrWidth_t
#include <semc.h>
Column address width configuration for memory devices.
Specifies the number of column address bits used by the external memory device. This setting determines how many address pins are configured and affects the memory organization and access patterns.
- Note
- Width_0 disables address pin configuration - use for simple SRAM/Flash without column addressing.
-
For SDRAM and burst-capable devices, match this to the device's column address width.
-
Incorrect width settings can cause address aliasing or inaccessible memory regions.
Example Device Specifications:
+------------------------+-------------------+--------------------+
| Memory Device | Column Addresses | Use Setting |
+------------------------+-------------------+--------------------+
| Simple SRAM/Flash | N/A |
Width_0 |
| SDRAM (8-bit columns) | A[7:0] |
Width_8 |
| SDRAM (10-bit columns) | A[9:0] |
Width_10 |
| SDRAM (12-bit columns) | A[11:0] |
Width_12 |
+------------------------+-------------------+--------------------+
@ Width_8
8-bit data bus (D[7:0]). Suitable for 8-bit memory devices or low pin-count designs.
@ Width_10
10-bit column address (A[9:0]). Common for standard SDRAM configurations.
@ Width_12
12-bit column address (A[11:0]). Maximum column address width, suitable for large SDRAM devices.
- See also
- SEMC_cfg_t::colAddrWidth
| Enumerator |
|---|
| Width_12 | 12-bit column address (A[11:0]). Maximum column address width, suitable for large SDRAM devices.
|
| Width_11 | 11-bit column address (A[10:0]). Common for medium-density SDRAM.
|
| Width_10 | 10-bit column address (A[9:0]). Common for standard SDRAM configurations.
|
| Width_9 | 9-bit column address (A[8:0]). Used in some SDRAM and synchronous memory devices.
|
| Width_8 | 8-bit column address (A[7:0]). Common for smaller SDRAM and burst-capable PSRAM.
|
| Width_7 | 7-bit column address (A[6:0]). Used in specialized or smaller memory configurations.
|
| Width_6 | 6-bit column address (A[5:0]). Minimal column addressing for compact devices.
|
| Width_5 | 5-bit column address (A[4:0]). Very limited column addressing.
|
| Width_4 | 4-bit column address (A[3:0]). Minimal configuration for small burst regions.
|
| Width_3 | 3-bit column address (A[2:0]). Extremely limited addressing, rarely used.
|
| Width_2 | 2-bit column address (A[1:0]). Minimal burst addressing capability.
|
| Width_0 | No column addressing. Do not configure address pins for column mode. Use for simple SRAM/NOR Flash without column addressing requirements.
|
◆ ConfigureSEMC() [1/2]
| void ConfigureSEMC |
( |
uint32_t | baseAddr, |
|
|
uint32_t | siz, |
|
|
SEMC_cfg_t && | cfg ) |
#include <semc.h>
Configure a Chip Select for the external data bus with rvalue reference configuration.
This function configures the Smart External Memory Controller (SEMC) for a specific chip select with the provided memory region and timing parameters. This overload accepts an rvalue reference, making it suitable for temporary configuration objects.
The SEMC controller manages external memory devices connected to the RT1061's parallel bus interface. Configuration includes timing parameters, bus width, addressing modes, and signal characteristics required by the external memory device.
- Parameters
-
| baseAddr | The base address to assign to the configured chip select. This address must be within the valid SEMC memory region and properly aligned based on the size parameter. Typical range: 0x80000000 - 0x9FFFFFFF for SEMC CS0-CS3. |
| siz | The size (in bytes) of the memory region assigned to this chip select. Must be a power of 2 and properly aligned with the base address. Common values include 64KB (0x10000), 128KB (0x20000), 256KB (0x40000), etc. |
| cfg | Rvalue reference to the SEMC_cfg_t structure containing the configuration parameters. This allows passing temporary configuration objects efficiently. |
- Note
- The base address and size must not overlap with other configured chip selects.
-
Ensure all timing parameters in the cfg structure match your external device's datasheet requirements.
-
The clkPin and csPin in the configuration must be properly initialized before calling this function.
- Warning
- Incorrect timing parameters can cause data corruption or system instability.
-
This function should be called during system initialization before accessing the external memory region.
Expand for Example Usage
Examples
- Basic SRAM Configuration (Async Mode, 8-bit)
#include <semc.h>
void UserMain(void *pd) {
0x80000000,
0x40000,
.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,
.clkPin = Pins[10],
.csPin = Pins[11]
}
);
uint8_t *extMem = (uint8_t *)0x80000000;
extMem[0] = 0x42;
iprintf("Value written: 0x%02X\n", extMem[0]);
}
- 16-bit Synchronous Burst Memory
#include <semc.h>
void ConfigureSyncMemory() {
0x80000000,
0x100000,
.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,
.clkPin = Pins[10],
.csPin = Pins[11]
}
);
}
- Multiple Chip Selects with Non-Multiplexed Addressing
#include <semc.h>
void ConfigureMultipleMemories() {
0x80000000,
0x80000,
.cs_setup = 1,
.cs_hold_min = 1,
.addr_setup = 2,
.addr_hold = 2,
.wr_en_lo = 3,
.wr_en_hi = 3,
.rd_en_lo = 3,
.rd_en_hi = 5,
.turnaround = 2,
.clkPin = Pins[10],
.csPin = Pins[11]
}
);
0x80080000,
0x100000,
.cs_setup = 2,
.cs_hold_min = 2,
.addr_setup = 3,
.addr_hold = 3,
.wr_en_lo = 5,
.wr_en_hi = 5,
.rd_en_lo = 6,
.rd_en_hi = 8,
.clkPin = Pins[10],
.csPin = Pins[12]
}
);
}
- See also
- ConfigureSEMC(uint32_t, uint32_t, SEMC_cfg_t&)
-
SEMC_cfg_t
◆ ConfigureSEMC() [2/2]
| void ConfigureSEMC |
( |
uint32_t | baseAddr, |
|
|
uint32_t | siz, |
|
|
SEMC_cfg_t & | cfg ) |
#include <semc.h>
Configure a Chip Select for the external data bus with lvalue reference configuration.
This function configures the Smart External Memory Controller (SEMC) for a specific chip select with the provided memory region and timing parameters. This overload accepts an lvalue reference, making it suitable for reusing existing configuration objects.
The SEMC controller manages external memory devices connected to the RT1061's parallel bus interface. Configuration includes timing parameters, bus width, addressing modes, and signal characteristics required by the external memory device.
- Parameters
-
| baseAddr | The base address to assign to the configured chip select. This address must be within the valid SEMC memory region and properly aligned based on the size parameter. Typical range: 0x80000000 - 0x9FFFFFFF for SEMC CS0-CS3. |
| siz | The size (in bytes) of the memory region assigned to this chip select. Must be a power of 2 and properly aligned with the base address. Common values include 64KB (0x10000), 128KB (0x20000), 256KB (0x40000), etc. |
| cfg | Lvalue reference to the SEMC_cfg_t structure containing the configuration parameters. This allows reusing configuration objects across multiple calls. |
- Note
- The base address and size must not overlap with other configured chip selects.
-
Ensure all timing parameters in the cfg structure match your external device's datasheet requirements.
-
The clkPin and csPin in the configuration must be properly initialized before calling this function.
- Warning
- Incorrect timing parameters can cause data corruption or system instability.
-
This function should be called during system initialization before accessing the external memory region.
Expand for Example Usage
Examples
- Reusing Configuration for Multiple Memory Banks
#include <semc.h>
void ConfigureMemoryBanks() {
.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,
.clkPin = Pins[10]
};
sramConfig.csPin = Pins[11];
sramConfig.csPin = Pins[12];
iprintf("Two memory banks configured\n");
}
- Conditional Configuration Based on Hardware Detection
#include <semc.h>
.clkPin = Pins[10],
.csPin = Pins[11]
};
if (isFastMemory) {
} else {
}
return cfg;
}
void UserMain(void *pd) {
bool fastHardware = DetectMemorySpeed();
SEMC_cfg_t config = GetMemoryConfig(fastHardware);
iprintf("Memory configured for %s device\n",
fastHardware ? "fast" : "slow");
}
uint32_t rd_en_hi
Definition semc.h:835
uint32_t cs_setup
Definition semc.h:828
uint32_t wr_en_hi
Definition semc.h:833
- Dynamic Configuration with User Input
#include <semc.h>
void ConfigureUserMemory() {
.cs_setup = 1,
.cs_hold_min = 1,
.addr_setup = 1,
.addr_hold = 1,
.clkPin = Pins[10],
.csPin = Pins[11]
};
int readSpeed = ReadConfigValue("memory.read_speed");
memConfig.rd_en_lo = readSpeed;
memConfig.rd_en_hi = readSpeed + 2;
int writeSpeed = ReadConfigValue("memory.write_speed");
memConfig.wr_en_lo = writeSpeed;
memConfig.wr_en_hi = writeSpeed + 2;
uint32_t baseAddr = ReadConfigValue("memory.base_addr");
uint32_t size = ReadConfigValue("memory.size");
iprintf("Memory configured from user settings\n");
}
- See also
- ConfigureSEMC(uint32_t, uint32_t, SEMC_cfg_t&&)
-
SEMC_cfg_t