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,76 @@
//*****************************************************************************
//
//! @file am_util.h
//!
//! @brief Top Include for all of the utilities
//!
//! This file provides all the includes necessary to use the utilities.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_H
#define AM_UTIL_H
//*****************************************************************************
//
// C99
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
//*****************************************************************************
//
// Utilities
//
//*****************************************************************************
#include "am_util_debug.h"
#include "am_util_delay.h"
#include "am_util_id.h"
#include "am_util_regdump.h"
#include "am_util_stdio.h"
#include "am_util_string.h"
#include "am_util_time.h"
#if defined(AM_PART_APOLLO3) || defined(AM_PART_APOLLO3P)
#include "am_util_ble.h"
#endif
#endif // AM_UTIL_H
@@ -0,0 +1,631 @@
//*****************************************************************************
//
//! @file am_util_apollo3_ble.c
//!
//! @brief Useful BLE functions not covered by the HAL.
//!
//! This file contains functions for interacting with the Apollo3 BLE hardware
//! that are not already covered by the HAL. Most of these commands either
//! adjust RF settings or facilitate RF testing operations.
//
//*****************************************************************************
//*****************************************************************************
//
// 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 <string.h>
#include "am_util_delay.h"
#include "am_mcu_apollo.h"
//*****************************************************************************
//
// Globals
//
//*****************************************************************************
//*****************************************************************************
//
// In DTM mode, set TX to constant trans mode for SRRC/FCC/CE
//set enable as 'true' to constant trans mode, 'false' back to normal
//*****************************************************************************
uint32_t
am_util_ble_set_constant_transmission(void *pHandle, bool enable)
{
am_hal_ble_state_t *pBLE = pHandle;
am_hal_ble_sleep_set(pBLE, false);
am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
if ( enable )
{
am_hal_ble_plf_reg_write(pBLE, 0x508000E0, 0x00008000);
}
else
{
am_hal_ble_plf_reg_write(pBLE, 0x508000E0, 0x00000000);
}
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Manually enable/disable transmitter
// set ui8TxCtrl as 1 to manually enable transmitter, 0 back to default
//
//*****************************************************************************
uint32_t
am_util_ble_transmitter_control(void *pHandle, uint8_t ui8TxCtrl)
{
am_hal_ble_state_t *pBLE = pHandle;
uint32_t RegValueTRX;
am_hal_ble_sleep_set(pBLE, false);
if (ui8TxCtrl)
{
RegValueTRX = 0x2000A;
}
else
{
RegValueTRX = 0x8;
}
//
// Unlock the BLE registers.
//
am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
am_hal_ble_plf_reg_write(pBLE, 0x52400000, RegValueTRX);
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//to fix the channel 1 bug in DTM mode
//
//*****************************************************************************
uint32_t
am_util_ble_init_rf_channel(void *pHandle)
{
if (!APOLLO3_GE_B0)
{
am_hal_ble_buffer(16) sWriteCommand;
am_hal_ble_buffer(16) sResponse;
am_hal_ble_state_t *pBLE = pHandle;
uint32_t ui32IntEnable;
uint32_t ui32Module = pBLE->ui32Module;
am_hal_ble_sleep_set(pBLE, false);
//issue the HCI command with to init for the channel 1
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x1d;
sWriteCommand.bytes[2] = 0x20;
sWriteCommand.bytes[3] = 0x01;
sWriteCommand.bytes[4] = 0x00;
//
// Temporarily disable BLE interrupts.
//
ui32IntEnable = BLEIFn(ui32Module)->INTEN;
BLEIFn(ui32Module)->INTEN = 0;
// reserved packet_payload
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
5);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
am_util_delay_ms(10);
// issue the HCI command with to stop test for the channel 1
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x1f;
sWriteCommand.bytes[2] = 0x20;
sWriteCommand.bytes[3] = 0x00;
// reserved packet_payload
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
4);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
//
// Re-enable BLE interrupts.
//
BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
BLEIFn(ui32Module)->INTEN = ui32IntEnable;
}
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// BLE init for BQB test
//set enable as 'true' to init as BQB test mode, 'false' back to default
//*****************************************************************************
uint32_t
am_util_ble_BQB_test_init(void *pHandle, bool enable)
{
am_hal_ble_state_t *pBLE = pHandle;
am_hal_ble_sleep_set(pBLE, false);
am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
if ( enable )
{
am_hal_ble_plf_reg_write(pBLE, 0x51800028, 0x0000209c);
}
else
{
am_hal_ble_plf_reg_write(pBLE, 0x51800028, 0x00003ff6);
}
am_hal_ble_plf_reg_write(pBLE, 0x45800070, 0x100);
am_hal_ble_plf_reg_write(pBLE, 0x45800070, 0);
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Set the 32M crystal frequency
// based on the tested values at customer side.
// set trim value smaller in case of negative frequency offset
// ui32TrimValue: default is 0x400
//*****************************************************************************
uint32_t
am_util_ble_crystal_trim_set(void *pHandle, uint32_t ui32TrimValue)
{
am_hal_ble_state_t *pBLE = pHandle;
uint32_t RegValueMCGR;
ui32TrimValue &= 0x7FF;
am_hal_ble_plf_reg_read(pBLE, 0x43000004, &RegValueMCGR);
//
// Unlock the BLE registers.
//
am_hal_ble_plf_reg_write(pBLE, 0x43000004, 0xFFFFFFFF);
am_hal_ble_plf_reg_write(pBLE, 0x43800004, ui32TrimValue);
am_hal_ble_plf_reg_write(pBLE, 0x43000004, RegValueMCGR);
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Manually enable/disable transmitter to output carrier signal
// set ui8TxChannel as 0 to 0x27 for each transmit channel, 0xFF back to normal modulate mode
//
//*****************************************************************************
uint32_t
am_util_ble_hci_reset(void *pHandle)
{
am_hal_ble_buffer(16) sWriteCommand;
am_hal_ble_buffer(16) sResponse;
am_hal_ble_state_t *pBLE = pHandle;
uint32_t ui32IntEnable;
am_hal_ble_sleep_set(pBLE, false);
uint32_t ui32Module = pBLE->ui32Module;
// issue the HCI command with to reset hci
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x03;
sWriteCommand.bytes[2] = 0x0c;
sWriteCommand.bytes[3] = 0x00;
//
// Temporarily disable BLE interrupts.
//
ui32IntEnable = BLEIFn(ui32Module)->INTEN;
BLEIFn(ui32Module)->INTEN = 0;
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
4);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
for (uint32_t i = 0; i < 1000; i++)
{
if ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0 )
{
break;
}
else if (i == (1000 - 1))
{
return AM_HAL_BLE_NO_HCI_RESPONSE;
}
else
{
am_util_delay_ms(1);
}
}
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
//
// Re-enable BLE interrupts.
//
BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
BLEIFn(ui32Module)->INTEN = ui32IntEnable;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//to do directly output modulation signal. change channel ranges from 0 to 0x27, pattern from 0 to 7.
//
//*****************************************************************************
uint32_t
am_util_ble_trasmitter_test_ex(void *pHandle, uint8_t channel, uint8_t pattern)
{
am_hal_ble_buffer(16) sWriteCommand;
am_hal_ble_buffer(16) sResponse;
am_hal_ble_state_t *pBLE = pHandle;
uint32_t ui32IntEnable;
am_hal_ble_sleep_set(pBLE, false);
uint32_t ui32Module = pBLE->ui32Module;
// issue the HCI command with to TX carrier wave
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x1E;
sWriteCommand.bytes[2] = 0x20;
sWriteCommand.bytes[3] = 0x03;
sWriteCommand.bytes[4] = channel;
sWriteCommand.bytes[5] = 0x25;
sWriteCommand.bytes[6] = pattern;
//
// Temporarily disable BLE interrupts.
//
ui32IntEnable = BLEIFn(ui32Module)->INTEN;
BLEIFn(ui32Module)->INTEN = 0;
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
7);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
for (uint32_t i = 0; i < 100; i++)
{
if (BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0)
{
break;
}
else if (i == (100 - 1))
{
return AM_HAL_BLE_NO_HCI_RESPONSE;
}
else
{
am_util_delay_ms(1);
}
}
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
//
// Re-enable BLE interrupts.
//
BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
BLEIFn(ui32Module)->INTEN = ui32IntEnable;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//to do directly receiver test. change channel ranges from 0 to 0x27, return received packets in 100ms.
//
//*****************************************************************************
uint32_t
am_util_ble_receiver_test_ex(void *pHandle, uint8_t channel, uint32_t *recvpackets)
{
am_hal_ble_buffer(16) sWriteCommand;
am_hal_ble_buffer(16) sResponse;
am_hal_ble_state_t *pBLE = pHandle;
uint32_t ui32IntEnable;
uint32_t ui32Module = pBLE->ui32Module;
am_hal_ble_sleep_set(pBLE, false);
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x1d;
sWriteCommand.bytes[2] = 0x20;
sWriteCommand.bytes[3] = 0x01;
sWriteCommand.bytes[4] = channel;
//
// Temporarily disable BLE interrupts.
//
ui32IntEnable = BLEIFn(ui32Module)->INTEN;
BLEIFn(ui32Module)->INTEN = 0;
// reserved packet_payload
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
5);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
am_util_delay_ms(100);
// issue the HCI command with to stop test for the channel 1
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x1f;
sWriteCommand.bytes[2] = 0x20;
sWriteCommand.bytes[3] = 0x00;
// reserved packet_payload
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
4);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
while ( BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ == 0 );
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
*recvpackets = (sResponse.bytes[8] << 8) + sResponse.bytes[7];
//
// Re-enable BLE interrupts.
//
BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
BLEIFn(ui32Module)->INTEN = ui32IntEnable;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
//to directly output carrier wave. change channel ranges from 0 to 0x27.
//
//*****************************************************************************
uint32_t
am_util_ble_set_carrier_wave_ex(void *pHandle, uint8_t channel)
{
am_hal_ble_buffer(16) sWriteCommand;
am_hal_ble_buffer(16) sResponse;
am_hal_ble_state_t *pBLE = pHandle;
uint32_t ui32IntEnable;
// channel 0xFF to disable the constant transmission
if ( channel == 0xFF )
{
am_util_ble_transmitter_control(pBLE, false);
return AM_HAL_STATUS_SUCCESS;
}
am_hal_ble_sleep_set(pBLE, false);
uint32_t ui32Module = pBLE->ui32Module;
// issue the HCI command with to TX carrier wave
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x1E;
sWriteCommand.bytes[2] = 0x20;
sWriteCommand.bytes[3] = 0x03;
sWriteCommand.bytes[4] = channel;
sWriteCommand.bytes[5] = 0x25;
sWriteCommand.bytes[6] = 0x00;
//
// Temporarily disable BLE interrupts.
//
ui32IntEnable = BLEIFn(ui32Module)->INTEN;
BLEIFn(ui32Module)->INTEN = 0;
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
7);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
for (uint32_t i = 0; i < 100; i++)
{
if (BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0)
{
break;
}
else if (i == (100 - 1))
{
return AM_HAL_BLE_NO_HCI_RESPONSE;
}
else
{
am_util_delay_ms(1);
}
}
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
//
// Re-enable BLE interrupts.
//
BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
BLEIFn(ui32Module)->INTEN = ui32IntEnable;
am_util_ble_transmitter_control(pBLE, true);
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// Manually enable/disable transmitter to output carrier wave signal
// set ui8TxChannel as 0 to 0x27 for each transmit channel, 0xFF back to normal modulate mode
//
//*****************************************************************************
uint32_t
am_util_ble_transmitter_control_ex(void *pHandle, uint8_t ui8TxChannel)
{
return am_util_ble_set_carrier_wave_ex(pHandle, ui8TxChannel);
}
//*****************************************************************************
//
//to directly output constant modulation signal. change channel from 0 to 0x27.
//
//*****************************************************************************
uint32_t
am_util_ble_set_constant_transmission_ex(void *pHandle, uint8_t channel)
{
am_hal_ble_buffer(16) sWriteCommand;
am_hal_ble_buffer(16) sResponse;
am_hal_ble_state_t *pBLE = pHandle;
uint32_t ui32IntEnable;
// channel 0xFF to disable the constant transmission
if ( channel == 0xFF )
{
am_util_ble_set_constant_transmission(pBLE, false);
return AM_HAL_STATUS_SUCCESS;
}
uint32_t ui32Module = pBLE->ui32Module;
am_util_ble_set_constant_transmission(pBLE, true);
// issue the HCI command with to TX constant transmission
sWriteCommand.bytes[0] = 0x01;
sWriteCommand.bytes[1] = 0x1E;
sWriteCommand.bytes[2] = 0x20;
sWriteCommand.bytes[3] = 0x03;
sWriteCommand.bytes[4] = channel;
sWriteCommand.bytes[5] = 0x25;
sWriteCommand.bytes[6] = 0x00;
//
// Temporarily disable BLE interrupts.
//
ui32IntEnable = BLEIFn(ui32Module)->INTEN;
BLEIFn(ui32Module)->INTEN = 0;
am_hal_ble_blocking_hci_write(pBLE,
AM_HAL_BLE_RAW,
sWriteCommand.words,
7);
BLEIFn(ui32Module)->BLEDBG_b.IOCLKON = 1;
//
// Wait for the response.
//
for (uint32_t i = 0; i < 100; i++)
{
if (BLEIFn(ui32Module)->BSTATUS_b.BLEIRQ != 0)
{
break;
}
else if (i == (100 - 1))
{
return AM_HAL_BLE_NO_HCI_RESPONSE;
}
else
{
am_util_delay_ms(1);
}
}
am_hal_ble_blocking_hci_read(pBLE, sResponse.words, 0);
//
// Re-enable BLE interrupts.
//
BLEIFn(ui32Module)->INTCLR = ui32IntEnable;
BLEIFn(ui32Module)->INTEN = ui32IntEnable;
return AM_HAL_STATUS_SUCCESS;
}
//*****************************************************************************
//
// read current modex value from BLEIP
//*****************************************************************************
uint32_t
am_util_ble_read_modex_value(void *pHandle)
{
am_hal_ble_state_t *pBLE = pHandle;
uint32_t temp = 0;
if (APOLLO3_GE_B0)
{
// for B0 Chip,the modex value address is changed to 0x20006874
am_hal_ble_plf_reg_read(pBLE, 0x20006874, &temp);
}
else
{
am_hal_ble_plf_reg_read(pBLE, 0x20006070, &temp);
}
return temp;
}
@@ -0,0 +1,81 @@
//*****************************************************************************
//
//! @file am_util_apollo3_ble.h
//!
//! @brief Useful BLE functions not covered by the HAL.
//!
//! This file contains functions for interacting with the Apollo3 BLE hardware
//! that are not already covered by the HAL. Most of these commands either
//! adjust RF settings or facilitate RF testing operations.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_BLE_H
#define AM_UTIL_BLE_H
//*****************************************************************************
//
// External function declarations.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif
extern uint32_t am_util_ble_set_constant_transmission(void *pHandle, bool enable);
extern uint32_t am_util_ble_transmitter_control(void *pHandle, uint8_t ui8TxCtrl);
extern uint32_t am_util_ble_init_rf_channel(void *pHandle);
extern uint32_t am_util_ble_BQB_test_init(void *pHandle, bool enable);
extern uint32_t am_util_ble_crystal_trim_set(void *pHandle, uint32_t ui32TrimValue);
extern uint32_t am_util_ble_hci_reset(void *pHandle);
extern uint32_t am_util_ble_trasmitter_test_ex(void *pHandle, uint8_t channel, uint8_t pattern);
extern uint32_t am_util_ble_receiver_test_ex(void *pHandle, uint8_t channel, uint32_t *recvpackets);
extern uint32_t am_util_ble_set_carrier_wave_ex(void *pHandle, uint8_t channel);
extern uint32_t am_util_ble_transmitter_control_ex(void *pHandle, uint8_t ui8TxChannel);
extern uint32_t am_util_ble_set_constant_transmission_ex(void *pHandle, uint8_t channel);
extern uint32_t am_util_ble_read_modex_value(void *pHandle);
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_BLE_H
@@ -0,0 +1,51 @@
//*****************************************************************************
//
//! @file am_util_debug.c
//!
//! @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.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_util_debug.h"
@@ -0,0 +1,114 @@
//*****************************************************************************
//
//! @file am_util_debug.h
//!
//! @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.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_DEBUG_H
#define AM_UTIL_DEBUG_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Debug printf macros.
//
//*****************************************************************************
#ifdef AM_DEBUG_PRINTF
#define am_util_debug_printf_init(x) \
am_util_stdio_printf_init(x);
#define am_util_debug_printf(...) \
am_util_stdio_printf(__VA_ARGS__);
#else
#define am_util_debug_printf_init(...)
#define am_util_debug_printf(...)
#endif // AM_DEBUG_PRINTF
//*****************************************************************************
//
// Debug trace macros.
//
//*****************************************************************************
#ifdef AM_DEBUG_TRACE
#define am_util_debug_trace_init(PinNumber) \
do \
{ \
am_hal_gpio_out_bit_clear(PinNumber); \
am_hal_gpio_pin_config(PinNumber, AM_HAL_GPIO_OUTPUT); \
} \
while(0)
#define am_util_debug_trace_start(PinNumber) \
am_hal_gpio_out_bit_set(PinNumber)
#define am_util_debug_trace_end(PinNumber) \
am_hal_gpio_out_bit_clear(PinNumber)
#else
#define am_util_debug_trace_init(PinNumber)
#define am_util_debug_trace_start(PinNumber)
#define am_util_debug_trace_end(PinNumber)
#endif // AM_DEBUG_TRACE
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_DEBUG_H
@@ -0,0 +1,137 @@
//*****************************************************************************
//
//! @file am_util_delay.c
//!
//! @brief A few useful delay functions.
//!
//! Functions for fixed delays.
//
//*****************************************************************************
//*****************************************************************************
//
// 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"
#include "am_util_delay.h"
//*****************************************************************************
//
//! @brief Delays for a desired amount of loops.
//!
//! @param ui32CycleLoops - Desired number of cycle loops to delay for.
//!
//! This function will delay for a number of cycle loops.
//!
//! @note - the number of cycles each loops takes to execute is approximately 3.
//! Therefore the actual number of cycles executed will be ~3x ui32CycleLoops.
//!
//! For example, a ui32CycleLoops value of 100 will delay for 300 cycles.
//!
//! @returns None
//
//*****************************************************************************
void
am_util_delay_cycles(uint32_t ui32Iterations)
{
//
// Call the BOOTROM cycle delay function
//
am_hal_flash_delay(ui32Iterations);
}
//*****************************************************************************
//
//! @brief Delays for a desired amount of milliseconds.
//!
//! @param ui32MilliSeconds - number of milliseconds to delay for.
//!
//! This function will delay for a number of milliseconds.
//!
//! @returns None
//
//*****************************************************************************
void
am_util_delay_ms(uint32_t ui32MilliSeconds)
{
uint32_t ui32Loops, ui32HFRC;
#if AM_APOLLO3_CLKGEN
am_hal_clkgen_status_t sClkgenStatus;
am_hal_clkgen_status_get(&sClkgenStatus);
ui32HFRC = sClkgenStatus.ui32SysclkFreq;
#else // AM_APOLLO3_CLKGEN
ui32HFRC = am_hal_clkgen_sysclk_get();
#endif // AM_APOLLO3_CLKGEN
ui32Loops = ui32MilliSeconds * (ui32HFRC / 3000);
//
// Call the BOOTROM cycle delay function
//
am_hal_flash_delay(ui32Loops);
}
//*****************************************************************************
//
//! @brief Delays for a desired amount of microseconds.
//!
//! @param ui32MicroSeconds - number of microseconds to delay for.
//!
//! This function will delay for a number of microseconds.
//!
//! @returns None
//
//*****************************************************************************
void
am_util_delay_us(uint32_t ui32MicroSeconds)
{
uint32_t ui32Loops, ui32HFRC;
#if AM_APOLLO3_CLKGEN
am_hal_clkgen_status_t sClkgenStatus;
am_hal_clkgen_status_get(&sClkgenStatus);
ui32HFRC = sClkgenStatus.ui32SysclkFreq;
#else // AM_APOLLO3_CLKGEN
ui32HFRC = am_hal_clkgen_sysclk_get();
#endif // AM_APOLLO3_CLKGEN
ui32Loops = ui32MicroSeconds * (ui32HFRC / 3000000);
//
// Call the BOOTROM cycle delay function
//
am_hal_flash_delay(ui32Loops);
}
@@ -0,0 +1,68 @@
//*****************************************************************************
//
//! @file am_util_delay.h
//!
//! @brief A few useful delay functions
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_DELAY_H
#define AM_UTIL_DELAY_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_util_delay_cycles(uint32_t ui32Iterations);
extern void am_util_delay_ms(uint32_t ui32MilliSeconds);
extern void am_util_delay_us(uint32_t ui32MicroSeconds);
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_DELAY_H
@@ -0,0 +1,444 @@
//*****************************************************************************
//
//! @file am_util_faultisr.c
//!
//! @brief An extended hard-fault handler.
//
// This module is intended to be completely portable with no HAL or BSP
// dependencies.
//
// Further, it is intended to be compiler/platform independent enabling it to
// run on GCC, Keil, IAR, etc.
//
//*****************************************************************************
//*****************************************************************************
//
// 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 "am_mcu_apollo.h"
//*****************************************************************************
//
// Macros
//
//*****************************************************************************
//
// Macros used by am_util_faultisr_collect_data().
//
#define AM_REG_SYSCTRL_CFSR_O 0xE000ED28
#define AM_REG_SYSCTRL_BFAR_O 0xE000ED38
#define AM_REGVAL(x) (*((volatile uint32_t *)(x)))
//*****************************************************************************
//
// Data structures
//
//*****************************************************************************
//
// Define a structure for local storage in am_util_faultisr_collect_data().
// Set structure alignment to 1 byte to minimize storage requirements.
//
#pragma pack(1)
typedef struct
{
//
// Stacked registers
//
volatile uint32_t u32R0;
volatile uint32_t u32R1;
volatile uint32_t u32R2;
volatile uint32_t u32R3;
volatile uint32_t u32R12;
volatile uint32_t u32LR;
volatile uint32_t u32PC;
volatile uint32_t u32PSR;
//
// Other data
//
volatile uint32_t u32FaultAddr;
volatile uint32_t u32BFAR;
volatile uint32_t u32CFSR;
volatile uint8_t u8MMSR;
volatile uint8_t u8BFSR;
volatile uint16_t u16UFSR;
} am_fault_t;
//
// Restore the default structure alignment
//
#pragma pack()
//*****************************************************************************
//
// Prototypes
//
//*****************************************************************************
void am_util_faultisr_collect_data(uint32_t u32IsrSP);
//
// Prototype for printf, if used.
//
extern uint32_t am_util_stdio_printf(char *pui8Fmt, ...);
//*****************************************************************************
//
// getStackedReg() will retrieve a specified register value, as it was stacked
// by the processor after the fault, from the stack.
//
// The registers are stacked in the following order:
// R0, R1, R2, R3, R12, LR, PC, PSR.
// To get R0 from the stack, call getStackedReg(0), r1 is getStackedReg(1)...
//
//*****************************************************************************
#if (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION < 6000000)
__asm uint32_t
#if AM_CMSIS_REGS
HardFault_Handler(void)
#else // AM_CMSIS_REGS
am_fault_isr(void)
#endif // AM_CMSIS_REGS
{
import am_util_faultisr_collect_data
push {r0, lr} // Always pushes to MSP stack
tst lr, #4 // Check if we should use MSP or PSP
itet eq // Instrs executed when: eq,ne,eq
mrseq r0, msp // bit2=0 indicating MSP stack
mrsne r0, psp // e: bit2=1 indicating PSP stack
addseq r0, r0, #8 // t: bit2=0, adjust for pushes to MSP stack
bl am_util_faultisr_collect_data
pop {r0, pc} // Restore from MSP stack
}
__asm uint32_t
getStackedReg(uint32_t regnum, uint32_t u32SP)
{
lsls r0, r0, #2
adds r0, r0, r1
ldr r0, [r0]
bx lr
}
#elif (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION > 6000000)
uint32_t __attribute__((naked))
#if AM_CMSIS_REGS
HardFault_Handler(void)
#else // AM_CMSIS_REGS
am_fault_isr(void)
#endif // AM_CMSIS_REGS
{
__asm(" push {r0,lr}"); // Always pushes to MSP stack
__asm(" tst lr, #4\n" // Check if we should use MSP or PSP
" itet eq\n" // Instrs executed when: eq,ne,eq
" mrseq r0, msp\n" // bit2=0 indicating MSP stack
" mrsne r0, psp\n" // e: bit2=1 indicating PSP stack
" addseq r0, r0, #8\n"); // t: bit2=0, adjust for pushes to MSP stack
__asm(" bl am_util_faultisr_collect_data");
__asm(" pop {r0,pc}"); // Restore from MSP stack
}
uint32_t __attribute__((naked))
getStackedReg(uint32_t regnum, uint32_t u32SP)
{
__asm(" lsls r0, r0, #2");
__asm(" adds r0, r1");
__asm(" ldr r0, [r0]");
__asm(" bx lr");
}
#elif defined(__GNUC_STDC_INLINE__)
uint32_t __attribute__((naked))
#if AM_CMSIS_REGS
HardFault_Handler(void)
#else // AM_CMSIS_REGS
am_fault_isr(void)
#endif // AM_CMSIS_REGS
{
__asm(" push {r0,lr}"); // Always pushes to MSP stack
__asm(" tst lr, #4"); // Check if we should use MSP or PSP
__asm(" itet eq"); // Instrs executed when: eq,ne,eq
__asm(" mrseq r0, msp"); // bit2=0 indicating MSP stack
__asm(" mrsne r0, psp"); // e: bit2=1 indicating PSP stack
__asm(" addseq r0, r0, #8"); // t: bit2=0, adjust for pushes to MSP stack
__asm(" bl am_util_faultisr_collect_data");
__asm(" pop {r0,pc}"); // Restore from MSP stack
}
uint32_t __attribute__((naked))
getStackedReg(uint32_t regnum, uint32_t u32SP)
{
__asm(" lsls r0, r0, #2");
__asm(" adds r0, r1");
__asm(" ldr r0, [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 uint32_t
#if AM_CMSIS_REGS
HardFault_Handler(void)
#else // AM_CMSIS_REGS
am_fault_isr(void)
#endif // AM_CMSIS_REGS
{
__asm("push {r0,lr}"); // Always pushes to MSP stack
__asm("tst lr, #4\n" // Check if we should use MSP or PSP
"itet eq\n" // Instrs executed when: eq,ne,eq
"mrseq r0, msp\n" // bit2=0 indicating MSP stack
"mrsne r0, psp\n" // e: bit2=1 indicating PSP stack
"addseq r0, r0, #8\n"); // t: bit2=0, adjust for pushes to MSP stack
__asm("bl am_util_faultisr_collect_data");
__asm("pop {r0,pc}"); // Restore from MSP stack
}
__stackless uint32_t
getStackedReg(uint32_t regnum, uint32_t u32SP)
{
__asm(" lsls r0, r0, #2");
__asm(" adds r0, r0, r1");
__asm(" ldr r0, [r0]");
__asm(" bx lr");
}
#pragma diag_default = Pe940 // Restore IAR compiler warning
#endif
//*****************************************************************************
//
// am_util_faultisr_collect_data(uint32_t u32IsrSP);
//
// This function is intended to be called by HardFault_Handler(), called
// when the processor receives a hard fault interrupt. This part of the
// handler parses through the various fault codes and saves them into a data
// structure so they can be readily examined by the user in the debugger.
//
// The input u32IsrSP is expected to be the value of the stack pointer when
// HardFault_Handler() was called.
//
//*****************************************************************************
void
am_util_faultisr_collect_data(uint32_t u32IsrSP)
{
volatile am_fault_t sFaultData;
am_hal_mcuctrl_fault_t sHalFaultData = {0};
uint32_t u32Mask = 0;
//
// Following is a brief overview of fault information provided by the M4.
// More details can be found in the Cortex M4 User Guide.
//
// CFSR (Configurable Fault Status Reg) contains MMSR, BFSR, and UFSR:
// 7:0 MMSR (MemManage)
// [0] IACCVIOL Instr fetch from a location that does not
// permit execution.
// [1] DACCVIOL Data access violation flag. MMAR contains
// address of the attempted access.
// [2] Reserved
// [3] MUNSTKERR MemMange fault on unstacking for a return
// from exception.
// [4] MSTKERR MemMange fault on stacking for exception
// entry.
// [5] MLSPERR MemMange fault during FP lazy state
// preservation.
// [6] Reserved
// [7] MMARVALID MemManage Fault Addr Reg (MMFAR) valid flag.
// 15:8 BusFault
// [0] IBUSERR If set, instruction bus error.
// [1] PRECISERR Data bus error. Stacked PC points to instr
// that caused the fault.
// [2] IMPRECISERR Data bus error, but stacked return addr is not
// related to the instr that caused the error and
// BFAR is not valid.
// [3] UNSTKERR Bus fault on unstacking for a return from
// exception.
// [4] STKERR Bus fault on stacking for exception entry.
// [5] LSPERR Bus fault during FP lazy state preservation.
// [6] Reserved
// [7] BFARVALID BFAR valid.
// 31:16 UFSR (UsageFault)
// [0] UNDEFINSTR Undefined instruction.
// [1] INVSTATE Invalid state.
// [2] INVPC Invalid PC load.
// [3] NOCP No coprocessor.
// [7:4] Reserved
// [8] UNALIGNED Unaligned access.
// [9] DIVBYZERO Divide by zero.
// [15:10] Reserved
//
//
// u32Mask is used for 2 things: 1) in the print loop, 2) as a spot to set
// a breakpoint at the end of the routine. If the printing is not used,
// we'll get a compiler warning; so to avoid that warning, we'll use it
// in a dummy assignment here.
//
sFaultData.u32CFSR = u32Mask; // Avoid compiler warning
sFaultData.u32CFSR = AM_REGVAL(AM_REG_SYSCTRL_CFSR_O);
sFaultData.u8MMSR = (sFaultData.u32CFSR >> 0) & 0xff;
sFaultData.u8BFSR = (sFaultData.u32CFSR >> 8) & 0xff;
sFaultData.u16UFSR = (sFaultData.u32CFSR >> 16) & 0xffff;
//
// The address of the location that caused the fault. e.g. if accessing an
// invalid data location caused the fault, that address will appear here.
//
sFaultData.u32BFAR = AM_REGVAL(AM_REG_SYSCTRL_BFAR_O);
//
// The address of the instruction that caused the fault is the stacked PC
// if BFSR bit1 is set.
//
sFaultData.u32FaultAddr = (sFaultData.u8BFSR & 0x02) ? getStackedReg(6, u32IsrSP) : 0xffffffff;
//
// Get the stacked registers.
// Note - the address of the instruction that caused the fault is u32PC.
//
sFaultData.u32R0 = getStackedReg(0, u32IsrSP);
sFaultData.u32R1 = getStackedReg(1, u32IsrSP);
sFaultData.u32R2 = getStackedReg(2, u32IsrSP);
sFaultData.u32R3 = getStackedReg(3, u32IsrSP);
sFaultData.u32R12 = getStackedReg(4, u32IsrSP);
sFaultData.u32LR = getStackedReg(5, u32IsrSP);
sFaultData.u32PC = getStackedReg(6, u32IsrSP);
sFaultData.u32PSR = getStackedReg(7, u32IsrSP);
//
// Use the HAL MCUCTRL functions to read the fault data.
//
#if AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_info_get(AM_HAL_MCUCTRL_INFO_FAULT_STATUS, &sHalFaultData);
#else // AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_fault_status(&sHalFaultData);
#endif // AM_APOLLO3_MCUCTRL
#ifdef AM_UTIL_FAULTISR_PRINT
//
// If printf has previously been initialized in the application, we should
// be able to print out the fault information.
//
am_util_stdio_printf("Hard Fault stacked data:\n");
am_util_stdio_printf(" R0 = 0x%08X\n", sFaultData.u32R0);
am_util_stdio_printf(" R1 = 0x%08X\n", sFaultData.u32R1);
am_util_stdio_printf(" R2 = 0x%08X\n", sFaultData.u32R2);
am_util_stdio_printf(" R3 = 0x%08X\n", sFaultData.u32R3);
am_util_stdio_printf(" R12 = 0x%08X\n", sFaultData.u32R12);
am_util_stdio_printf(" LR = 0x%08X\n", sFaultData.u32LR);
am_util_stdio_printf(" PC = 0x%08X\n", sFaultData.u32PC);
am_util_stdio_printf(" PSR = 0x%08X\n", sFaultData.u32PSR);
am_util_stdio_printf("Other Hard Fault data:\n");
am_util_stdio_printf(" Fault address = 0x%08X\n", sFaultData.u32FaultAddr);
am_util_stdio_printf(" BFAR (Bus Fault Addr Reg) = 0x%08X\n", sFaultData.u32BFAR);
am_util_stdio_printf(" MMSR (Mem Mgmt Fault Status Reg) = 0x%02X\n", sFaultData.u8MMSR);
am_util_stdio_printf(" BFSR (Bus Fault Status Reg) = 0x%02X\n", sFaultData.u8BFSR);
am_util_stdio_printf(" UFSR (Usage Fault Status Reg) = 0x%04X\n", sFaultData.u16UFSR);
//
// Print out any bits set in the BFSR.
//
u32Mask = 0x80;
while (u32Mask)
{
switch (sFaultData.u8BFSR & u32Mask)
{
case 0x80:
am_util_stdio_printf(" BFSR bit7: BFARVALID\n");
break;
case 0x40:
am_util_stdio_printf(" BFSR bit6: RESERVED\n");
break;
case 0x20:
am_util_stdio_printf(" BFSR bit5: LSPERR\n");
break;
case 0x10:
am_util_stdio_printf(" BFSR bit4: STKERR\n");
break;
case 0x08:
am_util_stdio_printf(" BFSR bit3: UNSTKERR\n");
break;
case 0x04:
am_util_stdio_printf(" BFSR bit2: IMPRECISERR\n");
break;
case 0x02:
am_util_stdio_printf(" BFSR bit1: PRECISEERR\n");
break;
case 0x01:
am_util_stdio_printf(" BFSR bit0: IBUSERR\n");
break;
default:
break;
}
u32Mask >>= 1;
}
//
// Print out any Apollo* Internal fault information.
//
am_util_stdio_printf("MCU Fault data:\n");
if (sHalFaultData.bICODE)
{
am_util_stdio_printf(" ICODE Fault Address: 0x%08X\n", sHalFaultData.ui32ICODE);
}
if (sHalFaultData.bDCODE)
{
am_util_stdio_printf(" DCODE Fault Address: 0x%08X\n", sHalFaultData.ui32DCODE);
}
if (sHalFaultData.bSYS)
{
am_util_stdio_printf(" SYS Fault Address: 0x%08X\n", sHalFaultData.ui32SYS);
}
#endif
u32Mask = 0;
//
// Spin in an infinite loop.
// We need to spin here inside the function so that we have access to
// local data, i.e. sFaultData.
//
while(1)
{
}
}
@@ -0,0 +1,219 @@
//*****************************************************************************
//
//! @file am_util_id.c
//!
//! @brief Identification of the Ambiq Micro device.
//!
//! This module contains functions for run time identification of Ambiq Micro
//! devices.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_util_id.h"
//*****************************************************************************
//
// Globals.
//
//*****************************************************************************
//
// Strings for use with pui8VendorName.
//
static const uint8_t g_DeviceNameApollo[] = "Apollo";
static const uint8_t g_DeviceNameApollo2[] = "Apollo2";
static const uint8_t g_DeviceNameApollo3[] = "Apollo3 Blue";
static const uint8_t g_DeviceNameApollo3p[] = "Apollo3 Blue Plus";
static const uint8_t g_ui8VendorNameAmbq[] = "AMBQ";
static const uint8_t g_ui8VendorNameUnknown[] = "????";
static const uint8_t g_ui8DeviceNameUnknown[] = "Unknown device";
//*****************************************************************************
// Return the major version of the chip rev.
// Returns: 'A', 'B', 'C', ...
//*****************************************************************************
static uint32_t
revmaj_get(uint32_t ui32ChipRev)
{
uint32_t ui32ret;
#ifdef _FLD2VAL
ui32ret = _FLD2VAL(MCUCTRL_CHIPREV_REVMAJ, ui32ChipRev);
#else
ui32ret = (ui32ChipRev & 0xF0) >> 4;
#endif
//
// Major revision is 1=A, 2=B, 3=C, ...
// Convert to the expected return value.
//
return ui32ret + 'A' - 1;
} // revmaj_get()
//*****************************************************************************
// Update the ID structure with the appropriate ChipRev letter.
// ui32minrevbase should be 0 for Apollo or Apollo2, 1 for Apollo3.
//*****************************************************************************
static void
chiprev_set(am_util_id_t *psIDDevice, uint32_t ui32minrevbase)
{
uint32_t ui32maj, ui32min;
ui32maj = ((psIDDevice->sMcuCtrlDevice.ui32ChipRev & 0xF0) >> 4);
psIDDevice->ui8ChipRevMaj = (uint8_t)('A' - 1 + ui32maj);
//
// For Apollo and Apollo2: rev0=0, rev1=1, ... (0-based)
// For Apollo3: rev0=1, rev1=2, ... (1-based)
//
ui32min = ((psIDDevice->sMcuCtrlDevice.ui32ChipRev & 0x0F) >> 0);
psIDDevice->ui8ChipRevMin = (uint8_t)('0' + ui32min - ui32minrevbase);
} // chiprev_set()
//*****************************************************************************
//
//! @brief Device identification.
//!
//! @param psIDDevice - ptr to a device ID structure (am_util_id_t*) to be
//! filled in by the function.
//!
//! This function provides additional information about the currently running
//! Ambiq Micro MCU device.
//!
//! @returns The ui32Device value, which is a value corresponding to the
//! device type.
//
//*****************************************************************************
uint32_t
am_util_id_device(am_util_id_t *psIDDevice)
{
uint32_t ui32PN, ui32ChipRev;
//
// Go get all the device (hardware) info from the HAL
//
#if AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_info_get(AM_HAL_MCUCTRL_INFO_DEVICEID, &psIDDevice->sMcuCtrlDevice);
#else // AM_APOLLO3_MCUCTRL
am_hal_mcuctrl_device_info_get(&psIDDevice->sMcuCtrlDevice);
#endif // AM_APOLLO3_MCUCTRL
//
// Device identification
//
ui32PN = psIDDevice->sMcuCtrlDevice.ui32ChipPN &
AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_PN_M;
ui32ChipRev = psIDDevice->sMcuCtrlDevice.ui32ChipRev;
if ( (psIDDevice->sMcuCtrlDevice.ui32JedecCID == 0xB105100D) &&
(psIDDevice->sMcuCtrlDevice.ui32JedecJEPID == 0x0000009B) &&
((psIDDevice->sMcuCtrlDevice.ui32JedecPN & 0xF00) != 0xE00) )
{
//
// It's Ambiq Micro, set up the VENDORID.
//
psIDDevice->pui8VendorName = g_ui8VendorNameAmbq;
}
else
{
//
// For now, set it as unknown vendor, but we may change it later.
//
psIDDevice->pui8VendorName = g_ui8VendorNameUnknown;
}
if ( psIDDevice->sMcuCtrlDevice.ui32VendorID ==
(('A' << 24) | ('M' << 16) | ('B' << 8) | ('Q' << 0)) )
{
//
// VENDORID is AMBQ, so set the string pointer.
//
psIDDevice->pui8VendorName = g_ui8VendorNameAmbq;
}
if ( ( ui32PN == AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO ) &&
((psIDDevice->sMcuCtrlDevice.ui32JedecPN & 0x0F0) == 0x0E0) )
{
psIDDevice->ui32Device = AM_UTIL_ID_APOLLO;
psIDDevice->pui8DeviceName = g_DeviceNameApollo;
chiprev_set(psIDDevice, 0);
//
// Force the vendor name for Apollo, which did not support VENDORID.
//
psIDDevice->pui8VendorName = g_ui8VendorNameAmbq;
}
else if ( ( ui32PN == AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO2 ) &&
((psIDDevice->sMcuCtrlDevice.ui32JedecPN & 0x0F0) == 0x0D0) )
{
psIDDevice->ui32Device = AM_UTIL_ID_APOLLO2;
psIDDevice->pui8DeviceName = g_DeviceNameApollo2;
chiprev_set(psIDDevice, 0);
}
else if ( ( ui32PN == AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO3 ) &&
((psIDDevice->sMcuCtrlDevice.ui32JedecPN & 0x0F0) == 0x0C0) &&
( revmaj_get(ui32ChipRev) <= 'B' ) )
{
psIDDevice->ui32Device = AM_UTIL_ID_APOLLO3;
psIDDevice->pui8DeviceName = g_DeviceNameApollo3;
chiprev_set(psIDDevice, 1);
}
else if ( ( ui32PN == AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO3P) &&
((psIDDevice->sMcuCtrlDevice.ui32JedecPN & 0x0F0) == 0x0C0) &&
( revmaj_get(ui32ChipRev) == 'C' ) )
{
psIDDevice->ui32Device = AM_UTIL_ID_APOLLO3P;
psIDDevice->pui8DeviceName = g_DeviceNameApollo3p;
chiprev_set(psIDDevice, 1);
}
else
{
psIDDevice->ui32Device = AM_UTIL_ID_UNKNOWN;
psIDDevice->pui8DeviceName = g_ui8DeviceNameUnknown;
psIDDevice->ui8ChipRevMaj = (uint8_t)'?';
psIDDevice->ui8ChipRevMin = (uint8_t)' ';
}
return psIDDevice->ui32Device;
}
@@ -0,0 +1,132 @@
//*****************************************************************************
//
//! @file am_util_id.h
//!
//! @brief Identification of the Ambiq Micro device.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_ID_H
#define AM_UTIL_ID_H
#include "am_mcu_apollo.h"
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! ID structure
//
//*****************************************************************************
typedef struct
{
//
//! Contains the HAL hardware information about the device.
//
am_hal_mcuctrl_device_t sMcuCtrlDevice;
//
//! Device type (derived value, not a hardware value)
//
uint32_t ui32Device;
//
//! Vendor name from the MCUCTRL VENDORID register and stringized here.
//
const uint8_t *pui8VendorName;
//
//! Device name (derived value, not a hardware value)
//
const uint8_t *pui8DeviceName;
//
// Major chip revision (e.g. char 'A' or 'B')
//
uint8_t ui8ChipRevMaj;
//
// Minor chip revision (e.g. char '0', '1', ' ')
//
uint8_t ui8ChipRevMin;
}
am_util_id_t;
//*****************************************************************************
//
// Macros for MCUCTRL CHIP_INFO field.
// Note - these macros are derived from the Apollo2 auto-generated register
// definitions.
//
//*****************************************************************************
#define AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO3P 0x07000000
#define AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO3 0x06000000
#define AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLOBL 0x05000000
#define AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO2 0x03000000
#define AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_APOLLO 0x01000000
#define AM_UTIL_MCUCTRL_CHIP_INFO_PARTNUM_PN_M 0xFF000000
//*****************************************************************************
//
// Macros for silicon identification
//
//*****************************************************************************
#define AM_UTIL_ID_UNKNOWN 0
#define AM_UTIL_ID_APOLLO 0x0001
#define AM_UTIL_ID_APOLLO2 0x0002
#define AM_UTIL_ID_APOLLO3 0x0003 // Apollo3 Blue
#define AM_UTIL_ID_APOLLO3P 0x0103 // Apollo3 Blue Plus
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern uint32_t am_util_id_device(am_util_id_t *psIDDevice);
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_ID_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,184 @@
//*****************************************************************************
//
//! @file am_util_regdump.h
//!
//! @brief Dump specified registers for debug purposes.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_REGDUMP_H
#define AM_UTIL_REGDUMP_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "am_mcu_apollo.h"
//
// Apollo peripherals
//
#define AM_UTIL_REGDUMP_ADC (1 << 0)
#define AM_UTIL_REGDUMP_CLKGEN (1 << 1)
#define AM_UTIL_REGDUMP_CTIMER (1 << 2)
#define AM_UTIL_REGDUMP_GPIO (1 << 3)
#define AM_UTIL_REGDUMP_IOM (1 << 4)
#define AM_UTIL_REGDUMP_IOS (1 << 5)
#define AM_UTIL_REGDUMP_MCUCTRL (1 << 6)
#define AM_UTIL_REGDUMP_RSTGEN (1 << 7)
#define AM_UTIL_REGDUMP_RTC (1 << 8)
#define AM_UTIL_REGDUMP_UART (1 << 9)
#define AM_UTIL_REGDUMP_VCOMP (1 << 10)
#define AM_UTIL_REGDUMP_WDT (1 << 11)
//
// Apollo2 new peripherals
//
#define AM_UTIL_REGDUMP_CACHE (1 << 12)
#define AM_UTIL_REGDUMP_PDM (1 << 13)
#define AM_UTIL_REGDUMP_PWRCTRL (1 << 14)
//
// Apollo3 new peripherals
//
#define AM_UTIL_REGDUMP_BLE (1 << 15)
#define AM_UTIL_REGDUMP_MSPI (1 << 16)
#define AM_UTIL_REGDUMP_INFO0 (1 << 24)
//
// ARM Core blocks
//
#define AM_UTIL_REGDUMP_ITM (1 << 25)
#define AM_UTIL_REGDUMP_NVIC (1 << 26)
#define AM_UTIL_REGDUMP_SYSCTRL (1 << 27)
#define AM_UTIL_REGDUMP_SYSTICK (1 << 28)
#define AM_UTIL_REGDUMP_TPIU (1 << 29)
//*****************************************************************************
//
// Module mask definitions
//
//*****************************************************************************
#define AM_UTIL_REGDUMP_APOLLO \
( AM_UTIL_REGDUMP_ADC | \
AM_UTIL_REGDUMP_CLKGEN | \
AM_UTIL_REGDUMP_CTIMER | \
AM_UTIL_REGDUMP_GPIO | \
AM_UTIL_REGDUMP_IOM | \
AM_UTIL_REGDUMP_IOS | \
AM_UTIL_REGDUMP_MCUCTRL | \
AM_UTIL_REGDUMP_RSTGEN | \
AM_UTIL_REGDUMP_RTC | \
AM_UTIL_REGDUMP_UART | \
AM_UTIL_REGDUMP_VCOMP | \
AM_UTIL_REGDUMP_WDT )
#define AM_UTIL_REGDUMP_APOLLO2 \
( AM_UTIL_REGDUMP_CACHE | \
AM_UTIL_REGDUMP_PDM | \
AM_UTIL_REGDUMP_PWRCTRL )
#define AM_UTIL_REGDUMP_CORE \
( AM_UTIL_REGDUMP_ITM | \
AM_UTIL_REGDUMP_NVIC | \
AM_UTIL_REGDUMP_SYSCTRL | \
AM_UTIL_REGDUMP_SYSTICK | \
AM_UTIL_REGDUMP_TPIU )
//
// Get a register dump of ALL modules in a block.
//
#ifdef AM_PART_APOLLO
#define AM_UTIL_REGDUMP_ALL \
( AM_UTIL_REGDUMP_APOLLO | \
AM_UTIL_REGDUMP_CORE )
#endif // PART_APOLLO
#if defined(AM_PART_APOLLO2) || defined(AM_PART_APOLLO3) || defined(AM_PART_APOLLO3P)
#define AM_UTIL_REGDUMP_ALL \
( AM_UTIL_REGDUMP_APOLLO | \
AM_UTIL_REGDUMP_APOLLO2 | \
AM_UTIL_REGDUMP_CORE )
#endif // PART_APOLLO
//
// Get a register dump of ALL modules in a block.
//
#define AM_UTIL_REGDUMP_MOD_ALL 0xFFFFFFFF
//
// This macro determines a mask given the first and last modules desired. e.g.
// REGDUMP_MOD_MASK(2,4) // Dump regs for modules 2, 3, and 4
//
#define REGDUMP_MOD_MASK(modfirst, modlast) \
(((1 << (modlast - modfirst + 1)) - 1) << modfirst)
//
// These macros determine a single module. e.g.
// REGDUMP_MOD2 | REGDUMP_MOD4 // Dump regs for modules 2 and 4 (skip 3)
//
#define REGDUMP_MOD(n) (1 << n)
#define REGDUMP_MOD0 (REGDUMP_MOD(0))
#define REGDUMP_MOD1 (REGDUMP_MOD(1))
#define REGDUMP_MOD2 (REGDUMP_MOD(2))
#define REGDUMP_MOD3 (REGDUMP_MOD(3))
#define REGDUMP_MOD4 (REGDUMP_MOD(4))
#define REGDUMP_MOD5 (REGDUMP_MOD(5))
#define REGDUMP_MOD6 (REGDUMP_MOD(6))
#define REGDUMP_MOD7 (REGDUMP_MOD(7))
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_util_regdump_print(uint32_t ui32PeriphMask, uint32_t ui32ModuleMask);
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_REGDUMP_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,87 @@
//*****************************************************************************
//
//! @file am_util_stdio.h
//!
//! @brief A few printf-style functions for use with Ambiq products
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_STDIO_H
#define AM_UTIL_STDIO_H
/* get va_list from compiler. */
#include <stdarg.h>
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
// buffer size for printf
#ifndef AM_PRINTF_BUFSIZE
#define AM_PRINTF_BUFSIZE 256
#endif
typedef void (*am_util_stdio_print_char_t)(char *pcStr);
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern void am_util_stdio_printf_init(am_util_stdio_print_char_t pfnCharPrint);
extern uint32_t am_util_stdio_strtoul(const char *str, char **endptr, int base);
extern bool am_util_stdio_textmode_set(bool bSetTextTranslationMode);
extern uint32_t am_util_stdio_vsprintf(char *pcBuf, const char *pcFmt, va_list pArgs);
extern uint32_t am_util_stdio_sprintf(char *pui8Buf, const char *pui8Fmt, ...);
extern uint32_t am_util_stdio_printf(const char *pui8Fmt, ...);
extern void am_util_stdio_terminal_clear(void);
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_STDIO_H
@@ -0,0 +1,613 @@
//*****************************************************************************
//
//! @file am_util_string.c
//!
//! @brief A subset of the functions provided in the C standard string library.
//!
//! The functions here are reimplementation of some of the standard "string"
//! functions.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_util_string.h"
//*****************************************************************************
//
//! @brief Table for quick lookup of character attributes.
//
//*****************************************************************************
#if MINIMIZE_CATTR_TABLE
#define CATTR_TBL_SIZE 128
#else
#define CATTR_TBL_SIZE 256
#endif
const uint8_t am_cattr[CATTR_TBL_SIZE] =
{
AM_CATTR_NONE, /* 0x00 */
AM_CATTR_NONE, /* 0x01 */
AM_CATTR_NONE, /* 0x02 */
AM_CATTR_NONE, /* 0x03 */
AM_CATTR_NONE, /* 0x04 */
AM_CATTR_NONE, /* 0x05 */
AM_CATTR_NONE, /* 0x06 */
AM_CATTR_NONE, /* 0x07 */
AM_CATTR_NONE, /* 0x08 */
AM_CATTR_WHSPACE, /* 0x09 */
AM_CATTR_WHSPACE, /* 0x0A */
AM_CATTR_WHSPACE, /* 0x0B */
AM_CATTR_WHSPACE, /* 0x0C */
AM_CATTR_WHSPACE, /* 0x0D */
AM_CATTR_NONE, /* 0x0E */
AM_CATTR_NONE, /* 0x0F */
AM_CATTR_NONE, /* 0x00 */
AM_CATTR_NONE, /* 0x11 */
AM_CATTR_NONE, /* 0x12 */
AM_CATTR_NONE, /* 0x13 */
AM_CATTR_NONE, /* 0x14 */
AM_CATTR_NONE, /* 0x15 */
AM_CATTR_NONE, /* 0x16 */
AM_CATTR_NONE, /* 0x17 */
AM_CATTR_NONE, /* 0x18 */
AM_CATTR_NONE, /* 0x19 */
AM_CATTR_NONE, /* 0x1A */
AM_CATTR_NONE, /* 0x1B */
AM_CATTR_NONE, /* 0x1C */
AM_CATTR_NONE, /* 0x1D */
AM_CATTR_NONE, /* 0x1E */
AM_CATTR_NONE, /* 0x1F */
AM_CATTR_WHSPACE, /* 0x20, space */
AM_CATTR_FILENM83, /* 0x21, ! */
AM_CATTR_NONE, /* 0x22, " */
AM_CATTR_FILENM83, /* 0x23, # */
AM_CATTR_FILENM83, /* 0x24, $ */
AM_CATTR_FILENM83, /* 0x25, % */
AM_CATTR_FILENM83, /* 0x26, & */
AM_CATTR_FILENM83, /* 0x27, ' */
AM_CATTR_FILENM83, /* 0x28, ( */
AM_CATTR_FILENM83, /* 0x29, ) */
AM_CATTR_NONE, /* 0x2A, * */
AM_CATTR_NONE, /* 0x2B, + */
AM_CATTR_NONE, /* 0x2C, , */
AM_CATTR_FILENM83, /* 0x2D, - */
AM_CATTR_FILENM83, /* 0x2E, . */
AM_CATTR_NONE, /* 0x2F, / */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x30, 0 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x31, 1 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x32, 2 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x33, 3 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x34, 4 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x35, 5 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x36, 6 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x37, 7 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x38, 8 */
AM_CATTR_DIGIT | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x39, 9 */
AM_CATTR_NONE, /* 0x3A, : */
AM_CATTR_NONE, /* 0x3B, ; */
AM_CATTR_NONE, /* 0x3C, < */
AM_CATTR_NONE, /* 0x3D, = */
AM_CATTR_NONE, /* 0x3E, > */
AM_CATTR_NONE, /* 0x3F, ? */
AM_CATTR_FILENM83, /* 0x40, @ */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x41, A */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x42, B */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x43, C */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x44, D */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x45, E */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x46, F */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x47, G */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x48, H */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x49, I */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x4A, J */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x4B, K */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x4C, L */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x4D, M */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x4E, N */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x4F, O */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x50, P */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x51, Q */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x52, R */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x53, S */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x54, T */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x55, U */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x56, V */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x57, W */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x58, X */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x59, Y */
AM_CATTR_ALPHA | AM_CATTR_UPPER | AM_CATTR_FILENM83, /* 0x5A, Z */
AM_CATTR_NONE, /* 0x5B, [ */
AM_CATTR_NONE, /* 0x5C, \ */
AM_CATTR_NONE, /* 0x5D, ] */
AM_CATTR_FILENM83, /* 0x5E, ^ */
AM_CATTR_FILENM83, /* 0x5F, _ */
AM_CATTR_FILENM83, /* 0x60, ` */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x61, a */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x62, b */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x63, c */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x64, d */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x65, e */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_XDIGIT | AM_CATTR_FILENM83, /* 0x66, f */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x67, g */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x68, h */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x69, i */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x6A, j */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x6B, k */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x6C, l */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x6D, m */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x6E, n */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x6F, o */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x70, p */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x71, q */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x72, r */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x73, s */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x74, t */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x75, u */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x76, v */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x77, w */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x78, x */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x79, y */
AM_CATTR_ALPHA | AM_CATTR_LOWER | AM_CATTR_FILENM83, /* 0x7A, z */
AM_CATTR_FILENM83, /* 0x7B, { */
AM_CATTR_NONE, /* 0x7C, | */
AM_CATTR_FILENM83, /* 0x7D, } */
AM_CATTR_FILENM83, /* 0x7E, ~ */
AM_CATTR_NONE /* 0x7F, delete */
//
// All bit7 chars are AM_CATTR_NONE.
//
};
//*****************************************************************************
//
//! @brief Character "is" functions
//!
//! This family of functions tests a given integer value in order to determine
//! whether the integer satisfies the test condition.
//! These functions are generally based on the C99 standard functions.
//!
//! By default all of the "is" functions are implemented as macros. To implement
//! as functions rather than macros, use a global compiler command line (-D)
//! option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS.
//!
//! Standard functions currently implemented include:
//! isalnum(), isalpha(), islower(), isupper(), isdigit(), isxdigit(),
//! isspace().
//!
//! Standard functions not currently implemented include:
//! iscntrl(), isgraph(), isprint(), ispunct(), isblank() (new for C99).
//!
//! Non-standard functions currently implemented include:
//! isfilenm83().
//!
//! @return Each function returns a nonzero value if the integer satisfies
//! the test condition and 0 if it does not.
//
//*****************************************************************************
#ifdef AM_UTIL_STRING_CTYPE_DISABLE_MACROS
int
am_util_string_isalnum(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & (AM_CATTR_ALPHA | AM_CATTR_DIGIT)) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & (AM_CATTR_ALPHA | AM_CATTR_DIGIT)) ? 1 : 0;
#endif
}
int
am_util_string_isalpha(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_ALPHA) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & AM_CATTR_ALPHA) ? 1 : 0;
#endif
}
int
am_util_string_isdigit(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_DIGIT) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & AM_CATTR_DIGIT) ? 1 : 0;
#endif
}
int am_util_string_islower(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_LOWER) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & AM_CATTR_LOWER) ? 1 : 0;
#endif
}
int
am_util_string_isspace(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_WHSPACE) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & AM_CATTR_WHSPACE) ? 1 : 0;
#endif
}
int
am_util_string_isupper(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_UPPER) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & AM_CATTR_UPPER) ? 1 : 0;
#endif
}
int
am_util_string_isxdigit(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_XDIGIT) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & AM_CATTR_XDIGIT) ? 1 : 0;
#endif
}
int am_util_string_tolower(int c)
{
#if MINIMIZE_CATTR_TABLE
return (am_cattr[c & 0x7f] & AM_CATTR_UPPER) ? c | 0x20 : c;
#else
return (am_cattr[c & 0xff] & AM_CATTR_UPPER) ? c | 0x20 : c;
#endif
}
int am_util_string_toupper(int c)
{
#if MINIMIZE_CATTR_TABLE
return (am_cattr[c & 0x7f] & AM_CATTR_LOWER) ? c & ~0x20 : c;
#else
return (am_cattr[c & 0xff] & AM_CATTR_LOWER) ? c & ~0x20 : c;
#endif
}
//
// Non-standard "is" Functions
//
int
am_util_string_isfilenm83(int c)
{
#if MINIMIZE_CATTR_TABLE
return (c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_FILENM83) ? 1 : 0;
#else
return (am_cattr[c & 0xff] & AM_CATTR_FILENM83) ? 1 : 0;
#endif
}
#endif // AM_UTIL_STRING_CTYPE_DISABLE_MACROS
//*****************************************************************************
//
//! @brief Compare two strings.
//!
//! @param str1 is the first string to compare.
//! @param str2 is the second string to compare
//!
//! This function steps through a pair of strings, character by character, to
//! determine if the strings contain the same characters. If the strings match,
//! this function will return a zero. If str1 is alphabetically earlier than
//! str2, the return value will be negative. Otherwise, the return value will
//! be positive.
//!
//! @return 0 for a perfect match, negative value if str1<str2, positive value
//! if str1>str2.
//
//*****************************************************************************
int32_t
am_util_string_strcmp(const char *str1, const char *str2)
{
return am_util_string_strncmp(str1, str2, 0xffffffff);
}
//*****************************************************************************
//
//! @brief Compare two strings with a specified count.
//!
//! @param str1 is the first string to compare.
//! @param str2 is the second string to compare
//! @param num is the maximum number of characters to compare.
//!
//! This function steps through a pair of strings, character by character, to
//! determine if the strings contain the same characters. If the strings match,
//! this function will return a zero. If str1 is alphabetically earlier than
//! str2, the return value will be negative. Otherwise, the return value will
//! be positive.
//!
//! @return 0 for a perfect match, negative value if str1<str2, positive value
//! if str1>str2.
//
//*****************************************************************************
int32_t
am_util_string_strncmp(const char *str1, const char *str2, uint32_t num)
{
while ( num-- )
{
// Check for inequality OR end of string
if ( *str1 != *str2 || *str1 == '\0' )
{
return *str1 - *str2;
}
str1++;
str2++;
}
//
// Since we made it here, the strings must be equal to n characters.
//
return 0;
}
//*****************************************************************************
//
//! @brief Compare two strings with a specified count and without regard to
//! letter case in the strings.
//!
//! @param str1 is the first string to compare.
//! @param str2 is the second string to compare
//! @param num is the maximum number of characters to compare.
//!
//! This function steps through a pair of strings, character by character, to
//! determine if the strings contain the same characters. If the strings match,
//! this function will return a zero. If str1 is alphabetically earlier than
//! str2, the return value will be negative. Otherwise, the return value will
//! be positive.
//!
//! @return 0 for a perfect match, negative value if str1<str2, positive value
//! if str1>str2.
//
//*****************************************************************************
int32_t
am_util_string_strnicmp(const char *str1, const char *str2, int num)
{
uint8_t cChar1, cChar2;
while ( *str1 && *str2 && num )
{
cChar1 = *str1;
cChar2 = *str2;
cChar1 |= ( am_cattr[cChar1] & AM_CATTR_UPPER ) ? 0x20 : 0x00;
cChar2 |= ( am_cattr[cChar2] & AM_CATTR_UPPER ) ? 0x20 : 0x00;
if ( cChar1 != cChar2 )
{
return cChar1 - cChar2;
}
str1++;
str2++;
num--;
}
//
// Since we made it here, the strings must be equal to n characters.
//
return 0;
}
//*****************************************************************************
//
//! @brief Compare two strings with case-insensitivity.
//!
//! @param str1 is the first string to compare.
//! @param str2 is the second string to compare
//!
//! This function compares each character in the 2 strings, converting all
//! alpha characters to lower-case to make the comparison.
//!
//! To illustrate a possible unexpected outcome due to comparing the strings
//! as lower case, consider the example strings "AMBIQ_MICRO" and "AMBIQMICRO".
//! For these strings, stricmp() will return a negative value (indicating the
//! first as before the second), whereas strcmp() will return a positive value.
//!
//! @return 0 for a case-insensitive match, negative value if str1<str2,
//! positive value if str1>str2.
//
//*****************************************************************************
int32_t
am_util_string_stricmp(const char *str1, const char *str2)
{
uint8_t cChar1, cChar2;
while ( *str1 && *str2 )
{
cChar1 = *str1++;
cChar2 = *str2++;
cChar1 |= ( am_cattr[cChar1] & AM_CATTR_UPPER ) ? 0x20 : 0x00;
cChar2 |= ( am_cattr[cChar2] & AM_CATTR_UPPER ) ? 0x20 : 0x00;
if ( cChar1 != cChar2 )
{
return cChar1 - cChar2;
}
}
return *str1 - *str2;
}
//*****************************************************************************
//
//! @brief Return the length of a string.
//!
//! @param pcStr pointer to the string.
//!
//! This function returns the length of the string at pcStr.
//!
//! @return length of the string pcStr.
//
//*****************************************************************************
uint32_t
am_util_string_strlen(const char *pcStr)
{
const char *pcS;
//
// Loop through the string.
//
for (pcS = pcStr; *pcS; ++pcS);
//
// Return the length.
//
return(pcS - pcStr);
}
//*****************************************************************************
//
//! @brief Copies a string.
//!
//! @param pcDst pointer to the destination string.
//! @param pcSrc pointer to the source string to be copied to pcDst.
//!
//! This function copies pcSrc to the location specified by pcDst.
//!
//! @return pcDst (the location of the destination string).
//
//*****************************************************************************
char *
am_util_string_strcpy(char *pcDst, const char *pcSrc)
{
char *pcRet = pcDst;
//
// Blindly copy the string until we hit a terminating NULL char.
//
do
{
*pcDst++ = *pcSrc;
} while ( *pcSrc++ );
return pcRet;
}
//*****************************************************************************
//
//! @brief Copies a specified number of characters of a string.
//!
//! @param pcDst pointer to the destination string.
//! @param pcSrc pointer to the source string to be copied to pcDst.
//!
//! This function copies uNum characters of pcSrc to the location specified
//! by pcDst.
//! If uNum is less than the length of pcSrc, a NULL terminating character
//! is not appended to the copied string. Thus the resultant string will be
//! exactly uNum chars in length and not terminated.
//! If uNum is greater than the length of pcSrc, then pcDst is padded with
//! NULL characters up to the uNum length.
//! Behavior is undefined if the addresses ranges overlap.
//!
//! @return pcDst (the location of the destination string).
//
//*****************************************************************************
char *
am_util_string_strncpy(char *pcDst, const char *pcSrc, uint32_t uNum)
{
char *pcRet = pcDst;
while (uNum > 0)
{
if ( *pcSrc )
{
*pcDst++ = *pcSrc++;
}
else
{
*pcDst++ = 0x00;
}
uNum--;
}
return pcRet;
}
//*****************************************************************************
//
//! @brief Concatenate a string.
//!
//! @param pcDst pointer to the destination string.
//! @param pcSrc pointer to the source string to be copied to pcDst.
//!
//! This function concatenates the string at pcSrc to the existing string
//! at pcDst.
//!
//! Both strings, pcDst and pcSrc, must be NULL-terminated.
//! No overflow checking is performed.
//! pcDst and pcSrc shall not overlap.
//!
//! @return pcDst (the location of the destination string).
//
//*****************************************************************************
char *
am_util_string_strcat(char *pcDst, const char *pcSrc)
{
char *pcRet = pcDst;
//
// Find the end of the existing string.
//
while ( *pcDst++ );
pcDst--;
//
// Now, copy the new string.
//
am_util_string_strcpy(pcDst, pcSrc);
return pcRet;
}
@@ -0,0 +1,161 @@
//*****************************************************************************
//
//! @file am_util_string.h
//!
//! @brief A subset of the functions provided in the C standard string library.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_STRING_H
#define AM_UTIL_STRING_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Character attributes lookup table defines.
//
//*****************************************************************************
#define AM_CATTR_NONE 0x00
#define AM_CATTR_ALPHA 0x01
#define AM_CATTR_LOWER 0x02
#define AM_CATTR_UPPER 0x04
#define AM_CATTR_DIGIT 0x08
#define AM_CATTR_XDIGIT 0x10
#define AM_CATTR_WHSPACE 0x20
#define AM_CATTR_FILENM83 0x80
//
// Set MINIMIZE_CATTR_TABLE to 1 to configure for minimal CATTR table size,
// (256 instead of 512 bytes) but at a cost of slightly larger code size.
// However, setting this option also provides an additional level of checking
// of the argument; if the argument is not a uint8_t, the functions are
// guaranteed to return 0.
//
#define MINIMIZE_CATTR_TABLE 0
//*****************************************************************************
//
// Globals
//
//*****************************************************************************
extern const uint8_t am_cattr[];
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern int32_t am_util_string_strcmp(const char *str1, const char *str2);
extern int32_t am_util_string_stricmp(const char *str1, const char *str2);
extern int32_t am_util_string_strncmp(const char *str1, const char *str2,
uint32_t num);
extern int32_t am_util_string_strnicmp(const char *str1, const char *str2,
int num);
extern uint32_t am_util_string_strlen(const char *pcStr);
extern char *am_util_string_strcpy(char *pcDst, const char *pcSrc);
extern char *am_util_string_strncpy(char *pcDst, const char *pcSrc, uint32_t uNum);
extern char *am_util_string_strcat(char *pcDst, const char *pcSrc);
//*****************************************************************************
//
// Character "is" macros and functions
//
//*****************************************************************************
//
// By default all of the "is" functions are implemented as macros. To implement
// as functions rather than macros, use a global compiler command line (-D)
// option to define AM_UTIL_STRING_CTYPE_DISABLE_MACROS.
//
#ifdef AM_UTIL_STRING_CTYPE_DISABLE_MACROS
extern int am_util_string_isalnum(int c);
extern int am_util_string_isalpha(int c);
extern int am_util_string_isdigit(int c);
extern int am_util_string_islower(int c);
extern int am_util_string_isspace(int c);
extern int am_util_string_isupper(int c);
extern int am_util_string_isxdigit(int c);
extern int am_util_string_tolower(int c);
extern int am_util_string_toupper(int c);
// Non-standard "is" Functions
extern int am_util_string_isfilenm83(int c);
#else
#if MINIMIZE_CATTR_TABLE
#define am_util_string_isalnum(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & (AM_CATTR_ALPHA | AM_CATTR_DIGIT)) ? 1 : 0)
#define am_util_string_isalpha(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_ALPHA) ? 1 : 0)
#define am_util_string_isdigit(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_DIGIT) ? 1 : 0)
#define am_util_string_islower(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_LOWER) ? 1 : 0)
#define am_util_string_isspace(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_WHSPACE) ? 1 : 0)
#define am_util_string_isupper(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_UPPER) ? 1 : 0)
#define am_util_string_isxdigit(c) ((c & 0xffffff80) ? 0 : (am_cattr[c] & AM_CATTR_XDIGIT) ? 1 : 0)
#define am_util_string_tolower(c) ((am_cattr[c & 0x7f] & AM_CATTR_UPPER) ? c | 0x20 : c)
#define am_util_string_toupper(c) ((am_cattr[c & 0x7f] & AM_CATTR_LOWER) ? c & ~0x20 : c)
#else
#define am_util_string_isalnum(c) (am_cattr[c & 0xff] & (AM_CATTR_ALPHA | AM_CATTR_DIGIT))
#define am_util_string_isalpha(c) (am_cattr[c & 0xff] & AM_CATTR_ALPHA)
#define am_util_string_isdigit(c) (am_cattr[c & 0xff] & AM_CATTR_DIGIT)
#define am_util_string_islower(c) (am_cattr[c & 0xff] & AM_CATTR_LOWER)
#define am_util_string_isspace(c) (am_cattr[c & 0xff] & AM_CATTR_WHSPACE)
#define am_util_string_isupper(c) (am_cattr[c & 0xff] & AM_CATTR_UPPER)
#define am_util_string_isxdigit(c) (am_cattr[c & 0xff] & AM_CATTR_XDIGIT)
#define am_util_string_tolower(c) ((am_cattr[c & 0xff] & AM_CATTR_UPPER) ? c | 0x20 : c)
#define am_util_string_toupper(c) ((am_cattr[c & 0xff] & AM_CATTR_LOWER) ? c & ~0x20 : c)
#endif // MINIMIZE_CATTR_TABLE
//
// Non-standard "is" Functions
//
#define am_util_string_isfilenm83(c) (am_cattr[c & 0xff] & AM_CATTR_FILENM83)
#endif // AM_UTIL_STRING_CTYPE_DISABLE_MACROS
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_STRING_H
@@ -0,0 +1,145 @@
//*****************************************************************************
//
//! @file am_util_time.h
//!
//! @brief Functions useful for RTC, calendar, time, etc. computations.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_util_time.h"
//*****************************************************************************
//
// Macro definitions.
//
//*****************************************************************************
#define AM_UTIL_TIME_IS_LEAP_YEAR(year) \
(year % 4 == 0 && ((year % 100 != 0) || (year % 400 != 0)))
//*****************************************************************************
//
// Local variables.
//
//*****************************************************************************
//
// Numer of days in each month in a standard year.
//
const static uint32_t g_iDaysPerMonth[] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//
// Weekday drift numbers for each month.
//
const static int g_iMonthOffsets[] =
{4, 0, 0, 3, 5, 1, 3, 6, 2, 4, 0, 2};
//*****************************************************************************
//
//! @brief Compute the day of the week given the month, day, and year.
//!
//! @param iYear - The year of the desired date (e.g. 2016).
//! @param iMonth - The month of the desired date (1-12).
//! @param iDay - The day of the month of the desired date (1-31).
//!
//! This function is general in nature, but is designed to be used with the RTC.
//!
//! @returns An index value indicating the day of the week.
//! 0-6 indicate Sun, Mon, Tue, Wed, Thu, Fri, Sat, respectively.
//! 7 indicates that the given date is invalid (e.g. 2/29/2015).
//
//*****************************************************************************
int
am_util_time_computeDayofWeek(int iYear, int iMonth, int iDay)
{
bool bInvalidDay;
int iYearOffset;
int iMonthOffset;
int iWeekday;
int iLeapYearOffset = 0;
//
// Validate inputs. Return 7 if any are out-of-bounds.
//
if ( (iMonth < 1) || (iMonth > 12) || (iYear < 0) || (iDay < 1) )
{
return 7;
}
//
// Make sure this day actually exists in this month. Make sure to include
// an exception for leap years.
//
if (iDay > g_iDaysPerMonth[iMonth - 1])
{
if (iMonth == 2 && AM_UTIL_TIME_IS_LEAP_YEAR(iYear) && iDay == 29)
{
bInvalidDay = false;
}
else
{
bInvalidDay = true;
}
}
else
{
bInvalidDay = false;
}
if (bInvalidDay)
{
return 7;
}
iYearOffset = 2 + iYear + iYear / 4 - iYear / 100 + iYear / 400;
iMonthOffset = g_iMonthOffsets[iMonth - 1];
if (AM_UTIL_TIME_IS_LEAP_YEAR(iYear) && (iMonth < 3))
{
iLeapYearOffset = -1;
}
iWeekday = iDay + iYearOffset + iMonthOffset + iLeapYearOffset;
return iWeekday % 7;
}
@@ -0,0 +1,66 @@
//*****************************************************************************
//
//! @file am_util_time.h
//!
//! @brief Functions useful for RTC, calendar, time, etc. computations.
//
//*****************************************************************************
//*****************************************************************************
//
// 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_UTIL_TIME_H
#define AM_UTIL_TIME_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
extern int am_util_time_computeDayofWeek(int iYear, int iMonth, int iDay);
#ifdef __cplusplus
}
#endif
#endif // AM_UTIL_TIME_H