RetroBSD
http://retrobsd.org/

Bitbanged I2C driver for RTC - in SmallerC?
http://retrobsd.org/viewtopic.php?f=5&t=37275
Page 1 of 2

Author:  Pito [ Sat Sep 12, 2015 4:35 pm ]
Post subject:  Bitbanged I2C driver for RTC - in SmallerC?

Hi, long time back I created a driver for RTC, which works fine in retrobsd, however it was compiled under Uecide (and the binary transferred to filesystem, used with cron). The i2cscan based on it is here for example:

viewtopic.php?f=5&t=37092&p=41251&hilit=rtc#p41250

May be experts may have a look at it and evaluate whether it could be compiled under latest SmallerC or not.

It includes pins.c (bitbanged i/o) and i2c.h (i2c bitbanged "driver") and read/write to PCF8563T RTC (could be changed easily to any DSxxxx RTC).

Enclosed find the files.
P.

Attachments:
rtcwrite8563.rar [4.26 KiB]
Downloaded 923 times
rtcread8563.rar [4.2 KiB]
Downloaded 517 times

Author:  wiz [ Sat Sep 12, 2015 9:37 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Hi Pito,

Nice.... I had to upgrade unrar but was able to extract archive.

Might be nicer to use zip or gzip?

Wiz

Author:  alexfru [ Sat Sep 12, 2015 11:15 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Pito wrote:
Hi, long time back I created a driver for RTC, which works fine in retrobsd, however it was compiled under Uecide (and the binary transferred to filesystem, used with cron).

May be experts may have a look at it and evaluate whether it could be compiled under latest SmallerC or not.


Well, the preprocessor runs out of memory when expanding PUTC() in _dxprnt(). But if you simply use the standard printf() and don't include prxntf.h, both read and write compile without any other modifications.

Author:  Pito [ Sun Sep 13, 2015 5:16 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Enclosed the zip with the drivers, currently for PCF8563T RTC.
Compiled with SmallerC (autobuild v356 fubarino), not tested with HW yet (but it worked in past) :)
Put the stuff into a folder, ie. /rtc, and run "make".

Author:  Pito [ Sun Sep 13, 2015 6:09 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

UPDATE:
Added i2cscan (prints out all i2c devices attached), and split i2c.h into i2c.h and 8563.h for easier handling.

Attachments:
rtc8563_i2cscan.zip [34.77 KiB]
Downloaded 519 times

Author:  vak [ Mon Sep 14, 2015 7:52 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

It makes sense to consider putting this stuff inside the kernel, so the regular date/time facilities can use it.

Author:  Pito [ Tue Sep 15, 2015 5:58 am ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Before that, maybe reading the RTC with the rtcXXXXrd and "inserting the date and time" into appropriate system variable(s) within the rtcXXXXrd would be a good move too. So we must not call the "date" in cron, but the rtcXXXXrd only..

Author:  wiz [ Thu Sep 17, 2015 5:38 am ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Hi Serge and all,

"It makes sense to include this driver in the kernel".

<rant>

I can't resist the temptation to point out again that implementing some sort of kernel loadable module would keep the kernel MUCH smaller and make adding, modifying and developing hardware drivers MUCH easier.

</rant.

Lots of fun :).

Wiz

Author:  vak [ Thu Sep 17, 2015 6:28 am ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Hi Wiz,
wiz wrote:
I can't resist the temptation to point out again that implementing some sort of kernel loadable module would keep the kernel MUCH smaller and make adding, modifying and developing hardware drivers MUCH easier.

I completely agree with you.
Loadable drivers would help _much_.
Technically it's possible, but quite complicated. As we have almost no space in kernel RAM, it requires to design some method of storing drivers in Flash memory, and exposing them as file entries in the root filesystem.
I just want to note, that I personally do not plan to work on this task in the forseable future (a year at least).

Regards,
--Serge

Author:  Pito [ Thu Sep 17, 2015 3:24 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

I would not mess with kernel. Maybe we have to focus on bug fixing and creating a reliable dev environment.
Waiting on single chip serial 8pin sram/fram/mram with 16Mbit capacity.
The ramdisk for swap is a signifficant improvement!
Currently only 4Mbit mrams/frams available so you need 4 of them for 2MB of swap.
"With enough quantity, you invent quality" :)

Author:  wiz [ Thu Sep 17, 2015 7:56 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Hi Serge and all,

Actually there is quite a bit of 'unused' ram in the kernel space of RetroBSD.

Plenty for driver development for me :).

I have a piece at zero for debugger/burn the chip use. And then a much bigger piece at the top of kernel ram.

I suspect there is LOTS more available if any real attempt is made to minimize kernel ram use.

I am NOT offering to do that. LOTS of work with LOTS of risks :).

My RF driver loads a part into RAM so the code works fast enough. [ram has 2 wait states verses flash which is much slower.]

Lots of fun.

Wiz

Author:  Pito [ Tue Sep 22, 2015 8:29 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

UPDATE
Added DS3231 High precision RTC

Small edits

Code:
# ls
DS3231.h     i2c.h        pins.h       rtc8563rd    rtc8563wr.c
Makefile     i2cscan      rtc3231rd.c  rtc8563rd.c
PCF8563.h    i2cscan.c    rtc3231wr.c  rtc8563wr
# make clean
rm -f *.o *~ rtc8563rd rtc8563wr i2cscan rtc3231rd rtc3231wr
# make
cc  -o rtc8563rd  rtc8563rd.c
cc  -o rtc8563wr  rtc8563wr.c
cc  -o i2cscan  i2cscan.c
cc  -o rtc3231rd  rtc3231rd.c
cc  -o rtc3231wr  rtc3231wr.c
#


Not tested in HW yet.

Attachments:
ds3231_pcf8563_i2cscan.zip [36.38 KiB]
Downloaded 517 times

Author:  Pito [ Wed Sep 23, 2015 7:44 am ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Hi, I want to change the system time and date directly in the rtcXXXXwr.c, thus I must not call "date" in the cron.
My naive understanding how to do it is as follows:
1. create epoch time from the ss, mn, hh,... we get the params from the RTC
2. read minuteswest param for the timezone (ie. -60 is MET)
3. insert the epoch time and minuteswest into time structure, like:
Code:
..
#include <sys/time.h>
..
// Time starts for RetroBSD on 1970-1-1
const unsigned int EPOCH_YEAR = 1970;
// Days since Epoch
unsigned int daysSinceEpoch(unsigned int y, unsigned int m, unsigned int d) {
  if (m < 3) {
    m += 12;
    y--;
  }
  return (365 * (y + 1 - EPOCH_YEAR)  + y / 4 - (EPOCH_YEAR - 1) / 4
    + (153 * m - 2) / 5 + d - 398);
}
// Seconds since Epoch */
unsigned int secondsSinceEpoch(unsigned int year, unsigned int month, unsigned int day,
                           unsigned int hour, unsigned int minute, unsigned int second) {
  unsigned int days = daysSinceEpoch(year, month, day);
  return (second + 60 * (minute + 60 * (hour + 24 * days));
}
..
unsigned int epoch_time = secondsSinceEpoch(yy, cm, dd, hh, mn, ss); // comes from RTC's regs
..
    struct timeval now;
    struct timezone tz;
 
    now.tv_sec = epoch_time;  // in seconds since 1970-1-1
    now.tv_usec = 0;

    tz.tz_minuteswest = mwest;  // ie. mwest = -60 is MET

    if(settimeofday(&now, &tz) == 0) {
        printf("settimeofday() successful..\r\n");
    }
    else {
        printf("settimeofday() failed..\r\n");
        return -1;
    }
..

Am I somehow correct?
So, for example:
Code:
rtc3231rd -60

writes RTC's date and time into system (as MET), and prints it out as well.

Code:
rtc3231wr 15 09 24 08 55 32

sets the DS3231 with a date and time.

Author:  Pito [ Thu Sep 24, 2015 11:15 am ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

It works in HW too :)
Module with DS3231 and serial flash, fubarino pin2=SDA, pin3=SCL, 2x10k pullups.

Code:
# ./i2cscan
I2C dev found, adr(r/w): 57(AF/AE)  68(D1/D0)
# ./rtc3231wr 15 09 24 13 09 50
# ./rtc3231rd
1509241309.58
# ./rtc3231rd
1509241310.22
# ./rtc3231rd
1509241311.13
#


Code:
# date
Mon Sep 21 14:18:10 PST 2015
# ./rtc3231rd | xargs date
Thu Sep 24 13:23:42 PST 2015
#


Code:
# ./rtc3231rd | xargs date -t -60
Thu Sep 24 13:26:28 MET 2015
#


Edit rc
Code:
..
rm -f /etc/nologin

/bin/i2cscan
echo -n "RTC: "
/bin/rtc3231rd
date  -t -60 `/bin/rtc3231rd`
echo -n "Starting daemons:"
update && echo -n "update"
cron && echo -n "cron"
echo

#/etc/rc.local
exit 0

and reboot:
Code:
..
sd0: type SDHC, size 3872256 kbytes, speed 13 Mbit/sec
phys mem  = 128 kbytes
user mem  = 96 kbytes
root dev  = rd0a (0,1)
root size = 102400 kbytes
swap dev  = rd0b (0,2)
swap size = 2048 kbytes
/dev/rd0a: 1371 files, 14119 used, 87880 free
I2C dev found, adr(r/w): 57(AF/AE)  68(D1/D0)
RTC:  1509241343.19
Thu Sep 24 13:43:19 MET 2015
Starting daemons: update cron


2.11 BSD UNIX (pic32) (console)

login: root
Password:
Welcome to RetroBSD!
erase ^?, kill ^U, intr ^C
# date
Thu Sep 24 13:43:27 MET 2015
#


And with the cron for updating the system time twice an hour:
Code:
# cd /etc
# cat > aaa
29,59 * * * * date -t -60 `/bin/rtc3231rd`
# cat aaa
29,59 * * * * date -t -60 `/bin/rtc3231rd`
# crontab aaa
# crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (aaa installed on Thu Sep 24 14:01:22 2015)
# (Cron version -- @(#) crontab.c 2.13.1 (2.11BSD) 1999/8/9)
29,59 * * * * date -t -60 `/bin/rtc3231rd`
#

And to verify it works (after a reboot):
Code:
# cd var
# ls
cron  lock  log   run
# cd log
# cat messages
..
<37>September 24 14:03:03 login: ROOT LOGIN ON console
<78>September 24 14:29:00 CRON[23]: (root) CMD (date -t -60 `/bin/rtc3231rd`)

<37>September 24 14:29:01 date: date set by root
<78>September 24 14:29:01 CRON[22]: (root) MAIL (mailed 29 bytes of output but got status 0x0001
)

Author:  Pito [ Thu Sep 24, 2015 7:19 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

And the direct writing of the RTC's date and time to OS (you do not need "date"):
Code:
// rtc3231rd2os.c
// Simple DS3231 RTC READING
// Sets the RetroBSD system time
// Use: rtc3231rd2os minuteswest
// minuteswest is a time difference from GMT towards West in minutes
// ie. "rtc3231rd2os -60" takes GMT time (out of your DS3231) and sets the MET timezone
// Epochtime is the GMT unix time (as set in your DS3231)
// Compiled under SmallerC
// Pito 9/2015

unsigned char decToBcd(unsigned char val){
   return ( (val/10*16) + (val%10) );
}

unsigned char bcdToDec(unsigned char val){
   return ( (val/16*10) + (val%16) );
}

unsigned char hh, mn, ss, yy, mm, dd, wd, cm;

#include "i2c.h"
#include "DS3231.h"
#include <sys/time.h>

// Time starts for RetroBSD on 1970-1-1
const int EPOCH_YEAR = 1970;
// Days since Epoch
int daysSinceEpoch(int y, int m, int d) {
   y = y + 2000;
   if (m < 3) {
   m += 12;
   y--;
  }
   return (365 * (y + 1 - EPOCH_YEAR)  + y / 4 - (EPOCH_YEAR - 1) / 4
   + (153 * m - 2) / 5 + d - 398);
}
// Seconds since Epoch */
int secondsSinceEpoch(int year,
            int month,
            int day,
            int hour,
            int minute,
            int second) {
  int days = daysSinceEpoch(year, month, day);
  return (second + 60 * (minute + 60 * (hour + 24 * days)));
}


int main (int argc, char **argv)
{
   int epoch_time;
   
   struct timeval now;
   struct timezone tz;
   
   int mwest;
   
   mwest = atoi(argv[1]);
   
   // init the pins driver !!
   if (pinsinit() < 0) return -1;
   // init i2c driver
   I2CInit();

   if (DS3231_Read()< 0){
      printf("### RTC NOT AVAILABLE!\n");
      pinsclose();
      return -1;
   }

   ss = bcdToDec(ss & 0x7F);
   mn = bcdToDec(mn & 0x7F);
   hh = bcdToDec(hh & 0x3F);
   dd = bcdToDec(dd & 0x3F);
   wd = bcdToDec(wd & 0x07);
   cm = bcdToDec(cm & 0x1F);
   yy = bcdToDec(yy);
   
   epoch_time = secondsSinceEpoch(yy, cm, dd, hh, mn, ss); // comes from RTC's regs
   
   now.tv_sec = (long)(epoch_time);  // in seconds since 1970-1-1
   now.tv_usec = 0L;  // ??? what to do with these useconds ???

   tz.tz_minuteswest = mwest;  // ie. mwest = -60 is MET

   if(settimeofday(&now, &tz) == 0) {
        printf("..settimeofday() successful..\r\n");
   }
   else {
        printf("..settimeofday() failed..\r\n");
        return -1;
   }
   printf("Epochtime %d\r\n", epoch_time);
   //printf("%02d%02d%02d%02d%02d.%02d\n",yy,cm,dd,hh,mn,ss);

   pinsclose();

   return 0;
}

Mind your RTC DS3231 must be set to GMT time!
Code:
# date
Thu Sep 24 21:36:33 MET 2015
# date -t -600 1010101010.10
Sun Oct 10 10:10:10 EST 2010
# date
Sun Oct 10 10:10:13 EST 2010
# rtc3231rd2os -60
..settimeofday() successful..
Epochtime 1443127044
# date
Thu Sep 24 21:37:26 MET 2015
#

Author:  vak [ Thu Sep 24, 2015 7:30 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Perfect!
Now it makes sense to integrate it into the standard /bin/date utility.
The question is how to parameterize it to make it generic enough.
It should be able to handle different pin assignments.
In future, when i2c driver available, it should use it as well.

Author:  Pito [ Thu Sep 24, 2015 7:59 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Still thinking about following - how to sync the os time via cron with the RTC properly??
It seems to me it is not as easy as I've done it :)
Otherwise the new time may jump +/- 1sec plus any delays with the rtc reading call..

Code:
# crontab -l
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (aaa installed on Thu Sep 24 22:03:39 2015)
# (Cron version -- @(#) crontab.c 2.13.1 (2.11BSD) 1999/8/9)
29,59 * * * * /bin/rtc3231rd2os -60 > /dev/null


Imagine you are going to measure the neutrino speed with a system based on retrobsd. You can get faster-than-speed-of-light-neutrinos easily :lol:

Author:  Pito [ Sat Sep 26, 2015 7:30 am ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

BTW, the DS3231 drivers can be used for the DS1307 "oldtimer" as well, without any changes 8-)

UPDATE: attached find the latest sources..

Code:
# time make
cc  -o rtc8563rd  rtc8563rd.c
cc  -o rtc8563wr  rtc8563wr.c
cc  -o rtc8563rd2os  rtc8563rd2os.c
cc  -o rtc3231rd  rtc3231rd.c
cc  -o rtc3231wr  rtc3231wr.c
cc  -o rtc3231rd2os  rtc3231rd2os.c
cc  -o i2cscan  i2cscan.c
       17.9 real         2.8 user        10.0 sys
#


Attachments:
ds3231_ds1307_pcf8563_i2cscan.zip [7.78 KiB]
Downloaded 488 times

Author:  Pito [ Sat Sep 26, 2015 10:35 am ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

And when reading GY-80 (10DOF module) and the RTC module.
Code:
# ./i2cscan
I2C dev found, adr(r/w): 1E(3D/3C)  53(A7/A6)  57(AF/AE)  68(D1/D0)  69(D3/D2)  77(EF/EE)


68 - DS3231 rtc
57 - flash eeprom
77 - BMP085 barometer
53 - ADXL345 - 3 axis accelerometer
1E - HMC5883L - 3 axis magnetometer
69 - L3G4200 - 3 axis gyro

Author:  wiz [ Sat Sep 26, 2015 7:27 pm ]
Post subject:  Re: Bitbanged I2C driver for RTC - in SmallerC?

Hi Serge,

I can't remember how to make a new topic, so I guess this will have to do?

Regards LiteBSD on Explorer 16 board, I was looking at my Explorer 16 and realized that it is very difficult to hook things to it. Ugh. Still, I will get the module and see if I can get Lite BSD running on it. And try to use that as a platform to get the 64 pin version of the chip up and running?

It occurs to me that it would be very nice to have a version of LiteBSD which runs on the 64 pin version of PIC32MZ...EF.

Does this seem easy to you?

I bet one could wire that chip 'dead bug' style and have a simple LiteBSD breadboard? I didn't see that any samples were available, but if you think LiteBSD 'should' run on the 64 pin version, I will probably order a few and see what I can come up with.

Lots of fun.

Wiz

Page 1 of 2 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/