Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed by
targets/cmsis/TARGET_ARM_SSG/TARGET_BEETLE/eflash_api.c
- Committer:
- <>
- Date:
- 2016-09-02
- Revision:
- 144:ef7eb2e8f9f7
File content as of revision 144:ef7eb2e8f9f7:
/* mbed Microcontroller Library * Copyright (c) 2015 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "eflash_api.h" /* EFlash Private Data */ typedef struct { /* basebank0 start address */ unsigned int basebank0; /* basebank0 mass erase + info pages address */ unsigned int basebank0_me; /* basebank1 start address */ unsigned int basebank1; /* basebank1 mass erase + info pages address */ unsigned int basebank1_me; } eflash_t; static eflash_t eflash; /* EFlash_IdCheck: Detect the part number to see if device is present */ int EFlash_IdCheck() { unsigned int eflash_id; eflash_id = EFlash_Readl(SYS_EFLASH_PIDR2) & (EFLASH_DES_1 | EFLASH_JEDEC); if (EFlash_Readl(SYS_EFLASH_PIDR0) != FLS_PID0 || EFlash_Readl(SYS_EFLASH_PIDR1) != FLS_PID1 || eflash_id != FLS_PID2) /* port ID and ARM ID does not match */ return 1; else return 0; } /* EFlash_ReturnBank1BaseAddress: Returns start address of bank 1 */ int EFlash_ReturnBank1BaseAddress() { unsigned int hwparams0; int baseaddr; hwparams0 = EFlash_Readl(SYS_EFLASH_HWPARAMS0) & EFLASH_FLASHSIZE; switch(hwparams0) { case 0x11: /* 128kb flash size - first page of bank 1 is 0x20000 */ baseaddr = 0x20000; break; case 0x12: /* 256kb flash size - first page of bank 1 is 0x40000 */ baseaddr = 0x40000; break; default: /* unsupported flash size */ baseaddr = -1; break; } return baseaddr; } /* EFlash_DriverInitialize: eFlash Driver Initialize function */ void EFlash_DriverInitialize() { /* Find the start address of banks */ eflash.basebank0 = 0x0; eflash.basebank0_me = 0x40000000; eflash.basebank1 = EFlash_ReturnBank1BaseAddress(); eflash.basebank1_me = 0x80000000; } /* EFlash_ClockConfig: eFlash Clock Configuration */ void EFlash_ClockConfig() { /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* * Configure to use external clock * EXTCL = 31250 ns -> * 1 ms = 32 clock count 32khz ext_clk -> ER_CLK_COUNT = 32 * 1 us = 84 clock count system_clk -> WR_CLK_COUNT = 84 * EXT_CLK_CONF = 0x1 [Erase] External clock used for erase counters (>1ms) * HCLK used for write counters * RD_CLK_COUNT = 0x3 */ EFlash_Writel(SYS_EFLASH_CONFIG0, 0x00200B43); /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); } /* * EFlash_Erase: Erases flash banks * Mode: * 0 - erases bank 0 * 1 - erases bank 1 * 2 - erases bank 0 + info pages * 3 - erases bank 1 + info pages * 4 - erases bank 0 + 1 * 5 - erases bank 0 + 1 with info pages */ void EFlash_Erase(int mode) { switch (mode) { case 0: /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #0 */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank0); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); break; case 1: /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #1 */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank1); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); break; case 2: /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #0 + info pages */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank0_me); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); break; case 3: /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #1 + info pages */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank1_me); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); break; case 4: /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #0 */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank0); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #1 */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank1); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller gets unlocked */ /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); break; case 5: /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #0 + info pages */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank0_me); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_LOCK_MASK) == EFLASH_LOCK); /* Erase Block #1 + info pages */ EFlash_Writel(SYS_EFLASH_WADDR, eflash.basebank1_me); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_MASS_ERASE); /* Wait until eFlash controller is not busy */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); break; default: break; } } /* EFlash_ErasePage: Erase a Page */ void EFlash_ErasePage(unsigned int waddr) { /* Erase the page starting a waddr */ EFlash_Writel(SYS_EFLASH_WADDR, waddr); EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_ERASE); /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); } /* * EFlash_Write: Write function * Parameters: * waddr - address in flash * data - data to be written */ void EFlash_Write(unsigned int waddr, unsigned int data) { /* Set Write Data Register */ EFlash_Writel(SYS_EFLASH_WDATA, data); /* Set Write Address Register */ EFlash_Writel(SYS_EFLASH_WADDR, waddr); /* Start Write Operation through CTRL register */ EFlash_Writel(SYS_EFLASH_CTRL, EFLASH_WRITE); /* Wait until eFlash controller gets unlocked */ while ((EFlash_Readl(SYS_EFLASH_STATUS) & EFLASH_BUSY_MASK) == EFLASH_BUSY); /* Flash Cache invalidate if FCache enabled */ if (FCache_isEnabled() == 1) FCache_Invalidate(); } /* * EFlash_WritePage: Write Page function * Parameters: * waddr - address in flash * page_size - data to be written * buf - buffer containing the data */ int EFlash_WritePage(unsigned int waddr, unsigned int page_size, unsigned char *buf) { unsigned int page_index; unsigned int data; /* To be verified */ for(page_index = 0; page_index < page_size; page_index = page_index + 4) { /* Recreate the 32 bit word */ data = ((unsigned int) buf[page_index + 3]) << 24 | ((unsigned int) buf[page_index + 2]) << 16 | ((unsigned int) buf[page_index + 1]) << 8 | ((unsigned int) buf[page_index]); /* Write the word in memory */ EFlash_Write(waddr, data); waddr += 4; } return 0; } /* * EFlash_Read: Read function * Parameters: * waddr - address in flash * Returns: * the vaule read at address waddr */ unsigned int EFlash_Read(unsigned int waddr) { unsigned int eflash_read = EFlash_Readl(waddr); return eflash_read; } /* * EFlash_Verify: Verifies if the eFlash has been written correctly. * Parameters: * waddr - address in flash * page_size - data to be written * buf - buffer containing the data * Returns: * (waddr+page_size) - OK or Failed Address */ unsigned int EFlash_Verify(unsigned int waddr, unsigned int page_size, unsigned char *buf) { unsigned int page_index; unsigned int eflash_data, buf_data; /* To be verified */ for(page_index = 0; page_index < page_size; page_index = page_index + 4) { /* Recreate the 32 bit word */ buf_data = ((unsigned int) buf[page_index + 3]) << 24 | ((unsigned int) buf[page_index + 2]) << 16 | ((unsigned int) buf[page_index + 1]) << 8 | ((unsigned int) buf[page_index]); /* Read the word in memory */ eflash_data = EFlash_Read(waddr); if (eflash_data != buf_data) break; waddr += 4; } /* Allign the address before return */ return (waddr); } /* * EFlash_BlankCheck: Verifies if there is any Blank Block in eFlash * Parameters: * waddr - address in flash * page_size - data to be written * pat - pattern of a blank block * Returns: * 0 - OK or 1- Failed */ int EFlash_BlankCheck(unsigned int waddr, unsigned int page_size, unsigned char pat) { unsigned int page_index; unsigned int eflash_data, buf_data; /* Page size div by 4 */ page_size = page_size >> 2; /* To be verified */ for(page_index = 0; page_index < page_size; page_index = page_index + 4) { /* Recreate the 32 bit word */ buf_data = ((unsigned int) pat) << 24 | ((unsigned int) pat) << 16 | ((unsigned int) pat) << 8 | ((unsigned int) pat); /* Read the word in memory */ eflash_data = EFlash_Read(waddr); if (eflash_data != buf_data) return 1; waddr += 4; } return 0; } /* * Delay ns (uncalibrated delay) */ void EFlash_Delay(unsigned int period) { int loop; for (loop = 0; loop < period; loop++) continue; }