Post Go back to editing

Rasp Pi SPI Initial Settings

Thread Summary

The user was unable to establish SPI communication with an ADAU1467 DSP on a Raspberry Pi. The solution involved using SPI mode 0 or 3, ensuring the correct pin connections on J1 (slave control port), and toggling the CS line to switch from I2C to SPI mode. The user also confirmed that a readback cell can be used to monitor the status of a logic gate in the DSP flow.
AI Generated Content
Category: Software
Product Number: ADAU1467
Software Version: 4.7

I am doing initial interface to a R-pi using J1 on the board.  MISO, SS, MOSI, and SCLK are all verified.  Can't seem to establish com with the board and read the registers. Couple questions.

1) Do I need to buffer the SS line with the Pi?

2) Do I need to change the DIP or boot switches on the board?

3) Are there any configuration options in SS that need to be changed/set for these lines?

Any reference examples would be appreciated.  

Thanks!

 

Parents
  • Disregard that code, that was an I2C test that I have not yet run... Here is the SPI test....

    #!/usr/bin/env python3
    """
    Test ADAU1467 hardware register read/write
    Based on DaveThib's advice from Analog Devices forum
    """
    import spidev
    import time
    import RPi.GPIO as GPIO

    RESET_PIN = 26

    class ADAU1467:
    def __init__(self):
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(RESET_PIN, GPIO.OUT, initial=GPIO.HIGH)

    self.spi = spidev.SpiDev()
    self.spi.open(0, 0)
    self.spi.max_speed_hz = 1000000
    self.spi.mode = 0
    time.sleep(0.1)

    def write_register_16bit(self, addr, value):
    """Write 16-bit value to hardware register"""
    addr_high = (addr >> 8) & 0xFF
    addr_low = addr & 0xFF
    val_high = (value >> 8) & 0xFF
    val_low = value & 0xFF

    packet = [addr_high, addr_low, val_high, val_low]
    self.spi.xfer2(packet)
    time.sleep(0.01)

    def read_register_16bit(self, addr):
    """Read 16-bit value from hardware register"""
    addr_high = ((addr >> 8) & 0xFF) | 0x01 # Set read bit
    addr_low = addr & 0xFF

    packet = [addr_high, addr_low, 0x00, 0x00]
    result = self.spi.xfer2(packet)

    # Return 16-bit value from bytes 2 and 3
    return (result[2] << 8) | result[3]

    def close(self):
    self.spi.close()
    GPIO.cleanup()

    # Test as Dave suggested
    print("=" * 60)
    print("ADAU1467 Hardware Register Test")
    print("Testing register 0xF026 (Clock Gen 3 Input Reference)")
    print("=" * 60)

    CLOCK_REG = 0xF026

    dsp = ADAU1467()

    # Step 1: Read default value
    print("\nStep 1: Read default value")
    default = dsp.read_register_16bit(CLOCK_REG)
    print(f" Register 0xF026 = 0x{default:04X} (expected 0x000E)")

    # Step 2: Write new value
    new_value = 0x0005 # Valid 5-bit value
    print(f"\nStep 2: Write new value 0x{new_value:04X}")
    dsp.write_register_16bit(CLOCK_REG, new_value)
    time.sleep(0.05)

    # Step 3: Read back
    verify = dsp.read_register_16bit(CLOCK_REG)
    print(f" Read back: 0x{verify:04X}")

    if verify == new_value:
    print("\n✓✓✓ SUCCESS! Hardware register write works!")
    else:
    print(f"\n✗ Failed (expected 0x{new_value:04X}, got 0x{verify:04X})")

    dsp.close()
    print("=" * 60)

    ****And the result....****

    ============================================================
    ADAU1467 Hardware Register Test
    Testing register 0xF026 (Clock Gen 3 Input Reference)
    ============================================================

    Step 1: Read default value
    Register 0xF026 = 0x00DD (expected 0x000E)

    Step 2: Write new value 0x0005
    Read back: 0x00DD

    ✗ Failed (expected 0x0005, got 0x00DD)
    ============================================================

  • Hello ElsaDog,

    Please note that when the DSP is powered on or comes out of reset, by default the slave control port will be an I2C port, so you have to put it in SPI mode to read/write via SPI.

    Please add this code snippet and try again.

    If it still doesn't work, please attach your hardware schematic and probe the SPI port and send us the scope shots.

    Regards,

    Harish

  • Great, thank you!  I am still working on SPI, can you sent me a quick diagram to validate pin connections, there are many variations I see out there, some with pins shorted, others not.  So to control via J1 using SPI, can you validate those connections and series resistors.  Also, I am doing some programming and have a question, can I read the status of a logic gate that is working as an OR gate in the flow? I do not see a reference to that gate in my export XML file.  If I cannot, do I insert a readback and poll it, or......  Thanks again!

  • Hello ElsaDog,

    Please follow the connections like below.

    uP/uC                           DSP (port J1)

    CS/SS ------------------> SS (9th pin)

    SCLK -------------------> SCLK (7th pin)

    MOSI -------------------> MOSI (8th pin)

    MISO<------------------- -MISO (5th pin)

    GND <---------------------GND (10th pin)

    The board already has a 10K pull up in the SS line.

    Also, I am doing some programming and have a question, can I read the status of a logic gate that is working as an OR gate in the flow? I do not see a reference to that gate in my export XML file.  If I cannot, do I insert a readback and poll it, or......  Thanks again!

    Yes, you can insert a readback cell and read the address of the readback cell from the exported files to know result/output of the logic gate.

    Regards,

    Harish

  • Thanks Harish, I have copied exactly.  I will explain my set up and see if you have any ideas.  I have two PIs so I can rule out any issue with HW.  I can reliably connect on a self booted board with I2C after a power reset (probably on board reset works too, but have not tried that yet.)  I read from David that you had to toggle the interface on SPI three times on the CS line to get the interface into SPI mode.  I did the exact sequence to connect to SPI as I did for I2C - power down board, connect SPI header on J1 wired as per your instructions, and cycled the CS line on a known register that I am consistently reading in I2C.  I do not seem to be able to get the interface to convert to SPI.  Attached find the sample python code and let me know if you see something obvious out of line.  I have monitored the lines with a scope, and I can see activity.  Thanks again for your help!!

    #!/usr/bin/env python3
    import spidev
    import time

    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 400000
    spi.mode = 1

    print("=" * 70)
    print("SPI Mode Switch + Mix Read (4 toggles)")
    print("=" * 70)

    MIX_ADDR = 1535
    addr_high = (MIX_ADDR >> 8) & 0xFF # 0x05
    addr_low = MIX_ADDR & 0xFF # 0xFF

    print("\n1. Toggle CS 4 times (I2C → SPI mode switch):")
    for i in range(4):
    result = spi.xfer2([0x00, 0x00, 0x00, 0x00])
    print(f" Toggle {i+1}: {' '.join(f'{b:02X}' for b in result)}")
    time.sleep(0.05)

    time.sleep(0.2)

    print("\n2. Read Mix Index (0x05FF):")
    result = spi.xfer2([0x01, addr_high, addr_low, 0x00, 0x00, 0x00, 0x00])
    print(f" Result: {' '.join(f'0x{b:02X}' for b in result)}")

    data_bytes = result[3:7]
    print(f" Data bytes: {' '.join(f'0x{b:02X}' for b in data_bytes)}")

    mix_value = data_bytes[3]
    if mix_value == 0x12:
    print(f" ✓✓✓ SPI WORKS! Reading Mix 2 (0x12)")
    elif mix_value in [0, 9, 18, 27, 36, 45]:
    print(f" ✓ Got mix value: {mix_value}")
    else:
    print(f" Value: {mix_value}")

    spi.close()

    Return values on program:

    cactus2@CACTUSPI:~ $ sudo python3 /home/cactus2/test_spi_mix_4toggle.py
    ======================================================================
    SPI Mode Switch + Mix Read (4 toggles)
    ======================================================================

    1. Toggle CS 4 times (I2C → SPI mode switch):
    Toggle 1: FF FF FF FF
    Toggle 2: FF FF FF FF
    Toggle 3: FF FF FF FF
    Toggle 4: FF FF FF FF

    2. Read Mix Index (0x05FF):
    Result: 0xFF 0xFF 0xFE 0x00 0x00 0x00 0x00
    Data bytes: 0x00 0x00 0x00 0x00
    ✓ Got mix value: 0

  • Hello ElsaDog,

    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 400000
    spi.mode = 1

    I have quickly noticed in your latest reply that it seems you use SPI mode 1, if you are then please note that the slave control port won't work with SPI mode 1,2.

    You should either use SPI mode 0 or 3. The datasheet says to use SPI mode 3, however SPI mode 0 also works fine. please make sure that you are using correct SPI mode.

    Regards,

    Harish

  • Fantastic, Harish!

    Mode 0 is working perfectly,  I was polling an audio router and finally got the data syntax correct.  I appreciate your incredible support!  

  • Is there a way to change the address in SS?  I am getting a strange condition on a readback that constantly shows a 1 in self boot mode, but when I go to SS studio linked, I see it toggle normally.  I added another readback with a different address, and got exactly the same result.  I am connecting via SPI in self boot mode, and other registers in the program are running just fine.  I have two readbacks that are looking at the same circuit reading from two different inputs, so everything is the same except that one shows a stuck 1 and the other toggles when reading from SPI in self boot.  Any ideas?

  • Also, Harish, I would like to put together a thread that could be used to help others with connecting.  I have learned a few things that would be a good thread to help people get off the ground controlling with either I2C or SPI.  Is there a way I should post such a topic or should I just upload it all here or??

    Thanks!

  • And just to add a bit more detail. I deployed additional switches into the workflow and am no able to write to them.  They are simple switches.  I have four of them, two I can write to, the other two I cannot.  It is not intermittent behavior as it is consistent the two that are working and the two that are not.  I also noticed that when I recompiled the project, it changed some original register address index.  So I found a switch had moved from 1487 to 1501.  Can you point me in a direction to better understand now to manage register assignments and what might be causing the same element to either work or not work in the same flow? 

  • Hello ElsaDog,

    Can you please attach your project or screenshot of your schematic?

    So I found a switch had moved from 1487 to 1501

    Yes, the parameter address may change each time you compile the project, if you want a fixed address then you can try IPAT here.

    what might be causing the same element to either work or not work in the same flow? 

    which is kind of strange, if the SPI connection is stable then it should work for every parameter and every time.

    Can you probe and see what's on the SPI line?

    Regards,

    Harish

  • Hello ElsaDog,

    Thanks for your contribution to the forum.

    You can create a new page (add a page to doc) and post your findings. we will acknowledge it.

    Regards,

    Harish

Reply Children
No Data