/******************************************************************************* * Function Name: CFG_EEPROM_Query ******************************************************************************** * * Summary: * Checks the status of an earlier call to CFG_EEPROM_StartWrite() or * CFG_EEPROM_StartErase(). * This function must be called until it returns a value other than * CYRET_STARTED. Once that occurs, the write or erase has been completed and * the SPC is unlocked. * * Parameters: * None * * Return: * CYRET_STARTED, if the SPC command is still processing. * CYRET_SUCCESS, if the operation was completed successfully. * CYRET_UNKNOWN, if there was an SPC error. * *******************************************************************************/ cystatus CFG_EEPROM_Query(void) { cystatus status; CySpcStart(); /* Check if SPC is idle */ if(CY_SPC_IDLE) { /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } else { status = CYRET_UNKNOWN; } /* Unlock SPC so that someone else can use it. */ CySpcUnlock(); } else { status = CYRET_STARTED; } return(status); }
/******************************************************************************* * Function Name: CySetFlashEEBuffer ******************************************************************************** * * Summary: * Sets the user supplied temporary buffer to store SPC data while performing * flash and EEPROM commands. This buffer is only necessary when Flash ECC is * disabled. * * Parameters: * buffer: * Address of block of memory to store temporary memory. The size of the block * of memory is CYDEV_FLS_ROW_SIZE + CYDEV_ECC_ROW_SIZE. * * Return: * status: * CYRET_SUCCESS if successful. * CYRET_BAD_PARAM if the buffer is NULL * *******************************************************************************/ cystatus CySetFlashEEBuffer(uint8 * buffer) { cystatus status = CYRET_SUCCESS; CySpcStart(); #if(CYDEV_ECC_ENABLE == 0) if(NULL == buffer) { status = CYRET_BAD_PARAM; } else if(CySpcLock() != CYRET_SUCCESS) { status = CYRET_LOCKED; } else { rowBuffer = buffer; CySpcUnlock(); } #else /* To supress the warning */ buffer = buffer; #endif /* (CYDEV_ECC_ENABLE == 0u) */ return(status); }
/******************************************************************************* * Function Name: CFG_EEPROM_StartWrite ******************************************************************************** * * Summary: * Starts a write of a row (16 bytes) of data to the EEPROM. * This function does not block. The function returns once the SPC has begun * writing the data. This function must be used in combination with * CFG_EEPROM_Query(). CFG_EEPROM_Query() must be called * until it returns a status other than CYRET_STARTED. That indicates that the * write has completed. Until CFG_EEPROM_Query() detects that * the write is complete, the SPC is marked as locked to prevent another * SPC operation from being performed. For a reliable write procedure to occur * you should call CFG_EEPROM_UpdateTemperature() API if the temperature * of the silicon has changed for more than 10C since component was started. * * Parameters: * rowData: The address of the data to write to the EEPROM. * rowNumber: The row number to write. * * Return: * CYRET_STARTED, if the SPC command to write was successfully started. * CYRET_BAD_PARAM, if the parameter rowNumber is out of range. * CYRET_LOCKED, if the SPC is being used. * CYRET_UNKNOWN, if there was an SPC error. * * Side effects: * After calling this API, the device should not be powered down, reset or switched * to low power modes until EEPROM operation is complete. * Ignoring this recommendation may lead to data corruption or silicon * unexpected behavior. * *******************************************************************************/ cystatus CFG_EEPROM_StartWrite(const uint8 * rowData, uint8 rowNumber) \ { cystatus status; CySpcStart(); if(rowNumber < (uint8) CY_EEPROM_NUMBER_ROWS) { /* See if we can get SPC. */ if(CySpcLock() == CYRET_SUCCESS) { /* Plan for failure */ status = CYRET_UNKNOWN; /* Command to load a row of data */ if(CySpcLoadRow(CY_SPC_FIRST_EE_ARRAYID, rowData, CYDEV_EEPROM_ROW_SIZE) == CYRET_STARTED) { while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } /* Command to erase and program the row. */ if(status == CYRET_SUCCESS) { if(CySpcWriteRow(CY_SPC_FIRST_EE_ARRAYID, (uint16)rowNumber, dieTemperature[0u], dieTemperature[1u]) == CYRET_STARTED) { status = CYRET_STARTED; } else { status = CYRET_UNKNOWN; } } else { status = CYRET_UNKNOWN; } } } else { status = CYRET_LOCKED; } } else { status = CYRET_BAD_PARAM; } return(status); }
/******************************************************************************* * Function Name: CFG_EEPROM_StartErase ******************************************************************************** * * Summary: * Starts the EEPROM sector erase. This function does not block. * The function returns once the SPC has begun writing the data. This function * must be used in combination with CFG_EEPROM_Query(). * CFG_EEPROM_Query() must be called until it returns a status * other than CYRET_STARTED. That indicates the erase has been completed. * Until CFG_EEPROM_Query() detects that the erase is * complete, the SPC is marked as locked to prevent another SPC operation * from being performed. * * Parameters: * sectorNumber: The sector number to erase. * * Return: * CYRET_STARTED, if the SPC command to erase was successfully started. * CYRET_BAD_PARAM, if the parameter sectorNumber is out of range. * CYRET_LOCKED, if the SPC is being used. * CYRET_UNKNOWN, if there was an SPC error. * * Side effects: * After calling this API, the device should not be powered down, reset or switched * to low power modes until EEPROM operation is complete. * Ignoring this recommendation may lead to data corruption or silicon * unexpected behavior. * *******************************************************************************/ cystatus CFG_EEPROM_StartErase(uint8 sectorNumber) { cystatus status; CySpcStart(); if(sectorNumber < (uint8) CY_EEPROM_NUMBER_ARRAYS) { /* See if we can get SPC. */ if(CySpcLock() == CYRET_SUCCESS) { /* Plan for failure */ status = CYRET_UNKNOWN; /* Command to load a row of data */ if(CySpcEraseSector(CY_SPC_FIRST_EE_ARRAYID, sectorNumber) == CYRET_STARTED) { status = CYRET_SUCCESS; } } else { status = CYRET_LOCKED; } } else { status = CYRET_BAD_PARAM; } return(status); }
/******************************************************************************* * Function Name: CyFlashGetSpcAlgorithm ******************************************************************************** * * Summary: * Sends a command to the SPC to download code into RAM. * * Parameters: * None * * Return: * status: * CYRET_SUCCESS - if successful * CYRET_LOCKED - if Flash writing already in use * CYRET_UNKNOWN - if there was an SPC error * *******************************************************************************/ static cystatus CyFlashGetSpcAlgorithm(void) { cystatus status; /* Make sure SPC is powered */ CySpcStart(); if(CySpcLock() == CYRET_SUCCESS) { status = CySpcGetAlgorithm(); if(CYRET_STARTED == status) { while(CY_SPC_BUSY) { /* Spin until idle. */ CyDelayUs(1u); } if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } } CySpcUnlock(); } else { status = CYRET_LOCKED; } return (status); }
void `$INSTANCE_NAME`_WriteByte(uint8 value, uint16 address) { uint8 row, offset; cystatus status; if(address < `$INSTANCE_NAME`_EEPROM_SIZE) { // calculate the row, and offset within the row row = address / `$INSTANCE_NAME`_EEPROM_ROW_SIZE; offset = address - ((uint16)row*(uint16)`$INSTANCE_NAME`_EEPROM_ROW_SIZE); // Turn on the SPC CySpcStart(); // lock the spc to prevent some other process from using it CySpcLock(); // loads a byte of data into the temporary SPC write buffer. Write the byte into the proper offset // in the temporary SPC buffer. The offset is an artifact of the "row" oriented write operations of // our EEPROM and flash. The load multibyte SPC function loads the temporary "row" with the data we intend // to write. later, this temporary row is written into the proper "row" with another function call. // to place the byte where we want it, we have to calculate the destination row, and offset within that // row. if(CySpcLoadMultiByte(CY_SPC_FIRST_EE_ARRAYID, offset, &value, `$INSTANCE_NAME`_SPC_BYTE_WRITE_SIZE) == CYRET_STARTED) { while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } // this is where we tell the SPC to write the write the temporary row into the EEPROM. if(CySpcWriteRow(CY_SPC_FIRST_EE_ARRAYID, row, dieTemperature[0], dieTemperature[1]) == CYRET_STARTED) { while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } } } /* Unlock the SPC so someone else can use it. */ CySpcUnlock(); // turn off the SPC CySpcStop(); } }
/******************************************************************************* * Function Name: CFG_EEPROM_EraseSector ******************************************************************************** * * Summary: * Erase an EEPROM sector (64 rows). This function blocks until the erase * operation is complete. Using this API helps to erase the EEPROM sector at * a time. This is faster than using individual writes but affects a cycle * recourse of the whole EEPROM row. * * Parameters: * sectorNumber: The sector number to erase. * * Return: * CYRET_SUCCESS, if the operation was successful. * CYRET_BAD_PARAM, if the parameter sectorNumber is out of range. * CYRET_LOCKED, if the SPC is being used. * CYRET_UNKNOWN, if there was an SPC error. * *******************************************************************************/ cystatus CFG_EEPROM_EraseSector(uint8 sectorNumber) { cystatus status; CySpcStart(); if(sectorNumber < (uint8) CFG_EEPROM_SECTORS_NUMBER) { /* See if we can get SPC. */ if(CySpcLock() == CYRET_SUCCESS) { if(CySpcEraseSector(CY_SPC_FIRST_EE_ARRAYID, sectorNumber) == CYRET_STARTED) { /* Plan for failure */ status = CYRET_UNKNOWN; while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } } else { status = CYRET_UNKNOWN; } /* Unlock SPC so that someone else can use it. */ CySpcUnlock(); } else { status = CYRET_LOCKED; } } else { status = CYRET_BAD_PARAM; } return(status); }
/******************************************************************************* * Function Name: CySetTempInt ******************************************************************************** * * Summary: * Sends a command to the SPC to read the die temperature. Sets a global value * used by the Write functions. This function must be called once before * executing a series of Flash writing functions. * * Parameters: * None * * Return: * status: * CYRET_SUCCESS - if successful * CYRET_LOCKED - if Flash writing already in use * CYRET_UNKNOWN - if there was an SPC error * *******************************************************************************/ static cystatus CySetTempInt(void) { cystatus status; /* Make sure SPC is powered */ CySpcStart(); /* Plan for failure. */ status = CYRET_UNKNOWN; if(CySpcLock() == CYRET_SUCCESS) { /* Write the command. */ #if(CY_PSOC5A) if(CYRET_STARTED == CySpcGetTemp(CY_TEMP_NUMBER_OF_SAMPLES, CY_TEMP_TIMER_PERIOD, CY_TEMP_CLK_DIV_SELECT)) #else if(CYRET_STARTED == CySpcGetTemp(CY_TEMP_NUMBER_OF_SAMPLES)) #endif /* (CY_PSOC5A) */ { do { if(CySpcReadData(dieTemperature, CY_FLASH_DIE_TEMP_DATA_SIZE) == CY_FLASH_DIE_TEMP_DATA_SIZE) { status = CYRET_SUCCESS; while(CY_SPC_BUSY) { /* Spin until idle. */ CyDelayUs(1u); } break; } } while(CY_SPC_BUSY); } CySpcUnlock(); } else { status = CYRET_LOCKED; } return (status); }
/******************************************************************************* * Function Name: CFG_EEPROM_ByteWritePos ******************************************************************************** * * Summary: * Writes a byte of data to the EEPROM. This is a blocking call. It will not * return until the write operation succeeds or fails. * * Parameters: * dataByte: The byte of data to write to the EEPROM. * rowNumber: The EEPROM row number to program. * byteNumber: The byte number within the row to program. * * Return: * CYRET_SUCCESS, if the operation was successful. * CYRET_BAD_PARAM, if the parameter rowNumber or byteNumber is out of range. * CYRET_LOCKED, if the SPC is being used. * CYRET_UNKNOWN, if there was an SPC error. * *******************************************************************************/ cystatus CFG_EEPROM_ByteWritePos(uint8 dataByte, uint8 rowNumber, uint8 byteNumber) \ { cystatus status; /* Start SPC */ CySpcStart(); if((rowNumber < (uint8) CY_EEPROM_NUMBER_ROWS) && (byteNumber < (uint8) SIZEOF_EEPROM_ROW)) { /* See if we can get SPC. */ if(CySpcLock() == CYRET_SUCCESS) { /* Plan for failure */ status = CYRET_UNKNOWN; /* Command to load byte of data */ if(CySpcLoadMultiByte(CY_SPC_FIRST_EE_ARRAYID, (uint16)byteNumber, &dataByte,\ CFG_EEPROM_SPC_BYTE_WRITE_SIZE) == CYRET_STARTED) { while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } /* Command to erase and program the row. */ if(status == CYRET_SUCCESS) { if(CySpcWriteRow(CY_SPC_FIRST_EE_ARRAYID, (uint16)rowNumber, dieTemperature[0u], dieTemperature[1u]) == CYRET_STARTED) { /* Plan for failure */ status = CYRET_UNKNOWN; while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } } else { status = CYRET_UNKNOWN; } } else { status = CYRET_UNKNOWN; } } /* Unlock SPC so that someone else can use it. */ CySpcUnlock(); } else { status = CYRET_LOCKED; } } else { status = CYRET_BAD_PARAM; } return(status); }
/******************************************************************************* * Function Name: CFG_EEPROM_WriteByte ******************************************************************************** * * Summary: * Writes a byte of data to the EEPROM. This function blocks until * the function is complete. For a reliable write procedure to occur you should * call CFG_EEPROM_UpdateTemperature() function if the temperature of the * silicon has been changed for more than 10C since the component was started. * * Parameters: * dataByte: The byte of data to write to the EEPROM * address: The address of data to be written. The maximum address is dependent * on the EEPROM size. * * Return: * CYRET_SUCCESS, if the operation was successful. * CYRET_BAD_PARAM, if the parameter sectorNumber is out of range. * CYRET_LOCKED, if the SPC is being used. * CYRET_UNKNOWN, if there was an SPC error. * *******************************************************************************/ cystatus CFG_EEPROM_WriteByte(uint8 dataByte, uint16 address) { cystatus status; uint16 rowNumber; uint16 byteNumber; CySpcStart(); if (address < CY_EEPROM_SIZE) { rowNumber = address/(uint16)CY_EEPROM_SIZEOF_ROW; byteNumber = address - (rowNumber * ((uint16)CY_EEPROM_SIZEOF_ROW)); if(CYRET_SUCCESS == CySpcLock()) { status = CySpcLoadMultiByte(CY_SPC_FIRST_EE_ARRAYID, byteNumber, &dataByte, \ CFG_EEPROM_SPC_BYTE_WRITE_SIZE); if (CYRET_STARTED == status) { /* Plan for failure */ status = CYRET_UNKNOWN; while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } /* Command to erase and program the row. */ if(CYRET_SUCCESS == status) { if(CySpcWriteRow(CY_SPC_FIRST_EE_ARRAYID, (uint16)rowNumber, dieTemperature[0u], dieTemperature[1u]) == CYRET_STARTED) { /* Plan for failure */ status = CYRET_UNKNOWN; while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } } else { status = CYRET_UNKNOWN; } } else { status = CYRET_UNKNOWN; } } else { if (CYRET_BAD_PARAM != status) { status = CYRET_UNKNOWN; } } CySpcUnlock(); } else { status = CYRET_LOCKED; } } else { status = CYRET_BAD_PARAM; } return (status); }
/******************************************************************************* * Function Name: EEPROM_Real_EraseSector ******************************************************************************** * * Summary: * Erases a sector of memory. This function blocks until the operation is * complete. * * Parameters: * sectorNumber: Sector number to erase. * * Return: * CYRET_SUCCESS, if the operation was successful. * CYRET_BAD_PARAM, if the parameter sectorNumber out of range. * CYRET_LOCKED, if the spc is being used. * CYRET_UNKNOWN, if there was an SPC error. * *******************************************************************************/ cystatus EEPROM_Real_EraseSector(uint8 sectorNumber) { cystatus status; /* Start the SPC */ CySpcStart(); if(sectorNumber < (uint8) CY_EEPROM_NUMBER_ARRAYS) { /* See if we can get the SPC. */ if(CySpcLock() == CYRET_SUCCESS) { #if(CY_PSOC5A) /* Plan for failure */ status = CYRET_UNKNOWN; /* Command to load a row of data */ if(CySpcLoadRow(CY_SPC_FIRST_EE_ARRAYID, 0, CYDEV_EEPROM_ROW_SIZE) == CYRET_STARTED) { while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } } /* Command to erase a sector */ if(status == CYRET_SUCCESS) { #endif /* (CY_PSOC5A) */ if(CySpcEraseSector(CY_SPC_FIRST_EE_ARRAYID, sectorNumber) == CYRET_STARTED) { /* Plan for failure */ status = CYRET_UNKNOWN; while(CY_SPC_BUSY) { /* Wait until SPC becomes idle */ } /* SPC is idle now */ if(CY_SPC_STATUS_SUCCESS == CY_SPC_READ_STATUS) { status = CYRET_SUCCESS; } } else { status = CYRET_UNKNOWN; } #if(CY_PSOC5A) } else { status = CYRET_UNKNOWN; } #endif /* (CY_PSOC5A) */ /* Unlock the SPC so someone else can use it. */ CySpcUnlock(); } else { status = CYRET_LOCKED; } } else { status = CYRET_BAD_PARAM; } return(status); }