[STM32F7] stm32F7 驱动 nand flash

[复制链接]
1715|19
 楼主| hanzhen654 发表于 2020-3-25 19:55 | 显示全部楼层 |阅读模式

执行NAND内存初始化序列
  1. HAL_StatusTypeDef  HAL_NAND_Init(NAND_HandleTypeDef *hnand, FMC_NAND_PCC_TimingTypeDef *ComSpace_Timing, FMC_NAND_PCC_TimingTypeDef *AttSpace_Timing)
  2. {
  3.   /* Check the NAND handle state */
  4.   if(hnand == NULL)
  5.   {
  6.      return HAL_ERROR;
  7.   }

  8.   if(hnand->State == HAL_NAND_STATE_RESET)
  9.   {
  10.     /* Allocate lock resource and initialize it */
  11.     hnand->Lock = HAL_UNLOCKED;
  12.     /* Initialize the low level hardware (MSP) */
  13.     HAL_NAND_MspInit(hnand);
  14.   }

  15.   /* Initialize NAND control Interface */
  16.   FMC_NAND_Init(hnand->Instance, &(hnand->Init));
  17.   
  18.   /* Initialize NAND common space timing Interface */  
  19.   FMC_NAND_CommonSpace_Timing_Init(hnand->Instance, ComSpace_Timing, hnand->Init.NandBank);
  20.   
  21.   /* Initialize NAND attribute space timing Interface */  
  22.   FMC_NAND_AttributeSpace_Timing_Init(hnand->Instance, AttSpace_Timing, hnand->Init.NandBank);
  23.   
  24.   /* Enable the NAND device */
  25.   __FMC_NAND_ENABLE(hnand->Instance);
  26.   
  27.   /* Update the NAND controller state */
  28.   hnand->State = HAL_NAND_STATE_READY;

  29.   return HAL_OK;
  30. }


 楼主| hanzhen654 发表于 2020-3-25 19:56 | 显示全部楼层
执行NAND内存取消初始化序列
  1. HAL_StatusTypeDef HAL_NAND_DeInit(NAND_HandleTypeDef *hnand)  
  2. {
  3.   /* Initialize the low level hardware (MSP) */
  4.   HAL_NAND_MspDeInit(hnand);

  5.   /* Configure the NAND registers with their reset values */
  6.   FMC_NAND_DeInit(hnand->Instance, hnand->Init.NandBank);

  7.   /* Reset the NAND controller state */
  8.   hnand->State = HAL_NAND_STATE_RESET;

  9.   /* Release Lock */
  10.   __HAL_UNLOCK(hnand);

  11.   return HAL_OK;
  12. }


 楼主| hanzhen654 发表于 2020-3-25 19:57 | 显示全部楼层
NAND MSP 初始化
  1. __weak void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
  2. {
  3.   /* Prevent unused argument(s) compilation warning */
  4.   UNUSED(hnand);
  5.   
  6.   /* NOTE : This function Should not be modified, when the callback is needed,
  7.             the HAL_NAND_MspInit could be implemented in the user file
  8.    */
  9. }


 楼主| hanzhen654 发表于 2020-3-25 19:59 | 显示全部楼层
Nand 设备中断
  1. void HAL_NAND_IRQHandler(NAND_HandleTypeDef *hnand)
  2. {
  3.   /* Check NAND interrupt Rising edge flag */
  4.   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_RISING_EDGE))
  5.   {
  6.     /* NAND interrupt callback*/
  7.     HAL_NAND_ITCallback(hnand);
  8.   
  9.     /* Clear NAND interrupt Rising edge pending bit */
  10.     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_RISING_EDGE);
  11.   }
  12.   
  13.   /* Check NAND interrupt Level flag */
  14.   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_LEVEL))
  15.   {
  16.     /* NAND interrupt callback*/
  17.     HAL_NAND_ITCallback(hnand);
  18.   
  19.     /* Clear NAND interrupt Level pending bit */
  20.     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_LEVEL);
  21.   }

  22.   /* Check NAND interrupt Falling edge flag */
  23.   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FALLING_EDGE))
  24.   {
  25.     /* NAND interrupt callback*/
  26.     HAL_NAND_ITCallback(hnand);
  27.   
  28.     /* Clear NAND interrupt Falling edge pending bit */
  29.     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FALLING_EDGE);
  30.   }
  31.   
  32.   /* Check NAND interrupt FIFO empty flag */
  33.   if(__FMC_NAND_GET_FLAG(hnand->Instance, hnand->Init.NandBank, FMC_FLAG_FEMPT))
  34.   {
  35.     /* NAND interrupt callback*/
  36.     HAL_NAND_ITCallback(hnand);
  37.   
  38.     /* Clear NAND interrupt FIFO empty pending bit */
  39.     __FMC_NAND_CLEAR_FLAG(hnand->Instance, FMC_FLAG_FEMPT);
  40.   }  

  41. }


 楼主| hanzhen654 发表于 2020-3-25 20:00 | 显示全部楼层
nand 中断回调
  1. __weak void HAL_NAND_ITCallback(NAND_HandleTypeDef *hnand)
  2. {
  3.   /* Prevent unused argument(s) compilation warning */
  4.   UNUSED(hnand);
  5.   
  6.   /* NOTE : This function Should not be modified, when the callback is needed,
  7.             the HAL_NAND_ITCallback could be implemented in the user file
  8.    */
  9. }


 楼主| hanzhen654 发表于 2020-3-25 20:09 | 显示全部楼层

读取NAND存储器电子签名
  1. HAL_StatusTypeDef HAL_NAND_Read_ID(NAND_HandleTypeDef *hnand, NAND_IDTypeDef *pNAND_ID)
  2. {
  3.   __IO uint32_t data = 0;
  4.   __IO uint32_t data1 = 0;
  5.   uint32_t deviceAddress = 0;

  6.   /* Process Locked */
  7.   __HAL_LOCK(hnand);  
  8.   
  9.   /* Check the NAND controller state */
  10.   if(hnand->State == HAL_NAND_STATE_BUSY)
  11.   {
  12.     return HAL_BUSY;
  13.   }
  14.   
  15.   /* Identify the device address */
  16.   deviceAddress = NAND_DEVICE;
  17.   
  18.   /* Update the NAND controller state */
  19.   hnand->State = HAL_NAND_STATE_BUSY;
  20.   
  21.   /* Send Read ID command sequence */        
  22.   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_READID;
  23.   __DSB();
  24.   *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  25.   __DSB();

  26.   /* Read the electronic signature from NAND flash */
  27.   if (hnand->Init.MemoryDataWidth == FMC_NAND_PCC_MEM_BUS_WIDTH_8)
  28.   {
  29.     data = *(__IO uint32_t *)deviceAddress;

  30.     /* Return the data read */
  31.     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
  32.     pNAND_ID->Device_Id  = ADDR_2ND_CYCLE(data);
  33.     pNAND_ID->Third_Id   = ADDR_3RD_CYCLE(data);
  34.     pNAND_ID->Fourth_Id  = ADDR_4TH_CYCLE(data);
  35.   }
  36.   else
  37.   {
  38.     data = *(__IO uint32_t *)deviceAddress;
  39.     data1 = *((__IO uint32_t *)deviceAddress + 4);
  40.    
  41.     /* Return the data read */
  42.     pNAND_ID->Maker_Id   = ADDR_1ST_CYCLE(data);
  43.     pNAND_ID->Device_Id  = ADDR_3RD_CYCLE(data);
  44.     pNAND_ID->Third_Id   = ADDR_1ST_CYCLE(data1);
  45.     pNAND_ID->Fourth_Id  = ADDR_3RD_CYCLE(data1);
  46.   }

  47.   /* Update the NAND controller state */
  48.   hnand->State = HAL_NAND_STATE_READY;
  49.   
  50.   /* Process unlocked */
  51.   __HAL_UNLOCK(hnand);   
  52.    
  53.   return HAL_OK;
  54. }



 楼主| hanzhen654 发表于 2020-3-25 20:11 | 显示全部楼层
nand flash 复位
  1. HAL_StatusTypeDef HAL_NAND_Reset(NAND_HandleTypeDef *hnand)
  2. {
  3.   uint32_t deviceAddress = 0;
  4.   
  5.   /* Process Locked */
  6.   __HAL_LOCK(hnand);
  7.    
  8.   /* Check the NAND controller state */
  9.   if(hnand->State == HAL_NAND_STATE_BUSY)
  10.   {
  11.      return HAL_BUSY;
  12.   }

  13.   /* Identify the device address */  
  14.   deviceAddress = NAND_DEVICE;
  15.   
  16.   /* Update the NAND controller state */   
  17.   hnand->State = HAL_NAND_STATE_BUSY;
  18.   
  19.   /* Send NAND reset command */  
  20.   *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = 0xFF;

  21.   /* Update the NAND controller state */   
  22.   hnand->State = HAL_NAND_STATE_READY;
  23.   
  24.   /* Process unlocked */
  25.   __HAL_UNLOCK(hnand);   
  26.   
  27.   return HAL_OK;
  28.   
  29. }


 楼主| hanzhen654 发表于 2020-3-25 20:11 | 显示全部楼层
初始化nand 设备
  1. HAL_StatusTypeDef  HAL_NAND_ConfigDevice(NAND_HandleTypeDef *hnand, NAND_DeviceConfigTypeDef *pDeviceConfig)
  2. {
  3.   hnand->Config.PageSize           = pDeviceConfig->PageSize;
  4.   hnand->Config.SpareAreaSize      = pDeviceConfig->SpareAreaSize;
  5.   hnand->Config.BlockSize          = pDeviceConfig->BlockSize;
  6.   hnand->Config.BlockNbr           = pDeviceConfig->BlockNbr;
  7.   hnand->Config.PlaneSize          = pDeviceConfig->PlaneSize;
  8.   hnand->Config.PlaneNbr           = pDeviceConfig->PlaneNbr;
  9.   hnand->Config.ExtraCommandEnable = pDeviceConfig->ExtraCommandEnable;
  10.   
  11.   return HAL_OK;
  12. }


 楼主| hanzhen654 发表于 2020-3-25 20:12 | 显示全部楼层
nand 读页操作 8bit
  1. HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
  2. {
  3.   __IO uint32_t index  = 0;
  4.   uint32_t tickstart = 0U;
  5.   uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
  6.   
  7.   /* Process Locked */
  8.   __HAL_LOCK(hnand);
  9.   
  10.   /* Check the NAND controller state */
  11.   if(hnand->State == HAL_NAND_STATE_BUSY)
  12.   {
  13.      return HAL_BUSY;
  14.   }
  15.   
  16.   /* Identify the device address */
  17.   deviceAddress = NAND_DEVICE;

  18.   /* Update the NAND controller state */
  19.   hnand->State = HAL_NAND_STATE_BUSY;
  20.   
  21.   /* NAND raw address calculation */
  22.   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  23.   
  24.   /* Page(s) read loop */  
  25.   while((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  26.   {
  27.     /* update the buffer size */
  28.     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
  29.    
  30.     /* Send read page command sequence */
  31.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  32.     __DSB();
  33.    
  34.     /* Cards with page size <= 512 bytes */
  35.     if((hnand->Config.PageSize) <= 512)
  36.     {
  37.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  38.       {
  39.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  40.         __DSB();
  41.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  42.         __DSB();
  43.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  44.         __DSB();
  45.       }
  46.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  47.       {
  48.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  49.         __DSB();
  50.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  51.         __DSB();
  52.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  53.         __DSB();
  54.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  55.         __DSB();
  56.       }
  57.     }
  58.     else /* (hnand->Config.PageSize) > 512 */
  59.     {
  60.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  61.       {
  62.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  63.         __DSB();
  64.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  65.         __DSB();
  66.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  67.         __DSB();
  68.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  69.         __DSB();
  70.       }
  71.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  72.       {
  73.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  74.         __DSB();
  75.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  76.         __DSB();
  77.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  78.         __DSB();
  79.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  80.         __DSB();
  81.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  82.         __DSB();
  83.       }
  84.     }

  85.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
  86.     __DSB();
  87.    
  88.    
  89.     if(hnand->Config.ExtraCommandEnable == ENABLE)
  90.     {
  91.       /* Get tick */
  92.       tickstart = HAL_GetTick();
  93.       
  94.       /* Read status until NAND is ready */
  95.       while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  96.       {
  97.         if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  98.         {
  99.           return HAL_TIMEOUT;
  100.         }
  101.       }
  102.       
  103.       /* Go back to read mode */
  104.       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
  105.       __DSB();
  106.     }
  107.    
  108.     /* Get Data into Buffer */   
  109.     for(; index < size; index++)
  110.     {
  111.       *(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
  112.     }
  113.    
  114.     /* Increment read pages number */
  115.     numPagesRead++;
  116.    
  117.     /* Decrement pages to read */
  118.     NumPageToRead--;
  119.    
  120.     /* Increment the NAND address */
  121.     nandAddress = (uint32_t)(nandAddress + 1);
  122.   }
  123.   
  124.   /* Update the NAND controller state */
  125.   hnand->State = HAL_NAND_STATE_READY;
  126.   
  127.   /* Process unlocked */
  128.   __HAL_UNLOCK(hnand);  
  129.    
  130.   return HAL_OK;

  131. }


 楼主| hanzhen654 发表于 2020-3-25 20:14 | 显示全部楼层
nand flash 页操作,16bit
  1. HAL_StatusTypeDef HAL_NAND_Read_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToRead)
  2. {   
  3.   __IO uint32_t index  = 0;
  4.   uint32_t tickstart = 0;
  5.   uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
  6.   
  7.   /* Process Locked */
  8.   __HAL_LOCK(hnand);
  9.   
  10.   /* Check the NAND controller state */
  11.   if(hnand->State == HAL_NAND_STATE_BUSY)
  12.   {
  13.      return HAL_BUSY;
  14.   }
  15.   
  16.   /* Identify the device address */
  17.   deviceAddress = NAND_DEVICE;

  18.   /* Update the NAND controller state */
  19.   hnand->State = HAL_NAND_STATE_BUSY;
  20.   
  21.   /* NAND raw address calculation */
  22.   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  23.   
  24.   /* Page(s) read loop */  
  25.   while((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  26.   {          
  27.     /* update the buffer size */
  28.     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
  29.    
  30.     /* Send read page command sequence */
  31.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;  
  32.     __DSB();
  33.    
  34.     /* Cards with page size <= 512 bytes */
  35.     if((hnand->Config.PageSize) <= 512)
  36.     {
  37.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  38.       {
  39.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  40.         __DSB();
  41.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  42.         __DSB();
  43.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  44.         __DSB();
  45.       }
  46.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  47.       {
  48.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  49.         __DSB();
  50.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  51.         __DSB();
  52.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  53.         __DSB();
  54.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  55.         __DSB();
  56.       }
  57.     }
  58.     else /* (hnand->Config.PageSize) > 512 */
  59.     {
  60.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  61.       {
  62.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  63.         __DSB();
  64.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  65.         __DSB();
  66.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  67.         __DSB();
  68.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  69.         __DSB();
  70.       }
  71.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  72.       {
  73.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  74.         __DSB();
  75.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  76.         __DSB();
  77.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  78.         __DSB();
  79.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  80.         __DSB();
  81.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  82.         __DSB();
  83.       }
  84.     }
  85.   
  86.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA))  = NAND_CMD_AREA_TRUE1;
  87.     __DSB();
  88.    
  89.     if(hnand->Config.ExtraCommandEnable == ENABLE)
  90.     {
  91.       /* Get tick */
  92.       tickstart = HAL_GetTick();
  93.       
  94.       /* Read status until NAND is ready */
  95.       while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  96.       {
  97.         if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  98.         {
  99.           return HAL_TIMEOUT;
  100.         }
  101.       }
  102.       
  103.       /* Go back to read mode */
  104.       *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
  105.       __DSB();
  106.     }
  107.    
  108.     /* Get Data into Buffer */   
  109.     for(; index < size; index++)
  110.     {
  111.       *(uint16_t *)pBuffer++ = *(uint16_t *)deviceAddress;
  112.     }
  113.    
  114.     /* Increment read pages number */
  115.     numPagesRead++;
  116.    
  117.     /* Decrement pages to read */
  118.     NumPageToRead--;
  119.    
  120.     /* Increment the NAND address */
  121.     nandAddress = (uint32_t)(nandAddress + 1);
  122.   }
  123.   
  124.   /* Update the NAND controller state */
  125.   hnand->State = HAL_NAND_STATE_READY;
  126.   
  127.   /* Process unlocked */
  128.   __HAL_UNLOCK(hnand);  
  129.    
  130.   return HAL_OK;
  131. }


 楼主| hanzhen654 发表于 2020-3-25 20:17 | 显示全部楼层
nand 写页操作 ,8bit
  1. HAL_StatusTypeDef HAL_NAND_Write_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToWrite)
  2. {
  3.   __IO uint32_t index = 0;
  4.   uint32_t tickstart = 0;
  5.   uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
  6.   
  7.   /* Process Locked */
  8.   __HAL_LOCK(hnand);  

  9.   /* Check the NAND controller state */
  10.   if(hnand->State == HAL_NAND_STATE_BUSY)
  11.   {
  12.      return HAL_BUSY;
  13.   }
  14.   
  15.   /* Identify the device address */
  16.   deviceAddress = NAND_DEVICE;
  17.   
  18.   /* Update the NAND controller state */
  19.   hnand->State = HAL_NAND_STATE_BUSY;
  20.   
  21.   /* NAND raw address calculation */
  22.   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  23.   
  24.   /* Page(s) write loop */
  25.   while((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  26.   {  
  27.     /* update the buffer size */
  28.     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);

  29.     /* Send write page command sequence */
  30.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  31.     __DSB();
  32.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  33.     __DSB();

  34.     /* Cards with page size <= 512 bytes */
  35.     if((hnand->Config.PageSize) <= 512)
  36.     {
  37.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  38.       {
  39.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  40.         __DSB();
  41.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  42.         __DSB();
  43.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  44.         __DSB();
  45.       }
  46.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  47.       {
  48.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  49.         __DSB();
  50.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  51.         __DSB();
  52.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  53.         __DSB();
  54.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  55.         __DSB();
  56.       }
  57.     }
  58.     else /* (hnand->Config.PageSize) > 512 */
  59.     {
  60.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  61.       {
  62.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  63.         __DSB();
  64.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  65.         __DSB();
  66.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  67.         __DSB();
  68.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  69.         __DSB();
  70.       }
  71.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  72.       {
  73.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  74.         __DSB();
  75.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  76.         __DSB();
  77.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  78.         __DSB();
  79.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  80.         __DSB();
  81.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  82.         __DSB();
  83.       }
  84.     }
  85.    
  86.     /* Write data to memory */
  87.     for(; index < size; index++)
  88.     {
  89.       *(__IO uint8_t *)deviceAddress = *(uint8_t *)pBuffer++;
  90.       __DSB();
  91.     }
  92.    
  93.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  94.     __DSB();
  95.    
  96.     /* Read status until NAND is ready */
  97.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  98.     {
  99.       /* Get tick */
  100.       tickstart = HAL_GetTick();
  101.    
  102.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  103.       {
  104.         return HAL_TIMEOUT;
  105.       }
  106.     }   

  107.     /* Increment written pages number */
  108.     numPagesWritten++;
  109.    
  110.     /* Decrement pages to write */
  111.     NumPageToWrite--;
  112.    
  113.     /* Increment the NAND address */
  114.     nandAddress = (uint32_t)(nandAddress + 1);
  115.   }
  116.   
  117.   /* Update the NAND controller state */
  118.   hnand->State = HAL_NAND_STATE_READY;
  119.   
  120.   /* Process unlocked */
  121.   __HAL_UNLOCK(hnand);      
  122.   
  123.   return HAL_OK;
  124. }


 楼主| hanzhen654 发表于 2020-3-25 20:18 | 显示全部楼层
nand 写页操作,16bit
  1. HAL_StatusTypeDef HAL_NAND_Write_Page_16b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint16_t *pBuffer, uint32_t NumPageToWrite)
  2. {
  3.   __IO uint32_t index = 0;
  4.   uint32_t tickstart = 0;
  5.   uint32_t deviceAddress = 0, size = 0, numPagesWritten = 0, nandAddress = 0;
  6.   
  7.   /* Process Locked */
  8.   __HAL_LOCK(hnand);  

  9.   /* Check the NAND controller state */
  10.   if(hnand->State == HAL_NAND_STATE_BUSY)
  11.   {
  12.      return HAL_BUSY;
  13.   }
  14.   
  15.   /* Identify the device address */
  16.   deviceAddress = NAND_DEVICE;
  17.   
  18.   /* Update the NAND controller state */
  19.   hnand->State = HAL_NAND_STATE_BUSY;
  20.   
  21.   /* NAND raw address calculation */
  22.   nandAddress = ARRAY_ADDRESS(pAddress, hnand);
  23.   
  24.   /* Page(s) write loop */
  25.   while((NumPageToWrite != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
  26.   {
  27.     /* update the buffer size */
  28.     size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesWritten);

  29.     /* Send write page command sequence */
  30.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
  31.     __DSB();
  32.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE0;
  33.     __DSB();

  34.     /* Cards with page size <= 512 bytes */
  35.     if((hnand->Config.PageSize) <= 512)
  36.     {
  37.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  38.       {
  39.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  40.         __DSB();
  41.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  42.         __DSB();
  43.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  44.         __DSB();
  45.       }
  46.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  47.       {
  48.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  49.         __DSB();
  50.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  51.         __DSB();
  52.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  53.         __DSB();
  54.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  55.         __DSB();
  56.       }
  57.     }
  58.     else /* (hnand->Config.PageSize) > 512 */
  59.     {
  60.       if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
  61.       {
  62.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  63.         __DSB();
  64.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  65.         __DSB();
  66.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  67.         __DSB();
  68.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  69.         __DSB();
  70.       }
  71.       else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
  72.       {
  73.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  74.         __DSB();
  75.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
  76.         __DSB();
  77.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
  78.         __DSB();
  79.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
  80.         __DSB();
  81.         *(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
  82.         __DSB();
  83.       }
  84.     }
  85.   
  86.     /* Write data to memory */
  87.     for(; index < size; index++)
  88.     {
  89.       *(__IO uint16_t *)deviceAddress = *(uint16_t *)pBuffer++;
  90.       __DSB();
  91.     }
  92.    
  93.     *(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
  94.     __DSB();
  95.    
  96.     /* Read status until NAND is ready */
  97.     while(HAL_NAND_Read_Status(hnand) != NAND_READY)
  98.     {
  99.       /* Get tick */
  100.       tickstart = HAL_GetTick();
  101.    
  102.       if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
  103.       {
  104.         return HAL_TIMEOUT;
  105.       }
  106.     }   

  107.     /* Increment written pages number */
  108.     numPagesWritten++;
  109.    
  110.     /* Decrement pages to write */
  111.     NumPageToWrite--;
  112.    
  113.     /* Increment the NAND address */
  114.     nandAddress = (uint32_t)(nandAddress + 1);
  115.   }
  116.   
  117.   /* Update the NAND controller state */
  118.   hnand->State = HAL_NAND_STATE_READY;
  119.   
  120.   /* Process unlocked */
  121.   __HAL_UNLOCK(hnand);      
  122.   
  123.   return HAL_OK;
  124. }


wowu 发表于 2020-4-7 14:28 | 显示全部楼层
这是调用的库函数吗
xiaoqizi 发表于 2020-4-7 14:29 | 显示全部楼层
结构很清晰
磨砂 发表于 2020-4-7 14:29 | 显示全部楼层
能用在f4上吗
 楼主| hanzhen654 发表于 2020-4-11 14:54 | 显示全部楼层
wowu 发表于 2020-4-7 14:28
这是调用的库函数吗

是啊,是用的库函数
 楼主| hanzhen654 发表于 2020-4-11 14:54 | 显示全部楼层

可以的,修改一下就可以了
 楼主| hanzhen654 发表于 2020-4-11 14:55 | 显示全部楼层

主要是驱动部分得清晰啊
隐去 发表于 2021-8-27 12:38 | 显示全部楼层
结构很清晰
koala889 发表于 2021-8-27 17:48 | 显示全部楼层
电子签名这个,我打算试试
您需要登录后才可以回帖 登录 | 注册

本版积分规则

73

主题

1766

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部