initial commit

This commit is contained in:
2022-10-23 23:45:43 -07:00
commit e190fa5193
6450 changed files with 8626944 additions and 0 deletions
@@ -0,0 +1,6 @@
Common Examples README
======================
The beauty of the Ambiq BSP system is that it can be used to create common example code. For example if we define the proper UART instance and TX/RX pads as part of the BSP then a single source file can be used to demonstrate UART functionality across all capable boards. To utilize this capability to the fullest the common examples source code should be isolated from specific boards. This reduces redundancy in maintenance.
This directory contains common source files that may be referred to by any of the boards included in this repo. For board-specific source code look beneath the respective board's directory.
@@ -0,0 +1,21 @@
Name:
=====
ble_freertos_tag
Description:
============
ARM Cordio BLE - Proximity Tag Example
Purpose:
========
This is a standard BLE Proximity Profile example.
Printing takes place over the ITM at 1M Baud.
******************************************************************************
@@ -0,0 +1,574 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := ble_freertos_tag
COMPILERNAME := gcc
PROJECT := $(TARGET)_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_FREERTOS
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+= -DSEC_ECC_CFG=SEC_ECC_CFG_UECC
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -Dgcc
DEFINES+=
INCLUDES = -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/stack/l2c
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/hid
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/fmpl
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/stack/att
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/uribeacon
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/apps
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/gap
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/include
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/hci/include
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/third_party/exactle/wsf/sources
INCLUDES+= -I$(SDKPATH)/third_party/FreeRTOSv10.1.1/Source/portable/GCC/AMapollo2
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/sec/common
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/bas
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/apps/app
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/include
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/third_party/exactle/wsf/include
INCLUDES+= -I$(COMMONPATH)/examples/ble_freertos_tag/src
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+= -I$(SDKPATH)/third_party/exactle/wsf/sources/port/freertos
INCLUDES+= -I$(SDKPATH)/third_party/FreeRTOSv10.1.1/Source/include
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/hci/ambiq/apollo3
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/stack/dm
INCLUDES+= -I$(SDKPATH)/third_party/exactle/wsf/sources/util
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/wdxs
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/gatt
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/include/app
INCLUDES+= -I$(SDKPATH)/third_party/uecc
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/services
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/apps/tag
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/stack/smp
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/stack/hci
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/stack/cfg
INCLUDES+= -I$(SDKPATH)/third_party/exactle/ble-host/sources/hci/ambiq
VPATH = $(SDKPATH)/utils
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/stack/l2c
VPATH+=:$(COMMONPATH)/examples/ble_freertos_tag/src
VPATH+=:$(SDKPATH)/third_party/exactle/wsf/sources/port/freertos
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/hid
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/fmpl
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/stack/att
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/sec/uecc
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/apps/app/common
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/hci/ambiq/apollo3
VPATH+=:$(SDKPATH)/third_party/exactle/wsf/sources/util
VPATH+=:$(SDKPATH)/third_party/FreeRTOSv10.1.1/Source
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/stack/dm
VPATH+=:$(SDKPATH)/third_party/FreeRTOSv10.1.1/Source/portable/MemMang
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/wdxs
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/gatt
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/gap
VPATH+=:$(SDKPATH)/third_party/uecc
VPATH+=:$(SDKPATH)/devices
VPATH+=:$(SDKPATH)/third_party/FreeRTOSv10.1.1/Source/portable/GCC/AMapollo2
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/services
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/apps/tag
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/sec/common
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/profiles/bas
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/stack/smp
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/apps/app
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/stack/hci
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/stack/cfg
VPATH+=:$(SDKPATH)/third_party/exactle/ble-host/sources/hci/ambiq
VPATH+=:$(SDKPATH)/third_party/exactle/ble-profiles/sources/apps/hidapp
LIBS = $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS += $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
SRC = l2c_coc.c
SRC += l2c_main.c
SRC += l2c_master.c
SRC += l2c_slave.c
SRC += ble_freertos_tag.c
SRC += radio_task.c
SRC += rtos.c
SRC += wsf_assert.c
SRC += wsf_buf.c
SRC += wsf_efs.c
SRC += wsf_math.c
SRC += wsf_msg.c
SRC += wsf_os.c
SRC += wsf_queue.c
SRC += wsf_timer.c
SRC += wsf_trace.c
SRC += hid_main.c
SRC += fmpl_main.c
SRC += attc_disc.c
SRC += attc_main.c
SRC += attc_proc.c
SRC += attc_read.c
SRC += attc_sign.c
SRC += attc_write.c
SRC += atts_ccc.c
SRC += atts_csf.c
SRC += atts_dyn.c
SRC += atts_ind.c
SRC += atts_main.c
SRC += atts_proc.c
SRC += atts_read.c
SRC += atts_sign.c
SRC += atts_write.c
SRC += att_main.c
SRC += att_uuid.c
SRC += sec_ecc.c
SRC += app_db.c
SRC += app_hw.c
SRC += app_ui.c
SRC += ui_console.c
SRC += ui_lcd.c
SRC += ui_main.c
SRC += ui_platform.c
SRC += ui_timer.c
SRC += hci_drv_apollo3.c
SRC += bda.c
SRC += bstream.c
SRC += calc128.c
SRC += crc32.c
SRC += print.c
SRC += terminal.c
SRC += wstr.c
SRC += dm_adv.c
SRC += dm_adv_ae.c
SRC += dm_adv_leg.c
SRC += dm_conn.c
SRC += dm_conn_cte.c
SRC += dm_conn_master.c
SRC += dm_conn_master_ae.c
SRC += dm_conn_master_leg.c
SRC += dm_conn_slave.c
SRC += dm_conn_slave_ae.c
SRC += dm_conn_slave_leg.c
SRC += dm_conn_sm.c
SRC += dm_dev.c
SRC += dm_dev_priv.c
SRC += dm_main.c
SRC += dm_past.c
SRC += dm_phy.c
SRC += dm_priv.c
SRC += dm_scan.c
SRC += dm_scan_ae.c
SRC += dm_scan_leg.c
SRC += dm_sec.c
SRC += dm_sec_lesc.c
SRC += dm_sec_master.c
SRC += dm_sec_slave.c
SRC += dm_sync_ae.c
SRC += wdxs_au.c
SRC += wdxs_dc.c
SRC += wdxs_ft.c
SRC += wdxs_main.c
SRC += wdxs_phy.c
SRC += wdxs_stream.c
SRC += gatt_main.c
SRC += gap_main.c
SRC += uECC.c
SRC += uECC_ll.c
SRC += port.c
SRC += sec_aes.c
SRC += sec_aes_rev.c
SRC += sec_ccm_hci.c
SRC += sec_cmac_hci.c
SRC += sec_ecc_debug.c
SRC += sec_ecc_hci.c
SRC += sec_main.c
SRC += bas_main.c
SRC += smpi_act.c
SRC += smpi_sc_act.c
SRC += smpi_sc_sm.c
SRC += smpi_sm.c
SRC += smpr_act.c
SRC += smpr_sc_act.c
SRC += smpr_sc_sm.c
SRC += smpr_sm.c
SRC += smp_act.c
SRC += smp_db.c
SRC += smp_main.c
SRC += smp_non.c
SRC += smp_sc_act.c
SRC += smp_sc_main.c
SRC += hci_main.c
SRC += cfg_stack.c
SRC += hci_cmd.c
SRC += hci_cmd_ae.c
SRC += hci_cmd_cte.c
SRC += hci_cmd_past.c
SRC += hci_cmd_phy.c
SRC += hci_core.c
SRC += hci_core_ps.c
SRC += hci_evt.c
SRC += hci_tr.c
SRC += hci_vs.c
SRC += hci_vs_ae.c
SRC += hidapp_main.c
SRC += am_util_ble.c
SRC += am_util_debug.c
SRC += am_util_delay.c
SRC += am_util_faultisr.c
SRC += am_util_id.c
SRC += am_util_stdio.c
SRC += event_groups.c
SRC += list.c
SRC += queue.c
SRC += tasks.c
SRC += timers.c
SRC += heap_2.c
SRC += am_devices_button.c
SRC += am_devices_led.c
SRC += svc_batt.c
SRC += svc_bps.c
SRC += svc_core.c
SRC += svc_cps.c
SRC += svc_cscs.c
SRC += svc_dis.c
SRC += svc_gls.c
SRC += svc_gyro.c
SRC += svc_hid.c
SRC += svc_hrs.c
SRC += svc_hts.c
SRC += svc_ipss.c
SRC += svc_plxs.c
SRC += svc_px.c
SRC += svc_rscs.c
SRC += svc_scpss.c
SRC += svc_temp.c
SRC += svc_uricfg.c
SRC += svc_wdxs.c
SRC += svc_wp.c
SRC += svc_wss.c
SRC += tag_main.c
SRC += app_disc.c
SRC += app_main.c
SRC += app_master.c
SRC += app_master_leg.c
SRC += app_server.c
SRC += app_slave.c
SRC += app_slave_leg.c
SRC += app_terminal.c
SRC += startup_gcc.c
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := $(COMMONPATH)/examples/ble_freertos_tag/gcc/startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections -fomit-frame-pointer
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories: $(CONFIG)
$(CONFIG):
@mkdir -p $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE := $(COMMONPATH)/examples/ble_freertos_tag/gcc/ble_freertos_tag_asb.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE := $(COMMONPATH)/examples/ble_freertos_tag/gcc/ble_freertos_tag_svl.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
@echo "Uploading using the Ambiq Secure Bootloader"
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
@echo "Uploading using the SparkFun Variable Loader"
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories
@@ -0,0 +1,63 @@
/******************************************************************************
*
* ble_freertos_tag.ld - Linker script for applications using startup_gnu.c
*
*****************************************************************************/
ENTRY(Reset_Handler)
MEMORY
{
ROMEM (rx) : ORIGIN = 0x0000C000, LENGTH = 960K
RWMEM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K
}
SECTIONS
{
.text :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
KEEP(*(.patch))
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
. = ALIGN(4);
_etext = .;
} > ROMEM
/* User stack section initialized by startup code. */
.stack (NOLOAD):
{
. = ALIGN(8);
*(.stack)
*(.stack*)
. = ALIGN(8);
} > RWMEM
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > RWMEM AT>ROMEM
/* used by startup to initialize data */
_init_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_sbss = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} > RWMEM
.ARM.attributes 0 : { *(.ARM.attributes) }
}
@@ -0,0 +1,63 @@
/******************************************************************************
*
* ble_freertos_tag.ld - Linker script for applications using startup_gnu.c
*
*****************************************************************************/
ENTRY(Reset_Handler)
MEMORY
{
ROMEM (rx) : ORIGIN = 0x00010000, LENGTH = 960K
RWMEM (rwx) : ORIGIN = 0x10000000, LENGTH = 384K
}
SECTIONS
{
.text :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
KEEP(*(.patch))
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
. = ALIGN(4);
_etext = .;
} > ROMEM
/* User stack section initialized by startup code. */
.stack (NOLOAD):
{
. = ALIGN(8);
*(.stack)
*(.stack*)
. = ALIGN(8);
} > RWMEM
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > RWMEM AT>ROMEM
/* used by startup to initialize data */
_init_data = LOADADDR(.data);
.bss :
{
. = ALIGN(4);
_sbss = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} > RWMEM
.ARM.attributes 0 : { *(.ARM.attributes) }
}
@@ -0,0 +1,354 @@
//*****************************************************************************
//
//! @file startup_gcc.c
//!
//! @brief Definitions for interrupt handlers, the vector table, and the stack.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
//*****************************************************************************
//
// Forward declaration of interrupt handlers.
//
//*****************************************************************************
extern void Reset_Handler(void) __attribute ((naked));
extern void NMI_Handler(void) __attribute ((weak));
extern void HardFault_Handler(void) __attribute ((weak));
extern void MemManage_Handler(void) __attribute ((weak, alias ("HardFault_Handler")));
extern void BusFault_Handler(void) __attribute ((weak, alias ("HardFault_Handler")));
extern void UsageFault_Handler(void) __attribute ((weak, alias ("HardFault_Handler")));
extern void SecureFault_Handler(void) __attribute ((weak));
extern void SVC_Handler(void) __attribute ((weak, alias ("am_default_isr")));
extern void DebugMon_Handler(void) __attribute ((weak, alias ("am_default_isr")));
extern void PendSV_Handler(void) __attribute ((weak, alias ("am_default_isr")));
extern void SysTick_Handler(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_brownout_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_watchdog_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_rtc_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_vcomp_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_ioslave_ios_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_ioslave_acc_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_iomaster0_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_iomaster1_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_iomaster2_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_iomaster3_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_iomaster4_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_iomaster5_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_ble_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_gpio_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_ctimer_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_uart_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_uart1_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_scard_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_adc_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_pdm0_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_mspi0_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_software0_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr0_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr1_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr2_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr3_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr4_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr5_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr6_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_stimer_cmpr7_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_clkgen_isr(void) __attribute ((weak, alias ("am_default_isr")));
extern void am_default_isr(void) __attribute ((weak));
//*****************************************************************************
//
// The entry point for the application.
//
//*****************************************************************************
extern int main(void);
//*****************************************************************************
//
// Reserve space for the system stack.
//
//*****************************************************************************
__attribute__ ((section(".stack")))
static uint32_t g_pui32Stack[0xac0];
//*****************************************************************************
//
// The vector table. Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000.
//
// Note: Aliasing and weakly exporting am_mpufault_isr, am_busfault_isr, and
// am_usagefault_isr does not work if am_fault_isr is defined externally.
// Therefore, we'll explicitly use am_fault_isr in the table for those vectors.
//
//*****************************************************************************
__attribute__ ((section(".isr_vector")))
void (* const g_am_pfnVectors[])(void) =
{
(void (*)(void))((uint32_t)g_pui32Stack + sizeof(g_pui32Stack)),
// The initial stack pointer
Reset_Handler, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MemManage_Handler
BusFault_Handler, // The BusFault_Handler
UsageFault_Handler, // The UsageFault_Handler
SecureFault_Handler, // The SecureFault_Handler
0, // Reserved
0, // Reserved
0, // Reserved
SVC_Handler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
0, // Reserved
PendSV_Handler, // The PendSV handler
SysTick_Handler, // The SysTick handler
//
// Peripheral Interrupts
//
am_brownout_isr, // 0: Brownout (rstgen)
am_watchdog_isr, // 1: Watchdog
am_rtc_isr, // 2: RTC
am_vcomp_isr, // 3: Voltage Comparator
am_ioslave_ios_isr, // 4: I/O Slave general
am_ioslave_acc_isr, // 5: I/O Slave access
am_iomaster0_isr, // 6: I/O Master 0
am_iomaster1_isr, // 7: I/O Master 1
am_iomaster2_isr, // 8: I/O Master 2
am_iomaster3_isr, // 9: I/O Master 3
am_iomaster4_isr, // 10: I/O Master 4
am_iomaster5_isr, // 11: I/O Master 5
am_ble_isr, // 12: BLEIF
am_gpio_isr, // 13: GPIO
am_ctimer_isr, // 14: CTIMER
am_uart_isr, // 15: UART0
am_uart1_isr, // 16: UART1
am_scard_isr, // 17: SCARD
am_adc_isr, // 18: ADC
am_pdm0_isr, // 19: PDM
am_mspi0_isr, // 20: MSPI0
am_software0_isr, // 21: SOFTWARE0
am_stimer_isr, // 22: SYSTEM TIMER
am_stimer_cmpr0_isr, // 23: SYSTEM TIMER COMPARE0
am_stimer_cmpr1_isr, // 24: SYSTEM TIMER COMPARE1
am_stimer_cmpr2_isr, // 25: SYSTEM TIMER COMPARE2
am_stimer_cmpr3_isr, // 26: SYSTEM TIMER COMPARE3
am_stimer_cmpr4_isr, // 27: SYSTEM TIMER COMPARE4
am_stimer_cmpr5_isr, // 28: SYSTEM TIMER COMPARE5
am_stimer_cmpr6_isr, // 29: SYSTEM TIMER COMPARE6
am_stimer_cmpr7_isr, // 30: SYSTEM TIMER COMPARE7
am_clkgen_isr, // 31: CLKGEN
};
//******************************************************************************
//
// Place code immediately following vector table.
//
//******************************************************************************
//******************************************************************************
//
// The Patch table.
//
// The patch table should pad the vector table size to a total of 64 entries
// (16 core + 48 periph) such that code begins at offset 0x100.
//
//******************************************************************************
__attribute__ ((section(".patch")))
uint32_t const __Patchable[] =
{
0, // 32
0, // 33
0, // 34
0, // 35
0, // 36
0, // 37
0, // 38
0, // 39
0, // 40
0, // 41
0, // 42
0, // 43
0, // 44
0, // 45
0, // 46
0, // 47
};
//*****************************************************************************
//
// The following are constructs created by the linker, indicating where the
// the "data" and "bss" segments reside in memory. The initializers for the
// "data" segment resides immediately following the "text" segment.
//
//*****************************************************************************
extern uint32_t _etext;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;
//*****************************************************************************
//
// This is the code that gets called when the processor first starts execution
// following a reset event. Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called.
//
//*****************************************************************************
#if defined(__GNUC_STDC_INLINE__)
void
Reset_Handler(void)
{
//
// Set the vector table pointer.
//
__asm(" ldr r0, =0xE000ED08\n"
" ldr r1, =g_am_pfnVectors\n"
" str r1, [r0]");
//
// Set the stack pointer.
//
__asm(" ldr sp, [r1]");
#ifndef NOFPU
//
// Enable the FPU.
//
__asm("ldr r0, =0xE000ED88\n"
"ldr r1,[r0]\n"
"orr r1,#(0xF << 20)\n"
"str r1,[r0]\n"
"dsb\n"
"isb\n");
#endif
//
// Copy the data segment initializers from flash to SRAM.
//
__asm(" ldr r0, =_init_data\n"
" ldr r1, =_sdata\n"
" ldr r2, =_edata\n"
"copy_loop:\n"
" ldr r3, [r0], #4\n"
" str r3, [r1], #4\n"
" cmp r1, r2\n"
" blt copy_loop\n");
//
// Zero fill the bss segment.
//
__asm(" ldr r0, =_sbss\n"
" ldr r1, =_ebss\n"
" mov r2, #0\n"
"zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
//
// Call the application's entry point.
//
main();
//
// If main returns then execute a break point instruction
//
__asm(" bkpt ");
}
#else
#error GNU STDC inline not supported.
#endif
//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI. This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
void
NMI_Handler(void)
{
//
// Go into an infinite loop.
//
while(1)
{
}
}
//*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
void
HardFault_Handler(void)
{
//
// Go into an infinite loop.
//
while(1)
{
}
}
//*****************************************************************************
//
// This is the code that gets called when the processor receives an unexpected
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
void
am_default_isr(void)
{
//
// Go into an infinite loop.
//
while(1)
{
}
}
@@ -0,0 +1,161 @@
//*****************************************************************************
//
//! @file FreeRTOSConfig.h
//!
//! @brief Configuration options for FreeRTOS
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#ifdef __cplusplus
extern "C"
{
#endif
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#ifdef AM_PART_APOLLO
#define configCPU_CLOCK_HZ 24000000UL
#else
#define configCPU_CLOCK_HZ 48000000UL
#endif
#define configTICK_RATE_HZ 1000
#define configMAX_PRIORITIES 4
#define configMINIMAL_STACK_SIZE (256)
#define configTOTAL_HEAP_SIZE (16 * 1024)
#define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 0
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_COUNTING_SEMAPHORES 0
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
#define configQUEUE_REGISTRY_SIZE 0
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 0
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_MALLOC_FAILED_HOOK 1
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 0
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Software timer related definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 3
#define configTIMER_QUEUE_LENGTH 5
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* Interrupt nesting behaviour configuration. */
#define configKERNEL_INTERRUPT_PRIORITY (0x7 << 5)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (0x4 << 5)
#define NVIC_configKERNEL_INTERRUPT_PRIORITY (0x7)
#define NVIC_configMAX_SYSCALL_INTERRUPT_PRIORITY (0x4)
/* Define to trap errors during development. */
#define configASSERT(x) if (( x ) == 0) while(1);
/* FreeRTOS MPU specific definitions. */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 0
#define INCLUDE_uxTaskPriorityGet 0
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 0
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 0
#define INCLUDE_xTaskGetSchedulerState 0
#define INCLUDE_xTaskGetCurrentTaskHandle 0
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
#define INCLUDE_pcTaskGetTaskName 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 1
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1 // Enable non-SysTick based Tick
#define configUSE_TICKLESS_IDLE 2 // Ambiq specific implementation for Tickless
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
extern uint32_t am_freertos_sleep(uint32_t);
extern void am_freertos_wakeup(uint32_t);
#define configPRE_SLEEP_PROCESSING( time ) \
do { \
(time) = am_freertos_sleep(time); \
} while (0);
#define configPOST_SLEEP_PROCESSING(time) am_freertos_wakeup(time)
#endif
/*-----------------------------------------------------------*/
#ifndef AM_PART_APOLLO
#define AM_FREERTOS_USE_STIMER_FOR_TICK
#endif
#ifdef AM_FREERTOS_USE_STIMER_FOR_TICK
#define configSTIMER_CLOCK_HZ 32768
#else // Use CTimer
#define configCTIMER_CLOCK_HZ 32768
#endif
#ifdef __cplusplus
}
#endif
#endif // FREERTOS_CONFIG_H
@@ -0,0 +1,166 @@
//*****************************************************************************
//
//! @file ble_freertos_tag.c
//!
//! @brief ARM Cordio BLE - Proximity Tag Example
//!
//! Purpose: This is a standard BLE Proximity Profile example.
//!
//! Printing takes place over the ITM at 1M Baud.
//!
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
//*****************************************************************************
//
// This application has a large number of common include files. For
// convenience, we'll collect them all together in a single header and include
// that everywhere.
//
//*****************************************************************************
#include "ble_freertos_tag.h"
#include "rtos.h"
//*****************************************************************************
//
// Enable printing to the console.
//
//*****************************************************************************
void
enable_print_interface(void)
{
//
// Initialize a debug printing interface.
//
am_bsp_itm_printf_enable();
}
//*****************************************************************************
//
// Main Function
//
//*****************************************************************************
int
main(void)
{
//
// Set the clock frequency
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
#ifndef NOFPU
//
// Enable the floating point module, and configure the core for lazy
// stacking.
//
am_hal_sysctrl_fpu_enable();
am_hal_sysctrl_fpu_stacking_enable(true);
#else
am_hal_sysctrl_fpu_disable();
#endif
//
// Configure the board for low power.
//
am_bsp_low_power_init();
// Turn off unused Flash & SRAM
#ifdef AM_PART_APOLLO
//
// SRAM bank power setting.
// Need to match up with actual SRAM usage for the program
// Current usage is between 32K and 40K - so disabling upper 3 banks
//
am_hal_mcuctrl_sram_power_set(AM_HAL_MCUCTRL_SRAM_POWER_DOWN_5 |
AM_HAL_MCUCTRL_SRAM_POWER_DOWN_6 |
AM_HAL_MCUCTRL_SRAM_POWER_DOWN_7,
AM_HAL_MCUCTRL_SRAM_POWER_DOWN_5 |
AM_HAL_MCUCTRL_SRAM_POWER_DOWN_6 |
AM_HAL_MCUCTRL_SRAM_POWER_DOWN_7);
#if 0 // Not turning off the Flash as it may be needed to download the image
//
// Flash bank power set.
//
am_hal_mcuctrl_flash_power_set(AM_HAL_MCUCTRL_FLASH_POWER_DOWN_1);
#endif
#endif // AM_PART_APOLLO
#ifdef AM_PART_APOLLO2
#if 0 // Not turning off the Flash as it may be needed to download the image
am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_FLASH512K);
#endif
am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_SRAM64K);
#endif // AM_PART_APOLLO2
//
// Enable printing to the console.
//
#ifdef AM_DEBUG_PRINTF
enable_print_interface();
#endif
//
// Initialize plotting interface.
//
am_util_debug_printf("FreeRTOS Tag Example\n");
//
// Run the application.
//
run_tasks();
//
// We shouldn't ever get here.
//
while (1)
{
}
}
@@ -0,0 +1,89 @@
//*****************************************************************************
//
//! @file ble_freertos_tag.h
//!
//! @brief Global includes for the ble_freertos_tag app.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef BLE_FREERTOS_TAG_H
#define BLE_FREERTOS_TAG_H
//*****************************************************************************
//
// Required built-ins.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
//*****************************************************************************
//
// Standard AmbiqSuite includes.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
//*****************************************************************************
//
// FreeRTOS include files.
//
//*****************************************************************************
#include "FreeRTOS.h"
#include "task.h"
#include "portmacro.h"
#include "portable.h"
#include "semphr.h"
#include "event_groups.h"
//#include "rtos.h"
//*****************************************************************************
//
// Task include files.
//
//*****************************************************************************
#include "radio_task.h"
#endif // FREERTOS_FIT_H
@@ -0,0 +1,77 @@
//*****************************************************************************
//
//! @file hci_apollo_config.h
//!
//! @brief This file describes the physical aspects of the HCI conection.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include "am_bsp.h"
#ifndef HCI_APOLLO_CONFIG_H
#define HCI_APOLLO_CONFIG_H
//*****************************************************************************
//
// Pin numbers and configuration.
//
// NOTE: RTS, CTS, and RESET are implemented as GPIOs, so no "CFG" field is
// needed.
//
//*****************************************************************************
//#define HCI_APOLLO_POWER_PIN AM_BSP_GPIO_EM9304_POWER
//#define HCI_APOLLO_POWER_CFG AM_BSP_GPIO_CFG_EM9304_POWER
#define HCI_APOLLO_RESET_PIN AM_BSP_GPIO_EM9304_RESET
//*****************************************************************************
//
// Other options.
//
// These options are provided in case your board setup is a little more
// unusual. Most boards shouldn't need these features. If in doubt, leave all
// of these features disabled.
//
//*****************************************************************************
#define HCI_APOLLO_CFG_OVERRIDE_ISR 1 // Override the exactle UART ISR
#endif // HCI_APOLLO_CONFIG_H
@@ -0,0 +1,401 @@
//*****************************************************************************
//
//! @file radio_task.c
//!
//! @brief Task to handle radio operation.
//!
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
//*****************************************************************************
//
// Global includes for this project.
//
//*****************************************************************************
#include "ble_freertos_tag.h"
//*****************************************************************************
//
// WSF standard includes.
//
//*****************************************************************************
#include "wsf_types.h"
#include "wsf_trace.h"
#include "wsf_buf.h"
#include "wsf_timer.h"
//*****************************************************************************
//
// Includes for operating the ExactLE stack.
//
//*****************************************************************************
#include "hci_handler.h"
#include "dm_handler.h"
#include "l2c_handler.h"
#include "att_handler.h"
#include "smp_handler.h"
#include "l2c_api.h"
#include "att_api.h"
#include "smp_api.h"
#include "app_api.h"
#include "hci_core.h"
#include "hci_drv.h"
#include "hci_drv_apollo.h"
#include "hci_drv_apollo3.h"
#include "hci_apollo_config.h"
#include "wsf_msg.h"
//*****************************************************************************
//
//
//*****************************************************************************
#include "tag_api.h"
#include "app_ui.h"
//*****************************************************************************
//
// Radio task handle.
//
//*****************************************************************************
TaskHandle_t radio_task_handle;
//*****************************************************************************
//
// Function prototypes
//
//*****************************************************************************
void exactle_stack_init(void);
void button_handler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
void setup_buttons(void);
//*****************************************************************************
//
// Timer for buttons.
//
//*****************************************************************************
wsfHandlerId_t ButtonHandlerId;
wsfTimer_t ButtonTimer;
//*****************************************************************************
//
// WSF buffer pools.
//
//*****************************************************************************
#define WSF_BUF_POOLS 4
// Important note: the size of g_pui32BufMem should includes both overhead of internal
// buffer management structure, wsfBufPool_t (up to 16 bytes for each pool), and pool
// description (e.g. g_psPoolDescriptors below).
// Memory for the buffer pool
// extra AMOTA_PACKET_SIZE bytes for OTA handling
static uint32_t g_pui32BufMem[
(WSF_BUF_POOLS*16
+ 16*8 + 32*4 + 64*6 + 280*8) / sizeof(uint32_t)];
// Default pool descriptor.
static wsfBufPoolDesc_t g_psPoolDescriptors[WSF_BUF_POOLS] =
{
{ 16, 8 },
{ 32, 4 },
{ 64, 6 },
{ 280, 8 }
};
//*****************************************************************************
//
// Tracking variable for the scheduler timer.
//
//*****************************************************************************
void radio_timer_handler(void);
//*****************************************************************************
//
// Poll the buttons.
//
//*****************************************************************************
void
button_handler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
{
//
// Restart the button timer.
//
WsfTimerStartMs(&ButtonTimer, 10);
#ifdef AM_BSP_NUM_BUTTONS
//
// Every time we get a button timer tick, check all of our buttons.
//
am_devices_button_array_tick(am_bsp_psButtons, AM_BSP_NUM_BUTTONS);
//
// If we got a a press, do something with it.
//
if ( am_devices_button_released(am_bsp_psButtons[0]) )
{
am_util_debug_printf("Got Button 0 Press\n");
AppUiBtnTest(APP_UI_BTN_1_SHORT);
}
if ( am_devices_button_released(am_bsp_psButtons[1]) )
{
am_util_debug_printf("Got Button 1 Press\n");
AppUiBtnTest(APP_UI_BTN_1_SHORT);
}
if ( am_devices_button_released(am_bsp_psButtons[2]) )
{
am_util_debug_printf("Got Button 2 Press\n");
}
#endif // AM_BSP_NUM_BUTTONS
}
//*****************************************************************************
//
// Sets up a button interface.
//
//*****************************************************************************
void
setup_buttons(void)
{
#ifdef AM_BSP_NUM_BUTTONS
//
// Enable the buttons for user interaction.
//
am_devices_button_array_init(am_bsp_psButtons, AM_BSP_NUM_BUTTONS);
//
// Start a timer.
//
ButtonTimer.handlerId = ButtonHandlerId;
WsfTimerStartSec(&ButtonTimer, 2);
#endif // AM_BSP_NUM_BUTTONS
}
//*****************************************************************************
//
// Initialization for the ExactLE stack.
//
//*****************************************************************************
void
exactle_stack_init(void)
{
wsfHandlerId_t handlerId;
uint16_t wsfBufMemLen;
//
// Set up timers for the WSF scheduler.
//
WsfOsInit();
WsfTimerInit();
//
// Initialize a buffer pool for WSF dynamic memory needs.
//
wsfBufMemLen = WsfBufInit(sizeof(g_pui32BufMem), (uint8_t *)g_pui32BufMem, WSF_BUF_POOLS,
g_psPoolDescriptors);
if (wsfBufMemLen > sizeof(g_pui32BufMem))
{
am_util_debug_printf("Memory pool is too small by %d\r\n",
wsfBufMemLen - sizeof(g_pui32BufMem));
}
//
// Initialize the WSF security service.
//
SecInit();
SecAesInit();
SecCmacInit();
SecEccInit();
//
// Set up callback functions for the various layers of the ExactLE stack.
//
handlerId = WsfOsSetNextHandler(HciHandler);
HciHandlerInit(handlerId);
handlerId = WsfOsSetNextHandler(DmHandler);
DmDevVsInit(0);
DmAdvInit();
DmConnInit();
DmConnSlaveInit();
DmSecInit();
DmSecLescInit();
DmPrivInit();
DmHandlerInit(handlerId);
handlerId = WsfOsSetNextHandler(L2cSlaveHandler);
L2cSlaveHandlerInit(handlerId);
L2cInit();
L2cSlaveInit();
handlerId = WsfOsSetNextHandler(AttHandler);
AttHandlerInit(handlerId);
AttsInit();
AttsIndInit();
AttcInit();
handlerId = WsfOsSetNextHandler(SmpHandler);
SmpHandlerInit(handlerId);
SmprInit();
SmprScInit();
HciSetMaxRxAclLen(251);
handlerId = WsfOsSetNextHandler(AppHandler);
AppHandlerInit(handlerId);
handlerId = WsfOsSetNextHandler(TagHandler);
TagHandlerInit(handlerId);
ButtonHandlerId = WsfOsSetNextHandler(button_handler);
handlerId = WsfOsSetNextHandler(HciDrvHandler);
HciDrvHandlerInit(handlerId);
}
//*****************************************************************************
//
// UART interrupt handler.
//
//*****************************************************************************
void
am_uart_isr(void)
{
uint32_t ui32Status;
//
// Read and save the interrupt status, but clear out the status register.
//
ui32Status = UARTn(0)->MIS;
UARTn(0)->IEC = ui32Status;
//
// Allow the HCI driver to respond to the interrupt.
//
//HciDrvUartISR(ui32Status);
// Signal radio task to run
WsfTaskSetReady(0, 0);
}
//*****************************************************************************
//
// Interrupt handler for BLE
//
//*****************************************************************************
void
am_ble_isr(void)
{
HciDrvIntService();
// Signal radio task to run
WsfTaskSetReady(0, 0);
}
//*****************************************************************************
//
// Perform initial setup for the radio task.
//
//*****************************************************************************
void
RadioTaskSetup(void)
{
am_util_debug_printf("RadioTask: setup\r\n");
NVIC_SetPriority(BLE_IRQn, NVIC_configMAX_SYSCALL_INTERRUPT_PRIORITY);
//
// Boot the radio.
//
HciDrvRadioBoot(1);
}
//*****************************************************************************
//
// Short Description.
//
//*****************************************************************************
void
RadioTask(void *pvParameters)
{
#if WSF_TRACE_ENABLED == TRUE
//
// Enable ITM
//
am_util_debug_printf("Starting wicentric trace:\n\n");
#endif
//
// Initialize the main ExactLE stack.
//
exactle_stack_init();
//
// Prep the buttons for use
//
setup_buttons();
//
// Start the "Tag" profile.
//
TagStart();
while (1)
{
//
// Calculate the elapsed time from our free-running timer, and update
// the software timers in the WSF scheduler.
//
wsfOsDispatcher();
}
}
@@ -0,0 +1,65 @@
//*****************************************************************************
//
//! @file radio_task.h
//!
//! @brief Functions and variables related to the radio task.
//!
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef RADIO_TASK_H
#define RADIO_TASK_H
//*****************************************************************************
//
// Radio task handle.
//
//*****************************************************************************
extern TaskHandle_t radio_task_handle;
//*****************************************************************************
//
// External function definitions.
//
//*****************************************************************************
extern void RadioTaskSetup(void);
extern void RadioTask(void *pvParameters);
#endif // RADIO_TASK_H
@@ -0,0 +1,214 @@
//*****************************************************************************
//
//! @file rtos.c
//!
//! @brief Essential functions to make the RTOS run correctly.
//!
//! These functions are required by the RTOS for ticking, sleeping, and basic
//! error checking.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "portmacro.h"
#include "portable.h"
#include "ble_freertos_tag.h"
//*****************************************************************************
//
// Task handle for the initial setup task.
//
//*****************************************************************************
TaskHandle_t xSetupTask;
//*****************************************************************************
//
// Interrupt handler for the CTIMER module.
//
//*****************************************************************************
void
am_ctimer_isr(void)
{
uint32_t ui32Status;
//
// Check the timer interrupt status.
//
ui32Status = am_hal_ctimer_int_status_get(false);
am_hal_ctimer_int_clear(ui32Status);
//
// Run handlers for the various possible timer events.
//
am_hal_ctimer_int_service(ui32Status);
}
//*****************************************************************************
//
// Sleep function called from FreeRTOS IDLE task.
// Do necessary application specific Power down operations here
// Return 0 if this function also incorporates the WFI, else return value same
// as idleTime
//
//*****************************************************************************
uint32_t am_freertos_sleep(uint32_t idleTime)
{
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
return 0;
}
//*****************************************************************************
//
// Recovery function called from FreeRTOS IDLE task, after waking up from Sleep
// Do necessary 'wakeup' operations here, e.g. to power up/enable peripherals etc.
//
//*****************************************************************************
void am_freertos_wakeup(uint32_t idleTime)
{
return;
}
//*****************************************************************************
//
// FreeRTOS debugging functions.
//
//*****************************************************************************
void
vApplicationMallocFailedHook(void)
{
//
// Called if a call to pvPortMalloc() fails because there is insufficient
// free memory available in the FreeRTOS heap. pvPortMalloc() is called
// internally by FreeRTOS API functions that create tasks, queues, software
// timers, and semaphores. The size of the FreeRTOS heap is set by the
// configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h.
//
while (1);
}
void
vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName)
{
(void) pcTaskName;
(void) pxTask;
//
// Run time stack overflow checking is performed if
// configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
// function is called if a stack overflow is detected.
//
while (1)
{
__asm("BKPT #0\n") ; // Break into the debugger
}
}
//*****************************************************************************
//
// High priority task to run immediately after the scheduler starts.
//
// This task is used for any global initialization that must occur after the
// scheduler starts, but before any functional tasks are running. This can be
// useful for enabling events, semaphores, and other global, RTOS-specific
// features.
//
//*****************************************************************************
void
setup_task(void *pvParameters)
{
//
// Print a debug message.
//
am_util_debug_printf("Running setup tasks...\r\n");
//
// Run setup functions.
//
RadioTaskSetup();
//
// Create the functional tasks
//
xTaskCreate(RadioTask, "RadioTask", 512, 0, 3, &radio_task_handle);
//
// The setup operations are complete, so suspend the setup task now.
//
vTaskSuspend(NULL);
while (1);
}
//*****************************************************************************
//
// Initializes all tasks
//
//*****************************************************************************
void
run_tasks(void)
{
//
// Set some interrupt priorities before we create tasks or start the scheduler.
//
// Note: Timer priority is handled by the FreeRTOS kernel, so we won't
// touch it here.
//
//
// Create essential tasks.
//
xTaskCreate(setup_task, "Setup", 512, 0, 3, &xSetupTask);
//
// Start the scheduler.
//
vTaskStartScheduler();
}
@@ -0,0 +1,75 @@
//*****************************************************************************
//
//! @file rtos.h
//!
//! @brief Essential functions to make the RTOS run
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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.3.2 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#ifndef RTOS_H
#define RTOS_H
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Macro definitions
//
//*****************************************************************************
// External variable definitions
//
//*****************************************************************************
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
void run_tasks(void);
#ifdef __cplusplus
}
#endif
#endif // RTOS_H
@@ -0,0 +1,401 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := blinky
COMPILERNAME := gcc
PROJECT := blinky_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.c
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_stdio.c
SRC+= am_devices_led.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(SDKPATH)/devices
VPATH+= $(COMMONPATH)/examples/blinky
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,84 @@
//*****************************************************************************
//
//! @file main.c
//!
//! @brief A simple LED blinking example.
//!
//
//*****************************************************************************
/*
Copyright (c) 2019 SparkFun Electronics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
#define BLINK_PERIOD 500
//*****************************************************************************
//
// Main
//
//*****************************************************************************
int
main(void)
{
// Set the clock frequency.
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
// Set the default cache configuration
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
// Configure the board for low power operation.
am_bsp_low_power_init();
// Set up BSP leds
#ifdef AM_BSP_NUM_LEDS
uint32_t ux, ui32GPIONumber;
for (ux = 0; ux < AM_BSP_NUM_LEDS; ux++) {
ui32GPIONumber = am_bsp_psLEDs[ux].ui32GPIONumber;
am_hal_gpio_pinconfig(ui32GPIONumber, g_AM_HAL_GPIO_OUTPUT);
am_devices_led_off(am_bsp_psLEDs, ux);
}
#endif // AM_BSP_NUM_LEDS
bool led_state = false;
// Blink forever
while (1)
{
// Toggle LEDs
#ifdef AM_BSP_NUM_LEDS
led_state = !led_state;
uint32_t ux;
for (ux = 0; ux < AM_BSP_NUM_LEDS; ux++) {
ui32GPIONumber = am_bsp_psLEDs[ux].ui32GPIONumber;
(led_state) ? am_devices_led_on(am_bsp_psLEDs, ux) : am_devices_led_off(am_bsp_psLEDs, ux);
}
#endif // AM_BSP_NUM_LEDS
// Delay
am_util_delay_ms(BLINK_PERIOD);
}
}
@@ -0,0 +1,401 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := hello_world_uart
COMPILERNAME := gcc
PROJECT := $(TARGET)_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.c
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_id.c
SRC+= am_util_stdio.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/examples/hello_world_uart
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,332 @@
//*****************************************************************************
//
//! @file hello_world_uart.c
//!
//! @brief A simple "Hello World" example using the UART peripheral.
//!
//! Purpose: This example prints a "Hello World" message with some device info
//! over UART at 115200 baud. To see the output of this program, run AMFlash,
//! and configure the console for UART. The example sleeps after it is done
//! printing.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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 v2.2.0-7-g63f7c2ba1 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
//*****************************************************************************
//
// UART handle.
//
//*****************************************************************************
void *phUART;
#define CHECK_ERRORS(x) \
if ((x) != AM_HAL_STATUS_SUCCESS) \
{ \
error_handler(x); \
}
volatile uint32_t ui32LastError;
//*****************************************************************************
//
// Catch HAL errors.
//
//*****************************************************************************
void
error_handler(uint32_t ui32ErrorStatus)
{
ui32LastError = ui32ErrorStatus;
while (1);
}
//*****************************************************************************
//
// UART buffers.
//
//*****************************************************************************
uint8_t g_pui8TxBuffer[256];
uint8_t g_pui8RxBuffer[2];
//*****************************************************************************
//
// UART configuration.
//
//*****************************************************************************
const am_hal_uart_config_t g_sUartConfig =
{
//
// Standard UART settings: 115200-8-N-1
//
.ui32BaudRate = 115200,
.ui32DataBits = AM_HAL_UART_DATA_BITS_8,
.ui32Parity = AM_HAL_UART_PARITY_NONE,
.ui32StopBits = AM_HAL_UART_ONE_STOP_BIT,
.ui32FlowControl = AM_HAL_UART_FLOW_CTRL_NONE,
//
// Set TX and RX FIFOs to interrupt at half-full.
//
.ui32FifoLevels = (AM_HAL_UART_TX_FIFO_1_2 |
AM_HAL_UART_RX_FIFO_1_2),
//
// Buffers
//
.pui8TxBuffer = g_pui8TxBuffer,
.ui32TxBufferSize = sizeof(g_pui8TxBuffer),
.pui8RxBuffer = g_pui8RxBuffer,
.ui32RxBufferSize = sizeof(g_pui8RxBuffer),
};
//*****************************************************************************
//
// UART0 interrupt handler.
//
//*****************************************************************************
void
am_uart_isr(void)
{
//
// Service the FIFOs as necessary, and clear the interrupts.
//
uint32_t ui32Status, ui32Idle;
am_hal_uart_interrupt_status_get(phUART, &ui32Status, true);
am_hal_uart_interrupt_clear(phUART, ui32Status);
am_hal_uart_interrupt_service(phUART, ui32Status, &ui32Idle);
}
//*****************************************************************************
//
// UART print string
//
//*****************************************************************************
void
uart_print(char *pcStr)
{
uint32_t ui32StrLen = 0;
uint32_t ui32BytesWritten = 0;
//
// Measure the length of the string.
//
while (pcStr[ui32StrLen] != 0)
{
ui32StrLen++;
}
//
// Print the string via the UART.
//
const am_hal_uart_transfer_t sUartWrite =
{
.ui32Direction = AM_HAL_UART_WRITE,
.pui8Data = (uint8_t *) pcStr,
.ui32NumBytes = ui32StrLen,
.ui32TimeoutMs = 0,
.pui32BytesTransferred = &ui32BytesWritten,
};
CHECK_ERRORS(am_hal_uart_transfer(phUART, &sUartWrite));
if (ui32BytesWritten != ui32StrLen)
{
//
// Couldn't send the whole string!!
//
while(1);
}
}
//*****************************************************************************
//
// Main
//
//*****************************************************************************
int
main(void)
{
am_util_id_t sIdDevice;
uint32_t ui32StrBuf;
//
// Set the clock frequency.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
//
// Initialize the printf interface for UART output.
//
CHECK_ERRORS(am_hal_uart_initialize(0, &phUART));
CHECK_ERRORS(am_hal_uart_power_control(phUART, AM_HAL_SYSCTRL_WAKE, false));
CHECK_ERRORS(am_hal_uart_configure(phUART, &g_sUartConfig));
//
// Enable the UART pins.
//
am_hal_gpio_pinconfig(AM_BSP_GPIO_COM_UART_TX, g_AM_BSP_GPIO_COM_UART_TX);
am_hal_gpio_pinconfig(AM_BSP_GPIO_COM_UART_RX, g_AM_BSP_GPIO_COM_UART_RX);
//
// Enable interrupts.
//
NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + AM_BSP_UART_PRINT_INST));
am_hal_interrupt_master_enable();
//
// Set the main print interface to use the UART print function we defined.
//
am_util_stdio_printf_init(uart_print);
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("Hello World!\n\n");
//
// Print the device info.
//
am_util_id_device(&sIdDevice);
am_util_stdio_printf("Vendor Name: %s\n", sIdDevice.pui8VendorName);
am_util_stdio_printf("Device type: %s\n", sIdDevice.pui8DeviceName);
am_util_stdio_printf("Qualified: %s\n",
sIdDevice.sMcuCtrlDevice.ui32Qualified ?
"Yes" : "No");
am_util_stdio_printf("Device Info:\n"
"\tPart number: 0x%08X\n"
"\tChip ID0: 0x%08X\n"
"\tChip ID1: 0x%08X\n"
"\tRevision: 0x%08X (Rev%c%c)\n",
sIdDevice.sMcuCtrlDevice.ui32ChipPN,
sIdDevice.sMcuCtrlDevice.ui32ChipID0,
sIdDevice.sMcuCtrlDevice.ui32ChipID1,
sIdDevice.sMcuCtrlDevice.ui32ChipRev,
sIdDevice.ui8ChipRevMaj, sIdDevice.ui8ChipRevMin );
//
// If not a multiple of 1024 bytes, append a plus sign to the KB.
//
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32FlashSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tFlash size: %7d (%d KB%s)\n",
sIdDevice.sMcuCtrlDevice.ui32FlashSize,
sIdDevice.sMcuCtrlDevice.ui32FlashSize / 1024,
&ui32StrBuf);
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32SRAMSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tSRAM size: %7d (%d KB%s)\n\n",
sIdDevice.sMcuCtrlDevice.ui32SRAMSize,
sIdDevice.sMcuCtrlDevice.ui32SRAMSize / 1024,
&ui32StrBuf);
//
// Print the compiler version.
//
am_hal_uart_tx_flush(phUART);
am_util_stdio_printf("App Compiler: %s\n", COMPILER_VERSION);
#ifdef AM_PART_APOLLO3
am_util_stdio_printf("HAL Compiler: %s\n", g_ui8HALcompiler);
am_util_stdio_printf("HAL SDK version: %d.%d.%d\n",
g_ui32HALversion.s.Major,
g_ui32HALversion.s.Minor,
g_ui32HALversion.s.Revision);
am_util_stdio_printf("HAL compiled with %s-style registers\n",
g_ui32HALversion.s.bAMREGS ? "AM_REG" : "CMSIS");
am_hal_security_info_t secInfo;
char sINFO[32];
uint32_t ui32Status;
ui32Status = am_hal_security_get_info(&secInfo);
if (ui32Status == AM_HAL_STATUS_SUCCESS)
{
if ( secInfo.bInfo0Valid )
{
am_util_stdio_sprintf(sINFO, "INFO0 valid, ver 0x%X", secInfo.info0Version);
}
else
{
am_util_stdio_sprintf(sINFO, "INFO0 invalid");
}
am_util_stdio_printf("SBL ver: 0x%x - 0x%x, %s\n",
secInfo.sblVersion, secInfo.sblVersionAddInfo, sINFO);
}
else
{
am_util_stdio_printf("am_hal_security_get_info failed 0x%X\n", ui32Status);
}
#endif // AM_PART_APOLLO3
//
// We are done printing.
// Disable the UART and interrupts
//
am_hal_uart_tx_flush(phUART);
CHECK_ERRORS(am_hal_uart_power_control(phUART, AM_HAL_SYSCTRL_DEEPSLEEP, false));
//
// Loop forever while sleeping.
//
while (1)
{
//
// Go to Deep Sleep.
//
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
}
@@ -0,0 +1,401 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := hello_world_uart_cpp
COMPILERNAME := gcc
PROJECT := $(TARGET)_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.cpp
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_id.c
SRC+= am_util_stdio.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/examples/hello_world_uart_cpp
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,345 @@
//*****************************************************************************
//
//! @file hello_world_uart.cpp
//!
//! @brief A simple "Hello World" example using the UART peripheral.
//!
//! Purpose: This example prints a "Hello World" message with some device info
//! over UART at 115200 baud. To see the output of this program, run AMFlash,
//! and configure the console for UART. The example sleeps after it is done
//! printing.
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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 v2.2.0-7-g63f7c2ba1 of the AmbiqSuite Development Package.
//
//*****************************************************************************
extern "C" { // extern "C" is required because Release 2.2.0 of the
#include "am_mcu_apollo.h" // AmbiqSuite SDK still has some HAL headers without
} // this CPP guard built in
#include "am_bsp.h"
#include "am_util.h"
//*****************************************************************************
//
// C++ Functionality demonstration
//
//*****************************************************************************
class CPPPrinter {
private:
protected:
public:
uint8_t value;
CPPPrinter( uint8_t _value ) : value(_value) {};
void printValue( void ){
am_util_stdio_printf("I am a CPPPrinter and my value is %d\n\n", value);
}
};
CPPPrinter myCPPPrinter(12);
//*****************************************************************************
//
// UART handle.
//
//*****************************************************************************
void *phUART;
#define CHECK_ERRORS(x) \
if ((x) != AM_HAL_STATUS_SUCCESS) \
{ \
error_handler(x); \
}
volatile uint32_t ui32LastError;
//*****************************************************************************
//
// Catch HAL errors.
//
//*****************************************************************************
void
error_handler(uint32_t ui32ErrorStatus)
{
ui32LastError = ui32ErrorStatus;
while (1);
}
//*****************************************************************************
//
// UART buffers.
//
//*****************************************************************************
uint8_t g_pui8TxBuffer[256];
uint8_t g_pui8RxBuffer[2];
//*****************************************************************************
//
// UART configuration.
//
//*****************************************************************************
am_hal_uart_config_t g_sUartConfig = {0};
//*****************************************************************************
//
// UART0 interrupt handler.
//
//*****************************************************************************
extern "C" void am_uart_isr(void)
{
//
// Service the FIFOs as necessary, and clear the interrupts.
//
uint32_t ui32Status, ui32Idle;
am_hal_uart_interrupt_status_get(phUART, &ui32Status, true);
am_hal_uart_interrupt_clear(phUART, ui32Status);
am_hal_uart_interrupt_service(phUART, ui32Status, &ui32Idle);
}
//*****************************************************************************
//
// UART print string
//
//*****************************************************************************
void
uart_print(char *pcStr)
{
uint32_t ui32StrLen = 0;
uint32_t ui32BytesWritten = 0;
//
// Measure the length of the string.
//
while (pcStr[ui32StrLen] != 0)
{
ui32StrLen++;
}
//
// Print the string via the UART.
//
const am_hal_uart_transfer_t sUartWrite =
{
.ui32Direction = AM_HAL_UART_WRITE,
.pui8Data = (uint8_t *) pcStr,
.ui32NumBytes = ui32StrLen,
.ui32TimeoutMs = 0,
.pui32BytesTransferred = &ui32BytesWritten,
};
CHECK_ERRORS(am_hal_uart_transfer(phUART, &sUartWrite));
if (ui32BytesWritten != ui32StrLen)
{
//
// Couldn't send the whole string!!
//
while(1);
}
}
//*****************************************************************************
//
// Main
//
//*****************************************************************************
extern "C" int main(void)
{
am_util_id_t sIdDevice;
uint32_t ui32StrBuf;
// Initialize Uart Configuration Structure
g_sUartConfig.ui32BaudRate = 115200;
g_sUartConfig.ui32DataBits = AM_HAL_UART_DATA_BITS_8;
g_sUartConfig.ui32Parity = AM_HAL_UART_PARITY_NONE;
g_sUartConfig.ui32StopBits = AM_HAL_UART_ONE_STOP_BIT;
g_sUartConfig.ui32FlowControl = AM_HAL_UART_FLOW_CTRL_NONE;
g_sUartConfig.ui32FifoLevels = (AM_HAL_UART_TX_FIFO_1_2 | AM_HAL_UART_RX_FIFO_1_2);
g_sUartConfig.pui8TxBuffer = g_pui8TxBuffer;
g_sUartConfig.ui32TxBufferSize = sizeof(g_pui8TxBuffer);
g_sUartConfig.pui8RxBuffer = g_pui8RxBuffer;
g_sUartConfig.ui32RxBufferSize = sizeof(g_pui8RxBuffer);
//
// Set the clock frequency.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
//
// Initialize the printf interface for UART output.
//
CHECK_ERRORS(am_hal_uart_initialize(0, &phUART));
CHECK_ERRORS(am_hal_uart_power_control(phUART, AM_HAL_SYSCTRL_WAKE, false));
CHECK_ERRORS(am_hal_uart_configure(phUART, &g_sUartConfig));
//
// Enable the UART pins.
//
am_hal_gpio_pinconfig(AM_BSP_GPIO_COM_UART_TX, g_AM_BSP_GPIO_COM_UART_TX);
am_hal_gpio_pinconfig(AM_BSP_GPIO_COM_UART_RX, g_AM_BSP_GPIO_COM_UART_RX);
//
// Enable interrupts.
//
NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + AM_BSP_UART_PRINT_INST));
am_hal_interrupt_master_enable();
//
// Set the main print interface to use the UART print function we defined.
//
am_util_stdio_printf_init(uart_print);
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("Hello World!\n\n");
//
// Test CPPPrinter
//
myCPPPrinter.printValue();
//
// Print the device info.
//
am_util_id_device(&sIdDevice);
am_util_stdio_printf("Vendor Name: %s\n", sIdDevice.pui8VendorName);
am_util_stdio_printf("Device type: %s\n", sIdDevice.pui8DeviceName);
am_util_stdio_printf("Qualified: %s\n",
sIdDevice.sMcuCtrlDevice.ui32Qualified ?
"Yes" : "No");
am_util_stdio_printf("Device Info:\n"
"\tPart number: 0x%08X\n"
"\tChip ID0: 0x%08X\n"
"\tChip ID1: 0x%08X\n"
"\tRevision: 0x%08X (Rev%c%c)\n",
sIdDevice.sMcuCtrlDevice.ui32ChipPN,
sIdDevice.sMcuCtrlDevice.ui32ChipID0,
sIdDevice.sMcuCtrlDevice.ui32ChipID1,
sIdDevice.sMcuCtrlDevice.ui32ChipRev,
sIdDevice.ui8ChipRevMaj, sIdDevice.ui8ChipRevMin );
//
// If not a multiple of 1024 bytes, append a plus sign to the KB.
//
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32FlashSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tFlash size: %7d (%d KB%s)\n",
sIdDevice.sMcuCtrlDevice.ui32FlashSize,
sIdDevice.sMcuCtrlDevice.ui32FlashSize / 1024,
&ui32StrBuf);
ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32SRAMSize % 1024 ) ? '+' : 0;
am_util_stdio_printf("\tSRAM size: %7d (%d KB%s)\n\n",
sIdDevice.sMcuCtrlDevice.ui32SRAMSize,
sIdDevice.sMcuCtrlDevice.ui32SRAMSize / 1024,
&ui32StrBuf);
//
// Print the compiler version.
//
am_hal_uart_tx_flush(phUART);
am_util_stdio_printf("App Compiler: %s\n", COMPILER_VERSION);
#ifdef AM_PART_APOLLO3
am_util_stdio_printf("HAL Compiler: %s\n", g_ui8HALcompiler);
am_util_stdio_printf("HAL SDK version: %d.%d.%d\n",
g_ui32HALversion.s.Major,
g_ui32HALversion.s.Minor,
g_ui32HALversion.s.Revision);
am_util_stdio_printf("HAL compiled with %s-style registers\n",
g_ui32HALversion.s.bAMREGS ? "AM_REG" : "CMSIS");
am_hal_security_info_t secInfo;
char sINFO[32];
uint32_t ui32Status;
ui32Status = am_hal_security_get_info(&secInfo);
if (ui32Status == AM_HAL_STATUS_SUCCESS)
{
if ( secInfo.bInfo0Valid )
{
am_util_stdio_sprintf(sINFO, "INFO0 valid, ver 0x%X", secInfo.info0Version);
}
else
{
am_util_stdio_sprintf(sINFO, "INFO0 invalid");
}
am_util_stdio_printf("SBL ver: 0x%x - 0x%x, %s\n",
secInfo.sblVersion, secInfo.sblVersionAddInfo, sINFO);
}
else
{
am_util_stdio_printf("am_hal_security_get_info failed 0x%X\n", ui32Status);
}
#endif // AM_PART_APOLLO3
//
// We are done printing.
// Disable the UART and interrupts
//
am_hal_uart_tx_flush(phUART);
CHECK_ERRORS(am_hal_uart_power_control(phUART, AM_HAL_SYSCTRL_DEEPSLEEP, false));
//
// Loop forever while sleeping.
//
while (1)
{
//
// Go to Deep Sleep.
//
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
}
@@ -0,0 +1,404 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := hm01b0_camera_uart
COMPILERNAME := gcc
PROJECT := $(TARGET)_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+= -I$(COMMONPATH)/third_party/hm01b0
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.cpp
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_id.c
SRC+= am_util_stdio.c
SRC+= HM01B0.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/examples/hm01b0_camera_uart
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+= $(COMMONPATH)/third_party/hm01b0
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,356 @@
// based on demo from Himax
/*
Copyright (c) 2019 SparkFun Electronics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
#include "HM01B0.h"
#include "HM01B0_RAW8_QVGA_8bits_lsb_5fps.h"
#include "platform.h"
//#define DEMO_HM01B0_TEST_MODE_ENABLE
#define DEMO_HM01B0_FRAMEBUFFER_DUMP_ENABLE
//*****************************************************************************
//
// HM01B0 Configuration
//
//*****************************************************************************
static hm01b0_cfg_t s_HM01B0Cfg =
{
// i2c settings
.ui16SlvAddr = HM01B0_DEFAULT_ADDRESS,
.eIOMMode = HM01B0_IOM_MODE,
.ui32IOMModule = HM01B0_IOM_MODULE,
.sIOMCfg =
{
.eInterfaceMode = HM01B0_IOM_MODE,
.ui32ClockFreq = HM01B0_I2C_CLOCK_FREQ,
},
.pIOMHandle = NULL,
.ui8PinSCL = HM01B0_PIN_SCL,
.ui8PinSDA = HM01B0_PIN_SDA,
// MCLK settings
.ui32CTimerModule = HM01B0_MCLK_GENERATOR_MOD,
.ui32CTimerSegment = HM01B0_MCLK_GENERATOR_SEG,
.ui32CTimerOutputPin = HM01B0_PIN_MCLK,
// data interface
.ui8PinD0 = HM01B0_PIN_D0,
.ui8PinD1 = HM01B0_PIN_D1,
.ui8PinD2 = HM01B0_PIN_D2,
.ui8PinD3 = HM01B0_PIN_D3,
.ui8PinD4 = HM01B0_PIN_D4,
.ui8PinD5 = HM01B0_PIN_D5,
.ui8PinD6 = HM01B0_PIN_D6,
.ui8PinD7 = HM01B0_PIN_D7,
.ui8PinVSYNC = HM01B0_PIN_VSYNC,
.ui8PinHSYNC = HM01B0_PIN_HSYNC,
.ui8PinPCLK = HM01B0_PIN_PCLK,
#ifdef HM01B0_PIN_TRIG
.ui8PinTrig = HM01B0_PIN_TRIG,
#endif // HM01B0_PIN_TRIG
#ifdef HM01B0_PIN_INT
.ui8PinInt = HM01B0_PIN_INT,
#endif // HM01B0_PIN_INT
.pfnGpioIsr = NULL,
};
static uint8_t s_ui8FrameBuffer[HM01B0_PIXEL_X_NUM * HM01B0_PIXEL_Y_NUM];
//*****************************************************************************
//
// Forward declarations
//
//*****************************************************************************
void boost_mode_enable(bool bEnable);
void am_gpio_isr(void);
void framebuffer_dump(uint8_t *pui8Buffer, uint32_t ui32BufferLen);
//*****************************************************************************
//
// High Speed UART Configuration
//
//*****************************************************************************
static const am_hal_uart_config_t g_sBspUartConfigHS =
{
//
// Standard UART settings: 115200-8-N-1
//
.ui32BaudRate = 115200,
.ui32DataBits = AM_HAL_UART_DATA_BITS_8,
.ui32Parity = AM_HAL_UART_PARITY_NONE,
.ui32StopBits = AM_HAL_UART_ONE_STOP_BIT,
.ui32FlowControl = AM_HAL_UART_FLOW_CTRL_NONE,
//
// Set TX and RX FIFOs to interrupt at half-full.
//
.ui32FifoLevels = (AM_HAL_UART_TX_FIFO_1_2 |
AM_HAL_UART_RX_FIFO_1_2),
//
// The default interface will just use polling instead of buffers.
//
.pui8TxBuffer = 0,
.ui32TxBufferSize = 0,
.pui8RxBuffer = 0,
.ui32RxBufferSize = 0,
};
//*****************************************************************************
//
// Main function.
//
//*****************************************************************************
int main(void)
{
uint32_t ui32Err = HM01B0_ERR_OK;
uint16_t ui16ModelId = 0x0000;
uint8_t ui8Mode = 0xFF;
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
//
// Set the default cache configuration
//
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//
// Configure the board for low power operation.
//
am_bsp_low_power_init();
#ifdef AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN
//
// Turn on the camera regulator
//
am_hal_gpio_pinconfig(AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN, g_AM_HAL_GPIO_OUTPUT_12);
am_hal_gpio_output_set(AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN);
#endif // AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN
//
// Enable the UART print interface at high speed
//
am_bsp_uart_printf_enable_custom(&g_sBspUartConfigHS);
//
// Clear the terminal and print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("HM01B0 Demo\n");
am_util_stdio_printf(" SCL:\tPin %d\n", s_HM01B0Cfg.ui8PinSCL);
am_util_stdio_printf(" SDA:\tPin %d\n", s_HM01B0Cfg.ui8PinSDA);
am_util_stdio_printf(" MCLK:\tPin %d\n", s_HM01B0Cfg.ui32CTimerOutputPin);
am_util_stdio_printf(" VSYNC:\tPin %d\n", s_HM01B0Cfg.ui8PinVSYNC);
am_util_stdio_printf(" HSYNC\tPin %d\n", s_HM01B0Cfg.ui8PinHSYNC);
am_util_stdio_printf(" PCLK:\tPin %d\n", s_HM01B0Cfg.ui8PinPCLK);
am_util_stdio_printf(" D0:\tPin %d\n", s_HM01B0Cfg.ui8PinD0);
am_util_stdio_printf(" D1:\tPin %d\n", s_HM01B0Cfg.ui8PinD1);
am_util_stdio_printf(" D2:\tPin %d\n", s_HM01B0Cfg.ui8PinD2);
am_util_stdio_printf(" D3:\tPin %d\n", s_HM01B0Cfg.ui8PinD3);
am_util_stdio_printf(" D4:\tPin %d\n", s_HM01B0Cfg.ui8PinD4);
am_util_stdio_printf(" D5:\tPin %d\n", s_HM01B0Cfg.ui8PinD5);
am_util_stdio_printf(" D6:\tPin %d\n", s_HM01B0Cfg.ui8PinD6);
am_util_stdio_printf(" D7:\tPin %d\n", s_HM01B0Cfg.ui8PinD7);
//
// Enable interrupts so we can receive messages from the boot host.
//
am_hal_interrupt_master_enable();
boost_mode_enable(true);
hm01b0_power_up(&s_HM01B0Cfg);
// todo: check the delay time to just fit the spec.
am_util_delay_ms(1);
hm01b0_mclk_enable(&s_HM01B0Cfg);
// todo: check the delay time to just fit the spec.
am_util_delay_ms(1);
hm01b0_init_if(&s_HM01B0Cfg);
hm01b0_get_modelid(&s_HM01B0Cfg, &ui16ModelId);
am_util_stdio_printf("HM01B0 Model ID 0x%04X\n", ui16ModelId);
hm01b0_init_system(&s_HM01B0Cfg, (hm_script_t *)sHM01B0InitScript, sizeof(sHM01B0InitScript)/sizeof(hm_script_t));
#ifdef DEMO_HM01B0_TEST_MODE_ENABLE
am_util_stdio_printf("HM01B0 Enable walking 1s test mode\n");
hm01b0_test_walking1s(&s_HM01B0Cfg);
#else
hm01b0_cal_ae(&s_HM01B0Cfg, 10, s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer));
#endif
while(1)
{
hm01b0_ae_cfg_t sAECfg;
hm01b0_get_mode(&s_HM01B0Cfg, &ui8Mode);
am_util_stdio_printf("HM01B0 current mode %d\n", ui8Mode);
ui32Err = hm01b0_get_ae(&s_HM01B0Cfg, &sAECfg);
am_util_stdio_printf("AE convergance(0x%02X) TargetMean 0x%02X, ConvergeInTh 0x%02X, AEMean 0x%02X\n", ui32Err, sAECfg.ui8AETargetMean, sAECfg.ui8ConvergeInTh, sAECfg.ui8AEMean);
hm01b0_cmd_update(&s_HM01B0Cfg);
hm01b0_set_mode(&s_HM01B0Cfg, HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES, 1);
hm01b0_blocking_read_oneframe(&s_HM01B0Cfg, s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer));
#ifdef DEMO_HM01B0_TEST_MODE_ENABLE
hm01b0_test_walking1s_check_data_sanity(s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer), 10);
am_util_delay_ms(3000);
#endif
#ifdef DEMO_HM01B0_FRAMEBUFFER_DUMP_ENABLE
framebuffer_dump(s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer));
#endif
memset(s_ui8FrameBuffer, 0x00, sizeof(s_ui8FrameBuffer));
// give some time for user to stop the external itm logging.
am_util_delay_ms(5000);
}
hm01b0_deinit_if(&s_HM01B0Cfg);
hm01b0_mclk_disable(&s_HM01B0Cfg);
hm01b0_power_down(&s_HM01B0Cfg);
boost_mode_enable(false);
//
// Loop forever.
//
while (1)
{
//
// Go to Deep Sleep.
//
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
}
//*****************************************************************************
//
// Helper Functions
//
//*****************************************************************************
// GPIO ISR
void
am_gpio_isr(void)
{
if (s_HM01B0Cfg.pfnGpioIsr)
s_HM01B0Cfg.pfnGpioIsr();
}
// frame buffer dump
void framebuffer_dump(uint8_t *pui8Buffer, uint32_t ui32BufferLen)
{
am_util_stdio_printf("+++ frame +++");
for (uint32_t ui32Idx = 0; ui32Idx < ui32BufferLen; ui32Idx++)
{
if ((ui32Idx & 0xF) == 0x00)
{
am_util_stdio_printf("\n0x%08X ", ui32Idx);
// this delay is to let itm have time to flush out data.
am_util_delay_ms(1);
}
am_util_stdio_printf("%02X ", *(pui8Buffer + ui32Idx));
}
am_util_stdio_printf("\n--- frame ---\n");
am_util_delay_ms(1);
}
// burst mode enable
void boost_mode_enable(bool bEnable){
am_hal_burst_avail_e eBurstModeAvailable;
am_hal_burst_mode_e eBurstMode;
// Check that the Burst Feature is available.
if (AM_HAL_STATUS_SUCCESS == am_hal_burst_mode_initialize(&eBurstModeAvailable)){
if (AM_HAL_BURST_AVAIL == eBurstModeAvailable){
am_util_stdio_printf("Apollo3 Burst Mode is Available\n");
}
else{
am_util_stdio_printf("Apollo3 Burst Mode is Not Available\n");
while(1){};
}
}
else{
am_util_stdio_printf("Failed to Initialize for Burst Mode operation\n");
}
// Make sure we are in "Normal" mode.
if (AM_HAL_STATUS_SUCCESS == am_hal_burst_mode_disable(&eBurstMode)){
if (AM_HAL_NORMAL_MODE == eBurstMode){
am_util_stdio_printf("Apollo3 operating in Normal Mode (48MHz)\n");
}
}
else{
am_util_stdio_printf("Failed to Disable Burst Mode operation\n");
}
// Put the MCU into "Burst" mode.
if (bEnable)
{
if (AM_HAL_STATUS_SUCCESS == am_hal_burst_mode_enable(&eBurstMode)){
if (AM_HAL_BURST_MODE == eBurstMode){
am_util_stdio_printf("Apollo3 operating in Burst Mode (96MHz)\n");
}
}
else{
am_util_stdio_printf("Failed to Enable Burst Mode operation\n");
}
}
}
@@ -0,0 +1,95 @@
#!/usr/bin/python
import os
import sys
import argparse
import os.path
from array import *
VERSION = 0
SUBVERSION = 1
HIMAX_CMD_OFFSET_OP = 0
HIMAX_CMD_OFFSET_ADDR = 1
HIMAX_CMD_OFFSET_REGADDR = 2
HIMAX_CMD_OFFSET_REGVALUE = 3
dict_DeviceDefaultAddress = {
'HM01B0': '24',
}
def check_file_existence(x):
if not os.path.isfile(x):
# Argparse uses the ArgumentTypeError to give a rejection message like:
# error: argument input: x does not exist
raise argparse.ArgumentTypeError("{0} does not exist".format(x))
return x
def create_outputfile(args):
path = os.path.dirname(os.path.abspath(args.ifile))
basename = os.path.split(os.path.splitext(args.ifile)[0])[-1]
outputfile = os.path.join(path, basename + '.h')
return outputfile
def do_convert(args, ofilename):
ofile = open(ofilename, 'w')
ofile.write("\n")
ofile.write("#include \"%s.h\"\n" % args.model)
ofile.write("\n")
ofile.write("const hm_script_t s%sInitScript[] =\n" % args.model)
ofile.write("{\n")
with open(args.ifile, 'r') as ifile:
for line in ifile:
items = line.split()
ofile.write("// %s\n" % (' '.join(items)))
print("// %s" % (' '.join(items)))
if len(items) > 1:
if items[HIMAX_CMD_OFFSET_OP] == 'W' and items[HIMAX_CMD_OFFSET_ADDR] == dict_DeviceDefaultAddress.get(args.model):
print(" {0x%s, 0x%s,}," % (items[HIMAX_CMD_OFFSET_REGADDR], items[HIMAX_CMD_OFFSET_REGVALUE]))
ofile.write(" {0x%s, 0x%s,},\n" % (items[HIMAX_CMD_OFFSET_REGADDR], items[HIMAX_CMD_OFFSET_REGVALUE]))
ofile.write("};\n")
ofile.close()
def main():
parser = argparse.ArgumentParser(
description = 'This program converts a given Himax Script into a c header file.')
parser.add_argument('-i', '--input',
dest = 'ifile',
required = True,
help = 'input file',
metavar = 'FILE',
type = check_file_existence)
parser.add_argument('-m', '--model',
dest = 'model',
required = True,
help = 'Himax Sensor Model',
choices = ['HM01B0'],
default = 'HM01B0',
)
parser.add_argument('-v', '--version',
help = 'show the program version',
action = 'version',
version = '%(prog)s {ver}'.format(ver = 'v%d.%d' %\
(VERSION, SUBVERSION)))
args = parser.parse_args()
ofilename = create_outputfile(args)
# print('%s' % ofile)
do_convert(args, ofilename)
print "done!"
if __name__ == "__main__":
main()
@@ -0,0 +1,177 @@
#!/usr/bin/python3
import os
import sys
import argparse
import os.path
from array import *
from PIL import Image
import numpy as np
import re
dict_Resolutions = {
'QVGA': (324, 244),
}
# height = 244
# width = 324
VERSION = 0
SUBVERSION = 1
class RawData:
ui8Array = None
def __init__(self):
self.ui8Array = array('B')
def check_file_existence(x):
if not os.path.isfile(x):
# Argparse uses the ArgumentTypeError to give a rejection message like:
# error: argument input: x does not exist
raise argparse.ArgumentTypeError("{0} does not exist".format(x))
return x
def create_bmp(args, framelist):
(width, height) = dict_Resolutions.get(args.resolution, ("Resolution not supported", 0, 0))
for idx, frame in enumerate(framelist):
bitmap = np.zeros((height, width), dtype=np.uint8)
h_idx = height - 1
w_idx = 0
# fill up bitmap array
for pixel in frame.ui8Array:
bitmap[h_idx, w_idx] = pixel
if w_idx == width - 1:
w_idx = 0
h_idx -= 1
else:
w_idx += 1
# h_idx = height - 1
# w_idx = width - 1
# # fill up bitmap array
# for pixel in frame.ui8Array:
# bitmap[h_idx, w_idx] = pixel
# if w_idx == 0:
# w_idx = width - 1
# h_idx -= 1
# else:
# w_idx -= 1
# h_idx = 0
# w_idx = 0
# # fill up bitmap array
# for pixel in frame.ui8Array:
# bitmap[h_idx, w_idx] = pixel
# if w_idx == width - 1:
# w_idx = 0
# h_idx += 1
# else:
# w_idx += 1
path = os.path.dirname(os.path.abspath(args.inputfile))
basename = os.path.split(os.path.splitext(args.inputfile)[0])[-1]
outputfile = os.path.join(path, basename + '_' + str(idx) + '.bmp')
# print (bitmap)
img = Image.fromarray(bitmap, 'L')
img.save(outputfile)
img.show()
print ("%s created" % (basename + '_' + str(idx) + '.bmp'))
def do_convert(args):
(width, height) = dict_Resolutions.get(args.resolution, ("Resolution not supported", 0, 0))
with open(args.inputfile) as f:
h_idx = 0
w_idx = 0
rawdata = None
framestart = False
framestop = False
framelist = list()
# collect all pixel data into an int array
for line in f:
if line == "+++ frame +++\n":
framestart = True
rawdata = RawData()
continue
elif line == '--- frame ---\n':
framestop = True
if framestart == True and framestop == False:
linelist = re.findall(r"[\w']+", line)
if len(linelist) != 17:
# drop this frame
framestart = False
continue
for item in linelist[1 : ]:
rawdata.ui8Array.append(int(item, base=16))
elif framestart == True and framestop == True:
(address, length) = rawdata.ui8Array.buffer_info()
if (length * rawdata.ui8Array.itemsize) != (height * width):
print ("Incorrect total data length %d" % length * rawdata.ui8Array.itemsize)
else:
framelist.append(rawdata)
framestart = False
framestop = False
create_bmp(args, framelist)
def main():
parser = argparse.ArgumentParser(
description = 'This program converts raw data from HM01B0 to a bmp file.')
parser.add_argument('-i', '--input',
dest = 'inputfile',
required = True,
help = 'input file',
metavar = 'FILE',
type = check_file_existence
)
parser.add_argument('-r', '--resolution',
dest = 'resolution',
required = False,
help = 'Resolution',
choices = ['QVGA'],
default = 'QVGA',
)
parser.add_argument('-v', '--version',
help = 'Program version',
action = 'version',
version = '%(prog)s {ver}'.format(ver = 'v%d.%d' %\
(VERSION, SUBVERSION))
)
args = parser.parse_args()
do_convert(args)
print ("done!")
if __name__ == "__main__":
main()
@@ -0,0 +1,439 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := i2c
COMPILERNAME := gcc
PROJECT := i2c_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+= -DAM_UTIL_FAULTISR_PRINT
DEFINES+= -DUNITY_INCLUDE_CONFIG_H
DEFINES+= -D__FPU_PRESENT
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.c
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_stdio.c
SRC+= am_hal_ble_patch.c
SRC+= am_hal_ble.c
SRC+= am_hal_ble_patch_b0.c
SRC+= am_hal_burst.c
SRC+= am_hal_cachectrl.c
SRC+= am_hal_adc.c
SRC+= am_hal_clkgen.c
SRC+= am_hal_cmdq.c
SRC+= am_hal_ctimer.c
SRC+= am_hal_debug.c
SRC+= am_hal_flash.c
SRC+= am_hal_global.c
SRC+= am_hal_gpio.c
SRC+= am_hal_interrupt.c
SRC+= am_hal_iom.c
SRC+= am_hal_ios.c
SRC+= am_hal_itm.c
SRC+= am_hal_mcuctrl.c
SRC+= am_hal_mspi.c
SRC+= am_hal_pdm.c
SRC+= am_hal_pwrctrl.c
SRC+= am_hal_queue.c
SRC+= am_hal_reset.c
SRC+= am_hal_rtc.c
SRC+= am_hal_scard.c
SRC+= am_hal_secure_ota.c
SRC+= am_hal_security.c
SRC+= am_hal_stimer.c
SRC+= am_hal_sysctrl.c
SRC+= am_hal_systick.c
SRC+= am_hal_tpiu.c
SRC+= am_hal_uart.c
SRC+= am_hal_wdt.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/examples/i2c
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+= $(SDKPATH)/mcu/apollo3/hal
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
# LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+= $(SDKPATH)/CMSIS/ARM/Lib/ARM/libarm_cortexM4lf_math.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,166 @@
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
// #define ASYNCH // comment out to use blocking methods
#define DEVICE_ADDR (0xEE)
#define DEVICE_ADDR_R (DEVICE_ADDR | 0x01)
#define DEVICE_ADDR_W (DEVICE_ADDR & 0xFE)
#define IOMN (2)
#define I2C_FREQ (AM_HAL_IOM_400KHZ)
void* iom_handle = NULL;
am_hal_iom_config_t iom_cfg = {0};
am_hal_iom_transfer_t xfer = {0};
#define report(s) am_util_stdio_printf("status: 0x%08X (function: %s, file: %s, line: %d)\n", s, __PRETTY_FUNCTION__, __FILE__, __LINE__)
volatile bool xfer_complete = false;
volatile uint32_t txn_stat = 0;
void xfer_complete_callback(void *pCallbackCtxt, uint32_t transactionStatus){
(void)pCallbackCtxt;
xfer_complete = true;
txn_stat = transactionStatus;
}
void init_iom( void ){
uint32_t status = AM_HAL_STATUS_SUCCESS;
iom_cfg.eInterfaceMode = AM_HAL_IOM_I2C_MODE;
iom_cfg.ui32ClockFreq = I2C_FREQ;
iom_cfg.pNBTxnBuf = NULL;
iom_cfg.ui32NBTxnBufLength = 0;
#ifdef ASYNCH
// iom_cfg.pNMTxnBuf = ???
// iom_cfg.ui32NBTxnBufLength = ???
#endif // ASYNCH
status = am_hal_iom_initialize(IOMN, &iom_handle);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_iom_power_ctrl(iom_handle, AM_HAL_SYSCTRL_WAKE, false);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_iom_configure(iom_handle, &iom_cfg);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_iom_enable(iom_handle);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
// config pins
status = am_hal_gpio_pinconfig(AM_BSP_GPIO_IOM2_SCL, g_AM_BSP_GPIO_IOM2_SCL);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_gpio_pinconfig(AM_BSP_GPIO_IOM2_SDA, g_AM_BSP_GPIO_IOM2_SDA);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
}
//*****************************************************************************
//
// Main
//
//*****************************************************************************
int
main(void)
{
uint32_t status = AM_HAL_STATUS_SUCCESS;
//
// Perform the standard initialzation for clocks, cache settings, and
// board-level low-power operation.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
am_bsp_low_power_init();
//
// Initialize the printf interface for UART output
//
am_bsp_uart_printf_enable();
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("I2C Testing\n\n");
// do i2c stuff
init_iom();
char cmd[2];
cmd[0] = 0x01;
cmd[1] = 0x00;
// i2c.write(addr8bit, cmd, 2);
xfer.uPeerInfo.ui32I2CDevAddr = DEVICE_ADDR_W;
xfer.ui32InstrLen = 0;
xfer.ui32Instr = 0;
xfer.ui32NumBytes = 2;
xfer.eDirection = AM_HAL_IOM_TX;
xfer.pui32TxBuffer = (uint32_t*)cmd;
xfer.pui32RxBuffer = NULL;
xfer.bContinue = false;
xfer.ui8RepeatCount = 0;
xfer.ui8Priority = 1;
xfer.ui32PauseCondition = 0;
xfer.ui32StatusSetClr = 0;
#ifndef AM_HAL_DISABLE_API_VALIDATION
am_util_stdio_printf("API Validation is enabled\n");
#else
am_util_stdio_printf("API Validation DISabled\n");
#endif
#ifdef ASYNCH
status = am_hal_iom_nonblocking_transfer(iom_handle, &xfer, xfer_complete_callback, NULL);
report(status);
while(!xfer_complete){
static uint32_t count = 0;
am_util_stdio_printf("waiting for xfer to complete... %d\n", count++);
if(count > 0x0000FFFF){
am_util_stdio_printf("!TIME OUT!\n");
break;
}
}
#else
status = am_hal_iom_blocking_transfer(iom_handle, &xfer);
report(status);
#endif // ASYNCH
const char* stat_msg = NULL;
switch(status){
case AM_HAL_STATUS_SUCCESS : stat_msg = "success"; break;
case AM_HAL_IOM_ERR_I2C_NAK : stat_msg = "NAK"; break;
case AM_HAL_IOM_ERR_I2C_ARB : stat_msg = "ARB"; break;
default:
stat_msg = "UNKNOWN ERROR";
break;
}
am_util_stdio_printf("I2C write result: %s\n", stat_msg);
// cmd[0] = 0x00;
// i2c.write(addr8bit, cmd, 1);
// i2c.read(addr8bit, cmd, 2);
//
// Loop forever while sleeping.
//
while (1)
{
//
// Go to Deep Sleep.
//
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
}
@@ -0,0 +1,412 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := linker_tests
COMPILERNAME := gcc
PROJECT := $(TARGET)_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+= -I$(COMMONPATH)/examples/linker_tests
INCLUDES+= -I$(COMMONPATH)/examples/linker_tests/test_framework
INCLUDES+= -I$(COMMONPATH)/examples/linker_tests/tests
INCLUDES+= -I$(COMMONPATH)/examples/linker_tests/tests/heap
INCLUDES+= -I$(COMMONPATH)/examples/linker_tests/tests/stack
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.cpp
SRC+= am_util_stdio.c
SRC+= startup_gcc.c
SRC+= system.c
SRC+= test_framework.cpp
SRC+= tests.cpp
SRC+= test_heap.cpp
SRC+= test_stack.cpp
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+= $(COMMONPATH)/examples/linker_tests
VPATH+= $(COMMONPATH)/examples/linker_tests/test_framework
VPATH+= $(COMMONPATH)/examples/linker_tests/tests
VPATH+= $(COMMONPATH)/examples/linker_tests/tests/heap
VPATH+= $(COMMONPATH)/examples/linker_tests/tests/stack
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions -fno-threadsafe-statics # added -fno-threadsafe-statics to allow static local contructors
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,43 @@
/*
Tests / verifies linker
Checks:
- heap allocation
- stack allocation
*/
#include "main.h"
#include "test_framework.h"
#include "tests.h"
// main
int main()
{
// Setup system clocks
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
// Set the default cache configuration
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
// Configure the board for low power operation.
am_bsp_low_power_init();
// Enable the UART print interface.
am_bsp_uart_printf_enable();
// Clear the terminal and print the banner.
am_util_stdio_terminal_clear();
am_util_stdio_printf("Linker Tests\n");
am_util_stdio_printf("=============\n");
am_util_stdio_printf("\n");
// run tests
run_tests(tests);
// Loop forever while sleeping.
while (1){
// Go to Deep Sleep.
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
}
@@ -0,0 +1,9 @@
#ifndef _MAIN_H_
#define _MAIN_H_
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
#include <stdbool.h>
#endif // _MAIN_H_
@@ -0,0 +1,18 @@
#include "test_framework.h"
void print_test_info( test_info_t* info ){
am_util_stdio_printf("Test Name: %s\n", (info->name != NULL) ? info->name : "N/A");
am_util_stdio_printf("==========\n");
am_util_stdio_printf("metric: %s\n", (info->metric != NULL) ? info->metric : "N/A");
am_util_stdio_printf("value: %d\n", info->value);
am_util_stdio_printf("\n");
}
void run_tests(test_fn* tests){
test_info_t* info;
while(*tests != NULL){
(*tests)(&info);
print_test_info(info);
tests++;
}
am_util_stdio_printf("\n\nAll tests complete\n");
}
@@ -0,0 +1,16 @@
#ifndef _TEST_FRAMEWORK_H_
#define _TEST_FRAMEWORK_H_
#include "main.h"
#include <stdlib.h>
typedef struct _test_info_t {
char* name;
char* metric;
uint32_t value;
} test_info_t;
typedef void (*test_fn)( test_info_t** info );
void print_test_info( test_info_t* info );
void run_tests(test_fn* tests);
#endif // _TEST_FRAMEWORK_H_
@@ -0,0 +1,23 @@
#include "test_heap.h"
//
// test_heap
void test_heap( test_info_t** info ){
static test_info_t test_heap_info;
static char* test_heap_name = "Heap Allocation";
test_heap_info.name = test_heap_name;
*(info) = &test_heap_info;
void* mem = NULL;
size_t len = 0;
// boost_mode_enable(true);
do {
len++;
mem = (void*)malloc( len * sizeof(uint8_t));
free(mem);
} while (mem != NULL);
// boost_mode_enable(false);
test_heap_info.metric = "largest allocated space";
test_heap_info.value = len;
}
@@ -0,0 +1,8 @@
#ifndef _TEST_HEAP_H_
#define _TEST_HEAP_H_
#include "tests.h"
void test_heap( test_info_t** info );
#endif // _TEST_HEAP_H_
@@ -0,0 +1,58 @@
#include "test_stack.h"
#define MEMORY_HEADSPACE 4096
// Globals
uint32_t stack_pointer;
uint32_t min_stack_pointer = 0xFFFFFFFF;
uint32_t free_mem;
uint32_t min_free_mem = 0xFFFFFFFF;
bool go_deeper = true;
uint32_t max_depth = 0;
extern unsigned char _sheap;
uint32_t free_memory( void ){
// Without an implementation of _sbrk (heap management) we are assuming
// that the heap has zero size. If there was heap management then you
// would compute the distance to the program break (the end of the heap)
void* local;
return (((uint32_t)&local) - ((uint32_t)&_sheap));
}
void update_stack_info( void ){
void* local;
stack_pointer = (uint32_t)(&local);
free_mem = free_memory();
min_free_mem = (free_mem < min_free_mem) ? free_mem : min_free_mem;
min_stack_pointer = (stack_pointer < min_stack_pointer) ? stack_pointer : min_stack_pointer;
}
void deep_horizon( void ){
update_stack_info();
if(free_memory() < MEMORY_HEADSPACE){
go_deeper = false;
return;
}
if( go_deeper ){
deep_horizon();
}
max_depth++;
}
//
// test_stack
void test_stack( test_info_t** info ){
static test_info_t test_stack_info;
static char* test_stack_name = "Stack Allocation";
test_stack_info.name = test_stack_name;
*(info) = &test_stack_info;
go_deeper = true;
min_free_mem = 0xFFFFFFFF;
max_depth = 0;
deep_horizon();
test_stack_info.metric = "recursion depth";
test_stack_info.value = max_depth;
}
@@ -0,0 +1,8 @@
#ifndef _TEST_STACK_H_
#define _TEST_STACK_H_
#include "tests.h"
void test_stack( test_info_t** info );
#endif // _TEST_STACK_H_
@@ -0,0 +1,30 @@
#include "tests.h"
test_fn tests[] = {
test_stack,
test_heap,
// test_fail,
// test_pass,
NULL, // NULL terminates the list
};
// test definitions
void test_fail( test_info_t** info ){
static test_info_t test_fail_info;
static char* test_fail_name = "Fail Test";
test_fail_info.name = test_fail_name;
test_fail_info.metric = "success";
test_fail_info.value = 0;
*(info) = &test_fail_info;
}
void test_pass( test_info_t** info ){
static test_info_t test_pass_info;
static char* test_pass_name = "Pass Test";
test_pass_info.name = test_pass_name;
test_pass_info.metric = "success";
test_pass_info.value = 1;
*(info) = &test_pass_info;
}
@@ -0,0 +1,18 @@
// test definitions
#ifndef _TESTS_H_
#define _TESTS_H_
#include "test_framework.h"
// included tests
#include "test_stack.h"
#include "test_heap.h"
// simple tests
void test_fail( test_info_t** info );
void test_pass( test_info_t** info );
// list of tests to run
extern test_fn tests[];
#endif // _TESTS_H_
@@ -0,0 +1,405 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := lis2dh12_accelerometer_uart
COMPILERNAME := gcc
PROJECT := $(TARGET)_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+= -I$(COMMONPATH)/third_party/lis2dh12
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.c
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_id.c
SRC+= am_util_stdio.c
SRC+= lis2dh12_reg.c
SRC+= lis2dh12_platform_apollo3.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/examples/lis2dh12_accelerometer_uart
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+= $(COMMONPATH)/third_party/lis2dh12
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,174 @@
/*
Copyright (c) 2019 SparkFun Electronics
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
#include "lis2dh12_platform_apollo3.h"
//
// Defines
#define LOOP_DELAY_MS 0
//
// Function Declarations
uint32_t initAccel( void );
//
// Global Variables
axis3bit16_t data_raw_acceleration;
axis1bit16_t data_raw_temperature;
float acceleration_mg[3];
float temperature_degC;
lis2dh12_platform_apollo3_if_t dev_if = {
.iomHandle = NULL, // Needs to be initialized later
.addCS = AM_BSP_ACCELEROMETER_I2C_ADDRESS, // Gets the accelerometer I2C address for the board
.useSPI = false, // Using I2C in this example
};
lis2dh12_ctx_t dev_ctx = {
.write_reg = lis2dh12_write_platform_apollo3, // write bytes function
.read_reg = lis2dh12_read_platform_apollo3, // read bytes function
.handle = (void*)&dev_if, // Apollo3-specific interface information
};
int main( void ){
uint32_t stat = AM_HAL_STATUS_SUCCESS;
// Board-agnostic setup
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
// Board-specific setup
am_bsp_low_power_init();
am_bsp_uart_printf_enable();
// Clear UART terminal
am_util_stdio_terminal_clear();
// Initialize accelerometer (uses board-specific code -- see function below)
stat = initAccel();
if( stat != 0 ){
am_util_stdio_printf("Accelerometer initialization failed with code: %d\n", stat);
}
am_util_stdio_printf("Accelerometer initialization successful");
while(1){
lis2dh12_reg_t reg;
// Check if accelerometer is ready with new temperature data
lis2dh12_temp_data_ready_get(&dev_ctx, &reg.byte);
if (reg.byte) {
/* Read temperature data */
lis2dh12_temperature_raw_get(&dev_ctx, data_raw_temperature.u8bit);
/* Convert to celsius */
temperature_degC = lis2dh12_from_lsb_hr_to_celsius(data_raw_temperature.i16bit);
}
// Check if accelerometer is ready with new acceleration data
lis2dh12_xl_data_ready_get(&dev_ctx, &reg.byte);
if (reg.byte){
/* Read acceleration data */
lis2dh12_acceleration_raw_get(&dev_ctx, data_raw_acceleration.u8bit);
/* convert to mg */
acceleration_mg[0] = lis2dh12_from_fs2_hr_to_mg(data_raw_acceleration.i16bit[0]);
acceleration_mg[1] = lis2dh12_from_fs2_hr_to_mg(data_raw_acceleration.i16bit[1]);
acceleration_mg[2] = lis2dh12_from_fs2_hr_to_mg(data_raw_acceleration.i16bit[2]);
// Print results if acceleration data was ready
am_util_stdio_printf("Acc [mg] %04.2f x, %04.2f y, %04.2f z, Temp [deg C] %04.2f,\r\n",
acceleration_mg[0], acceleration_mg[1], acceleration_mg[2], temperature_degC);
}
#ifdef LOOP_DELAY_MS
#if LOOP_DELAY_MS
am_util_delay_ms(LOOP_DELAY_MS);
#endif
#endif
}
// Disable debug
am_bsp_debug_printf_disable();
// Go to Deep Sleep.
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
uint32_t initAccel( void ){
uint32_t retVal32 = 0;
static uint8_t whoamI = 0;
am_hal_iom_config_t i2cConfig = {
.eInterfaceMode = AM_HAL_IOM_I2C_MODE,
.ui32ClockFreq = AM_HAL_IOM_100KHZ,
};
// Initialize the IOM.
retVal32 = am_hal_iom_initialize(AM_BSP_ACCELEROMETER_I2C_IOM, &(dev_if.iomHandle)); // set the iomHandle of the device interface
if(retVal32 != AM_HAL_STATUS_SUCCESS){ return retVal32; }
retVal32 = am_hal_iom_power_ctrl((dev_if.iomHandle), AM_HAL_SYSCTRL_WAKE, false);
if(retVal32 != AM_HAL_STATUS_SUCCESS){ return retVal32; }
retVal32 = am_hal_iom_configure((dev_if.iomHandle), &i2cConfig);
if(retVal32 != AM_HAL_STATUS_SUCCESS){ return retVal32; }
//
// Configure the IOM pins.
am_hal_gpio_pinconfig(AM_BSP_ACCELEROMETER_I2C_SDA_PIN, g_AM_BSP_ACCELEROMETER_I2C_SDA);
am_hal_gpio_pinconfig(AM_BSP_ACCELEROMETER_I2C_SCL_PIN, g_AM_BSP_ACCELEROMETER_I2C_SCL);
//
// Enable the IOM.
//
retVal32 = am_hal_iom_enable((dev_if.iomHandle));
if(retVal32 != AM_HAL_STATUS_SUCCESS){ return retVal32; }
//
// Apply accelerometer configuration
lis2dh12_device_id_get(&dev_ctx, &whoamI);
if (whoamI != LIS2DH12_ID){
return AM_HAL_STATUS_FAIL;
}
am_util_stdio_printf("Whoami (should be 0x33): 0x%2x\n", whoamI);
lis2dh12_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
lis2dh12_temperature_meas_set(&dev_ctx, LIS2DH12_TEMP_ENABLE);
lis2dh12_data_rate_set(&dev_ctx, LIS2DH12_ODR_25Hz);
lis2dh12_full_scale_set(&dev_ctx, LIS2DH12_2g);
lis2dh12_temperature_meas_set(&dev_ctx, LIS2DH12_TEMP_ENABLE);
lis2dh12_operating_mode_set(&dev_ctx, LIS2DH12_HR_12bit);
return 0;
}
@@ -0,0 +1,24 @@
Name:
=====
pdm_fft
Description:
============
An example to show basic PDM operation.
Purpose:
========
This example enables the PDM interface to record audio signals from an
external microphone. The required pin connections are:
Printing takes place over the ITM at 1M Baud.
GPIO 10 - PDM DATA
GPIO 11 - PDM CLK
******************************************************************************
@@ -0,0 +1,403 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := pdm_fft
COMPILERNAME := gcc
PROJECT := pdm_fft_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+= -DAM_UTIL_FAULTISR_PRINT
DEFINES+= -DUNITY_INCLUDE_CONFIG_H
DEFINES+= -D__FPU_PRESENT
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.c
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_stdio.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/examples/pdm_fft
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+= $(SDKPATH)/CMSIS/ARM/Lib/ARM/libarm_cortexM4lf_math.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,389 @@
//*****************************************************************************
//
//! @file pdm_fft.c
//!
//! @brief An example to show basic PDM operation.
//!
//! Purpose: This example enables the PDM interface to record audio signals from an
//! external microphone. The required pin connections are:
//!
//! Printing takes place over the ITM at 1M Baud.
//!
//! GPIO 10 - PDM DATA
//! GPIO 11 - PDM CLK
//
//*****************************************************************************
//*****************************************************************************
//
// Copyright (c) 2019, 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 v2.2.0-7-g63f7c2ba1 of the AmbiqSuite Development Package.
//
//*****************************************************************************
#define ARM_MATH_CM4
#include <arm_math.h>
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
//*****************************************************************************
//
// Example parameters.
//
//*****************************************************************************
#define PDM_FFT_SIZE 4096
#define PDM_FFT_BYTES (PDM_FFT_SIZE * 2)
#define PRINT_PDM_DATA 0
#define PRINT_FFT_DATA 0
//*****************************************************************************
//
// Global variables.
//
//*****************************************************************************
volatile bool g_bPDMDataReady = false;
uint32_t g_ui32PDMDataBuffer[PDM_FFT_SIZE];
float g_fPDMTimeDomain[PDM_FFT_SIZE * 2];
float g_fPDMFrequencyDomain[PDM_FFT_SIZE * 2];
float g_fPDMMagnitudes[PDM_FFT_SIZE * 2];
uint32_t g_ui32SampleFreq;
//*****************************************************************************
//
// PDM configuration information.
//
//*****************************************************************************
void *PDMHandle;
am_hal_pdm_config_t g_sPdmConfig =
{
.eClkDivider = AM_HAL_PDM_MCLKDIV_1,
.eLeftGain = AM_HAL_PDM_GAIN_0DB,
.eRightGain = AM_HAL_PDM_GAIN_0DB,
.ui32DecimationRate = 64,
.bHighPassEnable = 0,
.ui32HighPassCutoff = 0xB,
.ePDMClkSpeed = AM_HAL_PDM_CLK_6MHZ,
.bInvertI2SBCLK = 0,
.ePDMClkSource = AM_HAL_PDM_INTERNAL_CLK,
.bPDMSampleDelay = 0,
.bDataPacking = 1,
.ePCMChannels = AM_BSP_PDM_CHANNEL,
.ui32GainChangeDelay = 1,
.bI2SEnable = 0,
.bSoftMute = 0,
.bLRSwap = 0,
};
//*****************************************************************************
//
// PDM initialization.
//
//*****************************************************************************
void
pdm_init(void)
{
//
// Initialize, power-up, and configure the PDM.
//
am_hal_pdm_initialize(0, &PDMHandle);
am_hal_pdm_power_control(PDMHandle, AM_HAL_PDM_POWER_ON, false);
am_hal_pdm_configure(PDMHandle, &g_sPdmConfig);
am_hal_pdm_enable(PDMHandle);
//
// Configure the necessary pins.
//
am_hal_gpio_pinconfig(AM_BSP_PDM_DATA_PIN, g_AM_BSP_PDM_DATA);
am_hal_gpio_pinconfig(AM_BSP_PDM_CLOCK_PIN, g_AM_BSP_PDM_CLOCK);
//
// Configure and enable PDM interrupts (set up to trigger on DMA
// completion).
//
am_hal_pdm_interrupt_enable(PDMHandle, (AM_HAL_PDM_INT_DERR
| AM_HAL_PDM_INT_DCMP
| AM_HAL_PDM_INT_UNDFL
| AM_HAL_PDM_INT_OVF));
NVIC_EnableIRQ(PDM_IRQn);
}
//*****************************************************************************
//
// Print PDM configuration data.
//
//*****************************************************************************
void
pdm_config_print(void)
{
uint32_t ui32PDMClk;
uint32_t ui32MClkDiv;
float fFrequencyUnits;
//
// Read the config structure to figure out what our internal clock is set
// to.
//
switch (g_sPdmConfig.eClkDivider)
{
case AM_HAL_PDM_MCLKDIV_4: ui32MClkDiv = 4; break;
case AM_HAL_PDM_MCLKDIV_3: ui32MClkDiv = 3; break;
case AM_HAL_PDM_MCLKDIV_2: ui32MClkDiv = 2; break;
case AM_HAL_PDM_MCLKDIV_1: ui32MClkDiv = 1; break;
default:
ui32MClkDiv = 0;
}
switch (g_sPdmConfig.ePDMClkSpeed)
{
case AM_HAL_PDM_CLK_12MHZ: ui32PDMClk = 12000000; break;
case AM_HAL_PDM_CLK_6MHZ: ui32PDMClk = 6000000; break;
case AM_HAL_PDM_CLK_3MHZ: ui32PDMClk = 3000000; break;
case AM_HAL_PDM_CLK_1_5MHZ: ui32PDMClk = 1500000; break;
case AM_HAL_PDM_CLK_750KHZ: ui32PDMClk = 750000; break;
case AM_HAL_PDM_CLK_375KHZ: ui32PDMClk = 375000; break;
case AM_HAL_PDM_CLK_187KHZ: ui32PDMClk = 187000; break;
default:
ui32PDMClk = 0;
}
//
// Record the effective sample frequency. We'll need it later to print the
// loudest frequency from the sample.
//
g_ui32SampleFreq = (ui32PDMClk /
(ui32MClkDiv * 2 * g_sPdmConfig.ui32DecimationRate));
fFrequencyUnits = (float) g_ui32SampleFreq / (float) PDM_FFT_SIZE;
am_util_stdio_printf("Settings:\n");
am_util_stdio_printf("PDM Clock (Hz): %12d\n", ui32PDMClk);
am_util_stdio_printf("Decimation Rate: %12d\n", g_sPdmConfig.ui32DecimationRate);
am_util_stdio_printf("Effective Sample Freq.: %12d\n", g_ui32SampleFreq);
am_util_stdio_printf("FFT Length: %12d\n\n", PDM_FFT_SIZE);
am_util_stdio_printf("FFT Resolution: %15.3f Hz\n", fFrequencyUnits);
}
//*****************************************************************************
//
// Start a transaction to get some number of bytes from the PDM interface.
//
//*****************************************************************************
void
pdm_data_get(void)
{
//
// Configure DMA and target address.
//
am_hal_pdm_transfer_t sTransfer;
sTransfer.ui32TargetAddr = (uint32_t ) g_ui32PDMDataBuffer;
sTransfer.ui32TotalCount = PDM_FFT_BYTES;
//
// Start the data transfer.
//
am_hal_pdm_enable(PDMHandle);
am_util_delay_ms(100);
am_hal_pdm_fifo_flush(PDMHandle);
am_hal_pdm_dma_start(PDMHandle, &sTransfer);
}
//*****************************************************************************
//
// PDM interrupt handler.
//
//*****************************************************************************
void
am_pdm0_isr(void)
{
uint32_t ui32Status;
//
// Read the interrupt status.
//
am_hal_pdm_interrupt_status_get(PDMHandle, &ui32Status, true);
am_hal_pdm_interrupt_clear(PDMHandle, ui32Status);
//
// Once our DMA transaction completes, we will disable the PDM and send a
// flag back down to the main routine. Disabling the PDM is only necessary
// because this example only implemented a single buffer for storing FFT
// data. More complex programs could use a system of multiple buffers to
// allow the CPU to run the FFT in one buffer while the DMA pulls PCM data
// into another buffer.
//
if (ui32Status & AM_HAL_PDM_INT_DCMP)
{
am_hal_pdm_disable(PDMHandle);
g_bPDMDataReady = true;
}
}
//*****************************************************************************
//
// Analyze and print frequency data.
//
//*****************************************************************************
void
pcm_fft_print(void)
{
float fMaxValue;
uint32_t ui32MaxIndex;
int16_t *pi16PDMData = (int16_t *) g_ui32PDMDataBuffer;
uint32_t ui32LoudestFrequency;
//
// Convert the PDM samples to floats, and arrange them in the format
// required by the FFT function.
//
for (uint32_t i = 0; i < PDM_FFT_SIZE; i++)
{
if (PRINT_PDM_DATA)
{
am_util_stdio_printf("%d\n", pi16PDMData[i]);
}
g_fPDMTimeDomain[2 * i] = pi16PDMData[i] / 1.0;
g_fPDMTimeDomain[2 * i + 1] = 0.0;
}
if (PRINT_PDM_DATA)
{
am_util_stdio_printf("END\n");
}
//
// Perform the FFT.
//
arm_cfft_radix4_instance_f32 S;
arm_cfft_radix4_init_f32(&S, PDM_FFT_SIZE, 0, 1);
arm_cfft_radix4_f32(&S, g_fPDMTimeDomain);
arm_cmplx_mag_f32(g_fPDMTimeDomain, g_fPDMMagnitudes, PDM_FFT_SIZE);
if (PRINT_FFT_DATA)
{
for (uint32_t i = 0; i < PDM_FFT_SIZE / 2; i++)
{
am_util_stdio_printf("%f\n", g_fPDMMagnitudes[i]);
}
am_util_stdio_printf("END\n");
}
//
// Find the frequency bin with the largest magnitude.
//
arm_max_f32(g_fPDMMagnitudes, PDM_FFT_SIZE / 2, &fMaxValue, &ui32MaxIndex);
ui32LoudestFrequency = (g_ui32SampleFreq * ui32MaxIndex) / PDM_FFT_SIZE;
if (PRINT_FFT_DATA)
{
am_util_stdio_printf("Loudest frequency bin: %d\n", ui32MaxIndex);
}
am_util_stdio_printf("Loudest frequency: %d \n", ui32LoudestFrequency);
}
//*****************************************************************************
//
// Main
//
//*****************************************************************************
int
main(void)
{
//
// Perform the standard initialzation for clocks, cache settings, and
// board-level low-power operation.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
//am_bsp_low_power_init();
//
// Initialize the printf interface for UART output
//
am_bsp_uart_printf_enable();
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("PDM FFT example.\n\n");
//
// Turn on the PDM, set it up for our chosen recording settings, and start
// the first DMA transaction.
//
pdm_init();
pdm_config_print();
am_hal_pdm_fifo_flush(PDMHandle);
pdm_data_get();
//
// Loop forever while sleeping.
//
while (1)
{
am_hal_interrupt_master_disable();
if (g_bPDMDataReady)
{
g_bPDMDataReady = false;
pcm_fft_print();
while (PRINT_PDM_DATA || PRINT_FFT_DATA);
//
// Start converting the next set of PCM samples.
//
pdm_data_get();
}
//
// Go to Deep Sleep.
//
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
am_hal_interrupt_master_enable();
}
}
@@ -0,0 +1,439 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := spi
COMPILERNAME := gcc
PROJECT := spi_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+= -DAM_UTIL_FAULTISR_PRINT
DEFINES+= -DUNITY_INCLUDE_CONFIG_H
DEFINES+= -D__FPU_PRESENT
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.c
SRC+= startup_gcc.c
SRC+= am_util_delay.c
SRC+= am_util_faultisr.c
SRC+= am_util_stdio.c
SRC+= am_hal_ble_patch.c
SRC+= am_hal_ble.c
SRC+= am_hal_ble_patch_b0.c
SRC+= am_hal_burst.c
SRC+= am_hal_cachectrl.c
SRC+= am_hal_adc.c
SRC+= am_hal_clkgen.c
SRC+= am_hal_cmdq.c
SRC+= am_hal_ctimer.c
SRC+= am_hal_debug.c
SRC+= am_hal_flash.c
SRC+= am_hal_global.c
SRC+= am_hal_gpio.c
SRC+= am_hal_interrupt.c
SRC+= am_hal_iom.c
SRC+= am_hal_ios.c
SRC+= am_hal_itm.c
SRC+= am_hal_mcuctrl.c
SRC+= am_hal_mspi.c
SRC+= am_hal_pdm.c
SRC+= am_hal_pwrctrl.c
SRC+= am_hal_queue.c
SRC+= am_hal_reset.c
SRC+= am_hal_rtc.c
SRC+= am_hal_scard.c
SRC+= am_hal_secure_ota.c
SRC+= am_hal_security.c
SRC+= am_hal_stimer.c
SRC+= am_hal_sysctrl.c
SRC+= am_hal_systick.c
SRC+= am_hal_tpiu.c
SRC+= am_hal_uart.c
SRC+= am_hal_wdt.c
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/examples/spi
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+= $(SDKPATH)/mcu/apollo3/hal
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+= $(SDKPATH)/CMSIS/ARM/Lib/ARM/libarm_cortexM4lf_math.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,144 @@
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
// #define ASYNCH // comment out to use blocking methods
#define IOMN (2)
#define SPI_MODE (3)
#define SPI_FREQ (AM_HAL_IOM_4MHZ)
void* iom_handle = NULL;
am_hal_iom_config_t iom_cfg = {0};
am_hal_iom_transfer_t xfer = {0};
#define CS_PIN (16)
#define report(s) am_util_stdio_printf("status: 0x%08X (function: %s, file: %s, line: %d)\n", s, __PRETTY_FUNCTION__, __FILE__, __LINE__)
volatile bool xfer_complete = false;
volatile uint32_t txn_stat = 0;
void xfer_complete_callback(void *pCallbackCtxt, uint32_t transactionStatus){
(void)pCallbackCtxt;
xfer_complete = true;
txn_stat = transactionStatus;
}
void init_iom( void ){
uint32_t status = AM_HAL_STATUS_SUCCESS;
iom_cfg.eInterfaceMode = AM_HAL_IOM_SPI_MODE;
iom_cfg.ui32ClockFreq = SPI_FREQ;
iom_cfg.eSpiMode = SPI_MODE;
iom_cfg.pNBTxnBuf = NULL;
iom_cfg.ui32NBTxnBufLength = 0;
status = am_hal_iom_initialize(IOMN, &iom_handle);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_iom_power_ctrl(iom_handle, AM_HAL_SYSCTRL_WAKE, false);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_iom_configure(iom_handle, &iom_cfg);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_iom_enable(iom_handle);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
// config pins
status = am_hal_gpio_pinconfig(AM_BSP_GPIO_IOM2_MISO, g_AM_BSP_GPIO_IOM2_MISO);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_gpio_pinconfig(AM_BSP_GPIO_IOM2_MOSI, g_AM_BSP_GPIO_IOM2_MOSI);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }
status = am_hal_gpio_pinconfig(AM_BSP_GPIO_IOM2_SCK, g_AM_BSP_GPIO_IOM2_SCK);
if(status != AM_HAL_STATUS_SUCCESS){ report(status); }\
}
//*****************************************************************************
//
// Main
//
//*****************************************************************************
int
main(void)
{
uint32_t status = AM_HAL_STATUS_SUCCESS;
//
// Perform the standard initialzation for clocks, cache settings, and
// board-level low-power operation.
//
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
am_bsp_low_power_init();
//
// Initialize the printf interface for UART output
//
am_bsp_uart_printf_enable();
//
// Print the banner.
//
am_util_stdio_terminal_clear();
am_util_stdio_printf("PDM FFT example.\n\n");
// do spi stuff
init_iom();
char cmd[2];
cmd[0] = 0xEC;
cmd[1] = 0xC3;
xfer.uPeerInfo.ui32SpiChipSelect = 0;
xfer.ui32InstrLen = 0;
xfer.ui32Instr = 0;
xfer.ui32NumBytes = 1;
xfer.eDirection = AM_HAL_IOM_TX;
xfer.pui32TxBuffer = (uint32_t*)cmd;
xfer.pui32RxBuffer = NULL;
xfer.bContinue = false;
xfer.ui8RepeatCount = 0;
xfer.ui8Priority = 1;
xfer.ui32PauseCondition = 0;
xfer.ui32StatusSetClr = 0;
#ifdef ASYNCH
status = am_hal_iom_nonblocking_transfer(iom_handle, &xfer, xfer_complete_callback, NULL);
report(status);
#else
status = am_hal_iom_blocking_transfer(iom_handle, &xfer);
report(status);
#endif
char rx_buf[10];
xfer.eDirection = AM_HAL_IOM_FULLDUPLEX;
xfer.pui32TxBuffer = (uint32_t*)cmd;
xfer.pui32RxBuffer = (uint32_t*)rx_buf;
#ifdef ASYNCH
status = am_hal_iom_nonblocking_transfer(iom_handle, &xfer, xfer_complete_callback, NULL);
report(status);
#else
status = am_hal_iom_spi_blocking_fullduplex(iom_handle, &xfer);
report(status);
#endif
while (1)
{
#ifdef ASYNCH
status = am_hal_iom_nonblocking_transfer(iom_handle, &xfer, xfer_complete_callback, NULL);
#else
status = am_hal_iom_spi_blocking_fullduplex(iom_handle, &xfer);
#endif
if(status != AM_HAL_STATUS_SUCCESS){
report(status);
}
}
}
@@ -0,0 +1,417 @@
#******************************************************************************
#
# Makefile - Rules for building the libraries, examples and docs.
#
# Copyright (c) 2019, 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.1.0 of the AmbiqSuite Development Package.
#
#******************************************************************************
#******************************************************************************
#
# This is an example makefile for SparkFun Apollo3 boards as used in the
# AmbiqSuite SDK.
#
# Recommended usage
# make
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
# make clean
#
# Filepaths
# You can relocate this makefile easily by providing the path to the root of
# the AmbiqSuite SDK. If that path is not specified then this file will
# assume that it is located in
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
# and use relative paths
#
# User Configuration
# You must also specify which COM_PORT to use if you want to use the
# 'bootlaoder' targets.
# Windows example: COM_PORT=COM4
# *nix example: COM_PORT=/dev/usbserialxxxx
#
# Python vs. Executable
# For simplicity the upload tools are called as Python scripts by default.
# Make sure PYTHON is set to the appropriate command to run Python3 from the
# command line.
#
#******************************************************************************
#******************************************************************************
#
# User Options
#
#******************************************************************************
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
COM_PORT ?=
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
ASB_UPLOAD_BAUD ?=
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
SVL_UPLOAD_BAUD ?=
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
PYTHON3 ?=
# *Optionally* specify absolute paths to the SDK and the BSP
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
# Make sure to use / instead of \ when on Windows
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
BOARDPATH ?=# Set as the path to the board if not located at ../../..
PROJECTPATH ?=# Set as the path to the project if not located at ..
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
### Project Settings
TARGET := startup_tests
COMPILERNAME := gcc
PROJECT := $(TARGET)_gcc
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
ifeq ($(BOARD),)
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
else
BOARDPATH=../../../../$(BOARD)
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
endif
ifeq ($(COM_PORT),)
COM_PORT=COM4
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
endif
ifeq ($(PYTHON3),)
PYTHON3=python3
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
endif
ifeq ($(ASB_UPLOAD_BAUD),)
ASB_UPLOAD_BAUD=115200
$(warning defaulting to 115200 baud for ASB)
endif
ifeq ($(SVL_UPLOAD_BAUD),)
SVL_UPLOAD_BAUD=921600
$(warning defaulting to 921600 baud for SVL)
endif
ifeq ($(SDKPATH),)
SDKPATH =../../../../..
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
else
# When the SDKPATH is given export it
export SDKPATH
endif
ifeq ($(COMMONPATH),)
COMMONPATH =../../../../common
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
else
# When the COMMONPATH is given export it
export COMMONPATH
endif
ifeq ($(BOARDPATH),)
$(error Error: BOARDPATH must be provided)
else
# Ensure that boardpath does not include a trailing '/'
ifeq ($(notdir $(BOARDPATH)),)
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
endif
BOARD=$(notdir $(BOARDPATH))
# When the BOARDPATH is given export it
export BOARDPATH
endif
ifeq ($(PROJECTPATH),)
PROJECTPATH =..
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
else
# When the PROJECTPATH is given export it
export PROJECTPATH
endif
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
$(warning CONFIG=$(CONFIG))
#******************************************************************************
#
# User Defines / Includes / Sources / Libraries
#
#******************************************************************************
# Global Defines
DEFINES= -DPART_$(PART)
DEFINES+= -DAM_CUSTOM_BDADDR
DEFINES+= -DAM_PACKAGE_BGA
DEFINES+= -DWSF_TRACE_ENABLED
DEFINES+= -DAM_DEBUG_PRINTF
DEFINES+= -DAM_PART_APOLLO3
DEFINES+=
# Includes (Add paths to where example header files are located)
INCLUDES=
INCLUDES+= -I$(PROJECTPATH)/src
INCLUDES+= -I$(BOARDPATH)/bsp
INCLUDES+= -I$(SDKPATH)
INCLUDES+= -I$(SDKPATH)/utils
INCLUDES+= -I$(SDKPATH)/devices
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
INCLUDES+= -I$(COMMONPATH)/examples/startup_tests
INCLUDES+= -I$(COMMONPATH)/examples/startup_tests/test_framework
INCLUDES+= -I$(COMMONPATH)/examples/startup_tests/tests
INCLUDES+= -I$(COMMONPATH)/examples/startup_tests/tests/data
INCLUDES+= -I$(COMMONPATH)/examples/startup_tests/tests/bss
INCLUDES+= -I$(COMMONPATH)/examples/startup_tests/tests/constructors
INCLUDES+= -I$(COMMONPATH)/examples/startup_tests/tests/fn_init
INCLUDES+=
# Compilation Units (Add all the .c files you need to compile)
SRC=
SRC+= main.cpp
SRC+= am_util_stdio.c
SRC+= startup_gcc.c
SRC+= test_framework.cpp
SRC+= tests.cpp
SRC+= test_data.cpp
SRC+= test_bss.cpp
SRC+= test_constructors.cpp
SRC+= test_fn_init.cpp
SRC+=
# VPATH (Add paths to where your source files are located)
VPATH=
VPATH+= $(PROJECTPATH)/src
VPATH+= $(SDKPATH)/utils
VPATH+= $(COMMONPATH)/tools_sfe/templates
VPATH+= $(COMMONPATH)/examples/startup_tests
VPATH+= $(COMMONPATH)/examples/startup_tests/test_framework
VPATH+= $(COMMONPATH)/examples/startup_tests/tests
VPATH+= $(COMMONPATH)/examples/startup_tests/tests/data
VPATH+= $(COMMONPATH)/examples/startup_tests/tests/bss
VPATH+= $(COMMONPATH)/examples/startup_tests/tests/constructors
VPATH+= $(COMMONPATH)/examples/startup_tests/tests/fn_init
VPATH+=
# LIBS (Precompiled libraries to include in the linker step)
LIBS=
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
LIBS+=
#******************************************************************************
#
# Warning Messages
#
#******************************************************************************
### Bootloader Tools
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
SHELL:=/bin/bash
#### Setup ####
TOOLCHAIN ?= arm-none-eabi
PART = apollo3
CPU = cortex-m4
FPU = fpv4-sp-d16
# Default to FPU hardware calling convention. However, some customers and/or
# applications may need the software calling convention.
#FABI = softfp
FABI = hard
STARTUP_FILE := ./startup_$(COMPILERNAME).c
#### Required Executables ####
CC = $(TOOLCHAIN)-gcc
GCC = $(TOOLCHAIN)-gcc
CPP = $(TOOLCHAIN)-cpp
CXX = $(TOOLCHAIN)-g++
LD = $(TOOLCHAIN)-ld
CP = $(TOOLCHAIN)-objcopy
OD = $(TOOLCHAIN)-objdump
RD = $(TOOLCHAIN)-readelf
AR = $(TOOLCHAIN)-ar
SIZE = $(TOOLCHAIN)-size
RM = $(shell which rm 2>/dev/null)
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $($(exec)) 2>/dev/null),,\
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
ifneq ($(strip $(value K)),)
all clean:
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
$(RM) -rf bin
else
#******************************************************************************
#
# Machinery
#
#******************************************************************************
XSRC = $(filter %.cpp,$(SRC))
ZSRC = $(filter %.cc,$(SRC))
CSRC = $(filter %.c,$(SRC))
ASRC = $(filter %.s,$(SRC))
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
CSTD = -std=c99
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
CFLAGS+= -ffunction-sections -fdata-sections
CFLAGS+= -MMD -MP -Wall -g
CFLAGS+= -O0
CFLAGS+= $(DEFINES)
CFLAGS+= $(INCLUDES)
CFLAGS+=
XSTD = -std=gnu++11
XFLAGS = $(CFLAGS)
XFLAGS+= -fno-exceptions -fno-threadsafe-statics # added -fno-threadsafe-statics to allow static local contructors
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
LFLAGS+= -nostartfiles -static
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
LFLAGS+=
# Additional user specified CFLAGS
CFLAGS+=$(EXTRA_CFLAGS)
CPFLAGS = -Obinary
ODFLAGS = -S
#******************************************************************************
#
# Targets / Rules
#
#******************************************************************************
all: asb
asb: directories $(CONFIG)/$(TARGET)_asb.bin
svl: directories $(CONFIG)/$(TARGET)_svl.bin
directories:
@mkdir -p $(CONFIG)
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
@echo " Compiling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
@echo " Assembling $(COMPILERNAME) $<" ;\
$(CC) -c $(CFLAGS) $< -o $@
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
@echo " Copying $(COMPILERNAME) $@..." ;\
$(CP) $(CPFLAGS) $< $@ ;\
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
bootload: bootload_svl
clean:
@echo "Cleaning..." ;\
$(RM) -f $(OBJS) $(DEPS) \
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
$(CONFIG)/%.d: ;
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
$(MAKE) -C $(SDKPATH)/third_party/uecc
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
$(MAKE) -C $(BOARDPATH)/bsp/gcc
# Automatically include any generated dependencies
-include $(DEPS)
endif
.PHONY: all clean directories bootload bootload_asb bootload_svl
@@ -0,0 +1,44 @@
/*
Tests / verifies startup
Checks:
- data segment copy
- bss segment zero-fill
- C++ global static constructor initialization
*/
#include "main.h"
#include "test_framework.h"
#include "tests.h"
// main
int main()
{
// Setup system clocks
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
// Set the default cache configuration
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();
// Configure the board for low power operation.
am_bsp_low_power_init();
// Enable the UART print interface.
am_bsp_uart_printf_enable();
// Clear the terminal and print the banner.
am_util_stdio_terminal_clear();
am_util_stdio_printf("Startup Tests\n");
am_util_stdio_printf("=============\n");
am_util_stdio_printf("\n");
// run tests
run_tests(tests);
// Loop forever while sleeping.
while (1){
// Go to Deep Sleep.
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
}
}
@@ -0,0 +1,9 @@
#ifndef _MAIN_H_
#define _MAIN_H_
#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
#include <stdbool.h>
#endif // _MAIN_H_
@@ -0,0 +1,17 @@
#include "test_framework.h"
void print_test_info( test_info_t* info ){
am_util_stdio_printf("Test Name: %s\n", (info->name != NULL) ? info->name : "N/A");
am_util_stdio_printf("==========\n");
am_util_stdio_printf("status: %s\n", (info->passed) ? "passed" : "failed" );
am_util_stdio_printf("\n");
}
void run_tests(test_fn* tests){
test_info_t* info;
while(*tests != NULL){
(*tests)(&info);
print_test_info(info);
tests++;
}
am_util_stdio_printf("\n\nAll tests complete\n");
}
@@ -0,0 +1,15 @@
#ifndef _TEST_FRAMEWORK_H_
#define _TEST_FRAMEWORK_H_
#include "main.h"
#include <stdlib.h>
typedef struct _test_info_t {
char* name;
bool passed;
} test_info_t;
typedef void (*test_fn)( test_info_t** info );
void print_test_info( test_info_t* info );
void run_tests(test_fn* tests);
#endif // _TEST_FRAMEWORK_H_
@@ -0,0 +1,21 @@
#include "test_bss.h"
#define BYTES_TO_FILL 64
char bss_1[BYTES_TO_FILL];
char bss_2[BYTES_TO_FILL] = {0};
//
// test_bss
void test_bss( test_info_t** info ){
static test_info_t test_bss_info;
static char* test_bss_name = "BSS Zereo Fill";
test_bss_info.name = test_bss_name;
test_bss_info.passed = true;
*(info) = &test_bss_info;
for(size_t ix = 0; ix < BYTES_TO_FILL; ix++){
if(bss_1[ix] != 0){ test_bss_info.passed = false; }
if(bss_2[ix] != 0){ test_bss_info.passed = false; }
}
}
@@ -0,0 +1,8 @@
#ifndef _TEST_BSS_H_
#define _TEST_BSS_H_
#include "tests.h"
void test_bss( test_info_t** info );
#endif // _TEST_BSS_H_
@@ -0,0 +1,41 @@
#include "test_constructors.h"
#define STATE1 0x00
#define STATE2 0x01
#define STATE3 0xDD
#define STATE4 0xCC
/* A very simple class to test constructor execution */
class LEDSTATE {
private:
protected:
public:
uint8_t state; // Trivial initialization is 0
LEDSTATE(uint8_t init);
};
LEDSTATE::LEDSTATE(uint8_t init){
state=init;
}
// This object should be initialized with a non-zero state
LEDSTATE state1(STATE1);
LEDSTATE state2(STATE2);
LEDSTATE state3(STATE3);
//
// test_constructors
void test_constructors( test_info_t** info ){
static LEDSTATE state4(STATE4);
static test_info_t test_constructors_info;
static char* test_constructors_name = "Global / Static Constructors";
test_constructors_info.name = test_constructors_name;
test_constructors_info.passed = true;
*(info) = &test_constructors_info;
if(state1.state != STATE1){ test_constructors_info.passed = false; }
if(state2.state != STATE2){ test_constructors_info.passed = false; }
if(state3.state != STATE3){ test_constructors_info.passed = false; }
if(state4.state != STATE4){ test_constructors_info.passed = false; }
}
@@ -0,0 +1,8 @@
#ifndef _TEST_CONSTRUCTORS_H_
#define _TEST_CONSTRUCTORS_H_
#include "tests.h"
void test_constructors( test_info_t** info );
#endif // _TEST_CONSTRUCTORS_H_
@@ -0,0 +1,99 @@
#include "test_data.h"
#define BYTES_TO_COPY 8
// Automatially add some variables that won't be optimized
// away to fill up the number of requested bytes
#ifdef BYTES_TO_COPY
#if BYTES_TO_COPY > 0
#define VAR11 0xDE
#endif
#if BYTES_TO_COPY > 1
#define VAR12 0xAD
#endif
#if BYTES_TO_COPY > 2
#define VAR13 0xBE
#endif
#if BYTES_TO_COPY > 3
#define VAR14 0xEF
#endif
#if BYTES_TO_COPY > 4
#define VAR21 0xC0
#endif
#if BYTES_TO_COPY > 5
#define VAR22 0xFE
#endif
#if BYTES_TO_COPY > 6
#define VAR23 0xE6
#endif
#if BYTES_TO_COPY > 7
#define VAR24 0x0D
#endif
#endif // BYTES_TO_COPY
#ifdef BYTES_TO_COPY
static volatile char data[] = {
#if BYTES_TO_COPY > 0
VAR11,
#endif
#if BYTES_TO_COPY > 1
VAR12,
#endif
#if BYTES_TO_COPY > 2
VAR13,
#endif
#if BYTES_TO_COPY > 3
VAR14,
#endif
#if BYTES_TO_COPY > 4
VAR21,
#endif
#if BYTES_TO_COPY > 5
VAR22,
#endif
#if BYTES_TO_COPY > 6
VAR23,
#endif
#if BYTES_TO_COPY > 7
VAR24,
#endif
};
#endif // BYTES_TO_COPY
//
// test_data
void test_data( test_info_t** info ){
static test_info_t test_data_info;
static char* test_data_name = "Data Segment Copy";
test_data_info.name = test_data_name;
test_data_info.passed = true;
*(info) = &test_data_info;
// Verify that all bytes were copied into RAM correctly
#ifdef BYTES_TO_COPY
#if BYTES_TO_COPY > 0
if( data[0] != VAR11 ){ test_data_info.passed = false; }
#endif
#if BYTES_TO_COPY > 1
if( data[1] != VAR12 ){ test_data_info.passed = false; }
#endif
#if BYTES_TO_COPY > 2
if( data[2] != VAR13 ){ test_data_info.passed = false; }
#endif
#if BYTES_TO_COPY > 3
if( data[3] != VAR14 ){ test_data_info.passed = false; }
#endif
#if BYTES_TO_COPY > 4
if( data[4] != VAR21 ){ test_data_info.passed = false; }
#endif
#if BYTES_TO_COPY > 5
if( data[5] != VAR22 ){ test_data_info.passed = false; }
#endif
#if BYTES_TO_COPY > 6
if( data[6] != VAR23 ){ test_data_info.passed = false; }
#endif
#if BYTES_TO_COPY > 7
if( data[7] != VAR24 ){ test_data_info.passed = false; }
#endif
#endif // BYTES_TO_COPY
}
@@ -0,0 +1,8 @@
#ifndef _TEST_DATA_H_
#define _TEST_DATA_H_
#include "tests.h"
void test_data( test_info_t** info );
#endif // _TEST_DATA_H_
@@ -0,0 +1,21 @@
#include "test_fn_init.h"
#define VAL 0xFA
char init_fn( void ){
return VAL;
}
char var = init_fn();
//
// test_fn_init
void test_fn_init( test_info_t** info ){
static test_info_t test_fn_init_info;
static char* test_fn_init_name = "Initialization of Global by Function";
test_fn_init_info.name = test_fn_init_name;
test_fn_init_info.passed = true;
*(info) = &test_fn_init_info;
if( var != VAL ){ test_fn_init_info.passed = false; }
}
@@ -0,0 +1,8 @@
#ifndef _TEST_FN_INIT_H_
#define _TEST_FN_INIT_H_
#include "tests.h"
void test_fn_init( test_info_t** info );
#endif // _TEST_FN_INIT_H_
@@ -0,0 +1,30 @@
#include "tests.h"
test_fn tests[] = {
test_data,
test_bss,
test_constructors,
test_fn_init,
// test_fail,
// test_pass,
NULL, // NULL terminates the list
};
// test definitions
void test_fail( test_info_t** info ){
static test_info_t test_fail_info;
static char* test_fail_name = "Fail Test";
test_fail_info.name = test_fail_name;
test_fail_info.passed = false;
*(info) = &test_fail_info;
}
void test_pass( test_info_t** info ){
static test_info_t test_pass_info;
static char* test_pass_name = "Pass Test";
test_pass_info.name = test_pass_name;
test_pass_info.passed = true;
*(info) = &test_pass_info;
}
@@ -0,0 +1,20 @@
// test definitions
#ifndef _TESTS_H_
#define _TESTS_H_
#include "test_framework.h"
// included tests
#include "test_data.h"
#include "test_bss.h"
#include "test_constructors.h"
#include "test_fn_init.h"
// simple tests
void test_fail( test_info_t** info );
void test_pass( test_info_t** info );
// list of tests to run
extern test_fn tests[];
#endif // _TESTS_H_