SpiFlash25

Fork of SpiFlash25 by MultiTech

Committer:
Mike Fiore
Date:
Mon Dec 15 16:35:47 2014 -0600
Revision:
3:b173ba8ad165
Parent:
1:17246d2dfff3
Child:
4:751745dd637f
fix bug: can't create DigitalOut(NC) instances, we get an assert failure

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 {
mfiore 0:137807d94795 30 _cs.write(1);
mfiore 0:137807d94795 31 _spi.format(8, 3);
mfiore 0:137807d94795 32 _spi.frequency(75000000);
mfiore 0:137807d94795 33
Mike Fiore 3:b173ba8ad165 34 if (W != NC) {
Mike Fiore 3:b173ba8ad165 35 _w = new DigitalOut(W);
Mike Fiore 3:b173ba8ad165 36 _w->write(1);
Mike Fiore 3:b173ba8ad165 37 }
Mike Fiore 3:b173ba8ad165 38 if (HOLD != NC) {
Mike Fiore 3:b173ba8ad165 39 _hold = new DigitalOut(HOLD);
Mike Fiore 3:b173ba8ad165 40 _hold->write(1);
Mike Fiore 3:b173ba8ad165 41 }
Mike Fiore 1:17246d2dfff3 42
mfiore 0:137807d94795 43 _cs.write(0);
mfiore 0:137807d94795 44 _spi.write(READ_IDENTIFICATION);
mfiore 0:137807d94795 45 _id[ID_MANUFACTURER] = _spi.write(0x00);
mfiore 0:137807d94795 46 _id[ID_MEM_TYPE] = _spi.write(0x00);
mfiore 0:137807d94795 47 _id[ID_MEM_SIZE] = _spi.write(0x00);
mfiore 0:137807d94795 48 _cs.write(1);
mfiore 0:137807d94795 49
mfiore 0:137807d94795 50 _mem_size = 1 << _id[ID_MEM_SIZE];
mfiore 0:137807d94795 51 }
mfiore 0:137807d94795 52
mfiore 0:137807d94795 53 void SpiFlash25::format(int bits, int mode) {
mfiore 0:137807d94795 54 _spi.format(bits, mode);
mfiore 0:137807d94795 55 }
mfiore 0:137807d94795 56
mfiore 0:137807d94795 57 void SpiFlash25::frequency(int hz) {
mfiore 0:137807d94795 58 _spi.frequency(hz);
mfiore 0:137807d94795 59 }
mfiore 0:137807d94795 60
mfiore 0:137807d94795 61 bool SpiFlash25::read(int addr, int len, char* data) {
mfiore 0:137807d94795 62 if (addr + len > _mem_size) {
mfiore 0:137807d94795 63 return false;
mfiore 0:137807d94795 64 }
mfiore 0:137807d94795 65
mfiore 0:137807d94795 66 enable_write();
mfiore 0:137807d94795 67
mfiore 0:137807d94795 68 _cs.write(0);
mfiore 0:137807d94795 69 _spi.write(READ_DATA);
mfiore 0:137807d94795 70 _spi.write(high_byte(addr));
mfiore 0:137807d94795 71 _spi.write(mid_byte(addr));
mfiore 0:137807d94795 72 _spi.write(low_byte(addr));
mfiore 0:137807d94795 73
mfiore 0:137807d94795 74 for (int i = 0; i < len; i++) {
mfiore 0:137807d94795 75 data[i] = _spi.write(0x00);
mfiore 0:137807d94795 76 }
mfiore 0:137807d94795 77
mfiore 0:137807d94795 78 _cs.write(1);
mfiore 0:137807d94795 79
mfiore 0:137807d94795 80 return true;
mfiore 0:137807d94795 81 }
mfiore 0:137807d94795 82
mfiore 0:137807d94795 83 bool SpiFlash25::write(int addr, int len, const char* data) {
mfiore 0:137807d94795 84 if (addr + len > _mem_size) {
mfiore 0:137807d94795 85 return false;
mfiore 0:137807d94795 86 }
mfiore 0:137807d94795 87
mfiore 0:137807d94795 88 int written = 0;
mfiore 0:137807d94795 89 int write_size = 0;
mfiore 0:137807d94795 90
mfiore 0:137807d94795 91 while (written < len) {
mfiore 0:137807d94795 92 write_size = _page_size - ((addr + written) % _page_size);
mfiore 0:137807d94795 93 if (written + write_size > len) {
mfiore 0:137807d94795 94 write_size = len - written;
mfiore 0:137807d94795 95 }
mfiore 0:137807d94795 96
mfiore 0:137807d94795 97 if (! write_page(addr + written, write_size, data + written)) {
mfiore 0:137807d94795 98 return false;
mfiore 0:137807d94795 99 }
mfiore 0:137807d94795 100
mfiore 0:137807d94795 101 written += write_size;
mfiore 0:137807d94795 102 }
mfiore 0:137807d94795 103
mfiore 0:137807d94795 104 return true;
mfiore 0:137807d94795 105 }
mfiore 0:137807d94795 106
mfiore 0:137807d94795 107 char* SpiFlash25::read_id() {
mfiore 0:137807d94795 108 return _id;
mfiore 0:137807d94795 109 }
mfiore 0:137807d94795 110
mfiore 0:137807d94795 111 char SpiFlash25::read_status() {
mfiore 0:137807d94795 112 char status;
mfiore 0:137807d94795 113
mfiore 0:137807d94795 114 _cs.write(0);
mfiore 0:137807d94795 115 _spi.write(READ_STATUS);
mfiore 0:137807d94795 116 status = _spi.write(0x00);
mfiore 0:137807d94795 117 _cs.write(1);
mfiore 0:137807d94795 118
mfiore 0:137807d94795 119 return status;
mfiore 0:137807d94795 120 }
mfiore 0:137807d94795 121
mfiore 0:137807d94795 122 void SpiFlash25::clear_sector(int addr) {
mfiore 0:137807d94795 123 enable_write();
mfiore 0:137807d94795 124
mfiore 0:137807d94795 125 _cs.write(0);
mfiore 0:137807d94795 126 _spi.write(SECTOR_ERASE);
mfiore 0:137807d94795 127 _spi.write(high_byte(addr));
mfiore 0:137807d94795 128 _spi.write(mid_byte(addr));
mfiore 0:137807d94795 129 _spi.write(low_byte(addr));
mfiore 0:137807d94795 130 _cs.write(1);
mfiore 0:137807d94795 131
mfiore 0:137807d94795 132 wait_for_write();
mfiore 0:137807d94795 133 }
mfiore 0:137807d94795 134
mfiore 0:137807d94795 135 void SpiFlash25::clear_mem() {
mfiore 0:137807d94795 136 enable_write();
mfiore 0:137807d94795 137
mfiore 0:137807d94795 138 _cs.write(0);
mfiore 0:137807d94795 139 _spi.write(BULK_ERASE);
mfiore 0:137807d94795 140 _cs.write(1);
mfiore 0:137807d94795 141
mfiore 0:137807d94795 142 wait_for_write();
mfiore 0:137807d94795 143 }
mfiore 0:137807d94795 144
mfiore 0:137807d94795 145 bool SpiFlash25::write_page(int addr, int len, const char* data) {
mfiore 0:137807d94795 146 enable_write();
mfiore 0:137807d94795 147
mfiore 0:137807d94795 148 _cs.write(0);
mfiore 0:137807d94795 149 _spi.write(PAGE_PROGRAM);
mfiore 0:137807d94795 150 _spi.write(high_byte(addr));
mfiore 0:137807d94795 151 _spi.write(mid_byte(addr));
mfiore 0:137807d94795 152 _spi.write(low_byte(addr));
mfiore 0:137807d94795 153
mfiore 0:137807d94795 154 for (int i = 0; i < len; i++) {
mfiore 0:137807d94795 155 _spi.write(data[i]);
mfiore 0:137807d94795 156 }
mfiore 0:137807d94795 157
mfiore 0:137807d94795 158 _cs.write(1);
mfiore 0:137807d94795 159 wait_for_write();
mfiore 0:137807d94795 160
mfiore 0:137807d94795 161 return true;
mfiore 0:137807d94795 162 }
mfiore 0:137807d94795 163
mfiore 0:137807d94795 164 void SpiFlash25::enable_write() {
mfiore 0:137807d94795 165 _cs.write(0);
mfiore 0:137807d94795 166 _spi.write(WRITE_ENABLE);
mfiore 0:137807d94795 167 _cs.write(1);
mfiore 0:137807d94795 168 }
mfiore 0:137807d94795 169
mfiore 0:137807d94795 170 void SpiFlash25::wait_for_write() {
mfiore 0:137807d94795 171 while (read_status() & STATUS_WIP) {
mfiore 0:137807d94795 172 wait_us(10);
mfiore 0:137807d94795 173 }
Mike Fiore 1:17246d2dfff3 174 }