/***************************************************************************//** * \file cy_pdm_pcm_v2.c * \version 2.20 * * The source code file for the PDM_PCM driver. * ******************************************************************************** * \copyright * Copyright 2016-2019 Cypress Semiconductor Corporation * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ #include "cy_device.h" #if defined (CY_IP_MXPDM) #include "cy_pdm_pcm_v2.h" /** * \addtogroup group_pdm_pcm_functions_v2 * \{ */ /****************************************************************************** * Function Name: Cy_PDM_PCM_Channel_Init ***************************************************************************//** * * Initialize the PDM-PCM Channel * * \pre If the PDM-PCM module is initialized previously, the * * \param base The pointer to the PDM-PCM instance address * \param chan_config The pointer to a configuration structure. * \param channel_num The channel number to be initialized. * \return error / status code. See \ref cy_en_pdm_pcm_status_t. * *******************************************************************************/ cy_en_pdm_pcm_status_t Cy_PDM_PCM_Channel_Init(PDM_Type * base, cy_stc_pdm_pcm_channel_config_t const * chan_config, uint8_t channel_num) { cy_en_pdm_pcm_status_t ret = CY_PDM_PCM_BAD_PARAM; if((NULL != base) && (NULL != chan_config)) { CY_ASSERT_L2(CY_PDM_PCM_IS_WORD_SIZE_VALID(chan_config->wordSize)); CY_ASSERT_L2(CY_PDM_PCM_IS_SIGNEXTENSION_VALID(chan_config->signExtension)); CY_ASSERT_L2(CY_PDM_PCM_IS_TRIG_LEVEL(chan_config->rxFifoTriggerLevel)); CY_ASSERT_L2(CY_PDM_PCM_IS_SCALE_VALID(chan_config->fir0_scale)); CY_ASSERT_L2(CY_PDM_PCM_IS_SCALE_VALID(chan_config->fir1_scale)); ret = CY_PDM_PCM_SUCCESS; PDM_PCM_RX_FIFO_CTL(base, channel_num) = _VAL2FLD(PDM_CH_RX_FIFO_CTL_TRIGGER_LEVEL, chan_config->rxFifoTriggerLevel); PDM_PCM_CH_CTL(base, channel_num) = _VAL2FLD(PDM_CH_CTL_WORD_SIZE, chan_config->wordSize) | _BOOL2FLD(PDM_CH_CTL_WORD_SIGN_EXTEND, chan_config->signExtension) | _BOOL2FLD(PDM_CH_CTL_ENABLED, CY_PDM_PCM_ENABLE); PDM_PCM_CH_IF_CTL(base, channel_num) = _VAL2FLD(PDM_CH_IF_CTL_SAMPLE_DELAY, chan_config->sampledelay); PDM_PCM_CH_CIC_CTL(base, channel_num) = chan_config->cic_decim_code; PDM_PCM_CH_FIR0_CTL(base, channel_num) = _VAL2FLD(PDM_CH_FIR0_CTL_DECIM3, chan_config->fir0_decim_code) | _VAL2FLD(PDM_CH_FIR0_CTL_SCALE, chan_config->fir0_scale) | _VAL2FLD(PDM_CH_FIR0_CTL_ENABLED, chan_config->fir0_enable); PDM_PCM_CH_FIR1_CTL(base, channel_num) = _VAL2FLD(PDM_CH_FIR1_CTL_DECIM2, chan_config->fir1_decim_code) | _VAL2FLD(PDM_CH_FIR1_CTL_SCALE, chan_config->fir1_scale) | _VAL2FLD(PDM_CH_FIR1_CTL_ENABLED, CY_PDM_PCM_ENABLE); PDM_PCM_CH_DC_BLOCK_CTL(base, channel_num) = _VAL2FLD(PDM_CH_DC_BLOCK_CTL_CODE, chan_config->dc_block_code) | _VAL2FLD(PDM_CH_DC_BLOCK_CTL_ENABLED, CY_PDM_PCM_ENABLE); } return ret; } /****************************************************************************** * Function Name: Cy_PDM_PCM_Init ***************************************************************************//** * * Initialize the PDM-PCM module * * \pre If the PDM-PCM module is initialized previously, the * * \param base The pointer to the PDM-PCM instance address * \param config The pointer to a configuration structure. * \return error / status code. See \ref cy_en_pdm_pcm_status_t. * *******************************************************************************/ cy_en_pdm_pcm_status_t Cy_PDM_PCM_Init(PDM_Type * base, cy_stc_pdm_pcm_config_v2_t const * config) { cy_en_pdm_pcm_status_t ret = CY_PDM_PCM_BAD_PARAM; if((NULL != base) && (NULL != config)) { CY_ASSERT_L2(CY_PDM_PCM_IS_CLK_SEL_VALID(config->clksel)); CY_ASSERT_L2(CY_PDM_PCM_IS_HALVE_RATE_SET_VALID(config->halverate)); CY_ASSERT_L2(CY_PDM_PCM_IS_ROUTE_VALID(config->route)); ret = CY_PDM_PCM_SUCCESS; /* The clock setting */ PDM_PCM_CLOCK_CTL(base) = _VAL2FLD(PDM_CLOCK_CTL_CLOCK_DIV, config->clkDiv) | _VAL2FLD(PDM_CLOCK_CTL_CLOCK_SEL, config->clksel) | _VAL2FLD(PDM_CLOCK_CTL_HALVE, config->halverate); /* PDM-PCM ROUTE setting */ PDM_PCM_ROUTE_CTL(base) = _VAL2FLD(PDM_ROUTE_CTL_DATA_SEL, config->route); if(config->fir0_coeff_user_value) { PDM_PCM_FIR0_COEFF0(base) = _VAL2FLD(PDM_FIR0_COEFF0_DATA0, config->fir0_coeff[0].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF0_DATA1, config->fir0_coeff[0].coeff_data1); PDM_PCM_FIR0_COEFF1(base) = _VAL2FLD(PDM_FIR0_COEFF1_DATA0, config->fir0_coeff[1].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF1_DATA1, config->fir0_coeff[1].coeff_data1); PDM_PCM_FIR0_COEFF2(base) = _VAL2FLD(PDM_FIR0_COEFF2_DATA0, config->fir0_coeff[2].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF2_DATA1, config->fir0_coeff[2].coeff_data1); PDM_PCM_FIR0_COEFF3(base) = _VAL2FLD(PDM_FIR0_COEFF3_DATA0, config->fir0_coeff[3].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF3_DATA1, config->fir0_coeff[3].coeff_data1); PDM_PCM_FIR0_COEFF4(base) = _VAL2FLD(PDM_FIR0_COEFF4_DATA0, config->fir0_coeff[4].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF4_DATA1, config->fir0_coeff[4].coeff_data1); PDM_PCM_FIR0_COEFF5(base) = _VAL2FLD(PDM_FIR0_COEFF5_DATA0, config->fir0_coeff[5].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF5_DATA1, config->fir0_coeff[5].coeff_data1); PDM_PCM_FIR0_COEFF6(base) = _VAL2FLD(PDM_FIR0_COEFF6_DATA0, config->fir0_coeff[6].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF6_DATA1, config->fir0_coeff[6].coeff_data1); PDM_PCM_FIR0_COEFF7(base) = _VAL2FLD(PDM_FIR0_COEFF7_DATA0, config->fir0_coeff[7].coeff_data0) | _VAL2FLD(PDM_FIR0_COEFF7_DATA1, config->fir0_coeff[7].coeff_data1); } if(config->fir1_coeff_user_value) { PDM_PCM_FIR1_COEFF0(base) = _VAL2FLD(PDM_FIR1_COEFF0_DATA0, config->fir1_coeff[0].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF0_DATA1, config->fir1_coeff[0].coeff_data1); PDM_PCM_FIR1_COEFF1(base) = _VAL2FLD(PDM_FIR1_COEFF1_DATA0, config->fir1_coeff[1].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF1_DATA1, config->fir1_coeff[1].coeff_data1); PDM_PCM_FIR1_COEFF2(base) = _VAL2FLD(PDM_FIR1_COEFF2_DATA0, config->fir1_coeff[2].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF2_DATA1, config->fir1_coeff[2].coeff_data1); PDM_PCM_FIR1_COEFF3(base) = _VAL2FLD(PDM_FIR1_COEFF3_DATA0, config->fir1_coeff[3].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF3_DATA1, config->fir1_coeff[3].coeff_data1); PDM_PCM_FIR1_COEFF4(base) = _VAL2FLD(PDM_FIR1_COEFF4_DATA0, config->fir1_coeff[4].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF4_DATA1, config->fir1_coeff[4].coeff_data1); PDM_PCM_FIR1_COEFF5(base) = _VAL2FLD(PDM_FIR1_COEFF5_DATA0, config->fir1_coeff[5].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF5_DATA1, config->fir1_coeff[5].coeff_data1); PDM_PCM_FIR1_COEFF6(base) = _VAL2FLD(PDM_FIR1_COEFF6_DATA0, config->fir1_coeff[6].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF6_DATA1, config->fir1_coeff[6].coeff_data1); PDM_PCM_FIR1_COEFF7(base) = _VAL2FLD(PDM_FIR1_COEFF7_DATA0, config->fir1_coeff[7].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF7_DATA1, config->fir1_coeff[7].coeff_data1); PDM_PCM_FIR1_COEFF8(base) = _VAL2FLD(PDM_FIR1_COEFF8_DATA0, config->fir1_coeff[8].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF8_DATA1, config->fir1_coeff[8].coeff_data1); PDM_PCM_FIR1_COEFF9(base) = _VAL2FLD(PDM_FIR1_COEFF9_DATA0, config->fir1_coeff[9].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF9_DATA1, config->fir1_coeff[9].coeff_data1); PDM_PCM_FIR1_COEFF10(base) = _VAL2FLD(PDM_FIR1_COEFF10_DATA0, config->fir1_coeff[10].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF10_DATA1, config->fir1_coeff[10].coeff_data1); PDM_PCM_FIR1_COEFF11(base) = _VAL2FLD(PDM_FIR1_COEFF11_DATA0, config->fir1_coeff[11].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF11_DATA1, config->fir1_coeff[11].coeff_data1); PDM_PCM_FIR1_COEFF12(base) = _VAL2FLD(PDM_FIR1_COEFF12_DATA0, config->fir1_coeff[12].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF12_DATA1, config->fir1_coeff[12].coeff_data1); PDM_PCM_FIR1_COEFF13(base) = _VAL2FLD(PDM_FIR1_COEFF13_DATA0, config->fir1_coeff[13].coeff_data0) | _VAL2FLD(PDM_FIR1_COEFF13_DATA1, config->fir1_coeff[13].coeff_data1); } } return (ret); } /****************************************************************************** * Function Name: Cy_PDM_PCM_test_Init ***************************************************************************//** * * Initialize the PDM-PCM module * * \pre If the PDM-PCM module is initialized previously, the * * \param base The pointer to the PDM-PCM instance address * \param config The pointer to a configuration structure. * \param test_config test_config * \return error / status code. See \ref cy_en_pdm_pcm_status_t. * *******************************************************************************/ cy_en_pdm_pcm_status_t Cy_PDM_PCM_test_Init(PDM_Type * base, cy_stc_pdm_pcm_config_v2_t const * config, cy_stc_test_config_t const * test_config) { cy_en_pdm_pcm_status_t ret = CY_PDM_PCM_BAD_PARAM; if((NULL != base) && (NULL != config) && (NULL != test_config) ) { if(!test_config->enable) { return ret; } CY_ASSERT_L2(CY_PDM_PCM_IS_CLK_SEL_VALID(config->clksel)); CY_ASSERT_L2(CY_PDM_PCM_IS_HALVE_RATE_SET_VALID(config->halverate)); CY_ASSERT_L2(CY_PDM_PCM_IS_ROUTE_VALID(config->route)); ret = CY_PDM_PCM_SUCCESS; PDM_PCM_TEST_CTL(base) = _VAL2FLD(PDM_TEST_CTL_DRIVE_DELAY_HI, test_config->drive_delay_hi) | _VAL2FLD(PDM_TEST_CTL_DRIVE_DELAY_LO, test_config->drive_delay_lo); PDM_PCM_TEST_CTL(base) |= _VAL2FLD(PDM_TEST_CTL_MODE_HI, test_config->mode_hi) | _VAL2FLD(PDM_TEST_CTL_MODE_LO, test_config->mode_lo); PDM_PCM_TEST_CTL(base) |= _VAL2FLD(PDM_TEST_CTL_AUDIO_FREQ_DIV, test_config->audio_freq_div) | _BOOL2FLD(PDM_TEST_CTL_CH_ENABLED, test_config->enable); } return (ret); } /******************************************************************************* * Function Name: Cy_PDM_PCM_Channel_DeInit ****************************************************************************//** * * Uninitializes the PDM-PCM channel. * * \param base The pointer to the PDM-PCM instance address. * \param channel_num channel number to be de initialized. * *******************************************************************************/ void Cy_PDM_PCM_Channel_DeInit(PDM_Type * base, uint8_t channel_num) { PDM_PCM_CH_IF_CTL(base, channel_num) = CY_PDM_PCM_CH_IF_CTL_DEFAULT;/* Channel interface control default value */ PDM_PCM_CH_CTL(base, channel_num) = CY_PDM_PCM_CH_CTL_DEFAULT; /* Channel control default values */ PDM_PCM_CH_CIC_CTL(base, channel_num) = CY_PDM_PCM_CH_CIC_DECIM_CODE_DEFAULT; PDM_PCM_CH_FIR1_CTL(base, channel_num) = CY_PDM_PCM_CH_FIR1_DEFAULT; PDM_PCM_CH_DC_BLOCK_CTL(base, channel_num) = CY_PDM_PCM_CH_DCBLOCK_DEFAULT; PDM_PCM_CH_FIR0_CTL(base, channel_num) = 0UL; PDM_PCM_INTR_RX_MASK(base, channel_num) = 0UL; /* Disable interrupts */ PDM_PCM_RX_FIFO_CTL(base, channel_num) = 0UL; PDM_PCM_CTL_CLR(base) = (1 << channel_num); } /******************************************************************************* * Function Name: Cy_PDM_PCM_DeInit ****************************************************************************//** * * Uninitializes the PDM-PCM module. * * \param base The pointer to the PDM-PCM instance address. * *******************************************************************************/ void Cy_PDM_PCM_DeInit(PDM_Type * base) { PDM_PCM_ROUTE_CTL(base) = 0UL; /* Default Route settings */ PDM_PCM_TEST_CTL(base) = CY_PDM_PCM_TEST_CTL_DEFAULT; /* Default Test settings */ PDM_PCM_CTL(base) = 0UL; /* Disable the PDM_PCM IP block */ PDM_PCM_CLOCK_CTL(base) = CY_PDM_PCM_CLK_CTL_DEFAULT; /* The default clock settings */ } /** \} group_pdm_pcm_functions_v2 */ #endif /* CY_IP_MXPDM */ /* [] END OF FILE */