|
|
View previous topic :: View next topic |
Author |
Message |
eyewonder300
Joined: 09 Jun 2004 Posts: 52
|
DS1305 Alarm 0 set-up |
Posted: Wed Mar 30, 2005 8:20 am |
|
|
I am having problems making the DS1305 interrupt work. I want to have the RTC interrupt every second, and to be able to use the user RAM area for non-volatile storage of on-going data collection. I 'seem' to be correctly selecting/writing the SPI to the RTC, but data from user ram is not getting back correctly, so writting the control stuff is probably not making it there, either.
BTW, I have this on a PC Prototype w/w board, with the 32kHz xtal sitting on top of the DS1305 chip.
I will check back this evening, and will replay to all help offered.
Steve
Code: | // DS1305.h
// The file to setup & control the DS1305 RTC, as
// used in the Fuel Management Project
struct rtc_pin_map { // This structure is overlayed
int unused1:2; // on to Port C to gain
BOOLEAN ce; // access to the RTC chip enable.
int data : 5; //
} dsrtc;
#byte dsrtc = 7 // 7 is Port C
void RTC_INIT()
{
dsrtc.ce = 1; // select the RTC
spi_write(0x8F); // the control add of RTC
spi_write(0); // clear the WP bit
dsrtc.ce = 0; // drop the select
dsrtc.ce = 1; // select the RTC
spi_write(0x80); // the start of clock setting registers
spi_write(0); // set seconds to 0
spi_write(0); // set minutes to 0
spi_write(0); // set hours to 0
spi_write(0); // set day to 0
spi_write(0); // set date to 0
spi_write(0); // set month to 0
spi_write(0); // set year to 0
dsrtc.ce = 0; // drop the select
dsrtc.ce = 1; // select the RTC
spi_write(0x87); // the start of Alarm 0 registers
spi_write(0x80); // set mask bits to alarm at 1 sec intervals
spi_write(0x80); //
spi_write(0x80); //
spi_write(0x80); //
dsrtc.ce = 0; // drop the select
dsrtc.ce = 1; // select the RTC
spi_write(0x8F); // the control add of RTC
spi_write(0b00000101); // Oscillator on, enable Alarm 0 interrupt, 1-sec
dsrtc.ce = 0; // drop the select
}
void rtc_clear() // clears the 1-sec interrupt from Alarm 0
{
int temp, i;
dsrtc.ce = 1; // select RTC
spi_write(0x90); // read starting address
for(i=0;i<16;i++)
temp = spi_read(); // clear the interrupt flag bit
dsrtc.ce = 0; // drop the select
}
// Fuel_1.c
#include <16f877A.H>
#FUSES HS,NOPROTECT,NOWDT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
//#FUSES HS,NOPROTECT,NOWDT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,DEBUG
#use delay(clock=10000000)
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
#include "noritake_1.h"
#include "DS1305.h"
#int_ext // the RB0 (1-sec timer) interrupt
void one_second_tic()
{
rtc_init(); // ready for next 1-sec interrupt
}
void main()
{
byte temp_dat;
set_tris_a(0b010000); // supply transducer input
set_tris_b(0xFF); // Port B all inputs
set_tris_c(0b10010011); // set SPI, RTC CE, & RS232
set_tris_e(0b111); // all pins to outputs
output_low(pin_e0); // out 'test flags' for reading RTC
output_low(pin_e1);
output_low(pin_e2);
dsrtc.ce = 0;
delay_ms(300);
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64);
// setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_4);
// setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
enable_interrupts(global);
enable_interrupts(int_ext);
RTC_INIT();
vfd_init();
vfd_putc("Hello, Steve");
vfd_gotoxy(1,2);
vfd_putc("Testing RTC");
delay_ms(2000);
vfd_putc("\f"); // clear the display
dsrtc = 1; // select the RTC
delay_us(2);
spi_write(0xAA); // an address in user RAM
delay_us(2);
spi_write(0xcc); // some value, to test
delay_us(2);
dsrtc = 0;
dsrtc = 1;
delay_us(2);
spi_write(0x2A); // read the address we just wrote
delay_us(2);
temp_dat = spi_read();
dsrtc = 0;
output_high(pin_e0); // flag showing we made it here
if(temp_dat == 0xcc) // out test pattern written to user ram
{
output_high(pin_e1);
vfd_putc("Matched OK");
}
else
{
output_high(pin_e2);
vfd_putc("BAD READ!");
}
while(TRUE);
}
|
|
|
|
drh
Joined: 12 Jul 2004 Posts: 192 Location: Hemet, California USA
|
|
Posted: Wed Mar 30, 2005 1:13 pm |
|
|
The DS1035 datasheet shows a minimum CE inactive time of 1uS (@ 5V). If you have a 10Mhz osc., you need to add some delay between back to back writes. _________________ David |
|
|
eyewonder300
Joined: 09 Jun 2004 Posts: 52
|
|
Posted: Wed Mar 30, 2005 9:40 pm |
|
|
Tried putting 100uSec delays between ALL actions (writes and reads), with no success. Broke out the 'scope & confirmed xtal was oscillating ~100mV at 32kHz on pins 3 & 4, that PIC pin RC4 (SDI) was connected to RTC pin 13 (SDO), PIC pin RC5 (SDO) was connected to RTC pin 12 (SDI), PIC pin 18 (SCK) was connected to RTC pin 11 (SCLK) , and that RTC pin 9 (SERMODE) was connected to Vcc.
I will try manually setting SSPCON reg , to see if I can come up with anything that works. In the meantime, any further ideas are appreciated.
Thanks,
Steve |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Mar 31, 2005 4:33 pm |
|
|
Check your two calls to spi_read().
spi_read() without parameter only gives you the last received character from the SPI register, no clock pulses are generated! So either precede it with a call to spi_write(data) or use spi_read(data) in order to generate clock pulses and receive new data. |
|
|
eyewonder300
Joined: 09 Jun 2004 Posts: 52
|
Still no joy. |
Posted: Thu Mar 31, 2005 10:00 pm |
|
|
Put some dummy data in the 'spi_read(dummy)', but still did not work. I have tried all 8 combinations of clock polarity, clock select, and sample bit - see code.
I had the DS1305 wired up: 3v coin cell bat to VBat (pin 2), +5vdc to pin 16, VccIF (pin 14) , and sermode (pin 9). Vcc2 (pin 1) is grounded.
Used my logic probe to look at pins on the DS1305 during my attempts, and found that CE, SDI, & SCLK were pulsing, but SDO was NOT. Logic probe showed neither a hi or low, which on my probe usually means a floating pin. Reconfirmed that I did have continuity from the SDO pin to PIC SDI.
OK, so I changed the connection to sermode to ground, which should be a 3-wire configuration. Re-ran my code, and found that DS1305 SDO was now pulsing, but I was still not able to read anything but 0x00.
Reconfigured sermode to SPI, tried again, and still no joy.
Bad IC? And yes, I will grab at any straw floating by on this ocean.
Steve
Code: | // Fuel_1.c
#include <16f877A.H>
#FUSES HS,NOPROTECT,NOWDT,NOBROWNOUT,NOLVP,NOCPD,NOWRT
//#FUSES HS,NOPROTECT,NOWDT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,DEBUG
#use delay(clock=10000000)
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
#include "noritake_1.h"
#include "DS1305.h"
void write_one()
{
int temp_dat, dummy;
dummy = 0x33;
dsrtc = 1; // select the RTC
delay_us(10);
spi_write(0xAA); // an address in user RAM
spi_write(0xcc); // some value, to test
dsrtc = 0;
delay_us(10);
dsrtc = 1;
delay_us(10);
spi_write(0x2A); // read the address we just wrote
temp_dat = spi_read(0x33);
dsrtc = 0;
vfd_gotoxy(1,2);
vfd_putc("Read: ");
printf(vfd_putc,"%u",temp_dat);
vfd_putc(" ");
if(temp_dat == 0xcc) // out test pattern written to user ram
vfd_putc("Matched OK");
else
vfd_putc("BAD READ!");
}
void main()
{
#use fast_io(C)
set_tris_c(0b10010011); // set SPI, RTC CE, Return Xducer, & RS232
dsrtc.ce = 0;
delay_ms(300);
vfd_init();
vfd_putc("Hello, Steve");
vfd_gotoxy(1,2);
vfd_putc("Testing RTC");
delay_ms(2000);
config_master_spi_0();
RTC_INIT();
vfd_putc("\fUsing Master-0");
write_one();
delay_ms(3000);
config_master_spi_1();
RTC_INIT();
vfd_putc("\fUsing Master-1");
write_one();
delay_ms(3000);
config_master_spi_2();
RTC_INIT();
vfd_putc("\fUsing Master-2");
write_one();
delay_ms(3000);
config_master_spi_3();
RTC_INIT();
vfd_putc("\fUsing Master-3");
write_one();
delay_ms(3000);
config_master_spi_4();
RTC_INIT();
vfd_putc("\fUsing Master-4");
write_one();
delay_ms(3000);
config_master_spi_5();
RTC_INIT();
vfd_putc("\fUsing Master-5");
write_one();
delay_ms(3000);
config_master_spi_6();
RTC_INIT();
vfd_putc("\fUsing Master-6");
write_one();
delay_ms(3000);
config_master_spi_7();
RTC_INIT();
vfd_putc("\fUsing Master-7");
write_one();
delay_ms(3000);
while(TRUE);
}
// DS1305.h
// The file to setup & control the DS1305 RTC, as
// used in the Fuel Management Project
struct rtc_pin_map { // This structure is overlayed
int unused1:2; // on to Port C to gain
BOOLEAN ce; // access to the RTC chip enable.
int data : 5; //
} dsrtc;
#byte dsrtc = 7 // 7 is Port C
struct spi_sspcon {
int mode: 4;
boolean ckp;
boolean sspen;
boolean sspov;
boolean wcol;
}SSPCON ;
#byte SSPCON = 0x14
struct spi_sspstat {
boolean bf;
boolean ua;
boolean rw_;
boolean s;
boolean p;
boolean da_;
boolean cke;
boolean smp;
}SSPSTAT ;
#byte SSPSTAT = 0x94
void config_master_spi_0() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 0; // Clock polarity: idle is low
SSPSTAT.cke = 0; // xmit on clock idle -> active
SSPSTAT.smp = 0; // input data sampled in middle of output time
SSPCON.sspen = 1; // now enable SSP
}
void config_master_spi_1() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 1; // Clock polarity: idle is high
SSPSTAT.cke = 0; // xmit on clock idle -> active
SSPSTAT.smp = 0; // input data sampled in middle of output time
SSPCON.sspen = 1; // now enable SSP
}
void config_master_spi_2() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 0; // Clock polarity: idle is low
SSPSTAT.cke = 1; // xmit on clock active -> idle
SSPSTAT.smp = 0; // input data sampled in middle of output time
SSPCON.sspen = 1; // now enable SSP
}
void config_master_spi_3() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 1; // Clock polarity: idle is high
SSPSTAT.cke = 1; // xmit on clock active -> idle
SSPSTAT.smp = 0; // input data sampled in middle of output time
SSPCON.sspen = 1; // now enable SSP
}
void config_master_spi_4() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 0; // Clock polarity: idle is low
SSPSTAT.cke = 0; // xmit on clock idle -> active
SSPSTAT.smp = 1; // input data sampled at end of output time
SSPCON.sspen = 1; // now enable SSP
}
void config_master_spi_5() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 1; // Clock polarity: idle is high
SSPSTAT.cke = 0; // xmit on clock idle -> active
SSPSTAT.smp = 1; // input data sampled at end of output time
SSPCON.sspen = 1; // now enable SSP
}
void config_master_spi_6() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 0; // Clock polarity: idle is low
SSPSTAT.cke = 1; // xmit on clock active -> idle
SSPSTAT.smp = 1; // input data sampled at end of output time
SSPCON.sspen = 1; // now enable SSP
}
void config_master_spi_7() // set up the control PIC for SPI Master
{
SSPCON.sspen = 0; // disable SSP during setup
SSPCON.mode = 2; // Master, Fosc/64
SSPCON.ckp = 1; // Clock polarity: idle is high
SSPSTAT.cke = 1; // xmit on clock active -> idle
SSPSTAT.smp = 1; // input data sampled at end of output time
SSPCON.sspen = 1; // now enable SSP
}
void RTC_INIT()
{
dsrtc.ce = 1; // select the RTC
delay_us(10);
spi_write(0x8F); // the control add of RTC
spi_write(0); // clear the WP bit
dsrtc.ce = 0; // drop the select
delay_us(10);
dsrtc.ce = 1; // select the RTC
delay_us(10);
dsrtc.ce = 1; // select the RTC
delay_us(10);
spi_write(0x8F); // the control add of RTC
spi_write(0); // clear the WP bit
dsrtc.ce = 0; // drop the select
delay_us(10);
dsrtc.ce = 1; // select the RTC
delay_us(10);
spi_write(0x80); // the start of clock setting registers
spi_write(0); // set seconds to 0
spi_write(0); // set minutes to 0
spi_write(0); // set hours to 0
spi_write(0); // set day to 0
spi_write(0); // set date to 0
spi_write(0); // set month to 0
spi_write(0); // set year to 0
dsrtc.ce = 0; // drop the select
delay_us(10);
}
|
|
|
|
|
|
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
|