CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Mysterious SPI right shift problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
doug_h



Joined: 26 Feb 2004
Posts: 11

View user's profile Send private message

Mysterious SPI right shift problem
PostPosted: Tue Mar 02, 2004 12:53 am     Reply with quote

I'm having a problem with the spi_read / spi_write functions. I have a simple test program that writes to the configuration registers on the MCP2515 CAN controller and then reads back the values. The problem is the values I'm reading back have been right shifted one position. What am I doing wrong here???

Here's the output of the code:

Code:

CAN CFG TEST

Resetting the MCP2515

Reading registers...
CANSTAT = 40
CANCTRL = 43
CNF1 = 80
CNF2 = 00
CNF3 = 00

Writing status registers...
Setting CNF1 = 90
Setting CNF2 = 92
Setting CNF3 = 84

Reading back status registers...
CANSTAT = 00
CANCTRL = 00
CNF1 = 48
CNF2 = 49
CNF3 = 42

Running...


And here's the source code:
Code:
#include <16F876A.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=8000000)
#use rs232(DEBUGGER)

#define CAN_DO_DEBUG TRUE

//define the SPI control pins for PIC16F876A 28 PDIP
#define MCP2515_CS   PIN_B5
#define MCP2515_RESET_PIN PIN_A0
#define READCMD      0x03
#define WRITECMD   0x02

#include <mcp2515.c>

#define LED1  PIN_A0

int rreg;


void ResetMCP2515(void)
{
   output_high(MCP2515_CS);
   output_low(MCP2515_RESET_PIN);
   delay_us(10);
   output_high(MCP2515_RESET_PIN);
}

int ReadRegister(int regaddr)
{
   output_low(MCP2515_CS);
   spi_write(READCMD);
   spi_write(regaddr);
   rreg = spi_read(0);
   output_high(MCP2515_CS);
   return(rreg);
}

void WriteRegister(int regaddr, int regvalue)
{
   output_low(MCP2515_CS);
   spi_write(WRITECMD);
   spi_write(regaddr);
   spi_write(regvalue);
   output_high(MCP2515_CS);
}

void ConfigureMCP2515(void)
{
   int cnfr1 = 0x90;
   int cnfr2 = 0x92;
   int cnfr3 = 0x84;
   
   can_debug("Setting CNF1 = %2x\n", cnfr1);
   can_debug("Setting CNF2 = %2x\n", cnfr2);
   can_debug("Setting CNF3 = %2x\n", cnfr3);

   WriteRegister(CANCTRL, 0x80); //set to config mode
   WriteRegister(CNF1, cnfr1);
   WriteRegister(CNF2, cnfr2);
   WriteRegister(CNF3, cnfr3);
   WriteRegister(CANCTRL, 0x00); //reset to normal mode
}

void main()
{
   can_debug("\n\nCAN CFG TEST\n");
   
   setup_spi(spi_master | spi_h_to_l);

   can_debug("\nResetting the MCP2515\n");
   ResetMCP2515();

   can_debug("\nReading registers...\n");
   can_debug("CANSTAT = %2x\n", ReadRegister(CANSTAT));
   can_debug("CANCTRL = %2x\n", ReadRegister(CANCTRL));
   can_debug("CNF1 = %2x\n", ReadRegister(CNF1));
   can_debug("CNF2 = %2x\n", ReadRegister(CNF2));
   can_debug("CNF3 = %2x\n", ReadRegister(CNF3));

   can_debug("\nWriting status registers...\n");
   ConfigureMCP2515();

   can_debug("\r\nReading back status registers...\n");
   can_debug("CANSTAT = %2x\n", ReadRegister(CANSTAT));
   can_debug("CANCTRL = %2x\n", ReadRegister(CANCTRL));
   can_debug("CNF1 = %2x\n", ReadRegister(CNF1));
   can_debug("CNF2 = %2x\n", ReadRegister(CNF2));
   can_debug("CNF3 = %2x\n", ReadRegister(CNF3));

   can_debug("\nRunning...");

   while(TRUE) //blink the LED so we know we're running
   {
      output_low(LED1);
      delay_ms(500);
      output_high(LED1);
      delay_ms(500);
   }
}


Thanks in advance for any help you can give me.
Best regards,
Doug
mpfj



Joined: 09 Sep 2003
Posts: 95
Location: UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Mar 02, 2004 7:16 am     Reply with quote

Just a quick thought ... might the SPI clock be upside down ? This might clock the data at the wrong point (possibly just after it has changed) ...
Charlie U



Joined: 09 Sep 2003
Posts: 183
Location: Somewhere under water in the Great Lakes

View user's profile Send private message

PostPosted: Tue Mar 02, 2004 8:06 am     Reply with quote

I think mpfj may be correct. Check this old post and its thread. Specifically the reply from Chas on setting up the SPI interface.

http://www.ccsinfo.com/forum/viewtopic.php?t=17922
doug_h



Joined: 26 Feb 2004
Posts: 11

View user's profile Send private message

PostPosted: Tue Mar 02, 2004 9:59 am     Reply with quote

I tried changing the setup_spi() to use the spi_l_to_h flag to invert the clock, but now I get nothing back from the MCP2515. Is there another way to implement the clock change you suggested?
mpfj



Joined: 09 Sep 2003
Posts: 95
Location: UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Mar 02, 2004 10:13 am     Reply with quote

Actually there are 4 SPI modes ... 00, 01, 10 and 11

As you already know, the clock can be idle high / active low, or idle low / active high. However, the data sample / change point can also change ... it can be on either the rising or falling edge of the clock !!

Check the Microchip datasheets for the bits CKE (ClocK Edge) and CKP ((ClocK Polarity) ...

Unfortunately CCS don't directly support all 4 modes via the setup_spi() function. You'll either have to set the bits manaully, or look at this forum link ...
http://www.ccsinfo.com/forum/viewtopic.php?t=8747&highlight=spi+modes
doug_h



Joined: 26 Feb 2004
Posts: 11

View user's profile Send private message

PostPosted: Tue Mar 02, 2004 10:33 am     Reply with quote

Aha! This could indeed be the problem - I'll give it a try and report back.
Thanks
doug_h



Joined: 26 Feb 2004
Posts: 11

View user's profile Send private message

PostPosted: Tue Mar 02, 2004 2:57 pm     Reply with quote

Problem solved!

I changed the SPI setup code from this:
Code:

setup_spi(SPI_MASTER | SPI_H_TO_L);

To this:
Code:

setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_XMIT_L_TO_H);

And now everything is working.
Thanks a bunch guys! Smile
Guest








PostPosted: Sat Mar 15, 2008 5:20 am     Reply with quote

Hi
Does someone know how ideological scheme looks to this programme inserted by doug_h ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group