need to know how to write data into external flash memory(offchip).using MCU MC9S12A128B and the external flash memory chip is M29F040B.Is there any special code to be sent to the external flash memory.Using a cpld chip number being CY37128P84 125 JC which is used for the selecting the external flash chip.Also using metrowerks code warrior and BDM Multilink. Thanks for any help, Ranjita
flash memory(external)
Started by ●March 24, 2005
Reply by ●March 24, 20052005-03-24
risha wrote:> need to know how to write data into external flash > memory(offchip).using MCU MC9S12A128B and the external flash memory > chip is M29F040B.Is there any special code to be sent to the external > flash memory.Using a cpld chip number being CY37128P84 125 JC which is > used for the selecting the external flash chip.Also using metrowerks > code warrior and BDM Multilink. >Yes, you do need special writing sequences. Please get 29F040 data sheet (Google for it) and read the instructions from it. -- Tauno Voipio tauno voipio (at) iki fi
Reply by ●March 24, 20052005-03-24
This is a multi-part message in MIME format. --------------000008090400050503010209 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit risha schrieb:> need to know how to write data into external flash > memory(offchip).using MCU MC9S12A128B and the external flash memory > chip is M29F040B.Is there any special code to be sent to the external > flash memory.Using a cpld chip number being CY37128P84 125 JC which is > used for the selecting the external flash chip.Also using metrowerks > code warrior and BDM Multilink. > > > Thanks for any help, > RanjitaHi Ranjita The two attached files were once published on the website of STMicroelectronics (www.st.com) and contain library routines for the M29F040B Flash Memory. --------------000008090400050503010209 Content-Type: text/plain; name="c1191_08.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="c1191_08.c" /****c1191_08.c*4Mb Flash Memory************************************************ Filename: c1191_08.c Description: Library routines for the M29F040B and M29W040B 4Mb (512Kb x8) Flash Memories. Revision: 1.00 Date: 17/09/99 Author: Alex Nairac, Oxford Technical Solutions (www.ots.ndirect.co.uk) Copyright (c) 1999 STMicroelectronics. THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. ******************************************************************************** Version History. Ver. Date Comments 1.00 17/09/99 Initial Release of the Software. ******************************************************************************** This source file provides library C code for using the M29x040B devices. The following devices are supported in the code: M29F040B M29W040B The following functions are available in this library: FlashReadReset() to reset the flash for normal memory access FlashAutoSelect() to get information about the device FlashBlockErase() to erase one or more blocks FlashChipErase() to erase the whole chip FlashProgram() to program a byte or an array FlashErrorStr() to return the error string of an error For further information consult the Data Sheet and the Application Note. The Application Note gives information about how to modify this code for a specific application. Note that A0-A14 are set up correctly during the special write cycles required to issue commands to the Flash Memories. The devices supported by this application code only require A0-A10 to be set up correctly. However this application code sets up A0-A14 to remain compatible with previous generations of the devices. The hardware specific functions which need to be modified by the user are: FlashWrite() for writing a byte to the flash FlashRead() for reading a byte from the flash FlashPause() for timing short pauses (in micro seconds) A list of the error conditions is given at the end of the code. There are no timeouts implemented in the loops in the code. At each point where an infinite loop is implemented a comment /# TimeOut! #/ has been placed. It is up to the user to implement these to avoid the code hanging instead of timing out. Since C does not include a method for disabling interrupts to keep time- critical sections of code from being disabled. The user may wish to disable interrupt during parts of the code to avoid the FLASH_MPU_TOO_SLOW error from occuring if an interrupt occurs at the wrong time. Where interrupt should be disabled and re-enabled there is a /# DSI! #/ or /# ENI! #/ comment. The source code assumes that the compiler implements the numerical types as unsigned char 8 bits unsigned int 16 bits unsigned long 32 bits Additional changes to the code will be necessary if these are not correct. *******************************************************************************/ #include <stdlib.h> #include "c1191_08.h" /* Header file with global prototypes */ #define USE_M29F040B /******************************************************************************* Constants *******************************************************************************/ #define COUNTS_PER_MICROSECOND (200) #define MANUFACTURER_ST (0x20) /* Manufacturer code */ #define BASE_ADDR ((volatile unsigned char*)0x0000) /* BASE_ADDR is the base address of the flash, see the functions FlashRead() and FlashWrite(). Some applications which require a more complicated FlashRead() or FlashWrite() may not use BASE_ADDR */ #define ANY_ADDR (0x0000L) /* Any address offset within the Flash Memory will do */ #ifdef USE_M29F040B #define EXPECTED_DEVICE (0xE2) /* Device code for the M29F040B */ #endif #ifdef USE_M29W040B #define EXPECTED_DEVICE (0xE3) /* Device code for the M29W040B */ #endif static const unsigned long BlockOffset[] = /* Offset from BASE_ADDR of blocks */ { 0x00000L, /* Start offset of block 0 */ 0x10000L, /* Start offset of block 1 */ 0x20000L, /* Start offset of block 2 */ 0x30000L, /* Start offset of block 3 */ 0x40000L, /* Start offset of block 4 */ 0x50000L, /* Start offset of block 5 */ 0x60000L, /* Start offset of block 6 */ 0x70000L /* Start offset of block 7 */ }; #define NUM_BLOCKS (sizeof(BlockOffset)/sizeof(BlockOffset[0])) #define FLASH_SIZE (0x80000L) /* 512K */ /******************************************************************************* Static Prototypes The following functions are only needed in this module. *******************************************************************************/ static unsigned char FlashWrite( unsigned long ulOff, unsigned char ucVal ); static void FlashPause( unsigned int uMicroSeconds ); static int FlashDataToggle( void ); /****************************************************************************** The function FlashDataPoll() declared below is not used by this library but is provided as an illustration of the Data Polling Flow Chart *******************************************************************************/ #define ILLUSTRATION_ONLY #ifndef ILLUSTRATION_ONLY static int FlashDataPoll( unsigned long ulOff, unsigned char ucVal ); #endif /* !ILLUSTRATION_ONLY */ /******************************************************************************* Function: unsigned char FlashWrite( unsigned long ulOff, unsigned char ucVal) Arguments: ulOff is the byte offset in the flash to write to ucVal is the value to be written Returns: ucVal Description: This function is used to write a byte to the flash. On many microprocessor systems a macro can be used instead, increasing the speed of the flash routines. For example: #define FlashWrite( ulOff, ucVal ) ( BASE_ADDR[ulOff] = (unsigned char) ucVal ) A function is used here instead to allow the user to expand it if necessary. The function is made to return ucVal so that it is compatible with the macro. Pseudo Code: Step 1: Write ucVal to the byte offset in the flash Step 2: return ucVal *******************************************************************************/ static unsigned char FlashWrite( unsigned long ulOff, unsigned char ucVal ) { /* Step1, 2: Write ucVal to the byte offset in the flash and return it */ return BASE_ADDR[ulOff] = ucVal; } /******************************************************************************* Function: unsigned char FlashRead( unsigned long ulOff ) Arguments: ulOff is the byte offset into the flash to read from Returns: The unsigned char at the byte offset Description: This function is used to read a byte from the flash. On many microprocessor systems a macro can be used instead, increasing the speed of the flash routines. For example: #define FlashRead( ulOff ) ( BASE_ADDR[ulOff] ) A function is used here instead to allow the user to expand it if necessary. Pseudo Code: Step 1: Return the value at byte offset ulOff *******************************************************************************/ unsigned char FlashRead( unsigned long ulOff ) { /* Step 1 Return the value at byte offset ulOff */ return BASE_ADDR[ulOff]; } /******************************************************************************* Function: void FlashPause( unsigned int uMicroSeconds ) Arguments: uMicroSeconds is the length of the pause in microseconds Returns: none Description: This routine returns after uMicroSeconds have elapsed. It is used in several parts of the code to generate a pause required for correct operation of the flash part. The routine here works by counting. The user may already have a more suitable routine for timing which can be used. Pseudo Code: Step 1: Compute count size for pause. Step 2: Count to the required size. *****************************************************************/ static void FlashPause( unsigned int uMicroSeconds ) { volatile unsigned long ulCountSize; /* Step 1: Compute the count size */ ulCountSize = (unsigned long)uMicroSeconds * COUNTS_PER_MICROSECOND; /* Step 2: Count to the required size */ while( ulCountSize > 0 ) /* Test to see if finished */ ulCountSize--; /* and count down */ } /******************************************************************************* Function: void FlashReadReset( void ) Arguments: none Return Value: none Description: This function places the flash in the Read mode described in the Data Sheet. In this mode the flash can be read as normal memory. All of the other functions leave the flash in the Read mode so this is not strictly necessary. It is provided for completeness. Note: A wait of 10us is required if the command is called during a program or erase instruction. This is included here to guarantee correct operation. The functions in this library call this function if they suspect an error during programming or erasing so that the 10us pause is included. Otherwise they use the single instruction technique for increased speed. Pseudo Code: Step 1: write command sequence (see Commands Table of the Data Sheet) Step 2: wait 10us *******************************************************************************/ void FlashReadReset( void ) { /* Step 1: write command sequence */ FlashWrite( 0x5555L, 0xAA ); /* 1st Cycle */ FlashWrite( 0x2AAAL, 0x55 ); /* 2nd Cycle */ FlashWrite( ANY_ADDR, 0xF0 ); /* 3rd Cycle: write 0xF0 to ANY address */ /* Step 2: wait 10us */ FlashPause( 10 ); } /******************************************************************************* Function: int FlashAutoSelect( int iFunc ) Arguments: iFunc should be set to either the Read Signature values or to the block number. The header file defines the values for reading the Signature. Note: the first block is Block 0 Return Value: When iFunc is >= 0 the function returns FLASH_BLOCK_PROTECTED (01h) if the block is protected and FLASH_BLOCK_UNPROTECTED (00h) if it is unprotected. See the Auto Select command in the Data Sheet for further information. When iFunc is FLASH_READ_MANUFACTURER (-2) the function returns the manufacturer's code. The Manufacturer code for ST is 20h. When iFunc is FLASH_READ_DEVICE_CODE (-1) the function returns the Device Code. The device codes for the parts are: M29F040B E2h M29W040B E3h When iFunc is invalid the function returns FLASH_BLOCK_INVALID (-5) Description: This function can be used to read the electronic signature of the device, the manufacturer code or the protection level of a block. Pseudo Code: Step 1: Send the Auto Select command to the device Step 2: Read the required function from the device. Step 3: Return the device to Read mode. *******************************************************************************/ int FlashAutoSelect( int iFunc ) { int iRetVal; /* Holds the return value */ /* Step 1: Send the Auto Select command */ FlashWrite( 0x5555L, 0xAA ); /* 1st Cycle */ FlashWrite( 0x2AAAL, 0x55 ); /* 2nd Cycle */ FlashWrite( 0x5555L, 0x90 ); /* 3rd Cycle */ /* Step 2: Read the required function */ if( iFunc == FLASH_READ_MANUFACTURER ) iRetVal = (int) FlashRead( 0x0000L ); /* A0 = A1 = 0 */ else if( iFunc == FLASH_READ_DEVICE_CODE ) iRetVal = (int) FlashRead( 0x0001L ); /* A0 = 1, A1 = 0 */ else if( (iFunc >= 0) && (iFunc < NUM_BLOCKS) ) iRetVal = FlashRead( BlockOffset[iFunc] + 0x0002L ); /* A0 = 0, A1 = 1 */ else iRetVal = FLASH_BLOCK_INVALID; /* Step 3: Return to Read mode */ FlashWrite( ANY_ADDR, 0xF0 ); /* Use single instruction cycle method */ return iRetVal; } /******************************************************************************* Function: int FlashBlockErase( unsigned char ucNumBlocks, unsigned char ucBlock[] ) Arguments: ucNumBlocks holds the number of blocks in the array ucBlock ucBlock is an array containing the blocks to be erased. Return Value: The function returns the following conditions: FLASH_SUCCESS (-1) FLASH_TOO_MANY_BLOCKS (-3) FLASH_MPU_TOO_SLOW (-4) FLASH_WRONG_TYPE (-8) FLASH_ERASE_FAIL (-14) Number of the first protected or invalid block The user's array, ucBlock[] is used to report errors on the specified blocks. If a time-out occurs because the MPU is too slow then the blocks in ucBlocks which are not erased are overwritten with FLASH_BLOCK_NOT_ERASED (FFh) and the function returns FLASH_MPU_TOO_SLOW. If an error occurs during the erasing of the blocks the function returns FLASH_ERASE_FAIL. If both errors occur then the function will set the ucBlock array to FLASH_BLOCK_NOT_ERASED for the unerased blocks. It will return FLASH_ERASE_FAIL even though the FLASH_MPU_TOO_SLOW has also occurred. Description: This function erases up to ucNumBlocks in the flash. The blocks can be listed in any order. The function does not return until the blocks are erased. If any blocks are protected or invalid none of the blocks are erased. During the Erase Cycle the Data Toggle Flow Chart of the Data Sheet is followed. The polling bit, DQ7, is not used. Pseudo Code: Step 1: Check for correct flash type Step 2: Check for protected or invalid blocks Step 3: Write Block Erase command Step 4: Check for time-out blocks Step 5: Wait for the timer bit to be set. Step 6: Follow Data Toggle Flow Chart until Program/Erase Controller has completed Step 7: Return to Read mode (if an error occurred) *******************************************************************************/ int FlashBlockErase( unsigned char ucNumBlocks, unsigned char ucBlock[] ) { unsigned char ucCurBlock; /* Range Variable to track current block */ int iRetVal = FLASH_SUCCESS; /* Holds return value: optimistic initially! */ /* Step 1: Check for correct flash type */ if( !(FlashAutoSelect( FLASH_READ_MANUFACTURER ) == MANUFACTURER_ST) || !(FlashAutoSelect( FLASH_READ_DEVICE_CODE ) == EXPECTED_DEVICE ) ) return FLASH_WRONG_TYPE; /* Step 2: Check for protected or invalid blocks. */ if( ucNumBlocks > NUM_BLOCKS ) /* Check specified blocks <= NUM_BLOCKS */ return FLASH_TOO_MANY_BLOCKS; for( ucCurBlock = 0; ucCurBlock < ucNumBlocks; ucCurBlock++ ) { /* Use FlashAutoSelect to find protected or invalid blocks*/ if( FlashAutoSelect((int)ucBlock[ucCurBlock]) != FLASH_BLOCK_UNPROTECTED ) return (int)ucBlock[ucCurBlock]; /* Return protected/invalid blocks */ } /* Step 3: Write Block Erase command */ FlashWrite( 0x5555L, 0xAA ); FlashWrite( 0x2AAAL, 0x55 ); FlashWrite( 0x5555L, 0x80 ); FlashWrite( 0x5555L, 0xAA ); FlashWrite( 0x2AAAL, 0x55 ); /* DSI!: Time critical section. Additional blocks must be added every 50us */ for( ucCurBlock = 0; ucCurBlock < ucNumBlocks; ucCurBlock++ ) { FlashWrite( BlockOffset[ucBlock[ucCurBlock]], 0x30 ); /* Check for Erase Timeout Period (is bit DQ3 set?) */ if( (FlashRead( BlockOffset[ucBlock[0]] ) & 0x08) == 0x08 ) break; /* Cannot set any more blocks due to timeout */ } /* ENI! */ /* Step 4: Check for time-out blocks */ if( ucCurBlock < ucNumBlocks ) { /* Indicate that some blocks have been timed out of the erase list */ iRetVal = FLASH_MPU_TOO_SLOW; /* Now specify all other blocks as not being erased */ /* Note that we cannot tell if the first (potentially timed out) block is erasing or not */ while( ucCurBlock < ucNumBlocks ) { ucBlock[ucCurBlock++] = FLASH_BLOCK_NOT_ERASED; } } /* Step 5: Wait for the Erase Timer Bit (DQ3) to be set */ while( 1 ) /* TimeOut!: If, for some reason, the hardware fails then this loop may not exit. Use a timer function to implement a timeout from the loop. */ { if( ( FlashRead( BlockOffset[ucBlock[0]] ) & 0x08 ) == 0x08 ) break; /* Break when device starts the erase cycle */ } /* Step 6: Follow Data Toggle Flow Chart until Program/Erase Controller completes */ if( FlashDataToggle() != FLASH_SUCCESS ) { iRetVal = FLASH_ERASE_FAIL; /* Step 7: Return to Read mode (if an error occurred) */ FlashReadReset(); } return iRetVal; } /******************************************************************************* Function: int FlashChipErase( void ) Arguments: none Return Value: On success the function returns FLASH_SUCCESS (-1) If a block is protected then the function returns the number of the block and no blocks are erased. If the erase algorithms fails then the function returns FLASH_ERASE_FAIL (-2) If the wrong type of flash is detected then FLASH_WRONG_TYPE (-8) is returned. Description: The function can be used to erase the whole flash chip so long as no blocks are protected. If any blocks are protected then nothing is erased. Pseudo Code: Step 1: Check for correct flash type Step 2: Check that all blocks are unprotected Step 3: Send Chip Erase Command Step 4: Follow Data Toggle Flow Chart until Program/Erase Controller has completed. Step 5: Return to Read mode (if an error occurred) *******************************************************************************/ int FlashChipErase( void ) { unsigned char ucCurBlock; /* Used to track the current block in a range */ /* Step 1: Check for correct flash type */ if( !(FlashAutoSelect( FLASH_READ_MANUFACTURER ) == MANUFACTURER_ST) || !(FlashAutoSelect( FLASH_READ_DEVICE_CODE ) == EXPECTED_DEVICE ) ) return FLASH_WRONG_TYPE; /* Step 2: Check that all blocks are unprotected */ for( ucCurBlock = 0; ucCurBlock < NUM_BLOCKS; ucCurBlock++ ) { if( FlashAutoSelect( (int)ucCurBlock ) != FLASH_BLOCK_UNPROTECTED ) return (int)ucCurBlock; /* Return the first protected block */ } /* Step 3: Send Chip Erase Command */ FlashWrite( 0x5555L, 0xAA ); FlashWrite( 0x2AAAL, 0x55 ); FlashWrite( 0x5555L, 0x80 ); FlashWrite( 0x5555L, 0xAA ); FlashWrite( 0x2AAAL, 0x55 ); FlashWrite( 0x5555L, 0x10 ); /* Step 4: Follow Data Toggle Flow Chart until Program/Erase Controller has completed */ if( FlashDataToggle() != FLASH_SUCCESS ) { /* Step 5: Return to Read mode (if an error occurred) */ FlashReadReset(); return FLASH_ERASE_FAIL; } else return FLASH_SUCCESS; } /******************************************************************************* Function: int FlashProgram( unsigned long ulOff, size_t NumBytes, void *Array ) Arguments: ulOff is the byte offset into the flash to be programmed NumBytes holds the number of bytes in the array. Array is a pointer to the array to be programmed. Return Value: The function returns the following conditions: FLASH_SUCCESS (-1) FLASH_PROGRAM_FAIL (-6) FLASH_OFFSET_OUT_OF_RANGE (-7) FLASH_WRONG_TYPE (-8) Number of the first protected or invalid block On success the function returns FLASH_SUCCESS (-1). The function returns FLASH_PROGRAM_FAIL (-6) if a programming failure occurs. If the address range to be programmed exceeds the address range of the Flash Device the function returns FLASH_OFFSET_OUT_OF_RANGE (-7) and nothing is programmed. If the wrong type of flash is detected then FLASH_WRONG_TYPE (-8) is returned and nothing is programmed. If part of the address range to be programmed falls within a protected block, the function returns the number of the first protected block encountered and nothing is programmed. Description: This function is used to program an array into the flash. It does not erase the flash first and may fail if the block(s) are not erased first. Pseudo Code: Step 1: Check for correct flash type Step 2: Check the offset range is valid Step 3: Check that the block(s) to be programmed are not protected Step 4: While there is more to be programmed Step 5: Check for changes from '0' to '1' Step 6: Program the next byte Step 7: Follow Data Toggle Flow Chart until Program/Erase Controller has completed Step 8: Return to Read mode (if an error occurred) Step 9: Update pointers *******************************************************************************/ int FlashProgram( unsigned long ulOff, size_t NumBytes, void *Array ) { unsigned char *ucArrayPointer; /* Use an unsigned char to access the array */ unsigned long ulLastOff; /* Holds the last offset to be programmed */ unsigned char ucCurBlock; /* Range Variable to track current block */ /* Step 1: Check for correct flash type */ if( !(FlashAutoSelect( FLASH_READ_MANUFACTURER ) == MANUFACTURER_ST) || !(FlashAutoSelect( FLASH_READ_DEVICE_CODE ) == EXPECTED_DEVICE ) ) return FLASH_WRONG_TYPE; /* Step 2: Check the offset and range are valid */ ulLastOff = ulOff+NumBytes-1; if( ulLastOff >= FLASH_SIZE ) return FLASH_OFFSET_OUT_OF_RANGE; /* Step 3: Check that the block(s) to be programmed are not protected */ for( ucCurBlock = 0; ucCurBlock < NUM_BLOCKS; ucCurBlock++ ) { /* If the address range to be programmed ends before this block */ if( BlockOffset[ucCurBlock] > ulLastOff ) break; /* then we are done */ /* Else if the address range starts beyond this block */ else if( (ucCurBlock < (NUM_BLOCKS-1)) && (ulOff >= BlockOffset[ucCurBlock+1]) ) continue; /* then skip this block */ /* Otherwise if this block is not unprotected */ else if( FlashAutoSelect((int)ucCurBlock) != FLASH_BLOCK_UNPROTECTED ) return (int)ucCurBlock; /* Return first protected block */ } /* Step 4: While there is more to be programmed */ ucArrayPointer = (unsigned char *)Array; while( ulOff <= ulLastOff ) { /* Step 5: Check for changes from '0' to '1' */ if( ~FlashRead( ulOff ) & *ucArrayPointer ) /* Indicate failure as it is not possible to change a '0' to a '1' using a Program command. This must be done using an Erase command */ return FLASH_PROGRAM_FAIL; /* Step 6: Program the next byte */ FlashWrite( 0x5555L, 0xAA ); /* 1st cycle */ FlashWrite( 0x2AAAL, 0x55 ); /* 2nd cycle */ FlashWrite( 0x5555L, 0xA0 ); /* Program command */ FlashWrite( ulOff, *ucArrayPointer ); /* Program value */ /* Step 7: Follow Data Toggle Flow Chart until Program/Erase Controller has completed */ /* See Data Toggle Flow Chart of the Data Sheet */ if( FlashDataToggle() == FLASH_TOGGLE_FAIL ) { /* Step 8: Return to Read mode (if an error occurred) */ FlashReadReset(); return FLASH_PROGRAM_FAIL; } /* Step 9: Update pointers */ ulOff++; ucArrayPointer++; } return FLASH_SUCCESS; } /******************************************************************************* Function: static int FlashDataToggle( void ) Arguments: none Return Value: The function returns FLASH_SUCCESS if the Program/Erase Controller is successful or FLASH_TOGGLE_FAIL if there is a problem. Description: The function is used to monitor the Program/Erase Controller during erase or program operations. It returns when the Program/Erase Controller has completed. In the M29F040B Data Sheet or the M29W040B Data Sheet the Data Toggle Flow Chart shows the operation of the function. Pseudo Code: Step 1: Read DQ6 (into a byte) Step 2: Read DQ5 and DQ6 (into another byte) Step 3: If DQ6 did not toggle between the two reads then return FLASH_SUCCESS Step 4: Else if DQ5 is zero then operation is not yet complete, goto 1 Step 5: Else (DQ5 != 0), read DQ6 again Step 6: If DQ6 did not toggle between the last two reads then return FLASH_SUCCESS Step 7: Else return FLASH_TOGGLE_FAIL *******************************************************************************/ static int FlashDataToggle( void ) { unsigned char uc1, uc2; /* hold values read from any address offset within the Flash Memory */ while( 1 ) /* TimeOut!: If, for some reason, the hardware fails then this loop may not exit. Use a timer function to implement a timeout from the loop. */ { /* Step 1: Read DQ6 (into a byte) */ uc1 = FlashRead( ANY_ADDR ); /* Read DQ6 from the Flash (any address) */ /* Step 2: Read DQ5 and DQ6 (into another byte) */ uc2 = FlashRead( ANY_ADDR ); /* Read DQ5 and DQ6 from the Flash (any address) */ /* Step 3: If DQ6 did not toggle between the two reads then return FLASH_SUCCESS */ if( (uc1&0x40) == (uc2&0x40) ) /* DQ6 == NO Toggle */ return FLASH_SUCCESS; /* Step 4: Else if DQ5 is zero then operation is not yet complete */ if( (uc2&0x20) == 0x00 ) continue; /* Step 5: Else (DQ5 == 1), read DQ6 again */ uc1 = FlashRead( ANY_ADDR ); /* Read DQ6 from the Flash (any address) */ /* Step 6: If DQ6 did not toggle between the last two reads then return FLASH_SUCCESS */ if( (uc2&0x40) == (uc1&0x40) ) /* DQ6 == NO Toggle */ return FLASH_SUCCESS; /* Step 7: Else return FLASH_TOGGLE_FAIL */ else /* DQ6 == Toggle here means fail */ return FLASH_TOGGLE_FAIL; } /* end of while loop */ } #ifndef ILLUSTRATION_ONLY /******************************************************************************* Function: static int FlashDataPoll( unsigned long ulOff, unsigned char ucVal ) Arguments: ulOff should hold a valid offset to be polled. For programming this will be the offset of the byte being programmed. For erasing this can be any offset in the block(s) being erased. ucVal should hold the value being programmed. A value of FFh should be used when erasing. Return Value: The function returns FLASH_SUCCESS if the Program/Erase Controller is successful or FLASH_POLL_FAIL if there is a problem. Description: The function is used to monitor the Program/Erase Controller during erase or program operations. It returns when the Program/Erase Controller has completed. In the M29F040B Data Sheet or the M29W040B Data Sheet the Data Polling Flow Chart shows the operation of the function. Note: this library does not use the Data Polling Flow Chart to assess the correct operation of Program/Erase Controller, but uses the Data Toggle Flow Chart instead. The FlashDataPoll() function is only provided here as an illustration of the Data Polling Flow Chart in the Data Sheet. The code uses the function FlashDataToggle() instead. Pseudo Code: Step 1: Read DQ5 and DQ7 (into a byte) Step 2: If DQ7 is the same as ucVal(bit 7) then return FLASH_SUCCESS Step 3: Else if DQ5 is zero then operation is not yet complete, goto 1 Step 4: Else (DQ5 != 0), Read DQ7 Step 5: If DQ7 is now the same as ucVal(bit 7) then return FLASH_SUCCESS Step 6: Else return FLASH_POLL_FAIL *******************************************************************************/ static int FlashDataPoll( unsigned long ulOff, unsigned char ucVal ) { unsigned char uc; /* holds value read from valid address */ while( 1 ) /* TimeOut!: If, for some reason, the hardware fails then this loop may not exit. Use a timer function to implement a timeout from the loop. */ { /* Step 1: Read DQ5 and DQ7 (into a byte) */ uc = FlashRead( ulOff ); /* Read DQ5, DQ7 at valid addr */ /* Step 2: If DQ7 is the same as ucVal(bit 7) then return FLASH_SUCCESS */ if( (uc&0x80) == (ucVal&0x80) ) /* DQ7 == DATA */ return FLASH_SUCCESS; /* Step 3: Else if DQ5 is zero then operation is not yet complete */ if( (uc&0x20) == 0x00 ) continue; /* Step 4: Else (DQ5 == 1) */ uc = FlashRead( ulOff ); /* Read DQ7 at valid addr */ /* Step 5: If DQ7 is now the same as ucVal(bit 7) then return FLASH_SUCCESS */ if( (uc&0x80) == (ucVal&0x80) ) /* DQ7 == DATA */ return FLASH_SUCCESS; /* Step 6: Else return FLASH_POLL_FAIL */ else /* DQ7 != DATA here means fail */ return FLASH_POLL_FAIL; } /* end of while loop */ } #endif /* !ILLUSTRATION_ONLY */ /******************************************************************************* Function: char *FlashErrorStr( int iErrNum ); Arguments: iErrNum is the error number returned from another Flash Routine Return Value: A pointer to a string with the error message Description: This function is used to generate a text string describing the error from the flash. Call with the return value from another flash routine. Pseudo Code: Step 1: Check the error message range. Step 2: Return the correct string. *******************************************************************************/ char *FlashErrorStr( int iErrNum ) { static char *str[] = { "Flash Success", "Flash Poll Failure", "Flash Too Many Blocks", "MPU is too slow to erase all the blocks", "Flash Block selected is invalid", "Flash Program Failure", "Flash Address Offset Out Of Range", "Flash is of Wrong Type", "Flash Block Failed Erase", "Flash is Unprotected", "Flash is Protected", "Flash function not supported", "Flash Vpp Invalid", "Flash Erase Fail", "Flash Toggle Flow Chart Failure"}; /* Step 1: Check the error message range */ iErrNum = -iErrNum - 1; /* All errors are negative: make +ve & adjust */ if( iErrNum < 0 || iErrNum >= sizeof(str)/sizeof(str[0])) /* Check range */ return "Unknown Error\n"; /* Step 2: Return the correct string */ else return str[iErrNum]; } /******************************************************************************* List of Errors and Return values, Explanations and Help. ******************************************************************************** Return Name: Flash_SUCCESS Return Value: -1 Description: This value indicates that the flash command has executed correctly. ******************************************************************************** Error Name: Flash_POLL_FAIL Notes: The Data Polling Flow Chart, which applies to M29 series Flash only, is not used in this library. The function FlashDataPoll() is only provided as an illustration of the Data Polling Flow Chart. This error condition should not occur when using this library. Return Value: -2 Description: The Program/Erase Controller algorithm has not managed to complete the command operation successfully. This may be because the device is damaged Solution: Try the command again. If it fails a second time then it is likely that the device will need to be replaced. ******************************************************************************** Error Name: Flash_TOO_MANY_BLOCKS Notes: Applies to M29 series Flash only. Return Value: -3 Description: The user has chosen to erase more blocks than the device has. This may be because the array of blocks to erase contains the same block more than once. Solutions: Check that the program is trying to erase valid blocks. The device will only have NUM_BLOCKS blocks (defined at the top of the file). Also check that the same block has not been added twice or more to the array. ******************************************************************************** Error Name: Flash_MPU_TOO_SLOW Notes: Applies to M29 series Flash only. Return Value: -4 Description: The MPU has not managed to write all of the selected blocks to the device before the timeout period expired. See BLOCK ERASE COMMAND section of the Data Sheet for details. Solutions: If this occurs occasionally then it may be because an interrupt is occuring between writing the blocks to be erased. Search for "DSI!" in the code and disable interrupts during the time critical sections. If this error condition always occurs then it may be time for a faster microprocessor, a better optimising C compiler or, worse still, learn assembly. The immediate solution is to only erase one block at a time. Disable the test (by #define'ing out the code) and always call the function with one block at a time. ******************************************************************************** Error Name: Flash_BLOCK_INVALID Return Value: -5 Description: A request for an invalid block has been made. Valid blocks number from 0 to NUM_BLOCKS-1. Solution: Check that the block is in the valid range. ******************************************************************************** Error Name: Flash_PROGRAM_FAIL Return Value: -6 Description: The programmed value has not been programmed correctly. Solutions: Make sure that the block containing the value was erased before programming. Try erasing the block and re-programming the value. If it fails again then the device may need to be changed. ******************************************************************************** Error Name: Flash_OFFSET_OUT_OF_RANGE Return Value: -7 Description: The address offset given is out of the range of the device. Solution: Check that the address offset is in the valid range. ******************************************************************************** Error Name: Flash_WRONG_TYPE Return Value: -8 Description: The source code has been used to access the wrong type of flash. Solutions: Use a different flash chip with the target hardware or contact STMicroelectronics for a different source code library. ******************************************************************************** Error Name: Flash_BLOCK_FAILED_ERASE Notes: This error condition should not occur when using this library. Return Value: -9 Description: The previous erase to this block has not managed to successfully erase the block. Solution: Sadly the flash needs replacing. ******************************************************************************** Return Name: Flash_UNPROTECTED Notes: Applies to some M29 series Flash only. This condition should not occur when using this library. Return Value: -10 Description: The user has requested to unprotect a flash that is already unprotected or the user has requested to re-protect a flash that has no protected blocks. This is just a warning to the user that their operation did not make any changes and was not necessary. ******************************************************************************** Return Name: Flash_PROTECTED Notes: This condition should not occur when using this library. Return Value: -11 Description: The user has requested to protect a flash that is already protected. This is just a warning to the user that their operation did not make any changes and was not necessary. ******************************************************************************** Return Name: Flash_FUNCTION_NOT_SUPPORTED Notes: This condition should not occur when using this library. Return Value: -12 Description: The user has attempted to make use of functionality not available on this flash device (and thus not provided by the software drivers). This is simply a warning to the user. ******************************************************************************** Error Name: Flash_VPP_INVALID Notes: Applies to M28 series Flash only. This error condition should not occur when using this library. Return Value: -13 Description: A Program or a Block Erase has been attempted with the Vpp supply voltage outside the allowed ranges. This command had no effect since an invalid Vpp has the effect of protecting the whole of the flash device. Solution: The (hardware) configuration of Vpp will need to be modified to make programming or erasing the device possible. ******************************************************************************** Error Name: Flash_ERASE_FAIL Return Value: -14 Description: This indicates that the previous erasure of one block, many blocks or of the whole device has failed. Solution: Investigate this failure further by attempting to erase each block individually. If erasing a single block still causes failure, then the Flash sadly needs replacing. ******************************************************************************* Error Name: Flash_TOGGLE_FAIL Return Value: -15 Notes: This applies to M29 series Flash only. Description: The Program/Erase Controller algorithm has not managed to complete the command operation successfully. This may be because the device is damaged. Solution: Try the command again. If it fails a second time then it is likely that the device will need to be replaced. *******************************************************************************/ --------------000008090400050503010209 Content-Type: text/plain; name="c1191_08.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="c1191_08.h" /***c1191_08.h*Header File for c1191_08.c*************************************** Filename: c1191_08.h Description: Header file for c1191_08.c. Consult the C file for details Copyright (c) 1999 STMicroelectronics. THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. *******************************************************************************/ /******************************************************************************* Commands for the various functions *******************************************************************************/ #define FLASH_READ_MANUFACTURER (-2) #define FLASH_READ_DEVICE_CODE (-1) /******************************************************************************* Error Conditions and return values. See end of C file for explanations and help *******************************************************************************/ #define FLASH_BLOCK_PROTECTED (0x01) #define FLASH_BLOCK_UNPROTECTED (0x00) #define FLASH_BLOCK_NOT_ERASED (0xFF) #define FLASH_SUCCESS (-1) #define FLASH_POLL_FAIL (-2) #define FLASH_TOO_MANY_BLOCKS (-3) #define FLASH_MPU_TOO_SLOW (-4) #define FLASH_BLOCK_INVALID (-5) #define FLASH_PROGRAM_FAIL (-6) #define FLASH_OFFSET_OUT_OF_RANGE (-7) #define FLASH_WRONG_TYPE (-8) #define FLASH_ERASE_FAIL (-14) #define FLASH_TOGGLE_FAIL (-15) /******************************************************************************* Function Prototypes *******************************************************************************/ extern unsigned char FlashRead( unsigned long ulOff ); extern void FlashReadReset( void ); extern int FlashAutoSelect( int iFunc ); extern int FlashBlockErase( unsigned char ucNumBlocks, unsigned char ucBlock[]); extern int FlashChipErase( void ); extern int FlashProgram( unsigned long ulOff, size_t NumBytes, void *Array ); extern char *FlashErrorStr( int iErrNum ); --------------000008090400050503010209--
Reply by ●March 24, 20052005-03-24
> The two attached files were once published on the website of > STMicroelectronics (www.st.com) and contain library routines for the > M29F040B Flash Memory. >They are also "Copyright (c) 1999 STMicroelectronics". Does the license allow reproduction and publication? Or are you breaking the law?
Reply by ●March 24, 20052005-03-24
David Schmider schrieb:> risha schrieb: > >> need to know how to write data into external flash >> memory(offchip).using MCU MC9S12A128B and the external flash memory >> chip is M29F040B.Is there any special code to be sent to the external >> flash memory.Using a cpld chip number being CY37128P84 125 JC which is >> used for the selecting the external flash chip.Also using metrowerks >> code warrior and BDM Multilink. >> >> >> Thanks for any help, >> Ranjita > > > Hi Ranjita > > The two attached files were once published on the website of > STMicroelectronics (www.st.com) and contain library routines for the > M29F040B Flash Memory.... even more recent: http://www.st.com/stonline/books/pdf/docs/6887.pdf
Reply by ●March 24, 20052005-03-24
risha schrieb:> need to know how to write data into external flash > memory(offchip).using MCU MC9S12A128B and the external flash memory > chip is M29F040B.Is there any special code to be sent to the external > flash memory.Using a cpld chip number being CY37128P84 125 JC which is > used for the selecting the external flash chip.Also using metrowerks > code warrior and BDM Multilink. > > > Thanks for any help, > RanjitaHi Ranjita Here you will find the information you are looking for: http://www.st.com/stonline/books/pdf/docs/6887.pdf (There's even some C Code included)
Reply by ●March 24, 20052005-03-24
Dave schrieb:>>The two attached files were once published on the website of >>STMicroelectronics (www.st.com) and contain library routines for the >>M29F040B Flash Memory. >> > > They are also "Copyright (c) 1999 STMicroelectronics". Does the license > allow reproduction and publication? Or are you breaking the law? > >I'm sorry. Posting just the link might be more appropriate.
Reply by ●March 25, 20052005-03-25
ST produces device manual (http://www.st.com/stonline/books/pdf/docs/6580.pdf) and Application Notes with source code example ( http://www.st.com/stonline/books/pdf/docs/6887.pdf) on how to use that memory device. About ST SW Drivers, you can do whatever you want with that code as long as you keep the ST disclaimer in your code.
Reply by ●March 28, 20052005-03-28
David Schmider <david.schmider@gmx.ch> wrote in message news:<4242a0f3$1_3@news.bluewin.ch>...> risha schrieb: > > need to know how to write data into external flash > > memory(offchip).using MCU MC9S12A128B and the external flash memory > > chip is M29F040B.Is there any special code to be sent to the external > > flash memory.Using a cpld chip number being CY37128P84 125 JC which is > > used for the selecting the external flash chip.Also using metrowerks > > code warrior and BDM Multilink. > > > > > > Thanks for any help, > > Ranjita > > Hi Ranjita > > Here you will find the information you are looking for: > http://www.st.com/stonline/books/pdf/docs/6887.pdf > (There's even some C Code included)thanks everybody for the help but i have gone through the documents before i posted this mail but it did not write in the flash memory.So i had doubt when i was doin the right thing but it seems like i was right.So the memory location shows just ff so it does not take in the data i wonder why? could there be such that the external flash chip has gone bad if so how to check it?the document specifies that Check for correct flash type Step 2: Check the offset range is valid Step 3: Check that the block(s) to be programmed are not protected Step 4: While there is more to be programmed Step 5: Check for changes from �0' to �1' Step 6: Program the next byte one more thing flash was erased so condition has been met.so now what is that i could be not doing the right way? thanks for any help, ranjita
Reply by ●March 30, 20052005-03-30
In my group the first thing we do, it is to check the cfi capability of the flash. Try putting on the bus the "Auto select" command and verify the flash response is what you expect. You can try this also by putting the command directly in a debugger (if you have one). At least there is a first check whether it is a bus/interface problem or a broken flash.