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

SPI interfacing CC1000

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



Joined: 07 Dec 2006
Posts: 3

View user's profile Send private message

SPI interfacing CC1000
PostPosted: Thu Dec 07, 2006 2:39 pm     Reply with quote

i was wandering if anyone has any idea how the SPI interfacing CC1000(chipcon) is done. i am trying to convert the IAR to CCS. i don't know if the interfacing is done by just connectint the pin to th microcontroller or do i need to do it on the code.
thanks for the help
here is the code

/****************************************************************************/
/* Application note AN009 */
/* CC1000 interface library */
/* */
/* File: cc1000.c */
/* Revision: 2.1 */
/* */
/* Microcontroller: */
/* Microchip PIC16F876 */
/* Written for the IAR PIC16 compiler */
/* */
/* Author: Karl H. Torvmark, Field Applications Engineer, Chipcon */
/* */
/* Contact: Chipcon AS +47 22 95 85 44 */
/* [email protected] */
/* */
/* Changes: */
/* 2.1 : Added change of PLL register between RX and TX */
/* 2.0 : Changed file into library format, many other changes, added */
/* SPI code */
/* 1.0 : First version */
/****************************************************************************/

/****************************************************************************/
/* This library contains functions for configuring the CC1000. These */
/* routines use bit-banging to program the CC1000, faster configuration is */
/* possible by using a synchronous serial port such as a SPI interface. */
/* The header file "modemhw.h" contains definitions for the various I/O */
/* pins, the user should make a similar file to name the pins used to */
/* communicate with the CC1000. Routines to read and write the calibration */
/* values in the CC1000 are provided, they are not used in this reference */
/* application, but are useful in other applications, most notably */
/* frequency-agile and frequency hopping applications. See application */
/* note AN009 for more information. */
/* The routines in this file will have to be adapted depending on the MCU */
/* and compiler used. The method used for shifting data in and out may have */
/* to be changed if the bit ordering for bitfields is different from the */
/* IAR PIC compiler. */
/* */
/* Configuration routines are included in two versions: one using general */
/* I/O ports ("bit-banging"), and one using the built-in SPI interface of */
/* the PIC16F876. If possible, the SPI version should be used, as this is */
/* much faster. The SPI versions are used if the symbol "SPI" is defined, */
/* otherwise the general I/O-based version is used. */
/****************************************************************************/

/* *
* Revision history: *
* *
* $Log: cc1000pic.c,v $
* Revision 2.5 2003/05/08 10:03:30 tos
* Corrected LOCK monitor in Calibrate.
*
* Revision 2.4 2003/05/08 09:43:12 tos
* Corrections according to Errata Note 01: reset freq.synth if unable to lock PLL.
*
* Revision 2.3 2003/04/25 14:03:22 tos
* Corrected inconsistent monitoring of CC1000: [calibration complete] + [lock].
*
*
* *
****************************************************************************/


#include "io16f876.h"
#include "CC1000.h"
#include "modemhw.h"


// Value of time-out timer during calibration
#define CAL_TIMEOUT 0x7FFE
#define LOCK_TIMEOUT 0x7FFE

// PA power setting
#define PA_VALUE 0xF0

/****************************************************************************/
/* This routine sends new configuration data to the CC1000 */
/****************************************************************************/

void ConfigureCC1000(char Count, short Configuration[])
{
short val;
char i;

for (i=0;i<Count;i++) {
val=Configuration[i];
WriteToCC1000RegisterWord(val);
}

}

/****************************************************************************/
/* SPI versions of configuration routines. The SPI interface must be */
/* initialised correctly before use */
/****************************************************************************/

#ifdef SPI


/****************************************************************************/
/* This routine writes to a single CC1000 register */
/****************************************************************************/

void WriteToCC1000Register(char addr, char data)
{
char dummy;

PALE=0;

dummy=SSPBUF;
SSPBUF=(addr<<1)|0x01; // Write address to CC1000, write bit is always 1

// Wait until data is written
while (BF==0)
;
PALE=1;

dummy=SSPBUF;
SSPBUF=data;
while (BF==0)
;
}

/****************************************************************************/
/* This routine writes to a single CC1000 register, with data and address */
/* given in the same variable */
/****************************************************************************/

void WriteToCC1000RegisterWord(short addranddata)
{
char dummy;

union {
unsigned short data;
struct {
char LowByte;
char HighByte;
};
};

data=addranddata;
PALE=0;

dummy=SSPBUF;
SSPBUF=LowByte|0x01; // Write address to CC1000, write bit is always 1

// Wait until data is written
while (BF==0);
PALE=1;

dummy=SSPBUF;
SSPBUF=HighByte;
while (BF==0)
;
}

/****************************************************************************/
/* This routine reads from a single CC1000 register */
/****************************************************************************/

char ReadFromCC1000Register(char addr)
{

char Value;


PALE=0;
Value=SSPBUF;
SSPBUF=(addr<<1)&0xFE; // Write address to CC1000, write bit is always 0

// Wait until data is written
while (BF==0);
SSPOV=0;

// Switch direction
PDATA_OUT=1;
TRISC|=0x20; // Set up PDATAOUT as an input

PALE=1;

SSPBUF=0xFF; // Dummy write

while (BF==0);
Value=SSPBUF;

TRISC&=~0x20; // Set PDATAOUT as an output
return Value;
}

#else

/****************************************************************************/
/* General I/O pin "bit-bashing" versions of configuration routines. */
/****************************************************************************/

/****************************************************************************/
/* This routine writes to a single CC1000 register */
/****************************************************************************/

void WriteToCC1000Register(char addr, char data)
{
short val;

val=(short) (addr&0x7F)<<9 | (short) data &0x00FF;
WriteToCC1000RegisterWord(val);
}

/****************************************************************************/
/* This routine writes to a single CC1000 register, with address and data */
/* given in the same variable */
/****************************************************************************/

void WriteToCC1000RegisterWord(short addranddata)
{
char BitCounter;
union { // This union is used to easily access the most significant
// bit of the configuration data

// Note : This assumes that the C compiler stores bit-fields
// with the first field going into the LSB. If this is not the
// case, move the MSB definition to the first bit
unsigned short Data;
struct
{
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short :1;
unsigned short MSB :1;
};
};

PALE=1;

Data=addranddata;
PALE=0;

// Send address bits
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PCLK=1;
PDATA_OUT=MSB;
Data=Data<<1;
PCLK=0;
}
// Send read/write bit
// Ignore bit in data, always use 1

PCLK=1;
PDATA_OUT=1;
PCLK=0;
Data=Data<<1;
PCLK=1;
PALE=1;

// Send data bits

for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=1;
PDATA_OUT=MSB;
Data=Data<<1;
PCLK=0;
}
PCLK=1;
}

/****************************************************************************/
/* This routine reads from a single CC1000 register */
/****************************************************************************/

char ReadFromCC1000Register(char addr)
{
char BitCounter;

union { // This unit is used to easily access the most significant
// bit of the configuration data

// Note : This assumes that the C compiler stores bit-fields
// with the first field going into the LSB. If this is not the
// case, switch the MSB and LSB definitions
unsigned char Data;
struct
{
unsigned char LSB :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char MSB :1;
};
};

PALE=1;

Data=addr<<1;
PALE=0;

// Send address bits
for (BitCounter=0;BitCounter<7;BitCounter++)
{
PCLK=1;
PDATA_OUT=MSB;
Data=Data<<1;
PCLK=0;
}
// Send read/write bit
// Ignore bit in data, always use 0

PCLK=1;
PDATA_OUT=0;
PCLK=0;


PCLK=1;
PALE=1;

// Receive data bits

PDATA_OUT=1;

TRISC|=0x20; // Set up PDATA as an input

for (BitCounter=0;BitCounter<8;BitCounter++)
{
PCLK=0;
Data=Data<<1;
LSB=PDATA_IN;
PCLK=1;
}


TRISC&=~0x20; // Set up PDATA as an output again

return Data;
}

#endif
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 07, 2006 3:17 pm     Reply with quote

I guess you're trying to convert the source code in Chipcon AN009 to CCS.
This requires a good knowledge of the CCS compiler to do this.
You have to know the data type differences. For example, in most
compilers a 'short' is a 16-bit signed integer. In CCS, it's a 1-bit value.
Also, in other compilers an 'int' can be a 16 or 32 bit signed integer.
In CCS, it's an 8-bit unsigned integer.

You could probably convert this code if you defined the PIC registers
with #byte statements and the pins with #bit statements.
See this thread for an example.
http://www.ccsinfo.com/forum/viewtopic.php?t=18932

To convert this driver, you really need to thoroughly understand CCS,
and the SPI module, and SPI modes, and data types, etc.
I don't really want to do this for you. I am still very busy, as I
said in the link above, even though it's a couple years later.
GEST
Guest







PostPosted: Thu Dec 07, 2006 3:31 pm     Reply with quote

thanks for your help i will try to go through the whole CCS manual and hopefully i will come up with something
thanks again
Guest








PostPosted: Wed Jan 24, 2007 11:17 pm     Reply with quote

Dear PCM programmer
this is my code. It's working.

Code:
//file cc1000.c
void WriteToCC1000Register(char address, char data)
{
   char dummy;
   char addr;
   output_low(PIN_PALE);
    shift_left(&address,1,1);
    dummy =SSPBUF;
   spi_write(address);
   output_high(PIN_PALE);
   spi_write(data);
}

char ReadFromCC1000Register(char addr)
{
   char value;
   PALE=0;
   value=SSPBUF; //dummy read
   value=addr;
   shift_left(&value,1,0); //read bit is 0
   spi_write(value);
   PDATA_OUT=1;
   trisC |=0x20; //switch direction
   PALE=1;
   spi_write(0xFF);
   value=spi_read();
   trisC &=~0x20;
   return value;
}

void cc1000_reset()
{
   char mainvalue;
   mainvalue=ReadFromCC1000Register(CC1000_MAIN);
   WriteToCC1000Register(CC1000_MAIN,mainvalue & 0xFE);         // Reset CC1000
   WriteToCC1000Register(CC1000_MAIN,mainvalue | 0x01);         // Bring CC1000 out of reset
}   
void SetupCC1000PD(void)
{
  WriteToCC1000Register(CC1000_MAIN,0x3F);    // Put CC1000 into power-down
  WriteToCC1000Register(CC1000_PA_POW,0x00);  // Turn off PA to minimise current draw
}


Code:
//file main.c
#include <18Fxxxx.h>
#include "cc1000.h"
#include "mylib.h"

#fuses HS,NOWDT,NOPROTECT,LVP 
#use delay(clock=8000000)
#use SPI(DO=PIN_C5,DI=PIN_C4,CLK=PIN_C3,BITS=8)
// PA power setting
#define PA_VALUE 0xF0
#include "cc1000.c"
void main(void)
{
   char dummy;
   PORTC=0x00;
   TRISC=0x92;
   setup_spi(SPI_MASTER |SPI_H_TO_L |SPI_CLK_DIV_4); //5ns

//----------------------------------------------------   
   SetupCC1000PD();
   cc1000_reset();
      while(1){
        cc1000_write_register(CC1000_MAIN,0xA1);
        dummy =cc1000_read_register(CC1000_MAIN);
      }
   }


mylib.h include all my define of PALE, PDATA,PCLK, DCLK, DIO... as I posted before.
fadi
Guest







spi interfacing of AT89s8253 with cc1000
PostPosted: Sat Jul 18, 2009 12:14 am     Reply with quote

hello
I am also doing project on cc1000. You have written this code in PIC controller? Because I am using Atmel's AT89s8253 having spi interface. Could you please guide me of adding header files for this code and also the code regarding Atmel controller. Will this code work well with this controller?

regards
sunny
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