/* ****************************************************************************** * @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; }