SCSI2SD/software/SCSI2SD/v5.5/SCSI2SD.cydsn/Generated_Source/PSoC5/CySpc.c
2018-10-31 23:04:45 +10:00

694 lines
21 KiB
C
Executable File

/***************************************************************************//**
* \file CySpc.c
* \version 5.60
*
* \brief Provides an API for the System Performance Component.
* The SPC functions are not meant to be called directly by the user
* application.
*
********************************************************************************
* \copyright
* Copyright 2008-2017, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/
#include "CySpc.h"
#define CY_SPC_KEY_ONE (0xB6u)
#define CY_SPC_KEY_TWO(x) ((uint8) (((uint16) 0xD3u) + ((uint16) (x))))
/* Command Codes */
#define CY_SPC_CMD_LD_BYTE (0x00u)
#define CY_SPC_CMD_LD_MULTI_BYTE (0x01u)
#define CY_SPC_CMD_LD_ROW (0x02u)
#define CY_SPC_CMD_RD_BYTE (0x03u)
#define CY_SPC_CMD_RD_MULTI_BYTE (0x04u)
#define CY_SPC_CMD_WR_ROW (0x05u)
#define CY_SPC_CMD_WR_USER_NVL (0x06u)
#define CY_SPC_CMD_PRG_ROW (0x07u)
#define CY_SPC_CMD_ER_SECTOR (0x08u)
#define CY_SPC_CMD_ER_ALL (0x09u)
#define CY_SPC_CMD_RD_HIDDEN (0x0Au)
#define CY_SPC_CMD_PRG_PROTECT (0x0Bu)
#define CY_SPC_CMD_CHECKSUM (0x0Cu)
#define CY_SPC_CMD_DWNLD_ALGORITHM (0x0Du)
#define CY_SPC_CMD_GET_TEMP (0x0Eu)
#define CY_SPC_CMD_GET_ADC (0x0Fu)
#define CY_SPC_CMD_RD_NVL_VOLATILE (0x10u)
#define CY_SPC_CMD_SETUP_TS (0x11u)
#define CY_SPC_CMD_DISABLE_TS (0x12u)
#define CY_SPC_CMD_ER_ROW (0x13u)
/* Enable bit in Active and Alternate Active mode templates */
#define PM_SPC_PM_EN (0x08u)
/* Gate calls to the SPC. */
uint8 SpcLockState = CY_SPC_UNLOCKED;
#if(CY_PSOC5)
/***************************************************************************
* The wait-state pipeline must be enabled prior to accessing the SPC
* register interface regardless of CPU frequency. The CySpcLock() saves
* current wait-state pipeline state and enables it. The CySpcUnlock()
* function, which must be called after SPC transaction, restores original
* state.
***************************************************************************/
static uint32 spcWaitPipeBypass = 0u;
#endif /* (CY_PSOC5) */
/*******************************************************************************
* Function Name: CySpcStart
****************************************************************************//**
* Starts the SPC.
*
*******************************************************************************/
void CySpcStart(void)
{
/* Save current global interrupt enable and disable it */
uint8 interruptState = CyEnterCriticalSection();
CY_SPC_PM_ACT_REG |= PM_SPC_PM_EN;
CY_SPC_PM_STBY_REG |= PM_SPC_PM_EN;
/* Restore global interrupt enable state */
CyExitCriticalSection(interruptState);
}
/*******************************************************************************
* Function Name: CySpcStop
****************************************************************************//**
* Stops the SPC.
*
*******************************************************************************/
void CySpcStop(void)
{
/* Save current global interrupt enable and disable it */
uint8 interruptState = CyEnterCriticalSection();
CY_SPC_PM_ACT_REG &= ((uint8)(~PM_SPC_PM_EN));
CY_SPC_PM_STBY_REG &= ((uint8)(~PM_SPC_PM_EN));
/* Restore global interrupt enable state */
CyExitCriticalSection(interruptState);
}
/*******************************************************************************
* Function Name: CySpcReadData
****************************************************************************//**
* Reads data from the SPC.
*
* \param uint8 buffer:
* Address to store data read.
*
* \param uint8 size:
* Number of bytes to read from the SPC.
*
* \return
* uint8:
* The number of bytes read from the SPC.
*
*******************************************************************************/
uint8 CySpcReadData(uint8 buffer[], uint8 size)
{
uint8 i;
for(i = 0u; i < size; i++)
{
while(!CY_SPC_DATA_READY)
{
CyDelayUs(1u);
}
buffer[i] = CY_SPC_CPU_DATA_REG;
}
return(i);
}
/*******************************************************************************
* Function Name: CySpcLoadMultiByte
****************************************************************************//**
* Loads 1 to 32 bytes of data into the row latch of a Flash/EEPROM array.
*
* \param uint8 array:
* Id of the array.
*
* \param uint16 address:
* Flash/eeprom addrress
*
* \param uint8* buffer:
* Data to load to the row latch
*
* \param uint16 number:
* Number bytes to load.
*
* \return
* CYRET_STARTED
* CYRET_CANCELED
* CYRET_LOCKED
* CYRET_BAD_PARAM
*
*******************************************************************************/
cystatus CySpcLoadMultiByte(uint8 array, uint16 address, const uint8 buffer[], uint8 size)\
{
cystatus status = CYRET_STARTED;
uint8 i;
/***************************************************************************
* Check if number is correct for array. Number must be less than
* 32 for Flash or less than 16 for EEPROM.
***************************************************************************/
if(((array < CY_SPC_LAST_FLASH_ARRAYID) && (size < 32u)) ||
((array > CY_SPC_LAST_FLASH_ARRAYID) && (size < 16u)))
{
if(CY_SPC_IDLE)
{
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_ONE;
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_TWO(CY_SPC_CMD_LD_MULTI_BYTE);
CY_SPC_CPU_DATA_REG = CY_SPC_CMD_LD_MULTI_BYTE;
if(CY_SPC_BUSY)
{
CY_SPC_CPU_DATA_REG = array;
CY_SPC_CPU_DATA_REG = 1u & HI8(address);
CY_SPC_CPU_DATA_REG = LO8(address);
CY_SPC_CPU_DATA_REG = ((uint8)(size - 1u));
for(i = 0u; i < size; i++)
{
CY_SPC_CPU_DATA_REG = buffer[i];
}
}
else
{
status = CYRET_CANCELED;
}
}
else
{
status = CYRET_LOCKED;
}
}
else
{
status = CYRET_BAD_PARAM;
}
return(status);
}
/*******************************************************************************
* Function Name: CySpcLoadRow
****************************************************************************//**
* Loads a row of data into the row latch of a Flash/EEPROM array.
*
* The buffer pointer should point to the data that should be written to the
* flash row directly (no data in ECC/flash will be preserved). It is Flash API
* responsibility to prepare data: the preserved data are copied from flash into
* array with the modified data.
*
* \param uint8 array:
* Id of the array.
*
* \param uint8* buffer:
* Data to be loaded to the row latch
*
* \param uint8 size:
* The number of data bytes that the SPC expects to be written. Depends on the
* type of the array and, if the array is Flash, whether ECC is being enabled
* or not. There are following values: flash row latch size with ECC enabled,
* flash row latch size with ECC disabled and EEPROM row latch size.
*
* \return
* CYRET_STARTED
* CYRET_CANCELED
* CYRET_LOCKED
*
*******************************************************************************/
cystatus CySpcLoadRow(uint8 array, const uint8 buffer[], uint16 size)
{
cystatus status = CYRET_STARTED;
uint16 i;
/* Make sure the SPC is ready to accept command */
if(CY_SPC_IDLE)
{
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_ONE;
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_TWO(CY_SPC_CMD_LD_ROW);
CY_SPC_CPU_DATA_REG = CY_SPC_CMD_LD_ROW;
/* Make sure the command was accepted */
if(CY_SPC_BUSY)
{
CY_SPC_CPU_DATA_REG = array;
for(i = 0u; i < size; i++)
{
CY_SPC_CPU_DATA_REG = buffer[i];
}
}
else
{
status = CYRET_CANCELED;
}
}
else
{
status = CYRET_LOCKED;
}
return(status);
}
/*******************************************************************************
* Function Name: CySpcLoadRowFull
****************************************************************************//**
* Loads a row of data into the row latch of a Flash/EEPROM array.
*
* The only data that are going to be changed should be passed. The function
* will handle unmodified data preservation based on DWR settings and input
* parameters.
*
* \param uint8 array:
* Id of the array.
*
* \param uint16 row:
* Flash row number to be loaded.
*
* \param uint8* buffer:
* Data to be loaded to the row latch
*
* \param uint8 size:
* The number of data bytes that the SPC expects to be written. Depends on the
* type of the array and, if the array is Flash, whether ECC is being enabled
* or not. There are following values: flash row latch size with ECC enabled,
* flash row latch size with ECC disabled and EEPROM row latch size.
*
* \return
* CYRET_STARTED
* CYRET_CANCELED
* CYRET_LOCKED
*
*******************************************************************************/
cystatus CySpcLoadRowFull(uint8 array, uint16 row, const uint8 buffer[], uint16 size)\
{
cystatus status = CYRET_STARTED;
uint16 i;
#if (CYDEV_ECC_ENABLE == 0)
uint32 offset;
#endif /* (CYDEV_ECC_ENABLE == 0) */
/* Make sure the SPC is ready to accept command */
if(CY_SPC_IDLE)
{
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_ONE;
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_TWO(CY_SPC_CMD_LD_ROW);
CY_SPC_CPU_DATA_REG = CY_SPC_CMD_LD_ROW;
/* Make sure the command was accepted */
if(CY_SPC_BUSY)
{
CY_SPC_CPU_DATA_REG = array;
/*******************************************************************
* If "Enable Error Correcting Code (ECC)" and "Store Configuration
* Data in ECC" DWR options are disabled, ECC section is available
* for user data.
*******************************************************************/
#if ((CYDEV_ECC_ENABLE == 0u) && (CYDEV_CONFIGURATION_ECC == 0u))
/*******************************************************************
* If size parameter equals size of the ECC row and selected array
* identification corresponds to the flash array (but not to EEPROM
* array) then data are going to be written to the ECC section.
* In this case flash data must be preserved. The flash data copied
* from flash data section to the SPC data register.
*******************************************************************/
if ((size == CYDEV_ECC_ROW_SIZE) && (array <= CY_SPC_LAST_FLASH_ARRAYID))
{
offset = CYDEV_FLS_BASE +
((uint32) array * CYDEV_FLS_SECTOR_SIZE) +
((uint32) row * CYDEV_FLS_ROW_SIZE );
for (i = 0u; i < CYDEV_FLS_ROW_SIZE; i++)
{
CY_SPC_CPU_DATA_REG = CY_GET_XTND_REG8((void CYFAR *)(offset + i));
}
}
#endif /* ((CYDEV_ECC_ENABLE == 0u) && (CYDEV_CONFIGURATION_ECC == 0u)) */
for(i = 0u; i < size; i++)
{
CY_SPC_CPU_DATA_REG = buffer[i];
}
/*******************************************************************
* If "Enable Error Correcting Code (ECC)" DWR option is disabled,
* ECC section can be used for storing device configuration data
* ("Store Configuration Data in ECC" DWR option is enabled) or for
* storing user data in the ECC section ("Store Configuration Data in
* ECC" DWR option is enabled). In both cases, the data in the ECC
* section must be preserved if flash data is written.
*******************************************************************/
#if (CYDEV_ECC_ENABLE == 0)
/*******************************************************************
* If size parameter equals size of the flash row and selected array
* identification corresponds to the flash array (but not to EEPROM
* array) then data are going to be written to the flash data
* section. In this case, ECC section data must be preserved.
* The ECC section data copied from ECC section to the SPC data
* register.
*******************************************************************/
if ((size == CYDEV_FLS_ROW_SIZE) && (array <= CY_SPC_LAST_FLASH_ARRAYID))
{
offset = CYDEV_ECC_BASE +
((uint32) array * CYDEV_ECC_SECTOR_SIZE) +
((uint32) row * CYDEV_ECC_ROW_SIZE );
for (i = 0u; i < CYDEV_ECC_ROW_SIZE; i++)
{
CY_SPC_CPU_DATA_REG = CY_GET_XTND_REG8((void CYFAR *)(offset + i));
}
}
#else
if(0u != row)
{
/* To remove unreferenced local variable warning */
}
#endif /* (CYDEV_ECC_ENABLE == 0) */
}
else
{
status = CYRET_CANCELED;
}
}
else
{
status = CYRET_LOCKED;
}
return(status);
}
/*******************************************************************************
* Function Name: CySpcWriteRow
****************************************************************************//**
* Erases then programs a row in Flash/EEPROM with data in row latch.
*
* \param uint8 array:
* Id of the array.
*
* \param uint16 address:
* flash/eeprom addrress
*
* \param uint8 tempPolarity:
* temperature polarity.
* \param 1: the Temp Magnitude is interpreted as a positive value
* \param 0: the Temp Magnitude is interpreted as a negative value
*
* \param uint8 tempMagnitude:
* temperature magnitude.
*
* \return
* CYRET_STARTED
* CYRET_CANCELED
* CYRET_LOCKED
*
*******************************************************************************/
cystatus CySpcWriteRow(uint8 array, uint16 address, uint8 tempPolarity, uint8 tempMagnitude)\
{
cystatus status = CYRET_STARTED;
/* Make sure the SPC is ready to accept command */
if(CY_SPC_IDLE)
{
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_ONE;
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_TWO(CY_SPC_CMD_WR_ROW);
CY_SPC_CPU_DATA_REG = CY_SPC_CMD_WR_ROW;
/* Make sure the command was accepted */
if(CY_SPC_BUSY)
{
CY_SPC_CPU_DATA_REG = array;
CY_SPC_CPU_DATA_REG = HI8(address);
CY_SPC_CPU_DATA_REG = LO8(address);
CY_SPC_CPU_DATA_REG = tempPolarity;
CY_SPC_CPU_DATA_REG = tempMagnitude;
}
else
{
status = CYRET_CANCELED;
}
}
else
{
status = CYRET_LOCKED;
}
return(status);
}
/*******************************************************************************
* Function Name: CySpcEraseSector
****************************************************************************//**
* Erases all data in the addressed sector (block of 64 rows).
*
* \param uint8 array:
* Id of the array.
*
* \param uint8 sectorNumber:
* Zero based sector number within Flash/EEPROM array
*
* \return
* CYRET_STARTED
* CYRET_CANCELED
* CYRET_LOCKED
*
*******************************************************************************/
cystatus CySpcEraseSector(uint8 array, uint8 sectorNumber)
{
cystatus status = CYRET_STARTED;
/* Make sure the SPC is ready to accept command */
if(CY_SPC_IDLE)
{
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_ONE;
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_TWO(CY_SPC_CMD_ER_SECTOR);
CY_SPC_CPU_DATA_REG = CY_SPC_CMD_ER_SECTOR;
/* Make sure the command was accepted */
if(CY_SPC_BUSY)
{
CY_SPC_CPU_DATA_REG = array;
CY_SPC_CPU_DATA_REG = sectorNumber;
}
else
{
status = CYRET_CANCELED;
}
}
else
{
status = CYRET_LOCKED;
}
return(status);
}
/*******************************************************************************
* Function Name: CySpcGetTemp
****************************************************************************//**
* Returns the internal die temperature
*
* \param uint8 numSamples:
* Number of samples. Valid values are 1-5, resulting in 2 - 32 samples
* respectively.
*
* \param uint16 timerPeriod:
* Number of ADC ACLK cycles. A valid 14 bit value is accepted, higher 2 bits
* of 16 bit values are ignored.
*
* \param uint8 clkDivSelect:
* ADC ACLK clock divide value. Valid values are 2 - 225.
*
* \return
* CYRET_STARTED
* CYRET_CANCELED
* CYRET_LOCKED
*
*******************************************************************************/
cystatus CySpcGetTemp(uint8 numSamples)
{
cystatus status = CYRET_STARTED;
/* Make sure the SPC is ready to accept command */
if(CY_SPC_IDLE)
{
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_ONE;
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_TWO(CY_SPC_CMD_GET_TEMP);
CY_SPC_CPU_DATA_REG = CY_SPC_CMD_GET_TEMP;
/* Make sure the command was accepted */
if(CY_SPC_BUSY)
{
CY_SPC_CPU_DATA_REG = numSamples;
}
else
{
status = CYRET_CANCELED;
}
}
else
{
status = CYRET_LOCKED;
}
return(status);
}
/*******************************************************************************
* Function Name: CySpcLock
****************************************************************************//**
* Locks the SPC so it can not be used by someone else:
* - Saves wait-pipeline enable state and enable pipeline (PSoC5)
*
* \return
* CYRET_SUCCESS - if the resource was free.
* CYRET_LOCKED - if the SPC is in use.
*
*******************************************************************************/
cystatus CySpcLock(void)
{
cystatus status = CYRET_LOCKED;
uint8 interruptState;
/* Enter critical section */
interruptState = CyEnterCriticalSection();
if(CY_SPC_UNLOCKED == SpcLockState)
{
SpcLockState = CY_SPC_LOCKED;
status = CYRET_SUCCESS;
#if(CY_PSOC5)
if(0u != (CY_SPC_CPU_WAITPIPE_REG & CY_SPC_CPU_WAITPIPE_BYPASS))
{
/* Enable pipeline registers */
CY_SPC_CPU_WAITPIPE_REG &= ((uint32)(~CY_SPC_CPU_WAITPIPE_BYPASS));
/* At least 2 NOP instructions are recommended */
CY_NOP;
CY_NOP;
CY_NOP;
spcWaitPipeBypass = CY_SPC_CPU_WAITPIPE_BYPASS;
}
#endif /* (CY_PSOC5) */
}
/* Exit critical section */
CyExitCriticalSection(interruptState);
return(status);
}
/*******************************************************************************
* Function Name: CySpcUnlock
****************************************************************************//**
* Unlocks the SPC so it can be used by someone else:
* - Restores wait-pipeline enable state (PSoC5)
*
*******************************************************************************/
void CySpcUnlock(void)
{
uint8 interruptState;
/* Enter critical section */
interruptState = CyEnterCriticalSection();
/* Release the SPC object */
SpcLockState = CY_SPC_UNLOCKED;
#if(CY_PSOC5)
if(CY_SPC_CPU_WAITPIPE_BYPASS == spcWaitPipeBypass)
{
/* Force to bypass pipeline registers */
CY_SPC_CPU_WAITPIPE_REG |= CY_SPC_CPU_WAITPIPE_BYPASS;
/* At least 2 NOP instructions are recommended */
CY_NOP;
CY_NOP;
CY_NOP;
spcWaitPipeBypass = 0u;
}
#endif /* (CY_PSOC5) */
/* Exit critical section */
CyExitCriticalSection(interruptState);
}
/*******************************************************************************
* Function Name: CySpcGetAlgorithm
****************************************************************************//**
* Downloads SPC algorithm from SPC SROM into SRAM.
*
* \return
* CYRET_STARTED
* CYRET_LOCKED
*
*******************************************************************************/
cystatus CySpcGetAlgorithm(void)
{
cystatus status = CYRET_STARTED;
/* Make sure the SPC is ready to accept command */
if(CY_SPC_IDLE)
{
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_ONE;
CY_SPC_CPU_DATA_REG = CY_SPC_KEY_TWO(CY_SPC_CMD_DWNLD_ALGORITHM);
CY_SPC_CPU_DATA_REG = CY_SPC_CMD_DWNLD_ALGORITHM;
}
else
{
status = CYRET_LOCKED;
}
return(status);
}
/* [] END OF FILE */