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

Reading seconds value from ds1307 skipping with dspic30f4013
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ahmed-agt



Joined: 24 Oct 2014
Posts: 9

View user's profile Send private message

This is one of the suggested solution!
PostPosted: Tue Nov 13, 2018 9:14 am     Reply with quote

Ttelmah wrote:
Simple answer then, switch to using software I2C. On your chip this will make no difference at all (software can give over a MHz on a chip at this speed), and will fix the issue.

Using a software I2C instead of a hardware I2C, this can be done by adding the option FORCE_SW to your #use i2c() line as stated by CCS Support.
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Tue Nov 13, 2018 9:23 am     Reply with quote

Which is why I suggested it.
ahmed-agt



Joined: 24 Oct 2014
Posts: 9

View user's profile Send private message

The second solution using the hardware I2C.
PostPosted: Tue Nov 13, 2018 9:33 am     Reply with quote

The second option is to add a read of the I2CRCV
register before the first call to i2c_read() in your ds1307_read() function, for example changing
your ds1307_read() function the following:


Code:
void ds1307_read()
{
  #byte I2CRCV = getenv("SFR:I2CRCV")   
  unsigned int8 temp;

  i2c_start(); // Start I2C
  i2c_write(0xD0); // DS1307 address
  i2c_write(0x00); // Send register address
 
  i2c_start(); // Restart I2C
  i2c_write(0xD1); // Initialize data read
 
  temp = I2CRCV;
 
  second =i2c_read(1); // Read seconds from register 0  second
  minute =i2c_read(1); // Read minuts from register 1
  hour = i2c_read(1); // Read hour from register 2
  day = i2c_read(1); // Read day from register 3
  date = i2c_read(1); // Read date from register 4
  month = i2c_read(1); // Read month from register 5
  year = i2c_read(0); // Read year from register 6
  i2c_stop(); // Stop I2C
}


Finally, reading and copying the I2CRCV register to a temp RAM location before using the register solve the problem. These work for me!

Thanks you all for your support.
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Tue Nov 13, 2018 9:42 am     Reply with quote

I actually wonder if his problem is errata 13 for this chip. It appears that the output latch bit on the SDA pin overrides the I2C peripheral, so this pin must be set low for the hardware I2C to work correctly. Problem is this has to be done before enabling the I2C, so one would have to use 'NOINIT' in the #use I2C, then set this pin low, and call I2C_init.
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

Re: The second solution using the hardware I2C.
PostPosted: Tue Nov 13, 2018 1:23 pm     Reply with quote

ahmed-agt wrote:
The second option is to add a read of the I2CRCV
register before the first call to i2c_read() in your ds1307_read() function, for example changing
your ds1307_read() function the following:


Code:
void ds1307_read()
{
  #byte I2CRCV = getenv("SFR:I2CRCV")   
  unsigned int8 temp;

  i2c_start(); // Start I2C
  i2c_write(0xD0); // DS1307 address
  i2c_write(0x00); // Send register address
 
  i2c_start(); // Restart I2C
  i2c_write(0xD1); // Initialize data read
 
  temp = I2CRCV;
 
  second =i2c_read(1); // Read seconds from register 0  second
  minute =i2c_read(1); // Read minuts from register 1
  hour = i2c_read(1); // Read hour from register 2
  day = i2c_read(1); // Read day from register 3
  date = i2c_read(1); // Read date from register 4
  month = i2c_read(1); // Read month from register 5
  year = i2c_read(0); // Read year from register 6
  i2c_stop(); // Stop I2C
}


Finally, reading and copying the I2CRCV register to a temp RAM location before using the register solve the problem. These work for me!

Thanks you all for your support.


Interesting finding.
On the SPI, the register is meant to work this way, and the first SPI_read, will return what is already in the register, if there is a value in it, rather than performing a transfer, so you have to ensure the register is read before performing a request.
I2C though is not meant to behave this way and certainly does not for me on a lot of transfers.
It suggests that in this particular case, either because of an oddity in the DS chip or the PIC peripheral, it is functioning this way.
Definitely worth trying. Smile
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Nov 14, 2018 6:18 am     Reply with quote

been following this thread with interest.... and a couple comments.

1..I've never had a problem using the DS1307 with several types of PIC (46k22 being the latest) and since a LOT of people use it and the CCS driver, we'd have heard about this before so I suspect the OP's PIC.

2) I'd like to know what happens if 'seconds' are not read. Say start with 'minutes'. Does the 'minutes' come back as '00' ? If so try reading JUST 'hours' (or any one register), does that come back as '00' ? If so Only the 1st time or always ?

My projects with RTC all use the RTC to send an interrupt at a 1Hz rate, a 'heartbeat', to then have main() read sensors, update the local LCD and do some 'control'. I cannot recall ever seeing bad data from the RTC.

Assuming the devices are next to each other and proper pullups, I can't see any hardware issues.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Wed Nov 14, 2018 6:58 am     Reply with quote

One comment to this (which is why I suggested adding a delay earlier), the DS1307, only supports slow I2C, and has a longer delay between a repeated start, or a stop and a restart, than the standard I2C 'spec. It requires 4.7uSec between such events. Now on a normal PIC at a few MHz, this won't be a problem, but on the DsPIC at speed it is likely that extra delays _will_ be needed.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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