MXC-A36-Demo/MCU/components/drivers/peripheral/Src/driver_spdif.c

241 lines
6.2 KiB
C
Raw Normal View History

/*
******************************************************************************
* @file driver_spdif.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief SPDIF module driver.
* This file provides firmware functions to manage the
* SPDIF peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/******************************************************************************
* @fn SPDIF_IRQHandler
*
* @brief spdif handle function in spdif isr
*
* @param hspdif : spdif handle
*/
void SPDIF_IRQHandler(SPDIF_HandleTypeDef *hspdif)
{
if(__SPDIF_IS_INT_ALEMPTY())
{
if((__SPDIF_GET_INT_STATUS() & ALEMPTY_FLAG))
{
while(__SPDIF_GET_INT_STATUS() & FULL_FLAG)
{
SPDIF->SPDIF_FIFO_DATA = hspdif->p_TxData[ hspdif->u32_TxCount++];
if(hspdif->u32_TxCount >= hspdif->u32_TxSize)
{
__SPDIF_DISABLE_ALEMPTY_INT();
hspdif->b_TxBusy = false;
if(hspdif->TxCallback)
{
hspdif->TxCallback(hspdif);
}
break;
}
}
}
}
if(__SPDIF_IS_INT_ALFULL())
{
if(__SPDIF_GET_INT_STATUS() & ALFULL_FLAG)
{
while(!(__SPDIF_GET_INT_STATUS() & EMPTY_FLAG))
{
hspdif->p_RxData[hspdif->u32_RxCount++] = SPDIF->SPDIF_FIFO_DATA;
}
}
}
if(__SPDIF_IS_INT_SYNCERR())
{
if(__SPDIF_GET_INT_STATUS() & SYNCERR_FLAG)
{
while(!(__SPDIF_GET_INT_STATUS() & EMPTY_FLAG))
{
hspdif->p_RxData[hspdif->u32_RxCount++] = SPDIF->SPDIF_FIFO_DATA;
}
hspdif->b_RxBusy = false;
__SPDIF_DISABLE_ALFULL_INT();
if(hspdif->RxCallback)
{
hspdif->RxCallback(hspdif);
}
}
}
}
/******************************************************************************
* @fn spdif_init
*
* @brief Initialize the SPDIF according to the specified parameters
* in the SPDIF_HandleTypeDef
*
* @param hspdif : spdif handle
*/
void spdif_init(SPDIF_HandleTypeDef *hspdif)
{
SPDIF->SPDIF_CTRL.TSAMPLERATE = hspdif->Init.TxSampleRate;
SPDIF->SPDIF_CTRL.CHANNEL_MODE = hspdif->Init.CH_Mode;
SPDIF->SPDIF_CTRL.CLK_ENABLE = 0;
SPDIF->SPDIF_CTRL.FIFO_ENABLE = 1;
SPDIF->SPDIF_CTRL.SFR_ENABLE = 1;
SPDIF->SPDIF_CTRL.PARITYGEN = 1;
SPDIF->SPDIF_CTRL.DUPLICATE = 1;
SPDIF->SPDIF_CTRL.SETPREAMBB = 1;
SPDIF->SPDIF_CTRL.INTREQ_MASK = 1;
__SPDIF_FIFO_HALF_FULL_LEVEL(hspdif->Init.HALFIFOFull_Threshold);
__SPDIF_FIFO_ALMOST_EMPTY_LEVEL(hspdif->Init.ALFIFOEmpty_Threshold);
}
/******************************************************************************
* @fn spdif_msg_send
*
* @brief spdif send message
*
* @param hspdif : spdif handle
* fp_Data : send data pointer
* fu32_Size : send data size
*/
bool spdif_msg_send(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data, uint32_t fu32_Size)
{
if (fu32_Size == 0) return false;
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
__SPDIF_DISABLE();
hspdif->b_TxBusy = 1;
__SPDIF_Tx_MODE();
__SPDIF_ENABLE();
while(fu32_Size)
{
while(__SPDIF_GET_INT_STATUS() & FULL_FLAG);
SPDIF->SPDIF_FIFO_DATA = *fp_Data++;
fu32_Size--;
}
while(!(__SPDIF_GET_INT_STATUS() & UNDERR_FLAG));
hspdif->b_TxBusy = 0;
return true;
}
/******************************************************************************
* @fn spdif_msg_receive
*
* @brief spdif receive message
*
* @param hspdif : spdif handle
* fp_Data : the receive data buffer
*/
bool spdif_msg_receive(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data)
{
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
__SPDIF_DISABLE();
hspdif->b_RxBusy = 1;
__SPDIF_Rx_MODE();
__SPDIF_ENABLE();
while(1)
{
if(!(__SPDIF_GET_INT_STATUS() & EMPTY_FLAG))
{
*fp_Data++ = SPDIF->SPDIF_FIFO_DATA;
}
if(__SPDIF_GET_INT_STATUS() & SYNCERR_FLAG)
{
break;
}
}
hspdif->b_RxBusy = 0;
return true;
}
/******************************************************************************
* @fn spdif_msg_send_IT
*
* @brief spdif send message with isr
*
* @param hspdif : spdif handle
* fp_Data : send data pointer
* fu32_Size : send data size
*/
bool spdif_msg_send_IT(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data, uint32_t fu32_Size)
{
if (fu32_Size == 0) return false;
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
hspdif->u32_TxSize = fu32_Size;
hspdif->u32_TxCount = 0;
hspdif->p_TxData = fp_Data;
hspdif->b_TxBusy = 1;
__SPDIF_Tx_MODE();
__SPDIF_ENABLE();
__SPDIF_ENABLE_ALEMPTY_INT();
return true;
}
/******************************************************************************
* @fn spdif_msg_receive_IT
*
* @brief spdif receive message with isr
*
* @param hspdif : spdif handle
* fp_Data : the receive data buffer
*/
bool spdif_msg_receive_IT(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data)
{
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
hspdif->p_RxData = fp_Data;
hspdif->b_RxBusy = 1;
hspdif->u32_RxCount = 0;
__SPDIF_Tx_MODE();
__SPDIF_ENABLE();
__SPDIF_ENABLE_ALFULL_INT();
return true;
}