LPC55S68 做 4slot,32bit TDM。只有一个 slot 的信号出来。下面是 I2S 的配置:
void I2S_TxGetDefaultConfig(i2s_config_t *config) { config->masterSlave = kI2S_MasterSlaveNormalMaster;//kI2S_MasterSlaveNormalMaster; config->mode = kI2S_ModeDspWsShort;//kI2S_ModeDspWsLong;kI2S_ModeDspWs50;//kI2S_ModeI2sClassic; config->rightLow = false; config->leftJust = false; #if (defined(FSL_FEATURE_FLEXCOMM_I2S_HAS_DMIC_INTERCONNECTION) && FSL_FEATURE_FLEXCOMM_I2S_HAS_DMIC_INTERCONNECTION) config->pdmData = false; #endif config->sckPol = false; config->wsPol = true ;//false; config->divider = 1U; config->oneChannel = false; config->dataLength = 32; //16U; config->frameLength = 32 * 2 * 4; // 32bit ,2ch , 4 slot config->position = 0U; config->watermark = 4U; config->txEmptyZero = true; config->pack48 = false;
}
这个是 main.c:
/* * Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */
/******************************************************************************* * Includes ******************************************************************************/
#include "fsl_device_registers.h" #include "fsl_debug_console.h" #include "board.h" #include "fsl_i2c.h" #include "fsl_i2s.h" #include "fsl_wm8904.h" #include "music.h" #include "fsl_codec_common.h" #include <stdbool.h> #include "pin_mux.h" #include "fsl_sysctl.h" #include "fsl_codec_adapter.h" /******************************************************************************* * Definitions ******************************************************************************/
#define DEMO_I2C (I2C4) #define DEMO_I2S_MASTER_CLOCK_FREQUENCY 24576000 #define DEMO_I2S_TX (I2S7) #define DEMO_I2S_RX (I2S6) #define I2S_CLOCK_DIVIDER (CLOCK_GetPll0OutFreq() / 48000U / 16U / 2U / 2 ) #define DEMO_AUDIO_BIT_WIDTH (16) #define DEMO_AUDIO_SAMPLE_RATE (48000) #define DEMO_AUDIO_PROTOCOL kCODEC_BusI2S
/******************************************************************************* * Prototypes ******************************************************************************/
static void StartSoundPlayback(void);
static void StartDigitalLoopback(void);
static void TxCallback(I2S_Type *base, i2s_handle_t *handle, status_t completionStatus, void *userData);
static void RxCallback(I2S_Type *base, i2s_handle_t *handle, status_t completionStatus, void *userData);
/******************************************************************************* * Variables ******************************************************************************/ wm8904_config_t wm8904Config = { .i2cConfig = {.codecI2CInstance = BOARD_CODEC_I2C_INSTANCE, .codecI2CSourceClock = BOARD_CODEC_I2C_CLOCK_FREQ}, .recordSource = kWM8904_RecordSourceLineInput, .recordChannelLeft = kWM8904_RecordChannelLeft2, .recordChannelRight = kWM8904_RecordChannelRight2, .playSource = kWM8904_PlaySourceDAC, .slaveAddress = WM8904_I2C_ADDRESS, .protocol = kWM8904_ProtocolI2S, .format = {.sampleRate = kWM8904_SampleRate48kHz, .bitWidth = kWM8904_BitWidth16}, .mclk_HZ = DEMO_I2S_MASTER_CLOCK_FREQUENCY, .master = false, }; codec_config_t boardCodecConfig = {.codecDevType = kCODEC_WM8904, .codecDevConfig = &wm8904Config};
__ALIGN_BEGIN static uint8_t s_Buffer[400] __ALIGN_END; /* 100 samples => time about 2 ms */ static i2s_config_t s_TxConfig; static i2s_config_t s_RxConfig; static i2s_handle_t s_TxHandle;
static i2s_handle_t s_RxHandle; static i2s_transfer_t s_TxTransfer;
static i2s_transfer_t s_RxTransfer; extern codec_config_t boardCodecConfig; uint8_t codecHandleBuffer[CODEC_HANDLE_SIZE] = {0U}; codec_handle_t *codecHandle = (codec_handle_t *)codecHandleBuffer; /******************************************************************************* * Code ******************************************************************************/ void BOARD_InitSysctrl(void) { SYSCTL_Init(SYSCTL); /* select signal source for share set */ SYSCTL_SetShareSignalSrc(SYSCTL, kSYSCTL_ShareSet0, kSYSCTL_SharedCtrlSignalSCK, kSYSCTL_Flexcomm7); SYSCTL_SetShareSignalSrc(SYSCTL, kSYSCTL_ShareSet0, kSYSCTL_SharedCtrlSignalWS, kSYSCTL_Flexcomm7); /* select share set for special flexcomm signal */ SYSCTL_SetShareSet(SYSCTL, kSYSCTL_Flexcomm7, kSYSCTL_FlexcommSignalSCK, kSYSCTL_ShareSet0); SYSCTL_SetShareSet(SYSCTL, kSYSCTL_Flexcomm7, kSYSCTL_FlexcommSignalWS, kSYSCTL_ShareSet0); SYSCTL_SetShareSet(SYSCTL, kSYSCTL_Flexcomm6, kSYSCTL_FlexcommSignalSCK, kSYSCTL_ShareSet0); SYSCTL_SetShareSet(SYSCTL, kSYSCTL_Flexcomm6, kSYSCTL_FlexcommSignalWS, kSYSCTL_ShareSet0);
}
/*! * @brief Main function */ int main(void) { CLOCK_EnableClock(kCLOCK_InputMux); CLOCK_EnableClock(kCLOCK_Iocon); CLOCK_EnableClock(kCLOCK_Gpio0); CLOCK_EnableClock(kCLOCK_Gpio1);
/* USART0 clock */ CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
/* I2C clock */ CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);
PMC->PDRUNCFGCLR0 |= PMC_PDSLEEPCFG0_PDEN_XTAL32M_MASK; /*!< Ensure XTAL16M is on */ PMC->PDRUNCFGCLR0 |= PMC_PDSLEEPCFG0_PDEN_LDOXO32M_MASK; /*!< Ensure XTAL16M is on */ SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /*!< Ensure CLK_IN is on */ ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK;
CLOCK_AttachClk(kEXT_CLK_to_PLL0);
const pll_setup_t pll0Setup = { .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(8U) | SYSCON_PLL0CTRL_SELP(31U), .pllndec = SYSCON_PLL0NDEC_NDIV(125U), .pllpdec = SYSCON_PLL0PDEC_PDIV(8U), .pllsscg = {0x0U, (SYSCON_PLL0SSCG1_MDIV_EXT(3072U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, .pllRate = 24576000U, .flags = PLL_SETUPFLAG_WAITLOCK, }; /*!< Configure PLL to the desired values */ CLOCK_SetPLL0Freq(&pll0Setup);
/* Attach PLL clock to MCLK for I2S, no divider */ CLOCK_AttachClk(kPLL0_to_MCLK); SYSCON->MCLKDIV = SYSCON_MCLKDIV_DIV(0U); SYSCON->MCLKIO = 1U;
CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 1U, true); CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 1U, false);
/*!< Switch PLL0 clock source selector to XTAL16M */ /* I2S clocks */ CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM6); CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM7);
/* reset FLEXCOMM for I2C */ RESET_PeripheralReset(kFC4_RST_SHIFT_RSTn);
/* reset FLEXCOMM for I2S */ RESET_PeripheralReset(kFC6_RST_SHIFT_RSTn); RESET_PeripheralReset(kFC7_RST_SHIFT_RSTn); RESET_PeripheralReset(kFC5_RST_SHIFT_RSTn);
NVIC_ClearPendingIRQ(FLEXCOMM6_IRQn); NVIC_ClearPendingIRQ(FLEXCOMM7_IRQn);
/* Enable interrupts for I2S */ EnableIRQ(FLEXCOMM6_IRQn); EnableIRQ(FLEXCOMM7_IRQn); /* Initialize the rest */ BOARD_InitPins(); BOARD_BootClockFROHF96M(); BOARD_InitDebugConsole(); BOARD_InitSysctrl();
PRINTF("Configure WM8904 codec\r\n"); PRINTF("The main clock is %dHz\r\n",CLOCK_GetCoreSysClkFreq()/1000000); PRINTF("The Flexcomm7 clock is %dHz\r\n",CLOCK_GetFreq(kCLOCK_Flexcomm7 ));//CLOCK_GetClockAttachId(kPLL0_DIV_to_FLEXCOMM7)/10000); PRINTF("The Flexcomm6 clock is %dHz\r\n",CLOCK_GetFreq(kCLOCK_Flexcomm6 ));
/* protocol: i2s * sampleRate: 48K * bitwidth:16 */ #if 0 //Disable codec if (CODEC_Init(codecHandle, &boardCodecConfig) != kStatus_Success) { PRINTF("WM8904_Init failed!\r\n"); } /* Initial volume kept low for hearing safety. */ /* Adjust it to your needs, 0x0006 for -51 dB, 0x0039 for 0 dB etc. */ CODEC_SetVolume(codecHandle, kCODEC_PlayChannelHeadphoneLeft | kCODEC_PlayChannelHeadphoneRight, 0x0001); #endif PRINTF("Configure I2S\r\n");
/* * masterSlave = kI2S_MasterSlaveNormalMaster; * mode = kI2S_ModeI2sClassic; * rightLow = false; * leftJust = false; * pdmData = false; * sckPol = false; * wsPol = false; * divider = 1; * oneChannel = false; * dataLength = 16; * frameLength = 32; * position = 0; * watermark = 4; * txEmptyZero = true; * pack48 = false; */ I2S_TxGetDefaultConfig(&s_TxConfig); s_TxConfig.divider = I2S_CLOCK_DIVIDER; // s_TxConfig.wsPol = 1;
/* * masterSlave = kI2S_MasterSlaveNormalSlave; * mode = kI2S_ModeI2sClassic; * rightLow = false; * leftJust = false; * pdmData = false; * sckPol = false; * wsPol = false; * divider = 1; * oneChannel = false; * dataLength = 16; * frameLength = 32; * position = 0; * watermark = 4; * txEmptyZero = false; * pack48 = false; */ // I2S_RxGetDefaultConfig(&s_RxConfig);
I2S_TxInit(DEMO_I2S_TX, &s_TxConfig); // I2S_RxInit(DEMO_I2S_RX, &s_RxConfig);
if (true) { StartSoundPlayback(); } else { StartDigitalLoopback(); }
while (1) { } }
static void StartSoundPlayback(void) { PRINTF("Setup looping playback of sine wave\r\n");
s_TxTransfer.data = &g_Music[0]; s_TxTransfer.dataSize = sizeof(g_Music) ;
I2S_TxTransferCreateHandle(DEMO_I2S_TX, &s_TxHandle, TxCallback, (void *)&s_TxTransfer); I2S_TxTransferNonBlocking(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer);
}
static void StartDigitalLoopback(void) { PRINTF("Setup digital loopback\r\n");
s_TxTransfer.data = &s_Buffer[0]; s_TxTransfer.dataSize = sizeof(s_Buffer);
s_RxTransfer.data = &s_Buffer[0]; s_RxTransfer.dataSize = sizeof(s_Buffer);
I2S_TxTransferCreateHandle(DEMO_I2S_TX, &s_TxHandle, TxCallback, (void *)&s_TxTransfer); I2S_RxTransferCreateHandle(DEMO_I2S_RX, &s_RxHandle, RxCallback, (void *)&s_RxTransfer);
I2S_RxTransferNonBlocking(DEMO_I2S_RX, &s_RxHandle, s_RxTransfer); I2S_TxTransferNonBlocking(DEMO_I2S_TX, &s_TxHandle, s_TxTransfer); }
static void TxCallback(I2S_Type *base, i2s_handle_t *handle, status_t completionStatus, void *userData) { /* Enqueue the same original s_Buffer all over again */ i2s_transfer_t *transfer = (i2s_transfer_t *)userData; I2S_TxTransferNonBlocking(base, handle, *transfer); }
static void RxCallback(I2S_Type *base, i2s_handle_t *handle, status_t completionStatus, void *userData) { /* Enqueue the same original s_Buffer all over again */ i2s_transfer_t *transfer = (i2s_transfer_t *)userData; I2S_RxTransferNonBlocking(base, handle, *transfer);
} 不知道是配置的问题还是发送的时候的问题?
|