OSStatus platform_flash_write( const platform_flash_t *peripheral, volatile uint32_t* start_address, uint8_t* data ,uint32_t length ) { OSStatus err = kNoErr; require_action_quiet( peripheral != NULL, exit, err = kParamErr); require_action( *start_address >= peripheral->flash_start_addr && *start_address + length <= peripheral->flash_start_addr + peripheral->flash_length, exit, err = kParamErr); if( peripheral->flash_type == FLASH_TYPE_EMBEDDED ){ err = internalFlashWrite( start_address, (uint32_t *)data, length); require_noerr(err, exit); } #ifdef USE_MICO_SPI_FLASH else if( peripheral->flash_type == FLASH_TYPE_SPI ){ err = sflash_write( &sflash_handle, *start_address, data, length ); require_noerr(err, exit); *start_address += length; } #endif else{ err = kTypeErr; goto exit; } exit: return err; }
LOCAL int flashWrite(int sectorNum, char *buff, unsigned int offset, unsigned int count) { unsigned char *curBuffPtr, *sectorOffsetPtr; unsigned int len = count; int bytes; curBuffPtr = (unsigned char *)buff; sectorOffsetPtr = (unsigned char *)((sectorNum * FLASH_SECTOR_SIZE) + offset); /* Write holding block */ while (len) { if ((bytes = sflash_write(sih, cc, (unsigned int)sectorOffsetPtr, len, curBuffPtr)) < 0) { printf("flashWrite(): Failed: Sector %d, address 0x%x\n", sectorNum, (int)sectorOffsetPtr); return (ERROR); } /* Polling until command completion. Returns zero when complete. */ while (sflash_poll(sih, cc, (unsigned int)sectorOffsetPtr)); sectorOffsetPtr += bytes; len -= bytes; curBuffPtr += bytes; } return (OK); }
OSStatus platform_flash_write( platform_flash_driver_t *driver, volatile uint32_t* FlashAddress, uint8_t* Data ,uint32_t DataLength ) { OSStatus err = kNoErr; require_action_quiet( driver != NULL, exit, err = kParamErr); require_action_quiet( driver->initialized != false, exit, err = kNotInitializedErr); require_action( *FlashAddress >= driver->peripheral->flash_start_addr && *FlashAddress + DataLength <= driver->peripheral->flash_start_addr + driver->peripheral->flash_length, exit, err = kParamErr); #ifndef NO_MICO_RTOS mico_rtos_lock_mutex( &driver->flash_mutex ); #endif if( driver->peripheral->flash_type == FLASH_TYPE_INTERNAL ){ err = internalFlashWrite(FlashAddress, (uint32_t *)Data, DataLength); require_noerr(err, exit_with_mutex); } #ifdef USE_MICO_SPI_FLASH else if( driver->peripheral->flash_type == FLASH_TYPE_SPI ){ err = sflash_write( &sflash_handle, *FlashAddress, Data, DataLength ); require_noerr(err, exit_with_mutex); *FlashAddress += DataLength; } #endif else{ err = kTypeErr; goto exit_with_mutex; } exit_with_mutex: #ifndef NO_MICO_RTOS mico_rtos_unlock_mutex( &driver->flash_mutex ); #endif exit: return err; }
static int sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv; int bytes, ret = 0; /* Check address range */ if (!len) return 0; if ((to + len) > mtd->size) return -EINVAL; down(&sflash->lock); *retlen = 0; while (len) { if ((bytes = sflash_write(sflash->sbh, sflash->cc, (uint) to, len, buf)) < 0) { ret = bytes; break; } if ((ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10))) break; to += (loff_t) bytes; len -= bytes; buf += bytes; *retlen += bytes; } up(&sflash->lock); return ret; }
/* * writes the appropriate range of flash, a NULL buf simply erases * the region of flash */ int sflash_commit(si_t *sih, chipcregs_t *cc, uint offset, uint len, const uchar *buf) { struct sflash *sfl; uchar *block = NULL, *cur_ptr, *blk_ptr; uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder; uint blk_offset, blk_len, copied; int bytes, ret = 0; osl_t *osh; ASSERT(sih); osh = si_osh(sih); /* Check address range */ if (len <= 0) return 0; sfl = &sflash; if ((offset + len) > sfl->size) return -1; blocksize = sfl->blocksize; mask = blocksize - 1; /* Allocate a block of mem */ if (!(block = MALLOC(osh, blocksize))) return -1; while (len) { /* Align offset */ cur_offset = offset & ~mask; cur_length = blocksize; cur_ptr = block; remainder = blocksize - (offset & mask); if (len < remainder) cur_retlen = len; else cur_retlen = remainder; /* buf == NULL means erase only */ if (buf) { /* Copy existing data into holding block if necessary */ if ((offset & mask) || (len < blocksize)) { blk_offset = cur_offset; blk_len = cur_length; blk_ptr = cur_ptr; /* Copy entire block */ while (blk_len) { copied = sflash_read(sih, cc, blk_offset, blk_len, blk_ptr); blk_offset += copied; blk_len -= copied; blk_ptr += copied; } } /* Copy input data into holding block */ memcpy(cur_ptr + (offset & mask), buf, cur_retlen); } /* Erase block */ if ((ret = sflash_erase(sih, cc, (uint) cur_offset)) < 0) goto done; while (sflash_poll(sih, cc, (uint) cur_offset)); /* buf == NULL means erase only */ if (!buf) { offset += cur_retlen; len -= cur_retlen; continue; } /* Write holding block */ while (cur_length > 0) { if ((bytes = sflash_write(sih, cc, (uint) cur_offset, (uint) cur_length, (uchar *) cur_ptr)) < 0) { ret = bytes; goto done; } while (sflash_poll(sih, cc, (uint) cur_offset)); cur_offset += bytes; cur_length -= bytes; cur_ptr += bytes; } offset += cur_retlen; len -= cur_retlen; buf += cur_retlen; } ret = len; done: if (block) MFREE(osh, block, blocksize); return ret; }