/******************************************************************************\ * Copyright (C) 2000 Texas Instruments Incorporated. * All Rights Reserved *------------------------------------------------------------------------------ * FILENAME...... bsl_flash.c * DATE CREATED.. Thu 06/15/2001 * LAST MODIFIED. Thu 06/15/2001 * \******************************************************************************/ #define _FLASH_MOD_ #define _BOARD_MOD_ /****************************************\ * include files \****************************************/ #include "bsl_flash.h" #if (FLASH_SUPPORT) /******************************************************************************\ * L O C A L S E C T I O N \******************************************************************************/ /****************************************\ * FLASH static macro declarations \****************************************/ #if (BOARD_6711DSK | BOARD_6211DSK) #define FLASH_ADR1 0x90005555 /* Used to access the FLASH ROM */ #define FLASH_ADR2 0x90002AAA /* Used to access the FLASH ROM */ #define FLASH_PROGRAM_KEY1 0xAA /* Used to access the FLASH ROM */ #define FLASH_PROGRAM_KEY2 0x55 /* Used to access the FLASH ROM */ #define FLASH_PROGRAM_KEY3 0xA0 /* Used to access the FLASH ROM */ #define FLASH_ERASE_KEY1 0xAA /* Used to chip erase the FLASH ROM */ #define FLASH_ERASE_KEY2 0x55 /* Used to chip erase the FLASH ROM */ #define FLASH_ERASE_KEY3 0x80 /* Used to chip erase the FLASH ROM */ #define FLASH_ERASE_KEY4 0xAA /* Used to chip erase the FLASH ROM */ #define FLASH_ERASE_KEY5 0x55 /* Used to chip erase the FLASH ROM */ #define FLASH_ERASE_KEY6 0x10 /* Used to chip erase the FLASH ROM */ #define PAGE_NUMBER(x) ((x - FLASH_START_ADDR) / FLASH_PAGE_SIZE) #endif /****************************************\ * FLASH static typedef declarations \****************************************/ /****************************************\ * FLASH static function declarations \****************************************/ static inline int page_boundary_FLASH(char *flash_ptr, Uint32 page_size); static int validate_FLASH(Uint32 flahsAddr, Uint32 length); static inline void program_id_FLASH(); static void chip_erase_FLASH(); static inline void buffer_page_FLASH(Uint32 flashptr,char *bufferptr); /****************************************\ * FLASH static variable definitions \****************************************/ static char page_buffer[FLASH_PAGE_SIZE]; /****************************************\ * FLASH static function definitions \****************************************/ /*----------------------------------------------------------------------------*/ int page_boundary_FLASH(char *flash_ptr, Uint32 page_size){ int flag0 = ((int)flash_ptr) % page_size; return (!(flag0)); } /*----------------------------------------------------------------------------*/ int validate_FLASH(Uint32 flashAddr, Uint32 length){ int flag = 1; unsigned int depth; /* distance into memory */ depth = flashAddr - FLASH_START_ADDR + (unsigned int)length; /* check for valid FLASH range */ if ((flashAddr < FLASH_START_ADDR) || (flashAddr>=FLASH_END_ADDR)) flag = 0; /* check to make sure depth doesn't exceed FLASH_SIZE */ if (depth >FLASH_SIZE) flag = 0; return (flag); } /*----------------------------------------------------------------------------*/ void program_id_FLASH(){ *(volatile char *)FLASH_ADR1 = FLASH_PROGRAM_KEY1; *(volatile char *)FLASH_ADR2 = FLASH_PROGRAM_KEY2; *(volatile char *)FLASH_ADR1 = FLASH_PROGRAM_KEY3; } /*----------------------------------------------------------------------------*/ void chip_erase_FLASH(){ *(volatile char *)FLASH_ADR1 = FLASH_ERASE_KEY1; *(volatile char *)FLASH_ADR2 = FLASH_ERASE_KEY2; *(volatile char *)FLASH_ADR1 = FLASH_ERASE_KEY3; *(volatile char *)FLASH_ADR1 = FLASH_ERASE_KEY4; *(volatile char *)FLASH_ADR2 = FLASH_ERASE_KEY5; *(volatile char *)FLASH_ADR1 = FLASH_ERASE_KEY6; } /*----------------------------------------------------------------------------*/ void buffer_page_FLASH(Uint32 flashptr,char *bufferptr){ char *page_ptr = (char *)flashptr; char *buffer_ptr = bufferptr; int i; for (i=0;i<FLASH_PAGE_SIZE;i++){ *buffer_ptr++ = *page_ptr++; } } /*----------------------------------------------------------------------------*/ /******************************************************************************\ * G L O B A L S E C T I O N \******************************************************************************/ /****************************************\ * FLASH global variable definitions \****************************************/ /****************************************\ * FLASH global function definitions \****************************************/ /*----------------------------------------------------------------------------*/ void _FLASH_init() { static int initialized = 0; if (!initialized) { _BOARD_init(); initialized = 1; } } /*----------------------------------------------------------------------------*/ Uint32 FLASH_checksum(Uint32 locator, Uint32 length){ Uint32 oldCECTL1 = EMIF_RGET(CECTL1); int i; Uint32 fchecksum; /* locator is address in FLASH ROM */ unsigned char *locator_ptr = (unsigned char *)locator; #if (BOARD_6711DSK | BOARD_6211DSK) /* set CE1 space to 8-bit async mode */ EMIF_RSET(CECTL1,(oldCECTL1 & (~0x000000F0)) | 0x00000000); #endif /* checksum returned as "FFFFFFFF", -1, if error has occured */ fchecksum = 0xFFFFFFFF; if (validate_FLASH(locator, length)){ fchecksum = 0; for (i=0;i<length;i++) { fchecksum += *locator_ptr++; /* UNSIGNED SUMMATION OF BYTES */ } } EMIF_RSET(CECTL1,oldCECTL1); /* restore CE1 space */ return (fchecksum); } /*----------------------------------------------------------------------------*/ void FLASH_erase(Uint32 locator, Uint32 length){ Uint32 oldCECTL1 = EMIF_RGET(CECTL1); int i,j; /* stores the byte address of the start location to be erased */ Uint32 start_erase; /* pointer to last byte in the FLASH */ volatile char *end_erase_pos = (char *)(FLASH_END_ADDR - 1); volatile char locator_flag; /* destination is address in FLASH ROM */ volatile char *locator_ptr = (char *)locator; #if (BOARD_6711DSK | BOARD_6211DSK) /* set CE1 space to 8-bit async mode */ EMIF_RSET(CECTL1,(oldCECTL1 & (~0x000000F0)) | 0x00000000); #endif /*--------------------------------------------------------------------------* * buffer page if locator is not on page boundary * * or length is less than page size * *---------------------------------------------------------------------------*/ if ( (!page_boundary_FLASH((char *)locator, FLASH_PAGE_SIZE)) || (length<FLASH_PAGE_SIZE)){ buffer_page_FLASH( FLASH_PAGE_ADDR(PAGE_NUMBER(locator)), page_buffer); } start_erase = (locator % FLASH_PAGE_SIZE); for (i= start_erase; i <(length + start_erase);){ page_buffer[i] = 0xFF; if (page_boundary_FLASH((char *)(++i),FLASH_PAGE_SIZE)){ break; } } i -=start_erase; if (length == FLASH_ERASE_ALL){ program_id_FLASH(); /* accesses FLASH for programming */ *end_erase_pos = 0; chip_erase_FLASH(); /* wait for erase to complete before proceeding */ locator_flag = *end_erase_pos; while(locator_flag != (char)0xFF){ locator_flag = *end_erase_pos; } } else{ if (validate_FLASH(locator, length)){ program_id_FLASH(); /* accesses FLASH for programming */ /* DATA ERASE */ locator_ptr = (char *) (FLASH_PAGE_ADDR(PAGE_NUMBER(locator))); j=0; while (j<FLASH_PAGE_SIZE){ *locator_ptr++ = page_buffer[j]; /* clears locator */ j++; } locator_flag = *--locator_ptr; /* wait until write is completed in the FLASH before proceeding */ while (locator_flag != page_buffer[FLASH_PAGE_SIZE - 1]){ locator_flag = *locator_ptr; }/*end while*/ if (i<length) FLASH_erase((Uint32)++locator_ptr,(length-i)); }/*end if validate_FLASH*/ } EMIF_RSET(CECTL1,oldCECTL1); /* restore CE1 space */ } /*----------------------------------------------------------------------------*/ void FLASH_read(Uint32 locator, Uint32 dst, Uint32 length){ Uint32 oldCECTL1 = EMIF_RGET(CECTL1); int i; /* destination is specified address elsewhere */ char *dst_ptr = (char *)dst; /* source is address in FLASH ROM */ char *locator_ptr = (char *)locator; #if (BOARD_6711DSK | BOARD_6211DSK) /* set CE1 space to 8-bit async mode */ EMIF_RSET(CECTL1,(oldCECTL1 & (~0x000000F0)) | 0x00000000); #endif if (validate_FLASH(locator, length)){ /* copies souce to destination */ for (i=0;i<length;i++) *dst_ptr++ = *locator_ptr++; } EMIF_RSET(CECTL1,oldCECTL1); /* restore CE1 space */ } /*----------------------------------------------------------------------------*/ void FLASH_write(Uint32 src, Uint32 locator, Uint32 length){ Uint32 oldCECTL1 = EMIF_RGET(CECTL1); int i,j; /* stores the byte address of the start location to be erased */ Uint32 start_write; volatile char locator_flag; /* destination is address in FLASH ROM */ volatile char *locator_ptr = (char *)locator; /* source is specified address elsewhere */ volatile char *src_ptr = (char *)src; #if (BOARD_6711DSK | BOARD_6211DSK) /* set CE1 space to 8-bit async mode */ EMIF_RSET(CECTL1,(oldCECTL1 & (~0x000000F0)) | 0x00000000); #endif /*--------------------------------------------------------------------------* * buffer page if locator is not on page boundary * * or length is less than page size * *---------------------------------------------------------------------------*/ if ( (!page_boundary_FLASH((char *)locator, FLASH_PAGE_SIZE)) || (length<FLASH_PAGE_SIZE)){ buffer_page_FLASH( FLASH_PAGE_ADDR(PAGE_NUMBER(locator)), page_buffer); } start_write = (locator % FLASH_PAGE_SIZE); for (i= start_write; i <(length + start_write);){ page_buffer[i] = *src_ptr++; if (page_boundary_FLASH((char *)(++i),FLASH_PAGE_SIZE)){ break; } } i -= start_write; if (validate_FLASH(locator, length)){ program_id_FLASH(); /* accesses FLASH for programming */ /* DATA WRITE */ locator_ptr = (char *) (FLASH_PAGE_ADDR(PAGE_NUMBER(locator))); for (j=0; j<FLASH_PAGE_SIZE; j++){ *locator_ptr++ = page_buffer[j]; /* copies souce to destination */ } locator_flag = *--locator_ptr; /* wait until write is completed in the FLASH before proceeding */ while (locator_flag != page_buffer[FLASH_PAGE_SIZE - 1]){ locator_flag = *locator_ptr; }/*end while*/ if (i<length) FLASH_write( (Uint32)src_ptr, (Uint32)++locator_ptr, (Uint32)(length - i)); }/*end if validate_FLASH*/ EMIF_RSET(CECTL1,oldCECTL1); /* restore CE1 space */ } /*----------------------------------------------------------------------------*/ #endif /* FLASH_SUPPORT */ /******************************************************************************\ * End of bsl_flash.c \******************************************************************************/