drv_m25p16.c
Go to the documentation of this file.
1 /*
2  drv_m25p16.c : driver for Micron Technology MP25P16 flash memory
3 
4  Adapted from https://github.com/cleanflight/cleanflight/blob/master/src/main/drivers/flash_m25p16.c
5 
6  This file is part of BreezySTM32.
7 
8  BreezySTM32 is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  BreezySTM32 is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with BreezySTM32. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <stdlib.h>
23 #include <stdbool.h>
24 #include <stdint.h>
25 
26 #include "stm32f10x_conf.h"
27 #include "stm32f10x_gpio.h"
28 #include "core_cm3.h"
29 
30 // Chip Unique ID on F103
31 #define U_ID_0 (*(uint32_t*)0x1FFFF7E8)
32 #define U_ID_1 (*(uint32_t*)0x1FFFF7EC)
33 #define U_ID_2 (*(uint32_t*)0x1FFFF7F0)
34 
35 #define NAZE_SPI_INSTANCE SPI2
36 #define NAZE_SPI_CS_GPIO GPIOB
37 #define NAZE_SPI_CS_PIN GPIO_Pin_12
38 #define NAZE_CS_GPIO_CLK_PERIPHERAL RCC_APB2Periph_GPIOB
39 
40 // We either have this 16mbit flash chip on SPI or the MPU6500 acc/gyro depending on board revision:
41 #define M25P16_CS_GPIO NAZE_SPI_CS_GPIO
42 #define M25P16_CS_PIN NAZE_SPI_CS_PIN
43 #define M25P16_SPI_INSTANCE NAZE_SPI_INSTANCE
44 
45 
46 #include "drv_m25p16.h"
47 
48 #include <drv_spi.h>
49 #include <drv_system.h>
50 
51 #define M25P16_INSTRUCTION_RDID 0x9F
52 #define M25P16_INSTRUCTION_READ_BYTES 0x03
53 #define M25P16_INSTRUCTION_READ_STATUS_REG 0x05
54 #define M25P16_INSTRUCTION_WRITE_STATUS_REG 0x01
55 #define M25P16_INSTRUCTION_WRITE_ENABLE 0x06
56 #define M25P16_INSTRUCTION_WRITE_DISABLE 0x04
57 #define M25P16_INSTRUCTION_PAGE_PROGRAM 0x02
58 #define M25P16_INSTRUCTION_SECTOR_ERASE 0xD8
59 #define M25P16_INSTRUCTION_BULK_ERASE 0xC7
60 
61 #define M25P16_STATUS_FLAG_WRITE_IN_PROGRESS 0x01
62 #define M25P16_STATUS_FLAG_WRITE_ENABLED 0x02
63 
64 // Format is manufacturer, memory type, then capacity
65 #define JEDEC_ID_MICRON_M25P16 0x202015
66 #define JEDEC_ID_MICRON_N25Q064 0x20BA17
67 #define JEDEC_ID_WINBOND_W25Q64 0xEF4017
68 #define JEDEC_ID_MICRON_N25Q128 0x20ba18
69 #define JEDEC_ID_WINBOND_W25Q128 0xEF4018
70 
71 #define DISABLE_M25P16 GPIO_SetBits(M25P16_CS_GPIO, M25P16_CS_PIN)
72 #define ENABLE_M25P16 GPIO_ResetBits(M25P16_CS_GPIO, M25P16_CS_PIN)
73 
74 // The timeout we expect between being able to issue page program instructions
75 #define DEFAULT_TIMEOUT_MILLIS 6
76 
77 // These take sooooo long:
78 #define SECTOR_ERASE_TIMEOUT_MILLIS 5000
79 #define BULK_ERASE_TIMEOUT_MILLIS 21000
80 
82 
83 /*
84  * Whether we've performed an action that could have made the device busy for writes.
85  *
86  * This allows us to avoid polling for writable status when it is definitely ready already.
87  */
88 static bool couldBeBusy = false;
89 
93 static void m25p16_performOneByteCommand(uint8_t command)
94 {
96 
98 
100 }
101 
106 static void m25p16_writeEnable()
107 {
109 
110  // Assume that we're about to do some writing, so the device is just about to become busy
111  couldBeBusy = true;
112 }
113 
114 static uint8_t m25p16_readStatus()
115 {
117  uint8_t in[2];
118 
120 
121  spiTransfer(M25P16_SPI_INSTANCE, in, command, sizeof(command));
122 
124 
125  return in[1];
126 }
127 
129 {
130  // If couldBeBusy is false, don't bother to poll the flash chip for its status
132 
133  return !couldBeBusy;
134 }
135 
136 bool m25p16_waitForReady(uint32_t timeoutMillis)
137 {
138  uint32_t time = millis();
139  while (!m25p16_isReady()) {
140  if (millis() - time > timeoutMillis) {
141  return false;
142  }
143  }
144 
145  return true;
146 }
147 
154 {
155  uint8_t out[] = { M25P16_INSTRUCTION_RDID, 0, 0, 0};
156  uint8_t in[4];
157  uint32_t chipID;
158 
159  delay(50); // short delay required after initialisation of SPI device instance.
160 
161  /* Just in case transfer fails and writes nothing, so we don't try to verify the ID against random garbage
162  * from the stack:
163  */
164  in[1] = 0;
165 
167 
168  spiTransfer(M25P16_SPI_INSTANCE, in, out, sizeof(out));
169 
170  // Clearing the CS bit terminates the command early so we don't have to read the chip UID:
172 
173  // Manufacturer, memory type, and capacity
174  chipID = (in[1] << 16) | (in[2] << 8) | (in[3]);
175 
176  // All supported chips use the same pagesize of 256 bytes
177 
178  switch (chipID) {
180  geometry.sectors = 32;
181  geometry.pagesPerSector = 256;
182  break;
185  geometry.sectors = 128;
186  geometry.pagesPerSector = 256;
187  break;
190  geometry.sectors = 256;
191  geometry.pagesPerSector = 256;
192  break;
193  default:
194  // Unsupported chip or not an SPI NOR flash
195  geometry.sectors = 0;
196  geometry.pagesPerSector = 0;
197 
198  geometry.sectorSize = 0;
199  geometry.totalSize = 0;
200  return false;
201  }
202 
203  geometry.sectorSize = geometry.pagesPerSector * geometry.pageSize;
204  geometry.totalSize = geometry.sectorSize * geometry.sectors;
205 
206  couldBeBusy = true; // Just for luck we'll assume the chip could be busy even though it isn't specced to be
207 
208  return true;
209 }
210 
218 {
219  //Maximum speed for standard READ command is 20mHz, other commands tolerate 25mHz
221 
222  return m25p16_readIdentification();
223 }
224 
228 void m25p16_eraseSector(uint32_t address)
229 {
230  uint8_t out[] = { M25P16_INSTRUCTION_SECTOR_ERASE, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF};
231 
233 
235 
237 
238  spiTransfer(M25P16_SPI_INSTANCE, NULL, out, sizeof(out));
239 
241 }
242 
244 {
246 
248 
250 }
251 
252 void m25p16_pageProgramBegin(uint32_t address)
253 {
254  uint8_t command[] = { M25P16_INSTRUCTION_PAGE_PROGRAM, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF};
255 
257 
259 
261 
262  spiTransfer(M25P16_SPI_INSTANCE, NULL, command, sizeof(command));
263 }
264 
265 void m25p16_pageProgramContinue(const uint8_t *data, int length)
266 {
267  spiTransfer(M25P16_SPI_INSTANCE, NULL, data, length);
268 }
269 
271 {
273 }
274 
290 void m25p16_pageProgram(uint32_t address, const uint8_t *data, int length)
291 {
292  m25p16_pageProgramBegin(address);
293 
294  m25p16_pageProgramContinue(data, length);
295 
297 }
298 
307 int m25p16_readBytes(uint32_t address, uint8_t *buffer, int length)
308 {
309  uint8_t command[] = { M25P16_INSTRUCTION_READ_BYTES, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF};
310 
312  return 0;
313  }
314 
316 
317  spiTransfer(M25P16_SPI_INSTANCE, NULL, command, sizeof(command));
318  spiTransfer(M25P16_SPI_INSTANCE, buffer, NULL, length);
319 
321 
322  return length;
323 }
324 
331 {
332  return &geometry;
333 }
#define M25P16_INSTRUCTION_SECTOR_ERASE
Definition: drv_m25p16.c:58
uint8_t * data
Definition: drv_i2c.h:47
#define JEDEC_ID_MICRON_N25Q064
Definition: drv_m25p16.c:66
#define M25P16_SPI_INSTANCE
Definition: drv_m25p16.c:43
#define JEDEC_ID_WINBOND_W25Q128
Definition: drv_m25p16.c:69
uint32_t totalSize
Definition: drv_flash.h:34
volatile uint32_t millis(void)
Definition: system.c:50
#define DISABLE_M25P16
Definition: drv_m25p16.c:71
bool m25p16_waitForReady(uint32_t timeoutMillis)
Definition: drv_m25p16.c:136
void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
Definition: drv_spi.c:460
#define SECTOR_ERASE_TIMEOUT_MILLIS
Definition: drv_m25p16.c:78
static uint8_t buffer[BMP280_DATA_FRAME_SIZE]
Definition: drv_bmp280.c:61
int m25p16_readBytes(uint32_t address, uint8_t *buffer, int length)
Definition: drv_m25p16.c:307
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t data)
Definition: drv_spi.c:399
This file contains all the functions prototypes for the GPIO firmware library.
void m25p16_pageProgram(uint32_t address, const uint8_t *data, int length)
Definition: drv_m25p16.c:290
bool m25p16_init()
Definition: drv_m25p16.c:217
const flashGeometry_t * m25p16_getGeometry()
Definition: drv_m25p16.c:330
#define M25P16_INSTRUCTION_WRITE_ENABLE
Definition: drv_m25p16.c:55
void m25p16_pageProgramContinue(const uint8_t *data, int length)
Definition: drv_m25p16.c:265
#define SPI_18MHZ_CLOCK_DIVIDER
Definition: drv_spi.h:22
void m25p16_eraseCompletely()
Definition: drv_m25p16.c:243
static flashGeometry_t geometry
Definition: drv_m25p16.c:81
ROSLIB_DECL std::string command(const std::string &cmd)
#define BULK_ERASE_TIMEOUT_MILLIS
Definition: drv_m25p16.c:79
#define JEDEC_ID_MICRON_N25Q128
Definition: drv_m25p16.c:68
#define M25P16_INSTRUCTION_READ_STATUS_REG
Definition: drv_m25p16.c:53
#define M25P16_PAGESIZE
Definition: drv_m25p16.h:27
#define JEDEC_ID_WINBOND_W25Q64
Definition: drv_m25p16.c:67
void spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len)
Definition: drv_spi.c:430
uint8_t length
Definition: drv_i2c.h:48
#define M25P16_STATUS_FLAG_WRITE_IN_PROGRESS
Definition: drv_m25p16.c:61
const uint16_t pageSize
Definition: drv_flash.h:30
static bool couldBeBusy
Definition: drv_m25p16.c:88
#define JEDEC_ID_MICRON_M25P16
Definition: drv_m25p16.c:65
bool m25p16_isReady()
Definition: drv_m25p16.c:128
#define ENABLE_M25P16
Definition: drv_m25p16.c:72
static void m25p16_writeEnable()
Definition: drv_m25p16.c:106
uint32_t sectorSize
Definition: drv_flash.h:32
void m25p16_pageProgramBegin(uint32_t address)
Definition: drv_m25p16.c:252
#define NULL
Definition: usbd_def.h:50
#define M25P16_INSTRUCTION_READ_BYTES
Definition: drv_m25p16.c:52
#define DEFAULT_TIMEOUT_MILLIS
Definition: drv_m25p16.c:75
uint16_t sectors
Definition: drv_flash.h:27
#define M25P16_INSTRUCTION_PAGE_PROGRAM
Definition: drv_m25p16.c:57
static void m25p16_performOneByteCommand(uint8_t command)
Definition: drv_m25p16.c:93
#define M25P16_INSTRUCTION_BULK_ERASE
Definition: drv_m25p16.c:59
void m25p16_pageProgramFinish()
Definition: drv_m25p16.c:270
#define M25P16_INSTRUCTION_RDID
Definition: drv_m25p16.c:51
void m25p16_eraseSector(uint32_t address)
Definition: drv_m25p16.c:228
void delay(uint32_t ms)
Definition: system.c:101
static bool m25p16_readIdentification()
Definition: drv_m25p16.c:153
uint16_t pagesPerSector
Definition: drv_flash.h:29
static uint8_t m25p16_readStatus()
Definition: drv_m25p16.c:114


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Thu Apr 15 2021 05:07:46