見出し画像

JISC-SSD(SSD学習ボード)を使ってみる

はじめに

過去にFlashAir同人誌に関わったりしていた関係もあり、ひょんなことからJISC-SSDを入手させていただきました。

JISC-SSDは、キオクシア社のSSDの扱いを学習するためのボードとしてクレイン電子さんから発売予定のボードです。
[VOL-28]JISC-SSD(Jisaku In-Storage Computation SSD学習ボード) | 製品情報 | 株式会社クレイン電子 (crane-elec.co.jp)

ボードにはRP2040が乗っており、ほぼRaspberry Pi Pico互換で動かすことができます。

搭載されているNAND(TC58NVG0S3HTA00)のデータシートは以下から見ることができます。
SLC NAND型フラッシュメモリ製品一覧 | KIOXIA - Japan (日本語)

Lチカ

まずは何よりLチカでしょう。
Raspberry Pi Picoの開発環境を使用しますので、環境構築は以下を参考に実施してください。
Overview | Program RP2040 in Arduino | Adafruit Learning System
(Arduino公式よりもこちらのほうが最新を使用できるようです。公開後に差し替えました)


BOOL SELボタンを押しながら、RESETボタンを押すと書き込み待ちになります。

下記ソースでLチカできます

void setup() {
  pinMode(25,OUTPUT);
}

void loop() {
  digitalWrite(25,HIGH);
  delay(1000);
  digitalWrite(25,LOW);
  delay(1000);
}

シリアル出力はこんな感じです。
(書き込んで起動すると、シリアルポートが選べるようになっているので、シリアルモタを起動してください)

void setup() {
  pinMode(PIN_LED,OUTPUT);
  Serial.begin(115200);

  while(!Serial){
    digitalWrite(PIN_LED,LOW);
    delay(100);
    digitalWrite(PIN_LED,HIGH);
    delay(100);
  }

  Serial.println("Hello World");
}

void loop() {
}

ID読み出し

さて、Flashと通信してみましょう。
同人誌では、リセットからのBusy信号を観測していますが、オシロやロジアナがない場合これはできません。

ので、サクッと通信してしまいましょう。
以下のコードには、Flashとやりとりするための基礎的な関数と、ID読み出し機能を載せています。
(純粋にArduino言語でのみ書いているので、RP2040以外でNAND Flashを扱うのにも使えるかもしれません)

const int PIN_IO1 = 0;
const int PIN_IO2 = 1;
const int PIN_IO3 = 2;
const int PIN_IO4 = 3;
const int PIN_IO5 = 4;
const int PIN_IO6 = 5;
const int PIN_IO7 = 6;
const int PIN_IO8 = 7;
const int PIN_CEB0 = 8; //OUTPUT       Flash0 !ChipEnable (HIGH=無効. LOW=有効)
const int PIN_CEB1 = 9; //OUTPUT       Flash1 !ChipEnable (Not implemented)
const int PIN_CLE = 10; //OUTPUT       Command Latch Enable (HIGH=コマンドレジスタへの書き込み(WE立ち上がり時), LOW:無効)
const int PIN_ALE = 11; //OUTPUT       Address Latch Enable (HIGH=アドレスレジスタへの書き込み(WE立ち上がり時), LOW:無効)
const int PIN_WPB = 12; //OUTPUT       !Write Protect (HIGH=書込許可, LOW=書込禁止)
const int PIN_WEB = 13; //OUTPUT       !Write Enable (HIGH=待機, LOW=書込中, LOW→HIGH=データ確定)
const int PIN_REB = 14; //OUTPUT       !Read Enable (HIGH=待機, LOW=読込中, HIGH→LOW=データ確定)
const int PIN_RBB = 15; //INPUT_PULLUP Ready/!Busy (HIGH=Ready, LOW=Busy)

bool ssd_debug_log = true;

void io_set_output() {
  pinMode(PIN_IO1, OUTPUT);
  pinMode(PIN_IO2, OUTPUT);
  pinMode(PIN_IO3, OUTPUT);
  pinMode(PIN_IO4, OUTPUT);
  pinMode(PIN_IO5, OUTPUT);
  pinMode(PIN_IO6, OUTPUT);
  pinMode(PIN_IO7, OUTPUT);
  pinMode(PIN_IO8, OUTPUT);
}

void io_set_input() {
  pinMode(PIN_IO1, INPUT_PULLUP);
  pinMode(PIN_IO2, INPUT_PULLUP);
  pinMode(PIN_IO3, INPUT_PULLUP);
  pinMode(PIN_IO4, INPUT_PULLUP);
  pinMode(PIN_IO5, INPUT_PULLUP);
  pinMode(PIN_IO6, INPUT_PULLUP);
  pinMode(PIN_IO7, INPUT_PULLUP);
  pinMode(PIN_IO8, INPUT_PULLUP);
}

void io_write(byte d) {
  if (d & 1) {
    digitalWrite(PIN_IO1, HIGH);
  } else {
    digitalWrite(PIN_IO1, LOW);
  }
  if (d & 2) {
    digitalWrite(PIN_IO2, HIGH);
  } else {
    digitalWrite(PIN_IO2, LOW);
  }
  if (d & 4) {
    digitalWrite(PIN_IO3, HIGH);
  } else {
    digitalWrite(PIN_IO3, LOW);
  }
  if (d & 8) {
    digitalWrite(PIN_IO4, HIGH);
  } else {
    digitalWrite(PIN_IO4, LOW);
  }
  if (d & 16) {
    digitalWrite(PIN_IO5, HIGH);
  } else {
    digitalWrite(PIN_IO5, LOW);
  }
  if (d & 32) {
    digitalWrite(PIN_IO6, HIGH);
  } else {
    digitalWrite(PIN_IO6, LOW);
  }
  if (d & 64) {
    digitalWrite(PIN_IO7, HIGH);
  } else {
    digitalWrite(PIN_IO7, LOW);
  }
  if (d & 128) {
    digitalWrite(PIN_IO8, HIGH);
  } else {
    digitalWrite(PIN_IO8, LOW);
  }
}

byte io_read() {
  byte d = 0;
  if (digitalRead(PIN_IO1)) {
    d |= 1;
  }
  if (digitalRead(PIN_IO2)) {
    d |= 2;
  }
  if (digitalRead(PIN_IO3)) {
    d |= 4;
  }
  if (digitalRead(PIN_IO4)) {
    d |= 8;
  }
  if (digitalRead(PIN_IO5)) {
    d |= 16;
  }
  if (digitalRead(PIN_IO6)) {
    d |= 32;
  }
  if (digitalRead(PIN_IO7)) {
    d |= 64;
  }
  if (digitalRead(PIN_IO8)) {
    d |= 128;
  }
  return d;
}

void ssd_init()
{
  if (ssd_debug_log) {
    Serial.println("$ssd_init");
  }

  io_set_input();
  pinMode(PIN_CEB0, OUTPUT);
  pinMode(PIN_CEB1, OUTPUT);
  pinMode(PIN_CLE, OUTPUT);
  pinMode(PIN_ALE, OUTPUT);
  pinMode(PIN_WPB, OUTPUT);
  pinMode(PIN_WEB, OUTPUT);
  pinMode(PIN_REB, OUTPUT);
  pinMode(PIN_RBB, INPUT_PULLUP);

  digitalWrite(PIN_CEB0, LOW);
  digitalWrite(PIN_CEB1, HIGH);
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, LOW);
  digitalWrite(PIN_WPB, HIGH);
  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_REB, HIGH);
}

void ssd_reset()
{
  if (ssd_debug_log) {
    Serial.println("$ssd_reset");
  }

  digitalWrite(PIN_CLE, HIGH);
  digitalWrite(PIN_ALE, LOW);

  digitalWrite(PIN_WEB, LOW);

  io_set_output();
  io_write(0xFF);

  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_CLE, LOW);
}

void ssd_command_input(byte d)
{
  if (ssd_debug_log) {
    Serial.print("$ssd_command_input ");
    Serial.print(d, HEX);
    Serial.println();
  }

  digitalWrite(PIN_CLE, HIGH);
  digitalWrite(PIN_ALE, LOW);

  digitalWrite(PIN_WEB, LOW);

  io_set_output();
  io_write(d);

  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_CLE, LOW);

  io_set_input();
}

void ssd_address_input(byte a)
{
  if (ssd_debug_log) {
    Serial.print("$ssd_address_input ");
    Serial.print(a, HEX);
    Serial.println();
  }
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_set_output();
  io_write(a);
  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_ALE, LOW);

  io_set_input();
}

byte ssd_serial_data_output()
{
  if (ssd_debug_log) {
    Serial.print("$ssd_serial_data_output ");
  }
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, LOW);

  digitalWrite(PIN_REB, HIGH);
  io_set_input();
  digitalWrite(PIN_REB, LOW);
  byte d = io_read();
  digitalWrite(PIN_REB, HIGH);

  if (ssd_debug_log) {
    Serial.print(d, HEX);
    Serial.println();
  }
  return d;
}

void setup() {
  pinMode(PIN_LED, OUTPUT);
  ssd_init();
  Serial.begin(115200);

  //Serial表示待ち
  while (!Serial) {
    digitalWrite(PIN_LED, LOW);
    delay(100);
    digitalWrite(PIN_LED, HIGH);
    delay(100);
  }

  Serial.println("Ready");
  Serial.println(" --- read_id ---");
  ssd_command_input(0x90);
  ssd_address_input(0x00);

  int x1 = ssd_serial_data_output();
  int x2 = ssd_serial_data_output();
  int x3 = ssd_serial_data_output();
  int x4 = ssd_serial_data_output();
  int x5 = ssd_serial_data_output();

  Serial.print(x1,HEX);  Serial.print(",");
  Serial.print(x2,HEX);  Serial.print(",");
  Serial.print(x3,HEX);  Serial.print(",");
  Serial.print(x4,HEX);  Serial.print(",");
  Serial.print(x5,HEX);  Serial.println();
  
  Serial.println("Done");
}

void loop() {
}

実行して、シリアルモニタを開くと以下のように出ます。
この 98, F1, 80, 15, 72は、データシート(DST_TC58NVG0S3HTA00-TDE_EN_31435.pdf)の35pに記載されているので確認してみてください。

Ready
 --- read_id ---
$ssd_command_input 90
$ssd_address_input 0
$ssd_serial_data_output 98
$ssd_serial_data_output F1
$ssd_serial_data_output 80
$ssd_serial_data_output 15
$ssd_serial_data_output 72
98,F1,80,15,72
Done


Flashの読み書き

読み書きに必要なコードは以下のような感じです

const int PIN_IO1 = 0;
const int PIN_IO2 = 1;
const int PIN_IO3 = 2;
const int PIN_IO4 = 3;
const int PIN_IO5 = 4;
const int PIN_IO6 = 5;
const int PIN_IO7 = 6;
const int PIN_IO8 = 7;
const int PIN_CEB0 = 8; //OUTPUT       Flash0 !ChipEnable (HIGH=無効. LOW=有効)
const int PIN_CEB1 = 9; //OUTPUT       Flash1 !ChipEnable (Not implemented)
const int PIN_CLE = 10; //OUTPUT       Command Latch Enable (HIGH=コマンドレジスタへの書き込み(WE立ち上がり時), LOW:無効)
const int PIN_ALE = 11; //OUTPUT       Address Latch Enable (HIGH=アドレスレジスタへの書き込み(WE立ち上がり時), LOW:無効)
const int PIN_WPB = 12; //OUTPUT       !Write Protect (HIGH=書込許可, LOW=書込禁止)
const int PIN_WEB = 13; //OUTPUT       !Write Enable (HIGH=待機, LOW=書込中, LOW→HIGH=データ確定)
const int PIN_REB = 14; //OUTPUT       !Read Enable (HIGH=待機, LOW=読込中, HIGH→LOW=データ確定)
const int PIN_RBB = 15; //INPUT_PULLUP Ready/!Busy (HIGH=Ready, LOW=Busy)

bool ssd_debug_log = false;

void io_set_output() {
  pinMode(PIN_IO1, OUTPUT);
  pinMode(PIN_IO2, OUTPUT);
  pinMode(PIN_IO3, OUTPUT);
  pinMode(PIN_IO4, OUTPUT);
  pinMode(PIN_IO5, OUTPUT);
  pinMode(PIN_IO6, OUTPUT);
  pinMode(PIN_IO7, OUTPUT);
  pinMode(PIN_IO8, OUTPUT);
}

void io_set_input() {
  pinMode(PIN_IO1, INPUT_PULLUP);
  pinMode(PIN_IO2, INPUT_PULLUP);
  pinMode(PIN_IO3, INPUT_PULLUP);
  pinMode(PIN_IO4, INPUT_PULLUP);
  pinMode(PIN_IO5, INPUT_PULLUP);
  pinMode(PIN_IO6, INPUT_PULLUP);
  pinMode(PIN_IO7, INPUT_PULLUP);
  pinMode(PIN_IO8, INPUT_PULLUP);
}

void io_write(byte d) {
  if (d & 1) {
    digitalWrite(PIN_IO1, HIGH);
  } else {
    digitalWrite(PIN_IO1, LOW);
  }
  if (d & 2) {
    digitalWrite(PIN_IO2, HIGH);
  } else {
    digitalWrite(PIN_IO2, LOW);
  }
  if (d & 4) {
    digitalWrite(PIN_IO3, HIGH);
  } else {
    digitalWrite(PIN_IO3, LOW);
  }
  if (d & 8) {
    digitalWrite(PIN_IO4, HIGH);
  } else {
    digitalWrite(PIN_IO4, LOW);
  }
  if (d & 16) {
    digitalWrite(PIN_IO5, HIGH);
  } else {
    digitalWrite(PIN_IO5, LOW);
  }
  if (d & 32) {
    digitalWrite(PIN_IO6, HIGH);
  } else {
    digitalWrite(PIN_IO6, LOW);
  }
  if (d & 64) {
    digitalWrite(PIN_IO7, HIGH);
  } else {
    digitalWrite(PIN_IO7, LOW);
  }
  if (d & 128) {
    digitalWrite(PIN_IO8, HIGH);
  } else {
    digitalWrite(PIN_IO8, LOW);
  }
}

byte io_read() {
  byte d = 0;
  if (digitalRead(PIN_IO1)) {
    d |= 1;
  }
  if (digitalRead(PIN_IO2)) {
    d |= 2;
  }
  if (digitalRead(PIN_IO3)) {
    d |= 4;
  }
  if (digitalRead(PIN_IO4)) {
    d |= 8;
  }
  if (digitalRead(PIN_IO5)) {
    d |= 16;
  }
  if (digitalRead(PIN_IO6)) {
    d |= 32;
  }
  if (digitalRead(PIN_IO7)) {
    d |= 64;
  }
  if (digitalRead(PIN_IO8)) {
    d |= 128;
  }
  return d;
}

void io_wait_busy(){
  while(!digitalRead(PIN_RBB)){
    if(ssd_debug_log){
      Serial.println("BUSY!");
    }
    delayMicroseconds(10);
  }
}

void ssd_init()
{
  if (ssd_debug_log) {
    Serial.println("$ssd_init");
  }

  io_set_input();
  pinMode(PIN_CEB0, OUTPUT);
  pinMode(PIN_CEB1, OUTPUT);
  pinMode(PIN_CLE, OUTPUT);
  pinMode(PIN_ALE, OUTPUT);
  pinMode(PIN_WPB, OUTPUT);
  pinMode(PIN_WEB, OUTPUT);
  pinMode(PIN_REB, OUTPUT);
  pinMode(PIN_RBB, INPUT_PULLUP);

  digitalWrite(PIN_CEB0, LOW);
  digitalWrite(PIN_CEB1, HIGH);
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, LOW);
  digitalWrite(PIN_WPB, HIGH);
  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_REB, HIGH);
}

void ssd_reset()
{
  if (ssd_debug_log) {
    Serial.println("$ssd_reset");
  }

  digitalWrite(PIN_CLE, HIGH);
  digitalWrite(PIN_ALE, LOW);

  digitalWrite(PIN_WEB, LOW);

  io_set_output();
  io_write(0xFF);

  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_CLE, LOW);

  io_wait_busy();
}

void ssd_command_input(byte d)
{
  if (ssd_debug_log) {
    Serial.print("$ssd_command_input ");
    Serial.print(d, HEX);
    Serial.println();
  }

  digitalWrite(PIN_CLE, HIGH);
  digitalWrite(PIN_ALE, LOW);

  digitalWrite(PIN_WEB, LOW);

  io_set_output();
  io_write(d);

  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_CLE, LOW);

  io_set_input();
  io_wait_busy();
}

void ssd_data_input(byte d)
{
  if (ssd_debug_log) {
    Serial.print("$ssd_data_input ");
    Serial.print(d, HEX);
    Serial.println();
  }

  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, LOW);

  digitalWrite(PIN_WEB, LOW);

  io_set_output();
  io_write(d);

  digitalWrite(PIN_WEB, HIGH);

  io_set_input();
  io_wait_busy();
}

void ssd_address4_input(byte ca0, byte ca8, byte pa0, byte pa8)
{
  if (ssd_debug_log) {
    Serial.print("$ssd_addresses_input ");
    Serial.print(ca0, HEX);
    Serial.print(" ");
    Serial.print(ca8, HEX);
    Serial.print(" ");
    Serial.print(pa0, HEX);
    Serial.print(" ");
    Serial.print(pa8, HEX);
    Serial.println();
  }
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_set_output();
  io_write(ca0);
  digitalWrite(PIN_WEB, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_write(ca8);
  digitalWrite(PIN_WEB, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_write(pa0);
  digitalWrite(PIN_WEB, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_write(pa8);
  digitalWrite(PIN_WEB, HIGH);

  digitalWrite(PIN_ALE, LOW);

  io_set_input();
  io_wait_busy();
}

void ssd_address2_input(byte ca0, byte ca8)
{
  if (ssd_debug_log) {
    Serial.print("$ssd_addresses_input ");
    Serial.print(ca0, HEX);
    Serial.print(" ");
    Serial.print(ca8, HEX);
    Serial.println();
  }
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_set_output();
  io_write(ca0);
  digitalWrite(PIN_WEB, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_write(ca8);
  digitalWrite(PIN_WEB, HIGH);

  digitalWrite(PIN_ALE, LOW);

  io_set_input();
  io_wait_busy();
}

void ssd_address_input(byte a)
{
  if (ssd_debug_log) {
    Serial.print("$ssd_address_input ");
    Serial.print(a, HEX);
    Serial.println();
  }
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, HIGH);

  digitalWrite(PIN_WEB, LOW);
  io_set_output();
  io_write(a);
  digitalWrite(PIN_WEB, HIGH);
  digitalWrite(PIN_ALE, LOW);

  io_set_input();
  io_wait_busy();
}

byte ssd_serial_data_output()
{
  if (ssd_debug_log) {
    Serial.print("$ssd_serial_data_output ");
  }
  digitalWrite(PIN_CLE, LOW);
  digitalWrite(PIN_ALE, LOW);

  digitalWrite(PIN_REB, HIGH);
  io_set_input();
  digitalWrite(PIN_REB, LOW);
  byte d = io_read();
  digitalWrite(PIN_REB, HIGH);

  if (ssd_debug_log) {
    Serial.print(d, HEX);
    Serial.println();
  }
  io_wait_busy();
  return d;
}

const int PAGE_SIZE = 2176;
byte buff[PAGE_SIZE] = {0};

//1page = 2176byte
//1block = 128k+8k bytes (64pages)
//Capacity = 2176 * 64 * 1024 byte = 136MB

void read_id() {
  Serial.println(" --- read_id ---");
  ssd_command_input(0x90);
  ssd_address_input(0x00);

  int x1 = ssd_serial_data_output();
  int x2 = ssd_serial_data_output();
  int x3 = ssd_serial_data_output();
  int x4 = ssd_serial_data_output();
  int x5 = ssd_serial_data_output();

  Serial.print("Maker Code: ");
  Serial.print(x1, HEX);
  Serial.println();

  Serial.print("Device Code: ");
  Serial.print(x2, HEX);
  Serial.println();
  Serial.print("Chip Number, Cell Type: ");
  Serial.print(x3, HEX);
  Serial.println();
  Serial.print(" Chip Number: ");
  Serial.print(1 << (x3 & 3));
  Serial.println();
  Serial.print(" Cell Type: ");
  Serial.print(2 << ((x3 >> 2) & 3));
  Serial.println();

  Serial.print("Page Size, Block Size: ");
  Serial.print(x4, HEX);
  Serial.println();
  Serial.print(" Page Size: ");
  Serial.print(1 << (x4 & 3));
  Serial.println();
  Serial.print(" Block Size: ");
  Serial.print(64 << ((x4 >> 4) & 3));
  Serial.println();
  Serial.print(" I/O Width: ");
  Serial.print(8 << ((x4 >> 6) & 1));
  Serial.println();

  Serial.print("District Number: ");
  Serial.print(x5, HEX);
  Serial.println();
  Serial.print(" District Number: ");
  Serial.print(1 << ((x5 >> 2) & 3));
  Serial.println();
}

void read_status() {
  Serial.println(" --- read_status ---");
  ssd_command_input(0x70);

  int x1 = ssd_serial_data_output();

  Serial.print("Status :");
  Serial.print(x1, HEX);
  Serial.println();

  if ((x1 & 1) == 0) {
    Serial.println(" Chip Status1: Pass");
  } else {
    Serial.println(" Chip Status1: Fail");
  }
  if ((x1 & 2) == 0) {
    Serial.println(" Chip Status2: Pass");
  } else {
    Serial.println(" Chip Status2: Fail");
  }
  if (x1 & 32) {
    Serial.println(" Page Buffer Ready/Budy: Ready");
  } else {
    Serial.println(" Page Buffer Ready/Budy: Busy");
  }
  if (x1 & 64) {
    Serial.println(" Data Cache Ready/Budy: Ready");
  } else {
    Serial.println(" Data Cache Ready/Budy: Busy");
  }
  if (x1 & 128) {
    Serial.println(" Write Protect: Not Protected");
  } else {
    Serial.println(" Write Protect: Protected");
  }
}

void read_page(int page)
{
  Serial.println(" --- read_page ---");
  ssd_command_input(0x00);

  //カラムアドレスはページ内オフセットと思えば良い
  ssd_address4_input(0x00, 0x00, page & 0xFF, ((page >> 8) & 0xFF));
  ssd_command_input(0x30);

  for (int i = 0; i < PAGE_SIZE; i++) {
    buff[i] = ssd_serial_data_output();
  }
  for (int i = 0; i < PAGE_SIZE; i++) {
    Serial.print(buff[i], HEX);
    Serial.print(" ");
  }
  Serial.println(" ");
}

void write_page(int page)
{
  Serial.println(" --- write_page ---");
  ssd_command_input(0x80);
  ssd_address4_input(0x00, 0x00, page & 0xFF, ((page >> 8) & 0xFF));

  for (int i = 0; i < PAGE_SIZE; i++) {
    //ssd_data_input(page[i]);
    ssd_data_input((byte)i); //お試し連番
  }
  ssd_command_input(0x10);
  ssd_command_input(0x10);
}

void erase_page(int page)
{
  Serial.println(" --- erase_page ---");
  ssd_command_input(0x60);
  ssd_address2_input(page & 0xFF, ((page >> 8) & 0xFF)); //下位6bitに意味はない?
  ssd_command_input(0xD0);
}

void erase_all()
{
  Serial.println(" --- erase_all ---");
  for (int block = 0; block < 1024; block++) {
    int page = block * 64;
    ssd_command_input(0x60);
    ssd_address2_input(page & 0xFF, ((page >> 8) & 0xFF)); //下位6bitに意味はない?
    ssd_command_input(0xD0);
  }
}

//初期状態 or 全erase済みのときだけ有効
void bad_block_test() {
  for (int block = 0; block < 1024; block++) {
    bool bad = false;
    int page = block * 64;
    ssd_command_input(0x00);
    ssd_address4_input(0x00, 0x00, page & 0xFF, ((page >> 8) & 0xFF));
    ssd_command_input(0x30);
    if (ssd_serial_data_output() == 0) {
      bad = true;
    }
    if (bad) {
      Serial.print("BAD BLOCK: ");
      Serial.print(page);
      Serial.print(" - ");
      Serial.print(page + 63);
      Serial.print(" (");
      Serial.print(block);
      Serial.print(")");
      Serial.println();
    }
  }
}

void setup() {
  pinMode(PIN_LED, OUTPUT);
  ssd_init();
  Serial.begin(115200);

  //Serial表示待ち
  while (!Serial) {
    digitalWrite(PIN_LED, LOW);
    delay(100);
    digitalWrite(PIN_LED, HIGH);
    delay(100);
  }

  Serial.println("Ready");
  int page = 1;
  ssd_reset();
  read_id();
  read_status();

  read_page(page);
  read_status();
  //erase_all();
  //bad_block_test();
  
  erase_page(page);
  read_status();

  read_page(page);
  read_status();

  write_page(page);
  read_status();

  read_page(page);
  read_status();
  
  Serial.println("Done");
}

void loop() {
}

実行すると以下のようにNANDの読み書きが実行されます。

Ready
$ssd_reset
 --- read_id ---
$ssd_command_input 90
$ssd_address_input 0
$ssd_serial_data_output 98
$ssd_serial_data_output F1
$ssd_serial_data_output 80
$ssd_serial_data_output 15
$ssd_serial_data_output 72
Maker Code: 98
Device Code: F1
Chip Number, Cell Type: 80
 Chip Number: 1
 Cell Type: 2
Page Size, Block Size: 15
 Page Size: 2
 Block Size: 128
 I/O Width: 8
District Number: 72
 District Number: 1
Done
Ready
 --- read_id ---
Maker Code: 98
Device Code: F1
Chip Number, Cell Type: 80
 Chip Number: 1
 Cell Type: 2
Page Size, Block Size: 15
 Page Size: 2
 Block Size: 128
 I/O Width: 8
District Number: 72
 District Number: 1
 --- read_status ---
Status :E0
 Chip Status1: Pass
 Chip Status2: Pass
 Page Buffer Ready/Budy: Ready
 Data Cache Ready/Budy: Ready
 Write Protect: Not Protected
 --- read_page ---
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  
 --- read_status ---
Status :E0
 Chip Status1: Pass
 Chip Status2: Pass
 Page Buffer Ready/Budy: Ready
 Data Cache Ready/Budy: Ready
 Write Protect: Not Protected
 --- erase_page ---
 --- read_status ---
Status :E0
 Chip Status1: Pass
 Chip Status2: Pass
 Page Buffer Ready/Budy: Ready
 Data Cache Ready/Budy: Ready
 Write Protect: Not Protected
 --- read_page ---
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  
 --- read_status ---
Status :E0
 Chip Status1: Pass
 Chip Status2: Pass
 Page Buffer Ready/Budy: Ready
 Data Cache Ready/Budy: Ready
 Write Protect: Not Protected
 --- write_page ---
 --- read_status ---
Status :E0
 Chip Status1: Pass
 Chip Status2: Pass
 Page Buffer Ready/Budy: Ready
 Data Cache Ready/Budy: Ready
 Write Protect: Not Protected
 --- read_page ---
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F  
 --- read_status ---
Status :E0
 Chip Status1: Pass
 Chip Status2: Pass
 Page Buffer Ready/Budy: Ready
 Data Cache Ready/Budy: Ready
 Write Protect: Not Protected
Done

電源を入れ直すと、最初のreadが変わっているはずです。

おわりに

この記事に記載している内容のコードは、CC0とします。

最低限の動作のサンプルであり、WAITが要らないほど低速であったり、
特定のアドレスに書き込み続けてしまったり、NANDの管理や誤り訂正が実装されていなかったりします。

ぜひご自身で、よりよい(あるいは目的にあった)コードを記述してみてください。

もうすこしきれいに使用できるソースを作成中ですが、公開は期待せずお待ち下さい。
gpsnmeajp/jisc_ssd (github.com)