Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions linuxpy/codegen/spi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.

import pathlib

from linuxpy.codegen.base import CEnum, run

HEADERS = [
"/usr/include/linux/spi/spi.h",
"/usr/include/linux/spi/spidev.h",
]


TEMPLATE = """\
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.

# This file has been generated by {name}
# Date: {date}
# System: {system}
# Release: {release}
# Version: {version}

import enum

from linuxpy.ioctl import IOR as _IOR, IOW as _IOW, IOWR as _IOWR
from linuxpy.ctypes import u8, u16, u32, cuint, cint, cchar, culonglong
from linuxpy.ctypes import Struct, Union, POINTER, cvoidp


{enums_body}


{structs_body}


{iocs_body}"""


class Mode32(CEnum):
def add_item(self, name, value):
if "_BITUL" in value:
value = value.replace("_BITUL(", "").replace(")", "")
value = f"1 << {value}"
super().add_item(name, value)


# macros from #define statements
MACRO_ENUMS = [
CEnum("IOC", "SPI_IOC_"),
Mode32("Mode32", "SPI_", klass="IntFlag", filter=lambda k, v: "MASK" not in k),
]


this_dir = pathlib.Path(__file__).parent


def main(output=this_dir.parent / "spi" / "raw.py"):
run(__name__, HEADERS, TEMPLATE, MACRO_ENUMS, output=output)


if __name__ == "__main__":
main()
5 changes: 5 additions & 0 deletions linuxpy/spi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.
12 changes: 12 additions & 0 deletions linuxpy/spi/device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.


from linuxpy.device import BaseDevice


class Device(BaseDevice):
PREFIX = "/dev/spidev"
74 changes: 74 additions & 0 deletions linuxpy/spi/raw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.

# This file has been generated by __main__
# Date: 2024-10-10 06:46:12.660131
# System: Linux
# Release: 6.8.0-45-generic
# Version: #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024

import enum

from linuxpy.ctypes import Struct, cuint, culonglong, u8, u16, u32
from linuxpy.ioctl import IOR as _IOR, IOW as _IOW


class Mode32(enum.IntFlag):
CPHA = 1 << 0 # clock phase
CPOL = 1 << 1 # clock polarity
MODE_0 = 0 | 0 # (original MicroWire)
MODE_1 = 0 | CPHA
MODE_2 = CPOL | 0
MODE_3 = CPOL | CPHA
CS_HIGH = 1 << 2 # chipselect active high?
LSB_FIRST = 1 << 3 # per-word bits-on-wire
_3WIRE = 1 << 4 # SI/SO signals shared
LOOP = 1 << 5 # loopback mode
NO_CS = 1 << 6 # 1 dev/bus, no chipselect
READY = 1 << 7 # slave pulls low to pause
TX_DUAL = 1 << 8 # transmit with 2 wires
TX_QUAD = 1 << 9 # transmit with 4 wires
RX_DUAL = 1 << 10 # receive with 2 wires
RX_QUAD = 1 << 11 # receive with 4 wires
CS_WORD = 1 << 12 # toggle cs after each word
TX_OCTAL = 1 << 13 # transmit with 8 wires
RX_OCTAL = 1 << 14 # receive with 8 wires
_3WIRE_HIZ = 1 << 15 # high impedance turnaround
RX_CPHA_FLIP = 1 << 16 # flip CPHA on Rx only xfer
MOSI_IDLE_LOW = 1 << 17 # leave mosi line low when idle


class spi_ioc_transfer(Struct):
pass


spi_ioc_transfer._fields_ = [
("tx_buf", culonglong),
("rx_buf", culonglong),
("len", cuint),
("speed_hz", cuint),
("delay_usecs", u16),
("bits_per_word", u8),
("cs_change", u8),
("tx_nbits", u8),
("rx_nbits", u8),
("word_delay_usecs", u8),
("pad", u8),
]


class IOC(enum.IntEnum):
MAGIC = "k"
RD_MODE = _IOR(MAGIC, 1, u8)
WR_MODE = _IOW(MAGIC, 1, u8)
RD_LSB_FIRST = _IOR(MAGIC, 2, u8)
WR_LSB_FIRST = _IOW(MAGIC, 2, u8)
RD_BITS_PER_WORD = _IOR(MAGIC, 3, u8)
WR_BITS_PER_WORD = _IOW(MAGIC, 3, u8)
RD_MAX_SPEED_HZ = _IOR(MAGIC, 4, u32)
WR_MAX_SPEED_HZ = _IOW(MAGIC, 4, u32)
RD_MODE32 = _IOR(MAGIC, 5, u32)
WR_MODE32 = _IOW(MAGIC, 5, u32)