no-software internal RTC

Current solutions and designs.
tzok
Posts: 79
Joined: Sat Dec 30, 2017 2:27 pm

Re: no-software internal RTC

Post by tzok » Sun Sep 02, 2018 8:58 pm

Today I've discovered two things:
1) bit-mask for reading hour from ds3231 is 1 bit too short, and essentially unnecessary,
2) on TOS 1.62 it is not the CONTROL.ACC what polls the IKBD clock, but... STE_FIX.PRG (despite it is only for TOS 1.06, and here it displays that it is not required for this TOS).

tzok
Posts: 79
Joined: Sat Dec 30, 2017 2:27 pm

Re: no-software internal RTC

Post by tzok » Mon Sep 03, 2018 11:21 am

Last update (hope so).

For TOS 1.x it requires STE_FIX to work, so it only works on STe with TOS 1.06 and 1.62. On TOS 2.06 it doesn't require any software, so it should work on any ST running this version of TOS.

Code after clean up:

Code: Select all

/******************************************************************
 Created with PROGRAMINO IDE for Arduino - 06.08.2018 15:23:03
 Project     : Atari ST IKBD clock injector with DS3231 RTC
 Libraries   : SoftwareSerial, Wire
 Author      : TzOk
 Description : ARD_RX0 from KB_5, ARD_TX1 to ST_5, ARD_D10 from/to KB/ST_6
******************************************************************/

#include <SoftwareSerial.h>
#include <Wire.h>

#define DS3231_ADDRESS (0x68)
#define DS3231_REG_TIME (0x00)

SoftwareSerial Ctrl(10, 11);

byte cmd;
byte inj = 255;
byte dsDate[7];
byte stDate[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC};
//                ss,   mm,   hh,   DD,   MM,   YY

void setup()
{
  Serial.begin(7812);
  Ctrl.begin(7812);
  Ctrl.listen();
  Wire.begin();
}

void loop()
{
  if (Ctrl.available())
  {
    cmd = Ctrl.read();
    if (cmd == 0x1C) // Read RTC
    {
      Wire.beginTransmission(DS3231_ADDRESS);
      Wire.write(DS3231_REG_TIME);
      Wire.endTransmission();
      Wire.requestFrom(DS3231_ADDRESS, 7);
      while(!Wire.available()) {};
      for (byte i = 6; i < 255; i--)
      {
        dsDate[i] = Wire.read();
      }
      stDate[5] = (dsDate[1] & 0x80) ? dsDate[0] + 0xA0 : dsDate[0]; // YY : if CENTURY bit is SET => stDate = dsDate + 100
      stDate[4] = dsDate[1] & 0x1F; // MM
      stDate[3] = dsDate[2]; // DD
      stDate[2] = dsDate[4] & 0x3F; // hh
      stDate[1] = dsDate[5]; // mm
      stDate[0] = dsDate[6]; // ss
      inj = 6;
    }
    else if (cmd == 0x1B) // Set RTC
    {
      for (byte i = 5; i < 255; i--)
      {
        while(!Ctrl.available()) {};
        stDate[i] = Ctrl.read();
      }
      dsDate[0] = (stDate[5] < 0xA0) ? stDate[5] : stDate[5] - 0xA0; // YY : if stDate > 99 => dsDate = stDate - 100
      dsDate[1] = (stDate[5] < 0xA0) ? stDate[4] : stDate[4] + 0x80; // MM : if stDate > 99 => set CENTURY bit
      dsDate[2] = stDate[3]; // DD
      dsDate[3] = 0x01; // Day of Week : don't care, any valid value 1-7 will be ok`
      dsDate[4] = stDate[2]; // hh
      dsDate[5] = stDate[1]; // mm
      dsDate[6] = stDate[0]; // ss
      Wire.beginTransmission(DS3231_ADDRESS);
      Wire.write(DS3231_REG_TIME);
      for (byte i = 6; i < 255; i--)
      {
        Wire.write(dsDate[i]);
      }
      Wire.endTransmission();
    }
  }
}

void serialEvent() {
  if (inj == 255)
    Serial.write(Serial.read());
  else
  {
    Serial.read();
    Serial.write(stDate[inj--]);
  }
}
Explanation why it works - IKBD firmware has a "smart" BCD (de)coding routine, thus ignores any input that has a "halfbyte" value higher than 9, yet TOS has a "dumb" BCD (de)coding routine, which makes it accept any value. What is more, values like 0xA0 are correctly interpreted as 100. Atari programmers were obviously aware of this "feature", and that's why their control panel returns correct BCD values for years 80-99, and "erroneous" BCD for values 00-79* (as 100-179). In conjunction with the way the TOS internally stores the year it all works just fine, but not with the original IKBD.

* - actually I didn't check the year span which is sent as 20xx, and I'm not sure if the control.acc itself is responsible for setting the IKBD clock or, ste_fix.prg installs some clock update handler, to update the IKBD date when TOS date is changed. It is also interesting, why they have included IKBD<->TOS clock synchronization feature in ste_fix.prg, but not in TOS 1.62.

tzok
Posts: 79
Joined: Sat Dec 30, 2017 2:27 pm

Re: no-software internal RTC

Post by tzok » Tue Sep 04, 2018 7:00 pm

It is ready...
8165213200_1536065036-800x451.jpg
8165213200_1536065036-800x451.jpg (127.27 KiB) Viewed 240 times
2757590500_1536065030-800x451.jpg
2757590500_1536065030-800x451.jpg (109.37 KiB) Viewed 240 times
... and fits inside STe:
7399977500_1536065051-800x451.jpg
7399977500_1536065051-800x451.jpg (94.62 KiB) Viewed 240 times

Edit by IngoQ: Images scaled and uploaded to forum, high-res pictures available here:

https://obrazki.elektroda.pl/8165213200_1536065036.jpg
https://obrazki.elektroda.pl/2757590500_1536065030.jpg
https://obrazki.elektroda.pl/7399977500_1536065051.jpg

troed
Trusted Guru
Trusted Guru
Posts: 450
Joined: Mon Aug 21, 2017 10:27 pm

Re: no-software internal RTC

Post by troed » Tue Sep 04, 2018 7:26 pm

tzok wrote:
Tue Sep 04, 2018 7:00 pm
It is ready...
[images]

... and fits inside STe:
[images]
Will you be selling these yourself?

Edit by IngoQ: Removed images in quote

tzok
Posts: 79
Joined: Sat Dec 30, 2017 2:27 pm

Re: no-software internal RTC

Post by tzok » Tue Sep 04, 2018 7:57 pm

If there will be interest I may make a few units, but it was intended to be a DIY project. That is why I'm using a ready to use modules, rather than a custom PCB. It requires an Arduino Mini Pro or Nano V3 (or clone) and a "DS3231 for PI" RTC breakout board. Only very basic soldering skills are required for assembling such device.

tzok
Posts: 79
Joined: Sat Dec 30, 2017 2:27 pm

Re: no-software internal RTC

Post by tzok » Tue Sep 11, 2018 2:51 pm

I've done some further tests and:
* on STf(m) with TOS 1.00 - 1.04 it works using ST Control Panel (CONTROL.ACC), Panel is used both for synchronizing ST Clock with IKBD Clock on reboot and adjusting the clock,
* on STe with TOS 1.06/1.62 using STE_FIX.PRG and STE Control Panel (CONTROL.ACC), STE_FIX is used for synchronizing ST Clock with IKBD Clock on reboot, Panel is required only for adjusting the clock,
* on STe with TOS 2.06 it works using XControl (XCONTROL.ACC), ST Clock with IKBD Clock on reboot synchronization is done by TOS itself, Panel is required only for adjusting the clock.

tzok
Posts: 79
Joined: Sat Dec 30, 2017 2:27 pm

Re: no-software internal RTC

Post by tzok » Thu Sep 13, 2018 2:45 pm

I've experimentally measured the delay introduced by my ST IKBD RTC module:
SDS00048.png
SDS00048.png (164.6 KiB) Viewed 165 times
dT = 1.28ms
For comparison - screen redraw time in color mode is 20ms.

Post Reply