Skip to content

Commit 257821a

Browse files
committed
Added comments and made some changed to how the NSToSDRAMClockCycles Calculation worked
1 parent cb34552 commit 257821a

5 files changed

Lines changed: 101 additions & 48 deletions

File tree

include/core/io/SDRAM.hpp

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,34 +47,37 @@ class SDRAM {
4747
POWER_DOWN = 6,
4848
};
4949

50+
/**
51+
* All the states that the SDRAM can be held in.
52+
* NORMAL_MODE means normal operation with nothing special happening
53+
* SELF_REFRESH_MODE means that all data cells are refreshed automatically, but the MCU does not know when
54+
* POWER_DOWN_MODE means the off state
55+
*/
5056
enum class SDRAMState {
5157
NORMAL_MODE = 0,
5258
SELF_REFRESH_MODE,
5359
POWER_DOWN_MODE
5460
};
5561

56-
enum class SDRAMBank {
57-
BANK1 = 0,
58-
BANK2 = 1
59-
};
60-
6162
/**
6263
* Holds all SDRAM controller settings that map directly to
6364
* the HAL_SDRAM_Init configuration structure.
6465
*
66+
* Values should be looked for in stm32f4xx_ll_fmc.h with macro prefix FMC_SDRAM...
67+
*
6568
* Must be initialized before passing into the constructor
6669
*/
6770
struct SDRAMInitConfig {
68-
uint32_t sdBank;
69-
uint32_t columnBitsNumber;
70-
uint32_t rowBitsNumber;
71-
uint32_t memoryDataWidth;
72-
uint32_t internalBankNumber;
73-
uint32_t casLatency;
74-
uint32_t writeProtection;
75-
uint32_t sdClockPeriod;
76-
uint32_t readBurst;
77-
uint32_t readPipeDelay;
71+
uint32_t sdBank; // Bank number for the controller (0 or 1 usually)
72+
uint32_t columnBitsNumber; // number of Horizontal Addressing Cells
73+
uint32_t rowBitsNumber; // number of Vertical Addressing Cells
74+
uint32_t memoryDataWidth; // How large the data is: 8, 16, or 32 bit
75+
uint32_t internalBankNumber; // How many layers of columns and rows there are. Usually 1, 2, or 4
76+
uint32_t casLatency; // How many SDRAM CLK Cycles from data fetch received to data available from the output
77+
uint32_t writeProtection; // If you want bank protection on at initialization
78+
uint32_t sdClockPeriod; // How many MCU controller clock cycles per SDRAM CLK Cycle. Usually 1, 2, or 3
79+
uint32_t readBurst; // How many bytes to expect per read request.
80+
uint32_t readPipeDelay; // Number of SDRAM CLK Cycles until data is available from read. Usually 1
7881
};
7982

8083
/**
@@ -83,13 +86,13 @@ class SDRAM {
8386
* Must be initialized before passing into the constructor
8487
*/
8588
struct SDRAMTimingConfig {
86-
uint32_t loadToActiveDelay;
87-
uint32_t exitSelfRefreshDelay;
88-
uint32_t selfRefreshTime;
89-
uint32_t rowCycleDelay;
90-
uint32_t writeRecoveryTime;
91-
uint32_t rpDelay;
92-
uint32_t rcdDelay;
89+
uint32_t loadToActiveDelay; // Time to update the load/operation register to SDRAM being read for commands
90+
uint32_t exitSelfRefreshDelay; // How long to exit the self-refresh mode
91+
uint32_t selfRefreshTime; // SDRAM CLK Cycles a row will be unavailable for while refreshing
92+
uint32_t rowCycleDelay; // Number of SDRAM CLK Cycles until a new active command can be submitted to a bank
93+
uint32_t writeRecoveryTime; // SDRAM CLK Cycles from write until a precharge can be given
94+
uint32_t readToPrechargeDelay; // SDRAM CLK Cycles from read until a precharge
95+
uint32_t rcdDelay; // SDRAM CLK Cycles from an active to read/write
9396
};
9497

9598
struct SDRAMPinGroup {
@@ -111,24 +114,25 @@ class SDRAM {
111114

112115
/**
113116
* Gets the Frequency of the SDRAM CLK
114-
*
117+
* @param mcuClkPerSdramClk Number of microcontroller clock cycles for every SDRAM Clock Cycle
115118
* @return the SDRAM clock frequency
116119
*/
117-
static uint32_t getSdramClockFrequency();
120+
static uint32_t getSdramClockFrequency(uint8_t mcuClkPerSdramClk);
118121

119122
/**
120-
* Get how long one SDRAM Clock cycle is in picoseconds
121-
*
122-
* @return the SDRAM clock period in picoseconds
123+
* Get how long one SDRAM Clock cycle is in femtoseconds
124+
* @param mcuClkPerSdramClk Number of microcontroller clock cycles for every SDRAM Clock Cycle
125+
* @return the SDRAM clock period in femtoseconds
123126
*/
124-
static uint32_t getSdramClockPeriodPS();
127+
static uint32_t getSdramClockPeriodFS(uint8_t mcuClkPerSdramClk);
125128

126129
/**
127130
* Transform a time given in nanoseconds into how many clock cycles fit in that range
128-
*
131+
* @param nanoseconds Number of nanoseconds
132+
* @param mcuClkPerSdramClk Number of microcontroller clock cycles for every SDRAM Clock Cycle
129133
* @return the SDRAM clock period in nanoseconds
130134
*/
131-
static uint32_t NSToSdramClockCycles(uint32_t nanoseconds);
135+
static uint32_t NSToSdramClockCycles(uint32_t nanoseconds, uint8_t mcuClkPerSdramClk);
132136

133137
/**
134138
* Enable write protection for the sdram
@@ -192,12 +196,32 @@ class SDRAM {
192196
}
193197

194198
protected:
199+
/**
200+
* Starting address of the RAM
201+
*/
195202
uint32_t* memoryAddress;
203+
/**
204+
* All the pins used by the RAM
205+
*/
196206
SDRAMPinGroup& pins;
207+
/**
208+
* Base config of the SDRAM
209+
*/
197210
SDRAMInitConfig initConfig;
211+
/**
212+
* Timing Config for the SDRAM Controller
213+
*/
198214
SDRAMTimingConfig timingConfig;
215+
/**
216+
* Associated Device that holds all the commands necessary to start up the device
217+
*/
199218
const SDRAMDevice& device;
200219

220+
/**
221+
* Helper function to turn a HAL Status in than SDRAM::Status
222+
* @param hal_status
223+
* @return status returned by the HAL
224+
*/
201225
static constexpr Status HALStatusToSDRAMStatus(uint32_t hal_status) {
202226
return static_cast<Status>(hal_status);
203227
}
@@ -215,6 +239,6 @@ class SDRAMDevice {
215239

216240
} // namespace core::io
217241

218-
#endif
219-
220242
#endif // STM32F4xx
243+
244+
#endif // EVT_SDRAM_HPP

include/core/io/platform/f4xx/SDRAMf4xx.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,18 @@ class SDRAMf4xx : public SDRAM {
119119
*/
120120
static void InitHardware(SDRAMPinGroup& pins);
121121

122+
/**
123+
* Address of the SDRAM register in memory within the overarching FMC
124+
*/
122125
FMC_SDRAM_TypeDef* sdramDevice;
123126

127+
/**
128+
* SDRAM Initialization Config, passed to HAL for Low-Level initialization
129+
*/
124130
SDRAM_HandleTypeDef sdram;
131+
/**
132+
* SDRAM Timing Initialization Config
133+
*/
125134
FMC_SDRAM_TimingTypeDef sdramTiming;
126135
};
127136

include/core/manager.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,9 @@ SPI& getSPI(GPIO* CSPins[], uint8_t pinLength) {
333333
* Get an instance of SDRAM
334334
*
335335
* @tparam pins the array of pins that will be used by the SDRAM Controller
336-
* @param sdramDevice actual register of data
337-
* @param
336+
* @param initConfig SDRAM controller config used to determine clock speed, address, and more
337+
* @param timingConfig SDRAM controller config used for hardware level timing for sending commands
338+
* @param sdramDevice the actual device being used, implementing the start-up command sequence
338339
*/
339340
#ifdef SDRAM_SUPPORTED
340341
template<SDRAM::SDRAMPinGroup& pins>

src/core/io/SDRAM.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,38 @@
22

33
namespace core::io {
44

5-
SDRAM::SDRAM(uint32_t* memoryAddress, SDRAMPinGroup& pins, const SDRAMInitConfig& initConfig,
6-
const SDRAMTimingConfig& timingConfig, const SDRAMDevice& device)
7-
: memoryAddress(memoryAddress), pins(pins), initConfig(initConfig), timingConfig(timingConfig), device(device) {}
5+
SDRAM::SDRAM(uint32_t* memoryAddress, SDRAMPinGroup& pins, const SDRAMInitConfig& initConfig,
6+
const SDRAMTimingConfig& timingConfig, const SDRAMDevice& device)
7+
: memoryAddress(memoryAddress), pins(pins), initConfig(initConfig), timingConfig(timingConfig), device(device) {}
88

9-
uint32_t SDRAM::getSdramClockFrequency() {
10-
return HAL_RCC_GetSysClockFreq() / 2;
11-
}
9+
uint32_t SDRAM::getSdramClockFrequency(uint8_t mcuClkPerSdramClk) {
10+
return HAL_RCC_GetSysClockFreq() / mcuClkPerSdramClk;
11+
}
1212

13-
uint32_t SDRAM::getSdramClockPeriodPS() {
14-
return 1000000000UL / (getSdramClockFrequency() / 1000);
15-
}
13+
uint32_t SDRAM::getSdramClockPeriodFS(uint8_t mcuClkPerSdramClk) {
14+
return 1000000000UL / (getSdramClockFrequency(mcuClkPerSdramClk) / 1000000);
1615

17-
uint32_t SDRAM::NSToSdramClockCycles(uint32_t nanoseconds) {
18-
return (nanoseconds * 1000) / (getSdramClockPeriodPS() + 1);
19-
}
16+
/**
17+
1,000,000,000 / (getSdramClockFrequency(mcuClkPerSdramClk) / 1000000)
18+
1,000,000,000 / ((HAL_RCC_GetSysClockFreq() / mcuClkPerSdramClk) / 1000000
19+
Assume HAL_RCC_GetSysClockFreq() returns 100,000,000 Hz and mcuClkPerSdramClk = 2
20+
1,000,000,000 / ((100,000,000Hz / 2) / 1000000)
21+
1,000,000,000 / (50,000,000Hz / 1000000)
22+
1,000,000,000 / 50Hz (1 / Hz = s)
23+
20,000,000 fs
24+
25+
Why put 1 billion as the numerator? It is the largest base 10 number that would fit in a
26+
32-bit number. This gives maximum resolution for the following
27+
function that uses it and keeps the calculation clean.
28+
29+
Why divide getSdramClockFrequency(...) by 1 million? This gives us how many megahertz
30+
the clock is running at, which is the most imporant part of the clock speed in our case.
31+
This makes the denominator of the outer division as small as possible, allowing us to get a high
32+
amount of accuracy for femtoseconds per SDRAM clock period
33+
*/
34+
}
35+
36+
uint32_t SDRAM::NSToSdramClockCycles(uint32_t nanoseconds, uint8_t mcuClkPerSdramClk) {
37+
return (nanoseconds * 1000000) / (getSdramClockPeriodFS(mcuClkPerSdramClk) + 1);
38+
} // Multiplied by 1,000,000 to get from nanoseconds to femtoseconds
2039
} // namespace core::io

src/core/io/platform/f4xx/SDRAMf4xx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SDRAMf4xx::SDRAMf4xx(SDRAMPinGroup& pins, const SDRAMInitConfig& sdramInitConfig
2929
sdramTiming.SelfRefreshTime = sdramTimingConfig.selfRefreshTime;
3030
sdramTiming.RowCycleDelay = sdramTimingConfig.rowCycleDelay;
3131
sdramTiming.WriteRecoveryTime = sdramTimingConfig.writeRecoveryTime;
32-
sdramTiming.RPDelay = sdramTimingConfig.rpDelay;
32+
sdramTiming.RPDelay = sdramTimingConfig.readToPrechargeDelay;
3333
sdramTiming.RCDDelay = sdramTimingConfig.rcdDelay;
3434

3535
InitHardware(pins);
@@ -65,7 +65,7 @@ SDRAM::Status SDRAMf4xx::SendCommand(SDRAMCommand type, SDRAMCommandTarget targe
6565

6666
SDRAM::Status SDRAMf4xx::ProgramRefreshRate(uint32_t rowCount, uint32_t refreshTime) {
6767
HAL_StatusTypeDef halStatus = FMC_SDRAM_ProgramRefreshRate(
68-
this->sdramDevice, (((refreshTime * 1000) / rowCount) * (getSdramClockFrequency() / 1000000)) - 20);
68+
this->sdramDevice, (((refreshTime * 1000) / rowCount) * (getSdramClockFrequency(TODO) / 1000000)) - 20);
6969

7070
return SDRAM::HALStatusToSDRAMStatus(halStatus);
7171
}

0 commit comments

Comments
 (0)