drivers.Epaper.Epdconfig.Epdconfig

class drivers.Epaper.Epdconfig.Epdconfig

Hardware abstraction over RPi.GPIO and spidev for an e-paper module.

Owns the SPI device handle and exposes thin wrappers around the GPIO and SPI calls that drivers.Epaper.EPD.EPD needs. The pin map and SPI parameters mirror Waveshare’s reference firmware so that any compatible panel works without modification.

Variables:
  • RST_PIN (int) – BCM GPIO number for the panel RST line (17).

  • DC_PIN (int) – BCM GPIO number for the data/command DC line (25).

  • CS_PIN (int) – BCM GPIO number for the SPI CS line (8).

  • BUSY_PIN (int) – BCM GPIO number for the panel BUSY line (24).

  • GPIO (module) – Reference to the imported RPi.GPIO module.

  • SPI (spidev.SpiDev) – Handle to /dev/spidev0.0.

Example

>>> from drivers.Epaper.Epdconfig import Epdconfig
>>> cfg = Epdconfig()
>>> cfg.RST_PIN, cfg.DC_PIN, cfg.CS_PIN, cfg.BUSY_PIN
(17, 25, 8, 24)

Import RPi.GPIO and open the SPI device handle (bus 0, device 0).

Lazily imports RPi.GPIO and spidev inside the constructor so that the module can be imported on non-Pi hosts without immediately failing. The SPI handle is opened but not yet configured; call module_init() to set the mode and clock speed.

Parameters:

None.

Returns:

None.

Raises:
  • ModuleNotFoundError – If RPi.GPIO or spidev is not installed on the host.

  • FileNotFoundError – If /dev/spidev0.0 does not exist (the SPI driver is disabled in raspi-config).

  • PermissionError – If the calling user does not have access to the SPI or GPIO device nodes.

Example

>>> from drivers.Epaper.Epdconfig import Epdconfig
>>> cfg = Epdconfig()

Note

One Epdconfig instance is shared as a class attribute on drivers.Epaper.EPD.EPD, so creating additional instances is rarely necessary.

delay_ms(delaytime)

Block the current thread for a fixed number of milliseconds.

Thin wrapper around time.sleep() that converts milliseconds to seconds.

Parameters:

delaytime (int | float) – Delay duration in milliseconds.

Returns:

None.

Raises:

ValueError – If delaytime is negative.

Example

>>> cfg = Epdconfig()
>>> cfg.delay_ms(100)  # sleep 100 ms

Note

Used by the EPD driver around reset pulses and between busy polls; not suitable for sub-millisecond timing.

digital_read(pin)

Sample the current logic level of a GPIO pin.

Parameters:

pin (int) – BCM GPIO pin number. Must have been configured as an input via module_init().

Returns:

1 if the pin is HIGH, 0 if LOW.

Return type:

int

Raises:

RuntimeError – From RPi.GPIO if pin is not configured as an input.

Example

>>> cfg = Epdconfig()
>>> cfg.module_init()
>>> level = cfg.digital_read(cfg.BUSY_PIN)

Note

On this panel the BUSY line is active-low: 0 means the controller is processing a command, 1 means it is idle.

digital_write(pin, value)

Drive a GPIO pin to a HIGH or LOW logic level.

Parameters:
  • pin (int) – BCM GPIO pin number. Must have been configured as an output via module_init().

  • value (int | bool) – Output level. 1/True drives HIGH, 0/False drives LOW.

Returns:

None.

Raises:

RuntimeError – From RPi.GPIO if pin is not configured as an output.

Example

>>> cfg = Epdconfig()
>>> cfg.module_init()
>>> cfg.digital_write(cfg.RST_PIN, 0)

Note

Used by the EPD driver to bit-bang RST, DC, and CS around SPI transfers.

module_exit()

Close the SPI handle, force the panel idle, and run GPIO cleanup.

Logs "spi end" at debug level and closes SPI, then drives RST_PIN and DC_PIN low (per the Waveshare reference sequence for "close 5V, Module enters 0 power consumption") and calls GPIO.cleanup().

Parameters:

None.

Returns:

None.

Raises:

OSError – If the spidev handle is already closed when close() is invoked again.

Example

>>> cfg = Epdconfig()
>>> cfg.module_init()
>>> cfg.module_exit()

Note

After module_exit the panel must be re-initialized via module_init() (and a fresh EPD.init()) before any further I/O is attempted.

module_init()

Configure GPIO direction, SPI mode, and SPI clock speed.

Sets BCM pin numbering, disables RPi.GPIO warnings, and configures RST_PIN, DC_PIN, CS_PIN as outputs and BUSY_PIN as an input. Sets the SPI bus to max_speed_hz = 1_240_000 and mode = 0b00.

Parameters:

None.

Returns:

0 on success. The signature returns an int so the EPD driver can branch on the result (see EPD.init()).

Return type:

int

Raises:

RuntimeError – From RPi.GPIO if the host is not a Raspberry Pi or if pins are claimed by another process.

Example

>>> cfg = Epdconfig()
>>> cfg.module_init()
0

Note

Always pair with module_exit() to release peripherals. Re-running module_init after module_exit() is safe.

spi_writebyte(data)

Transmit a list of bytes over SPI using spidev.writebytes.

Parameters:

data (list[int]) – Bytes to send, each in the range 0..255. The CS line is managed by the SPI peripheral.

Returns:

None.

Raises:
  • OSError – If the SPI transfer fails (e.g. device closed).

  • TypeError – If data contains non-integer entries.

Example

>>> cfg = Epdconfig()
>>> cfg.module_init()
>>> cfg.spi_writebyte([0x9F])

Note

writebytes is unbuffered; for large payloads prefer spi_writebyte2().

spi_writebyte2(data)

Transmit a list of bytes over SPI using spidev.writebytes2.

writebytes2 supports arbitrarily long buffers and is faster for full-screen image transmission than spi_writebyte().

Parameters:

data (list[int]) – Bytes to send, each in the range 0..255.

Returns:

None.

Raises:
  • OSError – If the SPI transfer fails.

  • TypeError – If data contains non-integer entries.

Example

>>> cfg = Epdconfig()
>>> cfg.module_init()
>>> cfg.spi_writebyte2([0xFF] * 4736)  # full frame

Note

Currently not used by the EPD driver (which streams the framebuffer byte-by-byte via send_data()), but provided for future optimization.

BUSY_PIN = 24
CS_PIN = 8
DC_PIN = 25
GPIO
RST_PIN = 17
SPI