how to send 24 bit at once multiple times using SPI for multiple register

i’m trying to establish SPI a connection between a mega arduino board to Chip and control the out put. to achieve this i need to send 24 bit to 6 different register in the same time. please need any available help ,so far i have been working on this form the last two weeks and now kind in dead end rad :confused: :confused: .

the 24 bit are assigned as , 2 for operation 6 for the address and the other 16 data. i’m using the Oscilloscope to check the output and major the voltage.

the code is attach with post. as well the pdf for the ST SPI protocol.

#include <SPI.h>

const int SDO = 50; //input data from slave to master  
const int SDI = 51; //output data from master to slave 
const int CLK = 52; //output clock from master to slave  
const int ss = 53; //output selector from master to slave 

const byte Oc = B00; //write,

const byte AddrReg0 = B000000;
const byte Command0 = Oc +AddrReg0;
const byte dataReg0 = B0001000;
const byte dataReg00 = B00000000; 
const byte dataA = (Command0 + dataReg0 + dataReg00);

const byte AddrReg1 = B000001;
const byte Command1 = Oc +AddrReg1;
const byte dataReg1 = B00000000;
const byte dataReg11 = B00001110; 
const byte dataB = (Command1 + dataReg1 + dataReg11);


const byte AddrReg2 = B000010;
const byte Command2 = Oc + AddrReg2;
const byte dataReg2 = B10111100;
const byte dataReg22 = B00000010;  
const byte dataC = (Command2 + dataReg2 + dataReg22);// Danamic Brak disable 1-



const byte AddrReg3 = B000011;
const byte Command3 = Oc +AddrReg3;
const byte dataReg3 = B00000010;
const byte dataReg33 = B00000000; 

const byte dataD = (Command3 + dataReg3 + dataReg33);



const byte AddrReg4 = B000100;
const byte Command4 = Oc +AddrReg4;
const byte dataReg4 = B10000100;
const byte dataReg44 = B00100000; 
const byte dataE = (Command4 + dataReg4 + dataReg44);


const byte AddrReg5 = B000101;
const byte Command5 = Oc + AddrReg5;
const byte dataReg5 = B11000100;
const byte dataReg55 = B00100000; 
const byte dataF = (Command5 + dataReg5 + dataReg55);



void setup (void)
{
SPI.begin ();
SPI.setBitOrder(MSBFIRST); //We know this from the Data Sheet
digitalWrite(SS, HIGH);  // Make sure SS is held high
pinMode(SS, OUTPUT);     // Set SPI slave select pin as output
pinMode(SDO,INPUT);
pinMode(SDI, OUTPUT);
pinMode(CLK,OUTPUT);
delay(20);
SPI.setClockDivider(SPI_CLOCK_DIV8); // Slow down the master a bit

} 


void loop (void)
{

digitalWrite(SS, LOW);
SPI.transfer(Command0);
SPI.transfer(dataReg0);
SPI.transfer(dataReg00);

SPI.transfer(Command1);
SPI.transfer(dataReg1);
SPI.transfer(dataReg11);



SPI.transfer(Command2);
SPI.transfer(dataReg2);
SPI.transfer(dataReg22);
  
SPI.transfer(Command3);
SPI.transfer(dataReg3);
SPI.transfer(dataReg33);

SPI.transfer(Command4);
SPI.transfer(dataReg4);
SPI.transfer(dataReg44);

SPI.transfer(Command5);
SPI.transfer(dataReg5);
SPI.transfer(dataReg55);

 

digitalWrite(SS, HIGH);
// checking the data  that we send to reg 
Serial.print("dataA.[0] = ");Serial.println(dataA);
Serial.print("dataB.[1] = ");Serial.println(dataB);
Serial.print("dataC.[2] = ");Serial.println(dataC);
Serial.print("dataD.[4] = ");Serial.println(dataD);
Serial.print("dataE.[5] = ");Serial.println(dataE);
Serial.print("dataF.[6] = ");Serial.println(dataF);
delay(50);
}  // end of loop

Moderator edit: [code][/code] tags added. (Nick Gammon)

Nice job of using arrays and for loops, there. Not.

Why not?

The code you incorrectly posted does something. You did not say what it does. You expect it do something. You didn't say what.

All you did was complain that what it did was not what you want.

Try again, after reading the stickies at the top of the forum.

PaulS: Nice job of using arrays and for loops, there. Not.

Why not?

The code you incorrectly posted does something. You did not say what it does. You expect it do something. You didn't say what.

All you did was complain that what it did was not what you want.

Try again, after reading the stickies at the top of the forum.

Thank you for being funny . what i'm trying to do is send a data of arrays to 6 registers that are built in the chip, to be able to control the outputs of the chip.

1) the arrays are used to send a command to the chip ("as the chip design") 2) the oc is order of operation 3)when I look in the Mega bored i see the Tx LED light flashing but the is no response from the chip

I change the summation that i used to combine my variables to bitwise OR, but still no luck.

ex/ const byte Command0 = (Oc + AddrReg0); To: const byte Command0 = (Oc | AddrReg0);

From a quick look at the datasheet, CS needs to be deactivated (go to High) after each frame. Your code keeps it active until after you've sent all the frames.

Also, you could try starting with a simpler test program that reads some of the hard-coded information in the device. That would test your wiring and SPI settings.

Hackscribble: From a quick look at the datasheet, CS needs to be deactivated (go to High) after each frame. Your code keeps it active until after you've sent all the frames.

Also, you could try starting with a simpler test program that reads some of the hard-coded information in the device. That would test your wiring and SPI settings.

I did the first part, and it did not work. I did the second part, but I am not totally sure what you mean by a simpler code? We need to send six different commands to the six different registers in order to control the output.

You make a function. Eg.

void sendCommand (const byte command, const byte register1, const byte register2);
  {
  SPI.transfer(command);
  SPI.transfer(register1);
  SPI.transfer(register2);
  }

Now instead of 3 lines everywhere you can use one:

sendCommand (Command0, dataReg0, dataReg00);
sendCommand (Command1, dataReg1, dataReg11);

And so on. Although an array of commands and registers would be even better.

I am not totally sure what you mean by a simpler code? We need to send six different commands to the six different registers in order to control the output.

I was thinking of testing communication with the device by reading its factory-written ROM values.

For example, Appendix B of the datasheet shows the two byte codes for each device type. Table 10 and section 2.2.1 example 4 show that these can be read using op codes 0xC2 and 0xC3.

So you could add a test function like this to your code and call it as the last thing in setup().

void showProductCodes()
{
   Serial.println("Product codes:");
   digitalWrite(SS, LOW);
   SPI.transfer(0xC2);
   byte pCode1 = SPI.transfer(0);
   digitalWrite(SS, HIGH);
   delay(50); 
   digitalWrite(SS, LOW);
   SPI.transfer(0xC3);
   byte pCode2 = SPI.transfer(0);
   digitalWrite(SS, HIGH);
   Serial.print(pCode1, HEX); 
   Serial.print("   "); 
   Serial.print(pCode2, HEX);
}

You will also need to add this to setup().

Serial.begin(115200);

If the test function does not show the correct product codes, you know that there's a problem with the wiring, the SPI settings or setup (or the datasheet).

[quote author=Nick Gammon link=msg=2783448 date=1464900528] You make a function. Eg.

void sendCommand (const byte command, const byte register1, const byte register2);
  {
  SPI.transfer(command);
  SPI.transfer(register1);
  SPI.transfer(register2);
  }

Now instead of 3 lines everywhere you can use one:

sendCommand (Command0, dataReg0, dataReg00);
sendCommand (Command1, dataReg1, dataReg11);

And so on. Although an array of commands and registers would be even better.

[/quote]

Thank you very Much i will try it and let you know if it work.

Hackscribble: If the test function does not show the correct product codes, you know that there's a problem with the wiring, the SPI settings or setup (or the datasheet).

Thanks , you save me a lot of time.

Hi ,

I have been trying the last few days (weeks) to write SPI data using SPI library ("by using transfer() "). im not sure on how to send the data in binary of 24 bit from or how to read it. Im using ardruno broad Mega to command TN0897 chip, . i'm using every way i know but I still can't get a desired output

here is my pin out, with the data that need to send. The Data-In Frame consist of 24 bits (OpCode + Address + Data1 + Data2) The first two transmitted are Operation Code, The following 6 bits represent the address on.The subsequent 2 bytes contain the payload data.All data is written and read using within the same 24 bit

const int SDO = 50; //input data from slave to master  
const int SDI = 51; //output data from master to slave 
const int CLK = 52; //output clock from master to slave  
const int ss = 53; //output selector from master to slave

const byte dataA = 100000000001010100000001;
const byte dataB = 100000010010101001000010; 
const byte dataC = 100000100010101000000010;
const byte dataD = 100000110000000010000000;
const byte dataE = 100001000000010000000000;
const byte dataF = 100001011000000000100000;

The slave device max speed is 4MHz, set speed bit format and clock/data polarity while starting SPI transaction..

void setup (void)
{
  
  Serial.begin (115200);
  SPI.begin ();
  SPI.setBitOrder(LSBFIRST); //We know this from the Data Sheet
  SPI.setClockDivider(SPI_CLOCK_DIV8); // Slow down the master a bit
  SPI.setBitOrder(SPI_MODE2);
  digitalWrite(SS, HIGH);  // Make sure SS is held high
  pinMode(SS, OUTPUT);     // Set SPI slave select pin as output
  pinMode(SDO,INPUT);
  pinMode(SDI, OUTPUT);
  pinMode(CLK,OUTPUT);
  delay(50);
}

HERE HOW im send the data,

void loop (void)
{
  
  digitalWrite(SS, LOW);
  SPI.transfer(dataA);
  SPI.transfer(dataB);
  SPI.transfer(dataC);
  SPI.transfer(dataD);
  SPI.transfer(dataE);
  SPI.transfer(dataF);
  digitalWrite(SS, HIGH);
// checking the data  that we send to reg 
  Serial.print("SDO.[0] = ");Serial.println(SDI);

what i'm trying to do is send a data to 6 registers that are built in the chip, to be able to control the outputs pin of the chip. Also i try to read the output data that is received from the output pin to figure out whats the problem using the Global Status Bytes table but with no luck & It it didn't make a lot since to me.

I'm very new with programming, but i have okay background from the school. can someone please help me on how get it to work by send a command and receiving the desired output(or major the output pin voltage by the oscilloscope )

Thank you very much in advance for your help

Have you read the tutorials?

https://www.arduino.cc/en/Tutorial/SPIEEPROM

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi

ieee488: Have you read the tutorials?

https://www.arduino.cc/en/Tutorial/SPIEEPROM

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi

Yes Sir ! BUt Still didn't help me alot with what im doing

Isn't TN0897 the reference number of the ST technical note?

Which device are you actually using?

Hackscribble: Isn't TN0897 the reference number of the ST technical note?

Which device are you actually using?

Yes it is the same ?, which i am still unable to connect or command the chip.

Don't think so. The different devices are listed at the back of the technical note. Which one are you using?

And can you post a diagram of how you have the Mega and the device connected, including power supplies.

What output did you see from the test function I suggested in your other thread? http://forum.arduino.cc/index.php?topic=404634.msg2784063#msg2784063

Hackscribble:
Don’t think so. The different devices are listed at the back of the technical note. Which one are you using?

And can you post a diagram of how you have the Mega and the device connected, including power supplies.

I don’t think that the problem is for the connection because me and my other partner check everything ( input, output,voltage current and send signal). I believe is from the way i am send the command, because i need to send a specific command to each register in order to control the output.

I have a oscilloscope view for CLK, Select pin, and data in send it to chip out with no response form the output

also i was looking online and i saw this but i didn’t understand it how should i apply to my code ?
("The Arduino SPI EEPROM example might also be useful.

If you need to send data that isn’t 8-bytes, it would be exceedingly convenient if the data size (in bits) was a multiple of 8. In this case, the data is sent in 8-bit (or one-byte) chunks. The simplest way to do it is to treat your data as a byte array:

byte data = {0x00, 0x00, 0x00, 0x00}; // this is 24 bits (8bits/byte * 4 bytes)

// Transfer 24 bits of data
for (int i=0; i<4; i++) {
transfer(data*); // Send 8 bits*
}
Question: I’m very confused by this “8*4=24” bit above and below. This doesn’t make sense to me. Also, isn’t it SPI.transfer, not just transfer ?"") from http://electronics.stackexchange.com/questions/64927/how-to-write-to-93lc46b-eeprom-from-an-arduino-using-spi?answertab=active#tab-top

There are several problems with the code you posted in this thread.

But before wasting time trying to to help you with those, please try the test function from the other thread and say what results you see on serial monitor (and on the oscilloscope). This will help to prove out the hardware.

have a oscilloscope view for CLK, Select pin, and data in send it to chip out with no response form the output

Which output do you mean? SPI output from device back to Mega? Or the output of the device that the register writes are meant to control?

Try this program, which includes the test function from the other thread and calls it every 3 seconds. At the start of the program, the program also reads the SPI Frame ID which will confirm how many bytes of data the device expects in each transfer.

What results do you see on serial monitor and oscilloscope?

Note: you were using SPI mode 2. From the technical note, I think it might need to be mode 0. Also, you were using LSBFIRST. Datasheet says MSBFIRST.

#include <SPI.h>

void showProductCodes()
{
  Serial.println("Product codes:");
  digitalWrite(SS, LOW);
  SPI.transfer(0xC2);
  byte pCode1 = SPI.transfer(0);
  digitalWrite(SS, HIGH);
  delay(50);
  digitalWrite(SS, LOW);
  SPI.transfer(0xC3);
  byte pCode2 = SPI.transfer(0);
  digitalWrite(SS, HIGH);
  Serial.print(pCode1, HEX);
  Serial.print("   ");
  Serial.println(pCode2, HEX);
}

void showSPIFrameId()
{
  Serial.println("SPI Frame ID:");
  digitalWrite(SS, LOW);
  SPI.transfer(0xFE);
  byte frameID = SPI.transfer(0);
  digitalWrite(SS, HIGH);
  Serial.println(frameID, HEX);
}


void setup (void)
{
  Serial.begin(115200);

  digitalWrite(SS, HIGH);  // ensure SS stays high for now

  SPI.begin ();
  SPI.setBitOrder(MSBFIRST); //We know this from the Data Sheet
  SPI.setClockDivider(SPI_CLOCK_DIV8); // Slow down the master a bit
  SPI.setBitOrder(SPI_MODE0);

  showSPIFrameId();
}

void loop (void)
{
  showProductCodes();
  delay(3000);  // 3 seconds delay
}