spi_flash.c
Go to the documentation of this file.
1 
35 #ifdef PROFILING
36 #include "windows.h"
37 #endif
39 #define DUMMY_REGISTER (0x1084)
40 
41 #define TIMEOUT (-1) /*MS*/
42 
43 //#define DISABLE_UNSED_FLASH_FUNCTIONS
44 
45 #define HOST_SHARE_MEM_BASE (0xd0000UL)
46 #define CORTUS_SHARE_MEM_BASE (0x60000000UL)
47 #define NMI_SPI_FLASH_ADDR (0x111c)
48 /***********************************************************
49 SPI Flash DMA
50 ***********************************************************/
51 #define GET_UINT32(X,Y) (X[0+Y] + ((uint32)X[1+Y]<<8) + ((uint32)X[2+Y]<<16) +((uint32)X[3+Y]<<24))
52 #define SPI_FLASH_BASE (0x10200)
53 #define SPI_FLASH_MODE (SPI_FLASH_BASE + 0x00)
54 #define SPI_FLASH_CMD_CNT (SPI_FLASH_BASE + 0x04)
55 #define SPI_FLASH_DATA_CNT (SPI_FLASH_BASE + 0x08)
56 #define SPI_FLASH_BUF1 (SPI_FLASH_BASE + 0x0c)
57 #define SPI_FLASH_BUF2 (SPI_FLASH_BASE + 0x10)
58 #define SPI_FLASH_BUF_DIR (SPI_FLASH_BASE + 0x14)
59 #define SPI_FLASH_TR_DONE (SPI_FLASH_BASE + 0x18)
60 #define SPI_FLASH_DMA_ADDR (SPI_FLASH_BASE + 0x1c)
61 #define SPI_FLASH_MSB_CTL (SPI_FLASH_BASE + 0x20)
62 #define SPI_FLASH_TX_CTL (SPI_FLASH_BASE + 0x24)
63 
64 /*********************************************/
65 /* STATIC FUNCTIONS */
66 /*********************************************/
67 
79 {
80  sint8 ret = M2M_SUCCESS;
81  uint8 cmd[1];
82  uint32 reg;
83 
84  cmd[0] = 0x05;
85 
87  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
88  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
90  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
91  do
92  {
94  if(M2M_SUCCESS != ret) break;
95  }
96  while(reg != 1);
97 
98  reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
99  *val = reg & 0xff;
100  return ret;
101 }
102 
103 #ifdef DISABLE_UNSED_FLASH_FUNCTIONS
104 
112 static uint8 spi_flash_read_security_reg(void)
113 {
114  uint8 cmd[1];
115  uint32 reg;
116  sint8 ret = M2M_SUCCESS;
117 
118  cmd[0] = 0x2b;
119 
120  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 1);
121  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
122  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
124  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
125  do
126  {
128  if(M2M_SUCCESS != ret) break;
129  }
130  while(reg != 1);
131  reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
132 
133  return (sint8)reg & 0xff;
134 }
135 
143 static sint8 spi_flash_gang_unblock(void)
144 {
145  uint8 cmd[1];
146  uint32 val = 0;
147  sint8 ret = M2M_SUCCESS;
148 
149  cmd[0] = 0x98;
150 
151  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
152  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
153  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
154  ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
155  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
156  do
157  {
159  if(M2M_SUCCESS != ret) break;
160  }
161  while(val != 1);
162 
163  return ret;
164 }
165 
173 static sint8 spi_flash_clear_security_flags(void)
174 {
175  uint8 cmd[1];
176  uint32 val = 0;
177  sint8 ret = M2M_SUCCESS;
178 
179  cmd[0] = 0x30;
180 
181  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
182  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
183  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
184  ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
185  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
186  do
187  {
189  if(M2M_SUCCESS != ret) break;
190  }
191  while(val != 1);
192 
193  return ret;
194 }
195 #endif
196 
211 static sint8 spi_flash_load_to_cortus_mem(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
212 {
213  uint8 cmd[5];
214  uint32 val = 0;
215  sint8 ret = M2M_SUCCESS;
216 
217  cmd[0] = 0x0b;
218  cmd[1] = (uint8)(u32FlashAdr >> 16);
219  cmd[2] = (uint8)(u32FlashAdr >> 8);
220  cmd[3] = (uint8)(u32FlashAdr);
221  cmd[4] = 0xA5;
222 
223  ret += nm_write_reg(SPI_FLASH_DATA_CNT, u32Sz);
224  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
225  ret += nm_write_reg(SPI_FLASH_BUF2, cmd[4]);
226  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1f);
227  ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr);
228  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 5 | (1<<7));
229  do
230  {
232  if(M2M_SUCCESS != ret) break;
233  }
234  while(val != 1);
235 
236  return ret;
237 }
238 
250 {
251  uint8 cmd[4];
252  uint32 val = 0;
253  sint8 ret = M2M_SUCCESS;
254 
255  cmd[0] = 0x20;
256  cmd[1] = (uint8)(u32FlashAdr >> 16);
257  cmd[2] = (uint8)(u32FlashAdr >> 8);
258  cmd[3] = (uint8)(u32FlashAdr);
259 
260  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
261  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
262  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x0f);
263  ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
264  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7));
265  do
266  {
268  if(M2M_SUCCESS != ret) break;
269  }
270  while(val != 1);
271 
272  return ret;
273 }
274 
284 {
285  uint8 cmd[1];
286  uint32 val = 0;
287  sint8 ret = M2M_SUCCESS;
288 
289  cmd[0] = 0x06;
290 
291  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
292  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
293  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
294  ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
295  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
296  do
297  {
299  if(M2M_SUCCESS != ret) break;
300  }
301  while(val != 1);
302 
303  return ret;
304 }
305 
314 {
315  uint8 cmd[1];
316  uint32 val = 0;
317  sint8 ret = M2M_SUCCESS;
318  cmd[0] = 0x04;
319 
320  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
321  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
322  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x01);
323  ret += nm_write_reg(SPI_FLASH_DMA_ADDR, 0);
324  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
325  do
326  {
328  if(M2M_SUCCESS != ret) break;
329  }
330  while(val != 1);
331 
332  return ret;
333 }
334 
348 static sint8 spi_flash_page_program(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
349 {
350  uint8 cmd[4];
351  uint32 val = 0;
352  sint8 ret = M2M_SUCCESS;
353 
354  cmd[0] = 0x02;
355  cmd[1] = (uint8)(u32FlashAdr >> 16);
356  cmd[2] = (uint8)(u32FlashAdr >> 8);
357  cmd[3] = (uint8)(u32FlashAdr);
358 
359  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 0);
360  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]|(cmd[1]<<8)|(cmd[2]<<16)|(cmd[3]<<24));
361  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x0f);
362  ret += nm_write_reg(SPI_FLASH_DMA_ADDR, u32MemAdr);
363  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 4 | (1<<7) | ((u32Sz & 0xfffff) << 8));
364  do
365  {
367  if(M2M_SUCCESS != ret) break;
368  }
369  while(val != 1);
370 
371  return ret;
372 }
373 
387 static sint8 spi_flash_read_internal(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz)
388 {
389  sint8 ret = M2M_SUCCESS;
390  /* read size must be < 64KB */
391  ret = spi_flash_load_to_cortus_mem(HOST_SHARE_MEM_BASE, u32Addr, u32Sz);
392  if(M2M_SUCCESS != ret) goto ERR;
393  ret = nm_read_block(HOST_SHARE_MEM_BASE, pu8Buf, u32Sz);
394 ERR:
395  return ret;
396 }
397 
411 static sint8 spi_flash_pp(uint32 u32Offset, uint8 *pu8Buf, uint16 u16Sz)
412 {
413  sint8 ret = M2M_SUCCESS;
414  uint8 tmp;
416  /* use shared packet memory as temp mem */
417  ret += nm_write_block(HOST_SHARE_MEM_BASE, pu8Buf, u16Sz);
418  ret += spi_flash_page_program(HOST_SHARE_MEM_BASE, u32Offset, u16Sz);
419  do
420  {
421  if(ret != M2M_SUCCESS) goto ERR;
422  ret += spi_flash_read_status_reg(&tmp);
423  }
424  while(tmp & 0x01);
425  ret += spi_flash_write_disable();
426 ERR:
427  return ret;
428 }
429 
437 static uint32 spi_flash_rdid(void)
438 {
439  unsigned char cmd[1];
440  uint32 reg = 0;
441  uint32 cnt = 0;
442  sint8 ret = M2M_SUCCESS;
443 
444  cmd[0] = 0x9f;
445 
446  ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4);
447  ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]);
448  ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1);
450  ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7));
451  do
452  {
454  if(M2M_SUCCESS != ret) break;
455  if(++cnt > 500)
456  {
457  ret = M2M_ERR_INIT;
458  break;
459  }
460  }
461  while(reg != 1);
462  reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0);
463  M2M_PRINT("Flash ID %x \n",(unsigned int)reg);
464  return reg;
465 }
466 
473 #if 0
474 static void spi_flash_unlock(void)
475 {
476  uint8 tmp;
477  tmp = spi_flash_read_security_reg();
478  spi_flash_clear_security_flags();
479  if(tmp & 0x80)
480  {
482  spi_flash_gang_unblock();
483  }
484 }
485 #endif
486 
487 /*********************************************/
488 /* GLOBAL FUNCTIONS */
489 /*********************************************/
490 
505 sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32offset, uint32 u32Sz)
506 {
507  sint8 ret = M2M_SUCCESS;
508  if(u32Sz > FLASH_BLOCK_SIZE)
509  {
510  do
511  {
512  ret = spi_flash_read_internal(pu8Buf, u32offset, FLASH_BLOCK_SIZE);
513  if(M2M_SUCCESS != ret) goto ERR;
514  u32Sz -= FLASH_BLOCK_SIZE;
515  u32offset += FLASH_BLOCK_SIZE;
516  pu8Buf += FLASH_BLOCK_SIZE;
517  } while(u32Sz > FLASH_BLOCK_SIZE);
518  }
519 
520  ret = spi_flash_read_internal(pu8Buf, u32offset, u32Sz);
521 
522 ERR:
523  return ret;
524 }
525 
539 sint8 spi_flash_write(uint8* pu8Buf, uint32 u32Offset, uint32 u32Sz)
540 {
541 #ifdef PROFILING
542  unsigned long long t1 = 0;
543  uint32 percent =0;
544  uint32 tpercent =0;
545 #endif
546  sint8 ret = M2M_SUCCESS;
547  uint32 u32wsz;
548  uint32 u32off;
549  uint32 u32Blksz;
550  u32Blksz = FLASH_PAGE_SZ;
551  u32off = u32Offset % u32Blksz;
552 #ifdef PROFILING
553  tpercent = (u32Sz/u32Blksz)+((u32Sz%u32Blksz)>0);
554  t1 = GetTickCount64();
555  M2M_PRINT(">Start programming...\r\n");
556 #endif
557  if(u32Sz<=0)
558  {
559  M2M_ERR("Data size = %d",(int)u32Sz);
560  ret = M2M_ERR_FAIL;
561  goto ERR;
562  }
563 
564  if (u32off)/*first part of data in the address page*/
565  {
566  u32wsz = u32Blksz - u32off;
567  if(spi_flash_pp(u32Offset, pu8Buf, (uint16)BSP_MIN(u32Sz, u32wsz))!=M2M_SUCCESS)
568  {
569  ret = M2M_ERR_FAIL;
570  goto ERR;
571  }
572  if (u32Sz < u32wsz) goto EXIT;
573  pu8Buf += u32wsz;
574  u32Offset += u32wsz;
575  u32Sz -= u32wsz;
576  }
577  while (u32Sz > 0)
578  {
579  u32wsz = BSP_MIN(u32Sz, u32Blksz);
580 
581  /*write complete page or the remaining data*/
582  if(spi_flash_pp(u32Offset, pu8Buf, (uint16)u32wsz)!=M2M_SUCCESS)
583  {
584  ret = M2M_ERR_FAIL;
585  goto ERR;
586  }
587  pu8Buf += u32wsz;
588  u32Offset += u32wsz;
589  u32Sz -= u32wsz;
590 #ifdef PROFILING
591  percent++;
592  printf("\r>Complete Percentage = %d%%.\r",((percent*100)/tpercent));
593 #endif
594  }
595 EXIT:
596 #ifdef PROFILING
597  M2M_PRINT("\rDone\t\t\t\t\t\t");
598  M2M_PRINT("\n#Programming time = %f sec\n\r",(GetTickCount64() - t1)/1000.0);
599 #endif
600 ERR:
601  return ret;
602 }
603 
617 {
618  uint32 i = 0;
619  sint8 ret = M2M_SUCCESS;
620  uint8 tmp = 0;
621 #ifdef PROFILING
622  unsigned long long t;
623  t = GetTickCount64();
624 #endif
625  M2M_DBG("\r\n>Start erasing...\r\n");
626  for(i = u32Offset; i < (u32Sz +u32Offset); i += (16*FLASH_PAGE_SZ))
627  {
628  ret += spi_flash_write_enable();
629  ret += spi_flash_read_status_reg(&tmp);
630  ret += spi_flash_sector_erase(i);
631  ret += spi_flash_read_status_reg(&tmp);
632  do
633  {
634  if(ret != M2M_SUCCESS) goto ERR;
635  ret += spi_flash_read_status_reg(&tmp);
636  }while(tmp & 0x01);
637 
638  }
639  M2M_DBG("Done\r\n");
640 #ifdef PROFILING
641  M2M_PRINT("#Erase time = %f sec\n", (GetTickCount64()-t)/1000.0);
642 #endif
643 ERR:
644  return ret;
645 }
646 
655 {
656  uint32 u32FlashId = 0, u32FlashPwr = 0;
657  static uint32 gu32InernalFlashSize= 0;
658 
659  if(!gu32InernalFlashSize)
660  {
661  u32FlashId = spi_flash_rdid();//spi_flash_probe();
662  if(u32FlashId != 0xffffffff)
663  {
664  /*flash size is the third byte from the FLASH RDID*/
665  u32FlashPwr = ((u32FlashId>>16)&0xff) - 0x11; /*2MBIT is the min*/
666  /*That number power 2 to get the flash size*/
667  gu32InernalFlashSize = 1<<u32FlashPwr;
668  M2M_INFO("Flash Size %lu Mb\n",gu32InernalFlashSize);
669  }
670  else
671  {
672  M2M_ERR("Cann't Detect Flash size\n");
673  }
674  }
675 
676  return gu32InernalFlashSize;
677 }
#define M2M_ERR_FAIL
Definition: nm_common.h:63
#define SPI_FLASH_TR_DONE
Definition: spi_flash.c:59
#define SPI_FLASH_BUF_DIR
Definition: spi_flash.c:58
sint8 nm_read_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
Definition: nmbus.c:195
static uint32 spi_flash_rdid(void)
Read SPI Flash ID.
Definition: spi_flash.c:437
signed char sint8
Range of values between -128 to 127.
Definition: nm_bsp.h:111
sint8 nm_read_reg_with_ret(uint32 u32Addr, uint32 *pu32RetVal)
Definition: nmbus.c:130
sint8 nm_write_block(uint32 u32Addr, uint8 *puBuf, uint32 u32Sz)
Definition: nmbus.c:248
string cmd
#define DUMMY_REGISTER
Definition: spi_flash.c:39
#define printf(...)
#define M2M_SUCCESS
Definition: nm_common.h:51
#define SPI_FLASH_BUF2
Definition: spi_flash.c:57
#define M2M_ERR_INIT
Definition: nm_common.h:56
static sint8 spi_flash_pp(uint32 u32Offset, uint8 *pu8Buf, uint16 u16Sz)
Definition: spi_flash.c:411
#define FLASH_PAGE_SZ
Definition: spi_flash_map.h:58
#define SPI_FLASH_DATA_CNT
Definition: spi_flash.c:55
unsigned short uint16
Range of values between 0 to 65535.
Definition: nm_bsp.h:96
static sint8 spi_flash_read_status_reg(uint8 *val)
Definition: spi_flash.c:78
static sint8 spi_flash_sector_erase(uint32 u32FlashAdr)
Definition: spi_flash.c:249
sint8 spi_flash_read(uint8 *pu8Buf, uint32 u32offset, uint32 u32Sz)
Read a specified portion of data from SPI Flash. .
Definition: spi_flash.c:505
#define M2M_DBG(...)
Definition: nm_debug.h:81
uint32 spi_flash_get_size(void)
Returns with uint32 value which is total flash size .
Definition: spi_flash.c:654
#define SPI_FLASH_CMD_CNT
Definition: spi_flash.c:54
sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz)
Erase a specified portion of SPI Flash. .
Definition: spi_flash.c:616
static sint8 spi_flash_load_to_cortus_mem(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
Definition: spi_flash.c:211
sint8 nm_write_reg(uint32 u32Addr, uint32 u32Val)
Definition: nmbus.c:155
#define M2M_ERR(...)
Definition: nm_debug.h:80
#define BSP_MIN(x, y)
Definition: nm_bsp.h:59
SPI Flash.
static sint8 spi_flash_read_internal(uint8 *pu8Buf, uint32 u32Addr, uint32 u32Sz)
Definition: spi_flash.c:387
#define SPI_FLASH_DMA_ADDR
Definition: spi_flash.c:60
#define M2M_INFO(...)
Definition: nm_debug.h:83
#define FLASH_BLOCK_SIZE
Definition: spi_flash_map.h:52
unsigned long uint32
Range of values between 0 to 4294967295.
Definition: nm_bsp.h:103
#define HOST_SHARE_MEM_BASE
Definition: spi_flash.c:45
sint8 spi_flash_write(uint8 *pu8Buf, uint32 u32Offset, uint32 u32Sz)
Write a specified portion of data to SPI Flash. .
Definition: spi_flash.c:539
#define SPI_FLASH_BUF1
Definition: spi_flash.c:56
unsigned char uint8
Range of values between 0 to 255.
Definition: nm_bsp.h:89
static sint8 spi_flash_page_program(uint32 u32MemAdr, uint32 u32FlashAdr, uint32 u32Sz)
Definition: spi_flash.c:348
#define M2M_PRINT(...)
Definition: nm_debug.h:84
static sint8 spi_flash_write_disable(void)
Send write disable command to SPI flash.
Definition: spi_flash.c:313
uint32 nm_read_reg(uint32 u32Addr)
Definition: nmbus.c:104
static sint8 spi_flash_write_enable(void)
Send write enable command to SPI flash.
Definition: spi_flash.c:283


inertial_sense_ros
Author(s):
autogenerated on Sat Sep 19 2020 03:19:05