/******************************************************************************* * Function Name: Cy_MCWDT_GetCountCascaded ****************************************************************************//** * * Reports the current value of combined C1-C0 cascaded counters. * * \param base * The base pointer to a structure that describes the registers. * * \note * The user must enable both counters, and cascade C0 to C1, * before calling this function. C2 is not reported. * Instead, to get a 64-bit C2-C1-C0 cascaded value, the * user must call this function followed by * Cy_MCWDT_GetCount(base, CY_MCWDT_COUNTER2), and then combine the results. * \note This function does not return the correct result when it is called * after the Cy_MCWDT_Enable() or Cy_MCWDT_ResetCounters() function with * a delay less than two lf_clk cycles. The recommended waitUs parameter * value is 100 us. * *******************************************************************************/ uint32_t Cy_MCWDT_GetCountCascaded(MCWDT_STRUCT_Type const *base) { uint32_t countVal = MCWDT_STRUCT_MCWDT_CNTLOW(base); uint32_t counter1 = countVal >> MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR1_Pos; uint32_t counter0 = countVal & MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR0_Msk; uint32_t match0 = _FLD2VAL(MCWDT_STRUCT_MCWDT_MATCH_WDT_MATCH0, MCWDT_STRUCT_MCWDT_MATCH(base)); uint32_t match1 = _FLD2VAL(MCWDT_STRUCT_MCWDT_MATCH_WDT_MATCH1, MCWDT_STRUCT_MCWDT_MATCH(base)); /* * The counter counter0 goes to zero when it reaches the match0 * value (c0ClearOnMatch = 1) or reaches the maximum * value (c0ClearOnMatch = 0). The counter counter1 increments on * the next rising edge of the MCWDT clock after * the Clear On Match event takes place. * The software increments counter1 to eliminate the case * when the both counter0 and counter1 counters have zeros. */ if (0u == counter0) { counter1++; } /* Check if the counter0 is Free running */ if (0u == _FLD2VAL(MCWDT_STRUCT_MCWDT_CONFIG_WDT_CLEAR0, MCWDT_STRUCT_MCWDT_CONFIG(base))) { /* Save match0 value with the correction when counter0 * goes to zero when it reaches the match0 value. */ countVal = match0 + 1u; if (0u < counter1) { /* Set match to the maximum value */ match0 = MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR0_Msk; } if (countVal < counter0) { /* Decrement counter1 when the counter0 is great than match0 value */ counter1--; } } /* Add the correction to counter0 */ counter0 += counter1; /* Set counter1 match value to 65535 when the counter1 is free running */ if (0u == _FLD2VAL(MCWDT_STRUCT_MCWDT_CONFIG_WDT_CLEAR1, MCWDT_STRUCT_MCWDT_CONFIG(base))) { match1 = MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR1_Msk >> MCWDT_STRUCT_MCWDT_CNTLOW_WDT_CTR1_Pos; }
/******************************************************************************* * Function Name: Cy_DMAC_Descriptor_GetNextDescriptor ****************************************************************************//** * * Returns a next descriptor address of the specified descriptor. * * Based on the descriptor type, the offset of the address for the next descriptor may * vary. For a single-transfer descriptor type, this register is at offset 0x0c. * For the 1D-transfer descriptor type, this register is at offset 0x10. * For the 2D-transfer descriptor type, this register is at offset 0x14. * * \param descriptor * The descriptor structure instance declared by the user/component. * * \return * The pointer to the next descriptor. * * \funcusage * \snippet dmac\1.0\snippet\main.c snippet_Cy_DMAC_Descriptor_GetNextDescriptor * *******************************************************************************/ cy_stc_dmac_descriptor_t * Cy_DMAC_Descriptor_GetNextDescriptor(cy_stc_dmac_descriptor_t const * descriptor) { cy_stc_dmac_descriptor_t * retVal = NULL; CY_ASSERT_L1(NULL != descriptor); switch((cy_en_dmac_descriptor_type_t) _FLD2VAL(DMAC_CH_V2_DESCR_CTL_DESCR_TYPE, descriptor->ctl)) { case CY_DMAC_SINGLE_TRANSFER: case CY_DMAC_SCATTER_TRANSFER: retVal = (cy_stc_dmac_descriptor_t*) descriptor->xSize; break; case CY_DMAC_1D_TRANSFER: retVal = (cy_stc_dmac_descriptor_t*) descriptor->ySize; break; case CY_DMAC_2D_TRANSFER: retVal = (cy_stc_dmac_descriptor_t*) descriptor->nextPtr; break; case CY_DMAC_MEMORY_COPY: retVal = (cy_stc_dmac_descriptor_t*) descriptor->xIncr; break; default: /* An unsupported type of the descriptor */ break; } return (retVal); }
/******************************************************************************* * Function Name: Cy_DMAC_Descriptor_SetNextDescriptor ****************************************************************************//** * * Sets a Next Descriptor parameter for the specified descriptor. * * Based on the descriptor type, the offset of the address for the next descriptor may * vary. For the single-transfer descriptor type, this register is at offset 0x0c. * For the 1D-transfer descriptor type, this register is at offset 0x10. * For the 2D-transfer descriptor type, this register is at offset 0x14. * * \param descriptor * The descriptor structure instance declared by the user/component. * * \param nextDescriptor * The pointer to the next descriptor. * * \funcusage * \snippet dmac\1.0\snippet\main.c snippet_Cy_DMAC_Descriptor_SetNextDescriptor * *******************************************************************************/ void Cy_DMAC_Descriptor_SetNextDescriptor(cy_stc_dmac_descriptor_t * descriptor, cy_stc_dmac_descriptor_t const * nextDescriptor) { CY_ASSERT_L1(NULL != descriptor); switch((cy_en_dmac_descriptor_type_t) _FLD2VAL(DMAC_CH_V2_DESCR_CTL_DESCR_TYPE, descriptor->ctl)) { case CY_DMAC_SINGLE_TRANSFER: case CY_DMAC_SCATTER_TRANSFER: descriptor->xSize = (uint32_t)nextDescriptor; break; case CY_DMAC_1D_TRANSFER: descriptor->ySize = (uint32_t)nextDescriptor; break; case CY_DMAC_2D_TRANSFER: descriptor->nextPtr = (uint32_t)nextDescriptor; break; case CY_DMAC_MEMORY_COPY: descriptor->xIncr = (uint32_t)nextDescriptor; break; default: /* Unsupported type of descriptor */ break; } }
/******************************************************************************* * Function Name: Cy_DMAC_Descriptor_GetXloopDataCount ****************************************************************************//** * * Returns the number of data elements for the X loop of the specified * descriptor (for 1D or 2D descriptors only). * * \param descriptor * The descriptor structure instance declared by the user/component. * * \return * The number of data elements to transfer in the X loop. * * \funcusage * \snippet dmac\1.0\snippet\main.c snippet_Cy_DMAC_Descriptor_GetNextDescriptor * *******************************************************************************/ uint32_t Cy_DMAC_Descriptor_GetXloopDataCount(cy_stc_dmac_descriptor_t const * descriptor) { CY_ASSERT_L1(NULL != descriptor); uint32_t retVal = 0UL; cy_en_dmac_descriptor_type_t locDescriptorType = Cy_DMAC_Descriptor_GetDescriptorType(descriptor); CY_ASSERT_L1(CY_DMAC_SINGLE_TRANSFER != locDescriptorType); /* Convert the data count from the machine range (0-65535) into the user's range (1-65536). */ if (CY_DMAC_SCATTER_TRANSFER == locDescriptorType) { retVal = _FLD2VAL(DMAC_CH_V2_DESCR_X_SIZE_X_COUNT, descriptor->dst) + 1UL; } else { retVal = _FLD2VAL(DMAC_CH_V2_DESCR_X_SIZE_X_COUNT, descriptor->xSize) + 1UL; } return (retVal); }
/******************************************************************************* * Function Name: Cy_Crypto_Core_V1_Aes_InvKey ****************************************************************************//** * * Calculates an inverse block cipher key from the block cipher key. * * \param base * The pointer to the CRYPTO instance. * * \param aesState * The pointer to the AES state structure allocated by the user. The user * must not modify anything in this structure. * *******************************************************************************/ static void Cy_Crypto_Core_V1_Aes_InvKey(CRYPTO_Type *base, cy_stc_crypto_aes_state_t const *aesState) { /* Issue the AES_KEY instruction to prepare the key for decrypt operation */ Cy_Crypto_SetReg2Instr(base, (uint32_t)aesState->key, (uint32_t)aesState->invKey); Cy_Crypto_Run2ParamInstr(base, CY_CRYPTO_V1_AES_KEY_OPC, CY_CRYPTO_RSRC0_SHIFT, CY_CRYPTO_RSRC8_SHIFT); /* Wait until the AES instruction is complete */ while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, REG_CRYPTO_STATUS(base))) { } }
/******************************************************************************* * Function Name: Cy_SysTick_GetClockSource ****************************************************************************//** * * Gets the clock source for the SysTick counter. * * \returns \ref cy_en_systick_clock_source_t Clock source * *******************************************************************************/ cy_en_systick_clock_source_t Cy_SysTick_GetClockSource(void) { cy_en_systick_clock_source_t returnValue; if ((SYSTICK_CTRL & SysTick_CTRL_CLKSOURCE_Msk) != 0u) { returnValue = CY_SYSTICK_CLOCK_SOURCE_CLK_CPU; } else { returnValue = (cy_en_systick_clock_source_t) ((uint32_t) _FLD2VAL(CPUSS_SYSTICK_CTL_CLOCK_SOURCE, CPUSS_SYSTICK_CTL)); } return(returnValue); }
/******************************************************************************* * Function Name: Cy_Crypto_Core_V1_Aes_ProcessBlock ****************************************************************************//** * * Performs the AES block cipher. * * \param base * The pointer to the CRYPTO instance. * * \param aesState * The pointer to the AES state structure allocated by the user. The user * must not modify anything in this structure. * * \param dirMode * One of CRYPTO_ENCRYPT or CRYPTO_DECRYPT. * * \param dstBlock * The pointer to the cipher text. * * \param srcBlock * The pointer to the plain text. Must be 4-Byte aligned! * *******************************************************************************/ void Cy_Crypto_Core_V1_Aes_ProcessBlock(CRYPTO_Type *base, cy_stc_crypto_aes_state_t const *aesState, cy_en_crypto_dir_mode_t dirMode, uint32_t *dstBlock, uint32_t const *srcBlock) { Cy_Crypto_SetReg3Instr(base, (CY_CRYPTO_DECRYPT == dirMode) ? (uint32_t)aesState->invKey : (uint32_t)aesState->key, (uint32_t)srcBlock, (uint32_t)dstBlock); Cy_Crypto_Run3ParamInstr(base, (CY_CRYPTO_DECRYPT == dirMode) ? CY_CRYPTO_V1_AES_BLOCK_INV_OPC : CY_CRYPTO_V1_AES_BLOCK_OPC, CY_CRYPTO_RSRC0_SHIFT, CY_CRYPTO_RSRC4_SHIFT, CY_CRYPTO_RSRC12_SHIFT); /* Wait until the AES instruction is complete */ while (0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, REG_CRYPTO_STATUS(base))) { } }
/******************************************************************************* * Function Name: Cy_Crypto_Core_V1_Aes_Xor ****************************************************************************//** * * Perform the XOR of two 16-Byte memory structures. * All addresses must be 4-Byte aligned! * * \param base * The pointer to the CRYPTO instance. * * \param aesState * The pointer to the AES state structure allocated by the user. The user * must not modify anything in this structure. * * \param dstBlock * The pointer to the memory structure with the XOR results. * * \param src0Block * The pointer to the first memory structure. Must be 4-Byte aligned! * * \param src1Block * The pointer to the second memory structure. Must be 4-Byte aligned! * *******************************************************************************/ void Cy_Crypto_Core_V1_Aes_Xor(CRYPTO_Type *base, cy_stc_crypto_aes_state_t const *aesState, uint32_t *dstBlock, uint32_t const *src0Block, uint32_t const *src1Block) { Cy_Crypto_SetReg3Instr(base, (uint32_t)src0Block, (uint32_t)src1Block, (uint32_t)dstBlock); /* Issue the AES_XOR instruction */ Cy_Crypto_Run3ParamInstr(base, CY_CRYPTO_V1_AES_XOR_OPC, CY_CRYPTO_RSRC0_SHIFT, CY_CRYPTO_RSRC4_SHIFT, CY_CRYPTO_RSRC8_SHIFT); /* Wait until the AES instruction is complete */ while(0uL != _FLD2VAL(CRYPTO_STATUS_AES_BUSY, REG_CRYPTO_STATUS(base))) { } }
/******************************************************************************* * Function Name: Cy_WDT_Locked ****************************************************************************//** * \internal * Reports the WDT lock state. * * \return true - if WDT is locked, and false - if WDT is unlocked. * \endinternal *******************************************************************************/ static bool Cy_WDT_Locked(void) { /* Prohibits writing to the WDT registers and LFCLK */ return (0u != _FLD2VAL(SRSS_WDT_CTL_WDT_LOCK, SRSS->WDT_CTL)); }
/******************************************************************************* * Function Name: SystemCoreClockUpdate ****************************************************************************//** * * Gets core clock frequency and updates \ref SystemCoreClock, \ref * cy_Hfclk0FreqHz, and \ref cy_PeriClkFreqHz. * * Updates global variables used by the \ref Cy_SysLib_Delay(), \ref * Cy_SysLib_DelayUs(), and \ref Cy_SysLib_DelayCycles(). * *******************************************************************************/ void SystemCoreClockUpdate (void) { uint32_t srcFreqHz; uint32_t pathFreqHz; uint32_t fastClkDiv; uint32_t periClkDiv; uint32_t rootPath; uint32_t srcClk; /* Get root path clock for the high-frequency clock # 0 */ rootPath = _FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_MUX, SRSS->CLK_ROOT_SELECT[0u]); /* Get source of the root path clock */ srcClk = _FLD2VAL(SRSS_CLK_PATH_SELECT_PATH_MUX, SRSS->CLK_PATH_SELECT[rootPath]); /* Get frequency of the source */ switch (srcClk) { case CY_ROOT_PATH_SRC_IMO: srcFreqHz = CY_CLK_IMO_FREQ_HZ; break; case CY_ROOT_PATH_SRC_EXT: srcFreqHz = CY_CLK_EXT_FREQ_HZ; break; #if (SRSS_ECO_PRESENT == 1U) case CY_ROOT_PATH_SRC_ECO: srcFreqHz = CY_CLK_ECO_FREQ_HZ; break; #endif /* (SRSS_ECO_PRESENT == 1U) */ #if defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U) case CY_ROOT_PATH_SRC_ALTHF: srcFreqHz = cy_BleEcoClockFreqHz; break; #endif /* defined (CY_IP_MXBLESS) && (CY_IP_MXBLESS == 1UL) && (SRSS_ALTHF_PRESENT == 1U) */ case CY_ROOT_PATH_SRC_DSI_MUX: { uint32_t dsi_src; dsi_src = _FLD2VAL(SRSS_CLK_DSI_SELECT_DSI_MUX, SRSS->CLK_DSI_SELECT[rootPath]); switch (dsi_src) { case CY_ROOT_PATH_SRC_DSI_MUX_HVILO: srcFreqHz = CY_CLK_HVILO_FREQ_HZ; break; case CY_ROOT_PATH_SRC_DSI_MUX_WCO: srcFreqHz = CY_CLK_WCO_FREQ_HZ; break; #if (SRSS_ALTLF_PRESENT == 1U) case CY_ROOT_PATH_SRC_DSI_MUX_ALTLF: srcFreqHz = CY_CLK_ALTLF_FREQ_HZ; break; #endif /* (SRSS_ALTLF_PRESENT == 1U) */ #if (SRSS_PILO_PRESENT == 1U) case CY_ROOT_PATH_SRC_DSI_MUX_PILO: srcFreqHz = CY_CLK_PILO_FREQ_HZ; break; #endif /* (SRSS_PILO_PRESENT == 1U) */ default: srcFreqHz = CY_CLK_HVILO_FREQ_HZ; break; } } break; default: srcFreqHz = CY_CLK_EXT_FREQ_HZ; break; } if (rootPath == 0UL) { /* FLL */ bool fllLocked = ( 0UL != _FLD2VAL(SRSS_CLK_FLL_STATUS_LOCKED, SRSS->CLK_FLL_STATUS)); bool fllOutputOutput = ( 3UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3)); bool fllOutputAuto = ((0UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3)) || (1UL == _FLD2VAL(SRSS_CLK_FLL_CONFIG3_BYPASS_SEL, SRSS->CLK_FLL_CONFIG3))); if ((fllOutputAuto && fllLocked) || fllOutputOutput) { uint32_t fllMult; uint32_t refDiv; uint32_t outputDiv; fllMult = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_MULT, SRSS->CLK_FLL_CONFIG); refDiv = _FLD2VAL(SRSS_CLK_FLL_CONFIG2_FLL_REF_DIV, SRSS->CLK_FLL_CONFIG2); outputDiv = _FLD2VAL(SRSS_CLK_FLL_CONFIG_FLL_OUTPUT_DIV, SRSS->CLK_FLL_CONFIG) + 1UL; pathFreqHz = ((srcFreqHz / refDiv) * fllMult) / outputDiv; } else { pathFreqHz = srcFreqHz; } } else if (rootPath == 1UL) { /* PLL */ bool pllLocked = ( 0UL != _FLD2VAL(SRSS_CLK_PLL_STATUS_LOCKED, SRSS->CLK_PLL_STATUS[0UL])); bool pllOutputOutput = ( 3UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[0UL])); bool pllOutputAuto = ((0UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[0UL])) || (1UL == _FLD2VAL(SRSS_CLK_PLL_CONFIG_BYPASS_SEL, SRSS->CLK_PLL_CONFIG[0UL]))); if ((pllOutputAuto && pllLocked) || pllOutputOutput) { uint32_t feedbackDiv; uint32_t referenceDiv; uint32_t outputDiv; feedbackDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_FEEDBACK_DIV, SRSS->CLK_PLL_CONFIG[0UL]); referenceDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_REFERENCE_DIV, SRSS->CLK_PLL_CONFIG[0UL]); outputDiv = _FLD2VAL(SRSS_CLK_PLL_CONFIG_OUTPUT_DIV, SRSS->CLK_PLL_CONFIG[0UL]); pathFreqHz = ((srcFreqHz * feedbackDiv) / referenceDiv) / outputDiv; } else { pathFreqHz = srcFreqHz; } } else { /* Direct */ pathFreqHz = srcFreqHz; } /* Get frequency after hf_clk pre-divider */ pathFreqHz = pathFreqHz >> _FLD2VAL(SRSS_CLK_ROOT_SELECT_ROOT_DIV, SRSS->CLK_ROOT_SELECT[0u]); cy_Hfclk0FreqHz = pathFreqHz; /* Fast Clock Divider */ fastClkDiv = 1u + _FLD2VAL(CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, CPUSS->CM4_CLOCK_CTL); /* Peripheral Clock Divider */ periClkDiv = 1u + _FLD2VAL(CPUSS_CM0_CLOCK_CTL_PERI_INT_DIV, CPUSS->CM0_CLOCK_CTL); cy_PeriClkFreqHz = pathFreqHz / periClkDiv; pathFreqHz = pathFreqHz / fastClkDiv; SystemCoreClock = pathFreqHz; /* Sets clock frequency for Delay API */ cy_delayFreqHz = SystemCoreClock; cy_delayFreqMhz = (uint8_t)((cy_delayFreqHz + CY_DELAY_1M_MINUS_1_THRESHOLD) / CY_DELAY_1M_THRESHOLD); cy_delayFreqKhz = (cy_delayFreqHz + CY_DELAY_1K_MINUS_1_THRESHOLD) / CY_DELAY_1K_THRESHOLD; cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD * cy_delayFreqKhz; }