//***************************************************************************** // //! @brief Set up the stimer. //! //! @param ui32STimerConfig is the value to load into the configuration reg. //! //! This function should be used to perform the initial set-up of the //! stimer. //! //! @return The 32-bit current config of the STimer Config register // //***************************************************************************** uint32_t am_hal_stimer_config(uint32_t ui32STimerConfig) { uint32_t ui32CurrVal; // // Read the current config // ui32CurrVal = AM_REG(CTIMER, STCFG); // // Write our configuration value. // AM_REG(CTIMER, STCFG) = ui32STimerConfig; // // If all of the clock sources are not HFRC, disable LDO when sleeping if timers are enabled. // if ( (AM_BFR(CTIMER, STCFG, CLKSEL) == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV16) || (AM_BFR(CTIMER, STCFG, CLKSEL) == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV256) ) { AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 0); } else { AM_BFW(PWRCTRL, MISCOPT, DIS_LDOLPMODE_TIMERS, 1); } return ui32CurrVal; }
//***************************************************************************** // //! @brief Enable UART system clock. //! //! This function enables or disables the UART system clock. //! //! @param ui32Module is 0 or 1 for Apollo2. //! @param ui32UartEn is one of the following. //! AM_HAL_CLKGEN_UARTEN_DIS //! AM_HAL_CLKGEN_UARTEN_EN //! AM_HAL_CLKGEN_UARTEN_REDUCE_FREQ //! AM_HAL_CLKGEN_UARTEN_EN_POWER_SAV //! //! @return None. // //***************************************************************************** void am_hal_clkgen_uarten_set(uint32_t ui32Module, uint32_t ui32UartEn) { uint32_t ui32Mask; if ( (ui32Module >= AM_REG_UART_NUM_MODULES) || (ui32UartEn > AM_HAL_CLKGEN_UARTEN_EN_POWER_SAV) ) { return; } ui32UartEn <<= (ui32Module * AM_HAL_CLKGEN_UARTEN_UARTENn_S(ui32Module)); ui32Mask = ~(AM_HAL_CLKGEN_UARTEN_UARTENn_M(ui32Module)); // // Begin critical section. // AM_CRITICAL_BEGIN_ASM // // Set the UART clock // AM_REG(CLKGEN, UARTEN) &= ui32Mask; AM_REG(CLKGEN, UARTEN) |= ui32UartEn; // // Begin critical section. // AM_CRITICAL_END_ASM }
//***************************************************************************** // //! @brief Gets the fault status and capture registers. //! //! @param psFault is a pointer to a structure that will be used to store all //! fault info. //! //! This function gets the status of the ICODE, DCODE, and SYS bus faults and //! the addresses associated with the fault. //! //! @return None // //***************************************************************************** void am_hal_mcuctrl_fault_status(am_hal_mcuctrl_fault_t *psFault) { uint32_t ui32FaultStat; // // Read the Fault Status Register. // ui32FaultStat = AM_REG(MCUCTRL, FAULTSTATUS); psFault->bICODE = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_ICODE_M); psFault->bDCODE = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_DCODE_M); psFault->bSYS = (ui32FaultStat & AM_REG_MCUCTRL_FAULTSTATUS_SYS_M); // // Read the DCODE fault capture address register. // psFault->ui32DCODE = AM_REG(MCUCTRL, DCODEFAULTADDR); // // Read the ICODE fault capture address register. // psFault->ui32ICODE |= AM_REG(MCUCTRL, ICODEFAULTADDR); // // Read the ICODE fault capture address register. // psFault->ui32SYS |= AM_REG(MCUCTRL, SYSFAULTADDR); }
//***************************************************************************** // //! @brief Enable the PDM module. //! //! This function enables the PDM module in the mode previously defined by //! am_hal_pdm_config(). //! //! @return None. // //***************************************************************************** void am_hal_pdm_enable(void) { AM_REG(PDM, PCFG) |= AM_REG_PDM_PCFG_PDMCORE_EN; AM_REG(PDM, VCFG) |= ( AM_REG_PDM_VCFG_IOCLKEN_EN | AM_REG_PDM_VCFG_PDMCLK_EN | AM_REG_PDM_VCFG_RSTB_NORM ); }
//***************************************************************************** // //! @brief Disable the PDM module. //! //! This function disables the PDM module. //! //! @return None. // //***************************************************************************** void am_hal_pdm_disable(void) { AM_REG(PDM, PCFG) &= ~ AM_REG_PDM_PCFG_PDMCORE_EN; AM_REG(PDM, VCFG) &= ~ ( AM_REG_PDM_VCFG_IOCLKEN_EN | AM_REG_PDM_VCFG_PDMCLK_EN | AM_REG_PDM_VCFG_RSTB_NORM ); }
//***************************************************************************** // //! @brief Read the state of the wdt interrupt status. //! //! @param bEnabledOnly - return the status of only the enabled interrupts. //! //! This function extracts the interrupt status bits and returns the enabled or //! raw based on bEnabledOnly. //! //! @return WDT interrupt status. // //***************************************************************************** uint32_t am_hal_wdt_int_status_get(bool bEnabledOnly) { if (bEnabledOnly) { uint32_t u32RetVal = AM_REG(WDT, INTSTAT); return u32RetVal & AM_REG(WDT, INTEN); } else { return AM_REG(WDT, INTSTAT); } }
//***************************************************************************** // //! @brief Clear the stimer counter. //! //! This function clears the STimer Counter and leaves the stimer running. //! //! @return None. // //***************************************************************************** void am_hal_stimer_counter_clear(void) { // // Set the clear bit // AM_REG(CTIMER, STCFG) |= AM_REG_CTIMER_STCFG_CLEAR_M; // // Reset the clear bit // AM_REG(CTIMER, STCFG) &= ~AM_REG_CTIMER_STCFG_CLEAR_M; }
//***************************************************************************** // //! @brief Sets the interrupt status. //! //! @param ui32IntFlags interrupts to be enabled. //! //! This function sets the interrupts. //! //! Valid values for ui32IntFlags are: //! //! AM_HAL_CLKGEN_INT_RTC_ALARM //! AM_HAL_CLKGEN_INT_XT_FAIL //! AM_HAL_CLKGEN_INT_AUTOCAL_COMPLETE //! AM_HAL_CLKGEN_INT AUTOCAL_FAIL //! //! @return None. // //***************************************************************************** void am_hal_clkgen_int_set(uint32_t ui32Interrupt) { // // Set the interrupt status. // AM_REG(CLKGEN, INTSET) = ui32Interrupt; }
//***************************************************************************** // //! @brief Return enabled CLKGEN Interrupts. //! //! Use this function to get all enabled CLKGEN interrupts. //! //! @return enabled CLKGEN interrupts. // //***************************************************************************** uint32_t am_hal_clkgen_int_enable_get(void) { // // Return the enabled interrupts. // return AM_REG(CLKGEN, INTEN); }
//***************************************************************************** // //! @brief Gets the interrupt configuration. //! //! @param bEnabledOnly - return the status of only the enabled interrupts. //! //! This function gets the currently configured interrupts. //! //! @return the configured interrupts. //! //! Possible values for the return are: //! //! AM_HAL_CLKGEN_INT_RTC_ALARM //! AM_HAL_CLKGEN_INT_XT_FAIL //! AM_HAL_CLKGEN_INT_AUTOCAL_COMPLETE //! AM_HAL_CLKGEN_INT AUTOCAL_FAIL // //***************************************************************************** uint32_t am_hal_clkgen_int_status_get(bool bEnabledOnly) { // // Return the status. // if ( bEnabledOnly ) { uint32_t u32RetVal = AM_REG(CLKGEN, INTSTAT); u32RetVal &= AM_REG(CLKGEN, INTEN); return u32RetVal; } else { return AM_REG(CLKGEN, INTSTAT); } }
//***************************************************************************** // //! @brief Stops the desired oscillator(s) (OSC). //! //! @param ui32OscFlags oscillator(s) to stop. //! //! This function stops the desired oscillator(s) (OSC). //! //! Valid values for ui32OscFlags are: //! //! AM_HAL_CLKGEN_OSC_LFRC //! AM_HAL_CLKGEN_OSC_XT //! //! @return None. // //***************************************************************************** void am_hal_clkgen_osc_stop(uint32_t ui32OscFlags) { // // Stop the oscillator(s). // AM_REG(CLKGEN, OCTRL) |= ui32OscFlags; }
//***************************************************************************** // //! @brief Disable selected CLKGEN Interrupts. //! //! Use this function to disable the CLKGEN interrupts. //! //! @param ui32Interrupt - Use the macro bit fields provided in am_hal_clkgen.h //! //! @return None // //***************************************************************************** void am_hal_clkgen_int_disable(uint32_t ui32Interrupt) { // // Disable the interrupts. // AM_REG(CLKGEN, INTEN) &= ~ui32Interrupt; }
//***************************************************************************** // //! @brief Enable selected CLKGEN Interrupts. //! //! Use this function to enable the interrupts. //! //! @param ui32Interrupt - Use the macro bit fields provided in am_hal_clkgen.h //! //! @return None // //***************************************************************************** void am_hal_clkgen_int_enable(uint32_t ui32Interrupt) { // // Enable the interrupts. // AM_REG(CLKGEN, INTEN) |= ui32Interrupt; }
//***************************************************************************** // //! @brief Enables the clock out signal. //! //! @param ui32Signal desired location for the clock out signal. //! //! This function enables the clock out signal. See am_hal_clkgen.h for //! available signals. //! //! e.g. AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC //! AM_HAL_CLKGEN_CLKOUT_CKSEL_HFRC_DIV4 //! AM_HAL_CLKGEN_CLKOUT_CKSEL_LFRC //! //! @return None. // //***************************************************************************** void am_hal_clkgen_clkout_enable(uint32_t ui32Signal) { // // Enable the clock out on desired signal. // AM_REG(CLKGEN, CLKOUT) = AM_REG_CLKGEN_CLKOUT_CKEN_M | ui32Signal; }
//***************************************************************************** // //! @brief Disables the clock out signal. //! //! This function disables the clock out signal. //! //! @return None. // //***************************************************************************** void am_hal_clkgen_clkout_disable(void) { // // Disable the clock out. // AM_REG(CLKGEN, CLKOUT) = 0; }
//***************************************************************************** // //! @brief Starts the desired oscillator(s) (OSC). //! //! @param ui32OscFlags oscillator(s) to start. //! //! This function starts the desired oscillator(s) (OSC). //! //! Valid values for ui32OscFlags are: //! //! AM_HAL_CLKGEN_OSC_LFRC //! AM_HAL_CLKGEN_OSC_XT //! //! @return 0 None. // //***************************************************************************** void am_hal_clkgen_osc_start(uint32_t ui32OscFlags) { // // Start the oscillator(s). // AM_REG(CLKGEN, OCTRL) &= ~ui32OscFlags; }
//***************************************************************************** // //! @brief Clears the interrupts. //! //! @param ui32IntFlags interrupts to be cleared. //! //! This function clears the interrupts. //! //! Valid values for ui32IntFlags are: //! //! AM_HAL_CLKGEN_INT_RTC_ALARM //! AM_HAL_CLKGEN_INT_XT_FAIL //! AM_HAL_CLKGEN_INT_AUTOCAL_COMPLETE //! AM_HAL_CLKGEN_INT AUTOCAL_FAIL //! //! @return None. // //***************************************************************************** void am_hal_clkgen_int_clear(uint32_t ui32Interrupt) { // // Clear the interrupts. // AM_REG(CLKGEN, INTCLR) = ui32Interrupt; }
//***************************************************************************** // //! @brief Start capturing data with the specified capture register. //! //! @param ui32CaptureNum is the Capture Register Number to read. //! //! Use this function to start capturing. //! //! @return None. // //***************************************************************************** void am_hal_stimer_capture_stop(uint32_t ui32CaptureNum) { // // Disable it in the CTIMER block. // AM_REG(CTIMER, CAPTURE_CONTROL) &= ~(AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_M << ((AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_S - AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_S) * ui32CaptureNum)); }
//***************************************************************************** // //! @brief Select the clock divisor for the main system clock. //! //! @param ui32ClockSetting - The divisor value for the system clock. //! //! This function can be used to select the frequency of the main system clock. //! The \e ui32ClockSetting parameter should be set to one of the following //! values: //! //! AM_HAL_CLKGEN_SYSCLK_MAX //! AM_HAL_CLKGEN_SYSCLK_48MHZ //! //! @return None. // //***************************************************************************** void am_hal_clkgen_sysclk_select(uint32_t ui32ClockSetting) { am_hal_debug_assert_msg(ui32ClockSetting == AM_HAL_CLKGEN_SYSCLK_48MHZ, "am_hal_clkgen_sysclk_select(): invalid clock setting."); // // Unlock the clock control register. // AM_REG(CLKGEN, CLKKEY) = AM_REG_CLKGEN_CLKKEY_KEYVAL; // // Set the HFRC divisor to the user-selected value. // AM_REG(CLKGEN, CCTRL) = ui32ClockSetting; // // Lock the clock configuration registers. // AM_REG(CLKGEN, CLKKEY) = 0; }
//***************************************************************************** // //! @brief Disables the ITM //! //! This function completely disables the ARM ITM by resetting the TRCENA bit //! in the DEMCR register. //! //! @return None. // //***************************************************************************** void am_hal_itm_disable(void) { if (g_ui32HALflags & AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_M) { return; } // // Make sure the ITM_TCR is unlocked. // AM_REGVAL(AM_REG_ITM_LOCKAREG_O) = AM_REG_ITM_LOCKAREG_KEYVAL; // // Make sure the ITM/TPIU is not busy. // while ( AM_REG(ITM, TCR) & AM_REG_ITM_TCR_BUSY(1) ); // // Disable the ITM. // for (int ix = 0; ix < 100; ix++) { AM_REG(ITM, TCR) &= ~AM_REG_ITM_TCR_ITM_ENABLE(1); while ( AM_REG(ITM, TCR) & (AM_REG_ITM_TCR_ITM_ENABLE(1) | AM_REG_ITM_TCR_BUSY(1)) ); } // // Reset the TRCENA bit in the DEMCR register, which should disable the ITM // for operation. // AM_REG(SYSCTRL, DEMCR) &= ~AM_REG_SYSCTRL_DEMCR_TRCENA(1); // // Disable the TPIU clock source in MCU control. // AM_REG(MCUCTRL, TPIUCTRL) = AM_REG_MCUCTRL_TPIUCTRL_CLKSEL_0MHz | AM_REG_MCUCTRL_TPIUCTRL_ENABLE_DIS; }
//***************************************************************************** // //! @brief Enables the ITM //! //! This function enables the ARM ITM by setting the TRCENA bit in the DEMCR //! register. //! //! @return None. // //***************************************************************************** void am_hal_itm_enable(void) { if (g_ui32HALflags & AM_HAL_FLAGS_ITMSKIPENABLEDISABLE_M) { return; } // // To be able to access ITM registers, set the Trace Enable bit // in the Debug Exception and Monitor Control Register (DEMCR). // AM_REG(SYSCTRL, DEMCR) |= AM_REG_SYSCTRL_DEMCR_TRCENA(1); while ( !(AM_REG(SYSCTRL, DEMCR) & AM_REG_SYSCTRL_DEMCR_TRCENA(1)) ); // // Write the key to the ITM Lock Access register to unlock the ITM_TCR. // AM_REGVAL(AM_REG_ITM_LOCKAREG_O) = AM_REG_ITM_LOCKAREG_KEYVAL; // // Set the enable bits in the ITM trace enable register, and the ITM // control registers to enable trace data output. // AM_REGVAL(AM_REG_ITM_TPR_O) = 0x0000000f; AM_REGVAL(AM_REG_ITM_TER_O) = 0xffffffff; // // Write to the ITM control and status register (don't enable yet). // AM_REGVAL(AM_REG_ITM_TCR_O) = AM_WRITE_SM(AM_REG_ITM_TCR_ATB_ID, 0x15) | AM_WRITE_SM(AM_REG_ITM_TCR_TS_FREQ, 1) | AM_WRITE_SM(AM_REG_ITM_TCR_TS_PRESCALE, 1) | AM_WRITE_SM(AM_REG_ITM_TCR_SWV_ENABLE, 1) | AM_WRITE_SM(AM_REG_ITM_TCR_DWT_ENABLE, 0) | AM_WRITE_SM(AM_REG_ITM_TCR_SYNC_ENABLE, 0) | AM_WRITE_SM(AM_REG_ITM_TCR_TS_ENABLE, 0) | AM_WRITE_SM(AM_REG_ITM_TCR_ITM_ENABLE, 1); }
//***************************************************************************** // //! @brief Disables HFRC auto-adjustment. //! //! This function disables HFRC auto-adjustment. //! //! @return None. // //***************************************************************************** void am_hal_clkgen_hfrc_adjust_disable(void) { // // Disable the clock out. // AM_REG(CLKGEN, HFADJ) = AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_2 | AM_REG_CLKGEN_HFADJ_HFWARMUP_1SEC | AM_REG_CLKGEN_HFADJ_HFXTADJ(AM_REG_CLKGEN_HFADJ_HFXTADJ_DEFAULT) | AM_REG_CLKGEN_HFADJ_HFADJCK_4SEC | AM_REG_CLKGEN_HFADJ_HFADJEN_DIS; }
//***************************************************************************** // //! @brief Checks if itm is busy and provides a delay to flush the fifo //! //! This function disables the ARM ITM by resetting the TRCENA bit in the DEMCR //! register. //! //! @return None. // //***************************************************************************** void am_hal_itm_not_busy(void) { // // Make sure the ITM/TPIU is not busy. // while (AM_REG(ITM, TCR) & AM_REG_ITM_TCR_BUSY(1)); // // wait for 50us for the data to flush out // am_hal_itm_delay_us(50); }
//***************************************************************************** // //! @brief Configure the PDM module. //! //! This function reads the an \e am_hal_pdm_config_t structure and uses it to //! set up the PDM module. //! //! Please see the information on the am_hal_pdm_config_t configuration //! structure, found in am_hal_pdm.h, for more information on the parameters //! that may be set by this function. //! //! @return None. // //***************************************************************************** void am_hal_pdm_config(am_hal_pdm_config_t *psConfig) { // // setup the PDM PCFG register // AM_REG(PDM, PCFG) = psConfig->ui32PDMConfigReg; // // setup the PDM VCFG register // AM_REG(PDM, VCFG) = psConfig->ui32VoiceConfigReg; // // setup the PDM FIFO Threshold register // AM_REG(PDM, FTHR) = psConfig->ui32FIFOThreshold; // // Flush the FIFO for good measure. // am_hal_pdm_fifo_flush(); }
//***************************************************************************** // //! @brief Enables HFRC auto-adjustment at the specified interval. //! //! @param ui32Warmup - How long to give the HFRC to stabilize during each //! calibration attempt. //! @param ui32Frequency - How often the auto-adjustment should happen. //! //! This function enables HFRC auto-adjustment from an external crystal //! oscillator even when the crystal is not normally being used. //! //! ui32Warmup should be one of the following values: //! //! AM_REG_CLKGEN_HFADJ_HFWARMUP_1SEC //! AM_REG_CLKGEN_HFADJ_HFWARMUP_2SEC //! //! ui32Frequency should be one of the following values: //! //! AM_REG_CLKGEN_HFADJ_HFADJCK_4SEC //! AM_REG_CLKGEN_HFADJ_HFADJCK_16SEC //! AM_REG_CLKGEN_HFADJ_HFADJCK_32SEC //! AM_REG_CLKGEN_HFADJ_HFADJCK_64SEC //! AM_REG_CLKGEN_HFADJ_HFADJCK_128SEC //! AM_REG_CLKGEN_HFADJ_HFADJCK_256SEC //! AM_REG_CLKGEN_HFADJ_HFADJCK_512SEC //! AM_REG_CLKGEN_HFADJ_HFADJCK_1024SEC //! //! @return None. // //***************************************************************************** void am_hal_clkgen_hfrc_adjust_enable(uint32_t ui32Warmup, uint32_t ui32Frequency) { // // Set the HFRC Auto-adjust register for the user's chosen settings. Assume // that the HFRC should be calibrated to 48 MHz and that the crystal is // running at 32.768 kHz. // AM_REG(CLKGEN, HFADJ) = AM_REG_CLKGEN_HFADJ_HFADJ_GAIN_Gain_of_1_in_2 | ui32Warmup | AM_REG_CLKGEN_HFADJ_HFXTADJ(AM_REG_CLKGEN_HFADJ_HFXTADJ_DEFAULT) | ui32Frequency | AM_REG_CLKGEN_HFADJ_HFADJEN_EN; }
//***************************************************************************** // //! @brief Start capturing data with the specified capture register. //! //! @param ui32CaptureNum is the Capture Register Number to read (0-3). //! ui32GPIONumber is the pin number. //! bPolarity: false (0) = Capture on low to high transition. //! true (1) = Capture on high to low transition. //! //! Use this function to start capturing. //! //! @return None. // //***************************************************************************** void am_hal_stimer_capture_start(uint32_t ui32CaptureNum, uint32_t ui32GPIONumber, bool bPolarity) { uint32_t ui32CapCtrl; if ( ui32GPIONumber > (AM_HAL_GPIO_MAX_PADS-1) ) { return; } // // Set the polarity and pin selection in the GPIO block. // switch (ui32CaptureNum) { case 0: AM_BFW(GPIO, STMRCAP, STPOL0, bPolarity); AM_BFW(GPIO, STMRCAP, STSEL0, ui32GPIONumber); ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_A_M; break; case 1: AM_BFW(GPIO, STMRCAP, STPOL1, bPolarity); AM_BFW(GPIO, STMRCAP, STSEL1, ui32GPIONumber); ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_B_M; break; case 2: AM_BFW(GPIO, STMRCAP, STPOL2, bPolarity); AM_BFW(GPIO, STMRCAP, STSEL2, ui32GPIONumber); ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_C_M; break; case 3: AM_BFW(GPIO, STMRCAP, STPOL3, bPolarity); AM_BFW(GPIO, STMRCAP, STSEL3, ui32GPIONumber); ui32CapCtrl = AM_REG_CTIMER_CAPTURE_CONTROL_CAPTURE_D_M; break; default: return; // error concealment. } // // Enable it in the CTIMER Block // AM_REG(CTIMER, CAPTURE_CONTROL) |= ui32CapCtrl; }
//***************************************************************************** // //! @brief Get the current system clock frequency. //! //! This function can be used to determine the frequency of the main system //! clock. The return value is the system clock frequency measured in hertz. //! //! @return System clock frequency in Hz // //***************************************************************************** uint32_t am_hal_clkgen_sysclk_get(void) { uint32_t ui32ClockSetting; // // Read the value of the clock divider. // ui32ClockSetting = AM_REG(CLKGEN, CCTRL) & AM_REG_CLKGEN_CCTRL_CORESEL_M; switch ( ui32ClockSetting ) { case AM_REG_CLKGEN_CCTRL_CORESEL_HFRC: return 48000000; case AM_REG_CLKGEN_CCTRL_CORESEL_HFRC_DIV2: return 24000000; default: return 0xFFFFFFFF; } }
//***************************************************************************** // //! @brief Gets all relevant device information. //! //! @param psDevice is a pointer to a structure that will be used to store all //! device info. //! //! This function gets the device part number, chip IDs, and revision and //! stores them in the passed structure. //! //! @return None // //***************************************************************************** void am_hal_mcuctrl_device_info_get(am_hal_mcuctrl_device_t *psDevice) { // // Read the Part Number. // psDevice->ui32ChipPN = AM_REG(MCUCTRL, CHIP_INFO); // // Read the Chip ID0. // psDevice->ui32ChipID0 = AM_REG(MCUCTRL, CHIPID0); // // Read the Chip ID1. // psDevice->ui32ChipID1 = AM_REG(MCUCTRL, CHIPID1); // // Read the Chip Revision. // psDevice->ui32ChipRev = AM_REG(MCUCTRL, CHIPREV); // // Read the Part Number. // psDevice->ui32ChipPN = AM_REG(MCUCTRL, CHIP_INFO); // // Read the Chip ID0. // psDevice->ui32ChipID0 = AM_REG(MCUCTRL, CHIPID0); // // Read the Chip ID1. // psDevice->ui32ChipID1 = AM_REG(MCUCTRL, CHIPID1); // // Read the Chip Revision. // psDevice->ui32ChipRev = AM_REG(MCUCTRL, CHIPREV); // // Read the Chip VENDOR ID. // psDevice->ui32VendorID = AM_REG(MCUCTRL, VENDORID); // // Qualified from Part Number. // psDevice->ui32Qualified = (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_QUAL_M) >> AM_HAL_MCUCTRL_CHIP_INFO_QUAL_S; // // Flash size from Part Number. // psDevice->ui32FlashSize = g_am_hal_mcuctrl_flash_size[ (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_M) >> AM_HAL_MCUCTRL_CHIP_INFO_FLASH_SIZE_S]; // // SRAM size from Part Number. // psDevice->ui32SRAMSize = g_am_hal_mcuctrl_flash_size[ (psDevice->ui32ChipPN & AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_M) >> AM_HAL_MCUCTRL_CHIP_INFO_SRAM_SIZE_S]; // // Now, let's look at the JEDEC info. // The full partnumber is 12 bits total, but is scattered across 2 registers. // Bits [11:8] are 0xE. // Bits [7:4] are 0xE for Apollo, 0xD for Apollo2. // Bits [3:0] are defined differently for Apollo and Apollo2. // For Apollo, the low nibble is 0x0. // For Apollo2, the low nibble indicates flash and SRAM size. // psDevice->ui32JedecPN = (AM_BFR(JEDEC, PID0, PNL8) << 0); psDevice->ui32JedecPN |= (AM_BFR(JEDEC, PID1, PNH4) << 8); // // JEPID is the JEP-106 Manufacturer ID Code, which is assigned to Ambiq as // 0x1B, with parity bit is 0x9B. It is 8 bits located across 2 registers. // psDevice->ui32JedecJEPID = (AM_BFR(JEDEC, PID1, JEPIDL) << 0); psDevice->ui32JedecJEPID |= (AM_BFR(JEDEC, PID2, JEPIDH) << 4); // // CHIPREV is 8 bits located across 2 registers. // psDevice->ui32JedecCHIPREV = (AM_BFR(JEDEC, PID2, CHIPREVH4) << 4); psDevice->ui32JedecCHIPREV |= (AM_BFR(JEDEC, PID3, CHIPREVL4) << 0); // // Let's get the Coresight ID (32-bits across 4 registers) // For Apollo and Apollo2, it's expected to be 0xB105100D. // psDevice->ui32JedecCID = (AM_BFR(JEDEC, CID3, CID) << 24); psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID2, CID) << 16); psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID1, CID) << 8); psDevice->ui32JedecCID |= (AM_BFR(JEDEC, CID0, CID) << 0); }
//***************************************************************************** // //! @brief Disable the wdt interrupt. //! //! This function disablee the interrupt. //! //! @return None // //***************************************************************************** void am_hal_wdt_int_disable(void) { AM_REG(WDT, INTEN) &= ~AM_REG_WDT_INTSET_WDT_M; }
//***************************************************************************** // //! @brief Configure the watchdog timer. //! //! @param psConfig - pointer to a configuration structure containing the //! desired watchdog settings. //! //! This function will set the watchdog configuration register based on the //! user's desired settings listed in the structure referenced by psConfig. If //! the structure indicates that watchdog interrupts are desired, this function //! will also set the interrupt enable bit in the configuration register. //! //! @note In order to actually receive watchdog interrupt and/or watchdog reset //! events, the caller will also need to make sure that the watchdog interrupt //! vector is enabled in the ARM NVIC, and that watchdog resets are enabled in //! the reset generator module. Otherwise, the watchdog-generated interrupt and //! reset events will have no effect. //! //! @return None. // //***************************************************************************** void am_hal_wdt_init(const am_hal_wdt_config_t *psConfig) { uint32_t ui32ConfigVal; uint16_t ui16IntCount, ui16ResetCount; bool bResetEnabled = psConfig->ui32Config & AM_HAL_WDT_ENABLE_RESET; bool bInterruptEnabled = psConfig->ui32Config & AM_HAL_WDT_ENABLE_INTERRUPT; // // Read the desired settings from the psConfig structure. // ui16IntCount = psConfig->ui16InterruptCount; ui16ResetCount = psConfig->ui16ResetCount; // // Write the interrupt and reset count values to a temporary variable. // // Accept the passed Config value, but clear the Counts that we are about to set. ui32ConfigVal = psConfig->ui32Config & ~(AM_REG_WDT_CFG_INTVAL_M | AM_REG_WDT_CFG_RESVAL_M); ui32ConfigVal |= AM_WRITE_SM(AM_REG_WDT_CFG_INTVAL, ui16IntCount); ui32ConfigVal |= AM_WRITE_SM(AM_REG_WDT_CFG_RESVAL, ui16ResetCount); // // If interrupts should be enabled, set the appropriate bit in the // temporary variable. Also, enable the interrupt in INTEN register in the // watchdog module. // if ( bInterruptEnabled ) { // // Enable the watchdog interrupt if the configuration calls for them. // AM_REGn(WDT, 0, INTEN) |= AM_REG_WDT_INTEN_WDT_M; } else { // // Disable the watchdog interrupt if the configuration doesn't call for // watchdog interrupts. // AM_REGn(WDT, 0, INTEN) &= ~AM_REG_WDT_INTEN_WDT_M; } // // If resets should be enabled, set the appropriate bit in the temporary // variable. // if ( bResetEnabled ) { // // Also enable watchdog resets in the reset module. // AM_REG(RSTGEN, CFG) |= AM_REG_RSTGEN_CFG_WDREN_M; } else { // // Disable watchdog resets in the reset module. // AM_REG(RSTGEN, CFG) &= ~AM_REG_RSTGEN_CFG_WDREN_M; } // // Check for a user specified clock select. If none specified then // set 128Hz. // if ( !(psConfig->ui32Config & AM_REG_WDT_CFG_CLKSEL_M) ) { ui32ConfigVal |= AM_REG_WDT_CFG_CLKSEL_128HZ; } // // Write the saved value to the watchdog configuration register. // AM_REGn(WDT, 0, CFG) = ui32ConfigVal; }