|
|
/************************************************************************
|
|
|
* Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
|
|
|
* @file dac.c
|
|
|
* @author UartTFT Application Team
|
|
|
* @version V1.0.0
|
|
|
* @date 2023-02-24
|
|
|
* @brief
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
|
#include "dac.h"
|
|
|
|
|
|
#include "pit.h"
|
|
|
#include "data.h"
|
|
|
#include "bsp.h"
|
|
|
#include "pwm.h"
|
|
|
#include "pit32_drv.h"
|
|
|
#include "dmac_drv.h"
|
|
|
#include "levetop.h"
|
|
|
extern uint8_t Flash_type ;
|
|
|
/*SPI1 DMA channel base address*/
|
|
|
DMA_CHANNEL_REG *dac_dma_channel[4] = {(DMA_CHANNEL_REG *)(DMA2_BASE_ADDR), (DMA_CHANNEL_REG *)(DMA2_BASE_ADDR + 0x58),
|
|
|
(DMA_CHANNEL_REG *)(DMA2_BASE_ADDR + 0xB0), (DMA_CHANNEL_REG *)(DMA2_BASE_ADDR + 0x108)}; // global struct variable for for Channel registers
|
|
|
/*SPI1 DMA config base address */
|
|
|
DMA_CONTROL_REG *dac_dma_control = (DMA_CONTROL_REG *)(DMA2_BASE_ADDR + 0x2C0); // global struct variable for for DMAC registers
|
|
|
|
|
|
UINT16 etARRValue(UINT16 sample)
|
|
|
{
|
|
|
UINT16 arrValue;
|
|
|
/* Update OCA values to match the. WAV file sampling rate */
|
|
|
switch (sample)
|
|
|
{
|
|
|
case 8000:
|
|
|
arrValue = (uint16_t)(75000000 / 8000);
|
|
|
break; /* 8KHz = 75MHz / 9375 */
|
|
|
case 11025:
|
|
|
arrValue = (uint16_t)(75000000 / 11025);
|
|
|
break; /* 11.025KHz = 75MHz / 6802 */
|
|
|
case 16000:
|
|
|
arrValue = (uint16_t)(75000000 / 16000);
|
|
|
break; /* 16KHz = 75MHz / 4687 */
|
|
|
case 22050:
|
|
|
arrValue = (uint16_t)(75000000 / 22050);
|
|
|
break; /* 22.05KHz = 75MHz / 3401 */
|
|
|
case 44100:
|
|
|
arrValue = (uint16_t)(75000000 / 44100);
|
|
|
break; /* 44.1KHz = 75MHz / 1700 */
|
|
|
case 48000:
|
|
|
arrValue = (uint16_t)(75000000 / 48000);
|
|
|
break; /* 48KHz = 75MHz / 1562 */
|
|
|
default:
|
|
|
arrValue = 0;
|
|
|
break;
|
|
|
}
|
|
|
return arrValue - 1;
|
|
|
}
|
|
|
|
|
|
void DAC_SetData(UINT16 data)
|
|
|
{
|
|
|
DAC_Write_Data(data);
|
|
|
DAC->DAC_SWTR |= SW_TRIG;
|
|
|
DAC_Wait_Load_Done();
|
|
|
}
|
|
|
|
|
|
#include "dmac_drv.h"
|
|
|
|
|
|
#define DAC_TIMER ((PIT32_TypeDef *)PIT2_BASE_ADDR)
|
|
|
|
|
|
uint8_t gWavState = 0;
|
|
|
uint8_t dac_data_buff_1[4096];
|
|
|
uint8_t dac_data_buff_2[4096];
|
|
|
uint32_t gWavFlashAddr = 0;
|
|
|
uint16_t numflag = 0;
|
|
|
uint16_t bufflen = 0;
|
|
|
uint8_t finishflag = 0;
|
|
|
uint8_t wbuf_select = 0;
|
|
|
uint8_t gWavAddrFull_Flag = 0;
|
|
|
uint8_t last_select = 0;
|
|
|
uint8_t gWavType = 0;
|
|
|
uint8_t gWavFlag = 0;
|
|
|
uint16_t buffnum;
|
|
|
uint16_t bufflast;
|
|
|
uint32_t gWavLen = 0;
|
|
|
|
|
|
static void DAC_Timer_Init(unsigned int rate)
|
|
|
{
|
|
|
DAC_TIMER->PCSR &= (~PCSR_EN);
|
|
|
|
|
|
DAC_TIMER->PCSR &= (~PCSR_EN);
|
|
|
DAC_TIMER->PCSR = (0 << 8) | PCSR_OVW | PCSR_RLD;
|
|
|
|
|
|
DAC_TIMER->PMR = (g_ips_clk / 1000000 * (1000000 / (float)rate));
|
|
|
// PIT32->PCSR = (PIT32_CLK_DIV_1<<8)|PCSR_OVW|PCSR_RLD;
|
|
|
}
|
|
|
|
|
|
static void DAC_Timer_Enable(void)
|
|
|
{
|
|
|
DAC_TIMER->PCSR |= PCSR_EN;
|
|
|
}
|
|
|
|
|
|
static void DAC_Timer_Disable(void)
|
|
|
{
|
|
|
DAC_TIMER->PCSR &= ~PCSR_EN;
|
|
|
}
|
|
|
|
|
|
void DAC_DMA_Tran(UINT8 channel, UINT32 src, UINT32 length)
|
|
|
{
|
|
|
// DMA_Init(DMA2_BASE_ADDR);
|
|
|
// dac_dma_control->DMA_CONFIG = 1;
|
|
|
dac_dma_channel[channel]->DMA_SADDR = src;
|
|
|
dac_dma_channel[channel]->DMA_DADDR = 0x40021004;
|
|
|
// dac_dma_channel[channel]->DMA_CTRL = SIEC|DNOCHG|M2P_DMA|DWIDTH_B|SWIDTH_B|INTEN;
|
|
|
dac_dma_channel[channel]->DMA_CTRL = SIEC | DNOCHG | M2P_DMA | DWIDTH_HW | SWIDTH_HW | INTEN;
|
|
|
dac_dma_channel[channel]->DMA_CTRL_HIGH = length;
|
|
|
|
|
|
dac_dma_channel[channel]->DMA_CFG = 0;
|
|
|
dac_dma_channel[channel]->DMA_CFG_HIGH = DST_PER_DAC;
|
|
|
|
|
|
dac_dma_control->DMA_MASKTFR = CHANNEL_UMASK(channel);
|
|
|
dac_dma_control->DMA_CHEN = CHANNEL_WRITE_ENABLE(channel) | CHANNEL_ENABLE(channel);
|
|
|
}
|
|
|
void DAC_DMA_dis(UINT8 n)
|
|
|
{
|
|
|
dac_dma_channel[n]->DMA_CFG |= 1 << 8;
|
|
|
dac_dma_control->DMA_CHEN |= CHANNEL_WRITE_ENABLE(n);
|
|
|
dac_dma_control->DMA_CHEN &= ~CHANNEL_ENABLE(n);
|
|
|
dac_dma_channel[n]->DMA_CFG &= ~(1 << 8);
|
|
|
dac_dma_control->DMA_CONFIG = 0;
|
|
|
}
|
|
|
|
|
|
void dac_dma_tran(uint8_t *data, uint32_t len)
|
|
|
{
|
|
|
uint32_t tran_l = 0;
|
|
|
uint8_t *wDataBufOut = data;
|
|
|
tran_l = (len >> 1);
|
|
|
len -= (tran_l << 1);
|
|
|
|
|
|
// DMA_Init(DMA2_BASE_ADDR);
|
|
|
|
|
|
DAC_DMA_Tran(0, (uint32_t)wDataBufOut, tran_l);
|
|
|
}
|
|
|
|
|
|
void WAV_amplifier_EN(void)
|
|
|
{
|
|
|
SPI_ConfigGpio(SPI3, SPI_MOSI, GPIO_OUTPUT);
|
|
|
SPI_WriteGpioData(SPI3, SPI_MOSI, 1);
|
|
|
}
|
|
|
|
|
|
void WAV_amplifier_DIS(void)
|
|
|
{
|
|
|
SPI_ConfigGpio(SPI3, SPI_MOSI, GPIO_OUTPUT);
|
|
|
SPI_WriteGpioData(SPI3, SPI_MOSI, 0);
|
|
|
}
|
|
|
|
|
|
void close_wav_dac(void)
|
|
|
{
|
|
|
if (!gWavType)
|
|
|
{
|
|
|
var[0x700a * 2] = 0;
|
|
|
var[0x700a * 2 + 1] = 0;
|
|
|
}
|
|
|
|
|
|
gWavFlag = 0;
|
|
|
gWavAddrFull_Flag = 0;
|
|
|
WAV_amplifier_DIS();
|
|
|
DAC_Timer_Disable();
|
|
|
DAC_DMA_dis(0); // DAC uses channel 0 of DMA2
|
|
|
}
|
|
|
|
|
|
void Wav_DAC_Init(uint16_t num)
|
|
|
{
|
|
|
uint8_t buff[8];
|
|
|
WAV_amplifier_DIS();
|
|
|
gWavType = 0;
|
|
|
close_wav_dac();
|
|
|
if (num > 0 && num != 0x8000 && (num & 0x7FFF) <= addr_index[5])
|
|
|
{
|
|
|
if (num & 0x8000)
|
|
|
gWavType = 1;
|
|
|
else
|
|
|
gWavType = 0;
|
|
|
|
|
|
Flash_Read_UI(buff, addr_index[4] + ((num & 0x7FFF) - 1) * 8, 8);
|
|
|
gWavFlashAddr = buff[0] + (buff[1] << 8) + (buff[2] << 16) + (buff[3] << 24);
|
|
|
gWavLen = buff[4] + (buff[5] << 8) + (buff[6] << 16) + (buff[7] << 24);
|
|
|
if (gWavLen == 0)
|
|
|
{
|
|
|
gWavType = 0;
|
|
|
close_wav_dac();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bufflen = 4096;
|
|
|
if (Flash_type == 1)
|
|
|
bufflen = 4096;
|
|
|
buffnum = gWavLen / bufflen; // Total number of data packages
|
|
|
bufflast = gWavLen % bufflen; // Data volume of the last packet
|
|
|
if (bufflast > 0)
|
|
|
buffnum++;
|
|
|
else if (bufflast == 0)
|
|
|
bufflast = bufflen;
|
|
|
|
|
|
wbuf_select = 0;
|
|
|
last_select = 0;
|
|
|
numflag = 0;
|
|
|
gWavState = 1;
|
|
|
gWavFlag = 1;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
gWavType = 0;
|
|
|
close_wav_dac();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
uint8_t wav_reduce_para = 0;
|
|
|
uint8_t wav_reduce_para_last = 0;
|
|
|
void DMA2_IRQHandler(void)
|
|
|
{
|
|
|
uint32_t i = 0;
|
|
|
int16_t temp = 0;
|
|
|
|
|
|
if (dac_dma_control->DMA_STATTFR & 0x0f)
|
|
|
{
|
|
|
finishflag = 1;
|
|
|
numflag++;
|
|
|
}
|
|
|
|
|
|
dac_dma_control->DMA_CLRTFR = dac_dma_control->DMA_STATTFR;
|
|
|
dac_dma_control->DMA_CLRBLOCK = dac_dma_control->DMA_STATBLOCK;
|
|
|
dac_dma_control->DMA_CLRSRC = dac_dma_control->DMA_STATSRC;
|
|
|
dac_dma_control->DMA_CLRDST = dac_dma_control->DMA_STATDST;
|
|
|
dac_dma_control->DMA_CLRERR = dac_dma_control->DMA_STATERR;
|
|
|
|
|
|
if (wbuf_select == 0 && numflag<=buffnum) // Transfer the next packet of data
|
|
|
dac_dma_tran(dac_data_buff_1, bufflen);
|
|
|
else if (wbuf_select == 1 && numflag<=buffnum)
|
|
|
dac_dma_tran(dac_data_buff_2, bufflen);
|
|
|
|
|
|
if (numflag == (buffnum - 1)) // Last packet of data
|
|
|
{
|
|
|
bufflen = bufflast;
|
|
|
last_select = 1;
|
|
|
}
|
|
|
else if (numflag == buffnum) // Transfer completed
|
|
|
{
|
|
|
last_select = 2;
|
|
|
gWavAddrFull_Flag = 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void LT_PlayWav_DAC(void)
|
|
|
{
|
|
|
uint32_t i = 0;
|
|
|
int32_t temp = 0;
|
|
|
|
|
|
if (wav_reduce_para != 0 && wav_reduce_para_last == 0)
|
|
|
WAV_amplifier_EN();
|
|
|
else if (wav_reduce_para == 0 && wav_reduce_para_last != 0)
|
|
|
WAV_amplifier_DIS();
|
|
|
wav_reduce_para_last = wav_reduce_para;
|
|
|
|
|
|
if (gWavAddrFull_Flag == 1 && finishflag == 1 && numflag>buffnum)
|
|
|
{
|
|
|
gWavAddrFull_Flag = 0;
|
|
|
numflag = 0;
|
|
|
last_select = 0;
|
|
|
bufflen = 4096;
|
|
|
close_wav_dac();
|
|
|
if (gWavType == 1)
|
|
|
gWavState = 1;
|
|
|
}
|
|
|
else if (gWavAddrFull_Flag == 0)
|
|
|
{
|
|
|
if (gWavState == 1)
|
|
|
{
|
|
|
gWavState = 0;
|
|
|
// Read the first and second packet data
|
|
|
Flash_Read_UI(dac_data_buff_1, gWavFlashAddr + numflag * bufflen, bufflen);
|
|
|
for (i = 0; i < bufflen / 2; i++)
|
|
|
{
|
|
|
temp = (dac_data_buff_1[2 * i] >> 4) | (dac_data_buff_1[2 * i + 1] << 4);
|
|
|
temp = (((temp - 2048) * wav_reduce_para) >> 4) + 2048;
|
|
|
dac_data_buff_1[2 * i] = (temp << 4) & 0xF0;
|
|
|
dac_data_buff_1[2 * i + 1] = (temp >> 4) & 0xFF;
|
|
|
}
|
|
|
|
|
|
numflag++;
|
|
|
Flash_Read_UI(dac_data_buff_2, gWavFlashAddr + numflag * bufflen, bufflen);
|
|
|
for (i = 0; i < bufflen / 2; i++)
|
|
|
{
|
|
|
temp = (dac_data_buff_2[2 * i] >> 4) | (dac_data_buff_2[2 * i + 1] << 4);
|
|
|
temp = (((temp - 2048) * wav_reduce_para) >> 4) + 2048;
|
|
|
dac_data_buff_2[2 * i] = (temp << 4) & 0xF0;
|
|
|
dac_data_buff_2[2 * i + 1] = (temp >> 4) & 0xFF;
|
|
|
}
|
|
|
|
|
|
// Initialize DMA and DAC functions
|
|
|
DAC_Init(LEFTALIGNED_12BITS, TRIGGER_PIT, DET_ON_RISING);
|
|
|
dac_dma_control->DMA_CONFIG = 1;
|
|
|
|
|
|
NVIC_Init(2, 0, DMA2_IRQn, 2);
|
|
|
DAC_Timer_Init(22050);
|
|
|
DAC_Timer_Enable();
|
|
|
|
|
|
if (wav_reduce_para)
|
|
|
WAV_amplifier_EN();
|
|
|
|
|
|
dac_dma_tran(dac_data_buff_1, bufflen);
|
|
|
finishflag = 0;
|
|
|
wbuf_select = 1;
|
|
|
}
|
|
|
if (wbuf_select == 0 && finishflag == 1 && last_select == 0)
|
|
|
{
|
|
|
wbuf_select = 1;
|
|
|
finishflag = 0;
|
|
|
|
|
|
Flash_Read_UI(dac_data_buff_2, gWavFlashAddr + numflag * bufflen, bufflen);
|
|
|
for (i = 0; i < bufflen / 2; i++)
|
|
|
{
|
|
|
temp = (dac_data_buff_2[2 * i] >> 4) | (dac_data_buff_2[2 * i + 1] << 4);
|
|
|
temp = (((temp - 2048) * wav_reduce_para) >> 4) + 2048;
|
|
|
dac_data_buff_2[2 * i] = (temp << 4) & 0xF0;
|
|
|
dac_data_buff_2[2 * i + 1] = (temp >> 4) & 0xFF;
|
|
|
}
|
|
|
|
|
|
} // DMA2_IRQHandler
|
|
|
else if (wbuf_select == 1 && finishflag == 1 && last_select == 0)
|
|
|
{
|
|
|
wbuf_select = 0;
|
|
|
finishflag = 0;
|
|
|
|
|
|
Flash_Read_UI(dac_data_buff_1, gWavFlashAddr + numflag * bufflen, bufflen);
|
|
|
for (i = 0; i < bufflen / 2; i++)
|
|
|
{
|
|
|
temp = (dac_data_buff_1[2 * i] >> 4) | (dac_data_buff_1[2 * i + 1] << 4);
|
|
|
temp = (((temp - 2048) * wav_reduce_para) >> 4) + 2048;
|
|
|
dac_data_buff_1[2 * i] = (temp << 4) & 0xF0;
|
|
|
dac_data_buff_1[2 * i + 1] = (temp >> 4) & 0xFF;
|
|
|
}
|
|
|
}
|
|
|
else if (last_select == 1 && finishflag == 1)
|
|
|
{
|
|
|
finishflag = 0;
|
|
|
if (wbuf_select)
|
|
|
{
|
|
|
wbuf_select = 0;
|
|
|
Flash_Read_UI(dac_data_buff_1, gWavFlashAddr + numflag * bufflen, bufflen);
|
|
|
for (i = 0; i < bufflen / 2; i++)
|
|
|
{
|
|
|
temp = (dac_data_buff_1[2 * i] >> 4) | (dac_data_buff_1[2 * i + 1] << 4);
|
|
|
temp = (((temp - 2048) * wav_reduce_para) >> 4) + 2048;
|
|
|
dac_data_buff_1[2 * i] = (temp << 4) & 0xF0;
|
|
|
dac_data_buff_1[2 * i + 1] = (temp >> 4) & 0xFF;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
wbuf_select = 1;
|
|
|
Flash_Read_UI(dac_data_buff_2, gWavFlashAddr + numflag * bufflen, bufflen);
|
|
|
for (i = 0; i < bufflen / 2; i++)
|
|
|
{
|
|
|
temp = (dac_data_buff_2[2 * i] >> 4) | (dac_data_buff_2[2 * i + 1] << 4);
|
|
|
temp = (((temp - 2048) * wav_reduce_para) >> 4) + 2048;
|
|
|
dac_data_buff_2[2 * i] = (temp << 4) & 0xF0;
|
|
|
dac_data_buff_2[2 * i + 1] = (temp >> 4) & 0xFF;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|