initial commit

This commit is contained in:
2022-10-23 23:45:43 -07:00
commit e190fa5193
6450 changed files with 8626944 additions and 0 deletions
@@ -0,0 +1,48 @@
#******************************************************************************
#
# Makefile - Rules for compiling
#
# Copyright (c) 2020, Ambiq Micro
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# Third party software included in this distribution is subject to the
# additional license terms as defined in the /docs/licenses directory.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# This is part of revision 2.4.2 of the AmbiqSuite Development Package.
#
#******************************************************************************
# All makefiles use this to find the top level directory.
SWROOT?=../../..
# Include rules for building the HAL.
include $(SWROOT)/makedefs/am_hal.mk
# Generate pin definitions for apollo3.
CHIP_GENERATION = 3
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,678 @@
//*****************************************************************************
//
// am_hal_adc.h
//! @file
//!
//! @brief Functions for interfacing with the Analog to Digital Converter
//!
//! @addtogroup adc3 Analog-to-Digital Converter (ADC)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_ADC_H
#define AM_HAL_ADC_H
//*****************************************************************************
//
// CMSIS-style macro for handling a variable IOM module number.
//
#define ADCn(n) ((ADC_Type*)(ADC_BASE + (n * (ADC_BASE - ADC_BASE))))
//*****************************************************************************
//
// Maximum number of slots.
//
#define AM_HAL_ADC_MAX_SLOTS 8
//
// ADC clock selection.
//
typedef enum
{
AM_HAL_ADC_CLKSEL_OFF,
AM_HAL_ADC_CLKSEL_HFRC,
AM_HAL_ADC_CLKSEL_HFRC_DIV2
} am_hal_adc_clksel_e;
//
// ADC trigger polarity
//
typedef enum
{
AM_HAL_ADC_TRIGPOL_RISING,
AM_HAL_ADC_TRIGPOL_FALLING
} am_hal_adc_trigpol_e;
//
// ADC trigger selection
//
typedef enum
{
AM_HAL_ADC_TRIGSEL_EXT0,
AM_HAL_ADC_TRIGSEL_EXT1,
AM_HAL_ADC_TRIGSEL_EXT2,
AM_HAL_ADC_TRIGSEL_EXT3,
AM_HAL_ADC_TRIGSEL_VCOMP,
AM_HAL_ADC_TRIGSEL_SOFTWARE = 7
} am_hal_adc_trigsel_e;
//
// ADC reference selection.
//
typedef enum
{
AM_HAL_ADC_REFSEL_INT_2P0,
AM_HAL_ADC_REFSEL_INT_1P5,
AM_HAL_ADC_REFSEL_EXT_2P0,
AM_HAL_ADC_REFSEL_EXT_1P5
} am_hal_adc_refsel_e;
//
// ADC clock mode selection.
//
typedef enum
{
AM_HAL_ADC_CLKMODE_LOW_POWER, // Disable the clock between scans for LPMODE0.
// Set LPCKMODE to 0x1 while configuring the ADC.
AM_HAL_ADC_CLKMODE_LOW_LATENCY // Low Latency Clock Mode. When set, HFRC and the
// adc_clk will remain on while in functioning in LPMODE0.
} am_hal_adc_clkmode_e;
//
// ADC low-power mode selection.
//
typedef enum
{
AM_HAL_ADC_LPMODE0, // Low Latency Clock Mode. When set, HFRC and the adc_clk
// will remain on while in functioning in LPMODE0.
AM_HAL_ADC_LPMODE1 // Powers down all circuity and clocks associated with the
// ADC until the next trigger event. Between scans, the reference
// buffer requires up to 50us of delay from a scan trigger event
// before the conversion will commence while operating in this mode.
} am_hal_adc_lpmode_e;
//
// ADC repetition selection.
//
typedef enum
{
AM_HAL_ADC_SINGLE_SCAN,
AM_HAL_ADC_REPEATING_SCAN
} am_hal_adc_repeat_e;
//
// ADC measurement averaging configuration.
//
typedef enum
{
AM_HAL_ADC_SLOT_AVG_1,
AM_HAL_ADC_SLOT_AVG_2,
AM_HAL_ADC_SLOT_AVG_4,
AM_HAL_ADC_SLOT_AVG_8,
AM_HAL_ADC_SLOT_AVG_16,
AM_HAL_ADC_SLOT_AVG_32,
AM_HAL_ADC_SLOT_AVG_64,
AM_HAL_ADC_SLOT_AVG_128
} am_hal_adc_meas_avg_e;
//
// ADC slot precision mode.
//
typedef enum
{
AM_HAL_ADC_SLOT_14BIT,
AM_HAL_ADC_SLOT_12BIT,
AM_HAL_ADC_SLOT_10BIT,
AM_HAL_ADC_SLOT_8BIT
} am_hal_adc_slot_prec_e;
//
// ADC slot channel selection.
//
typedef enum
{
// Single-ended channels
AM_HAL_ADC_SLOT_CHSEL_SE0,
AM_HAL_ADC_SLOT_CHSEL_SE1,
AM_HAL_ADC_SLOT_CHSEL_SE2,
AM_HAL_ADC_SLOT_CHSEL_SE3,
AM_HAL_ADC_SLOT_CHSEL_SE4,
AM_HAL_ADC_SLOT_CHSEL_SE5,
AM_HAL_ADC_SLOT_CHSEL_SE6,
AM_HAL_ADC_SLOT_CHSEL_SE7,
AM_HAL_ADC_SLOT_CHSEL_SE8,
AM_HAL_ADC_SLOT_CHSEL_SE9,
// Differential channels.
AM_HAL_ADC_SLOT_CHSEL_DF0,
AM_HAL_ADC_SLOT_CHSEL_DF1,
// Miscellaneous other signals.
AM_HAL_ADC_SLOT_CHSEL_TEMP,
AM_HAL_ADC_SLOT_CHSEL_BATT,
AM_HAL_ADC_SLOT_CHSEL_VSS
} am_hal_adc_slot_chan_e;
//
// DMA priority.
//
typedef enum
{
AM_HAL_ADC_PRIOR_BEST_EFFORT,
AM_HAL_ADC_PRIOR_SERVICE_IMMED
} am_hal_adc_dma_prior_e;
//!
//! ADC control function request types for am_hal_adc_control().
//!
//! AM_HAL_ADC_REQ_TEMP_CELSIUS_GET:
//! pArgs must point to an array of 3 floats. To assure that the
//! array is valid, upon calling the 3rd float (pArgs[2]) must be
//! set to the value -123.456F.
//! AM_HAL_ADC_REQ_TEMP_TRIMS_GET:
//! pArgs must point to an array of 4 floats. To assure that the
//! array is valid, upon calling the 4th float (pArgs[3]) must be
//! set to the to the value -123.456F.
//! On return, pArgs[3] is set to 1 if the returned values are
//! calibrated, or 0 if default calibration values.
//!
typedef enum
{
AM_HAL_ADC_REQ_WINDOW_CONFIG,
AM_HAL_ADC_REQ_TEMP_CELSIUS_GET,
AM_HAL_ADC_REQ_TEMP_TRIMS_GET,
} am_hal_adc_request_e;
//
// ADC Sample structure.
//
typedef struct
{
uint32_t ui32Sample;
uint32_t ui32Slot;
} am_hal_adc_sample_t;
//*****************************************************************************
//
//! @brief Configuration structure for the ADC.
//
//*****************************************************************************
typedef struct
{
//! Select the ADC clock source.
am_hal_adc_clksel_e eClock;
//! Select the ADC trigger polarity.
am_hal_adc_trigpol_e ePolarity;
//! Select the ADC trigger source.
am_hal_adc_trigsel_e eTrigger;
//! Select the ADC reference voltage.
am_hal_adc_refsel_e eReference;
//! Whether to disable clocks between samples.
am_hal_adc_clkmode_e eClockMode;
//! Select the ADC power mode.
am_hal_adc_lpmode_e ePowerMode;
//! Select whether the ADC will re-trigger based on a signal from timer 3.
am_hal_adc_repeat_e eRepeat;
} am_hal_adc_config_t;
//*****************************************************************************
//
//! @brief Configuration structure for the ADC slot.
//
//*****************************************************************************
typedef struct
{
//! Select the number of measurements to average
am_hal_adc_meas_avg_e eMeasToAvg;
//! Select the precision mode
am_hal_adc_slot_prec_e ePrecisionMode;
//! Select the channel
am_hal_adc_slot_chan_e eChannel;
//! Select window comparison mode
bool bWindowCompare;
//! Enable the slot
bool bEnabled;
} am_hal_adc_slot_config_t;
//*****************************************************************************
//
//! @brief Configuration structure for the ADC DMA
//
//*****************************************************************************
typedef struct
{
//! ADC DMA dynamic priority enabled.
bool bDynamicPriority;
//! ADC DMA static priority.
am_hal_adc_dma_prior_e ePriority;
//! Enable DMA for ADC
bool bDMAEnable;
//! Transfer count in samples
uint32_t ui32SampleCount;
//! Target address
uint32_t ui32TargetAddress;
} am_hal_adc_dma_config_t;
//*****************************************************************************
//
//! @brief Window configuration structure for the ADC.
//
//*****************************************************************************
typedef struct
{
//! Scale window comparison
bool bScaleLimits;
//! Window limits
uint32_t ui32Upper;
uint32_t ui32Lower;
} am_hal_adc_window_config_t;
//*****************************************************************************
//
//! @brief Capabilities structure for the ADC.
//
//*****************************************************************************
typedef struct
{
uint32_t dummy;
} am_hal_adc_capabilities_t;
//*****************************************************************************
//
//! @brief Status structure for the ADC.
//
//*****************************************************************************
typedef struct
{
//
// ADC power status.
//
bool bPoweredOn;
bool bLPMode1;
//
// DMA status.
//
bool bErr;
bool bCmp;
bool bTIP;
} am_hal_adc_status_t;
//
// Transfer callback function prototype
//
typedef void (*am_hal_adc_callback_t)(void *pCallbackCtxt, uint32_t status);
//*****************************************************************************
//
//! @name ADC Interrupts
//! @brief Interrupt Status Bits for enable/disble use
//!
//! These macros may be used to enable an individual ADC interrupt cause.
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_INT_DERR (_VAL2FLD(ADC_INTEN_DERR, 1))
#define AM_HAL_ADC_INT_DCMP (_VAL2FLD(ADC_INTEN_DCMP, 1))
#define AM_HAL_ADC_INT_WCINC (_VAL2FLD(ADC_INTEN_WCINC, 1))
#define AM_HAL_ADC_INT_WCEXC (_VAL2FLD(ADC_INTEN_WCEXC, 1))
#define AM_HAL_ADC_INT_FIFOOVR2 (_VAL2FLD(ADC_INTEN_FIFOOVR2, 1))
#define AM_HAL_ADC_INT_FIFOOVR1 (_VAL2FLD(ADC_INTEN_FIFOOVR1, 1))
#define AM_HAL_ADC_INT_SCNCMP (_VAL2FLD(ADC_INTEN_SCNCMP, 1))
#define AM_HAL_ADC_INT_CNVCMP (_VAL2FLD(ADC_INTEN_CNVCMP, 1))
//! @}
//*****************************************************************************
//
//! @brief ADC Fifo Read macros
//!
//! These are helper macros for interpreting FIFO data. Each ADC FIFO entry
//! contains information about the slot number and the FIFO depth alongside the
//! current sample. These macros perform the correct masking and shifting to
//! read those values.
//!
//! The SAMPLE and FULL_SAMPLE options refer to the fractional part of averaged
//! samples. If you are not using hardware averaging or don't need the
//! fractional part of the ADC sample, you should just use
//! AM_HAL_ADC_FIFO_SAMPLE.
//!
//! If you do need the fractional part, use AM_HAL_ADC_FIFO_FULL_SAMPLE. This
//! macro will keep six bits of precision past the decimal point. Depending on
//! the number of averaged samples, anywhere between 1 and 6 of these bits will
//! be valid. Please consult the datasheet to find out how many bits of data
//! are valid for your chosen averaging settings.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_ADC_FIFO_SAMPLE(value) (_FLD2VAL(ADC_FIFO_DATA, value) >> 6)
#define AM_HAL_ADC_FIFO_FULL_SAMPLE(value) (_FLD2VAL(ADC_FIFO_DATA, value))
#define AM_HAL_ADC_FIFO_SLOT(value) (_FLD2VAL(ADC_FIFO_SLOTNUM, value))
#define AM_HAL_ADC_FIFO_COUNT(value) (_FLD2VAL(ADC_FIFO_COUNT, value))
//! @}
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! @brief ADC initialization function
//!
//! @param ui32Module - module instance.
//! @param handle - returns the handle for the module instance.
//!
//! This function accepts a module instance, allocates the interface and then
//! returns a handle to be used by the remaining interface functions.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_initialize(uint32_t ui32Module, void **ppHandle);
//*****************************************************************************
//
//! @brief MSPI deinitialization function
//!
//! @param handle - returns the handle for the module instance.
//!
//! This function accepts a handle to an instance and de-initializes the
//! interface.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_deinitialize(void *pHandle);
//*****************************************************************************
//
//! @brief ADC configuration function
//!
//! @param handle - handle for the module instance.
//! @param pConfig - pointer to the configuration structure.
//!
//! This function configures the ADC for operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_configure(void *pHandle,
am_hal_adc_config_t *psConfig);
//*****************************************************************************
//
//! @brief ADC slot configuration function
//!
//! @param handle - handle for the module instance.
//! @param pConfig - pointer to the configuration structure.
//!
//! This function configures the ADC slot for operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_configure_slot(void *pHandle,
uint32_t ui32SlotNumber,
am_hal_adc_slot_config_t *pSlotConfig);
//*****************************************************************************
//
//! @brief ADC DMA configuration function
//!
//! @param handle - handle for the module instance.
//! @param pConfig - pointer to the configuration structure.
//!
//! This function configures the ADC DMA for operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_configure_dma(void *pHandle,
am_hal_adc_dma_config_t *pDMAConfig);
//*****************************************************************************
//
//! @brief ADC device specific control function.
//!
//! @param handle - handle for the module instance.
//! @eRequest - One of:
//! AM_HAL_ADC_REQ_WINDOW_CONFIG
//! AM_HAL_ADC_REQ_TEMP_CELSIUS_GET (pArgs is required, see enums).
//! AM_HAL_ADC_REQ_TEMP_TRIMS_GET (pArgs is required, see enums).
//!
//! This function provides for special control functions for the ADC operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_control(void *pHandle,
am_hal_adc_request_e eRequest,
void *pArgs);
//*****************************************************************************
//
//! @brief ADC enable function
//!
//! @param handle - handle for the module instance.
//!
//! This function enables the ADC operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_enable(void *pHandle);
//*****************************************************************************
//
//! @brief ADC disable function
//!
//! @param handle - handle for the module instance.
//!
//! This function disables the ADC operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_disable(void *pHandle);
//*****************************************************************************
//
//! @brief ADC status function
//!
//! @param handle - handle for the interface.
//!
//! This function returns the current status of the DMA operation.
//!
//! @return status - DMA status flags.
//
//*****************************************************************************
extern uint32_t am_hal_adc_status_get(void *pHandle,
am_hal_adc_status_t *pStatus );
//*****************************************************************************
//
//! @brief ADC enable interrupts function
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - ADC interrupt mask.
//!
//! This function enables the specific indicated interrupts.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_interrupt_enable(void *pHandle, uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief ADC disable interrupts function
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - ADC interrupt mask.
//!
//! This function disable the specific indicated interrupts.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_interrupt_disable(void *pHandle, uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief ADC interrupt status function
//!
//! @param handle - handle for the interface.
//!
//! This function returns the specific indicated interrupt status.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_interrupt_status(void *pHandle,
uint32_t *pui32Status,
bool bEnabledOnly);
//*****************************************************************************
//
//! @brief ADC interrupt clear
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - uint32_t for interrupts to clear
//!
//! This function clears the interrupts for the given peripheral.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_interrupt_clear(void *pHandle, uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief ADC sample read function
//!
//! @param pHandle - handle for the module instance.
//! @param bFullSample - true to get a full sample including
//! the fractional part.
//! @param pui32InSampleBuffer - Ptr to the input sample buffer.
//! If NULL then samples will be read directly
//! from the FIFO.
//! @param pui32InOutNumberSamples - Ptr to variable containing the number of
//! samples.
//! @param pui32OutSampleBuffer - Ptr to the required output sample buffer.
//!
//! This function reads samples from the ADC FIFO or an SRAM sample buffer
//! returned by a DMA operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_samples_read(void *pHandle, bool bFullSample,
uint32_t *pui32InSampleBuffer,
uint32_t *pui32InOutNumberSamples,
am_hal_adc_sample_t *pui32OutBuffer);
//*****************************************************************************
//
//! @brief ADC FIFO trigger function
//!
//! @param handle - handle for the module instance.
//!
//! This function triggers the ADC operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_sw_trigger(void *pHandle);
//*****************************************************************************
//
//! @brief ADC power control function
//!
//! @param handle - handle for the interface.
//! @param ePowerState - the desired power state to move the peripheral to.
//! @param bRetainState - flag (if true) to save/restore peripheral state upon
//! power state change.
//!
//! This function updates the peripheral to a given power state.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_adc_power_control(void *pHandle,
am_hal_sysctrl_power_state_e ePowerState,
bool bRetainState);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_ADC_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,704 @@
//*****************************************************************************
//
//! @file am_hal_ble_patch.c
//!
//! @brief This is a binary patch for the BLE core.
//!
//! @addtogroup
//! @ingroup
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// BLE LL local supported feature flags.
//
// Bit position | Link Layer Feature
// 0 | LE Encryption
// 1 | Connection Parameters Request Procedure
// 2 | Extended Reject Indication
// 3 | Slave-initiated Features Exchange
// 4 | LE Ping
// 5 | LE Data Packet Length Extension
// 6 | LL Privacy
// 7 | Extended Scanner Filter Policies
//
// Specified 4.6 Feature Support, Link Layer Specification, Core V4.2.
//
//*****************************************************************************
#ifndef AM_HAL_BLE_LOCAL_FEATURE
#define AM_HAL_BLE_LOCAL_FEATURE 0x21
#endif
//*****************************************************************************
//
// Patches included in this file.
//
//*****************************************************************************
am_hal_ble_patch_t am_ble_buffer_patch;
am_hal_ble_patch_t am_ble_performance_patch;
am_hal_ble_patch_t am_ble_performance_copy_patch;
am_hal_ble_patch_t am_ble_nvds_patch;
//*****************************************************************************
//
// Patch application order.
//
//*****************************************************************************
am_hal_ble_patch_t *am_hal_ble_default_patch_array[] =
{
// FTCODE patches (type 0xAA)
// RAMCODE patches (type 0xBB)
&am_ble_performance_patch,
// Standard patches (type 0xCC)
&am_ble_buffer_patch,
// nvds param (type 0xDD)
&am_ble_nvds_patch,
};
am_hal_ble_patch_t *am_hal_ble_default_copy_patch_array[] =
{
// FTCODE patches (type 0xAA)
// RAMCODE patches (type 0xBB)
&am_ble_performance_copy_patch,
};
#define AM_HAL_BLE_NUM_DEFAULT_PATCHES \
(sizeof(am_hal_ble_default_patch_array) / \
sizeof(am_hal_ble_default_patch_array[0]))
am_hal_ble_patch_t **am_hal_ble_default_patches = am_hal_ble_default_patch_array;
am_hal_ble_patch_t **am_hal_ble_default_copy_patches = am_hal_ble_default_copy_patch_array;
const uint32_t am_hal_ble_num_default_patches = AM_HAL_BLE_NUM_DEFAULT_PATCHES;
//*****************************************************************************
//
// Patch Name: RAMCODE COPY PATCH v1.10 for Apollo3 A1
//
// Bi-directional data fix
// Modulation deviation fix
// Extend patch memory
// Transmit speed patch
// Added AGC table and enabled AGC
// Added local feature support setting
// Fix to connection interval calculation issue with MTK chip sets (OPPO R15 fix)
// Set VCO to 250mv
// Modex auto calibration update
// Fix connection interval calculation issue
// Increase RF LDO ref voltage form 1.0v to 1.1v
// Decrease DAC channel delay cycle
// Increase the VCO swing from 250mv to 300mv
// Fix MD trans schedule issue (disabled)
// Fix link loss issue
// Reduce duration from TX to TX
// Optimized 32K XO frequency calculation
// Fix channel map rejected issue
// Optimized AGC Table
// Date: 2019-01-30
//*****************************************************************************
const am_hal_ble_buffer(0x0912) am_ble_performance_copy_patch_data =
{
.bytes =
{
0x00,0x11,0x6e,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0xc5,0x01,
0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x70,0xb5,0x00,0x20,0x0c,0x49,0x49,0x88,
0x0c,0x4a,0x8b,0x18,0x1a,0x88,0x0c,0x49,0x9b,0x1c,0x00,0x24,0x13,0x25,0x2d,0x02,
0x0c,0x54,0x40,0x1c,0xa8,0x42,0xfb,0xdb,0x00,0x20,0x00,0x2a,0x04,0xdd,0x1c,0x5c,
0x0c,0x54,0x40,0x1c,0x90,0x42,0xfa,0xdb,0x04,0x48,0x80,0x47,0x00,0x20,0x70,0xbd,
0x00,0x48,0x00,0x20,0x02,0x48,0x00,0x20,0x00,0x35,0x00,0x20,0xaf,0x33,0x01,0x00,
0xa0,0x08,0x1f,0xb5,0x00,0x24,0x00,0x98,0x1d,0x28,0x43,0xd2,0x01,0x00,0x79,0x44,
0x09,0x79,0x49,0x18,0x8f,0x44,0x0e,0x13,0x40,0x1a,0x25,0x40,0x40,0x40,0x40,0x40,
0x40,0x40,0x40,0x40,0x40,0x40,0x2a,0x40,0x40,0x40,0x40,0x2d,0x40,0x32,0x40,0x35,
0x38,0x40,0x40,0x00,0x01,0x98,0xc0,0xb2,0x00,0xf0,0x07,0xfa,0x2c,0xe0,0x02,0x98,
0xc1,0xb2,0x01,0x98,0xc0,0xb2,0x00,0xf0,0xb8,0xf8,0x25,0xe0,0x06,0x98,0x83,0xb2,
0x03,0x98,0x82,0xb2,0x02,0x98,0xc1,0xb2,0x01,0x98,0xc0,0xb2,0x00,0xf0,0x71,0xf9,
0x1a,0xe0,0x01,0x98,0xc0,0xb2,0x00,0xf0,0x0a,0xf9,0x15,0xe0,0x00,0xf0,0x29,0xf8,
0x12,0xe0,0x01,0x98,0x80,0xb2,0x00,0xf0,0x62,0xf9,0x0d,0xe0,0x00,0xf0,0x3b,0xfb,
0x0a,0xe0,0x00,0xf0,0x94,0xfb,0x07,0xe0,0x01,0x98,0xc0,0xb2,0x00,0xf0,0xc7,0xfa,
0x04,0x46,0x01,0xe0,0x00,0x24,0xe4,0x43,0x20,0x46,0x04,0xb0,0x10,0xbd,0x03,0xb4,
0x01,0x48,0x01,0x90,0x01,0xbd,0x39,0x27,0x00,0x00,0x03,0xb4,0x01,0x48,0x01,0x90,
0x01,0xbd,0x95,0x28,0x00,0x00,0x03,0xb4,0x01,0x48,0x01,0x90,0x01,0xbd,0x01,0x01,
0x00,0x00,0xf0,0xb4,0x00,0x20,0x43,0x22,0x12,0x06,0x51,0x68,0xff,0x24,0x01,0x34,
0x21,0x43,0x51,0x60,0x51,0x68,0x23,0x03,0x19,0x43,0x51,0x60,0xa3,0x23,0xdb,0x05,
0x19,0x68,0x49,0x08,0x49,0x00,0x19,0x60,0x2a,0x49,0x09,0x69,0xce,0xb2,0x29,0x4d,
0x2a,0x4f,0x29,0x88,0xb9,0x42,0x01,0xd3,0x04,0x20,0x0d,0xe0,0x28,0x4f,0xb9,0x42,
0x01,0xd3,0x03,0x20,0x08,0xe0,0x26,0x4f,0xb9,0x42,0x01,0xd3,0x02,0x20,0x03,0xe0,
0x25,0x4f,0xb9,0x42,0x00,0xd3,0x01,0x20,0x24,0x4f,0x39,0x18,0x20,0x31,0x09,0x7e,
0xb1,0x42,0x09,0xda,0x00,0x28,0x01,0xdd,0x40,0x1e,0x40,0xb2,0x39,0x18,0x09,0x7a,
0x40,0x00,0xc0,0x19,0x00,0x8b,0x0b,0xe0,0x04,0x28,0x04,0xda,0x39,0x5c,0xb1,0x42,
0x01,0xdb,0x40,0x1c,0x40,0xb2,0x39,0x18,0x09,0x7a,0x40,0x00,0xc0,0x19,0x00,0x8b,
0x17,0x4e,0x31,0x62,0x19,0x68,0x49,0x08,0x49,0x00,0x19,0x60,0x15,0x4e,0x31,0x6b,
0x0f,0x46,0x27,0x43,0x37,0x63,0x98,0x62,0xa1,0x43,0x31,0x63,0x28,0x80,0x51,0x68,
0xb0,0x03,0x81,0x43,0x10,0x48,0x00,0x78,0xc0,0x07,0xc0,0x0f,0x03,0x05,0x19,0x43,
0x51,0x60,0x51,0x68,0x00,0x02,0xa1,0x43,0x01,0x43,0x51,0x60,0xf0,0xbc,0x70,0x47,
0x00,0x00,0x80,0x00,0x80,0x45,0x4e,0x60,0x00,0x20,0xf6,0x3f,0x00,0x00,0xf6,0x38,
0x00,0x00,0xf6,0x2d,0x00,0x00,0xf6,0x09,0x00,0x00,0xfc,0x67,0x00,0x20,0x80,0x04,
0xc0,0x50,0x40,0x00,0x80,0x45,0x3a,0x60,0x00,0x20,0xf0,0xb5,0x82,0xb0,0x43,0x22,
0x12,0x06,0x53,0x68,0x01,0x24,0x64,0x04,0x23,0x43,0x53,0x60,0xca,0x07,0xd2,0x0f,
0x96,0x46,0x8a,0x07,0xd3,0x0f,0x4a,0x07,0xd4,0x0f,0x0a,0x07,0xd2,0x0f,0x01,0x92,
0xca,0x06,0xd2,0x0f,0x00,0x92,0x8a,0x06,0xd2,0x0f,0x94,0x46,0x4a,0x06,0xd5,0x0f,
0xce,0x09,0x1f,0x4a,0x11,0x68,0x03,0x27,0x7f,0x05,0xb9,0x43,0x12,0x69,0x1d,0x4f,
0x3a,0x40,0x00,0x28,0x06,0xd0,0x01,0x28,0x09,0xd0,0x01,0x27,0xbf,0x05,0x02,0x28,
0x03,0xd0,0x39,0x43,0x00,0x28,0x06,0xd0,0x1b,0xe0,0x39,0x43,0xfa,0xe7,0x01,0x27,
0x7f,0x05,0x39,0x43,0xf6,0xe7,0x30,0x03,0x10,0x43,0x6a,0x01,0x10,0x43,0x62,0x46,
0xd2,0x02,0x10,0x43,0x00,0x9a,0xd2,0x01,0x10,0x43,0x01,0x9a,0x92,0x01,0x10,0x43,
0xa2,0x02,0x10,0x43,0x5a,0x02,0x10,0x43,0x72,0x46,0x12,0x02,0x10,0x43,0x08,0x4a,
0x10,0x61,0x07,0x48,0x01,0x60,0x43,0x20,0x00,0x06,0x41,0x68,0x01,0x22,0x52,0x04,
0x91,0x43,0x05,0x4a,0x12,0x78,0xd2,0x07,0x92,0x0b,0x11,0x43,0x41,0x60,0x02,0xb0,
0xf0,0xbd,0x00,0x00,0xc0,0x43,0x03,0xe0,0xff,0xff,0x3a,0x60,0x00,0x20,0xf8,0xb5,
0x00,0x24,0x43,0x20,0x00,0x06,0x41,0x68,0x01,0x27,0xbf,0x03,0x39,0x43,0x41,0x60,
0x41,0x68,0xba,0x00,0x11,0x43,0x41,0x60,0x21,0x48,0x05,0x68,0x51,0x1c,0x0d,0x43,
0x05,0x60,0x1f,0x4e,0xc8,0x20,0xb0,0x47,0x1f,0x49,0x88,0x68,0x38,0x43,0x88,0x60,
0x0e,0x46,0xf0,0x68,0x00,0x04,0xc7,0x0f,0x1a,0x49,0x01,0x20,0x88,0x47,0x20,0x46,
0x1a,0x49,0x64,0x1c,0x88,0x42,0x01,0xd8,0x00,0x2f,0xf2,0xd0,0x18,0x48,0x05,0x40,
0x13,0x48,0x05,0x60,0x01,0x20,0x40,0x03,0xb0,0x60,0xf1,0x68,0x15,0x48,0x01,0x40,
0x70,0x68,0x14,0x4a,0x10,0x40,0x08,0x43,0x70,0x60,0x30,0x68,0x3f,0x21,0x89,0x02,
0x88,0x43,0x30,0x60,0x43,0x21,0x09,0x06,0x4a,0x68,0x01,0x20,0x80,0x03,0x82,0x43,
0x0e,0x48,0x00,0x78,0xc0,0x07,0xc0,0x0f,0x83,0x03,0x1a,0x43,0x4a,0x60,0x4a,0x68,
0x01,0x23,0x1b,0x04,0x9a,0x43,0x00,0x04,0x02,0x43,0x4a,0x60,0xf8,0xbd,0x00,0x00,
0x40,0x52,0xa1,0x3b,0x00,0x00,0x00,0x00,0xc0,0x51,0x10,0x27,0x00,0x00,0xfe,0xff,
0xfe,0xff,0x3f,0x3f,0x00,0x00,0xc0,0xc0,0xff,0xff,0x3a,0x60,0x00,0x20,0x70,0x47,
0x00,0x00,0xf0,0xb5,0x83,0xb0,0x08,0x25,0x3c,0x49,0x00,0x20,0x08,0x70,0x43,0x20,
0x00,0x06,0x41,0x68,0xaa,0x02,0x11,0x43,0x41,0x60,0x29,0x27,0x38,0x49,0x7f,0x06,
0xf9,0x60,0x41,0x68,0x37,0x4b,0x91,0x43,0x1b,0x78,0xdb,0x07,0x9b,0x0c,0x19,0x43,
0x41,0x60,0x25,0x24,0xa4,0x01,0x41,0x68,0x11,0x43,0x41,0x60,0x41,0x68,0x52,0x10,
0x11,0x43,0x41,0x60,0xf8,0x68,0x03,0x21,0x49,0x06,0x88,0x43,0x56,0x03,0x06,0x43,
0x90,0x03,0x06,0x43,0xb8,0x68,0x01,0x20,0xff,0xf7,0x81,0xfe,0x21,0x46,0x10,0x20,
0xff,0xf7,0x83,0xfe,0x28,0x03,0x06,0x43,0x00,0x24,0x00,0x2d,0x0c,0xd9,0xfe,0x60,
0x25,0x49,0x64,0x20,0x88,0x47,0xf8,0x68,0x69,0x46,0x00,0x0a,0x80,0x1c,0x08,0x55,
0x64,0x1c,0xe4,0xb2,0xac,0x42,0xf2,0xd3,0x6a,0x46,0xd0,0x79,0x91,0x79,0x40,0x18,
0x51,0x79,0x12,0x79,0x89,0x18,0x40,0x18,0x6a,0x46,0xd1,0x78,0x41,0x18,0x90,0x78,
0x09,0x18,0x50,0x78,0x09,0x18,0x10,0x78,0x08,0x18,0x29,0x46,0xff,0xf7,0x63,0xfe,
0x12,0x49,0xc0,0xb2,0x08,0x70,0x39,0x68,0x01,0x22,0x92,0x02,0x11,0x43,0x39,0x60,
0x40,0x00,0x40,0x1c,0x78,0x61,0x00,0x20,0xff,0xf7,0x49,0xfe,0x43,0x21,0x09,0x06,
0x4a,0x68,0x01,0x20,0x00,0x03,0x82,0x43,0x0a,0x48,0x00,0x78,0xc0,0x07,0xc0,0x0f,
0x03,0x03,0x1a,0x43,0x4a,0x60,0x4a,0x68,0x01,0x23,0x5b,0x03,0x9a,0x43,0x40,0x03,
0x02,0x43,0x4a,0x60,0x03,0xb0,0xf0,0xbd,0x00,0x00,0x70,0x60,0x00,0x20,0xcc,0x34,
0x63,0x02,0x3a,0x60,0x00,0x20,0xa1,0x3b,0x00,0x00,0x70,0xb4,0x43,0x21,0x09,0x06,
0x48,0x68,0x01,0x24,0xa4,0x04,0x20,0x43,0x48,0x60,0xc4,0x20,0x87,0x22,0xd2,0x05,
0x10,0x60,0x5c,0x48,0x50,0x61,0x48,0x68,0x5c,0x4a,0xa0,0x43,0x12,0x78,0xd2,0x07,
0xd2,0x0f,0x93,0x04,0x18,0x43,0x48,0x60,0x8b,0x20,0x58,0x4b,0xc0,0x05,0x43,0x63,
0x58,0x4b,0x01,0x25,0xdd,0x60,0x06,0x25,0xcd,0x60,0x05,0x25,0xc5,0x63,0x85,0x68,
0x6d,0x08,0xf0,0x3d,0x85,0x60,0xc5,0x68,0x6d,0x08,0x5d,0x35,0xc5,0x60,0x05,0x69,
0x6d,0x08,0x05,0x61,0x45,0x69,0x6d,0x08,0x45,0x61,0x85,0x69,0x6d,0x08,0x85,0x61,
0xc5,0x69,0x6d,0x08,0xc5,0x61,0x05,0x6a,0x6d,0x08,0x05,0x62,0x45,0x6a,0x6d,0x08,
0x45,0x62,0x85,0x6a,0x6d,0x08,0x85,0x62,0xc5,0x6a,0x6d,0x08,0xc5,0x62,0x01,0x25,
0x1d,0x61,0x5d,0x62,0x9d,0x63,0x43,0x4b,0x1d,0x60,0x43,0x4d,0x5d,0x61,0x1d,0x6a,
0x6d,0x08,0x1d,0x62,0xc3,0x6a,0x01,0x25,0x2b,0x43,0xc3,0x62,0x48,0x68,0xa3,0x10,
0x18,0x43,0x48,0x60,0x48,0x68,0x9b,0x10,0x18,0x43,0x48,0x60,0x3d,0x48,0x3b,0x4b,
0x43,0x61,0x83,0x68,0x3f,0x25,0xad,0x05,0x2b,0x43,0x83,0x60,0x00,0x23,0xc3,0x60,
0x39,0x4b,0x83,0x61,0x39,0x4d,0x2b,0x68,0x1e,0x26,0xb3,0x43,0x2b,0x60,0x83,0x6a,
0xf5,0x03,0xab,0x43,0x1b,0x19,0x83,0x62,0x48,0x68,0xa3,0x10,0x98,0x43,0x13,0x04,
0x18,0x43,0x48,0x60,0x48,0x68,0x23,0x11,0x98,0x43,0x93,0x03,0x18,0x43,0x48,0x60,
0x48,0x68,0x63,0x11,0x18,0x43,0x48,0x60,0x29,0x20,0x40,0x06,0x04,0x6a,0x24,0x09,
0x24,0x01,0x08,0x34,0x04,0x62,0x48,0x68,0x98,0x43,0x53,0x03,0x18,0x43,0x48,0x60,
0x48,0x68,0x01,0x23,0x1b,0x05,0x18,0x43,0x48,0x60,0x28,0x24,0xa3,0x20,0xc0,0x05,
0x04,0x60,0x22,0x4d,0x2d,0x88,0x85,0x62,0x48,0x68,0x12,0x05,0x98,0x43,0x10,0x43,
0x48,0x60,0x1f,0x48,0xe6,0x21,0x01,0x70,0x04,0x72,0x1d,0x4a,0x1e,0x48,0x10,0x83,
0x1e,0x48,0xe0,0x23,0x03,0x76,0x1a,0x4c,0xd4,0x22,0x62,0x70,0x3c,0x22,0x62,0x72,
0x1b,0x4a,0x62,0x83,0x41,0x76,0xc8,0x22,0xa2,0x70,0x15,0x4d,0x46,0x24,0xac,0x72,
0x18,0x4c,0xac,0x83,0x81,0x76,0x29,0x46,0xca,0x70,0x50,0x21,0x2a,0x46,0xd1,0x72,
0x15,0x49,0xd1,0x83,0xc3,0x76,0x5a,0x21,0x11,0x73,0x13,0x49,0x11,0x84,0x03,0x77,
0x70,0xbc,0x70,0x47,0x00,0x00,0xff,0x7f,0x00,0x00,0x3a,0x60,0x00,0x20,0x49,0x02,
0x00,0x00,0x40,0x00,0x80,0x45,0x80,0x00,0x80,0x45,0x1e,0x02,0x00,0x00,0x03,0x00,
0x3c,0x00,0x00,0x00,0x40,0x52,0x08,0x00,0x0f,0x00,0x00,0x00,0xc0,0x51,0x4e,0x60,
0x00,0x20,0xfc,0x67,0x00,0x20,0xf6,0x07,0x00,0x00,0x1c,0x68,0x00,0x20,0xf6,0x09,
0x00,0x00,0xf6,0x2d,0x00,0x00,0xf6,0x38,0x00,0x00,0xf6,0x3f,0x00,0x00,0xf8,0xb5,
0x2d,0x48,0x00,0x68,0x00,0x28,0x54,0xd1,0x43,0x22,0x12,0x06,0x50,0x68,0x01,0x21,
0xc9,0x03,0x08,0x43,0x50,0x60,0x28,0x4f,0x3c,0x68,0x01,0x25,0x03,0x20,0x00,0x06,
0x20,0x43,0x38,0x60,0x00,0x26,0x25,0x49,0x1e,0x20,0x88,0x47,0x24,0x49,0x01,0x20,
0x88,0x47,0x78,0x68,0xc0,0x07,0xc0,0x0f,0x31,0x46,0x21,0x4a,0x76,0x1c,0x91,0x42,
0x01,0xd8,0x00,0x28,0xf2,0xd0,0x1c,0x48,0x81,0x68,0x1e,0x48,0x01,0x60,0x00,0x20,
0x00,0x26,0x00,0x2d,0x11,0xd0,0x1c,0x4b,0x32,0x46,0x00,0x25,0xcb,0x1a,0xaa,0x41,
0x14,0xda,0x40,0x1c,0x05,0x46,0x18,0x4f,0x4d,0x43,0x33,0x46,0x00,0x22,0x7d,0x1b,
0x9a,0x41,0x4d,0x1b,0x93,0x41,0xf4,0xdb,0x08,0xe0,0x14,0x4b,0x99,0x42,0x05,0xd2,
0x40,0x1c,0x02,0x46,0x4a,0x43,0x9a,0x1a,0x8a,0x42,0xf9,0xd8,0x01,0x21,0x09,0x06,
0x8c,0x43,0x49,0x00,0x0c,0x43,0x08,0x49,0x0c,0x60,0x43,0x22,0x12,0x06,0x51,0x68,
0x01,0x23,0xdb,0x03,0x99,0x43,0x0a,0x4b,0x1b,0x78,0xdb,0x07,0x1b,0x0c,0x19,0x43,
0x51,0x60,0xf8,0xbd,0x00,0x00,0x5c,0x60,0x00,0x20,0x00,0x00,0x40,0x44,0xa1,0x3b,
0x00,0x00,0x10,0x27,0x00,0x00,0x60,0x60,0x00,0x20,0x00,0x20,0xbc,0xbe,0x00,0xd0,
0x12,0x13,0x3a,0x60,0x00,0x20,0x70,0xb5,0x23,0x48,0x80,0x47,0x43,0x24,0x24,0x06,
0x01,0x21,0x60,0x68,0x89,0x04,0x08,0x43,0x60,0x60,0x1f,0x48,0x80,0x47,0x1f,0x48,
0x00,0x78,0xaa,0x28,0x06,0xd1,0xa0,0x68,0x80,0x07,0x03,0xd1,0x1d,0x49,0x88,0x47,
0x1d,0x49,0x08,0x60,0xa1,0x20,0xc0,0x05,0x02,0x6b,0x02,0x21,0x8a,0x43,0x0a,0x43,
0x02,0x63,0x01,0x21,0x02,0x6b,0x8a,0x43,0x0a,0x43,0x02,0x63,0x01,0x6b,0x04,0x26,
0xb1,0x43,0x31,0x43,0x01,0x63,0x14,0x4c,0x60,0x68,0x14,0x4d,0x80,0x00,0x04,0xd5,
0x01,0x20,0xa8,0x47,0x60,0x68,0x80,0x00,0xfa,0xd4,0x11,0x4c,0x0f,0x20,0x60,0x60,
0x01,0x20,0xa8,0x47,0x07,0x20,0x60,0x60,0x04,0x20,0xa8,0x47,0x06,0x20,0x60,0x60,
0x8b,0x21,0x0c,0x48,0xc9,0x05,0x08,0x60,0x0c,0x48,0x01,0x69,0x31,0x43,0x01,0x61,
0x30,0xbf,0x70,0xbd,0x00,0x00,0x35,0x37,0x00,0x00,0x39,0x9c,0x00,0x00,0x2c,0x60,
0x00,0x20,0xd1,0x39,0x00,0x00,0x54,0x60,0x00,0x20,0x80,0x00,0x80,0x45,0xa1,0x3b,
0x00,0x00,0x40,0x00,0x80,0x45,0x26,0x03,0x00,0x00,0x00,0xed,0x00,0xe0,0x70,0xb5,
0x2f,0x4d,0x0f,0x20,0x68,0x60,0x8b,0x24,0xe4,0x05,0x20,0x68,0x01,0x21,0x49,0x02,
0x88,0x43,0x20,0x60,0x2b,0x48,0x80,0x47,0x01,0x20,0x80,0xf3,0x10,0x88,0x29,0x48,
0x40,0x68,0x29,0x49,0x80,0x00,0x06,0xd4,0x20,0x68,0x08,0x22,0x10,0x43,0x20,0x60,
0x01,0x20,0x88,0x47,0x01,0xe0,0x01,0x20,0x88,0x47,0x24,0x48,0x80,0x47,0x24,0x48,
0x25,0x49,0x00,0x78,0x88,0x47,0x0d,0x20,0x68,0x60,0x23,0x48,0x80,0x47,0x43,0x20,
0x00,0x06,0x41,0x68,0x01,0x23,0x5b,0x03,0x19,0x43,0x41,0x60,0x29,0x21,0x1f,0x4a,
0x49,0x06,0xca,0x60,0x0a,0x6a,0x12,0x09,0x12,0x01,0x08,0x32,0x0a,0x62,0x0a,0x68,
0xdc,0x10,0x22,0x43,0x0a,0x60,0x1a,0x4a,0x12,0x78,0x52,0x00,0x52,0x1c,0x4a,0x61,
0x42,0x68,0x18,0x49,0x9a,0x43,0x09,0x78,0xc9,0x07,0xc9,0x0f,0x4b,0x03,0x1a,0x43,
0x42,0x60,0x43,0x68,0xa2,0x02,0x13,0x43,0x43,0x60,0x28,0x24,0xa3,0x23,0xdb,0x05,
0x1c,0x60,0x11,0x4c,0x24,0x88,0x9c,0x62,0x43,0x68,0x09,0x05,0x93,0x43,0x0b,0x43,
0x43,0x60,0x00,0x20,0x80,0xf3,0x10,0x88,0x0d,0x48,0x80,0x47,0x70,0xbd,0x40,0x00,
0x80,0x45,0x85,0x3b,0x01,0x00,0x80,0x00,0x80,0x45,0x89,0x44,0x01,0x00,0x6d,0x34,
0x01,0x00,0x40,0x60,0x00,0x20,0xa1,0x3b,0x00,0x00,0x99,0x4d,0x01,0x00,0xcc,0x34,
0x63,0x04,0x70,0x60,0x00,0x20,0x3a,0x60,0x00,0x20,0x4e,0x60,0x00,0x20,0xad,0x34,
0x01,0x00
}
};
am_hal_ble_patch_t am_ble_performance_copy_patch =
{
.ui32Type = 0xBB,
.ui32Length = 0x0912,
.ui32CRC = 0x9516,
.pui32Data = am_ble_performance_copy_patch_data.words,
};
//*****************************************************************************
//
// Patch Name: RAMCODE PATCH v1.10 for Apollo3 A1
//
// Bi-directional data fix
// Modulation deviation fix
// Extend patch memory
// Transmit speed patch
// Added AGC table and enabled AGC
// Added local feature support setting
// Fix to connection interval calculation issue with MTK chip sets (OPPO R15 fix)
// Set VCO to 250mv
// Modex auto calibration update
// Fix connection interval calculation issue
// Increase RF LDO ref voltage form 1.0v to 1.1v
// Decrease DAC channel delay cycle
// Increase the VCO swing from 250mv to 300mv
// Fix MD trans schedule issue (disabled)
// Fix link loss issue
// Reduce duration from TX to TX
// Optimized 32K XO frequency calculation
// Fix channel map rejected issue
// Optimized AGC Table
// Date: 2019-01-30
//*****************************************************************************
am_hal_ble_buffer(0x0104) am_ble_performance_patch_data =
{
.bytes =
{
0x00,0x11,0x02,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0xc5,0x01,
0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1b,0x00,0xa1,0x06,0x1f,0xb5,0x82,0xb0,0x08,0x98,0x00,0x90,
0x02,0xa8,0x0f,0xc8,0x01,0x4c,0xa0,0x47,0x06,0xb0,0x10,0xbd,0x01,0x35,0x00,0x20,
0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x08,0x48,0x80,0x47,0x00,0xbf,0x00,0xbf,
0x02,0x2d,0x05,0xd1,0x06,0x48,0x80,0x47,0x00,0xbf,0x00,0xbf,0x05,0x48,0x80,0x47,
0x00,0x21,0x03,0x9a,0x04,0x98,0x90,0x47,0x03,0x48,0x00,0x47,0x99,0x4a,0x01,0x00,
0x25,0x4b,0x01,0x00,0xaf,0x4a,0x01,0x00,0x8f,0x4c,0x01,0x00,0x00,0x00,0x00,0x00,
0x04,0x48,0x01,0x68,0x28,0x22,0x11,0x43,0x50,0x22,0x91,0x43,0x01,0x60,0x00,0xbf,
0x01,0x48,0x00,0x47,0x00,0x00,0xc0,0x52,0x63,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x48,0x01,0x68,0x50,0x22,0x11,0x43,0x28,0x22,0x91,0x43,0x01,0x60,0x00,0xbf,
0x01,0x48,0x00,0x47,0x00,0x00,0xc0,0x52,0x83,0x2a,0x00,0x00,0x00,0xbf,0x00,0xbf,
0x00,0xbf,0x00,0xbf,0x08,0x98,0x00,0x28,0x01,0xd0,0x01,0x20,0x02,0x90,0x00,0x20,
0x60,0x85,0x01,0x48,0x00,0x47,0x00,0xbf,0xd5,0xed,0x00,0x00,0x00,0xbf,0x00,0xbf,
0x60,0x88,0x00,0x28,0x04,0xd1,0x10,0x7d,0x08,0x28,0x01,0xd3,0x04,0x20,0x10,0x75,
0x02,0x98,0x81,0x79,0x01,0x20,0x01,0x43,0x02,0x98,0x81,0x71,0x00,0x48,0x00,0x47,
0xa5,0xf7,0x00,0x00
}
};
am_hal_ble_patch_t am_ble_performance_patch =
{
.ui32Type = 0xBB,
.ui32Length = 0x0104,
.ui32CRC = 0x933d,
.pui32Data = am_ble_performance_patch_data.words,
};
//*****************************************************************************
//
// Patch Name: Function PATCH v1.10 for Apollo3 A1
//
// Bi-directional data fix
// Modulation deviation fix
// Extend patch memory
// Transmit speed patch
// Added AGC table and enabled AGC
// Added local feature support setting
// Fix to connection interval calculation issue with MTK chip sets (OPPO R15 fix)
// Set VCO to 250mv
// Modex auto calibration update
// Fix connection interval calculation issue
// Increase RF LDO ref voltage form 1.0v to 1.1v
// Decrease DAC channel delay cycle
// Increase the VCO swing from 250mv to 300mv
// Fix MD trans schedule issue (disabled)
// Fix link loss issue
// Reduce duration from TX to TX
// Optimized 32K XO frequency calculation
// Fix channel map rejected issue
// Optimized AGC Table
// Date: 2019-01-30
//*****************************************************************************
const am_hal_ble_buffer(0x0d38) am_ble_buffer_patch_data =
{
.bytes =
{
0x00,0x22,0x38,0x0d,0xff,0xff,0x00,0x00,0x32,0x35,0x09,0x00,0x65,0x39,0x09,0x00,
0x2b,0x45,0x09,0x00,0xa9,0x48,0x09,0x00,0xf7,0x53,0x09,0x00,0x1a,0x5c,0x09,0x00,
0x1c,0x64,0x09,0x00,0xfd,0x6a,0x09,0x00,0x1a,0x75,0x09,0x00,0xde,0x7b,0x09,0x00,
0x4b,0x85,0x09,0x00,0xb3,0x8b,0x09,0x00,0x1f,0x95,0x09,0x00,0x4f,0x9c,0x09,0x00,
0xf5,0xa2,0x09,0x00,0x1e,0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x47,
0x41,0x48,0x00,0x20,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x05,0xb0,0xf0,0xbd,0x00,0x00,
0x90,0x67,0x00,0x20,0x10,0x27,0x00,0x00,0x00,0x10,0x00,0x20,0x88,0x13,0x00,0x00,
0x18,0x10,0x00,0x20,0xff,0x03,0x00,0x00,0xff,0xb5,0xff,0xb0,0x82,0xb0,0x07,0x46,
0x0c,0x46,0x16,0x46,0x00,0x25,0x30,0x48,0x06,0x60,0x84,0x99,0x04,0xd0,0xee,0x28,
0x02,0xd0,0x03,0x20,0x60,0x73,0x70,0xbd,0x60,0x7c,0xf1,0x28,0x06,0xd0,0xf2,0x28,
0x04,0xd0,0xf3,0x28,0x02,0xd0,0x02,0x20,0x60,0x73,0x70,0xbd,0x00,0x20,0x60,0x73,
0x70,0xbd,0x00,0x00,0x18,0x10,0x00,0x20,0x0a,0x10,0x00,0x20,0x00,0x48,0x00,0x47,
0x81,0x4d,0x00,0x20,0x70,0x88,0x00,0x28,0x16,0xd1,0x14,0x20,0x01,0x21,0x0b,0x20,
0xed,0xf7,0xc6,0xfc,0x10,0xbd,0x00,0x00,0x00,0x48,0x00,0x47,0x15,0x4e,0x00,0x20,
0x00,0x28,0x02,0xd0,0x08,0x78,0x01,0x28,0x1a,0xd0,0x08,0x78,0x02,0x28,0x17,0xd0,
0x00,0x28,0x0e,0xd0,0x01,0x28,0x0c,0xd0,0xf0,0xf7,0xd9,0xfe,0x00,0x28,0x08,0xd0,
0x00,0xf0,0x16,0xf8,0x32,0x20,0xef,0xf7,0x51,0xf8,0xf0,0xf7,0x80,0xe1,0x00,0xe0,
0x00,0xe1,0x00,0xe0,0x02,0x48,0x01,0x68,0x28,0x22,0x91,0x43,0x01,0x60,0x70,0x47,
0x00,0x00,0xc0,0x52,0x00,0x48,0x00,0x47,0x81,0x48,0x00,0x20,0x01,0x60,0x70,0x47,
0x00,0x00,0xc0,0x52,0x02,0x48,0x01,0x68,0x50,0x22,0x91,0x43,0x01,0x60,0x70,0x47,
0x00,0x00,0xc0,0x52,0x00,0x48,0x00,0x47,0xa1,0x48,0x00,0x20,0xc0,0x40,0x80,0x50,
0x10,0xb5,0x0b,0x46,0x11,0x46,0x02,0x24,0x0c,0x22,0x50,0x43,0x06,0x4a,0x80,0x18,
0x00,0x28,0x06,0xd0,0x42,0x68,0x00,0x2a,0x03,0xd0,0x18,0x46,0x00,0xf0,0x10,0xfb,
0x04,0x46,0x20,0x46,0x10,0xbd,0x00,0x00,0x98,0x56,0x01,0x00,0x00,0x49,0x08,0x47,
0x99,0x4e,0x00,0x20,0xf3,0xf7,0x5c,0xfd,0x7c,0x20,0x00,0x5b,0x0b,0xf8,0x40,0x19,
0xc1,0xb2,0x00,0x29,0x03,0xd0,0x40,0x34,0xa0,0x8f,0xf9,0xf7,0x73,0xfd,0x70,0xbd,
0x01,0x21,0xe1,0xe7,0x00,0x49,0x08,0x47,0x81,0x50,0x00,0x20,0x80,0xf3,0x10,0x88,
0x28,0x46,0xf3,0xf7,0x4d,0xf9,0x00,0x21,0x81,0xf3,0x10,0x88,0x00,0x28,0x0f,0xd0,
0x81,0x88,0x0a,0x46,0x0a,0x3a,0x46,0x2a,0x0c,0xd2,0x64,0x1c,0xd2,0x0b,0xd2,0x03,
0x0a,0x43,0xc2,0x84,0x00,0x20,0x80,0xf3,0x10,0x88,0x70,0x47,0x66,0x04,0x00,0x00,
0x40,0x44,0x80,0x50,0x00,0x49,0x08,0x47,0xed,0x50,0x00,0x20,0x11,0x90,0x80,0x8f,
0x0e,0x90,0x12,0x98,0x08,0x30,0x0d,0x90,0x12,0x98,0x30,0x30,0x0c,0x90,0x12,0x98,
0x44,0x30,0x0b,0x90,0x00,0x20,0x0a,0x90,0x01,0x25,0x0c,0x98,0x07,0xf0,0xa4,0xf8,
0x00,0x28,0x2d,0xd0,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,
0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x91,0xe0,0x0c,0x9a,0xff,0x20,0x22,0x23,
0x11,0x46,0x0a,0x30,0xfd,0xf7,0x9e,0xfb,0x07,0x70,0x61,0x88,0xc1,0x81,0xa1,0x88,
0x01,0x82,0xe1,0x88,0xc1,0x80,0x21,0x89,0x01,0x81,0xa1,0x7a,0xc0,0x01,0x23,0xe0,
0x77,0xe0,0x02,0x98,0x08,0x1a,0x40,0x01,0x40,0x09,0x90,0x42,0x1c,0xd9,0x02,0x98,
0x40,0x1a,0x40,0x01,0x40,0x09,0x40,0x42,0x16,0xe0,0x02,0x98,0x00,0xbf,0x00,0xbf,
0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0x20,
0x0a,0xe0,0x02,0x98,0x38,0x1a,0x40,0x01,0x40,0x09,0x90,0x42,0xc1,0x65,0x75,0x60,
0x60,0x89,0xb8,0x84,0x04,0x9a,0x01,0x20,0x50,0x75,0x60,0x88,0xf8,0x85,0x04,0x9a,
0x60,0x78,0x10,0x75,0x00,0x48,0x00,0x47,0xe1,0x48,0x00,0x20,0x00,0xbf,0x00,0x00,
0x60,0x89,0x3a,0x8d,0x40,0x1e,0x80,0xb2,0x82,0x42,0x03,0xd1,0x08,0x20,0x01,0x43,
0x03,0x98,0x81,0x71,0x07,0xb0,0xf0,0xbd,0x60,0x61,0x00,0x20,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
AM_HAL_BLE_LOCAL_FEATURE,//0x01,
0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
0xff,0x03,0x00,0x00,0xff,0x00,0x3c,0x1f,0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x00,
0x89,0x7d,0x00,0x00,0x02,0x20,0x00,0x00,0xfd,0x76,0x00,0x00,0x10,0x18,0x00,0x8c,
0xc0,0x0b,0x08,0x9b,0x5b,0x1e,0x18,0x42,0x05,0xd1,0x08,0x98,0x00,0x48,0x00,0x47,
0xc1,0x48,0x00,0x20,0x00,0xbf,0x00,0x00,0x80,0x4b,0xd2,0x18,0x50,0x84,0x01,0x20,
0x80,0xf3,0x10,0x88,0xb8,0x68,0x00,0x28,0x16,0xd0,0x00,0x20,0x00,0x28,0x19,0xd0,
0x38,0x6b,0x00,0x28,0x12,0xd0,0x00,0x20,0x00,0x28,0x13,0xd0,0x9f,0xfc,0x00,0x19,
0x06,0x4b,0x59,0x68,0x09,0x18,0x8a,0x08,0x94,0x00,0x09,0x1b,0x59,0x60,0x41,0x01,
0x08,0x1a,0x80,0x18,0x10,0xbd,0x00,0x00,0x2c,0x60,0x00,0x20,0xb8,0x67,0x00,0x20,
0x00,0x49,0x08,0x47,0x79,0x55,0x00,0x20,0x7d,0x21,0x80,0x6a,0x09,0x02,0x88,0x42,
0x02,0xd3,0x40,0x1a,0x01,0x22,0x00,0xe0,0x08,0x1a,0x00,0x2a,0x29,0x19,0x08,0x1a,
0x21,0x46,0xee,0xf7,0xb1,0xfe,0x88,0xb2,0x70,0xbd,0x28,0x30,0x60,0x30,0x00,0x7e,
0x70,0x47,0x10,0xb4,0x02,0x46,0x40,0x32,0xd3,0x8c,0x06,0x24,0x63,0x43,0x14,0x8d,
0xe3,0x18,0x9b,0xb2,0x93,0x84,0x60,0x30,0x41,0x75,0x18,0x46,0x10,0xbc,0x70,0x47,
0x28,0x30,0x60,0x30,0x40,0x7d,0x00,0x28,0x00,0x20,0x00,0x20,0x40,0x79,0x00,0x07,
0x02,0xd5,0x04,0x20,0x60,0x70,0x34,0xe0,0x28,0x69,0x05,0xf0,0x51,0xfb,0x00,0x28,
0x02,0xd0,0x02,0x20,0x60,0x70,0x2c,0xe0,0x03,0x98,0x03,0xf0,0x4d,0xfe,0x04,0x28,
0x07,0xd1,0x68,0x46,0x01,0x79,0x02,0x20,0x88,0x43,0x05,0xd0,0x00,0x20,0x00,0x28,
0x04,0xd0,0x00,0x20,0x60,0x70,0x1c,0xe0,0x01,0x20,0xf8,0xe7,0x58,0x67,0x00,0x20,
0x40,0x00,0x80,0x50,0xb8,0x67,0x00,0x20,0x00,0x00,0x00,0x04,0xc8,0x67,0x00,0x20,
0x00,0x49,0x08,0x47,0xcd,0x55,0x00,0x20,0x81,0x6a,0x7d,0x20,0x00,0x02,0x81,0x42,
0x02,0xd3,0x08,0x1a,0x01,0x22,0x00,0xe0,0x40,0x1a,0x00,0x2a,0x04,0xd0,0x60,0x43,
0xeb,0xf7,0xa4,0xfc,0x20,0x1a,0x03,0xe0,0x60,0x43,0xeb,0xf7,0xf8,0xb5,0x00,0x24,
0x1c,0x48,0x00,0x78,0x00,0x28,0x2d,0xd1,0x1b,0x4e,0x70,0x68,0x1b,0x4d,0x00,0x28,
0x09,0xda,0x1b,0x4f,0x01,0x21,0x0b,0x20,0xb8,0x47,0x01,0x21,0x0b,0x20,0xa8,0x47,
0x70,0x68,0x00,0x28,0xf6,0xdb,0x00,0x21,0x0b,0x20,0xa8,0x47,0x15,0x4e,0x0a,0x20,
0xb0,0x47,0x05,0x27,0x3f,0x07,0xf8,0x69,0x05,0x05,0x2d,0x0d,0x00,0x2d,0x04,0xd1,
0x11,0x48,0xc0,0x68,0x80,0x05,0x80,0x0e,0x0c,0xd0,0x64,0x2c,0x0a,0xd2,0x14,0x20,
0xb0,0x47,0xf8,0x69,0x00,0x05,0x00,0x0d,0xa8,0x42,0x04,0xd9,0x05,0x46,0x64,0x1c,
0x64,0x2c,0xf4,0xd3,0xf8,0xbd,0x03,0x49,0x01,0x20,0x08,0x70,0x07,0x49,0x08,0x70,
0xf8,0xbd,0x00,0x00,0x01,0x10,0x00,0x20,0x80,0x00,0x80,0x45,0x55,0x24,0x00,0x00,
0x91,0x23,0x00,0x00,0xa1,0x3b,0x00,0x00,0x00,0x00,0xc0,0x52,0x00,0x10,0x00,0x20,
0x10,0xb5,0x18,0x48,0x01,0x68,0x40,0x29,0x01,0xd2,0x40,0x21,0x01,0x60,0x80,0x7a,
0xc0,0x07,0x01,0xd0,0x00,0x20,0x10,0xbd,0x13,0x48,0x80,0x47,0x05,0x20,0x00,0x07,
0xc0,0x69,0x12,0x49,0x00,0x05,0x04,0xd0,0x08,0x78,0x01,0x28,0x14,0xd0,0x02,0x28,
0x12,0xd0,0x08,0x78,0x00,0x28,0x08,0xd0,0x01,0x28,0x06,0xd0,0x02,0x28,0x04,0xd0,
0x0b,0x48,0x80,0x47,0x0b,0x49,0x32,0x20,0x88,0x47,0x0b,0x49,0x04,0x20,0x88,0x47,
0x0a,0x48,0x80,0x47,0x00,0x20,0x10,0xbd,0x09,0x49,0x04,0x20,0x88,0x47,0x01,0x20,
0x10,0xbd,0x00,0x00,0xb8,0x67,0x00,0x20,0x05,0x93,0x00,0x00,0x18,0x10,0x00,0x20,
0x25,0x4b,0x01,0x00,0xa1,0x3b,0x00,0x00,0x41,0x44,0x01,0x00,0xaf,0x4a,0x01,0x00,
0x89,0x44,0x01,0x00,0xf0,0xb5,0x8d,0xb0,0x04,0x46,0x6c,0x49,0x04,0xa8,0x88,0x47,
0x7c,0x20,0x00,0x5b,0x03,0x90,0x00,0x25,0x00,0x20,0x02,0x90,0x01,0x20,0x80,0xf3,
0x10,0x88,0x60,0x6c,0x00,0x21,0x81,0xf3,0x10,0x88,0x26,0x46,0x60,0x36,0x00,0x28,
0x6b,0xd0,0x21,0x46,0x44,0x31,0x0c,0x91,0x28,0x39,0x0b,0x91,0x64,0x31,0x0a,0x91,
0x81,0x88,0xca,0x00,0x5e,0x49,0x51,0x18,0xc9,0x8c,0xc9,0x0b,0x00,0x29,0x5c,0xd0,
0x01,0x21,0x81,0xf3,0x10,0x88,0x00,0x68,0x01,0x90,0x5a,0x49,0x0c,0x98,0x88,0x47,
0x07,0x46,0xe0,0x69,0x00,0x28,0x03,0xd0,0x00,0x20,0x00,0x28,0x02,0xd0,0x08,0xe0,
0x01,0x20,0xfa,0xe7,0x53,0x49,0x0b,0x98,0x88,0x47,0x00,0x28,0x01,0xd0,0x52,0x49,
0x88,0x47,0x00,0x20,0x80,0xf3,0x10,0x88,0xb8,0x88,0x4d,0x49,0xc0,0x00,0x40,0x18,
0xc2,0x8c,0xd2,0x0b,0xd2,0x03,0xc2,0x84,0xb8,0x88,0x07,0x28,0x1e,0xd2,0x30,0x7e,
0x40,0x1e,0x30,0x76,0x01,0x20,0x80,0xf3,0x10,0x88,0x20,0x6b,0x00,0x28,0x13,0xd0,
0x00,0x20,0x00,0x28,0x05,0xd0,0x0a,0x98,0xfb,0x21,0x80,0x79,0x08,0x40,0x0a,0x99,
0x88,0x71,0x41,0x49,0x38,0x46,0x88,0x47,0x00,0x20,0x80,0xf3,0x10,0x88,0x3f,0x4a,
0x39,0x7b,0x03,0x98,0x90,0x47,0x15,0xe0,0x01,0x20,0xea,0xe7,0x09,0x28,0x0f,0xd9,
0xc0,0x00,0x40,0x18,0x00,0x8d,0x00,0x0a,0x00,0x90,0x39,0x49,0x38,0x46,0x88,0x47,
0x00,0x28,0x07,0xd0,0x00,0x98,0x00,0x28,0x04,0xd0,0x6d,0x1c,0xed,0xb2,0x01,0xe0,
0x6d,0x1c,0xed,0xb2,0x01,0x98,0x00,0x28,0x9a,0xd1,0x03,0x98,0x07,0x28,0x0e,0xd0,
0x00,0x2d,0x0c,0xd0,0x01,0x20,0x80,0xf3,0x10,0x88,0x30,0x7e,0x40,0x1b,0x30,0x76,
0x00,0x20,0x80,0xf3,0x10,0x88,0x2b,0x4a,0x29,0x46,0x03,0x98,0x90,0x47,0x01,0x20,
0x80,0xf3,0x10,0x88,0x28,0x48,0x23,0x4f,0x09,0x90,0xb8,0x47,0x04,0x46,0x00,0x20,
0x80,0xf3,0x10,0x88,0x20,0x00,0x36,0xd0,0x1f,0x4e,0xe0,0x88,0x03,0x99,0x88,0x42,
0x12,0xd1,0x07,0x28,0x07,0xd0,0xa1,0x7a,0x00,0x91,0x20,0x4f,0xe3,0x7a,0x22,0x7b,
0x21,0x89,0xb8,0x47,0x05,0xe0,0x1e,0x4b,0x21,0x79,0x20,0x89,0x2a,0x46,0x98,0x47,
0x02,0x90,0x20,0x46,0xb0,0x47,0x03,0xe0,0x1a,0x4a,0x21,0x46,0x04,0xa8,0x90,0x47,
0x01,0x20,0x80,0xf3,0x10,0x88,0x0f,0x49,0x09,0x98,0x88,0x47,0x04,0x46,0x20,0x00,
0x0c,0xd1,0x04,0x98,0x00,0x28,0x03,0xd0,0x00,0x20,0x00,0x28,0x02,0xd0,0x05,0xe0,
0x01,0x20,0xfa,0xe7,0x10,0x4a,0x04,0xa9,0x09,0x98,0x90,0x47,0x00,0x20,0x80,0xf3,
0x10,0x88,0x00,0x2c,0xc9,0xd1,0x02,0x98,0x0d,0xb0,0xf0,0xbd,0xb5,0x38,0x00,0x00,
0x40,0x44,0x80,0x50,0x45,0x39,0x00,0x00,0xa5,0x93,0x00,0x00,0x09,0xb8,0x00,0x00,
0x5d,0x56,0x00,0x00,0x05,0xb7,0x00,0x00,0xb8,0x61,0x00,0x20,0x29,0xb7,0x00,0x00,
0x35,0x22,0x01,0x00,0x67,0x39,0x00,0x00,0x0f,0x39,0x00,0x00,0xf1,0xb5,0x00,0x24,
0x15,0x4d,0x16,0x4e,0x01,0x20,0x80,0xf3,0x10,0x88,0x00,0x98,0xa8,0x47,0x00,0x21,
0x81,0xf3,0x10,0x88,0x00,0x28,0x17,0xd0,0x81,0x88,0x0a,0x46,0x0a,0x3a,0x46,0x2a,
0x14,0xd2,0xc9,0x00,0x89,0x19,0x09,0x8d,0x0f,0x0a,0x01,0x21,0x81,0xf3,0x10,0x88,
0x0b,0x49,0x88,0x47,0x00,0x28,0x03,0xd0,0x00,0x2f,0x01,0xd0,0x64,0x1c,0xe4,0xb2,
0x00,0x20,0x80,0xf3,0x10,0x88,0xdd,0xe7,0x20,0x46,0xf8,0xbd,0xc9,0x1f,0x49,0x29,
0xd8,0xd3,0x04,0x49,0x88,0x47,0xd5,0xe7,0x45,0x39,0x00,0x00,0x40,0x44,0x80,0x50,
0x5d,0x56,0x00,0x00,0xa5,0x93,0x00,0x00,0xf1,0xb5,0x92,0xb0,0x12,0x98,0x40,0x30,
0x11,0x90,0x80,0x8f,0x0e,0x90,0x12,0x98,0x08,0x30,0x0d,0x90,0x12,0x98,0x30,0x30,
0x0c,0x90,0x12,0x98,0x44,0x30,0x0b,0x90,0x00,0x20,0x0a,0x90,0x01,0x25,0x0c,0x98,
0x04,0x68,0x00,0x2c,0x03,0xd0,0x00,0x20,0x00,0x28,0x02,0xd0,0x93,0xe0,0x01,0x20,
0xfa,0xe7,0x0e,0x98,0xc1,0x00,0xf9,0x48,0x08,0x18,0x10,0x90,0xc0,0x8c,0xc0,0x0b,
0x00,0x28,0x6e,0xd0,0x0e,0x98,0xf6,0x49,0x80,0x00,0x0f,0x90,0x08,0x58,0xa0,0x30,
0x46,0x79,0x01,0x20,0x71,0x07,0x19,0xd5,0x00,0x2c,0x17,0xd0,0xf1,0x4f,0xb0,0x06,
0x07,0xd5,0x20,0x7b,0xb8,0x47,0x80,0x07,0x01,0xd4,0x00,0x20,0x06,0xe0,0x01,0x20,
0x04,0xe0,0x20,0x7b,0xb8,0x47,0xc0,0x07,0x03,0xd0,0x01,0x20,0x00,0x28,0x02,0xd0,
0x04,0xe0,0x00,0x20,0xfa,0xe7,0x24,0x68,0x00,0x2c,0xe8,0xd1,0x00,0x28,0x62,0xd0,
0xe5,0x4b,0x00,0x22,0x21,0x46,0x0c,0x98,0x98,0x47,0xa6,0x68,0xe3,0x4a,0x09,0xa9,
0x30,0x46,0x90,0x47,0x00,0x28,0x56,0xd1,0xa0,0x88,0xdc,0x4f,0xc0,0x00,0xc0,0x19,
0x40,0x8d,0xdf,0x49,0x41,0x18,0x00,0x20,0x08,0xaa,0x12,0x79,0x00,0x2a,0x06,0xdd,
0x32,0x5c,0x0a,0x54,0x40,0x1c,0x08,0xaa,0x12,0x79,0x90,0x42,0xf8,0xdb,0xd9,0x49,
0xa0,0x68,0x88,0x47,0xd2,0x49,0x0f,0x98,0x08,0x58,0xa0,0x30,0x40,0x79,0xc0,0x07,
0x03,0xd0,0x08,0xa9,0x08,0x79,0x00,0x1d,0x09,0x90,0x08,0xa8,0x01,0x79,0x10,0x98,
0x02,0x8d,0x09,0x02,0xd2,0xb2,0x0a,0x43,0x02,0x85,0x03,0x21,0x10,0x98,0x02,0x8d,
0x8a,0x43,0x0a,0x43,0x02,0x85,0x11,0x98,0x80,0x8f,0x00,0x21,0xc0,0x00,0xc0,0x19,
0xc1,0x84,0x0b,0x98,0x00,0x68,0x00,0x28,0x04,0xd0,0x00,0x20,0x00,0x28,0x03,0xd0,
0x10,0xe0,0x18,0xe0,0x01,0x20,0xf9,0xe7,0x0b,0x98,0xa1,0x88,0x40,0x68,0xca,0x00,
0xc1,0x49,0x80,0x88,0x51,0x18,0xc0,0x00,0xc0,0x19,0xc2,0x8c,0xd2,0x0b,0xd2,0x03,
0x0a,0x43,0xc2,0x84,0xbd,0x4a,0x21,0x46,0x0b,0x98,0x90,0x47,0x12,0x98,0x60,0x30,
0x01,0x7e,0x49,0x1c,0x01,0x76,0x11,0x98,0x80,0x8f,0x07,0x28,0x08,0xd2,0x0e,0x99,
0x8a,0x00,0xaf,0x49,0x89,0x58,0xa0,0x31,0x49,0x79,0x49,0x07,0x00,0xd5,0x00,0x25,
0x0d,0x99,0x09,0x68,0x00,0x29,0x1f,0xd0,0x00,0x21,0x2a,0x46,0x8a,0x43,0x77,0xd0,
0x07,0x28,0x76,0xd2,0xaf,0x49,0xae,0x48,0x88,0x47,0x09,0x90,0x00,0x20,0x08,0x90,
0x11,0x98,0x80,0x8f,0x81,0x00,0xa2,0x48,0x40,0x58,0xa0,0x30,0x40,0x79,0xc0,0x07,
0xc0,0x0f,0x07,0x90,0x0d,0x98,0x06,0x68,0x00,0x2e,0x09,0xd0,0x0d,0x99,0x30,0x68,
0x08,0x60,0x00,0x28,0x02,0xd0,0x03,0xe0,0x01,0x21,0xde,0xe7,0x0d,0x99,0x48,0x60,
0x00,0x2e,0x7d,0xd0,0x00,0x20,0x06,0x90,0x12,0x98,0x03,0x90,0x06,0xa8,0x04,0x90,
0x07,0x9f,0x09,0x9b,0x05,0x97,0x08,0x25,0x75,0x5f,0x00,0x20,0x02,0x90,0x01,0x90,
0x01,0x20,0x00,0x90,0x11,0x98,0x42,0x8e,0x84,0x46,0xd4,0xb2,0x01,0x20,0x29,0x46,
0x09,0x31,0x89,0xb2,0x05,0x9f,0x00,0x2f,0x01,0xd0,0x09,0x1d,0x89,0xb2,0xc9,0x00,
0x08,0x31,0x89,0xb2,0x67,0x46,0x3f,0x8e,0x8f,0x42,0x05,0xd2,0x50,0x3f,0x79,0x05,
0x0c,0x0e,0xa2,0x42,0x00,0xd2,0xd4,0xb2,0xa5,0x42,0x01,0xdd,0x64,0x08,0x64,0x00,
0x21,0x46,0x6f,0x1a,0x62,0x1c,0x97,0x42,0x05,0xdb,0x09,0x19,0x40,0x1c,0xc0,0xb2,
0x6f,0x1a,0x97,0x42,0xf9,0xda,0x98,0x42,0x01,0xd9,0x00,0x25,0x34,0xe0,0x04,0x99,
0x08,0x70,0x81,0x4f,0x81,0x49,0x7e,0x48,0x88,0x47,0x01,0x46,0x00,0x98,0x00,0x28,
0x12,0xd0,0x00,0x20,0x00,0x90,0xb0,0x7a,0x80,0x07,0x80,0x0f,0x01,0x28,0x09,0xd0,
0x02,0x20,0x88,0x72,0xf0,0x68,0xc2,0x88,0x02,0x92,0x80,0x88,0x01,0x90,0x09,0xe0,
0x62,0xe0,0x58,0xe0,0x01,0x20,0xf4,0xe7,0x01,0x20,0x88,0x72,0x02,0x98,0x00,0x19,
0x80,0xb2,0x02,0x90,0xa5,0x42,0x01,0xdd,0xcc,0x72,0x00,0xe0,0xcd,0x72,0x01,0x98,
0xc8,0x80,0x02,0x98,0x08,0x81,0x28,0x1b,0x05,0xb2,0x00,0x2d,0x22,0xdc,0x01,0x22,
0x05,0x9b,0x03,0x98,0xb8,0x47,0x01,0x25,0x00,0x2d,0x20,0xd0,0x68,0x46,0x00,0x7e,
0x08,0x99,0x09,0x18,0xc9,0xb2,0x08,0x91,0x09,0x99,0x08,0x1a,0x80,0xb2,0x00,0xe0,
0x35,0xe0,0x09,0x90,0x12,0x98,0xc0,0x69,0x00,0x28,0x1a,0xd0,0x12,0x98,0x00,0x6a,
0x06,0x60,0x12,0x98,0x06,0x62,0x00,0x20,0x30,0x60,0x08,0x98,0x0a,0x28,0x13,0xd9,
0x00,0x25,0x24,0xe0,0x00,0x22,0x05,0x9b,0x03,0x98,0xb8,0x47,0xaa,0xe7,0x0d,0x98,
0x00,0x68,0x00,0x28,0x01,0xd1,0x0d,0x99,0x4e,0x60,0x30,0x60,0x0d,0x98,0x06,0x60,
0x15,0xe0,0x12,0x98,0xc6,0x61,0xe4,0xe7,0x0d,0x98,0x06,0x68,0x00,0x2e,0x06,0xd0,
0x0d,0x99,0x30,0x68,0x08,0x60,0x00,0x28,0x01,0xd1,0x0d,0x99,0x48,0x60,0x00,0x2e,
0x00,0xd0,0x4f,0xe7,0x03,0xe0,0x4a,0x4a,0x0d,0x99,0x0b,0x98,0x90,0x47,0x00,0x2d,
0x02,0xd0,0x48,0x49,0x0d,0x98,0x88,0x47,0x0b,0x98,0x00,0x68,0x00,0x28,0x03,0xd0,
0x00,0x20,0x00,0x28,0x02,0xd0,0x4b,0xe0,0x01,0x20,0xfa,0xe7,0x11,0x98,0x80,0x8f,
0x07,0x28,0x45,0xd2,0x12,0x98,0x80,0x30,0xc0,0x78,0x04,0x28,0x40,0xd1,0x3b,0x49,
0x37,0x48,0x88,0x47,0x00,0x28,0x3b,0xd0,0x82,0x88,0x00,0x21,0x2b,0x4b,0xd2,0x00,
0xd2,0x18,0x51,0x85,0x81,0x88,0xc9,0x00,0xc9,0x18,0x8a,0x8d,0x54,0x04,0x64,0x0c,
0x00,0x22,0x8c,0x85,0x81,0x88,0xc9,0x00,0xc9,0x18,0x0c,0x8d,0xe4,0xb2,0x0c,0x85,
0x81,0x88,0x01,0x24,0xc9,0x00,0xc9,0x18,0x0d,0x8d,0xad,0x08,0xad,0x00,0x25,0x43,
0x0d,0x85,0x81,0x88,0xc9,0x00,0xc9,0x18,0xcc,0x8c,0xe4,0x0b,0xe4,0x03,0xcc,0x84,
0x0b,0x99,0x84,0x88,0x49,0x68,0xe5,0x00,0x1f,0x4c,0x89,0x88,0x2c,0x19,0xc9,0x00,
0xc9,0x18,0xcb,0x8c,0xdb,0x0b,0xdb,0x03,0x23,0x43,0xcb,0x84,0x0b,0x99,0x09,0x68,
0x00,0x29,0x0d,0xd0,0x0b,0x99,0x49,0x68,0x08,0x60,0x0b,0x99,0x48,0x60,0x02,0x60,
0x0b,0x98,0x00,0x68,0x00,0x28,0x06,0xd0,0x00,0x21,0x00,0x29,0x05,0xd0,0x3c,0xe0,
0x0b,0x99,0x08,0x60,0xf1,0xe7,0x01,0x21,0xf7,0xe7,0x00,0x28,0x0a,0xd0,0x07,0x4a,
0x81,0x88,0xc9,0x00,0x89,0x18,0xc9,0x8c,0xc9,0x0b,0x00,0x29,0x24,0xd0,0x00,0x68,
0x00,0x28,0xf5,0xd1,0x00,0x28,0x26,0xd0,0x27,0xe0,0x00,0x00,0x40,0x44,0x80,0x50,
0x60,0x61,0x00,0x20,0x81,0xaf,0x00,0x00,0x17,0x38,0x00,0x00,0x41,0x03,0x01,0x00,
0x00,0x40,0x80,0x50,0xa5,0x93,0x00,0x00,0x66,0x04,0x00,0x00,0x67,0x39,0x00,0x00,
0xe4,0x61,0x00,0x20,0xbb,0x39,0x00,0x00,0x11,0x00,0x01,0x00,0x45,0x39,0x00,0x00,
0x0f,0x39,0x00,0x00,0xb5,0x38,0x00,0x00,0x81,0x88,0xca,0x00,0x07,0x49,0x51,0x18,
0x89,0xb2,0x0a,0x91,0xd6,0xe7,0x00,0x20,0x0a,0x90,0x0a,0x99,0x0e,0x98,0x5a,0x22,
0x50,0x43,0x03,0x4a,0x80,0x18,0x81,0x84,0x13,0xb0,0xf0,0xbd,0x66,0x04,0x00,0x00,
0x80,0x40,0x80,0x50,0x10,0xb4,0x00,0x23,0x14,0x21,0x02,0x46,0x4a,0x43,0x11,0x49,
0x7d,0x24,0x09,0x68,0x24,0x02,0xa1,0x42,0x02,0xd9,0x09,0x1b,0x01,0x23,0x00,0xe0,
0x61,0x1a,0x48,0x43,0x81,0x00,0x41,0x18,0x88,0x0a,0x0c,0x0c,0x00,0x19,0x4c,0x0c,
0x00,0x19,0x4c,0x0d,0x00,0x19,0x4c,0x0e,0x00,0x19,0xc9,0x0f,0x40,0x18,0xc0,0x08,
0x00,0x2b,0x01,0xd0,0x10,0x18,0x01,0xe0,0x10,0x1a,0x40,0x1e,0x40,0x1e,0x10,0xbc,
0x70,0x47,0x00,0x00,0x54,0x60,0x00,0x20,0xf0,0xb4,0x00,0x23,0x18,0x4c,0xe5,0x6b,
0x18,0x49,0x7d,0x22,0x09,0x68,0x12,0x02,0x91,0x42,0x02,0xd3,0x8a,0x1a,0x01,0x23,
0x00,0xe0,0x52,0x1a,0x06,0x46,0x56,0x43,0xf2,0x13,0x51,0x43,0x71,0x1a,0x1e,0x26,
0x4e,0x43,0x4f,0x10,0xf6,0x19,0x8f,0x11,0xf6,0x19,0x49,0x12,0x71,0x18,0xce,0x13,
0x00,0x2b,0x01,0xd0,0x80,0x1a,0x00,0xe0,0x10,0x18,0x42,0x19,0x91,0x08,0x8d,0x00,
0x52,0x1b,0x00,0x2b,0x04,0xd0,0x43,0x01,0x18,0x1a,0x40,0x18,0x80,0x1b,0x03,0xe0,
0x43,0x01,0x18,0x1a,0x40,0x18,0x80,0x19,0xe2,0x63,0xf0,0xbc,0x70,0x47,0x00,0x00,
0x80,0x67,0x00,0x20,0x54,0x60,0x00,0x20
}
};
am_hal_ble_patch_t am_ble_buffer_patch =
{
.ui32Type = 0xCC,
.ui32Length = 0x0d38,
.ui32CRC = 0xf515,
.pui32Data = am_ble_buffer_patch_data.words,
};
//*****************************************************************************
//
// Patch Name: NVDS v1.10 for Apollo3 A1
//
// Bi-directional data fix
// Modulation deviation fix
// Extend patch memory
// Transmit speed patch
// Added AGC table and enabled AGC
// Added local feature support setting
// Fix to connection interval calculation issue with MTK chip sets (OPPO R15 fix)
// Set VCO to 250mv
// Modex auto calibration update
// Fix connection interval calculation issue
// Increase RF LDO ref voltage form 1.0v to 1.1v
// Decrease DAC channel delay cycle
// Increase the VCO swing from 250mv to 300mv
// Fix MD schedule issue (disabled)
// Fix link loss issue
// Reduce duration from TX to TX
// Optimized power consumption (32K clock drift,sleep clock accuracy,,advertising interval (undirect))
// Date: 2019-01-30
//
//*****************************************************************************
am_hal_ble_buffer(0x00be) am_ble_buffer_nvds_data =
{
.bytes =
{
0x4e,0x56,0x44,0x53, //NVDS_MAGIC_NUMBER
0x01,0x06,0x06,0xef,0xab,0x23,0x88,0x77,0x56, //bluetooth address
0x02,0x06,0x0a,0x4e,0x5a,0x38,0x38,0x30,0x31,0x56,0x31,0x41,0x00, //device name
0x03,0x06,0x01,0x00, //system clock frequency, 00=32MHz 01=24MHz others=16MHz
0x07,0x06,0x02,0x00,0x00, //32K clock drift, 0x01f4 = 500 ppm
0x0c,0x06,0x02,50,0x00, //sleep clock accuracy, 0x01f4 = 500 ppm
0x08,0x06,0x01,0x00, //01 for BQB qualification, 00 for normal usage
0x09,0x06,0x01,0x02, //clock source selection, 00 = internal RC32KHz, 02= use Apollo3 MCU 32.768KHz
0x0a,0x06,0x04,0x00,0x00,0x00,0x00, //eb 0x00000000 = auto detect and low frequency clock calibration
0x0b,0x06,0x01,0x96, //rx_ifs 0x96 = 150us
0x23,0x06,0x01,0x95, //tx_ifs 0x95 = 149us
0x0d,0x06,0x02,0xe8,0x03, //duration allowed for XO32M stabilization from external wakeup signal
0x0e,0x06,0x02,0xe8,0x03, //duration allowed for XO32M stabilization from internal wakeup signal
0x0f,0x06,0x02,0x2c,0x01, //duration allowed for radio to leave low power mode
0x10,0x06,0x04,0x00,0xc2,0x01,0x00, //set UART_BAUDRATE
0x11,0x06,0x01,0x01, //sleep algorithm enabled
0x12,0x06,0x01,0x01, //external wake-up support
0x13,0x06,0x02,0xf4,0x01, //duration of sleep and wake-up algorithm
0x14,0x06,0x02,0x60,0x00, //BLE Company ID
0x15,0x06,0x01,0x08, //BLE major version
0x16,0x06,0x01,0x03, //BLE minor version
0x17,0x06,0x01,0x29, //BLE SW version build
0x18,0x06,0x02,0xdc,0x05, //advertising interval (undirect)
0x19,0x06,0x02,0xe2,0x04, //advertising interval (direct)
0x20,0x06,0x01,0x01, //agc switch
0x21,0x06,0x01,0x02, //EA programming latency
0x22,0x06,0x01,0x00, //EA asap latency
0x24,0x06,0x04,0x42,0x02,0x60,0x09, //radio TRX timing
0x25,0x06,0x01,0x11, //modem polarity setting
0x26,0x06,0x01,0x00, //modem sync setting
0x27,0x06,0x01,0x02, //BLE reset delay
0x2d,0x06,0x01,0x00, //2 byte mode switch, 01 to enable
0x28,0x06,0x02,0xf6,0x3f, //initial agc gain setting
0x29,0x06,0x01,0x0f, //initial Tx output power, 0x0f is +4dBm
0x35,0x06,0x01,0x08, //maximum Tx ouput power setting
0x37,0x06,0x01,0x00, //RC32K calibration control, 0xAA to enable
0x05,0x06,0x02,0x34,0x00, //no use
0x04,0x06,0x01,0x20, //internal dvdd voltage level control if using 0.9V from MCU side
0x00,0x00,0x00,0x00 //dummy
}
};
am_hal_ble_patch_t am_ble_nvds_patch =
{
.ui32Type = 0xDD,
.ui32Length = 0x00be,
.ui32CRC = 0x7e77,
.pui32Data = am_ble_buffer_nvds_data.words,
};
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,105 @@
//*****************************************************************************
//
//! @file am_hal_ble_patch.h
//!
//! @brief This is a binary patch for the BLE core.
//!
//! @addtogroup
//! @ingroup
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_BLE_PATCH_H
#define AM_HAL_BLE_PATCH_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Patch array pointer.
//
//*****************************************************************************
extern am_hal_ble_patch_t **am_hal_ble_default_patches;
extern am_hal_ble_patch_t **am_hal_ble_default_copy_patches;
extern const uint32_t am_hal_ble_num_default_patches;
//*****************************************************************************
//
// Pointers for specific patches.
//
//*****************************************************************************
extern am_hal_ble_patch_t am_ble_performance_patch;
extern am_hal_ble_patch_t am_ble_nvds_patch;
//*****************************************************************************
//
// Default patch structure.
//
//*****************************************************************************
extern am_hal_ble_patch_t g_AMBLEDefaultPatch;
//*****************************************************************************
//
// Macros for accessing specific NVDS parameters.
//
//*****************************************************************************
#define AM_HAL_BLE_NVDS_CLOCKDRIFT_OFFSET 30
#define AM_HAL_BLE_NVDS_SLEEPCLOCKDRIFT_OFFSET 35
#define AM_HAL_BLE_NVDS_CLOCKSOURCE_OFFSET 44
#define AM_HAL_BLE_NVDS_SLEEPENABLE_OFFSET 85
#define AM_HAL_BLE_NVDS_AGC_OFFSET 125
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_BLE_PATCH_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,389 @@
//*****************************************************************************
//
//! @file am_hal_ble_patch_b0.c
//!
//! @brief This is a binary patch for the BLE core.
//!
//! @addtogroup
//! @ingroup
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// BLE LL local supported feature flags.
//
// Bit position | Link Layer Feature
// 0 | LE Encryption
// 1 | Connection Parameters Request Procedure
// 2 | Extended Reject Indication
// 3 | Slave-initiated Features Exchange
// 4 | LE Ping
// 5 | LE Data Packet Length Extension
// 6 | LL Privacy
// 7 | Extended Scanner Filter Policies
//
// Specified 4.6 Feature Support, Link Layer Specification, Core V4.2.
//
//*****************************************************************************
#ifndef AM_HAL_BLE_LOCAL_FEATURE
#define AM_HAL_BLE_LOCAL_FEATURE 0x21
#endif
//*****************************************************************************
//
// Patches included in this file.
//
//*****************************************************************************
am_hal_ble_patch_t am_ble_buffer_patch_b0;
am_hal_ble_patch_t am_ble_performance_patch_b0;
am_hal_ble_patch_t am_ble_nvds_patch_b0;
//*****************************************************************************
//
// Patch application order.
//
//*****************************************************************************
am_hal_ble_patch_t *am_hal_ble_default_patch_array_b0[] =
{
// FTCODE patches (type 0xAA)
// RAMCODE patches (type 0xBB)
&am_ble_performance_patch_b0,
// Standard patches (type 0xCC)
&am_ble_buffer_patch_b0,
// nvds param (type 0xDD)
&am_ble_nvds_patch_b0,
};
#define AM_HAL_BLE_NUM_DEFAULT_PATCHES_B0 \
(sizeof(am_hal_ble_default_patch_array_b0) / \
sizeof(am_hal_ble_default_patch_array_b0[0]))
am_hal_ble_patch_t **am_hal_ble_default_patches_b0 = am_hal_ble_default_patch_array_b0;
const uint32_t am_hal_ble_num_default_patches_b0 = AM_HAL_BLE_NUM_DEFAULT_PATCHES_B0;
//*****************************************************************************
//
// Patch Name: RAMCODE PATCH v0.4 for Apollo3 B0
// Reduce duration from TX to TX
// Optimized 32K XO frequency calculation
// Optimized AGC Table
// Fixed Channelmap indication rejected issue
// Fixed 800M Spur
// Fixed feature issue
// Fixed disconnect issue //long time large data transfer
// Date: 2019-10-25
//*****************************************************************************
am_hal_ble_buffer(0x0654)am_ble_performance_patch_data_b0 =
{
.bytes =
{
0x00,0x11,0x50,0x06,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0xc5,0x01,
0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x81,0x06,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x1f,0xb5,0x00,0x24,0x00,0x98,0x22,0x28,0x2d,0xd2,0x01,0x00,
0x79,0x44,0x09,0x79,0x49,0x18,0x8f,0x44,0x10,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,
0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x15,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x18,
0x2a,0x1b,0x1e,0x2a,0x2a,0x28,0x28,0x28,0x28,0x24,0x01,0x98,0xc0,0xb2,0x00,0xf0,
0x95,0xf8,0x14,0xe0,0x00,0xf0,0x16,0xf8,0x11,0xe0,0x00,0xf0,0xd1,0xf9,0x0e,0xe0,
0x00,0xf0,0x2c,0xfa,0x0b,0xe0,0x01,0x98,0xc0,0xb2,0x00,0xf0,0x5d,0xf9,0x04,0x46,
0x05,0xe0,0x00,0xf0,0xa3,0xfa,0x04,0x46,0x01,0xe0,0x00,0x24,0xe4,0x43,0x20,0x46,
0x04,0xb0,0x10,0xbd,0xf0,0xb4,0x00,0x20,0x43,0x22,0x12,0x06,0x51,0x68,0xff,0x24,
0x01,0x34,0x21,0x43,0x51,0x60,0x51,0x68,0x23,0x03,0x19,0x43,0x51,0x60,0xa3,0x23,
0xdb,0x05,0x19,0x68,0x49,0x08,0x49,0x00,0x19,0x60,0x2a,0x49,0x09,0x69,0xce,0xb2,
0x29,0x4d,0x2a,0x4f,0x29,0x88,0xb9,0x42,0x01,0xd3,0x04,0x20,0x0d,0xe0,0x28,0x4f,
0xb9,0x42,0x01,0xd3,0x03,0x20,0x08,0xe0,0x26,0x4f,0xb9,0x42,0x01,0xd3,0x02,0x20,
0x03,0xe0,0x25,0x4f,0xb9,0x42,0x00,0xd3,0x01,0x20,0x24,0x4f,0x39,0x18,0x20,0x31,
0x09,0x7e,0xb1,0x42,0x09,0xda,0x00,0x28,0x01,0xdd,0x40,0x1e,0x40,0xb2,0x39,0x18,
0x09,0x7a,0x40,0x00,0xc0,0x19,0x00,0x8b,0x0b,0xe0,0x04,0x28,0x04,0xda,0x39,0x5c,
0xb1,0x42,0x01,0xdb,0x40,0x1c,0x40,0xb2,0x39,0x18,0x09,0x7a,0x40,0x00,0xc0,0x19,
0x00,0x8b,0x17,0x4e,0x31,0x62,0x19,0x68,0x49,0x08,0x49,0x00,0x19,0x60,0x15,0x4e,
0x31,0x6b,0x0f,0x46,0x27,0x43,0x37,0x63,0x98,0x62,0xa1,0x43,0x31,0x63,0x28,0x80,
0x51,0x68,0xb0,0x03,0x81,0x43,0x10,0x48,0x00,0x78,0xc0,0x07,0xc0,0x0f,0x03,0x05,
0x19,0x43,0x51,0x60,0x51,0x68,0x00,0x02,0xa1,0x43,0x01,0x43,0x51,0x60,0xf0,0xbc,
0x70,0x47,0x00,0x00,0x80,0x00,0x80,0x45,0x50,0x68,0x00,0x20,0xf6,0x3f,0x00,0x00,
0xf6,0x38,0x00,0x00,0xf6,0x2d,0x00,0x00,0xf6,0x09,0x00,0x00,0x50,0x6e,0x00,0x20,
0x80,0x04,0xc0,0x50,0x40,0x00,0x80,0x45,0x3a,0x68,0x00,0x20,0xf0,0xb4,0x43,0x20,
0x00,0x06,0x41,0x68,0x01,0x22,0x92,0x04,0x11,0x43,0x41,0x60,0xc4,0x21,0x87,0x22,
0xd2,0x05,0x11,0x60,0x50,0x49,0x51,0x61,0x42,0x68,0x01,0x21,0x89,0x04,0x8a,0x43,
0x4e,0x49,0x09,0x78,0xc9,0x07,0xc9,0x0f,0x8b,0x04,0x1a,0x43,0x42,0x60,0x8b,0x23,
0x4b,0x4a,0xdb,0x05,0x5a,0x63,0x4b,0x4b,0x02,0x22,0xda,0x60,0x05,0x22,0xc2,0x60,
0x8b,0x23,0xdb,0x05,0xda,0x63,0x47,0x4b,0x01,0x22,0x1a,0x61,0x5a,0x62,0x9a,0x63,
0x45,0x4b,0x1a,0x60,0x45,0x4c,0x5c,0x61,0x8b,0x23,0xdb,0x05,0xdb,0x6a,0x13,0x43,
0x8b,0x22,0xd2,0x05,0xd3,0x62,0x42,0x68,0x01,0x25,0x2d,0x04,0x2a,0x43,0x42,0x60,
0x42,0x68,0xac,0x10,0x22,0x43,0x42,0x60,0x3e,0x4a,0x3d,0x4b,0x53,0x61,0x93,0x68,
0x3f,0x26,0xb6,0x05,0x33,0x43,0x93,0x60,0x00,0x23,0xd3,0x60,0x3a,0x4b,0x93,0x61,
0x3a,0x4e,0x33,0x68,0x1e,0x27,0xbb,0x43,0x33,0x60,0x93,0x6a,0xfe,0x03,0xb3,0x43,
0x26,0x01,0x9b,0x19,0x93,0x62,0x36,0x4b,0xf0,0x22,0x5a,0x60,0x42,0x68,0x0b,0x04,
0xaa,0x43,0x1a,0x43,0x42,0x60,0x42,0x68,0x8b,0x03,0xa2,0x43,0x1a,0x43,0x42,0x60,
0x42,0x68,0x64,0x10,0x22,0x43,0x42,0x60,0x29,0x22,0x52,0x06,0x13,0x6a,0x1b,0x09,
0x1b,0x01,0x08,0x33,0x13,0x62,0x2b,0x4b,0xd3,0x60,0x42,0x68,0x4b,0x03,0xa2,0x43,
0x1a,0x43,0x42,0x60,0x43,0x68,0xe2,0x01,0x13,0x43,0x43,0x60,0x28,0x24,0xa3,0x23,
0xdb,0x05,0x1c,0x60,0x24,0x4d,0x2d,0x88,0x9d,0x62,0x43,0x68,0x09,0x05,0x93,0x43,
0x0b,0x43,0x43,0x60,0x21,0x48,0xe6,0x21,0x01,0x70,0x04,0x72,0x1f,0x4a,0x20,0x48,
0x10,0x83,0x20,0x48,0xe0,0x23,0x03,0x76,0x1c,0x4c,0xd4,0x22,0x62,0x70,0x3c,0x22,
0x62,0x72,0x1d,0x4a,0x62,0x83,0x41,0x76,0xc8,0x22,0xa2,0x70,0x17,0x4d,0x46,0x24,
0xac,0x72,0x1a,0x4c,0xac,0x83,0x81,0x76,0x29,0x46,0xca,0x70,0x50,0x21,0x2a,0x46,
0xd1,0x72,0x17,0x49,0xd1,0x83,0xc3,0x76,0x5a,0x21,0x11,0x73,0x15,0x49,0x11,0x84,
0x03,0x77,0xf0,0xbc,0x70,0x47,0x00,0x00,0xff,0x7f,0x00,0x00,0x3a,0x68,0x00,0x20,
0x49,0x02,0x00,0x00,0x40,0x00,0x80,0x45,0x80,0x00,0x80,0x45,0x1e,0x02,0x00,0x00,
0x03,0x00,0x3c,0x00,0x00,0x00,0x40,0x52,0x08,0x00,0x0f,0x00,0x00,0x00,0xc0,0x51,
0x40,0x00,0x40,0x52,0xcc,0x34,0x63,0x02,0x50,0x68,0x00,0x20,0x50,0x6e,0x00,0x20,
0xf6,0x07,0x00,0x00,0x70,0x6e,0x00,0x20,0xf6,0x09,0x00,0x00,0xf6,0x2d,0x00,0x00,
0xf6,0x38,0x00,0x00,0xf6,0x3f,0x00,0x00,0xf8,0xb5,0x2d,0x48,0x00,0x68,0x00,0x28,
0x54,0xd1,0x43,0x22,0x12,0x06,0x50,0x68,0x01,0x21,0xc9,0x03,0x08,0x43,0x50,0x60,
0x28,0x4f,0x3c,0x68,0x01,0x25,0x03,0x20,0x00,0x06,0x20,0x43,0x38,0x60,0x00,0x26,
0x25,0x49,0x1e,0x20,0x88,0x47,0x24,0x49,0x01,0x20,0x88,0x47,0x78,0x68,0xc0,0x07,
0xc0,0x0f,0x31,0x46,0x21,0x4a,0x76,0x1c,0x91,0x42,0x01,0xd8,0x00,0x28,0xf2,0xd0,
0x1c,0x48,0x81,0x68,0x1e,0x48,0x01,0x60,0x00,0x20,0x00,0x26,0x00,0x2d,0x11,0xd0,
0x1c,0x4b,0x32,0x46,0x00,0x25,0xcb,0x1a,0xaa,0x41,0x14,0xda,0x40,0x1c,0x05,0x46,
0x18,0x4f,0x4d,0x43,0x33,0x46,0x00,0x22,0x7d,0x1b,0x9a,0x41,0x4d,0x1b,0x93,0x41,
0xf4,0xdb,0x08,0xe0,0x14,0x4b,0x99,0x42,0x05,0xd2,0x40,0x1c,0x02,0x46,0x4a,0x43,
0x9a,0x1a,0x8a,0x42,0xf9,0xd8,0x01,0x21,0x09,0x06,0x8c,0x43,0x49,0x00,0x0c,0x43,
0x08,0x49,0x0c,0x60,0x43,0x22,0x12,0x06,0x51,0x68,0x01,0x23,0xdb,0x03,0x99,0x43,
0x0a,0x4b,0x1b,0x78,0xdb,0x07,0x1b,0x0c,0x19,0x43,0x51,0x60,0xf8,0xbd,0x00,0x00,
0x60,0x68,0x00,0x20,0x00,0x00,0x40,0x44,0xe5,0x3e,0x00,0x00,0x10,0x27,0x00,0x00,
0x64,0x68,0x00,0x20,0x00,0x20,0xbc,0xbe,0x00,0xd0,0x12,0x13,0x3a,0x68,0x00,0x20,
0xf8,0xb5,0x24,0x48,0x80,0x47,0x43,0x24,0x24,0x06,0x01,0x21,0x60,0x68,0x89,0x04,
0x08,0x43,0x60,0x60,0x20,0x48,0x80,0x47,0x20,0x48,0x00,0x78,0xaa,0x28,0x06,0xd1,
0xa0,0x68,0x80,0x07,0x03,0xd1,0x1e,0x49,0x88,0x47,0x1e,0x49,0x08,0x60,0x06,0x27,
0xe7,0x60,0x1d,0x4c,0x01,0x20,0xa0,0x47,0xa1,0x20,0xc0,0x05,0x02,0x6b,0x02,0x21,
0x8a,0x43,0x0a,0x43,0x02,0x63,0x01,0x21,0x02,0x6b,0x8a,0x43,0x0a,0x43,0x02,0x63,
0x01,0x6b,0x04,0x25,0xa9,0x43,0x29,0x43,0x01,0x63,0x14,0x4e,0x70,0x68,0x80,0x00,
0x04,0xd5,0x01,0x20,0xa0,0x47,0x70,0x68,0x80,0x00,0xfa,0xd4,0x10,0x4e,0x0f,0x20,
0x70,0x60,0x01,0x20,0xa0,0x47,0x07,0x20,0x70,0x60,0x04,0x20,0xa0,0x47,0x77,0x60,
0x8b,0x21,0x0c,0x48,0xc9,0x05,0x08,0x60,0x0b,0x48,0x01,0x69,0x29,0x43,0x01,0x61,
0x30,0xbf,0xf8,0xbd,0x75,0x3a,0x00,0x00,0x85,0xa3,0x00,0x00,0x2c,0x68,0x00,0x20,
0x11,0x3d,0x00,0x00,0x58,0x68,0x00,0x20,0xe5,0x3e,0x00,0x00,0x80,0x00,0x80,0x45,
0x40,0x00,0x80,0x45,0x26,0x03,0x00,0x00,0x00,0xed,0x00,0xe0,0xf8,0xb5,0x05,0x20,
0x43,0x24,0x24,0x06,0xe0,0x60,0x30,0x4e,0x01,0x20,0xb0,0x47,0x2f,0x4f,0x0f,0x20,
0x78,0x60,0x8b,0x25,0xed,0x05,0x28,0x68,0x01,0x21,0x49,0x02,0x88,0x43,0x28,0x60,
0x2b,0x48,0x80,0x47,0x01,0x20,0x80,0xf3,0x10,0x88,0x2a,0x48,0x40,0x68,0x2a,0x49,
0x80,0x00,0x06,0xd4,0x28,0x68,0x08,0x22,0x10,0x43,0x28,0x60,0x01,0x20,0x88,0x47,
0x01,0xe0,0x01,0x20,0x88,0x47,0x25,0x48,0x80,0x47,0x25,0x48,0x00,0x78,0xb0,0x47,
0x0d,0x20,0x78,0x60,0x01,0x20,0xb0,0x47,0x22,0x48,0x80,0x47,0x60,0x68,0x01,0x22,
0x52,0x03,0x10,0x43,0x60,0x60,0x29,0x20,0x1f,0x49,0x40,0x06,0xc1,0x60,0x01,0x6a,
0x09,0x09,0x09,0x01,0x08,0x31,0x01,0x62,0x01,0x68,0xd3,0x10,0x19,0x43,0x01,0x60,
0x1a,0x49,0x09,0x78,0x49,0x00,0x49,0x1c,0x41,0x61,0x61,0x68,0x18,0x48,0x91,0x43,
0x00,0x78,0xc0,0x07,0xc0,0x0f,0x42,0x03,0x11,0x43,0x61,0x60,0x62,0x68,0x99,0x02,
0x0a,0x43,0x62,0x60,0x28,0x23,0xa3,0x22,0xd2,0x05,0x13,0x60,0x11,0x4b,0x1b,0x88,
0x93,0x62,0x62,0x68,0x00,0x05,0x8a,0x43,0x02,0x43,0x62,0x60,0x00,0x20,0x80,0xf3,
0x10,0x88,0x0d,0x48,0x80,0x47,0xf8,0xbd,0xe5,0x3e,0x00,0x00,0x40,0x00,0x80,0x45,
0x65,0x50,0x01,0x00,0x80,0x00,0x80,0x45,0xa1,0x59,0x01,0x00,0x29,0x48,0x01,0x00,
0x41,0x68,0x00,0x20,0xc5,0x64,0x01,0x00,0xcc,0x34,0x63,0x04,0x74,0x68,0x00,0x20,
0x3a,0x68,0x00,0x20,0x50,0x68,0x00,0x20,0x69,0x48,0x01,0x00,0x10,0xb5,0x15,0x48,
0x80,0x7a,0xc0,0x07,0x01,0xd0,0x00,0x20,0x10,0xbd,0x13,0x48,0x80,0x47,0x05,0x20,
0x00,0x07,0xc0,0x69,0x11,0x49,0x00,0x05,0x04,0xd0,0x08,0x78,0x01,0x28,0x14,0xd0,
0x02,0x28,0x12,0xd0,0x08,0x78,0x00,0x28,0x08,0xd0,0x01,0x28,0x06,0xd0,0x02,0x28,
0x04,0xd0,0x0b,0x48,0x80,0x47,0x0b,0x49,0x32,0x20,0x88,0x47,0x0a,0x49,0x04,0x20,
0x88,0x47,0x0a,0x48,0x80,0x47,0x00,0x20,0x10,0xbd,0x09,0x49,0x04,0x20,0x88,0x47,
0x01,0x20,0x10,0xbd,0x0c,0x6e,0x00,0x20,0x51,0x9a,0x00,0x00,0x18,0x10,0x00,0x20,
0x69,0x61,0x01,0x00,0xe5,0x3e,0x00,0x00,0x59,0x59,0x01,0x00,0xd3,0x60,0x01,0x00,
0xa1,0x59,0x01,0x00
}
};
am_hal_ble_patch_t am_ble_performance_patch_b0 =
{
.ui32Type = 0xBB,
.ui32Length = 0x0654,
.ui32CRC = 0x4c38,
.pui32Data = am_ble_performance_patch_data_b0.words,
};
//*****************************************************************************
//*****************************************************************************
//
// Patch Name: Function PATCH v0.4 for Apollo3 B0
//
// Reduce duration from TX to TX
// Optimized 32K XO frequency calculation
// Optimized AGC Table
// Fixed Channelmap indication rejected issue
// Fixed 800M Spur
// Fixed feature issue
// Fixed disconnect issue //long time large data transfer
// Date: 2019-10-25
//*****************************************************************************
const am_hal_ble_buffer(0x0230)am_ble_buffer_patch_data_b0 =
{
.bytes =
{
0x00,0x22,0x30,0x02,0x1f,0x00,0x00,0x00,0x84,0x65,0x06,0x00,0x73,0x6d,0x06,0x00,
0x75,0x75,0x06,0x00,0x17,0x7b,0x06,0x00,0xa9,0x85,0x06,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x20,0xec,0xf7,
0xf9,0xfc,0x00,0x28,0x0a,0xd0,0x00,0x20,0x00,0x90,0x03,0x46,0x02,0x46,0x01,0x46,
0x24,0x68,0x21,0x20,0x35,0x34,0xa0,0x47,0x00,0xbf,0x38,0xbd,0xef,0xf7,0xfb,0xfe,
0x0f,0x49,0x00,0x28,0x02,0xd0,0x08,0x78,0x01,0x28,0x12,0xd0,0x08,0x78,0x02,0x28,
0x0f,0xd0,0x00,0x28,0x06,0xd0,0x01,0x28,0x04,0xd0,0x00,0xf0,0x0c,0x6e,0x00,0x20,
0x00,0x00,0x00,0x04,0x1c,0x6e,0x00,0x20,0x00,0x49,0x08,0x47,0x41,0x34,0x00,0x20,
0x23,0x4e,0xca,0x7c,0x75,0x68,0xc9,0x6a,0x00,0x2a,0x1d,0xd0,0x7d,0x22,0x12,0x02,
0x91,0x42,0x02,0xd3,0x8a,0x1a,0x01,0x20,0x00,0xe0,0x52,0x1a,0x00,0x28,0x05,0xd0,
0x20,0x46,0x50,0x43,0xea,0xf7,0x02,0xfa,0x20,0x1a,0x04,0xe0,0xea,0xf7,0xde,0xf9,
0x00,0x19,0x01,0x02,0xc2,0x00,0x69,0x18,0x12,0x18,0x89,0x18,0x4a,0x0a,0x53,0x02,
0xc9,0x1a,0x71,0x60,0x1e,0x21,0x48,0x43,0x80,0x18,0x70,0xbd,0x2c,0x68,0x00,0x20,
0x0c,0x6e,0x00,0x20,0x00,0x49,0x08,0x47,0xb1,0x34,0x00,0x20,0xc1,0x7c,0xc0,0x6a,
0x00,0x29,0x15,0xd0,0x7d,0x21,0x09,0x02,0x88,0x42,0x02,0xd3,0x02,0xd5,0x04,0x20,
0x60,0x70,0x34,0xe0,0x28,0x69,0x06,0xf0,0xb5,0xf8,0x00,0x28,0x02,0xd0,0x02,0x20,
0x60,0x70,0x2c,0xe0,0x03,0x98,0x04,0xf0,0x1f,0xfa,0x04,0x28,0x07,0xd1,0x68,0x46,
0x01,0x79,0x02,0x20,0x88,0x43,0x05,0xd0,0x00,0x20,0x00,0x28,0x04,0xd0,0x00,0xbf,
0x00,0x20,0x1c,0xe0,0x01,0x20,0xf8,0xe7,0xf0,0x88,0x00,0x90,
//0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
AM_HAL_BLE_LOCAL_FEATURE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
0xff,0x03,0x00,0x00,0xff,0x00,0x3c,0x1f,0x00,0x00,0x00,0x00,0x01,0x20,0x00,0x00,
0x8d,0x84,0x00,0x00,0x02,0x20,0x00,0x00,0xcd,0x7d,0x00,0x00,0x03,0x20,0x00,0x00,
0xd1,0x7e,0x00,0x00,0x05,0x20,0x00,0x00,0xfd,0x84,0x00,0x00,0xf0,0xb4,0x00,0x23,
0x18,0x4c,0x25,0x69,0x18,0x49,0x7d,0x22,0x09,0x68,0x12,0x02,0x91,0x42,0x02,0xd3,
0x8a,0x1a,0x01,0x23,0x00,0xe0,0x52,0x1a,0x06,0x46,0x56,0x43,0xf2,0x13,0x51,0x43,
0x71,0x1a,0x1e,0x26,0x4e,0x43,0x4f,0x10,0xf6,0x19,0x8f,0x11,0xf6,0x19,0x49,0x12,
0x71,0x18,0xce,0x13,0x00,0x2b,0x01,0xd0,0x80,0x1a,0x00,0xe0,0x10,0x18,0x42,0x19,
0x91,0x08,0x8d,0x00,0x52,0x1b,0x00,0x2b,0x04,0xd0,0x43,0x01,0x18,0x1a,0x40,0x18,
0x80,0x1b,0x03,0xe0,0x43,0x01,0x18,0x1a,0x40,0x18,0x80,0x19,0x22,0x61,0xf0,0xbc,
0x70,0x47,0x00,0x00,0x00,0x6e,0x00,0x20,0x58,0x68,0x00,0x20,0x10,0xb4,0x00,0x23,
0x14,0x21,0x02,0x46,0x4a,0x43,0x11,0x49,0x7d,0x24,0x09,0x68,0x24,0x02,0xa1,0x42,
0x02,0xd9,0x09,0x1b,0x01,0x23,0x00,0xe0,0x61,0x1a,0x48,0x43,0x81,0x00,0x41,0x18,
0x88,0x0a,0x0c,0x0c,0x00,0x19,0x4c,0x0c,0x00,0x19,0x4c,0x0d,0x00,0x19,0x4c,0x0e,
0x00,0x19,0xc9,0x0f,0x40,0x18,0xc0,0x08,0x00,0x2b,0x01,0xd0,0x10,0x18,0x01,0xe0,
0x10,0x1a,0x40,0x1e,0x40,0x1e,0x10,0xbc,0x70,0x47,0x00,0x00,0x58,0x68,0x00,0x20
}
};
am_hal_ble_patch_t am_ble_buffer_patch_b0 =
{
.ui32Type = 0xCC,
.ui32Length = 0x0230,
.ui32CRC = 0x320c,
.pui32Data = am_ble_buffer_patch_data_b0.words,
};
//*****************************************************************************
//
// Patch Name: Function PATCH v0.4 for Apollo3 B0
// Reduce duration from TX to TX
// Optimized 32K XO frequency calculation
// Optimized AGC Table
// Fixed Channelmap indication rejected issue
// Fixed 800M Spur
// Fixed feature issue
// Date: 2019-05-15
//*****************************************************************************
am_hal_ble_buffer(0x00c2) am_ble_buffer_nvds_data_b0 =
{
.bytes =
{
0x4e,0x56,0x44,0x53, //NVDS_MAGIC_NUMBER
0x01,0x06,0x06,0xef,0xbb,0x23,0x88,0x77,0x66, //bluetooth address
0x02,0x06,0x0a,0x4e,0x5a,0x38,0x38,0x30,0x31,0x56,0x31,0x41,0x00, //device name
0x03,0x06,0x01,0x00, //system clock frequency, 00=32MHz 01=24MHz others=16MHz
0x07,0x06,0x02,0x00,0x00, //32K clock drift, 0x01f4 = 500 ppm
0x0c,0x06,0x02,50,0x00, //sleep clock accuracy in ppm, 0x01f4 = 500 ppm
0x08,0x06,0x01,0x00, //01 for BQB qualification, 00 for normal usage
0x09,0x06,0x01,0x02, //clock source selection, 00 = internal RC32KHz, 02= use Apollo3 MCU 32.768KHz
0x0a,0x06,0x04,0x00,0x00,0x00,0x00, //0x00000000 = auto detect and low frequency clock calibration
0x0b,0x06,0x01,0x96, //rx_ifs 0x96 = 150us
0x23,0x06,0x01,0x95, //tx_ifs 0x95 = 149us
0x0d,0x06,0x02,0xe8,0x3, //duration allowed for XO32M stabilization from external wakeup
0x0e,0x06,0x02,0xe8,0x3, //duration allowed for XO32M stabilization from internal wakeup signal
0x0f,0x06,0x02,0x2c,0x01, //duration allowed for radio to leave low power mode
0x10,0x06,0x04,0x00,0xc2,0x01,0x00, //set UART_BAUDRATE
0x11,0x06,0x01,0x01, //sleep algorithm enabled
// 0x11,0x06,0x01,0x00, //sleep algorithm disabled
0x12,0x06,0x01,0x01, //external wake-up support
0x13,0x06,0x02,0xf4,0x01, //duration of sleep and wake-up algorithm
0x14,0x06,0x02,0x60,0x00, //BLE Company ID
0x15,0x06,0x01,0x08, //BLE major version
0x16,0x06,0x01,0x03, //BLE minor version
0x17,0x06,0x01,0x29, //BLE SW version build
0x18,0x06,0x02,0xdc,0x05, //advertising interval (undirect)
0x19,0x06,0x02,0xe2,0x04, //advertising interval (direct)
0x20,0x06,0x01,0x01, //agc switch on
0x21,0x06,0x01,0x02, //EA programming latency,set '2' with master mode
0x22,0x06,0x01,0x00, //EA asap latency
0x24,0x06,0x04,0x5C,0x09,0x6A,0x09, //radio TRX timing
0x25,0x06,0x01,0x11, //modem polarity setting
0x26,0x06,0x01,0x00, //modem sync setting
0x27,0x06,0x01,0x02, //BLE reset delay
0x2d,0x06,0x01,0x00, //2 byte mode switch, 01 to enable
0x28,0x06,0x02,0xf6,0x2d, //initial agc gain setting
0x29,0x06,0x01,0x0f, //initial Tx output power, 0x0f is +4dBm
0x35,0x06,0x01,0x08, //maximum Tx ouput power setting
0x37,0x06,0x01,0x00, //RC32K calibration control, 0xAA to enable
0x05,0x06,0x02,0x34,0x00, //no use
0x04,0x06,0x01,0x20, //internal dvdd voltage level control if using 0.9V from MCU side
0x2e,0x06,0x01,0x00, //instant indication,set "0" to disbale instant reject
0x00,0x00,0x00,0x00 //dummy
}
};
am_hal_ble_patch_t am_ble_nvds_patch_b0 =
{
.ui32Type = 0xDD,
.ui32Length = 0x00c2,
.ui32CRC = 0x112b,
.pui32Data = am_ble_buffer_nvds_data_b0.words,
};
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,105 @@
//*****************************************************************************
//
//! @file am_hal_ble_patch_b0.h
//!
//! @brief This is a binary patch for the BLE core.
//!
//! @addtogroup
//! @ingroup
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_BLE_PATCH_B0_H
#define AM_HAL_BLE_PATCH_B0_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Patch array pointer.
//
//*****************************************************************************
extern am_hal_ble_patch_t **am_hal_ble_default_patches_b0;
extern am_hal_ble_patch_t **am_hal_ble_default_copy_patches_b0;
extern const uint32_t am_hal_ble_num_default_patches_b0;
//*****************************************************************************
//
// Pointers for specific patches.
//
//*****************************************************************************
extern am_hal_ble_patch_t am_ble_performance_patch_b0;
extern am_hal_ble_patch_t am_ble_nvds_patch_b0;
//*****************************************************************************
//
// Default patch structure.
//
//*****************************************************************************
extern am_hal_ble_patch_t g_AMBLEDefaultPatchB0;
//*****************************************************************************
//
// Macros for accessing specific NVDS parameters.
//
//*****************************************************************************
#define AM_HAL_BLE_NVDS_CLOCKDRIFT_OFFSET 30
#define AM_HAL_BLE_NVDS_SLEEPCLOCKDRIFT_OFFSET 35
#define AM_HAL_BLE_NVDS_CLOCKSOURCE_OFFSET 44
#define AM_HAL_BLE_NVDS_SLEEPENABLE_OFFSET 85
#define AM_HAL_BLE_NVDS_AGC_OFFSET 125
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_BLE_PATCH_B0_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,281 @@
//*****************************************************************************
//
// am_hal_burst.c
//! @file
//!
//! @brief Functions for controlling Burst Mode operation.
//!
//! @addtogroup burstmode3
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//
// Globals.
//
bool g_am_hal_burst_mode_available = false;
// ****************************************************************************
//
// am_hal_burst_mode_initialize()
// Burst mode initialization function
//
// ****************************************************************************
uint32_t
am_hal_burst_mode_initialize(am_hal_burst_avail_e *peBurstAvail)
{
uint32_t ui32Status;
//
// Check if the Burst Mode feature is available based on the SKU.
//
if ( 0 == MCUCTRL->SKU_b.ALLOWBURST )
{
//
// Burst mode is not available.
//
g_am_hal_burst_mode_available = false;
*peBurstAvail = AM_HAL_BURST_NOTAVAIL;
return AM_HAL_STATUS_INVALID_OPERATION;
}
//
// Enable the Burst Feature Event (DEVPWREVENTEN).
//
PWRCTRL->DEVPWREVENTEN_b.BURSTEVEN = 1;
//
// BLE buck is shared by Burst as well
// Enable the BLE buck trim values if in use
//
if (PWRCTRL->SUPPLYSRC_b.BLEBUCKEN)
{
am_hal_pwrctrl_blebuck_trim();
}
//
// Enable the Burst Functionality (FEATUREENABLE).
//
MCUCTRL->FEATUREENABLE_b.BURSTREQ = 1;
ui32Status = am_hal_flash_delay_status_check(10000,
(uint32_t)&MCUCTRL->FEATUREENABLE,
MCUCTRL_FEATUREENABLE_BURSTACK_Msk,
MCUCTRL_FEATUREENABLE_BURSTACK_Msk,
true);
if ( ui32Status != AM_HAL_STATUS_SUCCESS )
{
g_am_hal_burst_mode_available = false;
*peBurstAvail = AM_HAL_BURST_NOTAVAIL;
return ui32Status;
}
if ( 0 == MCUCTRL->FEATUREENABLE_b.BURSTAVAIL )
{
//
// Burst mode is not available.
//
g_am_hal_burst_mode_available = false;
*peBurstAvail = AM_HAL_BURST_NOTAVAIL;
return AM_HAL_STATUS_INVALID_OPERATION;
}
//
// Check the ACK for the Burst Functionality.
//
if ( MCUCTRL->FEATUREENABLE_b.BURSTACK == 0 )
{
//
// If NACK, return status.
//
g_am_hal_burst_mode_available = false;
*peBurstAvail = AM_HAL_BURST_NOTAVAIL;
return AM_HAL_STATUS_INVALID_OPERATION;
}
//
// Return Availability
//
g_am_hal_burst_mode_available = true;
*peBurstAvail = AM_HAL_BURST_AVAIL;
return AM_HAL_STATUS_SUCCESS;
}
// ****************************************************************************
//
// am_hal_burst_mode_enable()
// Burst mode enable function
//
// ****************************************************************************
uint32_t
am_hal_burst_mode_enable(am_hal_burst_mode_e *peBurstStatus)
{
uint32_t ui32Status;
//
// Check if Burst Mode is allowed and return status if it is not.
//
if (!g_am_hal_burst_mode_available)
{
*peBurstStatus = AM_HAL_NORMAL_MODE;
return AM_HAL_STATUS_INVALID_OPERATION;
}
//
// Request Burst Mode Enable (FREQCTRL)
//
CLKGEN->FREQCTRL_b.BURSTREQ = CLKGEN_FREQCTRL_BURSTREQ_EN;
// while (0 == AM_BFR(CLKGEN, FREQCTRL, BURSTACK));
ui32Status = am_hal_flash_delay_status_check(10000,
(uint32_t)&CLKGEN->FREQCTRL,
CLKGEN_FREQCTRL_BURSTSTATUS_Msk,
CLKGEN_FREQCTRL_BURSTSTATUS_Msk,
true);
if ( ui32Status != AM_HAL_STATUS_SUCCESS )
{
*peBurstStatus = AM_HAL_NORMAL_MODE;
return ui32Status;
}
//
// Check that the Burst Request was ACK'd.
//
if ( 0 == CLKGEN->FREQCTRL_b.BURSTACK )
{
*peBurstStatus = AM_HAL_NORMAL_MODE;
return AM_HAL_STATUS_FAIL;
}
//
// Check the Burst Mode Status (FREQCTRL)
//
if ( CLKGEN->FREQCTRL_b.BURSTSTATUS > 0)
{
*peBurstStatus = AM_HAL_BURST_MODE;
}
else
{
*peBurstStatus = AM_HAL_NORMAL_MODE;
}
return AM_HAL_STATUS_SUCCESS;
}
// ****************************************************************************
//
// am_hal_burst_mode_disable()
// Burst mode disable function
//
// ****************************************************************************
uint32_t
am_hal_burst_mode_disable(am_hal_burst_mode_e *peBurstStatus)
{
uint32_t ui32Status;
//
// Request Burst Mode Enable (FREQCTRL)
//
//
// Safely disable burst mode.
//
AM_CRITICAL_BEGIN
am_hal_flash_store_ui32((uint32_t*)&CLKGEN->FREQCTRL, CLKGEN_FREQCTRL_BURSTREQ_DIS);
AM_CRITICAL_END
//
// Disable the Burst Feature Event (DEVPWREVENTEN).
//
PWRCTRL->DEVPWREVENTEN_b.BURSTEVEN = 0;
ui32Status = am_hal_flash_delay_status_check(10000,
(uint32_t)&CLKGEN->FREQCTRL,
CLKGEN_FREQCTRL_BURSTSTATUS_Msk,
0,
true);
if ( ui32Status != AM_HAL_STATUS_SUCCESS )
{
*peBurstStatus = AM_HAL_NORMAL_MODE;
return ui32Status;
}
//
// Check the Burst Mode Status (FREQCTRL)
//
//
// Check the Burst Mode Status (FREQCTRL)
//
if ( CLKGEN->FREQCTRL_b.BURSTSTATUS > 0 )
{
*peBurstStatus = AM_HAL_BURST_MODE;
}
else
{
*peBurstStatus = AM_HAL_NORMAL_MODE;
}
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// am_hal_burst_mode_status() - Return current burst mode state.
//
// Implemented as a macro, this function returns the current burst mode state.
// AM_HAL_BURST_MODE
// AM_HAL_NORMAL_MODE
//
//*****************************************************************************
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,148 @@
//*****************************************************************************
//
// am_hal_burst.h
//! @file
//!
//! @brief Functions for controlling Burst Mode operation.
//!
//! @addtogroup burstmode3
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_BURST_H
#define AM_HAL_BURST_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Burst Mode Status enums
//
//*****************************************************************************
//
// Avail - the result of a feature availability interrogation.
//
typedef enum
{
AM_HAL_BURST_AVAIL,
AM_HAL_BURST_NOTAVAIL
} am_hal_burst_avail_e;
//
// Mode - the result of a change request.
//
typedef enum
{
AM_HAL_BURST_MODE,
AM_HAL_NORMAL_MODE,
} am_hal_burst_mode_e;
//*****************************************************************************
//
//! @brief Burst mode initialization function
//!
//! @param peBurstAvail - Availibility of feature
//!
//! This function initializes the Apollo3 MCU for Burst Mode operation. It does
//! not set the MCU into Burst Mode. This should be called once at system
//! initialization if Burst Mode is going to be used in the system.
//!
//! @return status of API call.
//
//*****************************************************************************
extern uint32_t am_hal_burst_mode_initialize(am_hal_burst_avail_e *peBurstAvail);
//*****************************************************************************
//
//! @brief Burst mode enable function
//!
//! @param peBurstStatus - resulting mode after call.
//!
//! This function enables the Apollo3 MCU into Burst Mode operation.
//!
//! @return status of API call.
//
//*****************************************************************************
extern uint32_t am_hal_burst_mode_enable(am_hal_burst_mode_e *peBurstStatus);
//*****************************************************************************
//
//! @brief Burst mode disable function
//!
//! @param peBurstStatus - resulting mode after call.
//!
//! This function disables the Apollo3 MCU from Burst Mode operation. It returns
//! the MCU to Normal Mode.
//!
//! @return status of API call.
//
//*****************************************************************************
extern uint32_t am_hal_burst_mode_disable(am_hal_burst_mode_e *peBurstStatus);
//*****************************************************************************
//
//! @brief Return current burst mode state
//!
//! Implemented as a macro, this function returns the current burst mode state.
//! AM_HAL_BURST_MODE
//! AM_HAL_NORMAL_MODE
//
//*****************************************************************************
#define am_hal_burst_mode_status() \
(CLKGEN->FREQCTRL_b.BURSTSTATUS ? AM_HAL_BURST_MODE : AM_HAL_NORMAL_MODE)
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_BURST_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,459 @@
//*****************************************************************************
//
// am_hal_cachectrl.c
//! @file
//!
//! @brief Functions for interfacing with the CACHE controller.
//!
//! @addtogroup cachectrl3 Cache Control (CACHE)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Default settings for the cache.
//
//*****************************************************************************
const am_hal_cachectrl_config_t am_hal_cachectrl_defaults =
{
.bLRU = 0,
.eDescript = AM_HAL_CACHECTRL_DESCR_1WAY_128B_1024E,
.eMode = AM_HAL_CACHECTRL_CONFIG_MODE_INSTR_DATA,
};
//*****************************************************************************
//
// Configure the cache with given and recommended settings, but do not enable.
//
//*****************************************************************************
uint32_t
am_hal_cachectrl_config(const am_hal_cachectrl_config_t *psConfig)
{
//
// In the case where cache is currently enabled, we need to gracefully
// bow out of that configuration before reconfiguring. The best way to
// accomplish that is to shut down the ID bits, leaving the cache enabled.
// Once the instr and data caches have been disabled, we can safely set
// any new configuration, including disabling the controller.
//
AM_CRITICAL_BEGIN
CACHECTRL->CACHECFG &=
~(CACHECTRL_CACHECFG_DCACHE_ENABLE_Msk |
CACHECTRL_CACHECFG_ICACHE_ENABLE_Msk);
AM_CRITICAL_END
CACHECTRL->CACHECFG =
_VAL2FLD(CACHECTRL_CACHECFG_ENABLE, 0) |
_VAL2FLD(CACHECTRL_CACHECFG_CACHE_CLKGATE, 1) |
_VAL2FLD(CACHECTRL_CACHECFG_CACHE_LS, 0) |
_VAL2FLD(CACHECTRL_CACHECFG_DATA_CLKGATE, 1) |
_VAL2FLD(CACHECTRL_CACHECFG_ENABLE_MONITOR, 0) |
_VAL2FLD(CACHECTRL_CACHECFG_LRU, psConfig->bLRU) |
_VAL2FLD(CACHECTRL_CACHECFG_CONFIG, psConfig->eDescript) |
((psConfig->eMode << CACHECTRL_CACHECFG_ICACHE_ENABLE_Pos) &
(CACHECTRL_CACHECFG_DCACHE_ENABLE_Msk |
CACHECTRL_CACHECFG_ICACHE_ENABLE_Msk));
return AM_HAL_STATUS_SUCCESS;
} // am_hal_cachectrl_config()
//*****************************************************************************
//
// Enable the cache.
//
//*****************************************************************************
uint32_t
am_hal_cachectrl_enable(void)
{
//
// Enable the cache
//
CACHECTRL->CACHECFG |= _VAL2FLD(CACHECTRL_CACHECFG_ENABLE, 1);
return AM_HAL_STATUS_SUCCESS;
} // am_hal_cachectrl_enable()
//*****************************************************************************
//
// Disable the cache.
//
//*****************************************************************************
uint32_t
am_hal_cachectrl_disable(void)
{
//
// Shut down as gracefully as possible.
// Disable the I/D cache enable bits first to allow a little time
// for any in-flight transactions to hand off to the line buffer.
// Then clear the enable.
//
AM_CRITICAL_BEGIN
CACHECTRL->CACHECFG &= ~(_VAL2FLD(CACHECTRL_CACHECFG_ICACHE_ENABLE, 1) |
_VAL2FLD(CACHECTRL_CACHECFG_DCACHE_ENABLE, 1));
CACHECTRL->CACHECFG &= ~_VAL2FLD(CACHECTRL_CACHECFG_ENABLE, 1);
AM_CRITICAL_END
return AM_HAL_STATUS_SUCCESS;
} // am_hal_cachectrl_disable()
//*****************************************************************************
//
// Control helper functions.
//
//*****************************************************************************
static bool
set_LPMMODE(uint32_t ui32value)
{
uint32_t ui32Val;
uint32_t *pui32RegAddr;
if ( ui32value > (CACHECTRL_FLASHCFG_LPMMODE_Msk >> CACHECTRL_FLASHCFG_LPMMODE_Pos) )
{
return false;
}
//
// Compute register address (assumes each reg is 1 word offset).
//
pui32RegAddr = (uint32_t*)&CACHECTRL->FLASHCFG;
AM_CRITICAL_BEGIN
ui32Val = am_hal_flash_load_ui32(pui32RegAddr);
ui32Val &= ~(CACHECTRL_FLASHCFG_LPMMODE_Msk |
CACHECTRL_FLASHCFG_LPM_RD_WAIT_Msk);
ui32Val |= _VAL2FLD(CACHECTRL_FLASHCFG_LPMMODE, ui32value) |
_VAL2FLD(CACHECTRL_FLASHCFG_LPM_RD_WAIT, 0x7);
am_hal_flash_store_ui32(pui32RegAddr, ui32Val);
AM_CRITICAL_END
return true;
} // set_LPMMODE()
static bool
set_SEDELAY(uint32_t ui32value)
{
uint32_t ui32Val;
uint32_t *pui32RegAddr;
if ( ui32value > (CACHECTRL_FLASHCFG_SEDELAY_Msk >> CACHECTRL_FLASHCFG_SEDELAY_Pos) )
{
return false;
}
//
// Compute register address (assumes each reg is 1 word offset).
//
pui32RegAddr = (uint32_t*)&CACHECTRL->FLASHCFG;
AM_CRITICAL_BEGIN
ui32Val = am_hal_flash_load_ui32(pui32RegAddr);
ui32Val &= ~(CACHECTRL_FLASHCFG_SEDELAY_Msk |
CACHECTRL_FLASHCFG_LPM_RD_WAIT_Msk);
ui32Val |= _VAL2FLD(CACHECTRL_FLASHCFG_SEDELAY, ui32value) |
_VAL2FLD(CACHECTRL_FLASHCFG_LPM_RD_WAIT, 0x7);
am_hal_flash_store_ui32(pui32RegAddr, ui32Val);
AM_CRITICAL_END
return true;
} // set_SEDELAY()
static bool
set_RDWAIT(uint32_t ui32value)
{
uint32_t ui32Val;
uint32_t *pui32RegAddr;
if ( ui32value > (CACHECTRL_FLASHCFG_RD_WAIT_Msk >> CACHECTRL_FLASHCFG_RD_WAIT_Pos) )
{
return false;
}
//
// Compute register address (assumes each reg is 1 word offset).
//
pui32RegAddr = (uint32_t*)&CACHECTRL->FLASHCFG;
AM_CRITICAL_BEGIN
ui32Val = am_hal_flash_load_ui32(pui32RegAddr);
ui32Val &= ~(CACHECTRL_FLASHCFG_RD_WAIT_Msk |
CACHECTRL_FLASHCFG_LPM_RD_WAIT_Msk);
ui32Val |= _VAL2FLD(CACHECTRL_FLASHCFG_RD_WAIT, ui32value) |
_VAL2FLD(CACHECTRL_FLASHCFG_LPM_RD_WAIT, 0x7);
am_hal_flash_store_ui32(pui32RegAddr, ui32Val);
AM_CRITICAL_END
return true;
} // set_RDWAIT()
//*****************************************************************************
//
// Select the cache configuration type.
//
//*****************************************************************************
uint32_t
am_hal_cachectrl_control(am_hal_cachectrl_control_e eControl, void *pArgs)
{
uint32_t ui32Arg;
uint32_t ui32SetMask = 0;
switch ( eControl )
{
case AM_HAL_CACHECTRL_CONTROL_FLASH_CACHE_INVALIDATE:
ui32SetMask = CACHECTRL_CTRL_INVALIDATE_Msk;
break;
case AM_HAL_CACHECTRL_CONTROL_STATISTICS_RESET:
if ( !_FLD2VAL(CACHECTRL_CACHECFG_ENABLE_MONITOR, CACHECTRL->CACHECFG) )
{
//
// The monitor must be enabled for the reset to have any affect.
//
return AM_HAL_STATUS_INVALID_OPERATION;
}
else
{
ui32SetMask = CACHECTRL_CTRL_RESET_STAT_Msk;
}
break;
case AM_HAL_CACHECTRL_CONTROL_FLASH_ALL_SLEEP_ENABLE:
ui32SetMask = CACHECTRL_CTRL_FLASH0_SLM_ENABLE_Msk |
CACHECTRL_CTRL_FLASH1_SLM_ENABLE_Msk;
break;
case AM_HAL_CACHECTRL_CONTROL_FLASH_ALL_SLEEP_DISABLE:
ui32SetMask = CACHECTRL_CTRL_FLASH0_SLM_DISABLE_Msk |
CACHECTRL_CTRL_FLASH1_SLM_DISABLE_Msk;
break;
case AM_HAL_CACHECTRL_CONTROL_FLASH0_SLEEP_ENABLE:
ui32SetMask = CACHECTRL_CTRL_FLASH0_SLM_ENABLE_Msk;
break;
case AM_HAL_CACHECTRL_CONTROL_FLASH0_SLEEP_DISABLE:
ui32SetMask = CACHECTRL_CTRL_FLASH0_SLM_DISABLE_Msk;
break;
case AM_HAL_CACHECTRL_CONTROL_FLASH1_SLEEP_ENABLE:
ui32SetMask = CACHECTRL_CTRL_FLASH1_SLM_ENABLE_Msk;
break;
case AM_HAL_CACHECTRL_CONTROL_FLASH1_SLEEP_DISABLE:
ui32SetMask = CACHECTRL_CTRL_FLASH1_SLM_DISABLE_Msk;
break;
case AM_HAL_CACHECTRL_CONTROL_MONITOR_ENABLE:
ui32SetMask = 0;
AM_CRITICAL_BEGIN
CACHECTRL->CACHECFG |= CACHECTRL_CACHECFG_ENABLE_MONITOR_Msk;
AM_CRITICAL_END
break;
case AM_HAL_CACHECTRL_CONTROL_MONITOR_DISABLE:
ui32SetMask = 0;
AM_CRITICAL_BEGIN
CACHECTRL->CACHECFG &= ~CACHECTRL_CACHECFG_ENABLE_MONITOR_Msk;
AM_CRITICAL_END
break;
case AM_HAL_CACHECTRL_CONTROL_LPMMODE_RESET:
//
// Safely set the reset values for LPMMODE, SEDELAY, and RDWAIT.
//
if ( !set_LPMMODE(AM_HAL_CACHECTRL_FLASHCFG_LPMMODE_NEVER) ||
!set_SEDELAY(0x7) ||
!set_RDWAIT(0x3) )
{
return AM_HAL_STATUS_FAIL;
}
break;
case AM_HAL_CACHECTRL_CONTROL_LPMMODE_RECOMMENDED:
//
// Safely set the as recommended values (from the datasheet)
// for LPMMODE, SEDELAY, and RDWAIT.
//
if ( !set_LPMMODE(AM_HAL_CACHECTRL_FLASHCFG_LPMMODE_STANDBY) ||
!set_SEDELAY(0x5) ||
!set_RDWAIT(0x1) )
{
return AM_HAL_STATUS_FAIL;
}
break;
case AM_HAL_CACHECTRL_CONTROL_LPMMODE_AGGRESSIVE:
//
// Safely set aggressive values for LPMMODE, SEDELAY, and RDWAIT.
// (For now select recommended values.)
//
if ( !set_LPMMODE(AM_HAL_CACHECTRL_FLASHCFG_LPMMODE_STANDBY) ||
!set_SEDELAY(0x6) ||
!set_RDWAIT(0x1) )
{
return AM_HAL_STATUS_FAIL;
}
break;
case AM_HAL_CACHECTRL_CONTROL_LPMMODE_SET:
//
// Safely set LPMMODE, SEDELAY, or RDWAIT.
// The new value is passed by reference via pArgs. That is, pArgs is
// assumed to be a pointer to a uint32_t of the new value.
//
if ( !pArgs )
{
return AM_HAL_STATUS_INVALID_ARG;
}
ui32Arg = *(uint32_t*)pArgs;
if ( !set_LPMMODE(ui32Arg) )
{
return AM_HAL_STATUS_FAIL;
}
break;
case AM_HAL_CACHECTRL_CONTROL_SEDELAY_SET:
if ( !pArgs )
{
return AM_HAL_STATUS_INVALID_ARG;
}
ui32Arg = *(uint32_t*)pArgs;
if ( !set_SEDELAY(ui32Arg) )
{
return AM_HAL_STATUS_FAIL;
}
break;
case AM_HAL_CACHECTRL_CONTROL_RDWAIT_SET:
if ( !pArgs )
{
return AM_HAL_STATUS_INVALID_ARG;
}
ui32Arg = *(uint32_t*)pArgs;
if ( !set_RDWAIT(ui32Arg) )
{
return AM_HAL_STATUS_FAIL;
}
break;
case AM_HAL_CACHECTRL_CONTROL_NC_CFG:
{
if ( pArgs == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
am_hal_cachectrl_nc_cfg_t *pNcCfg;
pNcCfg = (am_hal_cachectrl_nc_cfg_t *)pArgs;
#ifndef AM_HAL_DISABLE_API_VALIDATION
// Make sure the addresses are valid
if ((pNcCfg->ui32StartAddr & ~CACHECTRL_NCR0START_ADDR_Msk) ||
(pNcCfg->ui32EndAddr & ~CACHECTRL_NCR0START_ADDR_Msk))
{
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
if (pNcCfg->eNCRegion == AM_HAL_CACHECTRL_NCR0)
{
CACHECTRL->NCR0START = pNcCfg->ui32StartAddr;
CACHECTRL->NCR0END = pNcCfg->ui32EndAddr;
CACHECTRL->CACHECFG_b.ENABLE_NC0 = pNcCfg->bEnable;
}
else if (pNcCfg->eNCRegion == AM_HAL_CACHECTRL_NCR1)
{
CACHECTRL->NCR1START = pNcCfg->ui32StartAddr;
CACHECTRL->NCR1END = pNcCfg->ui32EndAddr;
CACHECTRL->CACHECFG_b.ENABLE_NC1 = pNcCfg->bEnable;
}
#ifndef AM_HAL_DISABLE_API_VALIDATION
else
{
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
return AM_HAL_STATUS_SUCCESS;
}
default:
return AM_HAL_STATUS_INVALID_ARG;
}
//
// All fields in the CACHECTRL register are write-only or read-only.
// A write to CACHECTRL acts as a mask-set. That is, only the bits
// written as '1' have an effect, any bits written as '0' are unaffected.
//
// Important note - setting of an enable and disable simultanously has
// unpredicable results.
//
if ( ui32SetMask )
{
CACHECTRL->CTRL = ui32SetMask;
}
return AM_HAL_STATUS_SUCCESS;
} // am_hal_cachectrl_control()
//*****************************************************************************
//
// Cache controller status function
//
//*****************************************************************************
uint32_t
am_hal_cachectrl_status_get(am_hal_cachectrl_status_t *psStatus)
{
uint32_t ui32Status;
if ( psStatus == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
ui32Status = CACHECTRL->CTRL;
psStatus->bFlash0SleepMode =
_FLD2VAL(CACHECTRL_CTRL_FLASH0_SLM_STATUS, ui32Status);
psStatus->bFlash1SleepMode =
_FLD2VAL(CACHECTRL_CTRL_FLASH1_SLM_STATUS, ui32Status);
psStatus->bCacheReady =
_FLD2VAL(CACHECTRL_CTRL_CACHE_READY, ui32Status);
return AM_HAL_STATUS_SUCCESS;
} // am_hal_cachectrl_status_get()
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,289 @@
// ****************************************************************************
//
// am_hal_cachectrl.h
//! @file
//!
//! @brief Functions for accessing and configuring the CACHE controller.
//!
//! @addtogroup cachectrl3 Cache Control (CACHE)
//! @ingroup apollo3hal
//! @{
//
// ****************************************************************************
// ****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
// ****************************************************************************
#ifndef AM_HAL_CACHECTRL_H
#define AM_HAL_CACHECTRL_H
#ifdef __cplusplus
extern "C"
{
#endif
//
// Designate this peripheral.
//
#define AM_APOLLO3_CACHECTRL 1
//
// Cachectrl status.
//
typedef struct
{
bool bFlash0SleepMode;
bool bFlash1SleepMode;
bool bCacheReady;
} am_hal_cachectrl_status_t;
// ****************************************************************************
//
//! @name Cache Config
//! @brief Configuration selection for the cache.
//!
//! These macros may be used in conjunction with the
//! am_hal_cachectrl_cache_config() function to select the cache type.
//!
//! @{
//
// ****************************************************************************
//
// Cache description type, where:
// nWay = number of ways (associativity)
// 128B = 128 bits linesize
// 512E = 512 entries, 1024E = 1024 entries
//
typedef enum
{
AM_HAL_CACHECTRL_DESCR_1WAY_128B_512E = CACHECTRL_CACHECFG_CONFIG_W1_128B_512E,
AM_HAL_CACHECTRL_DESCR_2WAY_128B_512E = CACHECTRL_CACHECFG_CONFIG_W2_128B_512E,
AM_HAL_CACHECTRL_DESCR_1WAY_128B_1024E = CACHECTRL_CACHECFG_CONFIG_W1_128B_1024E
} am_hal_cachectrl_descr_e;
typedef enum
{
AM_HAL_CACHECTRL_NCR0 = 0,
AM_HAL_CACHECTRL_NCR1 = 1
} am_hal_cachectrl_nc_region_e;
// Config struture for AM_HAL_CACHECTRL_CONTROL_NC_CFG
typedef struct
{
am_hal_cachectrl_nc_region_e eNCRegion;
bool bEnable;
uint32_t ui32StartAddr;
uint32_t ui32EndAddr;
} am_hal_cachectrl_nc_cfg_t;
//
// Control operations.
//
typedef enum
{
AM_HAL_CACHECTRL_CONTROL_FLASH_CACHE_INVALIDATE = 1,
AM_HAL_CACHECTRL_CONTROL_STATISTICS_RESET,
AM_HAL_CACHECTRL_CONTROL_FLASH_ALL_SLEEP_ENABLE,
AM_HAL_CACHECTRL_CONTROL_FLASH_ALL_SLEEP_DISABLE,
AM_HAL_CACHECTRL_CONTROL_FLASH0_SLEEP_ENABLE,
AM_HAL_CACHECTRL_CONTROL_FLASH0_SLEEP_DISABLE,
AM_HAL_CACHECTRL_CONTROL_FLASH1_SLEEP_ENABLE,
AM_HAL_CACHECTRL_CONTROL_FLASH1_SLEEP_DISABLE,
AM_HAL_CACHECTRL_CONTROL_MONITOR_ENABLE,
AM_HAL_CACHECTRL_CONTROL_MONITOR_DISABLE,
AM_HAL_CACHECTRL_CONTROL_LPMMODE_RESET,
AM_HAL_CACHECTRL_CONTROL_LPMMODE_RECOMMENDED,
AM_HAL_CACHECTRL_CONTROL_LPMMODE_AGGRESSIVE,
AM_HAL_CACHECTRL_CONTROL_LPMMODE_SET,
AM_HAL_CACHECTRL_CONTROL_SEDELAY_SET,
AM_HAL_CACHECTRL_CONTROL_RDWAIT_SET,
// Configure up to two non-cacheable regions
AM_HAL_CACHECTRL_CONTROL_NC_CFG,
} am_hal_cachectrl_control_e;
//
// Cache config values used for ui8Mode.
//
typedef enum
{
// Note - this enum ordering is critical, do not modify.
AM_HAL_CACHECTRL_CONFIG_MODE_DISABLE,
AM_HAL_CACHECTRL_CONFIG_MODE_INSTR,
AM_HAL_CACHECTRL_CONFIG_MODE_DATA,
AM_HAL_CACHECTRL_CONFIG_MODE_INSTR_DATA
} am_hal_cachectrl_config_mode_e;
//
// FLASHCFG LPMMODE.
//
typedef enum
{
AM_HAL_CACHECTRL_FLASHCFG_LPMMODE_NEVER = CACHECTRL_FLASHCFG_LPMMODE_NEVER,
AM_HAL_CACHECTRL_FLASHCFG_LPMMODE_STANDBY = CACHECTRL_FLASHCFG_LPMMODE_STANDBY,
AM_HAL_CACHECTRL_FLASHCFG_LPMMODE_ALWAYS = CACHECTRL_FLASHCFG_LPMMODE_ALWAYS
} am_hal_cachectrl_flashcfg_lppmode_e;
// ****************************************************************************
//
// Cache configuration structure
// This structure used for am_hal_cachectrl_config().
//
// ****************************************************************************
typedef struct
{
//
//! Set to one of:
//! AM_HAL_CACHECTRL_DESCR_1WAY_128B_512E
//! Direct mapped, 128-bit linesize, 512 entries (4 SRAMs active)
//! AM_HAL_CACHECTRL_DESCR_2WAY_128B_512E
//! Two way set associative, 128-bit linesize, 512 entries (8 SRAMs active)
//! AM_HAL_CACHECTRL_DESCR_1WAY_128B_1024E
//! Direct-mapped set associative, 128-bit linesize, 1024 entries (8 SRAMs active)
am_hal_cachectrl_descr_e eDescript;
//
//! Set to one of the following:
//! AM_HAL_CACHECTRL_CONFIG_MODE_DISABLE - Disable both instr and data caching
//! AM_HAL_CACHECTRL_CONFIG_MODE_INSTR - Enable instr caching only
//! AM_HAL_CACHECTRL_CONFIG_MODE_DATA - Enable data caching only
//! AM_HAL_CACHECTRL_CONFIG_MODE_INSTR_DATA - Enable both instr and data caching
am_hal_cachectrl_config_mode_e eMode;
//
//! Set to true to enable the LRU (least recently used) replacement policy.
//! Set to false to enable the LRR (least recently replaced) replacement policy.
//! Note - LRR minimizes writes to the TAG SRAM.
//
bool bLRU;
} am_hal_cachectrl_config_t;
extern const am_hal_cachectrl_config_t am_hal_cachectrl_defaults;
// ****************************************************************************
//
// Function prototypes
//
// ****************************************************************************
// ****************************************************************************
//
//! @brief Configure the cache using the supplied settings.
//!
//! @param psConfig - pointer to a config structure containing cache settings.
//!
//! This function takes in a structure of cache settings and uses them to
//! configure the cache. This function will configures all of the settings in
//! the structure as well as recommended settings for various other cache
//! configuration parameters.
//!
//! This function does NOT enable the cache, which is handled in a separate
//! function. In fact, if the cache is enabled prior to calling this function,
//! it will return from the call disabled.
//!
//! For most applications, the default cache settings will be the most
//! efficient choice. To use the default cache settings with this function, use
//! the address of the global am_hal_cachectrl_defaults structure as the
//! psConfig argument.
//!
//! @return Status.
//
// ****************************************************************************
extern uint32_t am_hal_cachectrl_config(const am_hal_cachectrl_config_t *psConfig);
// ****************************************************************************
//
//! @brief Enable the cache.
//!
//! Enable the cache for operation.
//!
//! @return Status.
//
// ****************************************************************************
extern uint32_t am_hal_cachectrl_enable(void);
// ****************************************************************************
//
//! @brief Disable the cache.
//!
//! Use this function to disable cache. Other configuration settings are not
//! not required.
//!
//! @return Status.
//
// ****************************************************************************
extern uint32_t am_hal_cachectrl_disable(void);
// ****************************************************************************
//
//! @brief Assert various specific controls on the cache.
//!
//! This function is used to apply various controls on the cache.
//!
//! @param eControl - One of the following:
//! AM_HAL_CACHECTRL_CONTROL_FLASH_CACHE_INVALIDATE
//! AM_HAL_CACHECTRL_CONTROL_STATISTICS_RESET
//! AM_HAL_CACHECTRL_CONTROL_FLASH_ALL_SLEEP_ENABLE,
//! AM_HAL_CACHECTRL_CONTROL_FLASH_ALL_SLEEP_DISABLE,
//! AM_HAL_CACHECTRL_CONTROL_FLASH0_SLEEP_ENABLE
//! AM_HAL_CACHECTRL_CONTROL_FLASH0_SLEEP_DISABLE
//! AM_HAL_CACHECTRL_CONTROL_FLASH1_SLEEP_ENABLE
//! AM_HAL_CACHECTRL_CONTROL_FLASH1_SLEEP_DISABLE
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_cachectrl_control(am_hal_cachectrl_control_e eControl,
void *pArgs);
// ****************************************************************************
//
//! @brief Cache controller status function
//!
//! This function returns the current status of the cache.
//!
//! @param psStatus - ptr to a status structure to receive the current statuses.
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_cachectrl_status_get(am_hal_cachectrl_status_t *psStatus);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_CACHECTRL_H
@@ -0,0 +1,410 @@
// ****************************************************************************
//
// am_hal_clkgen.c
//! @file
//!
//! @brief Functions for interfacing with the CLKGEN.
//!
//! @addtogroup clkgen3 Clock Generator (CLKGEN)
//! @ingroup apollo3hal
//! @{
//
// ****************************************************************************
// ****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
// ****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
// ****************************************************************************
//
// am_hal_clkgen_control()
// Apply various specific commands/controls on the CLKGEN module.
//
// ****************************************************************************
uint32_t
am_hal_clkgen_control(am_hal_clkgen_control_e eControl, void *pArgs)
{
uint32_t ui32Regval;
//
// Take a snapshot of the reset status, if not done already
//
if (!gAmHalResetStatus)
{
gAmHalResetStatus = RSTGEN->STAT;
}
switch ( eControl )
{
case AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX:
//
// Unlock the clock control register.
// Set the HFRC divisor to the required operating value.
// Lock the clock configuration registers.
//
CLKGEN->CLKKEY = CLKGEN_CLKKEY_CLKKEY_Key;
CLKGEN->CCTRL = CLKGEN_CCTRL_CORESEL_HFRC;
CLKGEN->CLKKEY = 0;
break;
case AM_HAL_CLKGEN_CONTROL_SYSCLK_DIV2:
CLKGEN->CLKKEY = CLKGEN_CLKKEY_CLKKEY_Key;
CLKGEN->CCTRL = CLKGEN_CCTRL_CORESEL_HFRC_DIV2;
CLKGEN->CLKKEY = 0;
break;
case AM_HAL_CLKGEN_CONTROL_LFRC_START:
CLKGEN->OCTRL_b.STOPRC = CLKGEN_OCTRL_STOPRC_EN;
break;
case AM_HAL_CLKGEN_CONTROL_XTAL_START:
CLKGEN->OCTRL_b.STOPXT = CLKGEN_OCTRL_STOPXT_EN;
break;
case AM_HAL_CLKGEN_CONTROL_LFRC_STOP:
CLKGEN->OCTRL_b.STOPRC = CLKGEN_OCTRL_STOPRC_STOP;
break;
case AM_HAL_CLKGEN_CONTROL_XTAL_STOP:
// Software Workaround to guarantee proper function of HFADJ.
if (APOLLO3_B0)
{
MCUCTRL->XTALCTRL_b.XTALICOMPTRIM = 1;
}
CLKGEN->OCTRL_b.STOPXT = CLKGEN_OCTRL_STOPXT_STOP;
break;
case AM_HAL_CLKGEN_CONTROL_RTC_SEL_LFRC:
CLKGEN->OCTRL_b.OSEL = CLKGEN_OCTRL_OSEL_RTC_LFRC;
break;
case AM_HAL_CLKGEN_CONTROL_RTC_SEL_XTAL:
CLKGEN->OCTRL_b.OSEL = CLKGEN_OCTRL_OSEL_RTC_XT;
break;
case AM_HAL_CLKGEN_CONTROL_HFADJ_ENABLE:
// Software Workaround to guarantee proper function of HFADJ.
if (APOLLO3_B0)
{
MCUCTRL->XTALCTRL_b.XTALICOMPTRIM = 3;
am_hal_flash_delay(FLASH_CYCLES_US(1000));
}
if ( pArgs == 0 )
{
ui32Regval =
_VAL2FLD(CLKGEN_HFADJ_HFADJGAIN, CLKGEN_HFADJ_HFADJGAIN_Gain_of_1_in_2) | /* Default value (Apollo3) */
_VAL2FLD(CLKGEN_HFADJ_HFWARMUP, CLKGEN_HFADJ_HFWARMUP_1SEC) | /* Default value */
_VAL2FLD(CLKGEN_HFADJ_HFXTADJ, 0x5B8) | /* Default value */
_VAL2FLD(CLKGEN_HFADJ_HFADJCK, CLKGEN_HFADJ_HFADJCK_4SEC) | /* Default value */
_VAL2FLD(CLKGEN_HFADJ_HFADJEN, CLKGEN_HFADJ_HFADJEN_EN);
}
else
{
ui32Regval = *(uint32_t*)pArgs;
}
//
// Make sure the ENABLE bit is set.
//
ui32Regval |= _VAL2FLD(CLKGEN_HFADJ_HFADJEN, CLKGEN_HFADJ_HFADJEN_EN);
CLKGEN->HFADJ = ui32Regval;
break;
case AM_HAL_CLKGEN_CONTROL_HFADJ_DISABLE:
CLKGEN->HFADJ_b.HFADJEN = 0;
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_control()
// ****************************************************************************
//
// am_hal_clkgen_status_get()
// This function returns the current value of various CLKGEN statuses.
//
// ****************************************************************************
uint32_t
am_hal_clkgen_status_get(am_hal_clkgen_status_t *psStatus)
{
uint32_t ui32Status;
if ( psStatus == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
psStatus->ui32SysclkFreq =
CLKGEN->CCTRL_b.CORESEL ?
AM_HAL_CLKGEN_FREQ_MAX_HZ / 2 :
AM_HAL_CLKGEN_FREQ_MAX_HZ;
ui32Status = CLKGEN->STATUS;
psStatus->eRTCOSC =
_FLD2VAL(CLKGEN_STATUS_OMODE, ui32Status) ?
AM_HAL_CLKGEN_STATUS_RTCOSC_LFRC :
AM_HAL_CLKGEN_STATUS_RTCOSC_XTAL;
psStatus->bXtalFailure =
_FLD2VAL(CLKGEN_STATUS_OSCF, ui32Status);
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_status_get()
// ****************************************************************************
//
// am_hal_clkgen_clkout_enable()
// This function is used to select and enable CLKOUT.
//
// ****************************************************************************
uint32_t
am_hal_clkgen_clkout_enable(bool bEnable, am_hal_clkgen_clkout_e eClkSelect)
{
if ( !bEnable )
{
CLKGEN->CLKOUT_b.CKEN = 0;
}
//
// Do a basic validation of the eClkSelect parameter.
// Not every value in the range is valid, but at least this simple check
// provides a reasonable chance that the parameter is valid.
//
if ( eClkSelect <= (am_hal_clkgen_clkout_e)CLKGEN_CLKOUT_CKSEL_LFRCNE )
{
//
// Are we actually changing the frequency?
//
if ( CLKGEN->CLKOUT_b.CKSEL != eClkSelect )
{
//
// Disable before changing the clock
//
CLKGEN->CLKOUT_b.CKEN = 0;
//
// Set the new clock select
//
CLKGEN->CLKOUT_b.CKSEL = eClkSelect;
}
//
// Enable/disable as requested.
//
CLKGEN->CLKOUT_b.CKEN = bEnable;
}
else
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_clkout_enable()
// ****************************************************************************
//
// am_hal_clkgen_interrupt_enable()
// Enable selected CLKGEN Interrupts.
//
// ****************************************************************************
uint32_t am_hal_clkgen_interrupt_enable(am_hal_clkgen_interrupt_e ui32IntMask)
{
if ( (ui32IntMask &
(CLKGEN_INTRPTEN_OF_Msk |
CLKGEN_INTRPTEN_ACC_Msk |
CLKGEN_INTRPTEN_ACF_Msk)) == 0 )
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Set the interrupt enables according to the mask.
//
CLKGEN->INTRPTEN |= ui32IntMask;
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_interrupt_enable()
// ****************************************************************************
//
// am_hal_clkgen_interrupt_disable(
// Disable selected CLKGEN Interrupts.
//
// ****************************************************************************
uint32_t
am_hal_clkgen_interrupt_disable(am_hal_clkgen_interrupt_e ui32IntMask)
{
if ( (ui32IntMask &
(CLKGEN_INTRPTEN_OF_Msk |
CLKGEN_INTRPTEN_ACC_Msk |
CLKGEN_INTRPTEN_ACF_Msk)) == 0 )
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Disable the interrupts.
//
CLKGEN->INTRPTEN &= ~ui32IntMask;
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_interrupt_disable()
//*****************************************************************************
//
// am_hal_clkgen_interrupt_clear()
// IOM interrupt clear
//
//*****************************************************************************
uint32_t
am_hal_clkgen_interrupt_clear(am_hal_clkgen_interrupt_e ui32IntMask)
{
if ( (ui32IntMask &
(CLKGEN_INTRPTEN_OF_Msk |
CLKGEN_INTRPTEN_ACC_Msk |
CLKGEN_INTRPTEN_ACF_Msk)) == 0 )
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Clear the requested interrupts.
//
CLKGEN->INTRPTCLR = ui32IntMask;
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_interrupt_clear()
// ****************************************************************************
//
// am_hal_clkgen_interrupt_status_get()
// Return CLKGEN interrupts.
//
// ****************************************************************************
uint32_t
am_hal_clkgen_interrupt_status_get(bool bEnabledOnly,
uint32_t *pui32IntStatus)
{
uint32_t ui32IntStatus;
if ( !pui32IntStatus )
{
return AM_HAL_STATUS_INVALID_ARG;
}
ui32IntStatus = CLKGEN->INTRPTSTAT;
if ( bEnabledOnly )
{
ui32IntStatus &= CLKGEN->INTRPTEN;
}
*pui32IntStatus = ui32IntStatus;
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_interrupt_status_get)
// ****************************************************************************
//
// This function sets the CLKGEN interrupts.
//
// ****************************************************************************
uint32_t
am_hal_clkgen_interrupt_set(am_hal_clkgen_interrupt_e ui32IntMask)
{
if ( (ui32IntMask &
(CLKGEN_INTRPTEN_OF_Msk |
CLKGEN_INTRPTEN_ACC_Msk |
CLKGEN_INTRPTEN_ACF_Msk)) == 0 )
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Set the interrupt status.
//
CLKGEN->INTRPTSET = ui32IntMask;
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_clkgen_interrupt_set()
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,366 @@
//*****************************************************************************
//
// am_hal_clkgen.h
//! @file
//!
//! @brief Functions for accessing and configuring the CLKGEN.
//!
//! @addtogroup clkgen3 Clock Generator (CLKGEN)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_CLKGEN_H
#define AM_HAL_CLKGEN_H
#ifdef __cplusplus
extern "C"
{
#endif
//
// Designate this peripheral.
//
#define AM_APOLLO3_CLKGEN 1
//*****************************************************************************
//
//! @name System Clock max frequency
//! @brief Defines the maximum clock frequency for this device.
//!
//! These macros provide a definition of the maximum clock frequency.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_CLKGEN_FREQ_MAX_HZ 48000000
#define AM_HAL_CLKGEN_FREQ_MAX_KHZ (AM_HAL_CLKGEN_FREQ_MAX_HZ / 1000)
#define AM_HAL_CLKGEN_FREQ_MAX_MHZ (AM_HAL_CLKGEN_FREQ_MAX_HZ / 1000000)
#define AM_HAL_CLKGEN_CORESEL_MAXDIV 1
//! @}
//
// Control operations.
//
typedef enum
{
AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX,
AM_HAL_CLKGEN_CONTROL_XTAL_START,
AM_HAL_CLKGEN_CONTROL_LFRC_START,
AM_HAL_CLKGEN_CONTROL_XTAL_STOP,
AM_HAL_CLKGEN_CONTROL_LFRC_STOP,
AM_HAL_CLKGEN_CONTROL_SYSCLK_DIV2,
AM_HAL_CLKGEN_CONTROL_RTC_SEL_XTAL,
AM_HAL_CLKGEN_CONTROL_RTC_SEL_LFRC,
AM_HAL_CLKGEN_CONTROL_HFADJ_ENABLE,
AM_HAL_CLKGEN_CONTROL_HFADJ_DISABLE,
} am_hal_clkgen_control_e;
//
// Current RTC oscillator.
//
typedef enum
{
AM_HAL_CLKGEN_STATUS_RTCOSC_XTAL,
AM_HAL_CLKGEN_STATUS_RTCOSC_LFRC,
} am_hal_clkgen_status_rtcosc_e;
//
// CLKOUT
//
typedef enum
{
AM_HAL_CLKGEN_CLKOUT_LFRC_1024 = 0x0, // LFRC
AM_HAL_CLKGEN_CLKOUT_XTAL_16384, // XTAL / 2
AM_HAL_CLKGEN_CLKOUT_XTAL_8192, // XTAL / 4
AM_HAL_CLKGEN_CLKOUT_XTAL_4096, // XTAL / 8
AM_HAL_CLKGEN_CLKOUT_XTAL_2048, // XTAL / 16
AM_HAL_CLKGEN_CLKOUT_XTAL_1024, // XTAL / 32
AM_HAL_CLKGEN_CLKOUT_RTC_1HZ = 0x10, // RTC
AM_HAL_CLKGEN_CLKOUT_XTAL_0_015 = 0x16, // XTAL / 2097152 = 0.015625 Hz
AM_HAL_CLKGEN_CLKOUT_XTAL_32768, // XTAL
AM_HAL_CLKGEN_CLKOUT_CG_100, // ClkGen 100Hz
AM_HAL_CLKGEN_CLKOUT_LFRC_512 = 0x23, // LFRC / 2 = 512 Hz
AM_HAL_CLKGEN_CLKOUT_LFRC_32, // LFRC / 32 = 32 Hz
AM_HAL_CLKGEN_CLKOUT_LFRC_2, // LFRC / 512 = 2 Hz
AM_HAL_CLKGEN_CLKOUT_LFRC_0_03, // LFRC / 32768 = 0.03125 Hz
AM_HAL_CLKGEN_CLKOUT_XTAL_128, // XTAL / 256 = 128 Hz
AM_HAL_CLKGEN_CLKOUT_XTAL_4, // XTAL / 8192 = 4 Hz
AM_HAL_CLKGEN_CLKOUT_XTAL_0_5, // XTAL / 65536 = 0.5 Hz
// The next 5 are Uncalibrated LFRC
AM_HAL_CLKGEN_CLKOUT_ULFRC_64, // ULFRC / 16 = 64 Hz (uncal LFRC)
AM_HAL_CLKGEN_CLKOUT_ULFRC_8, // ULFRC / 128 = 8 Hz (uncal LFRC)
AM_HAL_CLKGEN_CLKOUT_ULFRC_1, // ULFRC / 1024 = 1 Hz (uncal LFRC)
AM_HAL_CLKGEN_CLKOUT_ULFRC_0_25, // ULFRC / 4096 = 0.25 Hz (uncal LFRC)
AM_HAL_CLKGEN_CLKOUT_ULFRC_0_0009, // ULFRC / 1M = 0.000976 Hz (uncal LFRC)
//
AM_HAL_CLKGEN_CLKOUT_LFRC_0_0004 = 0x31, // LFRC / 2M = 0.00048828125 Hz
// Following are Not Autoenabled ("NE")
AM_HAL_CLKGEN_CLKOUT_XTALNE_32768 = 0x35, // XTALNE / 1 = 32768 Hz
AM_HAL_CLKGEN_CLKOUT_XTALNE_2048, // XTALNE / 16 = 2048 Hz
AM_HAL_CLKGEN_CLKOUT_LFRCNE_32, // LFRCNE / 32 = 32 Hz
AM_HAL_CLKGEN_CLKOUT_LFRCNE_1024 = 0x39 // LFRCNE / 1 = 1024 Hz
} am_hal_clkgen_clkout_e;
//
// ClkGen Interrupts
//
typedef enum
{
AM_HAL_CLKGEN_INTERRUPT_OF = CLKGEN_INTRPTEN_OF_Msk,
AM_HAL_CLKGEN_INTERRUPT_ACC = CLKGEN_INTRPTEN_ACC_Msk,
AM_HAL_CLKGEN_INTERRUPT_ACF = CLKGEN_INTRPTEN_ACF_Msk
} am_hal_clkgen_interrupt_e;
//
// Status structure.
//
typedef struct
{
//
// ui32SysclkFreq
// Returns the current system clock frequency, in hertz.
//
uint32_t ui32SysclkFreq;
//
// ui32RTCoscillator
//
// Returns the current RTC oscillator as one of:
// AM_HAL_CLKGEN_STATUS_RTCOSC_LFRC
// AM_HAL_CLKGEN_STATUS_RTCOSC_XTAL
//
uint32_t eRTCOSC;
//
// bXtalFailure
// true = XTAL has failed (is enabled but not oscillating). Also if the
// LFRC is selected as the oscillator in OCTRL.OSEL.
//
bool bXtalFailure;
} am_hal_clkgen_status_t;
// ****************************************************************************
//
//! @brief Apply various specific commands/controls on the CLKGEN module.
//!
//! This function is used to apply various controls on CLKGEN.
//!
//! @note IMPORTANT! This function MUST be called very early in execution of
//! an application with the parameter AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX
//! in order to set Apollo3 to its required operating frequency.
//!
//! @param eControl - One of the following:
//! AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX
//! AM_HAL_CLKGEN_CONTROL_XTAL_START
//! AM_HAL_CLKGEN_CONTROL_LFRC_START
//! AM_HAL_CLKGEN_CONTROL_XTAL_STOP
//! AM_HAL_CLKGEN_CONTROL_LFRC_STOP
//! AM_HAL_CLKGEN_CONTROL_RTC_SEL_XTAL
//! AM_HAL_CLKGEN_CONTROL_RTC_SEL_LFRC
//! AM_HAL_CLKGEN_CONTROL_HFADJ_ENABLE
//! AM_HAL_CLKGEN_CONTROL_HFADJ_DISABLE
//!
//! @return status - generic or interface specific status.
//!
//! @note After starting the XTAL, a 2 second warm-up delay is required.
//
// ****************************************************************************
extern uint32_t am_hal_clkgen_control(am_hal_clkgen_control_e eControl,
void *pArgs);
// ****************************************************************************
//
//! @brief Get CLKGEN status.
//!
//! This function returns the current value of various CLKGEN statuses.
//!
//! @param psStatus - ptr to a status structure to receive the current statuses.
//!
//! @return status - generic or interface specific status.
//!
//! @note After selection of the RTC Oscillator, a 2 second delay is required
//! before the new oscillator takes effect. Therefore the CLKGEN.STATUS.OMODE
//! bit will not reflect the new status until after the 2s wait period.
//
// ****************************************************************************
extern uint32_t am_hal_clkgen_status_get(am_hal_clkgen_status_t *psStatus);
// ****************************************************************************
//
//! @brief Enable CLKOUT.
//!
//! This function is used to enable and select a CLKOUT frequency.
//!
//! @param bEnable: true to enable, false to disable.
//! @param eClkSelect - One of the following:
//! AM_HAL_CLKGEN_CLKOUT_LFRC_1024
//! AM_HAL_CLKGEN_CLKOUT_XTAL_16384
//! AM_HAL_CLKGEN_CLKOUT_XTAL_8192
//! AM_HAL_CLKGEN_CLKOUT_XTAL_4096
//! AM_HAL_CLKGEN_CLKOUT_XTAL_2048
//! AM_HAL_CLKGEN_CLKOUT_XTAL_1024
//! AM_HAL_CLKGEN_CLKOUT_RTC_1HZ
//! AM_HAL_CLKGEN_CLKOUT_XTAL_0_015
//! AM_HAL_CLKGEN_CLKOUT_XTAL_32768
//! AM_HAL_CLKGEN_CLKOUT_CG_100
//! AM_HAL_CLKGEN_CLKOUT_LFRC_512
//! AM_HAL_CLKGEN_CLKOUT_LFRC_32
//! AM_HAL_CLKGEN_CLKOUT_LFRC_2
//! AM_HAL_CLKGEN_CLKOUT_LFRC_0_03
//! AM_HAL_CLKGEN_CLKOUT_XTAL_128
//! AM_HAL_CLKGEN_CLKOUT_XTAL_4
//! AM_HAL_CLKGEN_CLKOUT_XTAL_0_5
//!
//! The next 5 are Uncalibrated LFRC
//! AM_HAL_CLKGEN_CLKOUT_ULFRC_64
//! AM_HAL_CLKGEN_CLKOUT_ULFRC_8
//! AM_HAL_CLKGEN_CLKOUT_ULFRC_1
//! AM_HAL_CLKGEN_CLKOUT_ULFRC_0_25
//! AM_HAL_CLKGEN_CLKOUT_ULFRC_0_0009
//!
//! AM_HAL_CLKGEN_CLKOUT_LFRC_0_0004
//!
//! Following are Not Autoenabled ("NE")
//! AM_HAL_CLKGEN_CLKOUT_XTALNE_32768
//! AM_HAL_CLKGEN_CLKOUT_XTALNE_2048
//! AM_HAL_CLKGEN_CLKOUT_LFRCNE_32
//! AM_HAL_CLKGEN_CLKOUT_LFRCNE_1024
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_clkgen_clkout_enable(bool bEnable,
am_hal_clkgen_clkout_e eClkSelect);
// ****************************************************************************
//
//! @brief Enable selected CLKGEN Interrupts.
//!
//! Use this function to enable the interrupts.
//!
//! @param ui32IntMask - One or more of the following bitmasks.
//! AM_HAL_CLKGEN_INTERRUPT_OF
//! AM_HAL_CLKGEN_INTERRUPT_ACC
//! AM_HAL_CLKGEN_INTERRUPT_ACF
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_clkgen_interrupt_enable(am_hal_clkgen_interrupt_e ui32IntMask);
// ****************************************************************************
//
//! @brief Disable selected CLKGEN Interrupts.
//!
//! Use this function to disable the CLKGEN interrupts.
//!
//! @param ui32IntMask - One or more of the following bitmasks.
//! AM_HAL_CLKGEN_INTERRUPT_OF
//! AM_HAL_CLKGEN_INTERRUPT_ACC
//! AM_HAL_CLKGEN_INTERRUPT_ACF
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_clkgen_interrupt_disable(am_hal_clkgen_interrupt_e ui32IntMask);
//*****************************************************************************
//
//! @brief IOM interrupt clear
//!
//! @param ui32IntMask - interface specific interrupt mask.
//!
//! This function clears the interrupts for the given peripheral.
//!
//! The following are valid clear bits, any of which can be ORed together.
//! AM_HAL_CLKGEN_INTERRUPT_OF
//! AM_HAL_CLKGEN_INTERRUPT_ACC
//! AM_HAL_CLKGEN_INTERRUPT_ACF
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_clkgen_interrupt_clear(am_hal_clkgen_interrupt_e ui32IntMask);
// ****************************************************************************
//
//! @brief Return CLKGEN interrupts.
//!
//! Use this function to get all CLKGEN interrupts, or only the interrupts
//! that are enabled.
//!
//! @return All or only enabled CLKGEN interrupts.
//
// ****************************************************************************
extern uint32_t am_hal_clkgen_interrupt_status_get(bool bEnabledOnly,
uint32_t *pui32IntStatus);
// ****************************************************************************
//
//! @brief Sets the interrupt status.
//!
//! This function sets the CLKGEN interrupts.
//!
//! @param ui32IntMask - One or more of the following bitmasks.
//! AM_HAL_CLKGEN_INTERRUPT_OF
//! AM_HAL_CLKGEN_INTERRUPT_ACC
//! AM_HAL_CLKGEN_INTERRUPT_ACF
//!
//! @return None.
//
// ****************************************************************************
extern uint32_t am_hal_clkgen_interrupt_set(am_hal_clkgen_interrupt_e ui32IntMask);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_CLKGEN_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,847 @@
//*****************************************************************************
//
// am_hal_cmdq.c
//! @file
//!
//! @brief Functions for support command queue operations.
//!
//! @addtogroup
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
#define AM_HAL_MAGIC_CMDQ 0xCDCDCD
#define AM_HAL_CMDQ_CHK_HANDLE(h) ((h) && ((am_hal_handle_prefix_t *)(h))->s.bInit && (((am_hal_handle_prefix_t *)(h))->s.magic == AM_HAL_MAGIC_CMDQ))
// Make sure certain register assumptions are valid - else throw compile error
// Make sure the max HWIDX value is same for BLEIF, MSPI & IOM
// Make sure the CQCFG structure is same for BLEIF, MSPI & IOM
#if ((IOM0_CQCURIDX_CQCURIDX_Msk != MSPI_CQCURIDX_CQCURIDX_Msk) || \
(IOM0_CQCURIDX_CQCURIDX_Pos != MSPI_CQCURIDX_CQCURIDX_Pos) || \
(IOM0_CQCFG_CQEN_Pos != MSPI_CQCFG_CQEN_Pos) || \
(IOM0_CQCFG_CQEN_Msk != MSPI_CQCFG_CQEN_Msk) || \
(IOM0_CQCFG_CQPRI_Pos != MSPI_CQCFG_CQPRI_Pos) || \
(IOM0_CQCFG_CQPRI_Msk != MSPI_CQCFG_CQPRI_Msk) || \
(IOM0_CQCURIDX_CQCURIDX_Msk != BLEIF_CQCURIDX_CQCURIDX_Msk) || \
(IOM0_CQCURIDX_CQCURIDX_Pos != BLEIF_CQCURIDX_CQCURIDX_Pos) || \
(IOM0_CQCFG_CQEN_Pos != BLEIF_CQCFG_CQEN_Pos) || \
(IOM0_CQCFG_CQEN_Msk != BLEIF_CQCFG_CQEN_Msk) || \
(IOM0_CQCFG_CQPRI_Pos != BLEIF_CQCFG_CQPRI_Pos) || \
(IOM0_CQCFG_CQPRI_Msk != BLEIF_CQCFG_CQPRI_Msk) \
)
#error "MSPI and IOM HWIDX, CQCFG implementation needs to match for current CMDQ HAL implementation"
#endif
#define AM_HAL_CMDQ_HW_IDX_MAX (IOM0_CQCURIDX_CQCURIDX_Msk >> IOM0_CQCURIDX_CQCURIDX_Pos) // 8 bit value
#define AM_HAL_CMDQ_ENABLE_CQ(cfgReg) {AM_REGVAL((cfgReg)) |= _VAL2FLD(IOM0_CQCFG_CQEN, IOM0_CQCFG_CQEN_EN); }
#define AM_HAL_CMDQ_DISABLE_CQ(cfgReg) {AM_REGVAL((cfgReg)) &= ~_VAL2FLD(IOM0_CQCFG_CQEN, IOM0_CQCFG_CQEN_EN); }
#define AM_HAL_CMDQ_INIT_CQCFG(cfgReg, pri, enable) {AM_REGVAL((cfgReg)) = _VAL2FLD(IOM0_CQCFG_CQPRI, (pri)) | _VAL2FLD(IOM0_CQCFG_CQEN, (enable)); }
// Need to set the lsb of the CQ entry address for hardware to raise a CQUPD interrupt when processing this entry
#define AM_HAL_CMDQ_ENABLE_CQUPD_INT 0x1
typedef struct
{
volatile uint32_t* regCQCfg;
volatile uint32_t* regCQAddr;
volatile uint32_t* regCurIdx;
volatile uint32_t* regEndIdx;
volatile uint32_t* regCQPause;
uint32_t bitMaskCQPauseIdx;
volatile uint32_t* regCQStat;
// Different hardware blocks have different bit assignments for status flags
uint32_t bitMaskCQStatTIP;
uint32_t bitMaskCQStatErr;
uint32_t bitMaskCQStatPaused;
} am_hal_cmdq_registers_t;
typedef struct
{
am_hal_handle_prefix_t prefix;
uint32_t cmdQBufStart;
uint32_t cmdQBufEnd;
uint32_t cmdQHead;
uint32_t cmdQTail;
uint32_t cmdQNextTail;
uint32_t cmdQSize;
uint32_t curIdx;
uint32_t endIdx;
const am_hal_cmdq_registers_t *pReg;
uint32_t rawSeqStart;
} am_hal_cmdq_t;
// Global variables
static am_hal_cmdq_t gAmHalCmdq[AM_HAL_CMDQ_IF_MAX];
static const am_hal_cmdq_registers_t gAmHalCmdQReg[AM_HAL_CMDQ_IF_MAX] =
{
// AM_HAL_CMDQ_IF_IOM0
{
&IOM0->CQCFG, &IOM0->CQADDR,
&IOM0->CQCURIDX, &IOM0->CQENDIDX,
&IOM0->CQPAUSEEN, IOM0_CQPAUSEEN_CQPEN_IDXEQ,
&IOM0->CQSTAT, IOM0_CQSTAT_CQTIP_Msk,
IOM0_CQSTAT_CQERR_Msk, IOM0_CQSTAT_CQPAUSED_Msk
},
// AM_HAL_CMDQ_IF_IOM1
{
&IOM1->CQCFG, &IOM1->CQADDR,
&IOM1->CQCURIDX, &IOM1->CQENDIDX,
&IOM1->CQPAUSEEN, IOM0_CQPAUSEEN_CQPEN_IDXEQ,
&IOM1->CQSTAT, IOM0_CQSTAT_CQTIP_Msk,
IOM0_CQSTAT_CQERR_Msk, IOM0_CQSTAT_CQPAUSED_Msk
},
// AM_HAL_CMDQ_IF_IOM2
{
&IOM2->CQCFG, &IOM2->CQADDR,
&IOM2->CQCURIDX, &IOM2->CQENDIDX,
&IOM2->CQPAUSEEN, IOM0_CQPAUSEEN_CQPEN_IDXEQ,
&IOM2->CQSTAT, IOM0_CQSTAT_CQTIP_Msk,
IOM0_CQSTAT_CQERR_Msk, IOM0_CQSTAT_CQPAUSED_Msk
},
// AM_HAL_CMDQ_IF_IOM3
{
&IOM3->CQCFG, &IOM3->CQADDR,
&IOM3->CQCURIDX, &IOM3->CQENDIDX,
&IOM3->CQPAUSEEN, IOM0_CQPAUSEEN_CQPEN_IDXEQ,
&IOM3->CQSTAT, IOM0_CQSTAT_CQTIP_Msk,
IOM0_CQSTAT_CQERR_Msk, IOM0_CQSTAT_CQPAUSED_Msk
},
// AM_HAL_CMDQ_IF_IOM4
{
&IOM4->CQCFG, &IOM4->CQADDR,
&IOM4->CQCURIDX, &IOM4->CQENDIDX,
&IOM4->CQPAUSEEN, IOM0_CQPAUSEEN_CQPEN_IDXEQ,
&IOM4->CQSTAT, IOM0_CQSTAT_CQTIP_Msk,
IOM0_CQSTAT_CQERR_Msk, IOM0_CQSTAT_CQPAUSED_Msk
},
// AM_HAL_CMDQ_IF_IOM5
{
&IOM5->CQCFG, &IOM5->CQADDR,
&IOM5->CQCURIDX, &IOM5->CQENDIDX,
&IOM5->CQPAUSEEN, IOM0_CQPAUSEEN_CQPEN_IDXEQ,
&IOM5->CQSTAT, IOM0_CQSTAT_CQTIP_Msk,
IOM0_CQSTAT_CQERR_Msk, IOM0_CQSTAT_CQPAUSED_Msk
},
// AM_HAL_CMDQ_IF_MSPI
{
&MSPI->CQCFG, &MSPI->CQADDR,
&MSPI->CQCURIDX, &MSPI->CQENDIDX,
&MSPI->CQPAUSE, MSPI_CQPAUSE_CQMASK_CQIDX,
&MSPI->CQSTAT, MSPI_CQSTAT_CQTIP_Msk,
MSPI_CQSTAT_CQERR_Msk, MSPI_CQSTAT_CQPAUSED_Msk
},
// AM_HAL_CMDQ_IF_BLEIF
{
&BLEIF->CQCFG, &BLEIF->CQADDR,
&BLEIF->CQCURIDX, &BLEIF->CQENDIDX,
&BLEIF->CQPAUSEEN, BLEIF_CQPAUSEEN_CQPEN_CNTEQ,
&BLEIF->CQSTAT, BLEIF_CQSTAT_CQTIP_Msk,
BLEIF_CQSTAT_CQERR_Msk, BLEIF_CQSTAT_CQPAUSED_Msk
},
};
// Sync up with the current hardware indices and pointers
static void
update_indices(am_hal_cmdq_t *pCmdQ)
{
int32_t hwCurIdx;
//
// Start a critical section.
//
AM_CRITICAL_BEGIN
hwCurIdx = AM_REGVAL(pCmdQ->pReg->regCurIdx) & AM_HAL_CMDQ_HW_IDX_MAX;
// Derive the 32b values from the current hardware index values
// It is guaranteed that pCmdQ->endIdx is <= pCmdQ->curIdx + AM_HAL_CMDQ_HW_IDX_MAX - 1
pCmdQ->curIdx = (pCmdQ->endIdx & ~AM_HAL_CMDQ_HW_IDX_MAX) | hwCurIdx;
if (AM_HAL_U32_SMALLER(pCmdQ->endIdx, pCmdQ->curIdx))
{
pCmdQ->curIdx -= (AM_HAL_CMDQ_HW_IDX_MAX + 1);
}
pCmdQ->cmdQHead = AM_REGVAL(pCmdQ->pReg->regCQAddr);
//
// End the critical section.
//
AM_CRITICAL_END
}
//*****************************************************************************
//
//! @brief Initialize a Command Queue
//!
//! Initializes the command queue data structure for the given interface
//!
//! @param hwIf identifies the underlying hardware interface
//! @param cmdQSize Size of supplied memory in multiple of 8 Bytes
//! @param pCmdQBuf Command Queue Buffer
//! @param ppHandle Return Parameter - handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_init(am_hal_cmdq_if_e hwIf, am_hal_cmdq_cfg_t *pCfg, void **ppHandle)
{
am_hal_cmdq_t *pCmdQ;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (hwIf >= AM_HAL_CMDQ_IF_MAX)
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
if (!pCfg || !pCfg->pCmdQBuf || !ppHandle || (pCfg->cmdQSize < 2))
{
return AM_HAL_STATUS_INVALID_ARG;
}
if (gAmHalCmdq[hwIf].prefix.s.bInit)
{
return AM_HAL_STATUS_INVALID_OPERATION;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
pCmdQ = &gAmHalCmdq[hwIf];
pCmdQ->cmdQSize = pCfg->cmdQSize * sizeof(am_hal_cmdq_entry_t);
pCmdQ->cmdQTail = pCmdQ->cmdQNextTail = pCmdQ->cmdQHead = pCmdQ->cmdQBufStart = (uint32_t)pCfg->pCmdQBuf;
pCmdQ->cmdQBufEnd = (uint32_t)pCfg->pCmdQBuf + pCfg->cmdQSize * sizeof(am_hal_cmdq_entry_t);
pCmdQ->prefix.s.bInit = true;
pCmdQ->prefix.s.bEnable = false;
pCmdQ->prefix.s.magic = AM_HAL_MAGIC_CMDQ;
pCmdQ->pReg = &gAmHalCmdQReg[hwIf];
pCmdQ->curIdx = 0;
pCmdQ->endIdx = 0;
AM_REGVAL(pCmdQ->pReg->regCurIdx) = 0;
AM_REGVAL(pCmdQ->pReg->regEndIdx) = 0;
AM_REGVAL(pCmdQ->pReg->regCQPause) |= pCmdQ->pReg->bitMaskCQPauseIdx;
// Initialize the hardware registers
AM_REGVAL(pCmdQ->pReg->regCQAddr) = (uint32_t)pCfg->pCmdQBuf;
AM_HAL_CMDQ_INIT_CQCFG(pCmdQ->pReg->regCQCfg, pCfg->priority, false);
*ppHandle = pCmdQ;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Enable a Command Queue
//!
//! Enables the command queue for the given interface
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_enable(void *pHandle)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (pCmdQ->prefix.s.bEnable)
{
return AM_HAL_STATUS_SUCCESS;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
AM_HAL_CMDQ_ENABLE_CQ(pCmdQ->pReg->regCQCfg);
pCmdQ->prefix.s.bEnable = true;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Disable a Command Queue
//!
//! Disables the command queue for the given interface
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_disable(void *pHandle)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
if (!pCmdQ->prefix.s.bEnable)
{
return AM_HAL_STATUS_SUCCESS;
}
AM_HAL_CMDQ_DISABLE_CQ(pCmdQ->pReg->regCQCfg);
pCmdQ->prefix.s.bEnable = false;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Allocate a block of commands for posting to a command queue
//!
//! Allocates a contiguous block of command queue entries from the available
//! space in command queue
//!
//! @param pHandle handle for the command queue
//! @param numCmd Size of the command block (each block being 8 bytes)
//! @param ppBlock - Return parameter - Pointer to contiguous block of commands,
//! which can be posted
//! @param pIdx - Return parameter - monotonically increasing transaction index
//!
//! This function will take care of determining that enough space is available
//! to create the desired block. It also takes care of necessary wrap-around
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_alloc_block(void *pHandle, uint32_t numCmd, am_hal_cmdq_entry_t **ppBlock, uint32_t *pIdx)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
am_hal_cmdq_entry_t *pCmdQEntry;
uint32_t blockAddr;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (!ppBlock || !pIdx)
{
return AM_HAL_STATUS_INVALID_ARG;
}
if (pCmdQ->cmdQTail != pCmdQ->cmdQNextTail)
{
// Previously allocated block has not been posted/aborted yet
return AM_HAL_STATUS_INVALID_OPERATION;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
update_indices(pCmdQ);
// We need to not use the hwIdx completely, as otherwise we can not distinguish between
// Empty and full case
if (AM_HAL_U32_SMALLER((pCmdQ->curIdx + AM_HAL_CMDQ_HW_IDX_MAX - 1), (pCmdQ->endIdx)))
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
// Determine if we can allocate the block, and if so, where
if (pCmdQ->cmdQTail >= pCmdQ->cmdQHead)
{
// Choices: Following last block if there is enough space before wrap
// Otherwise, need to allocate block from the top of the memory
// For a sequence - we'll always come to this case, as the sequence is not started before building
// Need space for 2 more entries - one for updating curIdx, other for CQ Wrap
if ((pCmdQ->cmdQTail + (numCmd + 2)*sizeof(am_hal_cmdq_entry_t)) <= pCmdQ->cmdQBufEnd)
{
// Enough space in the queue without wrap
blockAddr = pCmdQ->cmdQTail;
}
else
{
// Need to wrap
// Need space for 1 more entry - for updating curIdx
if ((pCmdQ->cmdQBufStart + (numCmd + 1) * sizeof(am_hal_cmdq_entry_t)) < pCmdQ->cmdQHead)
{
// Initialize the tail of CmdQ for Wrap
pCmdQEntry = (am_hal_cmdq_entry_t *)pCmdQ->cmdQTail;
pCmdQEntry->address = (uint32_t)pCmdQ->pReg->regCQAddr;
pCmdQEntry->value = pCmdQ->cmdQBufStart;
blockAddr = pCmdQ->cmdQBufStart;
}
else
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
}
}
else
{
// Need space for 1 more entry - for updating curIdx
if ((pCmdQ->cmdQTail + (numCmd + 1) * sizeof(am_hal_cmdq_entry_t)) < pCmdQ->cmdQHead)
{
blockAddr = pCmdQ->cmdQTail;
}
else
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
}
*ppBlock = (am_hal_cmdq_entry_t *)blockAddr;
*pIdx = ++pCmdQ->endIdx;
pCmdQ->cmdQNextTail = blockAddr + numCmd * sizeof(am_hal_cmdq_entry_t);
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Release a block of commands previously allocated
//!
//! Releases the contiguous block of command queue entries previously allocated
//! without posting
//!
//! @param pHandle handle for the command queue
//!
//! This function will internally handles the curIdx/endIdx manipulation.
//! It also takes care of necessary wrap-around
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_release_block(void *pHandle)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (pCmdQ->cmdQTail == pCmdQ->cmdQNextTail)
{
// No block has been allocated
return AM_HAL_STATUS_INVALID_OPERATION;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
// Free up the block
pCmdQ->cmdQNextTail = pCmdQ->cmdQTail;
pCmdQ->endIdx--;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Post the last block allocated
//!
//! Post the contiguous block of command queue entries previously allocated
//!
//! @param pHandle handle for the command queue
//! @param bInt Whether the UPD interrupt is desired once the block is processed
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_post_block(void *pHandle, bool bInt)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
am_hal_cmdq_entry_t *pCmdQEntry;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (pCmdQ->cmdQTail == pCmdQ->cmdQNextTail)
{
// No block has been allocated
return AM_HAL_STATUS_INVALID_OPERATION;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
// CmdQ entries have already been populated. Just need to inform hardware of the new endIdx
// Fill up the index update entry
pCmdQEntry = (am_hal_cmdq_entry_t *)pCmdQ->cmdQNextTail;
pCmdQEntry->address = ((uint32_t)pCmdQ->pReg->regCurIdx) | (bInt ? AM_HAL_CMDQ_ENABLE_CQUPD_INT : 0);
pCmdQEntry->value = pCmdQ->endIdx;
// cmdQNextTail should now point to the first entry after the allocated block
pCmdQ->cmdQTail = pCmdQ->cmdQNextTail = (uint32_t)(pCmdQEntry + 1);
AM_REGVAL(pCmdQ->pReg->regEndIdx) = pCmdQ->endIdx & AM_HAL_CMDQ_HW_IDX_MAX;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Get Command Queue status
//!
//! Get the current state of the Command queue
//!
//! @param pHandle handle for the command queue
//! @param pStatus Return Parameter - status information
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_get_status(void *pHandle, am_hal_cmdq_status_t *pStatus)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
uint32_t status;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (!pStatus)
{
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
update_indices(pCmdQ);
pStatus->lastIdxProcessed = pCmdQ->curIdx;
pStatus->lastIdxAllocated = pCmdQ->endIdx;
pStatus->lastIdxPosted = pCmdQ->endIdx - ((pCmdQ->cmdQNextTail == pCmdQ->cmdQTail) ? 0 : 1);
status = AM_REGVAL(pCmdQ->pReg->regCQStat);
pStatus->bTIP = status & pCmdQ->pReg->bitMaskCQStatTIP;
pStatus->bPaused = status & pCmdQ->pReg->bitMaskCQStatPaused;
pStatus->bErr = status & pCmdQ->pReg->bitMaskCQStatErr;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Terminate a Command Queue
//!
//! Terminates the command queue data structure
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_term(void *pHandle, bool bForce)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
update_indices(pCmdQ);
if (!bForce && (pCmdQ->curIdx != pCmdQ->endIdx))
{
return AM_HAL_STATUS_IN_USE;
}
pCmdQ->prefix.s.bInit = false;
// Disable Command Queue
AM_HAL_CMDQ_DISABLE_CQ(pCmdQ->pReg->regCQCfg);
AM_REGVAL(pCmdQ->pReg->regCQPause) &= ~pCmdQ->pReg->bitMaskCQPauseIdx;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Clear the CQ error and resume with the next transaction.
//! The CQ is left disabled after this call
//! It is the responsibility of the caller to re-enable the CQ
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_error_resume(void *pHandle)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
am_hal_cmdq_entry_t *pCQAddr;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (!pCmdQ->prefix.s.bEnable)
{
return AM_HAL_STATUS_SUCCESS;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
// First Disable the Command Queue
AM_HAL_CMDQ_DISABLE_CQ(pCmdQ->pReg->regCQCfg);
// Need to identify end of block for the transaction where hardware is stuck
// Move the CQADDR to the last entry in the block which will update the curIdx
// and then move on.
pCQAddr = (am_hal_cmdq_entry_t *)AM_REGVAL(pCmdQ->pReg->regCQAddr);
while ((pCQAddr->address & ~AM_HAL_CMDQ_ENABLE_CQUPD_INT) != (uint32_t)(pCmdQ->pReg->regCurIdx))
{
// Is this element changing the CQ Address itself?
if (pCQAddr->address == (uint32_t)(pCmdQ->pReg->regCQAddr))
{
pCQAddr = (am_hal_cmdq_entry_t *)pCQAddr->value;
}
else
{
++pCQAddr;
}
}
// The pCQAddr now points to the address of the command which will update the curIdx
// Disable update interrupt, as we would have already handled this error
*(&pCQAddr->address) = (uint32_t)pCmdQ->pReg->regCurIdx;
AM_REGVAL(pCmdQ->pReg->regCQAddr) = (uint32_t)pCQAddr;
pCmdQ->prefix.s.bEnable = false;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Pause the CQ after finishing the current transaction.
//! The CQ is in paused state after this function returns, at the beginning of next transaction
//!
//! @param pHandle handle for the command queue
//! @param pSETCLRAddr Points to the SETCLR register for the module
//! @param ui32CQPauseSETCLR Value to be written to Pause the CQ
//! @param ui32CQUnpauseSETCLR Value to be written to unpause the CQ
//! @param ui32usMaxDelay Max time to wait (in uS)
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_pause(void *pHandle, uint32_t *pSETCLRAddr, uint32_t ui32CQPauseSETCLR, uint32_t ui32CQUnpauseSETCLR, uint32_t ui32usMaxDelay)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
uint32_t cqAddr;
am_hal_cmdq_entry_t *pCQAddr;
am_hal_cmdq_entry_t cqEntry;
uint32_t status = AM_HAL_STATUS_SUCCESS;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (!pCmdQ->prefix.s.bEnable)
{
return AM_HAL_STATUS_SUCCESS;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
// First Pause the Command Queue
*pSETCLRAddr = ui32CQPauseSETCLR;
status = am_hal_flash_delay_status_change(ui32usMaxDelay, (uint32_t)pCmdQ->pReg->regCQStat, pCmdQ->pReg->bitMaskCQStatPaused, pCmdQ->pReg->bitMaskCQStatPaused);
if (status != AM_HAL_STATUS_SUCCESS)
{
return status;
}
// Now seek for the end of current transaction
cqAddr = AM_REGVAL(pCmdQ->pReg->regCQAddr);
if (cqAddr == pCmdQ->cmdQNextTail)
{
// Already at the end
// No need to do anything else
}
else
{
// Need to identify end of block for the transaction
pCQAddr = (am_hal_cmdq_entry_t *)cqAddr;
while ((pCQAddr->address & ~AM_HAL_CMDQ_ENABLE_CQUPD_INT) != (uint32_t)(pCmdQ->pReg->regCurIdx))
{
if ( (uint32_t) ++pCQAddr >= pCmdQ->cmdQBufEnd )
{
// This should not happen
return AM_HAL_STATUS_FAIL;
}
}
// The pCQAddr now points to the address of the command which will update the curIdx
// We need to resume the CQ till it finishes this entry
// For that we'll temporarily replace the next entry to cause a Pause
// Backup the current content
cqEntry = *(++pCQAddr);
pCQAddr->address = (uint32_t)pSETCLRAddr;
pCQAddr->value = ui32CQPauseSETCLR;
// Wait for it to execute this new entry, or get paused for some other condition
do
{
// Resume the CQ
*pSETCLRAddr = ui32CQUnpauseSETCLR;
// Ensure CQ sees it
am_hal_flash_delay(3);
// Now wait for it to be paused again
status = am_hal_flash_delay_status_change(ui32usMaxDelay, (uint32_t)pCmdQ->pReg->regCQStat, pCmdQ->pReg->bitMaskCQStatPaused, pCmdQ->pReg->bitMaskCQStatPaused);
if (status != AM_HAL_STATUS_SUCCESS)
{
return status;
}
// Try Setting the PAUSE condition while in same position
*pSETCLRAddr = ui32CQPauseSETCLR;
// Ensure CQ sees it
am_hal_flash_delay(3);
status = am_hal_flash_delay_status_change(ui32usMaxDelay, (uint32_t)pCmdQ->pReg->regCQStat, pCmdQ->pReg->bitMaskCQStatPaused, pCmdQ->pReg->bitMaskCQStatPaused);
if (status != AM_HAL_STATUS_SUCCESS)
{
return status;
}
if (cqAddr == AM_REGVAL(pCmdQ->pReg->regCQAddr))
{
// CQ no longer moving
break;
}
else
{
cqAddr = AM_REGVAL(pCmdQ->pReg->regCQAddr);
}
#if 0
// Now that it is paused - check if we have reached our entry - or it paused somewhere else
cqAddr = AM_REGVAL(pCmdQ->pReg->regCQAddr);
if (cqAddr != (uint32_t)(pCQAddr + 1))
{
// It paused due to some other reason
// Try Setting the PAUSE condition while in same position
*pSETCLRAddr = ui32CQPauseSETCLR;
// Ensure CQ sees it
am_hal_flash_delay(3);
status = am_hal_flash_delay_status_change(ui32usMaxDelay, (uint32_t)pCmdQ->pReg->regCQStat, pCmdQ->pReg->bitMaskCQStatPaused, pCmdQ->pReg->bitMaskCQStatPaused);
if (status != AM_HAL_STATUS_SUCCESS)
{
return status;
}
if (AM_REGVAL(pCmdQ->pReg->regCQAddr) == cqAddr)
{
// CQ did not move after we set the PAUSE - so it is at a designated pause place
// Safe to return now
break;
}
else
{
// CQ is moving...need to retry
}
}
else
{
// Reached the desired place
break;
}
#endif
} while(1);
// Now let's revert the CQ content and set the CQADDR to correct place for it to resume later
// when the CQ is unpaused
*pCQAddr = cqEntry;
if (AM_REGVAL(pCmdQ->pReg->regCQAddr) == (uint32_t)(pCQAddr + 1))
{
AM_REGVAL(pCmdQ->pReg->regCQAddr) = (uint32_t)pCQAddr;
}
}
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Reset the Command Queue
//!
//! Reset the Command Queue & associated data structures
//! This will force the CQ reset
//! Caller needs to ensure CQ is in steady state before this is done
//! This also disables the CQ
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_reset(void *pHandle)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (pCmdQ->prefix.s.bEnable)
{
return AM_HAL_STATUS_INVALID_OPERATION;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
AM_HAL_CMDQ_DISABLE_CQ(pCmdQ->pReg->regCQCfg);
pCmdQ->cmdQTail = pCmdQ->cmdQNextTail = pCmdQ->cmdQHead = pCmdQ->cmdQBufStart;
pCmdQ->curIdx = 0;
pCmdQ->endIdx = 0;
AM_REGVAL(pCmdQ->pReg->regCurIdx) = 0;
AM_REGVAL(pCmdQ->pReg->regEndIdx) = 0;
// Initialize the hardware registers
AM_REGVAL(pCmdQ->pReg->regCQAddr) = pCmdQ->cmdQBufStart;
pCmdQ->prefix.s.bEnable = false;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//! @brief Post the last block allocated with the additional wrap to start
//!
//! Post the contiguous block of command queue entries previously allocated
//! with the additional wrap to start
//!
//! @param pHandle handle for the command queue
//! @param bInt Whether the UPD interrupt is desired once the block is processed
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_post_loop_block(void *pHandle, bool bInt)
{
am_hal_cmdq_t *pCmdQ = (am_hal_cmdq_t *)pHandle;
am_hal_cmdq_entry_t *pCmdQEntry;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (!AM_HAL_CMDQ_CHK_HANDLE(pHandle))
{
return AM_HAL_STATUS_INVALID_HANDLE;
}
if (pCmdQ->cmdQTail == pCmdQ->cmdQNextTail)
{
// No block has been allocated
return AM_HAL_STATUS_INVALID_OPERATION;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
// CmdQ entries have already been populated. Just need to inform hardware of the new endIdx
// Reset the index to 0
pCmdQEntry = (am_hal_cmdq_entry_t *)pCmdQ->cmdQNextTail;
pCmdQEntry->address = (uint32_t)pCmdQ->pReg->regCurIdx;
pCmdQEntry->value = 0;
pCmdQEntry++;
// Fill up the loopback entry
// At the alloc time, we were guaranteed one extra entry for loopback
pCmdQEntry->address = (uint32_t)pCmdQ->pReg->regCQAddr | (bInt ? AM_HAL_CMDQ_ENABLE_CQUPD_INT : 0);
pCmdQEntry->value = pCmdQ->cmdQBufStart;
// cmdQNextTail should now point to the first entry after the allocated block
pCmdQ->cmdQTail = pCmdQ->cmdQNextTail = (uint32_t)(pCmdQEntry + 1);
// Since we are not updating the curIdx - this will cause CQ to run indefinetely
AM_REGVAL(pCmdQ->pReg->regEndIdx) = pCmdQ->endIdx & AM_HAL_CMDQ_HW_IDX_MAX;
return AM_HAL_STATUS_SUCCESS;
}
@@ -0,0 +1,292 @@
//*****************************************************************************
//
// am_hal_cmdq.h
//! @file
//!
//! @brief Functions for support command queue operations.
//!
//! @addtogroup
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_CMDQ_H
#define AM_HAL_CMDQ_H
// Identification for underlying hardware interface
typedef enum
{
AM_HAL_CMDQ_IF_IOM0,
AM_HAL_CMDQ_IF_IOM1,
AM_HAL_CMDQ_IF_IOM2,
AM_HAL_CMDQ_IF_IOM3,
AM_HAL_CMDQ_IF_IOM4,
AM_HAL_CMDQ_IF_IOM5,
AM_HAL_CMDQ_IF_MSPI,
AM_HAL_CMDQ_IF_BLEIF,
AM_HAL_CMDQ_IF_MAX,
} am_hal_cmdq_if_e;
typedef enum
{
AM_HAL_CMDQ_PRIO_LOW,
AM_HAL_CMDQ_PRIO_HI,
} am_hal_cmdq_priority_e;
typedef struct
{
uint32_t cmdQSize;
uint32_t *pCmdQBuf;
am_hal_cmdq_priority_e priority;
} am_hal_cmdq_cfg_t;
typedef struct
{
uint32_t address;
uint32_t value;
} am_hal_cmdq_entry_t;
typedef struct
{
uint32_t lastIdxProcessed;
uint32_t lastIdxPosted;
uint32_t lastIdxAllocated;
bool bTIP;
bool bPaused;
bool bErr;
} am_hal_cmdq_status_t;
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! @brief Initialize a Command Queue
//!
//! Initializes the command queue data structure for the given interface
//!
//! @param hwIf identifies the underlying hardware interface
//! @param cmdQSize Size of supplied memory in multiple of 8 Bytes
//! @param pCmdQBuf Command Queue Buffer
//! @param ppHandle Return Parameter - handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_init(am_hal_cmdq_if_e hwIf, am_hal_cmdq_cfg_t *pCfg, void **ppHandle);
//*****************************************************************************
//
//! @brief Enable a Command Queue
//!
//! Enables the command queue for the given interface
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_enable(void *pHandle);
//*****************************************************************************
//
//! @brief Disable a Command Queue
//!
//! Disables the command queue for the given interface
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_disable(void *pHandle);
//*****************************************************************************
//
//! @brief Allocate a block of commands for posting to a command queue
//!
//! Allocates a contiguous block of command queue entries from the available
//! space in command queue
//!
//! @param pHandle handle for the command queue
//! @param numCmd Size of the command block (each block being 8 bytes)
//! @param ppBlock - Return parameter - Pointer to contiguous block of commands,
//! which can be posted
//! @param pIdx - Return parameter - monotonically increasing transaction index
//!
//! This function will take care of determining that enough space is available
//! to create the desired block. It also takes care of necessary wrap-around
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_alloc_block(void *pHandle, uint32_t numCmd, am_hal_cmdq_entry_t **ppBlock, uint32_t *pIdx);
//*****************************************************************************
//
//! @brief Release a block of commands previously allocated
//!
//! Releases the contiguous block of command queue entries previously allocated
//! without posting
//!
//! @param pHandle handle for the command queue
//!
//! This function will internally handles the curIdx/endIdx manipulation.
//! It also takes care of necessary wrap-around
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_release_block(void *pHandle);
//*****************************************************************************
//
//! @brief Post the last block allocated
//!
//! Post the contiguous block of command queue entries previously allocated
//!
//! @param pHandle handle for the command queue
//! @param bInt Whether the UPD interrupt is desired once the block is processed
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_post_block(void *pHandle, bool bInt);
//*****************************************************************************
//
//! @brief Get Command Queue status
//!
//! Get the current state of the Command queue
//!
//! @param pHandle handle for the command queue
//! @param pStatus Return Parameter - status information
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_get_status(void *pHandle, am_hal_cmdq_status_t *pStatus);
//*****************************************************************************
//
//! @brief Terminate a Command Queue
//!
//! Terminates the command queue data structure
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_term(void *pHandle, bool bForce);
//*****************************************************************************
//
//! @brief Clear the CQ error and resume with the next transaction.
//!
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_error_resume(void *pHandle);
//*****************************************************************************
//
//! @brief Pause the CQ after finishing the current transaction.
//! The CQ is in paused state after this function returns, at the beginning of next transaction
//!
//! @param pHandle handle for the command queue
//! @param pSETCLRAddr Points to the SETCLR register for the module
//! @param ui32CQPauseSETCLR Value to be written to Pause the CQ
//! @param ui32CQUnpauseSETCLR Value to be written to unpause the CQ
//! @param ui32usMaxDelay Max time to wait (in uS)
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_pause(void *pHandle, uint32_t *pSETCLRAddr,
uint32_t ui32CQPauseSETCLR,
uint32_t ui32CQUnpauseSETCLR, uint32_t ui32usMaxDelay);
//*****************************************************************************
//
//! @brief Reset the Command Queue
//!
//! Reset the Command Queue & associated data structures
//! This will force the CQ reset
//! Caller needs to ensure CQ is in steady state before this is done
//! This also disables the CQ
//!
//! @param pHandle handle for the command queue
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_reset(void *pHandle);
//*****************************************************************************
//
//! @brief Post the last block allocated with the additional wrap to start
//!
//! Post the contiguous block of command queue entries previously allocated
//! with the additional wrap to start
//!
//! @param pHandle handle for the command queue
//! @param bInt Whether the UPD interrupt is desired once the block is processed
//!
//! @return Returns 0 on success
//
//*****************************************************************************
uint32_t am_hal_cmdq_post_loop_block(void *pHandle, bool bInt);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_CMDQ_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,554 @@
//*****************************************************************************
//
// am_hal_ctimer.h
//! @file
//!
//! @brief Functions for accessing and configuring the CTIMER.
//!
//! @addtogroup ctimer3 Counter/Timer (CTIMER)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_CTIMER_H
#define AM_HAL_CTIMER_H
#ifdef __cplusplus
extern "C"
{
#endif
//
// Designate this peripheral.
//
#define AM_APOLLO3_CTIMER 1
//*****************************************************************************
//
// CTIMERADDRn()
// This is a specialized version of AM_REGADDRn(). It is necessary because
// the CTIMER does not work as a multi-module peripheral. In typical
// multi-module peripherals, the base address is defined as MODULE0_BASE.
// For CTIMER it's CTIMER_BASE (there is no module 0 defined).
//
// Usage:
// CTIMER_ADDRn(CTIMER, n, reg).
//
// periph: Must always be CTIMER.
// n: The timer number specified as a macro, variable, etc.
// reg: The register name always ending in '0'. E.g. TMR0, CTRL0, CMPRB0,
// etc (regardless of the timernum specified by 'n').
//
//*****************************************************************************
#define CTIMERADDRn(periph, n, reg) ( periph##_BASE + \
offsetof(periph##_Type, reg) + \
(n * (offsetof(periph##_Type, TMR1) - offsetof(periph##_Type, TMR0))) )
//
// Enumerations for the eOutputType argument of am_hal_ctimer_output_config().
//
typedef enum
{
AM_HAL_CTIMER_OUTPUT_NORMAL = 0x0,
AM_HAL_CTIMER_OUTPUT_SECONDARY = 0x1,
AM_HAL_CTIMER_OUTPUT_FORCE0 = 0x2,
AM_HAL_CTIMER_OUTPUT_FORCE1 = 0x3
} am_hal_ctimer_outputtype_e;
//*****************************************************************************
//
//! CMSIS-Style macro for handling a variable CTIMER module number.
//
//*****************************************************************************
#define CTIMERn(n) ((CTIMER_Type*)(CTIMER_BASE + (n * ((uint32_t)&CTIMER->TMR1 - (uint32_t)&CTIMER->TMR0))))
//*****************************************************************************
//
//! Number of timers
//
//*****************************************************************************
#define AM_HAL_CTIMER_TIMERS_NUM 8
//*****************************************************************************
//
//! Timer offset value
//
//*****************************************************************************
#define AM_HAL_CTIMER_TIMER_OFFSET ((uint32_t)&CTIMER->TMR1 - (uint32_t)&CTIMER->TMR0)
//*****************************************************************************
//
//! @name Interrupt Status Bits
//! @brief Interrupt Status Bits for enable/disble use
//!
//! These macros may be used to set and clear interrupt bits
//! @{
//
//*****************************************************************************
#define AM_HAL_CTIMER_INT_TIMERA0C0 CTIMER_INTEN_CTMRA0C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA0C1 CTIMER_INTEN_CTMRA0C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA1C0 CTIMER_INTEN_CTMRA1C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA1C1 CTIMER_INTEN_CTMRA1C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA2C0 CTIMER_INTEN_CTMRA2C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA2C1 CTIMER_INTEN_CTMRA2C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA3C0 CTIMER_INTEN_CTMRA3C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA3C1 CTIMER_INTEN_CTMRA3C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA4C0 CTIMER_INTEN_CTMRA4C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA4C1 CTIMER_INTEN_CTMRA4C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA5C0 CTIMER_INTEN_CTMRA5C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA5C1 CTIMER_INTEN_CTMRA5C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA6C0 CTIMER_INTEN_CTMRA6C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA6C1 CTIMER_INTEN_CTMRA6C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA7C0 CTIMER_INTEN_CTMRA7C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERA7C1 CTIMER_INTEN_CTMRA7C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB0C0 CTIMER_INTEN_CTMRB0C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB0C1 CTIMER_INTEN_CTMRB0C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB1C0 CTIMER_INTEN_CTMRB1C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB1C1 CTIMER_INTEN_CTMRB1C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB2C0 CTIMER_INTEN_CTMRB2C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB2C1 CTIMER_INTEN_CTMRB2C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB3C0 CTIMER_INTEN_CTMRB3C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB3C1 CTIMER_INTEN_CTMRB3C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB4C0 CTIMER_INTEN_CTMRB4C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB4C1 CTIMER_INTEN_CTMRB4C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB5C0 CTIMER_INTEN_CTMRB5C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB5C1 CTIMER_INTEN_CTMRB5C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB6C0 CTIMER_INTEN_CTMRB6C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB6C1 CTIMER_INTEN_CTMRB6C1INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB7C0 CTIMER_INTEN_CTMRB7C0INT_Msk
#define AM_HAL_CTIMER_INT_TIMERB7C1 CTIMER_INTEN_CTMRB7C1INT_Msk
//! @}
//*****************************************************************************
//
// DEPRECATED Interrupt Status Bits
//
//*****************************************************************************
#define AM_HAL_CTIMER_INT_TIMERA0 AM_HAL_CTIMER_INT_TIMERA0C0
#define AM_HAL_CTIMER_INT_TIMERB0 AM_HAL_CTIMER_INT_TIMERB0C0
#define AM_HAL_CTIMER_INT_TIMERA1 AM_HAL_CTIMER_INT_TIMERA1C0
#define AM_HAL_CTIMER_INT_TIMERB1 AM_HAL_CTIMER_INT_TIMERB1C0
#define AM_HAL_CTIMER_INT_TIMERA2 AM_HAL_CTIMER_INT_TIMERA2C0
#define AM_HAL_CTIMER_INT_TIMERB2 AM_HAL_CTIMER_INT_TIMERB2C0
#define AM_HAL_CTIMER_INT_TIMERA3 AM_HAL_CTIMER_INT_TIMERA3C0
#define AM_HAL_CTIMER_INT_TIMERB3 AM_HAL_CTIMER_INT_TIMERB3C0
//*****************************************************************************
//
//! @name Configuration options
//! @brief Configuration options for \e am_hal_ctimer_config_t
//!
//! These options are to be used with the \e am_hal_ctimer_config_t structure
//! used by \e am_hal_ctimer_config
//! @{
//
//*****************************************************************************
#define AM_HAL_CTIMER_CLK_PIN _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x00)
#define AM_HAL_CTIMER_HFRC_12MHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x01)
#define AM_HAL_CTIMER_HFRC_3MHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x02)
#define AM_HAL_CTIMER_HFRC_187_5KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x03)
#define AM_HAL_CTIMER_HFRC_47KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x04)
#define AM_HAL_CTIMER_HFRC_12KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x05)
#define AM_HAL_CTIMER_XT_32_768KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x06)
#define AM_HAL_CTIMER_XT_16_384KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x07)
#define AM_HAL_CTIMER_XT_2_048KHZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x08)
#define AM_HAL_CTIMER_XT_256HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x09)
#define AM_HAL_CTIMER_LFRC_512HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0A)
#define AM_HAL_CTIMER_LFRC_32HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0B)
#define AM_HAL_CTIMER_LFRC_1HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0C)
#define AM_HAL_CTIMER_LFRC_1_16HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0D)
#define AM_HAL_CTIMER_RTC_100HZ _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0E)
#define AM_HAL_CTIMER_HCLK_DIV4 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x0F)
#define AM_HAL_CTIMER_XT_DIV4 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x10)
#define AM_HAL_CTIMER_XT_DIV8 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x11)
#define AM_HAL_CTIMER_XT_DIV32 _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x12)
#define AM_HAL_CTIMER_RSVD _VAL2FLD(CTIMER_CTRL0_TMRA0CLK, 0x13)
//! @}
//*****************************************************************************
//
//! Timer function macros.
//!
//! @{
//
//*****************************************************************************
//! Single Count: Counts one time to the compare value, then the output
//! changes polarity and stays at that level, with an optional interrupt.
#define AM_HAL_CTIMER_FN_ONCE _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 0)
//! Repeated Count: Periodic 1-clock-cycle wide pulses with optional interrupts.
#define AM_HAL_CTIMER_FN_REPEAT _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 1)
//! Single Pulse (One Shot): A single pulse of programmed width, with an optional interrupt.
#define AM_HAL_CTIMER_FN_PWM_ONCE _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 2)
//! Repeated Pulse: A rectangular (or square) waveform with programmed high and
//! low widths, and optional interrupts on each cycle.
#define AM_HAL_CTIMER_FN_PWM_REPEAT _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 3)
//! Single Pattern: one burst of bits specified by the CMPR0/1/2/3 registers.
#define AM_HAL_CTIMER_FN_PTN_ONCE _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 4)
//! Repeated Pattern: repeated burst of bits specified by the CMPR0/1/2/3 registers.
#define AM_HAL_CTIMER_FN_PTN_REPEAT _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 5)
//! Continuous: Free running timer with a single level change on the output and
//! a single optional interrupt.
#define AM_HAL_CTIMER_FN_CONTINUOUS _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 6)
//! Alternate Pulse: like Repeated Pulse but alternating between two different
//! pulse width/spacing settings.
#define AM_HAL_CTIMER_FN_PWM_ALTERNATE _VAL2FLD(CTIMER_CTRL0_TMRA0FN, 7)
//! @}
//*****************************************************************************
//
//! Half-timer options.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_CTIMER_INT_ENABLE CTIMER_CTRL0_TMRA0IE0_Msk
//#define AM_HAL_CTIMER_PIN_ENABLE CTIMER_CTRL0_TMRA0PE_Msk
#define AM_HAL_CTIMER_PIN_INVERT CTIMER_CTRL0_TMRA0POL_Msk
#define AM_HAL_CTIMER_CLEAR CTIMER_CTRL0_TMRA0CLR_Msk
//! @}
//*****************************************************************************
//
//! Additional timer options.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_CTIMER_LINK CTIMER_CTRL0_CTLINK0_Msk
#define AM_HAL_CTIMER_ADC_TRIG CTIMER_CTRL3_ADCEN_Msk
//! @}
//*****************************************************************************
//
//! Timer selection macros.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_CTIMER_TIMERA 0x0000FFFF
#define AM_HAL_CTIMER_TIMERB 0xFFFF0000
#define AM_HAL_CTIMER_BOTH 0xFFFFFFFF
//! @}
//*****************************************************************************
//
//! Timer trigger options for Apollo3 Blue (rev B0 and later) including
//! Apollo3 Blue Plus.
//!
//! Valid only for CTIMER4 and CTIMER5 when CTLINK==1 and TMRA4TRIG==1
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCAP0 CTIMER_AUX4_TMRB4TRIG_A7OUT
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCAP1 CTIMER_AUX4_TMRB4TRIG_B7OUT
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCAP2 CTIMER_AUX4_TMRB4TRIG_A1OUT
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCAP3 CTIMER_AUX4_TMRB4TRIG_B1OUT
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP0 CTIMER_AUX4_TMRB4TRIG_B3OUT2
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP1 CTIMER_AUX4_TMRB4TRIG_A3OUT2
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP2 CTIMER_AUX4_TMRB4TRIG_A1OUT2
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP3 CTIMER_AUX4_TMRB4TRIG_B1OUT2
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP4 CTIMER_AUX4_TMRB4TRIG_A6OUT2DUAL
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP5 CTIMER_AUX4_TMRB4TRIG_A7OUT2DUAL
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP6 CTIMER_AUX4_TMRB4TRIG_B5OUT2DUAL
#define AM_HAL_CTIMER_AUX4_TMRB4TRIG_STIMERCMP7 CTIMER_AUX4_TMRB4TRIG_A5OUT2DUAL
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCAP0 CTIMER_AUX5_TMRB5TRIG_A7OUT
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCAP1 CTIMER_AUX5_TMRB5TRIG_B7OUT
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCAP2 CTIMER_AUX5_TMRB5TRIG_A1OUT
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCAP3 CTIMER_AUX5_TMRB5TRIG_B1OUT
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP0 CTIMER_AUX5_TMRB5TRIG_B3OUT2
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP1 CTIMER_AUX5_TMRB5TRIG_A3OUT2
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP2 CTIMER_AUX5_TMRB5TRIG_A1OUT2
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP3 CTIMER_AUX5_TMRB5TRIG_B1OUT2
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP4 CTIMER_AUX5_TMRB5TRIG_A6OUT2DUAL
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP5 CTIMER_AUX5_TMRB5TRIG_A7OUT2DUAL
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP6 CTIMER_AUX5_TMRB5TRIG_B5OUT2DUAL
#define AM_HAL_CTIMER_AUX5_TMRB5TRIG_STIMERCMP7 CTIMER_AUX5_TMRB5TRIG_A5OUT2DUAL
//! @}
//*****************************************************************************
//
//! @name All-In-One Configuration
//! @brief New API for multiple timer configuration.
//!
//! These options are to be used with the \e am_hal_ctimer_config_t structure
//! used by \e am_hal_ctimer_config
//! @{
//
//*****************************************************************************
//! CTimer AIO Compare Configuration.
typedef struct
{
//
//! Function Number.
//
uint32_t FN;
//
//! Timer Segment. Timer A, B, BOTH selector.
//
uint32_t AB;
//
//! Compare Register A0.
//
uint32_t A0;
//
//! Compare Register A1.
//
uint32_t A1;
//
//! Compare Register A2.
//
uint32_t A2;
//
//! Compare Register A3.
//
uint32_t A3;
//
//! Compare Register B0.
//
uint32_t B0;
//
//! Compare Register B1.
//
uint32_t B1;
//
//! Compare Register B2.
//
uint32_t B2;
//
//! Compare Register B3.
//
uint32_t B3;
//
//! LMT field values.
//
uint32_t LMT;
//
//! A "T" indicates that a 1 is loaded if the OUT2 output is used, otherwise a 0 is loaded.
//
uint32_t EN23;
//
//! TRIG: a single pattern will be triggered; TERM: a repeated pattern will be terminated.
//
uint32_t TRIG;
//
//! Select clock source: internal, external, a buck pulse, or output of another CTIMER.
//
uint32_t CLK;
//
//! Enable the primary interrupt INT.
//
uint32_t IE0;
//
//! Enable the secondary interrupt INT2.
//
uint32_t IE1;
//
//! Select the polarity of the OUT output.
//
uint32_t POL;
//
//! Select the polarity of the OUT2 output.
//
uint32_t POL23;
//
//! Select polarity of both OUT and OUT2 as a function of the trigger input.
//
uint32_t TINV;
//
//! Disable clock synchronization on read.
//
uint32_t NOSYNC;
//
//! Enable the timer.
// This is ANDed with the global enable in GLOBEN, and allows the counter to begin counting.
//
uint32_t EN;
//
// Clear the timer. This will hold the timer at zero even if EN is asserted.
// It is typically cleared at the end of a configuration and
// is probably not included in the function structure.
//
//uint32_t CLR;
}
am_hal_ctimer_aio_config_t;
//! CTimer AIO Output Selection and Interconnect.
typedef struct
{
//! Pad 0-9
uint32_t OUTCFG0;
//! Pad 10-19
uint32_t OUTCFG1;
//! Pad 20-29
uint32_t OUTCFG2;
//! Pad 30-31
uint32_t OUTCFG3;
}
am_hal_ctimer_aio_connect_t;
//! @}
//*****************************************************************************
//
//! Timer configuration structure
//
//*****************************************************************************
typedef struct
{
//
//! Set to 1 to operate this timer as a 32-bit timer instead of two 16-bit
//! timers.
//
uint32_t ui32Link;
//
//! Configuration options for TIMERA
//
uint32_t ui32TimerAConfig;
//
//! Configuration options for TIMERB
//
uint32_t ui32TimerBConfig;
}
am_hal_ctimer_config_t;
//*****************************************************************************
//
//! Function pointer type for CTimer interrupt handlers.
//
//*****************************************************************************
typedef void (*am_hal_ctimer_handler_t)(void);
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_ctimer_globen(uint32_t ui32ConfigVal);
extern void am_hal_ctimer_config(uint32_t ui32TimerNumber,
am_hal_ctimer_config_t *psConfig);
extern void am_hal_ctimer_config_single(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32ConfigVal);
extern void am_hal_ctimer_config_trigger(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32ConfigVal);
extern void am_hal_ctimer_start(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment);
extern void am_hal_ctimer_stop(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment);
extern void am_hal_ctimer_clear(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment);
extern uint32_t am_hal_ctimer_read(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment);
extern uint32_t am_hal_ctimer_output_config(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32PadNum,
uint32_t eOutputType,
uint32_t eDriveStrength);
extern void am_hal_ctimer_input_config(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32TimerOutputConfig);
extern void am_hal_ctimer_compare_set(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32CompareReg,
uint32_t ui32Value);
extern void am_hal_ctimer_aux_compare_set(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32CompareReg,
uint32_t ui32Value);
extern void am_hal_ctimer_period_set(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32Period,
uint32_t ui32OnTime);
extern void am_hal_ctimer_aux_period_set(uint32_t ui32TimerNumber,
uint32_t ui32TimerSegment,
uint32_t ui32Period,
uint32_t ui32OnTime);
extern void am_hal_ctimer_adc_trigger_enable(void);
extern void am_hal_ctimer_adc_trigger_disable(void);
extern void am_hal_ctimer_int_enable(uint32_t ui32Interrupt);
extern uint32_t am_hal_ctimer_int_enable_get(void);
extern void am_hal_ctimer_int_disable(uint32_t ui32Interrupt);
extern void am_hal_ctimer_int_set(uint32_t ui32Interrupt);
extern void am_hal_ctimer_int_clear(uint32_t ui32Interrupt);
extern uint32_t am_hal_ctimer_int_status_get(bool bEnabledOnly);
extern void am_hal_ctimer_int_register(uint32_t ui32Interrupt,
am_hal_ctimer_handler_t pfnHandler);
extern void am_hal_ctimer_int_service(uint32_t ui32Status);
//
// General function to do triple back-to-back reads.
//
extern void am_hal_triple_read(uint32_t u32TimerAddr, uint32_t ui32Data[]);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_CTIMER_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,95 @@
//*****************************************************************************
//
// am_hal_debug.c
//! @file
//!
//! @brief Useful functions for debugging.
//!
//! These functions and macros were created to assist with debugging. They are
//! intended to be as unintrusive as possible and designed to be removed from
//! the compilation of a project when they are no longer needed.
//!
//! @addtogroup haldebug3 HAL Debug/Assert Utilities
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
//! @brief Default implementation of a failed ASSERT statement.
//!
//! @param pcFile is the name of the source file where the error occurred.
//! @param ui32Line is the line number where the error occurred.
//! @param pcMessage is an optional message describing the failure.
//!
//! This function is called by am_hal_debug_assert() macro when the supplied
//! condition is not true. The implementation here simply halts the application
//! for further analysis. Individual applications may define their own
//! implementations of am_hal_debug_error() to provide more detailed feedback
//! about the failed am_hal_debug_assert() statement.
//!
//! @return Never.
//
//*****************************************************************************
#if defined (__IAR_SYSTEMS_ICC__)
__weak void
#else
void __attribute__((weak))
#endif
am_hal_debug_error(const char *pcFile, uint32_t ui32Line, const char *pcMessage)
{
//
// Halt for analysis.
//
while(1);
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,140 @@
//*****************************************************************************
//
// am_hal_debug.h
//! @file
//!
//! @brief Useful macros for debugging.
//!
//! These functions and macros were created to assist with debugging. They are
//! intended to be as unintrusive as possible and designed to be removed from
//! the compilation of a project when they are no longer needed.
//!
//! @addtogroup haldebug3 HAL Debug/Assert Utilities
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_DEBUG_H
#define AM_HAL_DEBUG_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Determine DBG_FILENAME
//
//*****************************************************************************
//
// By spec and convention, the standard __FILE__ compiler macro includes a full
// path (absolute or relative) to the file being compiled. This makes recreating
// binaries virtually impossible unless rebuilt on the same or identically
// configured system.
//
// To be able to build consistent binaries on different systems, we want to make
// sure the full pathname is not included in the binary. Only IAR EWARM provides
// an easy mechanism to provide only the filename without the path. For other
// platforms, we will simply use a generic pathname.
//
#if defined (__IAR_SYSTEMS_ICC__)
//
// With EWARM the --no_path_in_file_macros option reduces __FILE__ to only the
// module name. Therefore this define assumes the option is being used.
//
#define DBG_FILENAME __FILE__
#elif defined(__KEIL__)
//
// Keil provides __MODULE__ which is simply the module name portion of __FILE__.
//
#define DBG_FILENAME __MODULE__
#elif defined(__ARMCC_VERSION)
#define DBG_FILENAME __MODULE__
#else
//
// With GCC, we're out of luck.
//
#define DBG_FILENAME "debug_filename.ext"
//#define DBG_FILENAME __FILE__
#endif
//*****************************************************************************
//
// Debug assert macros.
//
//*****************************************************************************
#ifndef AM_HAL_DEBUG_NO_ASSERT
#define am_hal_debug_assert_msg(bCondition, pcMessage) \
if ( !(bCondition)) am_hal_debug_error(DBG_FILENAME, __LINE__, pcMessage)
#define am_hal_debug_assert(bCondition) \
if ( !(bCondition)) am_hal_debug_error(DBG_FILENAME, __LINE__, 0)
#else
#define am_hal_debug_assert_msg(bCondition, pcMessage)
#define am_hal_debug_assert(bCondition)
#endif // AM_DEBUG_ASSERT
//*****************************************************************************
//
// External function prototypes.
//
//*****************************************************************************
extern void am_hal_debug_error(const char *pcFile, uint32_t ui32Line,
const char *pcMessage);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_DEBUG_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,364 @@
//*****************************************************************************
//
// am_hal_flash.h
//! @file
//!
//! @brief Functions for performing Flash operations.
//!
//! @addtogroup flash3 Flash
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_FLASH_H
#define AM_HAL_FLASH_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <stdbool.h>
//*****************************************************************************
//
// Flash Program keys.
//
//*****************************************************************************
#define AM_HAL_FLASH_PROGRAM_KEY 0x12344321
#define AM_HAL_FLASH_INFO_KEY 0xD894E09E
//*****************************************************************************
//
// Some helpful SRAM values and macros.
//
//*****************************************************************************
#define AM_HAL_FLASH_SRAM_ADDR 0x10000000
#define AM_HAL_FLASH_SRAM_SIZE (384 * 1024)
#define AM_HAL_FLASH_SRAM_LARGEST_VALID_ADDR (AM_HAL_FLASH_SRAM_ADDR + AM_HAL_FLASH_SRAM_SIZE - 1)
//*****************************************************************************
//
// Some helpful flash values and macros.
//
//*****************************************************************************
#define AM_HAL_FLASH_ADDR 0x00000000
#define AM_HAL_FLASH_INSTANCE_SIZE ( 512 * 1024 )
#define AM_HAL_FLASH_NUM_INSTANCES 2
#define AM_HAL_FLASH_PAGE_SIZE ( 8 * 1024 )
#define AM_HAL_FLASH_INFO_SIZE AM_HAL_FLASH_PAGE_SIZE
#define AM_HAL_FLASH_INSTANCE_PAGES ( AM_HAL_FLASH_INSTANCE_SIZE / AM_HAL_FLASH_PAGE_SIZE )
#define AM_HAL_FLASH_TOTAL_SIZE ( AM_HAL_FLASH_INSTANCE_SIZE * AM_HAL_FLASH_NUM_INSTANCES )
#define AM_HAL_FLASH_LARGEST_VALID_ADDR ( AM_HAL_FLASH_ADDR + AM_HAL_FLASH_TOTAL_SIZE - 1 )
#define AM_HAL_FLASH_APPL_ADDR 0xC000
//
// Macros to determine whether a given address is a valid internal
// flash or SRAM address.
//
#define ISADDRSRAM(x) ((x >= AM_HAL_FLASH_SRAM_ADDR) && \
(x <= (AM_HAL_FLASH_SRAM_LARGEST_VALID_ADDR & ~0x3)))
#if AM_HAL_FLASH_ADDR == 0x0
#define ISADDRFLASH(x) (x <= (AM_HAL_FLASH_LARGEST_VALID_ADDR & ~0x3))
#else
#define ISADDRFLASH(x) ((x >= AM_HAL_FLASH_ADDR) && \
(x <= (AM_HAL_FLASH_LARGEST_VALID_ADDR & ~0x3)))
#endif
//
// Macros to describe the flash ROW layout.
//
#define AM_HAL_FLASH_ROW_WIDTH_BYTES (512)
//
// Convert an absolute flash address to an instance
//
#define AM_HAL_FLASH_ADDR2INST(addr) ( ( addr >> 19 ) & (AM_HAL_FLASH_NUM_INSTANCES - 1) )
//
// Convert an absolute flash address to a page number relative to the instance
//
#define AM_HAL_FLASH_ADDR2PAGE(addr) ( ( addr >> 13 ) & 0x3F )
//
// Convert an absolute flash address to an absolute page number
//
#define AM_HAL_FLASH_ADDR2ABSPAGE(addr) ( addr >> 13 )
//*****************************************************************************
//
//! Given an integer number of microseconds, convert to a value representing
//! the number of am_hal_flash_delay() cycles that will provide that amount
//! of delay. This macro is designed to take into account some of the call
//! overhead and latencies.
//!
//! e.g. To provide a 10us delay:
//! am_hal_flash_delay( FLASH_CYCLES_US(10) );
//!
//! As of SDK 2.1, burst mode is accounted for in am_hal_flash_delay().
//!
//! The FLASH_CYCLES_US macro assumes:
//! - Burst or normal mode operation.
//! - If cache is not enabled, use FLASH_CYCLES_US_NOCACHE() instead.
//
//*****************************************************************************
#define CYCLESPERITER (AM_HAL_CLKGEN_FREQ_MAX_MHZ / 3)
#define FLASH_CYCLES_US(n) ((n * CYCLESPERITER) + 0)
#define FLASH_CYCLES_US_NOCACHE(n) ( (n == 0) ? 0 : (n * CYCLESPERITER) - 5)
//
// Backward compatibility
//
#define am_hal_flash_program_otp am_hal_flash_program_info
#define am_hal_flash_program_otp_sram am_hal_flash_program_info_sram
//*****************************************************************************
//
//! Structure of pointers to helper functions invoking flash operations.
//
//! The functions we are pointing to here are in the Apollo 3
//! integrated BOOTROM.
//
//*****************************************************************************
typedef struct am_hal_flash_helper_struct
{
//
// The basics.
//
int (*flash_mass_erase)(uint32_t, uint32_t);
int (*flash_page_erase)(uint32_t, uint32_t, uint32_t);
int (*flash_program_main)(uint32_t, uint32_t *, uint32_t *, uint32_t);
int (*flash_program_info_area)(uint32_t, uint32_t, uint32_t *, uint32_t, uint32_t);
//
// Non-blocking variants, but be careful these are not interrupt safe so
// mask interrupts while these very long operations proceed.
//
int (*flash_mass_erase_nb)(uint32_t, uint32_t);
int (*flash_page_erase_nb)(uint32_t, uint32_t, uint32_t);
int (*flash_page_erase2_nb)( uint32_t value, uint32_t address);
bool (*flash_nb_operation_complete)(void);
//
// Useful utilities.
//
uint32_t (*flash_util_read_word)( uint32_t *);
void (*flash_util_write_word)( uint32_t *, uint32_t);
void (*bootrom_delay_cycles)(uint32_t ui32Cycles);
//
// Essentially these are recovery options.
//
int (*flash_info_erase)( uint32_t, uint32_t);
int (*flash_info_plus_main_erase)( uint32_t, uint32_t);
int (*flash_info_plus_main_erase_both)( uint32_t value);
int (*flash_recovery)( uint32_t value);
//
// The following functions pointers will generally never be called from
// user programs. They are here primarily to document these entry points
// which are usable from a debugger or debugger script.
//
void (*flash_program_main_from_sram)(void);
void (*flash_program_info_area_from_sram)(void);
void (*flash_erase_main_pages_from_sram)(void);
void (*flash_mass_erase_from_sram)(void);
void (*flash_info_erase_from_sram)(void);
void (*flash_info_plus_main_erase_from_sram)(void);
void (*flash_nb_operation_complete_from_sram)(void);
void (*flash_page_erase2_nb_from_sram)(void);
void (*flash_recovery_from_sram)(void);
} g_am_hal_flash_t;
extern const g_am_hal_flash_t g_am_hal_flash;
//*****************************************************************************
//
// Define some FLASH INFO SPACE values and macros.
//
//*****************************************************************************
#define AM_HAL_FLASH_INFO_ADDR 0x50020000
#define AM_HAL_FLASH_INFO_SECURITY_O 0x10
#define AM_HAL_FLASH_INFO_WRITPROT_O 0x40
#define AM_HAL_FLASH_INFO_COPYPROT_O 0x50
#define AM_HAL_FLASH_INFO_SECURITY_ADDR (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_SECURITY_O)
#define AM_HAL_FLASH_INFO_WRITPROT_ADDR (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_WRITPROT_O)
#define AM_HAL_FLASH_INFO_COPYPROT_ADDR (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_COPYPROT_O)
#define AM_HAL_FLASH_INFO_CUST_TRIM_ADDR (AM_HAL_FLASH_INFO_ADDR + 0x14)
//
// Define the customer info signature data (at AM_HAL_FLASH_INFO_ADDR).
// These bits must exist in the customer info space in order for many of the
// security and protection functions to work.
//
#define AM_HAL_FLASH_INFO_SIGNATURE0 0x48EAAD88
#define AM_HAL_FLASH_INFO_SIGNATURE1 0xC9705737
#define AM_HAL_FLASH_INFO_SIGNATURE2 0x0A6B8458
#define AM_HAL_FLASH_INFO_SIGNATURE3 0xE41A9D74
//
// Define the customer security bits (at AM_HAL_FLASH_INFO_SECURITY_ADDR)
//
#define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S 0
#define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S 1
#define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S 2
#define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S 3
#define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S 4
#define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S 8
#define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S 9
#define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S))
#define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S))
#define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S))
#define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S))
#define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M ((uint32_t)(0xF << AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S))
#define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S))
#define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
#define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP_M ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
#define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP ((uint32_t)(0x0 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
//
// Protection chunk macros
// AM_HAL_FLASH_INFO_CHUNK2ADDR: Convert a chunk number to an address
// AM_HAL_FLASH_INFO_CHUNK2INST: Convert a chunk number to an instance number
// AM_HAL_FLASH_INFO_ADDR2CHUNK: Convert an address to a chunk number
//
#define AM_HAL_FLASH_INFO_CHUNKSIZE (16*1024)
#define AM_HAL_FLASH_INFO_CHUNK2ADDR(n) (AM_HAL_FLASH_ADDR + (n << 14))
#define AM_HAL_FLASH_INFO_CHUNK2INST(n) ((n >> 5) & 1
#define AM_HAL_FLASH_INFO_ADDR2CHUNK(n) ((n) >> 14)
//*****************************************************************************
//
// Function prototypes for the helper functions
//
//*****************************************************************************
extern int am_hal_flash_mass_erase(uint32_t ui32ProgramKey, uint32_t ui32FlashInst);
extern int am_hal_flash_page_erase(uint32_t ui32ProgramKey, uint32_t ui32FlashInst,
uint32_t ui32PageNum);
extern int am_hal_flash_program_main(uint32_t ui32ProgramKey, uint32_t *pSrc,
uint32_t *pDst, uint32_t NumberOfWords);
//
// Recovery type functions for Customer INFO space.
//
extern int am_hal_flash_program_info(uint32_t ui32InfoKey, uint32_t ui32InfoInst,
uint32_t *pui32Src, uint32_t ui32Offset,
uint32_t ui32NumWords);
extern int am_hal_flash_erase_info(uint32_t ui32InfoKey,
uint32_t ui32Instance);
extern int am_hal_flash_erase_main_plus_info(uint32_t ui32InfoKey,
uint32_t ui32Instance);
extern int am_hal_flash_erase_main_plus_info_both_instances(
uint32_t ui32InfoKey);
extern void am_hal_flash_recovery(uint32_t ui32RecoveryKey);
//
// This function safely writes to a peripheral or memory address while executing
// from SRAM, thus avoiding any conflict with flash or INFO space.
//
extern void am_hal_flash_store_ui32(uint32_t *pui32Address, uint32_t ui32Data);
//
// BOOTROM resident reader, writer and delay utility functions.
//
extern uint32_t am_hal_flash_load_ui32(uint32_t *pui32Address);
extern void am_hal_flash_delay(uint32_t ui32Iterations);
extern uint32_t am_hal_flash_delay_status_change(uint32_t ui32Iterations,
uint32_t ui32Address,
uint32_t ui32Mask,
uint32_t ui32Value);
extern uint32_t am_hal_flash_delay_status_check(uint32_t ui32Iterations,
uint32_t ui32Address,
uint32_t ui32Mask,
uint32_t ui32Value,
bool bIsEqual);
//
// These functions update security/protection bits in the customer INFO blOCK.
//
extern bool am_hal_flash_customer_info_signature_check(void);
extern bool am_hal_flash_info_signature_set(uint32_t ui32InfoKey);
extern int32_t am_hal_flash_info_erase_disable(uint32_t ui32InfoKey);
extern bool am_hal_flash_info_erase_disable_check(void);
extern int32_t am_hal_flash_info_program_disable(uint32_t ui32InfoKey, uint32_t ui32Mask);
extern uint32_t am_hal_flash_info_program_disable_get(void);
extern int32_t am_hal_flash_wipe_flash_enable(uint32_t ui32InfoKey);
extern bool am_hal_flash_wipe_flash_enable_check(void);
extern int32_t am_hal_flash_wipe_sram_enable(uint32_t ui32InfoKey);
extern bool am_hal_flash_wipe_sram_enable_check(void);
extern int32_t am_hal_flash_swo_disable(uint32_t ui32InfoKey);
extern bool am_hal_flash_swo_disable_check(void);
extern int32_t am_hal_flash_debugger_disable(uint32_t ui32InfoKey);
extern bool am_hal_flash_debugger_disable_check(void);
extern int32_t am_hal_flash_copy_protect_set(uint32_t ui32InfoKey,
uint32_t *pui32StartAddress,
uint32_t *pui32StopAddress);
extern bool am_hal_flash_copy_protect_check(uint32_t *pui32StartAddress,
uint32_t *pui32StopAddress);
extern int32_t am_hal_flash_write_protect_set(uint32_t ui32InfoKey,
uint32_t *pui32StartAddress,
uint32_t *pui32StopAddress);
extern bool am_hal_flash_write_protect_check(uint32_t *pui32StartAddress,
uint32_t *pui32StopAddress);
extern int am_hal_flash_clear_bits(uint32_t ui32ProgramKey,
uint32_t *pui32Addr,
uint32_t ui32BitMask);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_FLASH_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,77 @@
//*****************************************************************************
//
// am_hal_global.c
//! @file
//!
//! @brief Locate global variables here.
//!
//! This module contains global variables that are used throughout the HAL.
//!
//! One use in particular is that it uses a global HAL flags variable that
//! contains flags used in various parts of the HAL.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Global Variables
//
//*****************************************************************************
uint32_t volatile g_ui32HALflags = 0x00000000;
//*****************************************************************************
//
// Version information
//
//*****************************************************************************
const uint8_t g_ui8HALcompiler[] = COMPILER_VERSION;
const am_hal_version_t g_ui32HALversion =
{
.s.bAMREGS = false,
.s.Major = AM_HAL_VERSION_MAJ,
.s.Minor = AM_HAL_VERSION_MIN,
.s.Revision = AM_HAL_VERSION_REV
};
@@ -0,0 +1,166 @@
//*****************************************************************************
//
// am_hal_global.h
//! @file
//!
//! @brief Locate all HAL global variables here.
//!
//! This module contains global variables that are used throughout the HAL,
//! but not necessarily those designated as const (which typically end up in
//! flash). Consolidating globals here will make it easier to manage them.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_GLOBAL_H
#define AM_HAL_GLOBAL_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Include the SDK global version information.
//
//*****************************************************************************
#include "../../am_sdk_version.h"
//*****************************************************************************
//
// Device definitions
//
//*****************************************************************************
#define AM_HAL_DEVICE_NAME "Apollo3 Blue"
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
// Utility for compile time assertions
// Will cause divide by 0 error at build time
#define _AM_ASSERT_CONCAT_(a, b) a##b
#define _AM_ASSERT_CONCAT(a, b) _AM_ASSERT_CONCAT_(a, b)
#define am_ct_assert(e) enum { _AM_ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
//*****************************************************************************
//
// Macros to determine compiler version information
//
//*****************************************************************************
//
// Since the stringize operator itself does not first expand macros, two levels
// of indirection are required in order to fully resolve the pre-defined
// compiler (integer) macros. The 1st level expands the macro, and the 2nd
// level actually stringizes it.
// This method will also work even if the argument is not a macro. However, if
// the argument is already a string, the string will end up with inserted quote
// marks.
//
#define STRINGIZE_VAL(n) STRINGIZE_VAL2(n)
#define STRINGIZE_VAL2(n) #n
#ifdef __GNUC__
#define COMPILER_VERSION ("GCC " __VERSION__)
#elif defined(__ARMCC_VERSION)
#define COMPILER_VERSION ("ARMCC " STRINGIZE_VAL(__ARMCC_VERSION))
#elif defined(__KEIL__)
#define COMPILER_VERSION "KEIL_CARM " STRINGIZE_VAL(__CA__)
#elif defined(__IAR_SYSTEMS_ICC__)
#define COMPILER_VERSION __VERSION__
#else
#define COMPILER_VERSION "Compiler unknown"
#endif
//*****************************************************************************
//
// Utility Macros
//
//*****************************************************************************
// As long as the two values are not apart by more that 2^31, this should give
// correct result, taking care of wraparound
#define AM_HAL_U32_GREATER(val1, val2) ((int32_t)((int32_t)(val1) - (int32_t)(val2)) > 0)
#define AM_HAL_U32_SMALLER(val1, val2) ((int32_t)((int32_t)(val1) - (int32_t)(val2)) < 0)
//******************************************************************************
//
// Global typedefs
//
//******************************************************************************
typedef union
{
uint32_t u32;
struct
{
uint32_t resvd : 7; // [6:0]
uint32_t bAMREGS : 1; // [7]
uint32_t Revision : 8; // [15:8]
uint32_t Minor : 8; // [23:16]
uint32_t Major : 8; // [31:24]
} s;
} am_hal_version_t;
typedef union
{
uint32_t u32;
struct
{
uint32_t magic : 24;
uint32_t bInit : 1;
uint32_t bEnable : 1;
uint32_t resv : 6;
} s;
} am_hal_handle_prefix_t;
//*****************************************************************************
//
// Global Variables extern declarations.
//
//*****************************************************************************
extern volatile uint32_t g_ui32HALflags;
extern const uint8_t g_ui8HALcompiler[];
extern const am_hal_version_t g_ui32HALversion;
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_GLOBAL_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,882 @@
//*****************************************************************************
//
// am_hal_gpio.h
//! @file
//!
//! @brief Functions for accessing and configuring the GPIO module.
//!
//! @addtogroup gpio3 GPIO
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_GPIO_H
#define AM_HAL_GPIO_H 1
#ifdef __cplusplus
extern "C"
{
#endif
//
// Designate this peripheral.
//
#define AM_APOLLO3_GPIO 1
//
// Maximum number of GPIOs on this device
//
#define AM_HAL_GPIO_MAX_PADS (50)
#define AM_HAL_GPIO_NUMWORDS ((AM_HAL_GPIO_MAX_PADS + 31) / 32)
//
//! Macros to assist with defining a GPIO mask given a GPIO number.
//!
//! IMPORTANT: AM_HAL_GPIO_BIT(n) is DEPRECATED and is provided only for
//! backward compatibility. It is replaced with AM_HAL_GPIO_MASKBIT().
//
#define AM_HAL_GPIO_BIT(n) (((uint64_t) 0x1) << n) /* DEPRECATED, PLEASE USE AM_HAL_GPIO_MASKBIT() */
//!
//! The following macros ensure forward compatibility with future SDK releases.
//! They should be used, in lieu of AM_HAL_GPIO_BIT(), when creating bitmasks
//! for GPIO interrupts.
//! AM_HAL_GPIO_MASKCREATE()
//! AM_HAL_GPIO_MASKBIT()
//!
#define AM_HAL_GPIO_MASKCREATE(sMaskNm) uint64_t p##sMaskNm=0
//! AM_HAL_GPIO_MASKCREATE() should be used before AM_HAL_GPIO_MASKBIT() to
//! ensure forward compatibility. In future releases it will allocate and
//! initialize a bitmask structure used in the various GPIO interrupt functions.
//!
// Implented as an inline function below.
//#define AM_HAL_GPIO_MASKBIT(psMaskNm, n) (psMaskNm |= (((uint64_t) 0x1) << n))
#define AM_HAL_GPIO_MASKBIT(psMaskNm, n) psMaskNm |= (((uint64_t) 0x1) << n)
//! AM_HAL_GPIO_MASKBIT(psMaskNm, n)
//! Support macros for use with AM_HAL_GPIO_MASKBIT().
//! AM_HAL_GPIO_MASKCREATE()
//! AM_HAL_GPIO_MASKCLR()
//!
//! To set a single bit based on a pin number in an existing bitmask structure.
//! AM_HAL_GPIO_MASKBIT(pGpioIntMask, n)
//! where n is the desired GPIO bit number.
//! Note - this usage is analogous to the deprecated AM_HAL_GPIO_BIT(n).
//!
#define AM_HAL_GPIO_MASKCLR(psMaskNm)
//! AM_HAL_GPIO_MASKCLR()
//! Clear an existing GpioIntMask bitmask structure.
//! Note that AM_HAL_GPIO_MASKCREATE() clears the bitmask struct on creation.
//! IMPORTANT - The AM_HAL_GPIO_MASKCLR() macro does not operate on any hardware
//! or register. It is used for initializing/clearing the memory allocated for
//! the bitmask structure.
//!
//! // Usage example for any Apollo device:
//! // Create a GPIO interrupt bitmask structure named GpioIntMask, initialize
//! // that structure, and create a ptr to that structure named pGpioIntMask.
//! // Then use that structure to pass a bitmask to the interrupt function.
//! AM_HAL_GPIO_MASKCREATE(GpioIntMask);
//! am_hal_gpio_interrupt_clear(AM_HAL_GPIO_MASKBIT(pGpioIntMask));
//!
//*****************************************************************************
//!
//! Structure for defining bitmasks used in the interrupt functions.
//!
//*****************************************************************************
typedef struct // Future use - not currently used for Apollo3.
{
union
{
volatile uint32_t Msk[AM_HAL_GPIO_NUMWORDS];
struct
{
volatile uint32_t b0: 1;
volatile uint32_t b1: 1;
volatile uint32_t b2: 1;
volatile uint32_t b3: 1;
volatile uint32_t b4: 1;
volatile uint32_t b5: 1;
volatile uint32_t b6: 1;
volatile uint32_t b7: 1;
volatile uint32_t b8: 1;
volatile uint32_t b9: 1;
volatile uint32_t b10: 1;
volatile uint32_t b11: 1;
volatile uint32_t b12: 1;
volatile uint32_t b13: 1;
volatile uint32_t b14: 1;
volatile uint32_t b15: 1;
volatile uint32_t b16: 1;
volatile uint32_t b17: 1;
volatile uint32_t b18: 1;
volatile uint32_t b19: 1;
volatile uint32_t b20: 1;
volatile uint32_t b21: 1;
volatile uint32_t b22: 1;
volatile uint32_t b23: 1;
volatile uint32_t b24: 1;
volatile uint32_t b25: 1;
volatile uint32_t b26: 1;
volatile uint32_t b27: 1;
volatile uint32_t b28: 1;
volatile uint32_t b29: 1;
volatile uint32_t b30: 1;
volatile uint32_t b31: 1;
volatile uint32_t b32: 1;
volatile uint32_t b33: 1;
volatile uint32_t b34: 1;
volatile uint32_t b35: 1;
volatile uint32_t b36: 1;
volatile uint32_t b37: 1;
volatile uint32_t b38: 1;
volatile uint32_t b39: 1;
volatile uint32_t b40: 1;
volatile uint32_t b41: 1;
volatile uint32_t b42: 1;
volatile uint32_t b43: 1;
volatile uint32_t b44: 1;
volatile uint32_t b45: 1;
volatile uint32_t b46: 1;
volatile uint32_t b47: 1;
volatile uint32_t b48: 1;
volatile uint32_t b49: 1;
volatile uint32_t brsvd: 14; // Pad out to the next full word
} Msk_b;
} U;
} am_hal_gpio_mask_t;
//*****************************************************************************
//!
//! Read types for am_hal_gpio_state_read().
//!
//*****************************************************************************
typedef enum
{
AM_HAL_GPIO_INPUT_READ,
AM_HAL_GPIO_OUTPUT_READ,
AM_HAL_GPIO_ENABLE_READ
} am_hal_gpio_read_type_e;
//*****************************************************************************
//!
//! Write types for am_hal_gpio_state_write().
//!
//*****************************************************************************
typedef enum
{
AM_HAL_GPIO_OUTPUT_CLEAR,
AM_HAL_GPIO_OUTPUT_SET,
AM_HAL_GPIO_OUTPUT_TOGGLE,
AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE,
AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE,
AM_HAL_GPIO_OUTPUT_TRISTATE_TOGGLE
} am_hal_gpio_write_type_e;
//*****************************************************************************
//!
//! Types for ui32GpioCfg bitfields in am_hal_gpio_pinconfig().
//!
//*****************************************************************************
//!
//! Power Switch configuration: am_hal_gpio_pincfg_t.ePowerSw enums
//!
typedef enum
{
AM_HAL_GPIO_PIN_POWERSW_NONE,
AM_HAL_GPIO_PIN_POWERSW_VDD,
AM_HAL_GPIO_PIN_POWERSW_VSS,
AM_HAL_GPIO_PIN_POWERSW_INVALID,
} am_hal_gpio_powersw_e;
//!
//! Pullup configuration: am_hal_gpio_pincfg_t.ePullup enums
//!
typedef enum
{
//
//! Define pullup enums.
//! The 1.5K - 24K pullup values are valid for select I2C enabled pads.
//! For Apollo3 these pins are 0-1,5-6,8-9,25,27,39-40,42-43,48-49.
//! The "weak" value is used for almost every other pad except pin 20.
//
AM_HAL_GPIO_PIN_PULLUP_NONE = 0x00,
AM_HAL_GPIO_PIN_PULLUP_WEAK,
AM_HAL_GPIO_PIN_PULLUP_1_5K,
AM_HAL_GPIO_PIN_PULLUP_6K,
AM_HAL_GPIO_PIN_PULLUP_12K,
AM_HAL_GPIO_PIN_PULLUP_24K,
AM_HAL_GPIO_PIN_PULLDOWN
} am_hal_gpio_pullup_e;
//!
//! Pad Drive Strength configuration: am_hal_gpio_pincfg_t.eDriveStrength enums
//!
typedef enum
{
//
//! DRIVESTRENGTH is a 2-bit field.
//! bit0 maps to bit2 of a PADREG field.
//! bit1 maps to bit0 of an ALTPADCFG field.
//
AM_HAL_GPIO_PIN_DRIVESTRENGTH_2MA = 0x0,
AM_HAL_GPIO_PIN_DRIVESTRENGTH_4MA = 0x1,
AM_HAL_GPIO_PIN_DRIVESTRENGTH_8MA = 0x2,
AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA = 0x3
} am_hal_gpio_drivestrength_e;
//!
//! OUTCFG pad configuration: am_hal_gpio_pincfg_t.eGPOutcfg enums
//! Applies only to GPIO configured pins.
//! Ultimately maps to GPIOCFG.OUTCFG, bits [2:1].
//!
typedef enum
{
AM_HAL_GPIO_PIN_OUTCFG_DISABLE = 0x0,
AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL = 0x1,
AM_HAL_GPIO_PIN_OUTCFG_OPENDRAIN = 0x2,
AM_HAL_GPIO_PIN_OUTCFG_TRISTATE = 0x3
} am_hal_gpio_outcfg_e;
//!
//! GPIO input configuration: am_hal_gpio_pincfg_t.eGPInput enums
//! Applies only to GPIO configured pins!
//! Ultimately maps to PADREG.INPEN, bit1.
//!
typedef enum
{
AM_HAL_GPIO_PIN_INPUT_AUTO = 0x0,
AM_HAL_GPIO_PIN_INPUT_NONE = 0x0,
AM_HAL_GPIO_PIN_INPUT_ENABLE = 0x1
} am_hal_gpio_input_e;
//!
//! GPIO interrupt direction configuration: am_hal_gpio_pincfg_t.eIntDir enums
//! Note: Setting INTDIR_NONE has the side-effect of disabling being able to
//! read a pin - the pin will always read back as 0.
//!
typedef enum
{
// Bit1 of these values maps to GPIOCFG.INCFG (b0).
// Bit0 of these values maps to GPIOCFG.INTD (b3).
AM_HAL_GPIO_PIN_INTDIR_LO2HI = 0x0,
AM_HAL_GPIO_PIN_INTDIR_HI2LO = 0x1,
AM_HAL_GPIO_PIN_INTDIR_NONE = 0x2,
AM_HAL_GPIO_PIN_INTDIR_BOTH = 0x3
} am_hal_gpio_intdir_e;
//!
//! am_hal_gpio_pincfg_t.eGPRdZero
//! For GPIO configurations (funcsel=3), the pin value can be read or 0 can be
//! forced as the read value.
//!
typedef enum
{
AM_HAL_GPIO_PIN_RDZERO_READPIN = 0x0,
AM_HAL_GPIO_PIN_RDZERO_ZERO = 0x1
} am_hal_gpio_readen_e;
//!
//! nCE polarity configuration: am_hal_gpio_pincfg_t.eCEpol enums
//!
typedef enum
{
AM_HAL_GPIO_PIN_CEPOL_ACTIVELOW = 0x0,
AM_HAL_GPIO_PIN_CEPOL_ACTIVEHIGH = 0x1
} am_hal_gpio_cepol_e;
//
// Apollo3 usage of bits [7:6] of a PADREG field:
// PULLUPs are available on pins: 0,1,5,6,8,9,25,27,39,40,42,43,48,49
// RESERVED on pins: 2,4,7,10-24,26,28-35,38,44-47
// VDD PWR on pins: 3, 36 (b7=0, b6=1)
// VSS PWR on pins: 37,41 (b7=1, b6=0)
//
//!
//! Define the am_hal_gpio_pinconfig() bitfield structure.
//! uFuncSel a value of 0-7 corresponding to the FNCSEL field of PADREG.
//! ePowerSw: Select pins can be set as a power source or sink.
//! ePullup: Select pins can enable a pullup of varying values.
//! eDriveStrength: Select pins can be set for varying drive strengths.
//! eGPOutcfg: GPIO pin only, corresponds to GPIOCFG.OUTCFG field.
//! eGPInput: GPIO pin only, corresponds to PADREG.INPEN.
//! eGPRdZero: GPIO read zero. Corresponds to GPIOCFG.INCFG.
//! eIntDir: Interrupt direction, l2h, h2l, both, none.
//! eGPRdZero: Read the pin value, or always read the pin as zero.
//! uIOMnum: nCE pin IOMnumber (0-5, or 6 for MSPI)
//! nNCE: Selects the SPI channel (CE) number (0-3)
//! eCEpol: CE polarity.
//!
typedef struct
{
uint32_t uFuncSel : 3; // [2:0] Function select (FUNCSEL)
uint32_t ePowerSw : 2; // [4:3] Pin is a power switch source (VCC) or sink (VSS)
uint32_t ePullup : 3; // [7:5] Pin will enable a pullup resistor
uint32_t eDriveStrength : 2; // [9:8] Pad strength designator
uint32_t eGPOutcfg : 2; // [11:10] OUTCFG (GPIO config only)
uint32_t eGPInput : 1; // [12:12] GPIO Input (GPIO config only)
uint32_t eIntDir : 2; // [14:13] Interrupt direction
uint32_t eGPRdZero : 1; // [15:15] GPIO read as zero
//
// The following descriptors designate the chip enable features of the
// pin being configured. If not a CE, these descriptors are ignored.
// uIOMnum is 0-5 for the IOMs, or 6 for MSPI, 7 is invalid.
//
uint32_t uIOMnum : 3; // [18:16] IOM number (0-5), 6 for MSPI
uint32_t uNCE : 2; // [20:19] NCE number (0-3).
uint32_t eCEpol : 1; // [21:21] NCE polarity.
uint32_t uRsvd22 : 10; // [31:22]
} am_hal_gpio_pincfg_t;
typedef struct
{
uint16_t uFuncSel : 1;
uint16_t ePowerSw : 1;
uint16_t ePullup : 1;
uint16_t eDriveStrength : 1;
uint16_t eGPOutcfg : 1;
uint16_t eGPInput : 1;
uint16_t eIntDir : 1;
uint16_t eGPRdZero : 1;
uint16_t uIOMnum : 1;
uint16_t uNCE : 1;
uint16_t eCEpol : 1;
uint16_t _reserved : 5;
} am_hal_gpio_pincfg_allow_t;
#define IOMNUM_MSPI 6
#define IOMNUM_MAX IOMNUM_MSPI
//
// Define shift and width values for the above bitfields.
// - C bitfields do not provide shift, width, or mask values.
// - Shift values are generally compiler specific. However for IAR, Keil, and
// GCC, the bitfields are all exactly as defined in the above structure.
// - These defines should be used sparingly.
//
#define UFUNCSEL_S 0
#define EPOWERSW_S 3
#define EPULLUP_S 5
#define EDRVSTR_S 8
#define EGPOUTCFG_S 10
#define EGPINPUT_S 12
#define EINTDIR_S 13
#define UIOMNUM_S 16
#define UNCE_S 19
#define ECEPOL_S 21
#define UFUNCSEL_W 3
#define EPOWERSW_W 2
#define EPULLUP_W 3
#define EDRVSTR_W 2
#define EGPOUTCFG_W 2
#define EGPINPUT_W 1
#define EINTDIR_W 2
#define UIOMNUM_W 3
#define UNCE_W 2
#define ECEPOL_W 1
//!
//! Define GPIO error codes that are returned by am_hal_gpio_pinconfig().
//!
enum am_hal_gpio_pincfgerr
{
AM_HAL_GPIO_ERR_PULLUP = (AM_HAL_STATUS_MODULE_SPECIFIC_START + 0x100),
AM_HAL_GPIO_ERR_PULLDOWN,
AM_HAL_GPIO_ERR_PWRSW,
AM_HAL_GPIO_ERR_INVCE,
AM_HAL_GPIO_ERR_INVCEPIN,
AM_HAL_GPIO_ERR_PULLUPENUM
};
//*****************************************************************************
//
// Globals
//
//*****************************************************************************
//*****************************************************************************
// Define some common GPIO pin configurations.
//*****************************************************************************
//! Basics
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_DISABLE;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_TRISTATE;
//! Input variations
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT;
//! Input with various pullups (weak, 1.5K, 6K, 12K, 24K)
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_1_5;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_6;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_12;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLUP_24;
//! Output variations
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_4;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_8;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_12;
extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_OUTPUT_WITH_READ;
//*****************************************************************************
//
// Function pointer type for GPIO interrupt handlers.
//
//*****************************************************************************
typedef void (*am_hal_gpio_handler_t)(void);
typedef void (*am_hal_gpio_handler_adv_t)(void *);
//*****************************************************************************
//
//! @brief Configure an Apollo3 pin.
//!
//! @param ui32Pin - pin number to be configured.
//! @param ui32GpioCfg - Contains multiple descriptor fields.
//!
//! This function configures a pin according to the descriptor parameters as
//! passed in sPinCfg. All parameters are validated with regard to each
//! other and according to the requested function. Once the parameters and
//! settings have been confirmed, the pin is configured accordingly.
//!
//! @return Status.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_pinconfig(uint32_t ui32Pin,
am_hal_gpio_pincfg_t sPincfg);
//*****************************************************************************
//
//! @brief Configure specified pins for FAST GPIO operation.
//!
//! @param ui64PinMask - a mask specifying up to 8 pins to be configured and
//! used for FAST GPIO (only bits 0-49 are valid).
//! @param bfGpioCfg - The GPIO configuration (same as am_hal_gpio_pinconfig()).
//! All of the pins specified by ui64PinMask will be set to this
//! configuration.
//! @param ui32Masks - If NULL, not used. Otherwise if provided, an array to
//! receive two 32-bit values, per pin, of the SET and CLEAR
//! masks that can be used for the BBSETCLEAR register.
//! The two 32-bit values will be placed at incremental indexes.
//! For example, say pin numbers 5 and 19 are indicated in the
//! mask, and an array pointer is provided in ui32Masks. This
//! array must be allocated by the caller to be at least 4 wds.
//! ui32Masks[0] = the set mask used for pin 5.
//! ui32Masks[1] = the clear mask used for pin 5.
//! ui32Masks[2] = the set mask used for pin 19.
//! ui32Masks[3] = the clear mask used for pin 19.
//!
//! @return Status.
//!
//! Fast GPIO helper macros:
//! am_hal_gpio_fastgpio_set(n) - Sets the value for pin number 'n'.
//! am_hal_gpio_fastgpio_clr(n) - Clear the value for pin number 'n'.
//!
//! am_hal_gpio_fastgpio_enable(n) - Enable Fast GPIO on pin 'n'.
//! am_hal_gpio_fastgpio_disable(n) - Disable Fast GPIO on pin 'n'.
//!
//! Note - The enable and disable macros assume the pin has already been
//! configured. Once disabled, the state of the pin will revert to the
//! state of the normal GPIO configuration for that pin.
//!
//! NOTES on pin configuration:
//! - To avoid glitches on the pin, it is strongly recommended that before
// calling am_hal_gpio_fast_pinconfig() that am_hal_gpio_fastgpio_disable()
//! first be called to make sure that Fast GPIO is disabled before config.
//! - If the state of the pin is important, preset the value of the pin to the
//! desired value BEFORE calling am_hal_gpio_fast_pinconfig(). The set and
//! clear macros shown above can be used for this purpose.
//!
//! NOTES on general use of Fast GPIO:
//! Fast GPIO input or output will not work if the pin is configured as
//! tristate. The overloaded OUTPUT ENABLE control is used for enabling both
//! modes, so Apollo3 logic specifically disallows Fast GPIO input or output
//! when the pin is configured for tristate mode.
//! Fast GPIO input can be used for pushpull, opendrain, or disable modes.
//!
//! Fast GPIO pin groupings:
//! The FaST GPIO pins are grouped across a matrix of pins. Each
//! row of pins is controlled by a single data bit.
//!
//! Referring to the below chart:
//! If pin 35 were configured for Fast GPIO output, it would be set
//! when bit3 of BBSETCLEAR.SET was written with a 1.
//! It would be cleared when bit3 of BBSETCLEAR.CLEAR was written with 1.
//!
//! Note that if all the pins in a row were configured for Fast GPIO output,
//! all the pins would respond to set/clear.
//!
//! Input works in a similar fashion.
//!
//! BIT PIN controlled
//! --- ---------------------------
//! 0 0 8 16 24 32 40 48
//! 1 1 9 17 25 33 41 49
//! 2 2 10 18 26 34 42
//! 3 3 11 19 27 35 43
//! 4 4 12 20 28 36 44
//! 5 5 13 21 29 37 45
//! 6 6 14 22 30 38 46
//! 7 7 15 23 31 39 47
//!
//
//*****************************************************************************
extern uint32_t am_hal_gpio_fast_pinconfig(uint64_t ui64PinMask,
am_hal_gpio_pincfg_t bfGpioCfg,
uint32_t ui32Masks[]);
//*****************************************************************************
//
//! @brief Read GPIO.
//!
//! @param ui32Pin - pin number to be read.
//! @param eReadType - State type to read. One of:
//! AM_HAL_GPIO_INPUT_READ
//! AM_HAL_GPIO_OUTPUT_READ
//! AM_HAL_GPIO_ENABLE_READ
//!
//! This function reads a pin state as given by eReadType.
//!
//! @return Status.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_state_read(uint32_t ui32Pin,
am_hal_gpio_read_type_e eReadType,
uint32_t *pu32RetVal);
//*****************************************************************************
//
//! @brief Write GPIO.
//!
//! @param ui32Pin - pin number to be read.
//!
//! @param eWriteType - State type to write. One of:
//! AM_HAL_GPIO_OUTPUT_SET - Write a one to a GPIO.
//! AM_HAL_GPIO_OUTPUT_CLEAR - Write a zero to a GPIO.
//! AM_HAL_GPIO_OUTPUT_TOGGLE - Toggle the GPIO value.
//! The following two apply when output is set for TriState (OUTCFG==3).
//! AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE - Enable a tri-state GPIO.
//! AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE - Disable a tri-state GPIO.
//!
//! This function writes a GPIO value.
//!
//! @return Status.
//! Fails if the pad is not configured for GPIO (PADFNCSEL != 3).
//
//*****************************************************************************
extern uint32_t am_hal_gpio_state_write(uint32_t ui32Pin,
am_hal_gpio_write_type_e eWriteType);
//*****************************************************************************
//
//! @brief Enable GPIO interrupts.
//!
//! @param ui64InterruptMask - Mask of GPIO interrupts to enable.
//! Only bits 0-49 are valid in the mask.
//!
//! @return Status.
//! Fails if any bit above bit49 is set in ui64InterruptMask.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_interrupt_enable(uint64_t ui64InterruptMask);
//*****************************************************************************
//
//! @brief Disable GPIO interrupts.
//!
//! @param ui64InterruptMask - Mask of GPIO interrupts to disable.
//! Only bits 0-49 are valid in the mask.
//!
//! @return Status.
//! Fails if any bit above bit49 is set in ui64InterruptMask.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_interrupt_disable(uint64_t ui64InterruptMask);
//*****************************************************************************
//
//! @brief Clear GPIO interrupts.
//!
//! @param ui64InterruptMask - Mask of GPIO interrupts to be cleared.
//! Only bits 0-49 are valid in the mask.
//!
//! @return Status.
//! Fails if any bit above bit49 is set in ui64InterruptMask.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_interrupt_clear(uint64_t ui64InterruptMask);
//*****************************************************************************
//
//! @brief Get GPIO interrupt status.
//!
//! @param bEnabledOnly - Return status only for currently enabled interrupts.
//!
//! @param pui64IntStatus - 64-bit variable to return a bitmask of the status
//! of the interrupts.
//!
//! @return Status.
//! Fails if pui64IntStatus is NULL.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_interrupt_status_get(bool bEnabledOnly,
uint64_t *pui64IntStatus);
//*****************************************************************************
//
//! @brief GPIO interrupt service routine registration.
//!
//! @param ui32GPIONumber - GPIO number (0-49) to be registered.
//!
//! @param pfnHandler - Function pointer to the callback.
//!
//! @return Status.
//! Fails if pfnHandler is NULL or ui32GPIONumber > 49.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_interrupt_register(uint32_t ui32GPIONumber,
am_hal_gpio_handler_t pfnHandler);
//*****************************************************************************
//
//! @brief Advanced GPIO interrupt service routine registration.
//!
//! @param ui32GPIONumber - GPIO number (0-49) to be registered.
//!
//! @param pfnHandler - Function pointer to the callback.
//!
//! @param pCtxt - context for the callback.
//!
//! @return Status.
//! Fails if pfnHandler is NULL or ui32GPIONumber > 49.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_interrupt_register_adv(uint32_t ui32GPIONumber,
am_hal_gpio_handler_adv_t pfnHandler, void *pCtxt);
//*****************************************************************************
//
// GPIO interrupt service routine.
//! @brief GPIO interrupt service routine registration.
//!
//! @param ui64Status - Mask of the interrupt(s) to be serviced. This mask is
//! typically obtained via a call to am_hal_gpio_interrupt_status_get().
//!
//! The intended use is that the application first registers a handler for a
//! particular GPIO via am_hal_gpio_interrupt_register(), and to supply the
//! main ISR, am_gpio_isr().
//!
//! On a GPIO interrupt, am_gpio_isr() calls am_hal_gpio_interrupt_status_get()
//! and provides the return value to this function.
//!
//! In the event that multiple GPIO interrupts are active, the corresponding
//! interrupt handlers will be called in numerical order by GPIO number
//! starting with the lowest GPIO number.
//!
//! @return Status.
//! AM_HAL_STATUS_INVALID_OPERATION if no handler had been registered
//! for any of the GPIOs that caused the interrupt.
//! AM_HAL_STATUS_OUT_OF_RANGE if any bit above bit49 is set.
//! AM_HAL_STATUS_FAIL if ui64Status is 0.
//! AM_HAL_STATUS_SUCCESS otherwise.
//
//*****************************************************************************
extern uint32_t am_hal_gpio_interrupt_service(uint64_t ui64Status);
//*****************************************************************************
//
//! @brief Macros to read GPIO values in an optimized manner.
//!
//! @param n - The GPIO number to be read.
//!
//! In almost all cases, it is reasonable to use am_hal_gpio_state_read() to
//! read GPIO values with all of the inherent error checking, critical
//! sectioning, and general safety.
//!
//! However, occasionally there is a need to read a GPIO value in an optimized
//! manner. These 3 macros will accomplish that. Each macro will return a
//! value of 1 or 0.
//!
//! Note that the macros are named as lower-case counterparts to the
//! enumerations for the am_hal_gpio_state_read() function. That is:
//!
//! AM_HAL_GPIO_INPUT_READ -> am_hal_gpio_input_read(n)
//! AM_HAL_GPIO_OUTPUT_READ -> am_hal_gpio_output_read(n)
//! AM_HAL_GPIO_ENABLE_READ -> am_hal_gpio_enable_read(n)
//!
//! @return Each macro will return a 1 or 0 per the value of the requested GPIO.
//!
//
//*****************************************************************************
#define am_hal_gpio_input_read(n) ( \
(AM_REGVAL( (AM_REGADDR(GPIO, RDA) + (((uint32_t)(n) & 0x20) >> 3)) ) >> /* Read appropriate register */ \
((uint32_t)(n) & 0x1F) ) & /* Shift by appropriate number of bits */ \
((uint32_t)0x1) ) /* Mask out the LSB */
#define am_hal_gpio_output_read(n) ( \
(AM_REGVAL( (AM_REGADDR(GPIO, WTA) + (((uint32_t)(n) & 0x20) >> 3)) ) >> /* Read appropriate register */ \
((uint32_t)(n) & 0x1F) ) & /* Shift by appropriate number of bits */ \
((uint32_t)0x1) ) /* Mask out the LSB */
#define am_hal_gpio_enable_read(n) ( \
(AM_REGVAL( (AM_REGADDR(GPIO, ENA) + (((uint32_t)(n) & 0x20) >> 3)) ) >> /* Read appropriate register */ \
((uint32_t)(n) & 0x1F) ) & /* Shift by appropriate number of bits */ \
((uint32_t)0x1) ) /* Mask out the LSB */
//*****************************************************************************
//
//! @brief Macros to write GPIO values in an optimized manner.
//!
//! @param n - The GPIO number to be written.
//!
//! In almost all cases, it is reasonable to use am_hal_gpio_state_write() to
//! write GPIO values with all of the inherent error checking, critical
//! sectioning, and general safety.
//!
//! However, occasionally there is a need to write a GPIO value in an optimized
//! manner. These 3 macros will accomplish that.
//!
//! Note that the macros are named as lower-case counterparts to the
//! enumerations for the am_hal_gpio_state_read() function. That is:
//!
//! AM_HAL_GPIO_OUTPUT_CLEAR -> am_hal_gpio_output_clear(n,v)
//! AM_HAL_GPIO_OUTPUT_SET -> am_hal_gpio_output_set(n,v)
//! AM_HAL_GPIO_OUTPUT_TOGGLE -> am_hal_gpio_output_toggle(n,v)
//! AM_HAL_GPIO_OUTPUT_TRISTATE_DISABLE -> am_hal_gpio_output_tristate_disable(n,v)
//! AM_HAL_GPIO_OUTPUT_TRISTATE_ENABLE -> am_hal_gpio_output_tristate_enable(n,v)
//! AM_HAL_GPIO_OUTPUT_TRISTATE_TOGGLE -> am_hal_gpio_output_toggle(n,v)
//!
//! @return None.
//!
//*****************************************************************************
//
// Note - these macros use byte-oriented addressing.
//
#define am_hal_gpio_output_clear(n) \
((*((volatile uint32_t *) \
((AM_REGADDR(GPIO, WTCA) + (((uint32_t)(n) & 0x20) >> 3))))) = \
((uint32_t) 0x1 << ((uint32_t)(n) % 32)))
#define am_hal_gpio_output_set(n) \
((*((volatile uint32_t *) \
((AM_REGADDR(GPIO, WTSA) + (((uint32_t)(n) & 0x20) >> 3))))) = \
((uint32_t) 0x1 << ((uint32_t)(n) % 32)))
#define am_hal_gpio_output_toggle(n) \
if ( 1 ) \
{ \
AM_CRITICAL_BEGIN \
((*((volatile uint32_t *) \
((AM_REGADDR(GPIO, WTA) + (((uint32_t)(n) & 0x20) >> 3))))) ^= \
((uint32_t) 0x1 << ((uint32_t)(n) % 32))); \
AM_CRITICAL_END \
}
#define am_hal_gpio_output_tristate_disable(n) \
((*((volatile uint32_t *) \
((AM_REGADDR(GPIO, ENCA) + (((uint32_t)(n) & 0x20) >> 3))))) = \
((uint32_t) 0x1 << ((uint32_t)(n) % 32)))
#define am_hal_gpio_output_tristate_enable(n) \
((*((volatile uint32_t *) \
((AM_REGADDR(GPIO, ENSA) + (((uint32_t)(n) & 0x20) >> 3))))) = \
((uint32_t) 0x1 << ((uint32_t)(n) % 32)))
#define am_hal_gpio_output_tristate_toggle(n) \
if ( 1 ) \
{ \
AM_CRITICAL_BEGIN \
((*((volatile uint32_t *) \
((AM_REGADDR(GPIO, ENA) + (((uint32_t)(n) & 0x20) >> 3))))) ^= \
((uint32_t) 0x1 << ((uint32_t)(n) % 32))); \
AM_CRITICAL_END \
}
//*****************************************************************************
//!
//! @brief Fast GPIO helper macros.
//!
//*****************************************************************************
//
// Define Fast GPIO enable and disable.
//
#define am_hal_gpio_fastgpio_enable(n) am_hal_gpio_output_tristate_enable(n)
#define am_hal_gpio_fastgpio_disable(n) am_hal_gpio_output_tristate_disable(n)
//
// Macros for accessing Fast GPIO: set, clear, and read.
// The 'n' parameter is the pin number.
// Note - these macros are most efficient if 'n' is a constant value, and
// of course when compiled with -O3.
//
#define am_hal_gpio_fastgpio_read(n) ((APBDMA->BBINPUT >> (n & 0x7)) & 0x1)
#define am_hal_gpio_fastgpio_set(n) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_SET, (1 << (n & 0x7))))
#define am_hal_gpio_fastgpio_clr(n) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_CLEAR, (1 << (n & 0x7))))
#define am_hal_gpio_fastgpio_setmsk(m) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_SET, m))
#define am_hal_gpio_fastgpio_clrmsk(m) (APBDMA->BBSETCLEAR = _VAL2FLD(APBDMA_BBSETCLEAR_CLEAR, m))
#define am_hal_gpio_fastgpio_wrval(val) (APBDMA->BBSETCLEAR = \
(_VAL2FLD(APBDMA_BBSETCLEAR_SET, val) | \
_VAL2FLD(APBDMA_BBSETCLEAR_CLEAR, val ^ 0xFF)))
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_GPIO_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,224 @@
//*****************************************************************************
//
// am_hal_interrupt.c
//! @file
//!
//! @brief Helper functions supporting interrupts and NVIC operation.
//!
//! These functions may be used for NVIC-level interrupt configuration.
//!
//! @addtogroup interrupt3 Interrupt (ARM NVIC support functions)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
//! @brief Globally enable interrupt service routines
//!
//! This function allows interrupt signals from the NVIC to trigger ISR entry
//! in the CPU. This function must be called if interrupts are to be serviced
//! in software.
//!
//! @return 1 if interrupts were previously disabled, 0 otherwise.
//
//*****************************************************************************
#if (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION < 6000000)
__asm uint32_t
am_hal_interrupt_master_enable(void)
{
mrs r0, PRIMASK
cpsie i
bx lr
}
#elif (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION >= 6000000)
uint32_t __attribute__((naked))
am_hal_interrupt_master_enable(void)
{
__asm(" mrs r0, PRIMASK");
__asm(" cpsie i");
__asm(" bx lr");
}
#elif defined(__GNUC_STDC_INLINE__)
uint32_t __attribute__((naked))
am_hal_interrupt_master_enable(void)
{
__asm(" mrs r0, PRIMASK");
__asm(" cpsie i");
__asm(" bx lr");
}
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing
// return statement on a non-void function
__stackless uint32_t
am_hal_interrupt_master_enable(void)
{
__asm(" mrs r0, PRIMASK");
__asm(" cpsie i");
__asm(" bx lr");
}
#pragma diag_default = Pe940 // Restore IAR compiler warning
#else
#error Compiler is unknown, please contact Ambiq support team
#endif
//*****************************************************************************
//
//! @brief Globally disable interrupt service routines
//!
//! This function prevents interrupt signals from the NVIC from triggering ISR
//! entry in the CPU. This will effectively stop incoming interrupt sources
//! from triggering their corresponding ISRs.
//!
//! @note Any external interrupt signal that occurs while the master interrupt
//! disable is active will still reach the "pending" state in the NVIC, but it
//! will not be allowed to reach the "active" state or trigger the
//! corresponding ISR. Instead, these interrupts are essentially "queued" until
//! the next time the master interrupt enable instruction is executed. At that
//! time, the interrupt handlers will be executed in order of decreasing
//! priority.
//!
//! @return 1 if interrupts were previously disabled, 0 otherwise.
//
//*****************************************************************************
#if (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION < 6000000)
__asm uint32_t
am_hal_interrupt_master_disable(void)
{
mrs r0, PRIMASK
cpsid i
bx lr
}
#elif (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION >= 6000000)
uint32_t __attribute__((naked))
am_hal_interrupt_master_disable(void)
{
__asm(" mrs r0, PRIMASK");
__asm(" cpsid i");
__asm(" bx lr");
}
#elif defined(__GNUC_STDC_INLINE__)
uint32_t __attribute__((naked))
am_hal_interrupt_master_disable(void)
{
__asm(" mrs r0, PRIMASK");
__asm(" cpsid i");
__asm(" bx lr");
}
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing
// return statement on a non-void function
__stackless uint32_t
am_hal_interrupt_master_disable(void)
{
__asm(" mrs r0, PRIMASK");
__asm(" cpsid i");
__asm(" bx lr");
}
#pragma diag_default = Pe940 // Restore IAR compiler warning
#else
#error Compiler is unknown, please contact Ambiq support team
#endif
//*****************************************************************************
//
//! @brief Sets the master interrupt state based on the input.
//!
//! @param ui32InterruptState - Desired PRIMASK value.
//!
//! This function directly writes the PRIMASK register in the ARM core. A value
//! of 1 will disable interrupts, while a value of zero will enable them.
//!
//! This function may be used along with am_hal_interrupt_master_disable() to
//! implement a nesting critical section. To do this, call
//! am_hal_interrupt_master_disable() to start the critical section, and save
//! its return value. To complete the critical section, call
//! am_hal_interrupt_master_set() using the saved return value as \e
//! ui32InterruptState. This will safely restore PRIMASK to the value it
//! contained just before the start of the critical section.
//!
//! @return None.
//
//*****************************************************************************
#if (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION < 6000000)
__asm void
am_hal_interrupt_master_set(uint32_t ui32InterruptState)
{
msr PRIMASK, r0
bx lr
}
#elif (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION >= 6000000)
void __attribute__((naked))
am_hal_interrupt_master_set(uint32_t ui32InterruptState)
{
__asm(" msr PRIMASK, r0");
__asm(" bx lr");
}
#elif defined(__GNUC_STDC_INLINE__)
void __attribute__((naked))
am_hal_interrupt_master_set(uint32_t ui32InterruptState)
{
__asm(" msr PRIMASK, r0");
__asm(" bx lr");
}
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing
// return statement on a non-void function
__stackless void
am_hal_interrupt_master_set(uint32_t ui32InterruptState)
{
__asm(" msr PRIMASK, r0");
__asm(" bx lr");
}
#pragma diag_default = Pe940 // Restore IAR compiler warning
#endif
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,83 @@
//*****************************************************************************
//
// am_hal_interrupt.h
//! @file
//!
//! @brief Helper functions supporting interrupts and NVIC operation.
//!
//! These functions may be used for NVIC-level interrupt configuration.
//!
//! @addtogroup interrupt3 Interrupt (ARM NVIC support functions)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_INTERRUPT_H
#define AM_HAL_INTERRUPT_H
#ifdef __cplusplus
extern "C"
{
#endif
//
// Define the last peripheral interrupt as AM_HAL_INTERRUPT_MAX.
// The total number of interrupts in the vector table is therefore
// (AM_HAL_INTERRUPT_MAX + 1 + 16).
//
#define AM_HAL_INTERRUPT_MAX (CLKGEN_IRQn)
extern uint32_t am_hal_interrupt_master_disable(void);
extern uint32_t am_hal_interrupt_master_enable(void);
extern void am_hal_interrupt_master_set(uint32_t ui32InterruptState);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_INTERRUPT_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,843 @@
//*****************************************************************************
//
//! @file am_hal_iom.h
//!
//! @brief Functions for accessing and configuring the IO Master module
//!
//! @addtogroup hal Hardware Abstraction Layer (HAL)
//! @addtogroup iom3 IO Master (SPI/I2C)
//! @ingroup hal
//! @{
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_IOM_H
#define AM_HAL_IOM_H
#include "am_hal_status.h"
#include "am_hal_sysctrl.h"
//*****************************************************************************
//
//! CMSIS-Style macro for handling a variable IOM module number.
//
//*****************************************************************************
#define IOMn(n) ((IOM0_Type*)(IOM0_BASE + (n * (IOM1_BASE - IOM0_BASE))))
//
// Maximum time to wait for hardware to finish a blocking transaction
// This is an escape to allow for bailing out in case of faulty peripheral
// (e.g. a device pulling the I2C clock low)
//
#define AM_HAL_IOM_MAX_BLOCKING_WAIT 500000 // 0.5 sec
//
// AM_HAL_IOM_CQ=1 will use the Command Queue in nonblocking transfers.
// 0 uses plain DMA (w/o CQ) in nonblocking transfers.
// This should be enabled only for A1 silicon.
//
#define AM_HAL_IOM_CQ 1
// Size guideline for allocation of application supploed buffers
#define AM_HAL_IOM_CQ_ENTRY_SIZE (24 * sizeof(uint32_t))
#define AM_HAL_IOM_HIPRIO_ENTRY_SIZE (8 * sizeof(uint32_t))
#define AM_HAL_IOM_SC_CLEAR(flag) ((flag) << 16)
#define AM_HAL_IOM_SC_SET(flag) ((flag))
// For IOM - Need to Clear the flag for unpausing
#define AM_HAL_IOM_SC_UNPAUSE(flag) AM_HAL_IOM_SC_CLEAR(flag)
#define AM_HAL_IOM_SC_PAUSE(flag) AM_HAL_IOM_SC_SET(flag)
// Use this macro to directly control the flags
#define AM_HAL_IOM_SETCLR(iom, scVal) \
do { \
IOMn((iom))->CQSETCLEAR = (scVal); \
} while (0);
// Flags 5, 7 & 6 are reserved by HAL
#define AM_HAL_IOM_PAUSE_FLAG_RESV (IOM0_CQPAUSEEN_CQPEN_SWFLAGEN7 | IOM0_CQPAUSEEN_CQPEN_SWFLAGEN6 | IOM0_CQPAUSEEN_CQPEN_SWFLAGEN5)
#define AM_HAL_IOM_SC_RESV_MASK (AM_HAL_IOM_PAUSE_FLAG_RESV | (AM_HAL_IOM_PAUSE_FLAG_RESV << 8) | (AM_HAL_IOM_PAUSE_FLAG_RESV << 16))
// We use SWFLAGEN7 to control SW pausing Command Queue - default unPause
// We use SWFLAGEN6 to pause on the sequece loopback - default Pause
#define AM_HAL_IOM_PAUSE_FLAG_IDX (_VAL2FLD(IOM0_CQPAUSEEN_CQPEN, IOM0_CQPAUSEEN_CQPEN_IDXEQ))
#define AM_HAL_IOM_PAUSE_FLAG_CQ (_VAL2FLD(IOM0_CQPAUSEEN_CQPEN, IOM0_CQPAUSEEN_CQPEN_SWFLAGEN7))
#define AM_HAL_IOM_PAUSE_FLAG_SEQLOOP (_VAL2FLD(IOM0_CQPAUSEEN_CQPEN, IOM0_CQPAUSEEN_CQPEN_SWFLAGEN6))
#define AM_HAL_IOM_PAUSE_FLAG_BLOCK (_VAL2FLD(IOM0_CQPAUSEEN_CQPEN, IOM0_CQPAUSEEN_CQPEN_SWFLAGEN5))
// By default - we Pause CQ for no more entries, or force pause from SW
#define AM_HAL_IOM_PAUSE_DEFAULT AM_HAL_IOM_PAUSE_FLAG_IDX
#define AM_HAL_IOM_CQP_PAUSE_DEFAULT (AM_HAL_IOM_PAUSE_FLAG_IDX | AM_HAL_IOM_PAUSE_FLAG_CQ)
//*****************************************************************************
//
// IOM Specific status codes
//
//*****************************************************************************
typedef enum
{
// Error in hardware command issued or illegal access by SW
AM_HAL_IOM_ERR_INVALID_OPER = AM_HAL_STATUS_MODULE_SPECIFIC_START,
// Loss of I2C multi-master arbitration
AM_HAL_IOM_ERR_I2C_ARB,
// I2C NAK
AM_HAL_IOM_ERR_I2C_NAK,
} am_hal_iom_err_e;
//*****************************************************************************
//
// General defines
//
//*****************************************************************************
#define AM_HAL_IOM_FIFO_SIZE_MAX 32
#define AM_HAL_IOM_MAX_OFFSETSIZE 3
#define AM_HAL_IOM_MAX_TXNSIZE_SPI 4095
#define AM_HAL_IOM_MAX_TXNSIZE_I2C 4095
#define AM_HAL_IOM_MAX_CS_SPI 3
//*****************************************************************************
//
//! @brief enumeration types for the IOM.
//
//*****************************************************************************
//
// IOM mode enumerations
//
typedef enum
{
AM_HAL_IOM_SPI_MODE,
AM_HAL_IOM_I2C_MODE,
AM_HAL_IOM_NUM_MODES
} am_hal_iom_mode_e;
//
// Transmit or receive enumerations.
// Make these enums consistent with the IOM CMD register values.
//
typedef enum
{
AM_HAL_IOM_TX,
AM_HAL_IOM_RX,
AM_HAL_IOM_FULLDUPLEX,
} am_hal_iom_dir_e;
//
// Enumerate the SPI modes. Note that these are arranged per the ordering of
// SPHA (bit1) and SPOL (bit0) in the IOM.MSPICFG register.
//
typedef enum
{
AM_HAL_IOM_SPI_MODE_0, // CPOL = 0; CPHA = 0
AM_HAL_IOM_SPI_MODE_2, // CPOL = 1; CPHA = 0
AM_HAL_IOM_SPI_MODE_1, // CPOL = 0; CPHA = 1
AM_HAL_IOM_SPI_MODE_3, // CPOL = 1; CPHA = 1
} am_hal_iom_spi_mode_e;
//*****************************************************************************
//
//! @brief Transfer callback function prototype
//
//*****************************************************************************
typedef void (*am_hal_iom_callback_t)(void *pCallbackCtxt, uint32_t transactionStatus);
//
//*****************************************************************************
//
//! @brief Configuration structure for the IOM.
//
//*****************************************************************************
typedef struct
{
//
//! Select the interface mode, SPI or I2C
//
am_hal_iom_mode_e eInterfaceMode;
//
//! Select the interface clock frequency
//
uint32_t ui32ClockFreq;
//
//! Select the SPI clock mode (polarity/phase). Ignored for I2C operation.
//
am_hal_iom_spi_mode_e eSpiMode;
//
// Non-Blocking transaction memory configuration
// Set length and pointer to Transfer Control Buffer.
// Length is in 4 byte multiples
//
uint32_t *pNBTxnBuf;
uint32_t ui32NBTxnBufLength;
}
am_hal_iom_config_t;
//*****************************************************************************
//
//! Configuration structure for an individual SPI device.
//
//*****************************************************************************
typedef struct
{
//
//! IOM module to use for communicating with this device.
//
uint32_t ui32Module;
//
//! Chip select signal that should be used for this device.
//
uint32_t ui32ChipSelect;
//
//! Additional options that will ALWAYS be ORed into the command word.
//
uint32_t ui32Options;
}
am_hal_iom_spi_device_t;
//*****************************************************************************
//
//! Configuration structure for an individual I2C device.
//
//*****************************************************************************
typedef struct
{
//
//! IOM module to use for communicating with this device.
//
uint32_t ui32Module;
//
//! I2C address associated with this device.
//
uint32_t ui32BusAddress;
//
//! Additional options that will ALWAYS be ORed into the command word.
//
uint32_t ui32Options;
}
am_hal_iom_i2c_device_t;
//*****************************************************************************
//
//! @brief Status structure for the IOM.
//
//*****************************************************************************
typedef struct
{
//
// IOM status.
//
bool bStatIdle;
bool bStatCmdAct;
bool bStatErr;
//!
//! DMA status
//! One of:
//! AM_HAL_IOM_STATUS_DMA_IN_PROGRESS
//! AM_HAL_IOM_STATUS_XFER_COMPLETE
//! AM_HAL_IOM_STATUS_DMAERR
//!
uint32_t ui32DmaStat;
uint32_t ui32MaxTransactions;
uint32_t ui32NumPendTransactions;
}
am_hal_iom_status_t;
//
// transfer structure
//
typedef struct
{
union
{
//
//! Chip enable (chip select) for this transaction on this device.
//
uint32_t ui32SpiChipSelect;
uint32_t ui32I2CDevAddr;
} uPeerInfo;
//
//! Instruction length (0,1,2, or 3).
//
uint32_t ui32InstrLen;
//
//! Device Instruction (aka Command). Often used as the offset.
//
uint32_t ui32Instr;
//
//! Number of bytes to transfer
//
uint32_t ui32NumBytes;
//
//! Transfer Direction (Transmit/Receive)
//
am_hal_iom_dir_e eDirection;
//
//! Buffer
//
uint32_t *pui32TxBuffer;
uint32_t *pui32RxBuffer;
//
// Continue - holds the SPI or I2C bus for multiple transactions.
//
bool bContinue;
//
// Repeat Count
//
uint8_t ui8RepeatCount;
//
//! DMA: Priority 0 = Low (best effort); 1 = High (service immediately)
//
uint8_t ui8Priority;
//! Command Queue Advanced control on gating conditions for transaction to start
//
uint32_t ui32PauseCondition;
//! Command Queue Advanced Post-Transaction status setting
uint32_t ui32StatusSetClr;
} am_hal_iom_transfer_t;
typedef struct
{
bool bLoop;
//! Command Queue Transaction Gating
uint32_t ui32PauseCondition;
//! Command Queue Post-Transaction status setting
uint32_t ui32StatusSetClr;
} am_hal_iom_seq_end_t;
typedef struct
{
uint8_t *pBuf; // Buffer provided to store the high priority transaction context
uint32_t size; // Size of buffer in bytes
} am_hal_iom_hiprio_cfg_t;
#define AM_HAL_IOM_DCX_INVALID 0xFF
typedef struct
{
uint8_t cs; // CS for which this configuration applies
uint8_t dcx; // alternate CS line used for DCX - AM_HAL_IOM_DCX_INVALID indicates DCX is not used
} am_hal_iom_dcx_cfg_t;
typedef struct
{
//! Command Queue Advanced control on gating conditions for transaction to start
uint32_t ui32PauseCondition;
//! Command Queue Advanced Post-Transaction status setting
uint32_t ui32StatusSetClr;
am_hal_cmdq_entry_t *pCQEntry;
uint32_t numEntries;
am_hal_iom_callback_t pfnCallback;
void *pCallbackCtxt;
uint32_t *pJmpAddr;
} am_hal_iom_cq_raw_t;
typedef enum
{
// Used to set/clear 8 CQ Pause flags - reserved flags are defined as AM_HAL_IOM_PAUSE_FLAG_RESV
// Pass uint32_t as pArgs
AM_HAL_IOM_REQ_FLAG_SETCLR = 0,
// Pass uint32_t as pArgs
AM_HAL_IOM_REQ_SPI_LSB,
// Pass uint32_t as pArgs
AM_HAL_IOM_REQ_SPI_FULLDUPLEX,
// Pass uint32_t as pArgs
AM_HAL_IOM_REQ_SPI_RDTHRESH,
// Pass uint32_t as pArgs
AM_HAL_IOM_REQ_SPI_WRTHRESH,
// Pause the CQ gracefully
// pArgs N/A
AM_HAL_IOM_REQ_PAUSE,
// Unpause the CQ
// pArgs N/A
AM_HAL_IOM_REQ_UNPAUSE,
// Get in and out of Sequence Mode - which allows building a sequence, which either runs once, or repeats
// Pass in bool as pArgs - true/false
AM_HAL_IOM_REQ_SET_SEQMODE,
// pArgs N/A
AM_HAL_IOM_REQ_SEQ_END,
// Initialize configuration for high priority trasactions
// These transactions take precedence over existing CQ transactions
// Pass am_hal_iom_hiprio_cfg_t * as pArgs
AM_HAL_IOM_REQ_INIT_HIPRIO,
// Create a block of transactions which are not paused in between
// pArgs N/A
AM_HAL_IOM_REQ_START_BLOCK,
// pArgs N/A
AM_HAL_IOM_REQ_END_BLOCK,
// Control the DCX line
// Pass am_hal_iom_dcx_cfg_t * as pArgs
AM_HAL_IOM_REQ_SET_DCX,
// Raw CQ transaction
// Pass am_hal_iom_cq_raw_t * as pArgs
AM_HAL_IOM_REQ_CQ_RAW,
AM_HAL_IOM_REQ_MAX
} am_hal_iom_request_e;
#define am_hal_iom_buffer(A) \
union \
{ \
uint32_t words[(A + 3) >> 2]; \
uint8_t bytes[A]; \
}
//*****************************************************************************
//
//! @name IOM Clock Frequencies
//! @brief Macro definitions for common SPI and I2C clock frequencies.
//!
//! These macros may be used with the ui32ClockFrequency member of the
//! am_hal_iom_config_t structure to set the clock frequency of the serial
//! interfaces.
//!
//! This list of frequencies is not exhaustive by any means. If your desired
//! frequency is not in this list, simply set ui32ClockFrequency to the
//! desired frequency (in Hz) when calling am_hal_iom_config().
//
//*****************************************************************************
#define AM_HAL_IOM_48MHZ 48000000
#define AM_HAL_IOM_24MHZ 24000000
#define AM_HAL_IOM_16MHZ 16000000
#define AM_HAL_IOM_12MHZ 12000000
#define AM_HAL_IOM_8MHZ 8000000
#define AM_HAL_IOM_6MHZ 6000000
#define AM_HAL_IOM_4MHZ 4000000
#define AM_HAL_IOM_3MHZ 3000000
#define AM_HAL_IOM_2MHZ 2000000
#define AM_HAL_IOM_1_5MHZ 1500000
#define AM_HAL_IOM_1MHZ 1000000
#define AM_HAL_IOM_750KHZ 750000
#define AM_HAL_IOM_500KHZ 500000
#define AM_HAL_IOM_400KHZ 400000
#define AM_HAL_IOM_375KHZ 375000
#define AM_HAL_IOM_250KHZ 250000
#define AM_HAL_IOM_125KHZ 125000
#define AM_HAL_IOM_100KHZ 100000
#define AM_HAL_IOM_50KHZ 50000
#define AM_HAL_IOM_10KHZ 10000
// Max Frequency supported in HAL
#define AM_HAL_IOM_MAX_FREQ AM_HAL_IOM_48MHZ
//*****************************************************************************
//
// IOM Interrupts
//
//*****************************************************************************
#define AM_HAL_IOM_INT_CQERR IOM0_INTEN_CQERR_Msk // Error during command queue operations
#define AM_HAL_IOM_INT_CQUPD IOM0_INTEN_CQUPD_Msk // Command queue operation performed a register write with the register address bit 0 set to 1.
#define AM_HAL_IOM_INT_CQPAUSED IOM0_INTEN_CQPAUSED_Msk // Command queue operation paused
#define AM_HAL_IOM_INT_DERR IOM0_INTEN_DERR_Msk // DMA error received
#define AM_HAL_IOM_INT_DCMP IOM0_INTEN_DCMP_Msk // DMA transfer complete
#define AM_HAL_IOM_INT_ARB IOM0_INTEN_ARB_Msk // Arbitration loss
#define AM_HAL_IOM_INT_STOP IOM0_INTEN_STOP_Msk // STOP command
#define AM_HAL_IOM_INT_START IOM0_INTEN_START_Msk // START command
#define AM_HAL_IOM_INT_ICMD IOM0_INTEN_ICMD_Msk // ILLEGAL command
#define AM_HAL_IOM_INT_IACC IOM0_INTEN_IACC_Msk // Illegal FIFO access
#define AM_HAL_IOM_INT_NAK IOM0_INTEN_NAK_Msk // I2C NAK
#define AM_HAL_IOM_INT_FOVFL IOM0_INTEN_FOVFL_Msk // Write FIFO overflow
#define AM_HAL_IOM_INT_FUNDFL IOM0_INTEN_FUNDFL_Msk // Read FIFO underflow
#define AM_HAL_IOM_INT_THR IOM0_INTEN_THR_Msk // FIFO threshold interrupt
#define AM_HAL_IOM_INT_CMDCMP IOM0_INTEN_CMDCMP_Msk // Command complete
#define AM_HAL_IOM_INT_SWERR (AM_HAL_IOM_INT_ICMD | AM_HAL_IOM_INT_IACC | AM_HAL_IOM_INT_FOVFL | AM_HAL_IOM_INT_FUNDFL)
#define AM_HAL_IOM_INT_I2CARBERR (AM_HAL_IOM_INT_ARB)
#define AM_HAL_IOM_INT_INTERR (AM_HAL_IOM_INT_CQERR | AM_HAL_IOM_INT_DERR)
#define AM_HAL_IOM_INT_ALL 0xFFFFFFFF
//
// Unsuccessful end of a transaction results in one more more of the following
//
#define AM_HAL_IOM_INT_ERR (AM_HAL_IOM_INT_SWERR | AM_HAL_IOM_INT_I2CARBERR | AM_HAL_IOM_INT_INTERR | AM_HAL_IOM_INT_NAK)
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! @brief IOM initialization function
//!
//! @param ui32Module - module instance.
//! @param handle - returns the handle for the module instance.
//!
//! This function accepts a module instance, allocates the interface and then
//! returns a handle to be used by the remaining interface functions.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_initialize(uint32_t ui32Module, void **ppHandle);
//*****************************************************************************
//
//! @brief IOM configuration function
//!
//! @param handle - handle for the IOM.
//! @param pConfig - pointer to the IOM specific configuration.
//!
//! This function configures the interface settings for the IO Master.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_configure(void *pHandle, am_hal_iom_config_t *psConfig);
//*****************************************************************************
//
//! @brief IOM enable function
//!
//! @param handle - handle for the interface.
//!
//! This function enables the IOM for operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_enable(void *pHandle);
//*****************************************************************************
//
//! @brief IOM disable function
//!
//! @param handle - handle for the interface.
//!
//! This function disables the IOMaster from operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_disable(void *pHandle);
//*****************************************************************************
//
//! @brief IOM control function
//!
//! @param handle - handle for the IOM.
//! @param eReq - device specific special request code.
//! @param pArgs - pointer to the request specific arguments.
//!
//! This function allows advanced settings
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_control(void *pHandle, am_hal_iom_request_e eReq, void *pArgs);
//*****************************************************************************
//
//! @brief IOM status function
//!
//! @param handle - handle for the interface.
//! @param psStatus - pointer to an interface specific structure used to
//! return the status of the interface.
//!
//! This function returns the current status of the interface.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_status_get(void *pHandle, am_hal_iom_status_t *psStatus);
//*****************************************************************************
//
//! @brief IOM enable interrupts function
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - interface specific interrupt mask.
//!
//! This function enables the specific indicated interrupts.
//!
//! The following are valid enable bits, any of which can be ORed together.
//! AM_REG_IOM_INTEN_CQERR_M // Error during command queue operations
//! AM_REG_IOM_INTEN_CQCMP_M // Command queue operation complete
//! AM_REG_IOM_INTEN_DERR_M // DMA error received
//! AM_REG_IOM_INTEN_DCMP_M // DMA transfer complete
//! AM_REG_IOM_INTEN_ARB_M // Arbitration loss
//! AM_REG_IOM_INTEN_STOP_M // STOP command
//! AM_REG_IOM_INTEN_START_M // START command
//! AM_REG_IOM_INTEN_ICMD // ILLEGAL command
//! AM_REG_IOM_INTEN_IACC_M // Illegal FIFO access
//! AM_REG_IOM_INTEN_NAK_M // I2C NAK
//! AM_REG_IOM_INTEN_FOVFL_M // Write FIFO overflow
//! AM_REG_IOM_INTEN_FUNDFL_M // Read FIFO underflow
//! AM_REG_IOM_INTEN_THR_M // FIFO threshold interrupt
//! AM_REG_IOM_INTEN_CMDCMP_M // Command complete
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_interrupt_enable(void *pHandle, uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief IOM disable interrupts function
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - interface specific interrupt mask.
//!
//! This function disables the specified interrupts.
//!
//! @return status - generic or interface specific status.
//!
//! The following are valid disable bits, any of which can be ORed together.
//! AM_REG_IOM_INTEN_CQERR_M // Error during command queue operations
//! AM_REG_IOM_INTEN_CQCMP_M // Command queue operation complete
//! AM_REG_IOM_INTEN_DERR_M // DMA error received
//! AM_REG_IOM_INTEN_DCMP_M // DMA transfer complete
//! AM_REG_IOM_INTEN_ARB_M // Arbitration loss
//! AM_REG_IOM_INTEN_STOP_M // STOP command
//! AM_REG_IOM_INTEN_START_M // START command
//! AM_REG_IOM_INTEN_ICMD // ILLEGAL command
//! AM_REG_IOM_INTEN_IACC_M // Illegal FIFO access
//! AM_REG_IOM_INTEN_NAK_M // I2C NAK
//! AM_REG_IOM_INTEN_FOVFL_M // Write FIFO overflow
//! AM_REG_IOM_INTEN_FUNDFL_M // Read FIFO underflow
//! AM_REG_IOM_INTEN_THR_M // FIFO threshold interrupt
//! AM_REG_IOM_INTEN_CMDCMP_M // Command complete
//
//*****************************************************************************
extern uint32_t am_hal_iom_interrupt_disable(void *pHandle, uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief IOM get interrupt status
//!
//! @param handle - handle for the interface.
//! @param pui32IntStatus - pointer to a uint32_t to return the interrupt status
//!
//! This function returns the interrupt status for the given peripheral.
//!
//! The following are valid status bits.
//! AM_REG_IOM_INTSTAT_CQERR_M // Error during command queue operations
//! AM_REG_IOM_INTSTAT_CQCMP_M // Command queue operation complete
//! AM_REG_IOM_INTSTAT_DERR_M // DMA error received
//! AM_REG_IOM_INTSTAT_DCMP_M // DMA transfer complete
//! AM_REG_IOM_INTSTAT_ARB_M // Arbitration loss
//! AM_REG_IOM_INTSTAT_STOP_M // STOP command
//! AM_REG_IOM_INTSTAT_START_M // START command
//! AM_REG_IOM_INTSTAT_ICMD // ILLEGAL command
//! AM_REG_IOM_INTSTAT_IACC_M // Illegal FIFO access
//! AM_REG_IOM_INTSTAT_NAK_M // I2C NAK
//! AM_REG_IOM_INTSTAT_FOVFL_M // Write FIFO overflow
//! AM_REG_IOM_INTSTAT_FUNDFL_M // Read FIFO underflow
//! AM_REG_IOM_INTSTAT_THR_M // FIFO threshold interrupt
//! AM_REG_IOM_INTSTAT_CMDCMP_M // Command complete
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_interrupt_status_get(void *pHandle, bool bEnabledOnly,
uint32_t *pui32IntStatus);
//*****************************************************************************
//
//! @brief IOM interrupt clear
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - interface specific interrupt mask.
//!
//! This function clears the interrupts for the given peripheral.
//!
//! The following are valid clear bits, any of which can be ORed together.
//! AM_REG_IOM_INTCLR_CQERR_M // Error during command queue operations
//! AM_REG_IOM_INTCLR_CQCMP_M // Command queue operation complete
//! AM_REG_IOM_INTCLR_DERR_M // DMA error received
//! AM_REG_IOM_INTCLR_DCMP_M // DMA transfer complete
//! AM_REG_IOM_INTCLR_ARB_M // Arbitration loss
//! AM_REG_IOM_INTCLR_STOP_M // STOP command
//! AM_REG_IOM_INTCLR_START_M // START command
//! AM_REG_IOM_INTCLR_ICMD // ILLEGAL command
//! AM_REG_IOM_INTCLR_IACC_M // Illegal FIFO access
//! AM_REG_IOM_INTCLR_NAK_M // I2C NAK
//! AM_REG_IOM_INTCLR_FOVFL_M // Write FIFO overflow
//! AM_REG_IOM_INTCLR_FUNDFL_M // Read FIFO underflow
//! AM_REG_IOM_INTCLR_THR_M // FIFO threshold interrupt
//! AM_REG_IOM_INTCLR_CMDCMP_M // Command complete
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_interrupt_clear(void *pHandle, uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief IOM interrupt service routine
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - interface specific interrupt mask indicating
//! interrupts to be serviced
//!
//! This function is designed to be called from within the user defined ISR
//! (am_iom_isr) in order to service the non-blocking, queued, or DMA processing
//! for a given module instance.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_interrupt_service(void *pHandle, uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief IOM power control function
//!
//! @param handle - handle for the interface.
//! @param ePowerState - the desired power state to move the peripheral to.
//! @param retainState - flag (if true) to save/restore perhipheral state upon
//! power state change.
//!
//! This function updates the peripheral to a given power state.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_power_ctrl(void *pHandle,
am_hal_sysctrl_power_state_e ePowerState,
bool retainState);
//*****************************************************************************
//
//! @brief IOM blocking transfer function
//!
//! @param handle - handle for the interface.
//! @param pTransaction - pointer to the transaction control structure.
//!
//! This function performs a transaction on the IOM in PIO mode. It handles
//! half duplex transactions only (TX or RX).
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_blocking_transfer(void *pHandle,
am_hal_iom_transfer_t *psTransaction);
//*****************************************************************************
//
//! @brief IOM non-blocking transfer function
//!
//! @param handle - handle for the interface.
//! @param pTransaction - pointer to the uniform transaction control structure.
//! @param pfnCallback - pointer the callback function to be executed when
//! transaction is complete can be set to NULL).
//! @param pCallbackCtxt- context registered which is passed on to the callback
//! function
//!
//! This function performs a transaction on the interface. It handles both full
//! and half duplex transactions. The callback is executed when the transaction
//! is complete.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_iom_nonblocking_transfer(void *pHandle,
am_hal_iom_transfer_t *psTransaction,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
//*****************************************************************************
//
//! @brief IOM uninitialize function
//!
//! @param handle - returns the handle for the module instance.
//!
//! This function accepts a handle to the initialized interface and returns
//! the peripheral instance to a known uninitialized state.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
//
// Uninitialize the interface and return the handle to a known state.
//
extern uint32_t am_hal_iom_uninitialize(void *pHandle);
//*****************************************************************************
//
//! @brief Perform a Full Duplex transaction.
//!
//! @param handle - handle for the interface.
//!
//! @return HAL status of the operation.
//
//*****************************************************************************
uint32_t
am_hal_iom_spi_blocking_fullduplex(void *pHandle,
am_hal_iom_transfer_t *psTransaction);
//
// IOM High Priority transfer function
//
uint32_t am_hal_iom_highprio_transfer(void *pHandle,
am_hal_iom_transfer_t *psTransaction,
am_hal_iom_callback_t pfnCallback,
void *pCallbackCtxt);
#ifdef __cplusplus
}
#endif
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
#endif // AM_HAL_IOM_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,377 @@
//*****************************************************************************
//
// am_hal_ios.h
//! @file
//!
//! @brief Functions for interfacing with the IO Slave module
//!
//! @addtogroup ios3 IO Slave (SPI/I2C)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_IOS_H
#define AM_HAL_IOS_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// CMSIS-style macro for handling a variable IOS module number.
//
#define IOSLAVEn(n) ((IOSLAVE_Type*)(IOSLAVE_BASE + (n * (IOSLAVE_BASE - IOSLAVE_BASE))))
//*****************************************************************************
//*****************************************************************************
//
//! @name Interface Configuration
//! @brief Macro definitions for configuring the physical interface of the IO
//! Slave
//!
//! These macros may be used with the am_hal_ios_config_t structure to set the
//! physical parameters of the SPI/I2C slave module.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_IOS_USE_SPI _VAL2FLD(IOSLAVE_CFG_IFCSEL, IOSLAVE_CFG_IFCSEL_SPI)
#define AM_HAL_IOS_SPIMODE_0 _VAL2FLD(IOSLAVE_CFG_SPOL, IOSLAVE_CFG_SPOL_SPI_MODES_0_3)
#define AM_HAL_IOS_SPIMODE_1 _VAL2FLD(IOSLAVE_CFG_SPOL, IOSLAVE_CFG_SPOL_SPI_MODES_1_2)
#define AM_HAL_IOS_SPIMODE_2 _VAL2FLD(IOSLAVE_CFG_SPOL, IOSLAVE_CFG_SPOL_SPI_MODES_1_2)
#define AM_HAL_IOS_SPIMODE_3 _VAL2FLD(IOSLAVE_CFG_SPOL, IOSLAVE_CFG_SPOL_SPI_MODES_0_3)
#define AM_HAL_IOS_USE_I2C _VAL2FLD(IOSLAVE_CFG_IFCSEL, IOSLAVE_CFG_IFCSEL_I2C)
#define AM_HAL_IOS_I2C_ADDRESS(n) _VAL2FLD(IOSLAVE_CFG_I2CADDR, n)
#define AM_HAL_IOS_LSB_FIRST _VAL2FLD(IOSLAVE_CFG_LSB, 1)
//! @}
//*****************************************************************************
//
//! @name Register Access Interrupts
//! @brief Macro definitions for register access interrupts.
//!
//! These macros may be used with any of the
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_IOS_ACCESS_INT_00 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 31)
#define AM_HAL_IOS_ACCESS_INT_01 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 30)
#define AM_HAL_IOS_ACCESS_INT_02 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 29)
#define AM_HAL_IOS_ACCESS_INT_03 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 28)
#define AM_HAL_IOS_ACCESS_INT_04 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 27)
#define AM_HAL_IOS_ACCESS_INT_05 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 26)
#define AM_HAL_IOS_ACCESS_INT_06 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 25)
#define AM_HAL_IOS_ACCESS_INT_07 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 24)
#define AM_HAL_IOS_ACCESS_INT_08 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 23)
#define AM_HAL_IOS_ACCESS_INT_09 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 22)
#define AM_HAL_IOS_ACCESS_INT_0A _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 21)
#define AM_HAL_IOS_ACCESS_INT_0B _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 20)
#define AM_HAL_IOS_ACCESS_INT_0C _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 19)
#define AM_HAL_IOS_ACCESS_INT_0D _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 18)
#define AM_HAL_IOS_ACCESS_INT_0E _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 17)
#define AM_HAL_IOS_ACCESS_INT_0F _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 16)
#define AM_HAL_IOS_ACCESS_INT_13 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 15)
#define AM_HAL_IOS_ACCESS_INT_17 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 14)
#define AM_HAL_IOS_ACCESS_INT_1B _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 13)
#define AM_HAL_IOS_ACCESS_INT_1F _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 12)
#define AM_HAL_IOS_ACCESS_INT_23 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 11)
#define AM_HAL_IOS_ACCESS_INT_27 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 10)
#define AM_HAL_IOS_ACCESS_INT_2B _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 9)
#define AM_HAL_IOS_ACCESS_INT_2F _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 8)
#define AM_HAL_IOS_ACCESS_INT_33 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 7)
#define AM_HAL_IOS_ACCESS_INT_37 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 6)
#define AM_HAL_IOS_ACCESS_INT_3B _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 5)
#define AM_HAL_IOS_ACCESS_INT_3F _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 4)
#define AM_HAL_IOS_ACCESS_INT_43 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 3)
#define AM_HAL_IOS_ACCESS_INT_47 _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 2)
#define AM_HAL_IOS_ACCESS_INT_4B _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 1)
#define AM_HAL_IOS_ACCESS_INT_4F _VAL2FLD(IOSLAVE_REGACCINTEN_REGACC, (uint32_t)1 << 0)
#define AM_HAL_IOS_ACCESS_INT_ALL 0xFFFFFFFF
//! @}
//*****************************************************************************
//
//! @name I/O Slave Interrupts
//! @brief Macro definitions for I/O slave (IOS) interrupts.
//!
//! These macros may be used with any of the
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_IOS_INT_FSIZE IOSLAVE_INTEN_FSIZE_Msk
#define AM_HAL_IOS_INT_FOVFL IOSLAVE_INTEN_FOVFL_Msk
#define AM_HAL_IOS_INT_FUNDFL IOSLAVE_INTEN_FUNDFL_Msk
#define AM_HAL_IOS_INT_FRDERR IOSLAVE_INTEN_FRDERR_Msk
#define AM_HAL_IOS_INT_GENAD IOSLAVE_INTEN_GENAD_Msk
#define AM_HAL_IOS_INT_IOINTW IOSLAVE_INTEN_IOINTW_Msk
#define AM_HAL_IOS_INT_XCMPWR IOSLAVE_INTEN_XCMPWR_Msk
#define AM_HAL_IOS_INT_XCMPWF IOSLAVE_INTEN_XCMPWF_Msk
#define AM_HAL_IOS_INT_XCMPRR IOSLAVE_INTEN_XCMPRR_Msk
#define AM_HAL_IOS_INT_XCMPRF IOSLAVE_INTEN_XCMPRF_Msk
#define AM_HAL_IOS_INT_ALL 0xFFFFFFFF
//! @}
//*****************************************************************************
//
//! @name I/O Slave Interrupts triggers
//! @brief Macro definitions for I/O slave (IOS) interrupts.
//!
//! These macros may be used with am_hal_ios_interrupt_set and am_hal_ios_interrupt_clear
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_IOS_IOINTCTL_INT0 (0x01)
#define AM_HAL_IOS_IOINTCTL_INT1 (0x02)
#define AM_HAL_IOS_IOINTCTL_INT2 (0x04)
#define AM_HAL_IOS_IOINTCTL_INT3 (0x08)
#define AM_HAL_IOS_IOINTCTL_INT4 (0x10)
#define AM_HAL_IOS_IOINTCTL_INT5 (0x20)
//! @}
//*****************************************************************************
//
// External variable definitions
//
//*****************************************************************************
//*****************************************************************************
//
//! @brief LRAM pointer
//!
//! Pointer to the base of the IO Slave LRAM.
//
//*****************************************************************************
extern volatile uint8_t * const am_hal_ios_pui8LRAM;
//*****************************************************************************
//
//! @brief Configuration structure for the IO slave module.
//!
//! This structure may be used along with the am_hal_ios_config() function to
//! select key parameters of the IO Slave module. See the descriptions of each
//! parameter within this structure for more information on what they control.
//
//*****************************************************************************
typedef struct
{
//
//! Interface Selection
//!
//! This word selects the physical behavior of the IO Slave port. For SPI
//! mode, this word should be the logical OR of one or more of the
//! following:
//!
//! AM_HAL_IOS_USE_SPI
//! AM_HAL_IOS_SPIMODE_0
//! AM_HAL_IOS_SPIMODE_1
//! AM_HAL_IOS_SPIMODE_2
//! AM_HAL_IOS_SPIMODE_3
//!
//! For I2C mode, use the logical OR of one or more of these values instead
//! (where n is the 7 or 10-bit I2C address to use):
//!
//! AM_HAL_IOS_USE_I2C
//! AM_HAL_IOS_I2C_ADDRESS(n)
//!
//! Also, in any mode, you may OR in this value to reverse the order of
//! incoming data bits.
//!
//! AM_HAL_IOS_LSB_FIRST
//
uint32_t ui32InterfaceSelect;
//
//! Read-Only section
//!
//! The IO Slave LRAM is split into three main sections. The first section
//! is a "Direct Write" section, which may be accessed for reads or write
//! either directly through the Apollo CPU, or over the SPI/I2C bus. The
//! "Direct Write" section always begins at LRAM offset 0x0. At the end of
//! the normal "Direct Write" space, there is a "Read Only" space, which is
//! read/write accessible to the Apollo CPU, but read-only over the I2C/SPI
//! Bus. This word selects the base address of this "Read Only" space.
//!
//! This value may be set to any multiple of 8 between 0x0 and 0x78,
//! inclusive. For the configuration to be valid, \e ui32ROBase must also
//! be less than or equal to \e ui32FIFOBase
//!
//! @note The address given here is in units of BYTES. Since the location
//! of the "Read Only" space may only be set in 8-byte increments, this
//! value must be a multiple of 8.
//!
//! For the avoidance of doubt this means 0x80 is 128 bytes. These functions
//! will shift right by 8 internally.
//
uint32_t ui32ROBase;
//
//! FIFO section
//!
//! After the "Direct Access" and "Read Only" sections is a section of LRAM
//! allocated to a FIFO. This section is accessible by the Apollo CPU
//! through the FIFO control registers, and accessible on the SPI/I2C bus
//! through the 0x7F address. This word selects the base address of the
//! FIFO space. The FIFO will extend from the address specified here to the
//! address specified in \e ui32RAMBase.
//!
//! This value may be set to any multiple of 8 between 0x0 and 0x78,
//! inclusive. For the configuration to be valid, \e ui32FIFOBase must also
//! be greater than or equal to \e ui32ROBase.
//!
//! @note The address given here is in units of BYTES. Since the location
//! of the "FIFO" space may only be set in 8-byte increments, this value
//! must be a multiple of 8.
//!
//! For the avoidance of doubt this means 0x80 is 128 bytes. These functions
//! will shift right by 8 internally.
//
uint32_t ui32FIFOBase;
//
//! RAM section
//!
//! At the end of the IOS LRAM, the user may allocate a "RAM" space that
//! can only be accessed by the Apollo CPU. This space will not interact
//! with the SPI/I2C bus at all, and may be used as general-purpose memory.
//! Unlike normal SRAM, this section of LRAM will retain its state through
//! Deep Sleep, so it may be used as a data retention space for
//! ultra-low-power applications.
//!
//! This value may be set to any multiple of 8 between 0x0 and 0x100,
//! inclusive. For the configuration to be valid, \e ui32RAMBase must also
//! be greater than or equal to \e ui32FIFOBase.
//!
//! @note The address given here is in units of BYTES. Since the location
//! of the "FIFO" space may only be set in 8-byte increments, this value
//! must be a multiple of 8.
//!
//! For the avoidance of doubt this means 0x80 is 128 bytes. These functions
//! will shift right by 8 internally.
//
uint32_t ui32RAMBase;
//
//! FIFO threshold
//!
//! The IO Slave module will trigger an interrupt when the number of
//! entries in the FIFO drops below this number of bytes.
//
uint32_t ui32FIFOThreshold;
//
// Pointer to an SRAM
//
uint8_t *pui8SRAMBuffer;
uint32_t ui32SRAMBufferCap;
}
am_hal_ios_config_t;
typedef enum
{
// Request with arg
AM_HAL_IOS_REQ_HOST_INTSET = 0,
AM_HAL_IOS_REQ_HOST_INTCLR,
AM_HAL_IOS_REQ_HOST_INTGET,
AM_HAL_IOS_REQ_HOST_INTEN_GET,
AM_HAL_IOS_REQ_READ_GADATA,
AM_HAL_IOS_REQ_ARG_MAX,
// Request without arg
AM_HAL_IOS_REQ_READ_POLL = AM_HAL_IOS_REQ_ARG_MAX,
AM_HAL_IOS_REQ_FIFO_UPDATE_CTR,
AM_HAL_IOS_REQ_FIFO_BUF_CLR,
AM_HAL_IOS_REQ_MAX
} am_hal_ios_request_e;
typedef struct
{
uint8_t *pui8Data;
volatile uint32_t ui32WriteIndex;
volatile uint32_t ui32ReadIndex;
volatile uint32_t ui32Length;
uint32_t ui32Capacity;
}am_hal_ios_buffer_t;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern uint32_t am_hal_ios_uninitialize(void *pHandle);
extern uint32_t am_hal_ios_initialize(uint32_t ui32Module, void **ppHandle);
extern uint32_t am_hal_ios_enable(void *pHandle);
extern uint32_t am_hal_ios_disable(void *pHandle);
// the following interrupts go back to the NVIC
extern uint32_t am_hal_ios_configure(void *pHandle, am_hal_ios_config_t *psConfig);
extern uint32_t am_hal_ios_interrupt_enable(void *pHandle, uint32_t ui32IntMask);
extern uint32_t am_hal_ios_interrupt_disable(void *pHandle, uint32_t ui32IntMask);
extern uint32_t am_hal_ios_interrupt_clear(void *pHandle, uint32_t ui32IntMask);
extern uint32_t am_hal_ios_interrupt_status_get(void *pHandle, bool bEnabledOnly, uint32_t *pui32IntStatus);
extern uint32_t am_hal_ios_interrupt_service(void *pHandle, uint32_t ui32IntMask);
// Returns the number of bytes actually written
extern uint32_t am_hal_ios_fifo_write(void *pHandle, uint8_t *pui8Data, uint32_t ui32NumBytes, uint32_t *pui32WrittenBytes);
extern uint32_t am_hal_ios_fifo_space_used(void *pHandle, uint32_t *pui32UsedSpace);
extern uint32_t am_hal_ios_fifo_space_left(void *pHandle, uint32_t *pui32LeftSpace);
extern uint32_t am_hal_ios_power_ctrl(void *pHandle, am_hal_sysctrl_power_state_e ePowerState, bool bRetainState);
extern uint32_t am_hal_ios_control(void *pHandle, am_hal_ios_request_e eReq, void *pArgs);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_IOS_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,434 @@
//*****************************************************************************
//
// am_hal_itm.c
//! @file
//!
//! @brief Functions for operating the instrumentation trace macrocell
//!
//! @addtogroup itm3 Instrumentation Trace Macrocell (ITM)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Global Variables
//
//*****************************************************************************
//*****************************************************************************
//
//! @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)
{
//
// To be able to access ITM registers, set the Trace Enable bit
// in the Debug Exception and Monitor Control Register (DEMCR).
//
CoreDebug->DEMCR |= _VAL2FLD(CoreDebug_DEMCR_TRCENA, 1);
while ( !(CoreDebug->DEMCR & _VAL2FLD(CoreDebug_DEMCR_TRCENA, 1)) );
//
// Write the key to the ITM Lock Access register to unlock the ITM_TCR.
//
ITM->LAR = ITM_LAR_KEYVAL;
//
// Set the enable bits in the ITM trace enable register, and the ITM
// control registers to enable trace data output.
//
ITM->TPR = 0x0000000F;
ITM->TER = 0xFFFFFFFF;
//
// Write to the ITM control and status register.
//
ITM->TCR =
_VAL2FLD(ITM_TCR_TraceBusID, 0x15) |
_VAL2FLD(ITM_TCR_GTSFREQ, 1) |
_VAL2FLD(ITM_TCR_TSPrescale, 1) |
_VAL2FLD(ITM_TCR_SWOENA, 1) |
_VAL2FLD(ITM_TCR_DWTENA, 0) |
_VAL2FLD(ITM_TCR_SYNCENA, 0) |
_VAL2FLD(ITM_TCR_TSENA, 0) |
_VAL2FLD(ITM_TCR_ITMENA, 1);
}
//*****************************************************************************
//
//! @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 ( MCUCTRL->TPIUCTRL == 0 )
{
//
// This is a disable without enable, which could be the case with some
// earlier versions of SBL. To avoid a hang, ITM (particularly TPIU
// clock) must first be enabled.
//
am_hal_itm_enable();
}
//
// Make sure the ITM/TPIU is not busy.
//
am_hal_itm_not_busy();
//
// Make sure the ITM_TCR is unlocked.
//
ITM->LAR = ITM_LAR_KEYVAL;
//
// Disable the ITM.
//
for (int ix = 0; ix < 100; ix++)
{
ITM->TCR &= ~_VAL2FLD(ITM_TCR_ITMENA, 1);
while ( ITM->TCR & (_VAL2FLD(ITM_TCR_ITMENA, 1) | _VAL2FLD(ITM_TCR_BUSY, 1)) );
}
//
// Reset the TRCENA bit in the DEMCR register, which should disable the ITM
// for operation.
//
CoreDebug->DEMCR &= ~_VAL2FLD(CoreDebug_DEMCR_TRCENA, 1);
while ( CoreDebug->DEMCR & _VAL2FLD(CoreDebug_DEMCR_TRCENA, 1) );
//
// Disable the TPIU clock source in MCU control.
//
MCUCTRL->TPIUCTRL =
_VAL2FLD(MCUCTRL_TPIUCTRL_CLKSEL, MCUCTRL_TPIUCTRL_CLKSEL_LOWPWR) |
_VAL2FLD(MCUCTRL_TPIUCTRL_ENABLE, MCUCTRL_TPIUCTRL_ENABLE_DIS);
while (MCUCTRL->TPIUCTRL);
}
//*****************************************************************************
//
//! @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 (ITM->TCR & _VAL2FLD(ITM_TCR_BUSY, 1));
//
// wait for 50us for the data to flush out
//
am_hal_flash_delay(FLASH_CYCLES_US(50));
}
//*****************************************************************************
//
//! @brief Enables tracing on a given set of ITM ports
//!
//! @param ui8portNum - Set ports to be enabled
//!
//! Enables tracing on the ports referred to by \e ui8portNum by writing the
//! associated bit in the Trace Privilege Register in the ITM. The value for
//! ui8portNum should be the logical OR one or more of the following values:
//!
//! \e ITM_PRIVMASK_0_7 - enable ports 0 through 7
//! \e ITM_PRIVMASK_8_15 - enable ports 8 through 15
//! \e ITM_PRIVMASK_16_23 - enable ports 16 through 23
//! \e ITM_PRIVMASK_24_31 - enable ports 24 through 31
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_itm_trace_port_enable(uint8_t ui8portNum)
{
ITM->TPR |= (0x00000001 << (ui8portNum>>3));
}
//*****************************************************************************
//
//! @brief Disable tracing on the given ITM stimulus port.
//!
//! @param ui8portNum
//!
//! Disables tracing on the ports referred to by \e ui8portNum by writing the
//! associated bit in the Trace Privilege Register in the ITM. The value for
//! ui8portNum should be the logical OR one or more of the following values:
//!
//! \e ITM_PRIVMASK_0_7 - disable ports 0 through 7
//! \e ITM_PRIVMASK_8_15 - disable ports 8 through 15
//! \e ITM_PRIVMASK_16_23 - disable ports 16 through 23
//! \e ITM_PRIVMASK_24_31 - disable ports 24 through 31
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_itm_trace_port_disable(uint8_t ui8portNum)
{
ITM->TPR &= ~(0x00000001 << (ui8portNum >> 3));
}
//*****************************************************************************
//
//! @brief Poll the given ITM stimulus register until not busy.
//!
//! @param ui32StimReg - stimulus register
//!
//! @return true if not busy, false if busy (timed out or other error).
//
//*****************************************************************************
bool
am_hal_itm_stimulus_not_busy(uint32_t ui32StimReg)
{
uint32_t ui32StimAddr = (uint32_t)&ITM->PORT[0] + (4 * ui32StimReg);
//
// Busy waiting until it is available, non-zero means ready.
//
while ( !AM_REGVAL(ui32StimAddr) );
return true;
}
//*****************************************************************************
//
//! @brief Writes a 32-bit value to the given ITM stimulus register.
//!
//! @param ui32StimReg - stimulus register
//! @param ui32Value - value to be written.
//!
//! Write a word to the desired stimulus register.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_itm_stimulus_reg_word_write(uint32_t ui32StimReg, uint32_t ui32Value)
{
uint32_t ui32StimAddr = (uint32_t)&ITM->PORT[0] + (4 * ui32StimReg);
//
// Busy waiting until it is available, non-zero means ready
//
while (!AM_REGVAL(ui32StimAddr));
//
// Write the register.
//
AM_REGVAL(ui32StimAddr) = ui32Value;
}
//*****************************************************************************
//
//! @brief Writes a short to the given ITM stimulus register.
//!
//! @param ui32StimReg - stimulus register
//! @param ui16Value - short to be written.
//!
//! Write a short to the desired stimulus register.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_itm_stimulus_reg_short_write(uint32_t ui32StimReg, uint16_t ui16Value)
{
uint32_t ui32StimAddr = (uint32_t)&ITM->PORT[0] + (4 * ui32StimReg);
//
// Busy waiting until it is available non-zero means ready
//
while ( !AM_REGVAL(ui32StimAddr) );
//
// Write the register.
//
*((volatile uint16_t *) ui32StimAddr) = ui16Value;
}
//*****************************************************************************
//
//! @brief Writes a byte to the given ITM stimulus register.
//!
//! @param ui32StimReg - stimulus register
//! @param ui8Value - byte to be written.
//!
//! Write a byte to the desired stimulus register.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_itm_stimulus_reg_byte_write(uint32_t ui32StimReg, uint8_t ui8Value)
{
uint32_t ui32StimAddr = (uint32_t)&ITM->PORT[0] + (4 * ui32StimReg);
//
// Busy waiting until it is available (non-zero means ready)
//
while (!AM_REGVAL(ui32StimAddr));
//
// Write the register.
//
*((volatile uint8_t *) ui32StimAddr) = ui8Value;
}
//*****************************************************************************
//
//! @brief Sends a Sync Packet.
//!
//! Sends a sync packet. This can be useful for external software should it
//! become out of sync with the ITM stream.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_itm_sync_send(void)
{
//
// Write the register.
//
am_hal_itm_stimulus_reg_word_write(AM_HAL_ITM_SYNC_REG,
AM_HAL_ITM_SYNC_VAL);
}
//*****************************************************************************
//
//! @brief Poll the print stimulus registers until not busy.
//!
//! @return true if not busy, false if busy (timed out or other error).
//
//*****************************************************************************
bool
am_hal_itm_print_not_busy(void)
{
//
// Poll stimulus register allocated for printing.
//
am_hal_itm_stimulus_not_busy(0);
return true;
}
//*****************************************************************************
//
//! @brief Prints a char string out of the ITM.
//!
//! @param pcString pointer to the character sting
//!
//! This function prints a sting out of the ITM.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_itm_print(char *pcString)
{
uint32_t ui32Length = 0;
//
// Determine the length of the string.
//
while (*(pcString + ui32Length))
{
ui32Length++;
}
//
// If there is no longer a word left, empty out the remaining characters.
//
while (ui32Length)
{
//
// Print string out the ITM.
//
am_hal_itm_stimulus_reg_byte_write(0, (uint8_t)*pcString++);
//
// Subtract from length.
//
ui32Length--;
}
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,109 @@
//*****************************************************************************
//
// am_hal_itm.h
//! @file
//!
//! @brief Functions for accessing and configuring the ARM ITM.
//!
//! @addtogroup itm3 Instrumentation Trace Macrocell (ITM)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_ITM_H
#define AM_HAL_ITM_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Sync Packet Defines
//
//*****************************************************************************
#define AM_HAL_ITM_SYNC_REG 23
#define AM_HAL_ITM_SYNC_VAL 0xF8F8F8F8
//*****************************************************************************
//
// PrintF Setup
//
//*****************************************************************************
#define AM_HAL_ITM_PRINT_NUM_BYTES 1
#define AM_HAL_ITM_PRINT_NUM_REGS 1
extern uint32_t am_hal_itm_print_registers[AM_HAL_ITM_PRINT_NUM_REGS];
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_itm_enable(void);
extern void am_hal_itm_disable(void);
extern void am_hal_itm_not_busy(void);
extern void am_hal_itm_sync_send(void);
extern void am_hal_itm_trace_port_enable(uint8_t ui8portNum);
extern void am_hal_itm_trace_port_disable(uint8_t ui8portNum);
extern bool am_hal_itm_stimulus_not_busy(uint32_t ui32StimReg);
extern void am_hal_itm_stimulus_reg_word_write(uint32_t ui32StimReg,
uint32_t ui32Value);
extern void am_hal_itm_stimulus_reg_short_write(uint32_t ui32StimReg,
uint16_t ui16Value);
extern void am_hal_itm_stimulus_reg_byte_write(uint32_t ui32StimReg,
uint8_t ui8Value);
extern bool am_hal_itm_print_not_busy(void);
extern void am_hal_itm_print(char *pcString);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_ITM_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,563 @@
//*****************************************************************************
//
// am_hal_mcuctrl.c
//! @file
//!
//! @brief Functions for interfacing with the MCUCTRL.
//!
//! @addtogroup mcuctrl3 MCU Control (MCUCTRL)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Global Variables.
//
//*****************************************************************************
//
// Define the flash sizes from CHIPPN.
//
const uint32_t
g_am_hal_mcuctrl_flash_size[AM_HAL_MCUCTRL_CHIPPN_FLASH_SIZE_N] =
{
16 * 1024, /* 0x0 0x00004000 16 KB */
32 * 1024, /* 0x1 0x00008000 32 KB */
64 * 1024, /* 0x2 0x00010000 64 KB */
128 * 1024, /* 0x3 0x00020000 128 KB */
256 * 1024, /* 0x4 0x00040000 256 KB */
512 * 1024, /* 0x5 0x00080000 512 KB */
1 * 1024 * 1024, /* 0x6 0x00100000 1 MB */
2 * 1024 * 1024, /* 0x7 0x00200000 2 MB */
3 * 1024 * 1024 / 2, /* 0x8 0x00600000 1.5 MB */
0, 0, 0, 0, 0, 0, 0
};
const uint32_t
g_am_hal_mcuctrl_sram_size[AM_HAL_MCUCTRL_CHIPPN_SRAM_SIZE_N] =
{
16 * 1024, /* 0x0 0x00004000 16 KB */
32 * 1024, /* 0x1 0x00008000 32 KB */
64 * 1024, /* 0x2 0x00010000 64 KB */
128 * 1024, /* 0x3 0x00020000 128 KB */
256 * 1024, /* 0x4 0x00040000 256 KB */
512 * 1024, /* 0x5 0x00080000 512 KB */
1 * 1024 * 1024, /* 0x6 0x00100000 1 MB */
384 * 1024, /* 0x7 0x00200000 384 KB */
768 * 1024, /* 0x8 0x000C0000 768 KB */
0, 0, 0, 0, 0, 0, 0
};
// ****************************************************************************
//
// device_info_get()
// Gets all relevant device information.
//
// ****************************************************************************
static void
device_info_get(am_hal_mcuctrl_device_t *psDevice)
{
//
// Read the Part Number.
//
psDevice->ui32ChipPN = MCUCTRL->CHIPPN;
//
// Read the Chip ID0.
//
psDevice->ui32ChipID0 = MCUCTRL->CHIPID0;
//
// Read the Chip ID1.
//
psDevice->ui32ChipID1 = MCUCTRL->CHIPID1;
//
// Read the Chip Revision.
//
psDevice->ui32ChipRev = MCUCTRL->CHIPREV;
//
// Read the Chip VENDOR ID.
//
psDevice->ui32VendorID = MCUCTRL->VENDORID;
//
// Read the SKU (new for Apollo3).
//
psDevice->ui32SKU = MCUCTRL->SKU;
//
// Qualified from Part Number.
//
psDevice->ui32Qualified = (psDevice->ui32ChipPN >> MCUCTRL_CHIPPN_PARTNUM_QUAL_S) & 0x1;
//
// Flash size from Part Number.
//
psDevice->ui32FlashSize =
g_am_hal_mcuctrl_flash_size[
(psDevice->ui32ChipPN & MCUCTRL_CHIPPN_PARTNUM_FLASHSIZE_M) >>
MCUCTRL_CHIPPN_PARTNUM_FLASHSIZE_S];
//
// SRAM size from Part Number.
//
psDevice->ui32SRAMSize =
g_am_hal_mcuctrl_sram_size[
(psDevice->ui32ChipPN & MCUCTRL_CHIPPN_PARTNUM_SRAMSIZE_M) >>
MCUCTRL_CHIPPN_PARTNUM_SRAMSIZE_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, 0xC for Apollo3.
// Bits [3:0] are defined differently for Apollo and Apollo2/Apollo3.
// For Apollo, the low nibble is 0x0.
// For Apollo2/Apollo3, the low nibble indicates flash and SRAM size.
//
psDevice->ui32JedecPN = JEDEC->PID0_b.PNL8 << 0;
psDevice->ui32JedecPN |= JEDEC->PID1_b.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 = JEDEC->PID1_b.JEPIDL << 0;
psDevice->ui32JedecJEPID |= JEDEC->PID2_b.JEPIDH << 4;
//
// CHIPREV is 8 bits located across 2 registers.
//
psDevice->ui32JedecCHIPREV = JEDEC->PID2_b.CHIPREVH4 << 4;
psDevice->ui32JedecCHIPREV |= JEDEC->PID3_b.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 = JEDEC->CID3_b.CID << 24;
psDevice->ui32JedecCID |= JEDEC->CID2_b.CID << 16;
psDevice->ui32JedecCID |= JEDEC->CID1_b.CID << 8;
psDevice->ui32JedecCID |= JEDEC->CID0_b.CID << 0;
} // device_info_get()
//*****************************************************************************
//
// mcuctrl_fault_status()
// Gets the fault status and capture registers.
//
//*****************************************************************************
static void
mcuctrl_fault_status(am_hal_mcuctrl_fault_t *psFault)
{
uint32_t ui32FaultStat;
//
// Read the Fault Status Register.
//
ui32FaultStat = MCUCTRL->FAULTSTATUS;
psFault->bICODE = (bool)(ui32FaultStat & MCUCTRL_FAULTSTATUS_ICODEFAULT_Msk);
psFault->bDCODE = (bool)(ui32FaultStat & MCUCTRL_FAULTSTATUS_DCODEFAULT_Msk);
psFault->bSYS = (bool)(ui32FaultStat & MCUCTRL_FAULTSTATUS_SYSFAULT_Msk);
//
// Read the DCODE fault capture address register.
//
psFault->ui32DCODE = MCUCTRL->DCODEFAULTADDR;
//
// Read the ICODE fault capture address register.
//
psFault->ui32ICODE |= MCUCTRL->ICODEFAULTADDR;
//
// Read the ICODE fault capture address register.
//
psFault->ui32SYS |= MCUCTRL->SYSFAULTADDR;
} // mcuctrl_fault_status()
// ****************************************************************************
//
// am_hal_mcuctrl_control()
// Apply various specific commands/controls on the MCUCTRL module.
//
// ****************************************************************************
uint32_t
am_hal_mcuctrl_control(am_hal_mcuctrl_control_e eControl, void *pArgs)
{
uint32_t ui32Tbl;
switch ( eControl )
{
case AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_ENABLE:
//
// Enable the Fault Capture registers.
//
MCUCTRL->FAULTCAPTUREEN_b.FAULTCAPTUREEN = 1;
break;
case AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_DISABLE:
//
// Disable the Fault Capture registers.
//
MCUCTRL->FAULTCAPTUREEN_b.FAULTCAPTUREEN = 0;
break;
case AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_ENABLE:
//
// Configure the bits in XTALCTRL that enable external 32KHz clock.
//
MCUCTRL->XTALCTRL &=
~(MCUCTRL_XTALCTRL_PDNBCMPRXTAL_Msk |
MCUCTRL_XTALCTRL_PDNBCOREXTAL_Msk |
MCUCTRL_XTALCTRL_BYPCMPRXTAL_Msk |
MCUCTRL_XTALCTRL_FDBKDSBLXTAL_Msk |
MCUCTRL_XTALCTRL_XTALSWE_Msk);
MCUCTRL->XTALCTRL |=
_VAL2FLD(MCUCTRL_XTALCTRL_PDNBCMPRXTAL, MCUCTRL_XTALCTRL_PDNBCMPRXTAL_PWRDNCOMP) |
_VAL2FLD(MCUCTRL_XTALCTRL_PDNBCOREXTAL, MCUCTRL_XTALCTRL_PDNBCOREXTAL_PWRDNCORE) |
_VAL2FLD(MCUCTRL_XTALCTRL_BYPCMPRXTAL, MCUCTRL_XTALCTRL_BYPCMPRXTAL_BYPCOMP) |
_VAL2FLD(MCUCTRL_XTALCTRL_FDBKDSBLXTAL, MCUCTRL_XTALCTRL_FDBKDSBLXTAL_DIS) |
_VAL2FLD(MCUCTRL_XTALCTRL_XTALSWE, MCUCTRL_XTALCTRL_XTALSWE_OVERRIDE_EN);
break;
case AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_DISABLE:
//
// Configure the bits in XTALCTRL that disable external 32KHz
// clock, thus re-configuring for the crystal.
//
MCUCTRL->XTALCTRL &=
~(MCUCTRL_XTALCTRL_PDNBCMPRXTAL_Msk |
MCUCTRL_XTALCTRL_PDNBCOREXTAL_Msk |
MCUCTRL_XTALCTRL_BYPCMPRXTAL_Msk |
MCUCTRL_XTALCTRL_FDBKDSBLXTAL_Msk |
MCUCTRL_XTALCTRL_XTALSWE_Msk);
MCUCTRL->XTALCTRL |=
_VAL2FLD(MCUCTRL_XTALCTRL_PDNBCMPRXTAL, MCUCTRL_XTALCTRL_PDNBCMPRXTAL_PWRUPCOMP) |
_VAL2FLD(MCUCTRL_XTALCTRL_PDNBCOREXTAL, MCUCTRL_XTALCTRL_PDNBCOREXTAL_PWRUPCORE) |
_VAL2FLD(MCUCTRL_XTALCTRL_BYPCMPRXTAL, MCUCTRL_XTALCTRL_BYPCMPRXTAL_USECOMP) |
_VAL2FLD(MCUCTRL_XTALCTRL_FDBKDSBLXTAL, MCUCTRL_XTALCTRL_FDBKDSBLXTAL_EN) |
_VAL2FLD(MCUCTRL_XTALCTRL_XTALSWE, MCUCTRL_XTALCTRL_XTALSWE_OVERRIDE_DIS);
break;
case AM_HAL_MCUCTRL_CONTROL_SRAM_PREFETCH:
{
uint32_t ui32SramPrefetch = *(uint32_t*)pArgs;
uint32_t ui32SetMsk, ui32ClrMsk, ui32SRAMreg;
//
// Validate the input flags.
//
if ( ui32SramPrefetch &
~(AM_HAL_MCUCTRL_SRAM_PREFETCH_INSTR |
AM_HAL_MCUCTRL_SRAM_PREFETCH_INSTRCACHE |
AM_HAL_MCUCTRL_SRAM_PREFETCH_DATA |
AM_HAL_MCUCTRL_SRAM_PREFETCH_DATACACHE |
AM_HAL_MCUCTRL_SRAM_NOPREFETCH_INSTR |
AM_HAL_MCUCTRL_SRAM_NOPREFETCH_INSTRCACHE |
AM_HAL_MCUCTRL_SRAM_NOPREFETCH_DATA |
AM_HAL_MCUCTRL_SRAM_NOPREFETCH_DATACACHE) )
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Given the rule that NOxxx overrides xxx, and keeping in mind
// that the cache settings cannot be set unless the regular
// prefetch is also being set or is already set, the following
// truth table results.
// Note - this same TT also applies to data settings.
// nc=no change.
// I IC NI NIC: I IC
// 0x0: 0 0 0 0 : nc nc
// 0x1: 0 0 0 1 : nc 0
// 0x2: 0 0 1 0 : 0 0
// 0x3: 0 0 1 1 : 0 0
// 0x4: 0 1 0 0 : INVALID
// 0x5: 0 1 0 1 : nc nc
// 0x6: 0 1 1 0 : INVALID
// 0x7: 0 1 1 1 : 0 0
// 0x8: 1 0 0 0 : 1 0
// 0x9: 1 0 0 1 : 1 0
// 0xA: 1 0 1 0 : 0 0
// 0xB: 1 0 1 1 : 0 0
// 0xC: 1 1 0 0 : 1 1
// 0xD: 1 1 0 1 : 1 0
// 0xE: 1 1 1 0 : INVALID
// 0xF: 1 1 1 1 : 0 0
//
ui32Tbl = 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_PREFETCH_INSTR) ? (1 << 3) : 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_PREFETCH_INSTRCACHE) ? (1 << 2) : 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_NOPREFETCH_INSTR) ? (1 << 1) : 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_NOPREFETCH_INSTRCACHE) ? (1 << 0) : 0;
//
// Now augment the table entries with current register settings.
//
ui32SRAMreg = MCUCTRL->SRAMMODE;
ui32Tbl |= ui32SRAMreg & MCUCTRL_SRAMMODE_IPREFETCH_Msk ? (1 << 3) : 0;
ui32Tbl |= ui32SRAMreg & MCUCTRL_SRAMMODE_IPREFETCH_CACHE_Msk ? (1 << 2) : 0;
ui32SetMsk = ui32ClrMsk = 0;
switch ( ui32Tbl )
{
case 0x0:
case 0x5:
break;
case 0x1:
ui32ClrMsk = MCUCTRL_SRAMMODE_IPREFETCH_CACHE_Msk;
break;
case 0x2:
case 0x3:
case 0x7:
case 0xA:
case 0xB:
case 0xF:
ui32ClrMsk = MCUCTRL_SRAMMODE_IPREFETCH_Msk | MCUCTRL_SRAMMODE_IPREFETCH_CACHE_Msk;
break;
case 0x4:
case 0x6:
case 0xE:
return AM_HAL_STATUS_INVALID_OPERATION;
case 0x8:
case 0x9:
case 0xD:
ui32SetMsk = MCUCTRL_SRAMMODE_IPREFETCH_Msk;
ui32ClrMsk = MCUCTRL_SRAMMODE_IPREFETCH_CACHE_Msk;
break;
case 0xC:
ui32SetMsk = MCUCTRL_SRAMMODE_IPREFETCH_Msk | MCUCTRL_SRAMMODE_IPREFETCH_CACHE_Msk;
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
} // switch()
//
// Now, repeat with data settings.
//
ui32Tbl = 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_PREFETCH_DATA) ? (1 << 3) : 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_PREFETCH_DATACACHE) ? (1 << 2) : 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_NOPREFETCH_DATA) ? (1 << 1) : 0;
ui32Tbl |= (ui32SramPrefetch & AM_HAL_MCUCTRL_SRAM_NOPREFETCH_DATACACHE) ? (1 << 0) : 0;
//
// Now augment the table entries with current register settings.
//
ui32Tbl |= ui32SRAMreg & MCUCTRL_SRAMMODE_DPREFETCH_Msk ? (1 << 3) : 0;
ui32Tbl |= ui32SRAMreg & MCUCTRL_SRAMMODE_DPREFETCH_CACHE_Msk ? (1 << 2) : 0;
switch ( ui32Tbl )
{
case 0x0:
case 0x5:
break;
case 0x1:
ui32ClrMsk = MCUCTRL_SRAMMODE_DPREFETCH_CACHE_Msk;
break;
case 0x2:
case 0x3:
case 0x7:
case 0xA:
case 0xB:
case 0xF:
ui32ClrMsk = MCUCTRL_SRAMMODE_DPREFETCH_Msk | MCUCTRL_SRAMMODE_DPREFETCH_CACHE_Msk;
break;
case 0x4:
case 0x6:
case 0xE:
return AM_HAL_STATUS_INVALID_OPERATION;
case 0x8:
case 0x9:
case 0xD:
ui32SetMsk = MCUCTRL_SRAMMODE_DPREFETCH_Msk;
ui32ClrMsk = MCUCTRL_SRAMMODE_DPREFETCH_CACHE_Msk;
break;
case 0xC:
ui32SetMsk = MCUCTRL_SRAMMODE_DPREFETCH_Msk | MCUCTRL_SRAMMODE_DPREFETCH_CACHE_Msk;
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
} // switch()
//
// Arrange the register update such that clrmsk will have precedence
// over setmsk.
//
AM_CRITICAL_BEGIN
ui32SRAMreg = MCUCTRL->SRAMMODE;
ui32SRAMreg |= ui32SetMsk;
ui32SRAMreg &= ~ui32ClrMsk;
MCUCTRL->SRAMMODE = ui32SRAMreg;
AM_CRITICAL_END
} // case AM_HAL_MCUCTRL_CONTROL_SRAM_PREFETCH
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_mcuctrl_control()
// ****************************************************************************
//
// am_hal_mcuctrl_status_get()
//! This function returns current status of the MCUCTRL as obtained from
//! various registers of the MCUCTRL block.
//
// ****************************************************************************
uint32_t
am_hal_mcuctrl_status_get(am_hal_mcuctrl_status_t *psStatus)
{
uint32_t ui32Status;
if ( psStatus == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
ui32Status = MCUCTRL->FEATUREENABLE;
psStatus->bBurstAck =
_FLD2VAL(MCUCTRL_FEATUREENABLE_BURSTACK, ui32Status);
psStatus->bBLEAck =
_FLD2VAL(MCUCTRL_FEATUREENABLE_BLEACK, ui32Status);
psStatus->bDebuggerLockout =
_FLD2VAL(MCUCTRL_DEBUGGER_LOCKOUT, MCUCTRL->DEBUGGER);
psStatus->bADCcalibrated =
_FLD2VAL(MCUCTRL_ADCCAL_ADCCALIBRATED, MCUCTRL->ADCCAL);
psStatus->bBattLoadEnabled =
_FLD2VAL(MCUCTRL_ADCBATTLOAD_BATTLOAD, MCUCTRL->ADCBATTLOAD);
ui32Status = MCUCTRL->BOOTLOADER;
psStatus->bSecBootOnColdRst =
_FLD2VAL(MCUCTRL_BOOTLOADER_SECBOOT, ui32Status);
psStatus->bSecBootOnWarmRst =
_FLD2VAL(MCUCTRL_BOOTLOADER_SECBOOTONRST, ui32Status);
return AM_HAL_STATUS_SUCCESS;
} // am_hal_mcuctrl_status_get()
// ****************************************************************************
//
// am_hal_mcuctrl_info_get()
// Get information of the given MCUCTRL item.
//
// ****************************************************************************
uint32_t
am_hal_mcuctrl_info_get(am_hal_mcuctrl_infoget_e eInfoGet, void *pInfo)
{
am_hal_mcuctrl_feature_t *psFeature;
uint32_t ui32Feature;
if ( pInfo == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
switch ( eInfoGet )
{
case AM_HAL_MCUCTRL_INFO_FEATURES_AVAIL:
psFeature = (am_hal_mcuctrl_feature_t*)pInfo;
ui32Feature = MCUCTRL->FEATUREENABLE;
psFeature->bBurstAvail =
_FLD2VAL(MCUCTRL_FEATUREENABLE_BURSTAVAIL, ui32Feature);
psFeature->bBLEavail =
_FLD2VAL(MCUCTRL_FEATUREENABLE_BLEAVAIL, ui32Feature);
ui32Feature = MCUCTRL->BOOTLOADER;
psFeature->ui8SecBootFeature =
_FLD2VAL(MCUCTRL_BOOTLOADER_SECBOOTFEATURE, ui32Feature);
ui32Feature = MCUCTRL->SKU;
psFeature->bBLEFeature =
_FLD2VAL(MCUCTRL_SKU_ALLOWBLE, ui32Feature);
psFeature->bBurstFeature =
_FLD2VAL(MCUCTRL_SKU_ALLOWBURST, ui32Feature);
break;
case AM_HAL_MCUCTRL_INFO_DEVICEID:
device_info_get((am_hal_mcuctrl_device_t *)pInfo);
break;
case AM_HAL_MCUCTRL_INFO_FAULT_STATUS:
mcuctrl_fault_status((am_hal_mcuctrl_fault_t*)pInfo);
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_mcuctrl_info_get()
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,367 @@
//*****************************************************************************
//
// am_hal_mcuctrl.h
//! @file
//!
//! @brief Functions for accessing and configuring the MCUCTRL.
//!
//! @addtogroup mcuctrl3 MCU Control (MCUCTRL)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_MCUCTRL_H
#define AM_HAL_MCUCTRL_H
#ifdef __cplusplus
extern "C"
{
#endif
//
// Designate this peripheral.
//
#define AM_APOLLO3_MCUCTRL 1
//*****************************************************************************
//
// Chip Revision IDentification.
//
//*****************************************************************************
#define APOLLO3_B0 \
((MCUCTRL->CHIPREV & \
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) == \
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_B) | \
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))
#define APOLLO3_A1 \
((MCUCTRL->CHIPREV & \
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) == \
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) | \
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV1)))
#define APOLLO3_A0 \
((MCUCTRL->CHIPREV & \
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) == \
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) | \
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))
//
// Determine if >= a given revision level.
//
#define APOLLO3_GE_B0 \
((MCUCTRL->CHIPREV & \
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) >= \
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_B) | \
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV0)))
#define APOLLO3_GE_A1 \
((MCUCTRL->CHIPREV & \
(MCUCTRL_CHIPREV_REVMAJ_Msk | MCUCTRL_CHIPREV_REVMIN_Msk)) >= \
(_VAL2FLD(MCUCTRL_CHIPREV_REVMAJ, MCUCTRL_CHIPREV_REVMAJ_A) | \
_VAL2FLD(MCUCTRL_CHIPREV_REVMIN, MCUCTRL_CHIPREV_REVMIN_REV1)))
//*****************************************************************************
//
// MCUCTRL specific definitions.
//
//*****************************************************************************
#define AM_HAL_MCUCTRL_CHIPPN_FLASH_SIZE_N ((MCUCTRL_CHIPPN_PARTNUM_FLASHSIZE_M >> MCUCTRL_CHIPPN_PARTNUM_FLASHSIZE_S) + 1)
#define AM_HAL_MCUCTRL_CHIPPN_SRAM_SIZE_N ((MCUCTRL_CHIPPN_PARTNUM_SRAMSIZE_M >> MCUCTRL_CHIPPN_PARTNUM_SRAMSIZE_S) + 1)
//*****************************************************************************
//
// MCUCTRL enumerations
//
//*****************************************************************************
//**************************************
//! MCUCTRL control operations
//**************************************
typedef enum
{
AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_ENABLE,
AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_DISABLE,
AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_ENABLE,
AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_DISABLE,
AM_HAL_MCUCTRL_CONTROL_SRAM_PREFETCH
} am_hal_mcuctrl_control_e;
//**************************************
//! MCUCTRL info get
//**************************************
typedef enum
{
AM_HAL_MCUCTRL_INFO_FEATURES_AVAIL,
AM_HAL_MCUCTRL_INFO_DEVICEID,
AM_HAL_MCUCTRL_INFO_FAULT_STATUS
} am_hal_mcuctrl_infoget_e;
//**************************************
//! MCUCTRL SRAM prefetch settings
//!
//! Prefetch settings are made via a call to:
//! am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_SRAM_PREFETCH,
//! &ui32PrefetchSetting);
//!
//! The settings may be logically ORed together to obtain the desired settings.
//!
//! Notes:
//! - NOPREFETCH settings override PREFETCH settings if both are provided.
//! For example, calling with both PREFETCH_INSTR and NOPREFETCH_INSTR
//! will result in instruction prefetch being disabled.
//! - When executing from SRAM, it is recommended that the PREFETCH_INSTR and
//! PREFETCH_INSTRCACHE bits be set.
//! - It is generally okay to have PREFETCH_INSTR & PREFETCH_INSTRCACHE enabled
//! even if no SRAM execution is expected.
//! - It is generally not recommended that data prefetch be enabled unless the
//! work flow has a large number of sequential accesses.
//! - Setting PREFETCH_INSTRCACHE requires PREFETCH_INSTR. This is enforced by
//! the function and an error is returned if both are not being set or if
//! PREFETCH_INSTR is not already set in the register.
//! - Setting PREFETCH_DATACACHE requires PREFETCH_DATA. This is enforced by
//! the function. An error is returned if both are not being set or if
//! PREFETCH_DATA is not already set in the register.
//**************************************
#define SRAM_NOPREFETCH_Pos 16
#define AM_HAL_MCUCTRL_SRAM_PREFETCH_INSTR (MCUCTRL_SRAMMODE_IPREFETCH_Msk << 0)
#define AM_HAL_MCUCTRL_SRAM_PREFETCH_INSTRCACHE (MCUCTRL_SRAMMODE_IPREFETCH_CACHE_Msk << 0)
#define AM_HAL_MCUCTRL_SRAM_PREFETCH_DATA (MCUCTRL_SRAMMODE_DPREFETCH_Msk << 0)
#define AM_HAL_MCUCTRL_SRAM_PREFETCH_DATACACHE (MCUCTRL_SRAMMODE_DPREFETCH_CACHE_Msk << 0)
#define AM_HAL_MCUCTRL_SRAM_NOPREFETCH_INSTR (MCUCTRL_SRAMMODE_IPREFETCH_Msk << SRAM_NOPREFETCH_Pos)
#define AM_HAL_MCUCTRL_SRAM_NOPREFETCH_INSTRCACHE (MCUCTRL_SRAMMODE_IPREFETCH_CACHE_Msk << SRAM_NOPREFETCH_Pos)
#define AM_HAL_MCUCTRL_SRAM_NOPREFETCH_DATA (MCUCTRL_SRAMMODE_DPREFETCH_Msk << SRAM_NOPREFETCH_Pos)
#define AM_HAL_MCUCTRL_SRAM_NOPREFETCH_DATACACHE (MCUCTRL_SRAMMODE_DPREFETCH_CACHE_Msk << SRAM_NOPREFETCH_Pos)
//*****************************************************************************
//
// MCUCTRL data structures
//
//*****************************************************************************
//**************************************
//! MCUCTRL device structure
//**************************************
typedef struct
{
//
//! Device part number. (BCD format)
//
uint32_t ui32ChipPN;
//
//! Unique Chip ID 0.
//
uint32_t ui32ChipID0;
//
//! Unique Chip ID 1.
//
uint32_t ui32ChipID1;
//
//! Chip Revision.
//
uint32_t ui32ChipRev;
//
//! Vendor ID.
//
uint32_t ui32VendorID;
//
//! SKU (Apollo3).
//
uint32_t ui32SKU;
//
//! Qualified chip.
//
uint32_t ui32Qualified;
//
//! Flash Size.
//
uint32_t ui32FlashSize;
//
//! SRAM Size.
//
uint32_t ui32SRAMSize;
//
// JEDEC chip info
//
uint32_t ui32JedecPN;
uint32_t ui32JedecJEPID;
uint32_t ui32JedecCHIPREV;
uint32_t ui32JedecCID;
}
am_hal_mcuctrl_device_t;
//**************************************
//! MCUCTRL fault structure
//**************************************
typedef struct
{
//
//! ICODE bus fault occurred.
//
bool bICODE;
//
//! ICODE bus fault address.
//
uint32_t ui32ICODE;
//
//! DCODE bus fault occurred.
//
bool bDCODE;
//
//! DCODE bus fault address.
//
uint32_t ui32DCODE;
//
//! SYS bus fault occurred.
//
bool bSYS;
//
//! SYS bus fault address.
//
uint32_t ui32SYS;
}
am_hal_mcuctrl_fault_t;
//**************************************
//! MCUCTRL status structure
//**************************************
typedef struct
{
bool bBurstAck; // FEATUREENABLE
bool bBLEAck; // "
bool bDebuggerLockout; // DEBUGGER
bool bADCcalibrated; // ADCCAL
bool bBattLoadEnabled; // ADCBATTLOAD
uint8_t bSecBootOnWarmRst; // BOOTLOADER
uint8_t bSecBootOnColdRst; // "
} am_hal_mcuctrl_status_t;
//**************************************
//! MCUCTRL features available structure
//**************************************
typedef struct
{
bool bBurstAvail; // FEATUREENABLE
bool bBLEavail; // "
bool bBLEFeature; // SKU
bool bBurstFeature; // "
uint8_t ui8SecBootFeature; // BOOTLOADER
} am_hal_mcuctrl_feature_t;
// ****************************************************************************
//
//! @brief Apply various specific commands/controls on the MCUCTRL module.
//!
//! This function is used to apply various controls to MCUCTRL.
//!
//! @param eControl - One of the following:
//! AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_ENABLE
//! AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_DISABLE
//! AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_ENABLE
//! AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_DISABLE
//! AM_HAL_MCUCTRL_CONTROL_SRAM_PREFETCH
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_mcuctrl_control(am_hal_mcuctrl_control_e eControl,
void *pArgs);
// ****************************************************************************
//
//! @brief MCUCTRL status function
//!
//! This function returns current status of the MCUCTRL as obtained from
//! various registers of the MCUCTRL block.
//!
//! @param psStatus - ptr to a status structure to receive the current statuses.
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_mcuctrl_status_get(am_hal_mcuctrl_status_t *psStatus);
// ****************************************************************************
//
//! @brief Get information of the given MCUCTRL item.
//!
//! This function returns a data structure of information regarding the given
//! MCUCTRL parameter.
//!
//! @param eInfoGet - One of the following: Return structure type:
//! AM_HAL_MCUCTRL_INFO_DEVICEID, psDevice
//! AM_HAL_MCUCTRL_INFO_FAULT_STATUS psFault
//!
//! @param pInfo - A pointer to a structure to receive the return data,
//! the type of which is dependent on the eInfo parameter.
//!
//! @return status - generic or interface specific status.
//
// ****************************************************************************
extern uint32_t am_hal_mcuctrl_info_get(am_hal_mcuctrl_infoget_e eInfoGet,
void *pInfo);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_MCUCTRL_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,780 @@
//*****************************************************************************
//
// am_hal_mspi.h
//! @file
//!
//! @brief Functions for accessing and configuring the MSPI.
//!
//! @addtogroup mspi3 Multi-bit SPI (MSPI)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_MSPI_H
#define AM_HAL_MSPI_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! CMSIS-Style macro for handling a variable MSPI module number.
//
//*****************************************************************************
#define MSPIn(n) ((MSPI_Type*)(MSPI_BASE + (n * (MSPI_BASE - MSPI_BASE))))
//
// USE_CQ=1 will use the Command Queue in nonblocking transfers.
// 0 uses plain DMA (w/o CQ) in nonblocking transfers.
//
#define MSPI_USE_CQ 1
#define AM_HAL_MSPI_MAX_FIFO_SIZE 16
#define AM_HAL_MSPI_DEFAULT_BURST_COUNT 32
// Size guideline for allocation of application supploed buffers
#define AM_HAL_MSPI_CQ_ENTRY_SIZE (18 * sizeof(uint32_t))
#define AM_HAL_MSPI_HIPRIO_ENTRY_SIZE (6 * sizeof(uint32_t))
#define AM_HAL_MSPI_SC_CLEAR(flag) ((flag) << 16)
#define AM_HAL_MSPI_SC_SET(flag) ((flag))
// For MSPI - Need to Set the flag for unpausing
#define AM_HAL_MSPI_SC_UNPAUSE(flag) AM_HAL_MSPI_SC_SET(flag)
#define AM_HAL_MSPI_SC_PAUSE(flag) AM_HAL_MSPI_SC_CLEAR(flag)
// Use this macro to directly control the flags
#define AM_HAL_MSPI_SETCLR(module, scVal) \
do { \
MSPIn(module)->CQSETCLEAR = (scVal); \
} while (0);
// Flags 5, 7 & 6 are reserved by HAL
#define AM_HAL_MSPI_PAUSE_FLAG_RESV (MSPI_CQFLAGS_CQFLAGS_SWFLAG7 | MSPI_CQFLAGS_CQFLAGS_SWFLAG6 | MSPI_CQFLAGS_CQFLAGS_SWFLAG5)
#define AM_HAL_MSPI_SC_RESV_MASK (AM_HAL_MSPI_PAUSE_FLAG_RESV | (AM_HAL_MSPI_PAUSE_FLAG_RESV << 8) | (AM_HAL_MSPI_PAUSE_FLAG_RESV << 16))
// We use SWFLAGEN7 to control SW pausing Command Queue - default unPause
// We use SWFLAGEN6 to pause on the sequece loopback - default Pause
// We use SWFLAGEN5 to pause CQ while a block is building
#define AM_HAL_MSPI_PAUSE_FLAG_IDX (_VAL2FLD(MSPI_CQFLAGS_CQFLAGS, MSPI_CQFLAGS_CQFLAGS_CQIDX))
#define AM_HAL_MSPI_PAUSE_FLAG_CQ (_VAL2FLD(MSPI_CQFLAGS_CQFLAGS, MSPI_CQFLAGS_CQFLAGS_SWFLAG7))
#define AM_HAL_MSPI_PAUSE_FLAG_SEQLOOP (_VAL2FLD(MSPI_CQFLAGS_CQFLAGS, MSPI_CQFLAGS_CQFLAGS_SWFLAG6))
#define AM_HAL_MSPI_PAUSE_FLAG_BLOCK (_VAL2FLD(MSPI_CQFLAGS_CQFLAGS, MSPI_CQFLAGS_CQFLAGS_SWFLAG5))
// By default - we Pause CQ for no more entries, or force pause from SW
#define AM_HAL_MSPI_PAUSE_DEFAULT (AM_HAL_MSPI_PAUSE_FLAG_IDX)
#define AM_HAL_MSPI_CQP_PAUSE_DEFAULT (AM_HAL_MSPI_PAUSE_FLAG_IDX | AM_HAL_MSPI_PAUSE_FLAG_CQ)
//*****************************************************************************
//
//! @name MSPI Interrupts
//! @brief Macro definitions for MSPI interrupt status bits.
//!
//! These macros correspond to the bits in the MSPI interrupt status register.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_MSPI_INT_SCRERR MSPI_INTEN_SCRERR_Msk
#define AM_HAL_MSPI_INT_CQERR MSPI_INTEN_CQERR_Msk
#define AM_HAL_MSPI_INT_CQPAUSED MSPI_INTEN_CQPAUSED_Msk
#define AM_HAL_MSPI_INT_CQUPD MSPI_INTEN_CQUPD_Msk
#define AM_HAL_MSPI_INT_CQCMP MSPI_INTEN_CQCMP_Msk
#define AM_HAL_MSPI_INT_DMAERR MSPI_INTEN_DERR_Msk
#define AM_HAL_MSPI_INT_DMACMP MSPI_INTEN_DCMP_Msk
#define AM_HAL_MSPI_INT_RX_FIFO_FULL MSPI_INTEN_RXF_Msk
#define AM_HAL_MSPI_INT_RX_FIFO_OVFL MSPI_INTEN_RXO_Msk
#define AM_HAL_MSPI_INT_RX_FIFO_UNFL MSPI_INTEN_RXU_Msk
#define AM_HAL_MSPI_INT_TX_FIFO_OVFL MSPI_INTEN_TXO_Msk
#define AM_HAL_MSPI_INT_TX_FIFO_EMPTY MSPI_INTEN_TXE_Msk
#define AM_HAL_MSPI_INT_CMDCMP MSPI_INTEN_CMDCMP_Msk
#define AM_HAL_MSPI_INT_ALL 0xFFFFFFFF
#define AM_HAL_MSPI_INT_ERR (AM_HAL_MSPI_INT_DMAERR | AM_HAL_MSPI_INT_CQERR | AM_HAL_MSPI_INT_SCRERR)
#define AM_HAL_MSPI_LINK_IOM_NONE 0x7
//*****************************************************************************
//
//! @brief Configuration structure for the MSPI.
//
//*****************************************************************************
//
// Number of bytes in the address
//
typedef enum
{
AM_HAL_MSPI_ADDR_1_BYTE,
AM_HAL_MSPI_ADDR_2_BYTE,
AM_HAL_MSPI_ADDR_3_BYTE,
AM_HAL_MSPI_ADDR_4_BYTE
} am_hal_mspi_addr_e;
//
// Number of bytes in the instruction
//
typedef enum
{
AM_HAL_MSPI_INSTR_1_BYTE,
AM_HAL_MSPI_INSTR_2_BYTE
} am_hal_mspi_instr_e;
//
// Transmit or receive
//
typedef enum
{
AM_HAL_MSPI_RX = 0,
AM_HAL_MSPI_TX = 1
} am_hal_mspi_dir_e;
//
// Mode of Transfer.
//
typedef enum
{
AM_HAL_MSPI_TRANS_PIO,
AM_HAL_MSPI_TRANS_DMA
} am_hal_mspi_trans_e;
//
// MSPI interface mode and chip enable selection
//
typedef enum
{
AM_HAL_MSPI_FLASH_SERIAL_CE0,
AM_HAL_MSPI_FLASH_SERIAL_CE1,
AM_HAL_MSPI_FLASH_DUAL_CE0,
AM_HAL_MSPI_FLASH_DUAL_CE1,
AM_HAL_MSPI_FLASH_QUAD_CE0,
AM_HAL_MSPI_FLASH_QUAD_CE1,
AM_HAL_MSPI_FLASH_OCTAL_CE0,
AM_HAL_MSPI_FLASH_OCTAL_CE1,
AM_HAL_MSPI_FLASH_QUADPAIRED,
AM_HAL_MSPI_FLASH_QUADPAIRED_SERIAL,
AM_HAL_MSPI_FLASH_MAX = AM_HAL_MSPI_FLASH_QUADPAIRED_SERIAL
} am_hal_mspi_device_e;
//
// Enumerate the SPI modes. Note that these are arranged per the ordering of
// SPHA (bit1) and SPOL (bit0) in the IOM.MSPICFG register.
//
typedef enum
{
AM_HAL_MSPI_SPI_MODE_0, // CPOL = 0; CPHA = 0
AM_HAL_MSPI_SPI_MODE_2, // CPOL = 1; CPHA = 0
AM_HAL_MSPI_SPI_MODE_1, // CPOL = 0; CPHA = 1
AM_HAL_MSPI_SPI_MODE_3, // CPOL = 1; CPHA = 1
} am_hal_mspi_spi_mode_e;
typedef enum
{
AM_HAL_MSPI_CLK_48MHZ = 1,
AM_HAL_MSPI_CLK_24MHZ = 2,
AM_HAL_MSPI_CLK_16MHZ = 3,
AM_HAL_MSPI_CLK_12MHZ = 4,
AM_HAL_MSPI_CLK_8MHZ = 6,
AM_HAL_MSPI_CLK_6MHZ = 8,
AM_HAL_MSPI_CLK_4P8MHZ = 10,
AM_HAL_MSPI_CLK_4MHZ = 12,
AM_HAL_MSPI_CLK_3P2MHZ = 15,
AM_HAL_MSPI_CLK_3MHZ = 16,
AM_HAL_MSPI_CLK_1P5MHZ = 32
} am_hal_mspi_clock_e;
//
// Transfer callback function prototype
//
typedef void (*am_hal_mspi_callback_t)(void *pCallbackCtxt, uint32_t status);
typedef struct
{
bool bLoop;
//! Command Queue Transaction Gating
uint32_t ui32PauseCondition;
//! Command Queue Post-Transaction status setting
uint32_t ui32StatusSetClr;
} am_hal_mspi_seq_end_t;
typedef struct
{
uint8_t *pBuf; // Buffer provided to store the high priority transaction context
uint32_t size; // Size of buffer in bytes
} am_hal_mspi_hiprio_cfg_t;
typedef struct
{
//! Command Queue Advanced control on gating conditions for transaction to start
uint32_t ui32PauseCondition;
//! Command Queue Advanced Post-Transaction status setting
uint32_t ui32StatusSetClr;
am_hal_cmdq_entry_t *pCQEntry;
uint32_t numEntries;
am_hal_mspi_callback_t pfnCallback;
void *pCallbackCtxt;
uint32_t *pJmpAddr;
} am_hal_mspi_cq_raw_t;
typedef enum
{
// Pass uint32_t as pConfig
AM_HAL_MSPI_REQ_APBCLK,
// Used to set/clear 8 CQ Pause flags - reserved flags are defined as AM_HAL_MSPI_PAUSE_FLAG_RESV
AM_HAL_MSPI_REQ_FLAG_SETCLR,
// Pass uint32_t as pConfig indicating the IOM# to link to. AM_HAL_MSPI_LINK_IOM_NONE indicates no IOM linked
AM_HAL_MSPI_REQ_LINK_IOM,
// pConfig N/A
AM_HAL_MSPI_REQ_SCRAMB_DIS,
// pConfig N/A
AM_HAL_MSPI_REQ_SCRAMB_EN,
// Pass uint32_t as pConfig
AM_HAL_MSPI_REQ_XIPACK,
// pConfig N/A
AM_HAL_MSPI_REQ_XIP_DIS,
// pConfig N/A
AM_HAL_MSPI_REQ_XIP_EN,
// Pass mspi_device_info_t as pConfig
AM_HAL_MSPI_REQ_DEVICE_CONFIG,
// Pause the CQ gracefully
AM_HAL_MSPI_REQ_PAUSE,
// Unpause the CQ
AM_HAL_MSPI_REQ_UNPAUSE,
// Get in and out of Sequence Mode - which allows building a sequence, which either runs once, or repeats
// Pass in bool as pConfig - true/false
AM_HAL_MSPI_REQ_SET_SEQMODE,
// Pass am_hal_mspi_seq_end_t * as pConfig
AM_HAL_MSPI_REQ_SEQ_END,
// Initialize configuration for high priority trasactions
// These transactions take precedence over existing CQ transactions
// Pass am_hal_mspi_hiprio_cfg_t * as pConfig
AM_HAL_MSPI_REQ_INIT_HIPRIO,
// Create a block of transactions which are not paused in between
// pConfig N/A
AM_HAL_MSPI_REQ_START_BLOCK,
// pConfig N/A
AM_HAL_MSPI_REQ_END_BLOCK,
// Raw CQ transaction
// Pass am_hal_mspi_cq_raw_t * as pConfig
AM_HAL_MSPI_REQ_CQ_RAW,
AM_HAL_MSPI_REQ_MAX
} am_hal_mspi_request_e;
typedef enum
{
AM_HAL_MSPI_XIPMIXED_NORMAL = 0,
AM_HAL_MSPI_XIPMIXED_D2 = 1, //1:1:2 timing for Instr:Addr:Data
AM_HAL_MSPI_XIPMIXED_AD2 = 3, //1:2:2 timing for Instr:Addr:Data
AM_HAL_MSPI_XIPMIXED_D4 = 5, //1:1:4 timing for Instr:Addr:Data
AM_HAL_MSPI_XIPMIXED_AD4 = 7 //1:4:4 timing for Instr:Addr:Data
} am_hal_mspi_xipmixed_mode_e;
//
// Device configuration structure
//
typedef struct
{
//
// MSPI device configuration for Polling I/O (PIO) Operation.
//
//! Number of turn around cycles between an Address write and Data read.
uint8_t ui8TurnAround;
//! Address Configuration
am_hal_mspi_addr_e eAddrCfg;
//! Instruction Configuration
am_hal_mspi_instr_e eInstrCfg;
//! Read instruction sent to flash device
uint8_t ui8ReadInstr;
//! Write instruction sent to flash device
uint8_t ui8WriteInstr;
//! External Flash Device configuration
am_hal_mspi_device_e eDeviceConfig;
//
// MSPI clock configuration.
//
//! SPI Mode.
am_hal_mspi_spi_mode_e eSpiMode;
//! Clock frequency
am_hal_mspi_clock_e eClockFreq;
//! XIPMIXED configure
am_hal_mspi_xipmixed_mode_e eXipMixedMode;
//
// MSPI device configuration for XIP/DMA/Scrambling operations.
//
//! Send Device Address
bool bSendAddr;
//! Send Device Instruction
bool bSendInstr;
//! Separate MOSI/MISO
bool bSeparateIO;
//! Enable Turnaround between Address write and Data read.
bool bTurnaround;
//
// MSPI DMA TCB/Command Queue memory allocation.
//
//! DMA Transfer Control Buffer size in words.
uint32_t ui32TCBSize;
//! DMA Transfer Control Buffer
uint32_t *pTCB;
//
// MSPI Scrambling configuration.
//
//! Scrambling Start Address
uint32_t scramblingStartAddr;
//! Scrambling End Address
uint32_t scramblingEndAddr;
} am_hal_mspi_dev_config_t;
//
// MSPI configuration record for determining virtual device configuration.
//
typedef struct
{
//! External Flash Device configuration
am_hal_mspi_device_e eDeviceConfig;
//! XIPMIXED configure
am_hal_mspi_xipmixed_mode_e eXipMixedMode;
//! Separate MOSI/MISO
bool bSeparateIO;
} mspi_device_info_t;
//
// MSPI Capabilities structure
//
typedef struct
{
am_hal_mspi_device_e eDeviceConfig;
} am_hal_mspi_capabilities_t;
//
// Device PIO transfer structure
//
typedef struct
{
//! Number of bytes to transfer
uint32_t ui32NumBytes;
//! Enable scrambling.
bool bScrambling;
//! Transfer Direction (Transmit/Receive)
am_hal_mspi_dir_e eDirection;
//! Send Device Address
bool bSendAddr;
//! Device Address
uint32_t ui32DeviceAddr;
//! Send Device Instruction
bool bSendInstr;
//! Device Instruction
uint16_t ui16DeviceInstr;
//! Enable Turnaround between Address write and Data read.
bool bTurnaround;
//! Paired-Quad
bool bQuadCmd;
//! Buffer
uint32_t *pui32Buffer;
} am_hal_mspi_pio_transfer_t;
//
// DMA transfer structure
//
typedef struct
{
//! Address Configuration
am_hal_mspi_addr_e eAddrCfg;
//! Priority 0 = Low (best effort); 1 = High (service immediately)
uint8_t ui8Priority;
//! Direction RX: 0 = Peripheral to Memory; TX: 1 = Memory to Peripheral
am_hal_mspi_dir_e eDirection;
//! Transfer Count
uint32_t ui32TransferCount;
//! External Flash Device Address
uint32_t ui32DeviceAddress;
//! Internal SRAM Address
uint32_t ui32SRAMAddress;
//! Command Queue Transaction Gating
uint32_t ui32PauseCondition;
//! Command Queue Post-Transaction status setting
uint32_t ui32StatusSetClr;
} am_hal_mspi_dma_transfer_t;
//
// MSPI status structure.
//
typedef struct
{
//
// DMA status.
//
bool bErr;
bool bCmp;
bool bTIP;
uint32_t ui32NumCQEntries;
} am_hal_mspi_status_t;
#define am_hal_mspi_buffer(A) \
union \
{ \
uint32_t words[(A + 3) >> 2]; \
uint8_t bytes[A]; \
}
//*****************************************************************************
//
//! @brief MSPI initialization function
//!
//! @param ui32Module - module instance.
//! @param handle - returns the handle for the module instance.
//!
//! This function accepts a module instance, allocates the interface and then
//! returns a handle to be used by the remaining interface functions.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_initialize(uint32_t ui32Module,
void **ppHandle);
//*****************************************************************************
//
//! @brief MSPI deinitialization function
//!
//! @param handle - the handle for the module instance.
//!
//! This function accepts a handle to an instance and de-initializes the
//! interface.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_deinitialize(void *pHandle);
//*****************************************************************************
//
//! @brief MSPI device configuration function
//!
//! @param handle - handle for the interface.
//! @param pConfig - pointer to the configuration structure.
//!
//! This function configures the MSPI settings for a particular external flash device.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_device_configure(void *pHandle,
am_hal_mspi_dev_config_t *pConfig);
//*****************************************************************************
//
//! @brief MSPI enable function
//!
//! @param handle - the handle for the module instance.
//!
//! This function accepts a handle to an instance and enables the
//! interface.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_enable(void *pHandle);
//*****************************************************************************
//
//! @brief MSPI disable function
//!
//! @param handle - the handle for the module instance.
//!
//! This function accepts a handle to an instance and disables the
//! interface.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_disable(void *pHandle);
//*****************************************************************************
//
//! @brief MSPI device specific control function.
//!
//! @param handle - handle for the interface.
//! @param request - device specific special request code.
//! @param pConfig - pointer to the request specific configuration.
//!
//! This function configures the MSPI settings for XIP or DMA operation.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_control(void *pHandle,
am_hal_mspi_request_e eRequest,
void *pConfig);
//*****************************************************************************
//
//! @brief MSPI capability interrogation function
//!
//! @param handle - handle for the interface.
//! @param pCapabilities - pointer to an interface specific structure used to
//! return the capabilities of the interface.
//!
//! This function returns the specific capabilities of the MSPI. In some
//! cases the capabilities may be instance specific (e.g. maximum data rate).
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_capabilities_get(void *pHandle,
am_hal_mspi_capabilities_t **pCapabilities);
//*****************************************************************************
//
//! @brief MSPI blocking transfer function
//!
//! @param pHandle - handle for the interface.
//! @param pTransaction - pointer to the transaction control structure.
//! @param ui32Timeout - timeout in usecs.
//!
//! This function performs a transaction on the MSPI in PIO mode. It handles
//! half duplex transactions only (TX or RX).
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_blocking_transfer(void *pHandle,
am_hal_mspi_pio_transfer_t *pTransaction,
uint32_t ui32Timeout);
//*****************************************************************************
//
//! @brief MSPI Non-Blocking transfer function
//!
//! @param handle - handle for the interface.
//! @param pTransaction - pointer to the transaction control structure.
//! @param pfnCallback - pointer the callback function to be executed when
//! transaction is complete.
//!
//! This function performs a transaction on the MSPI using either DMA or the
//! Command Queue with DMA. It handles half duplex transactions.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_nonblocking_transfer(void *pHandle,
void *pTransfer,
am_hal_mspi_trans_e eMode,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
//*****************************************************************************
//
//! @brief MSPI status function
//!
//! @param handle - handle for the interface.
//!
//! This function returns the current status of the DMA operation.
//!
//! @return status - DMA status flags.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_status_get(void *pHandle,
am_hal_mspi_status_t *pStatus );
//*****************************************************************************
//
//! @brief MSPI enable interrupts function
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - MSPI interrupt mask.
//!
//! This function enables the specific indicated interrupts.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_interrupt_enable(void *pHandle,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief MSPI disable interrupts function
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - MSPI interrupt mask.
//!
//! This function disable the specific indicated interrupts.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_interrupt_disable(void *pHandle,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief MSPI interrupt status function
//!
//! @param handle - handle for the interface.
//! @param pui32Status - returns the interrupt status value.
//! @param bEnabledOnly - TRUE: only report interrupt status for enalbed ints.
//! FALSE: report all interrupt status values.
//!
//! This function returns the specific indicated interrupt status.
//!
//! @return status - interrupt status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_interrupt_status_get(void *pHandle,
uint32_t *pui32Status,
bool bEnabledOnly);
//*****************************************************************************
//
//! @brief MSPI interrupt clear
//!
//! @param handle - handle for the interface.
//! @param ui32IntMask - uint32_t for interrupts to clear
//!
//! This function clears the interrupts for the given peripheral.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_interrupt_clear(void *pHandle,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief MSPI interrupt service routine
//!
//! @param handle - handle for the interface.
//! @param ui32IntStatus - interrupt status.
//!
//! This function is designed to be called from within the user defined ISR
//! in order to service the non-blocking, queued, or DMA processing for a given
//! module instance.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_interrupt_service(void *pHandle,
uint32_t ui32IntStatus);
//*****************************************************************************
//
//! @brief MSPI power control function
//!
//! @param handle - handle for the interface.
//! @param ePowerState - the desired power state to move the peripheral to.
//! @param bRetainState - flag (if true) to save/restore peripheral state upon
//! power state change.
//!
//! This function updates the peripheral to a given power state.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_mspi_power_control(void *pHandle,
am_hal_sysctrl_power_state_e ePowerState,
bool bRetainState);
//
// MSPI High Priority transfer function
//
extern uint32_t am_hal_mspi_highprio_transfer(void *pHandle,
am_hal_mspi_dma_transfer_t *pTransfer,
am_hal_mspi_trans_e eMode,
am_hal_mspi_callback_t pfnCallback,
void *pCallbackCtxt);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_MSPI_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,650 @@
//*****************************************************************************
//
//! @file am_hal_pdm.c
//!
//! @brief HAL implementation for the PDM module.
//!
//! @addtogroup
//! @ingroup
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// PDM magic number for handle verification.
//
//*****************************************************************************
#define AM_HAL_MAGIC_PDM 0xF956E2
#define AM_HAL_PDM_HANDLE_VALID(h) \
((h) && \
((am_hal_handle_prefix_t *)(h))->s.bInit && \
(((am_hal_handle_prefix_t *)(h))->s.magic == AM_HAL_MAGIC_PDM))
//*****************************************************************************
//
// Convenience macro for passing errors.
//
//*****************************************************************************
#define RETURN_ON_ERROR(x) \
if ((x) != AM_HAL_STATUS_SUCCESS) \
{ \
return (x); \
};
//*****************************************************************************
//
// Abbreviation for validating handles and returning errors.
//
//*****************************************************************************
#ifndef AM_HAL_DISABLE_API_VALIDATION
#define AM_HAL_PDM_HANDLE_CHECK(h) \
if (!AM_HAL_PDM_HANDLE_VALID(h)) \
{ \
return AM_HAL_STATUS_INVALID_HANDLE; \
}
#else
#define AM_HAL_PDM_HANDLE_CHECK(h)
#endif // AM_HAL_DISABLE_API_VALIDATION
//*****************************************************************************
//
// Helper macros for delays.
//
//*****************************************************************************
#define delay_ms(ms) \
if (1) \
{ \
am_hal_clkgen_status_t sClkGenStatus; \
am_hal_clkgen_status_get(&sClkGenStatus); \
am_hal_flash_delay((ms) * (sClkGenStatus.ui32SysclkFreq / 3000)); \
}
#define delay_us(us) \
if (1) \
{ \
am_hal_clkgen_status_t sClkGenStatus; \
am_hal_clkgen_status_get(&sClkGenStatus); \
am_hal_flash_delay((us) * (sClkGenStatus.ui32SysclkFreq / 3000000)); \
}
//*****************************************************************************
//
// Structure for handling PDM register state information for power up/down
//
//*****************************************************************************
typedef struct
{
bool bValid;
}
am_hal_pdm_register_state_t;
//*****************************************************************************
//
// Structure for handling PDM HAL state information.
//
//*****************************************************************************
typedef struct
{
am_hal_handle_prefix_t prefix;
am_hal_pdm_register_state_t sRegState;
uint32_t ui32Module;
}
am_hal_pdm_state_t;
//*****************************************************************************
//
// State structure for each module.
//
//*****************************************************************************
am_hal_pdm_state_t g_am_hal_pdm_states[AM_REG_PDM_NUM_MODULES];
//*****************************************************************************
//
// Static function definitions.
//
//*****************************************************************************
static uint32_t find_dma_threshold(uint32_t ui32TotalCount);
//*****************************************************************************
//
// Initialization function.
//
//*****************************************************************************
uint32_t
am_hal_pdm_initialize(uint32_t ui32Module, void **ppHandle)
{
//
// Check that the request module is in range.
//
if ( ui32Module >= AM_REG_PDM_NUM_MODULES )
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
//
// Check for valid arguements.
//
if (!ppHandle)
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Check if the handle is unallocated.
//
if (g_am_hal_pdm_states[ui32Module].prefix.s.bInit)
{
return AM_HAL_STATUS_INVALID_OPERATION;
}
//
// Initialize the handle.
//
g_am_hal_pdm_states[ui32Module].prefix.s.bInit = true;
g_am_hal_pdm_states[ui32Module].prefix.s.magic = AM_HAL_MAGIC_PDM;
g_am_hal_pdm_states[ui32Module].ui32Module = ui32Module;
g_am_hal_pdm_states[ui32Module].sRegState.bValid = false;
//
// Return the handle.
//
*ppHandle = (void *)&g_am_hal_pdm_states[ui32Module];
//
// Return the status.
//
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// De-Initialization function.
//
//*****************************************************************************
uint32_t
am_hal_pdm_deinitialize(void *pHandle)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *)pHandle;
//
// Check the handle.
//
AM_HAL_PDM_HANDLE_CHECK(pHandle);
//
// Reset the handle.
//
pState->prefix.s.bInit = false;
pState->prefix.s.magic = 0;
pState->ui32Module = 0;
//
// Return the status.
//
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Power control function.
//
//*****************************************************************************
uint32_t
am_hal_pdm_power_control(void *pHandle,
am_hal_sysctrl_power_state_e ePowerState,
bool bRetainState)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
am_hal_pwrctrl_periph_e ePDMPowerModule = ((am_hal_pwrctrl_periph_e)
(AM_HAL_PWRCTRL_PERIPH_PDM +
ui32Module));
//
// Check the handle.
//
AM_HAL_PDM_HANDLE_CHECK(pHandle);
//
// Decode the requested power state and update PDM operation accordingly.
//
switch (ePowerState)
{
//
// Turn on the PDM.
//
case AM_HAL_SYSCTRL_WAKE:
//
// Make sure we don't try to restore an invalid state.
//
if (bRetainState && !pState->sRegState.bValid)
{
return AM_HAL_STATUS_INVALID_OPERATION;
}
//
// Enable power control.
//
am_hal_pwrctrl_periph_enable(ePDMPowerModule);
if (bRetainState)
{
//
// Restore PDM registers
//
AM_CRITICAL_BEGIN;
pState->sRegState.bValid = false;
AM_CRITICAL_END;
}
break;
//
// Turn off the PDM.
//
case AM_HAL_SYSCTRL_NORMALSLEEP:
case AM_HAL_SYSCTRL_DEEPSLEEP:
if (bRetainState)
{
AM_CRITICAL_BEGIN;
pState->sRegState.bValid = true;
AM_CRITICAL_END;
}
//
// Disable power control.
//
am_hal_pwrctrl_periph_disable(ePDMPowerModule);
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Return the status.
//
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Configure the PDM.
//
//*****************************************************************************
uint32_t
am_hal_pdm_configure(void *pHandle, am_hal_pdm_config_t *psConfig)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
AM_HAL_PDM_HANDLE_CHECK(pHandle);
//
// Apply the config structure settings to the PCFG register.
//
PDMn(ui32Module)->PCFG_b.SOFTMUTE = psConfig->bSoftMute;
PDMn(ui32Module)->PCFG_b.CYCLES = psConfig->ui32GainChangeDelay;
PDMn(ui32Module)->PCFG_b.HPCUTOFF = psConfig->ui32HighPassCutoff;
PDMn(ui32Module)->PCFG_b.ADCHPD = psConfig->bHighPassEnable;
PDMn(ui32Module)->PCFG_b.SINCRATE = psConfig->ui32DecimationRate;
PDMn(ui32Module)->PCFG_b.MCLKDIV = psConfig->eClkDivider;
PDMn(ui32Module)->PCFG_b.PGALEFT = psConfig->eLeftGain;
PDMn(ui32Module)->PCFG_b.PGARIGHT = psConfig->eRightGain;
PDMn(ui32Module)->PCFG_b.LRSWAP = psConfig->bLRSwap;
//
// Set the PDM Core enable bit to enable PDM to PCM conversions.
//
PDMn(ui32Module)->PCFG_b.PDMCOREEN = PDM_PCFG_PDMCOREEN_EN;
//
// Program the "voice" registers.
//
PDMn(ui32Module)->VCFG_b.PDMCLKEN = PDM_VCFG_PDMCLKEN_DIS;
PDMn(ui32Module)->VCFG_b.IOCLKEN = PDM_VCFG_IOCLKEN_DIS;
PDMn(ui32Module)->VCFG_b.RSTB = PDM_VCFG_RSTB_RESET;
PDMn(ui32Module)->VCFG_b.CHSET = psConfig->ePCMChannels;
PDMn(ui32Module)->VCFG_b.PCMPACK = psConfig->bDataPacking;
PDMn(ui32Module)->VCFG_b.SELAP = psConfig->ePDMClkSource;
PDMn(ui32Module)->VCFG_b.DMICKDEL = psConfig->bPDMSampleDelay;
PDMn(ui32Module)->VCFG_b.BCLKINV = psConfig->bInvertI2SBCLK;
PDMn(ui32Module)->VCFG_b.I2SEN = psConfig->bI2SEnable;
PDMn(ui32Module)->VCFG_b.PDMCLKSEL = psConfig->ePDMClkSpeed;
delay_us(100);
PDMn(ui32Module)->VCFG_b.RSTB = PDM_VCFG_RSTB_NORM;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Enable the PDM.
//
//*****************************************************************************
uint32_t
am_hal_pdm_enable(void *pHandle)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
AM_HAL_PDM_HANDLE_CHECK(pHandle);
PDMn(ui32Module)->VCFG_b.IOCLKEN = PDM_VCFG_IOCLKEN_EN;
PDMn(ui32Module)->VCFG_b.PDMCLKEN = PDM_VCFG_PDMCLKEN_EN;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Disable the PDM.
//
//*****************************************************************************
uint32_t
am_hal_pdm_disable(void *pHandle)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
AM_HAL_PDM_HANDLE_CHECK(pHandle);
PDMn(ui32Module)->VCFG_b.IOCLKEN = PDM_VCFG_IOCLKEN_DIS;
PDMn(ui32Module)->VCFG_b.PDMCLKEN = PDM_VCFG_PDMCLKEN_DIS;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Given the total number of bytes in a DMA transaction, find a reasonable
// threshold setting.
//
//*****************************************************************************
static uint32_t
find_dma_threshold(uint32_t ui32TotalCount)
{
//
// Start with a threshold value of 24, and search downward for values that
// fit our criteria.
//
uint32_t ui32Threshold;
uint32_t ui32Minimum = AM_HAL_PDM_DMA_THRESHOLD_MIN;
for ( ui32Threshold = 24; ui32Threshold >= ui32Minimum; ui32Threshold -= 4 )
{
//
// With our loop parameters, we've already guaranteed that the
// threshold will be no higher than 24, and that it will be divisible
// by 4. The only remaining requirement is that ui32TotalCount must
// also be divisible by the threshold.
//
if ((ui32TotalCount % ui32Threshold) == 0)
{
break;
}
}
//
// If we found an appropriate value, we'll return it here. Otherwise, we
// will return zero.
//
if (ui32Threshold < ui32Minimum)
{
ui32Threshold = 0;
}
return ui32Threshold;
}
//*****************************************************************************
//
// Starts a DMA transaction from the PDM directly to SRAM
//
//*****************************************************************************
uint32_t
am_hal_pdm_dma_start(void *pHandle, am_hal_pdm_transfer_t *pDmaCfg)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
AM_HAL_PDM_HANDLE_CHECK(pHandle);
//
// Find an appropriate threshold size for this transfer.
//
uint32_t ui32Threshold = find_dma_threshold(pDmaCfg->ui32TotalCount);
//
// If we didn't find a threshold that will work, throw an error.
//
if (ui32Threshold == 0)
{
return AM_HAL_PDM_STATUS_BAD_TOTALCOUNT;
}
PDMn(ui32Module)->FIFOTHR = ui32Threshold;
//
// Configure DMA.
//
PDMn(ui32Module)->DMACFG = 0;
PDMn(ui32Module)->DMACFG_b.DMAPRI = PDM_DMACFG_DMAPRI_LOW;
PDMn(ui32Module)->DMACFG_b.DMADIR = PDM_DMACFG_DMADIR_P2M;
PDMn(ui32Module)->DMATOTCOUNT = pDmaCfg->ui32TotalCount;
PDMn(ui32Module)->DMATARGADDR = pDmaCfg->ui32TargetAddr;
//
// Make sure the trigger is set for threshold.
//
PDMn(ui32Module)->DMATRIGEN_b.DTHR = 1;
//
// Enable DMA
//
PDMn(ui32Module)->DMACFG_b.DMAEN = PDM_DMACFG_DMAEN_EN;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Flush the PDM FIFO
//
//*****************************************************************************
uint32_t
am_hal_pdm_fifo_flush(void *pHandle)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
AM_HAL_PDM_HANDLE_CHECK(pHandle);
PDMn(ui32Module)->FIFOFLUSH = 1;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Enable PDM passthrough to the I2S slave.
//
//*****************************************************************************
uint32_t
am_hal_pdm_i2s_enable(void *pHandle)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
AM_HAL_PDM_HANDLE_CHECK(pHandle);
uint32_t ui32Module = pState->ui32Module;
PDMn(ui32Module)->VCFG_b.I2SEN = PDM_VCFG_I2SEN_EN;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Disable PDM passthrough to the I2S slave.
//
//*****************************************************************************
uint32_t
am_hal_pdm_i2s_disable(void *pHandle)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
AM_HAL_PDM_HANDLE_CHECK(pHandle);
uint32_t ui32Module = pState->ui32Module;
PDMn(ui32Module)->VCFG_b.I2SEN = PDM_VCFG_I2SEN_DIS;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Interrupt enable.
//
//*****************************************************************************
uint32_t
am_hal_pdm_interrupt_enable(void *pHandle, uint32_t ui32IntMask)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
//
// Check the handle.
//
AM_HAL_PDM_HANDLE_CHECK(pHandle);
PDMn(ui32Module)->INTEN |= ui32IntMask;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Interrupt disable.
//
//*****************************************************************************
uint32_t
am_hal_pdm_interrupt_disable(void *pHandle, uint32_t ui32IntMask)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
//
// Check the handle.
//
AM_HAL_PDM_HANDLE_CHECK(pHandle);
PDMn(ui32Module)->INTEN &= ~ui32IntMask;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Interrupt clear.
//
//*****************************************************************************
uint32_t
am_hal_pdm_interrupt_clear(void *pHandle, uint32_t ui32IntMask)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
//
// Check the handle.
//
AM_HAL_PDM_HANDLE_CHECK(pHandle);
PDMn(ui32Module)->INTCLR = ui32IntMask;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Returns the interrupt status.
//
//*****************************************************************************
uint32_t
am_hal_pdm_interrupt_status_get(void *pHandle, uint32_t *pui32Status, bool bEnabledOnly)
{
am_hal_pdm_state_t *pState = (am_hal_pdm_state_t *) pHandle;
uint32_t ui32Module = pState->ui32Module;
//
// Check the handle.
//
AM_HAL_PDM_HANDLE_CHECK(pHandle);
//
// If requested, only return the interrupts that are enabled.
//
if ( bEnabledOnly )
{
*pui32Status = PDMn(ui32Module)->INTSTAT;
*pui32Status &= PDMn(ui32Module)->INTEN;
}
else
{
*pui32Status = PDMn(ui32Module)->INTSTAT;
}
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,317 @@
//*****************************************************************************
//
//! @file am_hal_pdm.h
//!
//! @brief API for the PDM module
//!
//! @addtogroup
//! @ingroup
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_PDM_H
#define AM_HAL_PDM_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// CMSIS-style macro for handling a variable IOS module number.
//
//*****************************************************************************
#define AM_REG_PDM_NUM_MODULES 1
#define PDMn(n) ((PDM_Type*)(PDM_BASE + (n * (PDM_BASE - PDM_BASE))))
//*****************************************************************************
//
// DMA threshold minimum.
//
// The PDM DMA works best if its threshold value is set to a multiple of 4
// between 16 and 24, but it will technically allow threshold settings between
// 4 and 24. This macro sets the minimum threshold value that the HAL layer
// will allow.
//
//*****************************************************************************
#define AM_HAL_PDM_DMA_THRESHOLD_MIN 16
//*****************************************************************************
//
// PDM-specific error conditions.
//
//*****************************************************************************
typedef enum
{
//
// The PDM HAL will throw this error if it can't find a threshold value to
// match the total-count value passed in by a caller requesting a DMA
// transfer. The PDM hardware requires all DMA transactions to be evenly
// divisible in chunks of one FIFO size or smaller. Try changing your
// ui32TotalCount value to a more evenly divisible number.
//
AM_HAL_PDM_STATUS_BAD_TOTALCOUNT = AM_HAL_STATUS_MODULE_SPECIFIC_START,
}
am_hal_pdm_status_e;
//*****************************************************************************
//
// Gain settings.
//
//*****************************************************************************
typedef enum
{
AM_HAL_PDM_GAIN_P405DB = PDM_PCFG_PGALEFT_P405DB,
AM_HAL_PDM_GAIN_P390DB = PDM_PCFG_PGALEFT_P390DB,
AM_HAL_PDM_GAIN_P375DB = PDM_PCFG_PGALEFT_P375DB,
AM_HAL_PDM_GAIN_P360DB = PDM_PCFG_PGALEFT_P360DB,
AM_HAL_PDM_GAIN_P345DB = PDM_PCFG_PGALEFT_P345DB,
AM_HAL_PDM_GAIN_P330DB = PDM_PCFG_PGALEFT_P330DB,
AM_HAL_PDM_GAIN_P315DB = PDM_PCFG_PGALEFT_P315DB,
AM_HAL_PDM_GAIN_P300DB = PDM_PCFG_PGALEFT_P300DB,
AM_HAL_PDM_GAIN_P285DB = PDM_PCFG_PGALEFT_P285DB,
AM_HAL_PDM_GAIN_P270DB = PDM_PCFG_PGALEFT_P270DB,
AM_HAL_PDM_GAIN_P255DB = PDM_PCFG_PGALEFT_P255DB,
AM_HAL_PDM_GAIN_P240DB = PDM_PCFG_PGALEFT_P240DB,
AM_HAL_PDM_GAIN_P225DB = PDM_PCFG_PGALEFT_P225DB,
AM_HAL_PDM_GAIN_P210DB = PDM_PCFG_PGALEFT_P210DB,
AM_HAL_PDM_GAIN_P195DB = PDM_PCFG_PGALEFT_P195DB,
AM_HAL_PDM_GAIN_P180DB = PDM_PCFG_PGALEFT_P180DB,
AM_HAL_PDM_GAIN_P165DB = PDM_PCFG_PGALEFT_P165DB,
AM_HAL_PDM_GAIN_P150DB = PDM_PCFG_PGALEFT_P150DB,
AM_HAL_PDM_GAIN_P135DB = PDM_PCFG_PGALEFT_P135DB,
AM_HAL_PDM_GAIN_P120DB = PDM_PCFG_PGALEFT_P120DB,
AM_HAL_PDM_GAIN_P105DB = PDM_PCFG_PGALEFT_P105DB,
AM_HAL_PDM_GAIN_P90DB = PDM_PCFG_PGALEFT_P90DB,
AM_HAL_PDM_GAIN_P75DB = PDM_PCFG_PGALEFT_P75DB,
AM_HAL_PDM_GAIN_P60DB = PDM_PCFG_PGALEFT_P60DB,
AM_HAL_PDM_GAIN_P45DB = PDM_PCFG_PGALEFT_P45DB,
AM_HAL_PDM_GAIN_P30DB = PDM_PCFG_PGALEFT_P30DB,
AM_HAL_PDM_GAIN_P15DB = PDM_PCFG_PGALEFT_P15DB,
AM_HAL_PDM_GAIN_0DB = PDM_PCFG_PGALEFT_0DB,
AM_HAL_PDM_GAIN_M15DB = PDM_PCFG_PGALEFT_M15DB,
AM_HAL_PDM_GAIN_M300DB = PDM_PCFG_PGALEFT_M300DB,
AM_HAL_PDM_GAIN_M45DB = PDM_PCFG_PGALEFT_M45DB,
AM_HAL_PDM_GAIN_M60DB = PDM_PCFG_PGALEFT_M60DB,
}
am_hal_pdm_gain_e;
//*****************************************************************************
//
// Clock Source selection.
//
//*****************************************************************************
typedef enum
{
AM_HAL_PDM_INTERNAL_CLK = PDM_VCFG_SELAP_INTERNAL,
AM_HAL_PDM_I2S_CLK = PDM_VCFG_SELAP_I2S,
}
am_hal_pdm_clksrc_e;
//*****************************************************************************
//
// PDM internal clock speed selection.
//
//*****************************************************************************
typedef enum
{
AM_HAL_PDM_CLK_DISABLE = PDM_VCFG_PDMCLKSEL_DISABLE,
AM_HAL_PDM_CLK_12MHZ = PDM_VCFG_PDMCLKSEL_12MHz,
AM_HAL_PDM_CLK_6MHZ = PDM_VCFG_PDMCLKSEL_6MHz,
AM_HAL_PDM_CLK_3MHZ = PDM_VCFG_PDMCLKSEL_3MHz,
AM_HAL_PDM_CLK_1_5MHZ = PDM_VCFG_PDMCLKSEL_1_5MHz,
AM_HAL_PDM_CLK_750KHZ = PDM_VCFG_PDMCLKSEL_750KHz,
AM_HAL_PDM_CLK_375KHZ = PDM_VCFG_PDMCLKSEL_375KHz,
AM_HAL_PDM_CLK_187KHZ = PDM_VCFG_PDMCLKSEL_187KHz,
}
am_hal_pdm_clkspd_e;
//*****************************************************************************
//
// PDM clock divider setting.
//
//*****************************************************************************
typedef enum
{
AM_HAL_PDM_MCLKDIV_4 = PDM_PCFG_MCLKDIV_MCKDIV4,
AM_HAL_PDM_MCLKDIV_3 = PDM_PCFG_MCLKDIV_MCKDIV3,
AM_HAL_PDM_MCLKDIV_2 = PDM_PCFG_MCLKDIV_MCKDIV2,
AM_HAL_PDM_MCLKDIV_1 = PDM_PCFG_MCLKDIV_MCKDIV1,
}
am_hal_pdm_mclkdiv_e;
//*****************************************************************************
//
// PCM Channel Select.
//
//*****************************************************************************
typedef enum
{
AM_HAL_PDM_CHANNEL_LEFT = PDM_VCFG_CHSET_LEFT,
AM_HAL_PDM_CHANNEL_RIGHT = PDM_VCFG_CHSET_RIGHT,
AM_HAL_PDM_CHANNEL_STEREO = PDM_VCFG_CHSET_STEREO,
}
am_hal_pdm_chset_e;
//*****************************************************************************
//
// PDM power state settings.
//
//*****************************************************************************
#define AM_HAL_PDM_POWER_ON AM_HAL_SYSCTRL_WAKE
#define AM_HAL_PDM_POWER_OFF AM_HAL_SYSCTRL_NORMALSLEEP
//*****************************************************************************
//
// PDM interrupts.
//
//*****************************************************************************
#define AM_HAL_PDM_INT_DERR PDM_INTSTAT_DERR_Msk
#define AM_HAL_PDM_INT_DCMP PDM_INTSTAT_DCMP_Msk
#define AM_HAL_PDM_INT_UNDFL PDM_INTSTAT_UNDFL_Msk
#define AM_HAL_PDM_INT_OVF PDM_INTSTAT_OVF_Msk
#define AM_HAL_PDM_INT_THR PDM_INTSTAT_THR_Msk
//*****************************************************************************
//
// Configuration structure for the PDM
//
//*****************************************************************************
typedef struct
{
// Clock
am_hal_pdm_mclkdiv_e eClkDivider;
// Gain
am_hal_pdm_gain_e eLeftGain;
am_hal_pdm_gain_e eRightGain;
// Decimation Rate
uint32_t ui32DecimationRate;
// Filters
bool bHighPassEnable;
uint32_t ui32HighPassCutoff;
// PDMCLKSEL
am_hal_pdm_clkspd_e ePDMClkSpeed;
// BCLKINV
bool bInvertI2SBCLK;
// SELAP
am_hal_pdm_clksrc_e ePDMClkSource;
// DMICKDEL
bool bPDMSampleDelay;
// PCMPACK
bool bDataPacking;
// CHSET
am_hal_pdm_chset_e ePCMChannels;
uint32_t ui32GainChangeDelay;
bool bI2SEnable;
bool bSoftMute;
bool bLRSwap;
}
am_hal_pdm_config_t;
//*****************************************************************************
//
// DMA transfer structure
//
//*****************************************************************************
typedef struct
{
uint32_t ui32TargetAddr;
uint32_t ui32TotalCount;
}
am_hal_pdm_transfer_t;
// Init/De-init.
extern uint32_t am_hal_pdm_initialize(uint32_t ui32Module, void **ppHandle);
extern uint32_t am_hal_pdm_deinitialize(void *pHandle);
// Power
extern uint32_t am_hal_pdm_power_control(void *pHandle, am_hal_sysctrl_power_state_e ePowerState, bool bRetainState);
// Config
extern uint32_t am_hal_pdm_configure(void *pHandle, am_hal_pdm_config_t *psConfig);
// Enable/Disable
extern uint32_t am_hal_pdm_enable(void *pHandle);
extern uint32_t am_hal_pdm_disable(void *pHandle);
// Gather PDM data.
extern uint32_t am_hal_pdm_dma_start(void *pHandle, am_hal_pdm_transfer_t *pDmaCfg);
// Flush the PDM FIFO.
extern uint32_t am_hal_pdm_fifo_flush(void *pHandle);
// I2S Passthrough
extern uint32_t am_hal_pdm_i2s_enable(void *pHandle);
extern uint32_t am_hal_pdm_i2s_disable(void *pHandle);
// Interrupts.
extern uint32_t am_hal_pdm_interrupt_enable(void *pHandle, uint32_t ui32IntMask);
extern uint32_t am_hal_pdm_interrupt_disable(void *pHandle, uint32_t ui32IntMask);
extern uint32_t am_hal_pdm_interrupt_clear(void *pHandle, uint32_t ui32IntMask);
extern uint32_t am_hal_pdm_interrupt_status_get(void *pHandle, uint32_t *pui32Status, bool bEnabledOnly);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_PDM_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,494 @@
//*****************************************************************************
//
// am_hal_pin.h
//! @file
//! @brief Macros for configuring specific pins.
//!
//! @addtogroup pin3 PIN definitions for Apollo3.
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_PIN_H
#define AM_HAL_PIN_H
//*****************************************************************************
//
// Pin definition macros.
//
//*****************************************************************************
#define AM_HAL_PIN_0_SLSCL (0)
#define AM_HAL_PIN_0_SLSCK (1)
#define AM_HAL_PIN_0_CLKOUT (2)
#define AM_HAL_PIN_0_GPIO (3)
#define AM_HAL_PIN_0_MSPI4 (5)
#define AM_HAL_PIN_0_NCE0 (7)
#define AM_HAL_PIN_1_SLSDAWIR3 (0)
#define AM_HAL_PIN_1_SLMOSI (1)
#define AM_HAL_PIN_1_UART0TX (2)
#define AM_HAL_PIN_1_GPIO (3)
#define AM_HAL_PIN_1_MSPI5 (5)
#define AM_HAL_PIN_1_NCE1 (7)
#define AM_HAL_PIN_2_UART1RX (0)
#define AM_HAL_PIN_2_SLMISO (1)
#define AM_HAL_PIN_2_UART0RX (2)
#define AM_HAL_PIN_2_GPIO (3)
#define AM_HAL_PIN_2_MSPI6 (5)
#define AM_HAL_PIN_2_NCE2 (7)
#define AM_HAL_PIN_3_UART0RTS (0)
#define AM_HAL_PIN_3_SLnCE (1)
#define AM_HAL_PIN_3_NCE3 (2)
#define AM_HAL_PIN_3_GPIO (3)
#define AM_HAL_PIN_3_MSPI7 (5)
#define AM_HAL_PIN_3_TRIG1 (6)
#define AM_HAL_PIN_3_I2S_WCLK (7)
#define AM_HAL_PIN_3_PSOURCE (3)
#define AM_HAL_PIN_4_UART0CTS (0)
#define AM_HAL_PIN_4_SLINT (1)
#define AM_HAL_PIN_4_NCE4 (2)
#define AM_HAL_PIN_4_GPIO (3)
#define AM_HAL_PIN_4_UART1RX (5)
#define AM_HAL_PIN_4_CTIM17 (6)
#define AM_HAL_PIN_4_MSPI2 (7)
#define AM_HAL_PIN_5_M0SCL (0)
#define AM_HAL_PIN_5_M0SCK (1)
#define AM_HAL_PIN_5_UART0RTS (2)
#define AM_HAL_PIN_5_GPIO (3)
#define AM_HAL_PIN_5_EXTHFA (5)
#define AM_HAL_PIN_5_CTIM8 (7)
#define AM_HAL_PIN_6_M0SDAWIR3 (0)
#define AM_HAL_PIN_6_M0MISO (1)
#define AM_HAL_PIN_6_UART0CTS (2)
#define AM_HAL_PIN_6_GPIO (3)
#define AM_HAL_PIN_6_CTIM10 (5)
#define AM_HAL_PIN_6_I2S_DAT (7)
#define AM_HAL_PIN_7_NCE7 (0)
#define AM_HAL_PIN_7_M0MOSI (1)
#define AM_HAL_PIN_7_CLKOUT (2)
#define AM_HAL_PIN_7_GPIO (3)
#define AM_HAL_PIN_7_TRIG0 (4)
#define AM_HAL_PIN_7_UART0TX (5)
#define AM_HAL_PIN_7_CTIM19 (7)
#define AM_HAL_PIN_8_M1SCL (0)
#define AM_HAL_PIN_8_M1SCK (1)
#define AM_HAL_PIN_8_NCE8 (2)
#define AM_HAL_PIN_8_GPIO (3)
#define AM_HAL_PIN_8_SCCCLK (4)
#define AM_HAL_PIN_8_UART1TX (6)
#define AM_HAL_PIN_9_M1SDAWIR3 (0)
#define AM_HAL_PIN_9_M1MISO (1)
#define AM_HAL_PIN_9_NCE9 (2)
#define AM_HAL_PIN_9_GPIO (3)
#define AM_HAL_PIN_9_SCCIO (4)
#define AM_HAL_PIN_9_UART1RX (6)
#define AM_HAL_PIN_10_UART1TX (0)
#define AM_HAL_PIN_10_M1MOSI (1)
#define AM_HAL_PIN_10_NCE10 (2)
#define AM_HAL_PIN_10_GPIO (3)
#define AM_HAL_PIN_10_PDMCLK (4)
#define AM_HAL_PIN_10_UART1RTS (5)
#define AM_HAL_PIN_11_ADCSE2 (0)
#define AM_HAL_PIN_11_NCE11 (1)
#define AM_HAL_PIN_11_CTIM31 (2)
#define AM_HAL_PIN_11_GPIO (3)
#define AM_HAL_PIN_11_SLINT (4)
#define AM_HAL_PIN_11_UART1CTS (5)
#define AM_HAL_PIN_11_UART0RX (6)
#define AM_HAL_PIN_11_PDMDATA (7)
#define AM_HAL_PIN_12_ADCD0NSE9 (0)
#define AM_HAL_PIN_12_NCE12 (1)
#define AM_HAL_PIN_12_CTIM0 (2)
#define AM_HAL_PIN_12_GPIO (3)
#define AM_HAL_PIN_12_SLnCE (4)
#define AM_HAL_PIN_12_PDMCLK (5)
#define AM_HAL_PIN_12_UART0CTS (6)
#define AM_HAL_PIN_12_UART1TX (7)
#define AM_HAL_PIN_13_ADCD0PSE8 (0)
#define AM_HAL_PIN_13_NCE13 (1)
#define AM_HAL_PIN_13_CTIM2 (2)
#define AM_HAL_PIN_13_GPIO (3)
#define AM_HAL_PIN_13_I2SBCLK (4)
#define AM_HAL_PIN_13_EXTHFB (5)
#define AM_HAL_PIN_13_UART0RTS (6)
#define AM_HAL_PIN_13_UART1RX (7)
#define AM_HAL_PIN_14_ADCD1P (0)
#define AM_HAL_PIN_14_NCE14 (1)
#define AM_HAL_PIN_14_UART1TX (2)
#define AM_HAL_PIN_14_GPIO (3)
#define AM_HAL_PIN_14_PDMCLK (4)
#define AM_HAL_PIN_14_EXTHFS (5)
#define AM_HAL_PIN_14_SWDCK (6)
#define AM_HAL_PIN_14_32KHZXT (7)
#define AM_HAL_PIN_15_ADCD1N (0)
#define AM_HAL_PIN_15_NCE15 (1)
#define AM_HAL_PIN_15_UART1RX (2)
#define AM_HAL_PIN_15_GPIO (3)
#define AM_HAL_PIN_15_PDMDATA (4)
#define AM_HAL_PIN_15_EXTXT (5)
#define AM_HAL_PIN_15_SWDIO (6)
#define AM_HAL_PIN_15_SWO (7)
#define AM_HAL_PIN_16_ADCSE0 (0)
#define AM_HAL_PIN_16_NCE16 (1)
#define AM_HAL_PIN_16_TRIG0 (2)
#define AM_HAL_PIN_16_GPIO (3)
#define AM_HAL_PIN_16_SCCRST (4)
#define AM_HAL_PIN_16_CMPIN0 (5)
#define AM_HAL_PIN_16_UART0TX (6)
#define AM_HAL_PIN_16_UART1RTS (7)
#define AM_HAL_PIN_17_CMPRF1 (0)
#define AM_HAL_PIN_17_NCE17 (1)
#define AM_HAL_PIN_17_TRIG1 (2)
#define AM_HAL_PIN_17_GPIO (3)
#define AM_HAL_PIN_17_SCCCLK (4)
#define AM_HAL_PIN_17_UART0RX (6)
#define AM_HAL_PIN_17_UART1CTS (7)
#define AM_HAL_PIN_18_CMPIN1 (0)
#define AM_HAL_PIN_18_NCE18 (1)
#define AM_HAL_PIN_18_CTIM4 (2)
#define AM_HAL_PIN_18_GPIO (3)
#define AM_HAL_PIN_18_UART0RTS (4)
#define AM_HAL_PIN_18_ANATEST2 (5)
#define AM_HAL_PIN_18_UART1TX (6)
#define AM_HAL_PIN_18_SCCIO (7)
#define AM_HAL_PIN_19_CMPRF0 (0)
#define AM_HAL_PIN_19_NCE19 (1)
#define AM_HAL_PIN_19_CTIM6 (2)
#define AM_HAL_PIN_19_GPIO (3)
#define AM_HAL_PIN_19_SCCCLK (4)
#define AM_HAL_PIN_19_ANATEST1 (5)
#define AM_HAL_PIN_19_UART1RX (6)
#define AM_HAL_PIN_19_I2SBCLK (7)
#define AM_HAL_PIN_20_SWDCK (0)
#define AM_HAL_PIN_20_NCE20 (1)
#define AM_HAL_PIN_20_GPIO (3)
#define AM_HAL_PIN_20_UART0TX (4)
#define AM_HAL_PIN_20_UART1TX (5)
#define AM_HAL_PIN_20_I2SBCLK (6)
#define AM_HAL_PIN_20_UART1RTS (7)
#define AM_HAL_PIN_21_SWDIO (0)
#define AM_HAL_PIN_21_NCE21 (1)
#define AM_HAL_PIN_21_GPIO (3)
#define AM_HAL_PIN_21_UART0RX (4)
#define AM_HAL_PIN_21_UART1RX (5)
#define AM_HAL_PIN_21_I2SBCLK (6)
#define AM_HAL_PIN_21_UART1CTS (7)
#define AM_HAL_PIN_22_UART0TX (0)
#define AM_HAL_PIN_22_NCE22 (1)
#define AM_HAL_PIN_22_CTIM12 (2)
#define AM_HAL_PIN_22_GPIO (3)
#define AM_HAL_PIN_22_PDMCLK (4)
#define AM_HAL_PIN_22_EXTLF (5)
#define AM_HAL_PIN_22_MSPI0 (6)
#define AM_HAL_PIN_22_SWO (7)
#define AM_HAL_PIN_23_UART0RX (0)
#define AM_HAL_PIN_23_NCE23 (1)
#define AM_HAL_PIN_23_CTIM14 (2)
#define AM_HAL_PIN_23_GPIO (3)
#define AM_HAL_PIN_23_I2SWCLK (4)
#define AM_HAL_PIN_23_CMPOUT (5)
#define AM_HAL_PIN_23_MSPI13 (6)
#define AM_HAL_PIN_23_EXTXT (7)
#define AM_HAL_PIN_24_UART1TX (0)
#define AM_HAL_PIN_24_NCE24 (1)
#define AM_HAL_PIN_24_MSPI8 (2)
#define AM_HAL_PIN_24_GPIO (3)
#define AM_HAL_PIN_24_UART0CTS (4)
#define AM_HAL_PIN_24_CTIM21 (5)
#define AM_HAL_PIN_24_32KHZXT (6)
#define AM_HAL_PIN_24_SWO (7)
#define AM_HAL_PIN_25_UART1RX (0)
#define AM_HAL_PIN_25_NCE25 (1)
#define AM_HAL_PIN_25_CTIM1 (2)
#define AM_HAL_PIN_25_GPIO (3)
#define AM_HAL_PIN_25_M2SDAWIR3 (4)
#define AM_HAL_PIN_25_M2MISO (5)
#define AM_HAL_PIN_26_EXTHF (0)
#define AM_HAL_PIN_26_NCE26 (1)
#define AM_HAL_PIN_26_CTIM3 (2)
#define AM_HAL_PIN_26_GPIO (3)
#define AM_HAL_PIN_26_SCCRST (4)
#define AM_HAL_PIN_26_MSPI1 (5)
#define AM_HAL_PIN_26_UART0TX (6)
#define AM_HAL_PIN_26_UART1CTS (7)
#define AM_HAL_PIN_27_UART0RX (0)
#define AM_HAL_PIN_27_NCE27 (1)
#define AM_HAL_PIN_27_CTIM5 (2)
#define AM_HAL_PIN_27_GPIO (3)
#define AM_HAL_PIN_27_M2SCL (4)
#define AM_HAL_PIN_27_M2SCK (5)
#define AM_HAL_PIN_28_I2SWCLK (0)
#define AM_HAL_PIN_28_NCE28 (1)
#define AM_HAL_PIN_28_CTIM7 (2)
#define AM_HAL_PIN_28_GPIO (3)
#define AM_HAL_PIN_28_M2MOSI (5)
#define AM_HAL_PIN_28_UART0TX (6)
#define AM_HAL_PIN_29_ADCSE1 (0)
#define AM_HAL_PIN_29_NCE29 (1)
#define AM_HAL_PIN_29_CTIM9 (2)
#define AM_HAL_PIN_29_GPIO (3)
#define AM_HAL_PIN_29_UART0CTS (4)
#define AM_HAL_PIN_29_UART1CTS (5)
#define AM_HAL_PIN_29_UART0RX (6)
#define AM_HAL_PIN_29_PDMDATA (7)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_30_ANATEST1 (0)
#define AM_HAL_PIN_30_NCE30 (1)
#define AM_HAL_PIN_30_CTIM11 (2)
#define AM_HAL_PIN_30_GPIO (3)
#define AM_HAL_PIN_30_UART0TX (4)
#define AM_HAL_PIN_30_UART1RTS (5)
#define AM_HAL_PIN_30_I2SDAT (7)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_31_ADCSE3 (0)
#define AM_HAL_PIN_31_NCE31 (1)
#define AM_HAL_PIN_31_CTIM13 (2)
#define AM_HAL_PIN_31_GPIO (3)
#define AM_HAL_PIN_31_UART0RX (4)
#define AM_HAL_PIN_31_SCCCLK (5)
#define AM_HAL_PIN_31_UART1RTS (7)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_32_ADCSE4 (0)
#define AM_HAL_PIN_32_NCE32 (1)
#define AM_HAL_PIN_32_CTIM15 (2)
#define AM_HAL_PIN_32_GPIO (3)
#define AM_HAL_PIN_32_SCCIO (4)
#define AM_HAL_PIN_32_EXTLF (5)
#define AM_HAL_PIN_32_UART1CTS (7)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_33_ADCSE5 (0)
#define AM_HAL_PIN_33_NCE33 (1)
#define AM_HAL_PIN_33_32KHZXT (2)
#define AM_HAL_PIN_33_GPIO (3)
#define AM_HAL_PIN_33_UART0CTS (5)
#define AM_HAL_PIN_33_CTIM23 (6)
#define AM_HAL_PIN_33_SWO (7)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_34_ADCSE6 (0)
#define AM_HAL_PIN_34_NCE34 (1)
#define AM_HAL_PIN_34_UART1RTS (2)
#define AM_HAL_PIN_34_GPIO (3)
#define AM_HAL_PIN_34_CMPRF2 (4)
#define AM_HAL_PIN_34_UART0RTS (5)
#define AM_HAL_PIN_34_UART0RX (6)
#define AM_HAL_PIN_34_PDMDATA (7)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_35_ADCSE7 (0)
#define AM_HAL_PIN_35_NCE35 (1)
#define AM_HAL_PIN_35_UART1TX (2)
#define AM_HAL_PIN_35_GPIO (3)
#define AM_HAL_PIN_35_I2SDAT (4)
#define AM_HAL_PIN_35_CTIM27 (5)
#define AM_HAL_PIN_35_UART0RTS (6)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_36_TRIG1 (0)
#define AM_HAL_PIN_36_NCE36 (1)
#define AM_HAL_PIN_36_UART1RX (2)
#define AM_HAL_PIN_36_GPIO (3)
#define AM_HAL_PIN_36_32KHZXT (4)
#define AM_HAL_PIN_36_UART1CTS (5)
#define AM_HAL_PIN_36_UART0CTS (6)
#define AM_HAL_PIN_36_PDMDATA (7)
#define AM_HAL_PIN_36_PSOURCE (3)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_37_TRIG2 (0)
#define AM_HAL_PIN_37_NCE37 (1)
#define AM_HAL_PIN_37_UART0RTS (2)
#define AM_HAL_PIN_37_GPIO (3)
#define AM_HAL_PIN_37_SCCIO (4)
#define AM_HAL_PIN_37_UART1TX (5)
#define AM_HAL_PIN_37_PDMCLK (6)
#define AM_HAL_PIN_37_CTIM29 (7)
#define AM_HAL_PIN_37_PSINK (3)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_38_TRIG3 (0)
#define AM_HAL_PIN_38_NCE38 (1)
#define AM_HAL_PIN_38_UART0CTS (2)
#define AM_HAL_PIN_38_GPIO (3)
#define AM_HAL_PIN_38_M3MOSI (5)
#define AM_HAL_PIN_38_UART1RX (6)
#endif // defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_39_UART0TX (0)
#define AM_HAL_PIN_39_UART1TX (1)
#define AM_HAL_PIN_39_CTIM25 (2)
#define AM_HAL_PIN_39_GPIO (3)
#define AM_HAL_PIN_39_M4SCL (4)
#define AM_HAL_PIN_39_M4SCK (5)
#define AM_HAL_PIN_40_UART0RX (0)
#define AM_HAL_PIN_40_UART1RX (1)
#define AM_HAL_PIN_40_TRIG0 (2)
#define AM_HAL_PIN_40_GPIO (3)
#define AM_HAL_PIN_40_M4SDAWIR3 (4)
#define AM_HAL_PIN_40_M4MISO (5)
#define AM_HAL_PIN_41_NCE41 (0)
#define AM_HAL_PIN_41_SWO (2)
#define AM_HAL_PIN_41_GPIO (3)
#define AM_HAL_PIN_41_I2SWCLK (4)
#define AM_HAL_PIN_41_UART1RTS (5)
#define AM_HAL_PIN_41_UART0TX (6)
#define AM_HAL_PIN_41_UART0RTS (7)
#define AM_HAL_PIN_41_PSINK (3)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_42_UART1TX (0)
#define AM_HAL_PIN_42_NCE42 (1)
#define AM_HAL_PIN_42_CTIM16 (2)
#define AM_HAL_PIN_42_GPIO (3)
#define AM_HAL_PIN_42_M3SCL (4)
#define AM_HAL_PIN_42_M3SCK (5)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_43_UART1RX (0)
#define AM_HAL_PIN_43_NCE43 (1)
#define AM_HAL_PIN_43_CTIM18 (2)
#define AM_HAL_PIN_43_GPIO (3)
#define AM_HAL_PIN_43_M3SDAWIR3 (4)
#define AM_HAL_PIN_43_M3MISO (5)
#endif // defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_44_UART1RTS (0)
#define AM_HAL_PIN_44_NCE44 (1)
#define AM_HAL_PIN_44_CTIM20 (2)
#define AM_HAL_PIN_44_GPIO (3)
#define AM_HAL_PIN_44_M4MOSI (5)
#define AM_HAL_PIN_44_UART0TX (6)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_45_UART1CTS (0)
#define AM_HAL_PIN_45_NCE45 (1)
#define AM_HAL_PIN_45_CTIM22 (2)
#define AM_HAL_PIN_45_GPIO (3)
#define AM_HAL_PIN_45_I2SDAT (4)
#define AM_HAL_PIN_45_PDMDATA (5)
#define AM_HAL_PIN_45_UART0RX (6)
#define AM_HAL_PIN_45_SWO (7)
#endif // defined (AM_PACKAGE_BGA)
#if defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_46_32KHZXT (0)
#define AM_HAL_PIN_46_NCE46 (1)
#define AM_HAL_PIN_46_CTIM24 (2)
#define AM_HAL_PIN_46_GPIO (3)
#define AM_HAL_PIN_46_SCCRST (4)
#define AM_HAL_PIN_46_PDMCLK (5)
#define AM_HAL_PIN_46_UART1TX (6)
#define AM_HAL_PIN_46_SWO (7)
#endif // defined (AM_PACKAGE_BGA)
#define AM_HAL_PIN_47_32KHZXT (0)
#define AM_HAL_PIN_47_NCE47 (1)
#define AM_HAL_PIN_47_CTIM26 (2)
#define AM_HAL_PIN_47_GPIO (3)
#define AM_HAL_PIN_47_M5MOSI (5)
#define AM_HAL_PIN_47_UART1RX (6)
#define AM_HAL_PIN_48_UART0TX (0)
#define AM_HAL_PIN_48_NCE48 (1)
#define AM_HAL_PIN_48_CTIM28 (2)
#define AM_HAL_PIN_48_GPIO (3)
#define AM_HAL_PIN_48_M5SCL (4)
#define AM_HAL_PIN_48_M5SCK (5)
#define AM_HAL_PIN_49_UART0RX (0)
#define AM_HAL_PIN_49_NCE49 (1)
#define AM_HAL_PIN_49_CTIM30 (2)
#define AM_HAL_PIN_49_GPIO (3)
#define AM_HAL_PIN_49_M5SDAWIR3 (4)
#define AM_HAL_PIN_49_M5MISO (5)
#endif // AM_HAL_PIN_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,637 @@
//*****************************************************************************
//
// am_hal_pwrctrl.c
//! @file
//!
//! @brief Functions for enabling and disabling power domains.
//!
//! @addtogroup pwrctrl3 Power Control
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//
// Maximum number of checks to memory power status before declaring error.
//
#define AM_HAL_PWRCTRL_MAX_WFE 20
//
// Define the peripheral control structure.
//
const struct
{
uint32_t ui32PeriphEnable;
uint32_t ui32PeriphStatus;
uint32_t ui32PeriphEvent;
}
am_hal_pwrctrl_peripheral_control[AM_HAL_PWRCTRL_PERIPH_MAX] =
{
{0, 0, 0}, // AM_HAL_PWRCTRL_PERIPH_NONE
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOS, PWRCTRL_DEVPWREN_PWRIOS_EN),
PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOS
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM0, PWRCTRL_DEVPWREN_PWRIOM0_EN),
PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM0
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM1, PWRCTRL_DEVPWREN_PWRIOM1_EN),
PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM1
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM2, PWRCTRL_DEVPWREN_PWRIOM2_EN),
PWRCTRL_DEVPWRSTATUS_HCPB_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPBEVEN, PWRCTRL_DEVPWREVENTEN_HCPBEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM2
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM3, PWRCTRL_DEVPWREN_PWRIOM3_EN),
PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM3
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM4, PWRCTRL_DEVPWREN_PWRIOM4_EN),
PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM4
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM5, PWRCTRL_DEVPWREN_PWRIOM5_EN),
PWRCTRL_DEVPWRSTATUS_HCPC_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPCEVEN, PWRCTRL_DEVPWREVENTEN_HCPCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_IOM5
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART0, PWRCTRL_DEVPWREN_PWRUART0_EN),
PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_UART0
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART1, PWRCTRL_DEVPWREN_PWRUART1_EN),
PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_UART1
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRADC, PWRCTRL_DEVPWREN_PWRADC_EN),
PWRCTRL_DEVPWRSTATUS_PWRADC_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_ADCEVEN, PWRCTRL_DEVPWREVENTEN_ADCEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_ADC
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRSCARD, PWRCTRL_DEVPWREN_PWRSCARD_EN),
PWRCTRL_DEVPWRSTATUS_HCPA_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_HCPAEVEN, PWRCTRL_DEVPWREVENTEN_HCPAEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_SCARD
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI, PWRCTRL_DEVPWREN_PWRMSPI_EN),
PWRCTRL_DEVPWRSTATUS_PWRMSPI_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_MSPIEVEN, PWRCTRL_DEVPWREVENTEN_MSPIEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_MSPI
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRPDM, PWRCTRL_DEVPWREN_PWRPDM_EN),
PWRCTRL_DEVPWRSTATUS_PWRPDM_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_PDMEVEN, PWRCTRL_DEVPWREVENTEN_PDMEVEN_EN)}, // AM_HAL_PWRCTRL_PERIPH_PDM
{_VAL2FLD(PWRCTRL_DEVPWREN_PWRBLEL, PWRCTRL_DEVPWREN_PWRBLEL_EN),
PWRCTRL_DEVPWRSTATUS_BLEL_Msk,
_VAL2FLD(PWRCTRL_DEVPWREVENTEN_BLELEVEN, PWRCTRL_DEVPWREVENTEN_BLELEVEN_EN)} // AM_HAL_PWRCTRL_PERIPH_BLEL
};
//
// Define the memory control structure.
//
const struct
{
uint32_t ui32MemoryEnable;
uint32_t ui32MemoryStatus;
uint32_t ui32MemoryEvent;
uint32_t ui32MemoryMask;
uint32_t ui32StatusMask;
uint32_t ui32PwdSlpEnable;
}
am_hal_pwrctrl_memory_control[AM_HAL_PWRCTRL_MEM_MAX] =
{
{0, 0, 0, 0, 0, 0},
{AM_HAL_PWRCTRL_MEMEN_SRAM_8K_DTCM,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K_DTCM,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_8K_DTCM,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_8K_DTCM},
{AM_HAL_PWRCTRL_MEMEN_SRAM_32K_DTCM,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K_DTCM,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_32K_DTCM,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_32K_DTCM},
{AM_HAL_PWRCTRL_MEMEN_SRAM_64K_DTCM,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K_DTCM,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_64K_DTCM,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_64K_DTCM},
{AM_HAL_PWRCTRL_MEMEN_SRAM_96K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_96K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_96K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_96K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_128K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_128K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_128K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_160K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_160K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_160K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_160K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_192K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_192K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_192K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_224K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_224K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_224K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_224K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_256K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_256K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_256K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_288K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_288K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_288K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_288K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_320K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_320K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_320K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_320K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_352K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_352K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_352K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_352K},
{AM_HAL_PWRCTRL_MEMEN_SRAM_384K,
AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_384K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_384K,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_384K},
{AM_HAL_PWRCTRL_MEMEN_FLASH_512K,
AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_512K,
AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_512K,
AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_512K},
{AM_HAL_PWRCTRL_MEMEN_FLASH_1M,
AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_1M,
AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_1M,
AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_1M},
{AM_HAL_PWRCTRL_MEMEN_CACHE,
0,
AM_HAL_PWRCTRL_MEMPWREVENTEN_CACHE,
AM_HAL_PWRCTRL_MEM_REGION_CACHE_MASK,
0,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_CACHE},
{AM_HAL_PWRCTRL_MEMEN_ALL,
AM_HAL_PWRCTRL_PWRONSTATUS_ALL,
AM_HAL_PWRCTRL_MEMPWREVENTEN_ALL,
AM_HAL_PWRCTRL_MEM_REGION_ALL_MASK,
AM_HAL_PWRCTRL_MEM_REGION_ALT_ALL_MASK,
AM_HAL_PWRCTRL_MEMPWDINSLEEP_ALL}
};
// ****************************************************************************
//
// am_hal_pwrctrl_periph_enable()
// Enable power for a peripheral.
//
// ****************************************************************************
uint32_t
am_hal_pwrctrl_periph_enable(am_hal_pwrctrl_periph_e ePeripheral)
{
//
// Enable power control for the given device.
//
AM_CRITICAL_BEGIN
PWRCTRL->DEVPWREN |= am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
AM_CRITICAL_END
for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WFE; wait_usecs += 10)
{
am_hal_flash_delay(FLASH_CYCLES_US(10));
if ( (PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) > 0)
{
break;
}
}
//
// Check the device status.
//
if ( (PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) > 0 )
{
return AM_HAL_STATUS_SUCCESS;
}
else
{
return AM_HAL_STATUS_FAIL;
}
}
// ****************************************************************************
//
// am_hal_pwrctrl_periph_disable()
// Disable power for a peripheral.
//
// ****************************************************************************
uint32_t
am_hal_pwrctrl_periph_disable(am_hal_pwrctrl_periph_e ePeripheral)
{
//
// Disable power domain for the given device.
//
AM_CRITICAL_BEGIN
PWRCTRL->DEVPWREN &= ~am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphEnable;
AM_CRITICAL_END
for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WFE; wait_usecs += 10)
{
am_hal_flash_delay(FLASH_CYCLES_US(10));
if ( (PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) == 0 )
{
break;
}
}
//
// Check the device status.
//
if ( ( PWRCTRL->DEVPWRSTATUS & am_hal_pwrctrl_peripheral_control[ePeripheral].ui32PeriphStatus) == 0 )
{
return AM_HAL_STATUS_SUCCESS;
}
else
{
return AM_HAL_STATUS_FAIL;
}
}
//*****************************************************************************
//
//! @brief Determine whether a peripheral is currently enabled.
//!
//! @param ePeripheral - The peripheral to enable.
//! @param pui32Enabled - Pointer to a ui32 that will return as 1 or 0.
//!
//! This function determines to the caller whether a given peripheral is
//! currently enabled or disabled.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
uint32_t
am_hal_pwrctrl_periph_enabled(am_hal_pwrctrl_periph_e ePeripheral,
uint32_t *pui32Enabled)
{
uint32_t ui32Mask = 0;
uint32_t ui32Enabled = 0;
if ( pui32Enabled == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
switch ( ePeripheral )
{
case AM_HAL_PWRCTRL_PERIPH_NONE:
case AM_HAL_PWRCTRL_PERIPH_SCARD:
break;
case AM_HAL_PWRCTRL_PERIPH_IOS:
case AM_HAL_PWRCTRL_PERIPH_UART0:
case AM_HAL_PWRCTRL_PERIPH_UART1:
ui32Mask = PWRCTRL_DEVPWRSTATUS_HCPA_Msk;
break;
case AM_HAL_PWRCTRL_PERIPH_IOM0:
case AM_HAL_PWRCTRL_PERIPH_IOM1:
case AM_HAL_PWRCTRL_PERIPH_IOM2:
ui32Mask = PWRCTRL_DEVPWRSTATUS_HCPB_Msk;
break;
case AM_HAL_PWRCTRL_PERIPH_IOM3:
case AM_HAL_PWRCTRL_PERIPH_IOM4:
case AM_HAL_PWRCTRL_PERIPH_IOM5:
ui32Mask = PWRCTRL_DEVPWRSTATUS_HCPC_Msk;
break;
case AM_HAL_PWRCTRL_PERIPH_ADC:
ui32Mask = PWRCTRL_DEVPWRSTATUS_PWRADC_Msk;
break;
case AM_HAL_PWRCTRL_PERIPH_MSPI:
ui32Mask = PWRCTRL_DEVPWRSTATUS_PWRMSPI_Msk;
break;
case AM_HAL_PWRCTRL_PERIPH_PDM:
ui32Mask = PWRCTRL_DEVPWRSTATUS_PWRPDM_Msk;
break;
case AM_HAL_PWRCTRL_PERIPH_BLEL:
ui32Mask = PWRCTRL_DEVPWRSTATUS_BLEL_Msk;
break;
default:
return AM_HAL_STATUS_FAIL;
}
if ( ui32Mask != 0 )
{
ui32Enabled = PWRCTRL->DEVPWRSTATUS & ui32Mask ? 1 : 0;
}
*pui32Enabled = ui32Enabled;
return AM_HAL_STATUS_SUCCESS;
}
// ****************************************************************************
//
// am_hal_pwrctrl_memory_enable()
// Enable a configuration of memory.
//
// ****************************************************************************
uint32_t
am_hal_pwrctrl_memory_enable(am_hal_pwrctrl_mem_e eMemConfig)
{
uint32_t ui32MemEnMask, ui32MemDisMask, ui32MemRegionMask, ui32MemStatusMask;
ui32MemEnMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryEnable;
ui32MemDisMask = ~am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryEnable;
ui32MemRegionMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryMask;
ui32MemStatusMask = am_hal_pwrctrl_memory_control[eMemConfig].ui32StatusMask;
//
// Disable unneeded memory. If nothing to be disabled, skip to save time.
//
// Note that a deliberate disable step using a disable mask is taken here
// for 2 reasons: 1) To only affect the specified type of memory, and 2)
// To avoid inadvertently disabling any memory currently being depended on.
//
if ( ui32MemDisMask != 0 )
{
PWRCTRL->MEMPWREN &=
~(ui32MemDisMask & ui32MemRegionMask) |
(_VAL2FLD(PWRCTRL_MEMPWREN_DTCM, PWRCTRL_MEMPWREN_DTCM_GROUP0DTCM0) |
_VAL2FLD(PWRCTRL_MEMPWREN_FLASH0, PWRCTRL_MEMPWREN_FLASH0_EN));
am_hal_flash_delay(FLASH_CYCLES_US(1));
}
//
// Enable the required memory.
//
if ( ui32MemEnMask != 0 )
{
PWRCTRL->MEMPWREN |= ui32MemEnMask;
for (uint32_t wait_usecs = 0; wait_usecs < AM_HAL_PWRCTRL_MAX_WFE; wait_usecs += 10)
{
am_hal_flash_delay(FLASH_CYCLES_US(10));
if ( (PWRCTRL->MEMPWRSTATUS & ui32MemStatusMask) ==
am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryStatus )
{
break;
}
}
}
//
// Return status based on whether the power control memory status has reached the desired state.
//
if ( ( PWRCTRL->MEMPWRSTATUS & ui32MemStatusMask) ==
am_hal_pwrctrl_memory_control[eMemConfig].ui32MemoryStatus )
{
return AM_HAL_STATUS_SUCCESS;
}
else
{
return AM_HAL_STATUS_FAIL;
}
}
// ****************************************************************************
//
// am_hal_pwrctrl_memory_deepsleep_powerdown()
// Power down respective memory.
//
// ****************************************************************************
uint32_t
am_hal_pwrctrl_memory_deepsleep_powerdown(am_hal_pwrctrl_mem_e eMemConfig)
{
if ( eMemConfig >= AM_HAL_PWRCTRL_MEM_MAX )
{
return AM_HAL_STATUS_FAIL;
}
//
// Power down the required memory.
//
PWRCTRL->MEMPWDINSLEEP |= am_hal_pwrctrl_memory_control[eMemConfig].ui32PwdSlpEnable;
return AM_HAL_STATUS_SUCCESS;
}
// ****************************************************************************
//
// am_hal_pwrctrl_memory_deepsleep_retain()
// Apply retention voltage to respective memory.
//
// ****************************************************************************
uint32_t
am_hal_pwrctrl_memory_deepsleep_retain(am_hal_pwrctrl_mem_e eMemConfig)
{
if ( eMemConfig >= AM_HAL_PWRCTRL_MEM_MAX )
{
return AM_HAL_STATUS_FAIL;
}
//
// Retain the required memory.
//
PWRCTRL->MEMPWDINSLEEP &= ~am_hal_pwrctrl_memory_control[eMemConfig].ui32PwdSlpEnable;
return AM_HAL_STATUS_SUCCESS;
}
// ****************************************************************************
//
// am_hal_pwrctrl_low_power_init()
// Initialize system for low power configuration.
//
// ****************************************************************************
uint32_t
am_hal_pwrctrl_low_power_init(void)
{
uint32_t ui32Status;
//
// Take a snapshot of the reset status, if not done already
//
if (!gAmHalResetStatus)
{
gAmHalResetStatus = RSTGEN->STAT;
}
//
// Software workaround for Errata ERR019.
//
if ((APOLLO3_A1) && (1 == PWRCTRL->SUPPLYSTATUS_b.SIMOBUCKON))
{
ui32Status = am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_PDM);
if (AM_HAL_STATUS_SUCCESS != ui32Status)
{
return ui32Status;
}
}
//
// Adjust the SIMOBUCK LP settings.
//
if (APOLLO3_GE_B0)
{
MCUCTRL->SIMOBUCK2_b.SIMOBUCKCORELPHIGHTONTRIM = 2;
MCUCTRL->SIMOBUCK2_b.SIMOBUCKCORELPLOWTONTRIM = 3;
MCUCTRL->SIMOBUCK3_b.SIMOBUCKCORELPHIGHTOFFTRIM = 5;
MCUCTRL->SIMOBUCK3_b.SIMOBUCKCORELPLOWTOFFTRIM = 2;
MCUCTRL->SIMOBUCK3_b.SIMOBUCKMEMLPHIGHTOFFTRIM = 6;
MCUCTRL->SIMOBUCK3_b.SIMOBUCKMEMLPLOWTOFFTRIM = 1;
MCUCTRL->SIMOBUCK3_b.SIMOBUCKMEMLPHIGHTONTRIM = 3;
MCUCTRL->SIMOBUCK4_b.SIMOBUCKMEMLPLOWTONTRIM = 3;
}
//
// Adjust the SIMOBUCK Timeout settings.
//
if (APOLLO3_GE_A1)
{
MCUCTRL->SIMOBUCK4_b.SIMOBUCKCOMP2TIMEOUTEN = 0;
}
//
// Configure cache for low power and performance.
//
am_hal_cachectrl_control(AM_HAL_CACHECTRL_CONTROL_LPMMODE_RECOMMENDED, 0);
//
// Check if the BLE is already enabled.
//
if ( PWRCTRL->DEVPWRSTATUS_b.BLEL == 0)
{
//
// First request the BLE feature and check that it was available and acknowledged.
//
MCUCTRL->FEATUREENABLE_b.BLEREQ = 1;
ui32Status = am_hal_flash_delay_status_check(10000,
(uint32_t)&MCUCTRL->FEATUREENABLE,
(MCUCTRL_FEATUREENABLE_BLEAVAIL_Msk |
MCUCTRL_FEATUREENABLE_BLEACK_Msk |
MCUCTRL_FEATUREENABLE_BLEREQ_Msk),
(MCUCTRL_FEATUREENABLE_BLEAVAIL_Msk |
MCUCTRL_FEATUREENABLE_BLEACK_Msk |
MCUCTRL_FEATUREENABLE_BLEREQ_Msk),
true);
if (AM_HAL_STATUS_SUCCESS != ui32Status)
{
return AM_HAL_STATUS_TIMEOUT;
}
//
// Next, enable the BLE Buck.
//
PWRCTRL->SUPPLYSRC |= _VAL2FLD(PWRCTRL_SUPPLYSRC_BLEBUCKEN,
PWRCTRL_SUPPLYSRC_BLEBUCKEN_EN);
//
// Allow the buck to go to low power mode in BLE sleep.
//
PWRCTRL->MISC |= _VAL2FLD(PWRCTRL_MISC_MEMVRLPBLE,
PWRCTRL_MISC_MEMVRLPBLE_EN);
//
// Check for Apollo3 A0 Silicon.
//
if ( APOLLO3_A0 )
{
// Disable SIMO Buck clkdiv because if ble is out of reset then the same bit divides the simobuck clk too aggressively.
MCUCTRL->SIMOBUCK4_b.SIMOBUCKCLKDIVSEL = 0x0;
MCUCTRL->BLEBUCK2_b.BLEBUCKTONHITRIM = 0xF;
MCUCTRL->BLEBUCK2_b.BLEBUCKTONLOWTRIM = 0xF;
}
}
return AM_HAL_STATUS_SUCCESS;
}
void am_hal_pwrctrl_blebuck_trim(void)
{
//
// Enable the BLE buck trim values
//
if ( APOLLO3_GE_A1 )
{
AM_CRITICAL_BEGIN
MCUCTRL->BLEBUCK2_b.BLEBUCKTONHITRIM = 0x19;
MCUCTRL->BLEBUCK2_b.BLEBUCKTONLOWTRIM = 0xC;
CLKGEN->BLEBUCKTONADJ_b.TONADJUSTEN = CLKGEN_BLEBUCKTONADJ_TONADJUSTEN_DIS;
AM_CRITICAL_END
}
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,260 @@
//*****************************************************************************
//
// am_hal_pwrctrl.h
//! @file
//!
//! @brief Functions for enabling and disabling power domains.
//!
//! @addtogroup pwrctrl3 Power Control
//! @ingroup apollo3hal
//! @{
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_PWRCTRL_H
#define AM_HAL_PWRCTRL_H
//
// Designate this peripheral.
//
#define AM_APOLLO3_PWRCTRL 1
typedef enum
{
AM_HAL_PWRCTRL_PERIPH_NONE,
AM_HAL_PWRCTRL_PERIPH_IOS,
AM_HAL_PWRCTRL_PERIPH_IOM0,
AM_HAL_PWRCTRL_PERIPH_IOM1,
AM_HAL_PWRCTRL_PERIPH_IOM2,
AM_HAL_PWRCTRL_PERIPH_IOM3,
AM_HAL_PWRCTRL_PERIPH_IOM4,
AM_HAL_PWRCTRL_PERIPH_IOM5,
AM_HAL_PWRCTRL_PERIPH_UART0,
AM_HAL_PWRCTRL_PERIPH_UART1,
AM_HAL_PWRCTRL_PERIPH_ADC,
AM_HAL_PWRCTRL_PERIPH_SCARD,
AM_HAL_PWRCTRL_PERIPH_MSPI,
AM_HAL_PWRCTRL_PERIPH_PDM,
AM_HAL_PWRCTRL_PERIPH_BLEL,
AM_HAL_PWRCTRL_PERIPH_MAX
} am_hal_pwrctrl_periph_e;
typedef enum
{
AM_HAL_PWRCTRL_MEM_NONE,
AM_HAL_PWRCTRL_MEM_SRAM_8K_DTCM,
AM_HAL_PWRCTRL_MEM_SRAM_32K_DTCM,
AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM,
AM_HAL_PWRCTRL_MEM_SRAM_96K,
AM_HAL_PWRCTRL_MEM_SRAM_128K,
AM_HAL_PWRCTRL_MEM_SRAM_160K,
AM_HAL_PWRCTRL_MEM_SRAM_192K,
AM_HAL_PWRCTRL_MEM_SRAM_224K,
AM_HAL_PWRCTRL_MEM_SRAM_256K,
AM_HAL_PWRCTRL_MEM_SRAM_288K,
AM_HAL_PWRCTRL_MEM_SRAM_320K,
AM_HAL_PWRCTRL_MEM_SRAM_352K,
AM_HAL_PWRCTRL_MEM_SRAM_384K,
AM_HAL_PWRCTRL_MEM_FLASH_512K,
AM_HAL_PWRCTRL_MEM_FLASH_1M,
AM_HAL_PWRCTRL_MEM_CACHE,
AM_HAL_PWRCTRL_MEM_ALL,
AM_HAL_PWRCTRL_MEM_MAX
} am_hal_pwrctrl_mem_e;
#define AM_HAL_PWRCTRL_MEM_FLASH_MIN AM_HAL_PWRCTRL_MEM_FLASH_512K
#define AM_HAL_PWRCTRL_MEM_FLASH_MAX AM_HAL_PWRCTRL_MEM_FLASH_1M
#define AM_HAL_PWRCTRL_MEM_SRAM_MIN AM_HAL_PWRCTRL_MEM_SRAM_8K_DTCM
#define AM_HAL_PWRCTRL_MEM_SRAM_MAX AM_HAL_PWRCTRL_MEM_SRAM_384K
//*****************************************************************************
//
// Macros to check whether Apollo3 bucks are enabled.
//
//*****************************************************************************
#define am_hal_pwrctrl_simobuck_enabled_check() \
(AM_BFR(PWRCTRL, SUPPLYSTATUS, SIMOBUCKON))
#define am_hal_pwrctrl_blebuck_enabled_check() \
(AM_BFR(PWRCTRL, SUPPLYSTATUS, BLEBUCKON))
//*****************************************************************************
//
// Function prototypes
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! @brief Enable power to a peripheral.
//!
//! @param ePeripheral - The peripheral to enable.
//!
//! This function enables power to the peripheral and waits for a
//! confirmation from the hardware.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_pwrctrl_periph_enable(am_hal_pwrctrl_periph_e ePeripheral);
//*****************************************************************************
//
//! @brief Disable power to a peripheral.
//!
//! @param ePeripheral - The peripheral to disable.
//!
//! This function disables power to the peripheral and waits for a
//! confirmation from the hardware.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_pwrctrl_periph_disable(am_hal_pwrctrl_periph_e ePeripheral);
//*****************************************************************************
//
//! @brief Determine whether a peripheral is currently enabled.
//!
//! @param ePeripheral - The peripheral to enable.
//! @param pui32Enabled - Pointer to a ui32 that will return as 1 or 0.
//!
//! This function determines to the caller whether a given peripheral is
//! currently enabled or disabled.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_pwrctrl_periph_enabled(
am_hal_pwrctrl_periph_e ePeripheral, uint32_t *pui32Enabled);
//*****************************************************************************
//
//! @brief Enable a configuration of memory.
//!
//! @param eMemConfig - The memory configuration.
//!
//! This function establishes the desired configuration of flash, SRAM, ICache,
//! and DCache (DTCM) according to the desired Memory Configuration mask.
//!
//! Only the type of memory specified is affected. Therefore separate calls
//! are required to affect power settings for FLASH, SRAM, or CACHE.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_pwrctrl_memory_enable(am_hal_pwrctrl_mem_e eMemConfig);
//*****************************************************************************
//
//! @brief Power down respective memory.
//!
//! @param eMemPwd - The memory power down enum.
//!
//! This function establishes the desired power down of flash, SRAM, ICache,
//! and DCache (DTCM) according to the desired enum.
//!
//! Only the type of memory specified is affected. Therefore separate calls
//! are required to affect power settings for FLASH, SRAM, or CACHE.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_pwrctrl_memory_deepsleep_powerdown(am_hal_pwrctrl_mem_e eMemConfig);
//*****************************************************************************
//
//! @brief Apply retention voltage to respective memory.
//!
//! @param eMemPwd - The memory power down enum.
//!
//! This function establishes the desired power retain of flash, SRAM, ICache,
//! and DCache (DTCM) according to the desired enum.
//!
//! Only the type of memory specified is affected. Therefore separate calls
//! are required to affect power settings for FLASH, SRAM, or CACHE.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_pwrctrl_memory_deepsleep_retain(am_hal_pwrctrl_mem_e eMemConfig);
//*****************************************************************************
//
//! @brief Initialize system for low power configuration.
//!
//! @param none.
//!
//! This function handles low power initialization.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_pwrctrl_low_power_init(void);
//*****************************************************************************
//
//! @brief Initialize BLE Buck Trims for Lowest Power.
//!
//! @param none.
//!
//! @return none.
//
//*****************************************************************************
extern void am_hal_pwrctrl_blebuck_trim(void);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_PWRCTRL_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,339 @@
//*****************************************************************************
//
// am_hal_pwrctrl_internal.h
//! @file
//!
//! @brief Internal definitions for Power Control
//!
//! @addtogroup pwrctrl3 Power Control
//! @ingroup apollo3hal
//! @{
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_PWRCTRL_INTERNAL_H
#define AM_HAL_PWRCTRL_INTERNAL_H
//*****************************************************************************
//
// Peripheral enable bits for am_hal_pwrctrl_periph_enable/disable()
//
//*****************************************************************************
#define AM_HAL_PWRCTRL_IOS (_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOS, PWRCTRL_DEVPWREN_PWRIOS_EN))
#define AM_HAL_PWRCTRL_IOM0 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM0, PWRCTRL_DEVPWREN_PWRIOM0_EN))
#define AM_HAL_PWRCTRL_IOM1 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM1, PWRCTRL_DEVPWREN_PWRIOM1_EN))
#define AM_HAL_PWRCTRL_IOM2 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM2, PWRCTRL_DEVPWREN_PWRIOM2_EN))
#define AM_HAL_PWRCTRL_IOM3 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM3, PWRCTRL_DEVPWREN_PWRIOM3_EN))
#define AM_HAL_PWRCTRL_IOM4 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM4, PWRCTRL_DEVPWREN_PWRIOM4_EN))
#define AM_HAL_PWRCTRL_IOM5 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRIOM5, PWRCTRL_DEVPWREN_PWRIOM5_EN))
#define AM_HAL_PWRCTRL_UART0 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART0, PWRCTRL_DEVPWREN_PWRUART0_EN))
#define AM_HAL_PWRCTRL_UART1 (_VAL2FLD(PWRCTRL_DEVPWREN_PWRUART1, PWRCTRL_DEVPWREN_PWRUART1_EN))
#define AM_HAL_PWRCTRL_ADC (_VAL2FLD(PWRCTRL_DEVPWREN_PWRADC, PWRCTRL_DEVPWREN_PWRADC_EN))
#define AM_HAL_PWRCTRL_SCARD (_VAL2FLD(PWRCTRL_DEVPWREN_PWRSCARD, PWRCTRL_DEVPWREN_PWRSCARD_EN))
#define AM_HAL_PWRCTRL_MSPI (_VAL2FLD(PWRCTRL_DEVPWREN_PWRMSPI, PWRCTRL_DEVPWREN_PWRMSPI_EN))
#define AM_HAL_PWRCTRL_PDM (_VAL2FLD(PWRCTRL_DEVPWREN_PWRPDM, PWRCTRL_DEVPWREN_PWRPDM_EN))
#define AM_HAL_PWRCTRL_BLEL (_VAL2FLD(PWRCTRL_DEVPWREN_PWRBLEL, PWRCTRL_DEVPWREN_PWRBLEL_EN))
#define AM_HAL_PWRCTRL_DEVPWREN_MASK 0x00003FFF
#define AM_HAL_PWRCTRL_DEVPWRSTATUS_MASK 0x000003FC
//*****************************************************************************
//
// Memory enable values for all defined memory configurations.
//
//*****************************************************************************
#define AM_HAL_PWRCTRL_MEMEN_SRAM_8K_DTCM (_VAL2FLD(PWRCTRL_MEMPWREN_DTCM, PWRCTRL_MEMPWREN_DTCM_GROUP0DTCM0))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_32K_DTCM (_VAL2FLD(PWRCTRL_MEMPWREN_DTCM, PWRCTRL_MEMPWREN_DTCM_GROUP0))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_64K_DTCM (_VAL2FLD(PWRCTRL_MEMPWREN_DTCM, PWRCTRL_MEMPWREN_DTCM_ALL))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_96K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_64K_DTCM | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP0))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_128K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_96K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP1))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_160K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_128K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP2))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_192K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_160K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP3))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_224K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_192K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP4))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_256K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_224K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP5))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_288K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_256K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP6))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_320K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_288K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP7))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_352K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_320K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP8))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_384K \
(AM_HAL_PWRCTRL_MEMEN_SRAM_352K | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_GROUP9))
#define AM_HAL_PWRCTRL_MEMEN_SRAM_ALL (AM_HAL_PWRCTRL_MEMEN_SRAM_384K)
#define AM_HAL_PWRCTRL_MEMEN_FLASH_512K PWRCTRL_MEMPWREN_FLASH0_Msk
#define AM_HAL_PWRCTRL_MEMEN_FLASH_1M \
(PWRCTRL_MEMPWREN_FLASH0_Msk | PWRCTRL_MEMPWREN_FLASH1_Msk)
#define AM_HAL_PWRCTRL_MEMEN_CACHE \
(PWRCTRL_MEMPWREN_CACHEB0_Msk | PWRCTRL_MEMPWREN_CACHEB2_Msk)
#define AM_HAL_PWRCTRL_MEMEN_CACHE_DIS (~AM_HAL_PWRCTRL_MEMEN_CACHE)
//
// Power up all available memory devices (this is the default power up state)
//
#define AM_HAL_PWRCTRL_MEMEN_ALL \
(_VAL2FLD(PWRCTRL_MEMPWREN_DTCM, PWRCTRL_MEMPWREN_DTCM_ALL) | \
_VAL2FLD(PWRCTRL_MEMPWREN_SRAM, PWRCTRL_MEMPWREN_SRAM_ALL) | \
_VAL2FLD(PWRCTRL_MEMPWREN_FLASH0, PWRCTRL_MEMPWREN_FLASH0_EN) | \
_VAL2FLD(PWRCTRL_MEMPWREN_FLASH1, PWRCTRL_MEMPWREN_FLASH1_EN) | \
_VAL2FLD(PWRCTRL_MEMPWREN_CACHEB0, PWRCTRL_MEMPWREN_CACHEB0_EN) | \
_VAL2FLD(PWRCTRL_MEMPWREN_CACHEB2, PWRCTRL_MEMPWREN_CACHEB2_EN))
//*****************************************************************************
//
// Memory deepsleep powerdown values for all defined memory configurations.
//
//*****************************************************************************
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_8K_DTCM (_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP, PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP_GROUP0DTCM0))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_32K_DTCM (_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP, PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP_GROUP0))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_64K_DTCM (_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP, PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP_ALL))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_96K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_64K_DTCM | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP0))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_128K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_96K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP1))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_160K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_128K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP2))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_192K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_160K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP3))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_224K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_192K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP4))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_256K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_224K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP5))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_288K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_256K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP6))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_320K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_288K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP7))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_352K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_320K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP8))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_384K \
(AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_352K | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_GROUP9))
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_ALL (AM_HAL_PWRCTRL_MEMPWDINSLEEP_SRAM_384K)
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_512K PWRCTRL_MEMPWDINSLEEP_FLASH0PWDSLP_Msk
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_FLASH_1M \
(PWRCTRL_MEMPWDINSLEEP_FLASH0PWDSLP_Msk | PWRCTRL_MEMPWDINSLEEP_FLASH1PWDSLP_Msk)
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_CACHE (PWRCTRL_MEMPWDINSLEEP_CACHEPWDSLP_Msk)
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_CACHE_DIS (~AM_HAL_PWRCTRL_MEMPWDINSLEEP_CACHE)
//
// Power down all available memory devices
//
#define AM_HAL_PWRCTRL_MEMPWDINSLEEP_ALL \
(_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP, PWRCTRL_MEMPWDINSLEEP_DTCMPWDSLP_ALL) | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP, PWRCTRL_MEMPWDINSLEEP_SRAMPWDSLP_ALL) | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_FLASH0PWDSLP, PWRCTRL_MEMPWDINSLEEP_FLASH0PWDSLP_EN) | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_FLASH1PWDSLP, PWRCTRL_MEMPWDINSLEEP_FLASH1PWDSLP_EN) | \
_VAL2FLD(PWRCTRL_MEMPWDINSLEEP_CACHEPWDSLP, PWRCTRL_MEMPWDINSLEEP_CACHEPWDSLP_EN))
//*****************************************************************************
//
// Memory status values for all defined memory configurations
//
//*****************************************************************************
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K_DTCM \
(PWRCTRL_MEMPWRSTATUS_DTCM00_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K_DTCM \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_8K_DTCM | \
PWRCTRL_MEMPWRSTATUS_DTCM01_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K_DTCM \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_32K_DTCM | \
PWRCTRL_MEMPWRSTATUS_DTCM1_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_96K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_64K_DTCM | \
PWRCTRL_MEMPWRSTATUS_SRAM0_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_96K | \
PWRCTRL_MEMPWRSTATUS_SRAM1_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_160K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_128K | \
PWRCTRL_MEMPWRSTATUS_SRAM2_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_160K | \
PWRCTRL_MEMPWRSTATUS_SRAM3_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_224K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_192K | \
PWRCTRL_MEMPWRSTATUS_SRAM4_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_224K | \
PWRCTRL_MEMPWRSTATUS_SRAM5_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_288K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_256K | \
PWRCTRL_MEMPWRSTATUS_SRAM6_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_320K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_288K | \
PWRCTRL_MEMPWRSTATUS_SRAM7_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_352K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_320K | \
PWRCTRL_MEMPWRSTATUS_SRAM8_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_384K \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_352K | \
PWRCTRL_MEMPWRSTATUS_SRAM9_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_ALL \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_384K)
#define AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_512K \
(PWRCTRL_MEMPWRSTATUS_FLASH0_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_1M \
(AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_512K | \
PWRCTRL_MEMPWRSTATUS_FLASH1_Msk)
#define AM_HAL_PWRCTRL_PWRONSTATUS_ALL \
(AM_HAL_PWRCTRL_PWRONSTATUS_SRAM_384K | \
AM_HAL_PWRCTRL_PWRONSTATUS_FLASH_1M)
//*****************************************************************************
//
// Memory event values for all defined memory configurations
//
//*****************************************************************************
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_8K_DTCM \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_DTCMEN, \
PWRCTRL_MEMPWREVENTEN_DTCMEN_GROUP0DTCM0EN))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_32K_DTCM \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_DTCMEN, \
PWRCTRL_MEMPWREVENTEN_DTCMEN_GROUP0EN))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_64K_DTCM \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_DTCMEN, \
PWRCTRL_MEMPWREVENTEN_DTCMEN_ALL))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_96K \
((_VAL2FLD(PWRCTRL_MEMPWREVENTEN_DTCMEN, \
PWRCTRL_MEMPWREVENTEN_DTCMEN_ALL)) | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP0EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_128K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_96K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP1EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_160K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_128K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP2EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_192K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_160K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP3EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_224K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_192K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP4EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_256K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_224K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP5EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_288K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_256K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP6EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_320K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_288K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP7EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_352K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_320K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP8EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_384K \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_352K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_SRAMEN, \
PWRCTRL_MEMPWREVENTEN_SRAMEN_GROUP9EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_512K \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_FLASH0EN, \
PWRCTRL_MEMPWREVENTEN_FLASH0EN_EN))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_1M \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_512K | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_FLASH1EN, \
PWRCTRL_MEMPWREVENTEN_FLASH1EN_EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_CACHE \
((_VAL2FLD(PWRCTRL_MEMPWREVENTEN_CACHEB0EN, \
PWRCTRL_MEMPWREVENTEN_CACHEB0EN_EN)) | \
(_VAL2FLD(PWRCTRL_MEMPWREVENTEN_CACHEB2EN, \
PWRCTRL_MEMPWREVENTEN_CACHEB2EN_EN)))
#define AM_HAL_PWRCTRL_MEMPWREVENTEN_ALL \
(AM_HAL_PWRCTRL_MEMPWREVENTEN_SRAM_384K | \
AM_HAL_PWRCTRL_MEMPWREVENTEN_FLASH_1M | \
AM_HAL_PWRCTRL_MEMPWREVENTEN_CACHE)
//*****************************************************************************
//
// Memory region mask values for all defined memory configurations
//
//*****************************************************************************
#define AM_HAL_PWRCTRL_MEM_REGION_SRAM_MASK AM_HAL_PWRCTRL_MEMEN_SRAM_ALL
#define AM_HAL_PWRCTRL_MEM_REGION_FLASH_MASK AM_HAL_PWRCTRL_MEMEN_FLASH_1M
#define AM_HAL_PWRCTRL_MEM_REGION_CACHE_MASK AM_HAL_PWRCTRL_MEMEN_CACHE
#define AM_HAL_PWRCTRL_MEM_REGION_ALT_CACHE_MASK AM_HAL_PWRCTRL_PWRONSTATUS_CACHE
#define AM_HAL_PWRCTRL_MEM_REGION_ALL_MASK AM_HAL_PWRCTRL_MEMEN_ALL
#define AM_HAL_PWRCTRL_MEM_REGION_ALT_ALL_MASK AM_HAL_PWRCTRL_PWRONSTATUS_ALL
#endif // AM_HAL_PWRCTRL_INTERNAL_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,293 @@
//*****************************************************************************
//
// am_hal_queue.c
//! @file
//!
//! @brief Functions for implementing a queue system.
//!
//! @addtogroup queue3 (QUEUE)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
//! @brief Initializes a queue.
//!
//! @param psQueue - Pointer to a queue structure.
//! @param pvData - Pointer to a memory location to be used for data storage.
//! @param ui32ItemSize - Number of bytes per item in the queue.
//! @param ui32ArraySize - Number of bytes in the data array.
//!
//! This function initializes the members of a queue structure and attaches it
//! to an array of memory that it can use for storage. This function should be
//! called before the queue is used.
//!
//! In this example, we are creating a queue that can hold 1024 32-bit
//! integers. The integers themselves will be stored in the array named
//! pui32WorkingSpace, while information about the queue itself will be stored
//! in sDataQueue.
//!
//! @note The caller should not modify any of the members of am_hal_queue_t
//! structures. The queue API will handle these members in a thread-safe way.
//!
//! @note The queue will remember what size data is in it. Other queue API
//! functions will perform transfers in units of "items" where one "item" is
//! the number of bytes you specify in the \e ui32ItemSize argument upon
//! initialization.
//!
//! Example usage:
//!
//! @code
//!
//! //
//! // Declare a queue structure and an array of bytes we can use to store
//! // data.
//! //
//! am_hal_queue_t sDataQueue;
//! uint32_t pui32WorkingSpace[1024];
//!
//! //
//! // Attach the queue structure to the working memory.
//! //
//! am_hal_queue_init(&sDataQueue, pui8WorkingSpace, sizeof(uint32_t)
//! sizeof(pui32WorkingSpace));
//!
//! @endcode
//!
//! The am_hal_queue_from_array macro is a convenient shorthand for this
//! operation. The code below does the same thing as the code above.
//!
//! @code
//!
//! //
//! // Declare a queue structure and an array of bytes we can use to store
//! // data.
//! //
//! am_hal_queue_t sDataQueue;
//! uint32_t pui32WorkingSpace[1024];
//!
//! //
//! // Attach the queue structure to the working memory.
//! //
//! am_hal_queue_from_array(&sDataQueue, pui8WorkingSpace);
//!
//! @endcode
//
//*****************************************************************************
void
am_hal_queue_init(am_hal_queue_t *psQueue, void *pvData, uint32_t ui32ItemSize,
uint32_t ui32ArraySize)
{
psQueue->ui32WriteIndex = 0;
psQueue->ui32ReadIndex = 0;
psQueue->ui32Length = 0;
psQueue->ui32Capacity = ui32ArraySize;
psQueue->ui32ItemSize = ui32ItemSize;
psQueue->pui8Data = (uint8_t *) pvData;
}
//*****************************************************************************
//
//! @brief Adds an item to the Queue
//!
//! @param psQueue - Pointer to a queue structure.
//! @param pvSource - Pointer to the data to be added.
//! @param ui32NumItems - Number of items to be added.
//!
//! This function will copy the data pointed to by pvSource into the queue. The
//! \e ui32NumItems term specifies the number of items to be copied from \e
//! pvSource. The size of an "item" depends on how the queue was initialized.
//! Please see am_hal_queue_init() for more information on this.
//!
//! @return true if the add operation was successful, or false if the queue
//! didn't have enough space.
//
//*****************************************************************************
bool
am_hal_queue_item_add(am_hal_queue_t *psQueue, const void *pvSource, uint32_t ui32NumItems)
{
uint8_t *pui8Source;
uint32_t ui32Bytes = ui32NumItems * psQueue->ui32ItemSize;
bool bSuccess = false;
pui8Source = (uint8_t *) pvSource;
AM_CRITICAL_BEGIN
//
// Check to make sure that the buffer isn't already full
//
if ( am_hal_queue_space_left(psQueue) >= ui32Bytes )
{
//
// Loop over the bytes in the source array.
//
for ( uint32_t i = 0; i < ui32Bytes; i++ )
{
//
// Write the value to the buffer, but only if the source pointer is
// valid.
//
if (pvSource)
{
psQueue->pui8Data[psQueue->ui32WriteIndex] = pui8Source[i];
}
//
// Advance the write index, making sure to wrap if necessary.
//
psQueue->ui32WriteIndex = ((psQueue->ui32WriteIndex + 1) %
psQueue->ui32Capacity);
}
//
// Update the length value appropriately.
//
psQueue->ui32Length += ui32Bytes;
//
// Report a success.
//
bSuccess = true;
}
else
{
//
// The buffer can't fit the amount of data requested. Return a
// failure.
//
bSuccess = false;
}
AM_CRITICAL_END
return bSuccess;
}
//*****************************************************************************
//
//! @brief Removes an item from the Queue
//!
//! @param psQueue - Pointer to a queue structure.
//! @param pvDest - Pointer to the data to be added.
//! @param ui32NumItems - Number of items to be added.
//!
//! This function will copy the data from the queue into the memory pointed to
//! by pvDest. The \e ui32NumItems term specifies the number of items to be
//! copied from the queue. The size of an "item" depends on how the queue was
//! initialized. Please see am_hal_queue_init() for more information on this.
//!
//! @return true if we were able to pull the requested number of items from the
//! queue, or false if the queue didn't have that many items to pull.
//
//*****************************************************************************
bool
am_hal_queue_item_get(am_hal_queue_t *psQueue, void *pvDest, uint32_t ui32NumItems)
{
uint8_t *pui8Dest;
uint32_t ui32Bytes = ui32NumItems * psQueue->ui32ItemSize;
bool bSuccess = false;
pui8Dest = (uint8_t *) pvDest;
AM_CRITICAL_BEGIN
//
// Check to make sure that the buffer isn't empty
//
if ( am_hal_queue_data_left(psQueue) >= ui32Bytes )
{
//
// Loop over the bytes in the destination array.
//
for ( uint32_t i = 0; i < ui32Bytes; i++ )
{
//
// Grab the next value from the buffer, but only if the
// destination pointer is valid.
//
if (pvDest)
{
pui8Dest[i] = psQueue->pui8Data[psQueue->ui32ReadIndex];
}
//
// Advance the read index, wrapping if needed.
//
psQueue->ui32ReadIndex = ((psQueue->ui32ReadIndex + 1) %
psQueue->ui32Capacity);
}
//
// Adjust the length value to reflect the change.
//
psQueue->ui32Length -= ui32Bytes;
//
// Report a success.
//
bSuccess = true;
}
else
{
//
// If the buffer didn't have enough data, just return false.
//
bSuccess = false;
}
AM_CRITICAL_END
return bSuccess;
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,164 @@
//*****************************************************************************
//
// am_hal_queue.h
//! @file
//!
//! @brief Functions for implementing a queue system.
//!
//! @addtogroup queue3 (QUEUE)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_QUEUE_H
#define AM_HAL_QUEUE_H
//*****************************************************************************
//
//! @brief A data structure that will operate as a queue.
//!
//! This data structure holds information necessary for operating a thread-safe
//! queue. When declaring a structure of type am_hal_queue_t, you will also need
//! to provide some working memory for the queue to use. For more information on
//! setting up and using the am_hal_queue_t structure, please see the
//! documentation for am_hal_queue_init().
//
//*****************************************************************************
typedef struct
{
uint32_t ui32WriteIndex;
uint32_t ui32ReadIndex;
uint32_t ui32Length;
uint32_t ui32Capacity;
uint32_t ui32ItemSize;
uint8_t *pui8Data;
}
am_hal_queue_t;
//*****************************************************************************
//
// Function-like macros.
//
//*****************************************************************************
//
// Returns true if the queue is empty.
//
#define am_hal_queue_empty(psQueue) \
((psQueue)->ui32Length == 0)
//
// Returns true if the queue is full.
//
#define am_hal_queue_full(psQueue) \
((psQueue)->ui32Length == (psQueue)->ui32Capacity)
//
// Returns the amount of space left in the queue (in bytes).
//
#define am_hal_queue_space_left(psQueue) \
((psQueue)->ui32Capacity - (psQueue)->ui32Length)
//
// Returns the number of configured items that will fit in the queue.
//
#define am_hal_queue_slots_left(psQueue) \
(((psQueue)->ui32Capacity - (psQueue)->ui32Length) \
/ (psQueue)->ui32ItemSize)
//
// Returns the amount of data in the queue (in bytes).
//
#define am_hal_queue_data_left(psQueue) \
((psQueue)->ui32Length)
//
// Returns the number of configured items left in the queue.
//
#define am_hal_queue_items_left(psQueue) \
((psQueue)->ui32Length / (psQueue)->ui32ItemSize)
//
// Can be used as a pointer to the next item to be read from the queue.
//
#define am_hal_queue_peek(psQueue) \
((void *) &((psQueue)->pui8Data[(psQueue)->ui32ReadIndex]))
//
// Can be used as a pointer to the next available slot in the queue memory.
//
#define am_hal_queue_next_slot(psQueue) \
((void *) &((psQueue)->pui8Data[(psQueue)->ui32WriteIndex]))
//*****************************************************************************
//
// Use this to make sure you get the size parameters right.
//
//*****************************************************************************
#define am_hal_queue_from_array(queue, array) \
am_hal_queue_init((queue), (array), sizeof((array)[0]), sizeof(array))
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern void am_hal_queue_init(am_hal_queue_t *psQueue, void *pvData, uint32_t ui32ItemSize, uint32_t ui32ArraySize);
extern bool am_hal_queue_item_add(am_hal_queue_t *psQueue, const void *pvSource, uint32_t ui32NumItems);
extern bool am_hal_queue_item_get(am_hal_queue_t *psQueue, void *pvDest, uint32_t ui32NumItems);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_QUEUE_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,313 @@
//*****************************************************************************
//
// am_hal_reset.c
//! @file
//!
//! @brief Hardware abstraction layer for the Reset Generator module.
//!
//! @addtogroup rstgen3 Reset Generator (RSTGEN)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
uint32_t gAmHalResetStatus = 0;
//*****************************************************************************
//
// am_hal_reset_enable()
// Enable and configure the Reset controller.
//
//*****************************************************************************
uint32_t
am_hal_reset_configure(am_hal_reset_configure_e eConfigure)
{
uint32_t ui32Val;
bool bEnable;
switch ( eConfigure )
{
case AM_HAL_RESET_BROWNOUT_HIGH_ENABLE:
bEnable = true;
ui32Val = RSTGEN_CFG_BODHREN_Msk;
break;
case AM_HAL_RESET_WDT_RESET_ENABLE:
bEnable = true;
ui32Val = RSTGEN_CFG_WDREN_Msk;
break;
case AM_HAL_RESET_BROWNOUT_HIGH_DISABLE:
bEnable = false;
ui32Val = RSTGEN_CFG_BODHREN_Msk;
break;
case AM_HAL_RESET_WDT_RESET_DISABLE:
bEnable = false;
ui32Val = RSTGEN_CFG_WDREN_Msk;
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
AM_CRITICAL_BEGIN
if ( bEnable )
{
RSTGEN->CFG |= ui32Val;
}
else
{
RSTGEN->CFG &= ~ui32Val;
}
AM_CRITICAL_END
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_reset_configure()
//*****************************************************************************
//
// am_hal_reset_control()
// Perform various reset functions including assertion of software resets.
//
//*****************************************************************************
uint32_t
am_hal_reset_control(am_hal_reset_control_e eControl, void *pArgs)
{
switch ( eControl )
{
case AM_HAL_RESET_CONTROL_SWPOR:
//
// Perform a Power On Reset level reset.
// Write the POR key to the software POR register.
//
RSTGEN->SWPOR =
_VAL2FLD(RSTGEN_SWPOR_SWPORKEY, RSTGEN_SWPOR_SWPORKEY_KEYVALUE);
break;
case AM_HAL_RESET_CONTROL_SWPOI:
//
// Perform a Power On Initialization level reset.
// Write the POI key to the software POI register.
//
RSTGEN->SWPOI =
_VAL2FLD(RSTGEN_SWPOI_SWPOIKEY, RSTGEN_SWPOI_SWPOIKEY_KEYVALUE);
break;
case AM_HAL_RESET_CONTROL_STATUSCLEAR:
//
// Clear ALL of the reset status register bits.
//
RSTGEN->STAT = 0;
break;
case AM_HAL_RESET_CONTROL_TPIU_RESET:
//
// Reset the TPIU.
//
RSTGEN->TPIURST = _VAL2FLD(RSTGEN_TPIURST_TPIURST, 1);
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_reset_control()
//*****************************************************************************
//
// am_hal_reset_status_get()
// Return status of the reset generator.
// Application MUST call this API at least once before going to deepsleep
// Otherwise this API will not provide correct reset status
//
//*****************************************************************************
uint32_t
am_hal_reset_status_get(am_hal_reset_status_t *psStatus)
{
// Need to read the status only the very first time
if ( psStatus == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Retrieve the reset generator status bits
//
if (!gAmHalResetStatus)
{
gAmHalResetStatus = RSTGEN->STAT;
}
psStatus->eStatus = (am_hal_reset_status_e)gAmHalResetStatus;
psStatus->bEXTStat = _FLD2VAL(RSTGEN_STAT_EXRSTAT, gAmHalResetStatus);
psStatus->bPORStat = _FLD2VAL(RSTGEN_STAT_PORSTAT, gAmHalResetStatus);
psStatus->bBODStat = _FLD2VAL(RSTGEN_STAT_BORSTAT, gAmHalResetStatus);
psStatus->bSWPORStat = _FLD2VAL(RSTGEN_STAT_SWRSTAT, gAmHalResetStatus);
psStatus->bSWPOIStat = _FLD2VAL(RSTGEN_STAT_POIRSTAT, gAmHalResetStatus);
psStatus->bDBGRStat = _FLD2VAL(RSTGEN_STAT_DBGRSTAT, gAmHalResetStatus);
psStatus->bWDTStat = _FLD2VAL(RSTGEN_STAT_WDRSTAT, gAmHalResetStatus);
psStatus->bBOUnregStat = _FLD2VAL(RSTGEN_STAT_BOUSTAT, gAmHalResetStatus);
psStatus->bBOCOREStat = _FLD2VAL(RSTGEN_STAT_BOCSTAT, gAmHalResetStatus);
psStatus->bBOMEMStat = _FLD2VAL(RSTGEN_STAT_BOFSTAT, gAmHalResetStatus);
psStatus->bBOBLEStat = _FLD2VAL(RSTGEN_STAT_BOBSTAT, gAmHalResetStatus);
//
// Return status.
// If the Reset Status is 0 - this implies application did not capture the snapshot
// before deepsleep, and hence the result is invalid
//
return (gAmHalResetStatus ? AM_HAL_STATUS_SUCCESS : AM_HAL_STATUS_FAIL);
} // am_hal_reset_status_get()
//*****************************************************************************
//
//! @brief Enable selected RSTGEN Interrupts.
//!
//! Use this function to enable the reset generator interrupts.
//!
//! @param ui32IntMask - One or more of the following bits, any of which can
//! be ORed together.
//! AM_HAL_RESET_INTERRUPT_BODH
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
uint32_t
am_hal_reset_interrupt_enable(uint32_t ui32IntMask)
{
AM_CRITICAL_BEGIN
RSTGEN->INTEN |= ui32IntMask;
AM_CRITICAL_END
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_reset_interrupt_enable()
//*****************************************************************************
//
// am_hal_reset_interrupt_disable()
// Disable selected RSTGEN Interrupts.
//
//*****************************************************************************
uint32_t
am_hal_reset_interrupt_disable(uint32_t ui32IntMask)
{
AM_CRITICAL_BEGIN
RSTGEN->INTEN &= ~ui32IntMask;
AM_CRITICAL_END
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_reset_interrupt_disable()
//*****************************************************************************
//
// am_hal_reset_interrupt_clear()
// Reset generator interrupt clear
//
//*****************************************************************************
uint32_t
am_hal_reset_interrupt_clear(uint32_t ui32IntMask)
{
RSTGEN->INTEN = ui32IntMask;
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_reset_interrupt_clear()
//*****************************************************************************
//
// am_hal_reset_interrupt_status_get()
// Get interrupt status of reset generator.
//
//*****************************************************************************
uint32_t
am_hal_reset_interrupt_status_get(bool bEnabledOnly,
uint32_t *pui32IntStatus)
{
if ( pui32IntStatus == NULL )
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Retrieve the reset generator status bits
//
*pui32IntStatus = RSTGEN->INTSTAT;
//
// Return success status.
//
return AM_HAL_STATUS_SUCCESS;
} // am_hal_reset_interrupt_status_get()
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,307 @@
//*****************************************************************************
//
// am_hal_reset.h
//! @file
//!
//! @brief Hardware abstraction layer for the Reset Generator module.
//!
//! @addtogroup rstgen3 Reset Generator (RSTGEN)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_RSTGEN_H
#define AM_HAL_RSTGEN_H
#ifdef __cplusplus
extern "C"
{
#endif
//
// Designate this peripheral.
//
#define AM_APOLLO3_RESET 1
//*****************************************************************************
//
// RESET specific definitions.
//
//*****************************************************************************
//**************************************
//! Reset Generator configuration values
//**************************************
typedef enum
{
AM_HAL_RESET_BROWNOUT_HIGH_ENABLE,
AM_HAL_RESET_WDT_RESET_ENABLE,
AM_HAL_RESET_BROWNOUT_HIGH_DISABLE,
AM_HAL_RESET_WDT_RESET_DISABLE
} am_hal_reset_configure_e;
//**************************************
//! Reset Generator control operations
//**************************************
typedef enum
{
AM_HAL_RESET_CONTROL_SWPOR,
AM_HAL_RESET_CONTROL_SWPOI,
AM_HAL_RESET_CONTROL_STATUSCLEAR,
AM_HAL_RESET_CONTROL_TPIU_RESET
} am_hal_reset_control_e;
//**************************************
//! Reset Generator status bits
//**************************************
typedef enum
{
AM_HAL_RESET_STATUS_EXTERNAL = RSTGEN_STAT_EXRSTAT_Msk,
AM_HAL_RESET_STATUS_POR = RSTGEN_STAT_PORSTAT_Msk,
AM_HAL_RESET_STATUS_BOD = RSTGEN_STAT_BORSTAT_Msk,
AM_HAL_RESET_STATUS_SWPOR = RSTGEN_STAT_SWRSTAT_Msk,
AM_HAL_RESET_STATUS_SWPOI = RSTGEN_STAT_POIRSTAT_Msk,
AM_HAL_RESET_STATUS_DEBUGGER = RSTGEN_STAT_DBGRSTAT_Msk,
AM_HAL_RESET_STATUS_WDT = RSTGEN_STAT_WDRSTAT_Msk,
AM_HAL_RESET_STATUS_BOUNREG = RSTGEN_STAT_BOUSTAT_Msk,
AM_HAL_RESET_STATUS_BOCORE = RSTGEN_STAT_BOCSTAT_Msk,
AM_HAL_RESET_STATUS_BOMEM = RSTGEN_STAT_BOFSTAT_Msk,
AM_HAL_RESET_STATUS_BOBLE = RSTGEN_STAT_BOBSTAT_Msk
} am_hal_reset_status_e;
//**************************************
//! RESET status structure
//**************************************
typedef struct
{
am_hal_reset_status_e
eStatus; // Return all status bits from RSTGEN.STAT
bool bEXTStat; // External reset
bool bPORStat; // Power-On reset
bool bBODStat; // Brown-Out reset
bool bSWPORStat; // SW Power-On reset or AIRCR reset
bool bSWPOIStat; // SW Power On Initialization reset
bool bDBGRStat; // Debugger reset
bool bWDTStat; // Watch Dog Timer reset
bool bBOUnregStat; // Unregulated Supply Brownout event
bool bBOCOREStat; // Core Regulator Brownout event
bool bBOMEMStat; // Memory Regulator Brownout event
bool bBOBLEStat; // BLE/Burst Regulator Brownout event
} am_hal_reset_status_t;
//
// Define interrupt bit(s)
//
#define AM_HAL_RESET_INTERRUPT_BODH RSTGEN_INTEN_BODH_Msk
// Global variable used to capture the reset status
extern uint32_t gAmHalResetStatus;
//*****************************************************************************
//
//! @brief Enable and configure the Reset controller.
//!
//! This function will configure the specified reset conditions.
//!
//! @param eConfigure - One of configuration enumerations.
//! AM_HAL_RESET_BROWNOUT_HIGH_ENABLE
//! AM_HAL_RESET_WDT_RESET_ENABLE
//! AM_HAL_RESET_BROWNOUT_HIGH_DISABLE
//! AM_HAL_RESET_WDT_RESET_DISABLE
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_reset_configure(am_hal_reset_configure_e eConfigure);
//*****************************************************************************
//
//! @brief Reset generator functions.
//!
//! This function will perform various reset functions including assertion
//! of software resets.
//!
//! @param eControl - One of the control enumerations.
//! AM_HAL_RESET_CONTROL_SWPOR - power on reset, which results in a reset of
//! all blocks except for registers in clock gen, RTC, stimer, PMU.
//! Equivalent to the reset state obtained by a hardware reset, use of
//! the ARM AIRCR (Application Interrupt and Reset Control Register)
//! core register, debugger reset, watchdog timer expiration, or
//! brown-out event.
//! AM_HAL_RESET_CONTROL_SWPOI - power on initialization, which results in a
//! reset of all blocks except for registers in clock gen, RTC, stimer.
//! The POI reset level is required in order to enable configuration
//! changes such as memory protection.
//! AM_HAL_RESET_CONTROL_STATUSCLEAR - Clear the entire STATUS register.
//! All reset status register bits are cleared.
//! AM_HAL_RESET_CONTROL_TPIU - Reset the TPIU.
//!
//! @return status - generic or interface specific status.
//! When resetting the chip (SWPOR or SWPOI), the function will obviously
//! not return to the caller.
//
//*****************************************************************************
extern uint32_t am_hal_reset_control(am_hal_reset_control_e eControl,
void *pArgs);
//*****************************************************************************
//
//! @brief Return status of the reset generator.
//!
//! This function will get the status bits from the reset generator.
//! The status value shows the type of reset(s) that have occurred since power
//! on
//! Application MUST call this API at least once before going to deepsleep
//! Otherwise this API will not provide correct reset status
//!
//! @param psStatus - Pointer to a data structure to receive the status
//! information. Most members of the structure are booleans that receive
//! the status of a particular bit.
//!
//! The eStatus member, however, returns a bitmask of one or more of the
//! following values:
//! AM_HAL_RESET_STATUS_EXTERNAL
//! AM_HAL_RESET_STATUS_POR
//! AM_HAL_RESET_STATUS_BOD
//! AM_HAL_RESET_STATUS_SWPOR
//! AM_HAL_RESET_STATUS_SWPOI
//! AM_HAL_RESET_STATUS_DEBUGGER
//! AM_HAL_RESET_STATUS_WDT
//! AM_HAL_RESET_STATUS_BOUNREG
//! AM_HAL_RESET_STATUS_BOCORE
//! AM_HAL_RESET_STATUS_BOMEM
//! AM_HAL_RESET_STATUS_BOBLE
//!
//! @return status. If the API was never called before a valid reset status
//! could be captured, AM_HAL_STATUS_FAIL is returned.
//! Otherwise AM_HAL_STATUS_SUCCESS implies valid reset status returned
//
//*****************************************************************************
extern uint32_t am_hal_reset_status_get(am_hal_reset_status_t *psStatus);
//*****************************************************************************
//
//! @brief Static reset of the TPIU.
//!
//! Use this function to reset the TPIU.
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_reset_tpiu_reset(void);
//*****************************************************************************
//
//! @brief Enable selected RSTGEN Interrupts.
//!
//! Use this function to enable the interrupts.
//!
//! @param ui32IntMask - One or more of the following bits, any of which can
//! be ORed together.
//! AM_HAL_RESET_INTERRUPT_BODH
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_reset_interrupt_enable(uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Disable selected RSTGEN Interrupts.
//!
//! Use this function to disable the RSTGEN interrupts.
//!
//! @param ui32IntMask - One or more of the following bits, any of which can
//! be ORed together.
//! AM_HAL_RESET_INTERRUPT_BODH
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_reset_interrupt_disable(uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Reset generator interrupt clear
//!
//! @param ui32IntMask - Interrupt mask.
//!
//! This function clears the reset generator interrupts.
//!
//! @param ui32IntMask - One or more of the following bits, any of which can
//! be ORed together.
//! AM_HAL_RESET_INTERRUPT_BODH
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_reset_interrupt_clear(uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Get interrupt status of reset generator.
//!
//! This function returns the interrupt status for the reset generator.
//!
//! @param pui32IntStatus - ptr to uint32_t to return the interrupt status.
//!
//! The following are valid status bits.
//! AM_HAL_RESET_INTERRUPT_BODH
//!
//! @return status - generic or interface specific status.
//
//*****************************************************************************
extern uint32_t am_hal_reset_interrupt_status_get(bool bEnabledOnly,
uint32_t *pui32IntStatus);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_RSTGEN_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,650 @@
//*****************************************************************************
//
// am_hal_rtc.c
//! @file
//!
//! @brief Functions for interfacing with the Real-Time Clock (RTC).
//!
//! @addtogroup rtc3 Real-Time Clock (RTC)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Converts a Binary Coded Decimal (BCD) byte to its Decimal form.
//
//*****************************************************************************
static uint8_t
bcd_to_dec(uint8_t ui8BCDByte)
{
return (((ui8BCDByte & 0xF0) >> 4) * 10) + (ui8BCDByte & 0x0F);
}
//*****************************************************************************
//
// Converts a Decimal byte to its Binary Coded Decimal (BCD) form.
//
//*****************************************************************************
static uint8_t
dec_to_bcd(uint8_t ui8DecimalByte)
{
return (((ui8DecimalByte / 10) << 4) | (ui8DecimalByte % 10));
}
//*****************************************************************************
//
//! @brief Selects the clock source for the RTC.
//!
//! @param ui32OSC the clock source for the RTC.
//!
//! This function selects the clock source for the RTC.
//!
//! Valid values for ui32OSC are:
//!
//! AM_HAL_RTC_OSC_XT
//!
//! @return None
//!
//! @note After selection of the RTC oscillator, a 2 second delay occurs before
//! the new setting is reflected in status. Therefore the CLKGEN.STATUS.OMODE
//! bit will not reflect the new status until after the 2s wait period.
//!
//
//*****************************************************************************
void
am_hal_rtc_osc_select(uint32_t ui32OSC)
{
if ( ui32OSC == AM_HAL_RTC_OSC_XT )
{
// Clear bit to 0 for XTAL
CLKGEN->OCTRL &= ~CLKGEN_OCTRL_OSEL_Msk;
}
}
//*****************************************************************************
//
//! @brief Enable/Start the RTC oscillator.
//!
//! Starts the RTC oscillator.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_osc_enable(void)
{
//
// Start the RTC Oscillator.
//
RTC->RTCCTL_b.RSTOP = 0;
}
//*****************************************************************************
//
//! @brief Disable/Stop the RTC oscillator.
//!
//! Stops the RTC oscillator.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_osc_disable(void)
{
//
// Stop the RTC Oscillator.
//
RTC->RTCCTL_b.RSTOP = 1;
}
//*****************************************************************************
//
//! @brief Configures the RTC for 12 or 24 hour time keeping.
//!
//! @param b12Hour - A 'true' configures the RTC for 12 hour time keeping.
//!
//! Configures the RTC for 12 (true) or 24 (false) hour time keeping.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_time_12hour(bool b12Hour)
{
//
// Set the 12/24 hour bit.
//
RTC->RTCCTL_b.HR1224 = b12Hour;
}
//*****************************************************************************
//
//! @brief Enable selected RTC interrupts.
//!
//! @param ui32Interrupt - desired interrupts
//!
//! Enables the RTC interrupts.
//!
//! ui32Interrupt should be the following:
//!
//! AM_HAL_RTC_INT_ALM
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_int_enable(uint32_t ui32Interrupt)
{
//
// Enable the interrupts.
//
RTC->INTEN |= ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Return the enabled RTC interrupts.
//!
//! Returns the enabled RTC interrupts.
//!
//! @return enabled RTC interrupts. Return is 0 or:
//!
//! AM_HAL_RTC_INT_ALM
//
//*****************************************************************************
uint32_t
am_hal_rtc_int_enable_get(void)
{
//
// Read the RTC interrupt enable register, and return its contents.
//
return RTC->INTEN;
}
//*****************************************************************************
//
//! @brief Disable selected RTC interrupts.
//!
//! @param ui32Interrupt - desired interrupts
//!
//! Disables the RTC interrupts.
//!
//! ui32Interrupt should be the following:
//!
//! AM_HAL_RTC_INT_ALM
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_int_disable(uint32_t ui32Interrupt)
{
//
// Disable the interrupts.
//
RTC->INTEN &= ~ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Sets the selected RTC interrupts.
//!
//! @param ui32Interrupt - desired interrupts
//!
//! Sets the RTC interrupts causing them to immediately trigger.
//!
//! ui32Interrupt should be the following:
//!
//! AM_HAL_RTC_INT_ALM
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_int_set(uint32_t ui32Interrupt)
{
//
// Set the interrupts.
//
RTC->INTSET = ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Clear selected RTC interrupts.
//!
//! @param ui32Interrupt - desired interrupts
//!
//! Clears the RTC interrupts.
//!
//! ui32Interrupt should be the following:
//!
//! AM_HAL_RTC_INT_ALM
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_int_clear(uint32_t ui32Interrupt)
{
//
// Clear the interrupts.
//
RTC->INTCLR = ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Returns the RTC interrupt status.
//!
//! @param bEnabledOnly - return the status of only the enabled interrupts.
//!
//! Returns the RTC interrupt status.
//!
//! @return Bitwise representation of the current interrupt status.
//!
//! The return value will be 0 or the following:
//!
//! AM_HAL_RTC_INT_ALM
//
//*****************************************************************************
uint32_t
am_hal_rtc_int_status_get(bool bEnabledOnly)
{
//
// Get the interrupt status.
//
if ( bEnabledOnly )
{
uint32_t u32RetVal;
u32RetVal = RTC->INTSTAT;
u32RetVal &= RTC->INTEN;
return u32RetVal & (AM_HAL_RTC_INT_ALM);
}
else
{
return RTC->INTSTAT & (AM_HAL_RTC_INT_ALM);
}
}
//*****************************************************************************
//
//! @brief Set the Real Time Clock counter registers.
//!
//! @param *pTime - A pointer to the time structure.
//!
//! Sets the RTC counter registers to the supplied values.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_time_set(am_hal_rtc_time_t *pTime)
{
//
// Enable writing to the counters.
//
RTC->RTCCTL_b.WRTC = RTC_RTCCTL_WRTC_EN;
//
// Write the RTCLOW register.
//
RTC->CTRLOW =
_VAL2FLD(RTC_CTRLOW_CTRHR, dec_to_bcd(pTime->ui32Hour)) |
_VAL2FLD(RTC_CTRLOW_CTRMIN, dec_to_bcd(pTime->ui32Minute)) |
_VAL2FLD(RTC_CTRLOW_CTRSEC, dec_to_bcd(pTime->ui32Second)) |
_VAL2FLD(RTC_CTRLOW_CTR100, dec_to_bcd(pTime->ui32Hundredths));
//
// Write the RTCUP register.
//
RTC->CTRUP =
_VAL2FLD(RTC_CTRUP_CEB, (pTime->ui32CenturyEnable)) |
_VAL2FLD(RTC_CTRUP_CB, (pTime->ui32Century)) |
_VAL2FLD(RTC_CTRUP_CTRWKDY, (pTime->ui32Weekday)) |
_VAL2FLD(RTC_CTRUP_CTRYR, dec_to_bcd((pTime->ui32Year))) |
_VAL2FLD(RTC_CTRUP_CTRMO, dec_to_bcd((pTime->ui32Month))) |
_VAL2FLD(RTC_CTRUP_CTRDATE, dec_to_bcd((pTime->ui32DayOfMonth)));
//
// Disable writing to the counters.
//
RTC->RTCCTL_b.WRTC = RTC_RTCCTL_WRTC_DIS;
}
//*****************************************************************************
//
//! @brief Get the Real Time Clock current time.
//!
//! @param *pTime - A pointer to the time structure to store the current time.
//!
//! Gets the RTC's current time
//!
//! @return 0 for success and 1 for error.
//
//*****************************************************************************
uint32_t
am_hal_rtc_time_get(am_hal_rtc_time_t *pTime)
{
uint32_t ui32RTCLow, ui32RTCUp, ui32Value;
//
// Read the upper and lower RTC registers.
//
ui32RTCLow = RTC->CTRLOW;
ui32RTCUp = RTC->CTRUP;
//
// Break out the lower word.
//
ui32Value =
((ui32RTCLow & RTC_CTRLOW_CTRHR_Msk) >> RTC_CTRLOW_CTRHR_Pos);
pTime->ui32Hour = bcd_to_dec(ui32Value);
ui32Value =
((ui32RTCLow & RTC_CTRLOW_CTRMIN_Msk) >> RTC_CTRLOW_CTRMIN_Pos);
pTime->ui32Minute = bcd_to_dec(ui32Value);
ui32Value =
((ui32RTCLow & RTC_CTRLOW_CTRSEC_Msk) >> RTC_CTRLOW_CTRSEC_Pos);
pTime->ui32Second = bcd_to_dec(ui32Value);
ui32Value =
((ui32RTCLow & RTC_CTRLOW_CTR100_Msk) >> RTC_CTRLOW_CTR100_Pos);
pTime->ui32Hundredths = bcd_to_dec(ui32Value);
//
// Break out the upper word.
//
pTime->ui32ReadError =
((ui32RTCUp & RTC_CTRUP_CTERR_Msk) >> RTC_CTRUP_CTERR_Pos);
pTime->ui32CenturyEnable =
((ui32RTCUp & RTC_CTRUP_CEB_Msk) >> RTC_CTRUP_CEB_Pos);
pTime->ui32Century =
((ui32RTCUp & RTC_CTRUP_CB_Msk) >> RTC_CTRUP_CB_Pos);
ui32Value =
((ui32RTCUp & RTC_CTRUP_CTRWKDY_Msk) >> RTC_CTRUP_CTRWKDY_Pos);
pTime->ui32Weekday = bcd_to_dec(ui32Value);
ui32Value =
((ui32RTCUp & RTC_CTRUP_CTRYR_Msk) >> RTC_CTRUP_CTRYR_Pos);
pTime->ui32Year = bcd_to_dec(ui32Value);
ui32Value =
((ui32RTCUp & RTC_CTRUP_CTRMO_Msk) >> RTC_CTRUP_CTRMO_Pos);
pTime->ui32Month = bcd_to_dec(ui32Value);
ui32Value =
((ui32RTCUp & RTC_CTRUP_CTRDATE_Msk) >> RTC_CTRUP_CTRDATE_Pos);
pTime->ui32DayOfMonth = bcd_to_dec(ui32Value);
//
// Was there a read error?
//
if (pTime->ui32ReadError)
{
return 1;
}
else
{
return 0;
}
}
//*****************************************************************************
//
//! @brief Sets the alarm repeat interval.
//!
//! @param ui32RepeatInterval the desired repeat interval.
//!
//! Sets the alarm repeat interval.
//!
//! Valid values for ui32RepeatInterval:
//!
//! AM_HAL_RTC_ALM_RPT_DIS
//! AM_HAL_RTC_ALM_RPT_YR
//! AM_HAL_RTC_ALM_RPT_MTH
//! AM_HAL_RTC_ALM_RPT_WK
//! AM_HAL_RTC_ALM_RPT_DAY
//! AM_HAL_RTC_ALM_RPT_HR
//! AM_HAL_RTC_ALM_RPT_MIN
//! AM_HAL_RTC_ALM_RPT_SEC
//! AM_HAL_RTC_ALM_RPT_10TH
//! AM_HAL_RTC_ALM_RPT_100TH
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_alarm_interval_set(uint32_t ui32RepeatInterval)
{
uint32_t ui32RptInt, ui32Alm100, ui32Value;
switch(ui32RepeatInterval)
{
//
// If repeat every 10th set RPT and ALM100 field accordinly
//
case AM_HAL_RTC_ALM_RPT_10TH:
ui32RptInt = AM_HAL_RTC_ALM_RPT_SEC;
ui32Alm100 = AM_HAL_RTC_ALM100_10TH;
break;
//
// If repeat every 100th set RPT and ALM100 field accordinly
//
case AM_HAL_RTC_ALM_RPT_100TH:
ui32RptInt = AM_HAL_RTC_ALM_RPT_SEC;
ui32Alm100 = AM_HAL_RTC_ALM100_100TH;
break;
//
// Otherwise set RPT as value passed. ALM100 values need to be 0xnn
// in this setting where n = 0-9.
//
default:
//
// Get the current value of the ALM100 field.
//
ui32Value = RTC->ALMLOW_b.ALM100;
//
// If ALM100 was previous EVERY_10TH or EVERY_100TH reset to zero
// otherwise keep previous setting.
//
ui32Alm100 = ui32Value >= 0xF0 ? 0 : ui32Value;
//
// Set RPT value to value passed.
//
ui32RptInt = ui32RepeatInterval;
break;
}
//
// Write the interval to the register.
//
RTC->RTCCTL_b.RPT = ui32RptInt;
//
// Write the Alarm 100 bits in the ALM100 register.
//
RTC->ALMLOW_b.ALM100 = ui32Alm100;
}
//*****************************************************************************
//
//! @brief Sets the RTC's Alarm.
//!
//! @param *pTime - A pointer to the time structure.
//! @param ui32RepeatInterval - the desired alarm repeat interval.
//!
//! Set the Real Time Clock Alarm Parameters.
//!
//! Valid values for ui32RepeatInterval:
//!
//! AM_HAL_RTC_ALM_RPT_DIS
//! AM_HAL_RTC_ALM_RPT_YR
//! AM_HAL_RTC_ALM_RPT_MTH
//! AM_HAL_RTC_ALM_RPT_WK
//! AM_HAL_RTC_ALM_RPT_DAY
//! AM_HAL_RTC_ALM_RPT_HR
//! AM_HAL_RTC_ALM_RPT_MIN
//! AM_HAL_RTC_ALM_RPT_SEC
//! AM_HAL_RTC_ALM_RPT_10TH
//! AM_HAL_RTC_ALM_RPT_EVERY_100TH
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_alarm_set(am_hal_rtc_time_t *pTime, uint32_t ui32RepeatInterval)
{
uint8_t ui8Value = 0;
//
// Write the interval to the register.
//
RTC->RTCCTL |= _VAL2FLD(RTC_RTCCTL_RPT, (ui32RepeatInterval > 0x7 ? 0x7 : ui32RepeatInterval));
//
// Check if the interval is 10th or every 100th and track it in ui8Value.
//
if (ui32RepeatInterval == AM_HAL_RTC_ALM_RPT_10TH)
{
ui8Value = 0xF0;
}
else if (ui32RepeatInterval == AM_HAL_RTC_ALM_RPT_100TH)
{
ui8Value = 0xFF;
}
//
// Write the ALMUP register.
//
RTC->ALMUP =
_VAL2FLD(RTC_ALMUP_ALMWKDY, (pTime->ui32Weekday)) |
_VAL2FLD(RTC_ALMUP_ALMMO, dec_to_bcd((pTime->ui32Month))) |
_VAL2FLD(RTC_ALMUP_ALMDATE, dec_to_bcd((pTime->ui32DayOfMonth)));
//
// Write the ALMLOW register.
//
RTC->ALMLOW =
_VAL2FLD(RTC_ALMLOW_ALMHR, dec_to_bcd(pTime->ui32Hour)) |
_VAL2FLD(RTC_ALMLOW_ALMMIN, dec_to_bcd(pTime->ui32Minute)) |
_VAL2FLD(RTC_ALMLOW_ALMSEC, dec_to_bcd(pTime->ui32Second)) |
_VAL2FLD(RTC_ALMLOW_ALM100, dec_to_bcd(pTime->ui32Hundredths) | ui8Value);
}
//*****************************************************************************
//
//! @brief Get the Real Time Clock Alarm Parameters
//!
//! @param *pTime - A pointer to the time structure to store the current alarm.
//!
//! Gets the RTC's Alarm time
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_rtc_alarm_get(am_hal_rtc_time_t *pTime)
{
uint32_t ui32ALMLow, ui32ALMUp, ui32Value;
//
// Read the upper and lower RTC registers.
//
ui32ALMLow = RTC->ALMLOW;
ui32ALMUp = RTC->ALMUP;
//
// Break out the lower word.
//
ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALMHR_Msk) >> RTC_ALMLOW_ALMHR_Pos);
pTime->ui32Hour = bcd_to_dec(ui32Value);
ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALMMIN_Msk) >> RTC_ALMLOW_ALMMIN_Pos);
pTime->ui32Minute = bcd_to_dec(ui32Value);
ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALMSEC_Msk) >> RTC_ALMLOW_ALMSEC_Pos);
pTime->ui32Second = bcd_to_dec(ui32Value);
ui32Value = ((ui32ALMLow & RTC_ALMLOW_ALM100_Msk) >> RTC_ALMLOW_ALM100_Pos);
pTime->ui32Hundredths = bcd_to_dec(ui32Value);
//
// Break out the upper word.
//
pTime->ui32ReadError = 0;
pTime->ui32CenturyEnable = 0;
pTime->ui32Century = 0;
ui32Value = ((ui32ALMUp & RTC_ALMUP_ALMWKDY_Msk) >> RTC_ALMUP_ALMWKDY_Pos);
pTime->ui32Weekday = bcd_to_dec(ui32Value);
pTime->ui32Year = 0;
ui32Value = ((ui32ALMUp & RTC_ALMUP_ALMMO_Msk) >> RTC_ALMUP_ALMMO_Pos);
pTime->ui32Month = bcd_to_dec(ui32Value);
ui32Value = ((ui32ALMUp & RTC_ALMUP_ALMDATE_Msk) >> RTC_ALMUP_ALMDATE_Pos);
pTime->ui32DayOfMonth = bcd_to_dec(ui32Value);
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,184 @@
//*****************************************************************************
//
// am_hal_rtc.h
//! @file
//!
//! @brief Functions for interfacing and accessing the Real-Time Clock (RTC).
//!
//! @addtogroup rtc3 Real-Time Clock (RTC)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_RTC_H
#define AM_HAL_RTC_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! @name OSC Start and Stop
//! @brief OSC Start and Stop defines.
//!
//! OSC Start and Stop defines to be used with \e am_hal_clkgen_osc_x().
//! @{
//
//*****************************************************************************
#define AM_HAL_RTC_OSC_XT 0x0
//! @}
//*****************************************************************************
//
//! @name RTC Interrupts
//! @brief Macro definitions for RTC interrupt status bits.
//!
//! These macros correspond to the bits in the RTC interrupt status register.
//! They may be used with any of the \e am_hal_rtc_int_x() functions.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_RTC_INT_ALM RTC_INTEN_ALM_Msk
//! @}
//*****************************************************************************
//
//! @name RTC Alarm Repeat Interval.
//! @brief Macro definitions for the RTC alarm repeat interval.
//!
//! These macros correspond to the RPT bits in the RTCCTL register.
//! They may be used with the \e am_hal_rtc_alarm_interval_set() function.
//!
//! Note: AM_HAL_RTC_ALM_RPT_10TH and AM_HAL_RTC_ALM_RPT_100TH do not
//! correspond to the RPT bits but are used in conjunction with setting the
//! ALM100 bits in the ALMLOW register.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_RTC_ALM_RPT_DIS 0x0
#define AM_HAL_RTC_ALM_RPT_YR 0x1
#define AM_HAL_RTC_ALM_RPT_MTH 0x2
#define AM_HAL_RTC_ALM_RPT_WK 0x3
#define AM_HAL_RTC_ALM_RPT_DAY 0x4
#define AM_HAL_RTC_ALM_RPT_HR 0x5
#define AM_HAL_RTC_ALM_RPT_MIN 0x6
#define AM_HAL_RTC_ALM_RPT_SEC 0x7
#define AM_HAL_RTC_ALM_RPT_10TH 0x8
#define AM_HAL_RTC_ALM_RPT_100TH 0x9
//! @}
//*****************************************************************************
//
//! @name RTC Alarm 100 Interval.
//! @brief Macro definitions for the RTC alarm ms intervals.
//!
//! These macros are used inside the #am_hal_rtc_alarm_interval_set function
//! when 10ms and 100ms repeated alarm intervals are desired.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_RTC_ALM100_DEFAULT 0x00
#define AM_HAL_RTC_ALM100_10TH 0xF0
#define AM_HAL_RTC_ALM100_100TH 0xFF
//! @}
//*****************************************************************************
//
//! @brief The basic time structure used by the HAL for RTC interaction.
//!
//! All values are positive whole numbers. The HAL routines convert back and
//! forth to BCD.
//
//*****************************************************************************
typedef struct am_hal_rtc_time_struct
{
uint32_t ui32ReadError;
uint32_t ui32CenturyEnable;
uint32_t ui32Weekday;
uint32_t ui32Century;
uint32_t ui32Year;
uint32_t ui32Month;
uint32_t ui32DayOfMonth;
uint32_t ui32Hour;
uint32_t ui32Minute;
uint32_t ui32Second;
uint32_t ui32Hundredths;
}am_hal_rtc_time_t;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_rtc_osc_select(uint32_t ui32OSC);
extern void am_hal_rtc_osc_enable(void);
extern void am_hal_rtc_osc_disable(void);
extern void am_hal_rtc_time_12hour(bool b12Hour);
extern void am_hal_rtc_time_set(am_hal_rtc_time_t *pTime);
extern uint32_t am_hal_rtc_time_get(am_hal_rtc_time_t *pTime);
extern void am_hal_rtc_alarm_interval_set(uint32_t ui32RepeatInterval);
extern void am_hal_rtc_alarm_set(am_hal_rtc_time_t *pTime,
uint32_t ui32RepeatInterval);
extern void am_hal_rtc_alarm_get(am_hal_rtc_time_t *pTime);
extern void am_hal_rtc_int_enable(uint32_t ui32Interrupt);
extern uint32_t am_hal_rtc_int_enable_get(void);
extern void am_hal_rtc_int_disable(uint32_t ui32Interrupt);
extern void am_hal_rtc_int_clear(uint32_t ui32Interrupt);
extern void am_hal_rtc_int_set(uint32_t ui32Interrupt);
extern uint32_t am_hal_rtc_int_status_get(bool bEnabledOnly);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_RTC_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,659 @@
//*****************************************************************************
//
// am_hal_scard.h
//! @file
//!
//! @brief Functions for accessing and configuring the SCARD.
//!
//! @addtogroup scard3
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_SCARD_H
#define AM_HAL_SCARD_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// CMSIS-style macro for handling a variable SCARD module number.
//
//*****************************************************************************
#define SCARDn(n) ((SCARD_Type*)(SCARD_BASE + (n * (SCARD_BASE - SCARD_BASE))))
//*****************************************************************************
//
// Initial character TS
//
//*****************************************************************************
#define AM_HAL_SCARD_DIR_MSB 0x3F //(H)LHHL LLL LLH, state L encodes value 1, msb
#define AM_HAL_SCARD_DIR_LSB 0x3B //(H)LHHL HHH LLH, state H encodes value 1, lsb
//*****************************************************************************
//
// Informations provided by T0
//
//*****************************************************************************
#define AM_HAL_SCARD_T0_BIT_TA1_MASK (1 << 4)
#define AM_HAL_SCARD_T0_BIT_TB1_MASK (1 << 5)
#define AM_HAL_SCARD_T0_BIT_TC1_MASK (1 << 6)
#define AM_HAL_SCARD_T0_BIT_TD1_MASK (1 << 7)
#define AM_HAL_SCARD_TA1_PRESENCE(T0) (((T0) & AM_HAL_SCARD_T0_BIT_TA1_MASK) == AM_HAL_SCARD_T0_BIT_TA1_MASK)
#define AM_HAL_SCARD_TB1_PRESENCE(T0) (((T0) & AM_HAL_SCARD_T0_BIT_TB1_MASK) == AM_HAL_SCARD_T0_BIT_TB1_MASK)
#define AM_HAL_SCARD_TC1_PRESENCE(T0) (((T0) & AM_HAL_SCARD_T0_BIT_TC1_MASK) == AM_HAL_SCARD_T0_BIT_TC1_MASK)
#define AM_HAL_SCARD_TD1_PRESENCE(T0) (((T0) & AM_HAL_SCARD_T0_BIT_TD1_MASK) == AM_HAL_SCARD_T0_BIT_TD1_MASK)
#define AM_HAL_SCARD_HISTORY_LEN(T0) ((T0)&0x0F)
//*****************************************************************************
//
// Protocol type T
//
//*****************************************************************************
#define AM_HAL_SCARD_PROTOCOL_T0 0
#define AM_HAL_SCARD_PROTOCOL_T1 1
#define AM_HAL_SCARD_PROTOCOL_T15 15
#define AM_HAL_SCARD_PROTOCOL_DEFAULT AM_HAL_SCARD_PROTOCOL_T0
//*****************************************************************************
//
// Structure and content of PPS request and PPS confirm
//
//*****************************************************************************
#define AM_HAL_SCARD_CLA_PPS 0xFF
#define AM_HAL_SCARD_PPS1_PRESENCE(PPS0) (((PPS0) & (1 << 4)) == (1 << 4))
#define AM_HAL_SCARD_PPS2_PRESENCE(PPS0) (((PPS0) & (1 << 5)) == (1 << 5))
#define AM_HAL_SCARD_PPS3_PRESENCE(PPS0) (((PPS0) & (1 << 6)) == (1 << 6))
//*****************************************************************************
//
// Informations provided by TA1
//
//*****************************************************************************
#define AM_HAL_SCARD_FI(TA1) (((TA1) >> 4) & 0x0F)
#define AM_HAL_SCARD_DI(TA1) (((TA1) >> 0) & 0x0F)
#define AM_HAL_SCARD_FI_DI_DEFAULT 0x11
//*****************************************************************************
//
// Informations provided by TDi
//
//*****************************************************************************
#define AM_HAL_SCARD_TDi_BIT_TAiP1_MASK (1 << 4)
#define AM_HAL_SCARD_TDi_BIT_TBiP1_MASK (1 << 5)
#define AM_HAL_SCARD_TDi_BIT_TCiP1_MASK (1 << 6)
#define AM_HAL_SCARD_TDi_BIT_TDiP1_MASK (1 << 7)
#define AM_HAL_SCARD_TAiP1_PRESENCE(TDi) (((TDi) & AM_HAL_SCARD_TDi_BIT_TAiP1_MASK) == AM_HAL_SCARD_TDi_BIT_TAiP1_MASK)
#define AM_HAL_SCARD_TBiP1_PRESENCE(TDi) (((TDi) & AM_HAL_SCARD_TDi_BIT_TBiP1_MASK) == AM_HAL_SCARD_TDi_BIT_TBiP1_MASK)
#define AM_HAL_SCARD_TCiP1_PRESENCE(TDi) (((TDi) & AM_HAL_SCARD_TDi_BIT_TCiP1_MASK) == AM_HAL_SCARD_TDi_BIT_TCiP1_MASK)
#define AM_HAL_SCARD_TDiP1_PRESENCE(TDi) (((TDi) & AM_HAL_SCARD_TDi_BIT_TDiP1_MASK) == AM_HAL_SCARD_TDi_BIT_TDiP1_MASK)
#define AM_HAL_SCARD_PROTOCOL_TYPE(TDi) ((TDi) & 0x0F)
#define AM_HAL_SCARD_MAX_ATR_LENGTH 33 //1+32
#define AM_HAL_SCARD_MAX_PPS_LENGTH 6
#define AM_HAL_SCARD_APDU_HEADER_LENGTH 5
#define AM_HAL_SCARD_SW_LENGTH 2
//*****************************************************************************
//
// TypeDefs
//
//*****************************************************************************
typedef struct
{
uint8_t pps0;
uint8_t pps1;
uint8_t pps2;
uint8_t pps3;
}am_hal_scard_pps_t;
typedef struct
{
uint8_t cla;
uint8_t ins;
uint8_t p1;
uint8_t p2;
uint8_t p3;
}am_hal_scard_header_t;
typedef struct
{
am_hal_scard_header_t header;
uint8_t data[256];
}am_hal_scard_tpdu_t;
typedef union
{
struct
{
uint8_t s0;
uint8_t s1;
}element;
uint16_t entirety;
}am_hal_scard_sw_t;
typedef enum
{
AM_HAL_SCARD_CONV_AUTO,
AM_HAL_SCARD_CONV_LSB_0X3B,
AM_HAL_SCARD_CONV_MSB_0X3F
}am_hal_scard_cardformat_e;
typedef enum
{
AM_HAL_SCARD_EVEN,
AM_HAL_SCARD_ODD
}am_hal_scard_parity_e;
typedef enum
{
AM_HAL_SCARD_APDU_CLA,
AM_HAL_SCARD_APDU_INS,
AM_HAL_SCARD_APDU_P1,
AM_HAL_SCARD_APDU_P2,
AM_HAL_SCARD_APDU_LC
}am_hal_scard_apdu_header_e;
//*****************************************************************************
//
// Definitions
//
//*****************************************************************************
#define SCARD_RST_LOW_TIME 42000
#define AM_HAL_SCARD_PARITY_ENABLE 0x10
//*****************************************************************************
//
// SCARD configuration options.
//
//*****************************************************************************
typedef struct
{
//
// Standard SCARD options.
//
uint32_t ui32Fidi;
uint32_t ui32Protocol;
uint32_t ui32Direction;
uint32_t ui32Parity;
uint32_t ui32GuardTime;
uint32_t ui32ClkLevel;
//
// Timeouts
//
uint32_t ui32TxTimeout;
uint32_t ui32RxTimeout;
//
// Buffers
//
uint8_t *pui8TxBuffer;
uint32_t ui32TxBufferSize;
uint8_t *pui8RxBuffer;
uint32_t ui32RxBufferSize;
}
am_hal_scard_config_t;
typedef enum
{
AM_HAL_SCARD_REQ_ACTIVATE = 0,
AM_HAL_SCARD_REQ_DEACTIVATE,
AM_HAL_SCARD_REQ_BAUDRATE,
AM_HAL_SCARD_REQ_CARD_FORMAT,
AM_HAL_SCARD_REQ_PARITY,
AM_HAL_SCARD_REQ_PROTOCOL,
AM_HAL_SCARD_REQ_GUARDTIME,
AM_HAL_SCARD_REQ_CLK_START,
AM_HAL_SCARD_REQ_CLK_STOP,
AM_HAL_SCARD_REQ_MAX
}am_hal_scard_request_e;
//*****************************************************************************
//
// @brief SCARD transfer structure.
//
// This structure describes a SCARD transaction that can be performed by \e
// am_hal_scard_transfer()
//
//*****************************************************************************
typedef struct
{
//! Determines whether data should be read or written.
//!
//! Should be either AM_HAL_SCARD_WRITE or AM_HAL_SCARD_READ
uint32_t ui32Direction;
//! Pointer to data to be sent, or space to fill with received data.
uint8_t *pui8Data;
//! Number of bytes to send or receive.
uint32_t ui32NumBytes;
//! Timeout in milliseconds.
//!
//! Given a timeout value, the \e am_hal_scard_transfer() function will keep
//! trying to transfer data until either the number of bytes is satisfied,
//! or the time runs out. If provided with a value of zero, the transfer
//! function will only send as much data as it can immediately deal with.
//! If provided with a timeout value of \e AM_HAL_SCARD_WAIT_FOREVER, the
//! function will block until either the final "read" byte is received or
//! the final "write" byte is placed in the output buffer.
uint32_t ui32TimeoutMs;
//! Number of bytes successfully transferred.
uint32_t *pui32BytesTransferred;
}
am_hal_scard_transfer_t;
//*****************************************************************************
//
// Scard transfer options.
//
//*****************************************************************************
#define AM_HAL_SCARD_WRITE 1
#define AM_HAL_SCARD_READ 0
#define AM_HAL_SCARD_WAIT_MAX_TIME 0xFFFF
#define AM_HAL_SCARD_WAIT_FOREVER 0xFFFFFFFF
#define AM_HAL_SCARD_CLK_FREQ 3000000
//*****************************************************************************
//
// SCARD interrupts.
//
//*****************************************************************************
#define AM_HAL_SCARD_INT_FHFEN SCARD_IER_FHFEN_Msk
#define AM_HAL_SCARD_INT_FT2RENDEN SCARD_IER_FT2RENDEN_Msk
#define AM_HAL_SCARD_INT_PEEN SCARD_IER_PEEN_Msk
#define AM_HAL_SCARD_INT_OVREN SCARD_IER_OVREN_Msk
#define AM_HAL_SCARD_INT_FEREN SCARD_IER_FEREN_Msk
#define AM_HAL_SCARD_INT_TBERBFEN SCARD_IER_TBERBFEN_Msk
#define AM_HAL_SCARD_INT_FNEEN SCARD_IER_FNEEN_Msk
#define AM_HAL_SCARD_INT_SYNCENDEN SCARD_IER1_SYNCENDEN_Msk
#define AM_HAL_SCARD_INT_PRLEN SCARD_IER1_PRLEN_Msk
#define AM_HAL_SCARD_INT_ECNTOVEREN SCARD_IER1_ECNTOVEREN_Msk
#define AM_HAL_SCARD_INT_ALL 0xFFFFFFFF
//*****************************************************************************
//
//! @name SCARD Status Register
//! @brief Macro definitions for SCARD Status Register Bits.
//
//*****************************************************************************
#define AM_HAL_SCARD_SR_TX_EMPTY (_VAL2FLD(SCARD_SR_TBERBF, 1))
#define AM_HAL_SCARD_SR_RX_FULL (_VAL2FLD(SCARD_SR_TBERBF, 1))
#define AM_HAL_SCARD_SR_RX_HALF_FULL (_VAL2FLD(SCARD_SR_FHF, 1))
#define AM_HAL_SCARD_SR_RX_NOT_EMPTY (_VAL2FLD(SCARD_SR_FNE, 1))
#define AM_HAL_SCARD_SR_FT2REND (_VAL2FLD(SCARD_SR_FT2REND, 1))
#define AM_HAL_SCARD_SR_IDLE (_VAL2FLD(SCARD_SR1_IDLE, 1))
//*****************************************************************************
//
// SCC FIFO size for Apollo3.
//
//*****************************************************************************
#define AM_HAL_SCARD_FIFO_MAX 8
//*****************************************************************************
//
//! @brief Initialize the SCARD interface.
//!
//! @param ui32Module is the module number for the SCARD to initialize.
//! @param ppHandle is the location to write the SCARD handle.
//!
//! This function sets internal tracking variables associated with a specific
//! SCARD module. It should be the first SCARD API called for each SCARD module in
//! use. The handle can be used to interact with the SCARD
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_initialize(uint32_t ui32Module, void **ppHandle);
//*****************************************************************************
//
//! @brief Deinitialize the SCARD interface.
//!
//! @param pHandle is a previously initialized SCARD handle.
//!
//! This function effectively disables future calls to interact with the SCARD
//! refered to by \e pHandle. The user may call this function if SCARD operation
//! is no longer desired.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_deinitialize(void *pHandle);
//*****************************************************************************
//
//! @brief Change the power state of the SCARD module.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//! @param ePowerstate is the desired power state of the SCARD.
//! @parame bRetainState is a flag to ask the HAL to save SCARD registers.
//!
//! This function can be used to switch the power to the SCARD on or off. If \e
//! bRetainState is true during a powerdown operation, it will store the SCARD
//! configuration registers to SRAM, so it can restore them on power-up.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_power_control(void *pHandle,
am_hal_sysctrl_power_state_e ePowerState,
bool bRetainState);
//*****************************************************************************
//
//! @brief Used to configure basic SCARD settings.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//! @param psConfig is a structure of SCARD configuration options.
//!
//! This function takes the options from an \e am_hal_scard_config_t structure,
//! and applies them to the SCARD referred to by \e pHandle.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_configure(void *pHandle,
am_hal_scard_config_t *psConfig);
//*****************************************************************************
//
//! @brief Transfer data through the SCARD interface.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//! @param am_hal_scard_transfer_t is a structure describing the operation.
//!
//! This function executes a transaction as described by the \e
//! am_hal_scard_transfer_t structure. It can either read or write, and it will
//! take advantage of any buffer space provided by the \e
//! am_hal_scard_configure() function.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_transfer(void *pHandle,
const am_hal_scard_transfer_t *pTransfer);
//*****************************************************************************
//
//! @brief Wait for the SCARD TX to become idle
//!
//! @param pHandle is the handle for the SCARD to operate on.
//!
//! This function waits (polling) for all data in the SCARD TX FIFO and SCARD TX
//! buffer (if configured) to be fully sent on the physical SCARD interface.
//! This is not the most power-efficient way to wait for SCARD idle, but it can be
//! useful in simpler applications, or where power-efficiency is less important.
//!
//! Once this function returns, the SCARD can be safely disabled without
//! interfering with any previous transmissions.
//!
//! For a more power-efficient way to shut down the SCARD, check the
//! \e am_hal_scard_interrupt_service() function.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_tx_flush(void *pHandle);
//*****************************************************************************
//
//! @brief This function handles the SCARD buffers during SCARD interrupts.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//! @param ui32Status is the interrupt status at the time of ISR entry.
//! @param pui32ScardTxIdle can be used to store the SCARD idle status.
//!
//! The main purpose of this function is to manage the SCARD buffer system. Any
//! buffers configured by \e am_hal_scard_buffer_configure will be managed by
//! this service routine. Data queued for transmit will be added to the SCARD TX
//! FIFO as space allows, and data stored in the SCARD RX FIFO will be copied
//! out and stored in the RX buffer. This function will skip this transfer for
//! any buffer that has not been configured.
//!
//! In addition, this function can be used to alert the caller when the SCARD
//! becomes idle via the optional \e pui32ScardTxIdle argument. This function
//! will set this variable any time it completes its operation and the SCARD TX
//! channel is no longer in use (including both the FIFO and any configured
//! buffer).
//!
//! For RTOS-enabled cases, this function does not necessarily need to be
//! called inside the actual ISR for the SCARD, but it should be called promptly
//! in response to the receipt of a SCARD TX, RX, or RX timeout interrupt. If
//! the service routine is not called quickly enough, the caller risks an RX
//! FIFO overflow (data can be lost here), or a TX FIFO underflow (usually not
//! harmful).
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_interrupt_service(void *pHandle,
uint32_t ui32Status,
uint32_t *pui32ScardTxIdle);
//*****************************************************************************
//
//! @brief Enable interrupts.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//! @param ui32IntMask is the bitmask of interrupts to enable.
//!
//! This function enables the SCARD interrupt(s) given by ui32IntMask. If
//! multiple interrupts are desired, they can be OR'ed together.
//!
//! @note This function need not be called for SCARD FIFO interrupts if the SCARD
//! buffer service provided by \e am_hal_scard_buffer_configure() and \e
//! am_hal_scard_interrupt_service() is already in use. Non-FIFO-related
//! interrupts do require the use of this function.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_SCARD_INT_FHFEN
//! AM_HAL_SCARD_INT_FT2RENDEN
//! AM_HAL_SCARD_INT_PEEN
//! AM_HAL_SCARD_INT_OVREN
//! AM_HAL_SCARD_INT_FEREN
//! AM_HAL_SCARD_INT_TBERBFEN
//! AM_HAL_SCARD_INT_FNEEN
//! AM_HAL_SCARD_INT_SYNCENDEN
//! AM_HAL_SCARD_INT_PRLEN
//! AM_HAL_SCARD_INT_ECNTOVEREN
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_interrupt_enable(void *pHandle, uint32_t ui32Index,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Disable interrupts.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//! @param ui32IntMask is the bitmask of interrupts to disable.
//!
//! This function disables the SCARD interrupt(s) given by ui32IntMask. If
//! multiple interrupts need to be disabled, they can be OR'ed together.
//!
//! @note This function need not be called for SCARD FIFO interrupts if the SCARD
//! buffer service provided by \e am_hal_scard_buffer_configure() and \e
//! am_hal_scard_interrupt_service() is already in use. Non-FIFO-related
//! interrupts do require the use of this function.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_SCARD_INT_FHFEN
//! AM_HAL_SCARD_INT_FT2RENDEN
//! AM_HAL_SCARD_INT_PEEN
//! AM_HAL_SCARD_INT_OVREN
//! AM_HAL_SCARD_INT_FEREN
//! AM_HAL_SCARD_INT_TBERBFEN
//! AM_HAL_SCARD_INT_FNEEN
//! AM_HAL_SCARD_INT_SYNCENDEN
//! AM_HAL_SCARD_INT_PRLEN
//! AM_HAL_SCARD_INT_ECNTOVEREN
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_interrupt_disable(void *pHandle, uint32_t ui32Index,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Clear interrupt status.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//! @param ui32IntMask is the bitmask of interrupts to clear.
//!
//! This function clears the SCARD interrupt(s) given by ui32IntMask. If
//! multiple interrupts need to be cleared, they can be OR'ed together.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_SCARD_INT_FHFEN
//! AM_HAL_SCARD_INT_FT2RENDEN
//! AM_HAL_SCARD_INT_PEEN
//! AM_HAL_SCARD_INT_OVREN
//! AM_HAL_SCARD_INT_FEREN
//! AM_HAL_SCARD_INT_TBERBFEN
//! AM_HAL_SCARD_INT_FNEEN
//! AM_HAL_SCARD_INT_SYNCENDEN
//! AM_HAL_SCARD_INT_PRLEN
//! AM_HAL_SCARD_INT_ECNTOVEREN
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_interrupt_clear(void *pHandle, uint32_t ui32Index,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Read interrupt status.
//!
//! @param pHandle is the handle for the SCARD to operate on.
//!
//! @param pui32Status is the returned interrupt status (all bits OR'ed
//! together)
//!
//! @param bEnabled determines whether to read interrupts that were not
//! enabled.
//!
//! This function reads the status the SCARD interrupt(s) if \e bEnabled is
//! true, it will only return the status of the enabled interrupts. Otherwise,
//! it will return the status of all interrupts, enabled or disabled.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_SCARD_INT_FHFEN
//! AM_HAL_SCARD_INT_FT2RENDEN
//! AM_HAL_SCARD_INT_PEEN
//! AM_HAL_SCARD_INT_OVREN
//! AM_HAL_SCARD_INT_FEREN
//! AM_HAL_SCARD_INT_TBERBFEN
//! AM_HAL_SCARD_INT_FNEEN
//! AM_HAL_SCARD_INT_SYNCENDEN
//! AM_HAL_SCARD_INT_PRLEN
//! AM_HAL_SCARD_INT_ECNTOVEREN
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable SCARD errors.
//
//*****************************************************************************
extern uint32_t am_hal_scard_interrupt_status_get(void *pHandle, uint32_t ui32Index,
uint32_t *pui32Status);
extern uint32_t am_hal_scard_control(void *pHandle, am_hal_scard_request_e eReq, void *pArgs);
typedef enum
{
AM_HAL_SCARD_STATUS_BUS_ERROR = AM_HAL_STATUS_MODULE_SPECIFIC_START,
AM_HAL_SCARD_STATUS_RX_QUEUE_FULL,
AM_HAL_SCARD_STATUS_PROTOCAL_NOT_SUPPORT,
}
am_hal_scard_errors_t;
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_SCARD_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,221 @@
//*****************************************************************************
//
// am_hal_secure_ota.c
//! @file
//!
//! @brief Functions for secure over-the-air.
//!
//! @addtogroup
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
// Local defines
#define FLASH_INVALID 0xFFFFFFFF
// Internal OTA state information
typedef struct
{
uint32_t flashSize;
uint32_t otaDescAddr;
uint32_t numOta;
} am_hal_secure_ota_state_t;
static am_hal_secure_ota_state_t gSOtaState;
// Erase a flash page
static void
erase_flash_page(uint32_t ui32ProgamKey, uint32_t ui32Addr)
{
uint32_t ui32CurrentPage, ui32CurrentBlock;
//
// Figure out what page and block we're working on.
//
ui32CurrentPage = AM_HAL_FLASH_ADDR2PAGE(ui32Addr);
ui32CurrentBlock = AM_HAL_FLASH_ADDR2INST(ui32Addr);
//
// Start a critical section.
//
AM_CRITICAL_BEGIN
am_hal_flash_page_erase(ui32ProgamKey,
ui32CurrentBlock, ui32CurrentPage);
//
// Exit the critical section.
//
AM_CRITICAL_END
}
//*****************************************************************************
//
//! @brief Initialize OTA state
//!
//! Initializes the OTA state. This should be called before doing any other operation
//!
//! @param ui32ProgamKey - The Flash programming key
//! @param pOtaDesc should be start of a flash page designated for OTA Descriptor
//!
//! This call will erase the flash page, which will then be incrementally
//! populated as OTA's are added. It will also initialize the OTAPOINTER to point
//! to this descriptor, marking it as invalid at the same time
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_ota_init(uint32_t ui32ProgamKey, uint32_t *pOtaDesc)
{
am_hal_mcuctrl_device_t sDevice;
uint32_t otaDescAddr = (uint32_t)pOtaDesc;
//
// Get chip specific info
//
am_hal_mcuctrl_info_get(AM_HAL_MCUCTRL_INFO_DEVICEID, &sDevice);
gSOtaState.flashSize = sDevice.ui32FlashSize;
// Validate the flash page
if ((otaDescAddr >= gSOtaState.flashSize) ||
(otaDescAddr & (AM_HAL_FLASH_PAGE_SIZE - 1)))
{
return AM_HAL_STATUS_INVALID_ARG;
}
// TODO - check against protected pages
// Erase the page
erase_flash_page(ui32ProgamKey, otaDescAddr);
// Initialize the OTA Pointer
MCUCTRL->OTAPOINTER = otaDescAddr;
gSOtaState.numOta = 0;
gSOtaState.otaDescAddr = otaDescAddr;
return AM_HAL_STATUS_SUCCESS;
}
// Add a new OTA to descriptor
//*****************************************************************************
//
//! @brief Add a new image for OTA
//!
//! Adds a new image to the OTA Descriptor.
//!
//! @param ui32ProgamKey - The Flash programming key
//! @param imageMagic image magic# identifying type of image being added to OTA descr
//! @param pImage should point to the start of new image to be added to descr
//!
//! This will program the next available entry in OTA descriptor. It will also set
//! appropriate state in the OTA pointer register
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_ota_add(uint32_t ui32ProgamKey, uint8_t imageMagic, uint32_t *pImage)
{
uint32_t imageAddr = (uint32_t)pImage;
// Validate the Image Pointer
if ((imageAddr >= gSOtaState.flashSize) ||
(imageAddr & (AM_HAL_FLASH_PAGE_SIZE - 1)))
{
return AM_HAL_STATUS_INVALID_ARG;
}
if (gSOtaState.numOta == AM_HAL_SECURE_OTA_MAX_OTA)
{
return AM_HAL_STATUS_OUT_OF_RANGE;
}
imageAddr |= AM_HAL_OTA_STATUS_PENDING;
// Program the OTA Descriptor word
am_hal_flash_program_main(ui32ProgamKey,
&imageAddr,
((uint32_t *)gSOtaState.otaDescAddr + gSOtaState.numOta++),
1);
// Set appropriate OTA Pointer bits
MCUCTRL->OTAPOINTER_b.OTAVALID = 1;
if (imageMagic == AM_IMAGE_MAGIC_SBL)
{
MCUCTRL->OTAPOINTER_b.OTASBLUPDATE = 1;
}
return AM_HAL_STATUS_SUCCESS;
}
// Get OTA Status
// Can be called anytime (generally after coming back from reset to check the status of OTA
// Will be also used by sbl_main to identify list of OTA's left for it (would show up as PENDING)
//*****************************************************************************
//
//! @brief Get Current OTA Descriptor state
//!
//! @param pOtaDesc should be start of a flash page designated for OTA Descriptor
//! @param maxOta Determines the size of the following buffer
//! @param pStatus - Return Parameter - populated by this function indicating the OTA
//! status of various OTA's
//!
//! This will retrieve the current OTA status of various images added to the OTA descr
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_get_ota_status(uint32_t *pOtaDesc, uint32_t maxOta, am_hal_ota_status_t *pStatus)
{
uint32_t numOta = 0;
// Fill up the return structure
while (maxOta--)
{
if (pOtaDesc[numOta] == FLASH_INVALID)
{
pStatus[numOta].pImage = (uint32_t *)pOtaDesc[numOta];
break;
}
else
{
pStatus[numOta].pImage = (uint32_t *)(pOtaDesc[numOta] & ~0x3);
pStatus[numOta].status = (am_hal_ota_status_e)(pOtaDesc[numOta] & 0x3);
}
numOta++;
}
return AM_HAL_STATUS_SUCCESS;
}
@@ -0,0 +1,227 @@
//*****************************************************************************
//
// am_hal_secure_ota.h
//! @file
//!
//! @brief Functions for secure over-the-air.
//!
//! @addtogroup
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_SECURE_OTA_H
#define AM_HAL_SECURE_OTA_H
// Ambiq Standard Image Format related definitions
// Magic Numbers
#define AM_IMAGE_MAGIC_SBL 0xA3
#define AM_IMAGE_MAGIC_AM3P 0x3A
#define AM_IMAGE_MAGIC_PATCH 0xAF
#define AM_IMAGE_MAGIC_MAIN 0xC0
#define AM_IMAGE_MAGIC_CHILD 0xCC
#define AM_IMAGE_MAGIC_NONSECURE 0xCB
#define AM_IMAGE_MAGIC_INFO0 0xCF
// First 30 words of the image headers follow similar pattern
typedef struct
{
union
{
uint32_t ui32;
struct
{
uint32_t blobSize : 20;
uint32_t resvd : 3;
uint32_t encrypted : 1;
uint32_t magicNum : 8;
} s;
} w0;
uint32_t crc;
union
{
uint32_t ui32;
struct
{
uint32_t authAlgo : 4;
uint32_t authKeyIdx : 4;
uint32_t encAlgo : 4;
uint32_t keyIdx : 4;
uint32_t resvd3 : 8;
uint32_t crcBoot : 1;
uint32_t authBoot : 1;
uint32_t resvd2 : 2;
uint32_t crcInstall : 1;
uint32_t authInstall : 1;
uint32_t resvd1 : 2;
} s;
} w2;
uint32_t w3;
uint32_t signature[8]; // w4-11
uint32_t iv[4]; // w12-w15
uint32_t kek[4]; // w16-w19
uint32_t signatureClear[8]; // w20-w27
union
{
uint32_t ui32;
struct
{
uint32_t offsetWords : 16;
uint32_t sizeWords : 16;
} info0;
struct
{
uint32_t encap : 1;
uint32_t resvd : 1;
uint32_t loadAddrMsb : 30;
} s1;
struct
{
uint32_t writeProtect : 1;
uint32_t copyProtect : 1;
uint32_t loadAddrMsb : 30;
} s;
} addrWord; // w28
union
{
uint32_t ui32;
uint32_t resv;
uint32_t key; // For info
struct
{
uint32_t version : 15;
uint32_t erasePrev : 1;
uint32_t resv : 16;
} s;
} versionKeyWord; // w29
} am_image_hdr_common_t;
// Bitmask used to clear encrypted status in flash
#define AM_IMAGE_BITMASK_ENCRYPTED 0x00800000
// Number of most significant bits in w28 used for load address
#define AM_IMAGE_LOAD_ADDR_MSB_BITS 30
#define AM_IMAGE_GET_LOADADDR(common) (((am_image_hdr_common_t *)(common))->addrWord.s.loadAddrMsb << (32 - AM_IMAGE_LOAD_ADDR_MSB_BITS))
#define AM_IMAGE_NUM_TRAILING_WORDS_TO_256 ((256 - sizeof(am_image_hdr_common_t))/4)
#define AM_IMAGE_MAX_CHILD_IMAGE AM_IMAGE_NUM_TRAILING_WORDS_TO_256
typedef struct
{
am_image_hdr_common_t common;
uint32_t childPtr[AM_IMAGE_MAX_CHILD_IMAGE];
} am_main_image_hdr_t;
typedef struct
{
am_image_hdr_common_t common;
uint32_t featureKey;
uint32_t resvd[1];
} am_thirdparty_image_hdr_t;
typedef struct
{
am_image_hdr_common_t common;
uint32_t resvd[AM_IMAGE_NUM_TRAILING_WORDS_TO_256];
} am_sbl_image_hdr_t;
// Reserved magic numbers allowed to be used by customer's own bootloader
#define AM_IMAGE_MAGIC_CUST(x) ((((x) & 0xF0) == 0xC0) && ((x) != 0xC0) && ((x) != 0xCC) && ((x) != 0xCB) && ((x) != 0xCF))
// OTA Upgrade related definitions
// Maximum number of OTAs
#define AM_HAL_SECURE_OTA_MAX_OTA 8
// OTA Protocol between OTA application and SecureBoot
// OTAPOINTER will be initialized as follows:
// Most significant 30 bits will correspond to most significant 30 bits of OTA Descriptor
// Least Significant bit (bit 0) should be initialized to 1 to indicate a valid OTA Descriptor
// bit 1 should be initialized to 1 to indicate that the list contains an SBL OTA
// OTA Descriptor points to a list of entries, each corresponding to an OTA blob, list terminating in 0xFFFFFFFF
// Each list entry word comprises of following:
// Most significant 30 bits will correspond to most significant 30 bits of OTA blob pointer
// Blob pointer needs to be aligned to Flash Page boundary (8K)
// Least Significant 2 bits should be initialized to 1 to indicate a valid OTA Pending
// After Secboot processes an OTA, it clears the least significant bit (bit 0)
// bit 1 indicates the status of the OTA - 0 for Success, 1 for Failure
#define AM_HAL_SECURE_OTA_OTA_VALID_MASK 0x3
#define AM_HAL_SECURE_OTA_OTA_GET_BLOB_PTR(ptr) ((uint32_t)(ptr) & ~AM_HAL_SECURE_OTA_OTA_VALID_MASK)
#define AM_HAL_SECURE_OTA_OTA_IS_VALID(ptr) (((uint32_t)(ptr) & AM_HAL_SECURE_OTA_OTA_VALID_MASK) == AM_HAL_SECURE_OTA_OTA_VALID_MASK)
#define AM_HAL_SECURE_OTA_OTA_LIST_END_MARKER 0xFFFFFFFF
// Bitmasks signifying the bit to be cleared for OTA success/failure
#define AM_HAL_SECURE_OTA_OTA_DONE_FAILURE_CLRMASK 0x1
#define AM_HAL_SECURE_OTA_OTA_DONE_SUCCESS_CLRMASK 0x3
// OTA Status
typedef enum
{
AM_HAL_OTA_STATUS_SUCCESS = 0x0,
AM_HAL_OTA_STATUS_ERROR = 0x1, // This should never happen
AM_HAL_OTA_STATUS_FAILURE = 0x2,
AM_HAL_OTA_STATUS_PENDING = 0x3,
} am_hal_ota_status_e;
// Per Image OTA Status information
typedef struct
{
uint32_t *pImage;
am_hal_ota_status_e status;
} am_hal_ota_status_t;
// pOtaDesc should be start of a flash page designated for OTA Descriptor
// This call will erase the flash page, which will then be incrementally populated as OTA's are added
// It will also initialize the OTAPOINTER to point to this descriptor, with LSB indicating it as invalid
uint32_t am_hal_ota_init(uint32_t ui32ProgamKey, uint32_t *pOtaDesc);
// Add a new OTA to descriptor
// This will program the next available entry in OTA descriptor
// Will also set the valid/sbl flags in OTA pointer register
uint32_t am_hal_ota_add(uint32_t ui32ProgamKey, uint8_t imageMagic, uint32_t *pImage);
// Get OTA Status
// Can be called anytime (generally after coming back from reset to check the status of OTA
// Will be also used by sbl_main to identify list of OTA's left for it (would show up as PENDING)
uint32_t am_hal_get_ota_status(uint32_t *pOtaDesc, uint32_t maxOta, am_hal_ota_status_t *pStatus);
#endif // AM_HAL_SECURE_OTA_H
@@ -0,0 +1,572 @@
//*****************************************************************************
//
// am_hal_security.c
//! @file
//!
//! @brief Functions for on-chip security features
//!
//! @addtogroup
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
// Local defines.
//*****************************************************************************
//
// ENABLE_EXTMEM_CRC
// By default, the CRC engine can only operate on data located in internal
// memory (i.e. flash or SRAM). This define enables am_hal_crc() to support
// external memories, but requires a small amount of global SRAM allocated for
// that purpose. If it is not desired to support this feature, set to 0.
//
#define ENABLE_EXTMEM_CRC 1
//
// Maximum iterations for hardware CRC to finish
//
#define MAX_CRC_WAIT 100000
#define AM_HAL_SECURITY_LOCKSTAT_CUSTOMER 0x1
#define AM_HAL_SECURITY_LOCKSTAT_RECOVERY 0x40000000
//*****************************************************************************
//
// Globals
//
//*****************************************************************************
#if ENABLE_EXTMEM_CRC
//
// Set up a small global buffer that can be used am_hal_crc32() when
// computing CRCs on external memory.
//
#define CRC_XFERBUF_SZ (512) // Reserve 512 bytes for the buffer
static uint32_t g_CRC_buffer[CRC_XFERBUF_SZ / 4];
#endif // ENABLE_EXTMEM_CRC
//
// Assign ptr variables to avoid an issue with GCC reading from location 0x0.
//
const volatile uint32_t *g_pFlash0 = (uint32_t*)(AM_HAL_SBL_ADDRESS + 0);
const volatile uint32_t *g_pFlash4 = (uint32_t*)(AM_HAL_SBL_ADDRESS + 4);
//*****************************************************************************
//
//! @brief Hardcoded function - to Run supplied main program
//!
//! @param r0 = vtor - address of the vector table
//!
//! @return Returns None
//
//*****************************************************************************
#if (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION < 6000000)
static __asm void
bl_run_main(uint32_t *vtor)
{
//
// Store the vector table pointer of the new image into VTOR.
//
movw r3, #0xED08
movt r3, #0xE000
str r0, [r3, #0]
//
// Load the new stack pointer into R1 and the new reset vector into R2.
//
ldr r3, [r0, #0]
ldr r2, [r0, #4]
//
// Set the stack pointer for the new image.
//
mov sp, r3
//
// Jump to the new reset vector.
//
bx r2
}
#elif (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION >= 6000000)
__attribute__((naked))
static void
bl_run_main(uint32_t *vtor)
{
__asm
(
" movw r3, #0xED08\n\t" // Store the vector table pointer of the new image into VTOR.
" movt r3, #0xE000\n\t"
" str r0, [r3, #0]\n\t"
" ldr r3, [r0, #0]\n\t" // Load the new stack pointer into R1 and the new reset vector into R2.
" ldr r2, [r0, #4]\n\t"
" mov sp, r3\n\t" // Set the stack pointer for the new image.
" bx r2\n\t" // Jump to the new reset vector.
);
}
#elif defined(__GNUC_STDC_INLINE__)
__attribute__((naked))
static void
bl_run_main(uint32_t *vtor)
{
__asm
(
" movw r3, #0xED08\n\t" // Store the vector table pointer of the new image into VTOR.
" movt r3, #0xE000\n\t"
" str r0, [r3, #0]\n\t"
" ldr r3, [r0, #0]\n\t" // Load the new stack pointer into R1 and the new reset vector into R2.
" ldr r2, [r0, #4]\n\t"
" mov sp, r3\n\t" // Set the stack pointer for the new image.
" bx r2\n\t" // Jump to the new reset vector.
);
}
#elif defined(__IAR_SYSTEMS_ICC__)
__stackless static inline void
bl_run_main(uint32_t *vtor)
{
__asm volatile (
" movw r3, #0xED08\n" // Store the vector table pointer of the new image into VTOR.
" movt r3, #0xE000\n"
" str r0, [r3, #0]\n"
" ldr r3, [r0, #0]\n" // Load the new stack pointer into R1 and the new reset vector into R2.
" ldr r2, [r0, #4]\n"
" mov sp, r3\n" // Set the stack pointer for the new image.
" bx r2\n" // Jump to the new reset vector.
);
}
#else
#error Compiler is unknown, please contact Ambiq support team
#endif
// Pre- SBLv2 known versions that do not support callback
static uint32_t sblPreV2[][4] = {
// flash0, flash4, sblVersion, sblVersionAddInfo
{0xA3007860, 0x2E2638FB, 0 , 0},
{0xA3007E14, 0x5EE4E461, 1 , 0},
{0xA3008290, 0xB49CECD5, 2 , 0},
};
//*****************************************************************************
//
//! @brief Get Device Security Info
//!
//! @param pSecInfo - Pointer to structure for returned security info
//!
//! This will retrieve the security information for the device
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_security_get_info(am_hal_security_info_t *pSecInfo)
{
uint32_t flash0;
uint32_t flash4;
uint32_t i;
bool bSbl;
if (!pSecInfo)
{
return AM_HAL_STATUS_INVALID_ARG;
}
pSecInfo->info0Version = AM_REGVAL(0x50020040);
pSecInfo->bInfo0Valid = MCUCTRL->SHADOWVALID_b.INFO0_VALID;
bSbl = MCUCTRL->BOOTLOADER_b.SECBOOTFEATURE;
if (bSbl)
{
// Check if we're running pre-SBLv2
flash0 = *g_pFlash0;
flash4 = *g_pFlash4;
// Check if SBL is installed
if ((flash0 >> 24) != AM_IMAGE_MAGIC_SBL)
{
return AM_HAL_STATUS_FAIL;
}
for ( i = 0; i < sizeof(sblPreV2) / sizeof(sblPreV2[0]); i++ )
{
if ((sblPreV2[i][0] == flash0) && (sblPreV2[i][1] == flash4))
{
// This is a device prior to SBLv2
pSecInfo->sblVersion = sblPreV2[i][2];
pSecInfo->sblVersionAddInfo = sblPreV2[i][3];
break;
}
}
if ( i == sizeof(sblPreV2) / sizeof(sblPreV2[0]) )
{
// SBLv2 or beyond
// Use SBL jump table function
uint32_t status;
uint32_t sblVersion;
uint32_t (*pFuncVersion)(uint32_t *) = (uint32_t (*)(uint32_t *))(AM_HAL_SBL_ADDRESS + 0x1D1);
status = pFuncVersion(&sblVersion);
if (status != AM_HAL_STATUS_SUCCESS)
{
return status;
}
pSecInfo->sblVersion = sblVersion & 0x7FFF;
pSecInfo->sblVersionAddInfo = sblVersion >> 15;
}
}
else
{
return AM_HAL_STATUS_FAIL;
}
return AM_HAL_STATUS_SUCCESS;
} // am_hal_security_get_info()
//*****************************************************************************
//
//! @brief Set the key for specified lock
//!
//! @param lockType - The lock type to be operated upon
//! @param pKey - Pointer to 128b key value
//!
//! This will program the lock registers for the specified lock and key
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_security_set_key(am_hal_security_locktype_t lockType, am_hal_security_128bkey_t *pKey)
{
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (pKey == NULL)
{
return AM_HAL_STATUS_INVALID_ARG;
}
switch (lockType)
{
case AM_HAL_SECURITY_LOCKTYPE_CUSTOMER:
case AM_HAL_SECURITY_LOCKTYPE_RECOVERY:
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
SECURITY->LOCKCTRL = lockType;
SECURITY->KEY0 = pKey->keys.key0;
SECURITY->KEY1 = pKey->keys.key1;
SECURITY->KEY2 = pKey->keys.key2;
SECURITY->KEY3 = pKey->keys.key3;
return AM_HAL_STATUS_SUCCESS;
} // am_hal_security_set_key()
//*****************************************************************************
//
//! @brief Get the current status of the specified lock
//!
//! @param lockType - The lock type to be operated upon
//! @param pbUnlockStatus - Pointer to return variable with lock status
//!
//! This will get the lock status for specified lock - true implies unlocked
//! Note that except for customer lock, other locks are self-locking on status read
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_security_get_lock_status(am_hal_security_locktype_t lockType, bool *pbUnlockStatus)
{
uint32_t unlockMask;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (pbUnlockStatus == NULL)
{
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
switch (lockType)
{
case AM_HAL_SECURITY_LOCKTYPE_CUSTOMER:
unlockMask = AM_HAL_SECURITY_LOCKSTAT_CUSTOMER;
break;
case AM_HAL_SECURITY_LOCKTYPE_RECOVERY:
unlockMask = AM_HAL_SECURITY_LOCKSTAT_RECOVERY;
break;
default:
return AM_HAL_STATUS_INVALID_ARG;
}
*pbUnlockStatus = SECURITY->LOCKSTAT & unlockMask;
return AM_HAL_STATUS_SUCCESS;
} // am_hal_security_get_lock_status()
//*****************************************************************************
//
//! @brief Compute CRC32 for a specified payload
//!
//! @param ui32StartAddr - The start address of the payload.
//! @param ui32SizeBytes - The length of payload in bytes.
//! @param pui32Crc - Pointer to variable to return the computed CRC.
//!
//! This function uses the hardware engine to compute CRC32 on an arbitrary data
//! payload. The payload can reside in any contiguous memory including external
//! memory.
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t
am_hal_crc32(uint32_t ui32StartAddr, uint32_t ui32SizeBytes, uint32_t *pui32Crc)
{
uint32_t status, ui32CRC32;
bool bInternal;
#ifndef AM_HAL_DISABLE_API_VALIDATION
if (pui32Crc == NULL)
{
return AM_HAL_STATUS_INVALID_ARG;
}
//
// Make sure size is multiple of 4 bytes
//
if (ui32SizeBytes & 0x3)
{
return AM_HAL_STATUS_INVALID_ARG;
}
#endif // AM_HAL_DISABLE_API_VALIDATION
status = AM_HAL_STATUS_OUT_OF_RANGE; // Default status
//
// Determine whether the startaddr is in internal flash or SRAM.
//
bInternal = ISADDRFLASH(ui32StartAddr) || ISADDRSRAM(ui32StartAddr);
if ( bInternal )
{
//
// Program the CRC engine to compute the crc
//
ui32CRC32 = 0xFFFFFFFF;
SECURITY->RESULT = ui32CRC32;
SECURITY->SRCADDR = ui32StartAddr;
SECURITY->LEN = ui32SizeBytes;
SECURITY->CTRL_b.FUNCTION = SECURITY_CTRL_FUNCTION_CRC32;
//
// Start the CRC
//
SECURITY->CTRL_b.ENABLE = 1;
//
// Wait for CRC to finish
//
status = am_hal_flash_delay_status_change(MAX_CRC_WAIT,
(uint32_t)&SECURITY->CTRL, SECURITY_CTRL_ENABLE_Msk, 0);
if (status == AM_HAL_STATUS_SUCCESS)
{
*pui32Crc = SECURITY->RESULT;
}
return status;
}
#if ENABLE_EXTMEM_CRC
uint32_t ui32XferSize, ui32cnt;
uint32_t *pui32Buf, *pui32Data;
//
// If we're here, the source data resides in non-internal memory (that is,
// not flash or SRAM).
//
// Begin the loop for computing the CRC of the external memory. The data
// will first be copied to the SRAM buffer.
//
// Program the parts of the CRC engine that will not need to change
// inside the loop: SRCADDR, FUNCTION, initial seed in RESULT.
// While inside the loop, only the LEN will need to be provided.
//
SECURITY->SRCADDR = (uint32_t)&g_CRC_buffer[0];
SECURITY->CTRL_b.FUNCTION = SECURITY_CTRL_FUNCTION_CRC32;
//
// During the loop the RESULT register must not be rewritten, even if the
// value written on each pass is identical. Rewriting it appears to reset
// a state machine such that an incorrect CRC value is computed.
//
ui32CRC32 = 0xFFFFFFFF;
SECURITY->RESULT = ui32CRC32;
pui32Data = (uint32_t*)ui32StartAddr;
while ( ui32SizeBytes )
{
//
// First copy a chunk of payload data to SRAM where the CRC engine
// can operate on it.
//
ui32XferSize = (ui32SizeBytes >= CRC_XFERBUF_SZ) ?
CRC_XFERBUF_SZ : ui32SizeBytes;
ui32SizeBytes -= ui32XferSize;
ui32cnt = ui32XferSize / 4;
pui32Buf = &g_CRC_buffer[0];
while ( ui32cnt-- )
{
*pui32Buf++ = *pui32Data++;
}
//
// Program the CRC engine's LEN parameter.
// All other parameters were preprogrammed: SRCADDR, FUNCTION, RESULT.
//
SECURITY->LEN = ui32XferSize;
//
// Start the CRC
//
SECURITY->CTRL_b.ENABLE = 1;
//
// Wait for CRC to finish
//
status = am_hal_flash_delay_status_change(MAX_CRC_WAIT,
(uint32_t)&SECURITY->CTRL, SECURITY_CTRL_ENABLE_Msk, 0);
if ( (status == AM_HAL_STATUS_SUCCESS) && !SECURITY->CTRL_b.CRCERROR )
{
ui32CRC32 = SECURITY->RESULT;
}
else if ( SECURITY->CTRL_b.CRCERROR )
{
return AM_HAL_STATUS_HW_ERR;
}
else
{
//
// Error from status_change function.
// Return the CRC value we do have, but return an error.
//
//return status;
break;
}
}
//
// Return result to caller
//
*pui32Crc = ui32CRC32;
#endif // ENABLE_EXTMEM_CRC
return status;
} // am_hal_crc32()
//*****************************************************************************
//
//! @brief Helper function to Perform exit operations for a secondary bootloader
//!
//! @param pImage - The address of the image to give control to
//!
//! This function does the necessary security operations while exiting from a
//! a secondary bootloader program. If still open, it locks the info0 key region,
//! as well as further updates to the flash protection register.
//! It also checks if it needs to halt to honor a debugger request.
//! If an image address is specified, control is transferred to the same on exit.
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success, if no image address specified
//! If an image address is provided, a successful execution results in transfer to
//! the image - and this function does not return.
//
//*****************************************************************************
uint32_t am_hal_bootloader_exit(uint32_t *pImage)
{
uint32_t status = AM_HAL_STATUS_SUCCESS;
//
// Lock the assets
//
if ( MCUCTRL->SHADOWVALID_b.INFO0_VALID &&
MCUCTRL->BOOTLOADER_b.PROTLOCK )
{
am_hal_security_128bkey_t keyVal;
uint32_t *pCustKey = (uint32_t *)0x50021A00;
bool bLockStatus;
//
// PROTLOCK Open
// This should also mean that Customer key is accessible
// Now lock the key by writing an incorrect value
//
keyVal.keyword[0] = ~pCustKey[0];
am_hal_security_set_key(AM_HAL_SECURITY_LOCKTYPE_CUSTOMER, &keyVal);
status = am_hal_security_get_lock_status(AM_HAL_SECURITY_LOCKTYPE_CUSTOMER, &bLockStatus);
if ((status != AM_HAL_STATUS_SUCCESS) || (bLockStatus))
{
return AM_HAL_STATUS_FAIL;
}
//
// Lock the protection register to prevent further region locking
// CAUTION!!! - Can not do AM_BFW on BOOTLOADER register as all writable bits in this register are Write 1 to clear
//
MCUCTRL->BOOTLOADER = _VAL2FLD(MCUCTRL_BOOTLOADER_PROTLOCK, 1);
//
// Check if we need to halt (debugger request)
//
if (MCUCTRL->SCRATCH0 & 0x1)
{
// Debugger wants to halt
uint32_t dhcsr = AM_REGVAL(0xE000EDF0);
// Clear the flag in Scratch register
MCUCTRL->SCRATCH0 &= ~0x1;
// Halt the core
dhcsr = ((uint32_t)0xA05F << 16) | (dhcsr & 0xFFFF) | 0x3;
AM_REGVAL(0xE000EDF0) = dhcsr;
// Resume from halt
}
}
// Give control to supplied image
if (pImage)
{
bl_run_main(pImage);
// Does not return
}
return status;
} // am_hal_bootloader_exit()
@@ -0,0 +1,184 @@
//*****************************************************************************
//
// am_hal_security.h
//! @file
//!
//! @brief Functions for security functions
//!
//! @addtogroup
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_SECURITY_H
#define AM_HAL_SECURITY_H
//
// Location of SBL install address for this device
//
// Important Note:
// Some caution should be observed when using AM_HAL_SBL_ADDRESS as an address.
// GCC considers use of this address to be a NULL pointer. When compiled with
// high optimization (-O3) and used to read the location with, for example,
// code such as *((volatile uint32_t *)(AM_HAL_SBL_ADDRESS)), GCC will insert
// an instruction it calls "UDF" (undefined), op-code 0xDEFF, which will cause
// a fault on execution to trap the "invalid" null-ptr usage.
// This does not appear to be an issue with IAR and Keil ARM5.
// It is likely an issue with Keil ARM6.
//
#define AM_HAL_SBL_ADDRESS 0x00000000
typedef struct
{
bool bInfo0Valid;
uint32_t info0Version;
uint32_t sblVersion;
uint32_t sblVersionAddInfo;
} am_hal_security_info_t;
// LOCK Definitions
typedef enum
{
AM_HAL_SECURITY_LOCKTYPE_CUSTOMER = 0x1,
AM_HAL_SECURITY_LOCKTYPE_RECOVERY = 0x9D,
} am_hal_security_locktype_t;
typedef union
{
uint32_t keyword[4];
struct
{
uint32_t key0;
uint32_t key1;
uint32_t key2;
uint32_t key3;
} keys;
} am_hal_security_128bkey_t;
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! @brief Get Device Security Info
//!
//! @param pSecInfo - Pointer to structure for returned security info
//!
//! This will retrieve the security information for the device
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_security_get_info(am_hal_security_info_t *pSecInfo);
//*****************************************************************************
//
//! @brief Set the key for specified lock
//!
//! @param lockType - The lock type to be operated upon
//! @param pKey - Pointer to 128b key value
//!
//! This will program the lock registers for the specified lock and key
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_security_set_key(am_hal_security_locktype_t lockType, am_hal_security_128bkey_t *pKey);
//*****************************************************************************
//
//! @brief Get the current status of the specified lock
//!
//! @param lockType - The lock type to be operated upon
//! @param pbUnlockStatus - Pointer to return variable with lock status
//!
//! This will get the lock status for specified lock
//! Note that except for customer lock, other locks are self-locking on status read
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_security_get_lock_status(am_hal_security_locktype_t lockType, bool *pbUnlockStatus);
//*****************************************************************************
//
//! @brief Compute CRC32 for a specified payload
//!
//! @param startAddr - The start address of the payload
//! @param sizeBytes - The length of payload in bytes
//! @param pCrc - Pointer to return computed CRC
//!
//! This will use the hardware engine to compute CRC32 on an arbitrary data payload
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success
//
//*****************************************************************************
uint32_t am_hal_crc32(uint32_t startAddr, uint32_t sizeBytes, uint32_t *pCrc);
//*****************************************************************************
//
//! @brief Helper function to Perform exit operations for a secondary bootloader
//!
//! @param pImage - The address of the image to give control to
//!
//! This function does the necessary security operations while exiting from a
//! a secondary bootloader program. If still open, it locks the info0 key region,
//! as well as further updates to the flash protection register.
//! It also checks if it needs to halt to honor a debugger request.
//! If an image address is specified, control is transferred to the same on exit.
//!
//! @return Returns AM_HAL_STATUS_SUCCESS on success, if no image address specified
//! If an image address is provided, a successful execution results in transfer to
//! the image - and this function does not return.
//
//*****************************************************************************
uint32_t am_hal_bootloader_exit(uint32_t *pImage);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_SECURITY_H
@@ -0,0 +1,88 @@
//*****************************************************************************
//
// am_hal_status.h
//! @file
//!
//! @brief Global status return codes for HAL interface.
//!
//! @addtogroup status3 Global Status Return Codes.
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_STATUS_H
#define AM_HAL_STATUS_H
#ifdef __cplusplus
extern "C"
{
#endif
//
// Global Status Returns
//
typedef enum
{
AM_HAL_STATUS_SUCCESS,
AM_HAL_STATUS_FAIL,
AM_HAL_STATUS_INVALID_HANDLE,
AM_HAL_STATUS_IN_USE,
AM_HAL_STATUS_TIMEOUT,
AM_HAL_STATUS_OUT_OF_RANGE,
AM_HAL_STATUS_INVALID_ARG,
AM_HAL_STATUS_INVALID_OPERATION,
AM_HAL_STATUS_MEM_ERR,
AM_HAL_STATUS_HW_ERR,
AM_HAL_STATUS_MODULE_SPECIFIC_START = 0x08000000,
} am_hal_status_e;
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_STATUS_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,641 @@
//*****************************************************************************
//
// am_hal_stimer.c
//! @file
//!
//! @brief Functions for interfacing with the system timer (STIMER).
//!
//! @addtogroup stimer3 System Timer (STIMER)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
//! @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 = CTIMER->STCFG;
//
// Write our configuration value.
//
CTIMER->STCFG = ui32STimerConfig;
#if AM_PART_APOLLO2
//
// If all of the clock sources are not HFRC, disable LDO when sleeping if timers are enabled.
//
if ( (CTIMER->STCFG_b.CLKSELCTIMER->STCFG_b.CLKSEL == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV16) ||
(CTIMER->STCFG_b.CLKSELCTIMER->STCFG_b.CLKSEL == AM_REG_CTIMER_STCFG_CLKSEL_HFRC_DIV256) )
{
PWRCTRL->MISC_b.FORCEMEMVRLPTIMERS = 0;
}
else
{
PWRCTRL->MISC_b.FORCEMEMVRLPTIMERS = 1;
}
#endif
return ui32CurrVal;
}
//*****************************************************************************
//
//! @brief Get the current stimer value.
//!
//! This function can be used to read, uninvasively, the value in the stimer.
//!
//! @return The 32-bit value from the STimer counter register.
//
//*****************************************************************************
uint32_t
am_hal_stimer_counter_get(void)
{
return CTIMER->STTMR;
}
//*****************************************************************************
//
//! @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
//
CTIMER->STCFG |= CTIMER_STCFG_CLEAR_Msk;
//
// Reset the clear bit
//
CTIMER->STCFG &= ~CTIMER_STCFG_CLEAR_Msk;
}
//*****************************************************************************
//
//! @brief Set the compare value.
//!
//! @param ui32CmprInstance is the compare register instance number (0-7).
//! @param ui32Delta is the value to add to the STimer counter and load into
//! the comparator register.
//!
//! NOTE: There is no way to set an absolute value into a comparator register.
//! Only deltas added to the STimer counter can be written to the compare
//! registers.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_stimer_compare_delta_set(uint32_t ui32CmprInstance, uint32_t ui32Delta)
{
uint32_t cfgVal;
uint32_t numTries = 0;
if ( ui32CmprInstance > 7 )
{
return;
}
// We need to disable the compare temporarily while setting the delta value
// That leaves a corner case where we could miss the trigger if setting a very
// small delta. To avoid this, we take critical section, and we should ensure
// that delta value is at least > 1
//
// Start a critical section.
//
AM_CRITICAL_BEGIN
//
// Get current CFG value
//
cfgVal = CTIMER->STCFG;
//
// Disable the compare if already enabled, when setting the new value
//
CTIMER->STCFG &= ~((AM_HAL_STIMER_CFG_COMPARE_A_ENABLE << ui32CmprInstance));
// In rare case the delta might not be effective
// We retry if that is the case.
// Allow for some variability in the value owing to execution latency
while (numTries++ < 4)
{
uint32_t expVal;
uint32_t expMax;
uint32_t cmpVal;
// Expected value
expVal = CTIMER->STTMR + ui32Delta;
// Max allowed - taking care of latency
expMax = expVal + 10;
//
// Set the delta
//
AM_REGVAL(AM_REG_STIMER_COMPARE(0, ui32CmprInstance)) = ui32Delta;
// Read back the compare value
cmpVal = AM_REGVAL(AM_REG_STIMER_COMPARE(0, ui32CmprInstance));
// Make sure the value is in expected range
if (!AM_HAL_U32_SMALLER(cmpVal, expVal) && !AM_HAL_U32_GREATER(cmpVal, expMax))
{
break;
}
}
//
// Restore Compare Enable bit
//
CTIMER->STCFG |= cfgVal & (AM_HAL_STIMER_CFG_COMPARE_A_ENABLE << ui32CmprInstance);
//
// End the critical section.
//
AM_CRITICAL_END
}
//*****************************************************************************
//
//! @brief Get the current stimer compare register value.
//!
//! @param ui32CmprInstance is the compare register instance number (0-7).
//!
//! This function can be used to read the value in an stimer compare register.
//!
//!
//! @return None.
//
//*****************************************************************************
uint32_t
am_hal_stimer_compare_get(uint32_t ui32CmprInstance)
{
if ( ui32CmprInstance > 7 )
{
return 0;
}
return AM_REGVAL(AM_REG_STIMER_COMPARE(0, ui32CmprInstance));
}
//*****************************************************************************
//
//! @brief Start capturing data with the specified capture register.
//!
//! @param ui32CaptureNum is the Capture Register Number to read (0-3).
//! @param ui32GPIONumber is the pin number.
//! @param 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:
GPIO->STMRCAP_b.STPOL0 = bPolarity;
GPIO->STMRCAP_b.STSEL0 = ui32GPIONumber;
ui32CapCtrl = CTIMER_CAPTURECONTROL_CAPTURE0_Msk;
break;
case 1:
GPIO->STMRCAP_b.STPOL1 = bPolarity;
GPIO->STMRCAP_b.STSEL1 = ui32GPIONumber;
ui32CapCtrl = CTIMER_CAPTURECONTROL_CAPTURE1_Msk;
break;
case 2:
GPIO->STMRCAP_b.STPOL2 = bPolarity;
GPIO->STMRCAP_b.STSEL2 = ui32GPIONumber;
ui32CapCtrl = CTIMER_CAPTURECONTROL_CAPTURE2_Msk;
break;
case 3:
GPIO->STMRCAP_b.STPOL3 = bPolarity;
GPIO->STMRCAP_b.STSEL3 = ui32GPIONumber;
ui32CapCtrl = CTIMER_CAPTURECONTROL_CAPTURE3_Msk;
break;
default:
return; // error concealment.
}
//
// Enable it in the CTIMER Block
//
CTIMER->CAPTURECONTROL |= ui32CapCtrl;
}
//*****************************************************************************
//
//! @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.
//
CTIMER->CAPTURECONTROL &=
~(CTIMER_CAPTURECONTROL_CAPTURE0_Msk <<
((CTIMER_CAPTURECONTROL_CAPTURE1_Pos -
CTIMER_CAPTURECONTROL_CAPTURE0_Pos) * ui32CaptureNum));
}
//*****************************************************************************
//
//! @brief Get the current stimer nvram register value.
//!
//! @param ui32NvramNum is the NVRAM Register Number to read.
//! @param ui32NvramVal is the value to write to NVRAM.
//!
//! This function can be used to read the value in an stimer NVRAM register.
//!
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_stimer_nvram_set(uint32_t ui32NvramNum, uint32_t ui32NvramVal)
{
if ( ui32NvramNum > 3 )
{
return;
}
//AM_REGn(CTIMER, 0, SNVR)
//AM_REG_STIMER_NVRAM(0, ui32NvramNum) = ui32NvramVal;
}
//*****************************************************************************
//
//! @brief Get the current stimer nvram register value.
//!
//! @param ui32NvramNum is the NVRAM Register Number to read.
//!
//! This function can be used to read the value in an stimer NVRAM register.
//!
//!
//! @return None.
//
//*****************************************************************************
uint32_t am_hal_stimer_nvram_get(uint32_t ui32NvramNum)
{
if ( ui32NvramNum > 3 )
{
return 0;
}
return AM_REGVAL(AM_REG_STIMER_NVRAM(0, ui32NvramNum));
}
//*****************************************************************************
//
//! @brief Get the current stimer capture register value.
//!
//! @param ui32CaptureNum is the Capture Register Number to read.
//!
//! This function can be used to read the value in an stimer capture register.
//!
//!
//! @return None.
//
//*****************************************************************************
uint32_t am_hal_stimer_capture_get(uint32_t ui32CaptureNum)
{
if ( ui32CaptureNum > 3 )
{
return 0;
}
return AM_REGVAL(AM_REG_STIMER_CAPTURE(0, ui32CaptureNum));
}
//*****************************************************************************
//
//! @brief Enables the selected system timer interrupt.
//!
//! @param ui32Interrupt is the interrupt to be used.
//!
//! This function will enable the selected interrupts in the STIMER interrupt
//! enable register. In order to receive an interrupt from an stimer component,
//! you will need to enable the interrupt for that component in this main
//! register, as well as in the stimer configuration register (accessible though
//! am_hal_stimer_config()), and in the NVIC.
//!
//! ui32Interrupt should be the logical OR of one or more of the following
//! values:
//!
//! AM_HAL_STIMER_INT_COMPAREA
//! AM_HAL_STIMER_INT_COMPAREB
//! AM_HAL_STIMER_INT_COMPAREC
//! AM_HAL_STIMER_INT_COMPARED
//! AM_HAL_STIMER_INT_COMPAREE
//! AM_HAL_STIMER_INT_COMPAREF
//! AM_HAL_STIMER_INT_COMPAREG
//! AM_HAL_STIMER_INT_COMPAREH
//!
//! AM_HAL_STIMER_INT_OVERFLOW
//!
//! AM_HAL_STIMER_INT_CAPTUREA
//! AM_HAL_STIMER_INT_CAPTUREB
//! AM_HAL_STIMER_INT_CAPTUREC
//! AM_HAL_STIMER_INT_CAPTURED
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_stimer_int_enable(uint32_t ui32Interrupt)
{
//
// Enable the interrupt at the module level.
//
CTIMERn(0)->STMINTEN |= ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Return the enabled stimer interrupts.
//!
//! This function will return all enabled interrupts in the STIMER
//! interrupt enable register.
//!
//! @return return enabled interrupts. This will be a logical or of:
//!
//! AM_HAL_STIMER_INT_COMPAREA
//! AM_HAL_STIMER_INT_COMPAREB
//! AM_HAL_STIMER_INT_COMPAREC
//! AM_HAL_STIMER_INT_COMPARED
//! AM_HAL_STIMER_INT_COMPAREE
//! AM_HAL_STIMER_INT_COMPAREF
//! AM_HAL_STIMER_INT_COMPAREG
//! AM_HAL_STIMER_INT_COMPAREH
//!
//! AM_HAL_STIMER_INT_OVERFLOW
//!
//! AM_HAL_STIMER_INT_CAPTUREA
//! AM_HAL_STIMER_INT_CAPTUREB
//! AM_HAL_STIMER_INT_CAPTUREC
//! AM_HAL_STIMER_INT_CAPTURED
//!
//! @return Return the enabled timer interrupts.
//
//*****************************************************************************
uint32_t
am_hal_stimer_int_enable_get(void)
{
//
// Return enabled interrupts.
//
return CTIMERn(0)->STMINTEN;
}
//*****************************************************************************
//
//! @brief Disables the selected stimer interrupt.
//!
//! @param ui32Interrupt is the interrupt to be used.
//!
//! This function will disable the selected interrupts in the STIMER
//! interrupt register.
//!
//! ui32Interrupt should be the logical OR of one or more of the following
//! values:
//!
//! AM_HAL_STIMER_INT_COMPAREA
//! AM_HAL_STIMER_INT_COMPAREB
//! AM_HAL_STIMER_INT_COMPAREC
//! AM_HAL_STIMER_INT_COMPARED
//! AM_HAL_STIMER_INT_COMPAREE
//! AM_HAL_STIMER_INT_COMPAREF
//! AM_HAL_STIMER_INT_COMPAREG
//! AM_HAL_STIMER_INT_COMPAREH
//!
//! AM_HAL_STIMER_INT_OVERFLOW
//!
//! AM_HAL_STIMER_INT_CAPTUREA
//! AM_HAL_STIMER_INT_CAPTUREB
//! AM_HAL_STIMER_INT_CAPTUREC
//! AM_HAL_STIMER_INT_CAPTURED
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_stimer_int_disable(uint32_t ui32Interrupt)
{
//
// Disable the interrupt at the module level.
//
CTIMERn(0)->STMINTEN &= ~ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Sets the selected stimer interrupt.
//!
//! @param ui32Interrupt is the interrupt to be used.
//!
//! This function will set the selected interrupts in the STIMER
//! interrupt register.
//!
//! ui32Interrupt should be the logical OR of one or more of the following
//! values:
//!
//! AM_HAL_STIMER_INT_COMPAREA
//! AM_HAL_STIMER_INT_COMPAREB
//! AM_HAL_STIMER_INT_COMPAREC
//! AM_HAL_STIMER_INT_COMPARED
//! AM_HAL_STIMER_INT_COMPAREE
//! AM_HAL_STIMER_INT_COMPAREF
//! AM_HAL_STIMER_INT_COMPAREG
//! AM_HAL_STIMER_INT_COMPAREH
//!
//! AM_HAL_STIMER_INT_OVERFLOW
//!
//! AM_HAL_STIMER_INT_CAPTUREA
//! AM_HAL_STIMER_INT_CAPTUREB
//! AM_HAL_STIMER_INT_CAPTUREC
//! AM_HAL_STIMER_INT_CAPTURED
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_stimer_int_set(uint32_t ui32Interrupt)
{
//
// Set the interrupts.
//
CTIMERn(0)->STMINTSET = ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Clears the selected stimer interrupt.
//!
//! @param ui32Interrupt is the interrupt to be used.
//!
//! This function will clear the selected interrupts in the STIMER
//! interrupt register.
//!
//! ui32Interrupt should be the logical OR of one or more of the following
//! values:
//!
//! AM_HAL_STIMER_INT_COMPAREA
//! AM_HAL_STIMER_INT_COMPAREB
//! AM_HAL_STIMER_INT_COMPAREC
//! AM_HAL_STIMER_INT_COMPARED
//! AM_HAL_STIMER_INT_COMPAREE
//! AM_HAL_STIMER_INT_COMPAREF
//! AM_HAL_STIMER_INT_COMPAREG
//! AM_HAL_STIMER_INT_COMPAREH
//!
//! AM_HAL_STIMER_INT_OVERFLOW
//!
//! AM_HAL_STIMER_INT_CAPTUREA
//! AM_HAL_STIMER_INT_CAPTUREB
//! AM_HAL_STIMER_INT_CAPTUREC
//! AM_HAL_STIMER_INT_CAPTURED
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_stimer_int_clear(uint32_t ui32Interrupt)
{
//
// Disable the interrupt at the module level.
//
CTIMERn(0)->STMINTCLR = ui32Interrupt;
}
//*****************************************************************************
//
//! @brief Returns either the enabled or raw stimer interrupt status.
//!
//! This function will return the stimer interrupt status.
//!
//! @param bEnabledOnly if true returns the status of the enabled interrupts
//! only.
//!
//! The return value will be the logical OR of one or more of the following
//! values:
//!
//!
//! @return Returns the stimer interrupt status.
//
//*****************************************************************************
uint32_t
am_hal_stimer_int_status_get(bool bEnabledOnly)
{
//
// Return the desired status.
//
uint32_t ui32RetVal = CTIMERn(0)->STMINTSTAT;
if ( bEnabledOnly )
{
ui32RetVal &= CTIMERn(0)->STMINTEN;
}
return ui32RetVal;
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,217 @@
//*****************************************************************************
//
// am_hal_stimer.h
//! @file
//!
//! @brief Functions for interfacing with the system timer (STIMER).
//!
//! @addtogroup stimer3 System Timer (STIMER)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_STIMER_H
#define AM_HAL_STIMER_H
#ifdef __cplusplus
extern "C"
{
#endif
//
//! Compute address of a given COMPARE register.
//! @note - The parameter n should be 0 (as only 1 stimer module exists).
//! For Apollo3, the parameter r should be 0-7 (compare) or 0-3 (capture).
//
#define AM_REG_STIMER_COMPARE(n, r) (CTIMERADDRn(CTIMER, n, SCMPR0) + \
(r * (offsetof(CTIMER_Type, SCMPR1) - offsetof(CTIMER_Type, SCMPR0))))
//! Compute address of a given CAPTURE register. r should be 0-3.
#define AM_REG_STIMER_CAPTURE(n, r) (CTIMERADDRn(CTIMER, n, SCAPT0) + \
(r * (offsetof(CTIMER_Type, SCAPT1) - offsetof(CTIMER_Type, SCAPT0))))
//! Compute address of a given NVRAM register. r should be 0-3.
#define AM_REG_STIMER_NVRAM(n, r) (CTIMERADDRn(CTIMER, n, SNVR0) + \
(r * (offsetof(CTIMER_Type, SNVR1) - offsetof(CTIMER_Type, SNVR0))))
//*****************************************************************************
//
//! @name Interrupt Status Bits
//! @brief Interrupt Status Bits for enable/disble use
//!
//! These macros may be used to set and clear interrupt bits
//! @{
//
//*****************************************************************************
#define AM_HAL_STIMER_INT_COMPAREA CTIMER_STMINTSTAT_COMPAREA_Msk
#define AM_HAL_STIMER_INT_COMPAREB CTIMER_STMINTSTAT_COMPAREB_Msk
#define AM_HAL_STIMER_INT_COMPAREC CTIMER_STMINTSTAT_COMPAREC_Msk
#define AM_HAL_STIMER_INT_COMPARED CTIMER_STMINTSTAT_COMPARED_Msk
#define AM_HAL_STIMER_INT_COMPAREE CTIMER_STMINTSTAT_COMPAREE_Msk
#define AM_HAL_STIMER_INT_COMPAREF CTIMER_STMINTSTAT_COMPAREF_Msk
#define AM_HAL_STIMER_INT_COMPAREG CTIMER_STMINTSTAT_COMPAREG_Msk
#define AM_HAL_STIMER_INT_COMPAREH CTIMER_STMINTSTAT_COMPAREH_Msk
#define AM_HAL_STIMER_INT_OVERFLOW CTIMER_STMINTSTAT_OVERFLOW_Msk
#define AM_HAL_STIMER_INT_CAPTUREA CTIMER_STMINTSTAT_CAPTUREA_Msk
#define AM_HAL_STIMER_INT_CAPTUREB CTIMER_STMINTSTAT_CAPTUREB_Msk
#define AM_HAL_STIMER_INT_CAPTUREC CTIMER_STMINTSTAT_CAPTUREC_Msk
#define AM_HAL_STIMER_INT_CAPTURED CTIMER_STMINTSTAT_CAPTURED_Msk
//! @}
//*****************************************************************************
//
//! @name STimer Configuration Bits
//! @brief Interrupt Status Bits for enable/disble use
//!
//! These macros may be used to set and clear interrupt bits
//! @{
//
//*****************************************************************************
#define AM_HAL_STIMER_CFG_THAW _VAL2FLD(CTIMER_STCFG_FREEZE, CTIMER_STCFG_FREEZE_THAW)
#define AM_HAL_STIMER_CFG_FREEZE _VAL2FLD(CTIMER_STCFG_FREEZE, CTIMER_STCFG_FREEZE_FREEZE)
#define AM_HAL_STIMER_CFG_RUN _VAL2FLD(CTIMER_STCFG_CLEAR, CTIMER_STCFG_CLEAR_RUN)
#define AM_HAL_STIMER_CFG_CLEAR _VAL2FLD(CTIMER_STCFG_CLEAR, CTIMER_STCFG_CLEAR_CLEAR)
#define AM_HAL_STIMER_CFG_COMPARE_A_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_A_EN, CTIMER_STCFG_COMPARE_A_EN_ENABLE)
#define AM_HAL_STIMER_CFG_COMPARE_B_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_B_EN, CTIMER_STCFG_COMPARE_B_EN_ENABLE)
#define AM_HAL_STIMER_CFG_COMPARE_C_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_C_EN, CTIMER_STCFG_COMPARE_C_EN_ENABLE)
#define AM_HAL_STIMER_CFG_COMPARE_D_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_D_EN, CTIMER_STCFG_COMPARE_D_EN_ENABLE)
#define AM_HAL_STIMER_CFG_COMPARE_E_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_E_EN, CTIMER_STCFG_COMPARE_E_EN_ENABLE)
#define AM_HAL_STIMER_CFG_COMPARE_F_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_F_EN, CTIMER_STCFG_COMPARE_F_EN_ENABLE)
#define AM_HAL_STIMER_CFG_COMPARE_G_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_G_EN, CTIMER_STCFG_COMPARE_G_EN_ENABLE)
#define AM_HAL_STIMER_CFG_COMPARE_H_ENABLE _VAL2FLD(CTIMER_STCFG_COMPARE_H_EN, CTIMER_STCFG_COMPARE_H_EN_ENABLE)
//! @}
//*****************************************************************************
//
//! @name Clock Configuration options
//! @brief STimer Configuration register options.
//!
//! These options are to be used with the am_hal_stimer_config() function.
//! @{
//
//*****************************************************************************
#define AM_HAL_STIMER_NO_CLK _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_NOCLK)
#define AM_HAL_STIMER_HFRC_3MHZ _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_HFRC_DIV16)
#define AM_HAL_STIMER_HFRC_187_5KHZ _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_HFRC_DIV256)
#define AM_HAL_STIMER_XTAL_32KHZ _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_XTAL_DIV1)
#define AM_HAL_STIMER_XTAL_16KHZ _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_XTAL_DIV2)
#define AM_HAL_STIMER_XTAL_1KHZ _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_XTAL_DIV32)
#define AM_HAL_STIMER_LFRC_1KHZ _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_LFRC_DIV1)
#define AM_HAL_STIMER_HFRC_CTIMER0A _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_CTIMER0A)
#define AM_HAL_STIMER_HFRC_CTIMER0B _VAL2FLD(CTIMER_STCFG_CLKSEL, CTIMER_STCFG_CLKSEL_CTIMER0B)
//! @}
//*****************************************************************************
//
//! @name Capture Control Register options.
//! @brief Configuration options for capture control register.
//!
//! These options are to be used with the am_hal_stimer_capture_control_set
//! function.
//! @{
//
//*****************************************************************************
#define AM_HAL_STIMER_CAPTURE0_ENABLE _VAL2FLD(CTIMER_CAPTURECONTROL_CAPTURE0, CTIMER_CAPTURECONTROL_CAPTURE0_ENABLE)
#define AM_HAL_STIMER_CAPTURE1_ENABLE _VAL2FLD(CTIMER_CAPTURECONTROL_CAPTURE1, CTIMER_CAPTURECONTROL_CAPTURE1_ENABLE)
#define AM_HAL_STIMER_CAPTURE2_ENABLE _VAL2FLD(CTIMER_CAPTURECONTROL_CAPTURE2, CTIMER_CAPTURECONTROL_CAPTURE2_ENABLE)
#define AM_HAL_STIMER_CAPTURE3_ENABLE _VAL2FLD(CTIMER_CAPTURECONTROL_CAPTURE3, CTIMER_CAPTURECONTROL_CAPTURE3_ENABLE)
//! @}
//*****************************************************************************
//
//! Stimer configuration structure
//
//*****************************************************************************
typedef struct
{
//
//! Configuration options for the STIMER
//
uint32_t ui32STimerConfig;
}
am_hal_stimer_config_t;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern uint32_t am_hal_stimer_config(uint32_t ui32STimerConfig);
extern uint32_t am_hal_stimer_counter_get(void);
extern void am_hal_stimer_counter_clear(void);
extern void am_hal_stimer_compare_delta_set(uint32_t ui32CmprInstance,
uint32_t ui32Delta);
extern uint32_t am_hal_stimer_compare_get(uint32_t ui32CmprInstance);
extern void am_hal_stimer_capture_start(uint32_t ui32CaptureNum,
uint32_t ui32GPIONumber,
bool bPolarity);
extern void am_hal_stimer_capture_stop(uint32_t ui32CaptureNum);
extern uint32_t am_hal_stimer_capture_get(uint32_t ui32CaptureNum);
extern void am_hal_stimer_nvram_set(uint32_t ui32NvramNum, uint32_t ui32NvramVal);
extern uint32_t am_hal_stimer_nvram_get(uint32_t ui32NvramNum);
extern void am_hal_stimer_int_enable(uint32_t ui32Interrupt);
extern uint32_t am_hal_stimer_int_enable_get(void);
extern void am_hal_stimer_int_disable(uint32_t ui32Interrupt);
extern void am_hal_stimer_int_set(uint32_t ui32Interrupt);
extern void am_hal_stimer_int_clear(uint32_t ui32Interrupt);
extern uint32_t am_hal_stimer_int_status_get(bool bEnabledOnly);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_STIMER_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,278 @@
//*****************************************************************************
//
// am_hal_sysctrl.c
//! @file
//!
//! @brief Functions for interfacing with the M4F system control registers
//!
//! @addtogroup sysctrl3 System Control (SYSCTRL)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Globals
//
//*****************************************************************************
//
// g_ui32BusWriteFlush is used by the macro, am_hal_sysctrl_bus_write_flush().
// It is made global here to avoid compiler 'set but not used' warnings.
//
static volatile uint32_t g_ui32BusWriteFlush;
//*****************************************************************************
//
//! @brief Place the core into sleep or deepsleep.
//!
//! @param bSleepDeep - False for Normal or True Deep sleep.
//!
//! This function puts the MCU to sleep or deepsleep depending on bSleepDeep.
//!
//! Valid values for bSleepDeep are:
//!
//! AM_HAL_SYSCTRL_SLEEP_NORMAL
//! AM_HAL_SYSCTRL_SLEEP_DEEP
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_sysctrl_sleep(bool bSleepDeep)
{
//
// Disable interrupts and save the previous interrupt state.
//
AM_CRITICAL_BEGIN
//
// If the user selected DEEPSLEEP and the TPIU is off, attempt to enter
// DEEP SLEEP.
//
if ( (bSleepDeep == AM_HAL_SYSCTRL_SLEEP_DEEP) &&
(MCUCTRL->TPIUCTRL_b.ENABLE == MCUCTRL_TPIUCTRL_ENABLE_DIS) )
{
//
// Retrieve the reset generator status bits
// This gets reset on Deep Sleep, so we take a snapshot here
//
if (!gAmHalResetStatus)
{
gAmHalResetStatus = RSTGEN->STAT;
}
//
// Prepare the core for deepsleep (write 1 to the DEEPSLEEP bit).
//
SCB->SCR |= _VAL2FLD(SCB_SCR_SLEEPDEEP, 1);
}
else
{
//
// Prepare the core for normal sleep (write 0 to the DEEPSLEEP bit).
//
SCB->SCR &= ~_VAL2FLD(SCB_SCR_SLEEPDEEP, 1);
}
//
// Before executing WFI, flush any buffered core and peripheral writes.
//
__DSB();
am_hal_sysctrl_bus_write_flush();
//
// Execute the sleep instruction.
//
__WFI();
//
// Upon wake, execute the Instruction Sync Barrier instruction.
//
__ISB();
//
// Restore the interrupt state.
//
AM_CRITICAL_END
}
//*****************************************************************************
//
//! @brief Enable the floating point module.
//!
//! Call this function to enable the ARM hardware floating point module.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_sysctrl_fpu_enable(void)
{
//
// Enable access to the FPU in both privileged and user modes.
// NOTE: Write 0s to all reserved fields in this register.
//
SCB->CPACR = _VAL2FLD(SCB_CPACR_CP11, 0x3) |
_VAL2FLD(SCB_CPACR_CP10, 0x3);
}
//*****************************************************************************
//
//! @brief Disable the floating point module.
//!
//! Call this function to disable the ARM hardware floating point module.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_sysctrl_fpu_disable(void)
{
//
// Disable access to the FPU in both privileged and user modes.
// NOTE: Write 0s to all reserved fields in this register.
//
SCB->CPACR = 0x00000000 &
~(_VAL2FLD(SCB_CPACR_CP11, 0x3) |
_VAL2FLD(SCB_CPACR_CP10, 0x3));
}
//*****************************************************************************
//
//! @brief Enable stacking of FPU registers on exception entry.
//!
//! @param bLazy - Set to "true" to enable "lazy stacking".
//!
//! This function allows the core to save floating-point information to the
//! stack on exception entry. Setting the bLazy option enables "lazy stacking"
//! for interrupt handlers. Normally, mixing floating-point code and interrupt
//! driven routines causes increased interrupt latency, because the core must
//! save extra information to the stack upon exception entry. With the lazy
//! stacking option enabled, the core will skip the saving of floating-point
//! registers when possible, reducing average interrupt latency.
//!
//! @note At reset of the Cortex M4, the ASPEN and LSPEN bits are set to 1,
//! enabling Lazy mode by default. Therefore this function will generally
//! only have an affect when setting for full-context save (or when switching
//! from full-context to lazy mode).
//!
//! @note See also:
//! infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0298a/DAFGGBJD.html
//!
//! @note Three valid FPU context saving modes are possible.
//! 1. Lazy ASPEN=1 LSPEN=1 am_hal_sysctrl_fpu_stacking_enable(true)
//! and default.
//! 2. Full-context ASPEN=1 LSPEN=0 am_hal_sysctrl_fpu_stacking_enable(false)
//! 3. No FPU state ASPEN=0 LSPEN=0 am_hal_sysctrl_fpu_stacking_disable()
//! 4. Invalid ASPEN=0 LSPEN=1
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_sysctrl_fpu_stacking_enable(bool bLazy)
{
uint32_t ui32fpccr;
//
// Set the requested FPU stacking mode in ISRs.
//
AM_CRITICAL_BEGIN
#define SYSCTRL_FPCCR_LAZY (FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk)
ui32fpccr = FPU->FPCCR;
ui32fpccr &= ~SYSCTRL_FPCCR_LAZY;
ui32fpccr |= (bLazy ? SYSCTRL_FPCCR_LAZY : FPU_FPCCR_ASPEN_Msk);
FPU->FPCCR = ui32fpccr;
AM_CRITICAL_END
}
//*****************************************************************************
//
//! @brief Disable FPU register stacking on exception entry.
//!
//! This function disables all stacking of floating point registers for
//! interrupt handlers. This mode should only be used when it is absolutely
//! known that no FPU instructions will be executed in an ISR.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_sysctrl_fpu_stacking_disable(void)
{
//
// Completely disable FPU context save on entry to ISRs.
//
AM_CRITICAL_BEGIN
FPU->FPCCR &= ~SYSCTRL_FPCCR_LAZY;
AM_CRITICAL_END
}
//*****************************************************************************
//
//! @brief Issue a system wide reset using the AIRCR bit in the M4 system ctrl.
//!
//! This function issues a system wide reset (Apollo POR level reset).
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_sysctrl_aircr_reset(void)
{
//
// Set the system reset bit in the AIRCR register
//
__NVIC_SystemReset();
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,117 @@
//*****************************************************************************
//
// am_hal_sysctrl.h
//! @file
//!
//! @brief Functions for interfacing with the M4F system control registers
//!
//! @addtogroup sysctrl3 System Control (SYSCTRL)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_SYSCTRL_H
#define AM_HAL_SYSCTRL_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Definitions for sleep mode parameter
//
//*****************************************************************************
#define AM_HAL_SYSCTRL_SLEEP_DEEP true
#define AM_HAL_SYSCTRL_SLEEP_NORMAL false
//*****************************************************************************
//
// Definition of Global Power State enumeration
//
//*****************************************************************************
typedef enum
{
AM_HAL_SYSCTRL_WAKE,
AM_HAL_SYSCTRL_NORMALSLEEP,
AM_HAL_SYSCTRL_DEEPSLEEP
} am_hal_sysctrl_power_state_e;
//*****************************************************************************
//
// Write flush - This function will hold the bus until all queued write
// operations have completed, thereby guaranteeing that all writes have
// been flushed.
//
//*****************************************************************************
#define SYNC_READ 0x5FFF0000
#define am_hal_sysctrl_bus_write_flush() \
if ( 1 ) \
{ \
uint32_t *pui32Flush = (uint32_t*)SYNC_READ; \
g_ui32BusWriteFlush = *pui32Flush; \
}
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_sysctrl_sleep(bool bSleepDeep);
extern void am_hal_sysctrl_fpu_enable(void);
extern void am_hal_sysctrl_fpu_disable(void);
extern void am_hal_sysctrl_fpu_stacking_enable(bool bLazy);
extern void am_hal_sysctrl_fpu_stacking_disable(void);
extern void am_hal_sysctrl_aircr_reset(void);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_SYSCTRL_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,350 @@
//*****************************************************************************
//
// am_hal_systick.c
//! @file
//!
//! @brief Functions for interfacing with the SYSTICK
//!
//! @addtogroup systick3 System Timer (SYSTICK)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
#define SYSTICK_MAX_TICKS ((1 << 24)-1)
#define MAX_U32 (0xffffffff)
//*****************************************************************************
//
//! @brief Start the SYSTICK.
//!
//! This function starts the systick timer.
//!
//! @note This timer does not run in deep-sleep mode as it runs from the core
//! clock, which is gated in deep-sleep. If a timer is needed in deep-sleep use
//! one of the ctimers instead. Also to note is this timer will consume higher
//! power than the ctimers.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_systick_start(void)
{
//
// Start the systick timer.
//
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
//*****************************************************************************
//
//! @brief Stop the SYSTICK.
//!
//! This function stops the systick timer.
//!
//! @note This timer does not run in deep-sleep mode as it runs from the core
//! clock, which is gated in deep-sleep. If a timer is needed in deep-sleep use
//! one of the ctimers instead. Also to note is this timer will consume higher
//! power than the ctimers.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_systick_stop(void)
{
//
// Stop the systick timer.
//
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
//*****************************************************************************
//
//! @brief Enable the interrupt in the SYSTICK.
//!
//! This function enables the interupt in the systick timer.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_systick_int_enable(void)
{
//
// Enable the systick timer interrupt.
//
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
}
//*****************************************************************************
//
//! @brief Disable the interrupt in the SYSTICK.
//!
//! This function disables the interupt in the systick timer.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_systick_int_disable(void)
{
//
// Disable the systick timer interrupt.
//
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
}
//*****************************************************************************
//
//! @brief Reads the interrupt status.
//!
//! This function reads the interrupt status in the systick timer.
//!
//! @return the interrupt status.
//
//*****************************************************************************
uint32_t
am_hal_systick_int_status_get(void)
{
//
// Return the systick timer interrupt status.
//
return SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk;
}
//*****************************************************************************
//
//! @brief Reset the interrupt in the SYSTICK.
//!
//! This function resets the systick timer by clearing out the configuration
//! register.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_systick_reset(void)
{
//
// Reset the systick timer interrupt.
//
SysTick->CTRL = 0x0;
}
//*****************************************************************************
//
//! @brief Load the value into the SYSTICK.
//!
//! @param ui32LoadVal the desired load value for the systick. Maximum value is
//! 0x00FF.FFFF.
//!
//! This function loads the desired value into the systick timer.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_systick_load(uint32_t ui32LoadVal)
{
//
// The proper SysTick initialization sequence is: (p 4-36 of the M4 UG).
// 1. Program reload value
// 2. Clear current value
// 3. Program CSR
// Write the given value to the reload register.
// Write the Current Value Register to clear it to 0.
//
SysTick->LOAD = ui32LoadVal;
SysTick->VAL = 0;
}
//*****************************************************************************
//
//! @brief Get the current count value in the SYSTICK.
//!
//! This function gets the current count value in the systick timer.
//!
//! @return Current count value.
//
//*****************************************************************************
uint32_t
am_hal_systick_count(void)
{
//
// Return the current systick timer count value.
//
return SysTick->VAL;
}
//*****************************************************************************
//
//! @brief Wait the specified number of ticks.
//!
//! This function delays for the given number of SysTick ticks.
//!
//! @note If the SysTick timer is being used elsewhere, it will be corrupted
//! by calling this function.
//!
//! @return 0 if successful.
//
//*****************************************************************************
uint32_t
am_hal_systick_wait_ticks(uint32_t ui32Ticks)
{
if ( ui32Ticks == 0 )
{
ui32Ticks++; // Make sure we get the COUNTFLAG
}
//
// The proper SysTick initialization sequence is: (p 4-36 of the M4 UG).
// 1. Program reload value
// 2. Clear current value
// 3. Program CSR
//
// Set the reload value to the required number of ticks.
//
SysTick->LOAD = ui32Ticks;
//
// Clear the current count.
//
SysTick->VAL = 0x0;
//
// Set to use the processor clock, but don't cause an exception (we'll poll).
//
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
//
// Poll till done
//
while ( !(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) );
//
// And disable systick before exiting.
//
SysTick->CTRL = 0x0;
return 0;
}
//*****************************************************************************
//
//! @brief Delay the specified number of microseconds.
//!
//! This function will use the SysTick timer to delay until the specified
//! number of microseconds have elapsed. It uses the processor clocks and
//! takes into account the current CORESEL setting.
//!
//! @note If the SysTick timer is being used elsewhere, it will be corrupted
//! by calling this function.
//!
//! @return Total number of SysTick ticks delayed.
//
//*****************************************************************************
uint32_t
am_hal_systick_delay_us(uint32_t ui32NumUs)
{
uint32_t ui32nLoops, ui32Ticks, uRet;
uint32_t ui32ClkFreq, ui32TicksPerMHz;
uint32_t ui32CoreSel = CLKGEN->CCTRL_b.CORESEL;
ui32nLoops = 0;
if ( (ui32CoreSel <= AM_HAL_CLKGEN_CORESEL_MAXDIV) && (ui32NumUs >= 2) )
{
//
// Determine clock freq, then whether we need more than 1 iteration.
//
ui32ClkFreq = AM_HAL_CLKGEN_FREQ_MAX_MHZ >> ui32CoreSel;
ui32ClkFreq <<= (am_hal_burst_mode_status() == AM_HAL_BURST_MODE)? 1 : 0;
ui32TicksPerMHz = SYSTICK_MAX_TICKS / ui32ClkFreq;
if ( ui32NumUs > ui32TicksPerMHz )
{
//
// Get number of required loops, as well as additional ticks.
//
ui32nLoops = ui32NumUs / ui32TicksPerMHz;
ui32NumUs = ui32NumUs % ui32TicksPerMHz;
}
//
// Compute the number of ticks required.
// Allow for about 2us of call overhead.
//
ui32Ticks = (ui32NumUs - 2) * ui32ClkFreq;
}
else
{
ui32Ticks = 1;
}
uRet = (ui32nLoops * SYSTICK_MAX_TICKS) + ui32Ticks;
while ( ui32nLoops )
{
am_hal_systick_wait_ticks(SYSTICK_MAX_TICKS);
ui32nLoops--;
}
am_hal_systick_wait_ticks(ui32Ticks);
return uRet;
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,86 @@
//*****************************************************************************
//
// am_hal_systick.h
//! @file
//!
//! @brief Functions for accessing and configuring the SYSTICK.
//!
//! @addtogroup systick3 System Timer (SYSTICK)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_SYSTICK_H
#define AM_HAL_SYSTICK_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_systick_start(void);
extern void am_hal_systick_stop(void);
extern void am_hal_systick_int_enable(void);
extern void am_hal_systick_int_disable(void);
extern uint32_t am_hal_systick_int_status_get(void);
extern void am_hal_systick_reset(void);
extern void am_hal_systick_load(uint32_t ui32LoadVal);
extern uint32_t am_hal_systick_count(void);
extern uint32_t am_hal_systick_wait_ticks(uint32_t u32Ticks);
extern uint32_t am_hal_systick_delay_us(uint32_t u32NumUs);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_SYSTICK_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,393 @@
//*****************************************************************************
//
// am_hal_tpiu.c
//! @file
//!
//! @brief Support functions for the ARM TPIU module
//!
//! Provides support functions for configuring the ARM TPIU module
//!
//! @addtogroup tpiu3 Trace Port Interface Unit (TPIU)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
//! @brief Enable the clock to the TPIU module.
//!
//! This function enables the clock to the TPIU module.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_tpiu_clock_enable(void)
{
//
// Enable the TPIU clock
//
MCUCTRL->TPIUCTRL |= MCUCTRL_TPIUCTRL_ENABLE_Msk;
}
//*****************************************************************************
//
//! @brief Disable the clock to the TPIU module.
//!
//! This function disables the clock to the TPIU module.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_tpiu_clock_disable(void)
{
//
// Disable the TPIU clock
//
MCUCTRL->TPIUCTRL &= ~MCUCTRL_TPIUCTRL_ENABLE_Msk;
}
//*****************************************************************************
//
//! @brief Set the output port width of the TPIU
//!
//! @param ui32PortWidth - The desired port width (in bits)
//!
//! This function uses the TPIU_CSPSR register to set the desired output port
//! width of the TPIU.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_tpiu_port_width_set(uint32_t ui32PortWidth)
{
TPI->CSPSR = 1 << (ui32PortWidth - 1);
}
//*****************************************************************************
//
//! @brief Read the supported_output port width of the TPIU
//!
//! This function uses the \e TPIU_SSPSR register to set the supported output
//! port widths of the TPIU.
//!
//! @return Current width of the TPIU output port
//
//*****************************************************************************
uint32_t
am_hal_tpiu_supported_port_width_get(void)
{
uint32_t i, ui32WidthValue;
//
// Read the supported width register.
//
ui32WidthValue = TPI->SSPSR;
//
// The register value is encoded in a one-hot format, so the position of
// the single set bit determines the actual width of the port.
//
for (i = 1; i < 32; i++)
{
//
// Check each bit for a '1'. When we find it, our current loop index
// will be equal to the port width.
//
if (ui32WidthValue == (0x1 << (i - 1)))
{
return i;
}
}
//
// We should never get here, but if we do, just return the smallest
// possible value for a supported trace port width.
//
return 1;
}
//*****************************************************************************
//
//! @brief Read the output port width of the TPIU
//!
//! This function uses the \e TPIU_CSPSR register to set the desired output
//! port width of the TPIU.
//!
//! @return Current width of the TPIU output port
//
//*****************************************************************************
uint32_t
am_hal_tpiu_port_width_get(void)
{
uint32_t ui32Temp;
uint32_t ui32Width;
ui32Width = 1;
ui32Temp = TPI->CSPSR;
while ( !(ui32Temp & 1) )
{
ui32Temp = ui32Temp >> 1;
ui32Width++;
if (ui32Width > 32)
{
ui32Width = 0;
break;
}
}
//
// Current width of the TPIU output port.
//
return ui32Width;
}
//*****************************************************************************
//
//! @brief Configure the TPIU based on the values in the configuration struct.
//!
//! @param psConfig - pointer to an am_hal_tpiu_config_t structure containing
//! the desired configuration information.
//!
//! This function reads the provided configuration structure, and sets the
//! relevant TPIU registers to achieve the desired configuration.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_tpiu_configure(am_hal_tpiu_config_t *psConfig)
{
//
// Set the clock freq in the MCUCTRL register.
//
MCUCTRL->TPIUCTRL |= psConfig->ui32TraceClkIn;
//
// Set the desired protocol.
//
TPI->SPPR = psConfig->ui32PinProtocol;
//
// Set the parallel port width. This may be redundant if the user has
// selected a serial protocol, but we'll set it anyway.
//
TPI->CSPSR = (1 << (psConfig->ui32ParallelPortSize - 1));
//
// Set the clock prescaler.
//
TPI->ACPR = psConfig->ui32ClockPrescaler;
}
//*****************************************************************************
//
//! @brief Enables the TPIU
//!
//! This function enables the ARM TPIU by setting the TPIU registers and then
//! enabling the TPIU clock source in MCU control register.
//!
//! @param psConfig - structure for configuration.
//! If ui32SetItmBaud, the other structure members are used to set the
//! TPIU configuration.
//! But for simplicity, ui32SetItmBaud can be set to one of the
//! following, in which case all other structure members are ignored.
//! In this case, the given BAUD rate is based on a div-by-8 HFRC clock.
//! AM_HAL_TPIU_BAUD_57600
//! AM_HAL_TPIU_BAUD_115200
//! AM_HAL_TPIU_BAUD_230400
//! AM_HAL_TPIU_BAUD_460800
//! AM_HAL_TPIU_BAUD_500000
//! AM_HAL_TPIU_BAUD_1M
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_tpiu_enable(am_hal_tpiu_config_t *psConfig)
{
am_hal_clkgen_status_t sClkGenStatus;
uint32_t ui32HFRC, ui32SWOscaler, ui32ITMbitrate;
ui32ITMbitrate = psConfig->ui32SetItmBaud;
//
// TPIU formatter & flush control register.
//
TPI->FFCR = 0;
if ( ui32ITMbitrate )
{
//
// Set the Current Parallel Port Size (note - only 1 bit can be set).
//
TPI->CSPSR = TPI_CSPSR_CWIDTH_1BIT;
//
// Use some default assumptions to set the ITM frequency.
//
if ( (ui32ITMbitrate < AM_HAL_TPIU_BAUD_57600 ) ||
(ui32ITMbitrate > AM_HAL_TPIU_BAUD_2M ) )
{
ui32ITMbitrate = AM_HAL_TPIU_BAUD_DEFAULT;
}
//
// Get the current HFRC frequency.
//
am_hal_clkgen_status_get(&sClkGenStatus);
ui32HFRC = sClkGenStatus.ui32SysclkFreq;
//
// Compute the SWO scaler value.
//
if ( ui32HFRC != 0xFFFFFFFF )
{
ui32SWOscaler = ((ui32HFRC / 8) / ui32ITMbitrate) - 1;
}
else
{
ui32SWOscaler = ( (AM_HAL_CLKGEN_FREQ_MAX_HZ / 8) /
AM_HAL_TPIU_BAUD_DEFAULT ) - 1;
}
//
// Set the scaler value.
//
TPI->ACPR = _VAL2FLD(TPI_ACPR_SWOSCALER, ui32SWOscaler);
//
// Set for UART mode
//
TPI->SPPR = _VAL2FLD( TPI_SPPR_TXMODE, TPI_SPPR_TXMODE_UART);
//
// Make sure we are not in test mode (important for proper deep sleep
// operation).
//
TPI->ITCTRL = _VAL2FLD(TPI_ITCTRL_Mode, TPI_ITCTRL_Mode_NORMAL);
//
// Enable the TPIU clock source in MCU control.
// Set TPIU clock for HFRC/8 (6MHz) operation.
//
MCUCTRL->TPIUCTRL =
_VAL2FLD(MCUCTRL_TPIUCTRL_CLKSEL, MCUCTRL_TPIUCTRL_CLKSEL_HFRCDIV8) |
_VAL2FLD(MCUCTRL_TPIUCTRL_ENABLE, MCUCTRL_TPIUCTRL_ENABLE_EN);
}
else
{
//
// Set the configuration according to the structure values.
//
//
// Set the Asynchronous Clock Prescaler Register.
//
TPI->ACPR = psConfig->ui32ClockPrescaler;
//
// Set the Selected Pin Protocol Register.
// e.g. AM_REG_TPIU_SPPR_TXMODE_UART
//
TPI->SPPR = psConfig->ui32PinProtocol;
//
// Set the Current Parallel Port Size (note - only 1 bit can be set).
// This may be redundant if the user has selected a serial protocol,
// but we'll set it anyway.
//
TPI->CSPSR = (1 << (psConfig->ui32ParallelPortSize - 1));
//
// Make sure we are not in test mode (important for proper deep sleep
// operation).
//
TPI->ITCTRL = _VAL2FLD(TPI_ITCTRL_Mode, TPI_ITCTRL_Mode_NORMAL);
//
// Set the clock freq and enable fields in the MCUCTRL register.
//
MCUCTRL->TPIUCTRL = psConfig->ui32TraceClkIn;
}
//
// Wait for 50us for the data to flush out.
//
am_hal_flash_delay(FLASH_CYCLES_US(50));
}
//*****************************************************************************
//
//! @brief Disables the TPIU
//!
//! This function disables the ARM TPIU by disabling the TPIU clock source
//! in MCU control register.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_tpiu_disable(void)
{
//
// Disable the TPIU clock source in MCU control.
//
MCUCTRL->TPIUCTRL =
_VAL2FLD(MCUCTRL_TPIUCTRL_CLKSEL, MCUCTRL_TPIUCTRL_CLKSEL_LOWPWR) |
_VAL2FLD(MCUCTRL_TPIUCTRL_ENABLE, MCUCTRL_TPIUCTRL_ENABLE_DIS);
}
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,197 @@
//*****************************************************************************
//
// am_hal_tpiu.h
//! @file
//!
//! @brief Definitions and structures for working with the TPIU.
//!
//! @addtogroup tpiu3 Trace Port Interface Unit (TPIU)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_TPIU_H
#define AM_HAL_TPIU_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// TPIU bit rate defines.
//
//*****************************************************************************
#define AM_HAL_TPIU_BAUD_57600 (115200 / 2)
#define AM_HAL_TPIU_BAUD_115200 (115200 * 1)
#define AM_HAL_TPIU_BAUD_230400 (115200 * 2)
#define AM_HAL_TPIU_BAUD_460800 (115200 * 4)
#define AM_HAL_TPIU_BAUD_250000 (1000000 / 4)
#define AM_HAL_TPIU_BAUD_500000 (1000000 / 2)
#define AM_HAL_TPIU_BAUD_1M (1000000 * 1)
#define AM_HAL_TPIU_BAUD_2M (1000000 * 2)
#define AM_HAL_TPIU_BAUD_DEFAULT (AM_HAL_TPIU_BAUD_1M)
//*****************************************************************************
//
// TPIU register defines.
//
//*****************************************************************************
#define AM_HAL_TPIU_SSPSR 0xE0040000 //! Supported Parallel Port Sizes
#define AM_HAL_TPIU_CSPSR 0xE0040004 //! Current Parallel Port Size
#define AM_HAL_TPIU_ACPR 0xE0040010 //! Asynchronous Clock Prescaler
#define AM_HAL_TPIU_SPPR 0xE00400F0 //! Selected Pin Protocol
#define AM_HAL_TPIU_TYPE 0xE0040FC8 //! TPIU Type
//*****************************************************************************
//
// TPIU ACPR defines.
//
//*****************************************************************************
#define AM_HAL_TPIU_ACPR_SWOSCALER_M 0x0000FFFF //! SWO baud rate prescalar
//*****************************************************************************
//
// TPIU_SPPR TXMODE defines.
//
//*****************************************************************************
#define AM_HAL_TPIU_SPPR_PARALLEL 0x00000000
#define AM_HAL_TPIU_SPPR_MANCHESTER 0x00000001
#define AM_HAL_TPIU_SPPR_NRZ 0x00000002
//*****************************************************************************
//
// TPIU Type defines
//
//*****************************************************************************
#define AM_HAL_TPIU_TYPE_NRZVALID 0x00000800
#define AM_HAL_TPIU_TYPE_MANCVALID 0x00000400
#define AM_HAL_TPIU_TYPE_PTINVALID 0x00000200
#define AM_HAL_TPIU_TYPE_FIFOSZ_M 0x000001C0
//*****************************************************************************
//
// TPIU Clock defines
//
//*****************************************************************************
#define AM_HAL_TPIU_TRACECLKIN_6MHZ AM_REG_MCUCTRL_TPIUCTRL_CLKSEL(0)
#define AM_HAL_TPIU_TRACECLKIN_3MHZ AM_REG_MCUCTRL_TPIUCTRL_CLKSEL(1)
#define AM_HAL_TPIU_TRACECLKIN_1_5MHZ AM_REG_MCUCTRL_TPIUCTRL_CLKSEL(2)
#define AM_HAL_TPIU_TRACECLKIN_750KHZ AM_REG_MCUCTRL_TPIUCTRL_CLKSEL(3)
//*****************************************************************************
//
//! @brief Structure used for configuring the TPIU
//
//*****************************************************************************
typedef struct
{
//
// If ui32SetItmBaud is non-zero, the ITM frequency is set to the given
// frequency, and is based on a divide-by-8 HFRC TPIU clock.
// If zero, other structure members are used to set the TPIU configuration.
//
uint32_t ui32SetItmBaud;
//
//! MCU Control TRACECLKIN clock freq.
//!
//! Valid values for ui32TraceClkIn are:
//!
//! AM_HAL_TPIU_TRACECLKIN_6MHZ
//! AM_HAL_TPIU_TRACECLKIN_3MHZ
//! AM_HAL_TPIU_TRACECLKIN_1_5MHZ
//! AM_HAL_TPIU_TRACECLKIN_750KHZ
//
uint32_t ui32TraceClkIn;
//
//! Protocol to use for the TPIU
//!
//! Valid values for ui32PinProtocol are:
//!
//! AM_HAL_TPIU_SPPR_PARALLEL
//! AM_HAL_TPIU_SPPR_MANCHESTER
//! AM_HAL_TPIU_SPPR_NRZ
//
uint32_t ui32PinProtocol;
//
//! Desired width of the TPIU parallel port
//
uint32_t ui32ParallelPortSize;
//
//! Desired Clock prescaler value
//
uint32_t ui32ClockPrescaler;
}
am_hal_tpiu_config_t;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_tpiu_clock_enable(void);
extern void am_hal_tpiu_clock_disable(void);
extern void am_hal_tpiu_port_width_set(uint32_t ui32PortWidth);
extern uint32_t am_hal_tpiu_supported_port_width_get(void);
extern uint32_t am_hal_tpiu_port_width_get(void);
extern void am_hal_tpiu_configure(am_hal_tpiu_config_t *psConfig);
extern void am_hal_tpiu_enable(am_hal_tpiu_config_t *psConfig);
extern void am_hal_tpiu_disable(void);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_TPIU_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,723 @@
//*****************************************************************************
//
// am_hal_uart.h
//! @file
//!
//! @brief Functions for accessing and configuring the UART.
//!
//! @addtogroup uart3 UART
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_UART_H
#define AM_HAL_UART_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// CMSIS-style macro for handling a variable MSPI module number.
//
#define UARTn(n) ((UART0_Type*)(UART0_BASE + (n * (UART1_BASE - UART0_BASE))))
//*****************************************************************************
//*****************************************************************************
//
// UART configuration options.
//
//*****************************************************************************
typedef struct
{
//
// Standard UART options.
//
uint32_t ui32BaudRate;
uint32_t ui32DataBits;
uint32_t ui32Parity;
uint32_t ui32StopBits;
uint32_t ui32FlowControl;
//
// Additional options.
//
uint32_t ui32FifoLevels;
//
// Buffers
//
uint8_t *pui8TxBuffer;
uint32_t ui32TxBufferSize;
uint8_t *pui8RxBuffer;
uint32_t ui32RxBufferSize;
}
am_hal_uart_config_t;
//*****************************************************************************
//
// @brief UART transfer structure.
//
// This structure describes a UART transaction that can be performed by \e
// am_hal_uart_transfer()
//
//*****************************************************************************
typedef struct
{
//! Determines whether data should be read or written.
//!
//! Should be either AM_HAL_UART_WRITE or AM_HAL_UART_READ
uint32_t ui32Direction;
//! Pointer to data to be sent, or space to fill with received data.
uint8_t *pui8Data;
//! Number of bytes to send or receive.
uint32_t ui32NumBytes;
//! Timeout in milliseconds.
//!
//! Given a timeout value, the \e am_hal_uart_transfer() function will keep
//! trying to transfer data until either the number of bytes is satisfied,
//! or the time runs out. If provided with a value of zero, the transfer
//! function will only send as much data as it can immediately deal with.
//! If provided with a timeout value of \e AM_HAL_UART_WAIT_FOREVER, the
//! function will block until either the final "read" byte is received or
//! the final "write" byte is placed in the output buffer.
uint32_t ui32TimeoutMs;
//! Number of bytes successfully transferred.
uint32_t *pui32BytesTransferred;
}
am_hal_uart_transfer_t;
//*****************************************************************************
//
// Maximum baudrate supported is 921600 for Apollo3-A1 and 1.5Mbaud for
// Apollo3-B0.
//
//*****************************************************************************
#define AM_HAL_UART_MAXIMUM_BAUDRATE_A1 921600
#define AM_HAL_UART_MAXIMUM_BAUDRATE_B0 1500000
//*****************************************************************************
//
// Uart transfer options.
//
//*****************************************************************************
#define AM_HAL_UART_WRITE 0
#define AM_HAL_UART_READ 1
#define AM_HAL_UART_WAIT_FOREVER 0xFFFFFFFF
//*****************************************************************************
//
// UART conficuration option values.
//
//*****************************************************************************
// Data bits.
#define AM_HAL_UART_DATA_BITS_8 (_VAL2FLD(UART0_LCRH_WLEN, 3))
#define AM_HAL_UART_DATA_BITS_7 (_VAL2FLD(UART0_LCRH_WLEN, 2))
#define AM_HAL_UART_DATA_BITS_6 (_VAL2FLD(UART0_LCRH_WLEN, 1))
#define AM_HAL_UART_DATA_BITS_5 (_VAL2FLD(UART0_LCRH_WLEN, 0))
// Parity.
#define AM_HAL_UART_PARITY_NONE 0
#define AM_HAL_UART_PARITY_ODD UART0_LCRH_PEN_Msk
#define AM_HAL_UART_PARITY_EVEN (UART0_LCRH_PEN_Msk | \
UART0_LCRH_EPS_Msk)
// Stop Bits
#define AM_HAL_UART_ONE_STOP_BIT (_VAL2FLD(UART0_LCRH_STP2, 0))
#define AM_HAL_UART_TWO_STOP_BITS (_VAL2FLD(UART0_LCRH_STP2, 1))
// Flow control
#define AM_HAL_UART_FLOW_CTRL_NONE 0
#define AM_HAL_UART_FLOW_CTRL_CTS_ONLY UART0_CR_CTSEN_Msk
#define AM_HAL_UART_FLOW_CTRL_RTS_ONLY UART0_CR_RTSEN_Msk
#define AM_HAL_UART_FLOW_CTRL_RTS_CTS (UART0_CR_CTSEN_Msk | \
UART0_CR_RTSEN_Msk)
// FIFO enable/disable.
#define AM_HAL_UART_FIFO_ENABLE (_VAL2FLD(UART0_LCRH_FEN, 1))
#define AM_HAL_UART_FIFO_DISABLE (_VAL2FLD(UART0_LCRH_FEN, 0))
// TX FIFO interrupt level settings.
#define AM_HAL_UART_TX_FIFO_1_8 (_VAL2FLD(UART0_IFLS_TXIFLSEL, 0))
#define AM_HAL_UART_TX_FIFO_1_4 (_VAL2FLD(UART0_IFLS_TXIFLSEL, 1))
#define AM_HAL_UART_TX_FIFO_1_2 (_VAL2FLD(UART0_IFLS_TXIFLSEL, 2))
#define AM_HAL_UART_TX_FIFO_3_4 (_VAL2FLD(UART0_IFLS_TXIFLSEL, 3))
#define AM_HAL_UART_TX_FIFO_7_8 (_VAL2FLD(UART0_IFLS_TXIFLSEL, 4))
// RX FIFO interrupt level settings.
#define AM_HAL_UART_RX_FIFO_1_8 (_VAL2FLD(UART0_IFLS_RXIFLSEL, 0))
#define AM_HAL_UART_RX_FIFO_1_4 (_VAL2FLD(UART0_IFLS_RXIFLSEL, 1))
#define AM_HAL_UART_RX_FIFO_1_2 (_VAL2FLD(UART0_IFLS_RXIFLSEL, 2))
#define AM_HAL_UART_RX_FIFO_3_4 (_VAL2FLD(UART0_IFLS_RXIFLSEL, 3))
#define AM_HAL_UART_RX_FIFO_7_8 (_VAL2FLD(UART0_IFLS_RXIFLSEL, 4))
//*****************************************************************************
//
// UART interrupts.
//
//*****************************************************************************
#define AM_HAL_UART_INT_OVER_RUN UART0_IER_OEIM_Msk
#define AM_HAL_UART_INT_BREAK_ERR UART0_IER_BEIM_Msk
#define AM_HAL_UART_INT_PARITY_ERR UART0_IER_PEIM_Msk
#define AM_HAL_UART_INT_FRAME_ERR UART0_IER_FEIM_Msk
#define AM_HAL_UART_INT_RX_TMOUT UART0_IER_RTIM_Msk
#define AM_HAL_UART_INT_TX UART0_IER_TXIM_Msk
#define AM_HAL_UART_INT_RX UART0_IER_RXIM_Msk
#define AM_HAL_UART_INT_DSRM UART0_IER_DSRMIM_Msk
#define AM_HAL_UART_INT_DCDM UART0_IER_DCDMIM_Msk
#define AM_HAL_UART_INT_CTSM UART0_IER_CTSMIM_Msk
#define AM_HAL_UART_INT_TXCMP UART0_IER_TXCMPMIM_Msk
//*****************************************************************************
//
//! @name UART Flag Register
//! @brief Macro definitions for UART Flag Register Bits.
//!
//! They may be used with the \e am_hal_uart_flags_get() function.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_UART_FR_TX_EMPTY (_VAL2FLD(UART0_FR_TXFE, UART0_FR_TXFE_XMTFIFO_EMPTY))
#define AM_HAL_UART_FR_RX_FULL (_VAL2FLD(UART0_FR_RXFF, UART0_FR_RXFF_RCVFIFO_FULL))
#define AM_HAL_UART_FR_TX_FULL (_VAL2FLD(UART0_FR_TXFF, UART0_FR_TXFF_XMTFIFO_FULL))
#define AM_HAL_UART_FR_RX_EMPTY (_VAL2FLD(UART0_FR_RXFE, UART0_FR_RXFE_RCVFIFO_EMPTY))
#define AM_HAL_UART_FR_BUSY (_VAL2FLD(UART0_FR_BUSY, UART0_FR_BUSY_BUSY))
#define AM_HAL_UART_FR_DCD_DETECTED (_VAL2FLD(UART0_FR_DCD, UART0_FR_DCD_DETECTED))
#define AM_HAL_UART_FR_DSR_READY (_VAL2FLD(UART0_FR_DSR, UART0_FR_DSR_READY))
#define AM_HAL_UART_FR_CTS UART0_FR_CTS_Msk
//! @}
//*****************************************************************************
//
// UART FIFO size for Apollo3.
//
//*****************************************************************************
#define AM_HAL_UART_FIFO_MAX 32
//*****************************************************************************
//
// Turn timeouts into indefinite waits.
//
//*****************************************************************************
#define AM_HAL_UART_WAIT_FOREVER 0xFFFFFFFF
//*****************************************************************************
//
//! @brief Initialize the UART interface.
//!
//! @param ui32Module is the module number for the UART to initialize.
//! @param ppHandle is the location to write the UART handle.
//!
//! This function sets internal tracking variables associated with a specific
//! UART module. It should be the first UART API called for each UART module in
//! use. The handle can be used to interact with the UART
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_initialize(uint32_t ui32Module, void **ppHandle);
//*****************************************************************************
//
//! @brief Deinitialize the UART interface.
//!
//! @param pHandle is a previously initialized UART handle.
//!
//! This function effectively disables future calls to interact with the UART
//! refered to by \e pHandle. The user may call this function if UART operation
//! is no longer desired.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_deinitialize(void *pHandle);
//*****************************************************************************
//
//! @brief Change the power state of the UART module.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param ePowerstate is the desired power state of the UART.
//! @parame bRetainState is a flag to ask the HAL to save UART registers.
//!
//! This function can be used to switch the power to the UART on or off. If \e
//! bRetainState is true during a powerdown operation, it will store the UART
//! configuration registers to SRAM, so it can restore them on power-up.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_power_control(void *pHandle,
am_hal_sysctrl_power_state_e ePowerState,
bool bRetainState);
//*****************************************************************************
//
//! @brief Used to configure basic UART settings.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param psConfig is a structure of UART configuration options.
//!
//! This function takes the options from an \e am_hal_uart_config_t structure,
//! and applies them to the UART referred to by \e pHandle.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_configure(void *pHandle,
const am_hal_uart_config_t *psConfig);
extern uint32_t am_hal_uart_configure_fifo(void *pHandle,
const am_hal_uart_config_t *psConfig,
bool bEnableFIFO);
//*****************************************************************************
//
//! @brief Transfer data through the UART interface.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param am_hal_uart_transfer_t is a structure describing the operation.
//!
//! This function executes a transaction as described by the \e
//! am_hal_uart_transfer_t structure. It can either read or write, and it will
//! take advantage of any buffer space provided by the \e
//! am_hal_uart_configure() function.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_transfer(void *pHandle,
const am_hal_uart_transfer_t *pTransfer);
//*****************************************************************************
//
//! @brief Wait for the UART TX to become idle
//!
//! @param pHandle is the handle for the UART to operate on.
//!
//! This function waits (polling) for all data in the UART TX FIFO and UART TX
//! buffer (if configured) to be fully sent on the physical UART interface.
//! This is not the most power-efficient way to wait for UART idle, but it can be
//! useful in simpler applications, or where power-efficiency is less important.
//!
//! Once this function returns, the UART can be safely disabled without
//! interfering with any previous transmissions.
//!
//! For a more power-efficient way to shut down the UART, check the
//! \e am_hal_uart_interrupt_service() function.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_tx_flush(void *pHandle);
//*****************************************************************************
//
//! @brief Read the UART flags.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param pui32Flags is the destination pointer for the UART flags.
//!
//! The UART hardware provides some information about the state of the physical
//! interface at all times. This function provides a way to read that data
//! directly. Below is a list of all possible UART flags.
//!
//! These correspond directly to the bits in the UART_FR register.
//!
//! @code
//!
//! AM_HAL_UART_FR_TX_EMPTY
//! AM_HAL_UART_FR_RX_FULL
//! AM_HAL_UART_FR_TX_FULL
//! AM_HAL_UART_FR_RX_EMPTY
//! AM_HAL_UART_FR_BUSY
//! AM_HAL_UART_FR_DCD_DETECTED
//! AM_HAL_UART_FR_DSR_READY
//! AM_HAL_UART_FR_CTS
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_flags_get(void *pHandle, uint32_t *pui32Flags);
//*****************************************************************************
//
//! @brief Read the UART FIFO directly.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param pui8Data is a pointer where the UART data should be written.
//! @param ui32NumBytes is the number of bytes to transfer.
//! @param pui32NumBytesRead is the nubmer of bytes actually transferred.
//!
//! This function reads the UART FIFO directly, and writes the resulting bytes
//! to pui8Data. Since the UART FIFO hardware has no direct size indicator, the
//! caller can only specify the maximum number of bytes they can handle. This
//! function will try to read as many bytes as possible. At the end of the
//! transfer, the number of bytes actually transferred will be written to the
//! pui32NumBytesRead parameter.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART error.
//
//*****************************************************************************
extern uint32_t am_hal_uart_fifo_read(void *pHandle,
uint8_t *pui8Data,
uint32_t ui32NumBytes,
uint32_t *pui32NumBytesRead);
//*****************************************************************************
//
//! @brief Write the UART FIFO directly.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param pui8Data is a pointer where the UART data should be written.
//! @param ui32NumBytes is the number of bytes to transfer.
//! @param pui32NumBytesWritten is the nubmer of bytes actually transferred.
//!
//! This function reads from pui8Data, and writes the requested number of bytes
//! directly to the UART FIFO. Since the UART FIFO hardware has no register to
//! tell us how much free space it has, the caller can only specify the number
//! of bytes they would like to send. This function will try to write as many
//! bytes as possible up to the requested number. At the end of the transfer,
//! the number of bytes actually transferred will be written to the
//! pui32NumBytesWritten parameter.
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART error.
//
//*****************************************************************************
extern uint32_t am_hal_uart_fifo_write(void *pHandle,
uint8_t *pui8Data,
uint32_t ui32NumBytes,
uint32_t *pui32NumBytesWritten);
//*****************************************************************************
//
//! @brief This function handles the UART buffers during UART interrupts.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param ui32Status is the interrupt status at the time of ISR entry.
//! @param pui32UartTxIdle can be used to store the UART idle status.
//!
//! The main purpose of this function is to manage the UART buffer system. Any
//! buffers configured by \e am_hal_uart_buffer_configure will be managed by
//! this service routine. Data queued for transmit will be added to the UART TX
//! FIFO as space allows, and data stored in the UART RX FIFO will be copied
//! out and stored in the RX buffer. This function will skip this transfer for
//! any buffer that has not been configured.
//!
//! In addition, this function can be used to alert the caller when the UART
//! becomes idle via the optional \e pui32UartTxIdle argument. This function
//! will set this variable any time it completes its operation and the UART TX
//! channel is no longer in use (including both the FIFO and any configured
//! buffer). To make sure this happens as early as possible, the user may
//! enable the UART_TXCMP interrupt as shown below.
//!
//! For RTOS-enabled cases, this function does not necessarily need to be
//! called inside the actual ISR for the UART, but it should be called promptly
//! in response to the receipt of a UART TX, RX, or RX timeout interrupt. If
//! the service routine is not called quickly enough, the caller risks an RX
//! FIFO overflow (data can be lost here), or a TX FIFO underflow (usually not
//! harmful).
//!
//! @code
//!
//! void
//! am_uart_isr(void)
//! {
//! //
//! // Service the FIFOs as necessary, and clear the interrupts.
//! //
//! uint32_t ui32Status;
//! uint32_t ui32UartIdle;
//!
//! am_hal_uart_interrupt_status_get(UART, &ui32Status, true);
//! am_hal_uart_interrupt_clear(UART, ui32Status);
//! am_hal_uart_interrupt_service(UART, ui32Status, &ui32UartIdle);
//!
//! ui32TXDoneFlag = ui32UartIdle;
//! }
//!
//! int
//! main(void)
//! {
//! ...
//!
//! // Initialize, power up, and configure the UART.
//! am_hal_uart_initialize(0, &UART);
//! am_hal_uart_power_control(UART, AM_HAL_SYSCTRL_WAKE, false);
//! am_hal_uart_configure(UART, &sUartConfig);
//!
//! ...
//!
//! // Enable the UART0 interrupt vector.
//! am_hal_uart_interrupt_enable(UART, AM_REG_UART_IER_TXCMPMIM_M);
//! am_hal_interrupt_enable(AM_HAL_INTERRUPT_UART0);
//! am_hal_interrupt_master_enable();
//! }
//!
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_interrupt_service(void *pHandle,
uint32_t ui32Status,
uint32_t *pui32UartTxIdle);
//*****************************************************************************
//
//! @brief Enable interrupts.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param ui32IntMask is the bitmask of interrupts to enable.
//!
//! This function enables the UART interrupt(s) given by ui32IntMask. If
//! multiple interrupts are desired, they can be OR'ed together.
//!
//! @note This function need not be called for UART FIFO interrupts if the UART
//! buffer service provided by \e am_hal_uart_buffer_configure() and \e
//! am_hal_uart_interrupt_service() is already in use. Non-FIFO-related
//! interrupts do require the use of this function.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_UART_INT_OVER_RUN
//! AM_HAL_UART_INT_BREAK_ERR
//! AM_HAL_UART_INT_PARITY_ERR
//! AM_HAL_UART_INT_FRAME_ERR
//! AM_HAL_UART_INT_RX_TMOUT
//! AM_HAL_UART_INT_TX
//! AM_HAL_UART_INT_RX
//! AM_HAL_UART_INT_DSRM
//! AM_HAL_UART_INT_DCDM
//! AM_HAL_UART_INT_CTSM
//! AM_HAL_UART_INT_TXCMP
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_interrupt_enable(void *pHandle,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Disable interrupts.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param ui32IntMask is the bitmask of interrupts to disable.
//!
//! This function disables the UART interrupt(s) given by ui32IntMask. If
//! multiple interrupts need to be disabled, they can be OR'ed together.
//!
//! @note This function need not be called for UART FIFO interrupts if the UART
//! buffer service provided by \e am_hal_uart_buffer_configure() and \e
//! am_hal_uart_interrupt_service() is already in use. Non-FIFO-related
//! interrupts do require the use of this function.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_UART_INT_OVER_RUN
//! AM_HAL_UART_INT_BREAK_ERR
//! AM_HAL_UART_INT_PARITY_ERR
//! AM_HAL_UART_INT_FRAME_ERR
//! AM_HAL_UART_INT_RX_TMOUT
//! AM_HAL_UART_INT_TX
//! AM_HAL_UART_INT_RX
//! AM_HAL_UART_INT_DSRM
//! AM_HAL_UART_INT_DCDM
//! AM_HAL_UART_INT_CTSM
//! AM_HAL_UART_INT_TXCMP
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_interrupt_disable(void *pHandle,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Clear interrupt status.
//!
//! @param pHandle is the handle for the UART to operate on.
//! @param ui32IntMask is the bitmask of interrupts to clear.
//!
//! This function clears the UART interrupt(s) given by ui32IntMask. If
//! multiple interrupts need to be cleared, they can be OR'ed together.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_UART_INT_OVER_RUN
//! AM_HAL_UART_INT_BREAK_ERR
//! AM_HAL_UART_INT_PARITY_ERR
//! AM_HAL_UART_INT_FRAME_ERR
//! AM_HAL_UART_INT_RX_TMOUT
//! AM_HAL_UART_INT_TX
//! AM_HAL_UART_INT_RX
//! AM_HAL_UART_INT_DSRM
//! AM_HAL_UART_INT_DCDM
//! AM_HAL_UART_INT_CTSM
//! AM_HAL_UART_INT_TXCMP
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_interrupt_clear(void *pHandle,
uint32_t ui32IntMask);
//*****************************************************************************
//
//! @brief Read interrupt status.
//!
//! @param pHandle is the handle for the UART to operate on.
//!
//! @param pui32Status is the returned interrupt status (all bits OR'ed
//! together)
//!
//! @param bEnabled determines whether to read interrupts that were not
//! enabled.
//!
//! This function reads the status the UART interrupt(s) if \e bEnabled is
//! true, it will only return the status of the enabled interrupts. Otherwise,
//! it will return the status of all interrupts, enabled or disabled.
//!
//! The full list of interrupts is given by the following:
//!
//! @code
//!
//! AM_HAL_UART_INT_OVER_RUN
//! AM_HAL_UART_INT_BREAK_ERR
//! AM_HAL_UART_INT_PARITY_ERR
//! AM_HAL_UART_INT_FRAME_ERR
//! AM_HAL_UART_INT_RX_TMOUT
//! AM_HAL_UART_INT_TX
//! AM_HAL_UART_INT_RX
//! AM_HAL_UART_INT_DSRM
//! AM_HAL_UART_INT_DCDM
//! AM_HAL_UART_INT_CTSM
//! AM_HAL_UART_INT_TXCMP
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_interrupt_status_get(void *pHandle,
uint32_t *pui32Status,
bool bEnabledOnly);
typedef enum
{
AM_HAL_UART_STATUS_BUS_ERROR = AM_HAL_STATUS_MODULE_SPECIFIC_START,
AM_HAL_UART_STATUS_RX_QUEUE_FULL,
AM_HAL_UART_STATUS_CLOCK_NOT_CONFIGURED,
AM_HAL_UART_STATUS_BAUDRATE_NOT_POSSIBLE,
}
am_hal_uart_errors_t;
//*****************************************************************************
//
//! @brief Check to see which interrupts are enabled.
//!
//! @param pHandle is the handle for the UART to operate on.
//!
//! @param pui32IntMask is the current set of interrupt enable bits (all bits
//! OR'ed together)
//!
//! This function checks the UART Interrupt Enable Register to see which UART
//! interrupts are currently enabled. The result will be an interrupt mask with
//! one bit set for each of the currently enabled UART interrupts.
//!
//! The full set of UART interrupt bits is given by the list below:
//!
//! @code
//!
//! AM_HAL_UART_INT_OVER_RUN
//! AM_HAL_UART_INT_BREAK_ERR
//! AM_HAL_UART_INT_PARITY_ERR
//! AM_HAL_UART_INT_FRAME_ERR
//! AM_HAL_UART_INT_RX_TMOUT
//! AM_HAL_UART_INT_TX
//! AM_HAL_UART_INT_RX
//! AM_HAL_UART_INT_DSRM
//! AM_HAL_UART_INT_DCDM
//! AM_HAL_UART_INT_CTSM
//! AM_HAL_UART_INT_TXCMP
//!
//! @endcode
//!
//! @return AM_HAL_STATUS_SUCCESS or applicable UART errors.
//
//*****************************************************************************
extern uint32_t am_hal_uart_interrupt_enable_get(void *pHandle, uint32_t *pui32IntMask);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_UART_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,416 @@
//*****************************************************************************
//
// am_hal_wdt.c
//! @file
//!
//! @brief Hardware abstraction layer for the Watchdog Timer module.
//!
//! @addtogroup wdt3 Watchdog Timer (WDT)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Adjacency check
//
// This is related to the timer read workaround. This macro checks to see if
// the two supplied count values are within one "tick" of eachother. It should
// still pass in the event of a timer rollover. The "B" read is assumed to
// follow the "A" read. The macro returns "TRUE" when the adjacent timer reads
// can be used.
//
//*****************************************************************************
#define adjacent(A, B) (((A) == (B)) || (((A) + 1) == (B)) || ((B) == 0))
//*****************************************************************************
//
//! @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 & ~(WDT_CFG_INTVAL_Msk | WDT_CFG_RESVAL_Msk);
ui32ConfigVal |= _VAL2FLD(WDT_CFG_INTVAL, ui16IntCount);
ui32ConfigVal |= _VAL2FLD(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.
//
WDT->INTEN |= WDT_INTEN_WDTINT_Msk;
}
else
{
//
// Disable the watchdog interrupt if the configuration doesn't call for
// watchdog interrupts.
//
WDT->INTEN &= ~WDT_INTEN_WDTINT_Msk;
}
//
// If resets should be enabled, set the appropriate bit in the temporary
// variable.
//
if ( bResetEnabled )
{
//
// Also enable watchdog resets in the reset module.
//
RSTGEN->CFG |= RSTGEN_CFG_WDREN_Msk;
}
else
{
//
// Disable watchdog resets in the reset module.
//
RSTGEN->CFG &= ~RSTGEN_CFG_WDREN_Msk;
}
//
// Check for a user specified clock select. If none specified then
// set 128Hz.
//
if ( !(psConfig->ui32Config & WDT_CFG_CLKSEL_Msk) )
{
ui32ConfigVal |= _VAL2FLD(WDT_CFG_CLKSEL, WDT_CFG_CLKSEL_128HZ);
}
//
// Write the saved value to the watchdog configuration register.
//
WDT->CFG = ui32ConfigVal;
} // am_hal_wdt_init()
//*****************************************************************************
//
//! @brief Starts the watchdog timer.
//!
//! Enables the watchdog timer tick using the 'enable' bit in the watchdog
//! configuration register. This function does not perform any locking of the
//! watchdog timer, so it can be disabled or reconfigured later.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_wdt_start(void)
{
//
// Make sure the watchdog timer is in the "reset" state, and then set the
// enable bit to start counting.
//
WDT->CFG |= WDT_CFG_WDTEN_Msk;
WDT->RSTRT = WDT_RSTRT_RSTRT_KEYVALUE;
} // am_hal_wdt_start()
//*****************************************************************************
//
//! @brief Stops the watchdog timer.
//!
//! Disables the watchdog timer tick by clearing the 'enable' bit in the
//! watchdog configuration register.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_wdt_halt(void)
{
//
// Clear the watchdog enable bit.
//
WDT->CFG &= ~WDT_CFG_WDTEN_Msk;
} // am_hal_wdt_halt()
//*****************************************************************************
//
//! @brief Locks the watchdog configuration and starts the watchdog timer.
//!
//! This function sets the watchdog "lock" register, which prevents software
//! from re-configuring the watchdog. This action will also set the enable bit
//! for the watchdog timer, so it will start counting immediately.
//!
//! @return None.
//
//*****************************************************************************
void
am_hal_wdt_lock_and_start(void)
{
//
// Write the 'key' value to the watchdog lock register.
//
WDT->LOCK = WDT_LOCK_LOCK_KEYVALUE;
} // am_hal_wdt_lock_and_start()
//*****************************************************************************
//
//! @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 ui32RetVal;
AM_CRITICAL_BEGIN
ui32RetVal = WDT->INTSTAT;
ui32RetVal &= WDT->INTEN;
AM_CRITICAL_END
return ui32RetVal;
}
else
{
return WDT->INTSTAT;
}
} // am_hal_wdt_int_status_get()
//*****************************************************************************
//
//! @brief Set the state of the wdt interrupt status bit.
//!
//! This function sets the interrupt bit.
//!
//! @return None
//
//*****************************************************************************
void
am_hal_wdt_int_set(void)
{
WDT->INTSET = WDT_INTSET_WDTINT_Msk;
} // am_hal_wdt_int_set()
//*****************************************************************************
//
//! @brief Clear the state of the wdt interrupt status bit.
//!
//! This function clear the interrupt bit.
//!
//! @return None
//
//*****************************************************************************
void
am_hal_wdt_int_clear(void)
{
WDT->INTCLR = WDT_INTCLR_WDTINT_Msk;
} // am_hal_wdt_int_clear()
//*****************************************************************************
//
//! @brief Enable the wdt interrupt.
//!
//! This function enable the interrupt.
//!
//! @return None
//
//*****************************************************************************
void
am_hal_wdt_int_enable(void)
{
WDT->INTEN |= WDT_INTEN_WDTINT_Msk;
} // am_hal_wdt_int_enable()
//*****************************************************************************
//
//! @brief Return the enabled WDT interrupts.
//!
//! This function returns the enabled WDT interrupts.
//!
//! @return enabled WDT interrupts.
//
//*****************************************************************************
uint32_t
am_hal_wdt_int_enable_get(void)
{
return WDT->INTEN;
} // am_hal_wdt_int_enable_get()
//*****************************************************************************
//
//! @brief Disable the wdt interrupt.
//!
//! This function disablee the interrupt.
//!
//! @return None
//
//*****************************************************************************
void
am_hal_wdt_int_disable(void)
{
WDT->INTEN &= ~WDT_INTEN_WDTINT_Msk;
} // am_hal_wdt_int_disable()
//*****************************************************************************
//
//! @brief Get the wdt counter value.
//!
//! This function reads the current value of watch dog timer counter register.
//!
//! @return None
//
//*****************************************************************************
uint32_t
am_hal_wdt_counter_get(void)
{
uint32_t ui32Values[3] = {0};
uint32_t ui32Value;
//
// Start a critical section.
//
uint32_t ui32InterruptState = am_hal_interrupt_master_disable();
//
// First, go read the value from the counter register 3 times
// back to back in assembly language.
//
am_hal_triple_read( AM_REGADDR(WDT, COUNT), ui32Values );
//
// Mask out the COUNT field from the 3 read values.
//
ui32Values[0] = _VAL2FLD(WDT_COUNT_COUNT, ui32Values[0]);
ui32Values[1] = _VAL2FLD(WDT_COUNT_COUNT, ui32Values[1]);
ui32Values[2] = _VAL2FLD(WDT_COUNT_COUNT, ui32Values[2]);
//
// Now, we'll figure out which of the three values is the correct time.
//
if (ui32Values[0] == ui32Values[1])
{
//
// If the first two values match, then neither one was a bad read.
// We'll take this as the current time.
//
ui32Value = ui32Values[1];
}
else
{
//
// If the first two values didn't match, then one of them might be bad.
// If one of the first two values is bad, then the third one should
// always be correct. We'll take the third value as the correct count.
//
ui32Value = ui32Values[2];
//
// If all of the statements about the architecture are true, the third
// value should be correct, and it should always be within one count of
// either the first or the second value.
//
// Just in case, we'll check against the previous two values to make
// sure that our final answer was reasonable. If it isn't, we will
// flag it as a "bad read", and fail this assert statement.
//
// This shouldn't ever happen, and it hasn't ever happened in any of
// our tests so far.
//
am_hal_debug_assert_msg((adjacent(ui32Values[1], ui32Values[2]) ||
adjacent(ui32Values[0], ui32Values[2])),
"Bad CDT read");
}
//
// End the critical section.
//
am_hal_interrupt_master_set(ui32InterruptState);
return ui32Value;
} // am_hal_wdt_counter_get()
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,187 @@
//*****************************************************************************
//
// am_hal_wdt.h
//! @file
//!
//! @brief Hardware abstraction layer for the Watchdog Timer module.
//!
//! @addtogroup wdt3 Watchdog Timer (WDT)
//! @ingroup apollo3hal
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2020, Ambiq Micro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision 2.4.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef AM_HAL_WDT_H
#define AM_HAL_WDT_H
#include <stdint.h>
#include <stdbool.h>
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
//*****************************************************************************
//
//! @name WDT Clock Divider Selections.
//! @brief Macro definitions for WDT clock frequencies.
//!
//! These macros may be used with the am_hal_wdt_config_t structure to set the
//! clock frequency of the watch dog timer.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_WDT_LFRC_CLK_DEFAULT (_VAL2FLD(WDT_CFG_CLKSEL, WDT_CFG_CLKSEL_128HZ))
#define AM_HAL_WDT_LFRC_CLK_128HZ (_VAL2FLD(WDT_CFG_CLKSEL, WDT_CFG_CLKSEL_128HZ))
#define AM_HAL_WDT_LFRC_CLK_16HZ (_VAL2FLD(WDT_CFG_CLKSEL, WDT_CFG_CLKSEL_16HZ))
#define AM_HAL_WDT_LFRC_CLK_1HZ (_VAL2FLD(WDT_CFG_CLKSEL, WDT_CFG_CLKSEL_1HZ))
#define AM_HAL_WDT_LFRC_CLK_1_16HZ (_VAL2FLD(WDT_CFG_CLKSEL, WDT_CFG_CLKSEL_1_16HZ))
#define AM_HAL_WDT_LFRC_CLK_OFF (_VAL2FLD(WDT_CFG_CLKSEL, WDT_CFG_CLKSEL_OFF))
//! @}
//*****************************************************************************
//
//! @name WDT Enable Reset in the WDT Configuration.
//! @brief Macro definitions for WDT Reset Enable.
//!
//! These macros may be used with the am_hal_wdt_config_t structure to enable
//! the watch dog timer to generate resets to the chip.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_WDT_ENABLE_RESET (_VAL2FLD(WDT_CFG_RESEN, 1))
#define AM_HAL_WDT_DISABLE_RESET (_VAL2FLD(WDT_CFG_RESEN, 0))
//! @}
//*****************************************************************************
//
//! @name WDT Enable Interrupt Generation from the WDT Configuration.
//! @brief Macro definitions for WDT Interrupt Enable.
//!
//! These macros may be used with the am_hal_wdt_config_t structure to enable
//! the watch dog timer to generate generate WDT interrupts.
//!
//! @{
//
//*****************************************************************************
#define AM_HAL_WDT_ENABLE_INTERRUPT (_VAL2FLD(WDT_CFG_INTEN, 1))
#define AM_HAL_WDT_DISABLE_INTERRUPT (_VAL2FLD(WDT_CFG_INTEN, 0))
//! @}
//*****************************************************************************
//
//! @brief Watchdog timer configuration structure.
//!
//! This structure is made to be used with the am_hal_wdt_init() function. It
//! describes the configuration of the watchdog timer.
//
//*****************************************************************************
typedef struct
{
//! Configuration Values for watchdog timer
//! event is generated.
uint32_t ui32Config;
//! Number of watchdog timer ticks allowed before a watchdog interrupt
//! event is generated.
uint16_t ui16InterruptCount;
//! Number of watchdog timer ticks allowed before the watchdog will issue a
//! system reset.
uint16_t ui16ResetCount;
}
am_hal_wdt_config_t;
//*****************************************************************************
//
//! @brief Restarts the watchdog timer ("Pets" the dog)
//!
//! This function restarts the watchdog timer from the beginning, preventing
//! any interrupt or reset even from occuring until the next time the watchdog
//! timer expires.
//!
//! @return None.
//
//*****************************************************************************
#define am_hal_wdt_restart() \
do \
{ \
WDT->RSTRT = WDT_RSTRT_RSTRT_KEYVALUE; \
(void)(WDT->RSTRT); \
} \
while (0)
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_hal_wdt_init(const am_hal_wdt_config_t *psConfig);
extern void am_hal_wdt_start(void);
extern void am_hal_wdt_halt(void);
extern void am_hal_wdt_lock_and_start(void);
extern uint32_t am_hal_wdt_counter_get(void);
extern void am_hal_wdt_int_enable(void);
extern uint32_t am_hal_wdt_int_enable_get(void);
extern void am_hal_wdt_int_disable(void);
extern void am_hal_wdt_int_clear(void);
extern void am_hal_wdt_int_set(void);
extern uint32_t am_hal_wdt_int_status_get(bool bEnabledOnly);
#ifdef __cplusplus
}
#endif
#endif // AM_HAL_WDT_H
//*****************************************************************************
//
// End Doxygen group.
//! @}
//
//*****************************************************************************
@@ -0,0 +1,179 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2020, Ambiq Micro
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# Third party software included in this distribution is subject to the
# additional license terms as defined in the /docs/licenses directory.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# This is part of revision 2.4.2 of the AmbiqSuite Development Package.
#
#******************************************************************************
TARGET := libam_hal
COMPILERNAME := gcc
PROJECT := libam_hal_gcc
CONFIG := bin
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
DEFINES = -DAM_ASSERT_INVALID_THRESHOLD=0
DEFINES+= -DAM_DEBUG_ASSERT
DEFINES+= -DAM_PART_APOLLO3
DEFINES+= -Dgcc
INCLUDES = -I../../../../CMSIS/AmbiqMicro/Include
INCLUDES+= -I../../../../mcu/apollo3
INCLUDES+= -I../../../../CMSIS/ARM/Include
VPATH = ..
SRC = am_hal_adc.c
SRC += am_hal_ble.c
SRC += am_hal_ble_patch.c
SRC += am_hal_ble_patch_b0.c
SRC += am_hal_burst.c
SRC += am_hal_cachectrl.c
SRC += am_hal_clkgen.c
SRC += am_hal_cmdq.c
SRC += am_hal_ctimer.c
SRC += am_hal_debug.c
SRC += am_hal_flash.c
SRC += am_hal_global.c
SRC += am_hal_gpio.c
SRC += am_hal_interrupt.c
SRC += am_hal_iom.c
SRC += am_hal_ios.c
SRC += am_hal_itm.c
SRC += am_hal_mcuctrl.c
SRC += am_hal_mspi.c
SRC += am_hal_pdm.c
SRC += am_hal_pwrctrl.c
SRC += am_hal_queue.c
SRC += am_hal_reset.c
SRC += am_hal_rtc.c
SRC += am_hal_scard.c
SRC += am_hal_secure_ota.c
SRC += am_hal_security.c
SRC += am_hal_stimer.c
SRC += am_hal_sysctrl.c
SRC += am_hal_systick.c
SRC += am_hal_tpiu.c
SRC += am_hal_uart.c
SRC += am_hal_wdt.c
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP -std=c99 -Wall
# Libraries O3 for production, examples O0 for debug.
CFLAGS+= -O3
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
ODFLAGS = -S
#### Rules ####
all: directories $(CONFIG)/$(TARGET).a
directories: $(CONFIG)
$(CONFIG):
@mkdir -p $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d $(INCS)
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d $(INCS)
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET).a: $(OBJS)
@echo " Library $(COMPILERNAME) $@" ;\
$(AR) rsvc $@ $(OBJS)
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).a
$(CONFIG)/%.d: ;
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories
@@ -0,0 +1,112 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2020, Ambiq Micro
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# Third party software included in this distribution is subject to the
# additional license terms as defined in the /docs/licenses directory.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# This is part of revision 2.4.2 of the AmbiqSuite Development Package.
#
#******************************************************************************
TARGET := libam_hal
COMPILERNAME := iar
PROJECT := libam_hal_iar
CONFIG := bin
AM_SoftwareRoot ?= ../../..
SHELL:=/bin/bash
#### Required Executables ####
K := $(shell type -p IarBuild.exe)
RM = $(shell which rm 2>/dev/null)
ifeq ($(K),)
all clean:
$(info Tools w/$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
LIBS = ${libraries}
INCS = ${incs}
all: directories $(CONFIG)/$(TARGET).a
# Source Dependencies must be defined before they are used.
SRCS = .././am_hal_adc.c
SRCS += .././am_hal_ble.c
SRCS += .././am_hal_ble_patch.c
SRCS += .././am_hal_ble_patch_b0.c
SRCS += .././am_hal_burst.c
SRCS += .././am_hal_cachectrl.c
SRCS += .././am_hal_clkgen.c
SRCS += .././am_hal_cmdq.c
SRCS += .././am_hal_ctimer.c
SRCS += .././am_hal_debug.c
SRCS += .././am_hal_flash.c
SRCS += .././am_hal_global.c
SRCS += .././am_hal_gpio.c
SRCS += .././am_hal_interrupt.c
SRCS += .././am_hal_iom.c
SRCS += .././am_hal_ios.c
SRCS += .././am_hal_itm.c
SRCS += .././am_hal_mcuctrl.c
SRCS += .././am_hal_mspi.c
SRCS += .././am_hal_pdm.c
SRCS += .././am_hal_pwrctrl.c
SRCS += .././am_hal_queue.c
SRCS += .././am_hal_reset.c
SRCS += .././am_hal_rtc.c
SRCS += .././am_hal_scard.c
SRCS += .././am_hal_secure_ota.c
SRCS += .././am_hal_security.c
SRCS += .././am_hal_stimer.c
SRCS += .././am_hal_sysctrl.c
SRCS += .././am_hal_systick.c
SRCS += .././am_hal_tpiu.c
SRCS += .././am_hal_uart.c
SRCS += .././am_hal_wdt.c
$(CONFIG)/$(TARGET).a: $(LIBS) $(INCS) $(SRCS)
IarBuild.exe libam_hal.ewp -make Debug -log info
directories: $(CONFIG)
$(CONFIG):
@mkdir -p $@
# BSP's need this.
clean:
@echo Cleaning... ;\
IarBuild.exe libam_hal.ewp -clean Debug -log all
endif
.PHONY: all clean directories
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\libam_hal.ewp</path>
</project>
<batchBuild/>
</workspace>
@@ -0,0 +1,115 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2020, Ambiq Micro
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# Third party software included in this distribution is subject to the
# additional license terms as defined in the /docs/licenses directory.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# This is part of revision 2.4.2 of the AmbiqSuite Development Package.
#
#******************************************************************************
TARGET := libam_hal
COMPILERNAME := Keil
PROJECT := libam_hal_Keil
CONFIG := bin
AM_SoftwareRoot ?= ../../../..
SHELL:=/bin/bash
#### Required Executables ####
K := $(shell type -p UV4.exe)
RM := $(shell which rm 2>/dev/null)
ifeq ($(K),)
all clean:
$(info Tools w/$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
LIBS =
INCS = ../../../../CMSIS/AmbiqMicro/Include
INCS+= ../../../../mcu/apollo3
INCS+= ../../../../CMSIS/ARM/Include
all: directories $(CONFIG)/$(TARGET).lib
# Source Dependencies must be defined before they are used.
SRCS = .././am_hal_adc.c
SRCS += .././am_hal_ble.c
SRCS += .././am_hal_ble_patch.c
SRCS += .././am_hal_ble_patch_b0.c
SRCS += .././am_hal_burst.c
SRCS += .././am_hal_cachectrl.c
SRCS += .././am_hal_clkgen.c
SRCS += .././am_hal_cmdq.c
SRCS += .././am_hal_ctimer.c
SRCS += .././am_hal_debug.c
SRCS += .././am_hal_flash.c
SRCS += .././am_hal_global.c
SRCS += .././am_hal_gpio.c
SRCS += .././am_hal_interrupt.c
SRCS += .././am_hal_iom.c
SRCS += .././am_hal_ios.c
SRCS += .././am_hal_itm.c
SRCS += .././am_hal_mcuctrl.c
SRCS += .././am_hal_mspi.c
SRCS += .././am_hal_pdm.c
SRCS += .././am_hal_pwrctrl.c
SRCS += .././am_hal_queue.c
SRCS += .././am_hal_reset.c
SRCS += .././am_hal_rtc.c
SRCS += .././am_hal_scard.c
SRCS += .././am_hal_secure_ota.c
SRCS += .././am_hal_security.c
SRCS += .././am_hal_stimer.c
SRCS += .././am_hal_sysctrl.c
SRCS += .././am_hal_systick.c
SRCS += .././am_hal_tpiu.c
SRCS += .././am_hal_uart.c
SRCS += .././am_hal_wdt.c
$(CONFIG)/$(TARGET).lib: $(LIBS) $(INCS) $(SRCS)
UV4.exe -b -t "libam_hal" libam_hal.uvprojx -j0 || [ $$? -eq 1 ]
directories: $(CONFIG)
$(CONFIG):
@mkdir -p $@
# BSP's need this.
clean:
@echo Cleaning... ;\
$(RM) -rf $(CONFIG)
endif
.PHONY: all clean directories
@@ -0,0 +1,712 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
<SchemaVersion>1.0</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Extensions>
<cExt>*.c</cExt>
<aExt>*.s*; *.src; *.a*</aExt>
<oExt>*.obj</oExt>
<lExt>*.lib</lExt>
<tExt>*.txt; *.h; *.inc</tExt>
<pExt>*.plm</pExt>
<CppX>*.cpp</CppX>
<nMigrate>0</nMigrate>
</Extensions>
<DaveTm>
<dwLowDateTime>0</dwLowDateTime>
<dwHighDateTime>0</dwHighDateTime>
</DaveTm>
<Target>
<TargetName>libam_hal</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<TargetOption>
<CLKADS>48000000</CLKADS>
<OPTTT>
<gFlags>1</gFlags>
<BeepAtEnd>1</BeepAtEnd>
<RunSim>0</RunSim>
<RunTarget>1</RunTarget>
<RunAbUc>0</RunAbUc>
</OPTTT>
<OPTHX>
<HexSelection>1</HexSelection>
<FlashByte>65535</FlashByte>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
</OPTHX>
<OPTLEX>
<PageWidth>79</PageWidth>
<PageLength>66</PageLength>
<TabStop>8</TabStop>
<ListingPath>.\Listings\</ListingPath>
</OPTLEX>
<ListingPage>
<CreateCListing>1</CreateCListing>
<CreateAListing>1</CreateAListing>
<CreateLListing>1</CreateLListing>
<CreateIListing>0</CreateIListing>
<AsmCond>1</AsmCond>
<AsmSymb>1</AsmSymb>
<AsmXref>0</AsmXref>
<CCond>1</CCond>
<CCode>0</CCode>
<CListInc>0</CListInc>
<CSymb>0</CSymb>
<LinkerCodeListing>0</LinkerCodeListing>
</ListingPage>
<OPTXL>
<LMap>1</LMap>
<LComments>1</LComments>
<LGenerateSymbols>1</LGenerateSymbols>
<LLibSym>1</LLibSym>
<LLines>1</LLines>
<LLocSym>1</LLocSym>
<LPubSym>1</LPubSym>
<LXref>0</LXref>
<LExpSel>0</LExpSel>
</OPTXL>
<OPTFL>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>1</IsCurrentTarget>
</OPTFL>
<CpuCode>255</CpuCode>
<DebugOpt>
<uSim>0</uSim>
<uTrg>1</uTrg>
<sLdApp>1</sLdApp>
<sGomain>1</sGomain>
<sRbreak>1</sRbreak>
<sRwatch>1</sRwatch>
<sRmem>1</sRmem>
<sRfunc>1</sRfunc>
<sRbox>1</sRbox>
<tLdApp>0</tLdApp>
<tGomain>0</tGomain>
<tRbreak>1</tRbreak>
<tRwatch>1</tRwatch>
<tRmem>1</tRmem>
<tRfunc>0</tRfunc>
<tRbox>1</tRbox>
<tRtrace>1</tRtrace>
<sRSysVw>1</sRSysVw>
<tRSysVw>1</tRSysVw>
<sRunDeb>0</sRunDeb>
<sLrtime>0</sLrtime>
<bEvRecOn>1</bEvRecOn>
<nTsel>3</nTsel>
<sDll></sDll>
<sDllPa></sDllPa>
<sDlgDll></sDlgDll>
<sDlgPa></sDlgPa>
<sIfile></sIfile>
<tDll></tDll>
<tDllPa></tDllPa>
<tDlgDll></tDlgDll>
<tDlgPa></tDlgPa>
<tIfile>.\Dbg_RAM.ini</tIfile>
<pMon>Segger\JL2CM3.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>JL2CM3</Key>
<Name>-U483027775 -O2510 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO1 -TC3000000 -TP21 -TDS2 -TDT0 -TDC1F -TIE1 -TIP0 -TB1 -TFE0 -FO7 -FD10000000 -FC4000 -FN1 -FF0Apollo3.FLM -FS00 -FL0100000 -FP0($$Device:AMA3B1KK-KBR$Flash\Apollo3.FLM)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DbgCM</Key>
<Name>-U-O206 -O206 -S2 -C0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO1 -TC3000000 -TP21 -TDS2 -TDT0 -TDC1F -TIE1 -TIP8 -FO7 -FD10000000 -FC4000 -FN1 -FF0Apollo -FS00 -FL080000</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
<Name>-UV0264NGE -O2510 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO1 -TC3000000 -TP21 -TDS8002 -TDT0 -TDC1F -TIE1 -TIP8 -FO7 -FD10000000 -FC4000 -FN1 -FF0Apollo3.FLM -FS00 -FL0100000 -FP0($$Device:AMA3B1KK-KBR$Flash\Apollo3.FLM)</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint/>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>
<DebugFlag>
<trace>0</trace>
<periodic>1</periodic>
<aLwin>1</aLwin>
<aCover>0</aCover>
<aSer1>0</aSer1>
<aSer2>0</aSer2>
<aPa>0</aPa>
<viewmode>1</viewmode>
<vrSel>0</vrSel>
<aSym>0</aSym>
<aTbox>0</aTbox>
<AscS1>0</AscS1>
<AscS2>0</AscS2>
<AscS3>0</AscS3>
<aSer3>0</aSer3>
<eProf>0</eProf>
<aLa>0</aLa>
<aPa1>0</aPa1>
<AscS4>0</AscS4>
<aSer4>1</aSer4>
<StkLoc>0</StkLoc>
<TrcWin>0</TrcWin>
<newCpu>0</newCpu>
<uProt>0</uProt>
</DebugFlag>
<LintExecutable></LintExecutable>
<LintConfigFile></LintConfigFile>
<bLintAuto>0</bLintAuto>
<Lin2Executable></Lin2Executable>
<Lin2ConfigFile></Lin2ConfigFile>
<bLin2Auto>0</bLin2Auto>
<bAutoGenD>0</bAutoGenD>
<bAuto2GenD>0</bAuto2GenD>
</TargetOption>
</Target>
<Group>
<GroupName>source_files</GroupName>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<cbSel>0</cbSel>
<RteFlg>0</RteFlg>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>1</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_adc.c</PathWithFileName>
<FilenameWithoutPath>am_hal_adc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>2</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_ble.c</PathWithFileName>
<FilenameWithoutPath>am_hal_ble.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>3</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_ble_patch.c</PathWithFileName>
<FilenameWithoutPath>am_hal_ble_patch.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>4</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_ble_patch_b0.c</PathWithFileName>
<FilenameWithoutPath>am_hal_ble_patch_b0.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>5</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_burst.c</PathWithFileName>
<FilenameWithoutPath>am_hal_burst.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>6</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_cachectrl.c</PathWithFileName>
<FilenameWithoutPath>am_hal_cachectrl.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>7</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_clkgen.c</PathWithFileName>
<FilenameWithoutPath>am_hal_clkgen.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>8</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_cmdq.c</PathWithFileName>
<FilenameWithoutPath>am_hal_cmdq.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>9</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_ctimer.c</PathWithFileName>
<FilenameWithoutPath>am_hal_ctimer.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>10</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_debug.c</PathWithFileName>
<FilenameWithoutPath>am_hal_debug.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>11</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_flash.c</PathWithFileName>
<FilenameWithoutPath>am_hal_flash.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>12</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_global.c</PathWithFileName>
<FilenameWithoutPath>am_hal_global.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>13</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_gpio.c</PathWithFileName>
<FilenameWithoutPath>am_hal_gpio.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>14</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_interrupt.c</PathWithFileName>
<FilenameWithoutPath>am_hal_interrupt.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>15</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_iom.c</PathWithFileName>
<FilenameWithoutPath>am_hal_iom.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>16</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_ios.c</PathWithFileName>
<FilenameWithoutPath>am_hal_ios.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>17</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_itm.c</PathWithFileName>
<FilenameWithoutPath>am_hal_itm.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>18</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_mcuctrl.c</PathWithFileName>
<FilenameWithoutPath>am_hal_mcuctrl.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_mspi.c</PathWithFileName>
<FilenameWithoutPath>am_hal_mspi.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_pdm.c</PathWithFileName>
<FilenameWithoutPath>am_hal_pdm.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_pwrctrl.c</PathWithFileName>
<FilenameWithoutPath>am_hal_pwrctrl.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>22</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_queue.c</PathWithFileName>
<FilenameWithoutPath>am_hal_queue.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>23</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_reset.c</PathWithFileName>
<FilenameWithoutPath>am_hal_reset.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>24</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_rtc.c</PathWithFileName>
<FilenameWithoutPath>am_hal_rtc.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>25</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_scard.c</PathWithFileName>
<FilenameWithoutPath>am_hal_scard.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>26</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_secure_ota.c</PathWithFileName>
<FilenameWithoutPath>am_hal_secure_ota.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>27</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_security.c</PathWithFileName>
<FilenameWithoutPath>am_hal_security.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>28</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_stimer.c</PathWithFileName>
<FilenameWithoutPath>am_hal_stimer.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>29</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_sysctrl.c</PathWithFileName>
<FilenameWithoutPath>am_hal_sysctrl.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>30</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_systick.c</PathWithFileName>
<FilenameWithoutPath>am_hal_systick.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>31</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_tpiu.c</PathWithFileName>
<FilenameWithoutPath>am_hal_tpiu.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>32</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_uart.c</PathWithFileName>
<FilenameWithoutPath>am_hal_uart.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>33</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<Focus>0</Focus>
<ColumnNumber>0</ColumnNumber>
<tvExpOptDlg>0</tvExpOptDlg>
<TopLine>0</TopLine>
<CurrentLine>0</CurrentLine>
<bDave2>0</bDave2>
<PathWithFileName>.././am_hal_wdt.c</PathWithFileName>
<FilenameWithoutPath>am_hal_wdt.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
</ProjectOpt>
@@ -0,0 +1,566 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
<SchemaVersion>2.1</SchemaVersion>
<Header>### uVision Project, (C) Keil Software</Header>
<Targets>
<Target>
<TargetName>libam_hal</TargetName>
<ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName>
<pArmCC></pArmCC>
<TargetOption>
<TargetCommonOption>
<Device>AMA3B1KK-KBR</Device>
<Vendor>Ambiq Micro</Vendor>
<PackID>AmbiqMicro.Apollo_DFP.1.1.0</PackID>
<PackURL>http://s3.asia.ambiqmicro.com/pack/</PackURL>
<Cpu>IROM(0x00000000,0x100000) IRAM(0x10000000,0x60000) CPUTYPE("Cortex-M4") FPU2 CLOCK(48000000) ELITTLE</Cpu>
<FlashUtilSpec></FlashUtilSpec>
<StartupFile></StartupFile>
<FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD10000000 -FC4000 -FN1 -FF0Apollo3 -FS00 -FL010000 -FP0($$Device:AMA3B1KK-KBR$Flash\Apollo3.FLM))</FlashDriverDll>
<DeviceId>0</DeviceId>
<RegisterFile></RegisterFile>
<MemoryEnv></MemoryEnv>
<Cmp></Cmp>
<Asm></Asm>
<Linker></Linker>
<OHString></OHString>
<InfinionOptionDll></InfinionOptionDll>
<SLE66CMisc></SLE66CMisc>
<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile>$$Device:AMA3B1KK-KBR$SVD\apollo3.svd</SFDFile>
<bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<LibPath></LibPath>
<RegisterFilePath>1024 BGA$Device\Include\apollo3.h\</RegisterFilePath>
<DBRegisterFilePath>1024 BGA$Device\Include\apollo3.h\</DBRegisterFilePath>
<TargetStatus>
<Error>0</Error>
<ExitCodeStop>0</ExitCodeStop>
<ButtonStop>0</ButtonStop>
<NotGenerated>0</NotGenerated>
<InvalidFlash>1</InvalidFlash>
</TargetStatus>
<OutputDirectory>.\bin\</OutputDirectory>
<OutputName>libam_hal</OutputName>
<CreateExecutable>0</CreateExecutable>
<CreateLib>1</CreateLib>
<CreateHexFile>0</CreateHexFile>
<DebugInformation>0</DebugInformation>
<BrowseInformation>1</BrowseInformation>
<ListingPath>.\Listings\</ListingPath>
<HexFormatSelection>1</HexFormatSelection>
<Merge32K>0</Merge32K>
<CreateBatchFile>0</CreateBatchFile>
<BeforeCompile>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopU1X>0</nStopU1X>
<nStopU2X>0</nStopU2X>
</BeforeCompile>
<BeforeMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name></UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopB1X>0</nStopB1X>
<nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name>fromelf --bin --output bin\libam_hal.bin bin\libam_hal.axf</UserProg1Name>
<UserProg2Name>fromelf -cedrst --output bin\libam_hal.txt bin\libam_hal.axf</UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X>
<nStopA2X>0</nStopA2X>
</AfterMake>
<SelectedForBatchBuild>0</SelectedForBatchBuild>
<SVCSIdString></SVCSIdString>
</TargetCommonOption>
<CommonProperty>
<UseCPPCompiler>0</UseCPPCompiler>
<RVCTCodeConst>0</RVCTCodeConst>
<RVCTZI>0</RVCTZI>
<RVCTOtherData>0</RVCTOtherData>
<ModuleSelection>0</ModuleSelection>
<IncludeInBuild>1</IncludeInBuild>
<AlwaysBuild>0</AlwaysBuild>
<GenerateAssemblyFile>0</GenerateAssemblyFile>
<AssembleAssemblyFile>0</AssembleAssemblyFile>
<PublicsOnly>0</PublicsOnly>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
<ComprImg>1</ComprImg>
</CommonProperty>
<DllOption>
<SimDllName>SARMCM3.DLL</SimDllName>
<SimDllArguments> -MPU</SimDllArguments>
<SimDlgDll>DCM.DLL</SimDlgDll>
<SimDlgDllArguments>-pCM4</SimDlgDllArguments>
<TargetDllName>SARMCM3.DLL</TargetDllName>
<TargetDllArguments> -MPU</TargetDllArguments>
<TargetDlgDll>TCM.DLL</TargetDlgDll>
<TargetDlgDllArguments>-pCM4</TargetDlgDllArguments>
</DllOption>
<DebugOption>
<OPTHX>
<HexSelection>1</HexSelection>
<HexRangeLowAddress>0</HexRangeLowAddress>
<HexRangeHighAddress>0</HexRangeHighAddress>
<HexOffset>0</HexOffset>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
</DebugOption>
<Utilities>
<Flash1>
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
<UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4096</DriverSelection>
</Flash1>
<bUseTDR>1</bUseTDR>
<Flash2>BIN\UL2CM3.DLL</Flash2>
<Flash3></Flash3>
<Flash4></Flash4>
<pFcarmOut></pFcarmOut>
<pFcarmGrp></pFcarmGrp>
<pFcArmRoot></pFcArmRoot>
<FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
<GenerateListings>0</GenerateListings>
<asHll>1</asHll>
<asAsm>1</asAsm>
<asMacX>1</asMacX>
<asSyms>1</asSyms>
<asFals>1</asFals>
<asDbgD>1</asDbgD>
<asForm>1</asForm>
<ldLst>0</ldLst>
<ldmm>1</ldmm>
<ldXref>1</ldXref>
<BigEnd>0</BigEnd>
<AdsALst>1</AdsALst>
<AdsACrf>1</AdsACrf>
<AdsANop>0</AdsANop>
<AdsANot>0</AdsANot>
<AdsLLst>1</AdsLLst>
<AdsLmap>1</AdsLmap>
<AdsLcgr>1</AdsLcgr>
<AdsLsym>1</AdsLsym>
<AdsLszi>1</AdsLszi>
<AdsLtoi>1</AdsLtoi>
<AdsLsun>1</AdsLsun>
<AdsLven>1</AdsLven>
<AdsLsxf>1</AdsLsxf>
<RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst>
<AdsCpuType>"Cortex-M4"</AdsCpuType>
<RvctDeviceName></RvctDeviceName>
<mOS>0</mOS>
<uocRom>0</uocRom>
<uocRam>0</uocRam>
<hadIROM>1</hadIROM>
<hadIRAM>1</hadIRAM>
<hadXRAM>0</hadXRAM>
<uocXRam>0</uocXRam>
<RvdsVP>2</RvdsVP>
<hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2>
<StupSel>8</StupSel>
<useUlib>0</useUlib>
<EndSel>0</EndSel>
<uLtcg>0</uLtcg>
<nSecure>0</nSecure>
<RoSelD>3</RoSelD>
<RwSelD>3</RwSelD>
<CodeSel>0</CodeSel>
<OptFeed>0</OptFeed>
<NoZi1>0</NoZi1>
<NoZi2>0</NoZi2>
<NoZi3>0</NoZi3>
<NoZi4>0</NoZi4>
<NoZi5>0</NoZi5>
<Ro1Chk>0</Ro1Chk>
<Ro2Chk>0</Ro2Chk>
<Ro3Chk>0</Ro3Chk>
<Ir1Chk>1</Ir1Chk>
<Ir2Chk>0</Ir2Chk>
<Ra1Chk>0</Ra1Chk>
<Ra2Chk>0</Ra2Chk>
<Ra3Chk>0</Ra3Chk>
<Im1Chk>1</Im1Chk>
<Im2Chk>0</Im2Chk>
<OnChipMemories>
<Ocm1>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm1>
<Ocm2>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm2>
<Ocm3>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm3>
<Ocm4>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm4>
<Ocm5>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm5>
<Ocm6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</Ocm6>
<IRAM>
<Type>0</Type>
<StartAddress>0x10000000</StartAddress>
<Size>0x60000</Size>
</IRAM>
<IROM>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x100000</Size>
</IROM>
<XRAM>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</XRAM>
<OCR_RVCT1>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT1>
<OCR_RVCT2>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT2>
<OCR_RVCT3>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT3>
<OCR_RVCT4>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x100000</Size>
</OCR_RVCT4>
<OCR_RVCT5>
<Type>1</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT5>
<OCR_RVCT6>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT6>
<OCR_RVCT7>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT7>
<OCR_RVCT8>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT8>
<OCR_RVCT9>
<Type>0</Type>
<StartAddress>0x10000000</StartAddress>
<Size>0x60000</Size>
</OCR_RVCT9>
<OCR_RVCT10>
<Type>0</Type>
<StartAddress>0x0</StartAddress>
<Size>0x0</Size>
</OCR_RVCT10>
</OnChipMemories>
<RvctStartVector></RvctStartVector>
</ArmAdsMisc>
<Cads>
<interw>1</interw>
<Optim>4</Optim>
<oTime>1</oTime>
<SplitLS>0</SplitLS>
<OneElfS>1</OneElfS>
<Strict>0</Strict>
<EnumInt>0</EnumInt>
<PlainCh>0</PlainCh>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<wLevel>2</wLevel>
<uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
<uC99>1</uC99>
<useXO>0</useXO>
<v6Lang>1</v6Lang>
<v6LangP>1</v6LangP>
<vShortEn>1</vShortEn>
<vShortWch>1</vShortWch>
<v6Lto>0</v6Lto>
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>AM_ASSERT_INVALID_THRESHOLD=0 AM_DEBUG_ASSERT AM_PART_APOLLO3 keil</Define>
<Undefine></Undefine>
<IncludePath>../../../../CMSIS/AmbiqMicro/Include;../../../../mcu/apollo3;../../../../CMSIS/ARM/Include</IncludePath>
</VariousControls>
</Cads>
<Aads>
<interw>1</interw>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<thumb>0</thumb>
<SplitLS>0</SplitLS>
<SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
<useXO>0</useXO>
<uClangAs>0</uClangAs>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<Undefine></Undefine>
<IncludePath></IncludePath>
</VariousControls>
</Aads>
<LDads>
<umfTarg>0</umfTarg>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<noStLib>0</noStLib>
<RepFail>1</RepFail>
<useFile>0</useFile>
<TextAddressRange>0x0</TextAddressRange>
<DataAddressRange>0x10000000</DataAddressRange>
<pXoBase></pXoBase>
<ScatterFile></ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<Misc></Misc>
<LinkerInputFile></LinkerInputFile>
<DisabledWarnings></DisabledWarnings>
</LDads>
</TargetArmAds>
</TargetOption>
<Groups>
<Group>
<GroupName>source_files</GroupName>
<Files>
<File>
<FileName>am_hal_adc.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_adc.c</FilePath>
</File>
<File>
<FileName>am_hal_ble.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_ble.c</FilePath>
</File>
<File>
<FileName>am_hal_ble_patch.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_ble_patch.c</FilePath>
</File>
<File>
<FileName>am_hal_ble_patch_b0.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_ble_patch_b0.c</FilePath>
</File>
<File>
<FileName>am_hal_burst.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_burst.c</FilePath>
</File>
<File>
<FileName>am_hal_cachectrl.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_cachectrl.c</FilePath>
</File>
<File>
<FileName>am_hal_clkgen.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_clkgen.c</FilePath>
</File>
<File>
<FileName>am_hal_cmdq.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_cmdq.c</FilePath>
</File>
<File>
<FileName>am_hal_ctimer.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_ctimer.c</FilePath>
</File>
<File>
<FileName>am_hal_debug.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_debug.c</FilePath>
</File>
<File>
<FileName>am_hal_flash.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_flash.c</FilePath>
</File>
<File>
<FileName>am_hal_global.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_global.c</FilePath>
</File>
<File>
<FileName>am_hal_gpio.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_gpio.c</FilePath>
</File>
<File>
<FileName>am_hal_interrupt.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_interrupt.c</FilePath>
</File>
<File>
<FileName>am_hal_iom.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_iom.c</FilePath>
</File>
<File>
<FileName>am_hal_ios.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_ios.c</FilePath>
</File>
<File>
<FileName>am_hal_itm.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_itm.c</FilePath>
</File>
<File>
<FileName>am_hal_mcuctrl.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_mcuctrl.c</FilePath>
</File>
<File>
<FileName>am_hal_mspi.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_mspi.c</FilePath>
</File>
<File>
<FileName>am_hal_pdm.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_pdm.c</FilePath>
</File>
<File>
<FileName>am_hal_pwrctrl.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_pwrctrl.c</FilePath>
</File>
<File>
<FileName>am_hal_queue.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_queue.c</FilePath>
</File>
<File>
<FileName>am_hal_reset.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_reset.c</FilePath>
</File>
<File>
<FileName>am_hal_rtc.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_rtc.c</FilePath>
</File>
<File>
<FileName>am_hal_scard.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_scard.c</FilePath>
</File>
<File>
<FileName>am_hal_secure_ota.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_secure_ota.c</FilePath>
</File>
<File>
<FileName>am_hal_security.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_security.c</FilePath>
</File>
<File>
<FileName>am_hal_stimer.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_stimer.c</FilePath>
</File>
<File>
<FileName>am_hal_sysctrl.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_sysctrl.c</FilePath>
</File>
<File>
<FileName>am_hal_systick.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_systick.c</FilePath>
</File>
<File>
<FileName>am_hal_tpiu.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_tpiu.c</FilePath>
</File>
<File>
<FileName>am_hal_uart.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_uart.c</FilePath>
</File>
<File>
<FileName>am_hal_wdt.c</FileName>
<FileType>1</FileType>
<FilePath>../am_hal_wdt.c</FilePath>
</File>
</Files>
</Group>
<Group>
<GroupName>lib</GroupName>
<Files>
</Files>
</Group>
</Groups>
</Target>
</Targets>
<RTE>
<apis/>
<components/>
<files/>
</RTE>
</Project>