The Bongiovi DPS SDK Sample Project for the Nuvoton ARM Processors contains everything you need to get started. It is pre-configured to allow easy adjustment of:
Instructions below are for the NUC505 platform:
This project is set up for the Keil ARM IDE using the Nuvoton NUC505 Board Support Package (BSP) version 3.00.003. The Bongiovi DPS Keil project folder must be placed next to the BSP folder in your working directory.
NOTE: This information is for basic usage of the DPS Sample Project. For more details about the functions and parameters for the NUC505 BSP refer to the NuMicro NUC505 Series Driver Reference Guide in /BSP Root Folder/Document.
NOTE: Exact line numbers are subject to change in future version. All line numbers are preceded with ~ to show they are approximate.
DPSlib.lib
This is the compiled DPS processing library.
DPSlib.h
This is the header file for DPSlib.lib. It contains compiler directives for easy setup of the NUC505 Audio board:
#define MAX_BUFF_LEN 512
This sets the buffer size in frames (number of stereo samples). When microphone feedback (FBX) is not in use (BGV_SPEAKER project) you may experiment with any value from 60 to 512. Higher numbers will cause more latency but will allow more DPS functions to be enabled. When FBX is enabled (BGV_MIC project) you must use power-of-2 values such at 64, 128, 256 (maximum).
#define BITS_16
This selects the 16 bit or 32 bit PCM to floating point conversion function. Comment this out for 32 bit mode.
#define USE_INTERNAL_CODEC
This selects the native NUC505 audio codec (configured for analog input by default) or external IIS. Comment out for external IIS mode.
#define RATE_48k
Selects 44.1kHZ or 48kHZ sample rate. Comment out for 44.1kHz operation.
All other functions are described in the DPS SDK NUC505 API Description.
This file handles NUC505 Audio Board I2S codec, UART and DMA setup.
Lines ~55 to ~58 set the volume levels of the analog to digital (ADC = input) and digital to analog (DAC = output) audio signal converters:
DAC
I2S_SET_INTERNAL_CODEC(I2S, 0x08, 0x01); // DAC Left Volume I2S_SET_INTERNAL_CODEC(I2S, 0x09, 0x01); // DAC Right Volume
The DAC analog volume level is adjusted in the 3rd input variable (in bold above). The range is 0x00 (0dB maximum) to 0x1E (-60dB minimum) to 0x1F (mute). Steps are -2dB.
ADC
I2S_SET_INTERNAL_CODEC(I2S, 0x10, 0x00); // ADC Left Volume I2S_SET_INTERNAL_CODEC(I2S, 0x11, 0x00); // ADC Right Volume
The ADC volume level is adjusted in the 3rd input variable (in bold above). The range is 0x0 (0dB unity gain) to 0xE (+22.4dB maximum gain) in 1.6dB steps. 0xF is mute.
The main() function contains the function calls that set up DPS (lines ~149 to ~156):
DPS_GlobalInitialize();
This initializes the DPS library.
DPS_EnableDPS();
This enables DPS processing.
DPS_EnableStereoWidening();
This enables Stereo Enhancement.
DPS_LoadPreset(1);
This loads preset (DPS Profile) #2.
New versions of the Sample Project include code to connect NUC505 GPIO pins to DPS API functions. This provides examples for using the NUC505 and DPS as an SoC for many audio devices.
Headphones and other new features are clearly commented in the latest DPS.h file.
This file is generated by the DPS Profile Creator. It contains 5 DPS Profile parameter sets in the form of an array of indexes. The presets included in the sample project have been designed to demonstrate DPS processing on a portable speaker:
These profiles may be selected using the API or UART commands. Click Here to learn more about generating the indices.c file to customize DPS for your audio device.
This is the interrupt service routine (ISR). It handles the direct memory access (DMA) buffers where the audio processing takes place.
The first part of the file (lines ~31 to ~136) handles the 32 or 16 bit integer to floating point conversion functions.
Line ~137 uses the RATE_48k directive to select between Dynamic Stereo Enhancement (44.1kHz) and Simple Stereo Enhancement (48kHz).
Line ~161 is the buffer handling function. The following functions are performed on an I2S audio stream:
Notice there are 2 alternating buffers used in this function. The DPS functions must be called exactly the same way for both buffers:
void I2S_IRQHandler(void) { uint32_t u32I2SIntFlag; u32I2SIntFlag = I2S_GET_INT_FLAG(I2S, (I2S_STATUS_RDMATIF_Msk | I2S_STATUS_RDMAEIF_Msk)); /* Two alternating DMA buffers triggered by IRQ */
Buffer #1
if (u32I2SIntFlag & I2S_STATUS_RDMATIF_Msk) //process buffer 1 { I2S_CLR_INT_FLAG(I2S, I2S_STATUS_RDMATIF_Msk); fixedToFloat(&PcmRxBuff[0][0], xf_L, BUFF_LEN); fixedToFloat(&PcmRxBuff[0][1], xf_R, BUFF_LEN); NoiseGateProcess(xf_L, xf_R); StereoExpand(xf_L, xf_R); DPS_Left(xf_L); DPS_Right(xf_R); floatToFixed(xf_L, &PcmTxBuff[0][0], BUFF_LEN); floatToFixed(xf_R, &PcmTxBuff[0][1], BUFF_LEN); }
Buffer #2
else if (u32I2SIntFlag & I2S_STATUS_RDMAEIF_Msk) //process buffer 2 { I2S_CLR_INT_FLAG(I2S, I2S_STATUS_RDMAEIF_Msk); if ( s_flag1 == 0 ) { s_flag1 = 1; I2S_ENABLE_TXDMA(I2S); I2S_ENABLE_TX(I2S); } fixedToFloat(&PcmRxBuff[1][0], xf_L, BUFF_LEN); fixedToFloat(&PcmRxBuff[1][1], xf_R, BUFF_LEN); NoiseGateProcess(xf_L, xf_R); StereoExpand(xf_L, xf_R); DPS_Left(xf_L); DPS_Right(xf_R); floatToFixed(xf_L, &PcmTxBuff[1][0], BUFF_LEN); floatToFixed(xf_R, &PcmTxBuff[1][1], BUFF_LEN); } }
NOTE: If a Bongiovi DPS audio processing function is not needed (for example – a noise gate is unnecessary on an I2S digital stream) the function may be removed from the processing loop. See Platform Considerations for details.