Arduino Due Master Programming

Hello everyone. I am making use of Arduino Due to transfer 24-bit data to the slave device (LMX2595) PLL IC. The programming of slave IC is in like MSB first, SPI-Mode0. Below is the code attached. I need to transfer 24-bit register values of about 79 registers to the slave Device. I am literally struggling for the past few months.

Could Anyone help me with the calculation of the clock speed for the data to be transferred at the slave end.

The maximum clock speed for Arduino Due is 84 MHz and for the slave end it is 75MHz.

I am not able to get any output.

Any help with respect to this will be greatly appreciated. Thanks in Advance.

#include <SPI.h>

SPISettings mySettting(4000000, MSBFIRST, SPI_MODE0);
const uint8_t ss = 10;


void setup()
{
  pinMode(ss, OUTPUT);
Serial.begin(9600);
SPI.begin();
SPI.beginTransaction(mySettting);
 
 digitalWrite(ss, LOW);  
  SPI.transfer(0x1C);
  SPI.transfer( 0x25);
  SPI.transfer(0x00);
  delay(1);
  digitalWrite(ss, HIGH);

digitalWrite(ss, LOW);  
  SPI.transfer(0x08);
  SPI.transfer(0x08);
  SPI.transfer(0x01);
  delay(1);
  digitalWrite(ss, HIGH);
digitalWrite(ss, LOW);  
  SPI.transfer(0x00);
  SPI.transfer(0x05);
  SPI.transfer(0x02);
  delay(1);
  digitalWrite(ss, HIGH);
digitalWrite(ss, LOW);  
  SPI.transfer(0x42);
  SPI.transfer(0x06);
  SPI.transfer(0x03);
  delay(1);
  digitalWrite(ss, HIGH);
SPI.endTransaction();
}

void loop() {
}

@vamshi97

Your topic was Moved to it's current location / section as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Could you please post a link to the datasheet of non-Arduino devices? If the chip is on a module please also provide a link to that.

The exact SPI speed is actually not that important. SPI has a clock signal and as long as the speed stays below the limit of the slave and your PCB design you should be fine.

Please also provide a schematic. Hand drawn on paper photo taken with smartphone is fine. No fritzing. :slight_smile: SPI is a PCB level chip to chip protocol. If your SPI bus leaves the PCB please show us a photo of your setup. Just in case you have 5m wires. :slight_smile:

I run your sketch on an Arduino Due. Your code seems to create the signals required by the datasheet. The delays are not necessary at all. They are a complete waste of time. At 4MHz SPI clock a single byte takes 2 microseconds to transmit. A 1ms delay before you raise SS just invites noise into the SPI peripheral and is 100.000 times longer than the minimum time defined in the LMX2595 datasheet.

I assume your example sends 3 transmissions to three different registers. All write operations. The first byte is RW set to 0 plus address and the other two bytes are data? I looked at page 13 of the datasheet and the signals on my oscilloscope looked like that.

The signal is a bit noisy on my board and creates some large over and under voltage at edges. I expect this to be worse with long wires.

Do you have an oscilloscope to look at the signals on your board?

Thanks for the response. But as you mentioned that there is no need of any delay for every data transfer, as per the timing diagram of LMX2595 I thought that 1ms delay is sufficient.
My other query is that as there are 0's in MSB will it get reflected at the slave end. I mean once I have monitored in serial monitor window I was unable to get the leading 0's in serial monitor.
Below is the image attached which shows the interconnection between Arduino Due and LMX2595 Evaluation Board.

Arduino Due ----------------> LMX2595

MOSI------------------------> SDI
SS---------------------------->CSB
SCLK-------------------------->SCK
GND---------------------------->GND

vamshi97:
as per the timing diagram of LMX2595 I thought that 1ms delay is sufficient.

Do not use any delay. The delay caused by instructions being executed are more than enough.

vamshi97:
My other query is that as there are 0's in MSB will it get reflected at the slave end. I mean once I have monitored in serial monitor window I was unable to get the leading 0's in serial monitor.

SPI uses a clock signal (SCK) to show the slave that the value is valid. This includes zero.
You can send 0 values on serial as well. But only for the transfer itself. A print of a number will not show leading zeros.

vamshi97:
Arduino Due ----------------> LMX2595

MOSI------------------------> SDI
SS---------------------------->CSB
SCLK-------------------------->SCK
GND---------------------------->GND

Did you connect MISO? How do you read values from the LMX2595?

Do you have an oscilloscope to look at the signals on your board?

That's fine.
I haven't monitored the signals on scope.
LMX2595 has muxout pin which is used to read back the register values, But I don't think so it is required to connect to MISO line of Controller.
Is that clock 4MHz sufficient or else should I change it for other value.

This is what the interface between Arduino Due and LMX2595 Evaluation Board.

vamshi97:
LMX2595 has muxout pin which is used to read back the register values, But I don't think so it is required to connect to MISO line of Controller.

That is OK. However, it might be useful to read the registers to make sure you set them correctly.

vamshi97:
Is that clock 4MHz sufficient or else should I change it for other value.

You do not need a fast clock speed. You are just writing registers for configuration. A fast clock means there is a higher chance you get errors when your wiring is bad. As I said before the SPI signal on my Due board has some over and under voltage spikes/ringing noise at the edges.

I would read the registers after writing before you look for any other issues. Maybe your SPI communication works, and the issue is somewhere else.

Okay. So, If I connect the muxout pin of LMX2595 to MISO pin of controller do I need to modify the code. I mean I am thinking that once I receive Acknowledgement from slave end then itself I need to transfer next set of data. Is it that way.

Could you please share me the signal on the scope which you have observed for this particular code.

vamshi97:
So, If I connect the muxout pin of LMX2595 to MISO pin of controller do I need to modify the code. I mean I am thinking that once I receive Acknowledgement from slave end then itself I need to transfer next set of data. Is it that way.

Yes, you need to write some code to send a READ to the device. The slave will send the data back. You need to compare the data you get with the one you send and the datasheet. There is no automatic acknowledge that will confirm the data.

Have a look at the Arduino Reference. The SPI transfer receives a byte while you send one.

The modification is easy. According to the datasheet the LMX2595 sends the data back after you send the address with the R/W bit set to 1. For the master to create the clock you just need to send two dummy bytes after the address.

uint8_t highByte;
uint8_t lowByte;
...
SPI.transfer(0x9C); // was 0x1C for read R/W bit must be 1
highByte = SPI.transfer(0x00);  // value send is ignored
lowByte = SPI.transfer(0x00);
...

I haven't got you. I mean at the slave end the muxout pin can be used in two way as lock detect and in read back mode. Now I will make the pin to act as read back mode. In this case as you have mentioned the code like SPI.transfer(0x9C), but the 1C is in hexadecimal format. In that case 8C also works.

Could you tell me where do I place the written code
uint8_t highByte;
uint8_t lowByte;
...
SPI.transfer(0x9C); // was 0x1C for read R/W bit must be 1
highByte = SPI.transfer(0x00); // value send is ignored
lowByte = SPI.transfer(0x00);
...

Shall I place entire the code
SPI.transfer(0x9C); // was 0x1C for read R/W bit must be 1
highByte = SPI.transfer(0x00); // value send is ignored
lowByte = SPI.transfer(0x00);

vamshi97:
I haven't got you. I mean at the slave end the muxout pin can be used in two way as lock detect and in read back mode. Now I will make the pin to act as read back mode. In this case as you have mentioned the code like SPI.transfer(0x9C), but the 1C is in hexadecimal format. In that case 8C also works.

I am just using your example and showed you how to do a read for the first write. For the read you need to change the first bit of the first byte you send to a 1.

0x1C changes to 0x9C

0x8C will also be a read but for a different address

0x0C would change to 0x8C

I have written a little test function and a sketch based on your example.

#include <SPI.h>

SPISettings mySettting( 4000000, MSBFIRST, SPI_MODE0 );
const uint8_t ss = 10;

void setup()
{
  pinMode( ss, OUTPUT );
  Serial.begin( 9600 );
  while ( !Serial );
  
  Serial.println( "LMX2595 SPI test." );
  
  SPI.begin();

  if ( !LMXSend( 0x1C, 0x25, 0x00 ) )
  {
    Serial.println( "Verify failed." );
  }

  if ( !LMXSend( 0x08, 0x08, 0x01 ) )
  {
    Serial.println( "Verify failed." );
  }

  if ( !LMXSend( 0x00, 0x05, 0x02 ) )
  {
    Serial.println( "Verify failed." );
  }

  if ( !LMXSend( 0x42, 0x06, 0x03 ) )
  {
    Serial.println( "Verify failed." );
  }

  Serial.println( "Test done." );
}

void loop()
{
}

bool LMXSend( uint8_t address, uint8_t highByte, uint8_t lowByte )
{  
#define SPI_DUMMY_BYTE 0x00

  SPI.beginTransaction( mySettting );
  digitalWrite( ss, LOW );
  SPI.transfer( address );
  SPI.transfer( highByte );
  SPI.transfer( lowByte );
  digitalWrite( ss, HIGH );
  SPI.endTransaction();

  uint8_t readAddress = address | 0x80;

  SPI.beginTransaction( mySettting );
  digitalWrite( ss, LOW );
  SPI.transfer( readAddress );
  uint8_t readHighByte = SPI.transfer( SPI_DUMMY_BYTE );
  uint8_t readLowByte = SPI.transfer( SPI_DUMMY_BYTE );
  digitalWrite( ss, HIGH );
  SPI.endTransaction();
 
  return ( ( highByte == readHighByte ) && ( lowByte == readLowByte ) );
}

See, if you can get a confirmation whether your SPI communication is working?

Apologies for the late reply. In the above code which you have mentioned do I need to send the entire data I mean complete 79-register data to slave device. will that work and reading it back from the slave device(LMX2595). I have interfaced Arduino Due with LMX2595, but unfortunately there was no output. (I have done only writing the register values to the slave device)

Thanks in Advance.

What is the output from the Serial Monitor when you run the sketch in reply #12?

verify failed was the output in serial monitor. I have executed the code which you have sent and I have added complete set of register values (I mean running 'if' loop for about 79 times). In the LMX2595 Evaluation Board I have connected the muxout pin to MISO pin of controller. I have got multiple times as verify failed which indicates that I guess it is not matching with the actual sent one.

I have the following doubt that the code which you have given the LMXsend function sends the 24-bit data and compares simultaneously?? (I hope the if loop is comparing, but if the data sent is successful then in the serial monitor window there should not be any display right)

Why do we require the bitwise OR operation address with 0x80 and the need of sending the dummy byte. I think the dummy byte written is only getting transferred rather than what the data I want to actual be written.

Thank you for patience reply.

vamshi97:
I have the following doubt that the code which you have given the LMXsend function sends the 24-bit data and compares simultaneously?? (I hope the if loop is comparing, but if the data sent is successful then in the serial monitor window there should not be any display right)

The LMXSend function sends one word (two bytes) and then reads them back from the same address. In most cases the value should match. There can be some registers that read a different value than the one you send. You can add a verify success to the code by adding an else{}.

vamshi97:
Why do we require the bitwise OR operation address with 0x80 and the need of sending the dummy byte.

The bitwise or turns the write into read. The address byte contains a R/W bit.
We need to send a dummy byte because we are the master and SPI is a bidirectional bus. It sends and receives at the same time. By sending a byte we clock the bits from the slave to the master.

Yes I have added the else loop, but even though there is no result. I mean what I am thinking is that I don't think so the data is transferred to the slave end. Is there anything I am missing, Do I need to add wire.h any further suggestions

vamshi97:
Is there anything I am missing, Do I need to add wire.h any further suggestions

No, the sketch is working correctly. I looked at the signal with an oscilloscope.

did you got the exact data in the scope. I mean HIGH and LOW of Equivalent hexadecimal data in binary format. Have you connected MOSI line to the scope??

Thankyou for your patience reply