
//flash 1.0V

/*********************************************************************
 * INCLUDES
 */
#include "bsp_flash.h"
#include "exception.h"
#include "system.h"
#include "nrf_sdh_soc.h"
#include "nrf_pwr_mgmt.h"
#include "nrf_sdm.h"

typedef enum
{
    NRF_STATE_IDLE,    //FALSH空闲
    NRF_STATE_BUSY,    //FLASH忙
} falsh_busy_state;

typedef enum
{
    NRF_FLASH_OPERATION_IDLE,            //!< No operations requested to the SoftDevice.
	  NRF_FLASH_OPERATION_FINISH
} nrf_flash_sd_state_t;

static volatile falsh_busy_state BUSY_FLAG =NRF_STATE_IDLE;
static volatile nrf_flash_sd_state_t FLASH_OP_state =NRF_FLASH_OPERATION_IDLE;

//等待flash操作完成
static void waitForFlashReady(void)
{
	  uint8_t flag =0;
	
	  //没有打开协议栈直接退出
	  sd_softdevice_is_enabled(&flag);
	  if(0 == flag){
			 BUSY_FLAG = NRF_STATE_IDLE;
			 FLASH_OP_state =NRF_FLASH_OPERATION_FINISH;
			 return;
		}
		
    while(BUSY_FLAG != NRF_STATE_IDLE)										// While fstorage is busy, sleep and wait for an event.
    {
       nrf_pwr_mgmt_run();
    }
}

void flash_evt_handler(uint32_t sys_evt, void *p_context)
{
    //UNUSED_PARAMETER(p_context);
//    DEBUG_LOG(" NRF_EVT_FLASH_OPERATION_SUCCESS\r\n");
	  
    if ((sys_evt != NRF_EVT_FLASH_OPERATION_SUCCESS) && (sys_evt != NRF_EVT_FLASH_OPERATION_ERROR))
    {
        return;
    }
    switch (sys_evt)
    {
			case NRF_EVT_FLASH_OPERATION_SUCCESS:
				   BUSY_FLAG =NRF_STATE_IDLE;
					 FLASH_OP_state =NRF_FLASH_OPERATION_FINISH;
					 break;
			case NRF_EVT_FLASH_OPERATION_ERROR:
				   BUSY_FLAG =NRF_STATE_IDLE;
					 break;
    }
}

NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, flash_evt_handler, NULL);


flash_OPER_Result sdflash_write(uint32_t *p_dst, uint32_t const *p_src, uint32_t sizewords)
{
	  if ((unsigned int)p_dst + (sizewords * 4) > END_FSTORAGE_ADDR || (unsigned int)p_dst < START_FSTORAGE_ADDR)
    {
        DEBUG_LOG(" ----------------------------sd_flash_write,0x%x 0x%x %d\r\n",  (unsigned int)p_dst, (unsigned int)p_src, sizewords);
        return FLASH_ERROR_ADDRESS_FAIL;
    }
		
		BUSY_FLAG =NRF_STATE_BUSY;
		FLASH_OP_state =NRF_FLASH_OPERATION_IDLE;
    sd_flash_write(p_dst, p_src, sizewords);
	  waitForFlashReady();
	
    if(NRF_FLASH_OPERATION_FINISH != FLASH_OP_state)return FLASH_ERROR_WRITE_FAIL;
    return FLASH_OP_SUCCESS;
}

flash_OPER_Result sdflash_page_erase(uint32_t page_addr)
{  
	  if(page_addr % 4 != 0 || page_addr == 0)return FLASH_ERROR_ADDRESS_FAIL;
	
    uint32_t page_number = page_addr / FLASH_PAGE_SIZE;
	  BUSY_FLAG =NRF_STATE_BUSY;
		FLASH_OP_state =NRF_FLASH_OPERATION_IDLE;
    sd_flash_page_erase(page_number);
	  waitForFlashReady();
	
	  if(NRF_FLASH_OPERATION_FINISH != FLASH_OP_state)return FLASH_ERROR_ERASE_FAIL;
//	  DEBUG_LOG(">>>>>>>>>>sdflash_page_erase FLASH_OP_SUCCESS,%02x\r\n",page_addr);
    return FLASH_OP_SUCCESS;
}



/****************************************************END OF FILE****************************************************/
