Class: SPI::LinuxSPIdev

Inherits:
Object
  • Object
show all
Defined in:
lib/mruby/spi.rb

Overview

Linux SPI Device driver

Constant Summary collapse

IOC_NONE =

Constants see: /usr/include/linux/spi/spidev.h, /usr/include/asm-generic/ioctl.h

0
IOC_WRITE =
1
IOC_READ =
2
SPI_IOC_MAGIC =
'k'.ord
SPI_IOC_RD_MODE =

Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) (limited to 8 bits) define SPI_IOC_RD_MODE _IOR(SPI_IOC_MAGIC, 1, __u8) define SPI_IOC_WR_MODE _IOW(SPI_IOC_MAGIC, 1, __u8)

_IOx( type, nr, size ) is bit mapped [RW][size:14][type:8][nr:8]
                        dir             | size    | type               | nr
IOC_READ  << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 1
SPI_IOC_WR_MODE =
IOC_WRITE << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 1
SPI_IOC_RD_LSB_FIRST =

Read / Write SPI bit justification define SPI_IOC_RD_LSB_FIRST _IOR(SPI_IOC_MAGIC, 2, __u8) define SPI_IOC_WR_LSB_FIRST _IOW(SPI_IOC_MAGIC, 2, __u8)

dir             | size    | type               | nr
IOC_READ  << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 2
SPI_IOC_WR_LSB_FIRST =
IOC_WRITE << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 2
SPI_IOC_RD_BITS_PER_WORD =

Read / Write SPI device word length (1..N) define SPI_IOC_RD_BITS_PER_WORD _IOR(SPI_IOC_MAGIC, 3, __u8) define SPI_IOC_WR_BITS_PER_WORD _IOW(SPI_IOC_MAGIC, 3, __u8)

dir             | size    | type               | nr
IOC_READ  << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 3
SPI_IOC_WR_BITS_PER_WORD =
IOC_WRITE << 30 | 1 << 16 | SPI_IOC_MAGIC << 8 | 3
SPI_IOC_RD_MAX_SPEED_HZ =

Read / Write SPI device default max speed hz define SPI_IOC_RD_MAX_SPEED_HZ _IOR(SPI_IOC_MAGIC, 4, __u32) define SPI_IOC_WR_MAX_SPEED_HZ _IOW(SPI_IOC_MAGIC, 4, __u32)

dir             | size    | type               | nr
IOC_READ  << 30 | 4 << 16 | SPI_IOC_MAGIC << 8 | 4
SPI_IOC_WR_MAX_SPEED_HZ =
IOC_WRITE << 30 | 4 << 16 | SPI_IOC_MAGIC << 8 | 4
SPI_IOC_MESSAGE =

define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char)

char[SPI_MSGSIZE(1) is 32 bytes.
NOTE: struct layout is the same in 64bit and 32bit userspace.
                        dir             | size    | type               | nr
IOC_WRITE << 30 |32 << 16 | SPI_IOC_MAGIC << 8 | 0

Instance Method Summary collapse

Constructor Details

#initialize(node, frequency, mode, first_bit) ⇒ LinuxSPIdev

constructor

Parameters:

  • node (String)

    device node of SPI

  • frequency (Integer)

    SCLK frequency.

  • mode (Integer)

    SPI mode (0..3)

  • first_bit (Constant)

    MSB_FIRST or LSB_FIRST

See Also:



91
92
93
94
95
96
97
# File 'lib/mruby/spi.rb', line 91

def initialize(node, frequency, mode, first_bit)
  @device = File.open(node, "r+:ASCII-8BIT")

  _set_max_speed_hz( frequency )
  _set_mode( mode )
  _set_lsb_first( first_bit )
end

Instance Method Details

#read(read_bytes) ⇒ String

Reads data of read_bytes bytes from the SPI bus.

Parameters:

  • read_bytes (Integer)

    read bytes.

Returns:

  • (String)

    reading datas.



119
120
121
# File 'lib/mruby/spi.rb', line 119

def read( read_bytes )
  @device.sysread( read_bytes )
end

#setmode(frequency: nil, mode: nil) ⇒ void

This method returns an undefined value.

Changes the operating mode (parameters) of the SPI.

Parameters:

  • frequency (Integer) (defaults to: nil)

    SCLK frequency.

  • mode (Integer) (defaults to: nil)

    SPI mode (0..3)



107
108
109
110
# File 'lib/mruby/spi.rb', line 107

def setmode( frequency:nil, mode:nil )
  _set_max_speed_hz( frequency )  if frequency
  _set_mode( mode )  if mode
end

#transfer(outputs, additional_read_bytes = 0) ⇒ String

Outputs data specified in outputs to the SPI bus while simultaneously reading data (General-purpose transfer).

Parameters:

  • outputs (Integer, String, Array<Integer>)

    output data.

  • additional_read_bytes (Integer) (defaults to: 0)

    additional read bytes

Returns:

  • (String)

    reading datas.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/mruby/spi.rb', line 145

def transfer( outputs, additional_read_bytes = 0 )

  # prepare the send buffer and receive buffer.
  send_data = _rebuild_output_data( [outputs] )
  len = send_data.size
  if additional_read_bytes > 0
    send_data << ("\x00".b * additional_read_bytes)
    len += additional_read_bytes
  end
  recv_data = "\x00".b * len

  # prepare the struct spi_ioc_transfer. (spidev.h)
  arg = [ [send_data].pack("P").unpack1("J"), # __u64           tx_buf;
          [recv_data].pack("P").unpack1("J"), # __u64           rx_buf;

          len,        # __u32           len;
          0,          # __u32           speed_hz;

          0,          # __u16           delay_usecs;
          0,          # __u8            bits_per_word;
          0,          # __u8            cs_change;
          0,          # __u8            tx_nbits;
          0,          # __u8            rx_nbits;
          0,          # __u8            word_delay_usecs;
          0,          # __u8            pad;
        ].pack("QQLLSCCCCCC")

  # trigger IOCTL.
  @device.ioctl( SPI_IOC_MESSAGE, arg )
  return recv_data
end

#write(*outputs) ⇒ nil

Outputs data specified in outputs to the SPI bus.

Parameters:

  • outputs (Integer, String, Array<Integer>)

    output data.

Returns:

  • (nil)


130
131
132
133
134
# File 'lib/mruby/spi.rb', line 130

def write( *outputs )
  send_data = _rebuild_output_data( outputs )
  @device.syswrite( send_data )
  return nil
end