/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors,  any
 * reproduction,  modification,  use or disclosure of AutoChips Software,  and
 * information contained herein,  in whole or in part,  shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2018. All rights reserved.
 *
 * BY OPENING THIS FILE,  RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES,  EXPRESS OR IMPLIED,  INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, 
 * INCORPORATED IN,  OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE,  AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE,  AT AUTOCHIPS'S OPTION,  TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE,  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */
/*
 *@version 1.1.0
 */

/*************<start>******************/

/**************************************
本实验实现将flash操作相关函数放到sram，
然后在main函数里面调用flash操作函数
***************************************/ 

/*************<include>****************/
#include "ac780x.h"   
#include "ac780x_gpio.h"
#include "ac780x_debugout.h"
#include "status.h"
#include "flash.h"
#include "string.h"
/*************<macro>******************/
#define TestAddressStart    0x08010000
#define TestPageNum         ((TestAddressStart - 0x08000000)/2048)
#define TestSize            0x1000  ///<4K


#define flashDriverStartAdd      0x20004000  ///<eflash driver start addr
/*************<enum>*******************/


/*************<union>******************/


/*************<struct>*****************/
typedef void (* flash_callback_t)(void);
typedef struct
{
    uint32_t PFlashBase;          /*!< The base address of P-Flash memory */
    uint32_t PFlashSize;          /*!< The size in byte of P-Flash memory */
    uint32_t DFlashBase;          /*!< For FlexNVM device, this is the base address of D-Flash memory (FlexNVM memory);
                                   *    For non-FlexNVM device, this field is unused */
    uint32_t DFlashSize;          /*!< For FlexNVM device, this is the size in byte of area
                                   *    which is used as D-Flash from FlexNVM memory;
                                   *    For non-FlexNVM device, this field is unused */
    uint32_t EERAMBase;           /*!< The base address of FlexRAM (for FlexNVM device)
                                   *    or acceleration RAM memory (for non-FlexNVM device) */
    uint32_t EEESize;             /*!< For FlexNVM device, this is the size in byte of EEPROM area which was partitioned
                                   *    from FlexRAM; For non-FlexNVM device, this field is unused */
    flash_callback_t CallBack;    /*!< Call back function to service the time critical events. Any code reachable from this function
                                   *   must not be placed in a Flash block targeted for a program/erase operation */
} flash_ssd_config_t;

typedef struct
{
    status_t (*FLASH_EraseAllBlock)(const flash_ssd_config_t * pSSDConfig);
    status_t (*FLASH_VerifyAllBlock)(const flash_ssd_config_t * pSSDConfig,uint8_t marginLevel);
    status_t (*FLASH_EraseSector)(const flash_ssd_config_t * pSSDConfig,uint32_t dest,uint32_t size);
    status_t (*FLASH_VerifySection)(const flash_ssd_config_t * pSSDConfig,uint32_t dest,uint16_t number,uint8_t marginLevel);
    void (*FLASH_EraseSuspend)(void);
    void (*FLASH_EraseResume)(void);
    status_t (*FLASH_Program)(const flash_ssd_config_t * pSSDConfig,uint32_t dest, uint32_t size,const uint8_t * pData);
    status_t (*FLASH_ProgramCheck)(const flash_ssd_config_t * pSSDConfig,uint32_t dest,uint32_t size,const uint8_t * pExpectedData,uint32_t * pFailAddr,uint8_t marginLevel);
    status_t (*FLASH_ProgramSection)(const flash_ssd_config_t * pSSDConfig,uint32_t dest,uint16_t number);
    status_t (*FLASH_EraseBlock)(const flash_ssd_config_t * pSSDConfig, uint32_t dest);
    status_t (*FLASH_CommandSequence)(const flash_ssd_config_t * pSSDConfig);
    status_t (*FLASH_VerifyBlock)(const flash_ssd_config_t * pSSDConfig,uint32_t dest,uint8_t marginLevel);
} tFlashOptInfo;

/*************<variable>***************/
uint32_t wBuff[512];
tFlashOptInfo *g_pstFlashOptInfo = (void *)0;
/*************<prototype>**************/

/**
* @prototype main(void)
*
* @param[in] void
* @return	 void
*
* @brief  	 实现eflash的option byte操作
*/
int main(void)
{
    uint16_t i;
    uint32_t * tmp = 0;
    
    InitDebug();
    InitDelay();
    
    
    memset((uint8_t *)flashDriverStartAdd, 0, sizeof(data));
    memcpy((uint8_t *)flashDriverStartAdd, data, sizeof(data));  /*copy driver*/
    tmp = (uint32_t *)flashDriverStartAdd;
    for(i=0; i<sizeof(tFlashOptInfo)/4; i++)
    {
        //tmp[i] -= 0x410;
        tmp[i] += (uint32_t)flashDriverStartAdd;
    }
    
    g_pstFlashOptInfo = (tFlashOptInfo *)flashDriverStartAdd;
    
    if (STATUS_SUCCESS != g_pstFlashOptInfo->FLASH_EraseSector(0, 0x08010000, 0x800))  /*erase sector*/
    {
        printf ("line%d: eflash error\r\n", __LINE__);  
    }
    
    for (i=0;i<512;i++)
    {
        wBuff[i] = i;
    }
    
    if (STATUS_SUCCESS != g_pstFlashOptInfo->FLASH_Program(0, 0x08010000, 0x800, (const uint8_t *)wBuff))  /*program data*/
    {
        printf ("line%d: eflash error\r\n", __LINE__);  
    }
   
    while(1)
    {
       
    }
}
/*************<end>********************/
