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

  • OK,. I have managed to get I2C working on J1, Master Header, by shorting pins 1-7 and 3-5.  I can now read and write registers! 

    1) Can you advise on if I can move this to the slave port?  so far no luck on that interface. 

    2) I still would like to get SPI working, but will fight that more, but should I be able to control this with my Pi on J6 and leave the master open for Sigma Studio program changes?  That workflow would be best for me.

    3) When I disconnect SS, and reset and reestablish com with the DSP, will my existing program continue to run?  Do I need to do any configuration with Self Boot to run the SS program and simply read and write registers with the controller?

    Thanks for your help!

  • I hope you read this one, first!  I have the self boot issue figured out, so now I only need to see if I can get I2C working on the Peripheral Control Port, and hopefully move to SPI.  So if you could please help me with question 1 and 2 from previous post.  Thanks!!

  • Hello ElsaDog,

    I think you have been using the wrong port, if you want to communicate with the DSP from your uC/uP/USBi, you must use the slave control port. It's always slave and only it allows the uC/uP/SS to program, read/write the DSP.

    The master control port (named as peripheral port in the eval board) is always master, it is used to program the self-boot EEPROM, program ADC/DAC, SPI flash etc.

    So, you have to use the port J1 (slave control port) in order to program the DSP.

    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!

Reply Children