⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 WRITE AMD 29LV010 FLASH easy to read and use
💻 C
📖 第 1 页 / 共 3 页
字号:
         static byte *selp;
         static byte sechigh;
         static byte *flashptr;  /* flash window (64K bytes) */
         static int oldsector = -1;
         word i;
         int retry;
       
         /**************************************************************/
         /* IMPORTANT: Note that flashptr is defined as a WORD pointer */
         /* If BYTE pointers are used, the command tables will have to */
         /* be remapped                                                */
         /* Note 1: flashptr is declared far - if system does not      */
         /*         support far pointers, this will have to be changed */
         /* Note 2: flashptr is declared static to avoid calling       */
         /*         get_flash_memptr() on successive sector accesses   */
         /**************************************************************/

         /******************************************************************/
         /* On systems where bus glitching is prevalent, some long command */
         /* strings may be interrupted and cause the command to fail (this */
         /* is most probable on six cycle commands such as chip erase). In */
         /* order to ensure that flash_command executes the command        */
         /* properly, it may be necessary to issue the command more than   */
         /* once in order for it to be accepted by the flash device.  In   */
         /* these cases it is recommended that the retry number be made    */
         /* positive (such as 1 or 2), so that flash_command will try      */
         /* to issue the command more than once.  Keep in mind that this   */
         /* will only be attempted if the command fails in the first       */
         /* attempt.                                                       */
         /******************************************************************/
         
         static int retrycount[] = {0,0,0,0,0,0,0,0,0,0};

         retry = retrycount[command];

         if(sector != oldsector) {
                flashptr = (byte *) get_flash_memptr(sector);
         }

again:

         if (command == FLASH_SELECT) {
                return;
         } else if (command == FLASH_RESET || command > FLASH_LASTCMD) {
                  flashptr[0] = 0xF0;   /* assume reset device to read mode */
         } else if (command == FLASH_ESUSPEND) {
                  flashptr[0] = 0xB0;   /* suspend sector erase */
         } else if (command == FLASH_ERESUME) {
                  flashptr[0] = 0x30;   /* resume suspended sector erase */
         } else if (command == FLASH_UBPROG) {
                  flashptr[0] = 0xA0;
                  flashptr[sector*0x10000+offset] = data;
         } else if (command == FLASH_UBRESET) {
                  flashptr[0] = 0x90;
                  flashptr[0] = 0x00;
         }
         else {
                  flashptr[0x555] = 0xAA;       /* unlock 1 */
                  flashptr[0x2AA] = 0x55;       /* unlock 2 */
                  switch (command) {
                         case FLASH_AUTOSEL:
                                flashptr[0x555] = 0x90;
                                break;
                         case FLASH_PROG:
                                flashptr[0x555] = 0xA0;
                                flashptr[0x10000*sector+offset] = data;
                                break;
                         case FLASH_CERASE:
                                flashptr[0x555] = 0x80;
                                flashptr[0x555] = 0xAA;
                                flashptr[0x2AA] = 0x55;
                                flashptr[0x555] = 0x10;
                                break;
                         case FLASH_SERASE:
                                flashptr[0x555]  = 0x80;
                                flashptr[0x555]  = 0xAA;
                                flashptr[0x2AA]  = 0x55;
                                flashptr[sector*0x10000+offset] = 0x30;
                                break;
                         case FLASH_UB:
                                flashptr[0x555] = 0x20;
                                break;
                  }
         }

         if (retry-- > 0 && flash_status(flashptr) == STATUS_READY) {
                goto again;
         }
}
/*********************************************************************/
/* Flash_write extends the functionality of flash_program() by       */
/* providing an faster way to program multiple data words, without   */
/* needing the function overhead of looping algorithms which         */
/* program word by word.  This function utilizes fast pointers       */
/* to quickly loop through bulk data.                                */
/*********************************************************************/
int flash_write(int sector, unsigned offset, byte *buf, 
                int nbytes, int ub)
{
         byte  *flashptr; /* flash window */
         byte  *src, *dst;
         word i;
         int stat;
         int retry = 0, retried = 0;

         flashptr = (byte *)get_flash_memptr(sector);
         dst = flashptr + offset/2;   /* (byte offset) */
         src = (byte *)buf;

         if ((nbytes | offset) & 1) {
                return -1;
         }

again:

         /* Check to see if we're in unlock bypass mode */
         if (ub == FALSE)
                flashptr[0] = 0xF0;  /* reset device to read mode */

         while ((stat = flash_status(flashptr)) == STATUS_BUSY) {}
         if (stat != STATUS_READY) {
                return (byte *)src - buf;
         }

         while (nbytes > 0) {
                if (ub == FALSE){
                  flashptr[0x555] = 0xAA;      /* unlock 1 */
                  flashptr[0x2AA] = 0x55;      /* unlock 2 */
                }
                flashptr[0x555] = 0xA0;
                *dst++ = *src++;
                for(i=0;i<0x50;i++)
                i=i;
                while ((stat = flash_status(flashptr)) == STATUS_BUSY) {}
                if (stat != STATUS_READY) break;
                nbytes -= 2;
         }

         if (stat != STATUS_READY || nbytes != 0) {
                if (retry-- > 0) {
                  ++retried;
                  --dst, --src;   /* back up */
                  goto again;     /* and retry the last word */
                }
                if (ub == FALSE)
                  flash_command(FLASH_RESET,sector,0,0);
         }

         return ((byte *)src - buf);
}

/*********************************************************************/
/* Flash_status utilizes the DQ6, DQ5, and DQ3 polling algorithms    */
/* described in the flash data book.  It can quickly ascertain the   */
/* operational status of the flash device, and return an             */
/* appropriate status code (defined in flash.h)                      */
/*********************************************************************/
 
int flash_status(word *fp)
{
         unsigned char d, t;
         int retry = 1;

again:

         d = *fp;        /* read data */
         t = d ^ *fp;    /* read it again and see what toggled */

         if (t == 0) {           /* no toggles, nothing's happening */
                return STATUS_READY;
         }
         else if (t == 0x04) { /* erase-suspend */
                if (retry--) goto again;    /* may have been write completion */
                return STATUS_ERSUSP;
         }
         else if (t & 0x40) {
                if (d & 0x20) {     /* timeout */
                  return STATUS_TIMEOUT;
                }
                else {
                  return STATUS_BUSY;
                }
         }

         if (retry--) goto again;    /* may have been write completion */

         return STATUS_ERROR;
}
/*********************************************************************/
/* BEGIN API WRAPPER FUNCTIONS                                       */
/*********************************************************************/
/* Flash_sector_erase() will erase a single sector dictated by the   */
/* sector parameter.                                                 */
/* Note: this function will merely BEGIN the erase program.  Code    */
/* execution will immediately return to the calling function         */
/*********************************************************************/

byte flash_sector_erase(byte sector)
{
        flash_command(FLASH_SERASE,sector,0,0);
        return(1);
}

/*********************************************************************/
/* Flash_sector_erase_int() is identical to flash_sector_erase(),    */
/* except it will wait until the erase is completed before returning */
/* control to the calling function.  This can be used in cases which */
/* require the program to hold until a sector is erased, without     */
/* adding the wait check external to this function.                  */
/*********************************************************************/

byte flash_sector_erase_int(byte sector)
{
        flash_command(FLASH_SERASE,sector,0,0);
        while (flash_status((byte *)get_flash_memptr(sector))
                         == STATUS_BUSY) { }
        return(1);
}

/*********************************************************************/
/* flash_reset() will reset the flash device to reading array data.  */
/* It is good practice to call this function after autoselect        */
/* sequences had been performed.                                     */
/*********************************************************************/

byte flash_reset(void)
{
  flash_command(FLASH_RESET,1,0,0);
  return(1);
}

/*********************************************************************/
/* flash_get_device_id() will perform an autoselect sequence on the  */
/* flash device, and return the device id of the component.          */
/* This function automatically resets to read mode.                  */
/*********************************************************************/

byte flash_get_device_id(byte sector)
{
         byte *fwp; /* flash window */
         byte answer;

         fwp = (byte *)get_flash_memptr(sector);

         flash_command(FLASH_AUTOSEL,sector,0,0);


         answer = *((fwp+1));
         
         flash_command(FLASH_RESET,sector,0,0);   /* just to be safe */
         return( (byte) answer );
}

/*********************************************************************/
/* flash_get_manuf_code() will perform an autoselect sequence on the */
/* flash device, and return the manufacturer code of the component.  */
/* This function automatically resets to read mode.                  */
/*********************************************************************/

byte flash_get_manuf_code(byte sector)
{
         byte *fwp; /* flash window */
         byte answer;
         word i;

         fwp = (byte *)get_flash_memptr(sector);

         flash_command(FLASH_AUTOSEL,sector,0,0);

         answer = *fwp;

         flash_command(FLASH_RESET,sector,0,0);   /* just to be safe */ 
         return( (byte) (answer & 0x00FF) );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -