MCUXpresso_MIMXRT1052xxxxB/boards/evkbimxrt1050/audio_examples/maestro_usb_speaker/main.c

199 lines
5.7 KiB
C

/*
* Copyright 2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Board includes */
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "main.h"
#include "cmd.h"
#include "audio_speaker.h"
#include "fsl_debug_console.h"
#include "usb_phy.h"
#include "fsl_gpio.h"
#include "fsl_iomuxc.h"
#include "fsl_dmamux.h"
#include "fsl_codec_common.h"
#include "fsl_wm8960.h"
#include "app_definitions.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define APP_TASK_STACK_SIZE (8 * 1024)
/*******************************************************************************
* Prototypes
******************************************************************************/
int BOARD_CODEC_Init(void);
/*******************************************************************************
* Variables
******************************************************************************/
codec_handle_t codecHandle = {0};
wm8960_config_t wm8960Config = {
.i2cConfig = {.codecI2CInstance = BOARD_CODEC_I2C_INSTANCE, .codecI2CSourceClock = BOARD_CODEC_I2C_CLOCK_FREQ},
.route = kWM8960_RoutePlaybackandRecord,
.leftInputSource = kWM8960_InputDifferentialMicInput3,
.rightInputSource = kWM8960_InputDifferentialMicInput2,
.playSource = kWM8960_PlaySourceDAC,
.slaveAddress = WM8960_I2C_ADDR,
.bus = kWM8960_BusI2S,
.format = {.mclk_HZ = 12288000U,
.sampleRate = kWM8960_AudioSampleRate48KHz,
.bitWidth = kWM8960_AudioBitWidth16bit},
.master_slave = false,
};
codec_config_t boardCodecConfig = {.codecDevType = kCODEC_WM8960, .codecDevConfig = &wm8960Config};
static app_handle_t app;
/*******************************************************************************
* Code
******************************************************************************/
/*
* AUDIO PLL setting: Frequency = Fref * (DIV_SELECT + NUM / DENOM)
* = 24 * (30 + 66/625)
* = 722.5344 MHz
*/
const clock_audio_pll_config_t audioPllConfig = {
.loopDivider = 30, /* PLL loop divider. Valid range for DIV_SELECT divider value: 27~54. */
.postDivider = 1, /* Divider after the PLL, should only be 1, 2, 4, 8, 16. */
.numerator = 66, /* 30 bit numerator of fractional loop divider. */
.denominator = 625, /* 30 bit denominator of fractional loop divider */
};
void BOARD_EnableSaiMclkOutput(bool enable)
{
if (enable)
{
IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK;
}
else
{
IOMUXC_GPR->GPR1 &= (~IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK);
}
}
int BOARD_CODEC_Init(void)
{
CODEC_Init(&codecHandle, &boardCodecConfig);
/* Initial volume kept low for hearing safety. */
CODEC_SetVolume(&codecHandle, kCODEC_PlayChannelHeadphoneLeft | kCODEC_PlayChannelHeadphoneRight, 50);
return 0;
}
void USB_DeviceClockInit(void)
{
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL,
BOARD_USB_PHY_TXCAL45DP,
BOARD_USB_PHY_TXCAL45DM,
};
if (CONTROLLER_ID == kUSB_ControllerEhci0)
{
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
}
else
{
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
}
USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ, &phyConfig);
}
void handleShellMessage(void *arg)
{
/* Wait for response message to be processed before returning to shell. */
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
}
void APP_Shell_Task(void *param)
{
PRINTF("[APP_Shell_Task] start\r\n");
/* Handle shell commands. Return when 'exit' command entered. */
shellCmd(handleShellMessage, param);
vTaskSuspend(NULL);
while (1)
;
}
int main(void)
{
int ret;
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_BootClockRUN();
/* 1. Init SAI clock .*/
CLOCK_InitAudioPll(&audioPllConfig);
BOARD_InitDebugConsole();
/*Clock setting for LPI2C*/
CLOCK_SetMux(kCLOCK_Lpi2cMux, BOARD_CODEC_I2C_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, BOARD_CODEC_I2C_CLOCK_SOURCE_DIVIDER);
CLOCK_SetMux(kCLOCK_Sai1Mux, DEMO_SAI1_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_Sai1PreDiv, DEMO_SAI1_CLOCK_SOURCE_PRE_DIVIDER);
CLOCK_SetDiv(kCLOCK_Sai1Div, DEMO_SAI1_CLOCK_SOURCE_DIVIDER);
/*Enable MCLK clock*/
BOARD_EnableSaiMclkOutput(true);
DMAMUX_Init(DEMO_DMAMUX);
DMAMUX_SetSource(DEMO_DMAMUX, DEMO_TX_CHANNEL, (uint8_t)DEMO_SAI_TX_SOURCE);
DMAMUX_EnableChannel(DEMO_DMAMUX, DEMO_TX_CHANNEL);
/*Clock setting for USB*/
USB_DeviceClockInit();
PRINTF("\r\n");
PRINTF("**********************************************\r\n");
PRINTF("Maestro audio USB speaker solutions demo start\r\n");
PRINTF("**********************************************\r\n");
PRINTF("\r\n");
/* Initialize OSA*/
OSA_Init();
ret = BOARD_CODEC_Init();
if (ret)
{
PRINTF("CODEC_Init failed\r\n");
return -1;
}
/* USB speaker initialization */
USB_DeviceApplicationInit();
/* Set shell command task priority = 4 */
if (xTaskCreate(APP_Shell_Task, "Shell Task", APP_TASK_STACK_SIZE, &app, configMAX_PRIORITIES - 3,
&app.shell_task_handle) != pdPASS)
{
PRINTF("\r\nFailed to create application task\r\n");
while (1)
;
}
/* Run RTOS */
vTaskStartScheduler();
/* Should not reach this statement */
return 0;
}