I'm having trouble getting sensible results from the DS1307 driver.
I've looked hard at the actual scope signals, which seem fine, and I've tested some of the functions (enabling the 32kHz oscillator and setting the square wave output) and they work fine also.
The problem is with the set time and read time (and set/read date) functions.
If I read the time, I get odd results:
time is HH:MM:SS 19:59:59
date is YY-MM-DD 59-59-59
2
time is HH:MM:SS 0:0:0
date is YY-MM-DD 0-0-0
i.e. where the hours/mins/secs are all the same, like the year/date/month.
I'm calling the functions like this:
HSerPrint "DS1307 initial report"
For LoopCounter = 1 to 20
HSerPrint LoopCounter
HSerPrintCRLF
call DS1307_ReadTime(hour, min, sec, am_pm)
HSerPrint "time is HH:MM:SS "
HSerPrint hour
HSerPrint ":"
HSerPrint min
HSerPrint ":"
HSerPrint sec
HSerPrintCRLF
Full code and transcripts are in the attachments (2 versions calling different but similar DS_1307 functions) . Further explanation can follow, but basically the code starts by setting the square-wave output function of the DS1307 20 times - so I can capture it on the oscilloscope. This works fine, the transactions are good, the DS1307 responds and the LED flashes appropriately.
The set and read time/date functions don't work.
I'm just after a short GCB program to push today's date and time into the DS1307, using a UART- ideally the PICKit3 UART tool.
Have you had a look in the demos? C:\GCstudio\gcbasic\demos\Real_Time_Clock_Solutions I think you have. There are many DS1307 demos.
if you took a demo ( a bit of the demo ) that set the date/time using bytes, so, missing out your serial string to byte conversion. Does it work? Trying to isolate what is happening.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
(thanks) - yes I've a CR2032 attached and the clock runs fine. I've an LED from SQW wave out (open drain) to the Vcc (i.e. 5V not 3V) - and when powered with 5V the LED flashes at 1Hz, as it should - but only after the chip has been configured once.
You have to check the clock using the SQW pin as just touching the 32768 xtal pins even with a 100Meg scope probe kills the oscillation.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ok, paring it right back, with no attempt to write to the part, just send it some read commands.
The time and date should have incremented as the RTC has run for a day or so.
The full files are attached, including the compiler stream (where I notice that SI2CINIT and SI2CSTART methods are mentioned?? )
But, focussing on the core of it, here's the first code to execute:
; ----- Main body of program commences here.
'Message after reset
HSerPrint "DS1307 initial report"
For LoopCounter = 1 to 20
HSerPrint LoopCounter
HSerPrintCRLF
DS1307_ReadClock(hour, min, sec, am_pm, DOW, date, month, year)
HSerPrint "time is HH:MM:SS "
HSerPrint hour
HSerPrint ":"
HSerPrint min
HSerPrint ":"
HSerPrint sec
HSerPrintCRLF
HSerPrint "date is YY-MM-DD "
HSerPrint year
HSerPrint "-"
HSerPrint month
HSerPrint "-"
HSerPrint date
HSerPrintCRLF
wait 1 sec
next
this produces the output below:
DS1307 initial report1
time is HH:MM:SS 16:56:56
date is YY-MM-DD 56-56-56
2
time is HH:MM:SS 17:57:57
date is YY-MM-DD 57-57-57
3
time is HH:MM:SS 19:59:59
date is YY-MM-DD 59-59-59
4
time is HH:MM:SS 0:0:0
date is YY-MM-DD 0-0-0
5
time is HH:MM:SS 1:1:1
date is YY-MM-DD 1-1-1
6
OK, progress, I simply switched to software I2C , and it all seems to work now.
Moreover, the previous write-time and write-date commands must have been recognised (using HW I2C) - so it was the HW I2C read commands that were failing.
Here is the transcript, showing the remnants of the earlier time and date setting, and showiung successful re-writing of time and date:
20
time is HH:MM:SS 17:36:34
date is YY-MM-DD 23-12-13
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
DATE 23 12 18
DATE 23 12 18
writing date as 23-12-18 message length was 13
new date/time is: YY-MM-DD HH:MM:SS 23-12-18 17:36:34</retn>
Go round again
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
TIME 21 31 42
TIME 21 31 42
writing time as 21:31:42 message length was 13
new date/time is: YY-MM-DD HH:MM:SS 23-12-18 21:31:42</retn>
Go round again
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
R
R</retn>
DS1307 time is HH:MM:SS 21:31:52
DS1307 date is YY-MM-DD 23-12-18
message length was 1
all the files are attached should they be of interest
Further update, same code, but different RTC module (i.e. DS1307 + xtal +battery)
the initial DS1307 reads show an illegal time:
...........................
DS1307 initial report1
time is HH:MM:SS 33:30:47
date is YY-MM-DD 23-12-13
2
time is HH:MM:SS 33:30:48
date is YY-MM-DD 23-12-13
.................................
the time would have been set at 20:31:42 by earlier code, and has incremented - apparently to an illegal value.
I can't guarantee that the time (HH) wasn't somehow mis-set to above 24h, but it's unlikely.
Certainly it is possible to set it to an illegal value - whereupon it misses the =23:59:59 to = 00:00:00 transition, in the RTC microcode.
here's transcript of setting to an illegal value:
.............................
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
TIME 31 31 42
TIME 31 31 42
writing time as 31:31:42 message length was 13
new date/time is: YY-MM-DD HH:MM:SS 23-12-13 31:31:42
..........................</retn>
Seems that the HWI2C routine in the DS1307 library are not quite right.
Re DS1307s and time keeping. I have seen many Chinese RTC that have poorly kepy time. Seems that cloning the chips and OSC does not work that well. :-(
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Interesting, yes - and I thank you for your unfailing interest - it can't be easy keeping track of the many different I2C peripherals, and the different ways in which users might address the "refer to datasheet" elements.
I tried to set-up the I2C pins properly - by using the PPS tool and the code it generates.
I'm not sure if the subsequent pin definitions are necessary (they are deemed necessary in the HI2C Overview section of helpfile) or indeed if they might contradict the previous set-up:
' Define HARDWARE I2C settings for PIC I2C peripheral
#define HI2C_DATA PORTC.1
#define HI2C_CLOCK PORTC.0
ODCONC = 0x03 ; set portC bits 0 and 1 as open-drain
I would imagine that the HW peripheral, once given its output pin mapping using PPS, would be addressed using registers that are independent of pinning.
So, I don't know why the HWI2C wants to know the pin details, it shouldn't need to.
It's one of many unknowns, I'm not asking that they all be explained - but a better understanding of what PPS does with regard to pin set-up, and what it omits to do, would be great.
On the clock accuracy, my horror story as it were, of inaccurate RTC's, was with bona-fide parts - I'll just say that if you want accuracy without grief, buy something with the crystal somehow embedded.
I did just check my two RTC's which use Alibaba DS1307's - and they're within a second of each other - about the time it took me to swap them over and write the same "current" time into both of them.
I'll be able to give better accuracy figures tomorrow, for those interested.
After that, I'll be looking at using just the read time/date functions, implemented on a 12LF1552 - which has HW I2C - though I might try with and without.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The PPS is needed if a PPS chip. The best way to check if a specific chip is a PPS chip... use PICINFO - if the PPS button is active then it is a PPS chip, also, PICINFO shows PPS information in the tabs.
I await your 12LF1552 implementation - there always could be issues in the library functions. The architecture of the GCBASIC implementation follows. These layers are intended to make support easier keeping the interfaces separate from hardware libraries.
OK, got it - you use #ifdef (HWI2C_DATA) in all sorts of libraries as a boolean, to use either the SWI2C or HWI2C driver instructions. Critically, you don't (seem to) use the port and pin information if its a HW peripheral - and it is therefore totally the responsibility of the programmer to set-up the pins correctly. This is all the information I need - it's a programmer job, and the compiler is not duplicating the efforts elsewhere.
For the 18F05 part used here, I need to define the PPS registers, and also to manually set the open-drain register? Don' know, I haven't got it working.
For the SW I2C, I'm not quite sure what "programmer" needs to do - since SDA needs to be used as input and output, SCL as output only, and both should be open-drain (i.e. driving the TRIS bits not the port bits) - this can't be set-up statically.
So, is it the case that pinning for SWI2C is down to the compiler - alone - it is given just the port.pin definition and sorts out TRIS and PORT and Latch (if implemented) correctly. .?
And conversely, for HWI2C, is pinning is the programmer responsibility, for PPS, TRIS, Open-drain [ODCONC] - because these are intentionally unknown by the driver...?
Is it true that the HWI2C treats the pin definitions as Booleans only? - it's defined somehow, or it's not.
I'm not at all campaigning for one approach or another - I only need clarity as to what the drivers do, and what they omit to do, and therefore what is required from me, and what is superfluous and therefore risky.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You have a good understanding on how GCBASIC uses conditional compilation to change the behaviour of the compilation process.
The same process ( different constants ) are used to control I2C, SPI and many other low level drivers.
With respect to HardWare I2C ( and many functional module ) once the hardware is enable then port setting is not required ( in the majority of chips ).
With respect to PPS. This is specific to PPS enabled chips and PPSTool should set the OpenDrain if required. But, PPSTool is not perfect and if you are in doubt then check the datasheet or use the Microchip standalone MCC tool.
RE SW I2C. The low level library handles the bi-directional port. Essentially, it does all the heavy lifting. Setting DIR ( TRIS ) as required. The compiler not the library resolves and use LATch when required.
RE HW I2C and ODCONC. I would have to check with Microchip but I believe, from my experience over many years, that ODCONC is essentially controlled by the enablement of I2C ( and other modules like SPI ). I have not had to use ODCONC with respect to HWI2C or HWSPI.
No problem in asking how this all works. If my understanding is incorrect ( it probalbly is :-) ) then let me know. If we can improve GCBASIC in terms of documentation or the compiler then we should based upon these insights.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If you want to see more.. in Preferences Editor / Compiler tab - check Create CDF.
The Conditional Definition File shows the Constants and the scripts being processed during compilation. It shows the following:
CODE/Constant - constants defined in a user program or library
SCRIPT/AddConstant constants defined in a #script/#endscript construct
SCRIPT/CurrentValue - constants already defined then redefined in another #script/#endscript construct CHECKSYSVARDEF - expansion of a mutli-condition conditional test.
Remainder of reports the user program or libraries code remaining post conditional processing.
It is a large file but the details of each constant and its use can be understood in the CDF.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That is a great insight into the fascinating mechanics of compilers - and the existence of a compiler "log" file is a revelation. It looks to solve my recurrent problem of "what is it actually doing?"
I tried to deconstruct Arduino code, to look at what functions called other functions, which in turn call yet more others - but at four levels down it was still expanding and I gave up.
A "compiler log" file would have taken out much of the manual look-up work, and GCB has it, brilliant. What I'm after is like the DOS "tree" command - but showing the sub-code dependencies, and bottoming them out.
The reason for this was to try and avoid the "works great when it works, but if it doesn't you're stumped" sort of problem.
Would it be possible to get the compiler to draw-up a "tree" ?
Other points covered next.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
On the subject of pin-definitions to enable HW peripherals, like I2C, it seems to be a three-way thing between the HW itself, the compiler, and the user program. There is a need for clarity and your post above is a great help.
Generally, there is a "priority of function" pertaining to each I/O pin - and enabling complex peripherals will over-trump general GPIO usage. This implies that TRIS, PORT and LATch registers are overridden and cannot be mis-set - which in turn implies that they don't need to be explicitly set by the user program.
There are complexities, like pins set-up for analog usage versus digital - and possible conflicts. See attached PIC 12LF1552 datasheet extract. The priorities vary in a complex manner which I've yet to decode into principles.
I'm glad you agree, we see a similar confused landscape. I seek to understand what PPS defines and what it leaves to the user-program (or compiler).
The PIC 18F05/Q40 says the following, on P394 of datasheet: Important: The pin locations for SDA and SCL are remappable through the Peripheral Pin Select (PPS)
registers. If new pin locations for SDA and SCL are desired, user software must configure the INLVLx,
SLRCONx, ODCONx, and TRISx registers for each new pin location. The RxyI2C registers cannot be
used since they are dedicated to the default pin locations. Additionally, the internal pull-ups for non-I2C
pins are not strong enough to drive the pins; therefore, external pull-up resistors must be used.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Finally, RTC performance of China-sourced DS1307 chips, and 32768Hz crystals.
Firstly, I cannot tell if the DS1307 chips are original, functionally equivalent, or counterfeit.
To me, counterfeit can be a prejudicial term for an entirely legal functional equivalent, or even a superior. It is allowed to make a "white-room" functional equivalent IC, look at Intel vs AMD, and it keeps the market-leader honest.
My results so far with unadjusted RTC and crystal are:
Sample #1:
+1.54 seconds per day [+19ppm] (+9.4 minutes per year)
Sample #2:
+2.3 seconds per day [+28ppm] (+14 minutes per year)
This is measured over a 7-day period, with 3x8mm leaded 32.768 kHz crystal.
I think they are good figures, the China-sourced parts are not at all dreadful. I'm not sure what ppm the crystals were claiming - I'll try next with some better-defined xtals, if anyone's interested.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
To adjust the frequency you have to put a small capacitor in parallel to the quartz, try with 5pF NP0 must be good quality otherwise it varies a lot with the temperature.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks Gigi, you are correct in identifying the crystal capacitive loading as the parameter that needs to be adjusted.
I've not seen parallel capacitance mentioned before, and I'm not sure it would work - normally it is two capacitors to ground that need to be adjusted.
This can't be done properly with any old sample crystal - the crystal itself might be 5ppm "sharp" - i.e. within tolerance but not "bang-on". If you adjust the capacitors for this one, you will bias the 32kHz frequency to one side, across a population of similar crystals.
What normally happens is that you get calibrated samples from the manufacturer, let's say 32,767.4Hz, and you adjust the loading till you get the same frequency as they measured. At that point, your loading capacitors are perfect and the parts will form a distribution centred on zero error.
It is quite a lot of work - hence my advice to use an integrated-crystal if you're not going for huge mass-production.
The point I was intending to make was simply that the RTC is pretty good without any adjustment - and the China-sourced parts aren't all bad.
I wouldn't want to guarantee any tolerances for mass-production, based on my sample of 2 parts - both of which run slow (so it's probable that my loading capacitances are a bit off...).
It's just a data point, a real measurement - it was surprisingly good actually - but it carries no statistical weight.
I might try again with better ppm crystals, but in truth, I doubt if my PC clock is any better than 20ppm - this generates the timestamp. The PC clock could easily be 40ppm out, but it gets updated to GMT every once in a while. This introduces errors that need a very long timebase - like a month - to eliminate.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, the problem is the capacity of the quartz which is not correct, so with a few Pico farads in parallel you can improve without having to resort to a better chip. I have used this system on some DS1302s and they have been working well for many years.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have been using the DS3231 for some time.
The quartz is integrated into the chip and they have a very high precision (2ppm) and stability that absolutely cannot be compared to the DS1307.
The module also has an AT24C32 EEPROM which can always be useful.
After the winter (so after several months of having set the time) I checked the time in the garden sprinkler in which I used the DS3231 with a clock connected to the DCF77 and the difference was less than a second.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm having trouble getting sensible results from the DS1307 driver.
I've looked hard at the actual scope signals, which seem fine, and I've tested some of the functions (enabling the 32kHz oscillator and setting the square wave output) and they work fine also.
The problem is with the set time and read time (and set/read date) functions.
If I read the time, I get odd results:
time is HH:MM:SS 19:59:59
date is YY-MM-DD 59-59-59
2
time is HH:MM:SS 0:0:0
date is YY-MM-DD 0-0-0
i.e. where the hours/mins/secs are all the same, like the year/date/month.
I'm calling the functions like this:
HSerPrint "DS1307 initial report"
For LoopCounter = 1 to 20
HSerPrint LoopCounter
HSerPrintCRLF
call DS1307_ReadTime(hour, min, sec, am_pm)
HSerPrint "time is HH:MM:SS "
HSerPrint hour
HSerPrint ":"
HSerPrint min
HSerPrint ":"
HSerPrint sec
HSerPrintCRLF
Full code and transcripts are in the attachments (2 versions calling different but similar DS_1307 functions) . Further explanation can follow, but basically the code starts by setting the square-wave output function of the DS1307 20 times - so I can capture it on the oscilloscope. This works fine, the transactions are good, the DS1307 responds and the LED flashes appropriately.
The set and read time/date functions don't work.
I'm just after a short GCB program to push today's date and time into the DS1307, using a UART- ideally the PICKit3 UART tool.
Any help appreciated.
Have you had a look in the demos? C:\GCstudio\gcbasic\demos\Real_Time_Clock_Solutions I think you have. There are many DS1307 demos.
if you took a demo ( a bit of the demo ) that set the date/time using bytes, so, missing out your serial string to byte conversion. Does it work? Trying to isolate what is happening.
Just checking...
Have you got a battery attached? I have it in mind the clock may not start if not. I seem to recall having a similar problem a few years ago.
(thanks) - yes I've a CR2032 attached and the clock runs fine. I've an LED from SQW wave out (open drain) to the Vcc (i.e. 5V not 3V) - and when powered with 5V the LED flashes at 1Hz, as it should - but only after the chip has been configured once.
You have to check the clock using the SQW pin as just touching the 32768 xtal pins even with a 100Meg scope probe kills the oscillation.
Oh, and just checked, with Vcc off, the LED connected to the 3V cell only, it flashes at 1Hz
Ok, paring it right back, with no attempt to write to the part, just send it some read commands.
The time and date should have incremented as the RTC has run for a day or so.
The full files are attached, including the compiler stream (where I notice that SI2CINIT and SI2CSTART methods are mentioned?? )
But, focussing on the core of it, here's the first code to execute:
; ----- Main body of program commences here.
'Message after reset
HSerPrint "DS1307 initial report"
For LoopCounter = 1 to 20
HSerPrint LoopCounter
HSerPrintCRLF
DS1307_ReadClock(hour, min, sec, am_pm, DOW, date, month, year)
HSerPrint "time is HH:MM:SS "
HSerPrint hour
HSerPrint ":"
HSerPrint min
HSerPrint ":"
HSerPrint sec
HSerPrintCRLF
HSerPrint "date is YY-MM-DD "
HSerPrint year
HSerPrint "-"
HSerPrint month
HSerPrint "-"
HSerPrint date
HSerPrintCRLF
wait 1 sec
next
this produces the output below:
DS1307 initial report1
time is HH:MM:SS 16:56:56
date is YY-MM-DD 56-56-56
2
time is HH:MM:SS 17:57:57
date is YY-MM-DD 57-57-57
3
time is HH:MM:SS 19:59:59
date is YY-MM-DD 59-59-59
4
time is HH:MM:SS 0:0:0
date is YY-MM-DD 0-0-0
5
time is HH:MM:SS 1:1:1
date is YY-MM-DD 1-1-1
6
It doesn't make sense.
OK, progress, I simply switched to software I2C , and it all seems to work now.
Moreover, the previous write-time and write-date commands must have been recognised (using HW I2C) - so it was the HW I2C read commands that were failing.
Here is the transcript, showing the remnants of the earlier time and date setting, and showiung successful re-writing of time and date:
20
time is HH:MM:SS 17:36:34
date is YY-MM-DD 23-12-13
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
DATE 23 12 18
DATE 23 12 18
writing date as 23-12-18 message length was 13
new date/time is: YY-MM-DD HH:MM:SS 23-12-18 17:36:34</retn>
Go round again
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
TIME 21 31 42
TIME 21 31 42
writing time as 21:31:42 message length was 13
new date/time is: YY-MM-DD HH:MM:SS 23-12-18 21:31:42</retn>
Go round again
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
R
R</retn>
DS1307 time is HH:MM:SS 21:31:52
DS1307 date is YY-MM-DD 23-12-18
message length was 1
all the files are attached should they be of interest
Further update, same code, but different RTC module (i.e. DS1307 + xtal +battery)
the initial DS1307 reads show an illegal time:
...........................
DS1307 initial report1
time is HH:MM:SS 33:30:47
date is YY-MM-DD 23-12-13
2
time is HH:MM:SS 33:30:48
date is YY-MM-DD 23-12-13
.................................
the time would have been set at 20:31:42 by earlier code, and has incremented - apparently to an illegal value.
I can't guarantee that the time (HH) wasn't somehow mis-set to above 24h, but it's unlikely.
Certainly it is possible to set it to an illegal value - whereupon it misses the =23:59:59 to = 00:00:00 transition, in the RTC microcode.
here's transcript of setting to an illegal value:
.............................
Set TIME as 'TIME HH MM SS'
or Set DATE as 'DATE YY MM DD'
or hit R <retn> for the RTC live values
TIME 31 31 42
TIME 31 31 42
writing time as 31:31:42 message length was 13
new date/time is: YY-MM-DD HH:MM:SS 23-12-13 31:31:42
..........................</retn>
Interesting.
Seems that the HWI2C routine in the DS1307 library are not quite right.
Re DS1307s and time keeping. I have seen many Chinese RTC that have poorly kepy time. Seems that cloning the chips and OSC does not work that well. :-(
Interesting, yes - and I thank you for your unfailing interest - it can't be easy keeping track of the many different I2C peripherals, and the different ways in which users might address the "refer to datasheet" elements.
I tried to set-up the I2C pins properly - by using the PPS tool and the code it generates.
I'm not sure if the subsequent pin definitions are necessary (they are deemed necessary in the HI2C Overview section of helpfile) or indeed if they might contradict the previous set-up:
I would imagine that the HW peripheral, once given its output pin mapping using PPS, would be addressed using registers that are independent of pinning.
So, I don't know why the HWI2C wants to know the pin details, it shouldn't need to.
It's one of many unknowns, I'm not asking that they all be explained - but a better understanding of what PPS does with regard to pin set-up, and what it omits to do, would be great.
On the clock accuracy, my horror story as it were, of inaccurate RTC's, was with bona-fide parts - I'll just say that if you want accuracy without grief, buy something with the crystal somehow embedded.
I did just check my two RTC's which use Alibaba DS1307's - and they're within a second of each other - about the time it took me to swap them over and write the same "current" time into both of them.
I'll be able to give better accuracy figures tomorrow, for those interested.
After that, I'll be looking at using just the read time/date functions, implemented on a 12LF1552 - which has HW I2C - though I might try with and without.
Sounds like you are having fun.
The following IS required.
HI2C_DATA
is key. This is used in many, many low level libraries to determine if HW or SW I2C is being used.The PPS is needed if a PPS chip. The best way to check if a specific chip is a PPS chip... use PICINFO - if the PPS button is active then it is a PPS chip, also, PICINFO shows PPS information in the tabs.
I await your 12LF1552 implementation - there always could be issues in the library functions. The architecture of the GCBASIC implementation follows. These layers are intended to make support easier keeping the interfaces separate from hardware libraries.
Ask questions. I am here to help.
OK, got it - you use #ifdef (HWI2C_DATA) in all sorts of libraries as a boolean, to use either the SWI2C or HWI2C driver instructions. Critically, you don't (seem to) use the port and pin information if its a HW peripheral - and it is therefore totally the responsibility of the programmer to set-up the pins correctly. This is all the information I need - it's a programmer job, and the compiler is not duplicating the efforts elsewhere.
For the 18F05 part used here, I need to define the PPS registers, and also to manually set the open-drain register? Don' know, I haven't got it working.
For the SW I2C, I'm not quite sure what "programmer" needs to do - since SDA needs to be used as input and output, SCL as output only, and both should be open-drain (i.e. driving the TRIS bits not the port bits) - this can't be set-up statically.
So, is it the case that pinning for SWI2C is down to the compiler - alone - it is given just the port.pin definition and sorts out TRIS and PORT and Latch (if implemented) correctly. .?
And conversely, for HWI2C, is pinning is the programmer responsibility, for PPS, TRIS, Open-drain [ODCONC] - because these are intentionally unknown by the driver...?
Is it true that the HWI2C treats the pin definitions as Booleans only? - it's defined somehow, or it's not.
I'm not at all campaigning for one approach or another - I only need clarity as to what the drivers do, and what they omit to do, and therefore what is required from me, and what is superfluous and therefore risky.
You have a good understanding on how GCBASIC uses conditional compilation to change the behaviour of the compilation process.
The same process ( different constants ) are used to control I2C, SPI and many other low level drivers.
With respect to HardWare I2C ( and many functional module ) once the hardware is enable then port setting is not required ( in the majority of chips ).
With respect to PPS. This is specific to PPS enabled chips and PPSTool should set the OpenDrain if required. But, PPSTool is not perfect and if you are in doubt then check the datasheet or use the Microchip standalone MCC tool.
RE SW I2C. The low level library handles the bi-directional port. Essentially, it does all the heavy lifting. Setting DIR ( TRIS ) as required. The compiler not the library resolves and use LATch when required.
RE HW I2C and ODCONC. I would have to check with Microchip but I believe, from my experience over many years, that ODCONC is essentially controlled by the enablement of I2C ( and other modules like SPI ). I have not had to use ODCONC with respect to HWI2C or HWSPI.
No problem in asking how this all works. If my understanding is incorrect ( it probalbly is :-) ) then let me know. If we can improve GCBASIC in terms of documentation or the compiler then we should based upon these insights.
If you want to see more.. in Preferences Editor / Compiler tab - check Create CDF.
The Conditional Definition File shows the Constants and the scripts being processed during compilation. It shows the following:
CODE/Constant - constants defined in a user program or library
SCRIPT/AddConstant constants defined in a #script/#endscript construct
SCRIPT/CurrentValue - constants already defined then redefined in another #script/#endscript construct
CHECKSYSVARDEF - expansion of a mutli-condition conditional test.
Remainder of reports the user program or libraries code remaining post conditional processing.
It is a large file but the details of each constant and its use can be understood in the CDF.
That is a great insight into the fascinating mechanics of compilers - and the existence of a compiler "log" file is a revelation. It looks to solve my recurrent problem of "what is it actually doing?"
I tried to deconstruct Arduino code, to look at what functions called other functions, which in turn call yet more others - but at four levels down it was still expanding and I gave up.
A "compiler log" file would have taken out much of the manual look-up work, and GCB has it, brilliant. What I'm after is like the DOS "tree" command - but showing the sub-code dependencies, and bottoming them out.
The reason for this was to try and avoid the "works great when it works, but if it doesn't you're stumped" sort of problem.
Would it be possible to get the compiler to draw-up a "tree" ?
Other points covered next.
You have the HTML file and that has all the use subs and from this you can build your own map solution.
If you need help, ping me
On the subject of pin-definitions to enable HW peripherals, like I2C, it seems to be a three-way thing between the HW itself, the compiler, and the user program. There is a need for clarity and your post above is a great help.
Generally, there is a "priority of function" pertaining to each I/O pin - and enabling complex peripherals will over-trump general GPIO usage. This implies that TRIS, PORT and LATch registers are overridden and cannot be mis-set - which in turn implies that they don't need to be explicitly set by the user program.
There are complexities, like pins set-up for analog usage versus digital - and possible conflicts. See attached PIC 12LF1552 datasheet extract. The priorities vary in a complex manner which I've yet to decode into principles.
Agree. Add to this complexity PPS. It adds another layer of 'priority'.
I'm glad you agree, we see a similar confused landscape. I seek to understand what PPS defines and what it leaves to the user-program (or compiler).
The PIC 18F05/Q40 says the following, on P394 of datasheet:
Important: The pin locations for SDA and SCL are remappable through the Peripheral Pin Select (PPS)
registers. If new pin locations for SDA and SCL are desired, user software must configure the INLVLx,
SLRCONx, ODCONx, and TRISx registers for each new pin location. The RxyI2C registers cannot be
used since they are dedicated to the default pin locations. Additionally, the internal pull-ups for non-I2C
pins are not strong enough to drive the pins; therefore, external pull-up resistors must be used.
Finally, RTC performance of China-sourced DS1307 chips, and 32768Hz crystals.
Firstly, I cannot tell if the DS1307 chips are original, functionally equivalent, or counterfeit.
To me, counterfeit can be a prejudicial term for an entirely legal functional equivalent, or even a superior. It is allowed to make a "white-room" functional equivalent IC, look at Intel vs AMD, and it keeps the market-leader honest.
My results so far with unadjusted RTC and crystal are:
Sample #1:
+1.54 seconds per day [+19ppm] (+9.4 minutes per year)
Sample #2:
+2.3 seconds per day [+28ppm] (+14 minutes per year)
This is measured over a 7-day period, with 3x8mm leaded 32.768 kHz crystal.
I think they are good figures, the China-sourced parts are not at all dreadful. I'm not sure what ppm the crystals were claiming - I'll try next with some better-defined xtals, if anyone's interested.
To adjust the frequency you have to put a small capacitor in parallel to the quartz, try with 5pF NP0 must be good quality otherwise it varies a lot with the temperature.
Thanks Gigi, you are correct in identifying the crystal capacitive loading as the parameter that needs to be adjusted.
I've not seen parallel capacitance mentioned before, and I'm not sure it would work - normally it is two capacitors to ground that need to be adjusted.
This can't be done properly with any old sample crystal - the crystal itself might be 5ppm "sharp" - i.e. within tolerance but not "bang-on". If you adjust the capacitors for this one, you will bias the 32kHz frequency to one side, across a population of similar crystals.
What normally happens is that you get calibrated samples from the manufacturer, let's say 32,767.4Hz, and you adjust the loading till you get the same frequency as they measured. At that point, your loading capacitors are perfect and the parts will form a distribution centred on zero error.
It is quite a lot of work - hence my advice to use an integrated-crystal if you're not going for huge mass-production.
The point I was intending to make was simply that the RTC is pretty good without any adjustment - and the China-sourced parts aren't all bad.
I wouldn't want to guarantee any tolerances for mass-production, based on my sample of 2 parts - both of which run slow (so it's probable that my loading capacitances are a bit off...).
It's just a data point, a real measurement - it was surprisingly good actually - but it carries no statistical weight.
I might try again with better ppm crystals, but in truth, I doubt if my PC clock is any better than 20ppm - this generates the timestamp. The PC clock could easily be 40ppm out, but it gets updated to GMT every once in a while. This introduces errors that need a very long timebase - like a month - to eliminate.
Yes, the problem is the capacity of the quartz which is not correct, so with a few Pico farads in parallel you can improve without having to resort to a better chip. I have used this system on some DS1302s and they have been working well for many years.
I have been using the DS3231 for some time.
The quartz is integrated into the chip and they have a very high precision (2ppm) and stability that absolutely cannot be compared to the DS1307.
The module also has an AT24C32 EEPROM which can always be useful.
After the winter (so after several months of having set the time) I checked the time in the garden sprinkler in which I used the DS3231 with a clock connected to the DCF77 and the difference was less than a second.