/******************************************************************************* * Function Name: Bootloader_SetFlashByte ******************************************************************************** * * Summary: * Writes a byte to the specified Flash memory location. * * Parameters: * address: * The address in Flash memory where data will be written * * runType: * Byte to be written * * Return: * None * *******************************************************************************/ void Bootloader_SetFlashByte(uint32 address, uint8 runType) { uint32 flsAddr = address - CYDEV_FLASH_BASE; uint8 rowData[CYDEV_FLS_ROW_SIZE]; uint8 arrayId = ( uint8 )(flsAddr / CYDEV_FLS_SECTOR_SIZE); uint16 rowNum = ( uint16 )((flsAddr % CYDEV_FLS_SECTOR_SIZE) / CYDEV_FLS_ROW_SIZE); uint32 baseAddr = address - (address % CYDEV_FLS_ROW_SIZE); uint16 idx; for(idx = 0u; idx < CYDEV_FLS_ROW_SIZE; idx++) { rowData[idx] = Bootloader_GET_CODE_BYTE(baseAddr + idx); } rowData[address % CYDEV_FLS_ROW_SIZE] = runType; (void) CyWriteRowData(arrayId, rowNum, rowData); /*************************************************************************** * When writing Flash, data in the instruction cache can become stale. * Therefore, the cache data does not correlate to the data just written to * Flash. A call to CyFlushCache() is required to invalidate the data in the * cache and force fresh information to be loaded from Flash. ***************************************************************************/ CyFlushCache(); }
/******************************************************************************* * The following code is OBSOLETE and must not be used. *******************************************************************************/ void Bootloadable_1_SetFlashByte(uint32 address, uint8 runType) { uint32 flsAddr = address - CYDEV_FLASH_BASE; uint8 rowData[CYDEV_FLS_ROW_SIZE]; #if !(CY_PSOC4) uint8 arrayId = ( uint8 )(flsAddr / CYDEV_FLS_SECTOR_SIZE); #endif /* !(CY_PSOC4) */ #if (CY_PSOC4) uint16 rowNum = ( uint16 )(flsAddr / CYDEV_FLS_ROW_SIZE); #else uint16 rowNum = ( uint16 )((flsAddr % CYDEV_FLS_SECTOR_SIZE) / CYDEV_FLS_ROW_SIZE); #endif /* (CY_PSOC4) */ uint32 baseAddr = address - (address % CYDEV_FLS_ROW_SIZE); uint16 idx; for (idx = 0u; idx < CYDEV_FLS_ROW_SIZE; idx++) { rowData[idx] = Bootloadable_1_GET_CODE_DATA(baseAddr + idx); } rowData[address % CYDEV_FLS_ROW_SIZE] = runType; #if(CY_PSOC4) (void) CySysFlashWriteRow((uint32) rowNum, rowData); #else (void) CyWriteRowData(arrayId, rowNum, rowData); #endif /* (CY_PSOC4) */ #if(CY_PSOC5) /*************************************************************************** * When writing to flash, data in the instruction cache can become obsolete. * Therefore, the cache data does not correlate to the data just written to * flash. A call to CyFlushCache() is required to invalidate the data in the * cache and force fresh information to be loaded from flash. ***************************************************************************/ CyFlushCache(); #endif /* (CY_PSOC5) */ }
/******************************************************************************* * Function Name: BlockLoad ******************************************************************************** * * Summary: * Writes an arbitrary block to NVM (flash or EEPROM) * * Parameters: * char mem: 'E' or 'F' for EEPROM or Flash; others undefined * uint16 size: number of bytes to be written * uint8* buffer: pointer to buffer to be written * * Return: * The result of the write attempt. * '\r' - okay * '?' - failure for some reason * *******************************************************************************/ static char BlockLoad(char mem, uint16 size, uint8* buffer, uint32 address) { char retVal = '?'; if ((mem != 'E') && (mem != 'F')) { return retVal; } /* Passed the first test: this is a valid write. Now, which kind? */ if (mem == 'E') { /* EEPROM writes unimplmented (yet) */ } else if (mem == 'F') { uint8 rowData[CYDEV_FLS_ROW_SIZE]; uint8* dataBuffer = buffer; /* There are several pieces of information we may need: * arrayId - which *array* of flash is this? This is a big block of many * rows; in the 5888, it's 0x10000 long. * rowNum - which row within that array? *Not* absolute row id! * baseAddr - if the address is not row aligned, which row does it start * within? * offset - where, within that row, does the data start? * multirow - do we need to do more than one row write to cover this data? */ uint8 arrayId = ( uint8 )(address / CYDEV_FLS_SECTOR_SIZE); uint16 rowNum = ( uint16 )((address % CYDEV_FLS_SECTOR_SIZE) / \ CYDEV_FLS_ROW_SIZE); uint32 baseAddr = address - (address % CYDEV_FLS_ROW_SIZE); uint32 offset = address % CYDEV_FLS_ROW_SIZE; uint8 multiRow = 0; uint8 currentRow = 0; if (size > (CYDEV_FLS_ROW_SIZE - offset)) { multiRow = 1; } /* Metadata created; let's write! */ do { uint16 idx; /* Partial row write section */ if ((size != CYDEV_FLS_ROW_SIZE) || (offset != 0)) { /* If this isn't a full row write, we need to cache the existing row */ for(idx = 0u; idx < CYDEV_FLS_ROW_SIZE; idx++) { rowData[idx] = Bootloader_GET_CODE_BYTE(baseAddr + \ (CYDEV_FLS_ROW_SIZE*currentRow) + idx); } dataBuffer = rowData; /* Now load the passed data into the dataBuffer at the offset, making * sure that we don't write past the end of the buffer */ memcpy(dataBuffer + offset, buffer, \ ((CYDEV_FLS_ROW_SIZE - offset) > size) ? \ (CYDEV_FLS_ROW_SIZE - offset) : \ size); } (void) CyWriteRowData(arrayId, rowNum, dataBuffer); buffer += (CYDEV_FLS_ROW_SIZE - offset); offset = 0; ++currentRow; } while (currentRow <= multiRow); retVal = '\r'; /************************************************************************* * When writing Flash, data in the instruction cache can become stale. * Therefore, the cache data does not correlate to the data just written to * Flash. A call to CyFlushCache() is required to invalidate the data in * the cache and force fresh information to be loaded from Flash. *************************************************************************/ CyFlushCache(); } return retVal; }
cystatus Em_EEPROM_Write(const uint8 srcBuf[], const uint8 eepromPtr[], uint32 byteCount) #endif /* (!CY_PSOC3) */ { uint8 writeBuffer[CY_FLASH_SIZEOF_ROW]; uint32 arrayId; uint32 rowId; uint32 dstIndex; uint32 srcIndex; cystatus rc; uint32 eeOffset; uint32 byteOffset; #if (!CY_PSOC4) #if (CYDEV_ECC_ENABLE == 0) uint8 rowBuffer[CY_FLASH_SIZEOF_ROW + CY_FLASH_SIZEOF_ECC_ROW]; #endif /* CYDEV_ECC_ENABLE == 0) */ #endif /* (!CY_PSOC4) */ eeOffset = (uint32)eepromPtr; #if (CY_PSOC3) eeOffset &= Em_EEPROM_CODE_ADDR_MASK; #endif /* (CY_PSOC3) */ /* Make sure, that eepromPtr[] points to ROM */ #if (CY_PSOC3) if (((uint32)eepromPtr >= Em_EEPROM_CODE_ADDR_OFFSET) && (((uint32)eepromPtr + byteCount) <= Em_EEPROM_CODE_ADDR_END)) #else if (((uint32)eepromPtr + byteCount) < Em_EEPROM_FLASH_END_ADDR) #endif /* (CY_PSOC3) */ { #if (!CY_PSOC4) (void)CySetTemp(); #if(CYDEV_ECC_ENABLE == 0) (void)CySetFlashEEBuffer(rowBuffer); #endif #endif /* (!CY_PSOC4) */ arrayId = eeOffset / CY_FLASH_SIZEOF_ARRAY; rowId = (eeOffset / CY_FLASH_SIZEOF_ROW) % Em_EEPROM_ROWS_IN_ARRAY; byteOffset = (CY_FLASH_SIZEOF_ARRAY * arrayId) + (CY_FLASH_SIZEOF_ROW * rowId); srcIndex = 0u; rc = CYRET_SUCCESS; while ((srcIndex < byteCount) && (CYRET_SUCCESS == rc)) { /* Copy data to the write buffer either from the source buffer or from the flash */ for (dstIndex = 0u; dstIndex < CY_FLASH_SIZEOF_ROW; dstIndex++) { if ((byteOffset >= eeOffset) && (srcIndex < byteCount)) { writeBuffer[dstIndex] = srcBuf[srcIndex]; srcIndex++; } else { writeBuffer[dstIndex] = CY_GET_XTND_REG8(CYDEV_FLASH_BASE + byteOffset); } byteOffset++; } /* Write flash row */ #if (CY_PSOC4) rc = CySysFlashWriteRow(rowId, writeBuffer); #else rc = CyWriteRowData((uint8)arrayId, (uint16)rowId, writeBuffer); #endif /* (CY_PSOC4) */ /* Go to the next row */ rowId++; #if (CY_FLASH_NUMBER_ARRAYS > 1) if (rowId >= Em_EEPROM_ROWS_IN_ARRAY) { arrayId++; rowId = 0u; } #endif /* (CY_FLASH_NUMBER_ARRAYS > 1) */ } /* Flush both Cache and PHUB prefetch buffer */ #if (CY_PSOC5) CyFlushCache(); #elif (CY_PSOC3) CY_FLASH_CONTROL_REG |= 6u; #endif /* (CY_PSOC5) */ } else { rc = CYRET_BAD_PARAM; } /* Mask return codes from flash, if they are not supported */ if ((CYRET_SUCCESS != rc) && (CYRET_BAD_PARAM != rc)) { rc = CYRET_UNKNOWN; } return (rc); }