{
  "family": "Sense",
  "name": "MIC",
  "rev": "a",
  "tile_id": 19,
  "json_version": "0.6",
  "updated_at": "2026-06-22T07:38:59.397Z",
  "headline": "I2C-output MEMS microphone",
  "description": "The Sense.MIC combines a PUI Audio AMM-2742-T-R omnidirectional MEMS microphone with the MAX11645 12-bit ADC. The microphone covers 20 Hz to 20 kHz with 59 dB SNR and 123 dB acoustic overload point. The ADC samples at up to 94.4 ksps and can operate a I2C speeds up to 1.7MHz, thereby fully covering the microphone's bandwidth. Suited for voice detection, sound-level monitoring, and audio recording applications.",
  "application_notes": [],
  "package": {
    "pads": 10,
    "type": "T44",
    "size_x": 4000,
    "size_y": 4000,
    "size_z": 0
  },
  "power": [
    {
      "max": 3.6,
      "min": 2.7,
      "type": "system",
      "notes": "",
      "gnd_pad": [
        "1"
      ],
      "function": "",
      "direction": "input",
      "is_required": true,
      "max_current": "",
      "positive_pad": [
        "10"
      ]
    }
  ],
  "components": [
    {
      "url": "https://www.analog.com/en/products/max11645.html",
      "part": "MAX11645",
      "datasheet": "https://mosaic-component-datasheets.s3.eu-north-1.amazonaws.com/19/unknown-MAX11645.pdf",
      "manufacturer": "Maxim"
    },
    {
      "url": "https://www.sameskydevices.com/product/resource/cmm-2718at-42316-tr.pdf",
      "part": "CMM-2718AT-42316-TR",
      "datasheet": "https://mosaic-component-datasheets.s3.eu-north-1.amazonaws.com/19/Same_Sky-CMM-2718AT-42316-TR.pdf",
      "manufacturer": "Same Sky"
    }
  ],
  "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": []
    },
    {
      "pad": "3",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": 0
      },
      "functions": []
    },
    {
      "pad": "4",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": -800
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "I2C.CLK",
          "direction": "bidirectional",
          "interface": "I2C"
        }
      ]
    },
    {
      "pad": "5",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": -1600,
        "center_y": -1600
      },
      "functions": [
        {
          "note": "",
          "type": "digital",
          "function": "I2C.DAT",
          "direction": "bidirectional",
          "interface": "I2C"
        }
      ]
    },
    {
      "pad": "6",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": -1600
      },
      "functions": [
        {
          "note": "reference analog audio output",
          "type": "analog",
          "function": "AOUT",
          "direction": "output"
        }
      ]
    },
    {
      "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": []
    },
    {
      "pad": "10",
      "geometry": {
        "size_x": 800,
        "size_y": 400,
        "center_x": 1600,
        "center_y": 1600
      },
      "functions": [
        {
          "note": "2.7-3.6V",
          "type": "power",
          "function": "V+",
          "direction": "input"
        }
      ]
    }
  ],
  "interfaces": [
    {
      "name": "I2C",
      "type": "I2C",
      "parameters": {
        "modes": [
          "slave"
        ],
        "addresses": [
          {
            "address": "0x36"
          }
        ],
        "max_clock_speed": "1.7MHz"
      },
      "pad_assignments": [
        {
          "pad": "4",
          "role": "bus",
          "function": "I2C.CLK",
          "is_required": true
        },
        {
          "pad": "5",
          "role": "bus",
          "function": "I2C.DAT",
          "is_required": true
        }
      ]
    }
  ],
  "twin": {
    "score": 1,
    "source": "// Digital twin for Sense.MIC — analog MEMS microphone + amplifier + ADC.\n//\n// Signal chain (schematic truth): a Same Sky/CUI CMM-2718AT analog MEMS mic\n// (−42 dBV/Pa, 57 dBA SNR, 130 dB AOP) is AC-coupled into an AD8605 op-amp with\n// ~48× non-inverting gain (R4 47k / R3 1k), biased to mid-rail; the amplified\n// output drives a MAX11645 12-bit I2C ADC (AIN0) AND is tapped out to a pad. The\n// twin drives the world with a sound-level slider (dB SPL) and runs it through\n// SPL → mic Vrms → ×48 gain → DC-biased 12-bit quantisation.\n//\n// PAD NOTE: the schematic routes the amplified analog output to pad 8. The\n// canonical tile JSON is mid-reconciliation and currently labels pad 6 as the\n// analog out (and still lists the old PUI AMM-2742 mic, no AD8605). This twin\n// emits the analog out under the \"AOUT\" net so it follows wherever the JSON maps\n// it; the DB still needs the mic part, the AD8605, and AOUT→pad 8 corrected.\nimport type { TileSim } from '../tileSim';\n\nconst I2C_ADDR = 0x36; // MAX11645 fixed I2C address\nconst AMP_GAIN = 48; // AD8605 non-inverting gain (1 + 47k/1k)\nconst MIC_MV_PER_PA = 7.943; // −42 dBV/Pa at the mic output\nconst ADC_FULL = 4096; // 12-bit\n\ninterface State {\n  sound_level: number; // ambient SPL in dB the user drives\n  vref_mv: number; // ADC reference (3300 VDD, 2048 internal)\n  ref_sel: number; // sense_mic_ref_t code\n  channel: number; // AIN0/AIN1\n  scan: number; // scan mode code\n  clock_sel: number; // internal/external clock\n  polarity: number; // 0 unipolar, 1 bipolar\n  asleep: number;\n\n  [field: string]: number;\n}\n\nconst pick = (args: number[], i: number, cur: number) =>\n  args.length > i && Number.isFinite(args[i]) ? args[i] : cur;\nconst clamp = (v: number, lo: number, hi: number) => Math.max(lo, Math.min(hi, v));\n\n// DC bias sits at mid-rail (the R1/R2 330k/330k divider biases the AD8605 input).\nconst dcOffset = () => Math.round(ADC_FULL / 2);\n\n// SPL → pressure (Pa), 1 Pa = 94 dB SPL.\nconst pascals = (spl: number) => Math.pow(10, (spl - 94) / 20);\n// Amplified RMS voltage at the ADC input (mV), before clipping to the rail.\nfunction adcVrmsMv(s: State): number {\n  return MIC_MV_PER_PA * pascals(s.asleep ? 0 : s.sound_level) * AMP_GAIN;\n}\n// RMS in ADC counts, clipped so the amp can't swing past the rail.\nfunction rmsCounts(s: State): number {\n  const mv = Math.min(adcVrmsMv(s), s.vref_mv / 2);\n  return Math.round((mv / s.vref_mv) * ADC_FULL);\n}\n// An instantaneous sample = bias + a representative positive excursion.\nconst rawSample = (s: State) => clamp(dcOffset() + rmsCounts(s), 0, ADC_FULL - 1);\nconst toMv = (s: State, counts: number) => Math.round((counts * s.vref_mv) / ADC_FULL);\n\nconst sim: TileSim<State> = {\n  tile: 'Sense.MIC',\n\n  defaultState: {\n    sound_level: 50, // quiet room\n    vref_mv: 3300, // VDD reference (default)\n    ref_sel: 0x00, // SENSE_MIC_REF_VDD\n    channel: 0,\n    scan: 0,\n    clock_sel: 0,\n    polarity: 0,\n    asleep: 0,\n  },\n\n  controls: [\n    {\n      type: 'slider',\n      field: 'sound_level',\n      label: 'Sound level',\n      min: 30,\n      max: 120,\n      step: 1,\n      unit: 'dB SPL',\n    },\n    { type: 'toggle', field: 'asleep', label: 'Asleep' },\n  ],\n\n  hostCalls: {\n    // ── lifecycle ──\n    tile_sense_mic_find: () => ({ scalar: I2C_ADDR }),\n    tile_sense_mic_init: () => ({ scalar: 0, nextState: { asleep: 0 } }),\n    tile_sense_mic_sleep: () => ({ nextState: { asleep: 1 } }),\n    tile_sense_mic_wake: () => ({ nextState: { asleep: 0 } }),\n    tile_sense_mic_reset: () => ({ nextState: { asleep: 0 } }),\n\n    // ── config ──\n    tile_sense_mic_set_reference: ({ args }) => {\n      const ref = pick(args, 0, 0);\n      // VDD (0/1) → 3300 mV; internal/buffered (2/3) → 2048 mV.\n      const vref = ref === 0x02 || ref === 0x03 ? 2048 : 3300;\n      return { nextState: { ref_sel: ref, vref_mv: vref } };\n    },\n    tile_sense_mic_set_channel: ({ args }) => ({ nextState: { channel: pick(args, 0, 0) } }),\n    tile_sense_mic_set_scan_mode: ({ args }) => ({ nextState: { scan: pick(args, 0, 0) } }),\n    tile_sense_mic_set_clock_mode: ({ args }) => ({ nextState: { clock_sel: pick(args, 0, 0) } }),\n    tile_sense_mic_set_polarity: ({ args }) => ({\n      nextState: { polarity: pick(args, 0, 0) ? 1 : 0 },\n    }),\n    tile_sense_mic_get_vref_mv: ({ state }) => ({ scalar: state.vref_mv }),\n\n    // ── data ──\n    tile_sense_mic_get_raw: ({ state }) => ({ scalar: rawSample(state) }),\n    tile_sense_mic_get_raw_mv: ({ state }) => ({ scalar: toMv(state, rawSample(state)) }),\n    tile_sense_mic_get_audio_sample: ({ state }) => ({ scalar: rmsCounts(state) }),\n    tile_sense_mic_get_dc_offset: () => ({ scalar: dcOffset() }),\n    tile_sense_mic_calibrate: () => ({ scalar: dcOffset() }),\n    tile_sense_mic_get_samples: ({ state }) => {\n      // A few modeled samples around the bias point (one cycle's worth).\n      const dc = dcOffset();\n      const a = rmsCounts(state);\n      return { array: [dc + a, dc, dc - a, dc, dc + a, dc, dc - a, dc] };\n    },\n\n    // ── pure-compute helpers (modeled from the level) ──\n    tile_sense_mic_dc_level: () => ({ scalar: dcOffset() }),\n    tile_sense_mic_peak_to_peak: ({ state }) => ({\n      scalar: clamp(Math.round(2 * Math.SQRT2 * rmsCounts(state)), 0, ADC_FULL - 1),\n    }),\n    tile_sense_mic_rms: ({ state }) => ({ scalar: rmsCounts(state) }),\n    tile_sense_mic_amplitude_mv: ({ state }) => ({\n      scalar: Math.min(Math.round(adcVrmsMv(state)), state.vref_mv / 2),\n    }),\n\n    // ── tier-2 SPL / events (0.1 dB units) ──\n    tile_sense_mic_read_spl_db: ({ state }) => ({\n      scalar: state.asleep ? 300 : Math.round(state.sound_level * 10),\n    }),\n    tile_sense_mic_is_loud: ({ state, args }) => ({\n      scalar: !state.asleep && state.sound_level * 10 > pick(args, 0, 700) ? 1 : 0,\n    }),\n    tile_sense_mic_wait_for_sound: ({ state, args }) => ({\n      scalar: !state.asleep && state.sound_level * 10 > pick(args, 0, 700) ? 1 : 0,\n    }),\n    tile_sense_mic_detect_clap: ({ state }) => ({\n      scalar: !state.asleep && state.sound_level > 85 ? 1 : 0,\n    }),\n  },\n\n  provenance: {\n    tile_sense_mic_find: 'canonical', // MAX11645 I2C 0x36\n    tile_sense_mic_get_vref_mv: 'canonical', // 3300 VDD / 2048 internal\n    tile_sense_mic_set_reference: 'canonical', // SETUP byte ref bits\n    tile_sense_mic_get_raw: 'canonical', // 12-bit ADC sample\n    tile_sense_mic_get_raw_mv: 'canonical', // raw·vref/4096\n    tile_sense_mic_get_dc_offset: 'canonical',\n    tile_sense_mic_dc_level: 'canonical',\n    // inferred — modeled from the driven sound level + the 48× analog chain\n    tile_sense_mic_get_audio_sample: 'inferred',\n    tile_sense_mic_get_samples: 'inferred',\n    tile_sense_mic_peak_to_peak: 'inferred',\n    tile_sense_mic_rms: 'inferred',\n    tile_sense_mic_amplitude_mv: 'inferred',\n    tile_sense_mic_read_spl_db: 'inferred', // gain-corrected mic-sensitivity model\n    tile_sense_mic_is_loud: 'inferred',\n    tile_sense_mic_wait_for_sound: 'inferred',\n    tile_sense_mic_detect_clap: 'inferred',\n    tile_sense_mic_calibrate: 'inferred',\n    power: 'inferred', // datasheet typicals; AD8605 + mic + ADC summed estimate\n  },\n\n  // Pad 8 (per schematic): the amplified analog output (mic ×48, DC-biased),\n  // tapped alongside the ADC's AIN0. Emitted as a millivolt level under \"AOUT\"\n  // so it tracks whatever pad the JSON maps that net to (pad 6 today, pad 8 once\n  // the DB is reconciled). I2C is the bus on pads 4/5.\n  padOutputs(state) {\n    return { AOUT: toMv(state, rawSample(state)) };\n  },\n\n  // Electrical: a pure load on V+ (pad 10) / GND (pad 1). The AD8605 (~1 mA) and\n  // mic (~250 µA) run continuously; the MAX11645 adds ~750 µA active and drops to\n  // ~0.5 µA in shutdown — so sleep only trims the ADC, the analog front-end stays\n  // on. Figures are datasheet typicals (estimate), hence power = inferred.\n  power(state) {\n    const adc = state.asleep ? 1 : 750; // µA\n    const ua = 250 /* mic */ + 1000 /* AD8605 */ + adc;\n    return {\n      draw_ua: ua,\n      rails: [\n        {\n          name: 'V+',\n          role: 'supply',\n          v_mv: 3300,\n          i_ua: ua,\n          pads: ['10'],\n          note: state.asleep ? 'ADC shutdown; mic+amp still on' : 'mic + AD8605 + ADC active',\n        },\n      ],\n    };\n  },\n};\n\nexport default sim;\n",
    "status": "validated",
    "updated_at": "2026-06-22T12:44:21.678Z"
  },
  "config": {
    "analogOut": {
      "kind": "boolean",
      "group": "Sidebands",
      "label": "Use AOUT analog output",
      "binding": {
        "pad": "6",
        "kind": "output"
      },
      "default": false,
      "options": [
        {
          "value": false,
          "firmware_contract": [
            {
              "via": "i2c",
              "type": "register",
              "value": "disabled",
              "register": "AOUT_EN"
            }
          ]
        },
        {
          "value": true,
          "netlist": {
            "expects": [
              {
                "to": {
                  "kind": "matchFunction",
                  "function": "ADC",
                  "capabilities": [
                    "analog-input"
                  ]
                },
                "tag": "analogOut.attached",
                "from": {
                  "pad": "6",
                  "kind": "tile"
                },
                "role": "data"
              }
            ]
          },
          "firmware_contract": [
            {
              "via": "i2c",
              "type": "register",
              "value": "enabled",
              "register": "AOUT_EN"
            }
          ]
        }
      ],
      "description": "Pad 6 carries the chip's filtered analog audio output. Opt in to read it via a Core ADC pad in addition to the I2C digital path."
    }
  }
}