Skip to content

Add PSRAM test case #496

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 20, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions Firmware/Test Sketches/PSRAM/PSRAM.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
Lee Leahy
12 June 2023

Determine the performance of the PSRAM.

Based upon: https://thingpulse.com/esp32-how-to-use-psram/
and: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/external-ram.html
*/

#include <Arduino.h>

#define MAX_LOOP_COUNT (1 * 1000 * 1000)
#define PSRAM_BYTES (2 * 1024 * 1024)

volatile uint8_t * buffer;
volatile uint8_t internalRam;
int psramBytes;
uint32_t psramPageSize;

void setup()
{
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.println();
Serial.print("PSRAM Size: ");
Serial.print(ESP.getPsramSize());
Serial.println();
Serial.println("PSRAM Access Times");
}

void loop()
{
int32_t index;
uint8_t junk;
uint32_t loopOverhead;
uint32_t microsEnd;
uint32_t microsStart;
uint32_t offset;

// Read data from the data cache
buffer = (volatile uint8_t *)ps_malloc(PSRAM_BYTES);
Serial.print("PSRAM buffer: ");
Serial.printf("%p\r\n", buffer);
Serial.flush();

// Compute the loop overhead
microsStart = micros();
for (index = 0; index < MAX_LOOP_COUNT; index++)
{
}
microsEnd = micros();
displayTime(microsStart, microsEnd, 0, "Loop overhead");
loopOverhead = microsEnd - microsStart;

// Prime the data
junk = internalRam;

// Read data from the internal RAM
microsStart = micros();
for (index = 0; index < MAX_LOOP_COUNT; index++)
junk = internalRam;
microsEnd = micros();
displayTime(microsStart, microsEnd, loopOverhead, "Internal RAM access");

if (buffer)
{
// Measure cached PSRAM access
microsStart = micros();
for (index = 0; index < MAX_LOOP_COUNT; index++)
junk = buffer[0];
microsEnd = micros();
displayTime(microsStart, microsEnd, loopOverhead, "Cached PSRAM access");

// Separate the two sets of measurements
Serial.println();

// Compute the loop overhead
microsStart = micros();
for (index = 0; index < MAX_LOOP_COUNT; index++)
{
junk = buffer[offset];
offset = (offset + psramPageSize) & (PSRAM_BYTES - 1);
}
microsEnd = micros();
displayTime(microsStart, microsEnd, 0, "Loop overhead");
loopOverhead = microsEnd - microsStart;

// Measure sequential accesses to PSRAM
for (psramPageSize = 1; psramPageSize <= 4096; psramPageSize <<= 1)
{
microsStart = micros();
for (index = 0; index < MAX_LOOP_COUNT; index++)
{
junk = buffer[offset];
offset = (offset + psramPageSize) & (PSRAM_BYTES - 1);
}
microsEnd = micros();
sprintf((char *)buffer, "Uncached PSRAM access, %4d byte page size", psramPageSize);
displayTime(microsStart, microsEnd, loopOverhead, (const char *)buffer);
}
}

// Done
while (1);
}

void displayTime(uint32_t microsStart, uint32_t microsEnd, uint32_t loopOverhead, const char * string)
{
uint32_t delta;
float nanoSeconds;
char text[128];

// Display the cache read time
delta = microsEnd - microsStart - loopOverhead;
nanoSeconds = (double)delta / 1000.;
sprintf(text, "%s: %8d - %8d - %5d = %7d: %7.3f nSec",
string, microsEnd, microsStart, loopOverhead, delta, nanoSeconds);
Serial.println(text);
Serial.flush();
}