예제 #1
0
OT_WEAK ot_u8  vprom_write(vaddr addr, ot_u16 value) {
/// 1. Resolve actual address from virtual address -- simple
/// 2. If the address is at the start of the block, erase the block
/// 3. Write the value to the place it must go
#if (VPROM_SIZE <= 0)
    return ~0;
#else
    static ot_u32   word;       // storage for word-write using halfwords
    ot_u32          paddr;
    FLASH_Status    err;
    ot_int          offset;
    
    err     = FLASH_COMPLETE;
    paddr   = _vprom_base + addr;
    
    // STM32L0 uses 128 byte flash pages.  Erase page if on page-start address
    if ((paddr & (FLASH_PAGE_SIZE-1)) == 0) {
        err = FLASH_Erase_Page(paddr);
    }
    
    offset = (paddr & 2);
    *(((ot_u8*)&word) + offset) = value;
    
    // Prepare the word and write it, but only when a full word is supplied
    // We also do unlocking and locking immediately around the write, because 
    // there is some importance in protecting flash memory.
    if (offset != 0) {
        FLASH->PRGKEYR  = FLASH_PRGKEY1;
        FLASH->PRGKEYR  = FLASH_PRGKEY2;  
        err             = FLASH_Program_Word(paddr, word);
        FLASH->PECR    |= FLASH_PECR_PRGLOCK;
    }
    
    return err;
#endif
}
예제 #2
0
/**
  * @brief This function handles FLASH interrupt request.
  * @param  None
  * @retval None
  */
void HAL_FLASH_IRQHandler(void)
{
  uint32_t temp;
  
  /* If the program operation is completed, disable the PROG Bit */
  FLASH->PECR &= (~FLASH_PECR_PROG);

  /* If the erase operation is completed, disable the ERASE Bit */
  FLASH->PECR &= (~FLASH_PECR_ERASE);

  /* Check FLASH End of Operation flag  */
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
  {
    if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
    {
      /*Nb of sector to erased can be decreased*/
      pFlash.NbPagesToErase--;

      /* Check if there are still sectors to erase*/
      if(pFlash.NbPagesToErase != 0)
      {
        temp = pFlash.Page;
        /*Indicate user which sector has been erased*/
        HAL_FLASH_EndOfOperationCallback(temp);

        /* Clear pending flags (if any) */  
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_ENDHV | FLASH_FLAG_WRPERR |\
                              FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR| FLASH_FLAG_OPTVERR |\
                              FLASH_FLAG_RDERR  | FLASH_FLAG_NOTZEROERR);  

        /*Increment sector number*/
        temp = pFlash.Page + PAGESIZE;
        pFlash.Page = pFlash.Page + PAGESIZE;
        FLASH_Erase_Page(temp);
      }
      else
      {
        /*No more sectors to Erase, user callback can be called.*/
        /*Reset Sector and stop Erase sectors procedure*/
        pFlash.Page = temp = 0xFFFFFFFF;
        pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(temp);
        /* Clear FLASH End of Operation pending bit */
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
      }
    }
    else 
    {
      if(pFlash.ProcedureOnGoing  == FLASH_PROC_PROGRAM)
      {
        /*Program ended. Return the selected address*/
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(pFlash.Address);
      }
      pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
      /* Clear FLASH End of Operation pending bit */
      __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
    }

  }
  /* Check FLASH operation error flags */
  if( (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ENDHV) != RESET) || \
      (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)|| (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET) || \
      (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR) != RESET)|| (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) != RESET) || \
      (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) != RESET))
  {
    if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
    {
      /*return the faulty sector*/
      temp = pFlash.Page;
      pFlash.Page = 0xFFFFFFFF;
    }
    else
    {
      /*retrun the faulty address*/
      temp = pFlash.Address;
    }
    
    /*Save the Error code*/
    FLASH_SetErrorCode();

    /* FLASH error interrupt user callback */
    HAL_FLASH_OperationErrorCallback(temp);
    /* Clear FLASH error pending bits */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_ENDHV | FLASH_FLAG_WRPERR |\
                           FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR| FLASH_FLAG_OPTVERR |\
                           FLASH_FLAG_RDERR  | FLASH_FLAG_NOTZEROERR);

    /*Stop the procedure ongoing*/
    pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
  }
  
  if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
  {
    /* Disable End of FLASH Operation interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);

    /* Disable Error source interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);

    /* Process Unlocked */
    __HAL_UNLOCK(&pFlash);
  }
    
}