# kdrv

The chip drivers of the Kode Dot: one per part, what each one hides, how the register tables work, and which page documents each chip.

## What it is

kdrv is the layer that knows the chips. Each driver speaks to one part: it
knows its address, its registers and its traps, and nothing about when the
part should be used. That decision belongs to the part's owner, an Active
Object in kaos. A driver is the only place in the SDK where a part number
appears, so swapping a chip touches one file and the board description.

A driver page in this section is the whole story of a part: what the chip is,
how the Kode Dot wires it, its registers, and how the driver is built over
them. The Kode Dot pages (`device/overview`) say what a part does for your
app; these pages say how it works underneath.

## How it is connected

```mermaid
flowchart TB
  ao["kaos<br/>the owner AO"] -- "function call" --> drv["kdrv<br/>the driver"]
  subgraph below["Below the driver"]
    khal["khal"]
    kbsp["kbsp"]
    idf["ESP-IDF components"]
  end
  drv -- "khal_i2c, khal_gpio, ..." --> khal
  drv -. "addresses, pins" .-> kbsp
  drv -- "esp_lcd, esp_hosted, ..." --> idf
  class ao ao
```

*Where kdrv sits*

### Calls in and out

A driver is called by exactly one Active Object, the part's owner, and calls
down into khal for the shared services: the I2C bus, GPIO, time. Its address
and pins come from kbsp as named constants; a driver never writes a pin
number itself. Where Espressif or the chip vendor publishes a component, kdrv
wraps it instead of rewriting it: the CO5300 panel through `esp_lcd_co5300`,
the ES8311 codec through `esp_codec_dev`, the radio link through
`esp_hosted`. Those versions are pinned exactly in the layer's
`idf_component.yml`, because the numbers the drivers check were measured
against them.

**Public headers speak `kode_status_t`.** No `esp_err_t`, no ESP-IDF type
crosses a kdrv header, which is what keeps ESP-IDF out of every layer above.

### Register maps

**Register maps are tables.** For the parts with a register map worth
reading (the BQ25896, the CW2217, the TCA6408A, the CST820, the ES8311, the
AW86233, the ST25R3916B, the ESP32-C5's status and the microSD card), every
field the datasheet names is one row: register, bit position, width, scale,
range, and whether it is writable.

- Two calls, `get` and `set`, read and write any field in its own unit,
  millivolts or milliamps rather than raw codes.
- A `set` writes only the field's bits. The charger, gauge, expander, touch
  and codec tables then read the register back, so a write the chip did not
  keep fails at once.
- The ESP32-C5 table is read-only. The microSD table reads the card, and its
  two writable rows set the bus width and clock the next mount asks for.
- The console prints the same tables, so `pmic`, `ioexp`, `tp`, `audio` and
  `haptic` show every field of their chip.
- What a table cannot say, a burst read or a register that clears when read,
  gets a typed call of its own.

### Layout

Each module has `include/` for its public header
and `src/` for its code. Every `include/` is on the include path, so code
writes `#include "kdrv_bq25896.h"` and never names the folder.

## The parts

Every module of the layer, the chip or job it covers, and the page that documents it.

| Module | Chip or job | Page |
| --- | --- | --- |
| `power` | BQ25896 charger and power path | `sdk/kdrv/bq25896` |
| `power` | CW2217 fuel gauge | `sdk/kdrv/cw2217` |
| `tca6408a` | TCA6408A I/O expander | `sdk/kdrv/tca6408a` |
| `led` | KTD2026 RGB LED driver | `sdk/kdrv/ktd2026` |
| `buttons` | The D-pad and the side buttons | `sdk/kdrv/buttons` |
| `clocks` | The 40 MHz and 32.768 kHz crystals | `sdk/kdrv/clocks` |
| `display` | CO5300 AMOLED panel over MIPI-DSI | `sdk/kdrv/co5300` |
| `cst820` | CST820 touch controller | `sdk/kdrv/cst820` |
| `audio` | ES8311 codec, speaker amplifier and microphone | `sdk/kdrv/es8311` |
| `motion` | QMI8658A IMU | `sdk/kdrv/qmi8658a` |
| `motion` | QMC5883P magnetometer | `sdk/kdrv/qmc5883p` |
| `motion` | AW86233 haptic driver and its motor | `sdk/kdrv/aw86233` |
| `radio` | ESP32-C5 radio coprocessor and its link | `sdk/kdrv/c5` |
| `radio` | Wi-Fi, Bluetooth and the network stack over the link | `sdk/kdrv/radio` |
| `nfc` | ST25R3916B NFC reader and card emulation | `sdk/kdrv/st25r3916` |
| `rfid` | The 125 kHz front end | `sdk/kdrv/rfid` |
| `ir` | Infrared, served by the ESP32-C5 | `sdk/kdrv/ir` |
| `storage` | microSD slot and the internal FAT | `sdk/kdrv/storage` |
| `apps` | The apps region of the flash and the image format | `sdk/kdrv/apps` |
| `mirror` | Hardware JPEG and the screen mirror | `sdk/kdrv/mirror` |
| `ov5640`, `station` | The E5 station's camera on J3, its relays, its ADC and the pads loop, built with `KODE_TEST_DOT` | `sdk/kaos/test-dot` |

## In the SDK

- [`components/kdrv`](https://github.com/kodediy/kode-sdk/tree/main/components/kdrv): one folder per module.
- [`components/kdrv/idf_component.yml`](https://github.com/kodediy/kode-sdk/blob/main/components/kdrv/idf_component.yml): the pinned components the drivers wrap.
