Go Down

Topic: Arduino Due Master Programming (Read 755 times) previous topic - next topic

vamshi97

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.


Code: [Select]
#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() {
}

  

ballscrewbob

@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.


It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google (who would have thunk it ! ) or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

Klaus_K

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. :) 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. :)

Klaus_K

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?

vamshi97

#4
Oct 10, 2020, 07:29 pm Last Edit: Oct 10, 2020, 07:33 pm by vamshi97
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


Klaus_K

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.

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.

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?

vamshi97

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.

vamshi97

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


Klaus_K

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.

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.

vamshi97

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.


Klaus_K

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.

https://www.arduino.cc/en/Reference/SPITransfer

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.
Code: [Select]
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);
...

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.

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);

Klaus_K

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.

Code: [Select]
#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?

vamshi97

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.

Klaus_K

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

Go Up