No way to use the whole RAM of an RTC ?

Hi
I am now stranded for more than one month solving a RAM trouble, would You please kindly help me ?

Working on a remote low power data collector, I was enthralled to test the RTC HV-1805-C3.

In sleep mode deconnecting the Arduino’s power supply, consuming only 22 nanoAmps from a super capacitor, and providing a generous 512 bytes RAM.

Sadly, I can’t use more than 256 bytes instead of 512

According to the application manual,
https://cdn.sparkfun.com/assets/0/8/4/2 /f/RV-1805-C3_App-Manual.pdf

the RTC is providing 2 sorts of RAM.

A six bit RAM from adress 0x40 to 0x7F, in 4 partitions of 64 bytes. The 2 upper bits being provided in adress 3F by the 2 XADS bits number 0 and 1.
A seven bit RAM from adress 0x80 to 0xFF in 2 partitions of 128 bytes. The upper bit being provided in adress 3F by the XADA bit number 2.
Attached : REGISTER 0x3F and REGISTERS 0x40 – 0xFF

I am using commonplace functions to write and read the bytes.

uint8_t RV::readByteFromRegister(uint8_t address) {
 uint8_t value = 0;
 _i2cPort->beginTransmission(RV_ADDRESS);
 _i2cPort->write(address);
 _i2cPort->endTransmission(false);

 _i2cPort->requestFrom(RV_ADDRESS, 1);
 value = _i2cPort->read();
 _i2cPort->endTransmission();
///Serial.print("_"); Serial.print(address); 
 return value;
}

                    
 bool RV::writeByteToRegister(uint8_t address, uint8_t value) {
  ///Serial.print("_"); ///Serial.println(readByteFromRegister(0x3F));
  _i2cPort->beginTransmission(RV_ADDRESS);
  _i2cPort->write(address);
  _i2cPort->write(value);
  return (_i2cPort->endTransmission() == 0);
}

This test , writing 0 in the first Standard RAM partition, 1 in the second, 2 in the third and 3 in the fourth partition.

Then writing 4 in the first Alternate RAM partition and 5 in the second partition.

byte value = rtc.readByteFromRegister(0x3F);
                   
               //****************  WRITING STANDARD RAM**************************///
                   
                            value &= 0b11111100; rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<64; i++) { byte a = 64 + i; rtc.writeByteToRegister(a, 0); }
                            value = rtc.readByteFromRegister(0x3F); value |= (0b01 << 0); rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<64; i++) { byte a = 64 + i; rtc.writeByteToRegister(a, 1); }
                            value = rtc.readByteFromRegister(0x3F); value |= (0b10 << 0); rtc.writeByteToRegister(0x3F,0x2);
              for (byte i=0; i<64; i++) { byte a = 64 + i; rtc.writeByteToRegister(a, 2); }
                            value = rtc.readByteFromRegister(0x3F); value |= (0b11 << 0); rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<64; i++) {byte a = 64 +i; rtc.writeByteToRegister(a, 3); !rtc.writeByteToRegister(a+64, 9); }
              
              //*******************WRITING ALTERNATE RAM *************************///
                            value = rtc.readByteFromRegister(0x3F); value &= 0b11111011; rtc.writeByteToRegister(0x3F,value); 
              for (byte i=0; i<128; i++) {byte a = 128 + i; rtc.writeByteToRegister(a, 4);}
                            value = rtc.readByteFromRegister(0x3F); value &= 0b11111011;value |= (1 << 2); rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<128; i++) { byte a = 128 + i; rtc.writeByteToRegister(a,5 ); }

              //******************* READING STANDARD RAM *************************///

                           rtc.writeByteToRegister(0x3F,0x0); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a); } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x1); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a); } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x2); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a);  } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x3); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a);  } Serial.println(" ");

              //****************** READING ALTERNATE RAM **************************///
              
                            rtc.writeByteToRegister(0x3F,0x0); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<128; i++) { byte a = 128 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a); } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x4); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<128; i++) { byte a = 128 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a)); Serial.print("_"); Serial.print(a); } Serial.println(" ");

Attached, sheet result 1, the Alternate RAM has overwritten the Standard RAM.

If writing first the Alternate RAM and then the Standard RAM, the Alternate RAM is overwritten. Attached sheet result 2.

THE STANDARD RAM IS OVERWRITING THE ALTERNATE RAM and vice versa.

I am completely lost and wondering whether there is some magic in the chip or more probably I am doing something wrong. Can somebody help me please?

Thanks a lot.

JB

You've posted a lot of information, but you haven't posted your actual code. I suspect it's due to the fact that you are using an 8-bit value to address the ram, or it's being handled somewhere in the code as an 8 bit value, but I can't see that without taking a look at your code.

Thanks a lot Perehama

Here is my code , very short , but it's a test

 #include <Wire.h>
 #include <RV1805C3.h>
 RV1805C3 rtc;         

; 
 void testAll() {
                   byte value = rtc.readByteFromRegister(0x3F);
                                 //*******************WRITING ALTERNATE RAM *************************///
                            value = rtc.readByteFromRegister(0x3F); value &= 0b11111011; rtc.writeByteToRegister(0x3F,value); 
              for (byte i=0; i<128; i++) {byte a = 128 + i; rtc.writeByteToRegister(a, 4);}
                            value = rtc.readByteFromRegister(0x3F); value &= 0b11111011;value |= (1 << 2); rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<128; i++) { byte a = 128 + i; rtc.writeByteToRegister(a,5 ); }
                   
               //****************  WRITING STANDARD RAM**************************///
                   
                            value &= 0b11111100; rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<64; i++) { byte a = 64 + i; rtc.writeByteToRegister(a, 0); }
                            value = rtc.readByteFromRegister(0x3F); value |= (0b01 << 0); rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<64; i++) { byte a = 64 + i; rtc.writeByteToRegister(a, 1); }
                            value = rtc.readByteFromRegister(0x3F); value |= (0b10 << 0); rtc.writeByteToRegister(0x3F,0x2);
              for (byte i=0; i<64; i++) { byte a = 64 + i; rtc.writeByteToRegister(a, 2); }
                            value = rtc.readByteFromRegister(0x3F); value |= (0b11 << 0); rtc.writeByteToRegister(0x3F,value);
              for (byte i=0; i<64; i++) {byte a = 64 +i; rtc.writeByteToRegister(a, 3); !rtc.writeByteToRegister(a+64, 9); }
              


              //******************* READING STANDARD RAM *************************///

                           rtc.writeByteToRegister(0x3F,0x0); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a); } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x1); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a); } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x2); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a);  } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x3); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<64; i++) { byte a = 64 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a);  } Serial.println(" ");

              //****************** READING ALTERNATE RAM **************************///
              
                            rtc.writeByteToRegister(0x3F,0x0); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<128; i++) { byte a = 128 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a));Serial.print("_"); Serial.print(a); } Serial.println(" ");
                            rtc.writeByteToRegister(0x3F,0x4); Serial.println(rtc.readByteFromRegister(0x3F));
              for (byte i=0; i<128; i++) { byte a = 128 + i; Serial.print(","); Serial.print(rtc.readByteFromRegister(a)); Serial.print("_"); Serial.print(a); } Serial.println(" ");

              
} 

void setup() {
                Wire.begin(); Serial.begin(9600);   
                while (rtc.begin() == false) {
                      Serial.println("Failed to detect RV-1805-C3!"); delay(5000);
                }
                rtc.reset(); delay(50);// Clears previous states

                rtc.setDateTimeFromISO8601("2018-10-06T14:18:54"); Serial.print(" date  ");Serial.println(rtc.getCurrentDateTime());
               testAll(); 
                      


}
void loop() { }

I strain to understand the 8 bit implication You mention?

Note that the Ambic AM18X5 RTC is using the same RAM application.
Thanks for Your concern, I am turning mad and finding really alone, having not had any answer from MicroCrystal

You are dealing with "paged" memory. You need to set a register to point to the page you want to use. Also, you will never be able to read or write overlapping from one page to another.

Paul

Thanks Paul_KD7HB for your guidance.

In my test I am clearly setting the 0x3F register first and then providing an adress.
Am I wrong there ?

It results that a byte written to an adress > 127 is also written to an adress >64 and <128 ?
a byte written to an adress between 64 and 127 is also writen to an adress > 127 ?

I am dealing partition after partition, to prevent any overlapping.

I can’t see any other way to write or read the RAM.

Thanks.

JB

Although I can see a couple of errors in your code, I didn't notice a cause for the exact behaviour you are seeing.

I always try to remember (often unsuccessfully) to read the errata for products before I use them. In this case I don't see an errata sheet, but I do see an updated datasheet on the manufacturer's updated product page. From this I propose that the initial product documentation was more of a wish list rather than an actual product spec.

On the product page and in the datasheet:

256 bytes user RAM.

In the application manual:

Up to 512 bytes of general purpose RAM

So I think either there are different (as far as I can tell undocumented) product versions with differing RAM, or the initial documentation was a wish list, or they test each device out of manufacturing to ensure that it has at least 1 byte of working RAM so they can meet their up-to-512-bytes claim.

Sorry you burned a month on this.

Thanks a lot Arduarn for your inquisitiveness and dedication to find a sad explanation.

I burned a month but it was a valuable experience , that enables me to learn quite a few at reading a data sheet and trying to understand how memory works. My brain will stop churning and it will be a treat. And I feel less dumb if there is no evident solution.

Nonetheless I find it irresponsible from Micro Crystal to lure buyers.
I now understand why they didn’t answer my request. It’s also my fault as I should have been aware of a red light alarm. There are 2 recent libraries for this RTC and none is evoking dealing with the RAM. If even the good people at Sparkfun stay clear, there should be a reason.

I am going to contact Micro Crystal again. I’ll also ask Ambiq who is providing a very similar RTC with exactly the same RAM organization. Perhaps they’ll be more cooperative ?

Regards to my code, bet there are some errors, I cropped it a lot, removing comments and uncomments. It was sort of a christmas tree , because I tried every possible options.

Thanks also for teaching me to look for errata, lesson learnt.

Kind regards

JB

I think I see a problem with how you are handling the XADA and XADS bits of the 3Fh register in your address management.

I think you create problems with the &= routines trying to preserve existing values. I think that bit 2 (the XADA bit) can stay set when you are working with the standard RAM. This may be a problem.

Based on the data sheet, everything in the 3Fh register except the lower three bits should be 0 or is Read Only.

I like the code you use for register address setting in the reading routines. It is simple and clear. Try using it for the writing routines.

rtc.writeByteToRegister(0x3F, 0x0);
rtc.writeByteToRegister(0x3F, 0x1);
rtc.writeByteToRegister(0x3F, 0x2);
rtc.writeByteToRegister(0x3F, 0x3);

//****************** READING ALTERNATE RAM **************************///
rtc.writeByteToRegister(0x3F, 0x0);
rtc.writeByteToRegister(0x3F, 0x4);
[\code]

Thanks Cattledog

I tried the option you suggest. No change, still the same overwriting process.
I also tested the Standard RAM writing with the XADA set to 1 instead of 0. Strictly the same result.

I am more and more certain that this RTC can't handle 512 bytes, but only 256.

The chip can't refrain from considering at same time both the XADS and XADS bits, IMHO they should have been mutually exclusive.

Worse the chip doesnt lock the adress, having it happily shifting over and under 128.

I fear it's time to throw the towel?

I am seeing a way to thin my code so as not needing more than 256 bytes, and after all I can also use the EEPROM, though I am reluctant, because this memory is wearing out.

I wish I could get hold of the FRAM of the ultra low power FRAM MSP430. Cypress and friends can't stand the competition low-powerwise.

Thanks a lot Cattledog.