3.3.2 Using the Library
The EMAFE peripheral library can be used in different ways:
- Direct Transfer: Read data samples from the registers of the EMAFE peripheral.
- DMA Transfer: Read a set of data samples from data memory.
Direct Transfer
APP_DATA appData;
/* Buffer setting */
#define APP_SAMPLE_CHANNELS 1600 // 320 samples/cycle(50Hz) * 5 cycles
/** Buffer to store sample sets */
static uint32_t pSamplesBuffer[APP_SAMPLE_CHANNELS] = {0};
void SYS_Initialize ( void* data )
{
(...)
EMAFE_Initialize();
(...)
}
void _appEmafeCallback(uint32_t interruptStatus)
{
if (interruptStatus & EMAFE_ISR_DRDY_Msk)
{
*appData.pSamplesData++ = EMAFE_GetDataChannel(EMAFE_CHN_2_ID);
appData.samplesCounter++;
if (appData.samplesCounter == APP_SAMPLE_CHANNELS)
{
EMAFE_DisableFilter(EMAFE_MR_LPF_ON2_Msk);
EMAFE_DisableInterrupt(EMAFE_IDR_DRDY_Msk);
appData.newDataReady = true;
}
}
}
static void _emafeADCReset(bool enable)
{
if (enable) {
/* Enable ADC SOFT RESET */
EMAFE_ADCEnableSoftReset();
} else {
/* Disable ADC SOFT RESET */
EMAFE_ADCDisableSoftReset();
/* Wait SYSRDY */
while (!(EMAFE_ADCIsAnalogSystemReady()));
}
}
static void _emafeConfigADCChannels(bool tempEnable, uint8_t gainI1, uint8_t gainI2)
{
/* EMAFE Release Reset */
_emafeADCReset(false);
/* Enable ADC Channels */
EMAFE_ADCI0Enable(tempEnable);
while (!EMAFE_ADCI0IsEnable());
EMAFE_ADCI1Enable(gainI1);
while (!EMAFE_ADCI1IsEnable());
EMAFE_ADCV1Enable();
while (!EMAFE_ADCV1IsEnable());
EMAFE_ADCI2Enable(gainI2);
while (!EMAFE_ADCI2IsEnable());
EMAFE_ADCV2Enable();
while (!EMAFE_ADCV2IsEnable());
/* Set ADC clock configuration */
EMAFE_ADCSetClockConfig(EMAFE_ADC_CLOCK_FREQRATIO_4,
EMAFE_ADC_CLOCK_MCLKDIV_ANACK2);
}
void APP_Initialize ( void )
{
/* Place the App state machine in its initial state. */
appData.state = APP_STATE_ADC_CONTROL_INIT;
appData.timer = SYS_TIME_HANDLE_INVALID;
appData.pSamplesData = pSamplesBuffer;
appData.samplesCounter = 0;
appData.newDataReady = false;
appData.dataFormat = EMAFE_EMR_FORMAT_FULLRANGE;
}
void APP_Tasks ( void )
{
switch ( appData.state )
{
/* Application's initial state. */
case APP_STATE_ADC_CONTROL_INIT:
{
_emafeConfigADCChannels(true, 0, 0);
/* Enable Analog controls. First enable LDO. */
appData.state = APP_STATE_ADC_ENABLE_LDO;
SYS_TIME_DelayMS(1, &appData.timer);
break;
}
case APP_STATE_ADC_ENABLE_LDO:
{
if ((appData.timer == SYS_TIME_HANDLE_INVALID) || (SYS_TIME_DelayIsComplete(appData.timer)))
{
if (EMAFE_ADCIsLDOEnable())
{
appData.state = APP_STATE_ADC_ENABLE_BIAS;
appData.timer = SYS_TIME_HANDLE_INVALID;
}
else
{
EMAFE_ADCEnableLDO();
SYS_TIME_DelayMS(10, &appData.timer);
}
}
}
break;
case APP_STATE_ADC_ENABLE_BIAS:
{
if ((appData.timer == SYS_TIME_HANDLE_INVALID) || (SYS_TIME_DelayIsComplete(appData.timer)))
{
if (EMAFE_ADCIsBIASEnable())
{
appData.state = APP_STATE_ADC_ENABLE_REF;
appData.timer = SYS_TIME_HANDLE_INVALID;
}
else
{
EMAFE_ADCEnableBIAS();
SYS_TIME_DelayMS(10, &appData.timer);
}
}
}
break;
case APP_STATE_ADC_ENABLE_REF:
{
if ((appData.timer == SYS_TIME_HANDLE_INVALID) || (SYS_TIME_DelayIsComplete(appData.timer)))
{
if (EMAFE_ADCIsREFEnable())
{
appData.state = APP_STATE_FILTER_CONTROL_INIT;
appData.timer = SYS_TIME_HANDLE_INVALID;
}
else
{
EMAFE_ADCEnableREF();
/* Wait 100 ms for VREF setting */
SYS_TIME_DelayMS(100, &appData.timer);
}
}
}
break;
case APP_STATE_FILTER_CONTROL_INIT:
{
/* LPFIF reset */
EMAFE_SoftReset();
/* Decimation LPFIF Filters exits the reset state */
EMAFE_SetSincDecimationFiltersReset(false);
/* Set DSP clock prescaler ratio */
EMAFE_SetClockPrescalerRatio(EMAFE_EMR_MCLKDIV_LPF_MCLKDIV4_Val);
EMAFE_SetDataFormat(appData.dataFormat);
EMAFE_SetOSR(EMAFE_EMR_OSR_OSR64_Val);
appData.state = APP_STATE_FILTER_START_CAPTURE;
SYS_TIME_DelayMS(2, &appData.timer);
break;
}
case APP_STATE_FILTER_START_CAPTURE:
{
if (SYS_TIME_DelayIsComplete(appData.timer))
{
appData.newDataReady = false;
appData.samplesCounter = 0;
appData.pSamplesData = pSamplesBuffer;
/* Register callback */
EMAFE_CallbackRegister(_appEmafeCallback);
/* Init Decimation Filters */
EMAFE_EnableFilter(EMAFE_MR_LPF_ON2_Msk);
/* Enable Interrupt */
EMAFE_EnableInterrupt(EMAFE_IER_DRDY_Msk);
appData.state = APP_STATE_FILTER_PRINT_SAMPLES;
}
}
break;
case APP_STATE_FILTER_PRINT_SAMPLES:
{
if (appData.newDataReady)
{
appData.pSamplesData = pSamplesBuffer;
appData.samplesCounter = 0;
appData.newDataReady = false;
SYS_TIME_DelayMS(5, &appData.timer);
}
if (SYS_TIME_DelayIsComplete(appData.timer))
{
if (appData.samplesCounter < APP_SAMPLE_CHANNELS)
{
uint16_t index;
for (index = 0; index < APP_SAMPLES_PRINT; index += 5)
{
uint32_t s0, s1, s2, s3, s4;
if (appData.dataFormat == EMAFE_EMR_FORMAT_FULLRANGE_Val)
{
s0 = *appData.pSamplesData;
appData.pSamplesData++;
s1 = *appData.pSamplesData;
appData.pSamplesData++;
s2 = *appData.pSamplesData;
appData.pSamplesData++;
s3 = *appData.pSamplesData;
appData.pSamplesData++;
s4 = *appData.pSamplesData;
appData.pSamplesData++;
}
else
{
s0 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s1 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s2 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s3 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s4 = *appData.pSamplesData << 8;
appData.pSamplesData++;
}
appData.samplesCounter += 5;
SYS_CONSOLE_Print(SYS_CONSOLE_INDEX_0, "%08X\r\n%08X\r\n%08X\r\n%08X\r\n%08X\r\n",
s0, s1, s2, s3, s4);
}
SYS_TIME_DelayMS(100, &appData.timer);
}
else
{
appData.state = APP_STATE_FILTER_IDLE;
}
}
}
break;
case APP_STATE_FILTER_IDLE:
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
DMA Transfer
APP_DATA appData;
/* Buffer setting */
#define APP_SAMPLE_CHANNELS 1600 // 320 samples/cycle(50Hz) * 5 cycles
/** Buffer to store sample sets */
static uint32_t pSamplesBuffer[APP_SAMPLE_CHANNELS] = {0};
void SYS_Initialize ( void* data )
{
(...)
EMAFE_Initialize();
(...)
}
void _appEmafeCallback(uint32_t interruptStatus)
{
if (interruptStatus & EMAFE_IER_ENDRX_Msk)
{
EMAFE_DMATransfer(false, EMAFE_PTCR_RXTDIS_Msk);
EMAFE_DisableInterrupt(EMAFE_IDR_ENDRX_Msk);
appData.newDataReady = true;
}
}
static void _emafeADCReset(bool enable)
{
if (enable) {
/* Enable ADC SOFT RESET */
EMAFE_ADCEnableSoftReset();
} else {
/* Disable ADC SOFT RESET */
EMAFE_ADCDisableSoftReset();
/* Wait SYSRDY */
while (!(EMAFE_ADCIsAnalogSystemReady()));
}
}
static void _emafeConfigADCChannels(bool tempEnable, uint8_t gainI1, uint8_t gainI2)
{
/* EMAFE Release Reset */
_emafeADCReset(false);
/* Enable ADC Channels */
EMAFE_ADCI0Enable(tempEnable);
while (!EMAFE_ADCI0IsEnable());
EMAFE_ADCI1Enable(gainI1);
while (!EMAFE_ADCI1IsEnable());
EMAFE_ADCV1Enable();
while (!EMAFE_ADCV1IsEnable());
EMAFE_ADCI2Enable(gainI2);
while (!EMAFE_ADCI2IsEnable());
EMAFE_ADCV2Enable();
while (!EMAFE_ADCV2IsEnable());
/* Set ADC clock configuration */
EMAFE_ADCSetClockConfig(EMAFE_ADC_CLOCK_FREQRATIO_4,
EMAFE_ADC_CLOCK_MCLKDIV_ANACK2);
}
void APP_Initialize ( void )
{
/* Place the App state machine in its initial state. */
appData.state = APP_STATE_ADC_CONTROL_INIT;
appData.timer = SYS_TIME_HANDLE_INVALID;
appData.pSamplesData = pSamplesBuffer;
appData.newDataReady = false;
appData.dataFormat = EMAFE_EMR_FORMAT_FULLRANGE;
}
void APP_Tasks ( void )
{
switch ( appData.state )
{
/* Application's initial state. */
case APP_STATE_ADC_CONTROL_INIT:
{
_emafeConfigADCChannels(true, 0, 0);
/* Enable Analog controls. First enable LDO. */
appData.state = APP_STATE_ADC_ENABLE_LDO;
SYS_TIME_DelayMS(1, &appData.timer);
break;
}
case APP_STATE_ADC_ENABLE_LDO:
{
if ((appData.timer == SYS_TIME_HANDLE_INVALID) || (SYS_TIME_DelayIsComplete(appData.timer)))
{
if (EMAFE_ADCIsLDOEnable())
{
appData.state = APP_STATE_ADC_ENABLE_BIAS;
appData.timer = SYS_TIME_HANDLE_INVALID;
}
else
{
EMAFE_ADCEnableLDO();
SYS_TIME_DelayMS(10, &appData.timer);
}
}
}
break;
case APP_STATE_ADC_ENABLE_BIAS:
{
if ((appData.timer == SYS_TIME_HANDLE_INVALID) || (SYS_TIME_DelayIsComplete(appData.timer)))
{
if (EMAFE_ADCIsBIASEnable())
{
appData.state = APP_STATE_ADC_ENABLE_REF;
appData.timer = SYS_TIME_HANDLE_INVALID;
}
else
{
EMAFE_ADCEnableBIAS();
SYS_TIME_DelayMS(10, &appData.timer);
}
}
}
break;
case APP_STATE_ADC_ENABLE_REF:
{
if ((appData.timer == SYS_TIME_HANDLE_INVALID) || (SYS_TIME_DelayIsComplete(appData.timer)))
{
if (EMAFE_ADCIsREFEnable())
{
appData.state = APP_STATE_FILTER_CONTROL_INIT;
appData.timer = SYS_TIME_HANDLE_INVALID;
}
else
{
EMAFE_ADCEnableREF();
/* Wait 100 ms for VREF setting */
SYS_TIME_DelayMS(100, &appData.timer);
}
}
}
break;
case APP_STATE_FILTER_CONTROL_INIT:
{
/* LPFIF reset */
EMAFE_SoftReset();
/* Decimation LPFIF Filters exits the reset state */
EMAFE_SetSincDecimationFiltersReset(false);
/* Set DSP clock prescaler ratio */
EMAFE_SetClockPrescalerRatio(EMAFE_EMR_MCLKDIV_LPF_MCLKDIV4_Val);
EMAFE_SetDataFormat(appData.dataFormat);
EMAFE_SetOSR(EMAFE_EMR_OSR_OSR64_Val);
appData.state = APP_STATE_FILTER_START_CAPTURE;
SYS_TIME_DelayMS(2, &appData.timer);
break;
}
case APP_STATE_FILTER_START_CAPTURE:
{
if (SYS_TIME_DelayIsComplete(appData.timer))
{
/* Register callback */
EMAFE_CallbackRegister(_appEmafeCallback);
/* Init Decimation Filters */
EMAFE_EnableFilter(EMAFE_MR_LPF_ON2_Msk);
/* Setup DMA */
EMAFE_EnableDMAChannel(EMAFE_MR_DMACH2_Msk);
EMAFE_DMATransfer(false, EMAFE_PTCR_RXTDIS_Msk);
EMAFE_DMASetup(pSamplesBuffer, APP_SAMPLE_CHANNELS, NULL, 0);
EMAFE_DMATransfer(true, EMAFE_PTCR_RXTEN_Msk);
/* Enable Interrupt */
EMAFE_EnableInterrupt(EMAFE_IER_ENDRX_Msk);
appData.state = APP_STATE_FILTER_PRINT_SAMPLES;
}
}
break;
case APP_STATE_FILTER_PRINT_SAMPLES:
{
if (appData.newDataReady)
{
appData.newDataReady = false;
appData.pSamplesData = pSamplesBuffer;
appData.samplesCounter = 0;
SYS_TIME_DelayMS(5, &appData.timer);
}
if (appData.pSamplesData != NULL)
{
if (SYS_TIME_DelayIsComplete(appData.timer))
{
if (appData.samplesCounter < APP_SAMPLE_CHANNELS)
{
uint16_t index;
for (index = 0; index < APP_SAMPLES_PRINT; index += 5)
{
uint32_t s0, s1, s2, s3, s4;
if (appData.dataFormat == EMAFE_EMR_FORMAT_FULLRANGE_Val)
{
s0 = *appData.pSamplesData;
appData.pSamplesData++;
s1 = *appData.pSamplesData;
appData.pSamplesData++;
s2 = *appData.pSamplesData;
appData.pSamplesData++;
s3 = *appData.pSamplesData;
appData.pSamplesData++;
s4 = *appData.pSamplesData;
appData.pSamplesData++;
}
else
{
s0 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s1 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s2 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s3 = *appData.pSamplesData << 8;
appData.pSamplesData++;
s4 = *appData.pSamplesData << 8;
appData.pSamplesData++;
}
appData.samplesCounter += 5;
SYS_CONSOLE_Print(SYS_CONSOLE_INDEX_0, "%08X\r\n%08X\r\n%08X\r\n%08X\r\n%08X\r\n",
s0, s1, s2, s3, s4);
}
SYS_TIME_DelayMS(100, &appData.timer);
}
else
{
appData.pSamplesData = NULL;
appData.state = APP_STATE_FILTER_IDLE;
}
}
}
}
break;
case APP_STATE_FILTER_IDLE:
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
