Dependencies: DM_FATFileSystem EthernetInterface HTTPClient mbed-rtos mbed-src
Fork of DMSupport by
Memory/InternalEEPROM.cpp@0:6b68dac0d986, 2014-11-21 (annotated)
- Committer:
- embeddedartists
- Date:
- Fri Nov 21 11:42:51 2014 +0000
- Revision:
- 0:6b68dac0d986
- Child:
- 9:a33326afd686
First version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 0:6b68dac0d986 | 1 | /* |
embeddedartists | 0:6b68dac0d986 | 2 | * Copyright 2013 Embedded Artists AB |
embeddedartists | 0:6b68dac0d986 | 3 | * |
embeddedartists | 0:6b68dac0d986 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
embeddedartists | 0:6b68dac0d986 | 5 | * you may not use this file except in compliance with the License. |
embeddedartists | 0:6b68dac0d986 | 6 | * You may obtain a copy of the License at |
embeddedartists | 0:6b68dac0d986 | 7 | * |
embeddedartists | 0:6b68dac0d986 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
embeddedartists | 0:6b68dac0d986 | 9 | * |
embeddedartists | 0:6b68dac0d986 | 10 | * Unless required by applicable law or agreed to in writing, software |
embeddedartists | 0:6b68dac0d986 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
embeddedartists | 0:6b68dac0d986 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
embeddedartists | 0:6b68dac0d986 | 13 | * See the License for the specific language governing permissions and |
embeddedartists | 0:6b68dac0d986 | 14 | * limitations under the License. |
embeddedartists | 0:6b68dac0d986 | 15 | */ |
embeddedartists | 0:6b68dac0d986 | 16 | |
embeddedartists | 0:6b68dac0d986 | 17 | #include "mbed.h" |
embeddedartists | 0:6b68dac0d986 | 18 | #include "InternalEEPROM.h" |
embeddedartists | 0:6b68dac0d986 | 19 | #include "dm_board_config.h" |
embeddedartists | 0:6b68dac0d986 | 20 | |
embeddedartists | 0:6b68dac0d986 | 21 | |
embeddedartists | 0:6b68dac0d986 | 22 | /****************************************************************************** |
embeddedartists | 0:6b68dac0d986 | 23 | * Defines and typedefs |
embeddedartists | 0:6b68dac0d986 | 24 | *****************************************************************************/ |
embeddedartists | 0:6b68dac0d986 | 25 | |
embeddedartists | 0:6b68dac0d986 | 26 | #define EEPROM_INT_ENDOFRW (1<<26) |
embeddedartists | 0:6b68dac0d986 | 27 | #define EEPROM_INT_ENDOFPROG (1<<28) |
embeddedartists | 0:6b68dac0d986 | 28 | |
embeddedartists | 0:6b68dac0d986 | 29 | #define EEPROM_PWRDWN (1<<0) |
embeddedartists | 0:6b68dac0d986 | 30 | |
embeddedartists | 0:6b68dac0d986 | 31 | /* |
embeddedartists | 0:6b68dac0d986 | 32 | * Commands (for the LPC_EEPROM->CMD register) |
embeddedartists | 0:6b68dac0d986 | 33 | */ |
embeddedartists | 0:6b68dac0d986 | 34 | #define EEPROM_CMD_8BITS_READ (0) /*!< EEPROM 8-bit read command */ |
embeddedartists | 0:6b68dac0d986 | 35 | #define EEPROM_CMD_16BITS_READ (1) /*!< EEPROM 16-bit read command */ |
embeddedartists | 0:6b68dac0d986 | 36 | #define EEPROM_CMD_32BITS_READ (2) /*!< EEPROM 32-bit read command */ |
embeddedartists | 0:6b68dac0d986 | 37 | #define EEPROM_CMD_8BITS_WRITE (3) /*!< EEPROM 8-bit write command */ |
embeddedartists | 0:6b68dac0d986 | 38 | #define EEPROM_CMD_16BITS_WRITE (4) /*!< EEPROM 16-bit write command */ |
embeddedartists | 0:6b68dac0d986 | 39 | #define EEPROM_CMD_32BITS_WRITE (5) /*!< EEPROM 32-bit write command */ |
embeddedartists | 0:6b68dac0d986 | 40 | #define EEPROM_CMD_ERASE_PRG_PAGE (6) /*!< EEPROM erase/program command */ |
embeddedartists | 0:6b68dac0d986 | 41 | #define EEPROM_CMD_RDPREFETCH (1 << 3)/*!< EEPROM read pre-fetch enable */ |
embeddedartists | 0:6b68dac0d986 | 42 | |
embeddedartists | 0:6b68dac0d986 | 43 | |
embeddedartists | 0:6b68dac0d986 | 44 | /****************************************************************************** |
embeddedartists | 0:6b68dac0d986 | 45 | * Local variables |
embeddedartists | 0:6b68dac0d986 | 46 | *****************************************************************************/ |
embeddedartists | 0:6b68dac0d986 | 47 | |
embeddedartists | 0:6b68dac0d986 | 48 | /****************************************************************************** |
embeddedartists | 0:6b68dac0d986 | 49 | * Private Functions |
embeddedartists | 0:6b68dac0d986 | 50 | *****************************************************************************/ |
embeddedartists | 0:6b68dac0d986 | 51 | |
embeddedartists | 0:6b68dac0d986 | 52 | void InternalEEPROM::powerUp() |
embeddedartists | 0:6b68dac0d986 | 53 | { |
embeddedartists | 0:6b68dac0d986 | 54 | LPC_EEPROM->PWRDWN = 0; |
embeddedartists | 0:6b68dac0d986 | 55 | } |
embeddedartists | 0:6b68dac0d986 | 56 | |
embeddedartists | 0:6b68dac0d986 | 57 | void InternalEEPROM::clearInterrupt(uint32_t mask) |
embeddedartists | 0:6b68dac0d986 | 58 | { |
embeddedartists | 0:6b68dac0d986 | 59 | LPC_EEPROM->INT_CLR_STATUS = mask; |
embeddedartists | 0:6b68dac0d986 | 60 | } |
embeddedartists | 0:6b68dac0d986 | 61 | |
embeddedartists | 0:6b68dac0d986 | 62 | void InternalEEPROM::waitForInterrupt(uint32_t mask) |
embeddedartists | 0:6b68dac0d986 | 63 | { |
embeddedartists | 0:6b68dac0d986 | 64 | while ((LPC_EEPROM->INT_STATUS & mask) != mask) { |
embeddedartists | 0:6b68dac0d986 | 65 | } |
embeddedartists | 0:6b68dac0d986 | 66 | |
embeddedartists | 0:6b68dac0d986 | 67 | clearInterrupt(mask); |
embeddedartists | 0:6b68dac0d986 | 68 | } |
embeddedartists | 0:6b68dac0d986 | 69 | |
embeddedartists | 0:6b68dac0d986 | 70 | void InternalEEPROM::setAddr(uint32_t pageAddr, uint32_t pageOffset) |
embeddedartists | 0:6b68dac0d986 | 71 | { |
embeddedartists | 0:6b68dac0d986 | 72 | LPC_EEPROM->ADDR = (pageAddr << 6) | pageOffset; |
embeddedartists | 0:6b68dac0d986 | 73 | } |
embeddedartists | 0:6b68dac0d986 | 74 | |
embeddedartists | 0:6b68dac0d986 | 75 | void InternalEEPROM::setCmd(uint32_t cmd) |
embeddedartists | 0:6b68dac0d986 | 76 | { |
embeddedartists | 0:6b68dac0d986 | 77 | LPC_EEPROM->CMD = cmd; |
embeddedartists | 0:6b68dac0d986 | 78 | } |
embeddedartists | 0:6b68dac0d986 | 79 | |
embeddedartists | 0:6b68dac0d986 | 80 | void InternalEEPROM::readPage(uint32_t pageAddr, uint32_t pageOffset, uint8_t* buf, uint32_t size) |
embeddedartists | 0:6b68dac0d986 | 81 | { |
embeddedartists | 0:6b68dac0d986 | 82 | clearInterrupt(EEPROM_INT_ENDOFRW); |
embeddedartists | 0:6b68dac0d986 | 83 | setAddr(pageAddr, pageOffset); |
embeddedartists | 0:6b68dac0d986 | 84 | setCmd(EEPROM_CMD_8BITS_READ | EEPROM_CMD_RDPREFETCH); |
embeddedartists | 0:6b68dac0d986 | 85 | for (int i = 0; i < size; i++) { |
embeddedartists | 0:6b68dac0d986 | 86 | buf[i] = LPC_EEPROM->RDATA & 0xff; |
embeddedartists | 0:6b68dac0d986 | 87 | waitForInterrupt(EEPROM_INT_ENDOFRW); |
embeddedartists | 0:6b68dac0d986 | 88 | } |
embeddedartists | 0:6b68dac0d986 | 89 | } |
embeddedartists | 0:6b68dac0d986 | 90 | |
embeddedartists | 0:6b68dac0d986 | 91 | void InternalEEPROM::writePage(uint32_t pageAddr, uint32_t pageOffset, const uint8_t* buf, uint32_t size) |
embeddedartists | 0:6b68dac0d986 | 92 | { |
embeddedartists | 0:6b68dac0d986 | 93 | clearInterrupt(EEPROM_INT_ENDOFRW); |
embeddedartists | 0:6b68dac0d986 | 94 | setCmd(EEPROM_CMD_8BITS_WRITE); |
embeddedartists | 0:6b68dac0d986 | 95 | setAddr(pageAddr, pageOffset); |
embeddedartists | 0:6b68dac0d986 | 96 | for (int i = 0; i < size; i++) { |
embeddedartists | 0:6b68dac0d986 | 97 | LPC_EEPROM->WDATA = buf[i]; |
embeddedartists | 0:6b68dac0d986 | 98 | waitForInterrupt(EEPROM_INT_ENDOFRW); |
embeddedartists | 0:6b68dac0d986 | 99 | } |
embeddedartists | 0:6b68dac0d986 | 100 | } |
embeddedartists | 0:6b68dac0d986 | 101 | |
embeddedartists | 0:6b68dac0d986 | 102 | void InternalEEPROM::eraseOrProgramPage(uint32_t pageAddr) |
embeddedartists | 0:6b68dac0d986 | 103 | { |
embeddedartists | 0:6b68dac0d986 | 104 | // Write data from page register to non-volatile memory |
embeddedartists | 0:6b68dac0d986 | 105 | clearInterrupt(EEPROM_INT_ENDOFPROG); |
embeddedartists | 0:6b68dac0d986 | 106 | setAddr(pageAddr, 0); |
embeddedartists | 0:6b68dac0d986 | 107 | setCmd(EEPROM_CMD_ERASE_PRG_PAGE); |
embeddedartists | 0:6b68dac0d986 | 108 | waitForInterrupt(EEPROM_INT_ENDOFPROG); |
embeddedartists | 0:6b68dac0d986 | 109 | } |
embeddedartists | 0:6b68dac0d986 | 110 | |
embeddedartists | 0:6b68dac0d986 | 111 | |
embeddedartists | 0:6b68dac0d986 | 112 | /****************************************************************************** |
embeddedartists | 0:6b68dac0d986 | 113 | * Public Functions |
embeddedartists | 0:6b68dac0d986 | 114 | *****************************************************************************/ |
embeddedartists | 0:6b68dac0d986 | 115 | |
embeddedartists | 0:6b68dac0d986 | 116 | InternalEEPROM::InternalEEPROM() : _initialized(false) |
embeddedartists | 0:6b68dac0d986 | 117 | { |
embeddedartists | 0:6b68dac0d986 | 118 | } |
embeddedartists | 0:6b68dac0d986 | 119 | |
embeddedartists | 0:6b68dac0d986 | 120 | InternalEEPROM::~InternalEEPROM() |
embeddedartists | 0:6b68dac0d986 | 121 | { |
embeddedartists | 0:6b68dac0d986 | 122 | } |
embeddedartists | 0:6b68dac0d986 | 123 | |
embeddedartists | 0:6b68dac0d986 | 124 | void InternalEEPROM::init() |
embeddedartists | 0:6b68dac0d986 | 125 | { |
embeddedartists | 0:6b68dac0d986 | 126 | if (!_initialized) { |
embeddedartists | 0:6b68dac0d986 | 127 | // Bring EEPROM device out of power down mode |
embeddedartists | 0:6b68dac0d986 | 128 | powerUp(); |
embeddedartists | 0:6b68dac0d986 | 129 | |
embeddedartists | 0:6b68dac0d986 | 130 | // Setup EEPROM timing to 375KHz based on PCLK rate |
embeddedartists | 0:6b68dac0d986 | 131 | uint32_t clk = SystemCoreClock; |
embeddedartists | 0:6b68dac0d986 | 132 | LPC_EEPROM->CLKDIV = SystemCoreClock / 375000 - 1; |
embeddedartists | 0:6b68dac0d986 | 133 | |
embeddedartists | 0:6b68dac0d986 | 134 | // Setup wait states (ticks needed for 15ms, 55ms and 35ms) |
embeddedartists | 0:6b68dac0d986 | 135 | uint32_t val; |
embeddedartists | 0:6b68dac0d986 | 136 | val = ((((clk / 1000000) * 15) / 1000) + 1); |
embeddedartists | 0:6b68dac0d986 | 137 | val |= (((((clk / 1000000) * 55) / 1000) + 1) << 8); |
embeddedartists | 0:6b68dac0d986 | 138 | val |= (((((clk / 1000000) * 35) / 1000) + 1) << 16); |
embeddedartists | 0:6b68dac0d986 | 139 | LPC_EEPROM->WSTATE = val; |
embeddedartists | 0:6b68dac0d986 | 140 | |
embeddedartists | 0:6b68dac0d986 | 141 | _initialized = true; |
embeddedartists | 0:6b68dac0d986 | 142 | } |
embeddedartists | 0:6b68dac0d986 | 143 | } |
embeddedartists | 0:6b68dac0d986 | 144 | |
embeddedartists | 0:6b68dac0d986 | 145 | void InternalEEPROM::powerDown() |
embeddedartists | 0:6b68dac0d986 | 146 | { |
embeddedartists | 0:6b68dac0d986 | 147 | LPC_EEPROM->PWRDWN = EEPROM_PWRDWN; |
embeddedartists | 0:6b68dac0d986 | 148 | } |
embeddedartists | 0:6b68dac0d986 | 149 | |
embeddedartists | 0:6b68dac0d986 | 150 | int InternalEEPROM::read(uint32_t pageAddr, uint32_t pageOffset, uint8_t* data, uint32_t size) |
embeddedartists | 0:6b68dac0d986 | 151 | { |
embeddedartists | 0:6b68dac0d986 | 152 | uint32_t numRead = 0; |
embeddedartists | 0:6b68dac0d986 | 153 | uint32_t readOffset = (pageOffset & (EEPROM_PAGE_SIZE - 1)); |
embeddedartists | 0:6b68dac0d986 | 154 | uint32_t readSize = EEPROM_PAGE_SIZE - readOffset; |
embeddedartists | 0:6b68dac0d986 | 155 | |
embeddedartists | 0:6b68dac0d986 | 156 | powerUp(); |
embeddedartists | 0:6b68dac0d986 | 157 | |
embeddedartists | 0:6b68dac0d986 | 158 | // Read and store data in buffer |
embeddedartists | 0:6b68dac0d986 | 159 | while (size) { |
embeddedartists | 0:6b68dac0d986 | 160 | // Make sure we don't write past the end of the buffer |
embeddedartists | 0:6b68dac0d986 | 161 | if (readSize > size) { |
embeddedartists | 0:6b68dac0d986 | 162 | readSize = size; |
embeddedartists | 0:6b68dac0d986 | 163 | } |
embeddedartists | 0:6b68dac0d986 | 164 | |
embeddedartists | 0:6b68dac0d986 | 165 | readPage(pageAddr, readOffset, &(data[numRead]), readSize); |
embeddedartists | 0:6b68dac0d986 | 166 | numRead += readSize; |
embeddedartists | 0:6b68dac0d986 | 167 | size -= readSize; |
embeddedartists | 0:6b68dac0d986 | 168 | |
embeddedartists | 0:6b68dac0d986 | 169 | // Change to next page |
embeddedartists | 0:6b68dac0d986 | 170 | pageAddr++; |
embeddedartists | 0:6b68dac0d986 | 171 | readOffset = 0; |
embeddedartists | 0:6b68dac0d986 | 172 | readSize = EEPROM_PAGE_SIZE; |
embeddedartists | 0:6b68dac0d986 | 173 | } |
embeddedartists | 0:6b68dac0d986 | 174 | return numRead; |
embeddedartists | 0:6b68dac0d986 | 175 | } |
embeddedartists | 0:6b68dac0d986 | 176 | |
embeddedartists | 0:6b68dac0d986 | 177 | int InternalEEPROM::write(uint32_t pageAddr, uint32_t pageOffset, const uint8_t* data, uint32_t size) |
embeddedartists | 0:6b68dac0d986 | 178 | { |
embeddedartists | 0:6b68dac0d986 | 179 | #if defined(DM_BOARD_USE_INT_EEPROM_WRITE) |
embeddedartists | 0:6b68dac0d986 | 180 | uint32_t numWritten = 0; |
embeddedartists | 0:6b68dac0d986 | 181 | uint32_t writeOffset = (pageOffset & (EEPROM_PAGE_SIZE - 1)); |
embeddedartists | 0:6b68dac0d986 | 182 | uint32_t writeSize = EEPROM_PAGE_SIZE - writeOffset; |
embeddedartists | 0:6b68dac0d986 | 183 | |
embeddedartists | 0:6b68dac0d986 | 184 | powerUp(); |
embeddedartists | 0:6b68dac0d986 | 185 | |
embeddedartists | 0:6b68dac0d986 | 186 | // Read and store data in buffer |
embeddedartists | 0:6b68dac0d986 | 187 | while (size) { |
embeddedartists | 0:6b68dac0d986 | 188 | // Make sure we don't read past the end of the buffer |
embeddedartists | 0:6b68dac0d986 | 189 | if (writeSize > size) { |
embeddedartists | 0:6b68dac0d986 | 190 | writeSize = size; |
embeddedartists | 0:6b68dac0d986 | 191 | } |
embeddedartists | 0:6b68dac0d986 | 192 | |
embeddedartists | 0:6b68dac0d986 | 193 | writePage(pageAddr, writeOffset, &(data[numWritten]), writeSize); |
embeddedartists | 0:6b68dac0d986 | 194 | eraseOrProgramPage(pageAddr); |
embeddedartists | 0:6b68dac0d986 | 195 | numWritten += writeSize; |
embeddedartists | 0:6b68dac0d986 | 196 | size -= writeSize; |
embeddedartists | 0:6b68dac0d986 | 197 | |
embeddedartists | 0:6b68dac0d986 | 198 | // Change to next page |
embeddedartists | 0:6b68dac0d986 | 199 | pageAddr++; |
embeddedartists | 0:6b68dac0d986 | 200 | writeOffset = 0; |
embeddedartists | 0:6b68dac0d986 | 201 | writeSize = EEPROM_PAGE_SIZE; |
embeddedartists | 0:6b68dac0d986 | 202 | } |
embeddedartists | 0:6b68dac0d986 | 203 | return numWritten; |
embeddedartists | 0:6b68dac0d986 | 204 | #else |
embeddedartists | 0:6b68dac0d986 | 205 | return 0; |
embeddedartists | 0:6b68dac0d986 | 206 | #endif |
embeddedartists | 0:6b68dac0d986 | 207 | } |
embeddedartists | 0:6b68dac0d986 | 208 | |
embeddedartists | 0:6b68dac0d986 | 209 | void InternalEEPROM::erasePage(uint32_t pageAddr) |
embeddedartists | 0:6b68dac0d986 | 210 | { |
embeddedartists | 0:6b68dac0d986 | 211 | #if defined(DM_BOARD_USE_INT_EEPROM_WRITE) |
embeddedartists | 0:6b68dac0d986 | 212 | |
embeddedartists | 0:6b68dac0d986 | 213 | powerUp(); |
embeddedartists | 0:6b68dac0d986 | 214 | |
embeddedartists | 0:6b68dac0d986 | 215 | clearInterrupt(EEPROM_INT_ENDOFRW); |
embeddedartists | 0:6b68dac0d986 | 216 | setCmd(EEPROM_CMD_32BITS_WRITE); |
embeddedartists | 0:6b68dac0d986 | 217 | setAddr(pageAddr, 0); |
embeddedartists | 0:6b68dac0d986 | 218 | for (int i = 0; i < EEPROM_PAGE_SIZE; i+=4) { |
embeddedartists | 0:6b68dac0d986 | 219 | LPC_EEPROM->WDATA = 0; |
embeddedartists | 0:6b68dac0d986 | 220 | waitForInterrupt(EEPROM_INT_ENDOFRW); |
embeddedartists | 0:6b68dac0d986 | 221 | } |
embeddedartists | 0:6b68dac0d986 | 222 | eraseOrProgramPage(pageAddr); |
embeddedartists | 0:6b68dac0d986 | 223 | #endif |
embeddedartists | 0:6b68dac0d986 | 224 | } |