Exemple #1
0
int flashPageErase(flashpage_t page){

  /* Only write on pages in the user area */
  if (!(FLASH_IS_ADDRESS_USERSPACE(FLASH_ADDRESS_OF_PAGE(page))))
    return FLASH_RETURN_NO_PERMISSION;

  /* Unlock flash for write access */
  if(flashUnlock() == CH_FAILED)
    return FLASH_RETURN_NO_PERMISSION;

  /* Wait for any busy flags. */
  flashWaitWhileBusy();

  /* Start deletion of page. */
  FLASH->CR |= FLASH_CR_PER;
  FLASH->AR = FLASH_ADDRESS_OF_PAGE(page);
  FLASH->CR |= FLASH_CR_STRT;

  /* Wait until it's finished. */
  flashWaitWhileBusy();

  /* Page erase flag does not clear automatically. */
  FLASH->CR &= !FLASH_CR_PER;

  /* Lock flash again */
  flashLock();

  /* Check deleted page for errors */
  if(flashPageCheckErased(page) == FALSE)
    return FLASH_RETURN_BADFLASH;  /* Page is not empty despite the erase cycle! */

  /* Successfully deleted page */
  return FLASH_RETURN_SUCCESS;
}
Exemple #2
0
int flashSectorErase(flashsector_t sector) {
	/* Unlock flash for write access */
	if (flashUnlock() == CH_FAILED)
		return FLASH_RETURN_NO_PERMISSION;

	/* Wait for any busy flags. */
	flashWaitWhileBusy();

	/* Setup parallelism before any program/erase */
	FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
	FLASH->CR |= FLASH_CR_PSIZE_VALUE;

	/* Start deletion of sector.
	 * SNB(3:1) is defined as:
	 * 0000 sector 0
	 * 0001 sector 1
	 * ...
	 * 1011 sector 11
	 * others not allowed */
	FLASH->CR &= ~(FLASH_CR_SNB_0 | FLASH_CR_SNB_1 | FLASH_CR_SNB_2 | FLASH_CR_SNB_3);
	if (sector & 0x1)
		FLASH->CR |= FLASH_CR_SNB_0;
	if (sector & 0x2)
		FLASH->CR |= FLASH_CR_SNB_1;
	if (sector & 0x4)
		FLASH->CR |= FLASH_CR_SNB_2;
	if (sector & 0x8)
		FLASH->CR |= FLASH_CR_SNB_3;
	FLASH->CR |= FLASH_CR_SER;
	FLASH->CR |= FLASH_CR_STRT;

	/* Wait until it's finished. */
	flashWaitWhileBusy();

	/* Sector erase flag does not clear automatically. */
	FLASH->CR &= ~FLASH_CR_SER;

	/* Lock flash again */
	flashLock()
	;

	/* Check deleted sector for errors */
	if (flashIsErased(flashSectorBegin(sector), flashSectorSize(sector)) == FALSE)
		return FLASH_RETURN_BAD_FLASH; /* Sector is not empty despite the erase cycle! */

	/* Successfully deleted sector */
	return FLASH_RETURN_SUCCESS;
}
Exemple #3
0
int flashPageWrite(flashpage_t page, const flashdata_t* buffer){
  volatile flashdata_t* const pageAddr =
                                     (flashdata_t*) FLASH_ADDRESS_OF_PAGE(page);

  /* Only write on pages in the user area */
  if (!(FLASH_IS_ADDRESS_USERSPACE(FLASH_ADDRESS_OF_PAGE(page))))
    return FLASH_RETURN_NO_PERMISSION;

  unsigned int pos;

  /* Unlock flash for write access */
  if(flashUnlock() == CH_FAILED)
    return FLASH_RETURN_NO_PERMISSION;

  flashWaitWhileBusy();

  for(pos = 0; pos < FLASH_PAGE_SIZE / sizeof(flashdata_t); pos++) {

    /* Enter flash programming mode. */
    FLASH->CR |= FLASH_CR_PG;

    /* Write half-word to flash. */
    pageAddr[pos] = buffer[pos];

    /* Wait for completion */
    flashWaitWhileBusy();

    /* Exit flash programming mode. */
    FLASH->CR &= ~FLASH_CR_PG;

    /* Check for flash error. */

    if (pageAddr[pos] != buffer[pos])
      return FLASH_RETURN_BADFLASH;
  }

  flashLock();

  return 0;
}
Exemple #4
0
static void flashWriteData(flashaddr_t address, const flashdata_t data) {
	/* Enter flash programming mode */
	FLASH->CR |= FLASH_CR_PG;

	/* Write the data */
	*(flashdata_t*) address = data;

	/* Wait for completion */
	flashWaitWhileBusy();

	/* Exit flash programming mode */
	FLASH->CR &= ~FLASH_CR_PG;
}
Exemple #5
0
int flashWrite(flashaddr_t address, const char* buffer, size_t size) {
	/* Unlock flash for write access */
	if (flashUnlock() == CH_FAILED)
		return FLASH_RETURN_NO_PERMISSION;

	/* Wait for any busy flags */
	flashWaitWhileBusy();

	/* Setup parallelism before any program/erase */
	FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
	FLASH->CR |= FLASH_CR_PSIZE_VALUE;

	/* Check if the flash address is correctly aligned */
	size_t alignOffset = address % sizeof(flashdata_t);
//	print("flash alignOffset=%d\r\n", alignOffset);
	if (alignOffset != 0) {
		/* Not aligned, thus we have to read the data in flash already present
		 * and update them with buffer's data */

		/* Align the flash address correctly */
		flashaddr_t alignedFlashAddress = address - alignOffset;

		/* Read already present data */
		flashdata_t tmp = *(volatile flashdata_t*) alignedFlashAddress;

		/* Compute how much bytes one must update in the data read */
		size_t chunkSize = sizeof(flashdata_t) - alignOffset;
		if (chunkSize > size)
			chunkSize = size; // this happens when both address and address + size are not aligned

		/* Update the read data with buffer's data */
		memcpy((char*) &tmp + alignOffset, buffer, chunkSize);

		/* Write the new data in flash */
		flashWriteData(alignedFlashAddress, tmp);

		/* Advance */
		address += chunkSize;
		buffer += chunkSize;
		size -= chunkSize;
	}

	/* Now, address is correctly aligned. One can copy data directly from
	 * buffer's data to flash memory until the size of the data remaining to be
	 * copied requires special treatment. */
	while (size >= sizeof(flashdata_t)) {
//		print("flash write size=%d\r\n", size);
		flashWriteData(address, *(const flashdata_t*) buffer);
		address += sizeof(flashdata_t);
		buffer += sizeof(flashdata_t);
		size -= sizeof(flashdata_t);
	}

	/* Now, address is correctly aligned, but the remaining data are to
	 * small to fill a entier flashdata_t. Thus, one must read data already
	 * in flash and update them with buffer's data before writing an entire
	 * flashdata_t to flash memory. */
	if (size > 0) {
		flashdata_t tmp = *(volatile flashdata_t*) address;
		memcpy(&tmp, buffer, size);
		flashWriteData(address, tmp);
	}

	/* Lock flash again */
	flashLock()
	;

	return FLASH_RETURN_SUCCESS;
}