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

problem with DS1305 and PIC18F6722

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



Joined: 16 Sep 2005
Posts: 138
Location: The Netherlands

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

problem with DS1305 and PIC18F6722
PostPosted: Tue Feb 13, 2007 1:59 am     Reply with quote

Hi

I have a problem with communication between a PIC18F6722 and a DS1305 via the second SPI port. I am using compiler version 3.222 so I don't have access to ds1305.c nor to the standard fuction for the second SPI port.

I have already searched this forum and the internet for possible slutions but couldn't find a solution...

I think my clocksignal is wrong, because I have CKE on 1 and when I compare the datasheets I conclude CKE needs to be 0.
But when I put CKE on 0 the PIC stalls in the rtc_init() function.

When I put CKE on 1 the ossiclator from the RTC doesn't seem to work (not initialized I guess?)

I have a battery connected to the DS1305 and have a 6 MHz ossilator on my PIC.

I have 2 LEDs on pin G3 and pin G4.

here is the code I use:
Code:
#include <18F6722.h>
#device adc=8
#fuses HS, NOWDT, NOPROTECT, NOLVP
#use delay(clock=6000000)
#use rs232(baud=9600, xmit=PIN_G1, rcv=PIN_G2, stream=USB)

//========================= DEFINES ============================================

#define CS_RTC    PIN_E4
#byte SSP2BUF = 0xF66
#byte SSP2CON = 0xF63
#byte SSP2STAT = 0xF64
#byte TRISD = 0xF95
#bit TRISD4 = TRISD.4
#bit TRISD6 = TRISD.6
#bit TRISD7 = TRISD.7
#bit CKP = SSP2CON.4
#bit CKE = SSP2STAT.6
#bit SMP = SSP2STAT.7
#bit BF = SSP2STAT.0

//========================= GLOBALS ============================================

char c;
int sec, min, hour, day, date, month, year;


//========================= SPI METHODS ========================================

void spi2_send(char data)
{
   char temp;
   temp = SSP2BUF;
   SSP2BUF = data;
   while(!BF);
}

//========================= RTC METHODS ========================================

char rtc_receive_byte()
{
   char data;

   spi2_send(0);
   delay_us(5);
   data = SSP2BUF;

   return data;
}

void rtc_init()
{
   //setup SPI
   SMP = 1;
   CKE = 1;
   CKP = 0;
   delay_ms(20);

   //start RTC
   output_high(CS_RTC);
   delay_us(10);

   //set control register
   spi2_send(0x8F);
   spi2_send(0);

   //stop RTC
   delay_us(10);
   output_low(CS_RTC);
}

void rtc_setTime(int newsec, int newmin, int newhour, int newday, int newdate,
                  int newmonth, int newyear)
//POST: sets RTC in 24-hour mode!
{
   //setup SPI
   SMP = 1;
   CKE = 1;
   CKP = 0;
   delay_ms(20);

   //start RTC
   output_high(CS_RTC);
   delay_us(10);

   //read raw values
   spi2_send(0x80);
   spi2_send(newsec);
   spi2_send(newmin);
   spi2_send(newhour);
   spi2_send(newday);
   spi2_send(newdate);
   spi2_send(newmonth);
   spi2_send(newyear);

   //stop RTC
   delay_us(10);
   output_low(CS_RTC);
}

void rtc_getTime()
//PRE: works only if RTC is in 24-hour mode!
{
   //setup SPI
   SMP = 1;
   CKE = 1;
   CKP = 0;
   delay_ms(20);

   //start RTC
   output_high(CS_RTC);
   delay_us(10);

   //read raw values
   spi2_send(0x00);
   sec = rtc_receive_byte();
   min = rtc_receive_byte();
   hour = rtc_receive_byte();
   date = rtc_receive_byte();
   date = rtc_receive_byte();
   month = rtc_receive_byte();
   year = rtc_receive_byte();

   //stop RTC
   delay_us(10);
   output_low(CS_RTC);
}

//========================== INIT ==============================================

void init()
{
   output_low(CS_RTC);
   TRISD4 = 0;
   TRISD6 = 0;
   TRISD7 = 1;
   SSP2CON = 0b00100011;
   fprintf(USB, "\n\rFirst Contact!\n\r\n\r");
   setup_timer_2(T2_DIV_BY_16,250,16);
   enable_interrupts(GLOBAL);

   delay_ms(20);
   output_high(PIN_G3);
   rtc_init();
   output_low(PIN_G3);
}

// ========================= MAIN ==============================================

void main()
{
   init();
   delay_ms(10);
   //rtc_setTime(0,30,14,1,1,2,7); //set time to: 14:30:00 1-2-07

   //fprintf(USB, "\n\rRTC clock set\n\r");
   while(1)
   {
      output_high(PIN_G4);
      delay_ms(1);
      rtc_getTime();
      output_low(PIN_G4);
     delay_ms(1);
   }
}


If you can have a look at it and give me some hints it would be very appreciated.

Cheers,
Jos
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 13, 2007 12:34 pm     Reply with quote

The CCS file ds1305.c uses software SPI. You want to use hardware SPI.

If you own the compiler, you can email CCS support, give them your
CCS user number to prove that you own the compiler, and ask them
to email you the file. They'll probably do it.

For an example of a hardware SPI driver, just Google for "ds1305.c".
You'll find .c and .h files for download from Seattle Robotics. These
are for a different compiler, but they will give you a good example.

With regard to the SPI mode, read my post in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=29656
I explain how to determine the SPI mode and how to setup the CCS
compiler to use the correct mode.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Feb 13, 2007 1:18 pm     Reply with quote

The DS1305 works in both SPI-mode_0_1 and SPI-mode_1_1, this means:
CKE=0
CKP=don't care
SMP=0

There is also an error in your rtc_init(). On power up the Write Protect bit (WP) in the Control Register is undefined, this means you will have to write twice to this register; once for clearing the Write Protection bit, than a second time for the value you want to set.
Code:
   // Remove possible write protect (undefined on initial power-on.
   // Can not write to other bits in this register when active, so those bits must be set later.
   spi2_send(0x8F);
   spi2_send(0);

   //set control register
   spi2_send(0x8F);
   spi2_send(0);
Foppie



Joined: 16 Sep 2005
Posts: 138
Location: The Netherlands

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

PostPosted: Wed Feb 14, 2007 5:12 am     Reply with quote

Thanks for the help. I want to use the hardware SPI indeed so I'll try later to get my hands on a d21305.c file from CCS. I studied the example of Seattle Robotics and it indeed gave me a good example, but not the solution.

I have indeed overlooked the write protection bit, but I cannot clear it. My PIC stalls in the function that should read that byte. See the code below.

I have altered the clock so that it matches CKielstras discription.

Code:
#include <18F6722.h>
#device adc=8
#fuses HS, NOWDT, NOPROTECT, NOLVP
#use delay(clock=6000000)
#use rs232(baud=9600, xmit=PIN_G1, rcv=PIN_G2, stream=USB)

//========================= DEFINES ============================================

#define CS_FLASH  PIN_E3
#define CS_RTC    PIN_E4
#define CS_DAC    PIN_E2
#byte SSP2BUF = 0xF66
#byte SSP2CON = 0xF63
#byte SSP2STAT = 0xF64
#byte TRISD = 0xF95
#bit TRISD4 = TRISD.4
#bit TRISD6 = TRISD.6
#bit TRISD7 = TRISD.7
#bit CKP = SSP2CON.4
#bit CKE = SSP2STAT.6
#bit SMP = SSP2STAT.7
#bit BF = SSP2STAT.0
#define RTCSMP 0
#define RTCCKE 0
#define RTCCKP 0

//========================= SPI METHODS ========================================

void spi2_send(char data)
{
   char temp;
   temp = SSP2BUF;
   SSP2BUF = data;
   while(!BF);
}

char spi2_receive()
{
   char data;

   spi2_send(0);
   delay_us(5);
   data = SSP2BUF;

   return data;
}

//========================= RTC METHODS ========================================

void rtc_init()
{
   int controlState;
   
   //setup SPI
   SMP = RTCSMP;
   CKE = RTCCKE;
   CKP = RTCCKP;
   delay_ms(20);

   //start RTC
   output_high(CS_RTC);
   delay_us(10);

   //read control register
   spi2_send(0x0F);
   output_high(PIN_G4);
   controlState = spi2_receive(); // <- HERE THE PIC STALLS
   output_low(PIN_G4);
   
   //stop RTC
   delay_us(10);
   output_low(CS_RTC);

   //delay between transmissions
   delay_ms(10);
   
   //start RTC
   output_high(CS_RTC);
   delay_us(10);
   
   //disable write protection
   spi2_send(0x8F);
   spi2_send(controlState & 0xBF);

   //stop RTC
   delay_us(10);
   output_low(CS_RTC);

   //delay between transmissions
   delay_ms(10);
   
   //start RTC
   output_high(CS_RTC);
   delay_us(10);

   //set control register
   spi2_send(0x8F);
   spi2_send(0);

   //stop RTC
   delay_us(10);
   output_low(CS_RTC);
}

void init()
{
   output_high(CS_FLASH);
   output_low(CS_RTC);
   output_high(CS_DAC);
   setup_adc_ports(AN0_TO_AN6|VSS_VREF);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
   TRISD4 = 0;
   TRISD6 = 0;
   TRISD7 = 1;
   SSP2CON = 0b00100011;
   setup_timer_2(T2_DIV_BY_16,250,16);

   delay_ms(20);
   rtc_init();
}

void main()
{
   init();
   delay_ms(10);

   fprintf(USB, "\n\rRTC clock set\n\r");
   while(1)
   {
   }
}


Does anyone knows why my PIC stalls?

The PIC ceases to stall when CKE = 1, but as CKielstra said, that is not the correct setting for this device...

Cheers,
Jos
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 14, 2007 12:43 pm     Reply with quote

You're trying to do two things at one time.

1. You're trying to create your own routines to support the 2nd hardware
SPI module, presumably because you have an older version of the
compiler, which lacks support for the 2nd module.

2. You're trying to create a hardware SPI driver for the DS1305.

My advice would be to do one thing at a time. First make a hardware
SPI driver for the DS1305 that runs on the first SPI module, and use
the built-in CCS functions to do this.

Also, when you write your routines for the 2nd SPI module, you should
look at the ASM code in the .LST file that CCS generates for the 1st SPI
module. Use that code as a guide in writing your own routines.
You could just convert it to C and change the register addresses.
That would be the safest method.
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