This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Example code for 29F010 Flash

Does anyone out there have any example code for in-circuit programming a 29F010 flash? I plan to set up one sector as "unprotected" and use that to store configuration data which can be modified in the field without a prom burner. The rest of the chip will be set up as "protected" and will contain program code and will be programmed with a prom programmer and not available for field modification. I need a starting point and will appreciate any help you can provide.

Parents
  • The following has been used with the Keil MCB520 evaluation board. It might be useful for what you are trying.

    Keil Support

    /*
    FMEM.C
    
    Routines to program the Intel 28F020/010 Flash Memory.
    */
    
    #include <absacc.h>
    #include "mcb520.h"
    #include "fmem.h"
    
    #define CMD_READ_MEMORY		0x00
    #define CMD_SETUP_ERASE		0x20
    #define CMD_ERASE_VERIFY	0xA0
    #define CMD_SETUP_PROGRAM	0x40
    #define CMD_PROGRAM_VERIFY	0xC0
    #define CMD_RESET		0xFF
    
    #define VPP_PORT		(VPP_NOT_ENABLE)
    #define VPP_OK_PORT		(VPP_NOT_OK)
    
    #define VPPH			0
    #define VPPL			1
    
    #define VPP_OK			0
    
    #define MAX_ERASE_PLSCNT	3000
    #define MAX_PROGRAM_PLSCNT	25
    
    #define DELAY_US1		2UL
    #define DELAY_US6               (DELAY_US1 * 6UL)
    #define DELAY_US10		(DELAY_US1 * 10UL)
    #define DELAY_MS10              (DELAY_US10 * 1000UL)
    #define DELAY_MS1000		(DELAY_MS10 * 100UL)
    
    unsigned char flash_program (
      unsigned long offset,
      unsigned char *buf,
      unsigned int buflen)
    {
    data volatile unsigned long i; 
    data volatile unsigned int  plscnt;  			/* quick pulse counter */
    
    /*------------------------------------------------
    Enable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPH;					/* set VPP HI */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is not good, continue */
        continue;
    
      goto VPP_GOOD;					/* if VPP is good, erase the FLASH */
      }
    
    VPP_PORT = VPPL;					/* set VPP LO */
    
    return (FLASH_VPP_FAIL);
    
    /*------------------------------------------------
    Loop thru the memory and program/verify each byte.
    ------------------------------------------------*/
    VPP_GOOD:
    
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
    for (plscnt = 0; (plscnt < MAX_PROGRAM_PLSCNT) && (buflen != 0); )
      {
      XBYTE [0]    = CMD_SETUP_PROGRAM;
      XBYTE [offset] = *buf; 				/* program byte */
    
      for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
      XBYTE [0] = CMD_PROGRAM_VERIFY;
      if (XBYTE [0] != *buf)				/* if byte is not programmed, try again */
        {
        plscnt++;
        continue;
        }
    
      buflen--;
      buf++;
      offset++;
      }
    
    /*------------------------------------------------
    Enable memory reads.
    ------------------------------------------------*/
    XBYTE [0] = CMD_READ_MEMORY;
    
    /*------------------------------------------------
    Disable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPL;					/* set VPP LO */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is good, continue */
        break;
      }
    
    return ((plscnt >= MAX_PROGRAM_PLSCNT) ? FLASH_PROGRAM_FAIL : FLASH_OK);
    }
    
    
    static unsigned int flash_clear_block (
      unsigned int plscnt)
    {
    data volatile unsigned long i;				/* temp var */
    data volatile unsigned long addr;    			/* address */
    
    for (addr = 0L; (plscnt < MAX_PROGRAM_PLSCNT) && (addr < 0x00010000); )
      {
      XBYTE [0]    = CMD_SETUP_PROGRAM;
      XBYTE [addr & 0xFFFF] = 0;				/* program 0 */
    
      for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
      XBYTE [0] = CMD_PROGRAM_VERIFY;
      if (XBYTE [0] != 0) 					/* if byte is not programmed, try again */
        {
        plscnt++;
        continue;
        }
    
      addr++;
      }
    
    return (plscnt);
    }
    
    
    static unsigned int flash_erase_block (
      unsigned int plscnt)
    {
    data volatile unsigned long i;				/* temp var */
    data volatile unsigned long addr;    			/* address */
    
    for (addr = 0L; (plscnt < MAX_ERASE_PLSCNT) && (addr < 0x00010000); plscnt++)
      {
      XBYTE [0] = CMD_SETUP_ERASE;
      XBYTE [0] = CMD_SETUP_ERASE;
    
      for (i = 0L; i < DELAY_MS10; i++);			/* delay for 10ms */
    
      for (; addr < 0x00010000; addr++)
        {
        XBYTE [addr & 0xFFFF] = CMD_ERASE_VERIFY;
    
        for (i = 0L; i < DELAY_US6; i++);  			/* delay for 6us */
    
        if (XBYTE [0] != 0xFF)				/* if byte is not erased, try again */
          break;
        }
      }
    
    return (plscnt);
    }
    
    
    /*------------------------------------------------------------------------------
    unsigned char flash_erase (void);
    
    This function uses the Quick Erase algorithm presented in the
    Intel Flash Memory Vol 1 1995 data book.
    ------------------------------------------------------------------------------*/
    unsigned char flash_erase (void)
    {
    data volatile unsigned long i; 
    data volatile unsigned int  plscnt;  			/* quick pulse counter */
    data unsigned char retval;
    
    /*------------------------------------------------
    Enable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPH;					/* set VPP HI */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is not good, continue */
        continue;
    
      goto VPP_GOOD;					/* if VPP is good, erase the FLASH */
      }
    
    VPP_PORT = VPPL;					/* set VPP LO */
    
    return (FLASH_VPP_FAIL);
    
    /*------------------------------------------------
    Loop thru the memory and program each byte to 0.
    ------------------------------------------------*/
    VPP_GOOD:
    
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
    plscnt = 0;
    
    for (i = 0; i < 4; i++)
      {
      ROM_A17 = ((i & 0x02) ? 1 : 0);
      ROM_A16 = ((i & 0x01) ? 1 : 0);
    
      if ((plscnt = flash_clear_block (plscnt)) >= MAX_PROGRAM_PLSCNT)
        {
        retval = FLASH_CLEAR_FAIL;
        goto ERASE_EXIT;
        }
      }
    
    /*------------------------------------------------
    Loop thru the memory and erase/verify each byte.
    ------------------------------------------------*/
    plscnt = 0;
    
    for (i = 0; i < 4; i++)
      {
      ROM_A17 = ((i & 0x02) ? 1 : 0);
      ROM_A16 = ((i & 0x01) ? 1 : 0);
    
      if ((plscnt = flash_erase_block (plscnt)) >= MAX_ERASE_PLSCNT)
        {
        retval = FLASH_ERASE_FAIL;
        goto ERASE_EXIT;
        }
      }
    
    retval = FLASH_OK;
    
    /*------------------------------------------------
    Enable memory reads.
    ------------------------------------------------*/
    ERASE_EXIT:
    XBYTE [0] = CMD_READ_MEMORY;
    
    /*------------------------------------------------
    Disable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPL;					/* set VPP LO */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is good, continue */
        break;
      }
    
    return (retval);
    }
    
    

Reply
  • The following has been used with the Keil MCB520 evaluation board. It might be useful for what you are trying.

    Keil Support

    /*
    FMEM.C
    
    Routines to program the Intel 28F020/010 Flash Memory.
    */
    
    #include <absacc.h>
    #include "mcb520.h"
    #include "fmem.h"
    
    #define CMD_READ_MEMORY		0x00
    #define CMD_SETUP_ERASE		0x20
    #define CMD_ERASE_VERIFY	0xA0
    #define CMD_SETUP_PROGRAM	0x40
    #define CMD_PROGRAM_VERIFY	0xC0
    #define CMD_RESET		0xFF
    
    #define VPP_PORT		(VPP_NOT_ENABLE)
    #define VPP_OK_PORT		(VPP_NOT_OK)
    
    #define VPPH			0
    #define VPPL			1
    
    #define VPP_OK			0
    
    #define MAX_ERASE_PLSCNT	3000
    #define MAX_PROGRAM_PLSCNT	25
    
    #define DELAY_US1		2UL
    #define DELAY_US6               (DELAY_US1 * 6UL)
    #define DELAY_US10		(DELAY_US1 * 10UL)
    #define DELAY_MS10              (DELAY_US10 * 1000UL)
    #define DELAY_MS1000		(DELAY_MS10 * 100UL)
    
    unsigned char flash_program (
      unsigned long offset,
      unsigned char *buf,
      unsigned int buflen)
    {
    data volatile unsigned long i; 
    data volatile unsigned int  plscnt;  			/* quick pulse counter */
    
    /*------------------------------------------------
    Enable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPH;					/* set VPP HI */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is not good, continue */
        continue;
    
      goto VPP_GOOD;					/* if VPP is good, erase the FLASH */
      }
    
    VPP_PORT = VPPL;					/* set VPP LO */
    
    return (FLASH_VPP_FAIL);
    
    /*------------------------------------------------
    Loop thru the memory and program/verify each byte.
    ------------------------------------------------*/
    VPP_GOOD:
    
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
    for (plscnt = 0; (plscnt < MAX_PROGRAM_PLSCNT) && (buflen != 0); )
      {
      XBYTE [0]    = CMD_SETUP_PROGRAM;
      XBYTE [offset] = *buf; 				/* program byte */
    
      for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
      XBYTE [0] = CMD_PROGRAM_VERIFY;
      if (XBYTE [0] != *buf)				/* if byte is not programmed, try again */
        {
        plscnt++;
        continue;
        }
    
      buflen--;
      buf++;
      offset++;
      }
    
    /*------------------------------------------------
    Enable memory reads.
    ------------------------------------------------*/
    XBYTE [0] = CMD_READ_MEMORY;
    
    /*------------------------------------------------
    Disable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPL;					/* set VPP LO */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is good, continue */
        break;
      }
    
    return ((plscnt >= MAX_PROGRAM_PLSCNT) ? FLASH_PROGRAM_FAIL : FLASH_OK);
    }
    
    
    static unsigned int flash_clear_block (
      unsigned int plscnt)
    {
    data volatile unsigned long i;				/* temp var */
    data volatile unsigned long addr;    			/* address */
    
    for (addr = 0L; (plscnt < MAX_PROGRAM_PLSCNT) && (addr < 0x00010000); )
      {
      XBYTE [0]    = CMD_SETUP_PROGRAM;
      XBYTE [addr & 0xFFFF] = 0;				/* program 0 */
    
      for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
      XBYTE [0] = CMD_PROGRAM_VERIFY;
      if (XBYTE [0] != 0) 					/* if byte is not programmed, try again */
        {
        plscnt++;
        continue;
        }
    
      addr++;
      }
    
    return (plscnt);
    }
    
    
    static unsigned int flash_erase_block (
      unsigned int plscnt)
    {
    data volatile unsigned long i;				/* temp var */
    data volatile unsigned long addr;    			/* address */
    
    for (addr = 0L; (plscnt < MAX_ERASE_PLSCNT) && (addr < 0x00010000); plscnt++)
      {
      XBYTE [0] = CMD_SETUP_ERASE;
      XBYTE [0] = CMD_SETUP_ERASE;
    
      for (i = 0L; i < DELAY_MS10; i++);			/* delay for 10ms */
    
      for (; addr < 0x00010000; addr++)
        {
        XBYTE [addr & 0xFFFF] = CMD_ERASE_VERIFY;
    
        for (i = 0L; i < DELAY_US6; i++);  			/* delay for 6us */
    
        if (XBYTE [0] != 0xFF)				/* if byte is not erased, try again */
          break;
        }
      }
    
    return (plscnt);
    }
    
    
    /*------------------------------------------------------------------------------
    unsigned char flash_erase (void);
    
    This function uses the Quick Erase algorithm presented in the
    Intel Flash Memory Vol 1 1995 data book.
    ------------------------------------------------------------------------------*/
    unsigned char flash_erase (void)
    {
    data volatile unsigned long i; 
    data volatile unsigned int  plscnt;  			/* quick pulse counter */
    data unsigned char retval;
    
    /*------------------------------------------------
    Enable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPH;					/* set VPP HI */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is not good, continue */
        continue;
    
      goto VPP_GOOD;					/* if VPP is good, erase the FLASH */
      }
    
    VPP_PORT = VPPL;					/* set VPP LO */
    
    return (FLASH_VPP_FAIL);
    
    /*------------------------------------------------
    Loop thru the memory and program each byte to 0.
    ------------------------------------------------*/
    VPP_GOOD:
    
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    for (i = 0L; i < DELAY_US10; i++); 			/* delay for 10us */
    
    plscnt = 0;
    
    for (i = 0; i < 4; i++)
      {
      ROM_A17 = ((i & 0x02) ? 1 : 0);
      ROM_A16 = ((i & 0x01) ? 1 : 0);
    
      if ((plscnt = flash_clear_block (plscnt)) >= MAX_PROGRAM_PLSCNT)
        {
        retval = FLASH_CLEAR_FAIL;
        goto ERASE_EXIT;
        }
      }
    
    /*------------------------------------------------
    Loop thru the memory and erase/verify each byte.
    ------------------------------------------------*/
    plscnt = 0;
    
    for (i = 0; i < 4; i++)
      {
      ROM_A17 = ((i & 0x02) ? 1 : 0);
      ROM_A16 = ((i & 0x01) ? 1 : 0);
    
      if ((plscnt = flash_erase_block (plscnt)) >= MAX_ERASE_PLSCNT)
        {
        retval = FLASH_ERASE_FAIL;
        goto ERASE_EXIT;
        }
      }
    
    retval = FLASH_OK;
    
    /*------------------------------------------------
    Enable memory reads.
    ------------------------------------------------*/
    ERASE_EXIT:
    XBYTE [0] = CMD_READ_MEMORY;
    
    /*------------------------------------------------
    Disable programming voltage and wait for it to
    stabalize.
    ------------------------------------------------*/
    VPP_PORT = VPPL;					/* set VPP LO */
    VPP_OK_PORT = 1;					/* enable input on VPP_OK_PORT */
    
    for (i = 0L; i < DELAY_MS1000; i++)
      {
      if (VPP_OK_PORT != VPP_OK)				/* if VPP is good, continue */
        break;
      }
    
    return (retval);
    }
    
    

Children