Skip to content

Commit

Permalink
Merge pull request #4 from SV-Zanshin/Block-read-and-write-to-SRAM
Browse files Browse the repository at this point in the history
Changed readRAM() and writeRAM()
  • Loading branch information
SV-Zanshin authored Aug 8, 2017
2 parents 21a5305 + 7360f57 commit 33552e4
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 44 deletions.
107 changes: 107 additions & 0 deletions Examples/AccessMemory/AccessMemory.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*******************************************************************************************************************
** Example program for using the MCP7940 library which demonstrates writing to and reading from the 64 bytes of **
** RAM available to the user on the chip. The readRAM() and writeRAM() functions accept any data type and this **
** example will accept characters typed in on the serial port and write them byte-by-bytte to RAM. Then the whole **
** character array is read and displayed with one readRAM() function call. **
** The library as well as the most current version of this program is available at GitHub using the address **
** https://github.com/SV-Zanshin/MCP7940 and a more detailed description of this program (and the library) can be **
** found at https://github.com/SV-Zanshin/MCP7940/wiki/SetAndCalibrate.ino **
** **
** The MCP7940 library uses the standard SPI Wire library for communications with the RTC chip and has also used **
** the class definitions of the standard RTClib library from Adafruit/Jeelabs. The data sheet for the MCP7940M is **
** located at http://ww1.microchip.com/downloads/en/DeviceDoc/20002292B.pdf. The MCP7940N has extra functionality **
** revolving around battery backup but this library's functionality covers that chip as well. **
** **
** On-chip digital trimming can be used to adjust for frequency variance caused by crystal tolerance and **
** temperature. Since the chip only output full seconds, a calibration cycle won't be effective until there is at **
** least one second difference between the RTC time and real time, and this might take a day or more to do, **
** particularly if the RTC and crystal is already close to being accurate. **
** **
** This program is free software: you can redistribute it and/or modify it under the terms of the GNU General **
** Public License as published by the Free Software Foundation, either version 3 of the License, or (at your **
** option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY **
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
** GNU General Public License for more details. You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
** **
** Vers. Date Developer Comments **
** ====== ========== =================== ======================================================================== **
** 1.0.0 2017-08-08 [email protected] Initial coding **
** **
*******************************************************************************************************************/
#include <MCP7940.h> // Include the MCP7940 RTC library //
/*******************************************************************************************************************
** Declare all program constants **
*******************************************************************************************************************/
const uint32_t SERIAL_SPEED = 115200; // Set the baud rate for Serial I/O //
const uint8_t LED_PIN = 13; // Arduino built-in LED pin number //
const uint8_t SPRINTF_BUFFER_SIZE = 32; // Buffer size for sprintf() //
/*******************************************************************************************************************
** Declare global variables and instantiate classes **
*******************************************************************************************************************/
MCP7940_Class MCP7940; // Create an instance of the MCP7940//
char inputBuffer[SPRINTF_BUFFER_SIZE]; // Buffer for sprintf()/sscanf() //
/*******************************************************************************************************************
** Method Setup(). This is an Arduino IDE method which is called upon boot or restart. It is only called one time **
** and then control goes to the main loop, which loop indefinately. **
*******************************************************************************************************************/
void setup() { // Arduino standard setup method //
Serial.begin(SERIAL_SPEED); // Start serial port at Baud rate //
#ifdef __AVR_ATmega32U4__ // If this is a 32U4 processor, then//
delay(3000); // wait 3 seconds for the serial //
#endif // interface to initialize //
Serial.print(F("\nStarting AccessMemory program\n")); // Show program information //
Serial.print(F("- Compiled with c++ version ")); // //
Serial.print(F(__VERSION__)); // Show compiler information //
Serial.print(F("\n- On ")); // //
Serial.print(F(__DATE__)); // //
Serial.print(F(" at ")); // //
Serial.print(F(__TIME__)); // //
Serial.print(F("\n")); // //
while (!MCP7940.begin()) { // Initialize RTC communications //
Serial.println(F("Unable to find MCP7940M. Checking again in 3s.")); // Show error text //
delay(3000); // wait a second //
} // of loop until device is located // //
Serial.println(F("MCP7940 initialized.")); // //
while (!MCP7940.deviceStatus()) { // Turn oscillator on if necessary //
Serial.println(F("Oscillator is off, turning it on.")); // //
bool deviceStatus = MCP7940.deviceStart(); // Start oscillator and return state//
if (!deviceStatus) { // If it didn't start //
Serial.println(F("Oscillator did not start, trying again.")); // Show error and //
delay(1000); // wait for a second //
} // of if-then oscillator didn't start // //
} // of while the oscillator is off // //
MCP7940.adjust(); // Set to library compile Date/Time //
Serial.println(F("Enter any text in the serial monitor and hit send")); // //
pinMode(LED_PIN,OUTPUT); // Declare built-in LED as output //
} // of method setup() // //

/*******************************************************************************************************************
** This is the main program for the Arduino IDE, it is an infinite loop and keeps on repeating. **
*******************************************************************************************************************/
void loop() { // //
static uint8_t secs; // store the seconds value //
static uint8_t memoryAddress = 0; // //
DateTime now = MCP7940.now(); // get the current time //
if (secs != now.second()) { // Output if seconds have changed //
sprintf(inputBuffer,"%04d-%02d-%02d %02d:%02d:%02d", now.year(), // Use sprintf() to pretty print //
now.month(), now.day(), now.hour(), now.minute(), now.second()); // date/time with leading zeros //
if (secs%10==0) Serial.println(inputBuffer); // Only Display every 10 seconds //
secs = now.second(); // Set the counter variable //
digitalWrite(LED_PIN,!digitalRead(LED_PIN)); // Toggle the LED //
} // of if the seconds have changed // //
if (Serial.available()) { // Check for serial port data //
uint8_t dataByte = Serial.read(); // read the byte from serial //
if (dataByte==0x0A) { // If the user hit return/enter //
MCP7940.writeRAM(memoryAddress++,0); // Terminate the string //
Serial.print("String \""); // //
char dataBuffer[64]; // Maximum data size possible //
uint8_t x = MCP7940.readRAM(0,dataBuffer); // Read all 64 bytes //
Serial.print(dataBuffer); // Print stops at character 0x00 //
Serial.println("\" was read back from memory."); // //
memoryAddress = 0; // Start again at beginning //
} else { // //
if (dataByte!=13) MCP7940.writeRAM(memoryAddress++,dataByte); // Write to memory and increment //
} // of if-then-else we have a LF // //
} // of if-then we have something to read from the serial port // //
} // of method loop() //----------------------------------//
40 changes: 0 additions & 40 deletions MCP7940.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,46 +373,6 @@ uint8_t MCP7940_Class::weekdayWrite(const uint8_t dow) { //
return dow; // return the value //
} // of method weekdayWrite() // //
/*******************************************************************************************************************
** Method readRAM is an overloaded function which will read either one byte or mutiple bytes from the 64 Byte **
** SRAM included in the MCP7940. No error, but no data is returned if the address goes outside of 64 byte range **
*******************************************************************************************************************/
void MCP7940_Class::readRAM(const uint8_t address, uint8_t* buf, // //
const uint8_t size) { // //
uint8_t addrByte = MCP7940_RAM_ADDRESS + (address%64); // Compute offset, wrap on overflow //
Wire.beginTransmission(MCP7940_ADDRESS); // Address the I2C device //
Wire.write(addrByte); // Start at specified address //
_TransmissionStatus = Wire.endTransmission(); // Close transmission //
Wire.requestFrom(MCP7940_ADDRESS, size); // Request data //
while(!Wire.available()); // Wait until the data is ready //
for (uint8_t pos=0;pos<size;pos++){buf[pos] = Wire.read();} // Loop for each byte to read //
} // of method readRAM() // //
/*******************************************************************************************************************
** Method readRAM(). This reads just one byte from RAM and is an interlude function to the multibyte readRAM **
*******************************************************************************************************************/
uint8_t MCP7940_Class::readRAM(const uint8_t address) { // //
uint8_t data; // //
readRAM(address, &data, 1); // Read just one byte at address //
return data; // return result //
} // of method readRAM() // //
/*******************************************************************************************************************
** Method writeRAM is an overloaded function which will write either one byte or mutiple bytes to the 64 Byte **
** SRAM included in the MCP7940. No error, but no data is written to addresses outside of teh 64 Byte range **
*******************************************************************************************************************/
void MCP7940_Class::writeRAM(const uint8_t address, uint8_t* buf, // //
const uint8_t size) { // //
uint8_t addrByte = MCP7940_RAM_ADDRESS + (address%64); // Compute offset, wrap on overflow //
Wire.beginTransmission(MCP7940_ADDRESS); // Address the I2C device //
Wire.write(addrByte); // Start at given address //
for (uint8_t pos=0;pos<size;pos++) {Wire.write(buf[pos]);} // Write each byte to RAM //
_TransmissionStatus = Wire.endTransmission(); // Close transmission //
} // of method writeRAM // //
/*******************************************************************************************************************
** Method writeRAM(). This writes just one byte to RAM and is an interlude function to the multibyte writeRAM **
*******************************************************************************************************************/
uint8_t MCP7940_Class::writeRAM(const uint8_t address,const uint8_t data) { // //
writeRAM(address, &data, 1); // Just call writeRAM with 1 byte //
} // of method writeRAM // //
/*******************************************************************************************************************
** Method calibrate(). This function accepts a current date/time value and compares that to the current date/time **
** of the RTC and computes a calibration factor depending upon the time difference between the two and how long **
** the timespan between the two is. The longer the period between setting the clock and comparing the difference **
Expand Down
Loading

0 comments on commit 33552e4

Please sign in to comment.