]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - psdk_cust/pdk_k2g_1_0_1_2_eng/packages/ti/board/diag/norflash/src/evmk2g_nor.c
Merge pull request #1 in PASDK/pasdk_sr from PASDK-318-input-task-code-repetition...
[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_2_eng / packages / ti / board / diag / norflash / src / evmk2g_nor.c
1 /*
2  * Copyright (c) 2010-2016, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
34 #include "platform_internal.h"
36 #if (PLATFORM_NOR_IN)
38 /**
39  *
40  * \file  evmk2g_nor.c
41  *
42  * \brief This file implements NOR flash driver for Nymonyx N25Q128 NOR flash
43  *
44  *****************************************************************************/
46 /************************
47  * Include Files
48  ************************/
50 #if (PLATFORM_NOR_WRITE_IN)
51 static NOR_STATUS
52 nor_wait_ready
53 (
54     uint32_t  timeout
55 )
56 {
57     NOR_STATUS  ret;
58     uint8_t       status;
59     uint8_t       cmd = SPI_NOR_CMD_RDSR;
61     do
62     {
64         /* Send Read Status command */
65         ret = spi_xfer(NOR_SPI_PORT,1, &cmd, NULL, FALSE);
66         if (ret)
67         {
68             return ret;
69         }
71         /* Read status value */
72         ret = spi_xfer(NOR_SPI_PORT,1, NULL, &status, TRUE);
73         if (ret)
74         {
75             return ret;
76         }
78         if ((status & SPI_NOR_SR_WIP) == 0)
79         {
80             break;
81         }
83         timeout--;
84         if (!timeout)
85         {
86             break;
87         }
89     } while (TRUE);
91     if ((status & SPI_NOR_SR_WIP) == 0)
92         return NOR_EOK;
94     /* Timed out */
95     return NOR_EFAIL;
96 }
97 #endif
99 /******************************************************************************
100  *
101  * Function:    nor_get_details
102  *
103  * Description: This function the details of NOR flash device.
104  *
105  * Parameters:  NOR_INFO nor_info - structure for information
106  *
107  * Return Value: status
108  ******************************************************************************/
109 uint32_t
110 nor_get_details
112                 PLATFORM_DEVICE_info*   nor_info
115     uint32_t uiStatus = SUCCESS, ret;
116     uint8_t               idcode[3];     /* Initialize the SPI interface */
118    /* Claim the SPI controller */
119     spi_claim(NOR_SPI_PORT,SPI_NOR_CS, SPI_MAX_FREQ);
121     /* Read the ID codes */
122     ret = spi_cmd(NOR_SPI_PORT,SPI_NOR_CMD_RDID, idcode, sizeof(idcode));
123     if (ret) {
124         spi_release(NOR_SPI_PORT);
125         platform_errno = PLATFORM_ERRNO_NOR;
126         return FAIL;
127     }
129     /* Get the actuals */
130     nor_info->manufacturer_id   = idcode[0];
131     nor_info->device_id         = (idcode[1] << SPI_NOR_CHAR_LENTH) | (idcode[2]);
133     /* No blocks are bad for NOR.. for now */
134     nor_info->bblist = NULL;
136     spi_release(NOR_SPI_PORT);
138     return uiStatus;
141 /******************************************************************************
142  *
143  * Function:    nor_init
144  *
145  * Description: This function configures the SPI controller communication
146  *              between the DSP and the NOR flash
147  *
148  * Parameters:  None
149  *
150  * Return Value: error status
151  *
152  ******************************************************************************/
153 NOR_STATUS
154 nor_init
156     void
159     NOR_STATUS          ret;
160     uint8_t               idcode[3];     /* Initialize the SPI interface */
162     /* Claim the SPI controller */
163     spi_claim(NOR_SPI_PORT,SPI_NOR_CS, SPI_MAX_FREQ);
165     /* Read the ID codes */
166     ret = spi_cmd(NOR_SPI_PORT,SPI_NOR_CMD_RDID, idcode, sizeof(idcode));
167     if (ret)
168     {
169         IFPRINT (platform_write( "nor_init: Error in reading the idcode\n"));
170         spi_release(NOR_SPI_PORT);
171         platform_errno = PLATFORM_ERRNO_NOR;
172         return NOR_EFAIL;
173     }
175     IFPRINT (platform_write("SF: Got idcode %02x %02x %02x\n", idcode[0], idcode[1], idcode[2]));
177     if (idcode[0] != SPI_NOR_MANUFACTURE_ID) {
178         /* Expected Manufacturer ID does not match */
179         spi_release(NOR_SPI_PORT);
180         platform_errno = PLATFORM_ERRNO_BADFLASHDEV;
181         return NOR_EFAIL;
182     }
184     spi_release(NOR_SPI_PORT);
185     return NOR_EOK;
188 /******************************************************************************
189  *
190  * Function:    nor_read
191  *
192  * Description: This function reads data from the NOR flash
193  *
194  * Parameters:  uint32_t addr     - Byte address of the NOR flash
195  *              uint32_t len      - Lenth in bytes to read
196  *              uint8_t* buf      - Pointer of the buffer to store the bytes read
197  *
198  * Return Value: error status
199  *
200  ******************************************************************************/
201 #if (PLATFORM_NOR_READ_IN)
202 NOR_STATUS
203 nor_read
205         PLATFORM_DEVICE_info*   p_device,
206     uint32_t      addr,
207     uint32_t      len,
208     uint8_t*      buf
211     uint8_t       cmd[4];
212     NOR_STATUS  ret_val;
214     /* Claim the SPI controller */
215     spi_claim(NOR_SPI_PORT,SPI_NOR_CS, SPI_MAX_FREQ);
217     /* Validate address input */
218     if(addr + len > SPI_NOR_MAX_FLASH_SIZE)
219     {
220         platform_errno = PLATFORM_ERRNO_FLASHADDR;
221         spi_release(NOR_SPI_PORT);
222         return NOR_EFAIL;
223     }
225     /* Initialize the command to be sent serially */
226     cmd[0]              = SPI_NOR_CMD_READ;
227     cmd[1]              = (uint8_t)(addr>>16);
228     cmd[2]              = (uint8_t)(addr>>8);
229     cmd[3]              = (uint8_t)addr;
231     ret_val = (spi_cmd_read(NOR_SPI_PORT,cmd, 4, buf, len));
233     spi_release(NOR_SPI_PORT);
234     return (ret_val);
236 #endif
238 /******************************************************************************
239  *
240  * Function:    nor_write
241  *
242  * Description: This function writes data to the NOR flash
243  *
244  * Parameters:  uint32_t addr     - Byte address of the NOR flash
245  *              uint32_t len      - Lenth in bytes to write
246  *              uint8_t* buf      - Pointer of the buffer to store the write data
247  *
248  * Return Value: error status
249  *
250  ******************************************************************************/
251 #if (PLATFORM_NOR_WRITE_IN)
252 NOR_STATUS
253 nor_write
255         PLATFORM_DEVICE_info*   p_device,
256     uint32_t      addr,
257     uint32_t      len,
258     uint8_t*      buf
261     uint32_t      page_addr;
262     uint32_t      byte_addr;
263     uint32_t      page_size;
264     uint32_t      loopCount;
266     uint32_t      chunk_len;
267     uint32_t      actual;
268     uint32_t      ret;
269     uint8_t       cmd[4];
271     /* Claim the SPI controller */
272     spi_claim(NOR_SPI_PORT,SPI_NOR_CS, SPI_MAX_FREQ);
274     /* Validate address input */
275     if(addr + len > SPI_NOR_MAX_FLASH_SIZE)
276     {
277         platform_errno = PLATFORM_ERRNO_NOFREEBLOCKS;
278         spi_release(NOR_SPI_PORT);
279         return NOR_EFAIL;
280     }
282     page_size = SPI_NOR_PAGE_SIZE;
283     page_addr = addr / page_size;
284     byte_addr = addr & (SPI_NOR_PAGE_SIZE - 1); /* % page_size; */
286     ret = NOR_EOK;
287     for (actual = 0; actual < len; actual += chunk_len)
288     {
289         /* Send Write Enable command */
290         ret = spi_cmd(NOR_SPI_PORT,SPI_NOR_CMD_WREN, NULL, 0);
291         if (ret)
292         {
293                 platform_errno = PLATFORM_ERRNO_DEV_FAIL;
294             spi_release(NOR_SPI_PORT);
295             return NOR_EFAIL;
296         }
298         /* Send Page Program command */
299         chunk_len = ((len - actual) < (page_size - byte_addr) ?
300             (len - actual) : (page_size - byte_addr));
302         cmd[0]  = SPI_NOR_CMD_PP;
303         cmd[1]  = (uint8_t)(addr>>16);
304         cmd[2]  = (uint8_t)(addr>>8);
305         cmd[3]  = (uint8_t)addr;
307         ret = spi_cmd_write(NOR_SPI_PORT,cmd, 4, buf + actual, chunk_len);
308         if (ret)
309         {
310                 platform_errno = PLATFORM_ERRNO_DEV_FAIL;
311             spi_release(NOR_SPI_PORT);
312             return NOR_EFAIL;
313         }
315         ret = nor_wait_ready(SPI_NOR_PROG_TIMEOUT);
316         if (ret)
317         {
318                 platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
319             spi_release(NOR_SPI_PORT);
320             return NOR_EFAIL;
321         }
323         page_addr++;
324         addr += chunk_len;
325         byte_addr = 0;
327         loopCount = 4000;
328         while (loopCount--) {
329             asm("   NOP");
330         }
332     }
334     spi_release(NOR_SPI_PORT);
335     return ((NOR_STATUS) ret);
337 #endif
339 /******************************************************************************
340  *
341  * Function:    nor_erase
342  *
343  * Description: This function writes data to the NOR flash
344  *
345  * Parameters:  uint32_t  sector_number - Sector number to erase,
346  *                                      if sector_number = -1, do bulk erase
347  *
348  * Return Value: error status
349  *
350  ******************************************************************************/
351 #if (PLATFORM_NOR_WRITE_IN)
352 NOR_STATUS
353 nor_erase
355         PLATFORM_DEVICE_info*   p_device,
356     uint32_t  sector_number
359     NOR_STATUS  ret;
360     uint8_t       cmd[4];
361     uint32_t      cmd_len;
362     uint32_t      address;
364     /* Claim the SPI controller */
365     spi_claim(NOR_SPI_PORT,SPI_NOR_CS, SPI_MAX_FREQ);
367     /*
368     * This function currently uses sector erase only.
369     * probably speed things up by using bulk erase
370     * when possible.
371     */
373     if (sector_number == SPI_NOR_BE_SECTOR_NUM)
374     {
375         cmd[0]  = SPI_NOR_CMD_BE;
376         cmd_len = 1;
378     }
379     else if (sector_number >= SPI_NOR_SECTOR_COUNT)
380     {
381         platform_errno = PLATFORM_ERRNO_NORADDR;
382         return NOR_EFAIL;
383     }
384     else
385     {
386         address = sector_number * SPI_NOR_SECTOR_SIZE;
387         cmd[0]  = SPI_NOR_CMD_SE;
388         cmd[1] = (address >> 16) & 0xff;
389         cmd[2] = (address >>  8) & 0xff;
390         cmd[3] = (address >>  0) & 0xff;
392         cmd_len = 4;
393     }
395     /* Send Write Enable command */
396     ret = spi_cmd(NOR_SPI_PORT,SPI_NOR_CMD_WREN, NULL, 0);
397     if (ret)
398     {
399         platform_errno = PLATFORM_ERRNO_DEV_FAIL;
400         spi_release(NOR_SPI_PORT);
401         return NOR_EFAIL;
402     }
404     ret = spi_cmd_write(NOR_SPI_PORT,cmd, cmd_len, NULL, 0);
405     if (ret)
406     {
407         platform_errno = PLATFORM_ERRNO_DEV_FAIL;
408         spi_release(NOR_SPI_PORT);
409         return NOR_EFAIL;
410     }
412     ret = nor_wait_ready(SPI_NOR_SECTOR_ERASE_TIMEOUT);
413     if (ret)
414     {
415         platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
416         spi_release(NOR_SPI_PORT);
417         return NOR_EFAIL;
418     }
419     spi_release(NOR_SPI_PORT);
420     return ret;
422 #endif
424 #endif /*(PLATFORM_NOR_IN)*/