{
  "family": "Store",
  "name": "O.128",
  "rev": "a",
  "tile_id": 15,
  "json_version": "0.10",
  "updated_at": "2026-05-01T12:45:31.344Z",
  "headline": "128Mbit NOR flash",
  "description": "The Store.M contains 128Mbits of NOR flash memory for non-volatile code and data storage with support for single, dual, or quad SPI communications at bus-clock rates of up to 104MHz.",
  "application_notes": [
    {
      "sort": 0,
      "details": "",
      "heading": "",
      "image_url": ""
    }
  ],
  "package": {
    "pads": 10,
    "type": "T44",
    "size_x": 4000,
    "size_y": 4000,
    "size_z": 0
  },
  "power": [
    {
      "max": 2,
      "min": 1.71,
      "type": "system",
      "notes": "",
      "gnd_pad": [
        "1"
      ],
      "function": "",
      "direction": "input",
      "is_required": true,
      "max_current": "",
      "positive_pad": [
        "10"
      ]
    }
  ],
  "components": [
    {
      "url": "https://www.renesas.com/en/products/at25ql128a",
      "part": "AT25QL128A",
      "datasheet": "https://mosaic-component-datasheets.s3.eu-north-1.amazonaws.com/15/Renesas-AT25QL128A.pdf",
      "manufacturer": "Renesas"
    }
  ],
  "pads": [
    {
      "pad": "1",
      "geometry": {
        "size_x": 1000,
        "size_y": 400,
        "center_x": -1500,
        "center_y": 1600
      },
      "functions": [
        {
          "note": "",
          "type": "power",
          "function": "GND",
          "direction": "input"
        }
      ]
    },
    {
      "pad": "2",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": 800
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "SPI.MOSI",
          "direction": "",
          "interface": "SPI"
        },
        {
          "note": "",
          "type": "digital",
          "function": "QSPI.IO0",
          "direction": "",
          "interface": "QSPI"
        }
      ]
    },
    {
      "pad": "3",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": 0
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "SPI.CS",
          "direction": "",
          "interface": "SPI"
        },
        {
          "note": "",
          "type": "digital",
          "function": "QSPI.CS",
          "direction": "",
          "interface": "QSPI"
        }
      ]
    },
    {
      "pad": "4",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": -800
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "SPI.CLK",
          "direction": "",
          "interface": "SPI"
        },
        {
          "note": "",
          "type": "digital",
          "function": "QSPI.CLK",
          "direction": "",
          "interface": "QSPI"
        }
      ]
    },
    {
      "pad": "5",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": -1600
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "SPI.MISO",
          "direction": "",
          "interface": "SPI"
        },
        {
          "note": "",
          "type": "digital",
          "function": "QSPI.IO1",
          "direction": "",
          "interface": "QSPI"
        }
      ]
    },
    {
      "pad": "6",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": -1600
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "WP",
          "direction": "input"
        },
        {
          "note": "",
          "type": "digital",
          "function": "QSPI.IO2",
          "direction": "",
          "interface": "QSPI"
        }
      ]
    },
    {
      "pad": "7",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": -800
      },
      "functions": []
    },
    {
      "pad": "8",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": 0
      },
      "functions": []
    },
    {
      "pad": "9",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": 800
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "HOLD",
          "direction": ""
        },
        {
          "note": "",
          "type": "digital",
          "function": "QSPI.IO3",
          "direction": "",
          "interface": "QSPI"
        }
      ]
    },
    {
      "pad": "10",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": 1600
      },
      "functions": [
        {
          "note": "1.71-2.0V",
          "type": "power",
          "function": "V+",
          "direction": "input"
        }
      ]
    }
  ],
  "interfaces": [
    {
      "name": "SPI",
      "type": "SPI",
      "parameters": {
        "modes": [
          "slave"
        ],
        "max_clock_speed": "104MHz"
      },
      "pad_assignments": [
        {
          "pad": "2",
          "role": "bus",
          "function": "SPI.MOSI",
          "is_required": true
        },
        {
          "pad": "3",
          "role": "other",
          "function": "SPI.CS",
          "is_required": true
        },
        {
          "pad": "4",
          "role": "bus",
          "function": "SPI.CLK",
          "is_required": true
        },
        {
          "pad": "5",
          "role": "bus",
          "function": "SPI.MISO",
          "is_required": true
        }
      ],
      "mutually_exclusive": [
        "QSPI"
      ]
    },
    {
      "name": "QSPI",
      "type": "QSPI",
      "parameters": {
        "modes": [
          "slave"
        ],
        "max_clock_speed": "104MHz"
      },
      "pad_assignments": [
        {
          "pad": "2",
          "role": "bus",
          "function": "QSPI.IO0"
        },
        {
          "pad": "3",
          "role": "other",
          "function": "QSPI.CS"
        },
        {
          "pad": "4",
          "role": "bus",
          "function": "QSPI.CLK"
        },
        {
          "pad": "5",
          "role": "bus",
          "function": "QSPI.IO1"
        },
        {
          "pad": "6",
          "role": "bus",
          "function": "QSPI.IO2"
        },
        {
          "pad": "9",
          "role": "bus",
          "function": "QSPI.IO3"
        }
      ],
      "mutually_exclusive": [
        "SPI"
      ]
    }
  ],
  "twin": {
    "score": 1,
    "source": "// Digital twin for Store.O.128 — Renesas/Adesto AT25QL128A 128 Mbit QSPI NOR flash.\n//\n// Now driver-backed (tile_store_o_128): the twin mirrors the SPI-NOR command set\n// — JEDEC ID, status (WIP/WEL), capacity, read / fast-read, write-enable, page\n// program, write (page-split), 4 KB sector / 64 KB block / chip erase, wait-ready,\n// deep power-down / release. SPI/QSPI on pads 2/3/4/5/6/9; V+ pad 10 (1.71–2.0 V);\n// GND pad 1.\n//\n// Identity + command/status semantics are canonical (datasheet/driver). Actual\n// stored bytes aren't modeled (read/program return/accept no real array data), and\n// the per-mode supply currents are representative AT25QL128A figures, so the power\n// layer is inferred. Operating mode drives the V+ draw; busy clears on wait_ready.\nimport type { TileSim } from '../tileSim';\n\nconst JEDEC_ID = 0x1f4218; // mfr 0x1F, type 0x42, capacity 0x18 (128 Mbit)\nconst CAPACITY = 0x1000000; // 16 MB\n\nconst SR_WIP = 0x01; // write in progress (busy)\nconst SR_WEL = 0x02; // write enable latch\n\nconst MODE_STANDBY = 0;\nconst MODE_READ = 1;\nconst MODE_PROGRAM = 2;\nconst MODE_ERASE = 3;\nconst MODE_DPD = 4;\n\nconst UVLO_MV = 1710;\n\n// representative AT25QL128A supply currents by mode (µA)\nconst I_STANDBY_UA = 12;\nconst I_READ_UA = 10_000;\nconst I_PROGRAM_UA = 20_000;\nconst I_ERASE_UA = 25_000;\nconst I_DPD_UA = 1;\n\ninterface State {\n  mode: number; // 0 standby, 1 read, 2 program, 3 erase, 4 deep power-down\n  wel: number; // write-enable latch\n  busy: number; // program/erase in progress (WIP)\n  vplus_mv: number;\n  [field: string]: number;\n}\n\nfunction modeUa(m: number): number {\n  if (m === MODE_READ) return I_READ_UA;\n  if (m === MODE_PROGRAM) return I_PROGRAM_UA;\n  if (m === MODE_ERASE) return I_ERASE_UA;\n  if (m === MODE_DPD) return I_DPD_UA;\n  return I_STANDBY_UA;\n}\n\nconst sim: TileSim<State> = {\n  tile: 'Store.O.128',\n\n  defaultState: { mode: MODE_STANDBY, wel: 0, busy: 0, vplus_mv: 1800 },\n\n  controls: [\n    { type: 'slider', field: 'mode', label: 'Mode (0std1rd2pg3er4dpd)', min: 0, max: 4, step: 1 },\n    {\n      type: 'slider',\n      field: 'vplus_mv',\n      label: 'V+ supply',\n      min: 1500,\n      max: 2000,\n      step: 10,\n      unit: 'mV',\n    },\n  ],\n\n  hostCalls: {\n    // ── lifecycle ──\n    tile_store_o_128_find: () => ({ scalar: 1 }), // JEDEC ID matches\n    tile_store_o_128_init: () => ({\n      scalar: 0,\n      nextState: { mode: MODE_STANDBY, wel: 0, busy: 0 },\n    }),\n\n    // ── identity / status ──\n    tile_store_o_128_read_jedec_id: () => ({ scalar: JEDEC_ID }),\n    tile_store_o_128_read_status: ({ state }) => ({\n      scalar: (state.busy ? SR_WIP : 0) | (state.wel ? SR_WEL : 0),\n    }),\n    tile_store_o_128_is_busy: ({ state }) => ({ scalar: state.busy }),\n    tile_store_o_128_get_capacity: () => ({ scalar: CAPACITY }),\n\n    // ── read (data bytes not modeled) ──\n    tile_store_o_128_read: () => ({ scalar: 0, nextState: { mode: MODE_READ } }),\n    tile_store_o_128_fast_read: () => ({ scalar: 0, nextState: { mode: MODE_READ } }),\n\n    // ── write / erase ──\n    tile_store_o_128_write_enable: () => ({ nextState: { wel: 1 } }),\n    tile_store_o_128_page_program: () => ({ nextState: { mode: MODE_PROGRAM, busy: 1, wel: 0 } }),\n    tile_store_o_128_write: () => ({ nextState: { mode: MODE_PROGRAM, busy: 1, wel: 0 } }),\n    tile_store_o_128_erase_sector: () => ({ nextState: { mode: MODE_ERASE, busy: 1, wel: 0 } }),\n    tile_store_o_128_erase_block: () => ({ nextState: { mode: MODE_ERASE, busy: 1, wel: 0 } }),\n    tile_store_o_128_erase_chip: () => ({ nextState: { mode: MODE_ERASE, busy: 1, wel: 0 } }),\n    tile_store_o_128_wait_ready: () => ({ scalar: 1, nextState: { busy: 0, mode: MODE_STANDBY } }),\n\n    // ── power ──\n    tile_store_o_128_deep_power_down: () => ({ nextState: { mode: MODE_DPD } }),\n    tile_store_o_128_release: () => ({ nextState: { mode: MODE_STANDBY } }),\n  },\n\n  provenance: {\n    tile_store_o_128_find: 'canonical', // JEDEC ID 0x1F4218\n    tile_store_o_128_read_jedec_id: 'canonical',\n    tile_store_o_128_read_status: 'canonical', // WIP/WEL bits\n    tile_store_o_128_is_busy: 'canonical',\n    tile_store_o_128_get_capacity: 'canonical', // 16 MB\n    tile_store_o_128_write_enable: 'canonical', // WEL set\n    tile_store_o_128_erase_sector: 'canonical', // 4 KB sector erase\n    tile_store_o_128_erase_block: 'canonical', // 64 KB block erase\n    tile_store_o_128_erase_chip: 'canonical',\n    tile_store_o_128_deep_power_down: 'canonical',\n    tile_store_o_128_release: 'canonical',\n    tile_store_o_128_init: 'inferred',\n    tile_store_o_128_wait_ready: 'inferred',\n    // read/program model the op + power but not actual stored bytes\n    tile_store_o_128_read: 'inferred',\n    tile_store_o_128_fast_read: 'inferred',\n    tile_store_o_128_page_program: 'inferred',\n    tile_store_o_128_write: 'inferred',\n    power: 'inferred', // mode topology canonical; per-mode currents representative\n  },\n\n  // Activity: busy during program/erase, data out (IO1/MISO) during read.\n  padOutputs(state) {\n    const on = state.vplus_mv >= UVLO_MV ? 1 : 0;\n    return {\n      busy:\n        on && (state.busy === 1 || state.mode === MODE_PROGRAM || state.mode === MODE_ERASE)\n          ? 1\n          : 0,\n      'IO1(MISO)': on && state.mode === MODE_READ ? 1 : 0,\n    };\n  },\n\n  // Single V+ rail (pad 10) draws per operating mode.\n  power(state) {\n    const i = state.vplus_mv >= UVLO_MV ? modeUa(state.mode) : 0;\n    const label =\n      ['standby', 'read', 'program', 'erase', 'deep power-down'][state.mode] ?? 'standby';\n    return {\n      draw_ua: i,\n      rails: [\n        {\n          name: 'V+',\n          role: 'supply',\n          v_mv: state.vplus_mv,\n          i_ua: i,\n          pads: ['10'],\n          note: `QSPI NOR flash — ${label}`,\n        },\n      ],\n    };\n  },\n};\n\nexport default sim;\n",
    "status": "validated",
    "updated_at": "2026-06-22 03:40:21"
  },
  "config": {
    "hold": {
      "kind": "boolean",
      "when": {
        "interfaceMode": "spi"
      },
      "group": "Sidebands",
      "label": "HOLD active",
      "binding": {
        "pad": "9",
        "kind": "strap",
        "states": {
          "low": "held",
          "high": "running (forced)",
          "open": "running (default, via internal PU)"
        }
      },
      "default": false,
      "options": [
        {
          "value": false,
          "states": {
            "9": "open"
          }
        },
        {
          "value": true,
          "states": {
            "9": "low"
          },
          "netlist": {
            "requires": [
              {
                "to": {
                  "kind": "rail",
                  "rail": "GND"
                },
                "tag": "hold.active.connection",
                "from": {
                  "pad": "9",
                  "kind": "tile"
                },
                "role": "power"
              }
            ]
          }
        }
      ],
      "description": "When true, pad 9 (HOLD) is tied to GND, pausing all SPI transactions on the bus (without resetting state). When false (default), pad 9 floats and the chip's internal pull-up keeps it deasserted. Only meaningful in SPI mode (in QSPI mode pad 9 is IO3)."
    },
    "writeProtect": {
      "kind": "boolean",
      "when": {
        "interfaceMode": "spi"
      },
      "group": "Sidebands",
      "label": "Write-protect",
      "binding": {
        "pad": "6",
        "kind": "strap",
        "states": {
          "low": "write-protected",
          "high": "unprotected (forced)",
          "open": "unprotected (default, via internal PU)"
        }
      },
      "default": false,
      "options": [
        {
          "value": false,
          "states": {
            "6": "open"
          }
        },
        {
          "value": true,
          "states": {
            "6": "low"
          },
          "netlist": {
            "requires": [
              {
                "to": {
                  "kind": "rail",
                  "rail": "GND"
                },
                "tag": "writeProtect.enabled.connection",
                "from": {
                  "pad": "6",
                  "kind": "tile"
                },
                "role": "power"
              }
            ]
          }
        }
      ],
      "description": "When true, pad 6 (WP) is tied to GND, write-protecting the lower portion of memory per the chip's status register. When false (default), pad 6 floats and the chip's internal pull-up keeps it deasserted (writes allowed). Only meaningful in SPI mode (in QSPI mode pad 6 is IO2)."
    },
    "interfaceMode": {
      "kind": "select",
      "group": "Interfaces",
      "label": "Interface mode",
      "default": "spi",
      "options": [
        {
          "label": "SPI (single-data)",
          "value": "spi",
          "activates": {
            "interface": "SPI"
          }
        },
        {
          "label": "QSPI (quad-data)",
          "value": "qspi",
          "activates": {
            "interface": "QSPI"
          }
        }
      ]
    }
  }
}