- 变量定义
#define ADC_SAMPLE_BUF_SIZE 128
uint32_t g_ui32ADCSampleBuffer[ADC_SAMPLE_BUF_SIZE];
am_hal_adc_sample_t SampleBuffer[ADC_SAMPLE_BUF_SIZE];
//
// ADC Device Handle.
//
static void *g_ADCHandle;
//
// ADC DMA complete flag.
//
volatile bool g_bADCDMAComplete;
//
// ADC DMA error flag.
//
volatile bool g_bADCDMAError;
//
// Define the ADC SE0 pin to be used.
//
const am_hal_gpio_pincfg_t g_AM_PIN_16_ADCSE0 =
{
.uFuncSel = AM_HAL_PIN_16_ADCSE0,
};
- ADC配置
//*****************************************************************************
//
// Configure the ADC.
//
//*****************************************************************************
void adc_config(void)
{
am_hal_adc_config_t ADCConfig;
am_hal_adc_slot_config_t ADCSlotConfig;
//
// Initialize the ADC and get the handle.
//
if ( AM_HAL_STATUS_SUCCESS != am_hal_adc_initialize(0, &g_ADCHandle) )
{
am_util_stdio_printf("Error - reservation of the ADC instance failed.\n");
}
//
// Power on the ADC.
//
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_power_control(g_ADCHandle,
AM_HAL_SYSCTRL_WAKE,
false) )
{
am_util_stdio_printf("Error - ADC power on failed.\n");
}
//
// Set up the ADC configuration parameters. These settings are reasonable
// for accurate measurements at a low sample rate.
//
ADCConfig.eClock = AM_HAL_ADC_CLKSEL_HFRC;
ADCConfig.ePolarity = AM_HAL_ADC_TRIGPOL_RISING;
ADCConfig.eTrigger = AM_HAL_ADC_TRIGSEL_SOFTWARE;
ADCConfig.eReference = AM_HAL_ADC_REFSEL_INT_1P5;
ADCConfig.eClockMode = AM_HAL_ADC_CLKMODE_LOW_LATENCY;
ADCConfig.ePowerMode = AM_HAL_ADC_LPMODE0;
ADCConfig.eRepeat = AM_HAL_ADC_REPEATING_SCAN;
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure(g_ADCHandle, &ADCConfig))
{
am_util_stdio_printf("Error - configuring ADC failed.\n");
}
//
// Set up an ADC slot
//
ADCSlotConfig.eMeasToAvg = AM_HAL_ADC_SLOT_AVG_128;
ADCSlotConfig.ePrecisionMode = AM_HAL_ADC_SLOT_14BIT;
ADCSlotConfig.eChannel = AM_HAL_ADC_SLOT_CHSEL_SE0;
ADCSlotConfig.bWindowCompare = false;
ADCSlotConfig.bEnabled = true;
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_slot(g_ADCHandle, 0, &ADCSlotConfig))
{
am_util_stdio_printf("Error - configuring ADC Slot 0 failed.\n");
}
//
// Configure the ADC to use DMA for the sample transfer.
//
adc_config_dma();
//
// For this example, the samples will be coming in slowly. This means we
// can afford to wake up for every conversion.
//
am_hal_adc_interrupt_enable(g_ADCHandle, AM_HAL_ADC_INT_DERR | AM_HAL_ADC_INT_DCMP );
//
// Enable the ADC.
//
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_enable(g_ADCHandle))
{
am_util_stdio_printf("Error - enabling ADC failed.\n");
}
}
- timer3配置
//*****************************************************************************
//
// Initialize the ADC repetitive sample timer A3.
//
//*****************************************************************************
void init_timerA3_for_ADC(void)
{
//
// Start a timer to trigger the ADC periodically (1 second).
//
am_hal_ctimer_config_single(3, AM_HAL_CTIMER_TIMERA,
AM_HAL_CTIMER_HFRC_12MHZ |
AM_HAL_CTIMER_FN_REPEAT |
AM_HAL_CTIMER_INT_ENABLE);
am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERA3);
am_hal_ctimer_period_set(3, AM_HAL_CTIMER_TIMERA, 10, 5);
//
// Enable the timer A3 to trigger the ADC directly
//
am_hal_ctimer_adc_trigger_enable();
//
// Start the timer.
//
am_hal_ctimer_start(3, AM_HAL_CTIMER_TIMERA);
}
- ADC DMA配置
//*****************************************************************************
//
// Configure the ADC.
//
//*****************************************************************************
void adc_config_dma(void)
{
am_hal_adc_dma_config_t ADCDMAConfig;
//
// Configure the ADC to use DMA for the sample transfer.
//
ADCDMAConfig.bDynamicPriority = true;
ADCDMAConfig.ePriority = AM_HAL_ADC_PRIOR_SERVICE_IMMED;
ADCDMAConfig.bDMAEnable = true;
ADCDMAConfig.ui32SampleCount = ADC_SAMPLE_BUF_SIZE;
ADCDMAConfig.ui32TargetAddress = (uint32_t)g_ui32ADCSampleBuffer;
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_configure_dma(g_ADCHandle, &ADCDMAConfig))
{
am_util_stdio_printf("Error - configuring ADC DMA failed.\n");
}
//
// Reset the ADC DMA flags.
//
g_bADCDMAComplete = false;
g_bADCDMAError = false;
}
- ADC中断处理函数
//*****************************************************************************
//
// Interrupt handler for the ADC.
//
//*****************************************************************************
void am_adc_isr(void)
{
uint32_t ui32IntMask;
//
// Read the interrupt status.
//
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_status(g_ADCHandle, &ui32IntMask, false))
{
am_util_stdio_printf("Error reading ADC interrupt status\n");
}
//
// Clear the ADC interrupt.
//
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, ui32IntMask))
{
am_util_stdio_printf("Error clearing ADC interrupt status\n");
}
//
// If we got a DMA complete, set the flag.
//
if (ui32IntMask & AM_HAL_ADC_INT_DCMP)
{
g_bADCDMAComplete = true;
}
//
// If we got a DMA error, set the flag.
//
if (ui32IntMask & AM_HAL_ADC_INT_DERR)
{
g_bADCDMAError = true;
}
}
- 主函数调用
//*****************************************************************************
//
// Main
//
//*****************************************************************************
int main(void)
{
am_util_id_t sIdDevice;
uint32_t ui32StrBuf;
//
// Set the clock frequency.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
//
// Initialize the printf interface for ITM output
//
am_bsp_itm_printf_enable();
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("Hello World!\n\n");
//
// Print the device info.
//
am_util_id_device(&sIdDevice);
am_util_stdio_printf("Vendor Name: %s\n", sIdDevice.pui8VendorName);
am_util_stdio_printf("Device type: %s\n", sIdDevice.pui8DeviceName);
am_util_stdio_printf("Qualified: %s\n",
sIdDevice.sMcuCtrlDevice.ui32Qualified ?
"Yes" : "No");
am_util_stdio_printf("Device Info:\n"
"\tPart number: 0x%08X\n"
"\tChip ID0: 0x%08X\n"
"\tChip ID1: 0x%08X\n"
"\tRevision: 0x%08X (Rev%c%c)\n",
sIdDevice.sMcuCtrlDevice.ui32ChipPN,
sIdDevice.sMcuCtrlDevice.ui32ChipID0,
sIdDevice.sMcuCtrlDevice.ui32ChipID1,
sIdDevice.sMcuCtrlDevice.ui32ChipRev,
sIdDevice.ui8ChipRevMaj, sIdDevice.ui8ChipRevMin );
//
// If not a multiple of 1024 bytes, append a plus sign to the KB.
//
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32FlashSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tFlash size: %7d (%d KB%s)\n",
sIdDevice.sMcuCtrlDevice.ui32FlashSize,
sIdDevice.sMcuCtrlDevice.ui32FlashSize / 1024,
&ui32StrBuf);
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32SRAMSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tSRAM size: %7d (%d KB%s)\n\n",
sIdDevice.sMcuCtrlDevice.ui32SRAMSize,
sIdDevice.sMcuCtrlDevice.ui32SRAMSize / 1024,
&ui32StrBuf);
//
// Print the compiler version.
//
am_util_stdio_printf("App Compiler: %s\n", COMPILER_VERSION);
#if defined(AM_PART_APOLLO3) || defined(AM_PART_APOLLO3P)
am_util_stdio_printf("HAL Compiler: %s\n", g_ui8HALcompiler);
am_util_stdio_printf("HAL SDK version: %d.%d.%d\n",
g_ui32HALversion.s.Major,
g_ui32HALversion.s.Minor,
g_ui32HALversion.s.Revision);
am_util_stdio_printf("HAL compiled with %s-style registers\n",
g_ui32HALversion.s.bAMREGS ? "AM_REG" : "CMSIS");
am_hal_security_info_t secInfo;
char sINFO[32];
uint32_t ui32Status;
ui32Status = am_hal_security_get_info(&secInfo);
if (ui32Status == AM_HAL_STATUS_SUCCESS)
{
if ( secInfo.bInfo0Valid )
{
am_util_stdio_sprintf(sINFO, "INFO0 valid, ver 0x%X", secInfo.info0Version);
}
else
{
am_util_stdio_sprintf(sINFO, "INFO0 invalid");
}
am_util_stdio_printf("SBL ver: 0x%x - 0x%x, %s\n",
secInfo.sblVersion, secInfo.sblVersionAddInfo, sINFO);
}
else
{
am_util_stdio_printf("am_hal_security_get_info failed 0x%X\n", ui32Status);
}
#endif // AM_PART_APOLLO3
//
// We are done printing.
// Disable debug printf messages on ITM.
//
// am_bsp_debug_printf_disable();
init_timerA3_for_ADC();
//
// Enable interrupts.
//
NVIC_EnableIRQ(ADC_IRQn);
am_hal_interrupt_master_enable();
//
// Set a pin to act as our ADC input
//
am_hal_gpio_pinconfig(16, g_AM_PIN_16_ADCSE0);
//
// Configure the ADC
//
adc_config();
//
// Trigger the ADC sampling for the first time manually.
//
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
{
am_util_stdio_printf("Error - triggering the ADC failed.\n");
}
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("ADC Example with 1.2Msps and LPMODE=0\n");
//
// Allow time for all printing to finish.
//
am_util_delay_ms(10);
//
while (1)
{
if (!g_bADCDMAComplete)
{
//
// Go to Deep Sleep.
//
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
//
// Check for DMA errors.
//
if (g_bADCDMAError)
{
am_util_stdio_printf("DMA Error occured\n");
while(1);
}
//
// Check if the ADC DMA completion interrupt occurred.
//
if (g_bADCDMAComplete)
{
{
uint32_t ui32SampleCount;
am_util_stdio_printf("DMA Complete\n");
ui32SampleCount = ADC_SAMPLE_BUF_SIZE;
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_samples_read(g_ADCHandle, false,
g_ui32ADCSampleBuffer,
&ui32SampleCount,
SampleBuffer))
{
am_util_stdio_printf("Error - failed to process samples.\n");
}
}
//
// Reset the DMA completion and error flags.
//
g_bADCDMAComplete = false;
//
// Re-configure the ADC DMA.
//
adc_config_dma();
//
// Clear the ADC interrupts.
//
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_interrupt_clear(g_ADCHandle, 0xFFFFFFFF))
{
am_util_stdio_printf("Error - clearing the ADC interrupts failed.\n");
}
//
// Trigger the ADC sampling for the first time manually.
//
if (AM_HAL_STATUS_SUCCESS != am_hal_adc_sw_trigger(g_ADCHandle))
{
am_util_stdio_printf("Error - triggering the ADC failed.\n");
}
}
}
}