1 /**
2 * \file
3 *
4 * \brief SAM SPI Flash Driver for SAMB11
5 *
6 * Copyright (C) 2015-2016 Atmel Corporation. All rights reserved.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 *
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * 3. The name of Atmel may not be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * 4. This software may only be redistributed and used in connection with an
26 * Atmel microcontroller product.
27 *
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *
40 * \asf_license_stop
41 *
42 */
43 /*
44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45 */
46 #include "spi_flash.h"
47
48 /**
49 * \brief SPI flash write enable.
50 *
51 * Enable SPI flash write
52 */
spi_flash_write_enable(void)53 static void spi_flash_write_enable(void)
54 {
55 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0);
56 SPI_FLASH0->CMD_BUFFER0.reg = SPI_FLASH_CMD_WRITE_ENABLE;
57 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_CMD;
58 SPI_FLASH0->DMA_START_ADDRESS.reg = SPI_FLASH_DMA_START_ADDRESS_RESETVALUE;
59
60 SPI_FLASH0->TRANSACTION_CTRL.reg = \
61 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
62 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x01);
63
64 while (SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
65 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) {
66 /* Wait for current flash transaction done. */
67 }
68 }
69
70 /**
71 * \brief SPI flash write disable.
72 *
73 * Disable SPI flash write
74 */
spi_flash_write_disable(void)75 static void spi_flash_write_disable(void)
76 {
77 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0);
78 SPI_FLASH0->CMD_BUFFER0.reg = SPI_FLASH_CMD_WRITE_DISABLE;
79 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_CMD;
80 SPI_FLASH0->DMA_START_ADDRESS.reg = SPI_FLASH_DMA_START_ADDRESS_MASK;
81
82 SPI_FLASH0->TRANSACTION_CTRL.reg = \
83 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
84 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x01);
85
86 while (SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
87 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) {
88 /* Wait for current flash transaction done. */
89 }
90 }
91
92 /**
93 * \brief SPI flash read status register.
94 *
95 * Read SPI flash status
96 *
97 * \return Status register value.
98 */
spi_flash_read_status_reg(void)99 static uint8_t spi_flash_read_status_reg(void)
100 {
101 volatile uint32_t status_value;
102
103 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0x01);
104 SPI_FLASH0->CMD_BUFFER0.reg = SPI_FLASH_CMD_READ_STATUS;
105 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_CMD;
106 SPI_FLASH0->DMA_START_ADDRESS.reg = (uint32_t)&status_value;
107
108 SPI_FLASH0->TRANSACTION_CTRL.reg = \
109 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
110 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x01);
111
112 while (SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
113 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) {
114 /* Wait for current flash transaction done. */
115 }
116
117 return (status_value & 0xFF);
118 }
119
120 /**
121 * \brief Program SPI Flash page
122 *
123 * Program SPI Flash page
124 *
125 * \param[in] memory_addr Start address of memory
126 * \param[in] flash_addr Start address of the spi flash
127 * \param[in] size Number of bytes to be programmed to flash
128 */
spi_flash_page_program(uint32_t flash_addr,uint32_t memory_addr,uint16_t size)129 static void spi_flash_page_program(uint32_t flash_addr, uint32_t memory_addr, uint16_t size)
130 {
131 unsigned char cmd[8];
132
133 spi_flash_write_enable();
134
135 cmd[0] = SPI_FLASH_CMD_PAGE_PROGRAM;
136 cmd[1] = (unsigned char) (flash_addr >> 16);
137 cmd[2] = (unsigned char) (flash_addr >> 8);
138 cmd[3] = (unsigned char) (flash_addr);
139
140 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0x0);
141 SPI_FLASH0->CMD_BUFFER0.reg = cmd[0] | (cmd[1] << 8) | (cmd[2] << 16) | (cmd[3] << 24);
142 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_PRO;
143 SPI_FLASH0->DMA_START_ADDRESS.reg = memory_addr;
144
145 SPI_FLASH0->TRANSACTION_CTRL.reg = \
146 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
147 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x04) | \
148 SPI_FLASH_TRANSACTION_CTRL_WDATA_COUNT(size);
149
150 while (SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
151 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) {
152 /* Wait for current flash transaction done. */
153 }
154
155 /* add additional read_status_reg before the while this gives the flash
156 * memory time to update the registers.
157 */
158 for(uint16_t i = 0; i < 0xFFFF; i++) {
159 /* Waiting... */
160 }
161 //spi_flash_read_status_reg();
162 while(spi_flash_read_status_reg() & 0x01);
163 spi_flash_write_disable();
164 }
165
166 /**
167 * \brief Initializes the SPI Flash module
168 *
169 * Initializes the SPI Flash module
170 */
spi_flash_init(void)171 void spi_flash_init(void)
172 {
173 /* PINMUX init */
174 LPMCU_MISC_REGS0->PINMUX_SEL_3.reg = \
175 LPMCU_MISC_REGS_PINMUX_SEL_3_LP_SIP_0_SEL_SPI_FLASH0_SCK | \
176 LPMCU_MISC_REGS_PINMUX_SEL_3_LP_SIP_1_SEL_SPI_FLASH0_TXD | \
177 LPMCU_MISC_REGS_PINMUX_SEL_3_LP_SIP_2_SEL_SPI_FLASH0_SSN | \
178 LPMCU_MISC_REGS_PINMUX_SEL_3_LP_SIP_3_SEL_SPI_FLASH0_RXD;
179
180 SPI_FLASH0->MODE_CTRL.reg = SPI_FLASH_MODE_CTRL_RESETVALUE;
181 spi_flash_leave_low_power_mode();
182 }
183
184 /**
185 * \brief Read SPI Flash Chip ID
186 *
187 * Reads SPI Flash Chip ID
188 */
spi_flash_rdid(void)189 uint32_t spi_flash_rdid(void)
190 {
191 volatile uint32_t register_value;
192
193 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0x04);
194 SPI_FLASH0->CMD_BUFFER0.reg = SPI_FLASH_CMD_READ_ID;
195 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_CMD;
196 SPI_FLASH0->DMA_START_ADDRESS.reg = (uint32_t)®ister_value;
197
198 SPI_FLASH0->TRANSACTION_CTRL.reg = \
199 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
200 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x01);
201
202 while (SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
203 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) {
204 /* Wait for current flash transaction done. */
205 }
206
207 return (register_value);
208 }
209
210 /**
211 * \brief Read SPI Flash memory
212 *
213 * Reads SPI Flash memory with up to page size (256 bytes) length
214 * \param[in] read_buf Pointer to buffer to read into
215 * \param[in] flash_addr Flash memory address to read from
216 * \param[in] size Data length to be read, must be less than or equal to FLASH_PAGE_SIZE
217 */
spi_flash_read(uint8_t * read_buf,uint32_t flash_addr,uint32_t size)218 void spi_flash_read(uint8_t *read_buf, uint32_t flash_addr, uint32_t size)
219 {
220 uint8_t cmd[8] = {0, };
221 uint32_t memory_addr;
222 uint32_t i=0;
223 uint8_t *data = read_buf;
224
225 /* Get the destination buffer Address. */
226 if((flash_addr + size) > FLASH_MEMORY_SIZE) {
227 for(i=0; i < size; i++) {
228 data[i] = 0;
229 }
230 }
231
232 memory_addr = (unsigned long)read_buf;
233
234 /* Perform read operation. */
235 cmd[0] = SPI_FLASH_CMD_READ_HIGH_SPEED;
236 cmd[1] = (unsigned char) (flash_addr >> 16);
237 cmd[2] = (unsigned char) (flash_addr >> 8);
238 cmd[3] = (unsigned char) (flash_addr);
239 cmd[4] = 0xA5;
240
241 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(size);
242 SPI_FLASH0->CMD_BUFFER0.reg = cmd[0] | (cmd[1] << 8) | (cmd[2] << 16) | (cmd[3] << 24);
243 SPI_FLASH0->CMD_BUFFER1.reg = cmd[4];
244 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_READ;
245 SPI_FLASH0->DMA_START_ADDRESS.reg = memory_addr;
246
247 SPI_FLASH0->TRANSACTION_CTRL.reg = \
248 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
249 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x05);
250
251 for (i = 0; i < 0xFF; i++) {
252 /* Waiting...*/
253 }
254 while ((SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
255 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) && \
256 (spi_flash_read_status_reg() & 0x01)){
257 /* Wait for current flash transaction done. */
258 }
259 }
260
261 /**
262 * \brief Write SPI Flash memory
263 *
264 * Writes SPI Flash memory with up to page size (256 bytes) length
265 * \param[in] write_buf Pointer to buffer to write from
266 * \param[in] flash_addr Flash memory address to write to
267 * \param[in] size Data length to be written, must be less than or
268 * equal to FLASH_PAGE_SIZE
269 */
spi_flash_write(void * write_buf,uint32_t flash_addr,uint32_t size)270 int8_t spi_flash_write(void *write_buf, uint32_t flash_addr, uint32_t size)
271 {
272 int8_t ret = -1;
273 uint32_t write_size;
274 uint32_t offset;
275 uint32_t memory_addr;
276
277 for (uint32_t i = 0; i < 0x1FFFF; i++) {
278 /* Waiting...*/
279 }
280 if((write_buf != NULL) && (size != 0)) {
281 /* Ensure the write size does not exceed the flash limit. */
282 if((flash_addr + size) <= FLASH_MEMORY_SIZE) {
283 /* Get the destination buffer Address. */
284 memory_addr = (unsigned long)write_buf;
285 /* Perform read operation. */
286 offset = flash_addr % FLASH_PAGE_SIZE;
287
288 /* First part of data in the address page. */
289 if (offset) {
290 write_size = FLASH_PAGE_SIZE - offset;
291 spi_flash_page_program(flash_addr, memory_addr, min(size, write_size));
292 if (size < write_size) {
293 ret = 0;
294 goto EXIT;
295 }
296 memory_addr += write_size;
297 flash_addr += write_size;
298 size -= write_size;
299 }
300 do {
301 write_size = min(size, FLASH_PAGE_SIZE);
302
303 /* Write complete page or the remaining data. */
304 spi_flash_page_program(flash_addr, memory_addr, write_size);
305 memory_addr += write_size;
306 flash_addr += write_size;
307 size -= write_size;
308 } while (size > 0);
309 ret = 0;
310 }
311 }
312 EXIT:
313 return ret;
314 }
315
316 /**
317 * \brief Erase SPI Flash sector
318 *
319 * Erases SPI Flash Sector
320 * \param[in] flash_addr Flash memory address within the sector to erase
321 */
spi_flash_sector_erase(uint32_t flash_addr)322 void spi_flash_sector_erase(uint32_t flash_addr)
323 {
324 uint8_t cmd[8] = {0,};
325 uint32_t i=0;
326
327 cmd[0] = SPI_FLASH_CMD_SECTOR_ERASE;
328 cmd[1] = (char)(flash_addr >> 16);
329 cmd[2] = (char)(flash_addr >> 8);
330 cmd[3] = (char)(flash_addr);
331
332 spi_flash_write_enable();
333 spi_flash_read_status_reg();
334
335 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0x0);
336 SPI_FLASH0->CMD_BUFFER0.reg = cmd[0] | (cmd[1] << 8) | (cmd[2] << 16) | (cmd[3] << 24);
337 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_PRO;
338 SPI_FLASH0->DMA_START_ADDRESS.reg = 0x0;
339
340 SPI_FLASH0->TRANSACTION_CTRL.reg = \
341 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
342 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x04);
343
344 for (i = 0; i < 0xFF; i++) {
345 /* Waiting...*/
346 }
347
348 while ((SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
349 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) && \
350 (spi_flash_read_status_reg() & 0x01)){
351 /* Wait for current flash transaction done. */
352 }
353 }
354
355 /**
356 * \brief Erase SPI Flash sector
357 *
358 * Erases SPI Flash Sector
359 * \param[in] start_offset Start address of the spi flash
360 * \param[in] size Size of the spi flash
361 *
362 * \retval 1 Address over spi flash memory size
363 * \retval 0 Operation complete
364 */
spi_flash_erase(uint32_t start_offset,uint32_t size)365 unsigned char spi_flash_erase(uint32_t start_offset, uint32_t size)
366 {
367 unsigned long end_offset = start_offset + size;
368
369
370 /* Check address overflow */
371 if (end_offset > FLASH_MEMORY_SIZE) {
372 return 1;
373 }
374
375 /* Align to previous sector boundary */
376 start_offset = start_offset & FLASH_SECT_MASK;
377
378 /* Erase next sectors */
379 spi_flash_write_enable();
380 while(start_offset < end_offset) {
381 spi_flash_sector_erase(start_offset);
382 while(spi_flash_read_status_reg() & 0x01) {
383 /* Waiting. */
384 }
385 start_offset += FLASH_SECTOR_SIZE;
386 }
387
388 spi_flash_write_disable();
389
390 return 0;
391 }
392
393 /**
394 * \brief Enter SPI Flash low power mode
395 *
396 * Enter SPI Flash low power mode
397 */
spi_flash_enter_low_power_mode(void)398 void spi_flash_enter_low_power_mode(void)
399 {
400 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0x0);
401 SPI_FLASH0->CMD_BUFFER0.reg = SPI_FLASH_CMD_ENTER_LOW_POWER;
402 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_CMD;
403 SPI_FLASH0->DMA_START_ADDRESS.reg = 0x0;
404
405 SPI_FLASH0->TRANSACTION_CTRL.reg = \
406 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
407 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x01);
408
409 while (SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
410 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) {
411 /* Wait for current flash transaction done. */
412 }
413 }
414
415 /**
416 * \brief Exit SPI Flash Low power mode
417 *
418 * Exit SPI Flash Low power mode
419 */
spi_flash_leave_low_power_mode(void)420 void spi_flash_leave_low_power_mode(void)
421 {
422 SPI_FLASH0->READ_CTRL.reg = SPI_FLASH_READ_CTRL_RDATA_COUNT(0x0);
423 SPI_FLASH0->CMD_BUFFER0.reg = SPI_FLASH_CMD_LEAVE_LOW_POWER;
424 SPI_FLASH0->DIRECTION.reg = SPI_FLASH_DIRECTION_CMD;
425 SPI_FLASH0->DMA_START_ADDRESS.reg = 0x0;
426
427 SPI_FLASH0->TRANSACTION_CTRL.reg = \
428 SPI_FLASH_TRANSACTION_CTRL_FLASH_TRANS_START | \
429 SPI_FLASH_TRANSACTION_CTRL_CMD_COUNT(0x01);
430
431 while (SPI_FLASH0->IRQ_STATUS.bit.FLASH_TRANS_DONE != \
432 SPI_FLASH_IRQ_STATUS_FLASH_TRANS_DONE) {
433 /* Wait for current flash transaction done. */
434 }
435 }
436
437 /**
438 * \brief Initializes the SPI Flash module
439 */
spi_flash_clock_init(void)440 void spi_flash_clock_init(void)
441 {
442 /* Reset SPI_Flash */
443 system_peripheral_reset(PERIPHERAL_SPI_FLASH);
444 system_peripheral_reset(PERIPHERAL_SPI_FLASH_IF);
445 /* SPI_Flash core clock enable */
446 system_clock_peripheral_enable(PERIPHERAL_SPI_FLASH);
447 /* change clock speed */
448 system_clock_peripheral_freq_config(PERIPHERAL_SPI_FLASH, CLOCK_FREQ_13_MHZ);
449 }
450
451 /**
452 * \brief Turns off the supply to SPI_Flash Core
453 *
454 * This functions turns off the supply to SPI_Flash core.
455 * Since SPI_Flash won't be used on every wakeup it is safe to disable
456 * the power to SPI_Flash core and enable it when required.
457 *
458 */
spi_flash_turn_off(void)459 void spi_flash_turn_off(void)
460 {
461 LPMCU_MISC_REGS0->PULL_ENABLE.reg &= ~LPMCU_MISC_REGS_PULL_ENABLE_LP_SIP__Msk;
462
463 LPMCU_MISC_REGS0->SPIFLASH_VDDIO_CTRL.reg = 0x0;
464 }
465
466 /**
467 * \brief Turns on the supply to SPI_Flash Core
468 *
469 * This functions turns on the supply to SPI_Flash core.
470 *
471 */
spi_flash_turn_on(void)472 void spi_flash_turn_on(void)
473 {
474 LPMCU_MISC_REGS0->PULL_ENABLE.reg |= LPMCU_MISC_REGS_PULL_ENABLE_LP_SIP__Msk;
475
476 LPMCU_MISC_REGS0->SPIFLASH_VDDIO_CTRL.reg = LPMCU_MISC_REGS_SPIFLASH_VDDIO_CTRL_ENABLE;
477 }