/* * ******************************************************************** * Initialization of a new 12887A to replace a 1287A in a Gridcase 1520 * ******************************************************************** * * Set the date and time, use BDC mode, 24h clock * If the oscillator is stopped, write start pattern to register A * Write 0x00 to all bytes from 0x0e to 0x7f (0x3f for a DS1287A) * Then put 12887A in grid 1520 * The computer should boot normally and write the configuration to * the 12887A ram * You can use this program to take a look at the configuration data afterwards * Just make sure to comment out the initialization block otherwise you will * overwrite the configuration data with 0x00s * * Interfacing the 1287A/12887A to the Arduino * * 1287A/12887A pin Arduino * ---- ------ * 1 (MOT) GND * 4 (AD0) I/O pin 2 * 5 (AD1) I/O pin 3 * 6 (AD2) I/O pin 4 * 7 (AD3) I/O pin 5 * 8 (AD4) I/O pin 6 * 9 (AD5) I/O pin 7 * 10 (AD6) I/O pin 8 * 11 (AD7) I/O pin 9 * 12 (GND) GND * 13 (CS) GND * 14 (AS) I/O pin 11 * 15 (R/W) I/O pin 12 * 17 (DS) I/O pin 14 * 18 (RESET) VCC * 24 (VCC) VCC * * If you use the CS line, wire it to I/O pin 10 of the Arduino * I chose to wire the CS pin to GND (always selected) but I left the code * to control the CS line - beware, it is untested at this point * * Sylvain Parent, 2018 */ // DS12887 ADDRESS REGISTERS const byte REGISTER_SECONDS = B00000000; // Seconds const byte REGISTER_SECONDS_ALARM = B00000001; // Seconds alarm const byte REGISTER_MINUTES = B00000010; // Minutes const byte REGISTER_MINUTES_ALARM = B00000011; // Minutes alarm const byte REGISTER_HOURS = B00000100; // Hours const byte REGISTER_HOURS_ALARM = B00000101; // Hours alarm const byte REGISTER_DOW = B00000110; // Day of week const byte REGISTER_DOM = B00000111; // Day of month const byte REGISTER_MONTH = B00001000; // Month const byte REGISTER_YEAR = B00001001; // Year const byte REGISTER_A = B00001010; // REGISTER A const byte REGISTER_B = B00001011; // REGISTER B const byte REGISTER_C = B00001100; // REGISTER C const byte REGISTER_D = B00001101; // REGISTER D const byte START = B00100000; // Start oscillator pattern byte dataPins[8] = {2, 3, 4, 5, 6, 7, 8, 9}; // dataPins = AD0 - AD7 byte CS = 10; // SELECT CHIP byte AS = 11; // STROBE ADDRESS byte WR = 12; // HIGH READ LOW WRITE byte DS = 14; // READ byte seconds, asecs, minutes, amins, hours, ahours; byte dow, dom, month, year; byte regA, regB, regC, regD; void switchRead() { for (int i=0; i<=7; i++) { pinMode(dataPins[i], INPUT_PULLUP); } return; } void switchWrite() { for (int i=0; i<=7; i++) { pinMode(dataPins[i], OUTPUT); } return; } byte readBusData() { byte dataBuffer = B00000000; for (int i=0; i<=7; i++) { bitWrite(dataBuffer, i, digitalRead(dataPins[i])); } return dataBuffer; } void writeBusData(byte data) { for (int i=0; i<8; i++) { digitalWrite(dataPins[i], bitRead(data, i)); } return; } byte getRegisterData(byte registerAddr) { byte dataBuffer = B00000000; digitalWrite(CS, LOW); //select the chip digitalWrite(DS, HIGH); //ds/rw high delayMicroseconds(10); digitalWrite(AS, HIGH); //as high switchWrite(); writeBusData(registerAddr); delayMicroseconds(100); digitalWrite(AS, LOW); //latch the address switchRead(); delayMicroseconds(100); digitalWrite(DS, LOW); //data strobe delayMicroseconds(10); dataBuffer = readBusData(); digitalWrite(DS, HIGH); digitalWrite(AS, HIGH); digitalWrite(CS, HIGH); //unselect the chip return dataBuffer; } void writeRegisterData(byte registerAddr, byte registerData) { digitalWrite(CS, LOW); //select the chip digitalWrite(WR, HIGH); digitalWrite(DS, HIGH); //ds/rw high switchWrite(); writeBusData(registerAddr); delayMicroseconds(100); digitalWrite(AS, LOW); //latch the address delayMicroseconds(100); writeBusData(registerData); delayMicroseconds(10); digitalWrite(WR, LOW); //enter write mode delayMicroseconds(10); digitalWrite(WR, HIGH); //write the data digitalWrite(AS, HIGH); return; } void getRTCDate() { minutes = getRegisterData(REGISTER_MINUTES); seconds = getRegisterData(REGISTER_SECONDS); hours = getRegisterData(REGISTER_HOURS); dow = getRegisterData(REGISTER_DOW); dom = getRegisterData(REGISTER_DOM); month = getRegisterData(REGISTER_MONTH); year = getRegisterData(REGISTER_YEAR); return; } void setup() { byte x; pinMode(CS, OUTPUT); pinMode(AS, OUTPUT); pinMode(WR, OUTPUT); pinMode(DS, OUTPUT); digitalWrite(CS, HIGH); digitalWrite(AS, HIGH); digitalWrite(WR, HIGH); digitalWrite(DS, HIGH); delayMicroseconds(200); /* Initialization block will run only once since it is in the setup() code * Set bit SET (control register B) * Set the date and time, use BDC mode, 24h clock * Write start pattern to register A * Unset bit SET * Write 0x00 to all bytes from 0x0e to 0x7f (use 0x3f for a DS1287A) */ switchWrite(); for (x=0x0e;x<=0x7f;x++) { writeRegisterData(x, 0x00); } writeRegisterData(REGISTER_B, 0x82); // bit SET high, mode 24h BCD writeRegisterData(REGISTER_SECONDS, 0x00); // 0 secondes writeRegisterData(REGISTER_MINUTES, 0x09); // 09 minutes writeRegisterData(REGISTER_HOURS, 0x22); // 22h writeRegisterData(REGISTER_DOW, 0x07); // saturday writeRegisterData(REGISTER_DOM, 0x31); // 31 writeRegisterData(REGISTER_MONTH, 0x01); // january writeRegisterData(REGISTER_YEAR, 0x98); // 1998 (keep the year valid for DOS) writeRegisterData(REGISTER_A, START); writeRegisterData(REGISTER_B, 0x02); // bit SET low, mode 24h BCD writeRegisterData(REGISTER_C, 0x00); // no interrup needed // end of initialization block // Comment out the initialization block if you want only to read the chip switchRead(); Serial.begin(115200); return; } void loop() { byte x, data; getRTCDate(); Serial.print("("); Serial.print(dow, HEX); Serial.print(") "); Serial.print(month, HEX); Serial.print("/"); Serial.print(dom, HEX); Serial.print("/"); Serial.print(year, HEX); Serial.print(" "); Serial.print(hours, HEX); Serial.print(":"); Serial.print(minutes, HEX); Serial.print("."); Serial.println(seconds, HEX); delay(500); for (x=0x0a;x<=0x7f;x++) { data = getRegisterData(x); Serial.print(x, HEX); Serial.print(" - "); Serial.println(data, HEX); } delay(60000); }