Пример #1
0
/**
 * Close file \a fd
 */
static int flash_avr_close(struct KFile *_fd)
{
	Flash *fd = FLASH_CAST(_fd);
	flash_avr_flush(fd);
	LOG_INFO("Flash file closed\n");
	return 0;
}
Пример #2
0
/**
 * Return true if no error are occurred after flash memory
 * read or write operation, otherwise return error code.
 */
static bool flash_getStatus(struct KBlock *blk)
{
	Flash *fls = FLASH_CAST(blk);
	/*
	 * This bit is set to one if an invalid command and/or a bad keywords was/were
	 * written in the Flash Command Register.
	 */
	if(MC_FSR & BV(MC_PROGE))
	{
		fls->hw->status |= FLASH_WR_ERR;
		LOG_ERR("flash not erased..\n");
		return false;
	}

	/*
	 * This bit is set to one if we programming of at least one locked lock
	 * region.
	 */
	if(MC_FSR & BV(MC_LOCKE))
	{
		fls->hw->status |= FLASH_WR_PROTECT;
		LOG_ERR("wr protect..\n");
		return false;
	}

	return true;
}
Пример #3
0
/**
 * Reopen file \a fd
 */
static struct KFile *flash_avr_reopen(struct KFile *fd)
{
	Flash *_fd = FLASH_CAST(fd);
	flash_avr_close(fd);
	flash_avr_open((struct Flash *)_fd);
	return fd;
}
Пример #4
0
/**
 * Write program memory.
 * Write \a size bytes from buffer \a _buf to file \a fd
 * \note Write operations are buffered.
 */
static size_t flash_avr_write(struct KFile *_fd, const void *_buf, size_t size)
{
	Flash *fd = FLASH_CAST(_fd);
	const uint8_t *buf =(const uint8_t *)_buf;

	page_t page;
	page_addr_t page_addr;
	size_t total_write = 0;


	ASSERT(fd->fd.seek_pos + (kfile_off_t)size <= (kfile_off_t)fd->fd.size);
	size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);

	LOG_INFO("Writing at pos[%u]\n", fd->fd.seek_pos);
	while (size)
	{
		page = fd->fd.seek_pos / SPM_PAGESIZE;
		page_addr = fd->fd.seek_pos % SPM_PAGESIZE;

		flash_avr_loadPage(fd, page);

		size_t wr_len = MIN(size, SPM_PAGESIZE - page_addr);
		memcpy(fd->page_buf + page_addr, buf, wr_len);
		fd->page_dirty = true;

		buf += wr_len;
		fd->fd.seek_pos += wr_len;
		size -= wr_len;
		total_write += wr_len;
	}
	LOG_INFO("written %u bytes\n", total_write);
	return total_write;
}
Пример #5
0
static bool flash_wait(struct KBlock *blk, uint32_t event)
{
	Flash *fls = FLASH_CAST(blk);
	ticks_t start = timer_clock();
	while (true)
	{
		if (!(FLASH_FMC_R & event))
			break;

		if (FLASH_FCRIS_R & FLASH_FCRIS_ARIS)
		{
			fls->hw->status |= FLASH_WR_PROTECT;
			LOG_ERR("wr protect..\n");
			return false;
		}

		if (timer_clock() - start > ms_to_ticks(CONFIG_FLASH_WR_TIMEOUT))
		{
			fls->hw->status |= FLASH_WR_TIMEOUT;
			LOG_ERR("Timeout..\n");
			return false;
		}

		cpu_relax();
	}

	return true;
}
Пример #6
0
static bool flash_wait(struct KBlock *blk)
{
	Flash *fls = FLASH_CAST(blk);
	ticks_t start = timer_clock();
	while (true)
	{
		if (!(EMB_FLASH->SR & FLASH_FLAG_BSY))
			break;

		if (EMB_FLASH->SR & FLASH_FLAG_PGERR)
		{
			fls->hw->status |= FLASH_NOT_ERASED;
			LOG_ERR("flash not erased..\n");
			return false;
		}

		if (EMB_FLASH->SR & FLASH_FLAG_WRPRTERR)
		{
			fls->hw->status |= FLASH_WR_PROTECT;
			LOG_ERR("wr protect..\n");
			return false;
		}

		if (timer_clock() - start > ms_to_ticks(CONFIG_FLASH_WR_TIMEOUT))
		{
			fls->hw->status |= FLASH_WR_TIMEOUT;
			LOG_ERR("Timeout..\n");
			return false;
		}

		cpu_relax();
	}

	return true;
}
Пример #7
0
/**
 * Read from file \a fd \a size bytes and put it in buffer \a buf
 * \return the number of bytes read.
 */
static size_t flash_avr_read(struct KFile *_fd, void *buf, size_t size)
{
	Flash *fd = FLASH_CAST(_fd);
	ASSERT(fd->fd.seek_pos + (kfile_off_t)size <= (kfile_off_t)fd->fd.size);
	size = MIN((kfile_off_t)size, fd->fd.size - fd->fd.seek_pos);

	LOG_INFO("Reading at pos[%u]\n", fd->fd.seek_pos);
	// Flush current buffered page (if modified).
	flash_avr_flush(fd);

	/*
	 * AVR pointers are 16 bits wide, this hack is needed to avoid
	 * compiler warning, cause fd->seek_pos is a 32bit offset.
	 */
	const uint8_t *pgm_addr = (const uint8_t *)0;
	pgm_addr += fd->fd.seek_pos;

	memcpy_P(buf, pgm_addr, size);
	fd->fd.seek_pos += size;
	LOG_INFO("Read %u bytes\n", size);
	return size;
}
Пример #8
0
static void at91_flash_clearerror(struct KBlock *blk)
{
	Flash *fls = FLASH_CAST(blk);
	fls->hw->status = 0;
}
Пример #9
0
static int at91_flash_error(struct KBlock *blk)
{
	Flash *fls = FLASH_CAST(blk);
	return fls->hw->status;
}
Пример #10
0
/**
 * Flush avr flash function.
 *
 * Write current buffered page in flash memory (if modified).
 * This function erase flash memory page before writing.
 */
static int flash_avr_kfileFlush(struct KFile *_fd)
{
	Flash *fd = FLASH_CAST(_fd);
	flash_avr_flush(fd);
	return 0;
}
Пример #11
0
static size_t lpc2_flash_writeDirect(struct KBlock *blk, block_idx_t idx, const void *_buf, size_t offset, size_t size)
{
	ASSERT(offset == 0);
	ASSERT(FLASH_PAGE_SIZE_BYTES == size);

	Flash *fls = FLASH_CAST(blk);
	if (!(fls->blk.priv.flags & KB_WRITE_ONCE))
		ASSERT(sector_size(idx) <= FLASH_PAGE_SIZE_BYTES);

	const uint8_t *buf = (const uint8_t *)_buf;
	cpu_flags_t flags;

	//Compute page address of current page.
	uint32_t addr = idx * blk->blk_size;
	uint32_t sector = addr_to_sector(addr);
	// Compute the first page index in the sector to manage the status
	int idx_sector = sector_addr(sector) /  blk->blk_size;

	LOG_INFO("Writing page[%ld]sector[%ld]idx[%d]\n", idx, sector, idx_sector);
	IRQ_SAVE_DISABLE(flags);

	IapCmd cmd;
	IapRes res;
	cmd.cmd = PREPARE_SECTOR_FOR_WRITE;
	cmd.param[0] = cmd.param[1] = sector;
	iap(&cmd, &res);

	if (res.status != CMD_SUCCESS)
		goto flash_error;

	if ((fls->blk.priv.flags & KB_WRITE_ONCE) &&
			bitarray_isRangeFull(&lpc2_bitx, idx_sector, erase_group[sector]))
	{
		kputs("blocchi pieni\n");
		ASSERT(0);
		goto flash_error;
	}

	bool erase = false;
	if ((fls->blk.priv.flags & KB_WRITE_ONCE) &&
			bitarray_isRangeEmpty(&lpc2_bitx, idx_sector, erase_group[sector]))
		erase = true;

	if (!(fls->blk.priv.flags & KB_WRITE_ONCE))
		erase = true;

	if (erase)
	{
		cmd.cmd = ERASE_SECTOR;
		cmd.param[0] = cmd.param[1] = sector;
		cmd.param[2] = CPU_FREQ / 1000;
		iap(&cmd, &res);

		if (res.status != CMD_SUCCESS)
			goto flash_error;
	}

	LOG_INFO("Writing page [%ld], addr [%ld] in sector[%ld]\n", idx, addr, sector);
	cmd.cmd = PREPARE_SECTOR_FOR_WRITE;
	cmd.param[0] = cmd.param[1] = sector;
	iap(&cmd, &res);

	if (res.status != CMD_SUCCESS)
		goto flash_error;

	if (fls->blk.priv.flags & KB_WRITE_ONCE)
	{
		if (bitarray_test(&lpc2_bitx, idx))
		{
			ASSERT(0);
			goto flash_error;
		}
		else
			bitarray_set(&lpc2_bitx, idx);
	}

	cmd.cmd = COPY_RAM_TO_FLASH;
	cmd.param[0] = addr;
	cmd.param[1] = (uint32_t)buf;
	cmd.param[2] = FLASH_PAGE_SIZE_BYTES;
	cmd.param[3] = CPU_FREQ / 1000;
	iap(&cmd, &res);

	if (res.status != CMD_SUCCESS)
		goto flash_error;

	IRQ_RESTORE(flags);
	LOG_INFO("Done\n");

	return blk->blk_size;

flash_error:
	LOG_ERR("%ld\n", res.status);
	fls->hw->status |= FLASH_WR_ERR;
	return 0;
}