arch/arm/src/tiva: Implemented Flash CONFIG_MTD_BYTE_WRITE for TM4c1294. Implemented the tiva_write function which will write an arbitrary number of bytes to flash (in multiple of 4).

This commit is contained in:
Shirshak Sengupta 2018-04-29 11:45:24 -06:00 committed by Gregory Nutt
parent 0835143537
commit ba0bbb93b0

View File

@ -2,7 +2,7 @@
* arch/arm/src/tiva/tiva_flash.c
*
* Copyright (c) 2013 Max Holtzberg. All rights reserved.
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2013, 2018 Gregory Nutt. All rights reserved.
*
* Authors: Max Holtzberg <mh@uvc.de>
* Gregory Nutt <gnutt@nuttx.org>
@ -64,8 +64,8 @@
****************************************************************************/
#define TIVA_VIRTUAL_NPAGES (TIVA_FLASH_NPAGES - CONFIG_TIVA_FLASH_STARTPAGE)
#define TIVA_VIRTUAL_BASE (TIVA_FLASH_BASE \
+ CONFIG_TIVA_FLASH_STARTPAGE * TIVA_FLASH_PAGESIZE)
#define TIVA_VIRTUAL_OFFSET (CONFIG_TIVA_FLASH_STARTPAGE * TIVA_FLASH_PAGESIZE)
#define TIVA_VIRTUAL_BASE (TIVA_FLASH_BASE + TIVA_VIRTUAL_OFFSET)
/****************************************************************************
* Private Types
@ -120,6 +120,7 @@ static struct tiva_dev_s g_lmdev =
#endif
tiva_ioctl
},
/* Initialization of any other implementation specific data goes here */
};
@ -138,12 +139,15 @@ static struct tiva_dev_s g_lmdev =
static int tiva_erase(FAR struct mtd_dev_s *dev, off_t startblock,
size_t nblocks)
{
int curpage;
off_t endblock;
uint32_t pageaddr;
uint32_t regval;
int curpage;
DEBUGASSERT(nblocks <= TIVA_VIRTUAL_NPAGES);
endblock = startblock + nblocks;
DEBUGASSERT(endblock <= TIVA_VIRTUAL_NPAGES);
for (curpage = startblock; curpage < nblocks; curpage++)
for (curpage = startblock; curpage < endblock; curpage++)
{
pageaddr = TIVA_VIRTUAL_BASE + curpage * TIVA_FLASH_PAGESIZE;
@ -160,7 +164,19 @@ static int tiva_erase(FAR struct mtd_dev_s *dev, off_t startblock,
/* wait until erase has finished */
while (getreg32(TIVA_FLASH_FMC) & FLASH_FMC_ERASE);
while (getreg32(TIVA_FLASH_FMC) & FLASH_FMC_ERASE)
{
}
/* Return an error if an access violation or erase error occurred. */
regval = getreg32(TIVA_FLASH_FCRIS);
regval &= (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS | FLASH_FCRIS_ERRIS);
if (regval != 0)
{
return -EACCES;
}
}
return OK;
@ -255,7 +271,90 @@ static ssize_t tiva_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
static ssize_t tiva_write(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
FAR const uint8_t *buf)
{
return -ENOSYS;
FAR const uint32_t *src = (uint32_t *)((uintptr_t)buf & ~3);
ssize_t remaining;
uint32_t regval;
DEBUGASSERT(dev != NULL && buf != NULL);
DEBUGASSERT(((uintptr_t)buf & 3) == 0 && (offset & 3) == 0 && (nbytes && 3) == 0);
/* Clear the flash access and error interrupts. */
putreg32(FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC | FLASH_FCMISC_ERMISC,
TIVA_FLASH_FCMISC);
/* Adjust the offset to the start of the partition.
* REVISIT: If we really wanted to gracefully handler unaligned addresses,
* offsets, and sizes we would have to do a little more than this.
*/
offset &= ~3;
offset += TIVA_VIRTUAL_OFFSET;
nbytes &= ~3;
remaining = nbytes;
#if defined(CONFIG_ARCH_CHIP_TM4C1294NC)
while (remaining > 0)
{
/* Set the address of this block of words. */
putreg32((offset & ~(0x7f)), TIVA_FLASH_FMA);
/* Loop over the words in this 32-word block. */
while(((offset & 0x7c) || (getreg32(TIVA_FLASH_FWBN) == 0)) &&
(remaining > 0))
{
/* Write this word into the write buffer. */
putreg32(*src++, (TIVA_FLASH_FWBN + (offset & 0x7c)));
offset += 4;
remaining -= 4;
}
/* Program the contents of the write buffer into flash. */
putreg32(FLASH_FMC_WRKEY | FLASH_FMC2_WRBUF, TIVA_FLASH_FMC2);
/* Wait until the write buffer has been programmed. */
while(getreg32(TIVA_FLASH_FMC2) & FLASH_FMC2_WRBUF)
{
}
}
#else
while (remaining > 0)
{
/* Program the next word. */
putreg32(offset, TIVA_FLASH_FMA);
putreg32(*src, TIVA_FLASH_FMD);
putreg32(FLASH_FMC_WRKEY | FLASH_FMC_WRITE, TIVA_FLASH_FMC);
/* Wait until the word has been programmed. */
while(getreg32(TIVA_FLASH_FMC) & FLASH_FMC_WRITE);
/* Increment to the next word. */
src++;
offset += 4;
remaining -= 4;
}
#endif
/* Return an error if an access violation or erase error occurred. */
regval = getreg32(TIVA_FLASH_FCRIS);
regval &= (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS | FLASH_FCRIS_INVDRIS |
FLASH_FCRIS_PROGRIS);
if (regval != 0)
{
return -EACCES;
}
return nbytes;
}
#endif