SpiFlash25

Fork of SpiFlash25 by MultiTech

Committer:
Mike Fiore
Date:
Mon Jun 08 15:52:34 2015 -0500
Revision:
4:751745dd637f
Parent:
3:b173ba8ad165
add sleep changes from git repo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mfiore 0:137807d94795 1 /* Library for SPI flash 25* devices.
mfiore 0:137807d94795 2 * Copyright (c) 2014 Multi-Tech Systems
mfiore 0:137807d94795 3 *
mfiore 0:137807d94795 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
mfiore 0:137807d94795 5 * of this software and associated documentation files (the "Software"), to deal
mfiore 0:137807d94795 6 * in the Software without restriction, including without limitation the rights
mfiore 0:137807d94795 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
mfiore 0:137807d94795 8 * copies of the Software, and to permit persons to whom the Software is
mfiore 0:137807d94795 9 * furnished to do so, subject to the following conditions:
mfiore 0:137807d94795 10 *
mfiore 0:137807d94795 11 * The above copyright notice and this permission notice shall be included in
mfiore 0:137807d94795 12 * all copies or substantial portions of the Software.
mfiore 0:137807d94795 13 *
mfiore 0:137807d94795 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
mfiore 0:137807d94795 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
mfiore 0:137807d94795 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
mfiore 0:137807d94795 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
mfiore 0:137807d94795 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mfiore 0:137807d94795 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
mfiore 0:137807d94795 20 * SOFTWARE.
mfiore 0:137807d94795 21 */
mfiore 0:137807d94795 22
mfiore 0:137807d94795 23 #include "SpiFlash25.h"
mfiore 0:137807d94795 24
Mike Fiore 1:17246d2dfff3 25 SpiFlash25::SpiFlash25(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName W, PinName HOLD, int page_size)
mfiore 0:137807d94795 26 : _spi(mosi, miso, sclk),
mfiore 0:137807d94795 27 _cs(cs),
mfiore 0:137807d94795 28 _page_size(page_size)
mfiore 0:137807d94795 29 {
Mike Fiore 4:751745dd637f 30
Mike Fiore 4:751745dd637f 31 wakeup();
Mike Fiore 4:751745dd637f 32
mfiore 0:137807d94795 33 _cs.write(1);
mfiore 0:137807d94795 34 _spi.format(8, 3);
mfiore 0:137807d94795 35 _spi.frequency(75000000);
mfiore 0:137807d94795 36
Mike Fiore 3:b173ba8ad165 37 if (W != NC) {
Mike Fiore 3:b173ba8ad165 38 _w = new DigitalOut(W);
Mike Fiore 3:b173ba8ad165 39 _w->write(1);
Mike Fiore 3:b173ba8ad165 40 }
Mike Fiore 3:b173ba8ad165 41 if (HOLD != NC) {
Mike Fiore 3:b173ba8ad165 42 _hold = new DigitalOut(HOLD);
Mike Fiore 3:b173ba8ad165 43 _hold->write(1);
Mike Fiore 3:b173ba8ad165 44 }
Mike Fiore 1:17246d2dfff3 45
mfiore 0:137807d94795 46 _cs.write(0);
mfiore 0:137807d94795 47 _spi.write(READ_IDENTIFICATION);
mfiore 0:137807d94795 48 _id[ID_MANUFACTURER] = _spi.write(0x00);
mfiore 0:137807d94795 49 _id[ID_MEM_TYPE] = _spi.write(0x00);
mfiore 0:137807d94795 50 _id[ID_MEM_SIZE] = _spi.write(0x00);
mfiore 0:137807d94795 51 _cs.write(1);
mfiore 0:137807d94795 52
mfiore 0:137807d94795 53 _mem_size = 1 << _id[ID_MEM_SIZE];
mfiore 0:137807d94795 54 }
mfiore 0:137807d94795 55
mfiore 0:137807d94795 56 void SpiFlash25::format(int bits, int mode) {
mfiore 0:137807d94795 57 _spi.format(bits, mode);
mfiore 0:137807d94795 58 }
mfiore 0:137807d94795 59
mfiore 0:137807d94795 60 void SpiFlash25::frequency(int hz) {
mfiore 0:137807d94795 61 _spi.frequency(hz);
mfiore 0:137807d94795 62 }
mfiore 0:137807d94795 63
mfiore 0:137807d94795 64 bool SpiFlash25::read(int addr, int len, char* data) {
mfiore 0:137807d94795 65 if (addr + len > _mem_size) {
mfiore 0:137807d94795 66 return false;
mfiore 0:137807d94795 67 }
mfiore 0:137807d94795 68
mfiore 0:137807d94795 69 enable_write();
mfiore 0:137807d94795 70
mfiore 0:137807d94795 71 _cs.write(0);
mfiore 0:137807d94795 72 _spi.write(READ_DATA);
mfiore 0:137807d94795 73 _spi.write(high_byte(addr));
mfiore 0:137807d94795 74 _spi.write(mid_byte(addr));
mfiore 0:137807d94795 75 _spi.write(low_byte(addr));
mfiore 0:137807d94795 76
mfiore 0:137807d94795 77 for (int i = 0; i < len; i++) {
mfiore 0:137807d94795 78 data[i] = _spi.write(0x00);
mfiore 0:137807d94795 79 }
mfiore 0:137807d94795 80
mfiore 0:137807d94795 81 _cs.write(1);
mfiore 0:137807d94795 82
mfiore 0:137807d94795 83 return true;
mfiore 0:137807d94795 84 }
mfiore 0:137807d94795 85
mfiore 0:137807d94795 86 bool SpiFlash25::write(int addr, int len, const char* data) {
mfiore 0:137807d94795 87 if (addr + len > _mem_size) {
mfiore 0:137807d94795 88 return false;
mfiore 0:137807d94795 89 }
mfiore 0:137807d94795 90
mfiore 0:137807d94795 91 int written = 0;
mfiore 0:137807d94795 92 int write_size = 0;
mfiore 0:137807d94795 93
mfiore 0:137807d94795 94 while (written < len) {
mfiore 0:137807d94795 95 write_size = _page_size - ((addr + written) % _page_size);
mfiore 0:137807d94795 96 if (written + write_size > len) {
mfiore 0:137807d94795 97 write_size = len - written;
mfiore 0:137807d94795 98 }
mfiore 0:137807d94795 99
mfiore 0:137807d94795 100 if (! write_page(addr + written, write_size, data + written)) {
mfiore 0:137807d94795 101 return false;
mfiore 0:137807d94795 102 }
mfiore 0:137807d94795 103
mfiore 0:137807d94795 104 written += write_size;
mfiore 0:137807d94795 105 }
mfiore 0:137807d94795 106
mfiore 0:137807d94795 107 return true;
mfiore 0:137807d94795 108 }
mfiore 0:137807d94795 109
mfiore 0:137807d94795 110 char* SpiFlash25::read_id() {
mfiore 0:137807d94795 111 return _id;
mfiore 0:137807d94795 112 }
mfiore 0:137807d94795 113
mfiore 0:137807d94795 114 char SpiFlash25::read_status() {
mfiore 0:137807d94795 115 char status;
mfiore 0:137807d94795 116
mfiore 0:137807d94795 117 _cs.write(0);
mfiore 0:137807d94795 118 _spi.write(READ_STATUS);
mfiore 0:137807d94795 119 status = _spi.write(0x00);
mfiore 0:137807d94795 120 _cs.write(1);
mfiore 0:137807d94795 121
mfiore 0:137807d94795 122 return status;
mfiore 0:137807d94795 123 }
mfiore 0:137807d94795 124
mfiore 0:137807d94795 125 void SpiFlash25::clear_sector(int addr) {
mfiore 0:137807d94795 126 enable_write();
mfiore 0:137807d94795 127
mfiore 0:137807d94795 128 _cs.write(0);
mfiore 0:137807d94795 129 _spi.write(SECTOR_ERASE);
mfiore 0:137807d94795 130 _spi.write(high_byte(addr));
mfiore 0:137807d94795 131 _spi.write(mid_byte(addr));
mfiore 0:137807d94795 132 _spi.write(low_byte(addr));
mfiore 0:137807d94795 133 _cs.write(1);
mfiore 0:137807d94795 134
mfiore 0:137807d94795 135 wait_for_write();
mfiore 0:137807d94795 136 }
mfiore 0:137807d94795 137
mfiore 0:137807d94795 138 void SpiFlash25::clear_mem() {
mfiore 0:137807d94795 139 enable_write();
mfiore 0:137807d94795 140
mfiore 0:137807d94795 141 _cs.write(0);
mfiore 0:137807d94795 142 _spi.write(BULK_ERASE);
mfiore 0:137807d94795 143 _cs.write(1);
mfiore 0:137807d94795 144
mfiore 0:137807d94795 145 wait_for_write();
mfiore 0:137807d94795 146 }
mfiore 0:137807d94795 147
mfiore 0:137807d94795 148 bool SpiFlash25::write_page(int addr, int len, const char* data) {
mfiore 0:137807d94795 149 enable_write();
mfiore 0:137807d94795 150
mfiore 0:137807d94795 151 _cs.write(0);
mfiore 0:137807d94795 152 _spi.write(PAGE_PROGRAM);
mfiore 0:137807d94795 153 _spi.write(high_byte(addr));
mfiore 0:137807d94795 154 _spi.write(mid_byte(addr));
mfiore 0:137807d94795 155 _spi.write(low_byte(addr));
mfiore 0:137807d94795 156
mfiore 0:137807d94795 157 for (int i = 0; i < len; i++) {
mfiore 0:137807d94795 158 _spi.write(data[i]);
mfiore 0:137807d94795 159 }
mfiore 0:137807d94795 160
mfiore 0:137807d94795 161 _cs.write(1);
mfiore 0:137807d94795 162 wait_for_write();
mfiore 0:137807d94795 163
mfiore 0:137807d94795 164 return true;
mfiore 0:137807d94795 165 }
mfiore 0:137807d94795 166
mfiore 0:137807d94795 167 void SpiFlash25::enable_write() {
mfiore 0:137807d94795 168 _cs.write(0);
mfiore 0:137807d94795 169 _spi.write(WRITE_ENABLE);
mfiore 0:137807d94795 170 _cs.write(1);
mfiore 0:137807d94795 171 }
mfiore 0:137807d94795 172
mfiore 0:137807d94795 173 void SpiFlash25::wait_for_write() {
mfiore 0:137807d94795 174 while (read_status() & STATUS_WIP) {
mfiore 0:137807d94795 175 wait_us(10);
mfiore 0:137807d94795 176 }
Mike Fiore 1:17246d2dfff3 177 }
Mike Fiore 4:751745dd637f 178
Mike Fiore 4:751745dd637f 179 void SpiFlash25::deep_power_down() {
Mike Fiore 4:751745dd637f 180 _cs.write(0);
Mike Fiore 4:751745dd637f 181 _spi.write(DEEP_POWER_DOWN);
Mike Fiore 4:751745dd637f 182 _cs.write(1);
Mike Fiore 4:751745dd637f 183 }
Mike Fiore 4:751745dd637f 184
Mike Fiore 4:751745dd637f 185 void SpiFlash25::wakeup() {
Mike Fiore 4:751745dd637f 186 _cs.write(0);
Mike Fiore 4:751745dd637f 187 _spi.write(DEEP_POWER_DOWN_RELEASE);
Mike Fiore 4:751745dd637f 188 _cs.write(1);
Mike Fiore 4:751745dd637f 189 }