Commits

iorodeo committed a56bb2d

Project creation.

Comments (0)

Files changed (13)

+syntax: glob
+*~
+*.pyc
+*.swp
+*.pkl
+*.ps
+*.bak

FlashMemory/Example/basic/basic.pde

+#include <Streaming.h>
+#include <FlashMemory.h>
+
+void printHelp();
+void eraseFlashPage();
+void writeToUint16FlashPage();
+void writeToUint8FlashPage();
+void printFlashPage();
+
+const char cmdPrintHelp = '0';
+const char cmdEraseFlashPage = '1';
+const char cmdWriteUint16ToFlashPage = '2';
+const char cmdWriteUint8ToFlashPage = '3';
+const char cmdPrintFlashPage = '4';
+
+const uint8 flashPageNum=1;
+
+void setup() {
+}
+
+void loop() {
+
+    while (SerialUSB.available() >0) {
+        char cmd = SerialUSB.read();
+
+        switch (cmd) {
+
+            case cmdPrintHelp:
+                printHelp();
+                break;
+
+            case cmdEraseFlashPage:
+                eraseFlashPage();
+                break;
+
+            case cmdWriteUint16ToFlashPage:
+                writeUint16ToFlashPage();
+                break;
+
+            case cmdWriteUint8ToFlashPage:
+                writeUint8ToFlashPage();
+                break;
+
+            case cmdPrintFlashPage:
+                printFlashPage();
+                break;
+
+            default:
+                break;
+        }
+    }
+}
+
+void printHelp() {
+    SerialUSB << "Command Summary" << endl;
+    SerialUSB << "-------------------------------------------------------------" << endl;
+    SerialUSB << "0 - print help" << endl;
+    SerialUSB << "1 - erase flash page" << endl;
+    SerialUSB << "2 - write uint16 data to flash page" << endl;
+    SerialUSB << "3 - write uint8 data to flash page" << endl;
+    SerialUSB << "4 - print flash page" << endl;
+    SerialUSB << endl;
+}
+
+void eraseFlashPage() {
+    flashMemory.erasePage(flashPageNum);
+    SerialUSB << "page erased" << endl;
+}
+
+void writeUint16ToFlashPage() {
+    uint16 value=0;
+    for (uint16 address=0; address<flashMemory.maxAddress; address++) {
+        flashMemory.writeData(flashPageNum,address,value);
+        value += 2;
+    }
+    SerialUSB << "uint16 data written to flash" << endl;
+}
+
+void writeUint8ToFlashPage() {
+    uint8 data0;
+    uint8 data1;
+    for (uint16 address=0; address<flashMemory.maxAddress; address++) {
+        flashMemory.writeData(flashPageNum,address,data0,data1);
+        if (data0 < 255) {
+            data0++;
+        }
+        else {
+            data0 = 0;
+            data1++;
+        }
+    }
+    SerialUSB << "uint8 data written to flash" << endl;
+}
+
+void printFlashPage() {
+    uint16 data_uint16;
+    uint8 data0_uint8;
+    uint8 data1_uint8;
+    SerialUSB << "Flash Page #: " << flashPageNum << endl;
+    SerialUSB << "-------------------------------------------------------------" << endl;
+    SerialUSB << "address : data_int16, data0_uint8, data1_uint8" << endl;
+    for (uint16 address=0; address<flashMemory.maxAddress; address++) {
+        flashMemory.readData(flashPageNum, address, data_uint16);
+        flashMemory.readData(flashPageNum, address, data0_uint8, data1_uint8);
+        SerialUSB << address << " : " << data_uint16 << ", " << data0_uint8 << ", " << data1_uint8 << endl;
+    }
+    SerialUSB << endl;
+}

FlashMemory/FlashMemory.cpp

+#include "FlashMemory.h"
+#include "WProgram.h"
+#include <Streaming.h>
+
+FlashMemory::FlashMemory() {
+    // Contructor for Flash memory - sets base address for flash memory
+    // pages.
+    for (uint8 i=0; i<numPages; i++) {
+        basePageAddress[i] = startAddress + i*((uint32) pageSize);
+    }
+    lock();
+}
+
+void FlashMemory::unlock() {
+    FLASH_Unlock();
+}
+
+void FlashMemory::lock() {
+    FLASH_Lock();
+}
+
+bool FlashMemory::erasePage(uint8 pageNum) {
+    // Erases a page of flash memory given the page number
+    FLASH_Status status;
+    if (pageNum >= numPages) {
+        return false;
+    }
+    unlock();
+    status = FLASH_ErasePage(basePageAddress[pageNum]);
+    lock();
+    if (status == FLASH_COMPLETE) {
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+bool FlashMemory::eraseAllPages() {
+    // Erases all pages of flash memory
+    bool rtnVal = true;
+    for (uint8 pageNum=0; pageNum<numPages; pageNum++) {
+        if (!erasePage(pageNum)) {
+            rtnVal = false;
+        }
+    }
+    return rtnVal;
+}
+
+bool FlashMemory::writeData(uint8 pageNum, uint16 address, uint16 data) {
+    // Writes uint16 data to the given page and address of flash memory.
+    uint32 trueAddress; 
+    FLASH_Status status;
+    if (pageNum >= numPages) {
+        return false;
+    }
+    if (address >= maxAddress) {
+        return false;
+    }
+    trueAddress = basePageAddress[pageNum] + 2*((uint32) address);
+    unlock();
+    status = FLASH_ProgramHalfWord(trueAddress, data);
+    lock();
+    if (status == FLASH_COMPLETE) {
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+bool FlashMemory::writeData(uint8 pageNum, uint16 address, uint8 data0, uint8 data1) {
+    // Writes two uint8 data to the given page and address of flash memory. 
+    uint16 packedData;
+    packedData = pack_uint8(data0,data1);
+    return writeData(pageNum, address, packedData);
+}
+
+bool FlashMemory::readData(uint8 pageNum, uint16 address, uint16 &data) {
+    // Reads the given page and address of flash memory and returns the value
+    // as a uint16. 
+    uint32 trueAddress; 
+    FLASH_Status status;
+    if (pageNum >= numPages) {
+        return false;
+    }
+    if (address >= maxAddress) {
+        return false;
+    }
+    trueAddress = basePageAddress[pageNum] + 2*((uint32) address); 
+    data = *((uint16*)  trueAddress);
+    return true;
+}
+
+bool FlashMemory::readData(uint8 pageNum, uint16 address, uint8 &data0, uint8 &data1) {
+    // Read the given page and address of flash memory and returns the data as two uint8. 
+    bool rtnVal;
+    uint16 packedData;
+    rtnVal = readData(pageNum, address, packedData);
+    unpack_uint8(packedData,data0,data1);
+    return rtnVal;
+}
+
+void FlashMemory::printBasePageAddress() {
+    // Prints the base page addresses
+    for (uint8 i=0; i<numPages; i++) {
+        SerialUSB << "page: " << i << " " << _HEX(basePageAddress[i]) << endl;
+    }
+    SerialUSB << endl;
+}
+
+void FlashMemory::printPage(uint8 pageNum, bool asUint8) {
+    // Prints the given page of flash memory.
+    uint16 value;
+    uint8 value0;
+    uint8 value1;
+    if (pageNum >= numPages) {
+        SerialUSB << "pageNum > numPages" << endl;
+        return;
+    }
+    SerialUSB << "page, address, value" << endl;
+    for (uint16 address=0; address<maxAddress; address++) { 
+        if (asUint8) {
+            readData(pageNum, address, value0, value1);
+            SerialUSB << pageNum << ", " << address << ", " << value0 << ", " << value1 << endl; 
+        }
+        else {
+            readData(pageNum, address, value);
+            SerialUSB << pageNum << ", " << address << ", " << value << endl; 
+        }
+    }
+    SerialUSB << endl;
+}
+
+uint16 pack_uint8(uint8 dataIn0, uint8 dataIn1) {
+    // Packs two uint8s into a uint16
+    return (((uint16) dataIn0) << 8) | ((uint16) dataIn1);
+}
+
+void unpack_uint8(uint16 dataIn, uint8 &dataOut0, uint8 &dataOut1) {
+    // Unpacks two uint8s from a unit16
+    dataOut0 = (uint8) (dataIn >> 8);
+    dataOut1 = (uint8) (0x00ff & dataIn);
+}
+
+FlashMemory flashMemory;
+

FlashMemory/FlashMemory.h

+#ifndef _FLASH_MEMORY_H_
+#define _FLASH_MEMORY_H_
+#include "wirish.h"
+#include "flash_stm32.h"
+
+#define FLASH_MEM_NUM_PAGES       ((uint8) 10)
+#define FLASH_MEM_PAGE_SIZE       ((uint16)0x400)  /* Page size = 1KByte */
+#define FLASH_MEM_START_ADDRESS   ((uint32)(0x8000000 + 128 * 1024 - FLASH_MEM_NUM_PAGES * FLASH_MEM_PAGE_SIZE))
+#define FLASH_MEM_MAX_ADDRESS     ((uint16) (((FLASH_MEM_PAGE_SIZE - 2)/2)+1))
+
+class FlashMemory {
+
+    public:
+        static const uint8 numPages = FLASH_MEM_NUM_PAGES;
+        static const uint16 pageSize = FLASH_MEM_PAGE_SIZE;
+        static const uint32 startAddress = FLASH_MEM_START_ADDRESS;
+        static const uint16 maxAddress = FLASH_MEM_MAX_ADDRESS;
+
+        FlashMemory();
+        bool erasePage(uint8 pageNum);
+        bool eraseAllPages();
+        bool writeData(uint8 pageNum, uint16 address, uint16 data);
+        bool writeData(uint8 pageNum, uint16 address, uint8 data0, uint8 data1);
+        bool readData(uint8 pageNum, uint16 address, uint16 &data);
+        bool readData(uint8 pageNum, uint16 address, uint8 &data0, uint8 &data1);
+
+        void printBasePageAddress();
+        void printPage(uint8 pageNum, bool asUint8=false);
+
+    private:
+        void lock();
+        void unlock();
+        uint32 basePageAddress[FLASH_MEM_NUM_PAGES];
+
+};
+
+
+uint16 pack_uint8(uint8 dataIn0, uint8 dataIn1);
+void unpack_uint8(uint16 dataIn, uint8 &dataOut0, uint8 &dataOut1);
+
+extern FlashMemory flashMemory;
+
+#endif

FlashMemory/LICENSE

+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+

FlashMemory/flash_stm32.cpp

+#include "libmaple.h"
+#include "util.h"
+#include "flash.h"
+#include "flash_stm32.h"
+
+#define FLASH_KEY1          ((uint32)0x45670123)
+#define FLASH_KEY2          ((uint32)0xCDEF89AB)
+
+/* Delay definition */
+#define EraseTimeout        ((uint32)0x00000FFF)
+#define ProgramTimeout      ((uint32)0x0000001F)
+
+/**
+  * @brief  Inserts a time delay.
+  * @param  None
+  * @retval None
+  */
+static void delay(void)
+{
+    __io uint32 i = 0;
+    for(i = 0xFF; i != 0; i--) { }
+}
+
+/**
+  * @brief  Returns the FLASH Status.
+  * @param  None
+  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+  *   FLASH_ERROR_WRP or FLASH_COMPLETE
+  */
+FLASH_Status FLASH_GetStatus(void)
+{
+    if ((FLASH_BASE->SR & FLASH_SR_BSY) == FLASH_SR_BSY)
+        return FLASH_BUSY;
+
+    if ((FLASH_BASE->SR & FLASH_SR_PGERR) != 0)
+        return FLASH_ERROR_PG;
+
+    if ((FLASH_BASE->SR & FLASH_SR_WRPRTERR) != 0 )
+        return FLASH_ERROR_WRP;
+
+    if ((FLASH_BASE->SR & FLASH_OBR_OPTERR) != 0 )
+        return FLASH_ERROR_OPT;
+
+    return FLASH_COMPLETE;
+}
+
+/**
+  * @brief  Waits for a Flash operation to complete or a TIMEOUT to occur.
+  * @param  Timeout: FLASH progamming Timeout
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *   FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout)
+{ 
+    FLASH_Status status;
+
+    /* Check for the Flash Status */
+    status = FLASH_GetStatus();
+    /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+    while ((status == FLASH_BUSY) && (Timeout != 0x00))
+    {
+        delay();
+        status = FLASH_GetStatus();
+        Timeout--;
+    }
+    if (Timeout == 0)
+        status = FLASH_TIMEOUT;
+    /* Return the operation status */
+    return status;
+}
+
+/**
+  * @brief  Erases a specified FLASH page.
+  * @param  Page_Address: The page address to be erased.
+  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+  *   FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+  */
+FLASH_Status FLASH_ErasePage(uint32 Page_Address)
+{
+    FLASH_Status status = FLASH_COMPLETE;
+    /* Check the parameters */
+    ASSERT(IS_FLASH_ADDRESS(Page_Address));
+    /* Wait for last operation to be completed */
+    status = FLASH_WaitForLastOperation(EraseTimeout);
+  
+    if(status == FLASH_COMPLETE)
+    {
+        /* if the previous operation is completed, proceed to erase the page */
+        FLASH_BASE->CR |= FLASH_CR_PER;
+        FLASH_BASE->AR = Page_Address;
+        FLASH_BASE->CR |= FLASH_CR_STRT;
+
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation(EraseTimeout);
+        if(status != FLASH_TIMEOUT)
+        {
+            /* if the erase operation is completed, disable the PER Bit */
+            FLASH_BASE->CR &= ~FLASH_CR_PER;
+        }
+        FLASH_BASE->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR);
+    }
+    /* Return the Erase Status */
+    return status;
+}
+
+/**
+  * @brief  Programs a half word at a specified address.
+  * @param  Address: specifies the address to be programmed.
+  * @param  Data: specifies the data to be programmed.
+  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+  *   FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. 
+  */
+FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data)
+{
+    FLASH_Status status = FLASH_BAD_ADDRESS;
+
+    if (IS_FLASH_ADDRESS(Address))
+    {
+        /* Wait for last operation to be completed */
+        status = FLASH_WaitForLastOperation(ProgramTimeout);
+        if(status == FLASH_COMPLETE)
+        {
+            /* if the previous operation is completed, proceed to program the new data */
+            FLASH_BASE->CR |= FLASH_CR_PG;
+            *(__io uint16*)Address = Data;
+            /* Wait for last operation to be completed */
+            status = FLASH_WaitForLastOperation(ProgramTimeout);
+            if(status != FLASH_TIMEOUT)
+            {
+                /* if the program operation is completed, disable the PG Bit */
+                FLASH_BASE->CR &= ~FLASH_CR_PG;
+            }
+            FLASH_BASE->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPRTERR);
+        }
+    }
+    return status;
+}
+
+/**
+  * @brief  Unlocks the FLASH Program Erase Controller.
+  * @param  None
+  * @retval None
+  */
+void FLASH_Unlock(void)
+{
+    /* Authorize the FPEC Access */
+    FLASH_BASE->KEYR = FLASH_KEY1;
+    FLASH_BASE->KEYR = FLASH_KEY2;
+}
+
+/**
+  * @brief  Locks the FLASH Program Erase Controller.
+  * @param  None
+  * @retval None
+  */
+void FLASH_Lock(void)
+{
+    /* Set the Lock Bit to lock the FPEC and the FCR */
+    FLASH_BASE->CR |= FLASH_CR_LOCK;
+}

FlashMemory/flash_stm32.h

+#ifndef __FLASH_STM32_H
+#define __FLASH_STM32_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef enum
+    {
+    FLASH_BUSY = 1,
+    FLASH_ERROR_PG,
+    FLASH_ERROR_WRP,
+    FLASH_ERROR_OPT,
+    FLASH_COMPLETE,
+    FLASH_TIMEOUT,
+    FLASH_BAD_ADDRESS
+    } FLASH_Status;
+
+#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF))
+
+FLASH_Status FLASH_WaitForLastOperation(uint32 Timeout);
+FLASH_Status FLASH_ErasePage(uint32 Page_Address);
+FLASH_Status FLASH_ProgramHalfWord(uint32 Address, uint16 Data);
+
+void FLASH_Unlock(void);
+void FLASH_Lock(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FLASH_STM32_H */
+Note, libraries may be licensed differently. The license for each individual
+library can be found in the file LICENSE file in the project directory for
+that library.   
+iorodeo_maple_libs
+---------------------
+
+A collection of libraries for use with the LeafLabs Maple.
+
+Summary:
+
+* FlashMemory: a library for reading, writing and erasing the flash memory on the Maple. 
+
+* SerialReceiver: a simple library for handling serial communication on the Maple. 
+  This is a port of SerialReceiver form iorodeo_arduino_libs.
+
+
+

SerialReceiver/Examples/basic/basic.pde

+#include "Streaming.h"
+#include "SerialReceiver.h"
+
+SerialReceiver receiver = SerialReceiver();
+
+void setup() {
+}
+
+void loop() {
+    int myInt;
+    float myFloat;
+
+    while (SerialUSB.available() > 0) {
+        receiver.process(SerialUSB.read());
+        if (receiver.messageReady()) {
+            SerialUSB << "Message Ready" << endl;
+            SerialUSB << "-------------" << endl;
+            myInt = receiver.readInt(0);
+            myFloat = receiver.readFloat(1);
+            SerialUSB << "myInt = " << _DEC(myInt) << endl;
+            SerialUSB << "myFloat = " << myFloat << endl;
+            SerialUSB << "-------------" << endl;
+            SerialUSB << endl;
+            receiver.reset();
+        }
+    }
+}
+

SerialReceiver/LICENSE

+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+

SerialReceiver/SerialReceiver.cpp

+#include <stdlib.h>
+#include <string.h>
+#include "Streaming.h"
+#include "SerialReceiver.h"
+
+SerialReceiver::SerialReceiver() {
+    error = SR_ERR_NONE;
+    resetState();
+    startChar = SR_DFLT_START_CHAR;
+    stopChar = SR_DFLT_STOP_CHAR;
+    sepChar = SR_DFLT_SEP_CHAR;
+    resetState();
+}
+
+bool SerialReceiver::messageReady() {
+    if (state == SR_STATE_MESSAGE) {
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+uint8 SerialReceiver::numberOfItems() {
+    if (state == SR_STATE_MESSAGE) {
+        return itemCnt;
+    }
+    else {
+        return 0;
+    }
+}
+
+char SerialReceiver::readChar(uint8 itemNum, uint8 ind) {
+    char rval;
+    if (checkItemRange(itemNum)) {
+        if (ind < itemLenBuffer[itemNum]) {
+            rval = itemBuffer[itemNum][ind];
+        }
+        else {
+            rval = 0;
+        }
+    }
+    else {
+        rval = 0;
+    }
+    return rval;
+}
+
+int SerialReceiver::readInt(uint8 itemNum) {
+    if (checkItemRange(itemNum)) {
+        return atoi(itemBuffer[itemNum]);
+    }
+    else {
+        return 0;
+    }
+}
+
+long SerialReceiver::readLong(uint8 itemNum) {
+    if (checkItemRange(itemNum)) {
+        return atol(itemBuffer[itemNum]);
+    }
+    else {
+        return 0;
+    }
+}
+
+double SerialReceiver::readDouble(uint8 itemNum) {
+    if(checkItemRange(itemNum)) {
+        return atof(itemBuffer[itemNum]);
+    }
+    else {
+        return 0;
+    }
+}
+
+float SerialReceiver::readFloat(uint8 itemNum) {
+    return (float) readDouble(itemNum);
+}
+
+void SerialReceiver::copyString(uint8 itemNum, char* string, uint8 size) {
+    if (checkItemRange(itemNum)) {
+        strlcpy(string,itemBuffer[itemNum],size);
+    }
+    else {
+        if (size >= 0) {
+            string[0] = '\0';
+        }
+    }
+}
+
+
+bool SerialReceiver::checkItemRange(uint8 itemNum) {
+    if ((state==SR_STATE_MESSAGE) && (itemNum >=0) && (itemNum < itemCnt)) {
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+void SerialReceiver::process(int serialByte) {
+    if (serialByte > 0){
+        switch (state) {
+            case SR_STATE_IDLE:
+                processNewMsg(serialByte);
+                break;
+            case SR_STATE_RECEIVING:
+                processCurMsg(serialByte);
+                break;
+            case SR_STATE_MESSAGE:
+                break;
+            default:
+                break;
+
+        }
+    }
+}
+
+void SerialReceiver::processNewMsg(int serialByte) {
+    if (serialByte == startChar) {
+        resetItems();
+        state = SR_STATE_RECEIVING;
+        error = SR_ERR_NONE;
+    }
+    else if ((serialByte == '\n') || (serialByte == ' ')) {
+        return;
+    }
+    else {
+        error = SR_ERR_ILLEGAL_CHAR;
+        resetState();
+    }
+}
+
+void SerialReceiver::processCurMsg(int serialByte) {
+    if (serialByte == startChar) {
+        handleStartChar(serialByte);
+    }
+    else if (serialByte == stopChar) {
+        handleStopChar(serialByte);
+    }
+
+    else if (serialByte == sepChar) {
+        handleSepChar(serialByte);
+    }
+
+    else {
+        handleNewChar(serialByte);
+    }
+}
+
+void SerialReceiver::handleStartChar(int serialByte) {
+    resetState();
+    error = SR_ERR_ILLEGAL_CHAR;
+}
+
+void SerialReceiver::handleStopChar(int serialByte) {
+    if (itemPos > 0) {
+        itemBuffer[itemCnt][itemPos] = '\0';
+        itemLenBuffer[itemCnt] = itemPos;
+        itemCnt++;
+    }
+    // Check message checksum here .... if not OK reset.
+    state = SR_STATE_MESSAGE;
+}
+
+void SerialReceiver::handleSepChar(int serialByte) {
+    if (itemPos > 0) {
+        if (itemCnt == SR_MAX_ITEMS) {
+            resetState();
+            error = SR_ERR_MESSAGE_LENGTH;
+        }
+        else {
+            itemBuffer[itemCnt][itemPos] = '\0';
+            itemLenBuffer[itemCnt] = itemPos;
+            itemCnt++;
+            itemPos = 0;
+        }
+    }
+    else {
+        resetState();
+        error = SR_ERR_ITEM_LENGTH;
+    }
+}
+
+void SerialReceiver::handleNewChar(int serialByte) {
+    if (itemPos == SR_MAX_ITEM_SZ) {
+        resetState();
+        error = SR_ERR_ITEM_LENGTH;
+    }
+    else {
+        if ((serialByte == '\n') || (serialByte == ' ')) {
+            return;
+        }
+        itemBuffer[itemCnt][itemPos] = serialByte;
+        itemPos++;
+    }
+}
+
+void SerialReceiver::reset() {
+    resetState();
+    error = SR_ERR_NONE;
+}
+
+void SerialReceiver::resetState() {
+    resetItems();
+    state = SR_STATE_IDLE;
+}
+
+void SerialReceiver::resetItems() {
+    itemCnt = 0;
+    itemPos = 0;
+    for (int i=0; i<SR_MAX_ITEMS;i++) {
+        itemBuffer[i][0] = '\0';
+        itemLenBuffer[i] = 0;
+    }
+}
+
+void SerialReceiver::printInfo() {
+    SerialUSB << "Current Message Info" << endl;
+    SerialUSB << "--------------------" << endl;
+    SerialUSB << "state:   " << _DEC(state) << endl;
+    SerialUSB << "error:   " << _DEC(error) << endl;
+    SerialUSB << "itemCnt: " << _DEC(itemCnt) << endl;
+    SerialUSB << "itemPos: " << _DEC(itemPos) << endl;
+    for (int i=0; i<itemCnt; i++) {
+        SerialUSB << "buf[" << _DEC(i) << "] = " << itemBuffer[i] << endl;
+    }
+    SerialUSB << endl;
+}
+
+void SerialReceiver::printMessageInfo() {
+    SerialUSB << "Message = " << endl;
+    for (int i=0; i<itemCnt; i++) {
+        SerialUSB << "buf[" << _DEC(i) << "] = " << itemBuffer[i] << ", len = " << _DEC(itemLenBuffer[i]) << endl;
+    }
+    SerialUSB << endl;
+}
+
+void SerialReceiver::printMessage() {
+    for (int i=0; i<itemCnt; i++) {
+        if (i < itemCnt-1) {
+            SerialUSB << itemBuffer[i] << " ";
+        }
+        else {
+            SerialUSB << itemBuffer[i];
+        }
+    }
+    SerialUSB << endl;
+}

SerialReceiver/SerialReceiver.h

+#include "WProgram.h" 
+
+#ifndef SerialReceiver_h
+#define SerialReceiver_h
+
+#define SR_MAX_ITEM_SZ 25
+#define SR_MAX_ITEMS   4
+
+#define SR_DFLT_START_CHAR '['
+#define SR_DFLT_STOP_CHAR ']'
+#define SR_DFLT_SEP_CHAR  ',' 
+
+#define SR_STATE_IDLE      0
+#define SR_STATE_RECEIVING 1
+#define SR_STATE_MESSAGE   2
+
+#define SR_ERR_NONE 0
+#define SR_ERR_ILLEGAL_CHAR 1
+#define SR_ERR_ITEM_LENGTH 2
+#define SR_ERR_MESSAGE_LENGTH 3
+
+class SerialReceiver {
+
+    public:
+        SerialReceiver();
+        void process(int serialByte);
+        bool messageReady();
+        void reset();
+        uint8 numberOfItems();
+        uint8 itemLength(uint8 itemNum);
+        char readChar(uint8 itemNum, uint8 ind); 
+        int readInt(uint8 itemNum);
+        long readLong(uint8 itemNum);
+        float readFloat(uint8 itemNum);
+        double readDouble(uint8 itemNum);
+        void copyString(uint8 itemNum, char *string, uint8 size);
+        void printInfo();
+        void printMessageInfo();
+        void printMessage();
+        
+    private:
+        uint8 state;
+        uint8 error;
+        char itemBuffer[SR_MAX_ITEMS][SR_MAX_ITEM_SZ+1];
+        uint8 itemLenBuffer[SR_MAX_ITEMS];
+        uint8 itemCnt;
+        uint8 itemPos; 
+        char startChar;
+        char stopChar; 
+        char sepChar;
+        void resetItems();
+        void resetState();
+        void processNewMsg(int serialByte);
+        void processCurMsg(int serialByte);
+        void handleNewChar(int serialByte);
+        void handleSepChar(int serialByte);
+        void handleStopChar(int serialByte);
+        void handleStartChar(int serialByte);
+        bool checkItemRange(uint8 itemNum);
+};
+
+
+#endif