ald_flash.c 4.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/**
  *********************************************************************************
  *
  * @file    ald_flash.c
  * @brief   FLASH module driver.
  *
  * @version V1.0
  * @date    20 Nov 2017
  * @author  AE Team
  * @note
  *
  * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
  */

#include "ald_flash.h"


/** @addtogroup ES32FXXX_ALD
  * @{
  */

/** @defgroup FLASH FLASH
  * @brief FLASH module driver
  * @{
  */

#ifdef ALD_FLASH

#if defined ( __ICCARM__ )
W
wangyq2018 已提交
30
#define __RAMFUNC       __ramfunc
31
#else
W
wangyq2018 已提交
32
#define __RAMFUNC
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
#endif

/** @defgroup Flash_Private_Variables Flash Private Variables
  * @{
  */
/* global variable*/
static op_cmd_type OP_CMD = OP_FLASH;
/**
  * @}
  */

/** @defgroup Flash_Private_Functions Flash Private Functions
  *  @brief   Flash Private functions
  * @{
  */
/**
  * @brief  Unlock the flash.
  * @retval Status, see @ref ald_status_t.
  */
__RAMFUNC static ald_status_t flash_unlock(void)
{
W
wangyq2018 已提交
54 55
	uint16_t i;
	uint16_t op_cmd = OP_CMD;
56

W
wangyq2018 已提交
57 58
	if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK))
		return ERROR;
59

W
wangyq2018 已提交
60 61 62
	FLASH_REG_UNLOCK();
	FLASH_IAP_ENABLE();
	FLASH_REQ();
63

W
wangyq2018 已提交
64 65 66 67
	for (i = 0; i < 0xFFFF; i++) {
		if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK))
			break;
	}
68

W
wangyq2018 已提交
69
	return i == 0xFFFF ? ERROR : OK;
70 71 72 73 74 75 76 77
}

/**
  * @brief  Lock the flash.
  * @retval Status, see @ref ald_status_t.
  */
__RAMFUNC static ald_status_t flash_lock(void)
{
W
wangyq2018 已提交
78 79
	uint16_t i;
	uint16_t op_cmd = OP_CMD;
80

W
wangyq2018 已提交
81 82
	FLASH_REG_UNLOCK();
	WRITE_REG(MSC->FLASHCR, 0x0);
83

W
wangyq2018 已提交
84 85 86 87
	for (i = 0; i < 0xFFFF; i++) {
		if (!(READ_BIT(MSC->FLASHSR, MSC_FLASHSR_FLASHACK_MSK)))
			break;
	}
88

W
wangyq2018 已提交
89
	return i == 0xFFFF ? ERROR : OK;
90 91 92 93 94 95 96 97 98
}

/**
  * @brief  Erase one page.
  * @param  addr: The erased page's address
  * @retval Status, see @ref ald_status_t.
  */
__RAMFUNC ald_status_t flash_page_erase(uint32_t addr)
{
W
wangyq2018 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	uint32_t i;
	uint16_t op_cmd = OP_CMD;

	if (flash_unlock() != OK)
		goto end;

	if (op_cmd == OP_FLASH) {
		CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);
		MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, FLASH_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS);
	}
	else {
		SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);
		MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, INFO_PAGE_ADDR(addr) << MSC_FLASHADDR_ADDR_POSS);
	}

	WRITE_REG(MSC->FLASHCMD, FLASH_CMD_PE);

	for (i = 0; i < 0xFFFF; i++) {
		if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK))
			continue;
		if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_ADDR_OV_MSK))
			goto end;
		if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_WRP_FLAG_MSK))
			goto end;
		if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_SERA_MSK))
			break;
	}

	if (i == 0xFFFF)
		goto end;

	if (flash_lock() == ERROR)
		goto end;

	return OK;
134
end:
W
wangyq2018 已提交
135 136
	flash_lock();
	return ERROR;
137 138 139 140 141 142 143 144 145 146 147 148
}

/**
  * @brief  Programme a word.
  * @param  addr: The word's address, it is must word align.
  * @param  data: The 8 bytes data be write.
  * @param  len: The number of data be write.
  * @param  fifo: Choose if use fifo.
  * @retval Status, see @ref ald_status_t.
  */
__RAMFUNC ald_status_t flash_word_program(uint32_t addr, uint32_t *data, uint32_t len, uint32_t fifo)
{
W
wangyq2018 已提交
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
	uint16_t i = 0;
	uint16_t prog_len;
	uint32_t *p_data = data;
	uint16_t op_cmd = OP_CMD;

	if (flash_unlock() != OK)
		goto end;

	if (op_cmd == OP_FLASH)
		CLEAR_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);
	else
		SET_BIT(MSC->FLASHADDR, MSC_FLASHADDR_IFREN_MSK);

	MODIFY_REG(MSC->FLASHADDR, MSC_FLASHADDR_ADDR_MSK, addr << MSC_FLASHADDR_ADDR_POSS);
	MODIFY_REG(MSC->FLASHCR, MSC_FLASHCR_FIFOEN_MSK, fifo << MSC_FLASHCR_FIFOEN_POS);

	for (prog_len = 0; prog_len < len; prog_len++) {
		if (fifo) {
			WRITE_REG(MSC->FLASHFIFO, p_data[0]);
			WRITE_REG(MSC->FLASHFIFO, p_data[1]);
		}
		else {
			WRITE_REG(MSC->FLASHDL, p_data[0]);
			WRITE_REG(MSC->FLASHDH, p_data[1]);
			WRITE_REG(MSC->FLASHCMD, FLASH_CMD_WP);
		}

		p_data += 2;

		for (i = 0; i < 0xFFFF; i++) {
			if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_BUSY_MSK))
				continue;
			if (READ_BIT(MSC->FLASHSR, MSC_FLASHSR_PROG_MSK))
				break;
		}
	}
	if (i == 0xFFFF)
		goto end;

	if (flash_lock() == ERROR)
		goto end;

	return OK;
192
end:
W
wangyq2018 已提交
193 194
	flash_lock();
	return ERROR;
195 196 197 198 199 200 201 202 203 204 205 206 207 208
}
/**
  * @}
  */

#endif

/**
  * @}
  */

/**
  * @}
  */