pcote_pi
Posts: 38
Joined: Mon Nov 03, 2014 12:29 am
Location: Montréal

Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Mon Dec 17, 2018 2:39 pm

Hello All,

I am trying to interface with the Ozone2Click sensor and it requires a 3 wire SPI communication.

I am using Java and PI4J library. It seems there is no way out of the box to use the SPI interface in a half duplex/3 wire configuration. The information I found is that the linux kernel can do it.

Is there a way in the config.txt to enable this SPI configuration?? Is there a way in Java/PI4J???

Many thanks in advance

Patrice

AnneRanch
Posts: 99
Joined: Fri Oct 19, 2018 1:48 pm

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Mon Dec 17, 2018 3:31 pm

I hate to post "me too", but here it comes.
You need to get real datasheet for your device.
I am not sure how to implement Linux ioctl in Java, but I am doing it in C++.
In some terminology using ioctl bypasses "driver" by directly working with Linux kernel.

I am finding out that SPI terminology is very inconsistent from vendor to vendor.
3 wire SPI should mean "from master to slave " " from slave to master" "common clock" .
In that scheme "device select AKA CE0/1 " is missing.
Some hardware may not need it.

I started with RPi header / hardware where you have access to two SPI shared devices by enabling appropriate CE. On header it is labelled simply as CE0 / CE1.
In raspi-config setting SPI defaults to Linux /dev/spidev0.0. Since that is actual Linux folder it is another "solid ground" you can build on.
The biggest issue, for me , so far has been that nobody actually reads SPI responses from slave to master.
How they read SD beats me.
Good luck.

User avatar
DougieLawson
Posts: 39124
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Mon Dec 17, 2018 4:54 pm

Three wire SPI means you only connect MISO (master in, slave out). MOSI is left as no connection (NC).
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
joan
Posts: 14936
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Mon Dec 17, 2018 5:44 pm

I'm not sure the Linux SPI drivers support 3-wire operation. 3-wire has to be supported by the underlying hardware. On the Pi only the main SPI supports 3-wire.

Someone else will have to check if the Linux SPI driver supports 3-wire.

My pigpio driver does support 3-wire (via the main SPI hardware).

For instance see http://abyz.me.uk/rpi/pigpio/cif.html#spiOpen

From the command line see http://abyz.me.uk/rpi/pigpio/pigs.html#SPIO

Example Python to read 3-wire MCP4131 (digital pot)

Code: Select all

#!/usr/bin/env python

# mcp4131.py
# 2016-01-06
# Public Domain

import time
import pigpio # http://abyz.me.uk/rpi/pigpio/python.html

INCPOT=0x04
DECPOT=0x08

# 00h Volatile Wiper 0 
#   Write Data 0000 00nn nnnn nnnn
#   Read Data  0000 11nn nnnn nnnn
#   Increment  0000 0100
#   Decrement  0000 1000

# 01h Volatile Wiper 1
#   Write Data 0001 00nn nnnn nnnn
#   Read Data  0001 11nn nnnn nnnn
#   Increment  0001 0100
#   Decrement  0001 1000

# 02h-03h Reserved

# 04h TCON
#   Write Data 0100 00nn nnnn nnnn
#   Read Data  0100 11nn nnnn nnnn

# 05h Status
#   Read Data  0101 11nn nnnn nnnn

# 06h-0Fh Reserved

# SPI open flags

W3=(1<<9) # select 3-wire operation
W3N1=(1<<10) # switch to miso after one byte
U0=(1<<5) # don't set CE0
U1=(1<<6) # don't set CE1

pi = pigpio.pi() # Connect to local Pi.

digpot_write = pi.spi_open(1, 50000) # first SPI open
digpot_read  = pi.spi_open(1,  50000, W3|W3N1) # 3-wire write 1 then read
adc          = pi.spi_open(0, 50000)

inc = True

potpos = 0

try:

   while True:

      pi.spi_write(digpot_write, [0, potpos])

      (b, d) = pi.spi_xfer(digpot_read, [0x0C, 0])
      if b == 2:
         rpos = d[1]
      else:
         rpos = -1

      (b, d) = pi.spi_xfer(adc, [1, 0x80, 0])
      if b == 3:
         c1 = d[1] & 0x0F
         c2 = d[2]
         ch0 = (c1<<8)+c2
      else:
         ch0 = -1

      (b, d) = pi.spi_xfer(adc, [1, 0xC0, 0])
      if b == 3:
         c1 = d[1] & 0x0F
         c2 = d[2]
         ch1 = (c1<<8)+c2
      else:
         ch1 = -1

      print("0={:4d} 1={:4d} pot={} ({})".format(ch0, ch1, potpos, rpos))

      if inc:
         potpos += 1
         if potpos > 129:
            inc = False
            potpos = 129
      else:
         potpos -= 1
         if potpos < 0:
            inc = True
            potpos = 0

      """
      if inc:
         cmd = DECPOT
      else:
         cmd = INCPOT

      (b, d) = pi.spi_xfer(digpot, [cmd])
      if b == 1:
         dp = d[0]
      else:
         dp = -1

      if ch1 > 4090:
         inc = False
      elif ch1 < 10:
         inc = True
      """

      time.sleep(0.05)

except:
   pi.spi_close(digpot_read)
   pi.spi_close(digpot_write)
   pi.spi_close(adc)
   pi.stop()
   print("closed handle and stopped ")

AnneRanch
Posts: 99
Joined: Fri Oct 19, 2018 1:48 pm

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Tue Dec 18, 2018 2:29 am

DougieLawson wrote:
Mon Dec 17, 2018 4:54 pm
Three wire SPI means you only connect MISO (master in, slave out). MOSI is left as no connection (NC).
This is very incomplete and confusing statement.
It is mixing the SPI spec and how it is physically implemented.

If we have true SPI - there are four communicational paths / wires , by definition .
How it is physically used depends on both master and slave.
If you do not need the slave response you do not have to wire it.
If the slave does not have "MISO" ability there is no reason to wire it.

RPi provides full SPI interface , four wires , as master only, including two optional
CE / SS or whatever naming convention is handy to use .


Since SPI is very loosed "standard" , according to some resources not really a defined standard,
it really boils down to how it is implemented in both hardware and software.
Some even use the data wire both ways - hence the MOSI / MISO designation becomes pretty meaningless.

User avatar
DougieLawson
Posts: 39124
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Tue Dec 18, 2018 8:00 am

It a bastardised version of SPI where the master doesn't send data to the slave for an input device. For something like a neopixel you only connect MOSI as the device never sends any data on MISO.
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

pcote_pi
Posts: 38
Joined: Mon Nov 03, 2014 12:29 am
Location: Montréal

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Tue Dec 18, 2018 3:34 pm

Hello,

I have tried to connect only MOSI or MISO. It does not work.

I believe the chip probably needs to be configured to use half duplex i.e talk and listen on the same pin. Not the default configuration.

AnneRanch
Posts: 99
Joined: Fri Oct 19, 2018 1:48 pm

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Tue Dec 18, 2018 4:09 pm

Have you look at this ?

https://www.mikroe.com/ozone-2-click

I did not read it in details , but it appears to have full flown SPI - all 4 wires.
Try to find how to read the device (SPI) ID - that should check both MOSI / MISO path.
My guess would be if the master is full SPI - as RPi is - "duplex" usage if either data wire is unlikely.
But again - that should be stated somewhere in their spec.
Good luck.

AnneRanch
Posts: 99
Joined: Fri Oct 19, 2018 1:48 pm

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Wed Dec 19, 2018 12:53 am

I do not want to muddy the waters , but here is one of the better "Serial Interface " description, taken from ILI9341 datasheet.

"ILI9341 supplies 3-lines/ 9-bit and 4-line/8-bit bi-directional serial interfaces for communication between host
and ILI9341. The 3-line serial mode consists of the chip enable input (CSX), the serial clock input (SCL) and
serial data Input/Output (SDA or SDI/SDO). The 4-line serial mode consists of the Data/Command selection
input (D/CX), chip enable input (CSX), the serial clock input (SCL) and serial data Input/Output (SDA or
SDI/SDO) for data transmission. The data bus (D [17:0]), which are not used, must be connected to GND. Serial
clock (SCL) is used for interface with MCU only, so it can be stopped when no communication is necessary."




As already mentioned - it does not USE SPI terminology - MISO . MOSI etc, but provides similar communication format.

In ILI9341 "switching" between 3 line and 4 line schema is accomplished via "D/Cx" signal.
However, the actual selection of the mode is via "IM" bits which in my case are unknown and programmed in inaccessible hardware.

The actual setting of these IM bits may not be so hard to figure out as soon as I can find a command which will give consistent display response.

Since RPi is SPI standard - no D/C - the display NEEDS to work in 3 -line / 9 bits scheme. I hope it will.


Addendum

This is getting worst by minute.
I am getting some software response using the dreaded "C/D" and 8 bits data transfer.
9 bits did not work at all.
I can turn the LCD off when I just send commands, so now I need to figure out how to read the response.

The "problem " is - I am getting response to command 0x17 - such command is not in datasheet.
Once I get a response it never changes.

I am shooting for command 0x4 which should respond with LCD/TFT ID.
Last edited by AnneRanch on Wed Dec 19, 2018 6:38 pm, edited 1 time in total.

pcote_pi
Posts: 38
Joined: Mon Nov 03, 2014 12:29 am
Location: Montréal

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Wed Dec 19, 2018 3:05 pm

I have checked the datasheet online at https://www.mikroe.com/ozone-2-click and it is in error. The board does not have SDI, it is NC. The MCP3550 chip which is on the board specifies 3-wire SPI.

For this module there is no MOSI or MISO. It is one line called SDO/--RDY--

My only hope at this time might be in Joan's code in Python. I am beginning to think that JAVA and PI4J might not be appropriate to talk to this module since it does not have the libraries to configure the Broadcom PI3 chip.

AnneRanch
Posts: 99
Joined: Fri Oct 19, 2018 1:48 pm

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Wed Dec 19, 2018 6:29 pm

How did you determine the datasheet is wrong?
It shows full SPI on their microBus connector , but it is missing i2c.

User avatar
joan
Posts: 14936
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Wed Dec 19, 2018 8:16 pm

I don't like the use of the phrase 3-wire SPI for the MCP3550. I believe properly speaking 3-wire SPI means both MOSI and MISO are the same pin/wire, so you can both send commands and receive results on the same pin.

The MCP3550 simply does not have a MOSI signal. It is commanded by the CS and SCLK lines. SDO is always an output from the chip.

Anyhow it's not standard SPI. You will have to control the CS line yourself.

It looks like you need the following algorithm.

Code: Select all

while True
   set CS low
   wait for SDO to go low
   perform 24 bit SPI transfer
   set CS high

pcote_pi
Posts: 38
Joined: Mon Nov 03, 2014 12:29 am
Location: Montréal

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Thu Jan 03, 2019 3:37 pm

To respond to the question regarding the validity of the online datasheet.

The online page providing technical details is wrong. Why? because I have the PDF datasheet and the module in my hand. The PDF datasheet does not say the same thing as the web page "datasheet". The PDF datasheet seems to be in accordance with the module.

pcote_pi
Posts: 38
Joined: Mon Nov 03, 2014 12:29 am
Location: Montréal

Re: Enable 3 Wire SPI aka Bidirectional, half duplex SPI

Thu Jan 03, 2019 4:32 pm

To Joan,

I keep the CS pin to GND so the chip continuously converting. I think I can do step 2).

Do you think you can clarify step 3)? I can write on SPI using PI4J using a 3 dimension byte array. But I get no result stored in it.

while True
1) set CS low
2) wait for SDO to go low
3) perform 24 bit SPI transfer
4) set CS high

Return to “Interfacing (DSI, CSI, I2C, etc.)”