/*******************************************************************************
* 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();
}
Esempio n. 2
0
/*******************************************************************************
* 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;
}
Esempio n. 4
0
    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);
}