Skip to content

Instantly share code, notes, and snippets.

@GOROman
Last active January 1, 2025 10:24
Show Gist options
  • Select an option

  • Save GOROman/913f4de4211f779a7f9c144cc3e01148 to your computer and use it in GitHub Desktop.

Select an option

Save GOROman/913f4de4211f779a7f9c144cc3e01148 to your computer and use it in GitHub Desktop.
ESP32 Arduino で外付けPSRAM(ESP-PSRAM64H)をSPI経由で読み書きする(Arduino)
#include <Arduino.h>
#include <SPI.h>
// ESP-PSRAM64H
// 1:CS Input Chip select signal(Active low)
// 2:SO/SIO[1] I/O Serial output
// 3:--/SIO[2]
// 4:VSS Ground
// 5:SI/SIO[0] I/O Serial input
// 6:CLK Input Clock signa
// 7:--/SIO[3]
// 8:Vcc Power supply(+3.3V)
// GPIO Pin Assignments
#define SPI_SCK 18 // 6:CLK Input Clock signa
#define SPI_MOSI 23 // 5:SI/SIO[0] I/O Serial input
#define SPI_MISO 38 // 2:SO/SIO[1] I/O Serial output
#define SPI_CS 27 // 1:CS Input Chip select signal(Active low)
// ESP-PSRAM64 Command
#define PSRAM_READ 0x03
#define PSRAM_FAST_READ 0x0B
#define PSRAM_FAST_READ_QUAD 0xEB
#define PSRAM_WRITE 0x02
#define PSRAM_QUAD_WRITE 0x38
#define PSRAM_ENTER_QMODE 0x35
#define PSRAM_EXIT_QMODE 0xF5
#define PSRAM_RESET_EN 0x66
#define PSRAM_RESET 0x99
#define PSRAM_SET_BURST_LEN 0xC0
#define PSRAM_DEVICE_ID 0x9F
#define PSRAM_CLOCK (20*1000*1000)
SPIClass spi(HSPI);
SPISettings spisettings(PSRAM_CLOCK, MSBFIRST, SPI_MODE0);
void PSRAM_reset() {
printf("resetPSRAM\n");
digitalWrite(SPI_CS, LOW);
// Reset-Enableコマンドを送信
spi.transfer(PSRAM_RESET_EN);
digitalWrite(SPI_CS, HIGH);
digitalWrite(SPI_CS, LOW);
// Resetコマンドを送信
spi.transfer(PSRAM_RESET);
digitalWrite(SPI_CS, HIGH);
}
void PSRAM_readID() {
printf("PSRAM_readID\n");
digitalWrite(SPI_CS, LOW);
spi.transfer(PSRAM_DEVICE_ID);
// アドレス送信 (24ビットアドレス = 3バイト)
for (int i=0; i<3; i++) { // 24bit
spi.transfer(0x00); // addr
}
// データ受信
for (int i=0; i<8; i++) {
uint8_t receivedData = spi.transfer(0x00); // ダミーの0x00を送信しつつデータを受信
printf("receivedData: [%d] 0x%02x\n", i, receivedData);
}
digitalWrite(SPI_CS, HIGH);
}
size_t PSRAM_write(uint32_t address, const uint8_t *data, size_t size) {
digitalWrite(SPI_CS, LOW);
// 書き込みコマンドを送信
spi.transfer(PSRAM_WRITE);
// アドレス送信 (24ビットアドレス = 3バイト)
spi.transfer((address >> 16) & 0xFF); // アドレス上位バイト
spi.transfer((address >> 8) & 0xFF); // アドレス中位バイト
spi.transfer(address & 0xFF); // アドレス下位バイト
// 書き込むデータ送信
size_t result = 0;
for (size_t i=0; i<size; i++) {
spi.transfer(data[i]);
printf("Write data: %06xH:[%02xH]\n", address+i, data[i]);
result++;
}
digitalWrite(SPI_CS, HIGH);
return result;
}
size_t PSRAM_read(uint32_t address, uint8_t *data, size_t size) {
digitalWrite(SPI_CS, LOW);
// 読み込みコマンドを送信
spi.transfer(PSRAM_READ);
// アドレス送信 (24ビットアドレス = 3バイト)
spi.transfer((address >> 16) & 0xFF); // アドレス上位バイト
spi.transfer((address >> 8) & 0xFF); // アドレス中位バイト
spi.transfer(address & 0xFF); // アドレス下位バイト
// データ受信
size_t result = 0;
for (size_t i=0; i<size; i++) {
data[i] = spi.transfer(0x00); // ダミーの0x00を送信しつつデータを受信
printf("Read data: %06xH:[%02xH]\n", address+i, data[i]);
result++;
}
digitalWrite(SPI_CS, HIGH);
return result;
}
void setup() {
// SPIピンの初期化
pinMode(SPI_CS, OUTPUT);
digitalWrite(SPI_CS, HIGH); // チップセレクトをHIGHに設定
spi.begin(SPI_SCK, SPI_MISO, SPI_MOSI, -1);
spi.beginTransaction(spisettings);
PSRAM_reset();
spi.endTransaction();
}
const uint8_t DATA[] = {
0xDe, 0xad, 0xBe, 0xef,
0xBa, 0xd0, 0xF0, 0x0d,
};
const size_t SIZE = sizeof(DATA);
uint32_t address = 0x000000; // 24bit address
void loop() {
spi.beginTransaction(spisettings);
PSRAM_readID();
PSRAM_write(address, DATA, SIZE);
delay(500);
uint8_t readData[SIZE];
size_t result = PSRAM_read(address, readData, sizeof(readData));
// Verify
for (size_t i=0; i<SIZE; i++) {
printf("Verify: %06xH:[%02xH] == [%02xH]...", address+i, DATA[i], readData[i]);
if (DATA[i] != readData[i]) {
printf("NG\n");
} else {
printf("OK\n");
}
}
address += SIZE;
spi.endTransaction();
// spi.end();
delay(1000);
}
@GOROman
Copy link
Author

GOROman commented Jan 1, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment