This fork is necessary for the Starship code.

Fork of BSP_DISCO_F429ZI by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f429i_discovery_sdram.c Source File

stm32f429i_discovery_sdram.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f429i_discovery_sdram.c
00004   * @author  MCD Application Team
00005   * @version V2.1.5
00006   * @date    27-January-2017
00007   * @brief   This file provides a set of functions needed to drive the
00008   *          IS42S16400J SDRAM memory mounted on STM32F429I-Discovery Kit.    
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00013   *
00014   * Redistribution and use in source and binary forms, with or without modification,
00015   * are permitted provided that the following conditions are met:
00016   *   1. Redistributions of source code must retain the above copyright notice,
00017   *      this list of conditions and the following disclaimer.
00018   *   2. Redistributions in binary form must reproduce the above copyright notice,
00019   *      this list of conditions and the following disclaimer in the documentation
00020   *      and/or other materials provided with the distribution.
00021   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022   *      may be used to endorse or promote products derived from this software
00023   *      without specific prior written permission.
00024   *
00025   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035   *
00036   ******************************************************************************
00037   */
00038 
00039 /* Includes ------------------------------------------------------------------*/
00040 #include "stm32f429i_discovery_sdram.h"
00041 
00042 // mbed
00043 void wait_ms(int ms);
00044 
00045 /** @addtogroup BSP
00046   * @{
00047   */ 
00048 
00049 /** @addtogroup STM32F429I_DISCOVERY
00050   * @{
00051   */
00052   
00053 /** @defgroup STM32F429I_DISCOVERY_SDRAM STM32F429I DISCOVERY SDRAM
00054   * @{
00055 */ 
00056 
00057 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Types_Definitions STM32F429I DISCOVERY SDRAM Private Types Definitions
00058   * @{
00059   */
00060 /**
00061   * @}
00062   */ 
00063 
00064 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Defines STM32F429I DISCOVERY SDRAM Private Defines
00065   * @{
00066   */
00067 /**
00068   * @}
00069   */  
00070 
00071 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Macros STM32F429I DISCOVERY SDRAM Private Macros
00072   * @{
00073   */ 
00074 /**
00075   * @}
00076   */  
00077 
00078 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Variables STM32F429I DISCOVERY SDRAM Private Variables
00079   * @{
00080   */
00081 static SDRAM_HandleTypeDef SdramHandle;
00082 static FMC_SDRAM_TimingTypeDef Timing;
00083 static FMC_SDRAM_CommandTypeDef Command;
00084 /**
00085   * @}
00086   */ 
00087 
00088 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Function_Prototypes STM32F429I DISCOVERY SDRAM Private Function Prototypes
00089   * @{
00090   */ 
00091 /**
00092   * @}
00093   */
00094 
00095 /** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Functions STM32F429I DISCOVERY SDRAM Private Functions
00096   * @{
00097   */
00098 
00099 /**
00100   * @brief  Initializes the SDRAM device.
00101   */
00102 uint8_t BSP_SDRAM_Init(void)
00103 {
00104   static uint8_t sdramstatus = SDRAM_ERROR;
00105 
00106   /* SDRAM device configuration */
00107   SdramHandle.Instance = FMC_SDRAM_DEVICE;
00108 
00109   /* FMC Configuration -------------------------------------------------------*/
00110   /* FMC SDRAM Bank configuration */
00111   /* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */
00112   /* TMRD: 2 Clock cycles */
00113   Timing.LoadToActiveDelay    = 2;
00114   /* TXSR: min=70ns (7x11.11ns) */
00115   Timing.ExitSelfRefreshDelay = 7;
00116   /* TRAS: min=42ns (4x11.11ns) max=120k (ns) */
00117   Timing.SelfRefreshTime      = 4;
00118   /* TRC:  min=70 (7x11.11ns) */
00119   Timing.RowCycleDelay        = 7;
00120   /* TWR:  min=1+ 7ns (1+1x11.11ns) */
00121   Timing.WriteRecoveryTime    = 2;
00122   /* TRP:  20ns => 2x11.11ns*/
00123   Timing.RPDelay              = 2;
00124   /* TRCD: 20ns => 2x11.11ns */
00125   Timing.RCDDelay             = 2;
00126   
00127   /* FMC SDRAM control configuration */
00128   SdramHandle.Init.SDBank             = FMC_SDRAM_BANK2;
00129   /* Row addressing: [7:0] */
00130   SdramHandle.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;
00131   /* Column addressing: [11:0] */
00132   SdramHandle.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;
00133   SdramHandle.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;
00134   SdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
00135   SdramHandle.Init.CASLatency         = SDRAM_CAS_LATENCY;
00136   SdramHandle.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
00137   SdramHandle.Init.SDClockPeriod      = SDCLOCK_PERIOD;
00138   SdramHandle.Init.ReadBurst          = SDRAM_READBURST;
00139   SdramHandle.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_1;
00140                     
00141   /* SDRAM controller initialization */
00142   /* __weak function can be surcharged by the application code */
00143   BSP_SDRAM_MspInit(&SdramHandle, (void *)NULL);
00144   if(HAL_SDRAM_Init(&SdramHandle, &Timing) != HAL_OK)
00145   {
00146     sdramstatus = SDRAM_ERROR;
00147   }
00148   else
00149   {
00150     sdramstatus = SDRAM_OK;
00151   }
00152   
00153   /* SDRAM initialization sequence */
00154   BSP_SDRAM_Initialization_sequence(REFRESH_COUNT);
00155   
00156   return sdramstatus;
00157 }
00158 
00159 /**
00160   * @brief  Programs the SDRAM device.
00161   * @param  RefreshCount: SDRAM refresh counter value 
00162   */
00163 void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount)
00164 {
00165   __IO uint32_t tmpmrd =0;
00166   
00167   /* Step 1:  Configure a clock configuration enable command */
00168   Command.CommandMode             = FMC_SDRAM_CMD_CLK_ENABLE;
00169   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00170   Command.AutoRefreshNumber       = 1;
00171   Command.ModeRegisterDefinition  = 0;
00172 
00173   /* Send the command */
00174   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
00175 
00176   /* Step 2: Insert 100 us minimum delay */ 
00177   /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
00178   //HAL_Delay(1);
00179   wait_ms(1);
00180   
00181   /* Step 3: Configure a PALL (precharge all) command */ 
00182   Command.CommandMode             = FMC_SDRAM_CMD_PALL;
00183   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00184   Command.AutoRefreshNumber       = 1;
00185   Command.ModeRegisterDefinition  = 0;
00186 
00187   /* Send the command */
00188   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);  
00189   
00190   /* Step 4: Configure an Auto Refresh command */ 
00191   Command.CommandMode             = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
00192   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00193   Command.AutoRefreshNumber       = 4;
00194   Command.ModeRegisterDefinition  = 0;
00195 
00196   /* Send the command */
00197   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
00198   
00199   /* Step 5: Program the external memory mode register */
00200   tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
00201                      SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |
00202                      SDRAM_MODEREG_CAS_LATENCY_3           |
00203                      SDRAM_MODEREG_OPERATING_MODE_STANDARD |
00204                      SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
00205   
00206   Command.CommandMode             = FMC_SDRAM_CMD_LOAD_MODE;
00207   Command.CommandTarget           = FMC_SDRAM_CMD_TARGET_BANK2;
00208   Command.AutoRefreshNumber       = 1;
00209   Command.ModeRegisterDefinition  = tmpmrd;
00210 
00211   /* Send the command */
00212   HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT);
00213   
00214   /* Step 6: Set the refresh rate counter */
00215   /* Set the device refresh rate */
00216   HAL_SDRAM_ProgramRefreshRate(&SdramHandle, RefreshCount); 
00217 }
00218 
00219 /**
00220   * @brief  Reads an mount of data from the SDRAM memory in polling mode. 
00221   * @param  uwStartAddress : Read start address
00222   * @param  pData : Pointer to data to be read  
00223   * @param  uwDataSize: Size of read data from the memory
00224   */
00225 uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
00226 {
00227   if(HAL_SDRAM_Read_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00228   {
00229     return SDRAM_ERROR;
00230   }
00231   else
00232   {
00233     return SDRAM_OK;
00234   }  
00235 }
00236 
00237 /**
00238   * @brief  Reads an mount of data from the SDRAM memory in DMA mode. 
00239   * @param  uwStartAddress : Read start address
00240   * @param  pData : Pointer to data to be read  
00241   * @param  uwDataSize: Size of read data from the memory
00242   */
00243 uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00244 {
00245   if(HAL_SDRAM_Read_DMA(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00246   {
00247     return SDRAM_ERROR;
00248   }
00249   else
00250   {
00251     return SDRAM_OK;
00252   }        
00253 }
00254   
00255 /**
00256   * @brief  Writes an mount of data to the SDRAM memory in polling mode.
00257   * @param  uwStartAddress : Write start address
00258   * @param  pData : Pointer to data to be written  
00259   * @param  uwDataSize: Size of written data from the memory
00260   */
00261 uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00262 {
00263   /* Disable write protection */
00264   HAL_SDRAM_WriteProtection_Disable(&SdramHandle);
00265   
00266   /*Write 32-bit data buffer to SDRAM memory*/
00267   if(HAL_SDRAM_Write_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00268   {
00269     return SDRAM_ERROR;
00270   }
00271   else
00272   {
00273     return SDRAM_OK;
00274   }  
00275 }
00276 
00277 /**
00278   * @brief  Writes an mount of data to the SDRAM memory in DMA mode.
00279   * @param  uwStartAddress : Write start address
00280   * @param  pData : Pointer to data to be written  
00281   * @param  uwDataSize: Size of written data from the memory
00282   */
00283 uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) 
00284 {
00285   if(HAL_SDRAM_Write_DMA(&SdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
00286   {
00287     return SDRAM_ERROR;
00288   }
00289   else
00290   {
00291     return SDRAM_OK;
00292   }   
00293 }
00294 
00295 /**
00296   * @brief  Sends command to the SDRAM bank.
00297   * @param  SdramCmd: Pointer to SDRAM command structure 
00298   * @retval HAL status
00299   */  
00300 uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)
00301 {
00302   if(HAL_SDRAM_SendCommand(&SdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)
00303   {
00304     return SDRAM_ERROR;
00305   }
00306   else
00307   {
00308     return SDRAM_OK;
00309   }
00310 }
00311 
00312 /**
00313   * @brief  Handles SDRAM DMA transfer interrupt request.
00314   */
00315 void BSP_SDRAM_DMA_IRQHandler(void)
00316 {
00317   HAL_DMA_IRQHandler(SdramHandle.hdma); 
00318 }
00319 
00320 /**
00321   * @brief  Initializes SDRAM MSP.
00322   * @note   This function can be surcharged by application code.
00323   * @param  hsdram: pointer on SDRAM handle
00324   * @param  Params: pointer on additional configuration parameters, can be NULL.
00325   */
00326 __weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00327 {
00328   static DMA_HandleTypeDef dmaHandle;
00329   GPIO_InitTypeDef GPIO_InitStructure;
00330 
00331   if(hsdram != (SDRAM_HandleTypeDef  *)NULL)
00332   {
00333   /* Enable FMC clock */
00334   __HAL_RCC_FMC_CLK_ENABLE();
00335 
00336   /* Enable chosen DMAx clock */
00337   __DMAx_CLK_ENABLE();
00338 
00339   /* Enable GPIOs clock */
00340   __HAL_RCC_GPIOB_CLK_ENABLE();
00341   __HAL_RCC_GPIOC_CLK_ENABLE();
00342   __HAL_RCC_GPIOD_CLK_ENABLE();
00343   __HAL_RCC_GPIOE_CLK_ENABLE();
00344   __HAL_RCC_GPIOF_CLK_ENABLE();
00345   __HAL_RCC_GPIOG_CLK_ENABLE();
00346                             
00347 /*-- GPIOs Configuration -----------------------------------------------------*/
00348 /*
00349  +-------------------+--------------------+--------------------+--------------------+
00350  +                       SDRAM pins assignment                                      +
00351  +-------------------+--------------------+--------------------+--------------------+
00352  | PD0  <-> FMC_D2   | PE0  <-> FMC_NBL0  | PF0  <-> FMC_A0    | PG0  <-> FMC_A10   |
00353  | PD1  <-> FMC_D3   | PE1  <-> FMC_NBL1  | PF1  <-> FMC_A1    | PG1  <-> FMC_A11   |
00354  | PD8  <-> FMC_D13  | PE7  <-> FMC_D4    | PF2  <-> FMC_A2    | PG8  <-> FMC_SDCLK |
00355  | PD9  <-> FMC_D14  | PE8  <-> FMC_D5    | PF3  <-> FMC_A3    | PG15 <-> FMC_NCAS  |
00356  | PD10 <-> FMC_D15  | PE9  <-> FMC_D6    | PF4  <-> FMC_A4    |--------------------+ 
00357  | PD14 <-> FMC_D0   | PE10 <-> FMC_D7    | PF5  <-> FMC_A5    |   
00358  | PD15 <-> FMC_D1   | PE11 <-> FMC_D8    | PF11 <-> FMC_NRAS  | 
00359  +-------------------| PE12 <-> FMC_D9    | PF12 <-> FMC_A6    | 
00360                      | PE13 <-> FMC_D10   | PF13 <-> FMC_A7    |    
00361                      | PE14 <-> FMC_D11   | PF14 <-> FMC_A8    |
00362                      | PE15 <-> FMC_D12   | PF15 <-> FMC_A9    |
00363  +-------------------+--------------------+--------------------+
00364  | PB5 <-> FMC_SDCKE1| 
00365  | PB6 <-> FMC_SDNE1 | 
00366  | PC0 <-> FMC_SDNWE |
00367  +-------------------+  
00368   
00369 */
00370   
00371   /* Common GPIO configuration */
00372   GPIO_InitStructure.Mode  = GPIO_MODE_AF_PP;
00373   GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
00374   GPIO_InitStructure.Pull  = GPIO_NOPULL;
00375   GPIO_InitStructure.Alternate = GPIO_AF12_FMC;
00376 
00377   /* GPIOB configuration */
00378   GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_6;
00379   HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);  
00380 
00381   /* GPIOC configuration */
00382   GPIO_InitStructure.Pin = GPIO_PIN_0;      
00383   HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);  
00384   
00385   /* GPIOD configuration */
00386   GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1  | GPIO_PIN_8 |
00387                            GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 |
00388                            GPIO_PIN_15;
00389   HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
00390 
00391   /* GPIOE configuration */
00392   GPIO_InitStructure.Pin = GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_7 |
00393                            GPIO_PIN_8  | GPIO_PIN_9  | GPIO_PIN_10 |
00394                            GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
00395                            GPIO_PIN_14 | GPIO_PIN_15;
00396   HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
00397 
00398   /* GPIOF configuration */
00399   GPIO_InitStructure.Pin = GPIO_PIN_0  | GPIO_PIN_1 | GPIO_PIN_2 | 
00400                            GPIO_PIN_3  | GPIO_PIN_4 | GPIO_PIN_5 |
00401                            GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
00402                            GPIO_PIN_14 | GPIO_PIN_15;
00403   HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
00404 
00405   /* GPIOG configuration */
00406   GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 |
00407                            GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
00408   HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
00409 
00410   /* Configure common DMA parameters */
00411   dmaHandle.Init.Channel             = SDRAM_DMAx_CHANNEL;
00412   dmaHandle.Init.Direction           = DMA_MEMORY_TO_MEMORY;
00413   dmaHandle.Init.PeriphInc           = DMA_PINC_ENABLE;
00414   dmaHandle.Init.MemInc              = DMA_MINC_ENABLE;
00415   dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
00416   dmaHandle.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
00417   dmaHandle.Init.Mode                = DMA_NORMAL;
00418   dmaHandle.Init.Priority            = DMA_PRIORITY_HIGH;
00419   dmaHandle.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
00420   dmaHandle.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00421   dmaHandle.Init.MemBurst            = DMA_MBURST_SINGLE;
00422   dmaHandle.Init.PeriphBurst         = DMA_PBURST_SINGLE; 
00423   
00424   dmaHandle.Instance = SDRAM_DMAx_STREAM;
00425   
00426   /* Associate the DMA handle */
00427   __HAL_LINKDMA(hsdram, hdma, dmaHandle);
00428   
00429   /* Deinitialize the stream for new transfer */
00430   HAL_DMA_DeInit(&dmaHandle);
00431   
00432   /* Configure the DMA stream */
00433   HAL_DMA_Init(&dmaHandle); 
00434   
00435   /* NVIC configuration for DMA transfer complete interrupt */
00436   HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 0x0F, 0);
00437   HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
00438   } /* of if(hsdram != (SDRAM_HandleTypeDef  *)NULL) */
00439 }
00440 
00441 /**
00442   * @brief  DeInitializes SDRAM MSP.
00443   * @note   This function can be surcharged by application code.
00444   * @param  hsdram: pointer on SDRAM handle
00445   * @param  Params: pointer on additional configuration parameters, can be NULL.
00446   */
00447 __weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef  *hsdram, void *Params)
00448 {
00449     static DMA_HandleTypeDef dma_handle;
00450 
00451     if(hsdram != (SDRAM_HandleTypeDef  *)NULL)
00452     {
00453       /* Disable NVIC configuration for DMA interrupt */
00454       HAL_NVIC_DisableIRQ(SDRAM_DMAx_IRQn);
00455 
00456       /* Deinitialize the stream for new transfer */
00457       dma_handle.Instance = SDRAM_DMAx_STREAM;
00458       HAL_DMA_DeInit(&dma_handle);
00459 
00460       /* DeInit GPIO pins can be done in the application
00461        (by surcharging this __weak function) */
00462 
00463       /* GPIO pins clock, FMC clock and DMA clock can be shut down in the application
00464        by surcharging this __weak function */
00465 
00466     } /* of if(hsdram != (SDRAM_HandleTypeDef  *)NULL) */
00467 }
00468 
00469 /**
00470   * @}
00471   */
00472 
00473 /**
00474   * @}
00475   */
00476 
00477 /**
00478   * @}
00479   */
00480 
00481 /**
00482   * @}
00483   */
00484 
00485 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/