241 lines
6.2 KiB
C
241 lines
6.2 KiB
C
|
/*
|
||
|
******************************************************************************
|
||
|
* @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;
|
||
|
}
|