initial commit
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
How to Regenerate Existing BSPs
|
||||
===============================
|
||||
After making changes to the BSP source files (```am_bsp.h```, ```am_bsp.c```, and ```bsp_pins.src```) you will still need to ensure that the ```libam_bsp.a``` archive is updated to reflect this (if this file exists then the build process simply uses it instead of compiling BSP sources). The simplest way is to navigate to the root of this repo and run ```./common/tools_sfe/scripts/regen_bsps.sh```
|
||||
|
||||
**all these automated methods rely on this repo being placed in the root directory of the AmbiqSuite SDK (alternately you may employ an environment variable {$AMSDK} pointing at the root) and having the prerequisite tools available**
|
||||
|
||||
How to Generate New BSP Files
|
||||
=============================
|
||||
|
||||
A Board Support Package is designed to provide a uniform interface to the hardware capabilities across boards, thus enabling users to easily identify what hardware is being used and increasing the compatibility of example applications.
|
||||
|
||||
To do so the BSP provides a listing of pin names and corresponding pin configurations, as well as several uniform API calls.
|
||||
|
||||
|
||||
am_bsp_pins.h + am_bsp_pins.c
|
||||
=============================
|
||||
|
||||
These files are used to create named configurations (and pins numbers) that represent what's on the board. The files are automatically generated by the ```pinconfig.py``` script. This uses pin definitions that the user sets up in the ```bsp_pins.src``` file which helps reduce maintenance effort. An example usage is (from the root directory of this repo):
|
||||
|
||||
```bash
|
||||
python common/bsp_pinconfig/pinconfig.py ${board}/bsp/bsp_pins.src ${selector} > ${board}/bsp/am_bsp_pins.${selector}
|
||||
```
|
||||
Where ```${board}``` is the directory for the board whose BSP is being generated and ```${selector}``` is one of ```c``` or ```h``` (which tells the script which file to generate)
|
||||
|
||||
|
||||
am_bsp.h + am_bsp.c
|
||||
===================
|
||||
|
||||
This compilation unit uses the pin definitions (above) to describe the common interface. It has a standard structure and contents, but it is also possible to add additional board-specific macros.
|
||||
|
||||
**The Header**
|
||||
The header is standardized and changes to it should be minimal
|
||||
Includes:
|
||||
- License + Copyright
|
||||
- Include guards (opening)
|
||||
- Includes
|
||||
- stdint
|
||||
- stdbool
|
||||
- am_mcu_apollo
|
||||
- am_bsp_pins
|
||||
- am_devices_led
|
||||
- am_devices_button
|
||||
- C++ guards (opening)
|
||||
|
||||
``` c
|
||||
//*****************************************************************************
|
||||
//
|
||||
// am_bsp.h
|
||||
//! @file
|
||||
//!
|
||||
//! @brief Functions to aid with configuring the GPIOs.
|
||||
//!
|
||||
//! @addtogroup BSP Board Support Package (BSP)
|
||||
//! @addtogroup apollo3_fpga_bsp BSP for the Apollo3 Hotshot FPGA
|
||||
//! @ingroup BSP
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// 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.0.0 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef AM_BSP_H
|
||||
#define AM_BSP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "am_bsp_pins.h"
|
||||
|
||||
//
|
||||
// Make individual includes to not require full port before usage.
|
||||
//#include "am_devices.h"
|
||||
//
|
||||
#include "am_devices_led.h"
|
||||
#include "am_devices_button.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Begin User Modifiable Area
|
||||
//
|
||||
//*****************************************************************************
|
||||
```
|
||||
|
||||
**The User Modifiable Area**
|
||||
Contents of this section are free reign. Nothing is required. Possible elements include:
|
||||
- Aliases for pin names
|
||||
- Definitions for HW not captured by the bsp_pins.src file
|
||||
|
||||
**Print Interface Area**
|
||||
Todo: explain what this area is about
|
||||
```c
|
||||
//*****************************************************************************
|
||||
//
|
||||
// End User Modifiable Area
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Print interface type
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AM_BSP_PRINT_INFC_NONE 0
|
||||
#define AM_BSP_PRINT_INFC_SWO 1
|
||||
#define AM_BSP_PRINT_INFC_UART0 2
|
||||
#define AM_BSP_PRINT_INFC_BUFFERED_UART0 3
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Structure containing UART configuration information while it is powered down.
|
||||
//
|
||||
//*****************************************************************************
|
||||
typedef struct
|
||||
{
|
||||
bool bSaved;
|
||||
uint32_t ui32TxPinNum;
|
||||
uint32_t ui32TxPinCfg;
|
||||
}
|
||||
am_bsp_uart_pwrsave_t;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// External data definitions.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern am_bsp_uart_pwrsave_t am_bsp_uart_pwrsave[AM_REG_UART_NUM_MODULES];
|
||||
|
||||
```
|
||||
|
||||
**The API Area**
|
||||
This area declares standard bsp functions that are used across AmbiqSuite examples. It is best to attempt to implement these functions in ```am_bsp.c```.
|
||||
```c
|
||||
//*****************************************************************************
|
||||
//
|
||||
// External function definitions.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void am_bsp_low_power_init(void);
|
||||
extern void am_bsp_iom_pins_enable(uint32_t ui32Module, am_hal_iom_mode_e eIOMMode);
|
||||
extern void am_bsp_iom_pins_disable(uint32_t ui32Module, am_hal_iom_mode_e eIOMMode);
|
||||
extern void am_bsp_mspi_pins_enable(am_hal_mspi_device_e eMSPIDevice);
|
||||
extern void am_bsp_mspi_pins_disable(am_hal_mspi_device_e eMSPIDevice);
|
||||
|
||||
extern void am_bsp_ios_pins_enable(uint32_t ui32Module, uint32_t ui32IOSMode); // SparkFun Edge does not expose IO Slave Clock signal, so hiding these functions
|
||||
extern void am_bsp_ios_pins_disable(uint32_t ui32Module, uint32_t ui32IOSMode);
|
||||
|
||||
extern void am_bsp_debug_printf_enable(void);
|
||||
extern void am_bsp_debug_printf_disable(void);
|
||||
|
||||
#ifdef AM_BSP_GPIO_ITM_SWO
|
||||
extern void am_bsp_itm_printf_enable(void);
|
||||
#else
|
||||
extern void am_bsp_itm_printf_enable(uint32_t ui32Pin, am_hal_gpio_pincfg_t sPincfg);
|
||||
#endif
|
||||
extern void am_bsp_itm_string_print(char *pcString);
|
||||
extern void am_bsp_itm_printf_disable(void);
|
||||
|
||||
extern void am_bsp_uart_string_print(char *pcString);
|
||||
extern void am_bsp_uart_printf_enable(void);
|
||||
extern void am_bsp_uart_printf_enable_custom(const am_hal_uart_config_t* p_config);
|
||||
extern void am_bsp_uart_printf_disable(void);
|
||||
|
||||
extern void am_bsp_buffered_uart_printf_enable(void);
|
||||
extern void am_bsp_buffered_uart_service(void);
|
||||
|
||||
extern uint32_t am_bsp_com_uart_transfer(const am_hal_uart_transfer_t *psTransfer);
|
||||
```
|
||||
|
||||
**The Footer**
|
||||
The footer just wraps it all up
|
||||
```c
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AM_BSP_H
|
||||
//*****************************************************************************
|
||||
//
|
||||
// End Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
```
|
||||
+653
@@ -0,0 +1,653 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# pinconfig.py
|
||||
#
|
||||
# @brief Script for generating a BSP pin file.
|
||||
|
||||
# *****************************************************************************
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# 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.2.0-hotfix-2.2.1 of the AmbiqSuite Development Package.
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
# *****************************************************************************
|
||||
# Imported modules
|
||||
# *****************************************************************************
|
||||
import argparse
|
||||
import textwrap
|
||||
import os.path
|
||||
import rsonlite
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
# Templates
|
||||
# *****************************************************************************
|
||||
filetemplateC = '''
|
||||
//*****************************************************************************
|
||||
//
|
||||
// {filename}
|
||||
//! @file
|
||||
//!
|
||||
//! @brief BSP pin configuration definitions.
|
||||
//!
|
||||
//! @addtogroup BSP Board Support Package (BSP)
|
||||
//! @addtogroup apollo3_evb_bsp BSP for the Apollo3 Engineering Board
|
||||
//! @ingroup BSP
|
||||
//! @{{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// 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.2.0-hotfix-2.2.1 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include "am_bsp.h"
|
||||
{pin_defs}
|
||||
//*****************************************************************************
|
||||
//
|
||||
// End Doxygen group.
|
||||
//! @}}
|
||||
//
|
||||
//*****************************************************************************
|
||||
'''.strip()
|
||||
|
||||
|
||||
filetemplateH = '''
|
||||
//*****************************************************************************
|
||||
//
|
||||
// {filename}
|
||||
//! @file
|
||||
//!
|
||||
//! @brief BSP pin configuration definitions.
|
||||
//!
|
||||
//! @addtogroup BSP Board Support Package (BSP)
|
||||
//! @addtogroup apollo3_bsp BSP for the Apollo3 EVB.
|
||||
//! @ingroup BSP
|
||||
//! @{{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// 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.2.0-hotfix-2.2.1 of the AmbiqSuite Development Package.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef {headerdef}
|
||||
#define {headerdef}
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "am_mcu_apollo.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{{
|
||||
#endif
|
||||
{pin_defs}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}}
|
||||
#endif
|
||||
|
||||
#endif // {headerdef}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// End Doxygen group.
|
||||
//! @}}
|
||||
//
|
||||
//*****************************************************************************
|
||||
'''.strip()
|
||||
|
||||
|
||||
sectiontemplate = '''
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// {pin_descr}
|
||||
//
|
||||
//*****************************************************************************
|
||||
'''.strip()
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# Globals
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# Command line support.
|
||||
#
|
||||
# *****************************************************************************
|
||||
def read_arguments():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('input', help='input src file name')
|
||||
parser.add_argument('CorH', help='C to create C file, H to create H file',
|
||||
choices=['C','H','c','h'])
|
||||
parser.add_argument('-g', '--guard', dest='headerdef', required=False, default='AM_BSP_PINS_H', help='optional string to use for header include guards - defaults to AM_BSP_PINS_H')
|
||||
parser.add_argument('-p', '--prefix', dest='prefix', required=False, default='AM_BSP_GPIO', help='optional string with which to prefix names - defaults to AM_BSP')
|
||||
parser.add_argument('-b', '--bgaguard', dest='bgaguard', required=False, default=None, help='if provided this script will place preprocessor guards around pins that only exist on the BGA package using the provided string as the check value')
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
# *****************************************************************************
|
||||
# parse_input()
|
||||
# *****************************************************************************
|
||||
def parse_input(filename):
|
||||
'''
|
||||
Simple wrapper to pull an rsonlite list from given file.
|
||||
'''
|
||||
with open(filename) as f:
|
||||
data = f.read()
|
||||
return rsonlite.loads(data)
|
||||
|
||||
# *****************************************************************************
|
||||
# list_to_dict()
|
||||
# *****************************************************************************
|
||||
def list_to_dict(L):
|
||||
'''
|
||||
rsonlite loads data from the rson files as a very-nested list. This
|
||||
function converts that list to a set of nested dictionaries. At each level,
|
||||
the dictionary keys correspond to the "headings", and the dictionary values
|
||||
are a list of the items under that "heading". Values assigned by
|
||||
equals-sign statements are (unfortunately) also converted to (key, list)
|
||||
pairs, the same way that subheadings are.
|
||||
'''
|
||||
if len(L) == 1:
|
||||
return L[0]
|
||||
else:
|
||||
D = dict()
|
||||
for x in L:
|
||||
if x[0] in D:
|
||||
D[x[0]] = D[x[0]] + [list_to_dict(x[1])]
|
||||
else:
|
||||
D[x[0]] = [list_to_dict(x[1])]
|
||||
return D
|
||||
|
||||
# *****************************************************************************
|
||||
# get_val()
|
||||
# *****************************************************************************
|
||||
def get_val(name, D):
|
||||
'''
|
||||
get_val is just a helper to make it more obvious when you are trying to get
|
||||
at an equals-sign-assigned value from the rson file dictionary.
|
||||
'''
|
||||
if name not in D:
|
||||
return "ERROR: {} VALUE MISSING".format(name)
|
||||
else:
|
||||
return D[name][0]
|
||||
|
||||
# *****************************************************************************
|
||||
# get_pinobj()
|
||||
# *****************************************************************************
|
||||
def get_pinobj(filename):
|
||||
'''
|
||||
Given the filename of an 'src' file, this function will return a 'pin'
|
||||
object corresponding to the fields described in the src file.
|
||||
'''
|
||||
|
||||
# Set the location for the supplementary files (infoblock, base addresses, etc.)
|
||||
srcdir = os.path.dirname(filename)
|
||||
|
||||
# Read in the contents of the src file, and use the rsonlite library to
|
||||
# parse them into a list.
|
||||
rson_data = parse_input(filename)
|
||||
|
||||
# Convert the list to a dictionary.
|
||||
rson_dict = list_to_dict(rson_data)
|
||||
|
||||
# Convert the dictionary to a block object, which will create field
|
||||
# objects as necessary. Return this object to the caller.
|
||||
return pinobj(rson_dict)
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
# pinfields
|
||||
# *****************************************************************************
|
||||
class pinfields:
|
||||
def __init__(self, pindict):
|
||||
|
||||
self.name = ''
|
||||
self.desc = ''
|
||||
self.pinnum = 0
|
||||
self.powersw = ''
|
||||
self.pullup = ''
|
||||
self.func_sel = ''
|
||||
self.drvstrength = 0
|
||||
self.intdir = 0
|
||||
self.GPOutcfg = ''
|
||||
self.GPinput = ''
|
||||
self.GPRdZero = ''
|
||||
self.IOMnum = ''
|
||||
self.CEnum = ''
|
||||
self.CEpol = ''
|
||||
self.bIomMSPIn = ''
|
||||
|
||||
intnotgiven = 65535
|
||||
strnotgiven = 'none_given'
|
||||
|
||||
if 'name' in pindict:
|
||||
self.name = get_val('name', pindict)
|
||||
else:
|
||||
self.name = strnotgiven
|
||||
|
||||
if 'desc' in pindict:
|
||||
self.desc = get_val('desc', pindict)
|
||||
else:
|
||||
self.desc = strnotgiven
|
||||
|
||||
if 'pinnum' in pindict:
|
||||
self.pinnum = int(get_val('pinnum', pindict))
|
||||
else:
|
||||
self.pinnum = intnotgiven
|
||||
|
||||
if 'powersw' in pindict:
|
||||
self.powersw = get_val('powersw', pindict)
|
||||
else:
|
||||
self.powersw = strnotgiven
|
||||
|
||||
if 'pullup' in pindict:
|
||||
self.pullup = get_val('pullup', pindict)
|
||||
else:
|
||||
self.pullup = strnotgiven
|
||||
|
||||
if 'func_sel' in pindict:
|
||||
self.func_sel = get_val('func_sel', pindict)
|
||||
else:
|
||||
self.func_sel = strnotgiven
|
||||
|
||||
if 'drvstrength' in pindict:
|
||||
self.drvstrength = int(get_val('drvstrength', pindict))
|
||||
else:
|
||||
self.drvstrength = intnotgiven
|
||||
|
||||
if 'intdir' in pindict:
|
||||
self.intdir = get_val('intdir', pindict)
|
||||
else:
|
||||
self.intdir = strnotgiven
|
||||
|
||||
if 'GPOutcfg' in pindict:
|
||||
self.GPOutcfg = get_val('GPOutcfg', pindict)
|
||||
else:
|
||||
self.GPOutcfg = strnotgiven
|
||||
|
||||
if 'GPinput' in pindict:
|
||||
self.GPinput = get_val('GPinput', pindict)
|
||||
else:
|
||||
self.GPinput = strnotgiven
|
||||
|
||||
if 'GPRdZero' in pindict:
|
||||
self.GPRdZero = get_val('GPRdZero', pindict)
|
||||
else:
|
||||
self.GPRdZero = strnotgiven
|
||||
|
||||
if 'IOMnum' in pindict:
|
||||
self.IOMnum = get_val('IOMnum', pindict)
|
||||
else:
|
||||
self.IOMnum = strnotgiven
|
||||
|
||||
if 'CEnum' in pindict:
|
||||
self.CEnum = get_val('CEnum', pindict)
|
||||
else:
|
||||
self.CEnum = strnotgiven
|
||||
|
||||
if 'CEpol' in pindict:
|
||||
self.CEpol = get_val('CEpol', pindict)
|
||||
else:
|
||||
self.CEpol = strnotgiven
|
||||
|
||||
if 'bIomMSPIn' in pindict:
|
||||
self.bIomMSPIn = get_val('bIomMSPIn', pindict)
|
||||
else:
|
||||
self.bIomMSPIn = strnotgiven
|
||||
|
||||
#
|
||||
# Check for an invalid field in the src file. If so, report it.
|
||||
#
|
||||
for fld in pindict:
|
||||
if fld != 'name' and \
|
||||
fld != 'desc' and \
|
||||
fld != 'pinnum' and \
|
||||
fld != 'powersw' and \
|
||||
fld != 'pullup' and \
|
||||
fld != 'func_sel' and \
|
||||
fld != 'drvstrength' and \
|
||||
fld != 'intdir' and \
|
||||
fld != 'GPOutcfg' and \
|
||||
fld != 'GPinput' and \
|
||||
fld != 'GPRdZero' and \
|
||||
fld != 'IOMnum' and \
|
||||
fld != 'CEnum' and \
|
||||
fld != 'CEpol' and \
|
||||
fld != 'bIomMSPIn':
|
||||
print("Invalid field: '%s.%s'" % (self.name, fld))
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
# pinobj
|
||||
# *****************************************************************************
|
||||
class pinobj:
|
||||
def __init__(self, pindict):
|
||||
self.name = 'name'
|
||||
self.srcver=0x0000
|
||||
self.pins = []
|
||||
|
||||
if 'pinsrc_ver' in pindict:
|
||||
# Convert rson list object to int
|
||||
ssrcver = pindict["pinsrc_ver"][0]
|
||||
if ssrcver[0:2].lower() == "0x":
|
||||
self.srcver = int(ssrcver,16)
|
||||
else:
|
||||
self.srcver = int(ssrcver,10)
|
||||
else:
|
||||
# If no src file version given, assume version for Apollo3
|
||||
self.srcver = 0x0003
|
||||
|
||||
# Run through all the pins given in the src file
|
||||
if 'pin' in pindict:
|
||||
#
|
||||
# Run through the 'pin' list.
|
||||
#
|
||||
for pin in pindict['pin']:
|
||||
self.pins.append(pinfields(pin))
|
||||
|
||||
# *****************************************************************************
|
||||
# write_Cfiles()
|
||||
# *****************************************************************************
|
||||
|
||||
def write_Cfiles(pinobj, bCreateC):
|
||||
#
|
||||
# Initializations
|
||||
#
|
||||
intnotgiven = 65535
|
||||
strnotgiven = 'none_given'
|
||||
strCfile = ''
|
||||
strHfile = ''
|
||||
|
||||
for pin in pinobj.pins:
|
||||
sectiondesc = pin.name.strip() + ' pin'
|
||||
if pin.desc == strnotgiven:
|
||||
sectiondesc += '.'
|
||||
else:
|
||||
sectiondesc += ': ' + pin.desc.strip()
|
||||
if sectiondesc[-1] != '.':
|
||||
sectiondesc += '.'
|
||||
strCfile += '\n'
|
||||
strCfile += sectiontemplate.format(pin_descr=sectiondesc)
|
||||
strCfile += '\n'
|
||||
strHfile += '\n'
|
||||
strHfile += sectiontemplate.format(pin_descr=sectiondesc)
|
||||
strHfile += '\n'
|
||||
|
||||
bga = False
|
||||
if ( 30 <= pin.pinnum <=38 ) or ( 42 <= pin.pinnum <= 43 ) or ( 45 <= pin.pinnum <= 46 ):
|
||||
bga = True
|
||||
|
||||
if pin.pinnum != intnotgiven:
|
||||
if bga and args.bgaguard:
|
||||
strHfile += '#if defined (' + args.bgaguard + ')\n'
|
||||
|
||||
strHfile += '#define ' + args.prefix + '_%-20s\t' % pin.name + '%d\n' % pin.pinnum
|
||||
strHfile += 'extern const am_hal_gpio_pincfg_t g_' + args.prefix + '_%s;\n' % pin.name
|
||||
|
||||
if bga and args.bgaguard:
|
||||
strHfile += '#endif // ' + args.bgaguard + '\n'
|
||||
#strHfile += '\n'
|
||||
|
||||
if bga and args.bgaguard:
|
||||
strCfile += '#if defined (' + args.bgaguard + ')\n'
|
||||
|
||||
strCfile += 'const am_hal_gpio_pincfg_t g_' + args.prefix + '_%s =\n' % pin.name
|
||||
strCfile += '{\n'
|
||||
strCfile += '%-25s' % ' .uFuncSel' + '= %s,\n' % pin.func_sel
|
||||
|
||||
if pin.powersw != strnotgiven:
|
||||
if (pin.powersw.lower() == "vdd") or \
|
||||
(pin.powersw.lower() == "vss") or \
|
||||
(pin.powersw.lower() == "none"):
|
||||
strCfile += '%-25s' % ' .ePowerSw' + '= AM_HAL_GPIO_PIN_POWERSW_%s,\n' % pin.powersw.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .ePowerSw' + '= %s,\n' % pin.powersw
|
||||
|
||||
if pin.pullup != strnotgiven:
|
||||
if (pin.pullup.lower() == "none") or \
|
||||
(pin.pullup.lower() == "weak") or \
|
||||
(pin.pullup.lower() == "pulldown") or \
|
||||
(pin.pullup.lower() == "1_5k") or \
|
||||
(pin.pullup.lower() == "6k") or \
|
||||
(pin.pullup.lower() == "12k") or \
|
||||
(pin.pullup.lower() == "24k"):
|
||||
strCfile += '%-25s' % ' .ePullup' + '= AM_HAL_GPIO_PIN_PULLUP_%s,\n' % pin.pullup.upper()
|
||||
elif (pin.pullup == "1_5") or \
|
||||
(pin.pullup == "6") or \
|
||||
(pin.pullup == "12") or \
|
||||
(pin.pullup == "24"):
|
||||
strCfile += '%-25s' % ' .ePullup' + '= AM_HAL_GPIO_PIN_PULLUP_%sK,\n' % pin.pullup
|
||||
else:
|
||||
strCfile += '%-25s' % ' .ePullup' + '= %s,\n' % pin.pullup
|
||||
|
||||
if pin.drvstrength != intnotgiven:
|
||||
if (pin.drvstrength != 2) and (pin.drvstrength != 4) and \
|
||||
(pin.drvstrength != 8) and (pin.drvstrength != 12):
|
||||
pin.drvstrength = 2
|
||||
strCfile += '%-25s' % ' .eDriveStrength' + '= AM_HAL_GPIO_PIN_DRIVESTRENGTH_%dMA,\n' % pin.drvstrength
|
||||
|
||||
if pin.GPOutcfg != strnotgiven:
|
||||
if (pin.GPOutcfg.lower() == "disable") or \
|
||||
(pin.GPOutcfg.lower() == "pushpull") or \
|
||||
(pin.GPOutcfg.lower() == "opendrain") or \
|
||||
(pin.GPOutcfg.lower() == "tristate"):
|
||||
strCfile += '%-25s' % ' .eGPOutcfg' + '= AM_HAL_GPIO_PIN_OUTCFG_%s,\n' % pin.GPOutcfg.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eGPOutcfg' + '= %s,\n' % pin.GPOutcfg
|
||||
|
||||
if pin.GPinput != strnotgiven:
|
||||
if (pin.GPinput.lower() == "true"):
|
||||
strCfile += '%-25s' % ' .eGPInput' + '= AM_HAL_GPIO_PIN_INPUT_ENABLE,\n'
|
||||
elif (pin.GPinput.lower() == "false"):
|
||||
strCfile += '%-25s' % ' .eGPInput' + '= AM_HAL_GPIO_PIN_INPUT_NONE,\n'
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eGPInput' + '= %s,\n' % pin.GPinput
|
||||
|
||||
if pin.GPRdZero != strnotgiven:
|
||||
if (pin.GPRdZero.lower() == "true") or \
|
||||
(pin.GPRdZero.lower() == "zero"):
|
||||
strCfile += '%-25s' % ' .eGPRdZero' + '= AM_HAL_GPIO_PIN_RDZERO_ZERO,\n'
|
||||
elif (pin.GPRdZero.lower() == "false") or \
|
||||
(pin.GPRdZero.lower() == "readpin"):
|
||||
strCfile += '%-25s' % ' .eGPRdZero' + '= AM_HAL_GPIO_PIN_RDZERO_READPIN,\n'
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eGPRdZero' + '= %s,\n' % pin.GPRdZero
|
||||
|
||||
if pin.intdir != strnotgiven:
|
||||
if (pin.intdir.lower() == "none") or \
|
||||
(pin.intdir.lower() == "lo2hi") or \
|
||||
(pin.intdir.lower() == "hi2lo") or \
|
||||
(pin.intdir.lower() == "either"):
|
||||
strCfile += '%-25s' % ' .eIntDir' + '= AM_HAL_GPIO_PIN_INTDIR_%s,\n' % pin.intdir.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eIntDir' + '= %s,\n' % pin.intdir
|
||||
|
||||
if (pin.bIomMSPIn != strnotgiven):
|
||||
if pinobj.srcver >= 0x0003:
|
||||
if ((pin.bIomMSPIn[0:1].lower() != "m") and (pin.bIomMSPIn != "0")):
|
||||
bIom = 1
|
||||
else:
|
||||
bIom = 0
|
||||
strCfile += '%-25s' % ' .bIomMSPIn' + '= %d,\n' % bIom
|
||||
|
||||
if pin.IOMnum != strnotgiven:
|
||||
strCfile += '%-25s' % ' .uIOMnum' + '= %s,\n' % str(pin.IOMnum)
|
||||
|
||||
if pin.CEnum != strnotgiven:
|
||||
strCfile += '%-25s' % ' .uNCE' + '= %s,\n' % str(pin.CEnum)
|
||||
|
||||
# Create the define
|
||||
strtmp = '#define ' + args.prefix + '_%s_CHNL' % (pin.name)
|
||||
strHfile += '%-40s' % strtmp + '%s\n' % str((pin.CEnum))
|
||||
|
||||
if pin.CEpol != strnotgiven:
|
||||
if (pin.CEpol.lower() == "low") or \
|
||||
(pin.CEpol.lower() == "high"):
|
||||
strCfile += '%-25s' % ' .eCEpol' + '= AM_HAL_GPIO_PIN_CEPOL_ACTIVE%s,\n' % pin.CEpol.upper()
|
||||
elif (pin.CEpol.lower() == "activelow") or \
|
||||
(pin.CEpol.lower() == "activehigh"):
|
||||
strCfile += '%-25s' % ' .eCEpol' + '= AM_HAL_GPIO_PIN_CEPOL_%s,\n' % pin.CEpol.upper()
|
||||
else:
|
||||
strCfile += '%-25s' % ' .eCEpol' + '= %s,\n' % pin.CEpol
|
||||
|
||||
# Eliminate the last comma from the last structure member
|
||||
strCfile = strCfile[:-2]
|
||||
|
||||
# Terminate the structure
|
||||
strCfile += '\n};\n'
|
||||
|
||||
if bga and args.bgaguard:
|
||||
strCfile += '#endif // ' + args.bgaguard + '\n'
|
||||
|
||||
if bCreateC:
|
||||
#
|
||||
# Develop and print the C file
|
||||
#
|
||||
S = filetemplateC.format(filename='am_bsp_pins.c', pin_defs=strCfile);
|
||||
print(S)
|
||||
else:
|
||||
#
|
||||
# Develop and print the H file
|
||||
#
|
||||
S = filetemplateH.format(filename='am_bsp_pins.h',
|
||||
pin_defs=strHfile,
|
||||
headerdef=args.headerdef)
|
||||
print(S)
|
||||
|
||||
|
||||
# *****************************************************************************
|
||||
#
|
||||
# main
|
||||
#
|
||||
# *****************************************************************************
|
||||
if __name__ == '__main__':
|
||||
|
||||
#
|
||||
# Get arguments.
|
||||
# First arg is a string for the input .src file.
|
||||
# Second arg must be a C or H.
|
||||
#
|
||||
args = read_arguments()
|
||||
if args.CorH.upper() == 'C':
|
||||
bCreateC = True
|
||||
else:
|
||||
bCreateC = False
|
||||
|
||||
pinobj = get_pinobj(args.input)
|
||||
|
||||
#
|
||||
# pinobj.pins is a list of the pins
|
||||
#
|
||||
write_Cfiles(pinobj, bCreateC)
|
||||
@@ -0,0 +1,294 @@
|
||||
'''
|
||||
rsonlite -- an extremely lightweight version of rson.
|
||||
|
||||
Copyright (c) 2012, Patrick Maupin
|
||||
|
||||
License :: MIT
|
||||
|
||||
http://pypi.python.org/pypi/rsonlite
|
||||
http://code.google.com/p/rson/
|
||||
|
||||
rsonlite makes it easy to build a file parser for
|
||||
declarative hierarchical data structures using indentation.
|
||||
(Spaces only, tabs not considered indentation.)
|
||||
|
||||
The only special characters are '#', '=', and indentation:
|
||||
|
||||
- Indentation denotes a key/value relationship. The
|
||||
value is indented from the key.
|
||||
|
||||
- = Denotes the start of a free-format string. These
|
||||
strings can contain '=' and '#' characters, and
|
||||
even be multi-line, but every line in the string
|
||||
must be indented past the initial equal sign.
|
||||
|
||||
Note that, for multi-line strings, indentation is
|
||||
preserved but normalized such that at least one
|
||||
line starts in the left column. This allows for
|
||||
restructuredText or Python code to exist inside
|
||||
multi-line strings.
|
||||
|
||||
- # Denotes the start of a line comment, when not
|
||||
inside a free-format string.
|
||||
|
||||
The only Python objects resulting from parsing a file
|
||||
with rsonlite are:
|
||||
|
||||
- strings:
|
||||
free-format strings (described above) can
|
||||
contain any character, but the whitespace
|
||||
before/after the string may be stripped.
|
||||
|
||||
Regular strings must fit on a single line and
|
||||
cannot contain '=' or '#' characters.
|
||||
|
||||
Regular strings may be used as keys in key/value
|
||||
pairs, but free-format strings may not.
|
||||
|
||||
- tuple:
|
||||
A key/value pair is a two-element tuple. The key is always
|
||||
a string. The value is always a list.
|
||||
|
||||
- list:
|
||||
The top level is a list, and the value element of every
|
||||
key/value pair tuple is also a list. Lists can contain
|
||||
strings and key/value pair tuples.
|
||||
'''
|
||||
|
||||
import re
|
||||
|
||||
version = __version__ = '0.1.0'
|
||||
|
||||
# Our attempt at rationalizing differences between Python 2 and Python 3.
|
||||
|
||||
try:
|
||||
basestring
|
||||
except NameError:
|
||||
basestring = str
|
||||
class unicode: pass
|
||||
|
||||
# Use OrderedDict if it's available
|
||||
|
||||
try:
|
||||
from collections import OrderedDict as stddict
|
||||
except ImportError:
|
||||
stddict = dict
|
||||
|
||||
# Splits the entire file into probable tokens.
|
||||
|
||||
splitter = re.compile('(\n *|=[^\n]*|#[^\n]*|[^\n#=]+)').findall
|
||||
|
||||
class RsonToken(str):
|
||||
''' A string that may be annotated with location information
|
||||
'''
|
||||
def __new__(cls, s, line, col):
|
||||
self = str.__new__(cls, s)
|
||||
self.line = line
|
||||
self.col = col
|
||||
return self
|
||||
def __add__(self, other):
|
||||
return RsonToken(str(self) + other, self.line, self.col)
|
||||
|
||||
|
||||
def gettoks(source):
|
||||
''' Convert string into (probable) tokens
|
||||
(some tokens may be recombined later, e.g. if they
|
||||
contain # or = but were already inside a string)
|
||||
'''
|
||||
|
||||
# Use "regular" strings, whatever that means for the given Python
|
||||
if isinstance(source, unicode):
|
||||
source = source.encode('utf-8', 'replace')
|
||||
elif not isinstance(source, basestring):
|
||||
source = source.decode('utf-8', 'replace')
|
||||
|
||||
# Convert MS-DOS or Mac line endings to the one true way, and
|
||||
# prefix the source with a linefeed to simplify the tokenization.
|
||||
source = '\n' + source.replace('\r\n', '\n').replace('\r', '\n')
|
||||
|
||||
line = 0
|
||||
for tok in splitter(source):
|
||||
if tok.startswith('\n'):
|
||||
line += 1
|
||||
col = len(tok)
|
||||
else:
|
||||
yield RsonToken(tok, line, col)
|
||||
col += len(tok)
|
||||
|
||||
def multiline(lineinfo, dedent):
|
||||
''' Returns one string for each line,
|
||||
properly dedented.
|
||||
'''
|
||||
linenum = lineinfo[0].line
|
||||
for tok in lineinfo:
|
||||
while linenum < tok.line:
|
||||
yield ''
|
||||
linenum += 1
|
||||
yield (tok.col - dedent) * ' ' + tok.rstrip()
|
||||
linenum += 1
|
||||
|
||||
def getfreeformat(toklist, firsttok, firstcol):
|
||||
''' Returns a free-formatted string.
|
||||
'''
|
||||
curline = firsttok.line
|
||||
firstpart = firsttok[1:].strip() # Get past = sign
|
||||
lineinfo = []
|
||||
while toklist and toklist[-1].col > firstcol:
|
||||
tok = toklist.pop()
|
||||
if tok.line == curline:
|
||||
lineinfo[-1] += tok
|
||||
else:
|
||||
lineinfo.append(tok)
|
||||
curline = tok.line
|
||||
if lineinfo:
|
||||
dedent = min(tok.col for tok in lineinfo)
|
||||
if firstpart:
|
||||
lineinfo.insert(0, RsonToken(firstpart, firsttok.line, dedent))
|
||||
firstpart = '\n'.join(multiline(lineinfo, dedent))
|
||||
return RsonToken(firstpart, firsttok.line, firsttok.col)
|
||||
|
||||
def loads(source):
|
||||
''' load a string into an rsonlite datastructure.
|
||||
If the source is not a string instance, then
|
||||
loads will attempt to convert it into a string
|
||||
instance, by encoding to UTF-8 on Python 2,
|
||||
or decoding from UTF-8 on Python 3.
|
||||
'''
|
||||
toklist = list(gettoks(source))
|
||||
toklist.reverse()
|
||||
result = [None]
|
||||
stack = []
|
||||
curcol = -1
|
||||
curlist = result
|
||||
while toklist:
|
||||
tok = toklist.pop()
|
||||
if tok.startswith('#'):
|
||||
continue
|
||||
col = tok.col
|
||||
if col > curcol:
|
||||
stack.append((curcol, curlist))
|
||||
oldlist = curlist
|
||||
curcol, curlist = col, []
|
||||
oldlist[-1] = oldlist[-1], curlist
|
||||
while col < curcol:
|
||||
curcol, curlist = stack.pop()
|
||||
if col != curcol:
|
||||
err = IndentationError('unindent does not match any outer indentation level')
|
||||
err.filename = '<rsonlite>'
|
||||
err.lineno = tok.line
|
||||
raise err
|
||||
if tok.startswith('='):
|
||||
curlist.append(getfreeformat(toklist, tok, col))
|
||||
else:
|
||||
curlist.append(RsonToken(tok.rstrip(), tok.line, tok.col))
|
||||
if toklist and toklist[-1].line == tok.line:
|
||||
tok = toklist.pop()
|
||||
if tok.startswith('='):
|
||||
curlist[-1] = curlist[-1], [getfreeformat(toklist, tok, col)]
|
||||
else:
|
||||
assert tok.startswith('#') # else problem in regex...
|
||||
result, = result
|
||||
return [] if result is None else result[1]
|
||||
|
||||
def dumps(data, indent=' ', initial_indent=''):
|
||||
''' Dump a string loaded with loads back out.
|
||||
'''
|
||||
def getstring(data, indent2):
|
||||
if '\n' in data:
|
||||
data = ('\n'+indent2).join([''] + data.split('\n'))
|
||||
return data
|
||||
|
||||
def recurse(data, indent2):
|
||||
assert isinstance(data, list), repr(data)
|
||||
for data in data:
|
||||
if isinstance(data, tuple):
|
||||
key, value = data
|
||||
if len(value) == 1 and isinstance(value[0], basestring):
|
||||
append('%s%s = %s' % (indent2, key, getstring(value[0], indent2+indent)))
|
||||
else:
|
||||
append('%s%s' % (indent2, key))
|
||||
recurse(value, indent2 + indent)
|
||||
else:
|
||||
assert isinstance(data, basestring)
|
||||
if '\n' in data or '=' in data or '#' in data:
|
||||
append(indent2 + '=')
|
||||
append(getstring(data, indent2 + ' '))
|
||||
else:
|
||||
append('%s%s' % (indent2, data))
|
||||
result = []
|
||||
append = result.append
|
||||
recurse(data, initial_indent)
|
||||
append('')
|
||||
return '\n'.join(result)
|
||||
|
||||
def pretty(data, indent=' '):
|
||||
''' Pretty-print a string loaded by loads into
|
||||
something that makes it easy to see the actual
|
||||
structure of the data. The return value of
|
||||
this should be parseable by eval()
|
||||
'''
|
||||
def recurse(data, indent2):
|
||||
assert isinstance(data, list)
|
||||
for data in data:
|
||||
assert isinstance(data, (tuple, basestring))
|
||||
if isinstance(data, tuple) and (
|
||||
len(data[1]) != 1 or not isinstance(data[1][0], basestring)):
|
||||
append('%s(%s, [' % (indent2, repr(data[0])))
|
||||
recurse(data[1], indent2 + indent)
|
||||
append('%s])' % (indent2))
|
||||
else:
|
||||
append('%s%s,' % (indent2, repr(data)))
|
||||
result = []
|
||||
append = result.append
|
||||
append('[')
|
||||
recurse(data, indent)
|
||||
append(']')
|
||||
append('')
|
||||
return '\n'.join(result)
|
||||
|
||||
##########################################################################
|
||||
# These higher-level functions might suffice for simple data, and also
|
||||
# provide a template for designing similar functions.
|
||||
|
||||
def stringparse(s, special=dict(true=True, false=False, null=None)):
|
||||
''' This gives an example of handling the JSON special identifiers
|
||||
true, false and null, and also of handling simple arrays.
|
||||
'''
|
||||
if s in special:
|
||||
return special[s]
|
||||
if s.startswith('[') and s.endswith(']'):
|
||||
t = s[1:-1]
|
||||
for ch in '"\'[]{}\n':
|
||||
if ch in t:
|
||||
return s
|
||||
return [x.strip() for x in t.split(',')]
|
||||
return s
|
||||
|
||||
def simpleparse(source, stringparse=stringparse, stddict=stddict):
|
||||
''' Return the simplest structure that uses dicts instead
|
||||
of tuples, and doesn't lose any source information.
|
||||
Use ordered dicts if they are available.
|
||||
'''
|
||||
def recurse(mylist):
|
||||
if len(mylist) == 1 and isinstance(mylist[0], basestring):
|
||||
return stringparse(mylist[0])
|
||||
keys = [x[0] for x in mylist if isinstance(x, tuple)]
|
||||
if not keys:
|
||||
return mylist # simple list
|
||||
if len(set(keys)) == len(mylist):
|
||||
return stddict((x, recurse(y)) for (x, y) in mylist)
|
||||
# Complicated. Make a list that might have multiple dicts
|
||||
result = []
|
||||
curdict = None
|
||||
for item in mylist:
|
||||
if not isinstance(item, tuple):
|
||||
result.append(stringparse(item))
|
||||
curdict = None
|
||||
continue
|
||||
key, value = item
|
||||
if curdict is None or key in curdict:
|
||||
curdict = stddict()
|
||||
result.append(curdict)
|
||||
curdict[key] = recurse(value)
|
||||
return result
|
||||
return recurse(source if isinstance(source, list) else loads(source))
|
||||
@@ -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.
|
||||
+21
@@ -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.
|
||||
|
||||
|
||||
|
||||
******************************************************************************
|
||||
|
||||
|
||||
+574
@@ -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
|
||||
+63
@@ -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) }
|
||||
}
|
||||
+63
@@ -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) }
|
||||
}
|
||||
+354
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
+161
@@ -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
|
||||
|
||||
+166
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+89
@@ -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
|
||||
+77
@@ -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
|
||||
+401
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
+65
@@ -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
|
||||
+214
@@ -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();
|
||||
}
|
||||
|
||||
+75
@@ -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);
|
||||
}
|
||||
}
|
||||
+401
@@ -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);
|
||||
}
|
||||
}
|
||||
+401
@@ -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
|
||||
+345
@@ -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);
|
||||
}
|
||||
}
|
||||
+404
@@ -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
|
||||
+356
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
+95
@@ -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()
|
||||
+177
@@ -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);
|
||||
}
|
||||
}
|
||||
+412
@@ -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_
|
||||
+18
@@ -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");
|
||||
}
|
||||
+16
@@ -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_
|
||||
+23
@@ -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;
|
||||
}
|
||||
+8
@@ -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_
|
||||
+58
@@ -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;
|
||||
}
|
||||
+8
@@ -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_
|
||||
+30
@@ -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;
|
||||
}
|
||||
+18
@@ -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_
|
||||
+405
@@ -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
|
||||
+174
@@ -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, ®.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, ®.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+417
@@ -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_
|
||||
+17
@@ -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");
|
||||
}
|
||||
+15
@@ -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_
|
||||
+21
@@ -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; }
|
||||
}
|
||||
}
|
||||
+8
@@ -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_
|
||||
+41
@@ -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; }
|
||||
}
|
||||
+8
@@ -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_
|
||||
+99
@@ -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
|
||||
}
|
||||
+8
@@ -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_
|
||||
+21
@@ -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; }
|
||||
}
|
||||
+8
@@ -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_
|
||||
+30
@@ -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;
|
||||
}
|
||||
+20
@@ -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_
|
||||
+1586
File diff suppressed because it is too large
Load Diff
+938
@@ -0,0 +1,938 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @file HM01B0.c
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "am_bsp.h"
|
||||
#include "am_util.h"
|
||||
#include "HM01B0.h"
|
||||
#include "HM01B0_Walking1s_01.h"
|
||||
#include "platform.h"
|
||||
|
||||
#define read_vsync() (AM_REGVAL(AM_REGADDR(GPIO, RDA)) & (1 << HM01B0_PIN_VSYNC))
|
||||
#define read_hsync() (AM_REGVAL(AM_REGADDR(GPIO, RDA)) & (1 << HM01B0_PIN_HSYNC))
|
||||
#define read_pclk() (AM_REGVAL(AM_REGADDR(GPIO, RDA)) & (1 << HM01B0_PIN_PCLK))
|
||||
#define read_byte() (APBDMA->BBINPUT)
|
||||
|
||||
const am_hal_gpio_pincfg_t g_HM01B0_pin_int =
|
||||
{
|
||||
.uFuncSel = 3,
|
||||
.eGPOutcfg = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
|
||||
.eIntDir = AM_HAL_GPIO_PIN_INTDIR_LO2HI,
|
||||
.eGPInput = AM_HAL_GPIO_PIN_INPUT_ENABLE,
|
||||
.eGPRdZero = AM_HAL_GPIO_PIN_RDZERO_READPIN
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Write HM01B0 registers
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui16Reg - Register address.
|
||||
//! @param pui8Value - Pointer to the data to be written.
|
||||
//! @param ui32NumBytes - Length of the data in bytes to be written.
|
||||
//!
|
||||
//! This function writes value to HM01B0 registers.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_write_reg(hm01b0_cfg_t *psCfg, \
|
||||
uint16_t ui16Reg, uint8_t *pui8Value, uint32_t ui32NumBytes)
|
||||
{
|
||||
am_hal_iom_transfer_t Transaction;
|
||||
|
||||
//
|
||||
// Create the transaction.
|
||||
//
|
||||
Transaction.ui32InstrLen = sizeof(uint16_t);
|
||||
Transaction.ui32Instr = (ui16Reg & 0x0000FFFF);
|
||||
Transaction.eDirection = AM_HAL_IOM_TX;
|
||||
Transaction.ui32NumBytes = ui32NumBytes;
|
||||
Transaction.pui32TxBuffer = (uint32_t *) pui8Value;
|
||||
Transaction.uPeerInfo.ui32I2CDevAddr = (uint32_t) psCfg->ui16SlvAddr;
|
||||
Transaction.bContinue = false;
|
||||
Transaction.ui8RepeatCount = 0;
|
||||
Transaction.ui32PauseCondition = 0;
|
||||
Transaction.ui32StatusSetClr = 0;
|
||||
|
||||
//
|
||||
// Execute the transction over IOM.
|
||||
//
|
||||
if (am_hal_iom_blocking_transfer(psCfg->pIOMHandle, &Transaction))
|
||||
{
|
||||
return HM01B0_ERR_I2C;
|
||||
}
|
||||
|
||||
return HM01B0_ERR_OK;
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Read HM01B0 registers
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui16Reg - Register address.
|
||||
//! @param pui8Value - Pointer to the buffer for read data to be put into.
|
||||
//! @param ui32NumBytes - Length of the data to be read.
|
||||
//!
|
||||
//! This function reads value from HM01B0 registers.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_read_reg(hm01b0_cfg_t *psCfg, \
|
||||
uint16_t ui16Reg, uint8_t *pui8Value, uint32_t ui32NumBytes)
|
||||
{
|
||||
am_hal_iom_transfer_t Transaction;
|
||||
|
||||
//
|
||||
// Create the transaction.
|
||||
//
|
||||
Transaction.ui32InstrLen = sizeof(uint16_t);
|
||||
Transaction.ui32Instr = (ui16Reg & 0x0000FFFF);
|
||||
Transaction.eDirection = AM_HAL_IOM_RX;
|
||||
Transaction.ui32NumBytes = ui32NumBytes;
|
||||
Transaction.pui32RxBuffer = (uint32_t *) pui8Value;;
|
||||
Transaction.uPeerInfo.ui32I2CDevAddr = (uint32_t) psCfg->ui16SlvAddr;
|
||||
Transaction.bContinue = false;
|
||||
Transaction.ui8RepeatCount = 0;
|
||||
Transaction.ui32PauseCondition = 0;
|
||||
Transaction.ui32StatusSetClr = 0;
|
||||
|
||||
//
|
||||
// Execute the transction over IOM.
|
||||
//
|
||||
if (am_hal_iom_blocking_transfer(psCfg->pIOMHandle, &Transaction))
|
||||
{
|
||||
return HM01B0_ERR_I2C;
|
||||
}
|
||||
|
||||
return HM01B0_ERR_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Load HM01B0 a given script
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psScrip - Pointer to the script to be loaded.
|
||||
//! @param ui32ScriptCmdNum - Number of entries in a given script.
|
||||
//!
|
||||
//! This function loads HM01B0 a given script.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_load_script(hm01b0_cfg_t *psCfg, hm_script_t *psScript, uint32_t ui32ScriptCmdNum)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
for (uint32_t idx = 0; idx < ui32ScriptCmdNum; idx++)
|
||||
{
|
||||
ui32Err = hm01b0_write_reg(psCfg, \
|
||||
(psScript + idx)->ui16Reg, \
|
||||
&((psScript + idx)->ui8Val), \
|
||||
sizeof(uint8_t));
|
||||
if (ui32Err != HM01B0_ERR_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Power up HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function powers up HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_power_up(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
// place holder
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Power down HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function powers up HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_power_down(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
// place holder
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Enable MCLK
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function utilizes CTimer to generate MCLK for HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_mclk_enable(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
#define MCLK_UI64PATTERN 0x55555555
|
||||
#define MCLK_UI64PATTERNLEN 31
|
||||
|
||||
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
|
||||
|
||||
//
|
||||
// Set up timer.
|
||||
//
|
||||
am_hal_ctimer_clear(psCfg->ui32CTimerModule, psCfg->ui32CTimerSegment);
|
||||
|
||||
am_hal_ctimer_config_single(psCfg->ui32CTimerModule,
|
||||
psCfg->ui32CTimerSegment,
|
||||
(
|
||||
AM_HAL_CTIMER_FN_PTN_REPEAT |
|
||||
AM_HAL_CTIMER_HFRC_12MHZ
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Set the pattern in the CMPR registers.
|
||||
//
|
||||
am_hal_ctimer_compare_set(psCfg->ui32CTimerModule, psCfg->ui32CTimerSegment, 0,
|
||||
(uint32_t)(MCLK_UI64PATTERN & 0xFFFF));
|
||||
am_hal_ctimer_compare_set(psCfg->ui32CTimerModule, psCfg->ui32CTimerSegment, 1,
|
||||
(uint32_t)((MCLK_UI64PATTERN >> 16) & 0xFFFF));
|
||||
|
||||
//
|
||||
// Set the timer trigger and pattern length.
|
||||
//
|
||||
am_hal_ctimer_config_trigger(psCfg->ui32CTimerModule,
|
||||
psCfg->ui32CTimerSegment,
|
||||
(
|
||||
(MCLK_UI64PATTERNLEN << CTIMER_AUX0_TMRA0LMT_Pos) |
|
||||
(CTIMER_AUX0_TMRB0TRIG_DIS << CTIMER_AUX0_TMRA0TRIG_Pos)
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
// Configure timer output pin.
|
||||
//
|
||||
am_hal_ctimer_output_config(psCfg->ui32CTimerModule,
|
||||
psCfg->ui32CTimerSegment,
|
||||
psCfg->ui32CTimerOutputPin,
|
||||
AM_HAL_CTIMER_OUTPUT_NORMAL,
|
||||
AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA);
|
||||
|
||||
//
|
||||
// Start the timer.
|
||||
//
|
||||
am_hal_ctimer_start(psCfg->ui32CTimerModule, psCfg->ui32CTimerSegment);
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Disable MCLK
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function disable CTimer to stop MCLK for HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_mclk_disable(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
//
|
||||
// Stop the timer.
|
||||
//
|
||||
am_hal_ctimer_stop(psCfg->ui32CTimerModule, psCfg->ui32CTimerSegment);
|
||||
am_hal_gpio_pinconfig(psCfg->ui32CTimerOutputPin, g_AM_HAL_GPIO_DISABLE);
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Initialize interfaces
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function initializes interfaces.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_init_if(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
void *pIOMHandle = NULL;
|
||||
|
||||
if ( psCfg->ui32IOMModule > AM_REG_IOM_NUM_MODULES )
|
||||
{
|
||||
return HM01B0_ERR_I2C;
|
||||
}
|
||||
|
||||
//
|
||||
// Enable fault detection.
|
||||
//
|
||||
#if AM_APOLLO3_MCUCTRL
|
||||
am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_FAULT_CAPTURE_ENABLE, 0);
|
||||
#else // AM_APOLLO3_MCUCTRL
|
||||
am_hal_mcuctrl_fault_capture_enable();
|
||||
#endif // AM_APOLLO3_MCUCTRL
|
||||
|
||||
//
|
||||
// Initialize the IOM instance.
|
||||
// Enable power to the IOM instance.
|
||||
// Configure the IOM for Serial operation during initialization.
|
||||
// Enable the IOM.
|
||||
//
|
||||
if (am_hal_iom_initialize(psCfg->ui32IOMModule, &pIOMHandle) ||
|
||||
am_hal_iom_power_ctrl(pIOMHandle, AM_HAL_SYSCTRL_WAKE, false) ||
|
||||
am_hal_iom_configure(pIOMHandle, &(psCfg->sIOMCfg)) ||
|
||||
am_hal_iom_enable(pIOMHandle))
|
||||
{
|
||||
return HM01B0_ERR_I2C;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Configure the IOM pins.
|
||||
//
|
||||
am_bsp_iom_pins_enable(psCfg->ui32IOMModule, psCfg->eIOMMode);
|
||||
|
||||
psCfg->pIOMHandle = pIOMHandle;
|
||||
}
|
||||
|
||||
// initialize pins for camera parallel interface.
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD0);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD1);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD2);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD3);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD4);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD5);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD6);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD7);
|
||||
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD0);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD1);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD2);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD3);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD4);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD5);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD6);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD7);
|
||||
|
||||
am_hal_gpio_fast_pinconfig((uint64_t)0x1 << psCfg->ui8PinD0 |
|
||||
(uint64_t)0x1 << psCfg->ui8PinD1 |
|
||||
(uint64_t)0x1 << psCfg->ui8PinD2 |
|
||||
(uint64_t)0x1 << psCfg->ui8PinD3 |
|
||||
(uint64_t)0x1 << psCfg->ui8PinD4 |
|
||||
(uint64_t)0x1 << psCfg->ui8PinD5 |
|
||||
(uint64_t)0x1 << psCfg->ui8PinD6 |
|
||||
(uint64_t)0x1 << psCfg->ui8PinD7,
|
||||
g_AM_HAL_GPIO_INPUT, 0);
|
||||
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinVSYNC, g_AM_HAL_GPIO_INPUT);
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinHSYNC, g_AM_HAL_GPIO_INPUT);
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinPCLK, g_AM_HAL_GPIO_INPUT);
|
||||
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinTrig, g_AM_HAL_GPIO_OUTPUT);
|
||||
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinInt, g_AM_HAL_GPIO_DISABLE);
|
||||
// am_hal_gpio_pinconfig(psCfg->ui8PinInt, g_HM01B0_pin_int);
|
||||
// am_hal_gpio_interrupt_clear(AM_HAL_GPIO_BIT(psCfg->ui8PinInt));
|
||||
// am_hal_gpio_interrupt_enable(AM_HAL_GPIO_BIT(psCfg->ui8PinInt));
|
||||
// NVIC_EnableIRQ(GPIO_IRQn);
|
||||
|
||||
return HM01B0_ERR_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Deinitialize interfaces
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function deinitializes interfaces.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_deinit_if(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
am_hal_iom_disable(psCfg->pIOMHandle);
|
||||
am_hal_iom_uninitialize(psCfg->pIOMHandle);
|
||||
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinSCL, g_AM_HAL_GPIO_DISABLE);
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinSDA, g_AM_HAL_GPIO_DISABLE);
|
||||
|
||||
// initialize pins for camera parallel interface.
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD0);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD1);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD2);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD3);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD4);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD5);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD6);
|
||||
am_hal_gpio_fastgpio_disable(psCfg->ui8PinD7);
|
||||
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD0);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD1);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD2);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD3);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD4);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD5);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD6);
|
||||
am_hal_gpio_fastgpio_clr(psCfg->ui8PinD7);
|
||||
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinVSYNC, g_AM_HAL_GPIO_DISABLE);
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinHSYNC, g_AM_HAL_GPIO_DISABLE);
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinPCLK, g_AM_HAL_GPIO_DISABLE);
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinTrig, g_AM_HAL_GPIO_DISABLE);
|
||||
am_hal_gpio_pinconfig(psCfg->ui8PinInt, g_AM_HAL_GPIO_DISABLE);
|
||||
|
||||
|
||||
return HM01B0_ERR_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get HM01B0 Model ID
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param pui16MID - Pointer to buffer for the read back model ID.
|
||||
//!
|
||||
//! This function reads back HM01B0 model ID.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_get_modelid(hm01b0_cfg_t *psCfg, uint16_t *pui16MID)
|
||||
{
|
||||
uint8_t ui8Data[1];
|
||||
uint32_t ui32Err;
|
||||
|
||||
*pui16MID = 0x0000;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_MODEL_ID_H, ui8Data, sizeof(ui8Data));
|
||||
if (ui32Err == HM01B0_ERR_OK)
|
||||
{
|
||||
*pui16MID |= (ui8Data[0] << 8);
|
||||
}
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_MODEL_ID_L, ui8Data, sizeof(ui8Data));
|
||||
if (ui32Err == HM01B0_ERR_OK)
|
||||
{
|
||||
*pui16MID |= ui8Data[0];
|
||||
}
|
||||
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Initialize HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psScript - Pointer to HM01B0 initialization script.
|
||||
//! @param ui32ScriptCmdNum - No. of commands in HM01B0 initialization script.
|
||||
//!
|
||||
//! This function initilizes HM01B0 with a given script.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_init_system(hm01b0_cfg_t *psCfg, hm_script_t *psScript, uint32_t ui32ScriptCmdNum)
|
||||
{
|
||||
return hm01b0_load_script(psCfg, psScript, ui32ScriptCmdNum);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Set HM01B0 in the walking 1s test mode
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function sets HM01B0 in the walking 1s test mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_test_walking1s(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
uint32_t ui32ScriptCmdNum = sizeof(sHM01b0TestModeScript_Walking1s) / sizeof(hm_script_t);
|
||||
hm_script_t *psScript = (hm_script_t *)sHM01b0TestModeScript_Walking1s;
|
||||
|
||||
return hm01b0_load_script(psCfg, psScript, ui32ScriptCmdNum);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Check the data read from HM01B0 in the walking 1s test mode
|
||||
//!
|
||||
//! @param pui8Buffer - Pointer to data buffer.
|
||||
//! @param ui32BufferLen - Buffer length
|
||||
//! @param ui32PrintCnt - Number of mismatched data to be printed out
|
||||
//!
|
||||
//! This function sets HM01B0 in the walking 1s test mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_test_walking1s_check_data_sanity(uint8_t *pui8Buffer, uint32_t ui32BufferLen, uint32_t ui32PrintCnt)
|
||||
{
|
||||
uint8_t ui8ByteData = *pui8Buffer;
|
||||
uint32_t ui32MismatchCnt = 0x00;
|
||||
|
||||
for (uint32_t ui32Idx = 0; ui32Idx < ui32BufferLen; ui32Idx++)
|
||||
{
|
||||
if (*(pui8Buffer + ui32Idx) != ui8ByteData)
|
||||
{
|
||||
if (ui32PrintCnt)
|
||||
{
|
||||
am_util_stdio_printf("[0x%08X] actual 0x%02X expected 0x%02X\n", ui32Idx, *(pui8Buffer + ui32Idx), ui8ByteData);
|
||||
am_util_delay_ms(1);
|
||||
ui32PrintCnt--;
|
||||
}
|
||||
ui32MismatchCnt++;
|
||||
}
|
||||
|
||||
if (ui8ByteData)
|
||||
ui8ByteData = ui8ByteData << 1;
|
||||
else
|
||||
ui8ByteData = 0x01;
|
||||
}
|
||||
|
||||
am_util_stdio_printf("Mismatch Rate %d/%d\n", ui32MismatchCnt, ui32BufferLen);
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Software reset HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function resets HM01B0 by issuing a reset command.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_reset_sw(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
uint8_t ui8Data[1] = {0x00};
|
||||
return hm01b0_write_reg(psCfg, HM01B0_REG_SW_RESET, ui8Data, sizeof(ui8Data));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get current HM01B0 operation mode.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param pui8Mode - Pointer to buffer
|
||||
//! - for the read back operation mode to be put into
|
||||
//!
|
||||
//! This function get HM01B0 operation mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_get_mode(hm01b0_cfg_t *psCfg, uint8_t *pui8Mode)
|
||||
{
|
||||
uint8_t ui8Data[1] = {0x01};
|
||||
uint32_t ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_MODE_SELECT, ui8Data, sizeof(ui8Data));
|
||||
|
||||
*pui8Mode = ui8Data[0];
|
||||
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Set HM01B0 operation mode.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui8Mode - Operation mode. One of:
|
||||
//! HM01B0_REG_MODE_SELECT_STANDBY
|
||||
//! HM01B0_REG_MODE_SELECT_STREAMING
|
||||
//! HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES
|
||||
//! HM01B0_REG_MODE_SELECT_STREAMING_HW_TRIGGER
|
||||
//! @param ui8FrameCnt - Frame count for HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES.
|
||||
//! - Discarded if other modes.
|
||||
//!
|
||||
//! This function set HM01B0 operation mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_set_mode(hm01b0_cfg_t *psCfg, uint8_t ui8Mode, uint8_t ui8FrameCnt)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
|
||||
if (ui8Mode == HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES)
|
||||
{
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_PMU_PROGRAMMABLE_FRAMECNT, &ui8FrameCnt, sizeof(ui8FrameCnt));
|
||||
}
|
||||
|
||||
if(ui32Err == HM01B0_ERR_OK)
|
||||
{
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_MODE_SELECT, &ui8Mode, sizeof(ui8Mode));
|
||||
}
|
||||
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Activate the updated settings to HM01B0.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! Some settings updated to HM01B0 will only be affected after calling this function
|
||||
//! 1. AE settings
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_cmd_update(hm01b0_cfg_t *psCfg)
|
||||
{
|
||||
uint8_t ui8Data = HM01B0_REG_GRP_PARAM_HOLD_HOLD;
|
||||
|
||||
return hm01b0_write_reg(psCfg, HM01B0_REG_GRP_PARAM_HOLD, &ui8Data, sizeof(ui8Data));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get HM01B0 AE convergance
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psAECfg - Pointer to the structure hm01b0_ae_cfg_t.
|
||||
//!
|
||||
//! This function checks if AE is converged or not and returns ui32Err accordingly.
|
||||
//! If caller needs detailed AE settings, psAECfg has to be non NULL.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_get_ae(hm01b0_cfg_t *psCfg, hm01b0_ae_cfg_t *psAECfg)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
uint8_t ui8AETargetMean;
|
||||
uint8_t ui8AEMinMean;
|
||||
uint8_t ui8AEMean;
|
||||
uint8_t ui8ConvergeInTh;
|
||||
uint8_t ui8ConvergeOutTh;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_AE_TARGET_MEAN, &ui8AETargetMean, sizeof(ui8AETargetMean));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_AE_MIN_MEAN, &ui8AEMinMean, sizeof(ui8AEMinMean));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_CONVERGE_IN_TH, &ui8ConvergeInTh, sizeof(ui8ConvergeInTh));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_CONVERGE_OUT_TH, &ui8ConvergeOutTh, sizeof(ui8ConvergeOutTh));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, 0x2020, &ui8AEMean, sizeof(ui8AEMean));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
if ((ui8AEMean < (ui8AETargetMean - ui8ConvergeInTh)) || (ui8AEMean > (ui8AETargetMean + ui8ConvergeInTh)))
|
||||
ui32Err = HM01B0_ERR_AE_NOT_CONVERGED;
|
||||
|
||||
if (psAECfg)
|
||||
{
|
||||
psAECfg->ui8AETargetMean = ui8AETargetMean;
|
||||
psAECfg->ui8AEMinMean = ui8AEMinMean;
|
||||
psAECfg->ui8ConvergeInTh = ui8ConvergeInTh;
|
||||
psAECfg->ui8ConvergeOutTh = ui8ConvergeOutTh;
|
||||
psAECfg->ui8AEMean = ui8AEMean;
|
||||
}
|
||||
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief AE calibration.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui8CalFrames - Frame counts for calibratoin.
|
||||
//! @param pui8Buffer - Pointer to the frame buffer.
|
||||
//! @param ui32BufferLen - Framebuffer size.
|
||||
//!
|
||||
//! This function lets HM01B0 AE settled as much as possible within a given frame counts.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_cal_ae(hm01b0_cfg_t *psCfg, uint8_t ui8CalFrames, uint8_t *pui8Buffer, uint32_t ui32BufferLen)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
hm01b0_ae_cfg_t sAECfg;
|
||||
|
||||
am_util_stdio_printf("[%s] +\n", __func__);
|
||||
|
||||
hm01b0_set_mode(psCfg, HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES, ui8CalFrames);
|
||||
|
||||
for (uint8_t i = 0; i < ui8CalFrames; i++)
|
||||
{
|
||||
|
||||
hm01b0_blocking_read_oneframe(psCfg, pui8Buffer, ui32BufferLen);
|
||||
|
||||
ui32Err = hm01b0_get_ae(psCfg, &sAECfg);
|
||||
|
||||
am_util_stdio_printf("AE Calibration(0x%02X) TargetMean 0x%02X, ConvergeInTh 0x%02X, AEMean 0x%02X\n", \
|
||||
ui32Err, sAECfg.ui8AETargetMean, sAECfg.ui8ConvergeInTh, sAECfg.ui8AEMean);
|
||||
|
||||
// if AE calibration is done in ui8CalFrames, just exit to save some time.
|
||||
if (ui32Err == HM01B0_ERR_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
hm01b0_set_mode(psCfg, HM01B0_REG_MODE_SELECT_STANDBY, 0);
|
||||
|
||||
am_util_stdio_printf("[%s] -\n", __func__);
|
||||
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Save HM01B0 exposure gain settings.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psExpoGainCtrl - Pointer to the structure hm01b0_snr_expo_gain_ctrl_t
|
||||
//!
|
||||
//! This function saves HM01B0 exposure gain settings.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_save_exposure_gains(hm01b0_cfg_t *psCfg, hm01b0_snr_expo_gain_ctrl_t *psExpoGainCtrl)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
uint8_t ui8IntegrationH;
|
||||
uint8_t ui8IntegrationL;
|
||||
uint8_t ui8AGain;
|
||||
uint8_t ui8DGain_H;
|
||||
uint8_t ui8DGain_L;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_INTEGRATION_H, &ui8IntegrationH, sizeof(ui8IntegrationH));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_INTEGRATION_L, &ui8IntegrationL, sizeof(ui8IntegrationL));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_ANALOG_GAIN, &ui8AGain, sizeof(ui8AGain));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_DIGITAL_GAIN_H, &ui8DGain_H, sizeof(ui8DGain_H));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_DIGITAL_GAIN_L, &ui8DGain_L, sizeof(ui8DGain_L));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
if (psExpoGainCtrl)
|
||||
{
|
||||
psExpoGainCtrl->ui8IntegrationH = ui8IntegrationH;
|
||||
psExpoGainCtrl->ui8IntegrationL = ui8IntegrationL;
|
||||
psExpoGainCtrl->ui8AGain = ui8AGain;
|
||||
psExpoGainCtrl->ui8DGain_H = ui8DGain_H;
|
||||
psExpoGainCtrl->ui8DGain_L = ui8DGain_L;
|
||||
}
|
||||
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Restore HM01B0 exposure gain settings.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psExpoGainCtrl - Pointer to the structure hm01b0_snr_expo_gain_ctrl_t
|
||||
//!
|
||||
//! This function restores HM01B0 exposure gain settings. The call flow shall be
|
||||
//! hm01b0_restore_exposure_gains() -> hm01b0_cmd_update() -> hm01b0_set_mode()
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_restore_exposure_gains(hm01b0_cfg_t *psCfg, hm01b0_snr_expo_gain_ctrl_t *psExpoGainCtrl)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
uint8_t ui8Tmp;
|
||||
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_INTEGRATION_H, &(psExpoGainCtrl->ui8IntegrationH), sizeof(psExpoGainCtrl->ui8IntegrationH));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_INTEGRATION_L, &(psExpoGainCtrl->ui8IntegrationL), sizeof(psExpoGainCtrl->ui8IntegrationL));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_ANALOG_GAIN, &ui8Tmp, sizeof(ui8Tmp));
|
||||
ui8Tmp = (ui8Tmp & ~(0x7 << 4)) | (psExpoGainCtrl->ui8AGain & (0x7 << 4));
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_ANALOG_GAIN, &ui8Tmp, sizeof(ui8Tmp));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_DIGITAL_GAIN_H, &ui8Tmp, sizeof(ui8Tmp));
|
||||
ui8Tmp = (ui8Tmp & ~(0x3 << 0)) | (psExpoGainCtrl->ui8DGain_H & (0x3 << 0));
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_DIGITAL_GAIN_H, &ui8Tmp, sizeof(ui8Tmp));
|
||||
if (ui32Err != HM01B0_ERR_OK) return ui32Err;
|
||||
|
||||
ui32Err = hm01b0_read_reg(psCfg, HM01B0_REG_DIGITAL_GAIN_L, &ui8Tmp, sizeof(ui8Tmp));
|
||||
ui8Tmp = (ui8Tmp & ~(0x3F << 2)) | (psExpoGainCtrl->ui8DGain_L & (0x3F << 2));
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_DIGITAL_GAIN_L, &ui8Tmp, sizeof(ui8Tmp));
|
||||
|
||||
return ui32Err;
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Hardware trigger HM01B0 to stream.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param bTrigger - True to start streaming
|
||||
//! - False to stop streaming
|
||||
//!
|
||||
//! This function triggers HM01B0 to stream by toggling the TRIG pin.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_hardware_trigger_streaming(hm01b0_cfg_t *psCfg, bool bTrigger)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
uint8_t ui8Mode;
|
||||
|
||||
ui32Err = hm01b0_get_mode(psCfg, &ui8Mode);
|
||||
|
||||
if (ui32Err != HM01B0_ERR_OK)
|
||||
goto end;
|
||||
|
||||
if (ui8Mode != HM01B0_REG_MODE_SELECT_STREAMING_HW_TRIGGER)
|
||||
{
|
||||
ui32Err = HM01B0_ERR_MODE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (bTrigger)
|
||||
{
|
||||
am_hal_gpio_output_set(psCfg->ui8PinTrig);
|
||||
}
|
||||
else
|
||||
{
|
||||
am_hal_gpio_output_clear(psCfg->ui8PinTrig);
|
||||
}
|
||||
|
||||
end:
|
||||
return ui32Err;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Set HM01B0 mirror mode.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param bHmirror - Horizontal mirror
|
||||
//! @param bVmirror - Vertical mirror
|
||||
//!
|
||||
//! This function set HM01B0 mirror mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_set_mirror(hm01b0_cfg_t *psCfg, bool bHmirror, bool bVmirror)
|
||||
{
|
||||
uint8_t ui8Data = 0x00;
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
|
||||
if (bHmirror)
|
||||
{
|
||||
ui8Data |= HM01B0_REG_IMAGE_ORIENTATION_HMIRROR;
|
||||
}
|
||||
|
||||
if (bVmirror)
|
||||
{
|
||||
ui8Data |= HM01B0_REG_IMAGE_ORIENTATION_VMIRROR;
|
||||
}
|
||||
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_IMAGE_ORIENTATION, &ui8Data, sizeof(ui8Data));
|
||||
|
||||
if (ui32Err == HM01B0_ERR_OK)
|
||||
{
|
||||
ui8Data = HM01B0_REG_GRP_PARAM_HOLD_HOLD;
|
||||
ui32Err = hm01b0_write_reg(psCfg, HM01B0_REG_GRP_PARAM_HOLD, &ui8Data, sizeof(ui8Data));
|
||||
}
|
||||
|
||||
return ui32Err;
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Read data of one frame from HM01B0.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param pui8Buffer - Pointer to the frame buffer.
|
||||
//! @param ui32BufferLen - Framebuffer size.
|
||||
//!
|
||||
//! This function read data of one frame from HM01B0.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_blocking_read_oneframe(hm01b0_cfg_t *psCfg, uint8_t *pui8Buffer, uint32_t ui32BufferLen)
|
||||
{
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
uint32_t ui32Idx = 0x00;
|
||||
|
||||
am_util_stdio_printf("[%s] +\n", __func__);
|
||||
|
||||
uint32_t ui32HsyncCnt = 0x00;
|
||||
|
||||
while((ui32HsyncCnt < HM01B0_PIXEL_Y_NUM))
|
||||
{
|
||||
while (0x00 == read_hsync());
|
||||
|
||||
// read one row
|
||||
while(read_hsync())
|
||||
{
|
||||
while(0x00 == read_pclk());
|
||||
|
||||
*(pui8Buffer + ui32Idx++) = read_byte();
|
||||
|
||||
if (ui32Idx == ui32BufferLen) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
while(read_pclk());
|
||||
}
|
||||
|
||||
ui32HsyncCnt++;
|
||||
}
|
||||
|
||||
end:
|
||||
am_util_stdio_printf("[%s] - Byte Counts %d\n", __func__, ui32Idx);
|
||||
|
||||
return ui32Err;
|
||||
|
||||
}
|
||||
+490
@@ -0,0 +1,490 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @file HM01B0.h
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef HM01B0_H
|
||||
#define HM01B0_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "am_bsp.h"
|
||||
#include "am_util.h"
|
||||
|
||||
#define HM01B0_DRV_VERSION (0)
|
||||
#define HM01B0_DRV_SUBVERSION (5)
|
||||
|
||||
#define HM01B0_DEFAULT_ADDRESS (0x24)
|
||||
|
||||
#define HM01B0_PIXEL_X_NUM (324)
|
||||
#define HM01B0_PIXEL_Y_NUM (244)
|
||||
|
||||
#define HM01B0_REG_MODEL_ID_H (0x0000)
|
||||
#define HM01B0_REG_MODEL_ID_L (0x0001)
|
||||
#define HM01B0_REG_SILICON_REV (0x0002)
|
||||
#define HM01B0_REG_FRAME_COUNT (0x0005)
|
||||
#define HM01B0_REG_PIXEL_ORDER (0x0006)
|
||||
|
||||
#define HM01B0_REG_MODE_SELECT (0x0100)
|
||||
#define HM01B0_REG_IMAGE_ORIENTATION (0x0101)
|
||||
#define HM01B0_REG_SW_RESET (0x0103)
|
||||
#define HM01B0_REG_GRP_PARAM_HOLD (0x0104)
|
||||
|
||||
#define HM01B0_REG_INTEGRATION_H (0x0202)
|
||||
#define HM01B0_REG_INTEGRATION_L (0x0203)
|
||||
#define HM01B0_REG_ANALOG_GAIN (0x0205)
|
||||
#define HM01B0_REG_DIGITAL_GAIN_H (0x020E)
|
||||
#define HM01B0_REG_DIGITAL_GAIN_L (0x020F)
|
||||
|
||||
#define HM01B0_REG_AE_TARGET_MEAN (0x2101)
|
||||
#define HM01B0_REG_AE_MIN_MEAN (0x2102)
|
||||
#define HM01B0_REG_CONVERGE_IN_TH (0x2103)
|
||||
#define HM01B0_REG_CONVERGE_OUT_TH (0x2104)
|
||||
|
||||
|
||||
#define HM01B0_REG_I2C_ID_SEL (0x3400)
|
||||
#define HM01B0_REG_I2C_ID_REG (0x3401)
|
||||
|
||||
#define HM01B0_REG_PMU_PROGRAMMABLE_FRAMECNT (0x3020)
|
||||
|
||||
// #define HM01B0_REG_MODE_SELECT (0x0100)
|
||||
#define HM01B0_REG_MODE_SELECT_STANDBY (0x00)
|
||||
#define HM01B0_REG_MODE_SELECT_STREAMING (0x01)
|
||||
#define HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES (0x03)
|
||||
#define HM01B0_REG_MODE_SELECT_STREAMING_HW_TRIGGER (0x05)
|
||||
|
||||
// #define HM01B0_REG_IMAGE_ORIENTATION (0x0101)
|
||||
#define HM01B0_REG_IMAGE_ORIENTATION_DEFAULT (0x00)
|
||||
#define HM01B0_REG_IMAGE_ORIENTATION_HMIRROR (0x01)
|
||||
#define HM01B0_REG_IMAGE_ORIENTATION_VMIRROR (0x02)
|
||||
#define HM01B0_REG_IMAGE_ORIENTATION_HVMIRROR (HM01B0_REG_IMAGE_ORIENTATION_HMIRROR | HM01B0_REG_IMAGE_ORIENTATION_HVMIRROR)
|
||||
|
||||
// #define HM01B0_REG_GRP_PARAM_HOLD (0x0104)
|
||||
#define HM01B0_REG_GRP_PARAM_HOLD_CONSUME (0x00)
|
||||
#define HM01B0_REG_GRP_PARAM_HOLD_HOLD (0x01)
|
||||
|
||||
enum
|
||||
{
|
||||
HM01B0_ERR_OK = 0x00,
|
||||
HM01B0_ERR_I2C,
|
||||
HM01B0_ERR_MODE,
|
||||
HM01B0_ERR_AE_NOT_CONVERGED,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t ui16Reg;
|
||||
uint8_t ui8Val;
|
||||
} hm_script_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t ui16SlvAddr;
|
||||
am_hal_iom_mode_e eIOMMode;
|
||||
uint32_t ui32IOMModule;
|
||||
am_hal_iom_config_t sIOMCfg;
|
||||
void *pIOMHandle;
|
||||
|
||||
uint32_t ui32CTimerModule;
|
||||
uint32_t ui32CTimerSegment;
|
||||
uint32_t ui32CTimerOutputPin;
|
||||
|
||||
uint8_t ui8PinSCL;
|
||||
uint8_t ui8PinSDA;
|
||||
uint8_t ui8PinD0;
|
||||
uint8_t ui8PinD1;
|
||||
uint8_t ui8PinD2;
|
||||
uint8_t ui8PinD3;
|
||||
uint8_t ui8PinD4;
|
||||
uint8_t ui8PinD5;
|
||||
uint8_t ui8PinD6;
|
||||
uint8_t ui8PinD7;
|
||||
uint8_t ui8PinVSYNC;
|
||||
uint8_t ui8PinHSYNC;
|
||||
uint8_t ui8PinPCLK;
|
||||
|
||||
uint8_t ui8PinTrig;
|
||||
uint8_t ui8PinInt;
|
||||
void (*pfnGpioIsr)(void);
|
||||
} hm01b0_cfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ui8AETargetMean;
|
||||
uint8_t ui8AEMinMean;
|
||||
uint8_t ui8ConvergeInTh;
|
||||
uint8_t ui8ConvergeOutTh;
|
||||
uint8_t ui8AEMean;
|
||||
} hm01b0_ae_cfg_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ui8IntegrationH;
|
||||
uint8_t ui8IntegrationL;
|
||||
uint8_t ui8AGain;
|
||||
uint8_t ui8DGain_H;
|
||||
uint8_t ui8DGain_L;
|
||||
} hm01b0_snr_expo_gain_ctrl_t;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Write HM01B0 registers
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui16Reg - Register address.
|
||||
//! @param pui8Value - Pointer to the data to be written.
|
||||
//! @param ui32NumBytes - Length of the data in bytes to be written.
|
||||
//!
|
||||
//! This function writes value to HM01B0 registers.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_write_reg(hm01b0_cfg_t *psCfg, \
|
||||
uint16_t ui16Reg, uint8_t *pui8Value, uint32_t ui32NumBytes);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Read HM01B0 registers
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui16Reg - Register address.
|
||||
//! @param pui8Value - Pointer to the buffer for read data to be put into.
|
||||
//! @param ui32NumBytes - Length of the data to be read.
|
||||
//!
|
||||
//! This function reads value from HM01B0 registers.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_read_reg(hm01b0_cfg_t *psCfg, \
|
||||
uint16_t ui16Reg, uint8_t *pui8Value, uint32_t ui32NumBytes);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Load HM01B0 a given script
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psScrip - Pointer to the script to be loaded.
|
||||
//! @param ui32ScriptCmdNum - Number of entries in a given script.
|
||||
//!
|
||||
//! This function loads HM01B0 a given script.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_load_script(hm01b0_cfg_t *psCfg, hm_script_t *psScript, uint32_t ui32ScriptCmdNum);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Power up HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function powers up HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_power_up(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Power down HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function powers up HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_power_down(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Enable MCLK
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function utilizes CTimer to generate MCLK for HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_mclk_enable(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Disable MCLK
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function disable CTimer to stop MCLK for HM01B0.
|
||||
//!
|
||||
//! @return none.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_mclk_disable(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Initialize interfaces
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function initializes interfaces.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_init_if(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Deinitialize interfaces
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function deinitializes interfaces.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_deinit_if(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get HM01B0 Model ID
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param pui16MID - Pointer to buffer for the read back model ID.
|
||||
//!
|
||||
//! This function reads back HM01B0 model ID.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_get_modelid(hm01b0_cfg_t *psCfg, uint16_t *pui16MID);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Initialize HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psScript - Pointer to HM01B0 initialization script.
|
||||
//! @param ui32ScriptCmdNum - No. of commands in HM01B0 initialization script.
|
||||
//!
|
||||
//! This function initilizes HM01B0 with a given script.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_init_system(hm01b0_cfg_t *psCfg, hm_script_t *psScript, uint32_t ui32ScriptCmdNum);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Set HM01B0 in the walking 1s test mode
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function sets HM01B0 in the walking 1s test mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_test_walking1s(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Check the data read from HM01B0 in the walking 1s test mode
|
||||
//!
|
||||
//! @param pui8Buffer - Pointer to data buffer.
|
||||
//! @param ui32BufferLen - Buffer length
|
||||
//! @param ui32PrintCnt - Number of mismatched data to be printed out
|
||||
//!
|
||||
//! This function sets HM01B0 in the walking 1s test mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hm01b0_test_walking1s_check_data_sanity(uint8_t *pui8Buffer, uint32_t ui32BufferLen, uint32_t ui32PrintCnt);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Software reset HM01B0
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! This function resets HM01B0 by issuing a reset command.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_reset_sw(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get current HM01B0 operation mode.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param pui8Mode - Pointer to buffer
|
||||
//! - for the read back operation mode to be put into
|
||||
//!
|
||||
//! This function get HM01B0 operation mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_get_mode(hm01b0_cfg_t *psCfg, uint8_t *pui8Mode);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Set HM01B0 operation mode.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui8Mode - Operation mode. One of:
|
||||
//! HM01B0_REG_MODE_SELECT_STANDBY
|
||||
//! HM01B0_REG_MODE_SELECT_STREAMING
|
||||
//! HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES
|
||||
//! HM01B0_REG_MODE_SELECT_STREAMING_HW_TRIGGER
|
||||
//! @param framecnt - Frame count for HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES.
|
||||
//! - Discarded if other modes.
|
||||
//!
|
||||
//! This function set HM01B0 operation mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_set_mode(hm01b0_cfg_t *psCfg, uint8_t ui8Mode, uint8_t framecnt);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Activate the updated settings to HM01B0.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//!
|
||||
//! Some settings updated to HM01B0 will only be affected after calling this function
|
||||
//! 1. AE settings
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_cmd_update(hm01b0_cfg_t *psCfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Get HM01B0 AE settings
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psAECfg - Pointer to the structure hm01b0_ae_cfg_t.
|
||||
//!
|
||||
//! This function checks if AE is converged or not and returns ui32Err accordingly.
|
||||
//! If caller needs detailed AE settings, psAECfg has to be non NULL.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_get_ae(hm01b0_cfg_t *psCfg, hm01b0_ae_cfg_t *psAECfg);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief AE calibration.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param ui8CalFrames - Frame counts for calibratoin.
|
||||
//! @param pui8Buffer - Pointer to the frame buffer.
|
||||
//! @param ui32BufferLen - Framebuffer size.
|
||||
//!
|
||||
//! This function lets HM01B0 AE settled as much as possible within a given frame counts.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_cal_ae(hm01b0_cfg_t *psCfg, uint8_t ui8CalFrames, uint8_t *pui8Buffer, uint32_t ui32BufferLen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Save HM01B0 exposure gain settings.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psExpoGainCtrl - Pointer to the structure hm01b0_snr_expo_gain_ctrl_t
|
||||
//!
|
||||
//! This function saves HM01B0 exposure gain settings.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_save_exposure_gains(hm01b0_cfg_t *psCfg, hm01b0_snr_expo_gain_ctrl_t *psExpoGainCtrl);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Restore HM01B0 exposure gain settings.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param psExpoGainCtrl - Pointer to the structure hm01b0_snr_expo_gain_ctrl_t
|
||||
//!
|
||||
//! This function restores HM01B0 exposure gain settings. The call flow shall be
|
||||
//! hm01b0_restore_exposure_gains() -> hm01b0_cmd_update() -> hm01b0_set_mode()
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_restore_exposure_gains(hm01b0_cfg_t *psCfg, hm01b0_snr_expo_gain_ctrl_t *psExpoGainCtrl);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Hardware trigger HM01B0 to stream.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param bTrigger - True to start streaming
|
||||
//! - False to stop streaming
|
||||
//!
|
||||
//! This function triggers HM01B0 to stream by toggling the TRIG pin.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_hardware_trigger_streaming(hm01b0_cfg_t *psCfg, bool bTrigger);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Set HM01B0 mirror mode.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param bHmirror - Horizontal mirror
|
||||
//! @param bVmirror - Vertical mirror
|
||||
//!
|
||||
//! This function set HM01B0 mirror mode.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_set_mirror(hm01b0_cfg_t *psCfg, bool bHmirror, bool bVmirror);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! @brief Read data of one frame from HM01B0.
|
||||
//!
|
||||
//! @param psCfg - Pointer to HM01B0 configuration structure.
|
||||
//! @param pui8Buffer - Pointer to the frame buffer.
|
||||
//! @param ui32BufferLen - Framebuffer size.
|
||||
//!
|
||||
//! This function read data of one frame from HM01B0.
|
||||
//!
|
||||
//! @return Error code.
|
||||
//
|
||||
//*****************************************************************************
|
||||
uint32_t hm01b0_blocking_read_oneframe(hm01b0_cfg_t *psCfg, \
|
||||
uint8_t *pui8Buffer, uint32_t ui32BufferLen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // AM_HAL_CTIMER_H
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
|
||||
#include "HM01B0.h"
|
||||
|
||||
const hm_script_t sHM01B0InitScript[] =
|
||||
{
|
||||
// ;*************************************************************************
|
||||
// ; Sensor: HM01B0
|
||||
// ; I2C ID: 24
|
||||
// ; Resolution: 324x244
|
||||
// ; Lens:
|
||||
// ; Flicker:
|
||||
// ; Frequency:
|
||||
// ; Description: AE control enable
|
||||
// ; 8-bit mode, LSB first
|
||||
// ;
|
||||
// ;
|
||||
// ; Note:
|
||||
// ;
|
||||
// ; $Revision: 1338 $
|
||||
// ; $Date:: 2017-04-11 15:43:45 +0800#$
|
||||
// ;*************************************************************************
|
||||
//
|
||||
// // ---------------------------------------------------
|
||||
// // HUB system initial
|
||||
// // ---------------------------------------------------
|
||||
// W 20 8A04 01 2 1
|
||||
// W 20 8A00 22 2 1
|
||||
// W 20 8A01 00 2 1
|
||||
// W 20 8A02 01 2 1
|
||||
// W 20 0035 93 2 1 ; [3]&[1] hub616 20bits in, [5:4]=1 mclk=48/2=24mhz
|
||||
// W 20 0036 00 2 1
|
||||
// W 20 0011 09 2 1
|
||||
// W 20 0012 B6 2 1
|
||||
// W 20 0014 08 2 1
|
||||
// W 20 0015 98 2 1
|
||||
// ;W 20 0130 16 2 1 ; 3m soc, signal buffer control
|
||||
// ;W 20 0100 44 2 1 ; [6] hub616 20bits in
|
||||
// W 20 0100 04 2 1 ; [6] hub616 20bits in
|
||||
// W 20 0121 01 2 1 ; [0] Q1 Intf enable, [1]:4bit mode, [2] msb first, [3] serial mode
|
||||
// W 20 0150 00 2 1 ;
|
||||
// W 20 0150 04 2 1 ;
|
||||
//
|
||||
//
|
||||
// //---------------------------------------------------
|
||||
// // Initial
|
||||
// //---------------------------------------------------
|
||||
// W 24 0103 00 2 1 ; software reset-> was 0x22
|
||||
{0x0103, 0x00,},
|
||||
// W 24 0100 00 2 1; power up
|
||||
{0x0100, 0x00,},
|
||||
//
|
||||
//
|
||||
//
|
||||
// //---------------------------------------------------
|
||||
// // Analog
|
||||
// //---------------------------------------------------
|
||||
// L HM01B0_analog_setting.txt
|
||||
{0x1003, 0x08,},
|
||||
{0x1007, 0x08,},
|
||||
{0x3044, 0x0A,},
|
||||
{0x3045, 0x00,},
|
||||
{0x3047, 0x0A,},
|
||||
{0x3050, 0xC0,},
|
||||
{0x3051, 0x42,},
|
||||
{0x3052, 0x50,},
|
||||
{0x3053, 0x00,},
|
||||
{0x3054, 0x03,},
|
||||
{0x3055, 0xF7,},
|
||||
{0x3056, 0xF8,},
|
||||
{0x3057, 0x29,},
|
||||
{0x3058, 0x1F,},
|
||||
{0x3059, 0x1E,},
|
||||
{0x3064, 0x00,},
|
||||
{0x3065, 0x04,},
|
||||
//
|
||||
//
|
||||
// //---------------------------------------------------
|
||||
// // Digital function
|
||||
// //---------------------------------------------------
|
||||
//
|
||||
// // BLC
|
||||
// W 24 1000 43 2 1 ; BLC_on, IIR
|
||||
{0x1000, 0x43,},
|
||||
// W 24 1001 40 2 1 ; [6] : BLC dithering en
|
||||
{0x1001, 0x40,},
|
||||
// W 24 1002 32 2 1 ; // blc_darkpixel_thd
|
||||
{0x1002, 0x32,},
|
||||
//
|
||||
// // Dgain
|
||||
// W 24 0350 7F 2 1 ; Dgain Control
|
||||
{0x0350, 0x7F,},
|
||||
//
|
||||
// // BLI
|
||||
// W 24 1006 01 2 1 ; [0] : bli enable
|
||||
{0x1006, 0x01,},
|
||||
//
|
||||
// // DPC
|
||||
// W 24 1008 00 2 1 ; [2:0] : DPC option 0: DPC off 1 : mono 3 : bayer1 5 : bayer2
|
||||
{0x1008, 0x00,},
|
||||
// W 24 1009 A0 2 1 ; cluster hot pixel th
|
||||
{0x1009, 0xA0,},
|
||||
// W 24 100A 60 2 1 ; cluster cold pixel th
|
||||
{0x100A, 0x60,},
|
||||
// W 24 100B 90 2 1 ; single hot pixel th
|
||||
{0x100B, 0x90,},
|
||||
// W 24 100C 40 2 1 ; single cold pixel th
|
||||
{0x100C, 0x40,},
|
||||
// //
|
||||
// advance VSYNC by 1 row
|
||||
{0x3022, 0x01,},
|
||||
// W 24 1012 00 2 1 ; Sync. enable VSYNC shift
|
||||
{0x1012, 0x01,},
|
||||
|
||||
//
|
||||
// // ROI Statistic
|
||||
// W 24 2000 07 2 1 ; [0] : AE stat en [1] : MD LROI stat en [2] : MD GROI stat en [3] : RGB stat ratio en [4] : IIR selection (1 -> 16, 0 -> 8)
|
||||
{0x2000, 0x07,},
|
||||
// W 24 2003 00 2 1 ; MD GROI 0 y start HB
|
||||
{0x2003, 0x00,},
|
||||
// W 24 2004 1C 2 1 ; MD GROI 0 y start LB
|
||||
{0x2004, 0x1C,},
|
||||
// W 24 2007 00 2 1 ; MD GROI 1 y start HB
|
||||
{0x2007, 0x00,},
|
||||
// W 24 2008 58 2 1 ; MD GROI 1 y start LB
|
||||
{0x2008, 0x58,},
|
||||
// W 24 200B 00 2 1 ; MD GROI 2 y start HB
|
||||
{0x200B, 0x00,},
|
||||
// W 24 200C 7A 2 1 ; MD GROI 2 y start LB
|
||||
{0x200C, 0x7A,},
|
||||
// W 24 200F 00 2 1 ; MD GROI 3 y start HB
|
||||
{0x200F, 0x00,},
|
||||
// W 24 2010 B8 2 1 ; MD GROI 3 y start LB
|
||||
{0x2010, 0xB8,},
|
||||
//
|
||||
// W 24 2013 00 2 1 ; MD LRIO y start HB
|
||||
{0x2013, 0x00,},
|
||||
// W 24 2014 58 2 1 ; MD LROI y start LB
|
||||
{0x2014, 0x58,},
|
||||
// W 24 2017 00 2 1 ; MD LROI y end HB
|
||||
{0x2017, 0x00,},
|
||||
// W 24 2018 9B 2 1 ; MD LROI y end LB
|
||||
{0x2018, 0x9B,},
|
||||
//
|
||||
// // AE
|
||||
// W 24 2100 01 2 1 ; [0]: AE control enable
|
||||
{0x2100, 0x01,},
|
||||
// W 24 2104 07 2 1 ; converge out th
|
||||
{0x2104, 0x07,},
|
||||
// W 24 2105 0C 2 1 ; max INTG Hb
|
||||
{0x2105, 0x0C,},
|
||||
// W 24 2106 78 2 1 ; max INTG Lb
|
||||
{0x2106, 0x78,},
|
||||
// W 24 2108 03 2 1 ; max AGain in full
|
||||
{0x2108, 0x03,},
|
||||
// W 24 2109 03 2 1 ; max AGain in bin2
|
||||
{0x2109, 0x03,},
|
||||
// W 24 210B 80 2 1 ; max DGain
|
||||
{0x210B, 0x80,},
|
||||
// W 24 210F 00 2 1 ; FS 60Hz Hb
|
||||
{0x210F, 0x00,},
|
||||
// W 24 2110 85 2 1 ; FS 60Hz Lb
|
||||
{0x2110, 0x85,},
|
||||
// W 24 2111 00 2 1 ; Fs 50Hz Hb
|
||||
{0x2111, 0x00,},
|
||||
// W 24 2112 A0 2 1 ; FS 50Hz Lb
|
||||
{0x2112, 0xA0,},
|
||||
//
|
||||
//
|
||||
// // MD
|
||||
// W 24 2150 03 2 1 ; [0] : MD LROI en [1] : MD GROI en
|
||||
{0x2150, 0x03,},
|
||||
//
|
||||
//
|
||||
// //---------------------------------------------------
|
||||
// // frame rate : 5 FPS
|
||||
// //---------------------------------------------------
|
||||
// W 24 0340 0C 2 1 ; smia frame length Hb
|
||||
{0x0340, 0x0C,},
|
||||
// W 24 0341 7A 2 1 ; smia frame length Lb 3192
|
||||
{0x0341, 0x7A,},
|
||||
//
|
||||
// W 24 0342 01 2 1 ; smia line length Hb
|
||||
{0x0342, 0x01,},
|
||||
// W 24 0343 77 2 1 ; smia line length Lb 375
|
||||
{0x0343, 0x77,},
|
||||
//
|
||||
// //---------------------------------------------------
|
||||
// // Resolution : QVGA 324x244
|
||||
// //---------------------------------------------------
|
||||
// W 24 3010 01 2 1 ; [0] : window mode 0 : full frame 324x324 1 : QVGA
|
||||
{0x3010, 0x01,},
|
||||
//
|
||||
//
|
||||
// W 24 0383 01 2 1 ;
|
||||
{0x0383, 0x01,},
|
||||
// W 24 0387 01 2 1 ;
|
||||
{0x0387, 0x01,},
|
||||
// W 24 0390 00 2 1 ;
|
||||
{0x0390, 0x00,},
|
||||
//
|
||||
// //---------------------------------------------------
|
||||
// // bit width Selection
|
||||
// //---------------------------------------------------
|
||||
// W 24 3011 70 2 1 ; [0] : 6 bit mode enable
|
||||
{0x3011, 0x70,},
|
||||
//
|
||||
//
|
||||
// W 24 3059 02 2 1 ; [7]: Self OSC En, [6]: 4bit mode, [5]: serial mode, [4:0]: keep value as 0x02
|
||||
{0x3059, 0x02,},
|
||||
// W 24 3060 01 2 1 ; [5]: gated_clock, [4]: msb first,
|
||||
{0x3060, 0x20,},
|
||||
// ; [3:2]: vt_reg_div -> div by 4/8/1/2
|
||||
// ; [1;0]: vt_sys_div -> div by 8/4/2/1
|
||||
//
|
||||
//
|
||||
{0x0101, 0x01,},
|
||||
// //---------------------------------------------------
|
||||
// // CMU update
|
||||
// //---------------------------------------------------
|
||||
//
|
||||
// W 24 0104 01 2 1 ; was 0100
|
||||
{0x0104, 0x01,},
|
||||
//
|
||||
//
|
||||
//
|
||||
// //---------------------------------------------------
|
||||
// // Turn on rolling shutter
|
||||
// //---------------------------------------------------
|
||||
// W 24 0100 01 2 1 ; was 0005 ; mode_select 00 : standby - wait fir I2C SW trigger 01 : streaming 03 : output "N" frame, then enter standby 04 : standby - wait for HW trigger (level), then continuous video out til HW TRIG goes off 06 : standby - wait for HW trigger (edge), then output "N" frames then enter standby
|
||||
{0x0100, 0x00,},
|
||||
//
|
||||
// ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
};
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
|
||||
#include "HM01B0.h"
|
||||
|
||||
const hm_script_t sHM01b0TestModeScript_Walking1s[] =
|
||||
{
|
||||
{0x2100, 0x00,}, //W 24 2100 00 2 1 ; AE
|
||||
{0x1000, 0x00,}, //W 24 1000 00 2 1 ; BLC
|
||||
{0x1008, 0x00,}, //W 24 1008 00 2 1 ; DPC
|
||||
{0x0205, 0x00,}, //W 24 0205 00 2 1 ; AGain
|
||||
{0x020E, 0x01,}, //W 24 020E 01 2 1 ; DGain
|
||||
{0x020F, 0x00,}, //W 24 020F 00 2 1 ; DGain
|
||||
{0x0601, 0x11,}, //W 24 0601 11 2 1 ; Test pattern
|
||||
{0x0104, 0x01,}, //W 24 0104 01 2 1 ;
|
||||
};
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// 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.
|
||||
*/
|
||||
|
||||
#ifndef HM01B0_PLATFORM_H
|
||||
#define HM01B0_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define HM01B0_PIN_D0 AM_BSP_GPIO_CAMERA_HM01B0_D0
|
||||
#define HM01B0_PIN_D1 AM_BSP_GPIO_CAMERA_HM01B0_D1
|
||||
#define HM01B0_PIN_D2 AM_BSP_GPIO_CAMERA_HM01B0_D2
|
||||
#define HM01B0_PIN_D3 AM_BSP_GPIO_CAMERA_HM01B0_D3
|
||||
#define HM01B0_PIN_D4 AM_BSP_GPIO_CAMERA_HM01B0_D4
|
||||
#define HM01B0_PIN_D5 AM_BSP_GPIO_CAMERA_HM01B0_D5
|
||||
#define HM01B0_PIN_D6 AM_BSP_GPIO_CAMERA_HM01B0_D6
|
||||
#define HM01B0_PIN_D7 AM_BSP_GPIO_CAMERA_HM01B0_D7
|
||||
#define HM01B0_PIN_VSYNC AM_BSP_GPIO_CAMERA_HM01B0_VSYNC
|
||||
#define HM01B0_PIN_HSYNC AM_BSP_GPIO_CAMERA_HM01B0_HSYNC
|
||||
#define HM01B0_PIN_PCLK AM_BSP_GPIO_CAMERA_HM01B0_PCLK
|
||||
#define HM01B0_PIN_SCL AM_BSP_CAMERA_HM01B0_I2C_SCL_PIN
|
||||
#define HM01B0_PIN_SDA AM_BSP_CAMERA_HM01B0_I2C_SDA_PIN
|
||||
|
||||
|
||||
// Some boards do not support TRIG or INT pins
|
||||
#ifdef AM_BSP_GPIO_CAMERA_HM01B0_TRIG
|
||||
#define HM01B0_PIN_TRIG AM_BSP_GPIO_CAMERA_HM01B0_TRIG
|
||||
#endif // AM_BSP_GPIO_CAMERA_HM01B0_TRIG
|
||||
|
||||
#ifdef AM_BSP_GPIO_CAMERA_HM01B0_INT
|
||||
#define HM01B0_PIN_INT AM_BSP_GPIO_CAMERA_HM01B0_INT
|
||||
#endif // AM_BSP_GPIO_CAMERA_HM01B0_INT
|
||||
|
||||
|
||||
// Define AP3B's CTIMER and output pin for HM01B0 MCLK generation
|
||||
#define HM01B0_MCLK_GENERATOR_MOD AM_BSP_CAMERA_HM01B0_MCLK_GEN_MOD
|
||||
#define HM01B0_MCLK_GENERATOR_SEG AM_BSP_CAMERA_HM01B0_MCLK_GEN_SEG
|
||||
#define HM01B0_PIN_MCLK AM_BSP_CAMERA_HM01B0_MCLK_PIN
|
||||
|
||||
// Deifne I2C controller and SCL(pin8)/SDA(pin9) are configured automatically.
|
||||
#define HM01B0_IOM_MODE AM_HAL_IOM_I2C_MODE
|
||||
#define HM01B0_IOM_MODULE AM_BSP_CAMERA_HM01B0_I2C_IOM
|
||||
#define HM01B0_I2C_CLOCK_FREQ AM_HAL_IOM_100KHZ
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HM01B0_PLATFORM_H
|
||||
Vendored
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
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 "lis2dh12_platform_apollo3.h"
|
||||
|
||||
/*
|
||||
* @brief Write generic device register (platform dependent)
|
||||
*
|
||||
* @param handle customizable argument. In this examples is used in
|
||||
* order to select the correct sensor bus handler.
|
||||
* @param reg register to write
|
||||
* @param bufp pointer to data to write in register reg
|
||||
* @param len number of consecutive register to write
|
||||
*
|
||||
*/
|
||||
int32_t lis2dh12_write_platform_apollo3(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
|
||||
{
|
||||
uint32_t retVal32 = 0;
|
||||
lis2dh12_platform_apollo3_if_t* pif = (lis2dh12_platform_apollo3_if_t*)handle;
|
||||
am_hal_iom_transfer_t iomTransfer = {0};
|
||||
|
||||
if( bufp == NULL ) { return AM_HAL_STATUS_FAIL; }
|
||||
if( pif == NULL ) { return AM_HAL_STATUS_FAIL; }
|
||||
if( pif->iomHandle == NULL) { return AM_HAL_STATUS_FAIL; }
|
||||
|
||||
// Set up transfer
|
||||
iomTransfer.uPeerInfo.ui32I2CDevAddr = pif->addCS;
|
||||
iomTransfer.ui32InstrLen = 1;
|
||||
iomTransfer.ui32Instr = (reg | 0x80);
|
||||
iomTransfer.ui32NumBytes = len;
|
||||
iomTransfer.eDirection = AM_HAL_IOM_TX;
|
||||
iomTransfer.pui32TxBuffer = (uint32_t*)bufp;
|
||||
iomTransfer.pui32RxBuffer = NULL;
|
||||
iomTransfer.bContinue = false;
|
||||
|
||||
if( pif->useSPI ){
|
||||
// ToDo: Support SPI w/ CS assertion
|
||||
}
|
||||
|
||||
// Send the transfer
|
||||
retVal32 = am_hal_iom_blocking_transfer(pif->iomHandle, &iomTransfer);
|
||||
|
||||
if( pif->useSPI ){
|
||||
// ToDo: Support SPI / CS de-assertion
|
||||
}
|
||||
|
||||
if( retVal32 != AM_HAL_STATUS_SUCCESS ){ return retVal32; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Read generic device register (platform dependent)
|
||||
*
|
||||
* @param handle customizable argument. In this examples is used in
|
||||
* order to select the correct sensor bus handler.
|
||||
* @param reg register to read
|
||||
* @param bufp pointer to buffer that store the data read
|
||||
* @param len number of consecutive register to read
|
||||
*
|
||||
*/
|
||||
int32_t lis2dh12_read_platform_apollo3(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
|
||||
{
|
||||
uint32_t retVal32 = 0;
|
||||
lis2dh12_platform_apollo3_if_t* pif = (lis2dh12_platform_apollo3_if_t*)handle;
|
||||
am_hal_iom_transfer_t iomTransfer = {0};
|
||||
|
||||
if( bufp == NULL ) { return AM_HAL_STATUS_FAIL; }
|
||||
if( pif == NULL ) { return AM_HAL_STATUS_FAIL; }
|
||||
if( pif->iomHandle == NULL) { return AM_HAL_STATUS_FAIL; }
|
||||
|
||||
// Set up first transfer
|
||||
iomTransfer.uPeerInfo.ui32I2CDevAddr = pif->addCS;
|
||||
iomTransfer.ui32InstrLen = 1;
|
||||
iomTransfer.ui32Instr = (reg | 0x80);
|
||||
iomTransfer.ui32NumBytes = 0;
|
||||
iomTransfer.eDirection = AM_HAL_IOM_TX;
|
||||
iomTransfer.bContinue = true;
|
||||
|
||||
if( pif->useSPI ){
|
||||
// ToDo: Support SPI w/ CS assertion
|
||||
}
|
||||
|
||||
// Send the first transfer
|
||||
retVal32 = am_hal_iom_blocking_transfer(pif->iomHandle, &iomTransfer);
|
||||
if( retVal32 != AM_HAL_STATUS_SUCCESS ){ return retVal32; }
|
||||
|
||||
// Change direction, and add the rx buffer
|
||||
iomTransfer.eDirection = AM_HAL_IOM_RX;
|
||||
iomTransfer.pui32RxBuffer = (uint32_t*)bufp;
|
||||
iomTransfer.ui32NumBytes = len;
|
||||
iomTransfer.bContinue = false;
|
||||
|
||||
// Send the second transfer
|
||||
retVal32 = am_hal_iom_blocking_transfer(pif->iomHandle, &iomTransfer);
|
||||
|
||||
if( retVal32 != AM_HAL_STATUS_SUCCESS ){ return retVal32; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef _LIS2DH12_PLATFORM_APOLLO3_H_
|
||||
#define _LIS2DH12_PLATFORM_APOLLO3_H_
|
||||
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "lis2dh12_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _lis2dh12_platform_apollo3_if_t {
|
||||
void* iomHandle; // IO Master instance
|
||||
uint8_t addCS; // I2C mode: the 7-bit I2C address (either 0x18 or 0x19 depeding on SA0 pin)
|
||||
// SPI mode: the Apollo3 pad to use for chip select
|
||||
bool useSPI; // Set 'true' if using SPI mode, else 'false'
|
||||
}lis2dh12_platform_apollo3_if_t;
|
||||
|
||||
int32_t lis2dh12_write_platform_apollo3(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len);
|
||||
int32_t lis2dh12_read_platform_apollo3(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _LIS2DH12_PLATFORM_APOLLO3_H_
|
||||
+2398
File diff suppressed because it is too large
Load Diff
+763
@@ -0,0 +1,763 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* @file lis2dh12_reg.h
|
||||
* @author Sensors Software Solution Team
|
||||
* @brief This file contains all the functions prototypes for the
|
||||
* lis2dh12_reg.c driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
|
||||
*
|
||||
* 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 STMicroelectronics nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef LIS2DH12_REGS_H
|
||||
#define LIS2DH12_REGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
/** @addtogroup LIS2DH12
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/** @defgroup LIS2DH12_sensors_common_types
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MEMS_SHARED_TYPES
|
||||
#define MEMS_SHARED_TYPES
|
||||
|
||||
/**
|
||||
* @defgroup axisXbitXX_t
|
||||
* @brief These unions are useful to represent different sensors data type.
|
||||
* These unions are not need by the driver.
|
||||
*
|
||||
* REMOVING the unions you are compliant with:
|
||||
* MISRA-C 2012 [Rule 19.2] -> " Union are not allowed "
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
typedef union{
|
||||
int16_t i16bit[3];
|
||||
uint8_t u8bit[6];
|
||||
} axis3bit16_t;
|
||||
|
||||
typedef union{
|
||||
int16_t i16bit;
|
||||
uint8_t u8bit[2];
|
||||
} axis1bit16_t;
|
||||
|
||||
typedef union{
|
||||
int32_t i32bit[3];
|
||||
uint8_t u8bit[12];
|
||||
} axis3bit32_t;
|
||||
|
||||
typedef union{
|
||||
int32_t i32bit;
|
||||
uint8_t u8bit[4];
|
||||
} axis1bit32_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct{
|
||||
uint8_t bit0 : 1;
|
||||
uint8_t bit1 : 1;
|
||||
uint8_t bit2 : 1;
|
||||
uint8_t bit3 : 1;
|
||||
uint8_t bit4 : 1;
|
||||
uint8_t bit5 : 1;
|
||||
uint8_t bit6 : 1;
|
||||
uint8_t bit7 : 1;
|
||||
} bitwise_t;
|
||||
|
||||
#define PROPERTY_DISABLE (0U)
|
||||
#define PROPERTY_ENABLE (1U)
|
||||
|
||||
#endif /* MEMS_SHARED_TYPES */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
/** @addtogroup LIS3MDL_Interfaces_Functions
|
||||
* @brief This section provide a set of functions used to read and
|
||||
* write a generic register of the device.
|
||||
* MANDATORY: return 0 -> no Error.
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
typedef int32_t (*lis2dh12_write_ptr)(void *, uint8_t, uint8_t*, uint16_t);
|
||||
typedef int32_t (*lis2dh12_read_ptr) (void *, uint8_t, uint8_t*, uint16_t);
|
||||
|
||||
typedef struct {
|
||||
/** Component mandatory fields **/
|
||||
lis2dh12_write_ptr write_reg;
|
||||
lis2dh12_read_ptr read_reg;
|
||||
/** Customizable optional pointer **/
|
||||
void *handle;
|
||||
} lis2dh12_ctx_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
/** @defgroup LIS2DH12_Infos
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/** I2C Device Address 8 bit format if SA0=0 -> 31 if SA0=1 -> 33 **/
|
||||
#define LIS2DH12_I2C_ADD_L 0x31U
|
||||
#define LIS2DH12_I2C_ADD_H 0x33U
|
||||
|
||||
/** Device Identification (Who am I) **/
|
||||
#define LIS2DH12_ID 0x33U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#define LIS2DH12_STATUS_REG_AUX 0x07U
|
||||
typedef struct {
|
||||
uint8_t not_used_01 : 2;
|
||||
uint8_t tda : 1;
|
||||
uint8_t not_used_02 : 3;
|
||||
uint8_t tor : 1;
|
||||
uint8_t not_used_03 : 1;
|
||||
} lis2dh12_status_reg_aux_t;
|
||||
|
||||
#define LIS2DH12_OUT_TEMP_L 0x0CU
|
||||
#define LIS2DH12_OUT_TEMP_H 0x0DU
|
||||
#define LIS2DH12_WHO_AM_I 0x0FU
|
||||
|
||||
#define LIS2DH12_CTRL_REG0 0x1EU
|
||||
typedef struct {
|
||||
uint8_t not_used_01 : 7;
|
||||
uint8_t sdo_pu_disc : 1;
|
||||
} lis2dh12_ctrl_reg0_t;
|
||||
|
||||
#define LIS2DH12_TEMP_CFG_REG 0x1FU
|
||||
typedef struct {
|
||||
uint8_t not_used_01 : 6;
|
||||
uint8_t temp_en : 2;
|
||||
} lis2dh12_temp_cfg_reg_t;
|
||||
|
||||
#define LIS2DH12_CTRL_REG1 0x20U
|
||||
typedef struct {
|
||||
uint8_t xen : 1;
|
||||
uint8_t yen : 1;
|
||||
uint8_t zen : 1;
|
||||
uint8_t lpen : 1;
|
||||
uint8_t odr : 4;
|
||||
} lis2dh12_ctrl_reg1_t;
|
||||
|
||||
#define LIS2DH12_CTRL_REG2 0x21U
|
||||
typedef struct {
|
||||
uint8_t hp : 3; /* HPCLICK + HP_IA2 + HP_IA1 -> HP */
|
||||
uint8_t fds : 1;
|
||||
uint8_t hpcf : 2;
|
||||
uint8_t hpm : 2;
|
||||
} lis2dh12_ctrl_reg2_t;
|
||||
|
||||
#define LIS2DH12_CTRL_REG3 0x22U
|
||||
typedef struct {
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t i1_overrun : 1;
|
||||
uint8_t i1_wtm : 1;
|
||||
uint8_t not_used_02 : 1;
|
||||
uint8_t i1_zyxda : 1;
|
||||
uint8_t i1_ia2 : 1;
|
||||
uint8_t i1_ia1 : 1;
|
||||
uint8_t i1_click : 1;
|
||||
} lis2dh12_ctrl_reg3_t;
|
||||
|
||||
#define LIS2DH12_CTRL_REG4 0x23U
|
||||
typedef struct {
|
||||
uint8_t sim : 1;
|
||||
uint8_t st : 2;
|
||||
uint8_t hr : 1;
|
||||
uint8_t fs : 2;
|
||||
uint8_t ble : 1;
|
||||
uint8_t bdu : 1;
|
||||
} lis2dh12_ctrl_reg4_t;
|
||||
|
||||
#define LIS2DH12_CTRL_REG5 0x24U
|
||||
typedef struct {
|
||||
uint8_t d4d_int2 : 1;
|
||||
uint8_t lir_int2 : 1;
|
||||
uint8_t d4d_int1 : 1;
|
||||
uint8_t lir_int1 : 1;
|
||||
uint8_t not_used_01 : 2;
|
||||
uint8_t fifo_en : 1;
|
||||
uint8_t boot : 1;
|
||||
} lis2dh12_ctrl_reg5_t;
|
||||
|
||||
#define LIS2DH12_CTRL_REG6 0x25U
|
||||
typedef struct {
|
||||
uint8_t not_used_01 : 1;
|
||||
uint8_t int_polarity : 1;
|
||||
uint8_t not_used_02 : 1;
|
||||
uint8_t i2_act : 1;
|
||||
uint8_t i2_boot : 1;
|
||||
uint8_t i2_ia2 : 1;
|
||||
uint8_t i2_ia1 : 1;
|
||||
uint8_t i2_click : 1;
|
||||
} lis2dh12_ctrl_reg6_t;
|
||||
|
||||
#define LIS2DH12_REFERENCE 0x26U
|
||||
#define LIS2DH12_STATUS_REG 0x27U
|
||||
typedef struct {
|
||||
uint8_t xda : 1;
|
||||
uint8_t yda : 1;
|
||||
uint8_t zda : 1;
|
||||
uint8_t zyxda : 1;
|
||||
uint8_t _xor : 1;
|
||||
uint8_t yor : 1;
|
||||
uint8_t zor : 1;
|
||||
uint8_t zyxor : 1;
|
||||
} lis2dh12_status_reg_t;
|
||||
|
||||
#define LIS2DH12_OUT_X_L 0x28U
|
||||
#define LIS2DH12_OUT_X_H 0x29U
|
||||
#define LIS2DH12_OUT_Y_L 0x2AU
|
||||
#define LIS2DH12_OUT_Y_H 0x2BU
|
||||
#define LIS2DH12_OUT_Z_L 0x2CU
|
||||
#define LIS2DH12_OUT_Z_H 0x2DU
|
||||
#define LIS2DH12_FIFO_CTRL_REG 0x2EU
|
||||
typedef struct {
|
||||
uint8_t fth : 5;
|
||||
uint8_t tr : 1;
|
||||
uint8_t fm : 2;
|
||||
} lis2dh12_fifo_ctrl_reg_t;
|
||||
|
||||
#define LIS2DH12_FIFO_SRC_REG 0x2FU
|
||||
typedef struct {
|
||||
uint8_t fss : 5;
|
||||
uint8_t empty : 1;
|
||||
uint8_t ovrn_fifo : 1;
|
||||
uint8_t wtm : 1;
|
||||
} lis2dh12_fifo_src_reg_t;
|
||||
|
||||
#define LIS2DH12_INT1_CFG 0x30U
|
||||
typedef struct {
|
||||
uint8_t xlie : 1;
|
||||
uint8_t xhie : 1;
|
||||
uint8_t ylie : 1;
|
||||
uint8_t yhie : 1;
|
||||
uint8_t zlie : 1;
|
||||
uint8_t zhie : 1;
|
||||
uint8_t _6d : 1;
|
||||
uint8_t aoi : 1;
|
||||
} lis2dh12_int1_cfg_t;
|
||||
|
||||
#define LIS2DH12_INT1_SRC 0x31U
|
||||
typedef struct {
|
||||
uint8_t xl : 1;
|
||||
uint8_t xh : 1;
|
||||
uint8_t yl : 1;
|
||||
uint8_t yh : 1;
|
||||
uint8_t zl : 1;
|
||||
uint8_t zh : 1;
|
||||
uint8_t ia : 1;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_int1_src_t;
|
||||
|
||||
#define LIS2DH12_INT1_THS 0x32U
|
||||
typedef struct {
|
||||
uint8_t ths : 7;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_int1_ths_t;
|
||||
|
||||
#define LIS2DH12_INT1_DURATION 0x33U
|
||||
typedef struct {
|
||||
uint8_t d : 7;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_int1_duration_t;
|
||||
|
||||
#define LIS2DH12_INT2_CFG 0x34U
|
||||
typedef struct {
|
||||
uint8_t xlie : 1;
|
||||
uint8_t xhie : 1;
|
||||
uint8_t ylie : 1;
|
||||
uint8_t yhie : 1;
|
||||
uint8_t zlie : 1;
|
||||
uint8_t zhie : 1;
|
||||
uint8_t _6d : 1;
|
||||
uint8_t aoi : 1;
|
||||
} lis2dh12_int2_cfg_t;
|
||||
|
||||
#define LIS2DH12_INT2_SRC 0x35U
|
||||
typedef struct {
|
||||
uint8_t xl : 1;
|
||||
uint8_t xh : 1;
|
||||
uint8_t yl : 1;
|
||||
uint8_t yh : 1;
|
||||
uint8_t zl : 1;
|
||||
uint8_t zh : 1;
|
||||
uint8_t ia : 1;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_int2_src_t;
|
||||
|
||||
#define LIS2DH12_INT2_THS 0x36U
|
||||
typedef struct {
|
||||
uint8_t ths : 7;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_int2_ths_t;
|
||||
|
||||
#define LIS2DH12_INT2_DURATION 0x37U
|
||||
typedef struct {
|
||||
uint8_t d : 7;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_int2_duration_t;
|
||||
|
||||
#define LIS2DH12_CLICK_CFG 0x38U
|
||||
typedef struct {
|
||||
uint8_t xs : 1;
|
||||
uint8_t xd : 1;
|
||||
uint8_t ys : 1;
|
||||
uint8_t yd : 1;
|
||||
uint8_t zs : 1;
|
||||
uint8_t zd : 1;
|
||||
uint8_t not_used_01 : 2;
|
||||
} lis2dh12_click_cfg_t;
|
||||
|
||||
#define LIS2DH12_CLICK_SRC 0x39U
|
||||
typedef struct {
|
||||
uint8_t x : 1;
|
||||
uint8_t y : 1;
|
||||
uint8_t z : 1;
|
||||
uint8_t sign : 1;
|
||||
uint8_t sclick : 1;
|
||||
uint8_t dclick : 1;
|
||||
uint8_t ia : 1;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_click_src_t;
|
||||
|
||||
#define LIS2DH12_CLICK_THS 0x3AU
|
||||
typedef struct {
|
||||
uint8_t ths : 7;
|
||||
uint8_t lir_click : 1;
|
||||
} lis2dh12_click_ths_t;
|
||||
|
||||
#define LIS2DH12_TIME_LIMIT 0x3BU
|
||||
typedef struct {
|
||||
uint8_t tli : 7;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_time_limit_t;
|
||||
|
||||
#define LIS2DH12_TIME_LATENCY 0x3CU
|
||||
typedef struct {
|
||||
uint8_t tla : 8;
|
||||
} lis2dh12_time_latency_t;
|
||||
|
||||
#define LIS2DH12_TIME_WINDOW 0x3DU
|
||||
typedef struct {
|
||||
uint8_t tw : 8;
|
||||
} lis2dh12_time_window_t;
|
||||
|
||||
#define LIS2DH12_ACT_THS 0x3EU
|
||||
typedef struct {
|
||||
uint8_t acth : 7;
|
||||
uint8_t not_used_01 : 1;
|
||||
} lis2dh12_act_ths_t;
|
||||
|
||||
#define LIS2DH12_ACT_DUR 0x3FU
|
||||
typedef struct {
|
||||
uint8_t actd : 8;
|
||||
} lis2dh12_act_dur_t;
|
||||
|
||||
/**
|
||||
* @defgroup LIS2DH12_Register_Union
|
||||
* @brief This union group all the registers that has a bitfield
|
||||
* description.
|
||||
* This union is usefull but not need by the driver.
|
||||
*
|
||||
* REMOVING this union you are complient with:
|
||||
* MISRA-C 2012 [Rule 19.2] -> " Union are not allowed "
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
typedef union{
|
||||
lis2dh12_status_reg_aux_t status_reg_aux;
|
||||
lis2dh12_ctrl_reg0_t ctrl_reg0;
|
||||
lis2dh12_temp_cfg_reg_t temp_cfg_reg;
|
||||
lis2dh12_ctrl_reg1_t ctrl_reg1;
|
||||
lis2dh12_ctrl_reg2_t ctrl_reg2;
|
||||
lis2dh12_ctrl_reg3_t ctrl_reg3;
|
||||
lis2dh12_ctrl_reg4_t ctrl_reg4;
|
||||
lis2dh12_ctrl_reg5_t ctrl_reg5;
|
||||
lis2dh12_ctrl_reg6_t ctrl_reg6;
|
||||
lis2dh12_status_reg_t status_reg;
|
||||
lis2dh12_fifo_ctrl_reg_t fifo_ctrl_reg;
|
||||
lis2dh12_fifo_src_reg_t fifo_src_reg;
|
||||
lis2dh12_int1_cfg_t int1_cfg;
|
||||
lis2dh12_int1_src_t int1_src;
|
||||
lis2dh12_int1_ths_t int1_ths;
|
||||
lis2dh12_int1_duration_t int1_duration;
|
||||
lis2dh12_int2_cfg_t int2_cfg;
|
||||
lis2dh12_int2_src_t int2_src;
|
||||
lis2dh12_int2_ths_t int2_ths;
|
||||
lis2dh12_int2_duration_t int2_duration;
|
||||
lis2dh12_click_cfg_t click_cfg;
|
||||
lis2dh12_click_src_t click_src;
|
||||
lis2dh12_click_ths_t click_ths;
|
||||
lis2dh12_time_limit_t time_limit;
|
||||
lis2dh12_time_latency_t time_latency;
|
||||
lis2dh12_time_window_t time_window;
|
||||
lis2dh12_act_ths_t act_ths;
|
||||
lis2dh12_act_dur_t act_dur;
|
||||
bitwise_t bitwise;
|
||||
uint8_t byte;
|
||||
} lis2dh12_reg_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
int32_t lis2dh12_read_reg(lis2dh12_ctx_t *ctx, uint8_t reg, uint8_t* data,
|
||||
uint16_t len);
|
||||
int32_t lis2dh12_write_reg(lis2dh12_ctx_t *ctx, uint8_t reg, uint8_t* data,
|
||||
uint16_t len);
|
||||
|
||||
extern float lis2dh12_from_fs2_hr_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs4_hr_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs8_hr_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs16_hr_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_lsb_hr_to_celsius(int16_t lsb);
|
||||
|
||||
extern float lis2dh12_from_fs2_nm_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs4_nm_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs8_nm_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs16_nm_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_lsb_nm_to_celsius(int16_t lsb);
|
||||
|
||||
extern float lis2dh12_from_fs2_lp_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs4_lp_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs8_lp_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_fs16_lp_to_mg(int16_t lsb);
|
||||
extern float lis2dh12_from_lsb_lp_to_celsius(int16_t lsb);
|
||||
|
||||
int32_t lis2dh12_temp_status_reg_get(lis2dh12_ctx_t *ctx, uint8_t *buff);
|
||||
int32_t lis2dh12_temp_data_ready_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_temp_data_ovr_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_temperature_raw_get(lis2dh12_ctx_t *ctx, uint8_t *buff);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_TEMP_DISABLE = 0,
|
||||
LIS2DH12_TEMP_ENABLE = 3,
|
||||
} lis2dh12_temp_en_t;
|
||||
int32_t lis2dh12_temperature_meas_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_temp_en_t val);
|
||||
int32_t lis2dh12_temperature_meas_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_temp_en_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_HR_12bit = 0,
|
||||
LIS2DH12_NM_10bit = 1,
|
||||
LIS2DH12_LP_8bit = 2,
|
||||
} lis2dh12_op_md_t;
|
||||
int32_t lis2dh12_operating_mode_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_op_md_t val);
|
||||
int32_t lis2dh12_operating_mode_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_op_md_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_POWER_DOWN = 0x00,
|
||||
LIS2DH12_ODR_1Hz = 0x01,
|
||||
LIS2DH12_ODR_10Hz = 0x02,
|
||||
LIS2DH12_ODR_25Hz = 0x03,
|
||||
LIS2DH12_ODR_50Hz = 0x04,
|
||||
LIS2DH12_ODR_100Hz = 0x05,
|
||||
LIS2DH12_ODR_200Hz = 0x06,
|
||||
LIS2DH12_ODR_400Hz = 0x07,
|
||||
LIS2DH12_ODR_1kHz620_LP = 0x08,
|
||||
LIS2DH12_ODR_5kHz376_LP_1kHz344_NM_HP = 0x09,
|
||||
} lis2dh12_odr_t;
|
||||
int32_t lis2dh12_data_rate_set(lis2dh12_ctx_t *ctx, lis2dh12_odr_t val);
|
||||
int32_t lis2dh12_data_rate_get(lis2dh12_ctx_t *ctx, lis2dh12_odr_t *val);
|
||||
|
||||
int32_t lis2dh12_high_pass_on_outputs_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_high_pass_on_outputs_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_AGGRESSIVE = 0,
|
||||
LIS2DH12_STRONG = 1,
|
||||
LIS2DH12_MEDIUM = 2,
|
||||
LIS2DH12_LIGHT = 3,
|
||||
} lis2dh12_hpcf_t;
|
||||
int32_t lis2dh12_high_pass_bandwidth_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_hpcf_t val);
|
||||
int32_t lis2dh12_high_pass_bandwidth_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_hpcf_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_NORMAL_WITH_RST = 0,
|
||||
LIS2DH12_REFERENCE_MODE = 1,
|
||||
LIS2DH12_NORMAL = 2,
|
||||
LIS2DH12_AUTORST_ON_INT = 3,
|
||||
} lis2dh12_hpm_t;
|
||||
int32_t lis2dh12_high_pass_mode_set(lis2dh12_ctx_t *ctx, lis2dh12_hpm_t val);
|
||||
int32_t lis2dh12_high_pass_mode_get(lis2dh12_ctx_t *ctx, lis2dh12_hpm_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_2g = 0,
|
||||
LIS2DH12_4g = 1,
|
||||
LIS2DH12_8g = 2,
|
||||
LIS2DH12_16g = 3,
|
||||
} lis2dh12_fs_t;
|
||||
int32_t lis2dh12_full_scale_set(lis2dh12_ctx_t *ctx, lis2dh12_fs_t val);
|
||||
int32_t lis2dh12_full_scale_get(lis2dh12_ctx_t *ctx, lis2dh12_fs_t *val);
|
||||
|
||||
int32_t lis2dh12_block_data_update_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_block_data_update_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_filter_reference_set(lis2dh12_ctx_t *ctx, uint8_t *buff);
|
||||
int32_t lis2dh12_filter_reference_get(lis2dh12_ctx_t *ctx, uint8_t *buff);
|
||||
|
||||
int32_t lis2dh12_xl_data_ready_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_xl_data_ovr_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_acceleration_raw_get(lis2dh12_ctx_t *ctx, uint8_t *buff);
|
||||
|
||||
int32_t lis2dh12_device_id_get(lis2dh12_ctx_t *ctx, uint8_t *buff);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_ST_DISABLE = 0,
|
||||
LIS2DH12_ST_POSITIVE = 1,
|
||||
LIS2DH12_ST_NEGATIVE = 2,
|
||||
} lis2dh12_st_t;
|
||||
int32_t lis2dh12_self_test_set(lis2dh12_ctx_t *ctx, lis2dh12_st_t val);
|
||||
int32_t lis2dh12_self_test_get(lis2dh12_ctx_t *ctx, lis2dh12_st_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_LSB_AT_LOW_ADD = 0,
|
||||
LIS2DH12_MSB_AT_LOW_ADD = 1,
|
||||
} lis2dh12_ble_t;
|
||||
int32_t lis2dh12_data_format_set(lis2dh12_ctx_t *ctx, lis2dh12_ble_t val);
|
||||
int32_t lis2dh12_data_format_get(lis2dh12_ctx_t *ctx, lis2dh12_ble_t *val);
|
||||
|
||||
int32_t lis2dh12_boot_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_boot_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_status_get(lis2dh12_ctx_t *ctx, lis2dh12_status_reg_t *val);
|
||||
|
||||
int32_t lis2dh12_int1_gen_conf_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_int1_cfg_t *val);
|
||||
int32_t lis2dh12_int1_gen_conf_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_int1_cfg_t *val);
|
||||
|
||||
int32_t lis2dh12_int1_gen_source_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_int1_src_t *val);
|
||||
|
||||
int32_t lis2dh12_int1_gen_threshold_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_int1_gen_threshold_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_int1_gen_duration_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_int1_gen_duration_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_int2_gen_conf_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_int2_cfg_t *val);
|
||||
int32_t lis2dh12_int2_gen_conf_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_int2_cfg_t *val);
|
||||
|
||||
int32_t lis2dh12_int2_gen_source_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_int2_src_t *val);
|
||||
|
||||
int32_t lis2dh12_int2_gen_threshold_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_int2_gen_threshold_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_int2_gen_duration_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_int2_gen_duration_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_DISC_FROM_INT_GENERATOR = 0,
|
||||
LIS2DH12_ON_INT1_GEN = 1,
|
||||
LIS2DH12_ON_INT2_GEN = 2,
|
||||
LIS2DH12_ON_TAP_GEN = 4,
|
||||
LIS2DH12_ON_INT1_INT2_GEN = 3,
|
||||
LIS2DH12_ON_INT1_TAP_GEN = 5,
|
||||
LIS2DH12_ON_INT2_TAP_GEN = 6,
|
||||
LIS2DH12_ON_INT1_INT2_TAP_GEN = 7,
|
||||
} lis2dh12_hp_t;
|
||||
int32_t lis2dh12_high_pass_int_conf_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_hp_t val);
|
||||
int32_t lis2dh12_high_pass_int_conf_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_hp_t *val);
|
||||
|
||||
int32_t lis2dh12_pin_int1_config_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_ctrl_reg3_t *val);
|
||||
int32_t lis2dh12_pin_int1_config_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_ctrl_reg3_t *val);
|
||||
|
||||
int32_t lis2dh12_int2_pin_detect_4d_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_int2_pin_detect_4d_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_INT2_PULSED = 0,
|
||||
LIS2DH12_INT2_LATCHED = 1,
|
||||
} lis2dh12_lir_int2_t;
|
||||
int32_t lis2dh12_int2_pin_notification_mode_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_lir_int2_t val);
|
||||
int32_t lis2dh12_int2_pin_notification_mode_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_lir_int2_t *val);
|
||||
|
||||
int32_t lis2dh12_int1_pin_detect_4d_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_int1_pin_detect_4d_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_INT1_PULSED = 0,
|
||||
LIS2DH12_INT1_LATCHED = 1,
|
||||
} lis2dh12_lir_int1_t;
|
||||
int32_t lis2dh12_int1_pin_notification_mode_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_lir_int1_t val);
|
||||
int32_t lis2dh12_int1_pin_notification_mode_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_lir_int1_t *val);
|
||||
|
||||
int32_t lis2dh12_pin_int2_config_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_ctrl_reg6_t *val);
|
||||
int32_t lis2dh12_pin_int2_config_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_ctrl_reg6_t *val);
|
||||
|
||||
int32_t lis2dh12_fifo_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_fifo_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_fifo_watermark_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_fifo_watermark_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_INT1_GEN = 0,
|
||||
LIS2DH12_INT2_GEN = 1,
|
||||
} lis2dh12_tr_t;
|
||||
int32_t lis2dh12_fifo_trigger_event_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_tr_t val);
|
||||
int32_t lis2dh12_fifo_trigger_event_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_tr_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_BYPASS_MODE = 0,
|
||||
LIS2DH12_FIFO_MODE = 1,
|
||||
LIS2DH12_DYNAMIC_STREAM_MODE = 2,
|
||||
LIS2DH12_STREAM_TO_FIFO_MODE = 3,
|
||||
} lis2dh12_fm_t;
|
||||
int32_t lis2dh12_fifo_mode_set(lis2dh12_ctx_t *ctx, lis2dh12_fm_t val);
|
||||
int32_t lis2dh12_fifo_mode_get(lis2dh12_ctx_t *ctx, lis2dh12_fm_t *val);
|
||||
|
||||
int32_t lis2dh12_fifo_status_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_fifo_src_reg_t *val);
|
||||
|
||||
int32_t lis2dh12_fifo_data_level_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_fifo_empty_flag_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_fifo_ovr_flag_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_fifo_fth_flag_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_tap_conf_set(lis2dh12_ctx_t *ctx, lis2dh12_click_cfg_t *val);
|
||||
int32_t lis2dh12_tap_conf_get(lis2dh12_ctx_t *ctx, lis2dh12_click_cfg_t *val);
|
||||
|
||||
int32_t lis2dh12_tap_source_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_click_src_t *val);
|
||||
|
||||
int32_t lis2dh12_tap_threshold_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_tap_threshold_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_TAP_PULSED = 0,
|
||||
LIS2DH12_TAP_LATCHED = 1,
|
||||
} lis2dh12_lir_click_t;
|
||||
int32_t lis2dh12_tap_notification_mode_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_lir_click_t val);
|
||||
int32_t lis2dh12_tap_notification_mode_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_lir_click_t *val);
|
||||
|
||||
int32_t lis2dh12_shock_dur_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_shock_dur_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_quiet_dur_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_quiet_dur_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_double_tap_timeout_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_double_tap_timeout_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_act_threshold_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_act_threshold_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
int32_t lis2dh12_act_timeout_set(lis2dh12_ctx_t *ctx, uint8_t val);
|
||||
int32_t lis2dh12_act_timeout_get(lis2dh12_ctx_t *ctx, uint8_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_PULL_UP_DISCONNECT = 0,
|
||||
LIS2DH12_PULL_UP_CONNECT = 1,
|
||||
} lis2dh12_sdo_pu_disc_t;
|
||||
int32_t lis2dh12_pin_sdo_sa0_mode_set(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_sdo_pu_disc_t val);
|
||||
int32_t lis2dh12_pin_sdo_sa0_mode_get(lis2dh12_ctx_t *ctx,
|
||||
lis2dh12_sdo_pu_disc_t *val);
|
||||
|
||||
typedef enum {
|
||||
LIS2DH12_SPI_4_WIRE = 0,
|
||||
LIS2DH12_SPI_3_WIRE = 1,
|
||||
} lis2dh12_sim_t;
|
||||
int32_t lis2dh12_spi_mode_set(lis2dh12_ctx_t *ctx, lis2dh12_sim_t val);
|
||||
int32_t lis2dh12_spi_mode_get(lis2dh12_ctx_t *ctx, lis2dh12_sim_t *val);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LIS2DH12_REGS_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
Vendored
+161
@@ -0,0 +1,161 @@
|
||||
on:
|
||||
push:
|
||||
|
||||
name: generate executables
|
||||
|
||||
jobs:
|
||||
windows:
|
||||
name: windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: repo
|
||||
uses: actions/checkout@v2.3.1
|
||||
with:
|
||||
path: asb
|
||||
fetch-depth: 0
|
||||
|
||||
- name: python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
|
||||
- name: git
|
||||
run: |
|
||||
git config --global user.email "apollo3-uploader-builder@sparkfun.com"
|
||||
git config --global user.name "apollo3-uploader-builder"
|
||||
git config --global pull.ff only
|
||||
cd asb
|
||||
git status
|
||||
git pull
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
- name: install
|
||||
run: |
|
||||
python --version
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
pip --version
|
||||
pip install -r asb/requirements.txt
|
||||
|
||||
- name: build
|
||||
run: |
|
||||
cd asb
|
||||
pyinstaller --onefile asb.py
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
- name: copy
|
||||
run: |
|
||||
Remove-Item -Recurse -Force asb\dist\windows
|
||||
mkdir asb\dist\windows
|
||||
Move-Item -Path asb\dist\asb.exe -Destination asb\dist\windows\asb.exe
|
||||
|
||||
- name: commit
|
||||
run: |
|
||||
cd asb
|
||||
git add dist\windows\*
|
||||
git commit -m "generated windows executable"
|
||||
git push
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
linux:
|
||||
name: linux
|
||||
needs: windows
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: repo
|
||||
uses: actions/checkout@v2.3.1
|
||||
with:
|
||||
path: asb
|
||||
fetch-depth: 0
|
||||
|
||||
- name: python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
|
||||
- name: git
|
||||
run: |
|
||||
git config --global user.email "apollo3-uploader-builder@sparkfun.com"
|
||||
git config --global user.name "apollo3-uploader-builder"
|
||||
git config --global pull.ff only
|
||||
cd asb
|
||||
git pull
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
- name: install
|
||||
run: |
|
||||
python --version
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
pip --version
|
||||
pip install -r asb/requirements.txt
|
||||
|
||||
- name: build
|
||||
run: |
|
||||
cd asb
|
||||
pyinstaller --onefile asb.py
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
- name: copy
|
||||
run: |
|
||||
rm -rf ./asb/dist/linux
|
||||
mkdir -p ./asb/dist/linux
|
||||
mv ./asb/dist/asb ./asb/dist/linux/asb
|
||||
|
||||
- name: commit
|
||||
run: |
|
||||
cd ./asb
|
||||
git add ./dist/linux/*
|
||||
git commit -m "generated linux executable"
|
||||
git push
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
macosx:
|
||||
name: macosx
|
||||
needs: linux
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: repo
|
||||
uses: actions/checkout@v2.3.1
|
||||
with:
|
||||
path: asb
|
||||
fetch-depth: 0
|
||||
|
||||
- name: python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
|
||||
- name: git
|
||||
run: |
|
||||
git config --global user.email "apollo3-uploader-builder@sparkfun.com"
|
||||
git config --global user.name "apollo3-uploader-builder"
|
||||
git config --global pull.ff only
|
||||
cd asb
|
||||
git pull
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
- name: install
|
||||
run: |
|
||||
python --version
|
||||
python -m pip install --upgrade pip setuptools wheel
|
||||
pip --version
|
||||
pip install -r asb/requirements.txt
|
||||
|
||||
- name: build
|
||||
run: |
|
||||
cd asb
|
||||
pyinstaller --onefile asb.py
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
|
||||
- name: copy
|
||||
run: |
|
||||
rm -rf ./asb/dist/macosx
|
||||
mkdir -p ./asb/dist/macosx
|
||||
mv ./asb/dist/asb ./asb/dist/macosx/asb
|
||||
|
||||
- name: commit
|
||||
run: |
|
||||
cd ./asb
|
||||
git add ./dist/macosx/*
|
||||
git commit -m "generated macosx executable"
|
||||
git push
|
||||
cd ${GITHUB_WORKSPACE}
|
||||
@@ -0,0 +1,127 @@
|
||||
# macosx
|
||||
.DS_Store
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
pip-wheel-metadata/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
@@ -0,0 +1,3 @@
|
||||

|
||||
|
||||
# Apollo3 Uploader - Ambiq Secure Bootloader (SVL)
|
||||
@@ -0,0 +1,527 @@
|
||||
#!/usr/bin/env python3
|
||||
# Utility functioins
|
||||
|
||||
import sys
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Signature import PKCS1_v1_5
|
||||
from Crypto.Hash import SHA256
|
||||
import array
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
import binascii
|
||||
|
||||
|
||||
ivVal0 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
FLASH_PAGE_SIZE = 0x2000 # 8K
|
||||
MAX_DOWNLOAD_SIZE = 0x48000 # 288K
|
||||
AM_SECBOOT_DEFAULT_NONSECURE_MAIN = 0xC000
|
||||
|
||||
AM_SECBOOT_AESCBC_BLOCK_SIZE_WORDS = 4
|
||||
AM_SECBOOT_AESCBC_BLOCK_SIZE_BYTES = 4*AM_SECBOOT_AESCBC_BLOCK_SIZE_WORDS
|
||||
|
||||
AM_SECBOOT_MIN_KEYIDX_INFO0 = 8 ## KeyIdx 8 - 15
|
||||
AM_SECBOOT_MAX_KEYIDX_INFO0 = 15
|
||||
AM_SECBOOT_MIN_KEYIDX_INFO1 = 0 ## KeyIdx 0 - 7
|
||||
AM_SECBOOT_MAX_KEYIDX_INFO1 = 7
|
||||
AM_SECBOOT_KEYIDX_BYTES = 16
|
||||
|
||||
# Encryption Algorithm
|
||||
AM_SECBOOT_ENC_ALGO_NONE = 0
|
||||
AM_SECBOOT_ENC_ALGO_AES128 = 1
|
||||
AM_SECBOOT_ENC_ALGO_MAX = AM_SECBOOT_ENC_ALGO_AES128
|
||||
# String constants
|
||||
helpEncAlgo = 'Encryption Algo? (0(default) = none, 1 = AES128)'
|
||||
|
||||
# Authentication Algorithm
|
||||
AM_SECBOOT_AUTH_ALGO_NONE = 0
|
||||
AM_SECBOOT_AUTH_ALGO_SHA256HMAC = 1
|
||||
AM_SECBOOT_AUTH_ALGO_MAX = AM_SECBOOT_AUTH_ALGO_SHA256HMAC
|
||||
# String constants
|
||||
helpAuthAlgo = 'Authentication Algo? (0(default) = none, 1 = SHA256)'
|
||||
|
||||
|
||||
FLASH_INVALID = 0xFFFFFFFF
|
||||
|
||||
# KeyWrap Mode
|
||||
AM_SECBOOT_KEYWRAP_NONE = 0
|
||||
AM_SECBOOT_KEYWRAP_XOR = 1
|
||||
AM_SECBOOT_KEYWRAP_AES128 = 2
|
||||
AM_SECBOOT_KEYWRAP_MAX = AM_SECBOOT_KEYWRAP_AES128
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Magic Numbers
|
||||
#
|
||||
#******************************************************************************
|
||||
AM_IMAGE_MAGIC_MAIN = 0xC0
|
||||
AM_IMAGE_MAGIC_CHILD = 0xCC
|
||||
AM_IMAGE_MAGIC_NONSECURE = 0xCB
|
||||
AM_IMAGE_MAGIC_INFO0 = 0xCF
|
||||
|
||||
# Dummy for creating images for customer - not understood by SBL
|
||||
# This could be any value from the definition:
|
||||
# #define AM_IMAGE_MAGIC_CUST(x) ((((x) & 0xF0) == 0xC0) && ((x) != 0xC0) && ((x) != 0xCC) && ((x) != 0xCB) && ((x) != 0xCF))
|
||||
AM_IMAGE_MAGIC_CUSTPATCH = 0xC1
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Image Types
|
||||
#
|
||||
#******************************************************************************
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_SBL = 0
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_AM3P = 1
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_PATCH = 2
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_MAIN = 3
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_CHILD = 4
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_CUSTPATCH = 5
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_NONSECURE = 6
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_INFO0 = 7
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_INFO0_NOOTA = 32
|
||||
AM_SECBOOT_WIRED_IMAGETYPE_INVALID = 0xFF
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Wired Message Types
|
||||
#
|
||||
#******************************************************************************
|
||||
AM_SECBOOT_WIRED_MSGTYPE_HELLO = 0
|
||||
AM_SECBOOT_WIRED_MSGTYPE_STATUS = 1
|
||||
AM_SECBOOT_WIRED_MSGTYPE_OTADESC = 2
|
||||
AM_SECBOOT_WIRED_MSGTYPE_UPDATE = 3
|
||||
AM_SECBOOT_WIRED_MSGTYPE_ABORT = 4
|
||||
AM_SECBOOT_WIRED_MSGTYPE_RECOVER = 5
|
||||
AM_SECBOOT_WIRED_MSGTYPE_RESET = 6
|
||||
AM_SECBOOT_WIRED_MSGTYPE_ACK = 7
|
||||
AM_SECBOOT_WIRED_MSGTYPE_DATA = 8
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Wired Message ACK Status
|
||||
#
|
||||
#******************************************************************************
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_SUCCESS = 0
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_FAILURE = 1
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_INVALID_INFO0 = 2
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_CRC = 3
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_SEC = 4
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_MSG_TOO_BIG = 5
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_UNKNOWN_MSGTYPE = 6
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_INVALID_ADDR = 7
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_INVALID_OPERATION = 8
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_INVALID_PARAM = 9
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_SEQ = 10
|
||||
AM_SECBOOT_WIRED_ACK_STATUS_TOO_MUCH_DATA = 11
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Definitions related to Image Headers
|
||||
#
|
||||
#******************************************************************************
|
||||
AM_HMAC_SIG_SIZE = 32
|
||||
AM_KEK_SIZE = 16
|
||||
AM_CRC_SIZE = 4
|
||||
|
||||
AM_MAX_UART_MSG_SIZE = 8192 # 8K buffer in SBL
|
||||
|
||||
# Wiredupdate Image Header
|
||||
AM_WU_IMAGEHDR_OFFSET_SIG = 16
|
||||
AM_WU_IMAGEHDR_OFFSET_IV = 48
|
||||
AM_WU_IMAGEHDR_OFFSET_KEK = 64
|
||||
AM_WU_IMAGEHDR_OFFSET_IMAGETYPE = (AM_WU_IMAGEHDR_OFFSET_KEK + AM_KEK_SIZE)
|
||||
AM_WU_IMAGEHDR_OFFSET_OPTIONS = (AM_WU_IMAGEHDR_OFFSET_IMAGETYPE + 1)
|
||||
AM_WU_IMAGEHDR_OFFSET_KEY = (AM_WU_IMAGEHDR_OFFSET_IMAGETYPE + 4)
|
||||
AM_WU_IMAGEHDR_OFFSET_ADDR = (AM_WU_IMAGEHDR_OFFSET_KEY + 4)
|
||||
AM_WU_IMAGEHDR_OFFSET_SIZE = (AM_WU_IMAGEHDR_OFFSET_ADDR + 4)
|
||||
|
||||
AM_WU_IMAGEHDR_START_HMAC = (AM_WU_IMAGEHDR_OFFSET_SIG + AM_HMAC_SIG_SIZE)
|
||||
AM_WU_IMAGEHDR_START_ENCRYPT = (AM_WU_IMAGEHDR_OFFSET_KEK + AM_KEK_SIZE)
|
||||
AM_WU_IMAGEHDR_SIZE = (AM_WU_IMAGEHDR_OFFSET_KEK + AM_KEK_SIZE + 16)
|
||||
|
||||
|
||||
# Image Header
|
||||
AM_IMAGEHDR_SIZE_MAIN = 256
|
||||
AM_IMAGEHDR_SIZE_AUX = (112 + AM_KEK_SIZE)
|
||||
|
||||
AM_IMAGEHDR_OFFSET_CRC = 4
|
||||
AM_IMAGEHDR_OFFSET_SIG = 16
|
||||
AM_IMAGEHDR_OFFSET_IV = 48
|
||||
AM_IMAGEHDR_OFFSET_KEK = 64
|
||||
AM_IMAGEHDR_OFFSET_SIGCLR = (AM_IMAGEHDR_OFFSET_KEK + AM_KEK_SIZE)
|
||||
AM_IMAGEHDR_START_CRC = (AM_IMAGEHDR_OFFSET_CRC + AM_CRC_SIZE)
|
||||
AM_IMAGEHDR_START_HMAC_INST = (AM_IMAGEHDR_OFFSET_SIG + AM_HMAC_SIG_SIZE)
|
||||
AM_IMAGEHDR_START_ENCRYPT = (AM_IMAGEHDR_OFFSET_KEK + AM_KEK_SIZE)
|
||||
AM_IMAGEHDR_START_HMAC = (AM_IMAGEHDR_OFFSET_SIGCLR + AM_HMAC_SIG_SIZE)
|
||||
AM_IMAGEHDR_OFFSET_ADDR = AM_IMAGEHDR_START_HMAC
|
||||
AM_IMAGEHDR_OFFSET_VERKEY = (AM_IMAGEHDR_OFFSET_ADDR + 4)
|
||||
AM_IMAGEHDR_OFFSET_CHILDPTR = (AM_IMAGEHDR_OFFSET_VERKEY + 4)
|
||||
|
||||
# Recover message
|
||||
AM_WU_RECOVERY_HDR_SIZE = 44
|
||||
AM_WU_RECOVERY_HDR_OFFSET_CUSTID = 8
|
||||
AM_WU_RECOVERY_HDR_OFFSET_RECKEY = (AM_WU_RECOVERY_HDR_OFFSET_CUSTID + 4)
|
||||
AM_WU_RECOVERY_HDR_OFFSET_NONCE = (AM_WU_RECOVERY_HDR_OFFSET_RECKEY + 16)
|
||||
AM_WU_RECOVERY_HDR_OFFSET_RECBLOB = (AM_WU_RECOVERY_HDR_OFFSET_NONCE + 16)
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# INFOSPACE related definitions
|
||||
#
|
||||
#******************************************************************************
|
||||
AM_SECBOOT_INFO0_SIGN_PROGRAMMED0 = 0x48EAAD88
|
||||
AM_SECBOOT_INFO0_SIGN_PROGRAMMED1 = 0xC9705737
|
||||
AM_SECBOOT_INFO0_SIGN_PROGRAMMED2 = 0x0A6B8458
|
||||
AM_SECBOOT_INFO0_SIGN_PROGRAMMED3 = 0xE41A9D74
|
||||
|
||||
AM_SECBOOT_INFO0_SIGN_UINIT0 = 0x5B75A5FA
|
||||
AM_SECBOOT_INFO0_SIGN_UINIT1 = 0x7B9C8674
|
||||
AM_SECBOOT_INFO0_SIGN_UINIT2 = 0x869A96FE
|
||||
AM_SECBOOT_INFO0_SIGN_UINIT3 = 0xAEC90860
|
||||
|
||||
INFO_SIZE_BYTES = (8 * 1024)
|
||||
INFO_MAX_AUTH_KEY_WORDS = 32
|
||||
INFO_MAX_ENC_KEY_WORDS = 32
|
||||
|
||||
INFO_MAX_AUTH_KEYS = (INFO_MAX_AUTH_KEY_WORDS*4//AM_SECBOOT_KEYIDX_BYTES)
|
||||
INFO_MAX_ENC_KEYS = (INFO_MAX_ENC_KEY_WORDS*4//AM_SECBOOT_KEYIDX_BYTES)
|
||||
|
||||
INFO0_SIGNATURE0_O = 0x00000000
|
||||
INFO0_SIGNATURE1_O = 0x00000004
|
||||
INFO0_SIGNATURE2_O = 0x00000008
|
||||
INFO0_SIGNATURE3_O = 0x0000000c
|
||||
INFO0_SECURITY_O = 0x00000010
|
||||
INFO0_CUSTOMER_TRIM_O = 0x00000014
|
||||
INFO0_CUSTOMER_TRIM2_O = 0x00000018
|
||||
INFO0_SECURITY_OVR_O = 0x00000020
|
||||
INFO0_SECURITY_WIRED_CFG_O = 0x00000024
|
||||
INFO0_SECURITY_WIRED_IFC_CFG0_O = 0x00000028
|
||||
INFO0_SECURITY_WIRED_IFC_CFG1_O = 0x0000002C
|
||||
INFO0_SECURITY_WIRED_IFC_CFG2_O = 0x00000030
|
||||
INFO0_SECURITY_WIRED_IFC_CFG3_O = 0x00000034
|
||||
INFO0_SECURITY_WIRED_IFC_CFG4_O = 0x00000038
|
||||
INFO0_SECURITY_WIRED_IFC_CFG5_O = 0x0000003C
|
||||
INFO0_SECURITY_VERSION_O = 0x00000040
|
||||
INFO0_SECURITY_SRAM_RESV_O = 0x00000050
|
||||
AM_REG_INFO0_SECURITY_SRAM_RESV_SRAM_RESV_M = 0x0000FFFF
|
||||
INFO0_WRITE_PROTECT_L_O = 0x000001f8
|
||||
INFO0_WRITE_PROTECT_H_O = 0x000001fc
|
||||
INFO0_COPY_PROTECT_L_O = 0x00000200
|
||||
INFO0_COPY_PROTECT_H_O = 0x00000204
|
||||
INFO0_WRITE_PROTECT_SBL_L_O = 0x000009f8
|
||||
INFO0_WRITE_PROTECT_SBL_H_O = 0x000009fc
|
||||
INFO0_COPY_PROTECT_SBL_L_O = 0x00000A00
|
||||
INFO0_COPY_PROTECT_SBL_H_O = 0x00000A04
|
||||
INFO0_MAIN_PTR1_O = 0x00000C00
|
||||
INFO0_MAIN_PTR2_O = 0x00000C04
|
||||
INFO0_KREVTRACK_O = 0x00000C08
|
||||
INFO0_AREVTRACK_O = 0x00000C0C
|
||||
INFO0_MAIN_CNT0_O = 0x00000FF8
|
||||
INFO0_MAIN_CNT1_O = 0x00000FFC
|
||||
|
||||
INFO0_CUST_KEK_W0_O = 0x00001800
|
||||
INFO0_CUST_KEK_W1_O = 0x00001804
|
||||
INFO0_CUST_KEK_W2_O = 0x00001808
|
||||
INFO0_CUST_KEK_W3_O = 0x0000180c
|
||||
INFO0_CUST_KEK_W4_O = 0x00001810
|
||||
INFO0_CUST_KEK_W5_O = 0x00001814
|
||||
INFO0_CUST_KEK_W6_O = 0x00001818
|
||||
INFO0_CUST_KEK_W7_O = 0x0000181c
|
||||
INFO0_CUST_KEK_W8_O = 0x00001820
|
||||
INFO0_CUST_KEK_W9_O = 0x00001824
|
||||
INFO0_CUST_KEK_W10_O = 0x00001828
|
||||
INFO0_CUST_KEK_W11_O = 0x0000182c
|
||||
INFO0_CUST_KEK_W12_O = 0x00001830
|
||||
INFO0_CUST_KEK_W13_O = 0x00001834
|
||||
INFO0_CUST_KEK_W14_O = 0x00001838
|
||||
INFO0_CUST_KEK_W15_O = 0x0000183c
|
||||
INFO0_CUST_KEK_W16_O = 0x00001840
|
||||
INFO0_CUST_KEK_W17_O = 0x00001844
|
||||
INFO0_CUST_KEK_W18_O = 0x00001848
|
||||
INFO0_CUST_KEK_W19_O = 0x0000184c
|
||||
INFO0_CUST_KEK_W20_O = 0x00001850
|
||||
INFO0_CUST_KEK_W21_O = 0x00001854
|
||||
INFO0_CUST_KEK_W22_O = 0x00001858
|
||||
INFO0_CUST_KEK_W23_O = 0x0000185c
|
||||
INFO0_CUST_KEK_W24_O = 0x00001860
|
||||
INFO0_CUST_KEK_W25_O = 0x00001864
|
||||
INFO0_CUST_KEK_W26_O = 0x00001868
|
||||
INFO0_CUST_KEK_W27_O = 0x0000186c
|
||||
INFO0_CUST_KEK_W28_O = 0x00001870
|
||||
INFO0_CUST_KEK_W29_O = 0x00001874
|
||||
INFO0_CUST_KEK_W30_O = 0x00001878
|
||||
INFO0_CUST_KEK_W31_O = 0x0000187c
|
||||
INFO0_CUST_AUTH_W0_O = 0x00001880
|
||||
INFO0_CUST_AUTH_W1_O = 0x00001884
|
||||
INFO0_CUST_AUTH_W2_O = 0x00001888
|
||||
INFO0_CUST_AUTH_W3_O = 0x0000188c
|
||||
INFO0_CUST_AUTH_W4_O = 0x00001890
|
||||
INFO0_CUST_AUTH_W5_O = 0x00001894
|
||||
INFO0_CUST_AUTH_W6_O = 0x00001898
|
||||
INFO0_CUST_AUTH_W7_O = 0x0000189c
|
||||
INFO0_CUST_AUTH_W8_O = 0x000018a0
|
||||
INFO0_CUST_AUTH_W9_O = 0x000018a4
|
||||
INFO0_CUST_AUTH_W10_O = 0x000018a8
|
||||
INFO0_CUST_AUTH_W11_O = 0x000018ac
|
||||
INFO0_CUST_AUTH_W12_O = 0x000018b0
|
||||
INFO0_CUST_AUTH_W13_O = 0x000018b4
|
||||
INFO0_CUST_AUTH_W14_O = 0x000018b8
|
||||
INFO0_CUST_AUTH_W15_O = 0x000018bc
|
||||
INFO0_CUST_AUTH_W16_O = 0x000018c0
|
||||
INFO0_CUST_AUTH_W17_O = 0x000018c4
|
||||
INFO0_CUST_AUTH_W18_O = 0x000018c8
|
||||
INFO0_CUST_AUTH_W19_O = 0x000018cc
|
||||
INFO0_CUST_AUTH_W20_O = 0x000018d0
|
||||
INFO0_CUST_AUTH_W21_O = 0x000018d4
|
||||
INFO0_CUST_AUTH_W22_O = 0x000018d8
|
||||
INFO0_CUST_AUTH_W23_O = 0x000018dc
|
||||
INFO0_CUST_AUTH_W24_O = 0x000018e0
|
||||
INFO0_CUST_AUTH_W25_O = 0x000018e4
|
||||
INFO0_CUST_AUTH_W26_O = 0x000018e8
|
||||
INFO0_CUST_AUTH_W27_O = 0x000018ec
|
||||
INFO0_CUST_AUTH_W28_O = 0x000018f0
|
||||
INFO0_CUST_AUTH_W29_O = 0x000018f4
|
||||
INFO0_CUST_AUTH_W30_O = 0x000018f8
|
||||
INFO0_CUST_AUTH_W31_O = 0x000018fc
|
||||
INFO0_CUST_PUBKEY_W0_O = 0x00001900
|
||||
INFO0_CUST_PUBKEY_W1_O = 0x00001904
|
||||
INFO0_CUST_PUBKEY_W2_O = 0x00001908
|
||||
INFO0_CUST_PUBKEY_W3_O = 0x0000190c
|
||||
INFO0_CUST_PUBKEY_W4_O = 0x00001910
|
||||
INFO0_CUST_PUBKEY_W5_O = 0x00001914
|
||||
INFO0_CUST_PUBKEY_W6_O = 0x00001918
|
||||
INFO0_CUST_PUBKEY_W7_O = 0x0000191c
|
||||
INFO0_CUST_PUBKEY_W8_O = 0x00001920
|
||||
INFO0_CUST_PUBKEY_W9_O = 0x00001924
|
||||
INFO0_CUST_PUBKEY_W10_O = 0x00001928
|
||||
INFO0_CUST_PUBKEY_W11_O = 0x0000192c
|
||||
INFO0_CUST_PUBKEY_W12_O = 0x00001930
|
||||
INFO0_CUST_PUBKEY_W13_O = 0x00001934
|
||||
INFO0_CUST_PUBKEY_W14_O = 0x00001938
|
||||
INFO0_CUST_PUBKEY_W15_O = 0x0000193c
|
||||
INFO0_CUST_PUBKEY_W16_O = 0x00001940
|
||||
INFO0_CUST_PUBKEY_W17_O = 0x00001944
|
||||
INFO0_CUST_PUBKEY_W18_O = 0x00001948
|
||||
INFO0_CUST_PUBKEY_W19_O = 0x0000194c
|
||||
INFO0_CUST_PUBKEY_W20_O = 0x00001950
|
||||
INFO0_CUST_PUBKEY_W21_O = 0x00001954
|
||||
INFO0_CUST_PUBKEY_W22_O = 0x00001958
|
||||
INFO0_CUST_PUBKEY_W23_O = 0x0000195c
|
||||
INFO0_CUST_PUBKEY_W24_O = 0x00001960
|
||||
INFO0_CUST_PUBKEY_W25_O = 0x00001964
|
||||
INFO0_CUST_PUBKEY_W26_O = 0x00001968
|
||||
INFO0_CUST_PUBKEY_W27_O = 0x0000196c
|
||||
INFO0_CUST_PUBKEY_W28_O = 0x00001970
|
||||
INFO0_CUST_PUBKEY_W29_O = 0x00001974
|
||||
INFO0_CUST_PUBKEY_W30_O = 0x00001978
|
||||
INFO0_CUST_PUBKEY_W31_O = 0x0000197c
|
||||
INFO0_CUST_PUBKEY_W32_O = 0x00001980
|
||||
INFO0_CUST_PUBKEY_W33_O = 0x00001984
|
||||
INFO0_CUST_PUBKEY_W34_O = 0x00001988
|
||||
INFO0_CUST_PUBKEY_W35_O = 0x0000198c
|
||||
INFO0_CUST_PUBKEY_W36_O = 0x00001990
|
||||
INFO0_CUST_PUBKEY_W37_O = 0x00001994
|
||||
INFO0_CUST_PUBKEY_W38_O = 0x00001998
|
||||
INFO0_CUST_PUBKEY_W39_O = 0x0000199c
|
||||
INFO0_CUST_PUBKEY_W40_O = 0x000019a0
|
||||
INFO0_CUST_PUBKEY_W41_O = 0x000019a4
|
||||
INFO0_CUST_PUBKEY_W42_O = 0x000019a8
|
||||
INFO0_CUST_PUBKEY_W43_O = 0x000019ac
|
||||
INFO0_CUST_PUBKEY_W44_O = 0x000019b0
|
||||
INFO0_CUST_PUBKEY_W45_O = 0x000019b4
|
||||
INFO0_CUST_PUBKEY_W46_O = 0x000019b8
|
||||
INFO0_CUST_PUBKEY_W47_O = 0x000019bc
|
||||
INFO0_CUST_PUBKEY_W48_O = 0x000019c0
|
||||
INFO0_CUST_PUBKEY_W49_O = 0x000019c4
|
||||
INFO0_CUST_PUBKEY_W50_O = 0x000019c8
|
||||
INFO0_CUST_PUBKEY_W51_O = 0x000019cc
|
||||
INFO0_CUST_PUBKEY_W52_O = 0x000019d0
|
||||
INFO0_CUST_PUBKEY_W53_O = 0x000019d4
|
||||
INFO0_CUST_PUBKEY_W54_O = 0x000019d8
|
||||
INFO0_CUST_PUBKEY_W55_O = 0x000019dc
|
||||
INFO0_CUST_PUBKEY_W56_O = 0x000019e0
|
||||
INFO0_CUST_PUBKEY_W57_O = 0x000019e4
|
||||
INFO0_CUST_PUBKEY_W58_O = 0x000019e8
|
||||
INFO0_CUST_PUBKEY_W59_O = 0x000019ec
|
||||
INFO0_CUST_PUBKEY_W60_O = 0x000019f0
|
||||
INFO0_CUST_PUBKEY_W61_O = 0x000019f4
|
||||
INFO0_CUST_PUBKEY_W62_O = 0x000019f8
|
||||
INFO0_CUST_PUBKEY_W63_O = 0x000019fc
|
||||
INFO0_CUSTOMER_KEY0_O = 0x00001a00
|
||||
INFO0_CUSTOMER_KEY1_O = 0x00001a04
|
||||
INFO0_CUSTOMER_KEY2_O = 0x00001a08
|
||||
INFO0_CUSTOMER_KEY3_O = 0x00001a0c
|
||||
INFO0_CUST_PUBHASH_W0_O = 0x00001a10
|
||||
INFO0_CUST_PUBHASH_W1_O = 0x00001a14
|
||||
INFO0_CUST_PUBHASH_W2_O = 0x00001a18
|
||||
INFO0_CUST_PUBHASH_W3_O = 0x00001a1c
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# CRC using ethernet poly, as used by Corvette hardware for validation
|
||||
#
|
||||
#******************************************************************************
|
||||
def crc32(L):
|
||||
return (binascii.crc32(L) & 0xFFFFFFFF)
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Pad the text to the block_size. bZeroPad determines how to handle text which
|
||||
# is already multiple of block_size
|
||||
#
|
||||
#******************************************************************************
|
||||
def pad_to_block_size(text, block_size, bZeroPad):
|
||||
text_length = len(text)
|
||||
amount_to_pad = block_size - (text_length % block_size)
|
||||
if (amount_to_pad == block_size):
|
||||
if (bZeroPad == 0):
|
||||
amount_to_pad = 0
|
||||
for i in range(0, amount_to_pad, 1):
|
||||
text += bytes(chr(amount_to_pad), 'ascii')
|
||||
return text
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# AES CBC encryption
|
||||
#
|
||||
#******************************************************************************
|
||||
def encrypt_app_aes(cleartext, encKey, iv):
|
||||
key = array.array('B', encKey).tostring()
|
||||
ivVal = array.array('B', iv).tostring()
|
||||
plaintext = array.array('B', cleartext).tostring()
|
||||
|
||||
encryption_suite = AES.new(key, AES.MODE_CBC, ivVal)
|
||||
cipher_text = encryption_suite.encrypt(plaintext)
|
||||
|
||||
return cipher_text
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# AES 128 CBC encryption
|
||||
#
|
||||
#******************************************************************************
|
||||
def encrypt_app_aes128(cleartext, encKey, iv):
|
||||
key = array.array('B', encKey).tostring()
|
||||
ivVal = array.array('B', iv).tostring()
|
||||
plaintext = array.array('B', cleartext).tostring()
|
||||
|
||||
encryption_suite = AES.new(key, AES.MODE_CBC, ivVal)
|
||||
cipher_text = encryption_suite.encrypt(plaintext)
|
||||
|
||||
return cipher_text
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# SHA256 HMAC
|
||||
#
|
||||
#******************************************************************************
|
||||
def compute_hmac(key, data):
|
||||
sig = hmac.new(array.array('B', key).tostring(), array.array('B', data).tostring(), hashlib.sha256).digest()
|
||||
return sig
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# RSA PKCS1_v1_5 sign
|
||||
#
|
||||
#******************************************************************************
|
||||
def compute_rsa_sign(prvKeyFile, data):
|
||||
key = open(prvKeyFile, "r").read()
|
||||
rsakey = RSA.importKey(key)
|
||||
signer = PKCS1_v1_5.new(rsakey)
|
||||
digest = SHA256.new()
|
||||
digest.update(bytes(data))
|
||||
sign = signer.sign(digest)
|
||||
return sign
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# RSA PKCS1_v1_5 sign verification
|
||||
#
|
||||
#******************************************************************************
|
||||
def verify_rsa_sign(pubKeyFile, data, sign):
|
||||
key = open(pubKeyFile, "r").read()
|
||||
rsakey = RSA.importKey(key)
|
||||
#print(hex(rsakey.n))
|
||||
verifier = PKCS1_v1_5.new(rsakey)
|
||||
digest = SHA256.new()
|
||||
digest.update(bytes(data))
|
||||
return verifier.verify(digest, sign)
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Fill one word in bytearray
|
||||
#
|
||||
#******************************************************************************
|
||||
def fill_word(barray, offset, w):
|
||||
barray[offset + 0] = (w >> 0) & 0x000000ff;
|
||||
barray[offset + 1] = (w >> 8) & 0x000000ff;
|
||||
barray[offset + 2] = (w >> 16) & 0x000000ff;
|
||||
barray[offset + 3] = (w >> 24) & 0x000000ff;
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Turn a 32-bit number into a series of bytes for transmission.
|
||||
#
|
||||
# This command will split a 32-bit integer into an array of bytes, ordered
|
||||
# LSB-first for transmission over the UART.
|
||||
#
|
||||
#******************************************************************************
|
||||
def int_to_bytes(n):
|
||||
A = [n & 0xFF,
|
||||
(n >> 8) & 0xFF,
|
||||
(n >> 16) & 0xFF,
|
||||
(n >> 24) & 0xFF]
|
||||
|
||||
return A
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Extract a word from a byte array
|
||||
#
|
||||
#******************************************************************************
|
||||
def word_from_bytes(B, n):
|
||||
return (B[n] + (B[n + 1] << 8) + (B[n + 2] << 16) + (B[n + 3] << 24))
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# automatically figure out the integer format (base 10 or 16)
|
||||
#
|
||||
#******************************************************************************
|
||||
def auto_int(x):
|
||||
return int(x, 0)
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# User controllable Prints control
|
||||
#
|
||||
#******************************************************************************
|
||||
# Defined print levels
|
||||
AM_PRINT_LEVEL_MIN = 0
|
||||
AM_PRINT_LEVEL_NONE = AM_PRINT_LEVEL_MIN
|
||||
AM_PRINT_LEVEL_ERROR = 1
|
||||
AM_PRINT_LEVEL_INFO = 2
|
||||
AM_PRINT_LEVEL_VERBOSE = 4
|
||||
AM_PRINT_LEVEL_DEBUG = 5
|
||||
AM_PRINT_LEVEL_MAX = AM_PRINT_LEVEL_DEBUG
|
||||
|
||||
# Global variable to control the prints
|
||||
AM_PRINT_VERBOSITY = AM_PRINT_LEVEL_INFO
|
||||
|
||||
helpPrintLevel = 'Set Log Level (0: None), (1: Error), (2: INFO), (4: Verbose), (5: Debug) [Default = Info]'
|
||||
|
||||
def am_set_print_level(level):
|
||||
global AM_PRINT_VERBOSITY
|
||||
AM_PRINT_VERBOSITY = level
|
||||
|
||||
def am_print(*args, level=AM_PRINT_LEVEL_INFO, **kwargs):
|
||||
global AM_PRINT_VERBOSITY
|
||||
if (AM_PRINT_VERBOSITY >= level):
|
||||
print(*args, **kwargs)
|
||||
@@ -0,0 +1,899 @@
|
||||
#!/usr/bin/env python3
|
||||
# Combination of the three steps to take an 'application.bin' file and run it on a SparkFun Artemis module
|
||||
|
||||
# Information:
|
||||
# This script performs the three main tasks:
|
||||
# 1. Convert 'application.bin' to an OTA update blob
|
||||
# 2. Convert the OTA blob into a wired update blob
|
||||
# 3. Push the wired update blob into the Artemis module
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from Crypto.Cipher import AES
|
||||
import array
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
import binascii
|
||||
import serial
|
||||
import serial.tools.list_ports as list_ports
|
||||
import time
|
||||
# from sf_am_defines import *
|
||||
from sys import exit
|
||||
|
||||
from am_defines import *
|
||||
from keys_info import keyTblAes, keyTblHmac, minAesKeyIdx, maxAesKeyIdx, minHmacKeyIdx, maxHmacKeyIdx, INFO_KEY, FLASH_KEY
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Global Variables
|
||||
#
|
||||
#******************************************************************************
|
||||
loadTries = 0 #If we fail, try again. Tracks the number of tries we've attempted
|
||||
loadSuccess = False
|
||||
blob2wiredfile = ''
|
||||
uploadbinfile = ''
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Generate the image blob as per command line parameters
|
||||
#
|
||||
#******************************************************************************
|
||||
def bin2blob_process(loadaddress, appFile, magicNum, crcI, crcB, authI, authB, protection, authKeyIdx, output, encKeyIdx, version, erasePrev, child0, child1, authalgo, encalgo):
|
||||
|
||||
global blob2wiredfile
|
||||
|
||||
app_binarray = bytearray()
|
||||
# Open the file, and read it into an array of integers.
|
||||
with appFile as f_app:
|
||||
app_binarray.extend(f_app.read())
|
||||
f_app.close()
|
||||
|
||||
encVal = 0
|
||||
if (encalgo != 0):
|
||||
encVal = 1
|
||||
if ((encKeyIdx < minAesKeyIdx) or (encKeyIdx > maxAesKeyIdx)):
|
||||
am_print("Invalid encKey Idx ", encKeyIdx, level=AM_PRINT_LEVEL_ERROR);
|
||||
return
|
||||
if (encalgo == 2):
|
||||
if (encKeyIdx & 0x1):
|
||||
am_print("Invalid encKey Idx ", encKeyIdx, level=AM_PRINT_LEVEL_ERROR);
|
||||
return
|
||||
keySize = 32
|
||||
else:
|
||||
keySize = 16
|
||||
if (authalgo != 0):
|
||||
if ((authKeyIdx < minHmacKeyIdx) or (authKeyIdx > maxHmacKeyIdx) or (authKeyIdx & 0x1)):
|
||||
am_print("Invalid authKey Idx ", authKeyIdx, level=AM_PRINT_LEVEL_ERROR);
|
||||
return
|
||||
|
||||
if (magicNum == AM_IMAGE_MAGIC_MAIN):
|
||||
hdr_length = AM_IMAGEHDR_SIZE_MAIN; #fixed header length
|
||||
elif ((magicNum == AM_IMAGE_MAGIC_CHILD) or (magicNum == AM_IMAGE_MAGIC_CUSTPATCH) or (magicNum == AM_IMAGE_MAGIC_NONSECURE) or (magicNum == AM_IMAGE_MAGIC_INFO0)):
|
||||
hdr_length = AM_IMAGEHDR_SIZE_AUX; #fixed header length
|
||||
else:
|
||||
am_print("magic number", hex(magicNum), " not supported", level=AM_PRINT_LEVEL_ERROR)
|
||||
return
|
||||
am_print("Header Size = ", hex(hdr_length))
|
||||
|
||||
#generate mutable byte array for the header
|
||||
hdr_binarray = bytearray([0x00]*hdr_length);
|
||||
|
||||
orig_app_length = (len(app_binarray))
|
||||
am_print("original app_size ",hex(orig_app_length), "(",orig_app_length,")")
|
||||
|
||||
am_print("load_address ",hex(loadaddress), "(",loadaddress,")")
|
||||
if (loadaddress & 0x3):
|
||||
am_print("load address needs to be word aligned", level=AM_PRINT_LEVEL_ERROR)
|
||||
return
|
||||
|
||||
if (magicNum == AM_IMAGE_MAGIC_INFO0):
|
||||
if (orig_app_length & 0x3):
|
||||
am_print("INFO0 blob length needs to be multiple of 4", level=AM_PRINT_LEVEL_ERROR)
|
||||
return
|
||||
if ((loadaddress + orig_app_length) > INFO_SIZE_BYTES):
|
||||
am_print("INFO0 Offset and length exceed size", level=AM_PRINT_LEVEL_ERROR)
|
||||
return
|
||||
|
||||
if (encVal == 1):
|
||||
block_size = AM_SECBOOT_AESCBC_BLOCK_SIZE_BYTES
|
||||
app_binarray = pad_to_block_size(app_binarray, block_size, 1)
|
||||
else:
|
||||
# Add Padding
|
||||
app_binarray = pad_to_block_size(app_binarray, 4, 0)
|
||||
|
||||
app_length = (len(app_binarray))
|
||||
am_print("app_size ",hex(app_length), "(",app_length,")")
|
||||
|
||||
# Create Image blobs
|
||||
|
||||
# w0
|
||||
blobLen = hdr_length + app_length
|
||||
w0 = (magicNum << 24) | ((encVal & 0x1) << 23) | blobLen
|
||||
|
||||
am_print("w0 =", hex(w0))
|
||||
fill_word(hdr_binarray, 0, w0)
|
||||
|
||||
# w2
|
||||
securityVal = ((authI << 1) | crcI) << 4 | (authB << 1) | crcB
|
||||
am_print("Security Value ", hex(securityVal))
|
||||
w2 = ((securityVal << 24) & 0xff000000) | ((authalgo) & 0xf) | ((authKeyIdx << 4) & 0xf0) | ((encalgo << 8) & 0xf00) | ((encKeyIdx << 12) & 0xf000)
|
||||
fill_word(hdr_binarray, 8, w2)
|
||||
am_print("w2 = ",hex(w2))
|
||||
|
||||
|
||||
if (magicNum == AM_IMAGE_MAGIC_INFO0):
|
||||
# Insert the INFO0 size and offset
|
||||
addrWord = ((orig_app_length>>2) << 16) | ((loadaddress>>2) & 0xFFFF)
|
||||
versionKeyWord = INFO_KEY
|
||||
else:
|
||||
# Insert the application binary load address.
|
||||
addrWord = loadaddress | (protection & 0x3)
|
||||
# Initialize versionKeyWord
|
||||
versionKeyWord = (version & 0x7FFF) | ((erasePrev & 0x1) << 15)
|
||||
|
||||
am_print("addrWord = ",hex(addrWord))
|
||||
fill_word(hdr_binarray, AM_IMAGEHDR_OFFSET_ADDR, addrWord)
|
||||
|
||||
am_print("versionKeyWord = ",hex(versionKeyWord))
|
||||
fill_word(hdr_binarray, AM_IMAGEHDR_OFFSET_VERKEY, versionKeyWord)
|
||||
|
||||
# Initialize child (Child Ptr/ Feature key)
|
||||
am_print("child0/feature = ",hex(child0))
|
||||
fill_word(hdr_binarray, AM_IMAGEHDR_OFFSET_CHILDPTR, child0)
|
||||
am_print("child1 = ",hex(child1))
|
||||
fill_word(hdr_binarray, AM_IMAGEHDR_OFFSET_CHILDPTR + 4, child1)
|
||||
|
||||
authKeyIdx = authKeyIdx - minHmacKeyIdx
|
||||
if (authB != 0): # Authentication needed
|
||||
am_print("Boot Authentication Enabled")
|
||||
# am_print("Key used for HMAC")
|
||||
# am_print([hex(keyTblHmac[authKeyIdx*AM_SECBOOT_KEYIDX_BYTES + n]) for n in range (0, AM_HMAC_SIG_SIZE)])
|
||||
# Initialize the clear image HMAC
|
||||
sigClr = compute_hmac(keyTblHmac[authKeyIdx*AM_SECBOOT_KEYIDX_BYTES:(authKeyIdx*AM_SECBOOT_KEYIDX_BYTES+AM_HMAC_SIG_SIZE)], (hdr_binarray[AM_IMAGEHDR_START_HMAC:hdr_length] + app_binarray))
|
||||
am_print("HMAC Clear")
|
||||
am_print([hex(n) for n in sigClr])
|
||||
# Fill up the HMAC
|
||||
for x in range(0, AM_HMAC_SIG_SIZE):
|
||||
hdr_binarray[AM_IMAGEHDR_OFFSET_SIGCLR + x] = sigClr[x]
|
||||
|
||||
# All the header fields part of the encryption are now final
|
||||
if (encVal == 1):
|
||||
am_print("Encryption Enabled")
|
||||
encKeyIdx = encKeyIdx - minAesKeyIdx
|
||||
ivValAes = os.urandom(AM_SECBOOT_AESCBC_BLOCK_SIZE_BYTES)
|
||||
am_print("Initialization Vector")
|
||||
am_print([hex(ivValAes[n]) for n in range (0, AM_SECBOOT_AESCBC_BLOCK_SIZE_BYTES)])
|
||||
keyAes = os.urandom(keySize)
|
||||
am_print("AES Key used for encryption")
|
||||
am_print([hex(keyAes[n]) for n in range (0, keySize)])
|
||||
# Encrypted Part
|
||||
am_print("Encrypting blob of size " , (hdr_length - AM_IMAGEHDR_START_ENCRYPT + app_length))
|
||||
enc_binarray = encrypt_app_aes((hdr_binarray[AM_IMAGEHDR_START_ENCRYPT:hdr_length] + app_binarray), keyAes, ivValAes)
|
||||
# am_print("Key used for encrypting AES Key")
|
||||
# am_print([hex(keyTblAes[encKeyIdx*keySize + n]) for n in range (0, keySize)])
|
||||
# Encrypted Key
|
||||
enc_key = encrypt_app_aes(keyAes, keyTblAes[encKeyIdx*keySize:encKeyIdx*keySize + keySize], ivVal0)
|
||||
am_print("Encrypted Key")
|
||||
am_print([hex(enc_key[n]) for n in range (0, keySize)])
|
||||
# Fill up the IV
|
||||
for x in range(0, AM_SECBOOT_AESCBC_BLOCK_SIZE_BYTES):
|
||||
hdr_binarray[AM_IMAGEHDR_OFFSET_IV + x] = ivValAes[x]
|
||||
# Fill up the Encrypted Key
|
||||
for x in range(0, keySize):
|
||||
hdr_binarray[AM_IMAGEHDR_OFFSET_KEK + x] = enc_key[x]
|
||||
else:
|
||||
enc_binarray = hdr_binarray[AM_IMAGEHDR_START_ENCRYPT:hdr_length] + app_binarray
|
||||
|
||||
|
||||
if (authI != 0): # Install Authentication needed
|
||||
am_print("Install Authentication Enabled")
|
||||
# am_print("Key used for HMAC")
|
||||
# am_print([hex(keyTblHmac[authKeyIdx*AM_SECBOOT_KEYIDX_BYTES + n]) for n in range (0, AM_HMAC_SIG_SIZE)])
|
||||
# Initialize the top level HMAC
|
||||
sig = compute_hmac(keyTblHmac[authKeyIdx*AM_SECBOOT_KEYIDX_BYTES:(authKeyIdx*AM_SECBOOT_KEYIDX_BYTES+AM_HMAC_SIG_SIZE)], (hdr_binarray[AM_IMAGEHDR_START_HMAC_INST:AM_IMAGEHDR_START_ENCRYPT] + enc_binarray))
|
||||
am_print("Generated Signature")
|
||||
am_print([hex(n) for n in sig])
|
||||
# Fill up the HMAC
|
||||
for x in range(0, AM_HMAC_SIG_SIZE):
|
||||
hdr_binarray[AM_IMAGEHDR_OFFSET_SIG + x] = sig[x]
|
||||
# compute the CRC for the blob - this is done on a clear image
|
||||
crc = crc32(hdr_binarray[AM_IMAGEHDR_START_CRC:hdr_length] + app_binarray)
|
||||
am_print("crc = ",hex(crc));
|
||||
w1 = crc
|
||||
fill_word(hdr_binarray, AM_IMAGEHDR_OFFSET_CRC, w1)
|
||||
|
||||
# now output all three binary arrays in the proper order
|
||||
output = output + '_OTA_blob.bin'
|
||||
blob2wiredfile = output # save the output of bin2blob for use by blob2wired
|
||||
am_print("Writing to file ", output)
|
||||
with open(output, mode = 'wb') as out:
|
||||
out.write(hdr_binarray[0:AM_IMAGEHDR_START_ENCRYPT])
|
||||
out.write(enc_binarray)
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Generate the image blob as per command line parameters
|
||||
#
|
||||
#******************************************************************************
|
||||
def blob2wired_process(appFile, imagetype, loadaddress, authalgo, encalgo, authKeyIdx, encKeyIdx, optionsVal, maxSize, output):
|
||||
global uploadbinfile
|
||||
|
||||
app_binarray = bytearray()
|
||||
# Open the file, and read it into an array of integers.
|
||||
print('testing: ' + appFile )
|
||||
with open(appFile,'rb') as f_app:
|
||||
app_binarray.extend(f_app.read())
|
||||
f_app.close()
|
||||
|
||||
# Make sure it is page multiple
|
||||
if ((maxSize & (FLASH_PAGE_SIZE - 1)) != 0):
|
||||
am_print ("split needs to be multiple of flash page size", level=AM_PRINT_LEVEL_ERROR)
|
||||
return
|
||||
|
||||
if (encalgo != 0):
|
||||
if ((encKeyIdx < minAesKeyIdx) or (encKeyIdx > maxAesKeyIdx)):
|
||||
am_print("Invalid encKey Idx ", encKeyIdx, level=AM_PRINT_LEVEL_ERROR)
|
||||
return
|
||||
if (encalgo == 2):
|
||||
if (encKeyIdx & 0x1):
|
||||
am_print("Invalid encKey Idx ", encKeyIdx, level=AM_PRINT_LEVEL_ERROR);
|
||||
return
|
||||
keySize = 32
|
||||
else:
|
||||
keySize = 16
|
||||
if (authalgo != 0):
|
||||
if ((authKeyIdx < minHmacKeyIdx) or (authKeyIdx > maxHmacKeyIdx) or (authKeyIdx & 0x1)):
|
||||
am_print("Invalid authKey Idx ", authKeyIdx, level=AM_PRINT_LEVEL_ERROR);
|
||||
return
|
||||
|
||||
hdr_length = AM_WU_IMAGEHDR_SIZE; #fixed header length
|
||||
am_print("Header Size = ", hex(hdr_length))
|
||||
|
||||
orig_app_length = (len(app_binarray))
|
||||
|
||||
if (encalgo != 0):
|
||||
block_size = keySize
|
||||
app_binarray = pad_to_block_size(app_binarray, block_size, 1)
|
||||
else:
|
||||
# Add Padding
|
||||
app_binarray = pad_to_block_size(app_binarray, 4, 0)
|
||||
|
||||
app_length = (len(app_binarray))
|
||||
am_print("app_size ",hex(app_length), "(",app_length,")")
|
||||
|
||||
if (app_length + hdr_length > maxSize):
|
||||
am_print("Image size bigger than max - Creating Split image")
|
||||
|
||||
start = 0
|
||||
# now output all three binary arrays in the proper order
|
||||
output = output + '_Wired_OTA_blob.bin'
|
||||
uploadbinfile = output; # save the name of the output from blob2wired
|
||||
out = open(output, mode = 'wb')
|
||||
|
||||
while (start < app_length):
|
||||
#generate mutable byte array for the header
|
||||
hdr_binarray = bytearray([0x00]*hdr_length);
|
||||
|
||||
if (app_length - start > maxSize):
|
||||
end = start + maxSize
|
||||
else:
|
||||
end = app_length
|
||||
|
||||
if (imagetype == AM_SECBOOT_WIRED_IMAGETYPE_INFO0_NOOTA):
|
||||
key = INFO_KEY
|
||||
# word offset
|
||||
fill_word(hdr_binarray, AM_WU_IMAGEHDR_OFFSET_ADDR, loadaddress>>2)
|
||||
else:
|
||||
key = FLASH_KEY
|
||||
# load address
|
||||
fill_word(hdr_binarray, AM_WU_IMAGEHDR_OFFSET_ADDR, loadaddress)
|
||||
# Create imageType & options
|
||||
hdr_binarray[AM_WU_IMAGEHDR_OFFSET_IMAGETYPE] = imagetype
|
||||
# Set the options only for the first block
|
||||
if (start == 0):
|
||||
hdr_binarray[AM_WU_IMAGEHDR_OFFSET_OPTIONS] = optionsVal
|
||||
else:
|
||||
hdr_binarray[AM_WU_IMAGEHDR_OFFSET_OPTIONS] = 0
|
||||
|
||||
# Create Info0 Update Blob for wired update
|
||||
fill_word(hdr_binarray, AM_WU_IMAGEHDR_OFFSET_KEY, key)
|
||||
# update size
|
||||
fill_word(hdr_binarray, AM_WU_IMAGEHDR_OFFSET_SIZE, end-start)
|
||||
|
||||
w0 = ((authalgo & 0xf) | ((authKeyIdx << 8) & 0xf00) | ((encalgo << 16) & 0xf0000) | ((encKeyIdx << 24) & 0x0f000000))
|
||||
|
||||
fill_word(hdr_binarray, 0, w0)
|
||||
|
||||
if (encalgo != 0):
|
||||
keyIdx = encKeyIdx - minAesKeyIdx
|
||||
ivValAes = os.urandom(AM_SECBOOT_AESCBC_BLOCK_SIZE_BYTES)
|
||||
am_print("Initialization Vector")
|
||||
am_print([hex(n) for n in ivValAes])
|
||||
keyAes = os.urandom(keySize)
|
||||
am_print("AES Key used for encryption")
|
||||
am_print([hex(keyAes[n]) for n in range (0, keySize)])
|
||||
# Encrypted Part - after security header
|
||||
enc_binarray = encrypt_app_aes((hdr_binarray[AM_WU_IMAGEHDR_START_ENCRYPT:hdr_length] + app_binarray[start:end]), keyAes, ivValAes)
|
||||
# am_print("Key used for encrypting AES Key")
|
||||
# am_print([hex(keyTblAes[keyIdx*AM_SECBOOT_KEYIDX_BYTES + n]) for n in range (0, keySize)])
|
||||
# Encrypted Key
|
||||
enc_key = encrypt_app_aes(keyAes, keyTblAes[keyIdx*AM_SECBOOT_KEYIDX_BYTES:(keyIdx*AM_SECBOOT_KEYIDX_BYTES + keySize)], ivVal0)
|
||||
am_print("Encrypted Key")
|
||||
am_print([hex(enc_key[n]) for n in range (0, keySize)])
|
||||
# Fill up the IV
|
||||
for x in range(0, AM_SECBOOT_AESCBC_BLOCK_SIZE_BYTES):
|
||||
hdr_binarray[AM_WU_IMAGEHDR_OFFSET_IV + x] = ivValAes[x]
|
||||
# Fill up the Encrypted Key
|
||||
for x in range(0, keySize):
|
||||
hdr_binarray[AM_WU_IMAGEHDR_OFFSET_KEK + x] = enc_key[x]
|
||||
else:
|
||||
enc_binarray = hdr_binarray[AM_WU_IMAGEHDR_START_ENCRYPT:hdr_length] + app_binarray[start:end]
|
||||
|
||||
|
||||
if (authalgo != 0): # Authentication needed
|
||||
keyIdx = authKeyIdx - minHmacKeyIdx
|
||||
# am_print("Key used for HMAC")
|
||||
# am_print([hex(keyTblHmac[keyIdx*AM_SECBOOT_KEYIDX_BYTES + n]) for n in range (0, AM_HMAC_SIG_SIZE)])
|
||||
# Initialize the HMAC - Sign is computed on image following the signature
|
||||
sig = compute_hmac(keyTblHmac[keyIdx*AM_SECBOOT_KEYIDX_BYTES:(keyIdx*AM_SECBOOT_KEYIDX_BYTES+AM_HMAC_SIG_SIZE)], hdr_binarray[AM_WU_IMAGEHDR_START_HMAC:AM_WU_IMAGEHDR_START_ENCRYPT] + enc_binarray)
|
||||
am_print("HMAC")
|
||||
am_print([hex(n) for n in sig])
|
||||
# Fill up the HMAC
|
||||
for x in range(0, AM_HMAC_SIG_SIZE):
|
||||
hdr_binarray[AM_WU_IMAGEHDR_OFFSET_SIG + x] = sig[x]
|
||||
|
||||
am_print("Writing to file ", output)
|
||||
am_print("Image from ", str(hex(start)), " to ", str(hex(end)), " will be loaded at", str(hex(loadaddress)))
|
||||
out.write(hdr_binarray[0:AM_WU_IMAGEHDR_START_ENCRYPT])
|
||||
out.write(enc_binarray)
|
||||
|
||||
# Reset start for next chunk
|
||||
start = end
|
||||
loadaddress = loadaddress + maxSize
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Main function
|
||||
#
|
||||
#******************************************************************************
|
||||
def upload(args, verboseprint):
|
||||
|
||||
global loadTries
|
||||
global loadSuccess
|
||||
|
||||
# Open a serial port, and communicate with Device
|
||||
#
|
||||
# Max flashing time depends on the amount of SRAM available.
|
||||
# For very large images, the flashing happens page by page.
|
||||
# However if the image can fit in the free SRAM, it could take a long time
|
||||
# for the whole image to be flashed at the end.
|
||||
# The largest image which can be stored depends on the max SRAM.
|
||||
# Assuming worst case ~100 ms/page of flashing time, and allowing for the
|
||||
# image to be close to occupying full SRAM (256K) which is 128 pages.
|
||||
|
||||
connection_timeout = 5
|
||||
|
||||
print('Connecting over serial port {}...'.format(args.port), flush=True)
|
||||
|
||||
#Check to see if the com port is available
|
||||
try:
|
||||
with serial.Serial(args.port, args.baud, timeout=connection_timeout) as ser:
|
||||
pass
|
||||
except:
|
||||
|
||||
#Show a list of com ports and recommend one
|
||||
print("Detected Serial Ports:")
|
||||
devices = list_ports.comports()
|
||||
port = None
|
||||
for dev in devices:
|
||||
print(dev.description)
|
||||
# The SparkFun BlackBoard has CH340 in the description
|
||||
if 'CH340' in dev.description:
|
||||
print("The port you selected was not found. But we did detect a CH340 on " + dev.device + " so you might try again on that port.")
|
||||
break
|
||||
elif 'FTDI' in dev.description:
|
||||
print("The port you selected was not found. But we did detect an FTDI on " + dev.device + " so you might try again on that port.")
|
||||
break
|
||||
elif 'USB Serial Device' in dev.description:
|
||||
print("The port you selected was not found. But we did detect a USB Serial Device on " + dev.device + " so you might try again on that port.")
|
||||
break
|
||||
else:
|
||||
print("Com Port not found - Did you select the right one?")
|
||||
|
||||
exit()
|
||||
|
||||
#Begin talking over com port
|
||||
|
||||
#The auto-bootload sequence is good but not fullproof. The bootloader
|
||||
#fails to correctly catch the BOOT signal about 1 out of ten times.
|
||||
#Auto-retry this number of times before we give up.
|
||||
|
||||
while loadTries < 3:
|
||||
loadSuccess = False
|
||||
|
||||
with serial.Serial(args.port, args.baud, timeout=connection_timeout) as ser:
|
||||
#DTR is driven low when serial port open. DTR has now pulled RST low.
|
||||
|
||||
time.sleep(0.005) #3ms and 10ms work well. Not 50, and not 0.
|
||||
|
||||
#Setting RTS/DTR high causes the bootload pin to go high, then fall across 100ms
|
||||
ser.setDTR(0) #Set DTR high
|
||||
ser.setRTS(0) #Set RTS high - support the CH340E
|
||||
|
||||
#Give bootloader a chance to run and check bootload pin before communication begins. But must initiate com before bootloader timeout of 250ms.
|
||||
time.sleep(0.100) #100ms works well
|
||||
|
||||
ser.reset_input_buffer() # reset the input bufer to discard any UART traffic that the device may have generated
|
||||
|
||||
connect_device(ser, args, verboseprint)
|
||||
|
||||
if(loadSuccess == True):
|
||||
print("Tries =", loadTries)
|
||||
print('Upload complete!')
|
||||
exit()
|
||||
else:
|
||||
print("Fail")
|
||||
|
||||
loadTries = loadTries + 1
|
||||
|
||||
print("Tries =", loadTries)
|
||||
print("Upload failed")
|
||||
exit()
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Communicate with Device
|
||||
#
|
||||
# Given a serial port, connects to the target device using the
|
||||
# UART.
|
||||
#
|
||||
#******************************************************************************
|
||||
def connect_device(ser, args, verboseprint):
|
||||
|
||||
global loadSuccess
|
||||
|
||||
# Send Hello
|
||||
#generate mutable byte array for the header
|
||||
hello = bytearray([0x00]*4)
|
||||
fill_word(hello, 0, ((8 << 16) | AM_SECBOOT_WIRED_MSGTYPE_HELLO))
|
||||
verboseprint('Sending Hello.')
|
||||
response = send_command(hello, 88, ser, verboseprint)
|
||||
|
||||
#Check if response failed
|
||||
if response == False:
|
||||
verboseprint("Failed to respond")
|
||||
return
|
||||
|
||||
verboseprint("Received response for Hello")
|
||||
word = word_from_bytes(response, 4)
|
||||
if ((word & 0xFFFF) == AM_SECBOOT_WIRED_MSGTYPE_STATUS):
|
||||
# Received Status
|
||||
print("Bootloader connected")
|
||||
|
||||
verboseprint("Received Status")
|
||||
verboseprint("length = ", hex((word >> 16)))
|
||||
verboseprint("version = ", hex(word_from_bytes(response, 8)))
|
||||
verboseprint("Max Storage = ", hex(word_from_bytes(response, 12)))
|
||||
verboseprint("Status = ", hex(word_from_bytes(response, 16)))
|
||||
verboseprint("State = ", hex(word_from_bytes(response, 20)))
|
||||
verboseprint("AMInfo = ")
|
||||
for x in range(24, 88, 4):
|
||||
verboseprint(hex(word_from_bytes(response, x)))
|
||||
|
||||
abort = args.abort
|
||||
if (abort != -1):
|
||||
# Send OTA Desc
|
||||
verboseprint('Sending Abort command.')
|
||||
abortMsg = bytearray([0x00]*8);
|
||||
fill_word(abortMsg, 0, ((12 << 16) | AM_SECBOOT_WIRED_MSGTYPE_ABORT))
|
||||
fill_word(abortMsg, 4, abort)
|
||||
if send_ackd_command(abortMsg, ser, verboseprint) == False:
|
||||
verboseprint("Failed to ack command")
|
||||
return
|
||||
|
||||
|
||||
otadescaddr = args.otadesc
|
||||
if (otadescaddr != 0xFFFFFFFF):
|
||||
# Send OTA Desc
|
||||
verboseprint('Sending OTA Descriptor = ', hex(otadescaddr))
|
||||
otaDesc = bytearray([0x00]*8);
|
||||
fill_word(otaDesc, 0, ((12 << 16) | AM_SECBOOT_WIRED_MSGTYPE_OTADESC))
|
||||
fill_word(otaDesc, 4, otadescaddr)
|
||||
if send_ackd_command(otaDesc, ser, verboseprint) == False:
|
||||
verboseprint("Failed to ack command")
|
||||
return
|
||||
|
||||
|
||||
imageType = args.imagetype
|
||||
if (uploadbinfile != ''):
|
||||
|
||||
# Read the binary file from the command line.
|
||||
with open(uploadbinfile, mode='rb') as binfile:
|
||||
application = binfile.read()
|
||||
# Gather the important binary metadata.
|
||||
totalLen = len(application)
|
||||
# Send Update command
|
||||
verboseprint('Sending Update Command.')
|
||||
|
||||
# It is assumed that maxSize is 256b multiple
|
||||
maxImageSize = args.split
|
||||
if ((maxImageSize & (FLASH_PAGE_SIZE - 1)) != 0):
|
||||
verboseprint ("split needs to be multiple of flash page size")
|
||||
return
|
||||
|
||||
# Each Block of image consists of AM_WU_IMAGEHDR_SIZE Bytes Image header and the Image blob
|
||||
maxUpdateSize = AM_WU_IMAGEHDR_SIZE + maxImageSize
|
||||
numUpdates = (totalLen + maxUpdateSize - 1) // maxUpdateSize # Integer division
|
||||
verboseprint("number of updates needed = ", numUpdates)
|
||||
|
||||
end = totalLen
|
||||
for numUpdates in range(numUpdates, 0 , -1):
|
||||
start = (numUpdates-1)*maxUpdateSize
|
||||
crc = crc32(application[start:end])
|
||||
applen = end - start
|
||||
verboseprint("Sending block of size ", str(hex(applen)), " from ", str(hex(start)), " to ", str(hex(end)))
|
||||
end = end - applen
|
||||
|
||||
update = bytearray([0x00]*16);
|
||||
fill_word(update, 0, ((20 << 16) | AM_SECBOOT_WIRED_MSGTYPE_UPDATE))
|
||||
fill_word(update, 4, applen)
|
||||
fill_word(update, 8, crc)
|
||||
# Size = 0 => We're not piggybacking any data to IMAGE command
|
||||
fill_word(update, 12, 0)
|
||||
|
||||
if send_ackd_command(update, ser, verboseprint) == False:
|
||||
verboseprint("Failed to ack command")
|
||||
return
|
||||
|
||||
# Loop over the bytes in the image, and send them to the target.
|
||||
resp = 0
|
||||
# Max chunk size is AM_MAX_UART_MSG_SIZE adjusted for the header for Data message
|
||||
maxChunkSize = AM_MAX_UART_MSG_SIZE - 12
|
||||
for x in range(0, applen, maxChunkSize):
|
||||
# Split the application into chunks of maxChunkSize bytes.
|
||||
# This is the max chunk size supported by the UART bootloader
|
||||
if ((x + maxChunkSize) > applen):
|
||||
chunk = application[start+x:start+applen]
|
||||
# print(str(hex(start+x)), " to ", str(hex(applen)))
|
||||
else:
|
||||
chunk = application[start+x:start+x+maxChunkSize]
|
||||
# print(str(hex(start+x)), " to ", str(hex(start + x + maxChunkSize)))
|
||||
|
||||
chunklen = len(chunk)
|
||||
|
||||
# Build a data packet with a "data command" a "length" and the actual
|
||||
# payload bytes, and send it to the target.
|
||||
dataMsg = bytearray([0x00]*8);
|
||||
fill_word(dataMsg, 0, (((chunklen + 12) << 16) | AM_SECBOOT_WIRED_MSGTYPE_DATA))
|
||||
# seqNo
|
||||
fill_word(dataMsg, 4, x)
|
||||
|
||||
verboseprint("Sending Data Packet of length ", chunklen)
|
||||
if send_ackd_command(dataMsg + chunk, ser, verboseprint) == False:
|
||||
verboseprint("Failed to ack command")
|
||||
return
|
||||
|
||||
if (args.raw != ''):
|
||||
|
||||
# Read the binary file from the command line.
|
||||
with open(args.raw, mode='rb') as rawfile:
|
||||
blob = rawfile.read()
|
||||
# Send Raw command
|
||||
verboseprint('Sending Raw Command.')
|
||||
ser.write(blob)
|
||||
|
||||
if (args.reset != 0):
|
||||
# Send reset
|
||||
verboseprint('Sending Reset Command.')
|
||||
resetmsg = bytearray([0x00]*8);
|
||||
fill_word(resetmsg, 0, ((12 << 16) | AM_SECBOOT_WIRED_MSGTYPE_RESET))
|
||||
# options
|
||||
fill_word(resetmsg, 4, args.reset)
|
||||
if send_ackd_command(resetmsg, ser, verboseprint) == False:
|
||||
verboseprint("Failed to ack command")
|
||||
return
|
||||
|
||||
|
||||
#Success! We're all done
|
||||
loadSuccess = True
|
||||
else:
|
||||
# Received Wrong message
|
||||
verboseprint("Received Unknown Message")
|
||||
word = word_from_bytes(response, 4)
|
||||
verboseprint("msgType = ", hex(word & 0xFFFF))
|
||||
verboseprint("Length = ", hex(word >> 16))
|
||||
verboseprint([hex(n) for n in response])
|
||||
#print("!!!Wired Upgrade Unsuccessful!!!....Terminating the script")
|
||||
|
||||
#exit()
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Send ACK'd command
|
||||
#
|
||||
# Sends a command, and waits for an ACK.
|
||||
#
|
||||
#******************************************************************************
|
||||
def send_ackd_command(command, ser, verboseprint):
|
||||
|
||||
response = send_command(command, 20, ser, verboseprint)
|
||||
|
||||
#Check if response failed
|
||||
if response == False:
|
||||
verboseprint("Response not valid")
|
||||
return False #Return error
|
||||
|
||||
word = word_from_bytes(response, 4)
|
||||
if ((word & 0xFFFF) == AM_SECBOOT_WIRED_MSGTYPE_ACK):
|
||||
# Received ACK
|
||||
if (word_from_bytes(response, 12) != AM_SECBOOT_WIRED_ACK_STATUS_SUCCESS):
|
||||
verboseprint("Received NACK")
|
||||
verboseprint("msgType = ", hex(word_from_bytes(response, 8)))
|
||||
verboseprint("error = ", hex(word_from_bytes(response, 12)))
|
||||
verboseprint("seqNo = ", hex(word_from_bytes(response, 16)))
|
||||
#print("!!!Wired Upgrade Unsuccessful!!!....Terminating the script")
|
||||
verboseprint("Upload failed: No ack to command")
|
||||
|
||||
return False #Return error
|
||||
|
||||
return response
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Send command
|
||||
#
|
||||
# Sends a command, and waits for the response.
|
||||
#
|
||||
#******************************************************************************
|
||||
def send_command(params, response_len, ser, verboseprint):
|
||||
|
||||
# Compute crc
|
||||
crc = crc32(params)
|
||||
# print([hex(n) for n in int_to_bytes(crc)])
|
||||
# print([hex(n) for n in params])
|
||||
# send crc first
|
||||
ser.write(int_to_bytes(crc))
|
||||
|
||||
# Next, send the parameters.
|
||||
ser.write(params)
|
||||
|
||||
response = ''
|
||||
response = ser.read(response_len)
|
||||
|
||||
# Make sure we got the number of bytes we asked for.
|
||||
if len(response) != response_len:
|
||||
verboseprint('No response for command 0x{:08X}'.format(word_from_bytes(params, 0) & 0xFFFF))
|
||||
n = len(response)
|
||||
if (n != 0):
|
||||
verboseprint("received bytes ", len(response))
|
||||
verboseprint([hex(n) for n in response])
|
||||
return False
|
||||
|
||||
return response
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Send a command that uses an array of bytes as its parameters.
|
||||
#
|
||||
#******************************************************************************
|
||||
def send_bytewise_command(command, params, response_len, ser):
|
||||
# Send the command first.
|
||||
ser.write(int_to_bytes(command))
|
||||
|
||||
# Next, send the parameters.
|
||||
ser.write(params)
|
||||
|
||||
response = ''
|
||||
response = ser.read(response_len)
|
||||
|
||||
# Make sure we got the number of bytes we asked for.
|
||||
if len(response) != response_len:
|
||||
print("Upload failed: No reponse to command")
|
||||
verboseprint('No response for command 0x{:08X}'.format(command))
|
||||
exit()
|
||||
|
||||
return response
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Errors
|
||||
#
|
||||
#******************************************************************************
|
||||
class BootError(Exception):
|
||||
pass
|
||||
|
||||
class NoAckError(BootError):
|
||||
pass
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser(description =
|
||||
'Combination script to upload application binaries to Artemis module. Includes:\n\t\'- bin2blob: create OTA blob from binary image\'\n\t\'- blob2wired: create wired update image from OTA blob\'\n\t\'- upload: send wired update image to Apollo3 Artemis module via serial port\'\n\nThere are many command-line arguments. They have been labeled by which steps they apply to\n')
|
||||
|
||||
parser.add_argument('-a', dest = 'abort', default=-1, type=int, choices = [0,1,-1],
|
||||
help = 'upload: Should it send abort command? (0 = abort, 1 = abort and quit, -1 = no abort) (default is -1)')
|
||||
|
||||
parser.add_argument('--authalgo', dest = 'authalgo', type=auto_int, default=0, choices=range(0, AM_SECBOOT_AUTH_ALGO_MAX+1),
|
||||
help = 'bin2blob, blob2wired: ' + str(helpAuthAlgo))
|
||||
|
||||
parser.add_argument('--authI', dest = 'authI', type=auto_int, default=0, choices=[0,1],
|
||||
help = 'bin2blob: Install Authentication check enabled (Default = N)?')
|
||||
|
||||
parser.add_argument('--authB', dest = 'authB', type=auto_int, default=0, choices=[0,1],
|
||||
help = 'bin2blob: Boot Authentication check enabled (Default = N)?')
|
||||
|
||||
parser.add_argument('--authkey', dest = 'authkey', type=auto_int, default=(minHmacKeyIdx), choices = range(minHmacKeyIdx, maxHmacKeyIdx + 1),
|
||||
help = 'bin2blob, blob2wired: Authentication Key Idx? (' + str(minHmacKeyIdx) + ' to ' + str(maxHmacKeyIdx) + ')')
|
||||
|
||||
parser.add_argument('-b', dest='baud', default=115200, type=int,
|
||||
help = 'upload: Baud Rate (default is 115200)')
|
||||
|
||||
parser.add_argument('--bin', dest='appFile', type=argparse.FileType('rb'),
|
||||
help='bin2blob: binary file (blah.bin)')
|
||||
|
||||
parser.add_argument('-clean', dest='clean', default=0, type=int,
|
||||
help = 'All: whether or not to remove intermediate files')
|
||||
|
||||
parser.add_argument('--child0', dest = 'child0', type=auto_int, default=hex(0xFFFFFFFF),
|
||||
help = 'bin2blob: child (blobPtr#0 for Main / feature key for AM3P)')
|
||||
|
||||
parser.add_argument('--child1', dest = 'child1', type=auto_int, default=hex(0xFFFFFFFF),
|
||||
help = 'bin2blob: child (blobPtr#1 for Main)')
|
||||
|
||||
parser.add_argument('--crcI', dest = 'crcI', type=auto_int, default=1, choices=[0,1],
|
||||
help = 'bin2blob: Install CRC check enabled (Default = Y)?')
|
||||
|
||||
parser.add_argument('--crcB', dest = 'crcB', type=auto_int, default=0, choices=[0,1],
|
||||
help = 'bin2blob: Boot CRC check enabled (Default = N)?')
|
||||
|
||||
parser.add_argument('--encalgo', dest = 'encalgo', type=auto_int, default=0, choices = range(0, AM_SECBOOT_ENC_ALGO_MAX+1),
|
||||
help = 'bin2blob, blob2wired: ' + str(helpEncAlgo))
|
||||
|
||||
parser.add_argument('--erasePrev', dest = 'erasePrev', type=auto_int, default=0, choices=[0,1],
|
||||
help = 'bin2blob: erasePrev (Valid only for main)')
|
||||
|
||||
# parser.add_argument('-f', dest='binfile', default='',
|
||||
# help = 'upload: Binary file to program into the target device')
|
||||
|
||||
parser.add_argument('-i', dest = 'imagetype', default=AM_SECBOOT_WIRED_IMAGETYPE_INVALID, type=auto_int,
|
||||
choices = [
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_SBL),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_AM3P),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_PATCH),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_MAIN),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_CHILD),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_CUSTPATCH),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_NONSECURE),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_INFO0),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_INFO0_NOOTA),
|
||||
(AM_SECBOOT_WIRED_IMAGETYPE_INVALID)
|
||||
],
|
||||
help = 'blob2wired, upload: ImageType ('
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_SBL) + ': SBL, '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_AM3P) + ': AM3P, '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_PATCH) + ': Patch, '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_MAIN) + ': Main, '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_CHILD) + ': Child, '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_CUSTPATCH) + ': CustOTA, '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_NONSECURE) + ': NonSecure, '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_INFO0) + ': Info0 '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_INFO0_NOOTA) + ': Info0_NOOTA) '
|
||||
+ str(AM_SECBOOT_WIRED_IMAGETYPE_INVALID) + ': Invalid) '
|
||||
'- default[Invalid]')
|
||||
|
||||
parser.add_argument('--kek', dest = 'kek', type=auto_int, default=(minAesKeyIdx), choices = range(minAesKeyIdx, maxAesKeyIdx+1),
|
||||
help = 'KEK index? (' + str(minAesKeyIdx) + ' to ' + str(maxAesKeyIdx) + ')')
|
||||
|
||||
parser.add_argument('--load-address-wired', dest='loadaddress_blob', type=auto_int, default=hex(0x60000),
|
||||
help='blob2wired: Load address of the binary - Where in flash the blob will be stored (could be different than install address of binary within).')
|
||||
|
||||
parser.add_argument('--load-address-blob', dest='loadaddress_image', type=auto_int, default=hex(AM_SECBOOT_DEFAULT_NONSECURE_MAIN),
|
||||
help='bin2blob: Load address of the binary.')
|
||||
|
||||
parser.add_argument('--loglevel', dest='loglevel', type=auto_int, default=AM_PRINT_LEVEL_INFO,
|
||||
choices = range(AM_PRINT_LEVEL_MIN, AM_PRINT_LEVEL_MAX+1),
|
||||
help='bin2blob, blob2wired: ' + str(helpPrintLevel))
|
||||
|
||||
parser.add_argument('--magic-num', dest='magic_num', default=hex(AM_IMAGE_MAGIC_NONSECURE),
|
||||
type=lambda x: x.lower(),
|
||||
# type = str.lower,
|
||||
choices = [
|
||||
hex(AM_IMAGE_MAGIC_MAIN),
|
||||
hex(AM_IMAGE_MAGIC_CHILD),
|
||||
hex(AM_IMAGE_MAGIC_CUSTPATCH),
|
||||
hex(AM_IMAGE_MAGIC_NONSECURE),
|
||||
hex(AM_IMAGE_MAGIC_INFO0)
|
||||
],
|
||||
help = 'bin2blob: Magic Num ('
|
||||
+ str(hex(AM_IMAGE_MAGIC_MAIN)) + ': Main, '
|
||||
+ str(hex(AM_IMAGE_MAGIC_CHILD)) + ': Child, '
|
||||
+ str(hex(AM_IMAGE_MAGIC_CUSTPATCH)) + ': CustOTA, '
|
||||
+ str(hex(AM_IMAGE_MAGIC_NONSECURE)) + ': NonSecure, '
|
||||
+ str(hex(AM_IMAGE_MAGIC_INFO0)) + ': Info0) '
|
||||
'- default[Main]'
|
||||
)
|
||||
|
||||
parser.add_argument('-o', dest = 'output', default='wuimage',
|
||||
help = 'all: Output filename (without the extension) [also used for intermediate filenames]')
|
||||
|
||||
parser.add_argument('-ota', dest = 'otadesc', type=auto_int, default=0xFE000,
|
||||
help = 'upload: OTA Descriptor Page address (hex) - (Default is 0xFE000 - at the end of main flash) - enter 0xFFFFFFFF to instruct SBL to skip OTA')
|
||||
|
||||
parser.add_argument('--options', dest = 'options', type=auto_int, default=0x1,
|
||||
help = 'blob2wired: Options (16b hex value) - bit0 instructs to perform OTA of the image after wired download (set to 0 if only downloading & skipping OTA flow)')
|
||||
|
||||
parser.add_argument('-p', dest = 'protection', type=auto_int, default=0, choices = [0x0, 0x1, 0x2, 0x3],
|
||||
help = 'bin2blob: protection info 2 bit C W')
|
||||
|
||||
parser.add_argument('-port', dest = 'port', help = 'upload: Serial COMx Port')
|
||||
|
||||
parser.add_argument('-r', dest = 'reset', default=1, type=auto_int, choices = [0,1,2],
|
||||
help = 'upload: Should it send reset command after image download? (0 = no reset, 1 = POI, 2 = POR) (default is 1)')
|
||||
|
||||
parser.add_argument('--raw', dest='raw', default='',
|
||||
help = 'upload: Binary file for raw message')
|
||||
|
||||
parser.add_argument('--split', dest='split', type=auto_int, default=hex(MAX_DOWNLOAD_SIZE),
|
||||
help='blob2wired, upload: Specify the max block size if the image will be downloaded in pieces')
|
||||
|
||||
parser.add_argument('--version', dest = 'version', type=auto_int, default=0,
|
||||
help = 'bin2blob: version (15 bit)')
|
||||
|
||||
parser.add_argument("-v", "--verbose", default=0, help="All: Enable verbose output",
|
||||
action="store_true")
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
args.magic_num = int(args.magic_num, 16)
|
||||
|
||||
|
||||
return args
|
||||
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Main function.
|
||||
#
|
||||
#******************************************************************************
|
||||
|
||||
# example calling:
|
||||
# python artemis_bin_to_board.py --bin application.bin --load-address-blob 0x20000 --magic-num 0xCB -o application --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b 921600 -port COM4 -r 1 -v
|
||||
|
||||
def main():
|
||||
# Read the arguments.
|
||||
args = parse_arguments()
|
||||
am_set_print_level(args.loglevel)
|
||||
|
||||
global blob2wiredfile
|
||||
|
||||
bin2blob_process(args.loadaddress_blob, args.appFile, args.magic_num, args.crcI, args.crcB, args.authI, args.authB, args.protection, args.authkey, args.output, args.kek, args.version, args.erasePrev, args.child0, args.child1, args.authalgo, args.encalgo)
|
||||
blob2wired_process( blob2wiredfile, args.imagetype, args.loadaddress_image, args.authalgo, args.encalgo, args.authkey, args.kek, args.options, args.split, args.output)
|
||||
|
||||
# todo: link the bin2blob step with the blob2wired step by input/output files
|
||||
|
||||
|
||||
#Create print function for verbose output if caller deems it: https://stackoverflow.com/questions/5980042/how-to-implement-the-verbose-or-v-option-into-a-script
|
||||
if args.verbose:
|
||||
def verboseprint(*args):
|
||||
# Print each argument separately so caller doesn't need to
|
||||
# stuff everything to be printed into a single string
|
||||
for arg in args:
|
||||
print(arg, end=''),
|
||||
print()
|
||||
else:
|
||||
verboseprint = lambda *a: None # do-nothing function
|
||||
|
||||
upload(args, verboseprint)
|
||||
|
||||
if(args.clean == 1):
|
||||
print('Cleaning up intermediate files') # todo: why isnt this showing w/ -clean option?
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
BIN
Binary file not shown.
Vendored
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python3
|
||||
from am_defines import *
|
||||
|
||||
minAesKeyIdx = 8
|
||||
maxAesKeyIdx = 15
|
||||
minHmacKeyIdx = 8
|
||||
maxHmacKeyIdx = 15
|
||||
|
||||
###### Following are just dummy keys - Should be substituted with real keys #######
|
||||
keyTblAes = [
|
||||
# Info0 Keys - Starting at index 8
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
||||
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||
0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,
|
||||
]
|
||||
|
||||
keyTblHmac = [
|
||||
# Info0 Keys - Starting at index 8
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
|
||||
0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,
|
||||
]
|
||||
|
||||
custKey = [
|
||||
0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,
|
||||
]
|
||||
|
||||
# These are dummy values. Contact AMBIQ to get the real Recovery Key
|
||||
recoveryKey = [
|
||||
0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE,
|
||||
]
|
||||
|
||||
###################################################################################
|
||||
|
||||
wrapKey = custKey
|
||||
minWrapMode = AM_SECBOOT_KEYWRAP_NONE
|
||||
|
||||
INFO_KEY = 0xd894e09e
|
||||
FLASH_KEY = 0x12344321
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
###### Requirements ######`
|
||||
pyinstaller == 3.6
|
||||
pycryptodome
|
||||
pyserial
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
//connect to device
|
||||
device AMA3B1KK-KBR
|
||||
si SWD
|
||||
speed 1000
|
||||
r
|
||||
sleep 10
|
||||
|
||||
//set C runtime environment
|
||||
wreg MSP, 0x10000100
|
||||
|
||||
// erase info0
|
||||
w4 0x10000000 0 // flash info instance
|
||||
w4 0x10000004 0xd894e09e // info 0 key
|
||||
w4 0x10000008 0xFFFFFFFF // clear return value
|
||||
setPC 0x08000085 // call the ROM helper function flash_info_erase_from_sram
|
||||
g
|
||||
sleep 50
|
||||
mem32 0x10000008 1 // dump return value for check
|
||||
|
||||
// program info0
|
||||
w4 0x10000000 0 // flash info instance
|
||||
w4 0x10000004 0 // offset
|
||||
w4 0x10000008 0x800 // length in words
|
||||
w4 0x1000000C 0xd894e09e // info 0 key
|
||||
w4 0x10000010 0xFFFFFFFF // clear return value
|
||||
loadbin info0_artemis_47_115200.bin 0x10001000 //load the info0 binary into sram
|
||||
setPC 0x08000061 // call the ROM helper function flash_program_info_area_from_sram
|
||||
g
|
||||
sleep 50
|
||||
mem32 0x10000010 1 // dump return value for check
|
||||
|
||||
loadbin artemis_svl.bin 0x0000C000 //load SVL into 0xC000 (end of Ambiq bootloader)
|
||||
|
||||
loadbin example1_blink.ino.bin 0x00010000 //load Blink after SVL
|
||||
|
||||
// perform software POI
|
||||
w4 0x40000004 0x1B
|
||||
|
||||
// quit
|
||||
qc
|
||||
@@ -0,0 +1,25 @@
|
||||
Artemis Bootloader
|
||||
==========================
|
||||
|
||||
The Artemis module is loaded with two bootloaders: the ASB and SVL. The Ambiq Secure Boot Loader (ASB) resides from 0x00 to 0xC000. This bootloader is physically part of the IC and is configured using the info0 registers. At power up, if the ASB is not activated, it jumps to 0xC000. The SparkFun Variable Bootloader (SVL) resides at 0xC000 and will wait for an incoming serial character. If a character is received, the baud rate will be auto-detected, the SVL will load new code, then jump to the new user code starting at 0x10000. The SVL times out after 50ms.
|
||||
|
||||
This directory contains the various binaries that are programmed onto each Artemis module:
|
||||
|
||||
* info0_artemis_47_115200.bin - Sets the Ambiq Secure Bootloader (ASB) to 115200bps with boot pin on 47
|
||||
* artemis_svl.bin - the SparkFun Variable Loader (SVL), starts at 0xC000
|
||||
* example1_blink.ino.bin - An example sketch to blink the LED. This shows code has been loaded but will be overwritten with new sketches.
|
||||
|
||||
For more information on the Artemis Bootloader see the Artemis Bootloader in the [Arduino_Apollo3 repo](https://github.com/sparkfun/Arduino_Apollo3/tree/master/bootloaders/artemis/!artemis_svl).
|
||||
|
||||
The ASB is configured based on the documents from Ambiq (Ambiq calls it the secure bootloader or SBL). See \AmbiqSuite-Rel2.x.x\docs\secure_bootloader\ for how to modify the info0 image.
|
||||
|
||||
* Run the bootloader at 921600bps: --u0 0x1C299c0
|
||||
* Currently pin 47 is used for BOOTLOAD: --gpio 0x2f
|
||||
* Bootloader to check if BOOTLOAD pin is high (not low): --gpiolvl 1
|
||||
* Trim timeout to 2500ms: --wTO 2500
|
||||
|
||||
This was used for Artemis v10 module that used pin 47 for boot:
|
||||
|
||||
create_info0.py --valid 1 info0_artemis_47 --pl 1 --u0 0x1C200c0 --u1 0xFFFF3031 --u2 0x2 --u3 0x0 --u4 0x0 --u5 0x0 --main 0xC000 --gpio 0x2f --version 0 --wTO 2500 --gpiolvl 1
|
||||
|
||||
We load a conservative 115200bps image into the Ambiq ASB section so that future updates can be applied. The SparkFun Variable Loader is a variable bootloader capable of operating from 9600bps to 921600bps.
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
# requires:
|
||||
# make
|
||||
|
||||
# example usage
|
||||
# locations:
|
||||
# from bsp repo root:
|
||||
# common/bsp_pinconfig/scripts/regen_bsp_libs.sh
|
||||
# from remote location: (requires $AMSDK environment variable -- {boards_sfe} can be whatever you named the root of the bsp repo )
|
||||
# $AMSDK/{boards_sfe}/common/bsp_pinconfig/scripts/regen_bsp_libs.sh -r $AMSDK/{boards_sfe}
|
||||
# arguments:
|
||||
# [-r $BSP_ROOT] path to bsp root optional -- defaults to the current directory
|
||||
# (should be specified when calling script remotely)
|
||||
# [-b $BOARDS_FILE] path to boards file optional -- defaults to all supported bsp boards
|
||||
# (for now boards must still have source files located in the bsp repo)
|
||||
|
||||
# setup
|
||||
set -e
|
||||
set -o errexit
|
||||
echo "" 1>&2
|
||||
|
||||
# get enclosing directory
|
||||
DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
|
||||
|
||||
# defaults
|
||||
BSP_ROOT=.
|
||||
BOARDS_FILE=$DIR/configuration/boards.sh
|
||||
|
||||
# handle arguments
|
||||
while getopts ":r:b:" opt; do
|
||||
case $opt in
|
||||
r) BSP_ROOT="$OPTARG"
|
||||
;;
|
||||
b) BOARDS_FILE="$OPTARG"
|
||||
;;
|
||||
\?) echo "Invalid option -$OPTARG" 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# verify bsp root
|
||||
echo "Using \$BSP_ROOT=$BSP_ROOT" 1>&2
|
||||
VFILE=$BSP_ROOT/README.md
|
||||
if [ -f "$VFILE" ];
|
||||
then
|
||||
echo "\$BSP_ROOT verification passed" 1>&2
|
||||
else
|
||||
echo "\$BSP_ROOT verification failed" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# load in boards to handle
|
||||
echo "Using \$BOARDS_FILE=$BOARDS_FILE" 1>&2
|
||||
source $BOARDS_FILE
|
||||
|
||||
echo "" 1>&2
|
||||
for value in $BOARDS
|
||||
do
|
||||
echo "Cleaning all examples for: $value" 1>&2
|
||||
|
||||
# https://unix.stackexchange.com/questions/86722/how-do-i-loop-through-only-directories-in-bash
|
||||
# https://stackoverflow.com/questions/4515866/iterate-through-subdirectories-in-bash
|
||||
# https://stackoverflow.com/questions/9018723/what-is-the-simplest-way-to-remove-a-trailing-slash-from-each-parameter
|
||||
# shopt -s nullglob
|
||||
for f in $BSP_ROOT/$value/examples/*/; do
|
||||
if [[ "$f" = "*" ]]; then continue; fi # protect from empty directories
|
||||
if [[ -d "$f" && ! -L "$f" ]]; then
|
||||
# # $f is a directory and is not a symlink
|
||||
# echo "Removing: $f/gcc/bin"
|
||||
# rm -rf $f/gcc/bin
|
||||
echo "cleaning ${f%/}"
|
||||
make -f ${f%/}/gcc/Makefile clean PROJECTPATH=${f%/}
|
||||
fi
|
||||
done
|
||||
done
|
||||
+1
@@ -0,0 +1 @@
|
||||
export BOARDS="edge edge2 artemis_module artemis_thing_plus redboard_artemis redboard_artemis_atp redboard_artemis_nano artemis_dk"
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"copy": [
|
||||
{
|
||||
"from": "devices",
|
||||
"to": "targets/TARGET_Ambiq_Micro/sdk/devices",
|
||||
"ignore": [
|
||||
"am_devices_da14581.c",
|
||||
"am_devices_da14581.h",
|
||||
"am_devices_em9304.c",
|
||||
"am_devices_em9304.h",
|
||||
"am_devices_fireball.c",
|
||||
"am_devices_fireball.h",
|
||||
"am_devices_mb85rc256v.c",
|
||||
"am_devices_mb85rc256v.h",
|
||||
"am_devices_mb85rs1mt.c",
|
||||
"am_devices_mb85rs1mt.h",
|
||||
"am_devices_mspi_atxp032.c",
|
||||
"am_devices_mspi_atxp032.h",
|
||||
"am_devices_mspi_psram_aps6404l.c",
|
||||
"am_devices_mspi_psram_aps6404l.h",
|
||||
"am_devices_mspi_rm67162.c",
|
||||
"am_devices_mspi_rm67162.h",
|
||||
"am_devices_mspi_s25fs064s.c",
|
||||
"am_devices_mspi_s25fs064s.h",
|
||||
"am_devices_spiflash.c",
|
||||
"am_devices_spiflash.h"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "utils",
|
||||
"to": "targets/TARGET_Ambiq_Micro/sdk/utils",
|
||||
"ignore": [
|
||||
"am_util_faultisr.c",
|
||||
"am_util_regdump.c"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "mcu",
|
||||
"to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/sdk/mcu",
|
||||
"ignore": [
|
||||
"apollo",
|
||||
"apollo2",
|
||||
"apollo3p",
|
||||
"Makefile",
|
||||
"gcc",
|
||||
"iar",
|
||||
"keil"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "CMSIS",
|
||||
"to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/sdk/CMSIS",
|
||||
"ignore": [
|
||||
"apollo1.h",
|
||||
"apollo2.h",
|
||||
"apollo3p.h",
|
||||
"system_apollo1.h",
|
||||
"system_apollo2.h",
|
||||
"system_apollo3p.h",
|
||||
"system_apollo1.c",
|
||||
"system_apollo2.c",
|
||||
"system_apollo3p.c",
|
||||
"startup_apollo1.s",
|
||||
"startup_apollo2.s",
|
||||
"startup_apollo3.s",
|
||||
"startup_apollo3p.s",
|
||||
"arm_math.h",
|
||||
"cmsis_armcc.h",
|
||||
"cmsis_armclang.h",
|
||||
"cmsis_compiler.h",
|
||||
"cmsis_gcc.h",
|
||||
"cmsis_iccarm.h",
|
||||
"cmsis_version.h",
|
||||
"core_cm4.h",
|
||||
"mpu_armv7.h",
|
||||
"arm_cortexM4l_math.lib",
|
||||
"arm_cortexM4lf_math.lib",
|
||||
"iar_cortexM4l_math.a",
|
||||
"iar_cortexM4lf_math.a",
|
||||
"libarm_cortexM4l_math.a"
|
||||
]
|
||||
},
|
||||
|
||||
{"from": "boards_sfe/artemis_dk/bsp", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/TARGET_SFE_ARTEMIS_DK/bsp", "ignore": ["gcc", "bsp_pins.src"]},
|
||||
{"from": "boards_sfe/artemis_thing_plus/bsp", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/TARGET_SFE_ARTEMIS_THING_PLUS/bsp", "ignore": ["gcc", "bsp_pins.src"]},
|
||||
{"from": "boards_sfe/edge/bsp", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/TARGET_SFE_EDGE/bsp", "ignore": ["gcc", "bsp_pins.src"]},
|
||||
{"from": "boards_sfe/edge2/bsp", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/TARGET_SFE_EDGE2/bsp", "ignore": ["gcc", "bsp_pins.src"]},
|
||||
{"from": "boards_sfe/redboard_artemis/bsp", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/TARGET_SFE_ARTEMIS/bsp", "ignore": ["gcc", "bsp_pins.src"]},
|
||||
{"from": "boards_sfe/redboard_artemis_atp/bsp", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/TARGET_SFE_ARTEMIS_ATP/bsp", "ignore": ["gcc", "bsp_pins.src"]},
|
||||
{"from": "boards_sfe/redboard_artemis_nano/bsp", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/TARGET_SFE_ARTEMIS_NANO/bsp", "ignore": ["gcc", "bsp_pins.src"]},
|
||||
|
||||
{"from": "boards_sfe/common/third_party/hm01b0", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/COMPONENT_hm01b0/hm01b0", "ignore": []},
|
||||
{"from": "boards_sfe/common/third_party/lis2dh12", "to": "targets/TARGET_Ambiq_Micro/TARGET_Apollo3/COMPONENT_lis2dh12/lis2dh12", "ignore": []}
|
||||
],
|
||||
|
||||
"generate": {
|
||||
"pincfgs": {
|
||||
"peripherals": {
|
||||
"src": "{_sdk}/boards_sfe/common/support/apollo3/peripherals/pins.src",
|
||||
"dest": "{_mbed}/targets/TARGET_Ambiq_Micro/TARGET_Apollo3/device/PeripheralPinConfigs",
|
||||
"guard": "_APOLLO3_PERIPHERAL_PIN_CONFIGS_H_",
|
||||
"bgaguard": "AM_PACKAGE_BGA",
|
||||
"prefix": "AP3_PER"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
# requires:
|
||||
# - 'make' available at the command line
|
||||
# - 'arm-none-eabi-xxx' available at the command line (preferred version is q4-2018-major)
|
||||
|
||||
# example usage
|
||||
# locations:
|
||||
# from bsp repo root:
|
||||
# common/bsp_pinconfig/scripts/regen_bsp_libs.sh
|
||||
# from remote location: (requires $AMSDK environment variable -- {boards_sfe} can be whatever you named the root of the bsp repo )
|
||||
# $AMSDK/{boards_sfe}/common/bsp_pinconfig/scripts/regen_bsp_libs.sh -r $AMSDK/{boards_sfe}
|
||||
# arguments:
|
||||
# [-r $BSP_ROOT] path to bsp root optional -- defaults to the current directory
|
||||
# (should be specified when calling script remotely)
|
||||
# [-b $BOARDS_FILE] path to boards file optional -- defaults to all supported bsp boards
|
||||
# (for now boards must still have source files located in the bsp repo)
|
||||
|
||||
# setup
|
||||
set -e
|
||||
set -o errexit
|
||||
echo "" 1>&2
|
||||
|
||||
# get enclosing directory
|
||||
DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
|
||||
|
||||
# defaults
|
||||
BSP_ROOT=.
|
||||
BOARDS_FILE=$DIR/configuration/boards.sh
|
||||
|
||||
# handle arguments
|
||||
while getopts ":r:b:" opt; do
|
||||
case $opt in
|
||||
r) BSP_ROOT="$OPTARG"
|
||||
;;
|
||||
b) BOARDS_FILE="$OPTARG"
|
||||
;;
|
||||
\?) echo "Invalid option -$OPTARG" 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# verify bsp root
|
||||
echo "Using \$BSP_ROOT=$BSP_ROOT" 1>&2
|
||||
VFILE=$BSP_ROOT/README.md
|
||||
if [ -f "$VFILE" ];
|
||||
then
|
||||
echo "\$BSP_ROOT verification passed" 1>&2
|
||||
else
|
||||
echo "\$BSP_ROOT verification failed" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# load in boards to handle
|
||||
echo "Using \$BOARDS_FILE=$BOARDS_FILE" 1>&2
|
||||
source $BOARDS_FILE
|
||||
|
||||
echo "" 1>&2
|
||||
for value in $BOARDS
|
||||
do
|
||||
echo "Regenerating bsp library for: $value" 1>&2
|
||||
make -C $BSP_ROOT/$value/bsp/gcc
|
||||
done
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env bash
|
||||
# requires:
|
||||
# - python3 available at the command line
|
||||
|
||||
# example usage
|
||||
# locations:
|
||||
# from bsp repo root:
|
||||
# common/bsp_pinconfig/scripts/regen_bsp_pins.sh
|
||||
# from remote location: (requires $AMSDK environment variable -- {boards_sfe} can be whatever you named the root of the bsp repo )
|
||||
# $AMSDK/{boards_sfe}/common/bsp_pinconfig/scripts/regen_bsp_pins.sh -r $AMSDK/{boards_sfe}
|
||||
# arguments:
|
||||
# [-r $BSP_ROOT] path to bsp root optional -- defaults to the current directory
|
||||
# (should be specified when calling script remotely)
|
||||
# [-b $BOARDS_FILE] path to boards file optional -- defaults to all supported bsp boards
|
||||
# (for now boards must still have source files located in the bsp repo)
|
||||
|
||||
# setup
|
||||
set -e
|
||||
set -o errexit
|
||||
echo "" 1>&2
|
||||
|
||||
# get enclosing directory
|
||||
DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
|
||||
|
||||
# defaults
|
||||
BSP_ROOT=.
|
||||
BOARDS_FILE=$DIR/configuration/boards.sh
|
||||
|
||||
# handle arguments
|
||||
while getopts ":r:b:" opt; do
|
||||
case $opt in
|
||||
r) BSP_ROOT="$OPTARG"
|
||||
;;
|
||||
b) BOARDS_FILE="$OPTARG"
|
||||
;;
|
||||
\?) echo "Invalid option -$OPTARG" 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# verify bsp root
|
||||
echo "Using \$BSP_ROOT=$BSP_ROOT" 1>&2
|
||||
VFILE=$BSP_ROOT/README.md
|
||||
if [ -f "$VFILE" ];
|
||||
then
|
||||
echo "\$BSP_ROOT verification passed" 1>&2
|
||||
else
|
||||
echo "\$BSP_ROOT verification failed" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# load in boards to handle
|
||||
echo "Using \$BOARDS_FILE=$BOARDS_FILE" 1>&2
|
||||
source $BOARDS_FILE
|
||||
|
||||
# generate bsp files for every board
|
||||
echo "" 1>&2
|
||||
for value in $BOARDS
|
||||
do
|
||||
echo "Regenerating bsp_pins files for: $value" 1>&2
|
||||
$BSP_ROOT/common/bsp_pinconfig/pinconfig.py $BSP_ROOT/$value/bsp/bsp_pins.src h > $BSP_ROOT/$value/bsp/am_bsp_pins.h
|
||||
$BSP_ROOT/common/bsp_pinconfig/pinconfig.py $BSP_ROOT/$value/bsp/bsp_pins.src c > $BSP_ROOT/$value/bsp/am_bsp_pins.c
|
||||
done
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
# requires:
|
||||
# - see requirements of source scripts
|
||||
|
||||
# example usage
|
||||
# locations:
|
||||
# from bsp repo root:
|
||||
# common/bsp_pinconfig/scripts/regen_bsps.sh
|
||||
# from remote location: (requires $AMSDK environment variable -- {boards_sfe} can be whatever you named the root of the bsp repo )
|
||||
# $AMSDK/{boards_sfe}/common/bsp_pinconfig/scripts/regen_bsps.sh -r $AMSDK/{boards_sfe}
|
||||
# arguments:
|
||||
# [-r $BSP_ROOT] path to bsp root optional -- defaults to the current directory
|
||||
# (should be specified when calling script remotely)
|
||||
# [-b $BOARDS_FILE] path to boards file optional -- defaults to all supported bsp boards
|
||||
# (for now boards must still have source files located in the bsp repo)
|
||||
|
||||
# setup
|
||||
set -e
|
||||
set -o errexit
|
||||
echo "" 1>&2
|
||||
|
||||
# get enclosing directory
|
||||
DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")")
|
||||
|
||||
# defaults
|
||||
BSP_ROOT=.
|
||||
BOARDS_FILE=$BSP_ROOT/common/tools_sfe/scripts/configuration/boards.sh
|
||||
|
||||
# handle arguments
|
||||
while getopts ":r:b:" opt; do
|
||||
case $opt in
|
||||
r) BSP_ROOT="$OPTARG"
|
||||
;;
|
||||
b) BOARDS_FILE="$OPTARG"
|
||||
;;
|
||||
\?) echo "Invalid option -$OPTARG" 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# regen pins and libs
|
||||
$BSP_ROOT/common/tools_sfe/scripts/regen_bsp_pins.sh -r $BSP_ROOT -b $BOARDS_FILE # regenerates source (.h and .c) files from the bsp_pins.src files
|
||||
$BSP_ROOT/common/tools_sfe/scripts/regen_bsp_libs.sh -r $BSP_ROOT -b $BOARDS_FILE # regenerates library archive files from bsp source (.h and .c) files
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3.8
|
||||
|
||||
# requires python3.8
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import os
|
||||
import subprocess
|
||||
from braceexpand import braceexpand as expand
|
||||
|
||||
# ***********************************************************************************
|
||||
#
|
||||
# Main function
|
||||
#
|
||||
# ***********************************************************************************
|
||||
def main():
|
||||
|
||||
# load configuration
|
||||
with open(args.config, 'r') as fin:
|
||||
config = json.loads(fin.read())
|
||||
|
||||
# handle copy steps
|
||||
for step in config['copy']:
|
||||
src_path = os.path.join(args.sdk, step['from'])
|
||||
dest_path = os.path.join(args.mbed, step['to'])
|
||||
ignore_patterns = step['ignore']
|
||||
print("copy")
|
||||
print("from '" + src_path + "'")
|
||||
print("to '" + dest_path + "'")
|
||||
print("\texcluding:")
|
||||
print(ignore_patterns)
|
||||
print()
|
||||
shutil.rmtree(dest_path, ignore_errors=True)
|
||||
shutil.copytree(src_path, dest_path, ignore=shutil.ignore_patterns(*ignore_patterns), dirs_exist_ok=True)
|
||||
|
||||
# handle pincfg generation
|
||||
print('generate pincfgs:')
|
||||
def absolutify(path):
|
||||
new_path = path
|
||||
new_path = new_path.replace('{_mbed}', args.mbed)
|
||||
new_path = new_path.replace('{_sdk}', args.sdk)
|
||||
return new_path
|
||||
|
||||
selectors = ['c', 'h']
|
||||
for name, job in config['generate']['pincfgs'].items():
|
||||
print('\t', name)
|
||||
for selector in selectors:
|
||||
results = subprocess.run( [
|
||||
'python',
|
||||
absolutify('{_sdk}/boards_sfe/common/bsp_pinconfig/pinconfig.py'),
|
||||
absolutify(job['src']), selector,
|
||||
'-g', job['guard'],
|
||||
'-p', job['prefix'],
|
||||
'-b', job['bgaguard']
|
||||
],
|
||||
capture_output=True)
|
||||
|
||||
with open(absolutify(job['dest']) + '.' + selector, 'wb') as fout:
|
||||
fout.write(results.stdout)
|
||||
errors = str(results.stderr)
|
||||
if errors != "b''":
|
||||
print('error: ', str(results.stderr))
|
||||
|
||||
exit()
|
||||
|
||||
|
||||
|
||||
# ******************************************************************************
|
||||
#
|
||||
# Main program flow
|
||||
#
|
||||
# ******************************************************************************
|
||||
if __name__ == '__main__':
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Utility to generate GCC flag and symbol files from mbed build profiles')
|
||||
|
||||
parser.add_argument('-m', '--mbed', dest='mbed', required=True, help='path to root of mbed')
|
||||
parser.add_argument('-c', '--config', dest='config', required=False, default='./boards_sfe/common/tools_sfe/scripts/configuration/mbed-config.json', help='path to the json configuration file')
|
||||
parser.add_argument('-s', '--sdk', dest='sdk', required=False, default='.', help='path to root of AmbiqSuiteSDK')
|
||||
parser.add_argument('-v', '--verbose', default=0, help='enable verbose output', action='store_true')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Create print function for verbose output if caller deems it: https://stackoverflow.com/questions/5980042/how-to-implement-the-verbose-or-v-option-into-a-script
|
||||
if args.verbose:
|
||||
def verboseprint(*args):
|
||||
# Print each argument separately so caller doesn't need to
|
||||
# stuff everything to be printed into a single string
|
||||
for arg in args:
|
||||
print(arg, end='', flush=True)
|
||||
print()
|
||||
else:
|
||||
verboseprint = lambda *a: None # do-nothing function
|
||||
|
||||
def twopartprint(verbosestr, printstr):
|
||||
if args.verbose:
|
||||
print(verbosestr, end = '')
|
||||
|
||||
print(printstr)
|
||||
|
||||
main()
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
# requires:
|
||||
|
||||
# a script to aid in upgrading the AmbiqSuite SDK
|
||||
|
||||
# # get enclosing directory
|
||||
# DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")") # can handle symlinks but fails on mac
|
||||
DIR=$(dirname -- "$BASH_SOURCE") # assumes no symlinks.... (for mac compatibility)
|
||||
|
||||
# import sh-realpath
|
||||
source $DIR/utility/sh-realpath/realpath.sh
|
||||
|
||||
# defaults
|
||||
SDK_ROOT=$DIR/../../../..
|
||||
UPGRADE_ROOT=
|
||||
|
||||
# handle arguments
|
||||
while getopts ":r:u:" opt; do
|
||||
case $opt in
|
||||
r) SDK_ROOT="$OPTARG"
|
||||
;;
|
||||
u) UPGRADE_ROOT="$OPTARG"
|
||||
;;
|
||||
\?) echo "Invalid option -$OPTARG" 1>&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ensure user provided -u option
|
||||
if [ -z "$UPGRADE_ROOT" ]
|
||||
then
|
||||
echo "User must provide -u option (path to upgrade sdk directory)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# make a temporary directory to hold the old sdk
|
||||
TMP_DIR=$(mktemp -d -t ambiqsuite_sdk_upgrade_tmp)
|
||||
echo "created temporary directory $TMP_DIR"
|
||||
|
||||
# get the sdk folder name (and verify)
|
||||
SDK_ROOT=$(realpath $SDK_ROOT)
|
||||
SDK_NAME=$(basename $SDK_ROOT)
|
||||
echo "Got SDK name: $SDK_NAME"
|
||||
VFILE=$SDK_ROOT/VERSION.txt
|
||||
if [ -f "$VFILE" ];
|
||||
then
|
||||
echo "\$SDK_ROOT verification passed" 1>&2
|
||||
else
|
||||
echo "\$SDK_ROOT verification failed" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get the upgrade folder (and verify)
|
||||
UPGRADE_ROOT=$(realpath $UPGRADE_ROOT)
|
||||
echo "Got upgrade SDK path: $UPGRADE_ROOT"
|
||||
VFILE=$UPGRADE_ROOT/VERSION.txt
|
||||
if [ -f "$VFILE" ];
|
||||
then
|
||||
echo "\$UPGRADE_ROOT verification passed" 1>&2
|
||||
else
|
||||
echo "\$UPGRADE_ROOT verification failed" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# copy sdk to temporary dir (being sure to keep hidden files)
|
||||
cp -r $SDK_ROOT/. $TMP_DIR
|
||||
|
||||
# remove old directory
|
||||
rm -rf $SDK_ROOT
|
||||
|
||||
# copy the upgrade to the SDK_ROOT
|
||||
cp -r $UPGRADE_ROOT $SDK_ROOT
|
||||
|
||||
# copy important directories from the old SDK to the upgrade
|
||||
cp -r $TMP_DIR/.git* $SDK_ROOT
|
||||
cp -r $TMP_DIR/README.md $SDK_ROOT
|
||||
cp -r $TMP_DIR/boards_sfe $SDK_ROOT
|
||||
|
||||
# clean up temporary folder
|
||||
rm -rf $TMP_DIR
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
# this script relies on the environment variable $AMSDK being set to the root of your AmbiqSuite SDK
|
||||
# use it when you have a pre-built binary file to upload onto a board
|
||||
|
||||
# default variables
|
||||
BINFILE=.
|
||||
ASB_UPLOAD_BAUD=115200
|
||||
PORT=COM4
|
||||
|
||||
# immutables
|
||||
COMMONPATH=$AMSDK/boards_sfe/common
|
||||
PYTHON3=python3
|
||||
AMBIQ_BIN2BOARD=$COMMONPATH/tools_sfe/asb/asb.py
|
||||
BINPATH=temp_
|
||||
|
||||
# handle arguments
|
||||
while getopts ":p:f:b:u:" opt; do
|
||||
case $opt in
|
||||
p) PORT="$OPTARG"
|
||||
;;
|
||||
f) BINFILE="$OPTARG"
|
||||
;;
|
||||
b) ASB_UPLOAD_BAUD="$OPTARG"
|
||||
;;
|
||||
u) UPLOADER="$OPTARG"
|
||||
;;
|
||||
\?) echo "Invalid option -$OPTARG" >&2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf "Uploading file with Ambiq Secure Bootloader:\n%s\n\n" "$BINFILE"
|
||||
|
||||
$PYTHON3 $AMBIQ_BIN2BOARD --bin $BINFILE --load-address-blob 0x20000 --magic-num 0xCB -o $BINPATH --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $ASB_UPLOAD_BAUD -port $PORT -r 2 -v
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Michael Kropat
|
||||
|
||||
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.
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
.PHONY: test
|
||||
test: lint unit-test
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
-shellcheck realpath.sh
|
||||
-checkbashisms realpath.sh
|
||||
|
||||
.PHONY: unit-test
|
||||
unit-test: t/*
|
||||
|
||||
t/%: force
|
||||
bash "$@"
|
||||
dash "$@"
|
||||
|
||||
.PHONY: force
|
||||
force: ;
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
# sh-realpath
|
||||
|
||||
*A portable, pure shell implementation of realpath*
|
||||
|
||||
Copy the functions in [realpath.sh](realpath.sh) into your shell script to
|
||||
avoid introducing a dependency on either `realpath` or `readlink -f`, since:
|
||||
|
||||
* `realpath` does not come installed by default
|
||||
* `readlink -f` **is not portable** to OS-X ([relevant man page](https://developer.apple.com/library/mac/documentation/Darwin/Reference/Manpages/man1/readlink.1.html))
|
||||
|
||||
## Usage
|
||||
|
||||
$ source ./realpath.sh
|
||||
$ realpath /proc/self
|
||||
/proc/2772
|
||||
|
||||
Or we can get tricky:
|
||||
|
||||
$ cd /tmp
|
||||
$ mkdir -p somedir/targetdir somedir/anotherdir
|
||||
$ ln -s somedir somedirlink
|
||||
$ ln -s somedir/anotherdir/../anotherlink somelink
|
||||
$ ln -s targetdir/targetpath somedir/anotherlink
|
||||
$ realpath .///somedirlink/././anotherdir/../../somelink
|
||||
/tmp/somedir/targetdir/targetpath
|
||||
|
||||
## API
|
||||
|
||||
Note: unlike `realpath(1)`, these functions take no options; **do not** use `--` to escape any arguments
|
||||
|
||||
| Function | Description
|
||||
| --------------------------------- | -------------
|
||||
| <pre>realpath PATH</pre> | Resolve all symlinks to `PATH`, then output the canonicalized result
|
||||
| <pre>resolve_symlinks PATH</pre> | If `PATH` is a symlink, follow it as many times as possible; output the path of the first non-symlink found
|
||||
| <pre>canonicalize_path PATH</pre> | Output absolute path that `PATH` refers to, resolving any relative directories (`.`, `..`) in `PATH` and any symlinks in `PATH`'s ancestor directories
|
||||
|
||||
### readlink Emulation
|
||||
|
||||
`realpath.sh` includes optional readlink emulation. It exposes a `readlink`
|
||||
function that calls the system `readlink(1)` if it exists. Otherwise it uses
|
||||
`stat(1)` to emulate the same functionality. In contrast to the functions in
|
||||
the previous section, you may pass `--` as the first argument, since you may be
|
||||
calling the system `readlink(1)`.
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
#!/bin/sh
|
||||
|
||||
realpath() {
|
||||
canonicalize_path "$(resolve_symlinks "$1")"
|
||||
}
|
||||
|
||||
resolve_symlinks() {
|
||||
_resolve_symlinks "$1"
|
||||
}
|
||||
|
||||
_resolve_symlinks() {
|
||||
_assert_no_path_cycles "$@" || return
|
||||
|
||||
local dir_context path
|
||||
path=$(readlink -- "$1")
|
||||
if [ $? -eq 0 ]; then
|
||||
dir_context=$(dirname -- "$1")
|
||||
_resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@"
|
||||
else
|
||||
printf '%s\n' "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
_prepend_dir_context_if_necessary() {
|
||||
if [ "$1" = . ]; then
|
||||
printf '%s\n' "$2"
|
||||
else
|
||||
_prepend_path_if_relative "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
_prepend_path_if_relative() {
|
||||
case "$2" in
|
||||
/* ) printf '%s\n' "$2" ;;
|
||||
* ) printf '%s\n' "$1/$2" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
_assert_no_path_cycles() {
|
||||
local target path
|
||||
|
||||
target=$1
|
||||
shift
|
||||
|
||||
for path in "$@"; do
|
||||
if [ "$path" = "$target" ]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
canonicalize_path() {
|
||||
if [ -d "$1" ]; then
|
||||
_canonicalize_dir_path "$1"
|
||||
else
|
||||
_canonicalize_file_path "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
_canonicalize_dir_path() {
|
||||
(cd "$1" 2>/dev/null && pwd -P)
|
||||
}
|
||||
|
||||
_canonicalize_file_path() {
|
||||
local dir file
|
||||
dir=$(dirname -- "$1")
|
||||
file=$(basename -- "$1")
|
||||
(cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file")
|
||||
}
|
||||
|
||||
# Optionally, you may also want to include:
|
||||
|
||||
### readlink emulation ###
|
||||
|
||||
readlink() {
|
||||
if _has_command readlink; then
|
||||
_system_readlink "$@"
|
||||
else
|
||||
_emulated_readlink "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
_has_command() {
|
||||
hash -- "$1" 2>/dev/null
|
||||
}
|
||||
|
||||
_system_readlink() {
|
||||
command readlink "$@"
|
||||
}
|
||||
|
||||
_emulated_readlink() {
|
||||
if [ "$1" = -- ]; then
|
||||
shift
|
||||
fi
|
||||
|
||||
_gnu_stat_readlink "$@" || _bsd_stat_readlink "$@"
|
||||
}
|
||||
|
||||
_gnu_stat_readlink() {
|
||||
local output
|
||||
output=$(stat -c %N -- "$1" 2>/dev/null) &&
|
||||
|
||||
printf '%s\n' "$output" |
|
||||
sed "s/^‘[^’]*’ -> ‘\(.*\)’/\1/
|
||||
s/^'[^']*' -> '\(.*\)'/\1/"
|
||||
# FIXME: handle newlines
|
||||
}
|
||||
|
||||
_bsd_stat_readlink() {
|
||||
stat -f %Y -- "$1" 2>/dev/null
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ./realpath.sh
|
||||
|
||||
setUp() {
|
||||
_test_previousdir=$PWD
|
||||
_test_workingdir=$(mktemp -d -t sh-realpath.XXXXXX)
|
||||
cd -P -- "$_test_workingdir"
|
||||
}
|
||||
|
||||
tearDown() {
|
||||
cd -- "$_test_previousdir"
|
||||
rm -rf -- "$_test_workingdir"
|
||||
}
|
||||
|
||||
it_outputs_pwd_when_passed_zero_args() {
|
||||
local output
|
||||
|
||||
output=$(canonicalize_path)
|
||||
|
||||
assertTrue '`canonicalize_path` succeeds' $?
|
||||
assertEquals 'outputs $PWD' "$PWD/" "$output"
|
||||
}
|
||||
|
||||
it_outputs_absolute_path_to_target_when_passed_the_name_of_a_non_existent_file() {
|
||||
local output
|
||||
|
||||
output=$(canonicalize_path non_existent_file)
|
||||
|
||||
assertTrue '`canonicalize_path non_existent_file` succeeds' $?
|
||||
assertEquals 'output is "$PWD/non_existent_file"' "$PWD/non_existent_file" "$output"
|
||||
}
|
||||
|
||||
it_returns_an_error_when_passed_a_path_in_a_non_existent_dir() {
|
||||
local output
|
||||
|
||||
output=$(canonicalize_path non_existent_dir/somepath 2>&1)
|
||||
|
||||
assertFalse '`canonicalize_path non_existent_dir/somepath` fails' $?
|
||||
assertNull 'no output' "$output"
|
||||
}
|
||||
|
||||
it_outputs_absolute_path_when_passed_the_name_of_a_path_in_a_subdir() {
|
||||
local output
|
||||
mkdir somedir
|
||||
|
||||
output=$(canonicalize_path somedir/somepath)
|
||||
|
||||
assertTrue '`canonicalize_path somedir/somepath` succeeds' $?
|
||||
assertEquals 'output is "$PWD/somedir/somepath"' "$PWD/somedir/somepath" "$output"
|
||||
}
|
||||
|
||||
it_returns_an_error_when_passed_a_path_in_a_symlink_to_nowhere() {
|
||||
ln -s non/existent/dir somelink
|
||||
|
||||
canonicalize_path somelink/somepath
|
||||
|
||||
assertFalse '`canonicalize_path somelink/somepath` fails' $?
|
||||
}
|
||||
|
||||
it_returns_the_target_dir_when_passed_a_symlink_to_another_dir() {
|
||||
local output
|
||||
mkdir somedir
|
||||
ln -s somedir somelink
|
||||
|
||||
output=$(canonicalize_path somelink)
|
||||
|
||||
assertTrue '`canonicalize_path somelink` succeeds' $?
|
||||
assertEquals 'output is "$PWD/somedir"' "$PWD/somedir" "$output"
|
||||
}
|
||||
|
||||
it_returns_absolute_path_of_target_directory_when_passed_a_path_in_a_symlink_to_another_dir() {
|
||||
local output
|
||||
mkdir somedir
|
||||
ln -s somedir somelink
|
||||
|
||||
output=$(canonicalize_path somelink/somepath)
|
||||
|
||||
assertTrue '`canonicalize_path somelink/somepath` succeeds' $?
|
||||
assertEquals 'output is "$PWD/somedir/somepath"' "$PWD/somedir/somepath" "$output"
|
||||
}
|
||||
|
||||
it_collapses_current_dir_references() {
|
||||
local output
|
||||
|
||||
output=$(canonicalize_path ././somepath)
|
||||
|
||||
assertTrue '`canonicalize_path ././somepath` succeeds' $?
|
||||
assertEquals 'output is "$PWD/somepath"' "$PWD/somepath" "$output"
|
||||
}
|
||||
|
||||
it_collapses_extra_slashes() {
|
||||
local output
|
||||
|
||||
output=$(canonicalize_path .///somepath)
|
||||
|
||||
assertTrue '`canonicalize_path .///somepath` succeeds' $?
|
||||
assertEquals 'output is "$PWD/somepath"' "$PWD/somepath" "$output"
|
||||
}
|
||||
|
||||
it_collapses_parent_dir_references() {
|
||||
local output
|
||||
mkdir -p somedir/anotherdir
|
||||
|
||||
output=$(canonicalize_path somedir/anotherdir/../../somepath)
|
||||
|
||||
assertTrue '`canonicalize_path somedir/anotherdir/../../somepath` succeeds' $?
|
||||
assertEquals 'output is "$PWD/somepath"' "$PWD/somepath" "$output"
|
||||
}
|
||||
|
||||
|
||||
##### Test Harness #####
|
||||
|
||||
# suite() -- find and register tests to be run
|
||||
# Derived from Gary Bernhardt's screencast #68
|
||||
# (https://www.destroyallsoftware.com/screencasts/catalog/test-driving-shell-scripts)
|
||||
suite() {
|
||||
local name tests
|
||||
tests=$(grep ^it_ "$0" | cut -d '(' -f 1)
|
||||
for name in $tests; do
|
||||
suite_addTest "$name"
|
||||
done
|
||||
}
|
||||
|
||||
if hash shunit2 2>/dev/null; then
|
||||
. shunit2
|
||||
else
|
||||
echo 'Error: shunit2(1) could not be located. Please install it on your $PATH.' >&2
|
||||
exit 1
|
||||
fi
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#!/bin/sh
|
||||
|
||||
. ./realpath.sh
|
||||
|
||||
setUp() {
|
||||
unset _system_readlink _gnu_stat_readlink _bsd_stat_readlink
|
||||
|
||||
_has_command() {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
it_calls_system_readlink_when_has_command_readlink_is_true() {
|
||||
_has_command() {
|
||||
test "$1" = readlink
|
||||
}
|
||||
|
||||
local readlink_arg1 readlink_arg2
|
||||
_system_readlink() {
|
||||
readlink_arg1="$1"
|
||||
readlink_arg2="$2"
|
||||
}
|
||||
|
||||
readlink -- some/path
|
||||
|
||||
assertEquals -- "$readlink_arg1"
|
||||
assertEquals some/path "$readlink_arg2"
|
||||
}
|
||||
|
||||
it_calls__gnu_stat_readlink_when_has_command_readlink_is_false() {
|
||||
local called
|
||||
_gnu_stat_readlink() {
|
||||
called=1
|
||||
}
|
||||
|
||||
readlink -- some/path
|
||||
|
||||
assertNotNull "_gnu_stat_readlink called" "$called"
|
||||
}
|
||||
|
||||
it_passes_actual_arg_to__gnu_stat_readlink() {
|
||||
local arg
|
||||
_gnu_stat_readlink() {
|
||||
arg="$1"
|
||||
}
|
||||
|
||||
readlink -- some/path
|
||||
|
||||
assertEquals some/path "$arg"
|
||||
}
|
||||
|
||||
it_passes_first_arg_to__gnu_stat_readlink_when_no_dashes() {
|
||||
local arg
|
||||
_gnu_stat_readlink() {
|
||||
arg="$1"
|
||||
}
|
||||
|
||||
readlink some/path
|
||||
|
||||
assertEquals some/path "$arg"
|
||||
}
|
||||
|
||||
it_doesnt_call__bsd_stat_readlink_when__gnu_stat_readlink_returns_true() {
|
||||
_gnu_stat_readlink() {
|
||||
return 0
|
||||
}
|
||||
|
||||
local called
|
||||
_bsd_stat_readlink() {
|
||||
called=1
|
||||
}
|
||||
|
||||
readlink -- some/path
|
||||
|
||||
assertNull "_bsd_stat_readlink not called" "$called"
|
||||
}
|
||||
|
||||
it_calls__bsd_stat_readlink_when__gnu_stat_readlink_returns_false() {
|
||||
_gnu_stat_readlink() {
|
||||
return 1
|
||||
}
|
||||
|
||||
local called
|
||||
_bsd_stat_readlink() {
|
||||
called=1
|
||||
}
|
||||
|
||||
readlink -- some/path
|
||||
|
||||
assertNotNull "_bsd_stat_readlink called" "$called"
|
||||
}
|
||||
|
||||
it_passes_actual_arg_to__bsd_stat_readlink() {
|
||||
_gnu_stat_readlink() {
|
||||
return 1
|
||||
}
|
||||
|
||||
local arg
|
||||
_bsd_stat_readlink() {
|
||||
arg="$1"
|
||||
}
|
||||
|
||||
readlink -- some/path
|
||||
|
||||
assertEquals some/path "$arg"
|
||||
}
|
||||
|
||||
##### Test Harness #####
|
||||
|
||||
# suite() -- find and register tests to be run
|
||||
# Derived from Gary Bernhardt's screencast #68
|
||||
# (https://www.destroyallsoftware.com/screencasts/catalog/test-driving-shell-scripts)
|
||||
suite() {
|
||||
local name tests
|
||||
tests=$(grep ^it_ "$0" | cut -d '(' -f 1)
|
||||
for name in $tests; do
|
||||
suite_addTest "$name"
|
||||
done
|
||||
}
|
||||
|
||||
if hash shunit2 2>/dev/null; then
|
||||
. shunit2
|
||||
else
|
||||
echo 'Error: shunit2(1) could not be located. Please install it on your $PATH.' >&2
|
||||
exit 1
|
||||
fi
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user