stm3210e_eval_fsmc_nor.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm3210e_eval_fsmc_nor.c
00004   * @author  MCD Application Team
00005   * @version V4.3.0
00006   * @date    10/15/2010
00007   * @brief   This file provides a set of functions needed to drive the M29W128FL, 
00008   *          M29W128GL and S29GL128P NOR memories mounted on STM3210E-EVAL board.
00009   ******************************************************************************
00010   * @copy
00011   *
00012   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00013   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00014   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00015   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00016   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00017   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00018   *
00019   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
00020   */ 
00021 
00022 /* Includes ------------------------------------------------------------------*/
00023 #include "stm3210e_eval_fsmc_nor.h"
00024 
00025 /** @addtogroup Utilities
00026   * @{
00027   */
00028   
00029 /** @addtogroup STM32_EVAL
00030   * @{
00031   */ 
00032 
00033 /** @addtogroup STM3210E_EVAL
00034   * @{
00035   */
00036   
00037 /** @addtogroup STM3210E_EVAL_FSMC_NOR
00038   * @brief      This file provides a set of functions needed to drive the M29W128FL, 
00039   *             M29W128GL and S29GL128P NOR memories mounted on STM3210E-EVAL board.
00040   * @{
00041   */ 
00042 
00043 /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Types
00044   * @{
00045   */ 
00046 /**
00047   * @}
00048   */ 
00049 
00050 /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Defines
00051   * @{
00052   */ 
00053 /** 
00054   * @brief  FSMC Bank 1 NOR/SRAM2  
00055   */
00056 #define Bank1_NOR2_ADDR       ((uint32_t)0x64000000)
00057 
00058 /* Delay definition */   
00059 #define BlockErase_Timeout    ((uint32_t)0x00A00000)
00060 #define ChipErase_Timeout     ((uint32_t)0x30000000) 
00061 #define Program_Timeout       ((uint32_t)0x00001400)     
00062 /**
00063   * @}
00064   */ 
00065 
00066 
00067 /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Macros
00068   * @{
00069   */
00070 #define ADDR_SHIFT(A) (Bank1_NOR2_ADDR + (2 * (A)))
00071 #define NOR_WRITE(Address, Data)  (*(__IO uint16_t *)(Address) = (Data))  
00072 /**
00073   * @}
00074   */ 
00075   
00076 
00077 /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Variables
00078   * @{
00079   */ 
00080 /**
00081   * @}
00082   */ 
00083 
00084 
00085 /** @defgroupSTM3210E_EVAL_FSMC_NOR_Private_Function_Prototypes
00086   * @{
00087   */ 
00088 /**
00089   * @}
00090   */ 
00091 
00092 
00093 /** @defgroup STM3210E_EVAL_FSMC_NOR_Private_Functions
00094   * @{
00095   */
00096 
00097 /**
00098   * @brief  Configures the FSMC and GPIOs to interface with the NOR memory.
00099   *         This function must be called before any write/read operation
00100   *         on the NOR.
00101   * @param  None
00102   * @retval None
00103   */
00104 void NOR_Init(void)
00105 {
00106   FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
00107   FSMC_NORSRAMTimingInitTypeDef  p;
00108   GPIO_InitTypeDef GPIO_InitStructure;
00109 
00110   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | 
00111                          RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
00112 
00113   /*-- GPIO Configuration ------------------------------------------------------*/
00114   /*!< NOR Data lines configuration */
00115   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
00116                                 GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
00117   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
00118   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
00119   GPIO_Init(GPIOD, &GPIO_InitStructure);
00120 
00121   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
00122                                 GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 |
00123                                 GPIO_Pin_14 | GPIO_Pin_15;
00124   GPIO_Init(GPIOE, &GPIO_InitStructure);
00125 
00126   /*!< NOR Address lines configuration */
00127   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
00128                                 GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_12 | GPIO_Pin_13 |
00129                                 GPIO_Pin_14 | GPIO_Pin_15;
00130   GPIO_Init(GPIOF, &GPIO_InitStructure);
00131 
00132   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |
00133                                 GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
00134   GPIO_Init(GPIOG, &GPIO_InitStructure);
00135 
00136   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
00137   GPIO_Init(GPIOD, &GPIO_InitStructure);
00138 
00139   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
00140   GPIO_Init(GPIOE, &GPIO_InitStructure);
00141 
00142   /*!< NOE and NWE configuration */
00143   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
00144   GPIO_Init(GPIOD, &GPIO_InitStructure);
00145 
00146   /*!< NE2 configuration */
00147   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
00148   GPIO_Init(GPIOG, &GPIO_InitStructure);
00149 
00150   /*!< Configure PD6 for NOR memory Ready/Busy signal */
00151   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
00152   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
00153   GPIO_Init(GPIOD, &GPIO_InitStructure);
00154   
00155   /*-- FSMC Configuration ----------------------------------------------------*/
00156   p.FSMC_AddressSetupTime = 0x02;
00157   p.FSMC_AddressHoldTime = 0x00;
00158   p.FSMC_DataSetupTime = 0x05;
00159   p.FSMC_BusTurnAroundDuration = 0x00;
00160   p.FSMC_CLKDivision = 0x00;
00161   p.FSMC_DataLatency = 0x00;
00162   p.FSMC_AccessMode = FSMC_AccessMode_B;
00163 
00164   FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
00165   FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
00166   FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
00167   FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
00168   FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
00169   FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;  
00170   FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
00171   FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
00172   FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
00173   FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
00174   FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
00175   FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
00176   FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
00177   FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
00178   FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
00179 
00180   FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
00181 
00182   /*!< Enable FSMC Bank1_NOR Bank */
00183   FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
00184 }
00185 
00186 /**
00187   * @brief  Reads NOR memory's Manufacturer and Device Code.
00188   * @param  NOR_ID: pointer to a NOR_IDTypeDef structure which will hold the 
00189   *         Manufacturer and Device Code.  
00190   * @retval None
00191   */
00192 void NOR_ReadID(NOR_IDTypeDef* NOR_ID)
00193 {
00194   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
00195   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
00196   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0090);
00197 
00198   NOR_ID->Manufacturer_Code = *(__IO uint16_t *) ADDR_SHIFT(0x0000);
00199   NOR_ID->Device_Code1 = *(__IO uint16_t *) ADDR_SHIFT(0x0001);
00200   NOR_ID->Device_Code2 = *(__IO uint16_t *) ADDR_SHIFT(0x000E);
00201   NOR_ID->Device_Code3 = *(__IO uint16_t *) ADDR_SHIFT(0x000F);
00202 }
00203 
00204 /**
00205   * @brief  Erases the specified Nor memory block.
00206   * @param  BlockAddr: address of the block to erase.
00207   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
00208   *         or NOR_TIMEOUT
00209   */
00210 NOR_Status NOR_EraseBlock(uint32_t BlockAddr)
00211 {
00212   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
00213   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
00214   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);
00215   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
00216   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
00217   NOR_WRITE((Bank1_NOR2_ADDR + BlockAddr), 0x30);
00218 
00219   return (NOR_GetStatus(BlockErase_Timeout));
00220 }
00221 
00222 /**
00223   * @brief  Erases the entire chip.
00224   * @param  None                      
00225   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
00226   *         or NOR_TIMEOUT
00227   */
00228 NOR_Status NOR_EraseChip(void)
00229 {
00230   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
00231   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
00232   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);
00233   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
00234   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
00235   NOR_WRITE(ADDR_SHIFT(0x0555), 0x0010);
00236 
00237   return (NOR_GetStatus(ChipErase_Timeout));
00238 }
00239 
00240 /**
00241   * @brief  Writes a half-word to the NOR memory.
00242   * @param  WriteAddr: NOR memory internal address to write to.
00243   * @param  Data: Data to write. 
00244   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
00245   *         or NOR_TIMEOUT
00246   */
00247 NOR_Status NOR_WriteHalfWord(uint32_t WriteAddr, uint16_t Data)
00248 {
00249   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
00250   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
00251   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00A0);
00252   NOR_WRITE((Bank1_NOR2_ADDR + WriteAddr), Data);
00253 
00254   return (NOR_GetStatus(Program_Timeout));
00255 }
00256 
00257 /**
00258   * @brief  Writes a half-word buffer to the FSMC NOR memory. 
00259   * @param  pBuffer: pointer to buffer. 
00260   * @param  WriteAddr: NOR memory internal address from which the data will be 
00261   *         written.
00262   * @param  NumHalfwordToWrite: number of Half words to write. 
00263   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
00264   *         or NOR_TIMEOUT
00265   */
00266 NOR_Status NOR_WriteBuffer(uint16_t* pBuffer, uint32_t WriteAddr, uint32_t NumHalfwordToWrite)
00267 {
00268   NOR_Status status = NOR_ONGOING; 
00269 
00270   do
00271   {
00272     /*!< Transfer data to the memory */
00273     status = NOR_WriteHalfWord(WriteAddr, *pBuffer++);
00274     WriteAddr = WriteAddr + 2;
00275     NumHalfwordToWrite--;
00276   }
00277   while((status == NOR_SUCCESS) && (NumHalfwordToWrite != 0));
00278   
00279   return (status); 
00280 }
00281 
00282 /**
00283   * @brief  Writes a half-word buffer to the FSMC NOR memory. This function 
00284   *         must be used only with S29GL128P NOR memory.
00285   * @param  pBuffer: pointer to buffer. 
00286   * @param  WriteAddr: NOR memory internal address from which the data will be 
00287   *         written.
00288   * @param  NumHalfwordToWrite: number of Half words to write.
00289   *         The maximum allowed value is 32 Half words (64 bytes).
00290   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
00291   *         or NOR_TIMEOUT
00292   */
00293 NOR_Status NOR_ProgramBuffer(uint16_t* pBuffer, uint32_t WriteAddr, uint32_t NumHalfwordToWrite)
00294 {
00295   uint32_t lastloadedaddress = 0x00;
00296   uint32_t currentaddress = 0x00;
00297   uint32_t endaddress = 0x00;
00298 
00299   /*!< Initialize variables */
00300   currentaddress = WriteAddr;
00301   endaddress = WriteAddr + NumHalfwordToWrite - 1;
00302   lastloadedaddress = WriteAddr;
00303 
00304   /*!< Issue unlock command sequence */
00305   NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
00306 
00307   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);  
00308 
00309   /*!< Write Write Buffer Load Command */
00310   NOR_WRITE(ADDR_SHIFT(WriteAddr), 0x0025);
00311   NOR_WRITE(ADDR_SHIFT(WriteAddr), (NumHalfwordToWrite - 1));
00312 
00313   /*!< Load Data into NOR Buffer */
00314   while(currentaddress <= endaddress)
00315   {
00316     /*!< Store last loaded address & data value (for polling) */
00317     lastloadedaddress = currentaddress;
00318  
00319     NOR_WRITE(ADDR_SHIFT(currentaddress), *pBuffer++);
00320     currentaddress += 1; 
00321   }
00322 
00323   NOR_WRITE(ADDR_SHIFT(lastloadedaddress), 0x29);
00324   
00325   return(NOR_GetStatus(Program_Timeout));
00326 }
00327 
00328 /**
00329   * @brief  Reads a half-word from the NOR memory. 
00330   * @param  ReadAddr: NOR memory internal address to read from.
00331   * @retval Half-word read from the NOR memory
00332   */
00333 uint16_t NOR_ReadHalfWord(uint32_t ReadAddr)
00334 {
00335   NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA); 
00336   NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);  
00337   NOR_WRITE((Bank1_NOR2_ADDR + ReadAddr), 0x00F0 );
00338 
00339   return (*(__IO uint16_t *)((Bank1_NOR2_ADDR + ReadAddr)));
00340 }
00341 
00342 /**
00343   * @brief  Reads a block of data from the FSMC NOR memory.
00344   * @param  pBuffer: pointer to the buffer that receives the data read from the 
00345   *         NOR memory.
00346   * @param  ReadAddr: NOR memory internal address to read from.
00347   * @param  NumHalfwordToRead : number of Half word to read.
00348   * @retval None
00349   */
00350 void NOR_ReadBuffer(uint16_t* pBuffer, uint32_t ReadAddr, uint32_t NumHalfwordToRead)
00351 {
00352   NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
00353   NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
00354   NOR_WRITE((Bank1_NOR2_ADDR + ReadAddr), 0x00F0);
00355 
00356   for(; NumHalfwordToRead != 0x00; NumHalfwordToRead--) /*!< while there is data to read */
00357   {
00358     /*!< Read a Halfword from the NOR */
00359     *pBuffer++ = *(__IO uint16_t *)((Bank1_NOR2_ADDR + ReadAddr));
00360     ReadAddr = ReadAddr + 2; 
00361   }  
00362 }
00363 
00364 /**
00365   * @brief  Returns the NOR memory to Read mode.
00366   * @param  None
00367   * @retval NOR_SUCCESS
00368   */
00369 NOR_Status NOR_ReturnToReadMode(void)
00370 {
00371   NOR_WRITE(Bank1_NOR2_ADDR, 0x00F0);
00372 
00373   return (NOR_SUCCESS);
00374 }
00375 
00376 /**
00377   * @brief  Returns the NOR memory to Read mode and resets the errors in the NOR 
00378   *         memory Status Register.  
00379   * @param  None
00380   * @retval NOR_SUCCESS
00381   */
00382 NOR_Status NOR_Reset(void)
00383 {
00384   NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA); 
00385   NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055); 
00386   NOR_WRITE(Bank1_NOR2_ADDR, 0x00F0); 
00387 
00388   return (NOR_SUCCESS);
00389 }
00390 
00391 /**
00392   * @brief  Returns the NOR operation status.
00393   * @param  Timeout: NOR progamming Timeout
00394   * @retval NOR_Status: The returned value can be: NOR_SUCCESS, NOR_ERROR
00395   *         or NOR_TIMEOUT
00396   */
00397 NOR_Status NOR_GetStatus(uint32_t Timeout)
00398 { 
00399   uint16_t val1 = 0x00, val2 = 0x00;
00400   NOR_Status status = NOR_ONGOING; 
00401   uint32_t timeout = Timeout;
00402 
00403   /*!< Poll on NOR memory Ready/Busy signal ----------------------------------*/
00404   while((GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) != RESET) && (timeout > 0)) 
00405   {
00406     timeout--;
00407   }
00408 
00409   timeout = Timeout;
00410   
00411   while((GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == RESET) && (timeout > 0))   
00412   {
00413     timeout--;
00414   }
00415   
00416   /*!< Get the NOR memory operation status -----------------------------------*/
00417   while((Timeout != 0x00) && (status != NOR_SUCCESS))
00418   {
00419     Timeout--;
00420 
00421     /*!< Read DQ6 and DQ5 */
00422     val1 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
00423     val2 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
00424 
00425     /*!< If DQ6 did not toggle between the two reads then return NOR_Success */
00426     if((val1 & 0x0040) == (val2 & 0x0040)) 
00427     {
00428       return NOR_SUCCESS;
00429     }
00430 
00431     if((val1 & 0x0020) != 0x0020)
00432     {
00433       status = NOR_ONGOING;
00434     }
00435 
00436     val1 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
00437     val2 = *(__IO uint16_t *)(Bank1_NOR2_ADDR);
00438     
00439     if((val1 & 0x0040) == (val2 & 0x0040)) 
00440     {
00441       return NOR_SUCCESS;
00442     }
00443     else if((val1 & 0x0020) == 0x0020)
00444     {
00445       return NOR_ERROR;
00446     }
00447   }
00448 
00449   if(Timeout == 0x00)
00450   {
00451     status = NOR_TIMEOUT;
00452   } 
00453 
00454   /*!< Return the operation status */
00455   return (status);
00456 }
00457 
00458 /**
00459   * @}
00460   */
00461 
00462 /**
00463   * @}
00464   */
00465 
00466 /**
00467   * @}
00468   */
00469 
00470 /**
00471   * @}
00472   */
00473 
00474 /**
00475   * @}
00476   */  
00477 
00478 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
STM32F10x Standard Peripherals Library: Footer

 

 

 

      For complete documentation on STM32(CORTEX M3) 32-bit Microcontrollers platform visit  www.st.com/STM32