Pages: [1]   Go Down
Author Topic: Problems reading a register value with SPI  (Read 2152 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I have a Duemilanova board and am working on getting an SPI device to work with it.  After a week of thinking that the device was faulty, I discovered that there is no clock signal on pin 13.  I am seeing the SlaveSelect pin go high and low when instructed to, but there is no signal on the clock pin.  I am wondering if I am missing something.  Here is the code:

Code:
#include <SPI.h>

#define SLAVESELECT 10
#define SPICLOCK 13
#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO
#define UBLB(a,b) ( ( (a) << 8) | (b) )
#define UBLB19(a,b) ( ( (a) << 16 ) | (b) )

void setup()
{
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK, OUTPUT);
  pinMode(SLAVESELECT, OUTPUT);
  digitalWrite(SLAVESELECT, HIGH);
  SPCR = B01010011; //
  clr=SPSR; // SPi Status Register
  clr=SPDR; // SPi Data Register
  delay(10);
  Serial.begin(115200);
  delay(500);
}

Am I forgetting to set something or turn some setting on?  I took the code directly from  the Apress Beginning Arduino book. I am using a Oscilloscope to verify the pin signals. Any thoughts on how to troubleshoot this?

Jay

« Last Edit: May 26, 2011, 02:53:34 pm by jradcliffe » Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The SPI clock only occurs when you are sending/receiving data.  Are you?

You should try the included SPI library instead of direct register manipulation.  If that still fails then you might have a hardware fault.

Code:
#include <SPI.h>

// set pin 10 as the slave select
const int slaveSelectPin = 10;

void setup() {
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin();
}

void loop() {
   byte received =  SPI.transaction(0x00);
}

Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 545
Posts: 27353
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You don't need to call these
#define SPICLOCK 13
#define DATAOUT 11 //MOSI
#define DATAIN 12 //MISO

  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK, OUTPUT);


this takes care of them
#include <SPI.h>

Don't you also need
spi.begin()
and then
spi.transfer(data_byte)  commands?

http://www.arduino.cc/playground/Code/Spi

You will see a burst of high-speed clock as the byte gets shifted out.
Nick Gammon has a page with scope captures showing this.
I have also posted (quite recently) code showing  transfers needed for talking to MAX7219, if you want to see concrete examples.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, so things are working better now.  Here is the modified code:
Code:
#include <SPI.h>

// set pin 10 as the slave select
const int slaveSelectPin = 10;

void setup() {
  Serial.begin(115200);
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin();
}

void loop() {
   byte received =  SPI.transfer(0x00);
   Serial.print("Register 0x00:0x");
   Serial.println(received,HEX);
   digitalWrite(slaveSelectPin, LOW);
   SPI.transfer(0x00);
   SPI.transfer(0xFF);
   digitalWrite(slaveSelectPin, HIGH);
   received =  SPI.transfer(0x00);
   Serial.print("Register 0x00:0x");
   Serial.println(received,HEX);
}

I see clock now on pin 13, with data on pin 12.  Problem now is my device (CC1101 RF Board) doesn't want to accept the write process.  Register 0x00 starts with 0x00 value, and after I try and write 0xFF to that register, it doesn't take. 

Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Read the datasheet for the device you are programming.

Address 0x00 is the IOCFG2 register.  I don't think 0xFF is a valid value for that register.  Perhaps that is the reason the write didn't work.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Changed to writing 0x02 which is a valid value for that register.  Still same result. 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I also tried to add some delay(s) in there (other posts on the forum suggested that).  I also have an RFM22B RF board that uses SPI and I get the same results with that board.  I also tried a different Arduino board.  Just trying to eliminate any possible hardware failures from the equation. 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

More work done today:

I have 2 setups: an RFM22B module hooked to a Arduino Duemilanova board, and a CC1101 hooked to a Arduino Uno board.

Running the RFM22B setup I get the following output. (0x0B = IOCFG2 which is a R/W register, default value 0x01)

Register 0x0B:0x1
Register 0x0B:0xFF
Register 0x0B:0xFF

Running the CC1101 setup I get the following output. (0x00 = IOCFG2 also R/W, default value 0x29)

Register 0x0B:0x0
Register 0x0B:0xF
Register 0x0B:0xF

Code:
void setup() {
  Serial.begin(115200);
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin();
}

void loop() {
   byte received =  SPI.transfer(0x00); //0x0B for RFM22B
   Serial.print("Register 0x00:0x");
   Serial.println(received,HEX);
   digitalWrite(slaveSelectPin, LOW); 
   delay(1000);
   byte received2 =  SPI.transfer(0x00); //0x0B for RFM22B
   Serial.print("Register 0x00:0x");
   Serial.println(received2,HEX);
}

This seems really odd.  I can't get consistent results.  I am quite frustrated that I can't seem to get the simplest of tasks (reading a value from a register) to work at all. 
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset



This is the clock and SI lines
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One more thing.  I am not using any resistors in the 4 SPI lines. It goes directly from the board to the Arduino.  I have read a lot on the topic of SPI and there really isn't any consistency in the use of pullup resistors on these lines.  Could that be causing problems?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8954
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For the CC1101, at least, you are supposed to send the command to read a register and then do another transaction to read the result (the chip can't return data until it knows what register you want to read:


Code:
const int slaveSelectPin = 10;

void setup() {
  Serial.begin(115200);
  // set the slaveSelectPin as an output:
  pinMode (slaveSelectPin, OUTPUT);
  // initialize SPI:
  SPI.begin();
}

void loop() {
   byte result;

   // Begin a read or write cycle
   digitalWrtite(slaveSelectPin, LOW);  Enable the slave

   // Send the command to read register 0
   SPI.transfer(0x00);

   // Now read a byte from the chip.  THE VALUE WE SEND MAKES NO DIFFERENCE WHEN READING.
   // We just need to generate 8 clock pulses and sample the MISO line to get the data.
   //  Sending a byte will generate the clock pulses
   result = SPI.transfer(0x42);

   //  Register read operation complete
   digitalWrite(slaveSelectPin, HIGH); 

   Serial.print("Register 0 contains 0x");
   Serial.println(result,HEX);

   delay(1000);
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually, I got it to work just now.  I added a 10k resister to the CSN line.  Now I get very consistent results. When I write a value to a register, it actually reads back what I expect to be there! W00t!

Thanks for all the help! Now if I can just get the carrier detect to work......smiley
Logged

Pages: [1]   Go Up
Jump to: