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)&register_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 }