Test application for the library FM24Vxx_I2C

Dependencies:   DebugLibrary FM24Vxx_I2C mbed

Revision:
0:30f4bcb2a3c0
Child:
1:e3c92ff30be3
diff -r 000000000000 -r 30f4bcb2a3c0 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Mar 23 15:54:36 2013 +0000
@@ -0,0 +1,479 @@
+#include <string>
+#include <iostream>
+#include <iomanip>
+
+#include "FM24Vxx_I2C.h"
+
+struct UserChoice {
+    char choice;
+    unsigned char moduleId;
+};
+
+/*
+ * Declare functions
+ */
+void AvailableIndicator(); // LED1 flashing for program while program is alive
+UserChoice DisplayMenuAndGetChoice(); // Display and get the user choice
+void RunStateMachine_WithStdStringValue(); // Write and read a string
+void RunStateMachine_WithByteValue(); // Write and read a byte
+void RunStateMachine_WithShortValue(CFM24VXX_I2C::Mode p_mode); // Write and read a short
+void RunStateMachine_WithIntegerValue(CFM24VXX_I2C::Mode p_mode); // Write and read an integer
+void RunStateMachine_WithStdVectorOfByteValue(); // Write and read a buffer of bytes
+void RunStateMachine_WithLengthPlusStdVectorOfByteValue(); // Write and read a buffer of bytes
+void ReadStdStringValue(const int p_address); // Read a string
+
+enum States {
+    Idle, // Idle state / Read memory operation done
+    Write, // Write memory operation
+    Written, // Write memory operation done
+    Read // Read memory operation
+};
+States g_state; // Process states for memory operations
+
+DigitalOut g_availableLed(LED1); // To verify if program in running
+Ticker g_available; // LED1 will flash with a period of 2s
+DigitalOut g_singleSeqNumScope(p6); // To synchronize the num scope to capture I2C trame
+UserChoice g_userChoice; // Used to store user choice from displayed menu
+
+CFM24VXX_I2C g_myEEPROM(p9, p10, 0x01, p5, 400000); // Create an instance of the class CFM24VXX_I2C, p9/28: SDA, p10/29:SDL, p5: wired to WP input of FM24Vxx, address: A2=0,A1=1, on I2C bus
+
+int main() {
+
+    g_singleSeqNumScope = 0;
+
+    // Launch available indicator
+    g_available.attach(&AvailableIndicator, 2.0);
+    
+    g_myEEPROM.WriteProtect(false); // Disabe WP (pin 7) - See DS21203M - Clause 2.4 Write-Protect (WP)
+
+    while (true) { // Interrupt driven processing
+        g_state = Idle; // Set initial state
+        g_userChoice = DisplayMenuAndGetChoice(); // Retrieve the user selection
+        DEBUG("User selects I2C Module %x", g_userChoice.moduleId)
+        switch (g_userChoice.choice) {
+            case 'a':
+                do {
+                    RunStateMachine_WithStdStringValue();
+                } while (g_state != Idle);
+                break;
+            case 'b':
+                do {
+                    RunStateMachine_WithByteValue();
+                } while (g_state != Idle);
+                break;
+            case 'c':
+                do {
+                    RunStateMachine_WithShortValue(CFM24VXX_I2C::BigEndian);
+                } while (g_state != Idle);
+                break;
+            case 'd':
+                do {
+                    RunStateMachine_WithShortValue(CFM24VXX_I2C::LittleEndian);
+                } while (g_state != Idle);
+                break;
+            case 'e':
+                do {
+                    RunStateMachine_WithIntegerValue(CFM24VXX_I2C::BigEndian);
+                } while (g_state != Idle);
+                break;
+            case 'f':
+                do {
+                    RunStateMachine_WithIntegerValue(CFM24VXX_I2C::LittleEndian);
+                } while (g_state != Idle);
+                break;
+            case 'g':
+                do {
+                    RunStateMachine_WithStdVectorOfByteValue();
+                } while (g_state != Idle);
+                break;
+            case 'h':
+                do {
+                    RunStateMachine_WithLengthPlusStdVectorOfByteValue();
+                } while (g_state != Idle);
+                break;
+            case 'i':
+                ReadStdStringValue(0x0100);
+                break;
+            case 'j':
+                ReadStdStringValue(0);
+                break;
+            case 'k':
+#if defined(__DEBUG)
+                g_myEEPROM.DumpMemoryArea(0, 0x14);
+#else // __DEBUG
+                std::cout << "DEBUG mode is not set, nothing to do!\r" << std::endl;
+#endif // __DEBUG
+                break;
+            case 'l':
+                g_myEEPROM.EraseMemoryArea(0, 0x14);
+                break;
+            case 'm':
+                {
+                    std::string test("Test");
+                    g_myEEPROM.Write(10, test);
+                }
+                break;
+            case 'n':
+                ReadStdStringValue(10);
+                break;
+            default:
+                std::cout << "Invalid user choice\r" << std::endl;
+                break;
+         } // End of 'switch' statement
+    } // End of 'while' statement
+} // End of program - nerver reached
+
+void AvailableIndicator()
+{
+    g_availableLed = !g_availableLed;
+} // End of AvailableIndicator
+
+UserChoice DisplayMenuAndGetChoice()
+{
+    static UserChoice userChoice;
+
+    // Display the title
+    std::cout << "\r" << std::endl << "FM24Vxx_I2C v0.1\r" << std::endl;
+    // Display the menu
+    std::cout << "\tWrite/Read with std::string:\t\t\ta\r" << std::endl;
+    std::cout << "\tWrite/Read with a byte:\t\t\t\tb\r" << std::endl;
+    std::cout << "\tWrite/Read with a short (Big Endian):\t\tc\r" << std::endl;
+    std::cout << "\tWrite/Read with a short (Little Endian):\td\r" << std::endl;
+    std::cout << "\tWrite/Read with an integer (Big Endian):\te\r" << std::endl;
+    std::cout << "\tWrite/Read with an integer (Little Endian):\tf\r" << std::endl;
+    std::cout << "\tWrite/Read with std::vector<byte>:\t\tg\r" << std::endl;
+    std::cout << "\tWrite/Read with std::vector<byte> + length:\th\r" << std::endl;
+    std::cout << "\tRead with std::string:\t\t\t\ti\r" << std::endl;
+    std::cout << "\tRead a string is address 0x0000:\t\tj\r" << std::endl;
+    std::cout << "\tHexadump from address 0x0000:\t\t\tk\r" << std::endl;
+    std::cout << "\tErase from address 0x0000:\t\t\tl\r" << std::endl;
+    std::cout << "\tWrite 'Test' at address 0x000a:\t\t\tm\r" << std::endl;
+    std::cout << "\tRead from address 0x000a:\t\t\tn\r" << std::endl;
+    std::cout << "Enter your choice: " << std::flush;
+    userChoice.choice = getchar();
+    return userChoice;
+}
+
+void RunStateMachine_WithStdStringValue()
+{
+    DEBUG_ENTER("RunStateMachine_WithStdStringValue")
+    
+    switch (g_state) {
+        case Idle:
+            g_state = Write;
+            break;
+        case Write: {
+                DEBUG("Writing data...");
+                time_t ctTime;
+                ctTime = time(NULL);  
+                std::string str("Current time is: ");
+                str += ctime(&ctTime);
+                str += " UTC";
+                std::cout << "RunStateMachine_WithStdStringValue: Write '" << str << "'\r" << std::endl;
+                g_singleSeqNumScope = 1;
+                if (!g_myEEPROM.Write(256, str)) { // Write the string, including the length indicator
+#ifdef __DEBUG
+                    DEBUG_FATAL("RunStateMachine_WithStdStringValue: write failed at address 256")
+#else // __DEBUG
+                    std::cout << "RunStateMachine_WithStdStringValue: write failed at address 256\r" << std::endl;
+#endif // __DEBUG
+                    g_state = Idle;
+                } else {
+                    g_state = Written;
+                }
+                g_singleSeqNumScope = 0;
+            }
+            break;
+        case Written:
+            g_state = Read;
+            wait(1.0); // To prevent I2C bus capacity memeory
+            break;
+        case Read: {
+                DEBUG("Reading datas...");
+                std::string readtext;
+                if (!g_myEEPROM.Read(256, readtext)) { // Read the string, including the length indicator
+#ifdef __DEBUG
+                    DEBUG_FATAL("RunStateMachine_WithStdStringValue: write failed at address 256")
+#else // __DEBUG
+                    std::cout << "RunStateMachine_WithStdStringValue: write failed at address 256\r" << std::endl;
+#endif // __DEBUG
+                } else {
+                    std::cout << "RunStateMachine_WithStdStringValue: Read: " << readtext << "\r" << std::endl;
+                }
+            }
+            g_state = Idle;
+            break;
+        default:
+            std::cout << "RunStateMachine_WithStdStringValue: Default!\r" << std::endl;
+            g_state = Idle;
+            break;
+    }
+
+    DEBUG_LEAVE("RunStateMachine_WithStdStringValue")
+}
+
+void RunStateMachine_WithByteValue() {
+    DEBUG_ENTER("RunStateMachine_WithByteValue")
+    
+    switch (g_state) {
+        case Idle:
+            g_state = Write;
+            break;
+        case Write:
+            DEBUG("Writing data...")
+            std::cout << "RunStateMachine_WithByteValue: Write 0xaa\r" << std::endl;
+            g_singleSeqNumScope = 1;
+            if (!g_myEEPROM.Write(128, (unsigned char)0xaa)) {
+#ifdef __DEBUG
+                DEBUG_FATAL("RunStateMachine_WithByteValue: write failed at address 128")
+#else // __DEBUG
+                std::cout << "RunStateMachine_WithByteValue: write failed at address 128\r" << std::endl;
+#endif // __DEBUG
+                g_state = Idle;
+            } else {
+                g_state = Written;
+            }
+            g_singleSeqNumScope = 0;
+            break;
+        case Written:
+            g_state = Read;
+            wait(1.0); // To prevent I2C bus capacity memeory
+            break;
+        case Read: {
+                DEBUG("Reading datas...")
+                unsigned char value = 0x00;
+                if (!g_myEEPROM.Read(128, &value)) {
+#ifdef __DEBUG
+                    DEBUG_FATAL("RunStateMachine_WithByteValue: Read operation failed at address 128")
+#else // __DEBUG
+                    std::cout << "RunStateMachine_WithByteValue: Read operation failed at address 128\r" << std::endl;
+#endif // __DEBUG
+                } else {
+                    std::cout << "RunStateMachine_WithByteValue: Read '0x" << std::setw(2) << std::setfill('0') << std::ios::hex << value << "'\r" << std::endl;
+                }
+            }
+            g_state = Idle;
+            break;
+        default:
+            std::cout << "RunStateMachine_WithByteValue: Default!\r" << std::endl;
+            g_state = Idle;
+            break;
+    }
+
+    DEBUG_LEAVE("RunStateMachine_WithByteValue")
+}
+
+void RunStateMachine_WithShortValue(CFM24VXX_I2C::Mode p_mode) {
+    DEBUG_ENTER("RunStateMachine_WithShortValue")
+    
+    switch (g_state) {
+        case Idle:
+            g_state = Write;
+            break;
+        case Write:
+            DEBUG("Writing data...")
+            std::cout << "RunStateMachine_WithShortValue: Write 0xbeef\r" << std::endl;
+            if (!g_myEEPROM.Write(64, (short)0xbeef, p_mode)) { // See http://en.wikipedia.org/wiki/Hexspeak for more ideas on hexadecimal wording!!!
+                DEBUG_FATAL("RunStateMachine_WithShortValue: write failed at address 64")
+                g_state = Idle;
+            } else {
+                g_state = Written;
+            }
+            break;
+        case Written:
+            g_state = Read;
+            wait(1.0); // To prevent I2C bus capacity memeory
+            break;
+        case Read: {
+                DEBUG("Reading datas...");
+                short value = 0;
+                if (!g_myEEPROM.Read(64, &value, p_mode)) {
+#ifdef __DEBUG
+                DEBUG_FATAL("RunStateMachine_WithShortValue: write failed at address 64")
+#else // __DEBUG
+                std::cout << "RunStateMachine_WithShortValue: write failed at address 64\r" << std::endl;
+#endif // __DEBUG
+                } else {
+                    std::cout << "RunStateMachine_WithShortValue: Read '0x" << std::cout << std::setw(4) << std::setfill('0') << std::hex << value << "' / '" << (unsigned short)value << "'\r" << std::endl;
+                }
+            }
+            g_state = Idle;
+            break;
+        default:
+            std::cout << "RunStateMachine_WithShortValue: Default!\r" << std::endl;
+            g_state = Idle;
+            break;
+    }
+
+    DEBUG_LEAVE("RunStateMachine_WithShortValue")
+}
+
+void RunStateMachine_WithIntegerValue(CFM24VXX_I2C::Mode p_mode) {
+    DEBUG_ENTER("RunStateMachine_WithIntegerValue")
+    
+    switch (g_state) {
+        case Idle:
+            g_state = Write;
+            break;
+        case Write:
+            DEBUG("Writing data...")
+            std::cout << "RunStateMachine_WithIntegerValue: Write 0xdeaddead\r" << std::endl;
+            if (!g_myEEPROM.Write(32, (int)0xdeaddead, p_mode)) {
+                DEBUG_FATAL("RunStateMachine_WithIntegerValue: write failed at address 32")
+                g_state = Idle;
+            } else {
+                g_state = Written;
+            }
+            break;
+        case Written:
+            g_state = Read;
+            wait(1.0); // To prevent I2C bus capacity memeory
+            break;
+        case Read: {
+                DEBUG("Reading datas...")
+                int value = 0;
+                if (!g_myEEPROM.Read(32, &value, p_mode)) {
+#ifdef __DEBUG
+                    DEBUG_FATAL("RunStateMachine_WithIntegerValue: write failed at address 32")
+#else // __DEBUG
+                    std::cout << "RunStateMachine_WithIntegerValue: write failed at address 32\r" << std::endl;
+#endif // __DEBUG
+                } else {
+                    std::cout << std::setw(8) << std::setfill('0') << std::hex << "RunStateMachine_WithIntegerValue: Read '0x" << value << "'/ '" << (unsigned int)value << "'\r" << std::endl;
+                }
+            }
+            g_state = Idle;
+            break;
+        default:
+            std::cout << "RunStateMachine_WithIntegerValue: Default!\r" << std::endl;
+            g_state = Idle;
+            break;
+    }
+
+    DEBUG_LEAVE("RunStateMachine_WithIntegerValue")
+}
+
+void RunStateMachine_WithStdVectorOfByteValue() {
+    DEBUG_ENTER("RunStateMachine_WithStdVectorOfByteValue")
+    
+    switch (g_state) {
+        case Idle:
+            g_state = Write;
+            break;
+        case Write: {
+                std::vector<unsigned char> datas;
+                datas.push_back(0xfe);
+                datas.push_back(0xed);
+                datas.push_back(0xfa);
+                datas.push_back(0xce);
+                DEBUG("Writing data...")
+                std::cout << "RunStateMachine_WithStdVectorOfByteValue: Write {0xfe, 0xed, 0xfa, 0xce}\r" << std::endl;
+                if (!g_myEEPROM.Write(16, datas, false)) { // Write the full buffer, not including the length indication
+                    DEBUG_FATAL("RunStateMachine_WithStdVectorOfByteValue: write failed at address 16")
+                    g_state = Idle;
+                } else {
+                    g_state = Written;
+                }
+            }
+            break;
+        case Written:
+            g_state = Read;
+            wait(1.0); // To prevent I2C bus capacity memeory
+            break;
+        case Read: {
+                DEBUG("Reading datas...")
+                std::vector<unsigned char> datas(4);
+                if (!g_myEEPROM.Read(16, datas, false)) { // Read bytes, without the lenght indication, buffer size shall be set before the call
+#ifdef __DEBUG
+                    DEBUG_FATAL("RunStateMachine_WithStdVectorOfByteValue: write failed at address 16")
+#else // __DEBUG
+                    std::cout << "RunStateMachine_WithStdVectorOfByteValue: write failed at address 16\r" << std::endl;
+#endif // __DEBUG
+                } else {
+                    std::cout << "RunStateMachine_WithStdVectorOfByteValue: Read {" << "', '" << datas[0] << "', '" << datas[1] << "', '" << datas[2] << "', '" << datas[3] <<"'}\r" << std::endl;
+                }
+            }
+            g_state = Idle;
+            break;
+        default:
+            std::cout << "RunStateMachine_WithStdVectorOfByteValue: Default!\r" << std::endl;
+            g_state = Idle;
+            break;
+    }
+
+    DEBUG_LEAVE("RunStateMachine_WithStdVectorOfByteValue")
+}
+
+void RunStateMachine_WithLengthPlusStdVectorOfByteValue() {
+    DEBUG_ENTER("RunStateMachine_WithLengthPlusStdVectorOfByteValue")
+    
+    switch (g_state) {
+        case Idle:
+            g_state = Write;
+            break;
+        case Write: {
+                DEBUG("Writing data...")
+                std::vector<unsigned char> datas;
+                datas.push_back(0xde);
+                datas.push_back(0x5e);
+                datas.push_back(0xa5);
+                datas.push_back(0xed);
+                std::cout << "RunStateMachine_WithLengthPlusStdVectorOfByteValue: Write {0xde, 0x5e, 0xa5, 0xed}\r" << std::endl;
+                if (!g_myEEPROM.Write(8, datas)) { // Write the full buffer, including the length indication
+                    DEBUG_FATAL("RunStateMachine_WithLengthPlusStdVectorOfByteValue: write failed at address 8")
+                    g_state = Idle;
+                } else {
+                    g_state = Written;
+                }
+            }
+            break;
+        case Written:
+            g_state = Read;
+            wait(1.0); // To prevent I2C bus capacity memeory
+            break;
+        case Read: {
+                DEBUG("Reading datas...")
+                std::vector<unsigned char> datas;
+                if (!g_myEEPROM.Read(8, datas)) { // Read bytes, including the lenght indication, buffer size is not set before the call
+#ifdef __DEBUG
+                    DEBUG_FATAL("RunStateMachine_WithStdVectorOfByteValue: write failed at address 8")
+#else // __DEBUG
+                    std::cout << "RunStateMachine_WithStdVectorOfByteValue: write failed at address 8\r" << std::endl;
+#endif // __DEBUG
+                } else {
+                    std::cout << "RunStateMachine_WithLengthPlusStdVectorOfByteValue: Read bytes:\r" << std::endl;
+                    vector<unsigned char>::iterator it;
+                    for (it = datas.begin() ; it < datas.end(); it++) {
+                         std::cout << "0x" << std::setw(2) << std::setfill('0') << std::hex << *it << " ";
+                    }
+                    std::cout << "\r" << std::endl;
+                }
+            }
+            g_state = Idle;
+            break;
+        default:
+            std::cout << "RunStateMachine_WithLengthPlusStdVectorOfByteValue: Default!\r" << std::endl;
+            g_state = Idle;
+            break;
+    }
+
+    DEBUG_LEAVE("RunStateMachine_WithLengthPlusStdVectorOfByteValue")
+}
+
+void ReadStdStringValue(const int p_address) {
+    DEBUG_ENTER("ReadStdStringValue: %d", p_address)
+
+    DEBUG("Reading datas...");
+    std::string readtext;
+    if (!g_myEEPROM.Read(p_address, readtext)) { // Read the string, including the length indicator
+#ifdef __DEBUG
+        DEBUG_FATAL("ReadStdStringValue: write failed at address 256")
+#else // __DEBUG
+        std::cout << "ReadStdStringValue: write failed at address 256\r" << std::endl;
+#endif // __DEBUG
+    } else {
+        std::cout << "ReadStdStringValue: Read:'" << readtext << "'\r" << std::endl;
+    }
+
+    DEBUG_LEAVE("ReadStdStringValue")
+}