//--------------------------------------------------------------
// File     : stm32f7_audio.h
//--------------------------------------------------------------

//--------------------------------------------------------------
#ifndef __STM32F7_AUDIO_H
#define __STM32F7_AUDIO_H

//--------------------------------------------------------------
// Includes
//--------------------------------------------------------------
#include <stddef.h>
#include "stm32_ub_system.h"
#include "wm8994.h"


//--------------------------------------------------------------
// Struktur von einem WAV-File
//--------------------------------------------------------------
typedef struct UB_WAV_t
{
  const uint8_t *table; // Tabelle mit den Daten
  uint32_t size;        // Anzahl der Bytes
}UB_WAV;

//--------------------------------------------------------------
// Einbinden der benutzen WAV-Files
//--------------------------------------------------------------
extern UB_WAV m32k16b_wav;
//extern UB_WAV s16k16b;


//--------------------------------------------------------------
// interne Struktur
//--------------------------------------------------------------
typedef struct {
  UB_WAV	*wav_ptr;
  uint32_t file_len;
  uint32_t fmt_len;
  uint16_t typ;
  uint16_t channels;
  uint32_t samplerate;
  uint32_t byterate;
  uint16_t framesize;
  uint16_t bitpersample;
  uint32_t data_len;
  uint32_t data_start;
}WAV_t;


//--------------------------------------------------------------
// interne Struktur
//--------------------------------------------------------------
typedef struct {
  uint8_t status; //  0=no init, 1=init, 2=play
  uint32_t akt_adr;
  uint32_t akt_pos;
}WAV_Status_t;



/* To have 2 separate audio stream in Both headphone and speaker the 4 slot must be activated */
#define CODEC_AUDIOFRAME_SLOT_0123           SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3
/* To have an audio stream in headphone only SAI Slot 0 and Slot 2 must be activated */
#define CODEC_AUDIOFRAME_SLOT_02             SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_2
/* To have an audio stream in speaker only SAI Slot 1 and Slot 3 must be activated */
#define CODEC_AUDIOFRAME_SLOT_13             SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_3

//--------------------------------------------------------------
// Audio OUT
//--------------------------------------------------------------


/* SAI2 OUT peripheral configuration defines for on-board I2S DAC */
//original onboard DAC is on SAI2
#define AUDIO_OUT_SAIx                           SAI2_Block_A
#define AUDIO_OUT_SAIx_CLK_ENABLE()              __HAL_RCC_SAI2_CLK_ENABLE()
#define AUDIO_OUT_SAIx_CLK_DISABLE()             __HAL_RCC_SAI2_CLK_DISABLE()
#define AUDIO_OUT_SAIx_SCK_AF                    GPIO_AF10_SAI2
#define AUDIO_OUT_SAIx_FS_SD_MCLK_AF             GPIO_AF10_SAI2

#define AUDIO_OUT_SAIx_MCLK_ENABLE()             __HAL_RCC_GPIOI_CLK_ENABLE()
#define AUDIO_OUT_SAIx_MCLK_GPIO_PORT            GPIOI
#define AUDIO_OUT_SAIx_MCLK_PIN                  GPIO_PIN_4
#define AUDIO_OUT_SAIx_SCK_SD_ENABLE()           __HAL_RCC_GPIOI_CLK_ENABLE()
#define AUDIO_OUT_SAIx_SCK_SD_2_ENABLE()         __HAL_RCC_GPIOD_CLK_ENABLE()
#define AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT          GPIOI
#define AUDIO_OUT_SAIx_SCK_SD_2_GPIO_PORT        GPIOD
#define AUDIO_OUT_SAIx_SCK_PIN                   GPIO_PIN_5
#define AUDIO_OUT_SAIx_SCK_2_PIN                 GPIO_PIN_13
#define AUDIO_OUT_SAIx_SD_PIN                    GPIO_PIN_6
#define AUDIO_OUT_SAIx_SD_2_PIN                  GPIO_PIN_11
#define AUDIO_OUT_SAIx_FS_ENABLE()               __HAL_RCC_GPIOI_CLK_ENABLE()
#define AUDIO_OUT_SAIx_FS_2_ENABLE()             __HAL_RCC_GPIOD_CLK_ENABLE()
#define AUDIO_OUT_SAIx_FS_GPIO_PORT              GPIOI
#define AUDIO_OUT_SAIx_FS_2_GPIO_PORT            GPIOD
#define AUDIO_OUT_SAIx_FS_PIN                    GPIO_PIN_7
#define AUDIO_OUT_SAIx_FS_2_PIN                  GPIO_PIN_12

/* SAI DMA Stream definitions */
#define AUDIO_OUT_SAIx_DMAx_CLK_ENABLE()         __HAL_RCC_DMA2_CLK_ENABLE()
#define AUDIO_OUT_SAIx_DMAx_STREAM               DMA2_Stream4
#define AUDIO_OUT_SAIx_DMAx_CHANNEL              DMA_CHANNEL_3
#define AUDIO_OUT_SAIx_DMAx_IRQ                  DMA2_Stream4_IRQn
#define AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE     DMA_PDATAALIGN_HALFWORD
#define AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE        DMA_MDATAALIGN_HALFWORD
#define DMA_MAX_SZE                              ((uint16_t)0xFFFF)

#define AUDIO_OUT_SAIx_DMAx_IRQHandler           DMA2_Stream4_IRQHandler

/* Select the interrupt preemption priority for the DMA interrupt */
#define AUDIO_OUT_IRQ_PREPRIO                    ((uint32_t)5)   /* Select the preemption priority level(0 is the highest) */


//--------------------------------------------------------------
// Audio IN
//--------------------------------------------------------------

/* SAI IN peripheral configuration defines */
#define AUDIO_IN_SAIx                            SAI2_Block_B
#define AUDIO_IN_SAIx_CLK_ENABLE()               __HAL_RCC_SAI2_CLK_ENABLE()
#define AUDIO_IN_SAIx_CLK_DISABLE()              __HAL_RCC_SAI2_CLK_DISABLE()
#define AUDIO_IN_SAIx_SD_AF                      GPIO_AF10_SAI2

#define AUDIO_IN_SAIx_SD_ENABLE()                __HAL_RCC_GPIOG_CLK_ENABLE()
#define AUDIO_IN_SAIx_SD_GPIO_PORT               GPIOG
#define AUDIO_IN_SAIx_SD_PIN                     GPIO_PIN_10

#define AUDIO_IN_INT_GPIO_ENABLE()               __HAL_RCC_GPIOH_CLK_ENABLE()
#define AUDIO_IN_INT_GPIO_PORT                   GPIOH
#define AUDIO_IN_INT_GPIO_PIN                    GPIO_PIN_15
#define AUDIO_IN_INT_IRQ                         EXTI15_10_IRQn

/* SAI DMA Stream definitions */
#define AUDIO_IN_SAIx_DMAx_CLK_ENABLE()          __HAL_RCC_DMA2_CLK_ENABLE()
#define AUDIO_IN_SAIx_DMAx_STREAM                DMA2_Stream7
#define AUDIO_IN_SAIx_DMAx_CHANNEL               DMA_CHANNEL_0
#define AUDIO_IN_SAIx_DMAx_IRQ                   DMA2_Stream7_IRQn
#define AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE      DMA_PDATAALIGN_HALFWORD
#define AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE         DMA_MDATAALIGN_HALFWORD

#define AUDIO_IN_SAIx_DMAx_IRQHandler            DMA2_Stream7_IRQHandler
#define AUDIO_IN_INT_IRQHandler                  EXTI15_10_IRQHandler

/* Select the interrupt preemption priority and sub-priority for the IT/DMA interrupt */
#define AUDIO_IN_IRQ_PREPRIO                     ((uint32_t)6)   /* Select the preemption priority level(0 is the highest) */

//--------------------------------------------------------------
// DMA
//--------------------------------------------------------------

#define DMA_MAX(x)           (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)



//--------------------------------------------------------------
// Globale Funktionen
//--------------------------------------------------------------
uint8_t UB_AUDIO_OUT_Init(uint16_t device, uint8_t volume, uint32_t frq);
uint8_t UB_AUDIO_OUT_Play_Array(uint16_t* pBuffer, uint32_t size);
uint8_t UB_AUDIO_OUT_Play_Wav(UB_WAV *wav, uint16_t device, uint8_t volume);
uint8_t UB_AUDIO_OUT_Stop(void);
uint8_t UB_AUDIO_OUT_SetVolume(uint8_t volume);
uint8_t UB_AUDIO_IN_Init(uint16_t device, uint8_t volume, uint32_t frq);
uint8_t UB_AUDIO_IN_Record_Array(uint16_t* pbuf, uint32_t size);
uint8_t UB_AUDIO_IN_Stop(void);
uint8_t BSP_AUDIO_IN_SetVolume(uint8_t volume);
uint8_t UB_AUDIO_IN_OUT_Init(uint16_t device_in, uint16_t device_out, uint8_t volume, uint32_t frq);
//--------------------------------------------------------------
uint8_t AUDIO_Fill_WAV_Data(UB_WAV *wav, WAV_t *wav_data);
uint8_t AUDIO_Play_Buffer(void);
uint8_t AUDIO_Init_Samples(uint8_t n, WAV_t *wav_data);
uint8_t AUDIO_Set_ActiveSample(uint32_t sample_flags);

//--------------------------------------------------------------
#endif // __STM32F7_AUDIO_H
