Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: flash-fs-example Dragonfly_Filesystem_Example Dragonfly_Low_Power_Example STM32F407VET6_SPIFlash ... more
SpiFlash25.cpp
00001 /* Library for SPI flash 25* devices. 00002 * Copyright (c) 2014 Multi-Tech Systems 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00020 * SOFTWARE. 00021 */ 00022 00023 #include "SpiFlash25.h" 00024 00025 SpiFlash25::SpiFlash25(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName W, PinName HOLD, int page_size, int mem_size) 00026 : _spi(mosi, miso, sclk), 00027 _cs(cs), 00028 _mem_size(mem_size), 00029 _page_size(page_size) 00030 { 00031 00032 _cs.write(1); 00033 _spi.format(8, 3); 00034 _spi.frequency(75000000); 00035 00036 if (W != NC) { 00037 _w = new DigitalOut(W); 00038 _w->write(1); 00039 } 00040 if (HOLD != NC) { 00041 _hold = new DigitalOut(HOLD); 00042 _hold->write(1); 00043 } 00044 00045 wakeup(); 00046 } 00047 00048 void SpiFlash25::format(int bits, int mode) { 00049 _spi.format(bits, mode); 00050 } 00051 00052 void SpiFlash25::frequency(int hz) { 00053 _spi.frequency(hz); 00054 } 00055 00056 bool SpiFlash25::read(int addr, int len, char* data) { 00057 if (addr + len > _mem_size) { 00058 return false; 00059 } 00060 00061 enable_write(); 00062 00063 _cs.write(0); 00064 _spi.write(READ_DATA); 00065 _spi.write(high_byte(addr)); 00066 _spi.write(mid_byte(addr)); 00067 _spi.write(low_byte(addr)); 00068 00069 for (int i = 0; i < len; i++) { 00070 data[i] = _spi.write(0x00); 00071 } 00072 00073 _cs.write(1); 00074 00075 return true; 00076 } 00077 00078 bool SpiFlash25::write(int addr, int len, const char* data) { 00079 if (addr + len > _mem_size) { 00080 return false; 00081 } 00082 00083 int written = 0; 00084 int write_size = 0; 00085 00086 while (written < len) { 00087 write_size = _page_size - ((addr + written) % _page_size); 00088 if (written + write_size > len) { 00089 write_size = len - written; 00090 } 00091 00092 if (! write_page(addr + written, write_size, data + written)) { 00093 return false; 00094 } 00095 00096 written += write_size; 00097 } 00098 00099 return true; 00100 } 00101 00102 char* SpiFlash25::read_id() { 00103 _cs.write(0); 00104 _spi.write(READ_IDENTIFICATION); 00105 _id[ID_MANUFACTURER] = _spi.write(0x00); 00106 _id[ID_MEM_TYPE] = _spi.write(0x00); 00107 _id[ID_MEM_SIZE] = _spi.write(0x00); 00108 _cs.write(1); 00109 00110 return _id; 00111 } 00112 00113 void SpiFlash25::write_status(char data) { 00114 enable_write(); 00115 _cs.write(0); 00116 _spi.write(WRITE_STATUS); 00117 _spi.write(data); 00118 _cs.write(1); 00119 wait_for_write(15); 00120 } 00121 00122 char SpiFlash25::read_status() { 00123 char status; 00124 00125 _cs.write(0); 00126 _spi.write(READ_STATUS); 00127 status = _spi.write(0x00); 00128 _cs.write(1); 00129 00130 return status; 00131 } 00132 00133 void SpiFlash25::clear_sector(int addr) { 00134 enable_write(); 00135 00136 _cs.write(0); 00137 _spi.write(SECTOR_ERASE); 00138 _spi.write(high_byte(addr)); 00139 _spi.write(mid_byte(addr)); 00140 _spi.write(low_byte(addr)); 00141 _cs.write(1); 00142 00143 wait_for_write(3000); 00144 } 00145 00146 void SpiFlash25::clear_mem() { 00147 enable_write(); 00148 00149 _cs.write(0); 00150 _spi.write(BULK_ERASE); 00151 _cs.write(1); 00152 00153 wait_for_write(20000); 00154 } 00155 00156 bool SpiFlash25::write_page(int addr, int len, const char* data) { 00157 enable_write(); 00158 00159 _cs.write(0); 00160 _spi.write(PAGE_PROGRAM); 00161 _spi.write(high_byte(addr)); 00162 _spi.write(mid_byte(addr)); 00163 _spi.write(low_byte(addr)); 00164 00165 for (int i = 0; i < len; i++) { 00166 _spi.write(data[i]); 00167 } 00168 00169 _cs.write(1); 00170 00171 return wait_for_write(5); 00172 } 00173 00174 void SpiFlash25::enable_write() { 00175 _cs.write(0); 00176 _spi.write(WRITE_ENABLE); 00177 _cs.write(1); 00178 } 00179 00180 bool SpiFlash25::wait_for_write(int32_t timeout_ms) { 00181 timeout_ms *= 100; 00182 while ((read_status() & STATUS_WIP) && (timeout_ms-- > 0)) { 00183 wait_us(10); 00184 } 00185 return timeout_ms > 0; 00186 } 00187 00188 void SpiFlash25::deep_power_down() { 00189 _cs.write(0); 00190 _spi.write(DEEP_POWER_DOWN); 00191 _cs.write(1); 00192 } 00193 00194 void SpiFlash25::wakeup() { 00195 _cs.write(0); 00196 _spi.write(DEEP_POWER_DOWN_RELEASE); 00197 _cs.write(1); 00198 } 00199
Generated on Thu Jul 14 2022 05:11:24 by
