initial commit
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user