Esempio n. 1
0
/*******************************************************************************
* Function Name  : NAND_Read
* Description    : Read sectors
* Input          : None
* Output         : None
* Return         : Status
*******************************************************************************/
uint16_t NAND_Read(uint32_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length)
{
  NAND_ADDRESS phAddress;

  
  phAddress    = NAND_GetAddress(Memory_Offset / NAND_PAGE_SIZE);
 

  if (phAddress.Zone != CurrentZone)
  {
    CurrentZone = phAddress.Zone;
    NAND_BuildLUT(CurrentZone);
  }

  if (LUT [phAddress.Block] & BAD_BLOCK)
  {
    return NAND_FAIL;
  }
  else
  {
    phAddress.Block = LUT [phAddress.Block] & ~ (USED_BLOCK | VALID_BLOCK);
    FSMC_NAND_ReadSmallPage ( (uint8_t *)Readbuff , phAddress, Transfer_Length / NAND_PAGE_SIZE);
  }
  return NAND_OK;
}
Esempio n. 2
0
/*******************************************************************************
* Function Name  : NAND_Write
* Description    : write one sector by once
* Input          : None
* Output         : None
* Return         : Status
*******************************************************************************/
uint16_t NAND_Write(uint32_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)
{
  char rdBuff[NAND_PAGE_SIZE];
  int index;
  /* check block status and calculate start and end addreses */
  wAddress    = NAND_GetAddress(Memory_Offset / NAND_PAGE_SIZE);

  printf("\r\nwrite ok\r\n");

  /*check Zone: if second zone is requested build second LUT*/
  if (wAddress.Zone != CurrentZone)
  {
      CurrentZone = wAddress.Zone;
      NAND_BuildLUT(CurrentZone);
  }

  phBlock     = LUT[wAddress.Block]; /* Block Index + flags */
  LogAddress  = wAddress.Block ; /* save logical block */

  /*  IDLE state  */
  /****************/
  if ( Write_State == WRITE_IDLE)
  {/* Idle state */

    if (phBlock & USED_BLOCK)
    { /* USED BLOCK */

      Block_State = OLD_BLOCK;
      /* Get a free Block for swap */
      fAddress.Block = NAND_GetFreeBlock();
      fAddress.Zone  = wAddress.Zone;
      Initial_Page = fAddress.Page  = wAddress.Page;

      /* write the new page */
      FSMC_NAND_WriteSmallPage((uint8_t *)Writebuff, fAddress, PAGE_TO_WRITE);
      Written_Pages++;

      /* get physical block */
      wAddress.Block = phBlock & 0x3FF;


      if (Written_Pages == SCSI_BlkLen)
      {
          NAND_Write_Cleanup();
          Written_Pages = 0;
          return NAND_OK;
      }
      else
      {
        if (wAddress.Page == (NAND_BLOCK_SIZE - 1))
        {
            NAND_Write_Cleanup();
            return NAND_OK;
        }
        Write_State = WRITE_ONGOING;
        return NAND_OK;
      }
    }
    else
    {/* UNUSED BLOCK */

      Block_State = UNUSED_BLOCK;
      /* write the new page */
      wAddress.Block = phBlock & 0x3FF;
      FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , wAddress, PAGE_TO_WRITE);

      Written_Pages++;
      if (Written_Pages == SCSI_BlkLen)
      {
          Written_Pages = 0;
          NAND_Write_Cleanup();
          return NAND_OK;
      }
      else
      {
          Write_State = WRITE_ONGOING;
          return NAND_OK;
      }
    }
  }
  /* WRITE state */
  /***************/
  if ( Write_State == WRITE_ONGOING)
  {/* Idle state */
    if (phBlock & USED_BLOCK)
    { /* USED BLOCK */

      wAddress.Block = phBlock & 0x3FF;
      Block_State = OLD_BLOCK;
      fAddress.Page  = wAddress.Page;

      /* check if next pages are in next block */
      if (wAddress.Page == (NAND_BLOCK_SIZE - 1))
      {
        /* write Last page  */
        FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , fAddress, PAGE_TO_WRITE);
        Written_Pages++;
        if (Written_Pages == SCSI_BlkLen)
        {
          Written_Pages = 0;
        }
        /* Clean up and Update the LUT */
        NAND_Write_Cleanup();
        Write_State = WRITE_IDLE;
        return NAND_OK;
      }

      /* write next page */
      FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , fAddress, PAGE_TO_WRITE);
      Written_Pages++;
      if (Written_Pages == SCSI_BlkLen)
      {
        Write_State = WRITE_IDLE;
        NAND_Write_Cleanup();
        Written_Pages = 0;
      }

    }
    else
    {/* UNUSED BLOCK */
      wAddress.Block = phBlock & 0x3FF;
      /* check if it is the last page in prev block */
      if (wAddress.Page == (NAND_BLOCK_SIZE - 1))
      {
        /* write Last page  */
        FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , wAddress, PAGE_TO_WRITE);
        Written_Pages++;
        if (Written_Pages == SCSI_BlkLen)
        {
          Written_Pages = 0;
        }

        /* Clean up and Update the LUT */
        NAND_Write_Cleanup();
        Write_State = WRITE_IDLE;


        return NAND_OK;
      }
      /* write next page in same block */
      FSMC_NAND_WriteSmallPage( (uint8_t *)Writebuff , wAddress, PAGE_TO_WRITE);
      Written_Pages++;
      if (Written_Pages == SCSI_BlkLen)
      {
        Write_State = WRITE_IDLE;
        NAND_Write_Cleanup();
        Written_Pages = 0;
      }
    }
  }
  return NAND_OK;
}
Esempio n. 3
0
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /* STM32F103xG HAL library initialization:
       - Configure the Flash prefetch
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
  HAL_Init();

  /* Configure LED1, LED2 and LED3 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED2);
  BSP_LED_Init(LED3);

  /* Configure the system clock to 72 MHz */
  SystemClock_Config();

  /*##-1- Configure the NAND device ##########################################*/
  /* NAND device configuration */
  nandHandle.Instance  = FSMC_NAND_DEVICE;
  
  /*NAND Configuration */  
  NAND_Timing.SetupTime     = 0;
  NAND_Timing.WaitSetupTime = 2; 
  NAND_Timing.HoldSetupTime = 1;
  NAND_Timing.HiZSetupTime  = 0;
  
  nandHandle.Init.NandBank        = FSMC_NAND_BANK2;
  nandHandle.Init.Waitfeature     = FSMC_NAND_PCC_WAIT_FEATURE_ENABLE;
  nandHandle.Init.MemoryDataWidth = FSMC_NAND_PCC_MEM_BUS_WIDTH_8;
  nandHandle.Init.EccComputation  = FSMC_NAND_ECC_ENABLE;
  nandHandle.Init.ECCPageSize     = FSMC_NAND_ECC_PAGE_SIZE_512BYTE;
  nandHandle.Init.TCLRSetupTime   = 0;
  nandHandle.Init.TARSetupTime    = 0;
  
  nandHandle.Info.BlockNbr      = NAND_MAX_ZONE;
  nandHandle.Info.BlockSize     = NAND_BLOCK_SIZE;
  nandHandle.Info.ZoneSize      = NAND_ZONE_SIZE;
  nandHandle.Info.PageSize      = NAND_PAGE_SIZE; 
  nandHandle.Info.SpareAreaSize = NAND_SPARE_AREA_SIZE;
  
  /* Initialize the NAND controller */
  if(HAL_NAND_Init(&nandHandle, &NAND_Timing, &NAND_Timing) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /* Read NAND memory ID */
  if(HAL_NAND_Read_ID(&nandHandle, &NAND_Id) != HAL_OK)
  {
    /* NAND read ID Error */
    Error_Handler();
  }

   /* Test the NAND ID correctness */
  if((NAND_Id.Maker_Id != NAND_ST_MAKERID) || (NAND_Id.Device_Id != NAND_ST_DEVICEID))
  {
    /* NAND ID not correct */
    Error_Handler();
  }
  
  /*##-2- Convert Address to NAND address#######################################*/ 
  NAND_GetAddress(WRITE_READ_ADDR, &NAND_Address);
  
  /*##-3- Erase NAND memory ###################################################*/ 
  if(HAL_NAND_Erase_Block(&nandHandle, &NAND_Address) != HAL_OK)
  {
    Error_Handler();
  }
  
  /*##-4- NAND memory read/write access  ######################################*/   
  /* Fill the buffer to write */
  Fill_Buffer(nand_aTxBuffer, BUFFER_SIZE, 0xD210);   
  
  /* Write data to the NAND memory */
  if(HAL_NAND_Write_Page(&nandHandle, &NAND_Address, nand_aTxBuffer, NB_PAGE) != HAL_OK)
  {
    Error_Handler();
  }
  
  /* Read back data from the NAND memory */
  if(HAL_NAND_Read_Page(&nandHandle, &NAND_Address, nand_aRxBuffer, NB_PAGE) != HAL_OK)
  {
    Error_Handler();
  }

  /*##-3- Checking data integrity ############################################*/
  if(Buffercmp(nand_aTxBuffer, nand_aRxBuffer, BUFFER_SIZE) != PASSED)
  {
    /* KO */
    /* Turn on LED2 */
    BSP_LED_On(LED2);
  }
  else
  {
    /* OK */
    /* Turn on LED1 */
    BSP_LED_On(LED1);
  }

  /* Infinite loop */
  while (1)
  {
  }
}